How to reuse code with symfony 5 bundles? Part 5. Configuration

Let's talk about how to stop copy-paste between projects and transfer the code to a re-usable symfony 5 plug-in bundle. A series of articles summarizing my experience with bundles will lead in practice from creating a minimal bundle and refactoring a demo application to tests and the bundle release cycle.


In a previous article, we talked about how to extend the functionality of a bundle in a host application using tags. In this article, we add the flexibility bundle: create a configuration file and define several parameters.


  • DI container parameters and their redefinition
  • Bundle configuration file
  • Work with configuration


If you are not completing the tutorial sequentially, then download the application from the repository and switch to the 4-extend branch .


Instructions for installing and starting the project in a file README.md. You will find the final version of the code for this article in the 5-configuration branch .


DI container parameters and their redefinition


There is already a configuration file inside the bundle config/services.yaml, where the configuration of the services of the DI container is determined. There you can define the parameters.


, -.

, . , soft-delete ( , «»). , .


config/services.yaml :


parameters:
    bravik.calendar.enable_soft_delete: true

venodor.package.parameter. snake_case : . , .


EditorController . $enableSoftDelete, false:


public function __construct(
    EventRepository $eventRepository,
    bool $enableSoftDelete = false
) { 
    //... 
}

, services.yaml :


bravik\CalendarBundle\Controller\EditorController:
    arguments:
        $enableSoftDelete: '%bravik.calendar.enable_soft_delete%'

, -   «».  , ,     « »,   .  false,   ,   «-».


services.yaml -. , , !


, :


  1. -, . , - , «  ». , . , ,
  2. -, .

.



: , , , , .

, . Symfony .


config/packages/, , . . , .


.


load() DependencyInjection/CalendarExtension.php :


public function load(array $configs, ContainerBuilder $container) {}

, ContainerBuilder $configs. dd($configs) : .


config/packages/ calendar.yaml:


calendar:                     # extension key
  enable_soft_delete: false

, Symfony config/packages/ . CalendarExtension::load(), Extension-, Extension snake_case. , .


, $configs:


^ array:1 [▼
  0 => array:1 [▼
    "enable_soft_delete" => false
  ]
]

PHP , - . ?


, . packages test, prod dev .


, . , , framework , $configs. .


(extension key) Symfony , load(). .


. 1 , dd($configs) .


:


, ? , .


CalendarExtension Configuration:


<?php
namespace bravik\CalendarBundle\DependencyInjection;

use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;

class Configuration implements ConfigurationInterface
{
    public function getConfigTreeBuilder()
    {
        $treeBuilder = new TreeBuilder('calendar');

        $treeBuilder->getRootNode()
            ->children()
                ->booleanNode('enable_soft_delete')->end()
            ->end()
        ;

        return $treeBuilder;
    }
}

TreeBuilder, , enable_soft_delete boolean.


TreeBuilder , , . , , .

, CalendarExtension::load() :


public function load(array $configs, ContainerBuilder $container)
{
    //...
    $configuration = new Configuration();
    $config = $this->processConfiguration($configuration, $configs);
}

processConfiguration() , Configuration, , , $config.


$config, .


, :


$container->setParameter(
    'bravik.calendar.enable_soft_delete',
    $config['enable_soft_delete']
);

, bravik.calendar.enable_soft_delete config/service.yaml.


   , «»   .


services.yaml bravik.calendar.enable_soft_delete. enable_soft_delete :


//$container->setParameter(
//    'bravik.calendar.enable_soft_delete',
//    $config['enable_soft_delete']
//);

$definition = $container->getDefinition(EditorController::class);
$definition->setArguments([
  '$enableSoftDelete' => $config['enable_soft_delete'],
]);


, , .


true/false :


Exception: Invalid type for path "calendar.enable_soft_delete". Expected boolean, but got string.

, ,


Exception: Undefined index: enable_soft_delete

: . . Configuration.


$treeBuilder->getRootNode()
    ->children()
        ->booleanNode('enable_soft_delete')
            ->defaultValue(false)
//            ->defaultFalse() //    booleanNode()
        ->end()
    ->end()
;

, , . :


$treeBuilder->getRootNode()
    ->children()
        ->booleanNode('enable_soft_delete')
            ->isRequired()
        ->end()
    ->end()
;

, . , deprecated.


. Symfony bin/console config:dump calendar, .


$treeBuilder->getRootNode()
    ->children()
        ->booleanNode('enable_soft_delete')
            ->isRequired()
            ->setDeprecated()
            ->info('Enables soft delete mode for articles. Articles would be marked as `archived` instead of deletion')
        ->end()
    ->end()
;

:


calendar:
    limits:
      per_day: 10
      per_month: 100

$treeBuilder->getRootNode()
    ->children()
        ->arrayNode('limits')
            ->addDefaultsIfNotSet()
            ->children()
                ->integerNode('per_day')
                    ->defaultValue(10)
                    ->validate()
                        ->ifTrue(function ($v) { return $v <= 0; })
                        ->thenInvalid('Number must be positive')
                    ->end()
                ->end()
                ->integerNode('per_month')
                    ->defaultValue(100)
                    ->validate()
                        ->ifTrue(function ($v) { return $v <= 0; })
                        ->thenInvalid('Number must be positive')
                    ->end()
                ->end()
            ->end()
        ->end()
    ->end()
    ;

. : .


Symfony , .

: .


c , . .


:


calendar:
    available_locales:
          locales:
              - { code: 'en', label: 'English' }
              - { code: 'ru', label: '' }

$treeBuilder->getRootNode()
    ->children()
        ->arrayNode('locales')
            ->addDefaultChildrenIfNoneSet()
            ->arrayPrototype()
                ->children()
                    ->scalarNode('code')
                        ->defaultValue('ru')
                    ->end()
                    ->scalarNode('label')
                        ->defaultValue('')
                    ->end()
                ->end()
            ->end()
        ->end()
    ->end()
;

-, .


. .



, , Symfony .


, — . , .


5-configuration.


Symfony .


:


Part 1. The minimum bundle
Part 2. We take out the code and templates in the bundle
Part 3. Integration of the bundle with the host: templates, styles, JS
Part 4. Interface for expanding the bundle
Part 5. Parameters and configuration
Part 6. Testing, microapplication inside the bundle
Part 7 Release cycle, installation and update


All Articles