0
votes

I was looking for an answer but i havent find anything helpful..

I asked on symfony github but they told me to write here.. https://github.com/symfony/symfony/issues/28650

I am writing a simple symfony bundle, but I have a problem with changing default configurations. I mean that I want to use yaml translations (not xliff), yaml doctrine mappings (not annotations), yaml validation (not annotations), etc. (i know that yaml in doctrine is deprecated)

Is there any possibility to change this configuration inside a bundle? I want my bundles to be self configured, I dont want to configure doctrine, translations, etc inside my main app.

Thanks for help

1

1 Answers

3
votes

You can define default configuration in Symfony via Extension Classes also take a look this Symfony Bundle Configuration guide, it's explains a lot about bundle configuration. Default configurations can be for doctrine, translations or anything else you can configure in application level. Even modifying other bundles configurations are possible with Prepend Extension

Config component is responsible manage this configuration rules, you can learn more about from Config Component and Defining and Processing Configuration Values pages in documentation.

FOSOAuthServerBundle is example for Doctrine default configuration.
They prefer XML but this is a format decision, configuration logic is same for XML, YAML or PHP.

msgphp/user-bundle configuration is an other example for configuration via PHP files.

Let's speak in code, this is an example for YAML configuration with doctrine entity and simple config array. First, create Configuration class provides default configuration rules for our bundle.

// src/Acme/HelloBundle/DependencyInjection/Configuration.php
namespace Acme\HelloBundle\DependencyInjection;

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

class Configuration implements ConfigurationInterface
{
    public function getConfigTreeBuilder()
    {
        $treeBuilder = new TreeBuilder();
        $rootNode = $treeBuilder->root('acme_hello');

        $rootNode
            ->children()
                ->arrayNode('simple_array')
                    ->children()
                        ->scalarNode('foo')->end()
                        ->scalarNode('bar')->end()
                    ->end()
                ->end()
                ->arrayNode('doctrine')
                    ->children()
                        ->arrayNode('entity')
                            ->children()
                                ->scalarNode('class')->isRequired()->cannotBeEmpty()->end()
                            ->end()
                        ->end()
                        ->arrayNode('manager')
                            ->children()
                                ->scalarNode('class')->defaultValue('Acme\\HelloBundle\\Entity\\Manager\\EntryManager')->end()
                            ->end()
                        ->end()
                     ->end()
                 ->end()
            ->end()
        ;

        return $treeBuilder;
    }
}

Second, prepare our bundle's extension class for load this configurations.

//src/Acme/HelloBundle/DependencyInjection/AcmeHelloExtension.php
namespace Acme\HelloBundle\DependencyInjection;

use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\Extension;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;

class AcmeHelloExtension extends Extension
{
    public function load(array $configs, ContainerBuilder $container)
    {
        $configuration = new Configuration();
        $config = $this->processConfiguration($configuration, $configs);

        $loader = new YamlFileLoader(
            $container,
            new FileLocator(__DIR__.'/../Resources/config')
        );
        $loader->load('acme_hello.yaml');
        $loader->load('services.yaml');

        // you now have these 2 config keys
        // $config['simple_array'] and $config['doctrine']
        // $container->getDefinition('acme_hello.simple_array.foo');
    }
}

Last, create default YAML definitions and register our entry manager to container.

//src/Acme/HelloBundle/Resources/config/acme_hello.yaml
acme_hello:
    simple_array:
        foo: 'hello'
        bar: 'world'
    doctrine:
        entity:
            class: 'Acme\HelloBundle\Entity\Entry'
        manager:
            class: 'Acme\HelloBundle\Entity\Manager\EntryManager'

//src/Acme/HelloBundle/Resources/config/services.yaml
services:
    acme_hello.entry_manager:
        class:     '%acme_hello.doctrine.manager.class%'
        arguments: [ '@doctrine.orm.entity_manager', '%acme_hello.doctrine.entity.class%' ]

Also we can override default configuration in application level.

//config/packages/acme_hello.yaml
acme_hello:
    simple_array:
        foo: 'world'
        bar: 'hello'