aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/symfony/routing/Symfony/Component/Routing/Loader
diff options
context:
space:
mode:
authorNicolas LÅ“uillet <nicolas.loeuillet@gmail.com>2013-08-03 19:26:54 +0200
committerNicolas LÅ“uillet <nicolas.loeuillet@gmail.com>2013-08-03 19:26:54 +0200
commit4f5b44bd3bd490309eb2ba7b44df4769816ba729 (patch)
tree6cefe170dfe0a5a361cb1e2d1fc4d580a3316d02 /vendor/symfony/routing/Symfony/Component/Routing/Loader
parent2b840e0cfb63a453bea67a98541f3df9c273c5f5 (diff)
downloadwallabag-4f5b44bd3bd490309eb2ba7b44df4769816ba729.tar.gz
wallabag-4f5b44bd3bd490309eb2ba7b44df4769816ba729.tar.zst
wallabag-4f5b44bd3bd490309eb2ba7b44df4769816ba729.zip
twig implementation
Diffstat (limited to 'vendor/symfony/routing/Symfony/Component/Routing/Loader')
-rw-r--r--vendor/symfony/routing/Symfony/Component/Routing/Loader/AnnotationClassLoader.php246
-rw-r--r--vendor/symfony/routing/Symfony/Component/Routing/Loader/AnnotationDirectoryLoader.php77
-rw-r--r--vendor/symfony/routing/Symfony/Component/Routing/Loader/AnnotationFileLoader.php122
-rw-r--r--vendor/symfony/routing/Symfony/Component/Routing/Loader/ClosureLoader.php52
-rw-r--r--vendor/symfony/routing/Symfony/Component/Routing/Loader/PhpFileLoader.php62
-rw-r--r--vendor/symfony/routing/Symfony/Component/Routing/Loader/XmlFileLoader.php238
-rw-r--r--vendor/symfony/routing/Symfony/Component/Routing/Loader/YamlFileLoader.php212
-rw-r--r--vendor/symfony/routing/Symfony/Component/Routing/Loader/schema/routing/routing-1.0.xsd64
8 files changed, 1073 insertions, 0 deletions
diff --git a/vendor/symfony/routing/Symfony/Component/Routing/Loader/AnnotationClassLoader.php b/vendor/symfony/routing/Symfony/Component/Routing/Loader/AnnotationClassLoader.php
new file mode 100644
index 00000000..9831d85a
--- /dev/null
+++ b/vendor/symfony/routing/Symfony/Component/Routing/Loader/AnnotationClassLoader.php
@@ -0,0 +1,246 @@
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
12namespace Symfony\Component\Routing\Loader;
13
14use Doctrine\Common\Annotations\Reader;
15use Symfony\Component\Config\Resource\FileResource;
16use Symfony\Component\Routing\Route;
17use Symfony\Component\Routing\RouteCollection;
18use Symfony\Component\Config\Loader\LoaderInterface;
19use Symfony\Component\Config\Loader\LoaderResolverInterface;
20
21/**
22 * AnnotationClassLoader loads routing information from a PHP class and its methods.
23 *
24 * You need to define an implementation for the getRouteDefaults() method. Most of the
25 * time, this method should define some PHP callable to be called for the route
26 * (a controller in MVC speak).
27 *
28 * The @Route annotation can be set on the class (for global parameters),
29 * and on each method.
30 *
31 * The @Route annotation main value is the route path. The annotation also
32 * recognizes several parameters: requirements, options, defaults, schemes,
33 * methods, host, and name. The name parameter is mandatory.
34 * Here is an example of how you should be able to use it:
35 *
36 * /**
37 * * @Route("/Blog")
38 * * /
39 * class Blog
40 * {
41 * /**
42 * * @Route("/", name="blog_index")
43 * * /
44 * public function index()
45 * {
46 * }
47 *
48 * /**
49 * * @Route("/{id}", name="blog_post", requirements = {"id" = "\d+"})
50 * * /
51 * public function show()
52 * {
53 * }
54 * }
55 *
56 * @author Fabien Potencier <fabien@symfony.com>
57 */
58abstract class AnnotationClassLoader implements LoaderInterface
59{
60 /**
61 * @var Reader
62 */
63 protected $reader;
64
65 /**
66 * @var string
67 */
68 protected $routeAnnotationClass = 'Symfony\\Component\\Routing\\Annotation\\Route';
69
70 /**
71 * @var integer
72 */
73 protected $defaultRouteIndex = 0;
74
75 /**
76 * Constructor.
77 *
78 * @param Reader $reader
79 */
80 public function __construct(Reader $reader)
81 {
82 $this->reader = $reader;
83 }
84
85 /**
86 * Sets the annotation class to read route properties from.
87 *
88 * @param string $class A fully-qualified class name
89 */
90 public function setRouteAnnotationClass($class)
91 {
92 $this->routeAnnotationClass = $class;
93 }
94
95 /**
96 * Loads from annotations from a class.
97 *
98 * @param string $class A class name
99 * @param string|null $type The resource type
100 *
101 * @return RouteCollection A RouteCollection instance
102 *
103 * @throws \InvalidArgumentException When route can't be parsed
104 */
105 public function load($class, $type = null)
106 {
107 if (!class_exists($class)) {
108 throw new \InvalidArgumentException(sprintf('Class "%s" does not exist.', $class));
109 }
110
111 $globals = array(
112 'path' => '',
113 'requirements' => array(),
114 'options' => array(),
115 'defaults' => array(),
116 'schemes' => array(),
117 'methods' => array(),
118 'host' => '',
119 );
120
121 $class = new \ReflectionClass($class);
122 if ($class->isAbstract()) {
123 throw new \InvalidArgumentException(sprintf('Annotations from class "%s" cannot be read as it is abstract.', $class));
124 }
125
126 if ($annot = $this->reader->getClassAnnotation($class, $this->routeAnnotationClass)) {
127 // for BC reasons
128 if (null !== $annot->getPath()) {
129 $globals['path'] = $annot->getPath();
130 } elseif (null !== $annot->getPattern()) {
131 $globals['path'] = $annot->getPattern();
132 }
133
134 if (null !== $annot->getRequirements()) {
135 $globals['requirements'] = $annot->getRequirements();
136 }
137
138 if (null !== $annot->getOptions()) {
139 $globals['options'] = $annot->getOptions();
140 }
141
142 if (null !== $annot->getDefaults()) {
143 $globals['defaults'] = $annot->getDefaults();
144 }
145
146 if (null !== $annot->getSchemes()) {
147 $globals['schemes'] = $annot->getSchemes();
148 }
149
150 if (null !== $annot->getMethods()) {
151 $globals['methods'] = $annot->getMethods();
152 }
153
154 if (null !== $annot->getHost()) {
155 $globals['host'] = $annot->getHost();
156 }
157 }
158
159 $collection = new RouteCollection();
160 $collection->addResource(new FileResource($class->getFileName()));
161
162 foreach ($class->getMethods() as $method) {
163 $this->defaultRouteIndex = 0;
164 foreach ($this->reader->getMethodAnnotations($method) as $annot) {
165 if ($annot instanceof $this->routeAnnotationClass) {
166 $this->addRoute($collection, $annot, $globals, $class, $method);
167 }
168 }
169 }
170
171 return $collection;
172 }
173
174 protected function addRoute(RouteCollection $collection, $annot, $globals, \ReflectionClass $class, \ReflectionMethod $method)
175 {
176 $name = $annot->getName();
177 if (null === $name) {
178 $name = $this->getDefaultRouteName($class, $method);
179 }
180
181 $defaults = array_replace($globals['defaults'], $annot->getDefaults());
182 foreach ($method->getParameters() as $param) {
183 if ($param->isOptional()) {
184 $defaults[$param->getName()] = $param->getDefaultValue();
185 }
186 }
187 $requirements = array_replace($globals['requirements'], $annot->getRequirements());
188 $options = array_replace($globals['options'], $annot->getOptions());
189 $schemes = array_replace($globals['schemes'], $annot->getSchemes());
190 $methods = array_replace($globals['methods'], $annot->getMethods());
191
192 $host = $annot->getHost();
193 if (null === $host) {
194 $host = $globals['host'];
195 }
196
197 $route = new Route($globals['path'].$annot->getPath(), $defaults, $requirements, $options, $host, $schemes, $methods);
198
199 $this->configureRoute($route, $class, $method, $annot);
200
201 $collection->add($name, $route);
202 }
203
204 /**
205 * {@inheritdoc}
206 */
207 public function supports($resource, $type = null)
208 {
209 return is_string($resource) && preg_match('/^(?:\\\\?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)+$/', $resource) && (!$type || 'annotation' === $type);
210 }
211
212 /**
213 * {@inheritdoc}
214 */
215 public function setResolver(LoaderResolverInterface $resolver)
216 {
217 }
218
219 /**
220 * {@inheritdoc}
221 */
222 public function getResolver()
223 {
224 }
225
226 /**
227 * Gets the default route name for a class method.
228 *
229 * @param \ReflectionClass $class
230 * @param \ReflectionMethod $method
231 *
232 * @return string
233 */
234 protected function getDefaultRouteName(\ReflectionClass $class, \ReflectionMethod $method)
235 {
236 $name = strtolower(str_replace('\\', '_', $class->name).'_'.$method->name);
237 if ($this->defaultRouteIndex > 0) {
238 $name .= '_'.$this->defaultRouteIndex;
239 }
240 $this->defaultRouteIndex++;
241
242 return $name;
243 }
244
245 abstract protected function configureRoute(Route $route, \ReflectionClass $class, \ReflectionMethod $method, $annot);
246}
diff --git a/vendor/symfony/routing/Symfony/Component/Routing/Loader/AnnotationDirectoryLoader.php b/vendor/symfony/routing/Symfony/Component/Routing/Loader/AnnotationDirectoryLoader.php
new file mode 100644
index 00000000..abd68ed6
--- /dev/null
+++ b/vendor/symfony/routing/Symfony/Component/Routing/Loader/AnnotationDirectoryLoader.php
@@ -0,0 +1,77 @@
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
12namespace Symfony\Component\Routing\Loader;
13
14use Symfony\Component\Routing\RouteCollection;
15use Symfony\Component\Config\Resource\DirectoryResource;
16
17/**
18 * AnnotationDirectoryLoader loads routing information from annotations set
19 * on PHP classes and methods.
20 *
21 * @author Fabien Potencier <fabien@symfony.com>
22 */
23class AnnotationDirectoryLoader extends AnnotationFileLoader
24{
25 /**
26 * Loads from annotations from a directory.
27 *
28 * @param string $path A directory path
29 * @param string|null $type The resource type
30 *
31 * @return RouteCollection A RouteCollection instance
32 *
33 * @throws \InvalidArgumentException When the directory does not exist or its routes cannot be parsed
34 */
35 public function load($path, $type = null)
36 {
37 $dir = $this->locator->locate($path);
38
39 $collection = new RouteCollection();
40 $collection->addResource(new DirectoryResource($dir, '/\.php$/'));
41 $files = iterator_to_array(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir), \RecursiveIteratorIterator::LEAVES_ONLY));
42 usort($files, function (\SplFileInfo $a, \SplFileInfo $b) {
43 return (string) $a > (string) $b ? 1 : -1;
44 });
45
46 foreach ($files as $file) {
47 if (!$file->isFile() || '.php' !== substr($file->getFilename(), -4)) {
48 continue;
49 }
50
51 if ($class = $this->findClass($file)) {
52 $refl = new \ReflectionClass($class);
53 if ($refl->isAbstract()) {
54 continue;
55 }
56
57 $collection->addCollection($this->loader->load($class, $type));
58 }
59 }
60
61 return $collection;
62 }
63
64 /**
65 * {@inheritdoc}
66 */
67 public function supports($resource, $type = null)
68 {
69 try {
70 $path = $this->locator->locate($resource);
71 } catch (\Exception $e) {
72 return false;
73 }
74
75 return is_string($resource) && is_dir($path) && (!$type || 'annotation' === $type);
76 }
77}
diff --git a/vendor/symfony/routing/Symfony/Component/Routing/Loader/AnnotationFileLoader.php b/vendor/symfony/routing/Symfony/Component/Routing/Loader/AnnotationFileLoader.php
new file mode 100644
index 00000000..33776fdc
--- /dev/null
+++ b/vendor/symfony/routing/Symfony/Component/Routing/Loader/AnnotationFileLoader.php
@@ -0,0 +1,122 @@
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
12namespace Symfony\Component\Routing\Loader;
13
14use Symfony\Component\Routing\RouteCollection;
15use Symfony\Component\Config\Resource\FileResource;
16use Symfony\Component\Config\Loader\FileLoader;
17use Symfony\Component\Config\FileLocatorInterface;
18
19/**
20 * AnnotationFileLoader loads routing information from annotations set
21 * on a PHP class and its methods.
22 *
23 * @author Fabien Potencier <fabien@symfony.com>
24 */
25class AnnotationFileLoader extends FileLoader
26{
27 protected $loader;
28
29 /**
30 * Constructor.
31 *
32 * @param FileLocatorInterface $locator A FileLocator instance
33 * @param AnnotationClassLoader $loader An AnnotationClassLoader instance
34 * @param string|array $paths A path or an array of paths where to look for resources
35 *
36 * @throws \RuntimeException
37 */
38 public function __construct(FileLocatorInterface $locator, AnnotationClassLoader $loader, $paths = array())
39 {
40 if (!function_exists('token_get_all')) {
41 throw new \RuntimeException('The Tokenizer extension is required for the routing annotation loaders.');
42 }
43
44 parent::__construct($locator, $paths);
45
46 $this->loader = $loader;
47 }
48
49 /**
50 * Loads from annotations from a file.
51 *
52 * @param string $file A PHP file path
53 * @param string|null $type The resource type
54 *
55 * @return RouteCollection A RouteCollection instance
56 *
57 * @throws \InvalidArgumentException When the file does not exist or its routes cannot be parsed
58 */
59 public function load($file, $type = null)
60 {
61 $path = $this->locator->locate($file);
62
63 $collection = new RouteCollection();
64 if ($class = $this->findClass($path)) {
65 $collection->addResource(new FileResource($path));
66 $collection->addCollection($this->loader->load($class, $type));
67 }
68
69 return $collection;
70 }
71
72 /**
73 * {@inheritdoc}
74 */
75 public function supports($resource, $type = null)
76 {
77 return is_string($resource) && 'php' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'annotation' === $type);
78 }
79
80 /**
81 * Returns the full class name for the first class in the file.
82 *
83 * @param string $file A PHP file path
84 *
85 * @return string|false Full class name if found, false otherwise
86 */
87 protected function findClass($file)
88 {
89 $class = false;
90 $namespace = false;
91 $tokens = token_get_all(file_get_contents($file));
92 for ($i = 0, $count = count($tokens); $i < $count; $i++) {
93 $token = $tokens[$i];
94
95 if (!is_array($token)) {
96 continue;
97 }
98
99 if (true === $class && T_STRING === $token[0]) {
100 return $namespace.'\\'.$token[1];
101 }
102
103 if (true === $namespace && T_STRING === $token[0]) {
104 $namespace = '';
105 do {
106 $namespace .= $token[1];
107 $token = $tokens[++$i];
108 } while ($i < $count && is_array($token) && in_array($token[0], array(T_NS_SEPARATOR, T_STRING)));
109 }
110
111 if (T_CLASS === $token[0]) {
112 $class = true;
113 }
114
115 if (T_NAMESPACE === $token[0]) {
116 $namespace = true;
117 }
118 }
119
120 return false;
121 }
122}
diff --git a/vendor/symfony/routing/Symfony/Component/Routing/Loader/ClosureLoader.php b/vendor/symfony/routing/Symfony/Component/Routing/Loader/ClosureLoader.php
new file mode 100644
index 00000000..8212c291
--- /dev/null
+++ b/vendor/symfony/routing/Symfony/Component/Routing/Loader/ClosureLoader.php
@@ -0,0 +1,52 @@
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
12namespace Symfony\Component\Routing\Loader;
13
14use Symfony\Component\Config\Loader\Loader;
15use Symfony\Component\Routing\RouteCollection;
16
17/**
18 * ClosureLoader loads routes from a PHP closure.
19 *
20 * The Closure must return a RouteCollection instance.
21 *
22 * @author Fabien Potencier <fabien@symfony.com>
23 *
24 * @api
25 */
26class ClosureLoader extends Loader
27{
28 /**
29 * Loads a Closure.
30 *
31 * @param \Closure $closure A Closure
32 * @param string|null $type The resource type
33 *
34 * @return RouteCollection A RouteCollection instance
35 *
36 * @api
37 */
38 public function load($closure, $type = null)
39 {
40 return call_user_func($closure);
41 }
42
43 /**
44 * {@inheritdoc}
45 *
46 * @api
47 */
48 public function supports($resource, $type = null)
49 {
50 return $resource instanceof \Closure && (!$type || 'closure' === $type);
51 }
52}
diff --git a/vendor/symfony/routing/Symfony/Component/Routing/Loader/PhpFileLoader.php b/vendor/symfony/routing/Symfony/Component/Routing/Loader/PhpFileLoader.php
new file mode 100644
index 00000000..98b7efbf
--- /dev/null
+++ b/vendor/symfony/routing/Symfony/Component/Routing/Loader/PhpFileLoader.php
@@ -0,0 +1,62 @@
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
12namespace Symfony\Component\Routing\Loader;
13
14use Symfony\Component\Config\Loader\FileLoader;
15use Symfony\Component\Config\Resource\FileResource;
16use Symfony\Component\Routing\RouteCollection;
17
18/**
19 * PhpFileLoader loads routes from a PHP file.
20 *
21 * The file must return a RouteCollection instance.
22 *
23 * @author Fabien Potencier <fabien@symfony.com>
24 *
25 * @api
26 */
27class PhpFileLoader extends FileLoader
28{
29 /**
30 * Loads a PHP file.
31 *
32 * @param string $file A PHP file path
33 * @param string|null $type The resource type
34 *
35 * @return RouteCollection A RouteCollection instance
36 *
37 * @api
38 */
39 public function load($file, $type = null)
40 {
41 // the loader variable is exposed to the included file below
42 $loader = $this;
43
44 $path = $this->locator->locate($file);
45 $this->setCurrentDir(dirname($path));
46
47 $collection = include $path;
48 $collection->addResource(new FileResource($path));
49
50 return $collection;
51 }
52
53 /**
54 * {@inheritdoc}
55 *
56 * @api
57 */
58 public function supports($resource, $type = null)
59 {
60 return is_string($resource) && 'php' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'php' === $type);
61 }
62}
diff --git a/vendor/symfony/routing/Symfony/Component/Routing/Loader/XmlFileLoader.php b/vendor/symfony/routing/Symfony/Component/Routing/Loader/XmlFileLoader.php
new file mode 100644
index 00000000..da7b33d8
--- /dev/null
+++ b/vendor/symfony/routing/Symfony/Component/Routing/Loader/XmlFileLoader.php
@@ -0,0 +1,238 @@
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
12namespace Symfony\Component\Routing\Loader;
13
14use Symfony\Component\Routing\RouteCollection;
15use Symfony\Component\Routing\Route;
16use Symfony\Component\Config\Resource\FileResource;
17use Symfony\Component\Config\Loader\FileLoader;
18use Symfony\Component\Config\Util\XmlUtils;
19
20/**
21 * XmlFileLoader loads XML routing files.
22 *
23 * @author Fabien Potencier <fabien@symfony.com>
24 * @author Tobias Schultze <http://tobion.de>
25 *
26 * @api
27 */
28class XmlFileLoader extends FileLoader
29{
30 const NAMESPACE_URI = 'http://symfony.com/schema/routing';
31 const SCHEME_PATH = '/schema/routing/routing-1.0.xsd';
32
33 /**
34 * Loads an XML file.
35 *
36 * @param string $file An XML file path
37 * @param string|null $type The resource type
38 *
39 * @return RouteCollection A RouteCollection instance
40 *
41 * @throws \InvalidArgumentException When the file cannot be loaded or when the XML cannot be
42 * parsed because it does not validate against the scheme.
43 *
44 * @api
45 */
46 public function load($file, $type = null)
47 {
48 $path = $this->locator->locate($file);
49
50 $xml = $this->loadFile($path);
51
52 $collection = new RouteCollection();
53 $collection->addResource(new FileResource($path));
54
55 // process routes and imports
56 foreach ($xml->documentElement->childNodes as $node) {
57 if (!$node instanceof \DOMElement) {
58 continue;
59 }
60
61 $this->parseNode($collection, $node, $path, $file);
62 }
63
64 return $collection;
65 }
66
67 /**
68 * Parses a node from a loaded XML file.
69 *
70 * @param RouteCollection $collection Collection to associate with the node
71 * @param \DOMElement $node Element to parse
72 * @param string $path Full path of the XML file being processed
73 * @param string $file Loaded file name
74 *
75 * @throws \InvalidArgumentException When the XML is invalid
76 */
77 protected function parseNode(RouteCollection $collection, \DOMElement $node, $path, $file)
78 {
79 if (self::NAMESPACE_URI !== $node->namespaceURI) {
80 return;
81 }
82
83 switch ($node->localName) {
84 case 'route':
85 $this->parseRoute($collection, $node, $path);
86 break;
87 case 'import':
88 $this->parseImport($collection, $node, $path, $file);
89 break;
90 default:
91 throw new \InvalidArgumentException(sprintf('Unknown tag "%s" used in file "%s". Expected "route" or "import".', $node->localName, $path));
92 }
93 }
94
95 /**
96 * {@inheritdoc}
97 *
98 * @api
99 */
100 public function supports($resource, $type = null)
101 {
102 return is_string($resource) && 'xml' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'xml' === $type);
103 }
104
105 /**
106 * Parses a route and adds it to the RouteCollection.
107 *
108 * @param RouteCollection $collection RouteCollection instance
109 * @param \DOMElement $node Element to parse that represents a Route
110 * @param string $path Full path of the XML file being processed
111 *
112 * @throws \InvalidArgumentException When the XML is invalid
113 */
114 protected function parseRoute(RouteCollection $collection, \DOMElement $node, $path)
115 {
116 if ('' === ($id = $node->getAttribute('id')) || (!$node->hasAttribute('pattern') && !$node->hasAttribute('path'))) {
117 throw new \InvalidArgumentException(sprintf('The <route> element in file "%s" must have an "id" and a "path" attribute.', $path));
118 }
119
120 if ($node->hasAttribute('pattern')) {
121 if ($node->hasAttribute('path')) {
122 throw new \InvalidArgumentException(sprintf('The <route> element in file "%s" cannot define both a "path" and a "pattern" attribute. Use only "path".', $path));
123 }
124
125 $node->setAttribute('path', $node->getAttribute('pattern'));
126 $node->removeAttribute('pattern');
127 }
128
129 $schemes = preg_split('/[\s,\|]++/', $node->getAttribute('schemes'), -1, PREG_SPLIT_NO_EMPTY);
130 $methods = preg_split('/[\s,\|]++/', $node->getAttribute('methods'), -1, PREG_SPLIT_NO_EMPTY);
131
132 list($defaults, $requirements, $options) = $this->parseConfigs($node, $path);
133
134 $route = new Route($node->getAttribute('path'), $defaults, $requirements, $options, $node->getAttribute('host'), $schemes, $methods);
135 $collection->add($id, $route);
136 }
137
138 /**
139 * Parses an import and adds the routes in the resource to the RouteCollection.
140 *
141 * @param RouteCollection $collection RouteCollection instance
142 * @param \DOMElement $node Element to parse that represents a Route
143 * @param string $path Full path of the XML file being processed
144 * @param string $file Loaded file name
145 *
146 * @throws \InvalidArgumentException When the XML is invalid
147 */
148 protected function parseImport(RouteCollection $collection, \DOMElement $node, $path, $file)
149 {
150 if ('' === $resource = $node->getAttribute('resource')) {
151 throw new \InvalidArgumentException(sprintf('The <import> element in file "%s" must have a "resource" attribute.', $path));
152 }
153
154 $type = $node->getAttribute('type');
155 $prefix = $node->getAttribute('prefix');
156 $host = $node->hasAttribute('host') ? $node->getAttribute('host') : null;
157 $schemes = $node->hasAttribute('schemes') ? preg_split('/[\s,\|]++/', $node->getAttribute('schemes'), -1, PREG_SPLIT_NO_EMPTY) : null;
158 $methods = $node->hasAttribute('methods') ? preg_split('/[\s,\|]++/', $node->getAttribute('methods'), -1, PREG_SPLIT_NO_EMPTY) : null;
159
160 list($defaults, $requirements, $options) = $this->parseConfigs($node, $path);
161
162 $this->setCurrentDir(dirname($path));
163
164 $subCollection = $this->import($resource, ('' !== $type ? $type : null), false, $file);
165 /* @var $subCollection RouteCollection */
166 $subCollection->addPrefix($prefix);
167 if (null !== $host) {
168 $subCollection->setHost($host);
169 }
170 if (null !== $schemes) {
171 $subCollection->setSchemes($schemes);
172 }
173 if (null !== $methods) {
174 $subCollection->setMethods($methods);
175 }
176 $subCollection->addDefaults($defaults);
177 $subCollection->addRequirements($requirements);
178 $subCollection->addOptions($options);
179
180 $collection->addCollection($subCollection);
181 }
182
183 /**
184 * Loads an XML file.
185 *
186 * @param string $file An XML file path
187 *
188 * @return \DOMDocument
189 *
190 * @throws \InvalidArgumentException When loading of XML file fails because of syntax errors
191 * or when the XML structure is not as expected by the scheme -
192 * see validate()
193 */
194 protected function loadFile($file)
195 {
196 return XmlUtils::loadFile($file, __DIR__.static::SCHEME_PATH);
197 }
198
199 /**
200 * Parses the config elements (default, requirement, option).
201 *
202 * @param \DOMElement $node Element to parse that contains the configs
203 * @param string $path Full path of the XML file being processed
204 *
205 * @return array An array with the defaults as first item, requirements as second and options as third.
206 *
207 * @throws \InvalidArgumentException When the XML is invalid
208 */
209 private function parseConfigs(\DOMElement $node, $path)
210 {
211 $defaults = array();
212 $requirements = array();
213 $options = array();
214
215 foreach ($node->getElementsByTagNameNS(self::NAMESPACE_URI, '*') as $n) {
216 switch ($n->localName) {
217 case 'default':
218 if ($n->hasAttribute('xsi:nil') && 'true' == $n->getAttribute('xsi:nil')) {
219 $defaults[$n->getAttribute('key')] = null;
220 } else {
221 $defaults[$n->getAttribute('key')] = trim($n->textContent);
222 }
223
224 break;
225 case 'requirement':
226 $requirements[$n->getAttribute('key')] = trim($n->textContent);
227 break;
228 case 'option':
229 $options[$n->getAttribute('key')] = trim($n->textContent);
230 break;
231 default:
232 throw new \InvalidArgumentException(sprintf('Unknown tag "%s" used in file "%s". Expected "default", "requirement" or "option".', $n->localName, $path));
233 }
234 }
235
236 return array($defaults, $requirements, $options);
237 }
238}
diff --git a/vendor/symfony/routing/Symfony/Component/Routing/Loader/YamlFileLoader.php b/vendor/symfony/routing/Symfony/Component/Routing/Loader/YamlFileLoader.php
new file mode 100644
index 00000000..9deea7fe
--- /dev/null
+++ b/vendor/symfony/routing/Symfony/Component/Routing/Loader/YamlFileLoader.php
@@ -0,0 +1,212 @@
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
12namespace Symfony\Component\Routing\Loader;
13
14use Symfony\Component\Routing\RouteCollection;
15use Symfony\Component\Routing\Route;
16use Symfony\Component\Config\Resource\FileResource;
17use Symfony\Component\Yaml\Parser as YamlParser;
18use Symfony\Component\Config\Loader\FileLoader;
19
20/**
21 * YamlFileLoader loads Yaml routing files.
22 *
23 * @author Fabien Potencier <fabien@symfony.com>
24 * @author Tobias Schultze <http://tobion.de>
25 *
26 * @api
27 */
28class YamlFileLoader extends FileLoader
29{
30 private static $availableKeys = array(
31 'resource', 'type', 'prefix', 'pattern', 'path', 'host', 'schemes', 'methods', 'defaults', 'requirements', 'options',
32 );
33 private $yamlParser;
34
35 /**
36 * Loads a Yaml file.
37 *
38 * @param string $file A Yaml file path
39 * @param string|null $type The resource type
40 *
41 * @return RouteCollection A RouteCollection instance
42 *
43 * @throws \InvalidArgumentException When a route can't be parsed because YAML is invalid
44 *
45 * @api
46 */
47 public function load($file, $type = null)
48 {
49 $path = $this->locator->locate($file);
50
51 if (!stream_is_local($path)) {
52 throw new \InvalidArgumentException(sprintf('This is not a local file "%s".', $path));
53 }
54
55 if (!file_exists($path)) {
56 throw new \InvalidArgumentException(sprintf('File "%s" not found.', $path));
57 }
58
59 if (null === $this->yamlParser) {
60 $this->yamlParser = new YamlParser();
61 }
62
63 $config = $this->yamlParser->parse(file_get_contents($path));
64
65 $collection = new RouteCollection();
66 $collection->addResource(new FileResource($path));
67
68 // empty file
69 if (null === $config) {
70 return $collection;
71 }
72
73 // not an array
74 if (!is_array($config)) {
75 throw new \InvalidArgumentException(sprintf('The file "%s" must contain a YAML array.', $path));
76 }
77
78 foreach ($config as $name => $config) {
79 if (isset($config['pattern'])) {
80 if (isset($config['path'])) {
81 throw new \InvalidArgumentException(sprintf('The file "%s" cannot define both a "path" and a "pattern" attribute. Use only "path".', $path));
82 }
83
84 $config['path'] = $config['pattern'];
85 unset($config['pattern']);
86 }
87
88 $this->validate($config, $name, $path);
89
90 if (isset($config['resource'])) {
91 $this->parseImport($collection, $config, $path, $file);
92 } else {
93 $this->parseRoute($collection, $name, $config, $path);
94 }
95 }
96
97 return $collection;
98 }
99
100 /**
101 * {@inheritdoc}
102 *
103 * @api
104 */
105 public function supports($resource, $type = null)
106 {
107 return is_string($resource) && 'yml' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'yaml' === $type);
108 }
109
110 /**
111 * Parses a route and adds it to the RouteCollection.
112 *
113 * @param RouteCollection $collection A RouteCollection instance
114 * @param string $name Route name
115 * @param array $config Route definition
116 * @param string $path Full path of the YAML file being processed
117 */
118 protected function parseRoute(RouteCollection $collection, $name, array $config, $path)
119 {
120 $defaults = isset($config['defaults']) ? $config['defaults'] : array();
121 $requirements = isset($config['requirements']) ? $config['requirements'] : array();
122 $options = isset($config['options']) ? $config['options'] : array();
123 $host = isset($config['host']) ? $config['host'] : '';
124 $schemes = isset($config['schemes']) ? $config['schemes'] : array();
125 $methods = isset($config['methods']) ? $config['methods'] : array();
126
127 $route = new Route($config['path'], $defaults, $requirements, $options, $host, $schemes, $methods);
128
129 $collection->add($name, $route);
130 }
131
132 /**
133 * Parses an import and adds the routes in the resource to the RouteCollection.
134 *
135 * @param RouteCollection $collection A RouteCollection instance
136 * @param array $config Route definition
137 * @param string $path Full path of the YAML file being processed
138 * @param string $file Loaded file name
139 */
140 protected function parseImport(RouteCollection $collection, array $config, $path, $file)
141 {
142 $type = isset($config['type']) ? $config['type'] : null;
143 $prefix = isset($config['prefix']) ? $config['prefix'] : '';
144 $defaults = isset($config['defaults']) ? $config['defaults'] : array();
145 $requirements = isset($config['requirements']) ? $config['requirements'] : array();
146 $options = isset($config['options']) ? $config['options'] : array();
147 $host = isset($config['host']) ? $config['host'] : null;
148 $schemes = isset($config['schemes']) ? $config['schemes'] : null;
149 $methods = isset($config['methods']) ? $config['methods'] : null;
150
151 $this->setCurrentDir(dirname($path));
152
153 $subCollection = $this->import($config['resource'], $type, false, $file);
154 /* @var $subCollection RouteCollection */
155 $subCollection->addPrefix($prefix);
156 if (null !== $host) {
157 $subCollection->setHost($host);
158 }
159 if (null !== $schemes) {
160 $subCollection->setSchemes($schemes);
161 }
162 if (null !== $methods) {
163 $subCollection->setMethods($methods);
164 }
165 $subCollection->addDefaults($defaults);
166 $subCollection->addRequirements($requirements);
167 $subCollection->addOptions($options);
168
169 $collection->addCollection($subCollection);
170 }
171
172 /**
173 * Validates the route configuration.
174 *
175 * @param array $config A resource config
176 * @param string $name The config key
177 * @param string $path The loaded file path
178 *
179 * @throws \InvalidArgumentException If one of the provided config keys is not supported,
180 * something is missing or the combination is nonsense
181 */
182 protected function validate($config, $name, $path)
183 {
184 if (!is_array($config)) {
185 throw new \InvalidArgumentException(sprintf('The definition of "%s" in "%s" must be a YAML array.', $name, $path));
186 }
187 if ($extraKeys = array_diff(array_keys($config), self::$availableKeys)) {
188 throw new \InvalidArgumentException(sprintf(
189 'The routing file "%s" contains unsupported keys for "%s": "%s". Expected one of: "%s".',
190 $path, $name, implode('", "', $extraKeys), implode('", "', self::$availableKeys)
191 ));
192 }
193 if (isset($config['resource']) && isset($config['path'])) {
194 throw new \InvalidArgumentException(sprintf(
195 '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.',
196 $path, $name
197 ));
198 }
199 if (!isset($config['resource']) && isset($config['type'])) {
200 throw new \InvalidArgumentException(sprintf(
201 'The "type" key for the route definition "%s" in "%s" is unsupported. It is only available for imports in combination with the "resource" key.',
202 $name, $path
203 ));
204 }
205 if (!isset($config['resource']) && !isset($config['path'])) {
206 throw new \InvalidArgumentException(sprintf(
207 'You must define a "path" for the route "%s" in file "%s".',
208 $name, $path
209 ));
210 }
211 }
212}
diff --git a/vendor/symfony/routing/Symfony/Component/Routing/Loader/schema/routing/routing-1.0.xsd b/vendor/symfony/routing/Symfony/Component/Routing/Loader/schema/routing/routing-1.0.xsd
new file mode 100644
index 00000000..daea8143
--- /dev/null
+++ b/vendor/symfony/routing/Symfony/Component/Routing/Loader/schema/routing/routing-1.0.xsd
@@ -0,0 +1,64 @@
1<?xml version="1.0" encoding="UTF-8" ?>
2
3<xsd:schema xmlns="http://symfony.com/schema/routing"
4 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
5 targetNamespace="http://symfony.com/schema/routing"
6 elementFormDefault="qualified">
7
8 <xsd:annotation>
9 <xsd:documentation><![CDATA[
10 Symfony XML Routing Schema, version 1.0
11 Authors: Fabien Potencier, Tobias Schultze
12
13 This scheme defines the elements and attributes that can be used to define
14 routes. A route maps an HTTP request to a set of configuration variables.
15 ]]></xsd:documentation>
16 </xsd:annotation>
17
18 <xsd:element name="routes" type="routes" />
19
20 <xsd:complexType name="routes">
21 <xsd:choice minOccurs="0" maxOccurs="unbounded">
22 <xsd:element name="import" type="import" />
23 <xsd:element name="route" type="route" />
24 </xsd:choice>
25 </xsd:complexType>
26
27 <xsd:group name="configs">
28 <xsd:choice>
29 <xsd:element name="default" nillable="true" type="element" />
30 <xsd:element name="requirement" type="element" />
31 <xsd:element name="option" type="element" />
32 </xsd:choice>
33 </xsd:group>
34
35 <xsd:complexType name="route">
36 <xsd:group ref="configs" minOccurs="0" maxOccurs="unbounded" />
37
38 <xsd:attribute name="id" type="xsd:string" use="required" />
39 <xsd:attribute name="path" type="xsd:string" />
40 <xsd:attribute name="pattern" type="xsd:string" />
41 <xsd:attribute name="host" type="xsd:string" />
42 <xsd:attribute name="schemes" type="xsd:string" />
43 <xsd:attribute name="methods" type="xsd:string" />
44 </xsd:complexType>
45
46 <xsd:complexType name="import">
47 <xsd:group ref="configs" minOccurs="0" maxOccurs="unbounded" />
48
49 <xsd:attribute name="resource" type="xsd:string" use="required" />
50 <xsd:attribute name="type" type="xsd:string" />
51 <xsd:attribute name="prefix" type="xsd:string" />
52 <xsd:attribute name="host" type="xsd:string" />
53 <xsd:attribute name="schemes" type="xsd:string" />
54 <xsd:attribute name="methods" type="xsd:string" />
55 </xsd:complexType>
56
57 <xsd:complexType name="element">
58 <xsd:simpleContent>
59 <xsd:extension base="xsd:string">
60 <xsd:attribute name="key" type="xsd:string" use="required" />
61 </xsd:extension>
62 </xsd:simpleContent>
63 </xsd:complexType>
64</xsd:schema>