在 CakePHP 3 中验证转换后的实体

Validating Translated Entities in CakePHP 3

我在 CakePHP3 中验证 I18N 字段时遇到一些困难。

翻译行为设置如下:

$this->addBehavior('Translate', [
    'fields' => ['name', 'body', 'slug'],
    'validator' => 'default'
]);

喜欢这里的广告:https://book.cakephp.org/3.0/en/orm/behaviors/translate.html#validating-translated-entities

核心验证工作正常。我在 validationDefault 函数中有一个验证规则,它检查名称是否不为空并且它工作正常。不过,我还想在此验证之上添加一些应用程序规则。 "name" 字段应具有唯一值。我不想允许多个实体具有相同的翻译名称。

这段代码显然不起作用。 CakePHP 文档也对此事保持沉默。

public function buildRules(RulesChecker $rules) {
    // prevent duplicate creation
    $rules->add($rules->isUnique(['name']));
    return $rules;
} 

这真的可能吗? 谢谢

您正在做的是为主模型上的 name 字段创建规则,这不会影响翻译。没有内置的功能,该行为仅通过使用 validationTranslated() 方法来协助验证规则,以防它存在于您的模型 class 上,它不会帮助应用程序规则。

您必须创建一个自定义应用程序规则来检查翻译 table,方法是匹配 fieldlocalemodel 和 [=16] =] 字段,类似于以下内容:

$rules->add(
    function (EntityInterface $entity) {
        $behavior = $this->behaviors()->get('Translate');
        $association = $this->association($behavior->getConfig('translationTable'));

        $result = true;
        foreach ($entity->get('_translations') as $locale => $translation) {
            $conditions = [
                $association->aliasField('field') => 'name',
                $association->aliasField('locale') => $locale,
                $association->aliasField('content') => $translation->get('name')
            ];

            if ($association->exists($conditions)) {
                $translation->setErrors([
                    'name' => [
                        'uniqueTranslation' => __d('cake', 'This value is already in use')
                    ]
                ]);

                $result = false;
            }
        }

        return $result;
    }
);

请注意,这使用关联对象而不是目标 table,这将确保自动应用模型名称等其他条件。

另外这需要在实体上手动设置错误,因为它们是嵌套的,这是规则检查器不支持的,目前它只能在第一级实体上设置错误(参见errorField选项)。

还应注意,可以修改翻译 table 关联的规则检查器(通过 Model.buildRules 事件),但这会导致设置错误将在主实体上放置在单独的 属性(默认情况下为 _i18n)中的新实体,其中表单助手不会发现错误,因此必须手动读取错误,这有点烦人。

另见