Блог Андрея

 
 

Удобное декорирование сервиса в Symfony с помощью консольной команды decorate-controller

En.

Связанные статьи:

Добавляем каптчу на форму запроса пароля по email. Перегружаем FOSUser ResettingController.

Публикуем свой бандл Symfony как пакет composer

Когда я решил декорировать контроллер FOSUserBundle ResettingController оказалось сложным написать конфигурацию регистрации нового сервиса. Помимо того, что я должен найти псевдонимы всех сервисов, которые принимает оригинальный контроллер, я должен написать класс, почти все методы которого просто вызывают методы декорируемого контроллера (это скучно!).

Мы хотим как можно больше использовать хорошие готовые решения, это значит, что операция декорирования контроллера из стороннего пакета будет рутинной.

Поэтому я создал консольную команду

php bin/console landlib:decorate-controller

которая создаёт заготовку класса контроллера, декорирующего нужный сервис и выводит в stdout фрагмент yaml конфигурации нового сервиса. Вам остаётся просто скопировать эту конфигурацию в ваш config/services.yaml.

Установка

composer require landlib/symfonytoolsbundle

И добавьте в ваш config/bundles.php

элемент массива

return [
// ...
Landlib\SymfonyToolsBundle\SymfonyToolsBundle::class => ['all' => true]
];

Использование

На примере декорирования FOS\UserBundle\Controller\ResettingController

php bin/console landlib:decorate-controller

Команда попросит ввести путь к перегружаемому контроллеру. Надо ввести абсолютный путь, например

/home/user/sym3.4project/vendor/friendsofsymfony/user-bundle/Controller/ResettingController.php

После этого команда сгенерирует файл

/home/user/sym3.4project/src/Controller/ResettingController.php

Если файл уже существует, он будет перезаписан или удалён! Копии не сохраняется.

и выведет фрагмент yaml конфигурации:

Add in your configuration config/services.yaml:

==================

    App\Controller\ResettingController:
        decorates: fos_user.resetting.controller
        arguments:
            - '@App\Controller\ResettingController.inner'
            - '@event_dispatcher'
            - '@fos_user.resetting.form.factory'
            - '@fos_user.user_manager'
            - '@fos_user.util.token_generator'
            - '@fos_user.mailer'
            - '%fos_user.resetting.retry_ttl%'
            - '@service_container'

==================

Remember to change the name of the controller in the routes or annotation file.

Обратите внимание, на последнюю строку вывода, маршрут(или маршруты) для тех actions, которые вы хотите перегрузить необходимо корректировать в конфигурации маршрутов вручную! (Потому что команда не может знать, какие из actions контроллера вы хотите перегрузить).

Проблемы

Если в процессе работы вы внезапно увидели ошибку Cannot autowire service..., значит вы забыли скопировать фрагмент конфигурации в ваш services.yaml.

Вы можете удалить файл

/home/user/sym3.4project/src/Controller/ResettingController.php

(путь к файлу приведен для примера из раздела Использование)

или добавить фрагмент конфигурации в ваш services.yaml.

О других возможностях пакета SymfonyToolsBundle читайте в документации на гитхаб.