Symfony DI вводит пустой массив вместо объекта диспетчера сущностей

Я пытаюсь внедрить объект диспетчера сущностей в свой класс проверки, однако Symfony DI вводит пустой массив (проверено с помощью var_dump). Я не могу понять, почему это не работает. Вот часть моего кода.

приложение/config.yml

services:
    unique_booking_date_validator:
        class: MyCompany\Bundle\AppBundle\Domain\Validator\UniqueBookingDate
        arguments:
            - "@doctrine.orm.entity_manager"
        tags:
            - { name: validator.constraint_validator, alias: unique_booking_date }

Мои занятия

namespace MyCompany\Bundle\AppBundle\Domain\Validator;

use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Constraint;

/** @Annotation */
class UniqueBookingDate extends Constraint
{
    protected $em;

    public function __construct(\Doctrine\ORM\EntityManager $em)
    {
        $this->em = $em;
    }
    public function validatedBy()
    {
        return 'unique_booking_date';
    }

    ...
}

Он возвращает это исключение:

Catchable Fatal Error: Argument 1 passed to MyCompany\Bundle\AppBundle\Domain\Validator
\UniqueBookingDate::__construct() must be an instance of Doctrine\ORM\EntityManager, 
array given, called in C:\htdocs\booking-manager\vendor\doctrine\annotations\lib\Doctrine\
Common\Annotations\DocParser.php on line 794 and defined in C:\htdocs\booking-manager
\src\MyCompany\Bundle\AppBundle\Domain\Validator\UniqueBookingDate.php line 20

Я использую Symfony v2.5.7. Что-то не так с кодом?


person dextervip    schedule 21.11.2014    source источник
comment
А что, если вы расширите UniqueBookingDate с помощью ConstraintValidator?   -  person Damaged Organic    schedule 21.11.2014
comment
@ Grimv01k У меня все еще та же проблема. Кажется, что тег validator.constraint_validator не регистрирует мой пользовательский валидатор должным образом, потому что я могу получить услугу по идентификатору с внедренным менеджером сущностей.   -  person dextervip    schedule 21.11.2014
comment
Похоже, вы действительно передаете пустой массив через services.yml. Я попытаюсь воспроизвести, но, может быть, определение такой формы, как arguments: [@doctrine.orm.entity_manager], что-то сделает?   -  person Damaged Organic    schedule 21.11.2014
comment
@ Grimv01k Все еще та же проблема.   -  person dextervip    schedule 21.11.2014
comment
Только что закончил это руководство: knpuniversity .com/screencast/question-answer-day/, в разделе Applying the Validation Logic есть такая ЭМ-инъекция, и она отлично работает. Может быть, даст вам подсказку... Из того, что я мог видеть, должен быть один класс, который расширяет Constraint, и один класс ConstraintValidator, в котором передается EM, и ваш tags также ожидает validator.constraint_validator. Если фатальный говорит, что массив пуст, то, вероятно, инъекция в config.yml пропущена. Я надеюсь, что это поможет вам.   -  person Damaged Organic    schedule 21.11.2014
comment
@ Grimv01k Извините за ошибку, я не разделил класс, как показано в руководстве. Спасибо :)   -  person dextervip    schedule 21.11.2014


Ответы (1)


Это не удается, потому что Symfony передает массив опций, ожидаемый родительским классом Constraint.

Вам нужно разделить свой валидатор на два класса: один класс аннотации и тот, который выполняет фактическую проверку.

/** @Annotation */
class UniqueBookingDate extends Constraint
{
    public function validatedBy()
    {
        return 'unique_booking_date_validator';
    }
}

Теперь настройте службу под названием unique_booking_date_validator, которая выполняет фактическую проверку. Здесь вы можете передать диспетчер сущностей и любые другие зависимости.

class UniqueBookingDateValidator extends ConstraintValidator
{
    protected $em;

    public function __construct(\Doctrine\ORM\EntityManager $em)
    {
        $this->em = $em;
    }

    public function validate($value, Constraint $constraint)
    {
        // do validation here
    }
}

Итак, ваш файл services.yml должен выглядеть примерно так:

services:
    unique_booking_date_validator:
        class: MyCompany\Bundle\AppBundle\Domain\Validator\UniqueBookingDateValidator
        tags:
            - { name: validator.constraint_validator, alias: unique_booking_date_validator }
        arguments:
            - "@doctrine.orm.entity_manager"

Чтобы увидеть хороший пример этого в действии, ознакомьтесь с валидатором UniqueEntity от Symfony или прочтите статью Symfony Cookbook.

person dchesterton    schedule 21.11.2014