Symfony2 - Вызовите валидатор электронной почты внутри пользовательского валидатора


Я создаю пользовательское ограничение валидатора для проверки "Контакта", что-то вроде "Джон Доу". Следуя Кулинарной книге, я создал класс ограничений:

<?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 в моем пользовательском валидаторе, чтобы проверить правильность электронной почты. Я не хочу изобретать велосипед и проверять электронную почту с помощью моего собственного регулярного выражения.

Все есть хорошо, если вы пытаетесь подтвердить действительный контакт, но проверяете контакт с недействительным электронным письмом ("Габриэль Гарсия ") он завершается с фатальной ошибкой PHP:

Неустранимая ошибка: Вызов функции-члена addViolation() для не-объекта в/home/dev/myproject/vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/EmailValidator.php в строке 58

Копание в EmailValidator.php класс, я понял, что проблема связана с контекстом $ (Контекст исполнения). Вот строка 58 из EmailValidator.php :

$this->context->addViolation($constraint->message, array('{{ value }}' => $value));

Похоже, что атрибут контекста класса равен нулю. Кто-нибудь знает, почему? Мне нужно куда-то его вколоть?

Заранее благодарю.

P.S.: Я использую Symfony 2.3. Не обращайте внимания на регулярное выражение, я знаю, что оно может быть намного лучше. Сейчас это просто для тестирования.

Author: Gabriel Gcia Fdez, 2013-06-27

3 answers

Вы можете напрямую использовать ограничение

См. 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
);

Наилучшие пожелания

 4
Author: Benjamin Lazarecki, 2013-06-27 12:10:53

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

$this->get('validator');

Не будет работать. Похоже, что единственная проблема, с которой столкнулся плакат, - это добавление EmailValidator в правильный контекст. Это должно сработать:

$emailValidator = new EmailValidator();
$emailValidator->initialize($this->context);
$emailValidator->validate($matches[2], $constraint);
 4
Author: AlexY, 2015-09-04 11:03:59

Найдя эту тему после того, как я попытался вызвать custom внутри custom, я провел глубокое исследование и, возможно, просто нашел другой лучший способ (более простой, по моему мнению).

Допустимо: Sf2.6>=

$this->context->getValidator()
    ->inContext($this->context)
    ->atPath("time_on_point")
    ->validate($timeOnPoint, new AssertCustom\DateTimeRange(array('min' => '+1 day')));

В этом случае я объявил новый пользовательский валидатор, такой как валидатор для конкретного класса, и я мог бы перейти непосредственно к полю по его имени. Преимущество этого: я могу вызвать другой обычай, только применив "новый AssertCustom", и если этому "assertcustom" нужна такая услуга, как постройте, у меня не будет зависимости, потому что служба конфигурации будет вызывать все это прозрачно.

Будьте осторожны, если вы вызываете рекурсивно (глубокое) поле, вам нужно будет адаптировать контекст в соответствии с комментариями, найденными в этом файле: Symfony\Компонент\Валидатор\Ограничения\Collectionvalidator

 1
Author: Draeli, 2015-05-03 12:50:46