Как переопределить любую часть пакета

При использовании сторонних пакетов вы можете захотеть настроить или переопределить некоторые из их функций. Этот документ описывает способы переопределения наиболее распространённых функций пакета.

Tip

Механизм переопределения пакета означает, что вы не можете использовать физические пути для ссылания на источники пакета (например, __DIR__/config/services.xml). Всегда используйте логические пути в ваших пакетах (например, @FooBundle/Resources/config/services.xml) и вызывайте метод locateResource(), чтобы преобразовывать их в физические пути при необходимости.

Шаблоны

Смотрите How to Override Templates from Third-Party Bundles.

Маршрутизация

Маршрутизация в Symfony никогда не импортируется автоматически. Если вы хотите включить маршруты из любого пакета, то они должны быть импортированы вручную откуда-то из вашего приложения (например, config/routes.yaml).

Самый простой способ "переопределить" маршрутизацию пакета - не импортировать её в принципе. Вместо импортирования маршрутизации стороннего пакета, просто скопируйте файл маршрутизации в ваше приложение, измените его и импортируйте.

Контроллеры

Если контроллер является сервисом, смотрите следующий раздел о том, как пеоепределить его. В обратном случае, определите новый маршрут + контроллер с одним путём, связанным с контроллером, который вы хотите переопределить (и убедитесь, что новый маршрут загружается до маршрута пакета).

Сервисы и конфигурация

Если вы хотите изменить определения сервисов другого пакета, вы можете испльзовать пропуск компилятора, чтобыизменить класс сервиса или чтобы изменить вызовы метода. В следующем примере, реализующий класс для original-service-id изменён на App\YourService:

1
.. code-block:: diff

// src/Kernel.php namespace App;

// ... + use AppServiceYourService; + use SymfonyComponentDependencyInjectionContainerBuilder; + use SymfonyComponentDependencyInjectionCompilerCompilerPassInterface;

class Kernel extends BaseKernel implements CompilerPassInterface { + public function process(ContainerBuilder $container) + { + $definition = $container->findDefinition('original-service-id'); + $definition->setClass(YourService::class); + } }

Чтобы узнать больше о пропусках компилятора, см. How to Work with Compiler Passes.

Сущности и их отображение

В связи с особенностями работы Doctrine, невозможно переопределить отображение сущностей пакета. Однако, если пакет предоставляет отображённый суперкласс (как, например, сущность User в FOSUserBundle), то можно переопределить атрибуты и ассоциации. Узнайте больше об этой функции и её ограничениях в документации Doctrine.

Формы

Существующие типы форм могут быть изменены путём определения расширений типа формы.

Метаданные валидации

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

Чтобы обойти это, сторонний пает должен иметь конфигурацию для групп валидации. Например, FOSUserBundle имеет такую конфигурацию. Чтобы создать вашу собственную валидацию, добавьте ограничения к новой группе валидации:

  • YAML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    # config/validator/validation.yaml
    FOS\UserBundle\Model\User:
        properties:
            plainPassword:
                - NotBlank:
                    groups: [AcmeValidation]
                - Length:
                    min: 6
                    minMessage: fos_user.password.short
                    groups: [AcmeValidation]
    
  • XML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    <!-- config/validator/validation.xml -->
    <?xml version="1.0" encoding="UTF-8" ?>
    <constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping
            http://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
    
        <class name="FOS\UserBundle\Model\User">
            <property name="plainPassword">
                <constraint name="NotBlank">
                    <option name="groups">
                        <value>AcmeValidation</value>
                    </option>
                </constraint>
    
                <constraint name="Length">
                    <option name="min">6</option>
                    <option name="minMessage">fos_user.password.short</option>
                    <option name="groups">
                        <value>AcmeValidation</value>
                    </option>
                </constraint>
            </property>
        </class>
    </constraint-mapping>
    

Теперь, обновите конфигурацию FOSUserBundle так, чтобы он использовал ваши группы валидации вместо исходных.

Преводы

Переводы не связаны с пакетами, но связаны с доменами. Это означает, что вы можете переопределить переводы из любого файла перевода, если он находится на правильном домене.

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