Added the Search API Synonym module to deal specifically with licence and license...
[yaffs-website] / vendor / symfony / dependency-injection / ParameterBag / ParameterBag.php
1 <?php
2
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 namespace Symfony\Component\DependencyInjection\ParameterBag;
13
14 use Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException;
15 use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
16 use Symfony\Component\DependencyInjection\Exception\RuntimeException;
17
18 /**
19  * Holds parameters.
20  *
21  * @author Fabien Potencier <fabien@symfony.com>
22  */
23 class ParameterBag implements ParameterBagInterface
24 {
25     protected $parameters = array();
26     protected $resolved = false;
27
28     private $normalizedNames = array();
29
30     /**
31      * @param array $parameters An array of parameters
32      */
33     public function __construct(array $parameters = array())
34     {
35         $this->add($parameters);
36     }
37
38     /**
39      * Clears all parameters.
40      */
41     public function clear()
42     {
43         $this->parameters = array();
44     }
45
46     /**
47      * Adds parameters to the service container parameters.
48      *
49      * @param array $parameters An array of parameters
50      */
51     public function add(array $parameters)
52     {
53         foreach ($parameters as $key => $value) {
54             $this->set($key, $value);
55         }
56     }
57
58     /**
59      * {@inheritdoc}
60      */
61     public function all()
62     {
63         return $this->parameters;
64     }
65
66     /**
67      * {@inheritdoc}
68      */
69     public function get($name)
70     {
71         $name = $this->normalizeName($name);
72
73         if (!array_key_exists($name, $this->parameters)) {
74             if (!$name) {
75                 throw new ParameterNotFoundException($name);
76             }
77
78             $alternatives = array();
79             foreach ($this->parameters as $key => $parameterValue) {
80                 $lev = levenshtein($name, $key);
81                 if ($lev <= \strlen($name) / 3 || false !== strpos($key, $name)) {
82                     $alternatives[] = $key;
83                 }
84             }
85
86             $nonNestedAlternative = null;
87             if (!\count($alternatives) && false !== strpos($name, '.')) {
88                 $namePartsLength = array_map('strlen', explode('.', $name));
89                 $key = substr($name, 0, -1 * (1 + array_pop($namePartsLength)));
90                 while (\count($namePartsLength)) {
91                     if ($this->has($key)) {
92                         if (\is_array($this->get($key))) {
93                             $nonNestedAlternative = $key;
94                         }
95                         break;
96                     }
97
98                     $key = substr($key, 0, -1 * (1 + array_pop($namePartsLength)));
99                 }
100             }
101
102             throw new ParameterNotFoundException($name, null, null, null, $alternatives, $nonNestedAlternative);
103         }
104
105         return $this->parameters[$name];
106     }
107
108     /**
109      * Sets a service container parameter.
110      *
111      * @param string $name  The parameter name
112      * @param mixed  $value The parameter value
113      */
114     public function set($name, $value)
115     {
116         $this->parameters[$this->normalizeName($name)] = $value;
117     }
118
119     /**
120      * {@inheritdoc}
121      */
122     public function has($name)
123     {
124         return array_key_exists($this->normalizeName($name), $this->parameters);
125     }
126
127     /**
128      * Removes a parameter.
129      *
130      * @param string $name The parameter name
131      */
132     public function remove($name)
133     {
134         unset($this->parameters[$this->normalizeName($name)]);
135     }
136
137     /**
138      * {@inheritdoc}
139      */
140     public function resolve()
141     {
142         if ($this->resolved) {
143             return;
144         }
145
146         $parameters = array();
147         foreach ($this->parameters as $key => $value) {
148             try {
149                 $value = $this->resolveValue($value);
150                 $parameters[$key] = $this->unescapeValue($value);
151             } catch (ParameterNotFoundException $e) {
152                 $e->setSourceKey($key);
153
154                 throw $e;
155             }
156         }
157
158         $this->parameters = $parameters;
159         $this->resolved = true;
160     }
161
162     /**
163      * Replaces parameter placeholders (%name%) by their values.
164      *
165      * @param mixed $value     A value
166      * @param array $resolving An array of keys that are being resolved (used internally to detect circular references)
167      *
168      * @return mixed The resolved value
169      *
170      * @throws ParameterNotFoundException          if a placeholder references a parameter that does not exist
171      * @throws ParameterCircularReferenceException if a circular reference if detected
172      * @throws RuntimeException                    when a given parameter has a type problem
173      */
174     public function resolveValue($value, array $resolving = array())
175     {
176         if (\is_array($value)) {
177             $args = array();
178             foreach ($value as $k => $v) {
179                 $args[\is_string($k) ? $this->resolveValue($k, $resolving) : $k] = $this->resolveValue($v, $resolving);
180             }
181
182             return $args;
183         }
184
185         if (!\is_string($value) || 2 > \strlen($value)) {
186             return $value;
187         }
188
189         return $this->resolveString($value, $resolving);
190     }
191
192     /**
193      * Resolves parameters inside a string.
194      *
195      * @param string $value     The string to resolve
196      * @param array  $resolving An array of keys that are being resolved (used internally to detect circular references)
197      *
198      * @return string The resolved string
199      *
200      * @throws ParameterNotFoundException          if a placeholder references a parameter that does not exist
201      * @throws ParameterCircularReferenceException if a circular reference if detected
202      * @throws RuntimeException                    when a given parameter has a type problem
203      */
204     public function resolveString($value, array $resolving = array())
205     {
206         // we do this to deal with non string values (Boolean, integer, ...)
207         // as the preg_replace_callback throw an exception when trying
208         // a non-string in a parameter value
209         if (preg_match('/^%([^%\s]+)%$/', $value, $match)) {
210             $key = $match[1];
211             $lcKey = strtolower($key); // strtolower() to be removed in 4.0
212
213             if (isset($resolving[$lcKey])) {
214                 throw new ParameterCircularReferenceException(array_keys($resolving));
215             }
216
217             $resolving[$lcKey] = true;
218
219             return $this->resolved ? $this->get($key) : $this->resolveValue($this->get($key), $resolving);
220         }
221
222         return preg_replace_callback('/%%|%([^%\s]+)%/', function ($match) use ($resolving, $value) {
223             // skip %%
224             if (!isset($match[1])) {
225                 return '%%';
226             }
227
228             $key = $match[1];
229             $lcKey = strtolower($key); // strtolower() to be removed in 4.0
230             if (isset($resolving[$lcKey])) {
231                 throw new ParameterCircularReferenceException(array_keys($resolving));
232             }
233
234             $resolved = $this->get($key);
235
236             if (!\is_string($resolved) && !is_numeric($resolved)) {
237                 throw new RuntimeException(sprintf('A string value must be composed of strings and/or numbers, but found parameter "%s" of type %s inside string value "%s".', $key, \gettype($resolved), $value));
238             }
239
240             $resolved = (string) $resolved;
241             $resolving[$lcKey] = true;
242
243             return $this->isResolved() ? $resolved : $this->resolveString($resolved, $resolving);
244         }, $value);
245     }
246
247     public function isResolved()
248     {
249         return $this->resolved;
250     }
251
252     /**
253      * {@inheritdoc}
254      */
255     public function escapeValue($value)
256     {
257         if (\is_string($value)) {
258             return str_replace('%', '%%', $value);
259         }
260
261         if (\is_array($value)) {
262             $result = array();
263             foreach ($value as $k => $v) {
264                 $result[$k] = $this->escapeValue($v);
265             }
266
267             return $result;
268         }
269
270         return $value;
271     }
272
273     /**
274      * {@inheritdoc}
275      */
276     public function unescapeValue($value)
277     {
278         if (\is_string($value)) {
279             return str_replace('%%', '%', $value);
280         }
281
282         if (\is_array($value)) {
283             $result = array();
284             foreach ($value as $k => $v) {
285                 $result[$k] = $this->unescapeValue($v);
286             }
287
288             return $result;
289         }
290
291         return $value;
292     }
293
294     private function normalizeName($name)
295     {
296         if (isset($this->normalizedNames[$normalizedName = strtolower($name)])) {
297             $normalizedName = $this->normalizedNames[$normalizedName];
298             if ((string) $name !== $normalizedName) {
299                 @trigger_error(sprintf('Parameter names will be made case sensitive in Symfony 4.0. Using "%s" instead of "%s" is deprecated since Symfony 3.4.', $name, $normalizedName), E_USER_DEPRECATED);
300             }
301         } else {
302             $normalizedName = $this->normalizedNames[$normalizedName] = (string) $name;
303         }
304
305         return $normalizedName;
306     }
307 }