Validation CakePHP3.1:我对翻译行为字段的验证,需要一些评论/评论方面的帮助吗

Validation CakePHP3.1:我对翻译行为字段的验证,需要一些评论/评论方面的帮助吗,validation,cakephp,internationalization,multilingual,cakephp-3.1,Validation,Cakephp,Internationalization,Multilingual,Cakephp 3.1,我使用了一个钩子来验证我翻译的字段,基于以下线程:。我已经做到了,但我希望你们能帮助我改进我的代码,所以请随意评论和修改 class ContentbuildersTable extends Table { public function initialize(array $config) { $this->addBehavior('Tree'); $this->addBehavior('Timestamp'); $t

我使用了一个钩子来验证我翻译的字段,基于以下线程:。我已经做到了,但我希望你们能帮助我改进我的代码,所以请随意评论和修改

class ContentbuildersTable extends Table
{

    public function initialize(array $config)
    {
        $this->addBehavior('Tree');
        $this->addBehavior('Timestamp');
        $this->addBehavior('Translate', [
            'fields' => [
                'slug'
            ]
        ]);
    }

    public function validationDefault(Validator $validator)
    {
        $data = null; // Contain our first $context validator

        $validator
            ->requirePresence('label')
            ->notEmpty('label', null, function($context) use (&$data) {
                $data = $context; // Update the $data with current $context
                return true;
            })
            ->requirePresence('type_id')
            ->notEmpty('type_id')
            ->requirePresence('is_activated')
            ->notEmpty('is_activated');

        $translationValidator = new Validator();
        $translationValidator
            ->requirePresence('slug')
            ->notEmpty('slug', null, function($context) use (&$data) {
                if (isset($data['data']['type_id']) && !empty($data['data']['type_id'])) {
                    if ($data['data']['type_id'] != Type::TYPE_HOMEPAGE) {
                        return true;
                    }
                    return false;
                }
                return true;
            });

        $validator
            ->addNestedMany('translations', $translationValidator);

        return $validator;
    }

}
我对我使用$data的技巧并不感到自豪,但我还没有找到将验证器的数据放入nestedValidator的方法

这里重要的一点是要注意,我的nestedValidator的唯一规则是“翻译”,这非常重要

class Contentbuilder extends Entity
{

    use TranslateTrait;

}
这里是I18ns工作的基础

class BetterFormHelper extends Helper\FormHelper
{

    public function input($fieldName, array $options = [])
    {
        $context = $this->_getContext();
        $explodedFieldName = explode('.', $fieldName);
        $errors = $context->entity()->errors($explodedFieldName[0]);

        if (is_array($errors) && !empty($errors) && empty($this->error($fieldName))) {
            if (isset($errors[$explodedFieldName[1]][$explodedFieldName[2]])) {
                $error = array_values($errors[$explodedFieldName[1]][$explodedFieldName[2]])[0];
                $options['templates']['inputContainer'] = '<div class="input {{type}} required error">{{content}} <div class="error-message">' . $error . '</div></div>';
            }
        }

        return parent::input($fieldName, $options);
    }

}

这里是我这边的一个.gif最终结果:

可能是重复的,它可能是这样工作的,但我认为这也只是一个临时的黑客(就像我在另一篇文章中所说的那样)对翻译输入字段进行自定义验证。。。您正在分离默认翻译字段并使用自定义翻译字段-您还可以使用虚拟字段而不是伪造的
translation.xx_xx
,并在最后合并它们。我认为目前这是一个可能的解决办法,只要嵌套验证程序和表单帮助程序的错误/问题仍然存在/未解决…无论如何,感谢您发布代码并将其链接到我的问题,我认为TranslateBehaviour是一个重要的特性,任何关于如何根据您的需要定制它的信息都是有用的,因为没有很多更复杂或定制用例的示例可用……它可能会以这种方式工作,但我认为这也只是一个暂时的攻击(就像我在另一篇文章中所说的)要对翻译输入字段进行自定义验证。。。您正在分离默认翻译字段并使用自定义翻译字段-您还可以使用虚拟字段而不是伪造的
translation.xx_xx
,并在最后合并它们。我认为目前这是一个可能的解决办法,只要嵌套验证程序和表单帮助程序的错误/问题仍然存在/未解决…无论如何,感谢您发布代码并将其链接到我的问题,我认为TranslateBehaviour是一个重要的特性,任何关于如何根据您的需要定制它的信息都是有用的,因为没有太多更复杂或定制用例的示例。。。
<?= $this->Form->create($entity, ['novalidate', 'data-load-in' => '#right-container']) ?>

<div class="tabs">

    <?= $this->Form->input('label') ?>
    <?= $this->Form->input('type_id', ['empty' => '---']) ?>
    <?= $this->Form->input('is_activated', ['required' => true]) ?>
    <?= $this->Form->input('translations.fr_FR.slug') ?>
    <?= $this->Form->input('_translations.en_US.slug') ?>

</div>

<?php
    echo $this->Form->submit(__("Save"));
    echo $this->Form->end();
?>
$entity = $this->Contentbuilders->patchEntity($entity, $this->request->data);

// We get the locales
$I18ns = TableRegistry::get('I18ns');
$langs = $I18ns->find('list', [
    'keyField' => 'id',
    'valueField' => 'locale'
])->toArray();

// Merging translations
if (isset($entity->translations)) {
    $entity->_translations = array_merge($entity->_translations, $entity->translations);
    unset($entity->translations);
}

foreach ($entity->_translations as $lang => $data) {
    if (in_array($lang, $langs)) {
        $entity->translation($lang)->set($data, ['guard' => false]);
    }
}