PageRenderTime 52ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/vendor/symfony/lib/service/sfServiceContainerBuilder.class.php

https://github.com/openpne/OpenPNE3
PHP | 338 lines | 174 code | 39 blank | 125 comment | 22 complexity | 83c6c41ec15971a0d608bf242febb515 MD5 | raw file
Possible License(s): Apache-2.0, LGPL-2.1
  1. <?php
  2. /*
  3. * This file is part of the symfony package.
  4. * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
  5. *
  6. * For the full copyright and license information, please view the LICENSE
  7. * file that was distributed with this source code.
  8. */
  9. /**
  10. * sfServiceContainerBuilder is a DI container that provides an interface to build the services.
  11. *
  12. * @package symfony
  13. * @subpackage service
  14. * @author Fabien Potencier <fabien.potencier@symfony-project.com>
  15. * @version SVN: $Id: sfServiceContainerBuilder.php 269 2009-03-26 20:39:16Z fabien $
  16. */
  17. class sfServiceContainerBuilder extends sfServiceContainer
  18. {
  19. protected
  20. $definitions = array(),
  21. $aliases = array(),
  22. $loading = array();
  23. /**
  24. * Sets a service.
  25. *
  26. * @param string $id The service identifier
  27. * @param object $service The service instance
  28. */
  29. public function setService($id, $service)
  30. {
  31. unset($this->aliases[$id]);
  32. parent::setService($id, $service);
  33. }
  34. /**
  35. * Returns true if the given service is defined.
  36. *
  37. * @param string $id The service identifier
  38. *
  39. * @return Boolean true if the service is defined, false otherwise
  40. */
  41. public function hasService($id)
  42. {
  43. return isset($this->definitions[$id]) || isset($this->aliases[$id]) || parent::hasService($id);
  44. }
  45. /**
  46. * Gets a service.
  47. *
  48. * @param string $id The service identifier
  49. *
  50. * @return object The associated service
  51. *
  52. * @throw InvalidArgumentException if the service is not defined
  53. * @throw LogicException if the service has a circular reference to itself
  54. */
  55. public function getService($id)
  56. {
  57. try
  58. {
  59. return parent::getService($id);
  60. }
  61. catch (InvalidArgumentException $e)
  62. {
  63. if (isset($this->loading[$id]))
  64. {
  65. throw new LogicException(sprintf('The service "%s" has a circular reference to itself.', $id));
  66. }
  67. if (!$this->hasServiceDefinition($id) && isset($this->aliases[$id]))
  68. {
  69. return $this->getService($this->aliases[$id]);
  70. }
  71. $definition = $this->getServiceDefinition($id);
  72. $this->loading[$id] = true;
  73. if ($definition->isShared())
  74. {
  75. $service = $this->services[$id] = $this->createService($definition);
  76. }
  77. else
  78. {
  79. $service = $this->createService($definition);
  80. }
  81. unset($this->loading[$id]);
  82. return $service;
  83. }
  84. }
  85. /**
  86. * Gets all service ids.
  87. *
  88. * @return array An array of all defined service ids
  89. */
  90. public function getServiceIds()
  91. {
  92. return array_unique(array_merge(array_keys($this->getServiceDefinitions()), array_keys($this->aliases), parent::getServiceIds()));
  93. }
  94. /**
  95. * Sets an alias for an existing service.
  96. *
  97. * @param string $alias The alias to create
  98. * @param string $id The service to alias
  99. */
  100. public function setAlias($alias, $id)
  101. {
  102. $this->aliases[$alias] = $id;
  103. }
  104. /**
  105. * Gets all defined aliases.
  106. *
  107. * @return array An array of aliases
  108. */
  109. public function getAliases()
  110. {
  111. return $this->aliases;
  112. }
  113. /**
  114. * Registers a service definition.
  115. *
  116. * This methods allows for simple registration of service definition
  117. * with a fluid interface.
  118. *
  119. * @param string $id The service identifier
  120. * @param string $class The service class
  121. *
  122. * @return sfServiceDefinition A sfServiceDefinition instance
  123. */
  124. public function register($id, $class)
  125. {
  126. return $this->setServiceDefinition($id, new sfServiceDefinition($class));
  127. }
  128. /**
  129. * Adds the service definitions.
  130. *
  131. * @param array $definitions An array of service definitions
  132. */
  133. public function addServiceDefinitions(array $definitions)
  134. {
  135. foreach ($definitions as $id => $definition)
  136. {
  137. $this->setServiceDefinition($id, $definition);
  138. }
  139. }
  140. /**
  141. * Sets the service definitions.
  142. *
  143. * @param array $definitions An array of service definitions
  144. */
  145. public function setServiceDefinitions(array $definitions)
  146. {
  147. $this->definitions = array();
  148. $this->addServiceDefinitions($definitions);
  149. }
  150. /**
  151. * Gets all service definitions.
  152. *
  153. * @return array An array of sfServiceDefinition instances
  154. */
  155. public function getServiceDefinitions()
  156. {
  157. return $this->definitions;
  158. }
  159. /**
  160. * Sets a service definition.
  161. *
  162. * @param string $id The service identifier
  163. * @param sfServiceDefinition $definition A sfServiceDefinition instance
  164. */
  165. public function setServiceDefinition($id, sfServiceDefinition $definition)
  166. {
  167. unset($this->aliases[$id]);
  168. return $this->definitions[$id] = $definition;
  169. }
  170. /**
  171. * Returns true if a service definition exists under the given identifier.
  172. *
  173. * @param string $id The service identifier
  174. *
  175. * @return Boolean true if the service definition exists, false otherwise
  176. */
  177. public function hasServiceDefinition($id)
  178. {
  179. return array_key_exists($id, $this->definitions);
  180. }
  181. /**
  182. * Gets a service definition.
  183. *
  184. * @param string $id The service identifier
  185. *
  186. * @return sfServiceDefinition A sfServiceDefinition instance
  187. *
  188. * @throw InvalidArgumentException if the service definition does not exist
  189. */
  190. public function getServiceDefinition($id)
  191. {
  192. if (!$this->hasServiceDefinition($id))
  193. {
  194. throw new InvalidArgumentException(sprintf('The service definition "%s" does not exist.', $id));
  195. }
  196. return $this->definitions[$id];
  197. }
  198. /**
  199. * Creates a service for a service definition.
  200. *
  201. * @param sfServiceDefinition $definition A service definition instance
  202. *
  203. * @return object The service described by the service definition
  204. */
  205. protected function createService(sfServiceDefinition $definition)
  206. {
  207. if (null !== $definition->getFile())
  208. {
  209. require_once $this->resolveValue($definition->getFile());
  210. }
  211. $r = new ReflectionClass($this->resolveValue($definition->getClass()));
  212. $arguments = $this->resolveServices($this->resolveValue($definition->getArguments()));
  213. if (null !== $definition->getConstructor())
  214. {
  215. $service = call_user_func_array(array($this->resolveValue($definition->getClass()), $definition->getConstructor()), $arguments);
  216. }
  217. else
  218. {
  219. $service = null === $r->getConstructor() ? $r->newInstance() : $r->newInstanceArgs($arguments);
  220. }
  221. foreach ($definition->getMethodCalls() as $call)
  222. {
  223. call_user_func_array(array($service, $call[0]), $this->resolveServices($this->resolveValue($call[1])));
  224. }
  225. if ($callable = $definition->getConfigurator())
  226. {
  227. if (is_array($callable) && is_object($callable[0]) && $callable[0] instanceof sfServiceReference)
  228. {
  229. $callable[0] = $this->getService((string) $callable[0]);
  230. }
  231. elseif (is_array($callable))
  232. {
  233. $callable[0] = $this->resolveValue($callable[0]);
  234. }
  235. if (!is_callable($callable))
  236. {
  237. throw new InvalidArgumentException(sprintf('The configure callable for class "%s" is not a callable.', get_class($service)));
  238. }
  239. call_user_func($callable, $service);
  240. }
  241. return $service;
  242. }
  243. /**
  244. * Replaces parameter placeholders (%name%) by their values.
  245. *
  246. * @param mixed $value A value
  247. *
  248. * @return mixed The same value with all placeholders replaced by their values
  249. *
  250. * @throw RuntimeException if a placeholder references a parameter that does not exist
  251. */
  252. public function resolveValue($value)
  253. {
  254. if (is_array($value))
  255. {
  256. $args = array();
  257. foreach ($value as $k => $v)
  258. {
  259. $args[$this->resolveValue($k)] = $this->resolveValue($v);
  260. }
  261. $value = $args;
  262. }
  263. else if (is_string($value))
  264. {
  265. if (preg_match('/^%([^%]+)%$/', $value, $match))
  266. {
  267. $value = $this->getParameter($match[1]);
  268. }
  269. else
  270. {
  271. $value = str_replace('%%', '%', preg_replace_callback('/(?<!%)(%)([^%]+)\1/', array($this, 'replaceParameter'), $value));
  272. }
  273. }
  274. return $value;
  275. }
  276. /**
  277. * Replaces service references by the real service instance.
  278. *
  279. * @param mixed $value A value
  280. *
  281. * @return mixed The same value with all service references replaced by the real service instances
  282. */
  283. public function resolveServices($value)
  284. {
  285. if (is_array($value))
  286. {
  287. $value = array_map(array($this, 'resolveServices'), $value);
  288. }
  289. else if (is_object($value) && $value instanceof sfServiceReference)
  290. {
  291. $value = $this->getService((string) $value);
  292. }
  293. return $value;
  294. }
  295. protected function replaceParameter($match)
  296. {
  297. return $this->getParameter($match[2]);
  298. }
  299. }