loading...
Cover image for Failed at making tag values in a doctrine listener configurable

Failed at making tag values in a doctrine listener configurable

c33s profile image Julian Updated on ・2 min read

my goal was to make a bundle with a configurable doctrine listener to allow the user to configure the connection and the priority for a postLoad event.

i had the following listener code service.yaml:

C33s\Doctrine\Listener\InjectFeatureManagerListener:
    tags:
        - { name: doctrine.event_listener, event: postLoad, connection: default, priority: 0 }

and i changed it to:


C33s\Doctrine\Listener\InjectFeatureManagerListener:
    tags:
        - { name: doctrine.event_listener, event: postLoad, connection: '%c33s_doctrine_extra.flagception.connection%', priority: '%c33s_doctrine_extra.flagception.priority%' }

Configuration.php

<?php
class Configuration implements ConfigurationInterface
{
    /**
     * {@inheritdoc}
     */
    public function getConfigTreeBuilder()
    {
        $treeBuilder = new TreeBuilder('c33s_doctrine_extra');

        $treeBuilder->getRootNode()
            ->addDefaultsIfNotSet()
            ->children()
                ->arrayNode('flagception')
                    ->canBeEnabled()
                    ->children()
                        ->scalarNode('connection')
                            ->defaultValue('default')
                        ->end()
                        ->integerNode('priority')
                            ->defaultValue(0)
                            ->info('to the same event (default priority = 0; higher numbers = listener is run earlier)')
                        ->end()
                    ->end()
                ->end()
            ->end()
        ;

        return $treeBuilder;
    }
}

C33sDoctrineExtraExtension.php

<?php
class C33sDoctrineExtraExtension extends Extension
{
    /**
     * {@inheritdoc}
     */
    public function load(array $configs, ContainerBuilder $container)
    {
        $configuration = new Configuration();
        $config = $this->processConfiguration($configuration, $configs);

        $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));

        if (true === $config['flagception']['enabled']) {
            $container->setParameter('c33s_doctrine_extra.flagception.connection', $config['flagception']['connection']);
            $container->setParameter('c33s_doctrine_extra.flagception.priority', $config['flagception']['priority']);
            $loader->load('entity_feature_manager_injector.yaml');
        }
//        $loader->load('services.yaml');
    }
}

which failed with:

Fatal error: Uncaught Symfony\Component\Debug\Exception\FatalThrowableError: Cannot unpack array with string keys in ...\vendor\symfony\doctrine-bridge\DependencyInjection\CompilerPass\RegisterEventListenersAndSubscribersPass.php on line 144

Symfony\Component\Debug\Exception\FatalThrowableError: Cannot unpack array with string keys in ...\vendor\symfony\doctrine-bridge\DependencyInjection\CompilerPass\RegisterEventListenersAndSubscribersPass.php on line 144

Call Stack:
    2.3161   24377048   1. Symfony\Component\Debug\ErrorHandler->handleException() ...\vendor\symfony\debug\ErrorHandler.php:0

digging into RegisterEventListenersAndSubscribersPass showed me that the parameters aren't resolved yet.

this is because the doctrines compiler pass RegisterEventListenersAndSubscribersPass which is instantiated in DoctrineBundle is instantiated with PassConfig::TYPE_BEFORE_OPTIMIZATION pass and in Symfony\Component\DependencyInjection\Compiler\PassConfig we can see, that the ResolveParameterPlaceHoldersPass is a PassConfig::TYPE_OPTIMIZE pass. which is executed after RegisterEventListenersAndSubscribersPass.

so no easy configureable doctrine listeners -.-

links:

Posted on by:

c33s profile

Julian

@c33s

see https://dev.to/c33s/comment/3eck

Discussion

markdown guide