Как переопределить шаблоны и контроллеры пакетов (FOSUserBundle) без использования наследования пакетов

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

Q1: вы пробовали symfony.com/doc/current/templating/…?

Brucie Alpha 14.06.2018 17:23

Возможно, stackoverflow.com/a/45239524/4224384 может частично помочь вам в этом.

yceruto 14.06.2018 18:15
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Symfony Station Communiqué - 17 февраля 2023 г
Symfony Station Communiqué - 17 февраля 2023 г
Это коммюнике первоначально появилось на Symfony Station , вашем источнике передовых новостей Symfony, PHP и кибербезопасности.
Управление ответами api для исключений на Symfony с помощью KernelEvents
Управление ответами api для исключений на Symfony с помощью KernelEvents
Много раз при создании api нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
1
2
589
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Переопределение ресурсов внутри пакета, начиная с Symfony 4.0 без наследования пакета

О контроллерах

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

<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 (которым я сейчас пользуюсь)?

Andrei Herford 18.06.2018 13:58

@AndreiHerford, плохо, вы должны вместо этого создать проход компилятора, чтобы получить и изменить определение службы twig.loader.native_filesystem. Ответ обновлен!

yceruto 26.06.2018 17:06

Другие вопросы по теме