I'm trying to add an item including multiple translations in one form with the CakePHP translate behaviour.
How can I validate the translation fields? E.g. make specific languages required?
Let's assume you have a simple items
table with a separate translations table items_i18n
, set up as described in the book. As simple example the items
table has only one field title
to translate and I want to save the title
in five languages. So I make a form like this (in add
view template):
echo $this->Form->create($item, ['controller' => 'Items', 'action' => 'add']);
echo $this->Form->input('title', ['label' => __('English')]);
echo $this->Form->input('_translations.es.title', ['label' => __('Spanish')]);
echo $this->Form->input('_translations.fr.title', ['label' => __('French')]);
echo $this->Form->input('_translations.de.title', ['label' => __('German')]);
echo $this->Form->input('_translations.it.title', ['label' => __('Italian')]);
echo $this->Form->button(__('Save'), ['type' => 'submit']);
echo $this->Form->end();
And saving in the controller (add
action/function) like this:
$item = $this->Items->newEntity();
if ($this->request->is('post')) {
$translations = [
'es' => ['title' => $this->request->data['_translations']['es']['title']],
'fr' => ['title' => $this->request->data['_translations']['fr']['title']],
'de' => ['title' => $this->request->data['_translations']['de']['title']],
'it' => ['title' => $this->request->data['_translations']['it']['title']],
];
foreach ($translations as $lang => $data) {
$item->translation($lang)->set($data, ['guard' => false]);
}
$item = $this->Items->patchEntity($item, $this->request->data, ['validate' => 'default'] );
if ( $this->Items->save($item) ) { $this->Flash->success(__('Saved.')); }
else { $this->Flash->error(__('Not saved.')); }
}
$this->set('item', $item);
This is working without validation or if I only have validation rules for the "native" title
field (well it should, I simplified the code for stackoverflow and renamed some parts for the example, so maybe there are some typos, but you should get the idea...).
Now let's further assume the languages English (default) and Spanish are required, other language fields are optional. How can I achieve that?
In the ItemsTable
I tried something like this for validation:
class ItemsTable extends Table {
public function validationDefault(Validator $validator) {
$validator
// Title English (default field)
->requirePresence('title')
->notEmpty('title', __('Required field'))
// Title Spanish (translate behaviour field)
->requirePresence('_translations.es.title')
->notEmpty('_translations.es.title', __('Required field'))
;
return $validator;
}
}
But this allways brings a validation error "This field is required" because patchEntity($item, $this->request->data);
results in the translations being thrown away. I know this by an open issue on GitHub about the saving workflow (btw +1 for this request :).
So currently I'm not sure if there is a way to define validation rules for translation fields when using the CakePHP translation behaviour... Required language fields is only an example, the same problem occurs if you want to validate e.g. the min/max lenght of a input field for a foreign language...