Я работал над крючком для проверки моих переведенных полей на основе этого потока: https://stackoverflow.com/a/33070156/4617689 а>. То, что я сделал, помогло, но я ищу вас, ребята, чтобы помочь мне улучшить мой код, поэтому не стесняйтесь комментировать и изменять
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, но я не нашел способа получить данные валидатора в свой вложенный валидатор...
Важно отметить, что я управляю своим вложенным валидатором только для «переводов», это очень важно!
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);
}
}
С помощью этого formHelper мы получим ошибки вложенной валидации и внедрим их во входные данные, мне не нравятся шаблоны, поэтому это очень уродливо.
<?= $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();
?>
Здесь требуется мой fr_FR.slug, когда для type_id не установлено значение Type::TYPE_HOMEPAGE, да, на моей домашней странице нет slug, обратите внимание, что en_US.slug вообще не требуется, потому что мне нужен только «translations.xx_XX.xxxx», а не '_translations.xx_XX.xxxx'.
И последняя часть кода, контроллер
$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]);
}
}
Вот .gif окончательного результата с моей стороны: http://i.giphy.com/3o85xyrLOTd7q0YVck.gif
translation.xx_XX
и объединять их в конце. Я думаю, что на данный момент это возможный обходной путь, пока ошибки/проблемы с вложенными валидаторами и помощником формы все еще открыты/не решены... - person Oops D'oh   schedule 07.11.2015