Как использовать наследование пакетов для переопределения частей пакета

Как использовать наследование пакетов для переопределения частей пакета

При работе со сторонними пакетами, вы скорее всего столкнётесь с ситуацией, когда вы захотите переопределить файл в этом стороннем пакете с помощью файла в одном из ваших собственных пакетов. Symfony предоставляет вам очень удобный способ переопределения таких вещей, как контроллеры, шаблоны и другие файлы в каталоге пакета Resources/.

Например, представьте, что вы установили FOSUserBundle, но хотите переопределить его базовый шаблон layout.html.twig, а также один из его контроллеров.

Для начала, создайте новый пакет под названием UserBundle и включите его в ваше приложение. Далее, зарегистрируйте сторонний FOSUserBundle как "родителя" вашего пакета:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// src/UserBundle/UserBundle.php
namespace UserBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;

class UserBundle extends Bundle
{
    public function getParent()
    {
        return 'FOSUserBundle';
    }
}

Сделав это простое изменение, вы теперь можете переопределять несколько частей FOSUserBundle просто создав файл с таким же именем.

Note

Несмотря на название метода, между пакетами не существует родительских / дочерних отношений, это просто способ расширять и переопределять существующий пакет.

Переопределение контроллеров

Представьте, что вы хоите добавить некоторую функциональность к registerAction() RegistrationController, который живёт внутри FOSUserBundle. Чтобы сделать это, просто создайте ваш собственный файл RegistrationController.php, переопределите первоначальный метод пакета и измените его функциональность:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// src/UserBundle/Controller/RegistrationController.php
namespace UserBundle\Controller;

use FOS\UserBundle\Controller\RegistrationController as BaseController;

class RegistrationController extends BaseController
{
    public function registerAction()
    {
        $response = parent::registerAction();

        // ... сделать заказные вещи
        return $response;
    }
}

Tip

В зависимости от того, насколько сильно вам нужно изменить поведение, вы можете вызвать parent::registerAction(), либо полностью заменить его логику вашей собственной.

Note

Переопределение контроллеров таким образом работает только если пакет ссылается на контроллер, используя стандартный синтаксис FOSUserBundle:Registration:register в маршрутах и шаблонах. Это лучшая практика.

Переопределение ресурсов: шаблоном, маршрутизации и др.

Большинство ресурсов также можно переопределить просто создав файл в том же местоположении, что и ваш родительский пакет.

Например, очень частонужно переопределить шаблон FOSUserBundle's layout.html.twig так, чтобы он использовал базовый макет вашего приложения. Так как файл живёт в Resources/views/layout.html.twig в FOSUserBundle, вы можете создать ваш собственный файл в том же месте UserBundle. Symfony полностью проигнорирует файл, живущий в FOSUserBundle, и использует вместо него ваш файл.

То же самое касается файлов маршрутизации и некоторых других ресурсов.

Note

Переопределение ресурсов работает только когда вы ссылаетесь на них с помощью метода @FOSUserBundle/Resources/config/routing/security.xml. Вам нужно использовать шорткат @BundleName при ссылании на ресурсы, чтобы они могли быть успешно переопределены (кроме шаблонов, которые переопределяются другим способом, как объясняется в How to Override Templates from Third-Party Bundles).

Caution

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

Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.