Новое в Symfony 6.1: Более простое расширение и настройка бандлов
15487

Новое в Symfony 6.1: Более простое расширение и настройка бандлов


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

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

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

Рассмотрим бандл Foo, который определяет следующий основной класс:

namespace Acme\Bundle\FooBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;

class FooBundle extends Bundle
{
}

Сначала нужно изменить его базовый класс на новый AbstractBundle:

// ...
use Symfony\Component\HttpKernel\Bundle\AbstractBundle;

class FooBundle extends AbstractBundle
{
}

Теперь вы хотите определить семантическую конфигурацию для этой связки? Забудьте о классе Configuration, объекте TreeBuilder, "псевдониме расширения" и т.д. Просто определите метод configure() в классе вашего бандла:

class FooBundle extends AbstractBundle
{
    // ...

    public function configure(DefinitionConfigurator $definition): void
      {
        // loads config definition from a file
        $definition->import('../config/definition.php');

        // loads config definition from multiple files (when it's too long you can split it)
        $definition->import('../config/definition/*.php');

        // if the configuration is short, consider adding it in this class
        $definition->rootNode()
            ->children()
                ->scalarNode('foo')->defaultValue('bar')->end()
            ->end()
        ;
    }
}

Наконец, если вы хотите настроить расширение вашего бандла или добавить параметры конфигурации в приложении, вам больше не нужно определять класс Extension, использовать XmlFileLoader и FileLocator для загрузки файлов конфигурации и т.д. Определите методы loadExtension() и/или prependExtension() в вашем бандле и все:

class FooBundle extends AbstractBundle
{
    // ...

    // $config is the bundle Configuration that you usually process in
    // ExtensionInterface::load() but already merged and processed
    public function loadExtension(array $config, ContainerConfigurator $container, ContainerBuilder $builder): void
      {
        $container->parameters()->set('foo', $config['foo']);
        $container->import('../config/services.php');

        if ('bar' === $config['foo']) {
            $container->services()->set(Parser::class);
        }
    }

    public function prependExtension(ContainerConfigurator $container, ContainerBuilder $builder): void
      {
        // prepend some config option
        $builder->prependExtensionConfig('framework', [
            'cache' => ['prefix_seed' => 'foo/bar'],
        ]);

        // append some config option
        $container->extension('framework', [
            'cache' => ['prefix_seed' => 'foo/bar'],
        ])

        // append options defined in some file (using any config format)
        $container->import('../config/packages/cache.php');
    }
}

Мы в восторге от этой новой возможности! Мы надеемся, что она понравится и вам, и вы начнете использовать ее сразу же после обновления до Symfony 6.1.