8000 [Routing] added the possibility to define default values and requirem… · symfony/symfony@2e1344e · GitHub
[go: up one dir, main page]

Skip to content

Commit 2e1344e

Browse files
committed
[Routing] added the possibility to define default values and requirements for placeholders in prefix
1 parent 1bd6e4d commit 2e1344e

File tree

12 files changed

+108
-17
lines changed

12 files changed

+108
-17
lines changed

CHANGELOG-2.1.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ To get the diff between two versions, go to https://github.com/symfony/symfony/c
7979

8080
### Routing
8181

82+
* added the possibility to define default values and requirements for placeholders in prefix
8283
* added RouterInterface::getRouteCollection
8384

8485
### Translation

src/Symfony/Component/Routing/Loader/XmlFileLoader.php

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,29 @@ protected function parseNode(RouteCollection $collection, \DOMElement $node, $pa
7676
$resource = (string) $node->getAttribute('resource');
7777
$type = (string) $node->getAttribute('type');
7878
$prefix = (string) $node->getAttribute('prefix');
79+
80+
$defaults = array();
81+
$requirements = array();
82+
83+
foreach ($node->childNodes as $n) {
84+
if (!$n instanceof \DOMElement) {
85+
continue;
86+
}
87+
88+
switch ($n->tagName) {
89+
case 'default':
90+
$defaults[(string) $n->getAttribute('key')] = trim((string) $n->nodeValue);
91+
break;
92+
case 'requirement':
93+
$requirements[(string) $n->getAttribute('key')] = trim((string) $n->nodeValue);
94+
break;
95+
default:
96+
throw new \InvalidArgumentException(sprintf('Unable to parse tag "%s"', $n->tagName));
97+
}
98+
}
99+
79100
$this->setCurrentDir(dirname($path));
80-
$collection->addCollection($this->import($resource, ('' !== $type ? $type : null), false, $file), $prefix);
101+
$collection->addCollection($this->import($resource, ('' !== $type ? $type : null), false, $file), $prefix, $defaults, $requirements);
81102
break;
82103
default:
83104
throw new \InvalidArgumentException(sprintf('Unable to parse tag "%s"', $node->tagName));

src/Symfony/Component/Routing/Loader/YamlFileLoader.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,11 @@ public function load($file, $type = null)
6767
if (isset($config['resource'])) {
6868
$type = isset($config['type']) ? $config['type'] : null;
6969
$prefix = isset($config['prefix']) ? $config['prefix'] : null;
70+
$defaults = isset($config['defaults']) ? $config['defaults'] : array();
71+
$requirements = isset($config['requirements']) ? $config['requirements'] : array();
72+
7073
$this->setCurrentDir(dirname($path));
71-
$collection->addCollection($this->import($config['resource'], $type, false, $file), $prefix);
74+
$collection->addCollection($this->import($config['resource'], $type, false, $file), $prefix, $defaults, $requirements);
7275
} else {
7376
$this->parseRoute($collection, $name, $config, $path);
7477
}

src/Symfony/Component/Routing/Loader/schema/routing/routing-1.0.xsd

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@
2626
</xsd:complexType>
2727

2828
<xsd:complexType name="import">
29+
<xsd:sequence>
30+
<xsd:element name="default" type="element" minOccurs="0" maxOccurs="unbounded" />
31+
<xsd:element name="requirement" type="element" minOccurs="0" maxOccurs="unbounded" />
32+
</xsd:sequence>
33+
2934
<xsd:attribute name="resource" type="xsd:string" />
3035
<xsd:attribute name="type" type="xsd:string" />
3136
<xsd:attribute name="prefix" type="xsd:string" />

src/Symfony/Component/Routing/Route.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,21 @@ public function getDefaults()
162162
public function setDefaults(array $defaults)
163163
{
164164
$this->defaults = array();
165+
166+
return $this->addDefaults($defaults);
167+
}
168+
169+
/**
170+
* Adds defaults.
171+
*
172+
* This method implements a fluent interface.
173+
*
174+
* @param array $defaults The defaults
175+
*
176+
* @return Route The current Route instance
177+
*/
178+
public function addDefaults(array $defaults)
179+
{
165180
foreach ($defaults as $name => $default) {
166181
$this->defaults[(string) $name] = $default;
167182
}
@@ -232,6 +247,21 @@ public function getRequirements()
232247
public function setRequirements(array $requirements)
233248
{
234249
$this->requirements = array();
250+
251+
return $this->addRequirements($requirements);
252+
}
253+
254+
/**
255+
* Adds requirements.
256+
*
257+
* This method implements a fluent interface.
258+
*
259+
* @param array $requirements The requirements
260+
*
261+
* @return Route The current Route instance
262+
*/
263+
public function addRequirements(array $requirements)
264+
{
235265
foreach ($requirements as $key => $regex) {
236266
$this->requirements[$key] = $this->sanitizeRequirement($key, $regex);
237267
}

src/Symfony/Component/Routing/RouteCollection.php

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -165,15 +165,17 @@ public function remove($name)
165165
/**
166166
* Adds a route collection to the current set of routes (at the end of the current set).
167167
*
168-
* @param RouteCollection $collection A RouteCollection instance
169-
* @param string $prefix An optional prefix to add before each pattern of the route collection
168+
* @param RouteCollection $collection A RouteCollection instance
169+
* @param string $prefix An optional prefix to add before each pattern of the route collection
170+
* @param array $defaults An array of default values
171+
* @param array $requirements An array of requirements
170172
*
171173
* @api
172174
*/
173-
public function addCollection(RouteCollection $collection, $prefix = '')
175+
public function addCollection(RouteCollection $collection, $prefix = '', $defaults = array(), $requirements = array())
174176
{
175177
$collection->setParent($this);
176-
$collection->addPrefix($prefix);
178+
$collection->addPrefix($prefix, $defaults, $requirements);
177179

178180
// remove all routes with the same name in all existing collections
179181
foreach (array_keys($collection->all()) as $name) {
@@ -186,11 +188,13 @@ public function addCollection(RouteCollection $collection, $prefix = '')
186188
/**
187189
* Adds a prefix to all routes in the current set.
188190
*
189-
* @param string $prefix An optional prefix to add before each pattern of the route collection
191+
* @param string $prefix An optional prefix to add before each pattern of the route collection
192+
* @param array $defaults An array of default values
193+
* @param array $requirements An array of requirements
190194
*
191195
* @api
192196
*/
193-
public function addPrefix($prefix)
197+
public function addPrefix($prefix, $defaults = array(), $requirements = array())
194198
{
195199
// a prefix must not end with a slash
196200
$prefix = rtrim($prefix, '/');
@@ -208,9 +212,11 @@ public function addPrefix($prefix)
208212

209213
foreach ($this->routes as $name => $route) {
210214
if ($route instanceof RouteCollection) {
211-
$route->addPrefix($prefix);
215+
$route->addPrefix($prefix, $defaults, $requirements);
212216
} else {
213217
$route->setPattern($prefix.$route->getPattern());
218+
$route->addDefaults($defaults);
219+
$route->addRequirements($requirements);
214220
}
215221
}
216222
}

tests/Symfony/Tests/Component/Routing/Fixtures/validresource.xml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,8 @@
44
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
55
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
66

7-
<import resource="validpattern.xml" />
7+
<import resource="validpattern.xml" prefix="/{foo}">
8+
<default key="foo">foo</default>
9+
<requirement key="foo">\d+</requirement>
10+
</import>
811
</routes>
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
blog_show:
2-
resource: validpattern.yml
2+
resource: validpattern.yml
3+
prefix: /{foo}
4+
defaults: { 'foo': 'foo' }
5+
requirements: { 'foo': '\d+' }

tests/Symfony/Tests/Component/Routing/Loader/XmlFileLoaderTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ public function testLoadWithImport()
5151

5252
$this->assertEquals(1, count($routes), 'One route is loaded');
5353
$this->assertContainsOnly('Symfony\Component\Routing\Route', $routes);
54+
$this->assertEquals('foo', $routes['blog_show']->getDefault('foo'));
55+
$this->assertEquals('\d+', $routes['blog_show']->getRequirement('foo'));
5456
}
5557

5658
/**
@@ -89,4 +91,3 @@ protected function validate(\DOMDocument $dom)
8991
return true;
9092
}
9193
}
92-

tests/Symfony/Tests/Component/Routing/Loader/YamlFileLoaderTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ public function testLoadWithResource()
8888

8989
$this->assertEquals(1, count($routes), 'One route is loaded');
9090
$this->assertContainsOnly('Symfony\Component\Routing\Route', $routes);
91+
$this->assertEquals('foo', $routes['blog_show']->getDefault('foo'));
92+
$this->assertEquals('\d+', $routes['blog_show']->getRequirement('foo'));
9193
}
9294

9395
/**

tests/Symfony/Tests/Component/Routing/RouteCollectionTest.php

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,10 @@ public function testAddCollection()
103103
$collection->add('foo', $foo = new Route('/foo'));
104104
$collection1 = new RouteCollection();
105105
$collection1->add('foo', $foo1 = new Route('/foo1'));
106-
$collection->addCollection($collection1, '/foo');
107-
$this->assertEquals('/foo/foo1', $collection->get('foo')->getPattern(), '->addCollection() can add a prefix to all merged routes');
106+
$collection->addCollection($collection1, '/{foo}', array('foo' => 'foo'), array('foo' => '\d+'));
107+
$this->assertEquals('/{foo}/foo1', $collection->get('foo')->getPattern(), '->addCollection() can add a prefix to all merged routes');
108+
$this->assertEquals(array('foo' => 'foo'), $collection->get('foo')->getDefaults(), '->addCollection() can add a prefix to all merged routes');
109+
$this->assertEquals(array('foo' => '\d+'), $collection->get('foo')->getRequirements(), '->addCollection() can add a prefix to all merged routes');
108110

109111
$collection = new RouteCollection();
110112
$collection->addResource($foo = new FileResource(__DIR__.'/Fixtures/foo.xml'));
@@ -119,9 +121,13 @@ public function testAddPrefix()
119121
$collection = new RouteCollection();
120122
$collection->add('foo', $foo = new Route('/foo'));
121123
$collection->add('bar', $bar = new Route('/bar'));
122-
$collection->addPrefix('/admin');
123-
$this->assertEquals('/admin/foo', $collection->get('foo')->getPattern(), '->addPrefix() adds a prefix to all routes');
124-
$this->assertEquals('/admin/bar', $collection->get('bar')->getPattern(), '->addPrefix() adds a prefix to all routes');
124+
$collection->addPrefix('/{admin}', array('admin' => 'admin'), array('admin' => '\d+'));
125+
$this->assertEquals('/{admin}/foo', $collection->get('foo')->getPattern(), '->addPrefix() adds a prefix to all routes');
126+
$this->assertEquals('/{admin}/bar', $collection->get('bar')->getPattern(), '->addPrefix() adds a prefix to all routes');
127+
$this->assertEquals(array('admin' => 'admin'), $collection->get('foo')->getDefaults(), '->addPrefix() adds a prefix to all routes');
128+
$this->assertEquals(array('admin' => 'admin'), $collection->get('bar')->getDefaults(), '->addPrefix() adds a prefix to all routes');
129+
$this->assertEquals(array('admin' => '\d+'), $collection->get('foo')->getRequirements(), '->addPrefix() adds a prefix to all routes');
130+
$this->assertEquals(array('admin' => '\d+'), $collection->get('bar')->getRequirements(), '->addPrefix() adds a prefix to all routes');
125131
}
126132

127133
public function testResource()

tests/Symfony/Tests/Component/Routing/RouteTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ public function testDefaults()
6868

6969
$route->setDefault('_controller', $closure = function () { return 'Hello'; });
7070
$this->assertEquals($closure, $route->getDefault('_controller'), '->setDefault() sets a default value');
71+
72+
$route->setDefaults(array('foo' => 'foo'));
73+
$route->addDefaults(array('bar' => 'bar'));
74+
$this->assertEquals($route, $route->addDefaults(array()), '->addDefaults() implements a fluent interface');
75+
$this->assertEquals(array('foo' => 'foo', 'bar' => 'bar'), $route->getDefaults(), '->addDefaults() keep previous defaults');
7176
}
7277

7378
public function testRequirements()
@@ -80,6 +85,11 @@ public function testRequirements()
8085
$route->setRequirements(array('foo' => '^\d+$'));
8186
$this->assertEquals('\d+', $route->getRequirement('foo'), '->getRequirement() removes ^ and $ from the pattern');
8287
$this->assertEquals($route, $route->setRequirements(array()), '->setRequirements() implements a fluent interface');
88+
89+
$route->setRequirements(array('foo' => '\d+'));
90+
$route->addRequirements(array('bar' => '\d+'));
91+
$this->assertEquals($route, $route->addRequirements(array()), '->addRequirements() implements a fluent interface');
92+
$this->assertEquals(array('foo' => '\d+', 'bar' => '\d+'), $route->getRequirements(), '->addRequirement() keep previous requirements');
8393
}
8494

8595
public function testRequirement()

0 commit comments

Comments
 (0)
0