diff options
Diffstat (limited to 'vendor/symfony/routing/Symfony/Component/Routing/Loader/XmlFileLoader.php')
-rw-r--r-- | vendor/symfony/routing/Symfony/Component/Routing/Loader/XmlFileLoader.php | 238 |
1 files changed, 238 insertions, 0 deletions
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 | |||
12 | namespace Symfony\Component\Routing\Loader; | ||
13 | |||
14 | use Symfony\Component\Routing\RouteCollection; | ||
15 | use Symfony\Component\Routing\Route; | ||
16 | use Symfony\Component\Config\Resource\FileResource; | ||
17 | use Symfony\Component\Config\Loader\FileLoader; | ||
18 | use 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 | */ | ||
28 | class 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 | } | ||