annotate vendor/symfony/routing/Loader/YamlFileLoader.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 129ea1e6d783
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 /*
Chris@0 4 * This file is part of the Symfony package.
Chris@0 5 *
Chris@0 6 * (c) Fabien Potencier <fabien@symfony.com>
Chris@0 7 *
Chris@0 8 * For the full copyright and license information, please view the LICENSE
Chris@0 9 * file that was distributed with this source code.
Chris@0 10 */
Chris@0 11
Chris@0 12 namespace Symfony\Component\Routing\Loader;
Chris@0 13
Chris@17 14 use Symfony\Component\Config\Loader\FileLoader;
Chris@17 15 use Symfony\Component\Config\Resource\FileResource;
Chris@17 16 use Symfony\Component\Routing\Route;
Chris@0 17 use Symfony\Component\Routing\RouteCollection;
Chris@0 18 use Symfony\Component\Yaml\Exception\ParseException;
Chris@0 19 use Symfony\Component\Yaml\Parser as YamlParser;
Chris@0 20
Chris@0 21 /**
Chris@0 22 * YamlFileLoader loads Yaml routing files.
Chris@0 23 *
Chris@0 24 * @author Fabien Potencier <fabien@symfony.com>
Chris@0 25 * @author Tobias Schultze <http://tobion.de>
Chris@0 26 */
Chris@0 27 class YamlFileLoader extends FileLoader
Chris@0 28 {
Chris@17 29 private static $availableKeys = [
Chris@14 30 'resource', 'type', 'prefix', 'path', 'host', 'schemes', 'methods', 'defaults', 'requirements', 'options', 'condition', 'controller',
Chris@17 31 ];
Chris@0 32 private $yamlParser;
Chris@0 33
Chris@0 34 /**
Chris@0 35 * Loads a Yaml file.
Chris@0 36 *
Chris@0 37 * @param string $file A Yaml file path
Chris@0 38 * @param string|null $type The resource type
Chris@0 39 *
Chris@0 40 * @return RouteCollection A RouteCollection instance
Chris@0 41 *
Chris@0 42 * @throws \InvalidArgumentException When a route can't be parsed because YAML is invalid
Chris@0 43 */
Chris@0 44 public function load($file, $type = null)
Chris@0 45 {
Chris@0 46 $path = $this->locator->locate($file);
Chris@0 47
Chris@0 48 if (!stream_is_local($path)) {
Chris@0 49 throw new \InvalidArgumentException(sprintf('This is not a local file "%s".', $path));
Chris@0 50 }
Chris@0 51
Chris@0 52 if (!file_exists($path)) {
Chris@0 53 throw new \InvalidArgumentException(sprintf('File "%s" not found.', $path));
Chris@0 54 }
Chris@0 55
Chris@0 56 if (null === $this->yamlParser) {
Chris@0 57 $this->yamlParser = new YamlParser();
Chris@0 58 }
Chris@0 59
Chris@14 60 $prevErrorHandler = set_error_handler(function ($level, $message, $script, $line) use ($file, &$prevErrorHandler) {
Chris@14 61 $message = E_USER_DEPRECATED === $level ? preg_replace('/ on line \d+/', ' in "'.$file.'"$0', $message) : $message;
Chris@14 62
Chris@14 63 return $prevErrorHandler ? $prevErrorHandler($level, $message, $script, $line) : false;
Chris@14 64 });
Chris@14 65
Chris@0 66 try {
Chris@14 67 $parsedConfig = $this->yamlParser->parseFile($path);
Chris@0 68 } catch (ParseException $e) {
Chris@0 69 throw new \InvalidArgumentException(sprintf('The file "%s" does not contain valid YAML.', $path), 0, $e);
Chris@14 70 } finally {
Chris@14 71 restore_error_handler();
Chris@0 72 }
Chris@0 73
Chris@0 74 $collection = new RouteCollection();
Chris@0 75 $collection->addResource(new FileResource($path));
Chris@0 76
Chris@0 77 // empty file
Chris@0 78 if (null === $parsedConfig) {
Chris@0 79 return $collection;
Chris@0 80 }
Chris@0 81
Chris@0 82 // not an array
Chris@17 83 if (!\is_array($parsedConfig)) {
Chris@0 84 throw new \InvalidArgumentException(sprintf('The file "%s" must contain a YAML array.', $path));
Chris@0 85 }
Chris@0 86
Chris@0 87 foreach ($parsedConfig as $name => $config) {
Chris@0 88 $this->validate($config, $name, $path);
Chris@0 89
Chris@0 90 if (isset($config['resource'])) {
Chris@0 91 $this->parseImport($collection, $config, $path, $file);
Chris@0 92 } else {
Chris@0 93 $this->parseRoute($collection, $name, $config, $path);
Chris@0 94 }
Chris@0 95 }
Chris@0 96
Chris@0 97 return $collection;
Chris@0 98 }
Chris@0 99
Chris@0 100 /**
Chris@0 101 * {@inheritdoc}
Chris@0 102 */
Chris@0 103 public function supports($resource, $type = null)
Chris@0 104 {
Chris@17 105 return \is_string($resource) && \in_array(pathinfo($resource, PATHINFO_EXTENSION), ['yml', 'yaml'], true) && (!$type || 'yaml' === $type);
Chris@0 106 }
Chris@0 107
Chris@0 108 /**
Chris@0 109 * Parses a route and adds it to the RouteCollection.
Chris@0 110 *
Chris@0 111 * @param RouteCollection $collection A RouteCollection instance
Chris@0 112 * @param string $name Route name
Chris@0 113 * @param array $config Route definition
Chris@0 114 * @param string $path Full path of the YAML file being processed
Chris@0 115 */
Chris@0 116 protected function parseRoute(RouteCollection $collection, $name, array $config, $path)
Chris@0 117 {
Chris@17 118 $defaults = isset($config['defaults']) ? $config['defaults'] : [];
Chris@17 119 $requirements = isset($config['requirements']) ? $config['requirements'] : [];
Chris@17 120 $options = isset($config['options']) ? $config['options'] : [];
Chris@0 121 $host = isset($config['host']) ? $config['host'] : '';
Chris@17 122 $schemes = isset($config['schemes']) ? $config['schemes'] : [];
Chris@17 123 $methods = isset($config['methods']) ? $config['methods'] : [];
Chris@0 124 $condition = isset($config['condition']) ? $config['condition'] : null;
Chris@0 125
Chris@14 126 if (isset($config['controller'])) {
Chris@14 127 $defaults['_controller'] = $config['controller'];
Chris@14 128 }
Chris@14 129
Chris@0 130 $route = new Route($config['path'], $defaults, $requirements, $options, $host, $schemes, $methods, $condition);
Chris@0 131
Chris@0 132 $collection->add($name, $route);
Chris@0 133 }
Chris@0 134
Chris@0 135 /**
Chris@0 136 * Parses an import and adds the routes in the resource to the RouteCollection.
Chris@0 137 *
Chris@0 138 * @param RouteCollection $collection A RouteCollection instance
Chris@0 139 * @param array $config Route definition
Chris@0 140 * @param string $path Full path of the YAML file being processed
Chris@0 141 * @param string $file Loaded file name
Chris@0 142 */
Chris@0 143 protected function parseImport(RouteCollection $collection, array $config, $path, $file)
Chris@0 144 {
Chris@0 145 $type = isset($config['type']) ? $config['type'] : null;
Chris@0 146 $prefix = isset($config['prefix']) ? $config['prefix'] : '';
Chris@17 147 $defaults = isset($config['defaults']) ? $config['defaults'] : [];
Chris@17 148 $requirements = isset($config['requirements']) ? $config['requirements'] : [];
Chris@17 149 $options = isset($config['options']) ? $config['options'] : [];
Chris@0 150 $host = isset($config['host']) ? $config['host'] : null;
Chris@0 151 $condition = isset($config['condition']) ? $config['condition'] : null;
Chris@0 152 $schemes = isset($config['schemes']) ? $config['schemes'] : null;
Chris@0 153 $methods = isset($config['methods']) ? $config['methods'] : null;
Chris@0 154
Chris@14 155 if (isset($config['controller'])) {
Chris@14 156 $defaults['_controller'] = $config['controller'];
Chris@14 157 }
Chris@14 158
Chris@17 159 $this->setCurrentDir(\dirname($path));
Chris@0 160
Chris@14 161 $imported = $this->import($config['resource'], $type, false, $file);
Chris@14 162
Chris@17 163 if (!\is_array($imported)) {
Chris@17 164 $imported = [$imported];
Chris@0 165 }
Chris@14 166
Chris@14 167 foreach ($imported as $subCollection) {
Chris@14 168 /* @var $subCollection RouteCollection */
Chris@14 169 $subCollection->addPrefix($prefix);
Chris@14 170 if (null !== $host) {
Chris@14 171 $subCollection->setHost($host);
Chris@14 172 }
Chris@14 173 if (null !== $condition) {
Chris@14 174 $subCollection->setCondition($condition);
Chris@14 175 }
Chris@14 176 if (null !== $schemes) {
Chris@14 177 $subCollection->setSchemes($schemes);
Chris@14 178 }
Chris@14 179 if (null !== $methods) {
Chris@14 180 $subCollection->setMethods($methods);
Chris@14 181 }
Chris@14 182 $subCollection->addDefaults($defaults);
Chris@14 183 $subCollection->addRequirements($requirements);
Chris@14 184 $subCollection->addOptions($options);
Chris@14 185
Chris@14 186 $collection->addCollection($subCollection);
Chris@0 187 }
Chris@0 188 }
Chris@0 189
Chris@0 190 /**
Chris@0 191 * Validates the route configuration.
Chris@0 192 *
Chris@0 193 * @param array $config A resource config
Chris@0 194 * @param string $name The config key
Chris@0 195 * @param string $path The loaded file path
Chris@0 196 *
Chris@0 197 * @throws \InvalidArgumentException If one of the provided config keys is not supported,
Chris@0 198 * something is missing or the combination is nonsense
Chris@0 199 */
Chris@0 200 protected function validate($config, $name, $path)
Chris@0 201 {
Chris@17 202 if (!\is_array($config)) {
Chris@0 203 throw new \InvalidArgumentException(sprintf('The definition of "%s" in "%s" must be a YAML array.', $name, $path));
Chris@0 204 }
Chris@0 205 if ($extraKeys = array_diff(array_keys($config), self::$availableKeys)) {
Chris@17 206 throw new \InvalidArgumentException(sprintf('The routing file "%s" contains unsupported keys for "%s": "%s". Expected one of: "%s".', $path, $name, implode('", "', $extraKeys), implode('", "', self::$availableKeys)));
Chris@0 207 }
Chris@0 208 if (isset($config['resource']) && isset($config['path'])) {
Chris@17 209 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));
Chris@0 210 }
Chris@0 211 if (!isset($config['resource']) && isset($config['type'])) {
Chris@17 212 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));
Chris@0 213 }
Chris@0 214 if (!isset($config['resource']) && !isset($config['path'])) {
Chris@17 215 throw new \InvalidArgumentException(sprintf('You must define a "path" for the route "%s" in file "%s".', $name, $path));
Chris@0 216 }
Chris@14 217 if (isset($config['controller']) && isset($config['defaults']['_controller'])) {
Chris@14 218 throw new \InvalidArgumentException(sprintf('The routing file "%s" must not specify both the "controller" key and the defaults key "_controller" for "%s".', $path, $name));
Chris@14 219 }
Chris@0 220 }
Chris@0 221 }