Reputation: 59
I am trying to save multiple translations for column name in a single form submit but it always result in an exception 'name' doesn't have a default value. Below given is my implementation according to cakephp's latest documentation.
Table Structure for words
CREATE TABLE `words` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`slug` varchar(255) NOT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `slug` (`slug`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Table word_i18n structure that hold all the translations for table words
CREATE TABLE `word_i18n` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`locale` varchar(6) NOT NULL,
`model` varchar(255) NOT NULL,
`foreign_key` int(10) NOT NULL,
`field` varchar(255) NOT NULL,
`content` mediumtext,
PRIMARY KEY (`id`),
KEY `locale` (`locale`),
KEY `model` (`model`),
KEY `row_id` (`foreign_key`),
KEY `field` (`field`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Added the translation behavior to the WordsTable
public function initialize(array $config)
{
parent::initialize($config);
$this->table('words');
$this->displayField('name');
$this->primaryKey('id');
$this->addBehavior('Timestamp');
$this->addBehavior('Translate', [
'fields' => ['name'],
'translationTable' => 'word_i18n',
]);
}
/**
* Validation Rules
*/
public function validationDefault(Validator $validator)
{
$validator
->integer('id')
->allowEmpty('id', 'create');
$validator
->requirePresence('name', 'create')
->notEmpty('name');
$validator
->notEmpty('slug')
->add('slug', 'unique', ['rule' => 'validateUnique', 'provider'=> 'table']);
return $validator;
}
Word Entity with Translation Trait
class Word extends Entity
{
use TranslateTrait;
/**
* Fields that can be mass assigned using newEntity() or patchEntity().
*
* Note that when '*' is set to true, this allows all unspecified fields to
* be mass assigned. For security purposes, it is advised to set '*' to false
* (or remove it), and explicitly make individual fields accessible as needed.
*
* @var array
*/
protected $_accessible = [
'*' => true,
'id' => false
];
}
Controller Method to render and handle the submission
public function add()
{
I18n::locale("en"); // Sets the default locale
$word = $this->Words->newEntity();
if ($this->request->is('post')) {
$word = $this->Words->patchEntity($word, $this->request->data, ['translations' => true]);
//debug($word);die;
if ($this->Words->save($word)) {
$this->Flash->success(__('The word has been saved.'));
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error(__('The word could not be saved. Please, try again.'));
}
}
$this->set(compact('word'));
$this->set('_serialize', ['word']);
}
And at last the form to submit data
<?= $this->Form->create($word); ?>
<fieldset>
<legend><?= __('Add Word') ?></legend>
<?php
echo $this->Form->input('_translations.en.name',['class'=>"form-control ui-flat", "label" => __("Name [{0}]", ["English"])]);
echo $this->Form->input('_translations.ja.name',['class'=>"form-control ui-flat", "label" => __("Name [{0}]", ["Japanese"]) ]);
echo $this->Form->input('_translations.ko.name',['class'=>"form-control ui-flat", "label" => __("Name [{0}]", ["Korean"])]);
echo $this->Form->input('_translations.zh.name',['class'=>"form-control ui-flat", "label" => __("Name [{0}]", ["Chinese"])]);
echo $this->Form->button(__('Submit'),array('class'=>"btn btn-success ui-flat pull-right"));
?>
</fieldset>
<?= $this->Form->end() ?>
Everything is implement to the cakephp's documentation but always got an validation error for fields name is _required This field is required And if remove the _translations.en from the name first form field and submits it passes the validation but leads to an sql error Field 'name' doesn't have a default value.
Upvotes: 0
Views: 448
Reputation: 41
You’ll need to remember to add _translations into the $_accessible fields of your entity as well.
https://book.cakephp.org/3.0/en/orm/behaviors/translate.html
Upvotes: 1
Reputation: 59
To save the multiple translations at same time just make sure translated columns does not exists in the table.
Here we have to remove the name from the table words.
And also remove the validation rule requirePresense for the translated column.
Upvotes: 0