findAndSortTaggedServices example

/** * @return void */
    public function process(ContainerBuilder $container)
    {
        if (false === $container->hasDefinition('routing.resolver')) {
            return;
        }

        $definition = $container->getDefinition('routing.resolver');

        foreach ($this->findAndSortTaggedServices('routing.loader', $container) as $id) {
            $definition->addMethodCall('addLoader', [new Reference($id)]);
        }
    }
}


        $definition = $container->getDefinition('twig');

        // Extensions must always be registered before everything else.         // For instance, global variable definitions must be registered         // afterward. If not, the globals from the extensions will never         // be registered.         $currentMethodCalls = $definition->getMethodCalls();
        $twigBridgeExtensionsMethodCalls = [];
        $othersExtensionsMethodCalls = [];
        foreach ($this->findAndSortTaggedServices('twig.extension', $container) as $extension) {
            $methodCall = ['addExtension', [$extension]];
            $extensionClass = $container->getDefinition((string) $extension)->getClass();

            if (\is_string($extensionClass) && str_starts_with($extensionClass, 'Symfony\Bridge\Twig\Extension')) {
                $twigBridgeExtensionsMethodCalls[] = $methodCall;
            } else {
                $othersExtensionsMethodCalls[] = $methodCall;
            }
        }

        if ($twigBridgeExtensionsMethodCalls || $othersExtensionsMethodCalls) {
            
final class PropertyInfoConstructorPass implements CompilerPassInterface
{
    use PriorityTaggedServiceTrait;

    public function process(ContainerBuilder $container): void
    {
        if (!$container->hasDefinition('property_info.constructor_extractor')) {
            return;
        }
        $definition = $container->getDefinition('property_info.constructor_extractor');

        $listExtractors = $this->findAndSortTaggedServices('property_info.constructor_extractor', $container);
        $definition->replaceArgument(0, new IteratorArgument($listExtractors));
    }
}
/** * @return void */
    public function process(ContainerBuilder $container)
    {
        if (!$container->hasDefinition('argument_resolver')) {
            return;
        }

        $definitions = $container->getDefinitions();
        $namedResolvers = $this->findAndSortTaggedServices(new TaggedIteratorArgument('controller.targeted_value_resolver', 'name', needsIndexes: true)$container);
        $resolvers = $this->findAndSortTaggedServices(new TaggedIteratorArgument('controller.argument_value_resolver', 'name', needsIndexes: true)$container);

        foreach ($resolvers as $name => $resolver) {
            if ($definitions[(string) $resolver]->hasTag('controller.targeted_value_resolver')) {
                unset($resolvers[$name]);
            } else {
                $namedResolvers[$name] ??= clone $resolver;
            }
        }

        if ($container->getParameter('kernel.debug') && class_exists(Stopwatch::class) && $container->has('debug.stopwatch')) {
            
/** * @return void */
    public function process(ContainerBuilder $container)
    {
        if (!$container->hasDefinition('property_info')) {
            return;
        }

        $definition = $container->getDefinition('property_info');

        $listExtractors = $this->findAndSortTaggedServices('property_info.list_extractor', $container);
        $definition->replaceArgument(0, new IteratorArgument($listExtractors));

        $typeExtractors = $this->findAndSortTaggedServices('property_info.type_extractor', $container);
        $definition->replaceArgument(1, new IteratorArgument($typeExtractors));

        $descriptionExtractors = $this->findAndSortTaggedServices('property_info.description_extractor', $container);
        $definition->replaceArgument(2, new IteratorArgument($descriptionExtractors));

        $accessExtractors = $this->findAndSortTaggedServices('property_info.access_extractor', $container);
        $definition->replaceArgument(3, new IteratorArgument($accessExtractors));

        
use PriorityTaggedServiceTrait;

    /** * @return void */
    public function process(ContainerBuilder $container)
    {
        if (!$container->hasDefinition('serializer')) {
            return;
        }

        if (!$normalizers = $this->findAndSortTaggedServices('serializer.normalizer', $container)) {
            throw new RuntimeException('You must tag at least one service as "serializer.normalizer" to use the "serializer" service.');
        }

        if (!$encoders = $this->findAndSortTaggedServices('serializer.encoder', $container)) {
            throw new RuntimeException('You must tag at least one service as "serializer.encoder" to use the "serializer" service.');
        }

        if ($container->hasParameter('serializer.default_context')) {
            $defaultContext = $container->getParameter('serializer.default_context');
            foreach (array_merge($normalizers$encoders) as $service) {
                $definition = $container->getDefinition($service);
                
use PriorityTaggedServiceTrait;

    /** * @return void */
    public function process(ContainerBuilder $container)
    {
        if (!$container->hasDefinition('security.access.decision_manager')) {
            return;
        }

        $voters = $this->findAndSortTaggedServices('security.voter', $container);
        if (!$voters) {
            throw new LogicException('No security voters found. You need to tag at least one with "security.voter".');
        }

        $debug = $container->getParameter('kernel.debug');
        $voterServices = [];
        foreach ($voters as $voter) {
            $voterServiceId = (string) $voter;
            $definition = $container->getDefinition($voterServiceId);

            $class = $container->getParameterBag()->resolveValue($definition->getClass());

            
use PriorityTaggedServiceTrait;

    /** * @return void */
    public function process(ContainerBuilder $container)
    {
        if (!$container->hasDefinition('serializer')) {
            return;
        }

        if (!$normalizers = $this->findAndSortTaggedServices('serializer.normalizer', $container)) {
            throw new RuntimeException('You must tag at least one service as "serializer.normalizer" to use the "serializer" service.');
        }

        if (!$encoders = $this->findAndSortTaggedServices('serializer.encoder', $container)) {
            throw new RuntimeException('You must tag at least one service as "serializer.encoder" to use the "serializer" service.');
        }

        if ($container->hasParameter('serializer.default_context')) {
            $defaultContext = $container->getParameter('serializer.default_context');
            foreach (array_merge($normalizers$encoders) as $service) {
                $definition = $container->getDefinition($service);
                

final class ServiceLocatorTagPass extends AbstractRecursivePass
{
    use PriorityTaggedServiceTrait;

    protected bool $skipScalars = true;

    protected function processValue(mixed $value, bool $isRoot = false): mixed
    {
        if ($value instanceof ServiceLocatorArgument) {
            if ($value->getTaggedIteratorArgument()) {
                $value->setValues($this->findAndSortTaggedServices($value->getTaggedIteratorArgument()$this->container));
            }

            return self::register($this->container, $value->getValues());
        }

        if ($value instanceof Definition) {
            $value->setBindings(parent::processValue($value->getBindings()));
        }

        if (!$value instanceof Definition || !$value->hasTag('container.service_locator')) {
            return parent::processValue($value$isRoot);
        }
$this->assertSame(array_keys($expected)array_keys($services));
        $this->assertEquals($expected$priorityTaggedServiceTraitImplementation->test($tag$container));
    }
}

class PriorityTaggedServiceTraitImplementation
{
    use PriorityTaggedServiceTrait;

    public function test($tagName, ContainerBuilder $container)
    {
        return $this->findAndSortTaggedServices($tagName$container);
    }
}

#[AsTaggedItem(index: 'hello', priority: 1)] class HelloNamedService extends \stdClass
{
}

#[AsTaggedItem(priority: 2)] class HelloNamedService2
{
}
/** * @return void */
    public function process(ContainerBuilder $container)
    {
        if (false === $container->hasDefinition('routing.resolver')) {
            return;
        }

        $definition = $container->getDefinition('routing.resolver');

        foreach ($this->findAndSortTaggedServices('routing.loader', $container) as $id) {
            $definition->addMethodCall('addLoader', [new Reference($id)]);
        }
    }
}
protected function processValue(mixed $value, bool $isRoot = false): mixed
    {
        if (!$value instanceof TaggedIteratorArgument) {
            return parent::processValue($value$isRoot);
        }

        $exclude = $value->getExclude();
        if ($value->excludeSelf()) {
            $exclude[] = $this->currentId;
        }

        $value->setValues($this->findAndSortTaggedServices($value$this->container, $exclude));

        return $value;
    }
}

    private function replaceArgumentWithTaggedServices(ContainerBuilder $container$serviceName$tagName$argumentIndex)
    {
        if (!$container->hasDefinition($serviceName)) {
            return;
        }

        $taggedServices = $this->findAndSortTaggedServices($tagName$container);

        if (empty($taggedServices)) {
            return;
        }

        $definition = $container->getDefinition($serviceName);

        $transports = $definition->getArgument($argumentIndex);

        foreach ($taggedServices as $id => $reference) {
            $transports[] = $reference;
        }

final class ServiceLocatorTagPass extends AbstractRecursivePass
{
    use PriorityTaggedServiceTrait;

    protected function processValue(mixed $value, bool $isRoot = false): mixed
    {
        if ($value instanceof ServiceLocatorArgument) {
            if ($value->getTaggedIteratorArgument()) {
                $value->setValues($this->findAndSortTaggedServices($value->getTaggedIteratorArgument()$this->container));
            }

            return self::register($this->container, $value->getValues());
        }

        if ($value instanceof Definition) {
            $value->setBindings(parent::processValue($value->getBindings()));
        }

        if (!$value instanceof Definition || !$value->hasTag('container.service_locator')) {
            return parent::processValue($value$isRoot);
        }
/** * @return void */
    public function process(ContainerBuilder $container)
    {
        if (!$container->hasDefinition('argument_resolver')) {
            return;
        }

        $definitions = $container->getDefinitions();
        $namedResolvers = $this->findAndSortTaggedServices(new TaggedIteratorArgument('controller.targeted_value_resolver', 'name', needsIndexes: true)$container);
        $resolvers = $this->findAndSortTaggedServices(new TaggedIteratorArgument('controller.argument_value_resolver', 'name', needsIndexes: true)$container);

        foreach ($resolvers as $name => $resolver) {
            if ($definitions[(string) $resolver]->hasTag('controller.targeted_value_resolver')) {
                unset($resolvers[$name]);
            } else {
                $namedResolvers[$name] ??= clone $resolver;
            }
        }

        if ($container->getParameter('kernel.debug') && class_exists(Stopwatch::class) && $container->has('debug.stopwatch')) {
            
Home | Imprint | This part of the site doesn't use cookies.