Подтвердить что ты не робот

Как разрешить пустые значения в валидаторах symfony2

Я хотел бы применить валидаторы к свойствам объекта только тогда, когда значение не пустое, т.е.

Теперь стандартное поведение symfony:

class Entity
{
    /**
     * @ORM\Column(type="string", nullable=true)
     * @Assert\Email()
     */
    protected $email;
    (...)
}

этот объект не будет проходить проверку, если электронное письмо равно null или пустая строка, есть ли способ сказать validator для утверждения как допустимого, пустого значения и проверить только, если в поле есть данные?

PS Я знаю, что я могу написать валидатор обратного вызова, но обращение к обратному вызову для каждого поля просто для того, чтобы иметь функцию allowEmpty, не так хорошо.

4b9b3361

Ответ 1

Вы должны явно установить 'required' => false в свой FormBuilder класс для всех необязательных полей. Здесь параграф, описывающий параметры типа поля.

Ответ 2

Настройка параметра required не является решением:

Также обратите внимание, что установка требуемой опции в true не приведет к применению проверки на стороне сервера. Другими словами, если пользователь отправляет пустое значение для поля (например, со старым браузером или веб-службой, например), он будет принят как допустимое значение, если вы не используете ограничение проверки Symfony NotBlank или NotNull.

http://symfony.com/doc/current/book/forms.html#field-type-options

Для моих пользовательских валидаторов я добавляю

if (null == $value) {
    return true;
}

к методу isValid(). Однако я не уверен, что будет лучшим способом для стандартных классов валидатора.

Ответ 3

На всякий случай кто-то сталкивается с этим вопросом. Я предпочитаю лично решить эту проблему, добавив следующий атрибут внутри моего шаблона Twig:

{{ form_row(form.<field>, {'required': false}) }}

Ответ 4

если я правильно понимаю, что вы хотите проверить на стороне сервера только в том случае, если введено значение. Я точно такой же. Я хочу проверить URL-адрес, только если указан URL-адрес. Лучший способ, которым я столкнулся, - написать собственный собственный класс проверки. Вы можете написать общий настраиваемый класс проверки.

Я следил за этой ссылкой https://symfony-docs-chs.readthedocs.org/en/2.0/cookbook/validation/custom_constraint.html, за исключением нескольких изменений из-за последней версии Symfony. Вот реализация

Acme\BundleNameBundle\Validator\Ограничения\cstmUrl

namespace Acme\BundleNameBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Constraints\Url;

/**
 * @Annotation
 */
class CstmUrl extends Url
{
    public $message = 'The URL "%string%" is not valid';
}

Acme\BundleNameBundle\Validator\Ограничения\cstmUrlValidator

namespace Acme\BundleNameBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Constraints\Url;
use Symfony\Component\Validator\Constraints\UrlValidator;

class CstmUrlValidator extends UrlValidator
{
    public function validate($value, Constraint $constraint)
    {
        if(!$value || empty($value))
            return true;

        parent::validate($value, $constraint);
    }
}

Validtion.yml

Acme\BundleNameBundle\Entity\Student:
    Url:
        - Acme\BundleNameBundle\Validator\Constraints\CstmUrl: ~

внутри Контроллер просто привязывает ограничение, которое вы обычно выполняете

'constraints'=> new CstmUrl(array("message"=>"Invalid url provided"))

Я уверен, что могут быть другие лучшие способы сделать это, но пока я чувствую, что это хорошо работает.

Ответ 5

Вот трюк, который я нашел на самом деле:

https://github.com/symfony/symfony/issues/5906

Вам нужно написать трансформатор данных, который ничего не делает, а затем добавить его в свое поле. После этого juste вызовите метод submit() со вторым параметром на false.

Обратите внимание, что это нормально с Symfony 2.3.

Ответ 6

Удовлетворение типа поля. http://symfony.com/doc/current/book/forms.html#field-type-guessing

Это зависит от вашего объявления формы: "Угадание" активируется, когда вы опускаете второй аргумент методу add() (или передаете ему null). Если вы передадите options в качестве третьего аргумента (сделано для dueDate выше), эти параметры применяются к угаданному полю. "