Security update for permissions_by_term
[yaffs-website] / vendor / behat / behat / src / Behat / Behat / HelperContainer / Call / Filter / ServicesResolver.php
1 <?php
2
3 /*
4  * This file is part of the Behat.
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\Behat\HelperContainer\Call\Filter;
12
13 use Behat\Behat\Definition\Definition;
14 use Behat\Behat\HelperContainer\Environment\ServiceContainerEnvironment;
15 use Behat\Behat\Definition\Call\DefinitionCall;
16 use Behat\Behat\HelperContainer\ArgumentAutowirer;
17 use Behat\Behat\HelperContainer\Exception\UnsupportedCallException;
18 use Behat\Behat\Transformation\Call\TransformationCall;
19 use Behat\Behat\Transformation\Transformation;
20 use Behat\Testwork\Call\Call;
21 use Behat\Testwork\Call\Filter\CallFilter;
22 use Behat\Testwork\Environment\Call\EnvironmentCall;
23 use Psr\Container\ContainerExceptionInterface;
24 use Psr\Container\ContainerInterface;
25
26 /**
27  * Dynamically resolves call arguments using the service container.
28  *
29  * @author Konstantin Kudryashov <ever.zet@gmail.com>
30  */
31 final class ServicesResolver implements CallFilter
32 {
33     /**
34      * {@inheritdoc}
35      */
36     public function supportsCall(Call $call)
37     {
38         return ($call instanceof DefinitionCall || $call instanceof TransformationCall)
39             && $call->getEnvironment() instanceof ServiceContainerEnvironment;
40     }
41
42     /**
43      * Filters a call and returns a new one.
44      *
45      * @param Call $call
46      *
47      * @return Call
48      *
49      * @throws UnsupportedCallException
50      * @throws ContainerExceptionInterface
51      */
52     public function filterCall(Call $call)
53     {
54         if ($container = $this->getContainer($call)) {
55             $autowirer = new ArgumentAutowirer($container);
56             $newArguments = $autowirer->autowireArguments($call->getCallee()->getReflection(), $call->getArguments());
57
58             return $this->repackageCallIfNewArguments($call, $newArguments);
59         }
60
61         return $call;
62     }
63
64     /**
65      * Gets container from the call.
66      *
67      * @param Call $call
68      *
69      * @return null|ContainerInterface
70      *
71      * @throws UnsupportedCallException if given call is not EnvironmentCall or environment is not ServiceContainerEnvironment
72      */
73     private function getContainer(Call $call)
74     {
75         if (!$call instanceof EnvironmentCall) {
76             throw new UnsupportedCallException(sprintf(
77                 'ServicesResolver can not filter `%s` call.',
78                 get_class($call)
79             ), $call);
80         }
81
82         $environment = $call->getEnvironment();
83
84         if (!$environment instanceof ServiceContainerEnvironment) {
85             throw new UnsupportedCallException(sprintf(
86                 'ServicesResolver can not filter `%s` call.',
87                 get_class($call)
88             ), $call);
89         }
90
91         return $environment->getServiceContainer();
92     }
93
94     /**
95      * Repackages old calls with new arguments, but only if two differ.
96      *
97      * @param Call $call
98      * @param array $arguments
99      *
100      * @return Call
101      *
102      * @throws UnsupportedCallException if given call is not DefinitionCall or TransformationCall
103      */
104     private function repackageCallIfNewArguments(Call $call, array $arguments)
105     {
106         if ($arguments === $call->getArguments()) {
107             return $call;
108         }
109
110         return $this->repackageCallWithNewArguments($call, $arguments);
111     }
112
113     /**
114      * Repackages old calls with new arguments.
115      *
116      * @param Call  $call
117      * @param array $newArguments
118      *
119      * @return DefinitionCall|TransformationCall
120      *
121      * @throws UnsupportedCallException
122      */
123     private function repackageCallWithNewArguments(Call $call, array $newArguments)
124     {
125         if ($call instanceof DefinitionCall) {
126             return $this->repackageDefinitionCall($call, $newArguments);
127         }
128
129         if ($call instanceof TransformationCall) {
130             return $this->repackageTransformationCall($call, $newArguments);
131         }
132
133         throw new UnsupportedCallException(
134             sprintf(
135                 'ServicesResolver can not filter `%s` call.',
136                 get_class($call)
137             ), $call
138         );
139     }
140
141     /**
142      * Repackages definition call with new arguments.
143      *
144      * @param DefinitionCall $call
145      * @param array $newArguments
146      *
147      * @return DefinitionCall
148      *
149      * @throws UnsupportedCallException
150      */
151     private function repackageDefinitionCall(DefinitionCall $call, array $newArguments)
152     {
153         $definition = $call->getCallee();
154
155         if (!$definition instanceof Definition) {
156             throw new UnsupportedCallException(
157                 sprintf(
158                     'Something is wrong in callee associated with `%s` call.',
159                     get_class($call)
160                 ), $call
161             );
162         }
163
164         return new DefinitionCall(
165             $call->getEnvironment(),
166             $call->getFeature(),
167             $call->getStep(),
168             $definition,
169             $newArguments,
170             $call->getErrorReportingLevel()
171         );
172     }
173
174     /**
175      * Repackages transformation call with new arguments.
176      *
177      * @param TransformationCall $call
178      * @param array $newArguments
179      *
180      * @return TransformationCall
181      *
182      * @throws UnsupportedCallException
183      */
184     private function repackageTransformationCall(TransformationCall $call, array $newArguments)
185     {
186         $transformation = $call->getCallee();
187
188         if (!$transformation instanceof Transformation) {
189             throw new UnsupportedCallException(
190                 sprintf(
191                     'Something is wrong in callee associated with `%s` call.',
192                     get_class($call)
193                 ), $call
194             );
195         }
196
197         return new TransformationCall(
198             $call->getEnvironment(),
199             $call->getDefinition(),
200             $transformation,
201             $newArguments
202         );
203     }
204 }