[ Index ]

PHP Cross Reference of phpBB-3.1.12-deutsch

title

Body

[close]

/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Loader/ -> YamlFileLoader.php (source)

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


Generated: Thu Jan 11 00:25:41 2018 Cross-referenced by PHPXref 0.7.1