<?php
namespace Knp\Bundle\MenuBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Reference;
/**
* This compiler pass registers the voters in the Matcher.
*
* @author Christophe Coevoet <stof@notk.org>
*
* @internal
*/
class AddVotersPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
if (!$container->hasDefinition('knp_menu.matcher')) {
return;
}
$definition = $container->getDefinition('knp_menu.matcher');
$listener = $container->getDefinition('knp_menu.listener.voters');
$hasRequestAwareVoter = false;
$voters = [];
foreach ($container->findTaggedServiceIds('knp_menu.voter') as $id => $tags) {
// Process only the first tag. Registering the same voter multiple time
// does not make any sense, and this allows user to overwrite the tag added
// by the autoconfiguration to change the priority (autoconfigured tags are
// always added at the end of the list).
$tag = $tags[0];
$priority = isset($tag['priority']) ? (int) $tag['priority'] : 0;
$voters[$priority][] = new Reference($id);
if (isset($tag['request']) && $tag['request']) {
@trigger_error('Using the "request" attribute of the "knp_menu.voter" tag is deprecated since version 2.2. Inject the RequestStack in the voter instead.', E_USER_DEPRECATED);
$hasRequestAwareVoter = true;
$listener->addMethodCall('addVoter', [new Reference($id)]);
}
}
if (!$hasRequestAwareVoter) {
$container->removeDefinition('knp_menu.listener.voters');
}
if (empty($voters)) {
return;
}
krsort($voters);
$sortedVoters = \call_user_func_array('array_merge', $voters);
if (class_exists(IteratorArgument::class)) {
$definition->replaceArgument(0, new IteratorArgument($sortedVoters));
} else {
// BC layer for Symfony DI < 3.3
$definition->replaceArgument(0, $sortedVoters);
}
}
}