0611b1f69e322045f6d9751919873d30c6233f4a
[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\ParameterNotFoundException;
15 use Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException;
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     /**
29      * @param array $parameters An array of parameters
30      */
31     public function __construct(array $parameters = array())
32     {
33         $this->add($parameters);
34     }
35
36     /**
37      * Clears all parameters.
38      */
39     public function clear()
40     {
41         $this->parameters = array();
42     }
43
44     /**
45      * Adds parameters to the service container parameters.
46      *
47      * @param array $parameters An array of parameters
48      */
49     public function add(array $parameters)
50     {
51         foreach ($parameters as $key => $value) {
52             $this->parameters[strtolower($key)] = $value;
53         }
54     }
55
56     /**
57      * {@inheritdoc}
58      */
59     public function all()
60     {
61         return $this->parameters;
62     }
63
64     /**
65      * {@inheritdoc}
66      */
67     public function get($name)
68     {
69         $name = strtolower($name);
70
71         if (!array_key_exists($name, $this->parameters)) {
72             if (!$name) {
73                 throw new ParameterNotFoundException($name);
74             }
75
76             $alternatives = array();
77             foreach ($this->parameters as $key => $parameterValue) {
78                 $lev = levenshtein($name, $key);
79                 if ($lev <= strlen($name) / 3 || false !== strpos($key, $name)) {
80                     $alternatives[] = $key;
81                 }
82             }
83
84             throw new ParameterNotFoundException($name, null, null, null, $alternatives);
85         }
86
87         return $this->parameters[$name];
88     }
89
90     /**
91      * Sets a service container parameter.
92      *
93      * @param string $name  The parameter name
94      * @param mixed  $value The parameter value
95      */
96     public function set($name, $value)
97     {
98         $this->parameters[strtolower($name)] = $value;
99     }
100
101     /**
102      * {@inheritdoc}
103      */
104     public function has($name)
105     {
106         return array_key_exists(strtolower($name), $this->parameters);
107     }
108
109     /**
110      * Removes a parameter.
111      *
112      * @param string $name The parameter name
113      */
114     public function remove($name)
115     {
116         unset($this->parameters[strtolower($name)]);
117     }
118
119     /**
120      * {@inheritdoc}
121      */
122     public function resolve()
123     {
124         if ($this->resolved) {
125             return;
126         }
127
128         $parameters = array();
129         foreach ($this->parameters as $key => $value) {
130             try {
131                 $value = $this->resolveValue($value);
132                 $parameters[$key] = $this->unescapeValue($value);
133             } catch (ParameterNotFoundException $e) {
134                 $e->setSourceKey($key);
135
136                 throw $e;
137             }
138         }
139
140         $this->parameters = $parameters;
141         $this->resolved = true;
142     }
143
144     /**
145      * Replaces parameter placeholders (%name%) by their values.
146      *
147      * @param mixed $value     A value
148      * @param array $resolving An array of keys that are being resolved (used internally to detect circular references)
149      *
150      * @return mixed The resolved value
151      *
152      * @throws ParameterNotFoundException          if a placeholder references a parameter that does not exist
153      * @throws ParameterCircularReferenceException if a circular reference if detected
154      * @throws RuntimeException                    when a given parameter has a type problem.
155      */
156     public function resolveValue($value, array $resolving = array())
157     {
158         if (is_array($value)) {
159             $args = array();
160             foreach ($value as $k => $v) {
161                 $args[$this->resolveValue($k, $resolving)] = $this->resolveValue($v, $resolving);
162             }
163
164             return $args;
165         }
166
167         if (!is_string($value)) {
168             return $value;
169         }
170
171         return $this->resolveString($value, $resolving);
172     }
173
174     /**
175      * Resolves parameters inside a string.
176      *
177      * @param string $value     The string to resolve
178      * @param array  $resolving An array of keys that are being resolved (used internally to detect circular references)
179      *
180      * @return string The resolved string
181      *
182      * @throws ParameterNotFoundException          if a placeholder references a parameter that does not exist
183      * @throws ParameterCircularReferenceException if a circular reference if detected
184      * @throws RuntimeException                    when a given parameter has a type problem.
185      */
186     public function resolveString($value, array $resolving = array())
187     {
188         // we do this to deal with non string values (Boolean, integer, ...)
189         // as the preg_replace_callback throw an exception when trying
190         // a non-string in a parameter value
191         if (preg_match('/^%([^%\s]+)%$/', $value, $match)) {
192             $key = strtolower($match[1]);
193
194             if (isset($resolving[$key])) {
195                 throw new ParameterCircularReferenceException(array_keys($resolving));
196             }
197
198             $resolving[$key] = true;
199
200             return $this->resolved ? $this->get($key) : $this->resolveValue($this->get($key), $resolving);
201         }
202
203         $self = $this;
204
205         return preg_replace_callback('/%%|%([^%\s]+)%/', function ($match) use ($self, $resolving, $value) {
206             // skip %%
207             if (!isset($match[1])) {
208                 return '%%';
209             }
210
211             $key = strtolower($match[1]);
212             if (isset($resolving[$key])) {
213                 throw new ParameterCircularReferenceException(array_keys($resolving));
214             }
215
216             $resolved = $self->get($key);
217
218             if (!is_string($resolved) && !is_numeric($resolved)) {
219                 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));
220             }
221
222             $resolved = (string) $resolved;
223             $resolving[$key] = true;
224
225             return $self->isResolved() ? $resolved : $self->resolveString($resolved, $resolving);
226         }, $value);
227     }
228
229     public function isResolved()
230     {
231         return $this->resolved;
232     }
233
234     /**
235      * {@inheritdoc}
236      */
237     public function escapeValue($value)
238     {
239         if (is_string($value)) {
240             return str_replace('%', '%%', $value);
241         }
242
243         if (is_array($value)) {
244             $result = array();
245             foreach ($value as $k => $v) {
246                 $result[$k] = $this->escapeValue($v);
247             }
248
249             return $result;
250         }
251
252         return $value;
253     }
254
255     /**
256      * {@inheritdoc}
257      */
258     public function unescapeValue($value)
259     {
260         if (is_string($value)) {
261             return str_replace('%%', '%', $value);
262         }
263
264         if (is_array($value)) {
265             $result = array();
266             foreach ($value as $k => $v) {
267                 $result[$k] = $this->unescapeValue($v);
268             }
269
270             return $result;
271         }
272
273         return $value;
274     }
275 }