В моем проекте на основе Symfony 2.8 я использую FOSUserBundle и расширил его с помощью специального MyUserBundle, используя наследование пакетов.
При попытке обновить FOSUserBundle с 2.0.2 до 2.1.2 я столкнулся с несколькими проблемами.
Поскольку наследование пакетов не рекомендуется в Symfony 3.4 и полностью исключено в Symfony 4.0, я сейчас пытаюсь достичь того же результата без использования наследования пакетов.
Я нашел много информации, которая показывает, что ресурсы пакета можно переопределить, просто поместив файлы в app/Resources/<BundleName>/.... Таким образом, шаблоны FOSUserBundle можно переопределить, поместив их в app/Resources/FOSUserBundle/views/<template.html.twig>.
Хотя это будет работать, это не даст такого же результата, как наследование пакетов. Я могу использовать свой унаследованный пакет в разных проектах и, таким образом, повторно использовать один и тот же код снова и снова. Решение app/Resources/<BundleName>/... будет работать только для текущего проекта.
Вопрос 1: Как переопределить шаблоны (и другие ресурсы) в настраиваемом пакете, который можно использовать в разных проектах, а не в папке app/Resources для конкретного проекта?
Вопрос 2: Как переопределить поведение контроллеров, которым не предлагать событие для этого?
В настоящее время я использую наследование пакетов, чтобы переопределить confirmedAction, чтобы отправить пользователя на страницу пользовательской настройки, а не на страницу по умолчанию:
// Original FOSUserBundle code
public function confirmedAction(Request $request) {
$user = $this->getUser();
if (!is_object($user) || !$user instanceof UserInterface) {
throw new AccessDeniedException('This user does not have access to this section.');
}
return $this->render('@FOSUser/Registration/confirmed.html.twig', array(
'user' => $user,
'targetUrl' => $this->getTargetUrlFromSession($request->getSession()),
));
}
// MyUserBundle codes which should override the default behavior
public function confirmedAction(Request $request) {
$user = $this->getUser();
if (!is_object($user) || !$user instanceof UserInterface) {
throw new AccessDeniedException('This user does not have access to this section.');
}
// Send user to setup-page
return $this->redirectToRoute('app_user_setup');
}
Как я могу таким же образом контролировать поведение и отправлять пользователя на страницу настройки вместо страницы подтверждения по умолчанию без использования наследования пакетов?
Насколько мне известно, FOSUserBundle не предоставляет возможности указать цель подтверждения. Конечно, я мог бы перехватить запрос на подтвержденный маршрут с помощью некоторого прослушивателя событий запроса и перенаправить его. Но это было бы довольно взломано. Будет ли это правильным решением, или есть более чистый способ добиться того же?
Возможно, stackoverflow.com/a/45239524/4224384 может частично помочь вам в этом.




О контроллерах
Маршруты! - способ добиться этого сейчас, «первый найденный маршрут побеждает», поэтому убедитесь, что вы задали тот же маршрут перед исходным, с вашим настраиваемым контроллером. например.:
<route id = "fos_user_registration_confirmed" path = "/confirmed" methods = "GET">
<default key = "_controller">MyUserBundle\Controller\RegistrationController::confirmedAction</default>
</route>
Затем ваш файл маршрутизации MyUserBundle/Resources/config/routing/registration.xml должен быть импортирован до файла маршрутизации FOSUserBundle. Таким образом, ваше настраиваемое действие будет выполнено вместо исходного fos_user.registration.controller:confirmedAction.
О шаблонах
Опять же, «первый найденный шаблон побеждает», поэтому убедитесь, что путь к вашему пакету views определен до пути в пространстве имен FOSUser Twig. Вы можете добиться этого, создав компилятор пройти:
// MyUserBundle/DependencyInjection/Compiler/TwigPass.php
$path = dirname(__DIR__, 2).'/Resources/views';
$twigFilesystemLoaderDefinition = $container->findDefinition('twig.loader.native_filesystem');
$twigFilesystemLoaderDefinition->addMethodCall('prependPath', array($path, 'FOSUser'));
Проверьте пути к загрузчику Twig, запустив bin/console debug:twig, он должен выглядеть так:
@FOSUser - vendor/acme/my-user-bundle/Resources/views
- vendor/friendsofsymfony/user-bundle/Resources/views
Отсюда вы можете переопределить любой шаблон FOSUserBundle, например Registration/confirmed.html.twig, при вызове @FOSUser/Registration/confirmed.html.twig.
Спасибо! Я получаю сообщение, что twig.loader.native_filesystem не существует? Включено ли это только в SF> 2.8 (которым я сейчас пользуюсь)?
@AndreiHerford, плохо, вы должны вместо этого создать проход компилятора, чтобы получить и изменить определение службы twig.loader.native_filesystem. Ответ обновлен!
Q1: вы пробовали symfony.com/doc/current/templating/…?