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

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

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

我想要的:

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

patchEntity 之后我得到的是:

[
    'name' => '',
    'slug' => '',
    'season' => ''
]

在我的IngredientController.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']);
}

在我的 Ingredient.php 实体中

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

在我的IngredientsTable.php

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" 和 "slug" 字段中有一个数组。 var $locales 仅包含语言环境数组(en_US 和 fr_CA)

谢谢!

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

看看

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

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

为了验证翻译的字段,您可能应该使用 a custom translation table class, and make use of application rules!

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

在我看来:

<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]);
}

您应该添加一种方法来检测请求中的语言环境是否有效和受支持。