CakePHP 3.1: Validation for translate behaviour fields (i18n) -


i'm trying add item including multiple translations in 1 form cakephp translate behaviour.

how can validate translation fields? e.g. make specific languages required?

let's assume have simple items table separate translations table items_i18n, set described in book. simple example items table has 1 field title translate , want save title in 5 languages. make form (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 controller (add action/function) 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 $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 working without validation or if have validation rules "native" title field (well should, simplified code stackoverflow , renamed parts example, maybe there typos, should idea...).

now let's further assume languages english (default) , spanish required, other language fields optional. how can achieve that?

in itemstable tried 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 allways brings validation error "this field required" because patchentity($item, $this->request->data); results in translations being thrown away. know open issue on github saving workflow (btw +1 request :).

so i'm not sure if there way define validation rules translation fields when using cakephp translation behaviour... required language fields example, same problem occurs if want validate e.g. min/max lenght of input field foreign language...

ok, think found solution. @ least temporarily, because discovered issue nestedvalidator , formhelper.

currently validation still applied all additional languages. not wanted , not final answer. if have idea how can apply validation single languages please leave comment or answer.

so current intermediate solution cakephp 3.1.1:

in table class add nested validator i18n translation fields.

these nested validation rules apply additional language fields, because grouped in $this->request->data['_translations']:

class itemstable extends table {   public function validationdefault(validator $validator) {     $validator       // title english (default language)       ->requirepresence('title')       ->notempty('title')       ->add('title', [           'minlength'=>['rule'=>['minlength', 2], 'message' => __('minlength 2')],           'maxlength'=>['rule'=>['maxlength', 255], 'message' => __('maxlength 255')],           ])       ;       // nested validation i18n fields (translate behaviour)       // these rules apply 'title' fields in additional languages       $translationvalidator = new validator();       $translationvalidator         ->requirepresence('title', 'false') // want translation optional         ->allowempty('title') // want translation optional         ->add('title', [           'minlength'=>['rule'=>['minlength', 5], 'message' => __('minlength 5')],           'maxlength'=>['rule'=>['maxlength', 255], 'message' => __('maxlength 255')],           ])       ;       // apply nested validator "main" validation       // ('_translations' containing translated input data)       $validator         ->addnestedmany('_translations', $translationvalidator)         // prevent "field required" "_translations" data         ->requirepresence('_translations', 'false')         ->allowempty('_translations')         ;     return $validator;   } } 

in test setup want translation fields optional , have other minlength default language. can see in code above, added allowempty , set requirepresence false translation fields. translatebehaviour still forcing translation title fields required. added additionally 'required' => false translation input fields in add/edit form:

echo $this->form->input('_translations.es.title', ['required' => false]); 

the separate validation rules applied translation fields, shown in debug result (added temporarily in controller while testing):

$item = $this->items->patchentity($item, $this->request->data); debug($item); 

when enter 1 character in input fields, minlength error messages available in debug error array.

but formhelper not support nested error messages. reported issue on github. temporarily solution show error in form checking error array manually. so, add in controller:

$item = $this->items->patchentity($item, $this->request->data); if ( !$item->errors() ) {   foreach ($this->request->data['_translations'] $lang => $data) {     $item->translation($lang)->set($data, ['guard' => false]);     } } // temp workaround issue#7532: else {   $this->set('formerrors', $language->errors());  } 

and in add/edit view can check , use additional $formerrors array:

if ( isset($formerrors['_translations']['es']['title']) ) { ... } 

another interesting approach shown in answer question.


Comments

Popular posts from this blog

resizing Telegram inline keyboard -

command line - How can a Python program background itself? -

php - "cURL error 28: Resolving timed out" on Wordpress on Azure App Service on Linux -