/vendor/symfony/dependency-injection/ParameterBag/ParameterBag.php

https://gitlab.com/reasonat/test8 · PHP · 286 lines · 150 code · 44 blank · 92 comment · 17 complexity · 729338bcb72deab8dc5a075fae3e7ba5 MD5 · raw file

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