From 08791fe29f114f8a5d5596b417ab8378bde326cb Mon Sep 17 00:00:00 2001 From: Hamatoma Date: Sat, 4 May 2024 15:17:32 +0200 Subject: [PATCH] V 0.2.6 Word umgebaut, verbImperfect MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit - Module Verb und Noun entfallen, Word arbeitet mit strukturiertem Attribut options - GermanGrammar: Korrekturen in verbImperfect() und verbPresent() - Phrase: - umbenannt: phrase_id in german_id - Word: - Wortarten als Registerblätter - lokale Dateien für CSS+JS --- app/Helpers/GermanGrammar.php | 80 ++- app/Helpers/KeyValueStorage.php | 1 + app/Helpers/ViewHelperLocal.php | 18 +- app/Http/Controllers/PhraseController.php | 20 +- app/Http/Controllers/WordController.php | 497 +++++++++++++++--- app/Models/Phrase.php | 3 +- app/Models/Word.php | 4 +- composer.lock | 355 ++++++------- .../2024_03_21_191359_create_words_table.php | 3 +- ...2024_03_21_202004_create_phrases_table.php | 2 +- .../2024_03_21_202154_create_nouns_table.php | 30 -- .../2024_03_23_185143_create_verbs_table.php | 44 -- ...024_04_09_190303_add_phrases_phrase_id.php | 26 - ....php => 2024_04_29_191459_alter_words.php} | 7 +- database/seeders/WordSeeder.php | 24 +- lang/de_DE.json | 9 +- public/css/bootstrap-icons.css | 1 + public/css/bootstrap.min.css | 1 + public/css/fonts | 1 + public/css/gadeku.css | 15 + public/js/bootstrap.min.js | 1 + resources/lang/sources/gadeku.de.json | 9 +- resources/views/layouts/backend.blade.php | 13 +- resources/views/layouts/frontend.blade.php | 13 +- resources/views/noun/edit.blade.php | 2 +- resources/views/phrase/create.blade.php | 2 - resources/views/phrase/show.blade.php | 2 +- resources/views/word/create.blade.php | 11 +- resources/views/word/edit-adjective.blade.php | 19 + resources/views/word/edit-noun.blade.php | 33 ++ resources/views/word/edit-verb.blade.php | 47 ++ resources/views/word/edit.blade.php | 19 +- resources/views/word/index.blade.php | 1 + 33 files changed, 845 insertions(+), 468 deletions(-) create mode 120000 app/Helpers/KeyValueStorage.php delete mode 100644 database/migrations/2024_03_21_202154_create_nouns_table.php delete mode 100644 database/migrations/2024_03_23_185143_create_verbs_table.php delete mode 100644 database/migrations/2024_04_09_190303_add_phrases_phrase_id.php rename database/migrations/{2024_04_13_131901_change_words_word_id.php => 2024_04_29_191459_alter_words.php} (67%) create mode 120000 public/css/bootstrap-icons.css create mode 120000 public/css/bootstrap.min.css create mode 120000 public/css/fonts create mode 120000 public/js/bootstrap.min.js create mode 100644 resources/views/word/edit-adjective.blade.php create mode 100644 resources/views/word/edit-noun.blade.php create mode 100644 resources/views/word/edit-verb.blade.php diff --git a/app/Helpers/GermanGrammar.php b/app/Helpers/GermanGrammar.php index 3814253..10d6bd9 100644 --- a/app/Helpers/GermanGrammar.php +++ b/app/Helpers/GermanGrammar.php @@ -3,85 +3,81 @@ namespace App\Helpers; class GermanGrammar { - public static function verbImperfect(string $infinitive, int $person, bool $singular) + public static function baseFormOfVerb(string $verb) + { + if (str_ends_with($verb, 'ln') || str_ends_with($verb, 'en')) { + $rc = substr($verb, 0, -2); + } else { + $rc = $verb; + } + return $rc; + } + public static function verbImperfect(string $baseForm, int $person, bool $singular) { - $base = substr($infinitive, 0, strlen($infinitive) - 2); if ($singular) { - $end1 = 'te'; - $end2 = 'test'; - if (str_ends_with($base, 't')) { - // rosten - $between = 'e'; - } else { - // kaufen - $between = ''; - } - switch ($person) { - case 1: - default: - $rc = "$base$between$end1"; + switch ($person) { + case 1: // schnitt kauf-te lächel-te + default: // schnitt kauf-te lächel-te + $rc = $baseForm; break; case 2: - $rc = "$base$between$end2"; + // schnitt-est kauf-test lächel-test + $rc = str_ends_with($baseForm, 't') ? "{$baseForm}est" : "{$baseForm}test"; break; } } else { - $end1 = 'ten'; - $end3 = 'tet'; - if (str_ends_with($base, 't')) { - // rosten - $between = 'e'; - } else { - // kaufen - $between = ''; - } - switch ($person) { - default: - case 1: - $rc = "$base$between$end1"; + $short = str_ends_with($baseForm, 't'); + switch ($person) { + default: // schnitt-en kauf-ten lächel-ten + case 1: // schnitt-en kauf-ten lächel-ten + $rc = $short ? "{$baseForm}en" : "{$baseForm}ten"; break; - case 2: - $rc = "$base$between$end3"; + case 2: // schnitt-et kauf-tet lächel-tet + $rc = $short ? "{$baseForm}et" : "{$baseForm}tet"; break; } } return $rc; } - public static function verbParticipe(string $infinitive): string{ - $base = substr($infinitive, 0, strlen($infinitive) - 2); - $rc = str_ends_with($base, 't') ? "ge$base" . 'tet' : "ge$base" . "t"; + + public static function verbParticiple(string $baseForm): string + { + $rc = str_ends_with($baseForm, 't') ? "ge$baseForm" . 'tet' : "ge$baseForm" . "t"; return $rc; } - public static function verbPresent(string $infinitive, int $person, bool $singular) + public static function verbPresent(string $infinitive, int $person, bool $singular, ?string $baseForm = null) { - $base = substr($infinitive, 0, strlen($infinitive) - 2); - if (str_ends_with($base, 's')) { + if ($baseForm == null) { + $baseForm = self::baseFormOfVerb($infinitive); + } + if (str_ends_with($baseForm, 's')) { // reisen $end2 = 't'; } else { // kochen $end2 = 'st'; } + $between = str_ends_with($baseForm, 'd') ? 'e' : ''; if ($singular) { switch ($person) { case 1: - $rc = $base . 'e'; + $rc = "{$baseForm}e"; break; case 2: - $rc = $base . $end2; + $rc = "$baseForm{$between}$end2"; break; default: - $rc = $base . 't'; + $rc = "$baseForm{$between}t"; break; } } else { switch ($person) { default: case 1: - $rc = $base . 'en'; + $rc = $infinitive; break; case 2: - $rc = $base . 't'; + $rc = "$baseForm{$between}t"; break; } } diff --git a/app/Helpers/KeyValueStorage.php b/app/Helpers/KeyValueStorage.php new file mode 120000 index 0000000..9f50bf6 --- /dev/null +++ b/app/Helpers/KeyValueStorage.php @@ -0,0 +1 @@ +../../vendor/hamatoma/laraknife/resources/helpers/KeyValueStorage.php \ No newline at end of file diff --git a/app/Helpers/ViewHelperLocal.php b/app/Helpers/ViewHelperLocal.php index 882c28e..ee922e5 100644 --- a/app/Helpers/ViewHelperLocal.php +++ b/app/Helpers/ViewHelperLocal.php @@ -22,7 +22,7 @@ class ViewHelperLocal * @param int $indexActive the index (0..N-1) of the tab that should be the active tab * @param int $referenceId used for links */ - public static function getNavigationTabInfo(string $name, int $indexActive, int $referenceId = 0): ?NavigationTabs + public static function getNavigationTabInfo(string $name, int $indexActive, int $referenceId = 0, ?string $options = null): ?NavigationTabs { $rc = null; switch ($name) { @@ -32,6 +32,19 @@ class ViewHelperLocal "Documents;/note-index_documents/$referenceId" ], $indexActive); break; + case 'word-edit': + $header = StringHelper::toCapital($options); + if (strpos('verb adjective noun', $options) !== false) { + $rc = new NavigationTabs([ + "Word;/word-edit/$referenceId", + "$header;/word-edit$options/$referenceId" + ], $indexActive); + } else { + $rc = new NavigationTabs([ + "Word;/word-edit/$referenceId", + ], 0); + } + break; default: break; } @@ -41,7 +54,8 @@ class ViewHelperLocal * Tests whether the current user has a role. * @param int $neededPriority ROLE_ADMIN...ROLE_GUEST */ - public static function hasNeededRole(int $neededPriority): bool{ + public static function hasNeededRole(int $neededPriority): bool + { $role = Auth::user()->role_id; return $role <= $neededPriority; } diff --git a/app/Http/Controllers/PhraseController.php b/app/Http/Controllers/PhraseController.php index 1c31c0a..f178c2f 100644 --- a/app/Http/Controllers/PhraseController.php +++ b/app/Http/Controllers/PhraseController.php @@ -30,22 +30,18 @@ class PhraseController extends Controller 'phrase' => '', 'language_scope' => '', 'word_id' => '', - 'phrase_id' => '', + 'german_id' => '', 'owner_id' => '', 'verifiedby_id' => '' ]; } $optionsLanguage = SProperty::optionsByScope('language', $fields['language_scope'], '-'); - $optionsWord = DbHelper::comboboxDataOfTable('words', 'name', 'id', $fields['word_id'], __('')); - $optionsPhrase = DbHelper::comboboxDataOfTable('words', 'name', 'id', $fields['phrase_id'], __('')); $optionsOwner = DbHelper::comboboxDataOfTable('users', 'name', 'id', $fields['owner_id'], __('')); $optionsVerifiedby = DbHelper::comboboxDataOfTable('users', 'name', 'id', $fields['verifiedby_id'], __('')); $context = new ContextLaraKnife($request, $fields); $rc = view('phrase.create', [ 'context' => $context, 'optionsLanguage' => $optionsLanguage, - 'optionsWord' => $optionsWord, - 'optionsPhrase' => $optionsPhrase, 'optionsOwner' => $optionsOwner, 'optionsVerifiedby' => $optionsVerifiedby, ]); @@ -77,7 +73,7 @@ class PhraseController extends Controller ]; } if ($fields['lastLanguage'] != $fields['language']) { - $phraseTranslation = Phrase::where(['language_scope' => $fields['language'], 'phrase_id' => $phrase->id])->first(); + $phraseTranslation = Phrase::where(['language_scope' => $fields['language'], 'german_id' => $phrase->id])->first(); if ($phraseTranslation != null) { $fields['translation'] = $phraseTranslation->phrase; } @@ -115,7 +111,7 @@ class PhraseController extends Controller $sql = " SELECT t0.*, t1.name as language_scope, - (select phrase from phrases t4 where t4.phrase_id=t0.id and t4.language_scope=$lang) as translation + (select phrase from phrases t4 where t4.german_id=t0.id and t4.language_scope=$lang) as translation FROM phrases t0 LEFT JOIN sproperties t1 ON t1.id=t0.language_scope LEFT JOIN users t2 ON t2.id=t0.owner_id @@ -137,7 +133,7 @@ LEFT JOIN users t2 ON t2.id=t0.owner_id if ($fields['verified'] != null) { // 1: not verified 2: verified $not = $fields['verified'] == 1 ? '' : ' NOT'; - array_push($conditions, "EXISTS(SELECT id FROM phrases ph WHERE ph.id=t0.phrase_id AND ph.language_scope=$lang AND ph.verifiedby_id IS$not NULL)"); + array_push($conditions, "EXISTS(SELECT id FROM phrases ph WHERE ph.id=t0.german_id AND ph.language_scope=$lang AND ph.verifiedby_id IS$not NULL)"); } ViewHelper::addConditionPattern($conditions, $parameters, 't0.phrase', 'text'); } @@ -263,19 +259,19 @@ LEFT JOIN users t2 ON t2.id=t0.owner_id $phraseDb = Phrase::find($id); if ($phrase->phrase !== $phraseDb->phrase) { // Invalidate all verifications in all languages:: - DB::update("UPDATE phrases SET verifiedby_id=NULL where phrase_id=$id;"); + DB::update("UPDATE phrases SET verifiedby_id=NULL where german_id=$id;"); // Store new phrase: $phrase->update(['phrase' => $validated['phrase']]); } elseif ($phrase->verifiedby_id == null){ $id2 = auth()->id(); - DB::update("UPDATE phrases SET verifiedby_id=$id2 where phrase_id=$id;"); + DB::update("UPDATE phrases SET verifiedby_id=$id2 where german_id=$id;"); } // Does translation already exists? - $phraseTranslation = Phrase::where(['language_scope' => $fields['language'], 'phrase_id' => $phrase->id])->first(); + $phraseTranslation = Phrase::where(['language_scope' => $fields['language'], 'german_id' => $phrase->id])->first(); if ($phraseTranslation == null) { // Store the new record: Phrase::create([ - 'phrase_id' => $id, + 'german_id' => $id, 'phrase' => $validated['translation'], 'owner_id' => auth()->id(), 'language_scope' => $fields['language'] diff --git a/app/Http/Controllers/WordController.php b/app/Http/Controllers/WordController.php index 18bd4b9..d357b98 100644 --- a/app/Http/Controllers/WordController.php +++ b/app/Http/Controllers/WordController.php @@ -10,11 +10,18 @@ use App\Models\SProperty; use App\Helpers\Pagination; use App\Helpers\ViewHelper; use Illuminate\Http\Request; +use App\Helpers\StringHelper; +use App\Helpers\GermanGrammar; +use App\Helpers\KeyValueStorage; +use App\Helpers\ViewHelperLocal; use App\Helpers\ContextLaraKnife; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Validator; +define('GERMAN', 1202); +define('SEPARATOR_OPTIONS', ';'); + class WordController extends Controller { /** @@ -29,18 +36,14 @@ class WordController extends Controller if (count($fields) === 0) { $fields = [ 'word' => '', - 'usage' => '', 'wordtype_scope' => '', - 'verifiedby_id' => '' ]; } $optionsWordtype = SProperty::optionsByScope('wordtype', $fields['wordtype_scope'], '-'); - $optionsVerifiedby = DbHelper::comboboxDataOfTable('users', 'name', 'id', $fields['verifiedby_id'], __('')); $context = new ContextLaraKnife($request, $fields); $rc = view('word.create', [ 'context' => $context, 'optionsWordtype' => $optionsWordtype, - 'optionsVerifiedby' => $optionsVerifiedby, ]); } return $rc; @@ -50,52 +53,242 @@ class WordController extends Controller */ public function edit(Word $word, Request $request) { + $rc = null; if ($request->btnSubmit === 'btnCancel') { $rc = redirect('/word-index'); } else { $fields = $request->all(); - $phrase = Phrase::where(['word_id' => $word->id, 'language_scope' => 1202])->first(); - if ($phrase == null){ - $phrase = Phrase::create(['word_id' => $word->id, 'phrase' => $word->word, - 'language_scope' => 1202, 'owner_id' => auth()->id()]); + if ($request->btnSubmit === 'btnStore') { + $rc = $this->update($word, $fields, $request); } - if (count($fields) === 1) { - $fields = [ - 'word' => $word->word, - 'usage' => $phrase->phrase, - 'wordtype_scope' => $phrase->wordtype_scope, - 'language' => $request->language, - 'lastLanguage' => '', - 'translation' => '' - ]; - } elseif (count($fields) === 0) { - $fields = [ - 'word' => $word->word, - 'usage' => $phrase->phrase, - 'wordtype_scope' => $phrase->wordtype_scope, - 'language' => SProperty::idOfLocalization(auth()->user()->localization), - 'lastLanguage' => '', - 'translation' => '' - ]; + if ($rc == null) { + $phrase = Phrase::where(['word_id' => $word->id, 'language_scope' => GERMAN])->first(); + if ($phrase == null) { + $phrase = Phrase::create([ + 'german_id' => $word->id, + 'phrase' => $word->word, + 'language_scope' => GERMAN, + 'owner_id' => auth()->id() + ]); + } + if (count($fields) === 0) { + $fields = [ + 'word' => $word->word, + 'usage' => $phrase->phrase, + 'wordtype_scope' => $phrase->wordtype_scope, + 'language' => SProperty::idOfLocalization(auth()->user()->localization), + 'lastLanguage' => '', + 'translation' => '' + ]; + } elseif ($fields['lastLanguage'] !== $fields['language']) { + $translation = Word::where(['language_scope' => $fields['language'], 'german_id' => $word->id])->first(); + $fields['translation'] = $translation == null ? '' : $translation->word; + $fields['lastLanguage'] = $fields['language']; + } + if ($fields['translation'] === '' || $fields['lastLanguage'] != $fields['language']) { + $phraseTranslation = Word::where(['language_scope' => $fields['language'], 'german_id' => $word->id])->first(); + if ($phraseTranslation != null) { + $fields['translation'] = $phraseTranslation->word; + } + } + $fields['lastLanguage'] = $fields['language']; + $selection = $this->wordTypeToSelection($word->wordtype_scope); + $optionsWordtype = SProperty::optionsByScope('wordtype', $word->wordtype_scope, ''); + $optionsLanguage = SProperty::optionsByScope('localization', $fields['language'], ''); + $context = new ContextLaraKnife($request, $fields, $word); + $navigationTabInfo = ViewHelperLocal::getNavigationTabInfo('word-edit', 0, $word->id, $selection); + $rc = view('word.edit', [ + 'context' => $context, + 'optionsWordtype' => $optionsWordtype, + 'optionsLanguage' => $optionsLanguage, + 'navTabsInfo' => $navigationTabInfo + ]); } - if ($fields['translation'] === '' || $fields['lastLanguage'] != $fields['language']) { - $phraseTranslation = Word::where(['language_scope' => $fields['language'], 'word_id' => $word->id])->first(); - if ($phraseTranslation != null) { - $fields['translation'] = $phraseTranslation->word; + } + return $rc; + } + public function editAdjective(Word $word, Request $request) + { + $rc = null; + if ($request->btnSubmit === 'btnCancel') { + $rc = redirect('/word-index'); + } else { + $a1 = $word->word; + $fields = $request->all(); + $options = new KeyValueStorage($word->options ?? ''); + if ($request->btnSubmit === 'btnStore') { + $rc = $this->updateVariants($word, 'adjective', $fields, $options, $request); + } + if ($rc == null) { + if (count($fields) == 0) { + $forms = explode(SEPARATOR_OPTIONS, $options->get('formen') ?? ''); + $fields['comparative'] = count($forms) <= 1 ? null : $forms[1]; + $fields['superlative'] = count($forms) <= 2 ? null : $forms[2]; + } + if ($request->btnSubmit === 'btnFill') { + if ($fields['comparative'] == null) { + $value = str_ends_with($fields['comparative'], 'e') ? "{$a1}r" : "{$a1}er"; + $fields['comparative'] = $value; + } + if ($fields['superlative'] == null) { + $value = preg_match('/[sß]$/', $a1) ? "{$a1}esten" : "{$a1}sten"; + $fields['superlative'] = $value; + } + } + if ($request->btnSubmit === 'btnStore') { + $rc = $this->updateVariants($word, 'adjective', $fields, $options, $request); } } - $fields['lastLanguage'] = $fields['language']; - $optionsWordtype = SProperty::optionsByScope('wordtype', $word->wordtype_scope, ''); - $optionsLanguage = SProperty::optionsByScope('localization', $fields['language'], ''); + $selection = $this->wordTypeToSelection($word->wordtype_scope); $context = new ContextLaraKnife($request, $fields, $word); - $rc = view('word.edit', [ + $navigationTabInfo = ViewHelperLocal::getNavigationTabInfo('word-edit', 1, $word->id, $selection); + $rc = view('word.edit-adjective', [ 'context' => $context, - 'optionsWordtype' => $optionsWordtype, - 'optionsLanguage' => $optionsLanguage, + 'navTabsInfo' => $navigationTabInfo ]); } return $rc; } + public function editNoun(Word $word, Request $request) + { + $rc = null; + if ($request->btnSubmit === 'btnCancel') { + $rc = redirect('/word-index'); + } else { + $d1 = $word->word; + $fields = $request->all(); + $options = new KeyValueStorage($word->options ?? ''); + if ($request->btnSubmit === 'btnStore') { + $rc = $this->updateVariants($word, 'noun', $fields, $options, $request); + } + if ($rc == null) { + if (count($fields) == 0) { + $forms = $options->get('formen') ?? ''; + $values = explode(SEPARATOR_OPTIONS, substr($forms, 1)); + for ($no = 2; $no <= 8; $no++) { + $fields["d$no"] = count($values) <= 1 ? null : $values[$no - 2]; + } + $fields['genus'] = $options->get('genus') ?? ''; + } + if ($request->btnSubmit === 'btnFill') { + $source = $fields['d3'] ?? $fields['d2'] ?? $d1; + for ($no = 2; $no <= 8; $no++) { + if ($fields[$key = "d$no"] == null) { + $fields[$key] = $source; + } + } + } + switch ($fields['genus']) { + case 'f': + $fields['a1'] = 'die'; + $fields['a2'] = 'der'; + $fields['a3'] = 'der'; + $fields['a4'] = 'die'; + break; + case 'n': + $fields['a1'] = 'das'; + $fields['a2'] = 'des'; + $fields['a3'] = 'dem'; + $fields['a4'] = 'das'; + break; + case 'm': + default: + $fields['a1'] = 'der'; + $fields['a2'] = 'des'; + $fields['a3'] = 'dem'; + $fields['a4'] = 'den'; + break; // die den den die + } + if ($request->btnSubmit === 'btnStore') { + $rc = $this->updateVariants($word, 'noun', $fields, $options, $request); + } + } + $selection = $this->wordTypeToSelection($word->wordtype_scope); + $optionsGenus = SProperty::optionsByScope('genus', $fields['genus'], '-', 'name', 'shortname'); + $context = new ContextLaraKnife($request, $fields, $word); + $navigationTabInfo = ViewHelperLocal::getNavigationTabInfo('word-edit', 1, $word->id, $selection); + $rc = view('word.edit-noun', [ + 'context' => $context, + 'optionsGenus' => $optionsGenus, + 'navTabsInfo' => $navigationTabInfo + ]); + } + return $rc; + } + public function editVerb(Word $word, Request $request) + { + $rc = null; + if ($request->btnSubmit === 'btnCancel') { + $rc = redirect('/word-index'); + } else { + $c1 = $word->word; + $fields = $request->all(); + $options = new KeyValueStorage($word->options ?? ''); + if ($request->btnSubmit === 'btnStore') { + $rc = $this->updateVariants($word, 'verb', $fields, $options, $request); + } + if ($rc == null) { + if (count($fields) != 0) { + ViewHelper::addFieldIfMissing($fields, 'transitive', 'F'); + } else { + $forms = $options->get('formen') ?? ''; + $values = explode(SEPARATOR_OPTIONS, substr($forms, 1)); + for ($no = 1; $no <= 12; $no++) { + $fields["c$no"] = count($values) < max(2, $no - 1) ? '' : $values[$no - 1]; + } + $fields['participle'] = count($values) < 12 ? '' : $values[12]; + $fields['separablepart'] = $options->get('trennteil') ?? ''; + $fields['transitive'] = $options->get('transitiv') ?? ''; + $fields['info'] = $options->get('info') ?? ''; + $fields['word'] = $c1; + } + if ($request->btnSubmit === 'btnFill') { + $baseForm = GermanGrammar::baseFormOfVerb($infinitive = $word->word); + if ($fields['c1'] != null) { + $baseForm = $fields['c1']; + if (str_ends_with($baseForm, 'e')) { + $baseForm = substr($baseForm, 0, -1); + } + } + $this->editVerbSetDefault($fields, $baseForm, $infinitive, 'c1', 1, true, false); + $this->editVerbSetDefault($fields, $baseForm, $infinitive, 'c2', 2, true, false); + $this->editVerbSetDefault($fields, $baseForm, $infinitive, 'c3', 3, true, false); + $this->editVerbSetDefault($fields, $baseForm, $infinitive, 'c4', 1, false, false); + $this->editVerbSetDefault($fields, $baseForm, $infinitive, 'c5', 2, false, false); + $this->editVerbSetDefault($fields, $baseForm, $infinitive, 'c6', 3, false, false); + if ($fields['c7'] != null) { + $baseForm = $fields['c7']; + } + if ($fields['c7'] != null) { + $baseForm = $fields['c7']; + } + $this->editVerbSetDefault($fields, $baseForm, $infinitive, 'c7', 1, true, true); + $this->editVerbSetDefault($fields, $baseForm, $infinitive, 'c8', 2, true, true); + $this->editVerbSetDefault($fields, $baseForm, $infinitive, 'c9', 3, true, true); + $this->editVerbSetDefault($fields, $baseForm, $infinitive, 'c10', 1, false, true); + $this->editVerbSetDefault($fields, $baseForm, $infinitive, 'c11', 2, false, true); + $this->editVerbSetDefault($fields, $baseForm, $infinitive, 'c12', 3, false, true); + } + $context = new ContextLaraKnife($request, $fields, $word); + $navigationTabInfo = ViewHelperLocal::getNavigationTabInfo('word-edit', 1, $word->id, 'verb'); + $rc = view('word.edit-verb', [ + 'context' => $context, + 'navTabsInfo' => $navigationTabInfo + ]); + } + } + return $rc; + } + private function editVerbSetDefault(array &$fields, string $baseForm, string $infinitive, string $field, int $person, bool $isSingular, bool $isPast) + { + if ($fields[$field] == null || $fields[$field] == '') { + if (!$isPast) { + $fields[$field] = GermanGrammar::verbPresent($infinitive, $person, $isSingular, $baseForm); + } else { + $fields[$field] = GermanGrammar::verbImperfect($baseForm, $person, $isSingular); + } + } + } /** * Remove the specified resource from storage. */ @@ -118,7 +311,7 @@ class WordController extends Controller $lang = count($fields) == 0 ? SProperty::idOfLocalization() : $fields['language']; $sql = " SELECT t0.*, t1.name as wordtype, - (select word from words t4 where t4.word_id=t0.id and t4.language_scope=$lang) as translation + (select word from words t4 where t4.german_id=t0.id and t4.language_scope=$lang) as translation FROM words t0 LEFT JOIN sproperties t1 ON t1.id=t0.wordtype_scope "; @@ -135,12 +328,12 @@ LEFT JOIN sproperties t1 ON t1.id=t0.wordtype_scope '_sortParams' => 't0.word:asc;id:asc' ]; } else { - ViewHelper::addConditionPattern($conditions, $parameters, 't0.word', 'name'); + ViewHelper::addConditionPattern($conditions, $parameters, 't0.word', 'word'); ViewHelper::addConditionComparism($conditions, $parameters, 'wordtype_scope', 'wordtype'); ViewHelper::addConditionComparism($conditions, $parameters, 'owner_id', 'owner'); ViewHelper::addConditionPattern($conditions, $parameters, 'usage'); } - ViewHelper::addConditionConstComparison($conditions, $parameters, 't0.language_scope', 1202); + ViewHelper::addConditionConstComparison($conditions, $parameters, 't0.language_scope', GERMAN); $sql = DbHelper::addConditions($sql, $conditions); $sql = DbHelper::addOrderBy($sql, $fields['_sortParams']); $pagination = new Pagination($sql, $parameters, $fields); @@ -169,13 +362,50 @@ LEFT JOIN sproperties t1 ON t1.id=t0.wordtype_scope * Returns the validation rules. * @return array The validation rules. */ - private function rules(bool $isCreate = false): array + private function rules(string $variant): array { - $rc = [ - 'name' => 'required', - 'usage' => 'required', - 'verifiedby_id' => '' - ]; + switch ($variant) { + case 'trans': + $rc = [ + 'word' => 'required', + 'usage' => 'required', + 'verifiedby_id' => '' + ]; + break; + case 'noun': + $rc = [ + 'genus' => 'required', + 'd2' => 'required', + 'd3' => 'required', + 'd4' => 'required', + 'd5' => 'required', + 'd6' => 'required', + 'd7' => 'required', + 'd8' => 'required' + ]; + break; + case 'verb': + $rc = [ + 'participle' => 'required', + 'c1' => 'required', + 'c2' => 'required', + 'c3' => 'required', + 'c4' => 'required', + 'c5' => 'required', + 'c6' => 'required', + 'c7' => 'required', + 'c8' => 'required', + 'c9' => 'required', + 'c10' => 'required', + 'c11' => 'required', + 'c12' => 'required', + ]; + break; + case 'adjective': + $rc = [ + ]; + break; + } return $rc; } public static function routes() @@ -186,7 +416,12 @@ LEFT JOIN sproperties t1 ON t1.id=t0.wordtype_scope Route::put('/word-store', [WordController::class, 'store'])->middleware('auth'); Route::post('/word-edit/{word}', [WordController::class, 'edit'])->middleware('auth'); Route::get('/word-edit/{word}', [WordController::class, 'edit'])->middleware('auth'); - Route::post('/word-update/{word}', [WordController::class, 'update'])->middleware('auth'); + Route::post('/word-editnoun/{word}', [WordController::class, 'editNoun'])->middleware('auth'); + Route::get('/word-editnoun/{word}', [WordController::class, 'editNoun'])->middleware('auth'); + Route::post('/word-editverb/{word}', [WordController::class, 'editVerb'])->middleware('auth'); + Route::get('/word-editverb/{word}', [WordController::class, 'editVerb'])->middleware('auth'); + Route::post('/word-editadjective/{word}', [WordController::class, 'editAdjective'])->middleware('auth'); + Route::get('/word-editadjective/{word}', [WordController::class, 'editAdjective'])->middleware('auth'); Route::get('/word-show/{word}/delete', [WordController::class, 'show'])->middleware('auth'); Route::delete('/word-show/{word}/delete', [WordController::class, 'destroy'])->middleware('auth'); } @@ -218,15 +453,20 @@ LEFT JOIN sproperties t1 ON t1.id=t0.wordtype_scope public function store(Request $request) { $rc = null; + $word = null; if ($request->btnSubmit === 'btnStore') { $fields = $request->all(); - $validator = Validator::make($fields, $this->rules(true)); + $validator = Validator::make($fields, ['word' => 'required', 'wordtype_scope' => 'required']); if ($validator->fails()) { + $rc = $validator->errors(); $rc = back()->withErrors($validator)->withInput(); } else { $validated = $validator->validated(); - $validated['usage'] = strip_tags($validated['usage']); - Word::create($validated); + $validated['owner'] = auth()->user()->id; + $validated['owner'] = auth()->user()->id; + $validated['language_scope'] = GERMAN; + $word = Word::create($validated); + $rc = redirect("/word-edit/$word->id"); } } if ($rc == null) { @@ -237,38 +477,32 @@ LEFT JOIN sproperties t1 ON t1.id=t0.wordtype_scope /** * Update the specified resource in storage. */ - public function update(Word $word, Request $request) + public function update(Word $word, array &$fields, Request $request) { $rc = null; $session = $request->session(); - if ($request->btnSubmit === 'btnInternal') { - // Language combobox has been changed: - $url = "/word-edit/$word->id?language=" . $request->language; - $rc = redirect($url); - } elseif ($request->btnSubmit === 'btnStore') { - $id = $word->id; - $fields = $request->all(); - $validator = Validator::make($fields, $this->rules(false)); - if ($validator->fails()) { - $errors = $validator->errors(); - $rc = back()->withErrors($validator)->withInput(); - } else { - $validated = $validator->validated(); - $validated['usage'] = strip_tags($validated['usage']); - // Word has been changed? - $wordDb = Word::find($id); - if ($word->word !== $wordDb->word) { - // Invalidate all verifications in all languages: - DB::update("UPDATE phrases SET verifiedby_id=NULL WHERE word_id=$id;"); - // Store new phrase: - $word->update(['phrase' => $validated['phrase']]); - } + $id = $word->id; + $validator = Validator::make($fields, $this->rules('trans')); + if ($validator->fails()) { + $errors = $validator->errors(); + $rc = back()->withErrors($validator)->withInput(); + } else { + // Word has been changed? + $wordDb = Word::find($id); + if ($fields['word'] !== $wordDb->word) { + // Invalidate all verifications in all languages: + DB::update("UPDATE phrases SET verifiedby_id=NULL WHERE german_id=$id;"); + // Store new phrase: + $word->update(['word' => $fields['word']]); + } + $fields['usage'] = strip_tags($fields['usage']); + if ($fields['translation'] != null) { // Does translation already exists? - $wordTranslation = word::where(['language_scope' => $fields['language'], 'word_id' => $word->id])->first(); + $wordTranslation = word::where(['language_scope' => $fields['language'], 'german_id' => $word->id])->first(); if ($wordTranslation == null) { // Store the new record: word::create([ - 'word_id' => $id, + 'german_id' => $id, 'word' => $fields['translation'], 'wordtype_scope' => $word->wordtype_scope, 'owner_id' => auth()->id(), @@ -276,19 +510,116 @@ LEFT JOIN sproperties t1 ON t1.id=t0.wordtype_scope ]); } else { // Update only if changed: - if ($wordTranslation->word !== $fields['translation']) { - $wordTranslation->update(['word' => $validated['translation'], 'verifiedby_id' => null]); - } else if ($word->verifiedby_id == null){ - $wordTranslation->update(['verifiedby_id' => auth()->id()]); - } + if ($wordTranslation->word !== $fields['translation']) { + $wordTranslation->update(['word' => $fields['translation'], 'verifiedby_id' => null]); + } else if ($word->verifiedby_id == null) { + $wordTranslation->update(['verifiedby_id' => auth()->id()]); } } - $lang = $fields['language']; - $rc = redirect("/word-edit/$id?language=$lang"); } - if ($rc == null) { - $rc = redirect('/word-index'); + $phrase = Phrase::where(['word_id' => $id, 'language_scope' => GERMAN])->first(); + if ($phrase == null) { + Phrase::create([ + 'word_id' => $id, + 'phrase' => $fields['usage'], + 'language_scope' => GERMAN, + 'owner_id' => auth()->user()->id + ]); + } elseif ($phrase->phrase !== $fields['usage']) { + $phrase->update(['phrase' => $fields['usage'], 'verifiedby_id' => null]); + } } return $rc; } + public function updateVariants(Word $word, string $variant, array &$fields, KeyValueStorage &$options, Request $request) + { + $rc = null; + $session = $request->session(); + $id = $word->id; + $validator = Validator::make($fields, $this->rules($variant)); + if ($validator->fails()) { + $errors = $validator->errors(); + $rc = back()->withErrors($validator)->withInput(); + } else { + switch ($variant) { + case 'noun': + $options->put('genus', $fields['genus']); + $value = ";"; + for ($no = 2; $no <= 8; $no++) { + $value .= $fields["d$no"] . SEPARATOR_OPTIONS; + } + $options->put('formen', $value); + if ($options->hasChanged) { + $value = $options->toString(); + $word->update(['options' => $value, 'verifiedby_id' => null]); + } + break; + case 'verb': + ViewHelper::addFieldIfMissing($fields, 'transitive', 'F'); + $options->put('transitiv', $fields['transitive']); + $options->put('trennteil', $fields['separablepart'] ?? ''); + $options->put('info', $fields['info'] ?? ''); + $value = SEPARATOR_OPTIONS; + for ($no = 1; $no <= 12; $no++) { + $value .= $fields["c$no"] . SEPARATOR_OPTIONS; + } + $value .= $fields['participle'] . SEPARATOR_OPTIONS; + $options->put('formen', $value); + if ($options->hasChanged) { + $value = $options->toString(); + $word->update(['options' => $value, 'verifiedby_id' => null]); + } + break; + case 'adjective': + $value = SEPARATOR_OPTIONS . $fields['comparative'] . SEPARATOR_OPTIONS . $fields['superlative'] . SEPARATOR_OPTIONS; + $options->put('formen', $value); + if ($options->hasChanged) { + $value = $options->toString(); + $word->update(['options' => $value, 'verifiedby_id' => null]); + } + break; + default: + break; + } + } + return $rc; + } + public function wordTypeToSelection(int $wordType) + { + switch ($wordType) { + case 2001: + $selection = 'noun'; + break; + case 2002: + $selection = 'verb'; + break; + case 2003: + $selection = 'adjective'; + break; + case 2004: + $selection = 'preposition'; + break; + case 2005: + $selection = 'adverb'; + break; + case 2006: + $selection = 'pronoun'; + break; + case 2007: + $selection = 'article'; + break; + case 2008: + $selection = 'conjunction'; + break; + case 2009: + $selection = 'interjection'; + break; + case 2010: + $selection = 'numeral'; + break; + default: + $selection = null; + } + return $selection; + } } diff --git a/app/Models/Phrase.php b/app/Models/Phrase.php index da77f90..d3eeca5 100644 --- a/app/Models/Phrase.php +++ b/app/Models/Phrase.php @@ -16,8 +16,7 @@ class Phrase extends Model 'phrase', 'language_scope', 'word_id', - 'phrase_id', - 'baselanguage_id', + 'german_id', 'owner_id', 'verifiedby_id' ]; diff --git a/app/Models/Word.php b/app/Models/Word.php index a66217e..ca77e2e 100644 --- a/app/Models/Word.php +++ b/app/Models/Word.php @@ -19,6 +19,8 @@ class Word extends Model 'language_scope', 'word_id', 'verifiedby_id', - 'owner_id' + 'owner_id', + 'options', + 'german_id' ]; } diff --git a/composer.lock b/composer.lock index de67f3b..5ef73e4 100644 --- a/composer.lock +++ b/composer.lock @@ -1056,7 +1056,7 @@ "dist": { "type": "path", "url": "../laraknife", - "reference": "b903164d1c0f98b70657238210a55b05769cff3c" + "reference": "fdc1af63b7d821c111b630663be1f0bcbba93fa5" }, "require-dev": { "phpunit/phpunit": "11.0.x-dev" @@ -1087,16 +1087,16 @@ }, { "name": "laravel/framework", - "version": "v11.5.0", + "version": "v11.6.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "e3c24268f1404805e15099b9f035fe310cb30753" + "reference": "e090ee638ebd4ce221d8bad43b49bbf59ea70ae5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/e3c24268f1404805e15099b9f035fe310cb30753", - "reference": "e3c24268f1404805e15099b9f035fe310cb30753", + "url": "https://api.github.com/repos/laravel/framework/zipball/e090ee638ebd4ce221d8bad43b49bbf59ea70ae5", + "reference": "e090ee638ebd4ce221d8bad43b49bbf59ea70ae5", "shasum": "" }, "require": { @@ -1199,7 +1199,7 @@ "league/flysystem-sftp-v3": "^3.0", "mockery/mockery": "^1.6", "nyholm/psr7": "^1.2", - "orchestra/testbench-core": "^9.0.6", + "orchestra/testbench-core": "^9.0.15", "pda/pheanstalk": "^5.0", "phpstan/phpstan": "^1.4.7", "phpunit/phpunit": "^10.5|^11.0", @@ -1288,20 +1288,20 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2024-04-23T15:11:31+00:00" + "time": "2024-04-30T13:30:08+00:00" }, { "name": "laravel/prompts", - "version": "v0.1.20", + "version": "v0.1.21", "source": { "type": "git", "url": "https://github.com/laravel/prompts.git", - "reference": "bf9a360c484976692de0f3792f30066f4f4b34a2" + "reference": "23ea808e8a145653e0ab29e30d4385e49f40a920" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/prompts/zipball/bf9a360c484976692de0f3792f30066f4f4b34a2", - "reference": "bf9a360c484976692de0f3792f30066f4f4b34a2", + "url": "https://api.github.com/repos/laravel/prompts/zipball/23ea808e8a145653e0ab29e30d4385e49f40a920", + "reference": "23ea808e8a145653e0ab29e30d4385e49f40a920", "shasum": "" }, "require": { @@ -1341,11 +1341,12 @@ "license": [ "MIT" ], + "description": "Add beautiful and user-friendly forms to your command-line applications.", "support": { "issues": "https://github.com/laravel/prompts/issues", - "source": "https://github.com/laravel/prompts/tree/v0.1.20" + "source": "https://github.com/laravel/prompts/tree/v0.1.21" }, - "time": "2024-04-18T00:45:25+00:00" + "time": "2024-04-30T12:46:16+00:00" }, { "name": "laravel/serializable-closure", @@ -2032,16 +2033,16 @@ }, { "name": "nesbot/carbon", - "version": "3.3.0", + "version": "3.3.1", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "7219739c4e01d4680c980545821733b6ed8ee880" + "reference": "8ff64b92c1b1ec84fcde9f8bb9ff2ca34cb8a77a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/7219739c4e01d4680c980545821733b6ed8ee880", - "reference": "7219739c4e01d4680c980545821733b6ed8ee880", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/8ff64b92c1b1ec84fcde9f8bb9ff2ca34cb8a77a", + "reference": "8ff64b92c1b1ec84fcde9f8bb9ff2ca34cb8a77a", "shasum": "" }, "require": { @@ -2134,7 +2135,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T16:35:06+00:00" + "time": "2024-05-01T06:54:22+00:00" }, { "name": "nette/schema", @@ -3305,16 +3306,16 @@ }, { "name": "symfony/clock", - "version": "v7.0.5", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/clock.git", - "reference": "8b9d08887353d627d5f6c3bf3373b398b49051c2" + "reference": "2008671acb4a30b01c453de193cf9c80549ebda6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/clock/zipball/8b9d08887353d627d5f6c3bf3373b398b49051c2", - "reference": "8b9d08887353d627d5f6c3bf3373b398b49051c2", + "url": "https://api.github.com/repos/symfony/clock/zipball/2008671acb4a30b01c453de193cf9c80549ebda6", + "reference": "2008671acb4a30b01c453de193cf9c80549ebda6", "shasum": "" }, "require": { @@ -3359,7 +3360,7 @@ "time" ], "support": { - "source": "https://github.com/symfony/clock/tree/v7.0.5" + "source": "https://github.com/symfony/clock/tree/v7.0.7" }, "funding": [ { @@ -3375,20 +3376,20 @@ "type": "tidelift" } ], - "time": "2024-03-02T12:46:12+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/console", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "fde915cd8e7eb99b3d531d3d5c09531429c3f9e5" + "reference": "c981e0e9380ce9f146416bde3150c79197ce9986" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/fde915cd8e7eb99b3d531d3d5c09531429c3f9e5", - "reference": "fde915cd8e7eb99b3d531d3d5c09531429c3f9e5", + "url": "https://api.github.com/repos/symfony/console/zipball/c981e0e9380ce9f146416bde3150c79197ce9986", + "reference": "c981e0e9380ce9f146416bde3150c79197ce9986", "shasum": "" }, "require": { @@ -3452,7 +3453,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.0.6" + "source": "https://github.com/symfony/console/tree/v7.0.7" }, "funding": [ { @@ -3468,20 +3469,20 @@ "type": "tidelift" } ], - "time": "2024-04-01T11:04:53+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/css-selector", - "version": "v7.0.3", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "ec60a4edf94e63b0556b6a0888548bb400a3a3be" + "reference": "b08a4ad89e84b29cec285b7b1f781a7ae51cf4bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/ec60a4edf94e63b0556b6a0888548bb400a3a3be", - "reference": "ec60a4edf94e63b0556b6a0888548bb400a3a3be", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/b08a4ad89e84b29cec285b7b1f781a7ae51cf4bc", + "reference": "b08a4ad89e84b29cec285b7b1f781a7ae51cf4bc", "shasum": "" }, "require": { @@ -3517,7 +3518,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v7.0.3" + "source": "https://github.com/symfony/css-selector/tree/v7.0.7" }, "funding": [ { @@ -3533,20 +3534,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T15:02:46+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.4.0", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", "shasum": "" }, "require": { @@ -3555,7 +3556,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -3584,7 +3585,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0" }, "funding": [ { @@ -3600,20 +3601,20 @@ "type": "tidelift" } ], - "time": "2023-05-23T14:45:45+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "symfony/error-handler", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "46a4cc138f799886d4bd70477c55c699d3e9dfc8" + "reference": "cf97429887e40480c847bfeb6c3991e1e2c086ab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/46a4cc138f799886d4bd70477c55c699d3e9dfc8", - "reference": "46a4cc138f799886d4bd70477c55c699d3e9dfc8", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/cf97429887e40480c847bfeb6c3991e1e2c086ab", + "reference": "cf97429887e40480c847bfeb6c3991e1e2c086ab", "shasum": "" }, "require": { @@ -3659,7 +3660,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v7.0.6" + "source": "https://github.com/symfony/error-handler/tree/v7.0.7" }, "funding": [ { @@ -3675,20 +3676,20 @@ "type": "tidelift" } ], - "time": "2024-03-19T11:57:22+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v7.0.3", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "834c28d533dd0636f910909d01b9ff45cc094b5e" + "reference": "db2a7fab994d67d92356bb39c367db115d9d30f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/834c28d533dd0636f910909d01b9ff45cc094b5e", - "reference": "834c28d533dd0636f910909d01b9ff45cc094b5e", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/db2a7fab994d67d92356bb39c367db115d9d30f9", + "reference": "db2a7fab994d67d92356bb39c367db115d9d30f9", "shasum": "" }, "require": { @@ -3739,7 +3740,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v7.0.3" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.0.7" }, "funding": [ { @@ -3755,20 +3756,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T15:02:46+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.4.2", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "4e64b49bf370ade88e567de29465762e316e4224" + "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/4e64b49bf370ade88e567de29465762e316e4224", - "reference": "4e64b49bf370ade88e567de29465762e316e4224", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/8f93aec25d41b72493c6ddff14e916177c9efc50", + "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50", "shasum": "" }, "require": { @@ -3778,7 +3779,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -3815,7 +3816,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.4.2" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.0" }, "funding": [ { @@ -3831,20 +3832,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T14:51:35+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "symfony/finder", - "version": "v7.0.0", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "6e5688d69f7cfc4ed4a511e96007e06c2d34ce56" + "reference": "4d58f0f4fe95a30d7b538d71197135483560b97c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/6e5688d69f7cfc4ed4a511e96007e06c2d34ce56", - "reference": "6e5688d69f7cfc4ed4a511e96007e06c2d34ce56", + "url": "https://api.github.com/repos/symfony/finder/zipball/4d58f0f4fe95a30d7b538d71197135483560b97c", + "reference": "4d58f0f4fe95a30d7b538d71197135483560b97c", "shasum": "" }, "require": { @@ -3879,7 +3880,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v7.0.0" + "source": "https://github.com/symfony/finder/tree/v7.0.7" }, "funding": [ { @@ -3895,20 +3896,20 @@ "type": "tidelift" } ], - "time": "2023-10-31T17:59:56+00:00" + "time": "2024-04-28T11:44:19+00:00" }, { "name": "symfony/http-foundation", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "8789625dcf36e5fbf753014678a1e090f1bc759c" + "reference": "0194e064b8bdc29381462f790bab04e1cac8fdc8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/8789625dcf36e5fbf753014678a1e090f1bc759c", - "reference": "8789625dcf36e5fbf753014678a1e090f1bc759c", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/0194e064b8bdc29381462f790bab04e1cac8fdc8", + "reference": "0194e064b8bdc29381462f790bab04e1cac8fdc8", "shasum": "" }, "require": { @@ -3956,7 +3957,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v7.0.6" + "source": "https://github.com/symfony/http-foundation/tree/v7.0.7" }, "funding": [ { @@ -3972,20 +3973,20 @@ "type": "tidelift" } ], - "time": "2024-03-19T11:46:48+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/http-kernel", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "34c872391046d59af804af62d4573b829cfe4824" + "reference": "e07bb9bd86e7cd8ba2d3d9c618eec9d1bbe06d25" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/34c872391046d59af804af62d4573b829cfe4824", - "reference": "34c872391046d59af804af62d4573b829cfe4824", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/e07bb9bd86e7cd8ba2d3d9c618eec9d1bbe06d25", + "reference": "e07bb9bd86e7cd8ba2d3d9c618eec9d1bbe06d25", "shasum": "" }, "require": { @@ -4039,6 +4040,7 @@ "symfony/translation-contracts": "^2.5|^3", "symfony/uid": "^6.4|^7.0", "symfony/validator": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0", "symfony/var-exporter": "^6.4|^7.0", "twig/twig": "^3.0.4" }, @@ -4068,7 +4070,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v7.0.6" + "source": "https://github.com/symfony/http-kernel/tree/v7.0.7" }, "funding": [ { @@ -4084,20 +4086,20 @@ "type": "tidelift" } ], - "time": "2024-04-03T06:12:25+00:00" + "time": "2024-04-29T12:20:25+00:00" }, { "name": "symfony/mailer", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "eb0c3187c7ddfde12d8aa0e1fa5fb29e730a41e0" + "reference": "4ff41a7c7998a88cfdc31b5841ef64d9246fc56a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/eb0c3187c7ddfde12d8aa0e1fa5fb29e730a41e0", - "reference": "eb0c3187c7ddfde12d8aa0e1fa5fb29e730a41e0", + "url": "https://api.github.com/repos/symfony/mailer/zipball/4ff41a7c7998a88cfdc31b5841ef64d9246fc56a", + "reference": "4ff41a7c7998a88cfdc31b5841ef64d9246fc56a", "shasum": "" }, "require": { @@ -4148,7 +4150,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v7.0.6" + "source": "https://github.com/symfony/mailer/tree/v7.0.7" }, "funding": [ { @@ -4164,20 +4166,20 @@ "type": "tidelift" } ], - "time": "2024-03-28T09:20:36+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/mime", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "99362408c9abdf8c7cadcf0529b6fc8b16f5ace2" + "reference": "3adbf110c306546f6f00337f421d2edca0e8d3c0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/99362408c9abdf8c7cadcf0529b6fc8b16f5ace2", - "reference": "99362408c9abdf8c7cadcf0529b6fc8b16f5ace2", + "url": "https://api.github.com/repos/symfony/mime/zipball/3adbf110c306546f6f00337f421d2edca0e8d3c0", + "reference": "3adbf110c306546f6f00337f421d2edca0e8d3c0", "shasum": "" }, "require": { @@ -4232,7 +4234,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v7.0.6" + "source": "https://github.com/symfony/mime/tree/v7.0.7" }, "funding": [ { @@ -4248,7 +4250,7 @@ "type": "tidelift" } ], - "time": "2024-03-21T19:37:36+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/polyfill-ctype", @@ -4963,16 +4965,16 @@ }, { "name": "symfony/process", - "version": "v7.0.4", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "0e7727191c3b71ebec6d529fa0e50a01ca5679e9" + "reference": "3839e56b94dd1dbd13235d27504e66baf23faba0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/0e7727191c3b71ebec6d529fa0e50a01ca5679e9", - "reference": "0e7727191c3b71ebec6d529fa0e50a01ca5679e9", + "url": "https://api.github.com/repos/symfony/process/zipball/3839e56b94dd1dbd13235d27504e66baf23faba0", + "reference": "3839e56b94dd1dbd13235d27504e66baf23faba0", "shasum": "" }, "require": { @@ -5004,7 +5006,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v7.0.4" + "source": "https://github.com/symfony/process/tree/v7.0.7" }, "funding": [ { @@ -5020,20 +5022,20 @@ "type": "tidelift" } ], - "time": "2024-02-22T20:27:20+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/routing", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "cded64e5bbf9f31786f1055fcc76718fdd77519c" + "reference": "9f82bf7766ccc9c22ab7aeb9bebb98351483fa5b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/cded64e5bbf9f31786f1055fcc76718fdd77519c", - "reference": "cded64e5bbf9f31786f1055fcc76718fdd77519c", + "url": "https://api.github.com/repos/symfony/routing/zipball/9f82bf7766ccc9c22ab7aeb9bebb98351483fa5b", + "reference": "9f82bf7766ccc9c22ab7aeb9bebb98351483fa5b", "shasum": "" }, "require": { @@ -5085,7 +5087,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v7.0.6" + "source": "https://github.com/symfony/routing/tree/v7.0.7" }, "funding": [ { @@ -5101,25 +5103,26 @@ "type": "tidelift" } ], - "time": "2024-03-28T21:02:11+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.4.2", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "11bbf19a0fb7b36345861e85c5768844c552906e" + "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/11bbf19a0fb7b36345861e85c5768844c552906e", - "reference": "11bbf19a0fb7b36345861e85c5768844c552906e", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", + "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", "shasum": "" }, "require": { "php": ">=8.1", - "psr/container": "^1.1|^2.0" + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" }, "conflict": { "ext-psr": "<1.1|>=2" @@ -5127,7 +5130,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -5167,7 +5170,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.4.2" + "source": "https://github.com/symfony/service-contracts/tree/v3.5.0" }, "funding": [ { @@ -5183,20 +5186,20 @@ "type": "tidelift" } ], - "time": "2023-12-19T21:51:00+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "symfony/string", - "version": "v7.0.4", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "f5832521b998b0bec40bee688ad5de98d4cf111b" + "reference": "e405b5424dc2528e02e31ba26b83a79fd4eb8f63" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/f5832521b998b0bec40bee688ad5de98d4cf111b", - "reference": "f5832521b998b0bec40bee688ad5de98d4cf111b", + "url": "https://api.github.com/repos/symfony/string/zipball/e405b5424dc2528e02e31ba26b83a79fd4eb8f63", + "reference": "e405b5424dc2528e02e31ba26b83a79fd4eb8f63", "shasum": "" }, "require": { @@ -5253,7 +5256,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.0.4" + "source": "https://github.com/symfony/string/tree/v7.0.7" }, "funding": [ { @@ -5269,20 +5272,20 @@ "type": "tidelift" } ], - "time": "2024-02-01T13:17:36+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/translation", - "version": "v7.0.4", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "5b75e872f7d135d7abb4613809fadc8d9f3d30a0" + "reference": "1515e03afaa93e6419aba5d5c9d209159317100b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/5b75e872f7d135d7abb4613809fadc8d9f3d30a0", - "reference": "5b75e872f7d135d7abb4613809fadc8d9f3d30a0", + "url": "https://api.github.com/repos/symfony/translation/zipball/1515e03afaa93e6419aba5d5c9d209159317100b", + "reference": "1515e03afaa93e6419aba5d5c9d209159317100b", "shasum": "" }, "require": { @@ -5347,7 +5350,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v7.0.4" + "source": "https://github.com/symfony/translation/tree/v7.0.7" }, "funding": [ { @@ -5363,20 +5366,20 @@ "type": "tidelift" } ], - "time": "2024-02-22T20:27:20+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/translation-contracts", - "version": "v3.4.2", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "43810bdb2ddb5400e5c5e778e27b210a0ca83b6b" + "reference": "b9d2189887bb6b2e0367a9fc7136c5239ab9b05a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/43810bdb2ddb5400e5c5e778e27b210a0ca83b6b", - "reference": "43810bdb2ddb5400e5c5e778e27b210a0ca83b6b", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/b9d2189887bb6b2e0367a9fc7136c5239ab9b05a", + "reference": "b9d2189887bb6b2e0367a9fc7136c5239ab9b05a", "shasum": "" }, "require": { @@ -5385,7 +5388,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -5425,7 +5428,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.4.2" + "source": "https://github.com/symfony/translation-contracts/tree/v3.5.0" }, "funding": [ { @@ -5441,20 +5444,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T14:51:35+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "symfony/uid", - "version": "v7.0.3", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/uid.git", - "reference": "87cedaf3fabd7b733859d4d77aa4ca598259054b" + "reference": "4f3a5d181999e25918586c8369de09e7814e7be2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/uid/zipball/87cedaf3fabd7b733859d4d77aa4ca598259054b", - "reference": "87cedaf3fabd7b733859d4d77aa4ca598259054b", + "url": "https://api.github.com/repos/symfony/uid/zipball/4f3a5d181999e25918586c8369de09e7814e7be2", + "reference": "4f3a5d181999e25918586c8369de09e7814e7be2", "shasum": "" }, "require": { @@ -5499,7 +5502,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/uid/tree/v7.0.3" + "source": "https://github.com/symfony/uid/tree/v7.0.7" }, "funding": [ { @@ -5515,20 +5518,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T15:02:46+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/var-dumper", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "66d13dc207d5dab6b4f4c2b5460efe1bea29dbfb" + "reference": "d1627b66fd87c8b4d90cabe5671c29d575690924" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/66d13dc207d5dab6b4f4c2b5460efe1bea29dbfb", - "reference": "66d13dc207d5dab6b4f4c2b5460efe1bea29dbfb", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/d1627b66fd87c8b4d90cabe5671c29d575690924", + "reference": "d1627b66fd87c8b4d90cabe5671c29d575690924", "shasum": "" }, "require": { @@ -5582,7 +5585,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v7.0.6" + "source": "https://github.com/symfony/var-dumper/tree/v7.0.7" }, "funding": [ { @@ -5598,7 +5601,7 @@ "type": "tidelift" } ], - "time": "2024-03-19T11:57:22+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "tijsverkoyen/css-to-inline-styles", @@ -6058,16 +6061,16 @@ }, { "name": "laravel/pint", - "version": "v1.15.2", + "version": "v1.15.3", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "2c9f8004899815f3f0ee3cb28ef7281e2b589134" + "reference": "3600b5d17aff52f6100ea4921849deacbbeb8656" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/2c9f8004899815f3f0ee3cb28ef7281e2b589134", - "reference": "2c9f8004899815f3f0ee3cb28ef7281e2b589134", + "url": "https://api.github.com/repos/laravel/pint/zipball/3600b5d17aff52f6100ea4921849deacbbeb8656", + "reference": "3600b5d17aff52f6100ea4921849deacbbeb8656", "shasum": "" }, "require": { @@ -6120,7 +6123,7 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2024-04-23T15:42:34+00:00" + "time": "2024-04-30T15:02:26+00:00" }, { "name": "laravel/sail", @@ -7945,16 +7948,16 @@ }, { "name": "spatie/flare-client-php", - "version": "1.4.4", + "version": "1.5.1", "source": { "type": "git", "url": "https://github.com/spatie/flare-client-php.git", - "reference": "17082e780752d346c2db12ef5d6bee8e835e399c" + "reference": "e27977d534eefe04c154c6fd8460217024054c05" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/flare-client-php/zipball/17082e780752d346c2db12ef5d6bee8e835e399c", - "reference": "17082e780752d346c2db12ef5d6bee8e835e399c", + "url": "https://api.github.com/repos/spatie/flare-client-php/zipball/e27977d534eefe04c154c6fd8460217024054c05", + "reference": "e27977d534eefe04c154c6fd8460217024054c05", "shasum": "" }, "require": { @@ -8002,7 +8005,7 @@ ], "support": { "issues": "https://github.com/spatie/flare-client-php/issues", - "source": "https://github.com/spatie/flare-client-php/tree/1.4.4" + "source": "https://github.com/spatie/flare-client-php/tree/1.5.1" }, "funding": [ { @@ -8010,20 +8013,20 @@ "type": "github" } ], - "time": "2024-01-31T14:18:45+00:00" + "time": "2024-05-03T15:43:14+00:00" }, { "name": "spatie/ignition", - "version": "1.14.0", + "version": "1.14.1", "source": { "type": "git", "url": "https://github.com/spatie/ignition.git", - "reference": "80385994caed328f6f9c9952926932e65b9b774c" + "reference": "c23cc018c5f423d2f413b99f84655fceb6549811" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/ignition/zipball/80385994caed328f6f9c9952926932e65b9b774c", - "reference": "80385994caed328f6f9c9952926932e65b9b774c", + "url": "https://api.github.com/repos/spatie/ignition/zipball/c23cc018c5f423d2f413b99f84655fceb6549811", + "reference": "c23cc018c5f423d2f413b99f84655fceb6549811", "shasum": "" }, "require": { @@ -8093,20 +8096,20 @@ "type": "github" } ], - "time": "2024-04-26T08:45:51+00:00" + "time": "2024-05-03T15:56:16+00:00" }, { "name": "spatie/laravel-ignition", - "version": "2.5.2", + "version": "2.7.0", "source": { "type": "git", "url": "https://github.com/spatie/laravel-ignition.git", - "reference": "c93fcadcc4629775c839ac9a90916f07a660266f" + "reference": "f52124d50122611e8a40f628cef5c19ff6cc5b57" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/c93fcadcc4629775c839ac9a90916f07a660266f", - "reference": "c93fcadcc4629775c839ac9a90916f07a660266f", + "url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/f52124d50122611e8a40f628cef5c19ff6cc5b57", + "reference": "f52124d50122611e8a40f628cef5c19ff6cc5b57", "shasum": "" }, "require": { @@ -8115,8 +8118,8 @@ "ext-mbstring": "*", "illuminate/support": "^10.0|^11.0", "php": "^8.1", - "spatie/flare-client-php": "^1.3.5", - "spatie/ignition": "^1.13.2", + "spatie/flare-client-php": "^1.5", + "spatie/ignition": "^1.14", "symfony/console": "^6.2.3|^7.0", "symfony/var-dumper": "^6.2.3|^7.0" }, @@ -8124,11 +8127,11 @@ "livewire/livewire": "^2.11|^3.3.5", "mockery/mockery": "^1.5.1", "openai-php/client": "^0.8.1", - "orchestra/testbench": "^8.0|^9.0", - "pestphp/pest": "^2.30", - "phpstan/extension-installer": "^1.2", + "orchestra/testbench": "8.22.3|^9.0", + "pestphp/pest": "^2.34", + "phpstan/extension-installer": "^1.3.1", "phpstan/phpstan-deprecation-rules": "^1.1.1", - "phpstan/phpstan-phpunit": "^1.3.3", + "phpstan/phpstan-phpunit": "^1.3.16", "vlucas/phpdotenv": "^5.5" }, "suggest": { @@ -8185,20 +8188,20 @@ "type": "github" } ], - "time": "2024-04-16T08:57:16+00:00" + "time": "2024-05-02T13:42:49+00:00" }, { "name": "symfony/yaml", - "version": "v7.0.3", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "2d4fca631c00700597e9442a0b2451ce234513d3" + "reference": "0d3916ae69ea28b59d94b60c4f2b50f4e25adb5c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/2d4fca631c00700597e9442a0b2451ce234513d3", - "reference": "2d4fca631c00700597e9442a0b2451ce234513d3", + "url": "https://api.github.com/repos/symfony/yaml/zipball/0d3916ae69ea28b59d94b60c4f2b50f4e25adb5c", + "reference": "0d3916ae69ea28b59d94b60c4f2b50f4e25adb5c", "shasum": "" }, "require": { @@ -8240,7 +8243,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v7.0.3" + "source": "https://github.com/symfony/yaml/tree/v7.0.7" }, "funding": [ { @@ -8256,7 +8259,7 @@ "type": "tidelift" } ], - "time": "2024-01-23T15:02:46+00:00" + "time": "2024-04-28T11:44:19+00:00" }, { "name": "theseer/tokenizer", diff --git a/database/migrations/2024_03_21_191359_create_words_table.php b/database/migrations/2024_03_21_191359_create_words_table.php index d56b27f..6b053a6 100644 --- a/database/migrations/2024_03_21_191359_create_words_table.php +++ b/database/migrations/2024_03_21_191359_create_words_table.php @@ -15,9 +15,10 @@ return new class extends Migration $table->id(); $table->timestamps(); $table->string('word', 64); + $table->text('options')->nullable(); $table->integer('wordtype_scope'); $table->integer('language_scope'); - $table->foreignId('baselanguage_id')->nullable()->references('id')->on('words'); + $table->foreignId('german_id')->nullable()->references('id')->on('words'); $table->foreignId('owner_id')->nullable()->references('id')->on('users'); $table->foreignId('verifiedby_id')->nullable()->references('id')->on('users'); }); diff --git a/database/migrations/2024_03_21_202004_create_phrases_table.php b/database/migrations/2024_03_21_202004_create_phrases_table.php index 5f1f76f..bee922d 100644 --- a/database/migrations/2024_03_21_202004_create_phrases_table.php +++ b/database/migrations/2024_03_21_202004_create_phrases_table.php @@ -17,7 +17,7 @@ return new class extends Migration $table->text('phrase'); $table->integer('language_scope'); $table->foreignId('word_id')->nullable()->references('id')->on('words'); - $table->foreignId('baselanguage_id')->nullable()->references('id')->on('phrases'); + $table->foreignId('german_id')->nullable()->references('id')->on('phrases'); $table->foreignId('owner_id')->nullable()->references('id')->on('users'); $table->foreignId('verifiedby_id')->nullable()->references('id')->on('users'); }); diff --git a/database/migrations/2024_03_21_202154_create_nouns_table.php b/database/migrations/2024_03_21_202154_create_nouns_table.php deleted file mode 100644 index 21cf80c..0000000 --- a/database/migrations/2024_03_21_202154_create_nouns_table.php +++ /dev/null @@ -1,30 +0,0 @@ -id(); - $table->timestamps(); - $table->integer('genus_scope'); - $table->foreignId('word_id')->references('id')->on('words'); - $table->foreignId('plural_id')->references('id')->on('words'); - }); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - Schema::dropIfExists('nouns'); - } -}; diff --git a/database/migrations/2024_03_23_185143_create_verbs_table.php b/database/migrations/2024_03_23_185143_create_verbs_table.php deleted file mode 100644 index 50c462e..0000000 --- a/database/migrations/2024_03_23_185143_create_verbs_table.php +++ /dev/null @@ -1,44 +0,0 @@ -id(); - $table->timestamps(); - $table->foreignId('word_id')->references('id')->on('words'); - $table->string('presence1s', 32); - $table->string('presence2s', 32); - $table->string('presence3s', 32); - $table->string('presence1p', 32); - $table->string('presence2p', 32); - $table->string('presence3p', 32); - $table->string('imperfect1s', 32); - $table->string('imperfect2s', 32); - $table->string('imperfect3s', 32); - $table->string('imperfect1p', 32); - $table->string('imperfect2p', 32); - $table->string('imperfect3p', 32); - $table->string('participle', 32); - $table->string('separablepart', 16)->nullable(); - $table->boolean('transitive'); - $table->string('options')->nullable(); - }); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - Schema::dropIfExists('verbs'); - } -}; diff --git a/database/migrations/2024_04_09_190303_add_phrases_phrase_id.php b/database/migrations/2024_04_09_190303_add_phrases_phrase_id.php deleted file mode 100644 index b5df4d3..0000000 --- a/database/migrations/2024_04_09_190303_add_phrases_phrase_id.php +++ /dev/null @@ -1,26 +0,0 @@ -foreignId('phrase_id')->nullable()->references('id')->on('phrases'); - }); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - // - } -}; diff --git a/database/migrations/2024_04_13_131901_change_words_word_id.php b/database/migrations/2024_04_29_191459_alter_words.php similarity index 67% rename from database/migrations/2024_04_13_131901_change_words_word_id.php rename to database/migrations/2024_04_29_191459_alter_words.php index 8d93f93..e13ba0a 100644 --- a/database/migrations/2024_04_13_131901_change_words_word_id.php +++ b/database/migrations/2024_04_29_191459_alter_words.php @@ -4,15 +4,14 @@ use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ public function up(): void { - Schema::table('words', function(Blueprint $table) { - $table->renameColumn('baselanguage_id', 'word_id'); + Schema::table('words', function (Blueprint $table) { + $table->string('info', 128)->nullable(); }); } diff --git a/database/seeders/WordSeeder.php b/database/seeders/WordSeeder.php index de5347f..484d521 100644 --- a/database/seeders/WordSeeder.php +++ b/database/seeders/WordSeeder.php @@ -2,6 +2,7 @@ namespace Database\Seeders; +use App\Models\SProperty; use Illuminate\Database\Seeder; use Illuminate\Support\Facades\DB; use Illuminate\Database\Console\Seeds\WithoutModelEvents; @@ -13,17 +14,16 @@ class WordSeeder extends Seeder */ public function run(): void { - DB::table('sproperties')->insert([ - 'id' => 2001, 'scope' => 'wordtype', 'name' => 'Noun', 'order' => '10', 'shortname' => 'N' - ]); - DB::table('sproperties')->insert([ - 'id' => 2002, 'scope' => 'wordtype', 'name' => 'Verb', 'order' => '20', 'shortname' => 'V' - ]); - DB::table('sproperties')->insert([ - 'id' => 2003, 'scope' => 'wordtype', 'name' => 'Adjective', 'order' => '30', 'shortname' => 'Adj' - ]); - DB::table('sproperties')->insert([ - 'id' => 2004, 'scope' => 'wordtype', 'name' => 'Preposition', 'order' => '40', 'shortname' => 'Prep' - ]); + // int $id, string $scope, string $name, int $order, string $shortname + SProperty::insertIfNotExists(2001, 'wordtype', 'Noun', '10', 'N'); + SProperty::insertIfNotExists(2002, 'wordtype', 'Verb', '20', 'V'); + SProperty::insertIfNotExists(2003, 'wordtype', 'Adjective', '30', 'ADJ'); + SProperty::insertIfNotExists(2004, 'wordtype', 'Preposition', '40', 'PREP'); + SProperty::insertIfNotExists(2005, 'wordtype', 'Adverb', '50', 'ADV'); + SProperty::insertIfNotExists(2006, 'wordtype', 'Pronoun', '60', 'PRO'); + SProperty::insertIfNotExists(2007, 'wordtype', 'Article', '70', 'ART'); + SProperty::insertIfNotExists(2008, 'wordtype', 'Conjunction', '80', 'CON'); + SProperty::insertIfNotExists(2009, 'wordtype', 'Interjection', '90', 'INT'); + SProperty::insertIfNotExists(2010, 'wordtype', 'Numeral', '100', 'NUM'); } } diff --git a/lang/de_DE.json b/lang/de_DE.json index c64904d..b0f2071 100644 --- a/lang/de_DE.json +++ b/lang/de_DE.json @@ -15,7 +15,6 @@ "Category": "Kategorie", "Change": "\u00c4ndern", "Change Password of an User": "Passwort eines Benutzers \u00e4ndern", - "Change of a Chapter": "\u00c4nderung eines Kapitels", "Change of a File": "\u00c4ndern einer Datei", "Change of a Menu Item": "\u00c4ndern einer Men\u00fceintrags", "Change of a Note": "\u00c4ndern einer Notiz", @@ -31,9 +30,9 @@ "Chapter": "Kapitel", "Chapters": "Kapitel", "Columns": "Spalten", + "Comparative": "Komparativ", "Confirmation": "Best\u00e4tigung", "Contents": "Inhalt", - "Creation of a Chapter": "Neues Kapitel", "Creation of a Document": "Hochladen eines Dokuments", "Creation of a File": "Hochladen einer Datei", "Creation of a Menu Item": "Erstellen eine Men\u00fceintrags", @@ -42,17 +41,15 @@ "Creation of a Role": "Erstellen eine Rolle", "Creation of a Scoped Property": "Erzeugen einer bereichsbasierten Eigenschaft", "Creation of a Term": "Erstellen eines Termins", - "Creation of a Verb": "Neues Verb", + "Creation of a Word": "Neues Wort", "Creation of an User": "Erstellen eines Benutzers", "Date": "Datum", "Delete": "L\u00f6schen", "Deletion of a Document": "L\u00f6schen eines Dokuments", "Deletion of a Menu Item": "L\u00f6schen eines Men\u00fceintrags", "Deletion of a Note": "L\u00f6schen einer Notiz", - "Deletion of a Noun": "L\u00f6schen eines Nomens", "Deletion of a Page": "L\u00f6schen einer Seite", "Deletion of a Scoped Property": "L\u00f6schen einer bereichsbasierten Eigenschaft", - "Deletion of a Verb": "L\u00f6schen eines Verbs", "Deletion of a Word": "L\u00f6schen eines Wortes", "Deletion of an User": "L\u00f6schen eines Benutzers", "Description": "Beschreibung", @@ -67,6 +64,7 @@ "Filegroup": "Gruppe", "Filename": "Dateiname", "Files": "Dateien", + "Fill": "F\u00fcllen", "Filtered": "Gefiltert", "French (France)": "Franz\u00f6sisch (Frankreich)", "From": "Von", @@ -129,6 +127,7 @@ "Status": "Status", "Store": "Speichern", "Store Menu": "Men\u00fc speichern", + "Superlative": "Superlativ", "Term": "Termin", "Terms": "Termine", "Text": "Text", diff --git a/public/css/bootstrap-icons.css b/public/css/bootstrap-icons.css new file mode 120000 index 0000000..0736d05 --- /dev/null +++ b/public/css/bootstrap-icons.css @@ -0,0 +1 @@ +../../vendor/hamatoma/laraknife/resources/css/bootstrap-icons.css \ No newline at end of file diff --git a/public/css/bootstrap.min.css b/public/css/bootstrap.min.css new file mode 120000 index 0000000..cfb7509 --- /dev/null +++ b/public/css/bootstrap.min.css @@ -0,0 +1 @@ +../../vendor/hamatoma/laraknife/resources/css/bootstrap.min.css \ No newline at end of file diff --git a/public/css/fonts b/public/css/fonts new file mode 120000 index 0000000..272d916 --- /dev/null +++ b/public/css/fonts @@ -0,0 +1 @@ +../../vendor/hamatoma/laraknife/resources/css/fonts \ No newline at end of file diff --git a/public/css/gadeku.css b/public/css/gadeku.css index 74154d5..f271512 100644 --- a/public/css/gadeku.css +++ b/public/css/gadeku.css @@ -20,4 +20,19 @@ input, button { } .translation:hover { visibility: visible; +} +.lkn-text h1{ + padding: 0.25rem; + color: white; + text-align: center; + background-color: blue; + border-bottom: solid 0.1rem blue; + border-radius: 0.25rem; +} +.lkn-text h2, .lkn-text h3{ + /* color: rgb(213, 78, 29); */ + color: blue; + border-bottom: solid 0.1rem blue; +.lkn-text h4, .lkn-text h5{ + color: blue; } \ No newline at end of file diff --git a/public/js/bootstrap.min.js b/public/js/bootstrap.min.js new file mode 120000 index 0000000..f53236d --- /dev/null +++ b/public/js/bootstrap.min.js @@ -0,0 +1 @@ +../../vendor/hamatoma/laraknife/resources/js/bootstrap.min.js \ No newline at end of file diff --git a/resources/lang/sources/gadeku.de.json b/resources/lang/sources/gadeku.de.json index e5aa039..806f65a 100644 --- a/resources/lang/sources/gadeku.de.json +++ b/resources/lang/sources/gadeku.de.json @@ -2,7 +2,6 @@ "!comment": "Bitte alphabetisch sortiert eintragen!", "": "", "Adjective": "Adjektiv", -"Change of a Chapter": "Änderung eines Kapitels", "Change of a Noun": "Änderung eines Nomens", "Change of a Phrase": "Änderung eines Satzes", "Change of a Verb": "Änderung eines Verbs", @@ -11,13 +10,12 @@ "Chapter": "Kapitel", "Chapters": "Kapitel", "cloze text": "Lückentext", +"Comparative": "Komparativ", "Contents": "Inhalt", -"Creation of a Chapter": "Neues Kapitel", -"Creation of a Verb": "Neues Verb", -"Deletion of a Noun": "Löschen eines Nomens", -"Deletion of a Verb": "Löschen eines Verbs", +"Creation of a Word": "Neues Wort", "Deletion of a Word": "Löschen eines Wortes", "feminine": "Femininum", +"Fill": "Füllen", "free text": "Freier Text", "Genus": "Geschlecht", "grammar rules": "Grammatikregeln", @@ -32,6 +30,7 @@ "Phrases": "Sätze", "Preposition": "Präposition", "snaketext": "Schlangentext", +"Superlative": "Superlativ", "Translation": "Übersetzung", "Verb": "Verb", "Verbs": "Verben", diff --git a/resources/views/layouts/backend.blade.php b/resources/views/layouts/backend.blade.php index 77546c2..fb80772 100644 --- a/resources/views/layouts/backend.blade.php +++ b/resources/views/layouts/backend.blade.php @@ -6,19 +6,28 @@ {{ config('app.name', 'Laravel') }} - + + + + @vite(['resources/sass/app.scss', 'resources/js/app.js']) + +