PageRenderTime 33ms CodeModel.GetById 8ms RepoModel.GetById 1ms app.codeStats 0ms

/sites/all/modules/service_container/modules/providers/service_container_symfony/lib/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php

https://gitlab.com/leoplanxxi/dr7-web-buap-2016
PHP | 421 lines | 273 code | 70 blank | 78 comment | 67 complexity | 52b31ca278827170a5fdb059fc74ca6a 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\Loader;
  11. use Symfony\Component\DependencyInjection\DefinitionDecorator;
  12. use Symfony\Component\DependencyInjection\Alias;
  13. use Symfony\Component\DependencyInjection\ContainerInterface;
  14. use Symfony\Component\DependencyInjection\Definition;
  15. use Symfony\Component\DependencyInjection\Reference;
  16. use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
  17. use Symfony\Component\DependencyInjection\Exception\RuntimeException;
  18. use Symfony\Component\Config\Resource\FileResource;
  19. use Symfony\Component\Yaml\Parser as YamlParser;
  20. use Symfony\Component\ExpressionLanguage\Expression;
  21. /**
  22. * YamlFileLoader loads YAML files service definitions.
  23. *
  24. * The YAML format does not support anonymous services (cf. the XML loader).
  25. *
  26. * @author Fabien Potencier <fabien@symfony.com>
  27. */
  28. class YamlFileLoader extends FileLoader
  29. {
  30. private $yamlParser;
  31. /**
  32. * {@inheritdoc}
  33. */
  34. public function load($resource, $type = null)
  35. {
  36. $path = $this->locator->locate($resource);
  37. $content = $this->loadFile($path);
  38. $this->container->addResource(new FileResource($path));
  39. // empty file
  40. if (null === $content) {
  41. return;
  42. }
  43. // imports
  44. $this->parseImports($content, $path);
  45. // parameters
  46. if (isset($content['parameters'])) {
  47. if (!is_array($content['parameters'])) {
  48. throw new InvalidArgumentException(sprintf('The "parameters" key should contain an array in %s. Check your YAML syntax.', $resource));
  49. }
  50. foreach ($content['parameters'] as $key => $value) {
  51. $this->container->setParameter($key, $this->resolveServices($value));
  52. }
  53. }
  54. // extensions
  55. $this->loadFromExtensions($content);
  56. // services
  57. $this->parseDefinitions($content, $resource);
  58. }
  59. /**
  60. * {@inheritdoc}
  61. */
  62. public function supports($resource, $type = null)
  63. {
  64. return is_string($resource) && in_array(pathinfo($resource, PATHINFO_EXTENSION), array('yml', 'yaml'), true);
  65. }
  66. /**
  67. * Parses all imports.
  68. *
  69. * @param array $content
  70. * @param string $file
  71. */
  72. private function parseImports($content, $file)
  73. {
  74. if (!isset($content['imports'])) {
  75. return;
  76. }
  77. if (!is_array($content['imports'])) {
  78. throw new InvalidArgumentException(sprintf('The "imports" key should contain an array in %s. Check your YAML syntax.', $file));
  79. }
  80. foreach ($content['imports'] as $import) {
  81. if (!is_array($import)) {
  82. throw new InvalidArgumentException(sprintf('The values in the "imports" key should be arrays in %s. Check your YAML syntax.', $file));
  83. }
  84. $this->setCurrentDir(dirname($file));
  85. $this->import($import['resource'], null, isset($import['ignore_errors']) ? (bool) $import['ignore_errors'] : false, $file);
  86. }
  87. }
  88. /**
  89. * Parses definitions.
  90. *
  91. * @param array $content
  92. * @param string $file
  93. */
  94. private function parseDefinitions($content, $file)
  95. {
  96. if (!isset($content['services'])) {
  97. return;
  98. }
  99. if (!is_array($content['services'])) {
  100. throw new InvalidArgumentException(sprintf('The "services" key should contain an array in %s. Check your YAML syntax.', $file));
  101. }
  102. foreach ($content['services'] as $id => $service) {
  103. $this->parseDefinition($id, $service, $file);
  104. }
  105. }
  106. /**
  107. * Parses a definition.
  108. *
  109. * @param string $id
  110. * @param array $service
  111. * @param string $file
  112. *
  113. * @throws InvalidArgumentException When tags are invalid
  114. */
  115. private function parseDefinition($id, $service, $file)
  116. {
  117. if (is_string($service) && 0 === strpos($service, '@')) {
  118. $this->container->setAlias($id, substr($service, 1));
  119. return;
  120. }
  121. if (!is_array($service)) {
  122. throw new InvalidArgumentException(sprintf('A service definition must be an array or a string starting with "@" but %s found for service "%s" in %s. Check your YAML syntax.', gettype($service), $id, $file));
  123. }
  124. if (isset($service['alias'])) {
  125. $public = !array_key_exists('public', $service) || (bool) $service['public'];
  126. $this->container->setAlias($id, new Alias($service['alias'], $public));
  127. return;
  128. }
  129. if (isset($service['parent'])) {
  130. $definition = new DefinitionDecorator($service['parent']);
  131. } else {
  132. $definition = new Definition();
  133. }
  134. if (isset($service['class'])) {
  135. $definition->setClass($service['class']);
  136. }
  137. if (isset($service['scope'])) {
  138. $definition->setScope($service['scope']);
  139. }
  140. if (isset($service['synthetic'])) {
  141. $definition->setSynthetic($service['synthetic']);
  142. }
  143. if (isset($service['synchronized'])) {
  144. trigger_error(sprintf('The "synchronized" key in file "%s" is deprecated since version 2.7 and will be removed in 3.0.', $file), E_USER_DEPRECATED);
  145. $definition->setSynchronized($service['synchronized'], 'request' !== $id);
  146. }
  147. if (isset($service['lazy'])) {
  148. $definition->setLazy($service['lazy']);
  149. }
  150. if (isset($service['public'])) {
  151. $definition->setPublic($service['public']);
  152. }
  153. if (isset($service['abstract'])) {
  154. $definition->setAbstract($service['abstract']);
  155. }
  156. if (isset($service['factory'])) {
  157. if (is_string($service['factory'])) {
  158. if (strpos($service['factory'], ':') !== false && strpos($service['factory'], '::') === false) {
  159. $parts = explode(':', $service['factory']);
  160. $definition->setFactory(array($this->resolveServices('@'.$parts[0]), $parts[1]));
  161. } else {
  162. $definition->setFactory($service['factory']);
  163. }
  164. } else {
  165. $definition->setFactory(array($this->resolveServices($service['factory'][0]), $service['factory'][1]));
  166. }
  167. }
  168. if (isset($service['factory_class'])) {
  169. trigger_error(sprintf('The "factory_class" key in file "%s" is deprecated since version 2.6 and will be removed in 3.0. Use "factory" instead.', $file), E_USER_DEPRECATED);
  170. $definition->setFactoryClass($service['factory_class']);
  171. }
  172. if (isset($service['factory_method'])) {
  173. trigger_error(sprintf('The "factory_method" key in file "%s" is deprecated since version 2.6 and will be removed in 3.0. Use "factory" instead.', $file), E_USER_DEPRECATED);
  174. $definition->setFactoryMethod($service['factory_method']);
  175. }
  176. if (isset($service['factory_service'])) {
  177. trigger_error(sprintf('The "factory_service" key in file "%s" is deprecated since version 2.6 and will be removed in 3.0. Use "factory" instead.', $file), E_USER_DEPRECATED);
  178. $definition->setFactoryService($service['factory_service']);
  179. }
  180. if (isset($service['file'])) {
  181. $definition->setFile($service['file']);
  182. }
  183. if (isset($service['arguments'])) {
  184. $definition->setArguments($this->resolveServices($service['arguments']));
  185. }
  186. if (isset($service['properties'])) {
  187. $definition->setProperties($this->resolveServices($service['properties']));
  188. }
  189. if (isset($service['configurator'])) {
  190. if (is_string($service['configurator'])) {
  191. $definition->setConfigurator($service['configurator']);
  192. } else {
  193. $definition->setConfigurator(array($this->resolveServices($service['configurator'][0]), $service['configurator'][1]));
  194. }
  195. }
  196. if (isset($service['calls'])) {
  197. if (!is_array($service['calls'])) {
  198. throw new InvalidArgumentException(sprintf('Parameter "calls" must be an array for service "%s" in %s. Check your YAML syntax.', $id, $file));
  199. }
  200. foreach ($service['calls'] as $call) {
  201. if (isset($call['method'])) {
  202. $method = $call['method'];
  203. $args = isset($call['arguments']) ? $this->resolveServices($call['arguments']) : array();
  204. } else {
  205. $method = $call[0];
  206. $args = isset($call[1]) ? $this->resolveServices($call[1]) : array();
  207. }
  208. $definition->addMethodCall($method, $args);
  209. }
  210. }
  211. if (isset($service['tags'])) {
  212. if (!is_array($service['tags'])) {
  213. throw new InvalidArgumentException(sprintf('Parameter "tags" must be an array for service "%s" in %s. Check your YAML syntax.', $id, $file));
  214. }
  215. foreach ($service['tags'] as $tag) {
  216. if (!is_array($tag)) {
  217. throw new InvalidArgumentException(sprintf('A "tags" entry must be an array for service "%s" in %s. Check your YAML syntax.', $id, $file));
  218. }
  219. if (!isset($tag['name'])) {
  220. throw new InvalidArgumentException(sprintf('A "tags" entry is missing a "name" key for service "%s" in %s.', $id, $file));
  221. }
  222. $name = $tag['name'];
  223. unset($tag['name']);
  224. foreach ($tag as $attribute => $value) {
  225. if (!is_scalar($value) && null !== $value) {
  226. throw new InvalidArgumentException(sprintf('A "tags" attribute must be of a scalar-type for service "%s", tag "%s", attribute "%s" in %s. Check your YAML syntax.', $id, $name, $attribute, $file));
  227. }
  228. }
  229. $definition->addTag($name, $tag);
  230. }
  231. }
  232. if (isset($service['decorates'])) {
  233. $renameId = isset($service['decoration_inner_name']) ? $service['decoration_inner_name'] : null;
  234. $definition->setDecoratedService($service['decorates'], $renameId);
  235. }
  236. $this->container->setDefinition($id, $definition);
  237. }
  238. /**
  239. * Loads a YAML file.
  240. *
  241. * @param string $file
  242. *
  243. * @return array The file content
  244. *
  245. * @throws InvalidArgumentException when the given file is not a local file or when it does not exist
  246. */
  247. protected function loadFile($file)
  248. {
  249. if (!class_exists('Symfony\Component\Yaml\Parser')) {
  250. throw new RuntimeException('Unable to load YAML config files as the Symfony Yaml Component is not installed.');
  251. }
  252. if (!stream_is_local($file)) {
  253. throw new InvalidArgumentException(sprintf('This is not a local file "%s".', $file));
  254. }
  255. if (!file_exists($file)) {
  256. throw new InvalidArgumentException(sprintf('The service file "%s" is not valid.', $file));
  257. }
  258. if (null === $this->yamlParser) {
  259. $this->yamlParser = new YamlParser();
  260. }
  261. return $this->validate($this->yamlParser->parse(file_get_contents($file)), $file);
  262. }
  263. /**
  264. * Validates a YAML file.
  265. *
  266. * @param mixed $content
  267. * @param string $file
  268. *
  269. * @return array
  270. *
  271. * @throws InvalidArgumentException When service file is not valid
  272. */
  273. private function validate($content, $file)
  274. {
  275. if (null === $content) {
  276. return $content;
  277. }
  278. if (!is_array($content)) {
  279. throw new InvalidArgumentException(sprintf('The service file "%s" is not valid. It should contain an array. Check your YAML syntax.', $file));
  280. }
  281. foreach ($content as $namespace => $data) {
  282. if (in_array($namespace, array('imports', 'parameters', 'services'))) {
  283. continue;
  284. }
  285. if (!$this->container->hasExtension($namespace)) {
  286. $extensionNamespaces = array_filter(array_map(function ($ext) { return $ext->getAlias(); }, $this->container->getExtensions()));
  287. throw new InvalidArgumentException(sprintf(
  288. 'There is no extension able to load the configuration for "%s" (in %s). Looked for namespace "%s", found %s',
  289. $namespace,
  290. $file,
  291. $namespace,
  292. $extensionNamespaces ? sprintf('"%s"', implode('", "', $extensionNamespaces)) : 'none'
  293. ));
  294. }
  295. }
  296. return $content;
  297. }
  298. /**
  299. * Resolves services.
  300. *
  301. * @param string|array $value
  302. *
  303. * @return array|string|Reference
  304. */
  305. private function resolveServices($value)
  306. {
  307. if (is_array($value)) {
  308. $value = array_map(array($this, 'resolveServices'), $value);
  309. } elseif (is_string($value) && 0 === strpos($value, '@=')) {
  310. return new Expression(substr($value, 2));
  311. } elseif (is_string($value) && 0 === strpos($value, '@')) {
  312. if (0 === strpos($value, '@@')) {
  313. $value = substr($value, 1);
  314. $invalidBehavior = null;
  315. } elseif (0 === strpos($value, '@?')) {
  316. $value = substr($value, 2);
  317. $invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE;
  318. } else {
  319. $value = substr($value, 1);
  320. $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE;
  321. }
  322. if ('=' === substr($value, -1)) {
  323. $value = substr($value, 0, -1);
  324. $strict = false;
  325. } else {
  326. $strict = true;
  327. }
  328. if (null !== $invalidBehavior) {
  329. $value = new Reference($value, $invalidBehavior, $strict);
  330. }
  331. }
  332. return $value;
  333. }
  334. /**
  335. * Loads from Extensions.
  336. *
  337. * @param array $content
  338. */
  339. private function loadFromExtensions($content)
  340. {
  341. foreach ($content as $namespace => $values) {
  342. if (in_array($namespace, array('imports', 'parameters', 'services'))) {
  343. continue;
  344. }
  345. if (!is_array($values)) {
  346. $values = array();
  347. }
  348. $this->container->loadFromExtension($namespace, $values);
  349. }
  350. }
  351. }