annotate vendor/symfony/dependency-injection/ParameterBag/ParameterBag.php @ 8:50b0d041100e

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