Я создаю специальное ограничение валидатора для проверки «Contact», что-то вроде «John Doe <jdoe@example.com>». После Поваренной книги я создал класс Constraint:
<?php namespace MyCompany\MyBundle\Validator\Constraints; use Symfony\Component\Validator\Constraint; /** * @Annotation */ class Contact extends Constraint { public $message = 'The string "%string%" is not a valid Contact.'; }
а также создал валидатор:
<?php namespace MyCompany\MyBundle\Validator\Constraints; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Constraints\Email; use Symfony\Component\Validator\Constraints\EmailValidator; class ContactValidator extends ConstraintValidator { public function validate($value, Constraint $constraint) { if (!preg_match('#(.*)\s+<(.*)>#', $value, $matches)) { $this->context->addViolation($constraint->message, array('%string%' => $value)); } $emailValidator = new EmailValidator(); if (isset($matches[2]) && $emailValidator->validate($matches[2], new Email())) { $this->context->addViolation($constraint->message, array('%string%' => $value)); } } }
Дело в том, что я пытаюсь использовать EmailValidator Symfony в моем настраиваемом валидаторе, чтобы проверить, что письмо действительно. Я не хочу изобретать колесо и проверять электронную почту, используя собственное регулярное выражение.
Все хорошо, когда вы пытаетесь проверить действительный контакт, но, проверяя контакт с недействительным адресом электронной почты («Gabriel Garcia <infoinv4l1d3mai1.com>)), он сходит с ошибкой PHP Fatal:
Неустранимая ошибка: вызов функции-члена addViolation () для не-объекта в /home/dev/myproject/vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/EmailValidator.php в строке 58
Копаясь в классе EmailValidator.php, я понял, что проблема связана с $ context (ExecutionContext). Вот строка 58 EmailValidator.php:
$this->context->addViolation($constraint->message, array('{{ value }}' => $value));
Кажется, что атрибут контекста класса равен NULL. Кто-нибудь знает почему? Мне нужно что-то ввести?
Заранее спасибо.
PS: Я использую Symfony 2.3. Не обращайте внимания на регулярное выражение, я знаю, что это может быть намного лучше. Это просто для тестирования прямо сейчас.
Вы можете напрямую использовать ограничение
см. http://symfony.com/doc/current/book/validation.html
use Symfony\Component\Validator\Constraints\Email $emailConstraint = new Email(); // use the validator to validate the value $errorList = $this->get('validator')->validateValue( $email, $emailConstraint );
С наилучшими пожеланиями
Я думаю, что исходный вопрос заключался в использовании EmailValidator внутри Custom Validator, и в этом сценарии контейнер недоступен, поэтому
$this->get('validator');
не будет работать. Кажется, что единственная проблема, которую плакат заключал в том, чтобы добавить EmailValidator addViolation в правильный контекст. Это должно работать:
$emailValidator = new EmailValidator(); $emailValidator->initialize($this->context); $emailValidator->validate($matches[2], $constraint);
Обнаружив эту тему после того, как вы попытались вызвать обычай внутри таможни, я провел глубокое исследование, и я мог бы найти еще один лучший способ (проще по мне).
Действительно: Sf2.6> =
$this->context->getValidator() ->inContext($this->context) ->atPath("time_on_point") ->validate($timeOnPoint, new AssertCustom\DateTimeRange(array('min' => '+1 day')));
В этом случае я объявлял новый пользовательский валидатор, например, валидатор, специфичный для класса, и я мог перейти непосредственно к полю по его имени. Преимущество этого: я могу назвать другой обычай, применяя только «новый AssertCustom», и если этому «AssertCustom» нужен сервис, такой как конструктор, у меня не будет зависимости, потому что служба конфигурации будет транслировать все содержимое прозрачно.
Будьте осторожны, если вы вызываете рекурсивно (глубокое) поле, вам нужно будет адаптировать контекст в соответствии с комментариями, найденными в этом файле: Symfony \ Component \ Validator \ Constraints \ CollectionValidator