Security update for permissions_by_term
[yaffs-website] / vendor / behat / behat / src / Behat / Testwork / ServiceContainer / ServiceProcessor.php
1 <?php
2
3 /*
4  * This file is part of the Behat Testwork.
5  * (c) Konstantin Kudryashov <ever.zet@gmail.com>
6  *
7  * For the full copyright and license information, please view the LICENSE
8  * file that was distributed with this source code.
9  */
10
11 namespace Behat\Testwork\ServiceContainer;
12
13 use Symfony\Component\DependencyInjection\Alias;
14 use Symfony\Component\DependencyInjection\ContainerBuilder;
15 use Symfony\Component\DependencyInjection\Reference;
16
17 /**
18  * Provides additional service finding functionality.
19  *
20  * @author Konstantin Kudryashov <ever.zet@gmail.com>
21  * @author Christophe Coevoet <stof@notk.org>
22  */
23 final class ServiceProcessor
24 {
25     /**
26      * Finds and sorts (by priority) service references by provided tag.
27      *
28      * @param ContainerBuilder $container
29      * @param string           $tag
30      *
31      * @return Reference[]
32      */
33     public function findAndSortTaggedServices(ContainerBuilder $container, $tag)
34     {
35         $serviceTags = array();
36         foreach ($container->findTaggedServiceIds($tag) as $id => $tags) {
37             $firstTags = current($tags);
38
39             $serviceTags[] = array_merge(array('priority' => 0), $firstTags, array('id' => $id));
40         }
41
42         usort($serviceTags, function ($tag1, $tag2) { return $tag2['priority'] - $tag1['priority']; });
43         $serviceReferences = array_map(function ($tag) { return new Reference($tag['id']); }, $serviceTags);
44
45         return $serviceReferences;
46     }
47
48     /**
49      * Processes wrappers of a service, found by provided tag.
50      *
51      * The wrappers are applied by descending priority.
52      * The first argument of the wrapper service receives the inner service.
53      *
54      * @param ContainerBuilder $container
55      * @param string           $target     The id of the service being decorated
56      * @param string           $wrapperTag The tag used by wrappers
57      */
58     public function processWrapperServices(ContainerBuilder $container, $target, $wrapperTag)
59     {
60         $references = $this->findAndSortTaggedServices($container, $wrapperTag);
61
62         foreach ($references as $reference) {
63             $id = (string) $reference;
64             $renamedId = $id . '.inner';
65
66             // This logic is based on Symfony\Component\DependencyInjection\Compiler\DecoratorServicePass
67
68             // we create a new alias/service for the service we are replacing
69             // to be able to reference it in the new one
70             if ($container->hasAlias($target)) {
71                 $alias = $container->getAlias($target);
72                 $public = $alias->isPublic();
73                 $container->setAlias($renamedId, new Alias((string) $alias, false));
74             } else {
75                 $definition = $container->getDefinition($target);
76                 $public = $definition->isPublic();
77                 $definition->setPublic(false);
78                 $container->setDefinition($renamedId, $definition);
79             }
80
81             $container->setAlias($target, new Alias($id, $public));
82             // Replace the reference so that users don't need to bother about the way the inner service is referenced
83             $wrappingService = $container->getDefinition($id);
84             $wrappingService->replaceArgument(0, new Reference($renamedId));
85         }
86     }
87 }