DEV Community

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

Posted on • Edited on

2 2

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:

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read more →

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more