vimal
vimal

Reputation: 59

Cakephp 3 unable to save multiple translations at same time

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

Answers (2)

mickeyze2
mickeyze2

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

vimal
vimal

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

Related Questions