comparison vendor/symfony/dependency-injection/ParameterBag/ParameterBag.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children 1fec387a4317
comparison
equal deleted inserted replaced
-1:000000000000 0:4c8ae668cc8c
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 $nonNestedAlternative = null;
85 if (!count($alternatives) && false !== strpos($name, '.')) {
86 $namePartsLength = array_map('strlen', explode('.', $name));
87 $key = substr($name, 0, -1 * (1 + array_pop($namePartsLength)));
88 while (count($namePartsLength)) {
89 if ($this->has($key)) {
90 if (is_array($this->get($key))) {
91 $nonNestedAlternative = $key;
92 }
93 break;
94 }
95
96 $key = substr($key, 0, -1 * (1 + array_pop($namePartsLength)));
97 }
98 }
99
100 throw new ParameterNotFoundException($name, null, null, null, $alternatives, $nonNestedAlternative);
101 }
102
103 return $this->parameters[$name];
104 }
105
106 /**
107 * Sets a service container parameter.
108 *
109 * @param string $name The parameter name
110 * @param mixed $value The parameter value
111 */
112 public function set($name, $value)
113 {
114 $this->parameters[strtolower($name)] = $value;
115 }
116
117 /**
118 * {@inheritdoc}
119 */
120 public function has($name)
121 {
122 return array_key_exists(strtolower($name), $this->parameters);
123 }
124
125 /**
126 * Removes a parameter.
127 *
128 * @param string $name The parameter name
129 */
130 public function remove($name)
131 {
132 unset($this->parameters[strtolower($name)]);
133 }
134
135 /**
136 * {@inheritdoc}
137 */
138 public function resolve()
139 {
140 if ($this->resolved) {
141 return;
142 }
143
144 $parameters = array();
145 foreach ($this->parameters as $key => $value) {
146 try {
147 $value = $this->resolveValue($value);
148 $parameters[$key] = $this->unescapeValue($value);
149 } catch (ParameterNotFoundException $e) {
150 $e->setSourceKey($key);
151
152 throw $e;
153 }
154 }
155
156 $this->parameters = $parameters;
157 $this->resolved = true;
158 }
159
160 /**
161 * Replaces parameter placeholders (%name%) by their values.
162 *
163 * @param mixed $value A value
164 * @param array $resolving An array of keys that are being resolved (used internally to detect circular references)
165 *
166 * @return mixed The resolved value
167 *
168 * @throws ParameterNotFoundException if a placeholder references a parameter that does not exist
169 * @throws ParameterCircularReferenceException if a circular reference if detected
170 * @throws RuntimeException when a given parameter has a type problem.
171 */
172 public function resolveValue($value, array $resolving = array())
173 {
174 if (is_array($value)) {
175 $args = array();
176 foreach ($value as $k => $v) {
177 $args[$this->resolveValue($k, $resolving)] = $this->resolveValue($v, $resolving);
178 }
179
180 return $args;
181 }
182
183 if (!is_string($value)) {
184 return $value;
185 }
186
187 return $this->resolveString($value, $resolving);
188 }
189
190 /**
191 * Resolves parameters inside a string.
192 *
193 * @param string $value The string to resolve
194 * @param array $resolving An array of keys that are being resolved (used internally to detect circular references)
195 *
196 * @return string The resolved string
197 *
198 * @throws ParameterNotFoundException if a placeholder references a parameter that does not exist
199 * @throws ParameterCircularReferenceException if a circular reference if detected
200 * @throws RuntimeException when a given parameter has a type problem.
201 */
202 public function resolveString($value, array $resolving = array())
203 {
204 // we do this to deal with non string values (Boolean, integer, ...)
205 // as the preg_replace_callback throw an exception when trying
206 // a non-string in a parameter value
207 if (preg_match('/^%([^%\s]+)%$/', $value, $match)) {
208 $key = $match[1];
209 $lcKey = strtolower($key);
210
211 if (isset($resolving[$lcKey])) {
212 throw new ParameterCircularReferenceException(array_keys($resolving));
213 }
214
215 $resolving[$lcKey] = true;
216
217 return $this->resolved ? $this->get($key) : $this->resolveValue($this->get($key), $resolving);
218 }
219
220 return preg_replace_callback('/%%|%([^%\s]+)%/', function ($match) use ($resolving, $value) {
221 // skip %%
222 if (!isset($match[1])) {
223 return '%%';
224 }
225
226 $key = $match[1];
227 $lcKey = strtolower($key);
228 if (isset($resolving[$lcKey])) {
229 throw new ParameterCircularReferenceException(array_keys($resolving));
230 }
231
232 $resolved = $this->get($key);
233
234 if (!is_string($resolved) && !is_numeric($resolved)) {
235 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));
236 }
237
238 $resolved = (string) $resolved;
239 $resolving[$lcKey] = true;
240
241 return $this->isResolved() ? $resolved : $this->resolveString($resolved, $resolving);
242 }, $value);
243 }
244
245 public function isResolved()
246 {
247 return $this->resolved;
248 }
249
250 /**
251 * {@inheritdoc}
252 */
253 public function escapeValue($value)
254 {
255 if (is_string($value)) {
256 return str_replace('%', '%%', $value);
257 }
258
259 if (is_array($value)) {
260 $result = array();
261 foreach ($value as $k => $v) {
262 $result[$k] = $this->escapeValue($v);
263 }
264
265 return $result;
266 }
267
268 return $value;
269 }
270
271 /**
272 * {@inheritdoc}
273 */
274 public function unescapeValue($value)
275 {
276 if (is_string($value)) {
277 return str_replace('%%', '%', $value);
278 }
279
280 if (is_array($value)) {
281 $result = array();
282 foreach ($value as $k => $v) {
283 $result[$k] = $this->unescapeValue($v);
284 }
285
286 return $result;
287 }
288
289 return $value;
290 }
291 }