Как проверить подформы формы с отображением объектов в Symfony2?

У меня есть форма, которая сопоставлена ​​с сущностью ('data_class' => ...). У меня есть валидаторы, настроенные (через аннотации) для свойств сущности.

Сущность имеет свойство (nameTranslations) типа доктрины array. Я создал настраиваемый тип поля, состоящий из нескольких полей, которые назначаются этому полю в форме. Каждое из полей подчиненной формы (типа text) имеет настройку валидаторов (NotBlank) с помощью опции validation_constraint.

Я пробовал различные аннотации проверки для свойства nameTranslations, включая Valid(). Я пробовал настройки error_bubbling практически на чем угодно. Подформа (поле nameTranslations) вообще не проверяется.

Подформа:

class TranslatableTextType extends AbstractType
{
    private $langs;

    /**
    * {@inheritDoc}
    */
    public function __construct($multilang)
    {
        $this->langs = $multilang->getLangs();
    }

    /**
    * {@inheritDoc}
    */
    public function buildForm(FormBuilder $builder, array $options)
    {
        foreach($this->langs as $locale => $lang)
        {
            $builder->add($locale, 'text', array(
                'label' => sprintf("%s [%s]", $options['label'], $lang),
                'error_bubbling' => true,
            ));
        }
    }

    /**
    * {@inheritDoc}
    */
    public function getDefaultOptions(array $options)
    {
        $constraints = [
            'fields' => [],
            'allowExtraFields' => true,
            'allowMissingFields' => true,
        ];

        foreach($this->langs as $locale => $lang)
        {
            $constraints['fields'][$locale] = new NotBlank();
        }

        $collectionConstraint = new Collection($constraints);

        return [
            'validation_constraint' => $collectionConstraint,
            'label' => '',
            'error_bubbling' => true
        ];
    }

    /**
    * {@inheritDoc}
    */
    public function getParent(array $options)
    {
        return 'form';
    }

    /**
    * {@inheritDoc}
    */
    public function getName()
    {
        return 'translatable_text';
    }
}

В основной форме:

$builder->add('nameTranslations', 'translatable_text', [
            'label' => 'Name'
        ]);

В сущности:

/**
 * @var array
 *
 * @Assert\Valid
 * @ORM\Column(type="array")
 */
protected $nameTranslations;

person pinkeen    schedule 11.01.2013    source источник
comment
Эта проблема была исправлена ​​в последующих версиях symfony. Я думаю, что это была ошибка в 2.0.   -  person pinkeen    schedule 22.08.2014


Ответы (1)


Я думаю, вам следует использовать тип коллекции вместо пользовательского или ваш пользовательский тип должен иметь тип коллекции, определенный как родительский.

Вы можете использовать валидатор All, например:

/**
 * @Assert\All({
 *     @Assert\NotBlank
 * })
 * @ORM\Column(type="array")
 */
 protected $nameTranslations;

он проверит, не является ли каждое значение массива пустым.

person l3l0    schedule 11.01.2013
comment
Для коллекции плохо подходит, там (по большей части времени) фиксированное количество полей. Кроме того, у меня точно такая же проблема с другим полем, которое нельзя преобразовать в коллекцию, даже если бы я захотел. Я не понимаю, почему symfony не проверяет подчиненную форму, когда каждое поле имеет валидатор, и поле, к которому прикреплена эта подчиненная форма, также имеет валидатор (ORM\Validate). Даже если ваше решение сработает (не могу проверить его прямо сейчас, дома), оно будет проверять подчиненную форму в целом — было бы лучше, если бы каждое поле обрабатывалось отдельно (UX). - person pinkeen; 11.01.2013
comment
symfony.com/doc/master/reference/forms/ типы/ поэтому по умолчанию не проверяются подчиненные формы... и я не понимаю, почему фиксированное количество полей не подходит для типа коллекции... тип коллекции следует использовать, когда вы хотите иметь много подчиненных форм (типов) ... Кстати, даже если вы не используете коллекцию, вы можете проверить это ограничением All - person l3l0; 11.01.2013
comment
Из cascade_validation: Вместо использования этого параметра вы также можете использовать ограничение Valid в своей модели, чтобы принудительно проверять дочерний объект, хранящийся в свойстве. Уже пробовал ограничение Valid. Что касается спора о коллекции - я не могу использовать коллекцию для другого поля с той же проблемой. Коллекция не подходит для многих областей и больше похожа на обходной путь, чем на решение. - person pinkeen; 12.01.2013