PageRenderTime 47ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/PHP-E4/gsbslim/server/slim/vendor/pimple/pimple/src/Pimple/Container.php

https://gitlab.com/mlassabe/LASSABE
PHP | 282 lines | 121 code | 36 blank | 125 comment | 19 complexity | d431824e2742395ae4d5099a680ecd9b MD5 | raw file
  1. <?php
  2. /*
  3. * This file is part of Pimple.
  4. *
  5. * Copyright (c) 2009 Fabien Potencier
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a copy
  8. * of this software and associated documentation files (the "Software"), to deal
  9. * in the Software without restriction, including without limitation the rights
  10. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. * copies of the Software, and to permit persons to whom the Software is furnished
  12. * to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in all
  15. * copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. * THE SOFTWARE.
  24. */
  25. namespace Pimple;
  26. /**
  27. * Container main class.
  28. *
  29. * @author Fabien Potencier
  30. */
  31. class Container implements \ArrayAccess
  32. {
  33. private $values = array();
  34. private $factories;
  35. private $protected;
  36. private $frozen = array();
  37. private $raw = array();
  38. private $keys = array();
  39. /**
  40. * Instantiate the container.
  41. *
  42. * Objects and parameters can be passed as argument to the constructor.
  43. *
  44. * @param array $values The parameters or objects.
  45. */
  46. public function __construct(array $values = array())
  47. {
  48. $this->factories = new \SplObjectStorage();
  49. $this->protected = new \SplObjectStorage();
  50. foreach ($values as $key => $value) {
  51. $this->offsetSet($key, $value);
  52. }
  53. }
  54. /**
  55. * Sets a parameter or an object.
  56. *
  57. * Objects must be defined as Closures.
  58. *
  59. * Allowing any PHP callable leads to difficult to debug problems
  60. * as function names (strings) are callable (creating a function with
  61. * the same name as an existing parameter would break your container).
  62. *
  63. * @param string $id The unique identifier for the parameter or object
  64. * @param mixed $value The value of the parameter or a closure to define an object
  65. *
  66. * @throws \RuntimeException Prevent override of a frozen service
  67. */
  68. public function offsetSet($id, $value)
  69. {
  70. if (isset($this->frozen[$id])) {
  71. throw new \RuntimeException(sprintf('Cannot override frozen service "%s".', $id));
  72. }
  73. $this->values[$id] = $value;
  74. $this->keys[$id] = true;
  75. }
  76. /**
  77. * Gets a parameter or an object.
  78. *
  79. * @param string $id The unique identifier for the parameter or object
  80. *
  81. * @return mixed The value of the parameter or an object
  82. *
  83. * @throws \InvalidArgumentException if the identifier is not defined
  84. */
  85. public function offsetGet($id)
  86. {
  87. if (!isset($this->keys[$id])) {
  88. throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));
  89. }
  90. if (
  91. isset($this->raw[$id])
  92. || !is_object($this->values[$id])
  93. || isset($this->protected[$this->values[$id]])
  94. || !method_exists($this->values[$id], '__invoke')
  95. ) {
  96. return $this->values[$id];
  97. }
  98. if (isset($this->factories[$this->values[$id]])) {
  99. return $this->values[$id]($this);
  100. }
  101. $raw = $this->values[$id];
  102. $val = $this->values[$id] = $raw($this);
  103. $this->raw[$id] = $raw;
  104. $this->frozen[$id] = true;
  105. return $val;
  106. }
  107. /**
  108. * Checks if a parameter or an object is set.
  109. *
  110. * @param string $id The unique identifier for the parameter or object
  111. *
  112. * @return bool
  113. */
  114. public function offsetExists($id)
  115. {
  116. return isset($this->keys[$id]);
  117. }
  118. /**
  119. * Unsets a parameter or an object.
  120. *
  121. * @param string $id The unique identifier for the parameter or object
  122. */
  123. public function offsetUnset($id)
  124. {
  125. if (isset($this->keys[$id])) {
  126. if (is_object($this->values[$id])) {
  127. unset($this->factories[$this->values[$id]], $this->protected[$this->values[$id]]);
  128. }
  129. unset($this->values[$id], $this->frozen[$id], $this->raw[$id], $this->keys[$id]);
  130. }
  131. }
  132. /**
  133. * Marks a callable as being a factory service.
  134. *
  135. * @param callable $callable A service definition to be used as a factory
  136. *
  137. * @return callable The passed callable
  138. *
  139. * @throws \InvalidArgumentException Service definition has to be a closure of an invokable object
  140. */
  141. public function factory($callable)
  142. {
  143. if (!method_exists($callable, '__invoke')) {
  144. throw new \InvalidArgumentException('Service definition is not a Closure or invokable object.');
  145. }
  146. $this->factories->attach($callable);
  147. return $callable;
  148. }
  149. /**
  150. * Protects a callable from being interpreted as a service.
  151. *
  152. * This is useful when you want to store a callable as a parameter.
  153. *
  154. * @param callable $callable A callable to protect from being evaluated
  155. *
  156. * @return callable The passed callable
  157. *
  158. * @throws \InvalidArgumentException Service definition has to be a closure of an invokable object
  159. */
  160. public function protect($callable)
  161. {
  162. if (!method_exists($callable, '__invoke')) {
  163. throw new \InvalidArgumentException('Callable is not a Closure or invokable object.');
  164. }
  165. $this->protected->attach($callable);
  166. return $callable;
  167. }
  168. /**
  169. * Gets a parameter or the closure defining an object.
  170. *
  171. * @param string $id The unique identifier for the parameter or object
  172. *
  173. * @return mixed The value of the parameter or the closure defining an object
  174. *
  175. * @throws \InvalidArgumentException if the identifier is not defined
  176. */
  177. public function raw($id)
  178. {
  179. if (!isset($this->keys[$id])) {
  180. throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));
  181. }
  182. if (isset($this->raw[$id])) {
  183. return $this->raw[$id];
  184. }
  185. return $this->values[$id];
  186. }
  187. /**
  188. * Extends an object definition.
  189. *
  190. * Useful when you want to extend an existing object definition,
  191. * without necessarily loading that object.
  192. *
  193. * @param string $id The unique identifier for the object
  194. * @param callable $callable A service definition to extend the original
  195. *
  196. * @return callable The wrapped callable
  197. *
  198. * @throws \InvalidArgumentException if the identifier is not defined or not a service definition
  199. */
  200. public function extend($id, $callable)
  201. {
  202. if (!isset($this->keys[$id])) {
  203. throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));
  204. }
  205. if (!is_object($this->values[$id]) || !method_exists($this->values[$id], '__invoke')) {
  206. throw new \InvalidArgumentException(sprintf('Identifier "%s" does not contain an object definition.', $id));
  207. }
  208. if (!is_object($callable) || !method_exists($callable, '__invoke')) {
  209. throw new \InvalidArgumentException('Extension service definition is not a Closure or invokable object.');
  210. }
  211. $factory = $this->values[$id];
  212. $extended = function ($c) use ($callable, $factory) {
  213. return $callable($factory($c), $c);
  214. };
  215. if (isset($this->factories[$factory])) {
  216. $this->factories->detach($factory);
  217. $this->factories->attach($extended);
  218. }
  219. return $this[$id] = $extended;
  220. }
  221. /**
  222. * Returns all defined value names.
  223. *
  224. * @return array An array of value names
  225. */
  226. public function keys()
  227. {
  228. return array_keys($this->values);
  229. }
  230. /**
  231. * Registers a service provider.
  232. *
  233. * @param ServiceProviderInterface $provider A ServiceProviderInterface instance
  234. * @param array $values An array of values that customizes the provider
  235. *
  236. * @return static
  237. */
  238. public function register(ServiceProviderInterface $provider, array $values = array())
  239. {
  240. $provider->register($this);
  241. foreach ($values as $key => $value) {
  242. $this[$key] = $value;
  243. }
  244. return $this;
  245. }
  246. }