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

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

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

Шаблоны

Чтобы получить информацию о переопределнии шаболнов, см.

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

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

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

Контроллеры

Предположив, что вовлечённый сторонний пакет использует несервисные контроллеры (а так происходит почти всегда), вы можете просто переопределить контроллеры с помощью наследования пакетов. Чтобы узнать больше, см. How to Use Bundle Inheritance to Override Parts of a Bundle. Если контроллер является сервисом, смотрите следующий раздел о том, как пеоепределить его.

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

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// src/Acme/DemoBundle/DependencyInjection/Compiler/OverrideServiceCompilerPass.php
namespace Acme\DemoBundle\DependencyInjection\Compiler;

use Acme\DemoBundle\YourService;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class OverrideServiceCompilerPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container)
    {
        $definition = $container->getDefinition('original-service-id');
        $definition->setClass(YourService::class);
    }
}

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

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

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

Формы

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

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

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

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

  • YAML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    # src/Acme/UserBundle/Resources/config/validation.yml
    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
    <!-- src/Acme/UserBundle/Resources/config/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 так, чтобы он использовал ваши группы валидации вместо исходных.

Преводы

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

Caution

Файлы перевода не знают о наследовании пакетов. Если вы хотите переопределить переводы из родительского или любого другого пакета, убедитесь, что пакет, содержащий ваши переводы загружен после пакета, переводы которого вы переопределете. Это делаетс в AppKernel.

Наконец, переводы, находящиеся в app/Resources/translations будут переопределять все другие переводы, так как эти файлы всегда загружаются последими.

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