| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314 | 
							- <?php
 
- /*
 
-  * This file is part of the Symfony package.
 
-  *
 
-  * (c) Fabien Potencier <fabien@symfony.com>
 
-  *
 
-  * For the full copyright and license information, please view the LICENSE
 
-  * file that was distributed with this source code.
 
-  */
 
- namespace Symfony\Component\Routing\Loader;
 
- use Symfony\Component\Config\Loader\FileLoader;
 
- use Symfony\Component\Config\Resource\FileResource;
 
- use Symfony\Component\Routing\Loader\Configurator\Traits\HostTrait;
 
- use Symfony\Component\Routing\Loader\Configurator\Traits\LocalizedRouteTrait;
 
- use Symfony\Component\Routing\Loader\Configurator\Traits\PrefixTrait;
 
- use Symfony\Component\Routing\RouteCollection;
 
- use Symfony\Component\Yaml\Exception\ParseException;
 
- use Symfony\Component\Yaml\Parser as YamlParser;
 
- use Symfony\Component\Yaml\Yaml;
 
- /**
 
-  * YamlFileLoader loads Yaml routing files.
 
-  *
 
-  * @author Fabien Potencier <fabien@symfony.com>
 
-  * @author Tobias Schultze <http://tobion.de>
 
-  */
 
- class YamlFileLoader extends FileLoader
 
- {
 
-     use HostTrait;
 
-     use LocalizedRouteTrait;
 
-     use PrefixTrait;
 
-     private const AVAILABLE_KEYS = [
 
-         'resource', 'type', 'prefix', 'path', 'host', 'schemes', 'methods', 'defaults', 'requirements', 'options', 'condition', 'controller', 'name_prefix', 'trailing_slash_on_root', 'locale', 'format', 'utf8', 'exclude', 'stateless',
 
-     ];
 
-     private $yamlParser;
 
-     /**
 
-      * Loads a Yaml file.
 
-      *
 
-      * @param string      $file A Yaml file path
 
-      * @param string|null $type The resource type
 
-      *
 
-      * @return RouteCollection
 
-      *
 
-      * @throws \InvalidArgumentException When a route can't be parsed because YAML is invalid
 
-      */
 
-     public function load($file, ?string $type = null)
 
-     {
 
-         $path = $this->locator->locate($file);
 
-         if (!stream_is_local($path)) {
 
-             throw new \InvalidArgumentException(sprintf('This is not a local file "%s".', $path));
 
-         }
 
-         if (!file_exists($path)) {
 
-             throw new \InvalidArgumentException(sprintf('File "%s" not found.', $path));
 
-         }
 
-         if (null === $this->yamlParser) {
 
-             $this->yamlParser = new YamlParser();
 
-         }
 
-         try {
 
-             $parsedConfig = $this->yamlParser->parseFile($path, Yaml::PARSE_CONSTANT);
 
-         } catch (ParseException $e) {
 
-             throw new \InvalidArgumentException(sprintf('The file "%s" does not contain valid YAML: ', $path).$e->getMessage(), 0, $e);
 
-         }
 
-         $collection = new RouteCollection();
 
-         $collection->addResource(new FileResource($path));
 
-         // empty file
 
-         if (null === $parsedConfig) {
 
-             return $collection;
 
-         }
 
-         // not an array
 
-         if (!\is_array($parsedConfig)) {
 
-             throw new \InvalidArgumentException(sprintf('The file "%s" must contain a YAML array.', $path));
 
-         }
 
-         foreach ($parsedConfig as $name => $config) {
 
-             if (0 === strpos($name, 'when@')) {
 
-                 if (!$this->env || 'when@'.$this->env !== $name) {
 
-                     continue;
 
-                 }
 
-                 foreach ($config as $name => $config) {
 
-                     $this->validate($config, $name.'" when "@'.$this->env, $path);
 
-                     if (isset($config['resource'])) {
 
-                         $this->parseImport($collection, $config, $path, $file);
 
-                     } else {
 
-                         $this->parseRoute($collection, $name, $config, $path);
 
-                     }
 
-                 }
 
-                 continue;
 
-             }
 
-             $this->validate($config, $name, $path);
 
-             if (isset($config['resource'])) {
 
-                 $this->parseImport($collection, $config, $path, $file);
 
-             } else {
 
-                 $this->parseRoute($collection, $name, $config, $path);
 
-             }
 
-         }
 
-         return $collection;
 
-     }
 
-     /**
 
-      * {@inheritdoc}
 
-      */
 
-     public function supports($resource, ?string $type = null)
 
-     {
 
-         return \is_string($resource) && \in_array(pathinfo($resource, \PATHINFO_EXTENSION), ['yml', 'yaml'], true) && (!$type || 'yaml' === $type);
 
-     }
 
-     /**
 
-      * Parses a route and adds it to the RouteCollection.
 
-      */
 
-     protected function parseRoute(RouteCollection $collection, string $name, array $config, string $path)
 
-     {
 
-         if (isset($config['alias'])) {
 
-             $alias = $collection->addAlias($name, $config['alias']);
 
-             $deprecation = $config['deprecated'] ?? null;
 
-             if (null !== $deprecation) {
 
-                 $alias->setDeprecated(
 
-                     $deprecation['package'],
 
-                     $deprecation['version'],
 
-                     $deprecation['message'] ?? ''
 
-                 );
 
-             }
 
-             return;
 
-         }
 
-         $defaults = $config['defaults'] ?? [];
 
-         $requirements = $config['requirements'] ?? [];
 
-         $options = $config['options'] ?? [];
 
-         foreach ($requirements as $placeholder => $requirement) {
 
-             if (\is_int($placeholder)) {
 
-                 throw new \InvalidArgumentException(sprintf('A placeholder name must be a string (%d given). Did you forget to specify the placeholder key for the requirement "%s" of route "%s" in "%s"?', $placeholder, $requirement, $name, $path));
 
-             }
 
-         }
 
-         if (isset($config['controller'])) {
 
-             $defaults['_controller'] = $config['controller'];
 
-         }
 
-         if (isset($config['locale'])) {
 
-             $defaults['_locale'] = $config['locale'];
 
-         }
 
-         if (isset($config['format'])) {
 
-             $defaults['_format'] = $config['format'];
 
-         }
 
-         if (isset($config['utf8'])) {
 
-             $options['utf8'] = $config['utf8'];
 
-         }
 
-         if (isset($config['stateless'])) {
 
-             $defaults['_stateless'] = $config['stateless'];
 
-         }
 
-         $routes = $this->createLocalizedRoute($collection, $name, $config['path']);
 
-         $routes->addDefaults($defaults);
 
-         $routes->addRequirements($requirements);
 
-         $routes->addOptions($options);
 
-         $routes->setSchemes($config['schemes'] ?? []);
 
-         $routes->setMethods($config['methods'] ?? []);
 
-         $routes->setCondition($config['condition'] ?? null);
 
-         if (isset($config['host'])) {
 
-             $this->addHost($routes, $config['host']);
 
-         }
 
-     }
 
-     /**
 
-      * Parses an import and adds the routes in the resource to the RouteCollection.
 
-      */
 
-     protected function parseImport(RouteCollection $collection, array $config, string $path, string $file)
 
-     {
 
-         $type = $config['type'] ?? null;
 
-         $prefix = $config['prefix'] ?? '';
 
-         $defaults = $config['defaults'] ?? [];
 
-         $requirements = $config['requirements'] ?? [];
 
-         $options = $config['options'] ?? [];
 
-         $host = $config['host'] ?? null;
 
-         $condition = $config['condition'] ?? null;
 
-         $schemes = $config['schemes'] ?? null;
 
-         $methods = $config['methods'] ?? null;
 
-         $trailingSlashOnRoot = $config['trailing_slash_on_root'] ?? true;
 
-         $namePrefix = $config['name_prefix'] ?? null;
 
-         $exclude = $config['exclude'] ?? null;
 
-         if (isset($config['controller'])) {
 
-             $defaults['_controller'] = $config['controller'];
 
-         }
 
-         if (isset($config['locale'])) {
 
-             $defaults['_locale'] = $config['locale'];
 
-         }
 
-         if (isset($config['format'])) {
 
-             $defaults['_format'] = $config['format'];
 
-         }
 
-         if (isset($config['utf8'])) {
 
-             $options['utf8'] = $config['utf8'];
 
-         }
 
-         if (isset($config['stateless'])) {
 
-             $defaults['_stateless'] = $config['stateless'];
 
-         }
 
-         $this->setCurrentDir(\dirname($path));
 
-         /** @var RouteCollection[] $imported */
 
-         $imported = $this->import($config['resource'], $type, false, $file, $exclude) ?: [];
 
-         if (!\is_array($imported)) {
 
-             $imported = [$imported];
 
-         }
 
-         foreach ($imported as $subCollection) {
 
-             $this->addPrefix($subCollection, $prefix, $trailingSlashOnRoot);
 
-             if (null !== $host) {
 
-                 $this->addHost($subCollection, $host);
 
-             }
 
-             if (null !== $condition) {
 
-                 $subCollection->setCondition($condition);
 
-             }
 
-             if (null !== $schemes) {
 
-                 $subCollection->setSchemes($schemes);
 
-             }
 
-             if (null !== $methods) {
 
-                 $subCollection->setMethods($methods);
 
-             }
 
-             if (null !== $namePrefix) {
 
-                 $subCollection->addNamePrefix($namePrefix);
 
-             }
 
-             $subCollection->addDefaults($defaults);
 
-             $subCollection->addRequirements($requirements);
 
-             $subCollection->addOptions($options);
 
-             $collection->addCollection($subCollection);
 
-         }
 
-     }
 
-     /**
 
-      * Validates the route configuration.
 
-      *
 
-      * @param array  $config A resource config
 
-      * @param string $name   The config key
 
-      * @param string $path   The loaded file path
 
-      *
 
-      * @throws \InvalidArgumentException If one of the provided config keys is not supported,
 
-      *                                   something is missing or the combination is nonsense
 
-      */
 
-     protected function validate($config, string $name, string $path)
 
-     {
 
-         if (!\is_array($config)) {
 
-             throw new \InvalidArgumentException(sprintf('The definition of "%s" in "%s" must be a YAML array.', $name, $path));
 
-         }
 
-         if (isset($config['alias'])) {
 
-             $this->validateAlias($config, $name, $path);
 
-             return;
 
-         }
 
-         if ($extraKeys = array_diff(array_keys($config), self::AVAILABLE_KEYS)) {
 
-             throw new \InvalidArgumentException(sprintf('The routing file "%s" contains unsupported keys for "%s": "%s". Expected one of: "%s".', $path, $name, implode('", "', $extraKeys), implode('", "', self::AVAILABLE_KEYS)));
 
-         }
 
-         if (isset($config['resource']) && isset($config['path'])) {
 
-             throw new \InvalidArgumentException(sprintf('The routing file "%s" must not specify both the "resource" key and the "path" key for "%s". Choose between an import and a route definition.', $path, $name));
 
-         }
 
-         if (!isset($config['resource']) && isset($config['type'])) {
 
-             throw new \InvalidArgumentException(sprintf('The "type" key for the route definition "%s" in "%s" is unsupported. It is only available for imports in combination with the "resource" key.', $name, $path));
 
-         }
 
-         if (!isset($config['resource']) && !isset($config['path'])) {
 
-             throw new \InvalidArgumentException(sprintf('You must define a "path" for the route "%s" in file "%s".', $name, $path));
 
-         }
 
-         if (isset($config['controller']) && isset($config['defaults']['_controller'])) {
 
-             throw new \InvalidArgumentException(sprintf('The routing file "%s" must not specify both the "controller" key and the defaults key "_controller" for "%s".', $path, $name));
 
-         }
 
-         if (isset($config['stateless']) && isset($config['defaults']['_stateless'])) {
 
-             throw new \InvalidArgumentException(sprintf('The routing file "%s" must not specify both the "stateless" key and the defaults key "_stateless" for "%s".', $path, $name));
 
-         }
 
-     }
 
-     /**
 
-      * @throws \InvalidArgumentException If one of the provided config keys is not supported,
 
-      *                                   something is missing or the combination is nonsense
 
-      */
 
-     private function validateAlias(array $config, string $name, string $path): void
 
-     {
 
-         foreach ($config as $key => $value) {
 
-             if (!\in_array($key, ['alias', 'deprecated'], true)) {
 
-                 throw new \InvalidArgumentException(sprintf('The routing file "%s" must not specify other keys than "alias" and "deprecated" for "%s".', $path, $name));
 
-             }
 
-             if ('deprecated' === $key) {
 
-                 if (!isset($value['package'])) {
 
-                     throw new \InvalidArgumentException(sprintf('The routing file "%s" must specify the attribute "package" of the "deprecated" option for "%s".', $path, $name));
 
-                 }
 
-                 if (!isset($value['version'])) {
 
-                     throw new \InvalidArgumentException(sprintf('The routing file "%s" must specify the attribute "version" of the "deprecated" option for "%s".', $path, $name));
 
-                 }
 
-             }
 
-         }
 
-     }
 
- }
 
 
  |