Cakephp 3.0.8:数组内部"name"字段在patchEntity后消失


Cakephp 3.0.8: array inside "name" field disappears after patchEntity

我正在测试cakephp 3.0.8,我有一个问题。我试图同时添加多种语言的新成分,为此,我需要我的表单在"名称"和包含语言和数据库中i18n表中该语言值的"段"字段中有一个数组。但是在保存之前的patchEntity之后,数组消失了,我不明白为什么。

我想要的:

[
    'name' => [
        'en_US' => 'Title',
        'fr_CA' => 'Titre'
    ],
    'slug' => [
        'en_US' => 'Slug',
        'fr_CA' => 'Slug Fr'
    ],
    'season' => ''
]

我在patchEntity:

之后的内容
[
    'name' => '',
    'slug' => '',
    'season' => ''
]

在我的成分控制器。php

public function add()
{
    $ingredient = $this->Ingredients->newEntity();
    if ($this->request->is('post')) {
        debug($this->request->data);
        $ingredient = $this->Ingredients->patchEntity($ingredient, $this->request->data);
        $ingredient->locale = Configure::read('Config.locales');
        debug($ingredient);die();
        if ($this->Ingredients->save($ingredient)) {
            $this->Flash->success(__('The ingredient has been saved.'));
            return $this->redirect(['action' => 'index']);
        } else {
            $this->Flash->error(__('The ingredient could not be saved. Please, try again.'));
        }
    }
    $this->set(compact('ingredient', 'recipes'));
    $this->set('_serialize', ['ingredient']);
}

在我的成分。php实体

protected $_accessible = [
    'name' => true,
    'slug' => true,
    'season' => true,
    'recipe_count' => false,
    'recipes' => false,
    '*' => false
];

在我的目录

public function validationDefault(Validator $validator)
{       
    $validator
        ->requirePresence('name', 'create')
        ->notEmpty('name');
    $validator
        ->allowEmpty('slug');
    $validator
        ->allowEmpty('season');
    return $validator;
}

最后在add。ctp视图

<div class="ingredients form large-10 medium-9 columns">
<?= $this->Form->create($ingredient) ?>
<fieldset>
    <legend><?= __('Add Ingredient') ?></legend>
    <?php
        foreach ($locales as $lang) {
            echo $this->Form->input('name.'.$lang, ['label' => 'Title ('.$lang.')']);
            echo $this->Form->input('slug.'.$lang, ['label' => 'Slug ('.$lang.')']);
        }
        echo $this->Form->input('season');
    ?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>

CakePHP用控制台生成了所有代码,除了add.ctp,我稍微修改了一下,使其在"name"answers"slug"字段中有一个数组。var $locale只包含一个locale数组(en_US和fr_CA)

谢谢!

在编组过程中,数据是根据列类型进行转换的,列很可能是字符串类型,因此不能将数组修补为它们,这将导致空字符串。

看一下

  • Cookbook>…ORM>行为>翻译>保存多个翻译
  • https://github.com/cakephp/cakephp/issues/4902

现在,使用文档中所示的traits translation()方法。您可以在修补实体之前或之后的保存过程中执行此操作。建议不要在表单中使用实际的列名,以便您可以轻松地在请求数据中打补丁。

注意,原始实体应该保留默认的语言内容。因此,如果默认值恰好是en_US,那么您应该只存储fr_CA作为翻译。

为了验证已翻译的字段,您可能应该使用一个自定义的翻译表类,并使用应用程序规则!

这是我的代码,它似乎工作得很好!

在我看来:

<div class="ingredients form large-10 medium-9 columns">
<?= $this->Form->create($ingredient) ?>
<fieldset>
    <legend><?= __('Add Ingredient') ?></legend>
    <?php
        echo $this->Form->input('name', ['label' => __('Title')]);
        foreach ($locales as $lang) {
            echo $this->Form->input('locales.'.$lang.'.name', ['label' => __('Title')]);
        }
        echo $this->Form->input('slug');
        echo $this->Form->input('season');
    ?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>

我在控制器中保存之前添加了这段代码:

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

您应该添加一种方法来检测请求中的区域设置是否有效和受支持。