DEV Community

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

Posted on • Edited on

Failed at making tag values in a doctrine listener configurable

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 }
Enter fullscreen mode Exit fullscreen mode

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%' }
Enter fullscreen mode Exit fullscreen mode

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;
    }
}
Enter fullscreen mode Exit fullscreen mode

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');
    }
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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:

Top comments (0)