CakePHP 3.0.8 Übersetzungsverhalten und Datenüberprüfung (requirePresence, notEmpty)

Mein Problem ist einfach, aber ich kann nicht herausfinden, wie ich es lösen soll.

Meine Website ist mehrsprachig. Ich möchte, dass der Benutzer einen Artikel in mehreren Sprachen hinzufügen kann, wenn er dies wünscht, und dabei die Eingaben seiner Sprache (abhängig von seinem Gebietsschema) benötigt.

Problem ist, dass mit CakePHPs Konventionen zur Übersetzung alle Eingaben mit dem Feldnamen enden müssen, egal in welcher Sprache. Alle Felder haben also die gleiche Regel für dasselbe Feld. Ich kann keinen "Namen" festlegen, während ein anderer in einer anderen Sprache nicht erforderlich ist.

Zum Beispiel wäre die Eingabe der Standardsprache:

<input type="text" name="name" required="required" maxlength="45" id="name">

Und darunter die Eingabe einer anderen Sprache für dasselbe Feld:

<input type="text" name="locales[fr_CA][name]" required="required" maxlength="45" id="locales-fr-ca-name">

Das Attribut "Erforderlich" wird aufgrund der folgenden Regeln automatisch zu beiden hinzugefügt:

$validator
    ->requirePresence('name', 'create')
    ->notEmpty('name')
    ->add('name', [
        'length' => [
            'rule' => ['minLength', 10],
            'message' => 'The title needs to be at least 10 characters long.',
        ]
    ]);

Hinweis: Ich muss das Gebietsschema auf den Standardwert (en_US) ändern, wenn ich speichere, um in mehreren Sprachen + der Standardsprache speichern zu können (ansonsten werden die Standardeingaben in der Standardtabelle UND in der i18n-Tabelle gespeichert).

if ($this->request->is('post')) {
    I18n::locale('en_US');
    // ......

EDIT: Also hier ist der komplette Code, wenn ich speichere (IngredientsController.php)

public function add() {
    $ingredient = $this->Ingredients->newEntity();
    if ($this->request->is('post')) {
        $ingredient = $this->Ingredients->patchEntity($ingredient, $this->request->data);

        if(isset($this->request->data['locales'])) {
            foreach ($this->request->data['locales'] as $lang => $data) {
                $ingredient->translation($lang)->set($data, ['guard' => false]);
            }
        }

        $locale = I18n::locale(); // At this point the locale is fr_CA (not de default)
        I18n::locale('en_US'); // Change the locale to the default

        if ($this->Ingredients->save($ingredient)) {
            $this->Flash->success(__('The ingredient has been saved.'));
            I18n::locale($locale); // Put the locale back to the user's locale
            return $this->redirect(['action' => 'index']);
        } else {
            I18n::locale($locale);
            $this->Flash->error(__('The ingredient could not be saved. Please, try again.'));
        }
    }

    $this->set(compact('ingredient'));
    $this->set('_serialize', ['ingredient']);
}

Ich setze das Standardgebietsschema auf bootstrap.php

/**
 * Set the default locale. This controls how dates, number and currency is
 * formatted and sets the default language to use for translations.
 */
ini_set('intl.default_locale', 'en_US');
Configure::write('Config.locales', ['fr_CA']);

Ich bestimme das Gebietsschema des Benutzers in der AppController.php

public function beforeFilter(Event $event)
{
    $locales = Configure::read('Config.locales');
    $boom = explode(',', str_replace('-', '_', $_SERVER['HTTP_ACCEPT_LANGUAGE']));
    $user_lang = substr($boom[0], 0, 2);

    // This piece of code is only to change the locale to fr_CA even if the user's language is just fr or fr_FR
    if(in_array($user_lang, Configure::read('Config.langs'))) {
        if(in_array($boom[0], $locales)) {
            I18n::locale($boom[0]);
        } else {
            foreach ($locales as $locale) {
                if(substr($locale, 0, 2) == $user_lang) {
                    I18n::locale($locale);
                }
            }
        }
    }

    $this->set('locales', $locales);
    $this->set('locale', I18n::locale());
}

Wenn ich in einem anderen Gebietsschema als dem Standardspeicher speichere, werden dieselben Standardeingaben in der Ingredient-Tabelle UND in der i18n-Tabelle in fr_CA @ gespeicher

Antworten auf die Frage(2)

Ihre Antwort auf die Frage