Skip to content

Commit

Permalink
merged branch stof/routing_options_import (PR #3775)
Browse files Browse the repository at this point in the history
Commits
-------

3c32569 [Routing] Added the possibility to define options for imported resources

Discussion
----------

[Routing] Added the possibility to define options for imported resources

Closes #2772
  • Loading branch information
fabpot committed Apr 4, 2012
2 parents 479d808 + 3c32569 commit 71c9dc3
Show file tree
Hide file tree
Showing 12 changed files with 59 additions and 17 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG-2.1.md
Expand Up @@ -348,7 +348,7 @@ To get the diff between two versions, go to https://github.com/symfony/symfony/c


* the UrlMatcher does not throw a \LogicException any more when the required scheme is not the current one * the UrlMatcher does not throw a \LogicException any more when the required scheme is not the current one
* added a TraceableUrlMatcher * added a TraceableUrlMatcher
* added the possibility to define default values and requirements for placeholders in prefix, including imported routes * added the possibility to define options, default values and requirements for placeholders in prefix, including imported routes
* added RouterInterface::getRouteCollection * added RouterInterface::getRouteCollection


### Security ### Security
Expand Down
6 changes: 5 additions & 1 deletion src/Symfony/Component/Routing/Loader/XmlFileLoader.php
Expand Up @@ -79,6 +79,7 @@ protected function parseNode(RouteCollection $collection, \DOMElement $node, $pa


$defaults = array(); $defaults = array();
$requirements = array(); $requirements = array();
$options = array();


foreach ($node->childNodes as $n) { foreach ($node->childNodes as $n) {
if (!$n instanceof \DOMElement) { if (!$n instanceof \DOMElement) {
Expand All @@ -92,13 +93,16 @@ protected function parseNode(RouteCollection $collection, \DOMElement $node, $pa
case 'requirement': case 'requirement':
$requirements[(string) $n->getAttribute('key')] = trim((string) $n->nodeValue); $requirements[(string) $n->getAttribute('key')] = trim((string) $n->nodeValue);
break; break;
case 'option':
$options[(string) $n->getAttribute('key')] = trim((string) $n->nodeValue);
break;
default: default:
throw new \InvalidArgumentException(sprintf('Unable to parse tag "%s"', $n->tagName)); throw new \InvalidArgumentException(sprintf('Unable to parse tag "%s"', $n->tagName));
} }
} }


$this->setCurrentDir(dirname($path)); $this->setCurrentDir(dirname($path));
$collection->addCollection($this->import($resource, ('' !== $type ? $type : null), false, $file), $prefix, $defaults, $requirements); $collection->addCollection($this->import($resource, ('' !== $type ? $type : null), false, $file), $prefix, $defaults, $requirements, $options);
break; break;
default: default:
throw new \InvalidArgumentException(sprintf('Unable to parse tag "%s"', $node->tagName)); throw new \InvalidArgumentException(sprintf('Unable to parse tag "%s"', $node->tagName));
Expand Down
3 changes: 2 additions & 1 deletion src/Symfony/Component/Routing/Loader/YamlFileLoader.php
Expand Up @@ -69,9 +69,10 @@ public function load($file, $type = null)
$prefix = isset($config['prefix']) ? $config['prefix'] : null; $prefix = isset($config['prefix']) ? $config['prefix'] : null;
$defaults = isset($config['defaults']) ? $config['defaults'] : array(); $defaults = isset($config['defaults']) ? $config['defaults'] : array();
$requirements = isset($config['requirements']) ? $config['requirements'] : array(); $requirements = isset($config['requirements']) ? $config['requirements'] : array();
$options = isset($config['options']) ? $config['options'] : array();


$this->setCurrentDir(dirname($path)); $this->setCurrentDir(dirname($path));
$collection->addCollection($this->import($config['resource'], $type, false, $file), $prefix, $defaults, $requirements); $collection->addCollection($this->import($config['resource'], $type, false, $file), $prefix, $defaults, $requirements, $options);
} else { } else {
$this->parseRoute($collection, $name, $config, $path); $this->parseRoute($collection, $name, $config, $path);
} }
Expand Down
Expand Up @@ -29,6 +29,7 @@
<xsd:sequence> <xsd:sequence>
<xsd:element name="default" type="element" minOccurs="0" maxOccurs="unbounded" /> <xsd:element name="default" type="element" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="requirement" type="element" minOccurs="0" maxOccurs="unbounded" /> <xsd:element name="requirement" type="element" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="option" type="element" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence> </xsd:sequence>


<xsd:attribute name="resource" type="xsd:string" /> <xsd:attribute name="resource" type="xsd:string" />
Expand Down
22 changes: 20 additions & 2 deletions src/Symfony/Component/Routing/Route.php
Expand Up @@ -107,9 +107,27 @@ public function getOptions()
*/ */
public function setOptions(array $options) public function setOptions(array $options)
{ {
$this->options = array_merge(array( $this->options = array(
'compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler', 'compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler',
), $options); );

return $this->addOptions($options);
}

/**
* Adds options.
*
* This method implements a fluent interface.
*
* @param array $options The options
*
* @return Route The current Route instance
*/
public function addOptions(array $options)
{
foreach ($options as $name => $option) {
$this->options[(string) $name] = $option;
}


return $this; return $this;
} }
Expand Down
11 changes: 7 additions & 4 deletions src/Symfony/Component/Routing/RouteCollection.php
Expand Up @@ -179,13 +179,14 @@ public function remove($name)
* @param string $prefix An optional prefix to add before each pattern of the route collection * @param string $prefix An optional prefix to add before each pattern of the route collection
* @param array $defaults An array of default values * @param array $defaults An array of default values
* @param array $requirements An array of requirements * @param array $requirements An array of requirements
* @param array $options An array of options
* *
* @api * @api
*/ */
public function addCollection(RouteCollection $collection, $prefix = '', $defaults = array(), $requirements = array()) public function addCollection(RouteCollection $collection, $prefix = '', $defaults = array(), $requirements = array(), $options = array())
{ {
$collection->setParent($this); $collection->setParent($this);
$collection->addPrefix($prefix, $defaults, $requirements); $collection->addPrefix($prefix, $defaults, $requirements, $options);


// remove all routes with the same name in all existing collections // remove all routes with the same name in all existing collections
foreach (array_keys($collection->all()) as $name) { foreach (array_keys($collection->all()) as $name) {
Expand All @@ -201,10 +202,11 @@ public function addCollection(RouteCollection $collection, $prefix = '', $defaul
* @param string $prefix An optional prefix to add before each pattern of the route collection * @param string $prefix An optional prefix to add before each pattern of the route collection
* @param array $defaults An array of default values * @param array $defaults An array of default values
* @param array $requirements An array of requirements * @param array $requirements An array of requirements
* @param array $options An array of options
* *
* @api * @api
*/ */
public function addPrefix($prefix, $defaults = array(), $requirements = array()) public function addPrefix($prefix, $defaults = array(), $requirements = array(), $options = array())
{ {
// a prefix must not end with a slash // a prefix must not end with a slash
$prefix = rtrim($prefix, '/'); $prefix = rtrim($prefix, '/');
Expand All @@ -218,11 +220,12 @@ public function addPrefix($prefix, $defaults = array(), $requirements = array())


foreach ($this->routes as $name => $route) { foreach ($this->routes as $name => $route) {
if ($route instanceof RouteCollection) { if ($route instanceof RouteCollection) {
$route->addPrefix($prefix, $defaults, $requirements); $route->addPrefix($prefix, $defaults, $requirements, $options);
} else { } else {
$route->setPattern($prefix.$route->getPattern()); $route->setPattern($prefix.$route->getPattern());
$route->addDefaults($defaults); $route->addDefaults($defaults);
$route->addRequirements($requirements); $route->addRequirements($requirements);
$route->addOptions($options);
} }
} }
} }
Expand Down
Expand Up @@ -7,5 +7,6 @@
<import resource="validpattern.xml" prefix="/{foo}"> <import resource="validpattern.xml" prefix="/{foo}">
<default key="foo">foo</default> <default key="foo">foo</default>
<requirement key="foo">\d+</requirement> <requirement key="foo">\d+</requirement>
<option key="foo">bar</option>
</import> </import>
</routes> </routes>
Expand Up @@ -3,3 +3,4 @@ blog_show:
prefix: /{foo} prefix: /{foo}
defaults: { 'foo': 'foo' } defaults: { 'foo': 'foo' }
requirements: { 'foo': '\d+' } requirements: { 'foo': '\d+' }
options: { 'foo': 'bar' }
Expand Up @@ -61,6 +61,7 @@ public function testLoadWithImport()
$this->assertContainsOnly('Symfony\Component\Routing\Route', $routes); $this->assertContainsOnly('Symfony\Component\Routing\Route', $routes);
$this->assertEquals('foo', $routes['blog_show']->getDefault('foo')); $this->assertEquals('foo', $routes['blog_show']->getDefault('foo'));
$this->assertEquals('\d+', $routes['blog_show']->getRequirement('foo')); $this->assertEquals('\d+', $routes['blog_show']->getRequirement('foo'));
$this->assertEquals('bar', $routes['blog_show']->getOption('foo'));
} }


/** /**
Expand Down
Expand Up @@ -101,6 +101,7 @@ public function testLoadWithResource()
$this->assertContainsOnly('Symfony\Component\Routing\Route', $routes); $this->assertContainsOnly('Symfony\Component\Routing\Route', $routes);
$this->assertEquals('foo', $routes['blog_show']->getDefault('foo')); $this->assertEquals('foo', $routes['blog_show']->getDefault('foo'));
$this->assertEquals('\d+', $routes['blog_show']->getRequirement('foo')); $this->assertEquals('\d+', $routes['blog_show']->getRequirement('foo'));
$this->assertEquals('bar', $routes['blog_show']->getOption('foo'));
} }


/** /**
Expand Down
16 changes: 14 additions & 2 deletions src/Symfony/Component/Routing/Tests/RouteCollectionTest.php
Expand Up @@ -107,10 +107,14 @@ public function testAddCollection()
$collection->add('foo', $foo = new Route('/foo')); $collection->add('foo', $foo = new Route('/foo'));
$collection1 = new RouteCollection(); $collection1 = new RouteCollection();
$collection1->add('foo', $foo1 = new Route('/foo1')); $collection1->add('foo', $foo1 = new Route('/foo1'));
$collection->addCollection($collection1, '/{foo}', array('foo' => 'foo'), array('foo' => '\d+')); $collection->addCollection($collection1, '/{foo}', array('foo' => 'foo'), array('foo' => '\d+'), array('foo' => 'bar'));
$this->assertEquals('/{foo}/foo1', $collection->get('foo')->getPattern(), '->addCollection() can add a prefix to all merged routes'); $this->assertEquals('/{foo}/foo1', $collection->get('foo')->getPattern(), '->addCollection() can add a prefix to all merged routes');
$this->assertEquals(array('foo' => 'foo'), $collection->get('foo')->getDefaults(), '->addCollection() can add a prefix to all merged routes'); $this->assertEquals(array('foo' => 'foo'), $collection->get('foo')->getDefaults(), '->addCollection() can add a prefix to all merged routes');
$this->assertEquals(array('foo' => '\d+'), $collection->get('foo')->getRequirements(), '->addCollection() can add a prefix to all merged routes'); $this->assertEquals(array('foo' => '\d+'), $collection->get('foo')->getRequirements(), '->addCollection() can add a prefix to all merged routes');
$this->assertEquals(
array('foo' => 'bar', 'compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler'),
$collection->get('foo')->getOptions(), '->addCollection() can add an option to all merged routes'
);


$collection = new RouteCollection(); $collection = new RouteCollection();
$collection->addResource($foo = new FileResource(__DIR__.'/Fixtures/foo.xml')); $collection->addResource($foo = new FileResource(__DIR__.'/Fixtures/foo.xml'));
Expand All @@ -125,13 +129,21 @@ public function testAddPrefix()
$collection = new RouteCollection(); $collection = new RouteCollection();
$collection->add('foo', $foo = new Route('/foo')); $collection->add('foo', $foo = new Route('/foo'));
$collection->add('bar', $bar = new Route('/bar')); $collection->add('bar', $bar = new Route('/bar'));
$collection->addPrefix('/{admin}', array('admin' => 'admin'), array('admin' => '\d+')); $collection->addPrefix('/{admin}', array('admin' => 'admin'), array('admin' => '\d+'), array('foo' => 'bar'));
$this->assertEquals('/{admin}/foo', $collection->get('foo')->getPattern(), '->addPrefix() adds a prefix to all routes'); $this->assertEquals('/{admin}/foo', $collection->get('foo')->getPattern(), '->addPrefix() adds a prefix to all routes');
$this->assertEquals('/{admin}/bar', $collection->get('bar')->getPattern(), '->addPrefix() adds a prefix to all routes'); $this->assertEquals('/{admin}/bar', $collection->get('bar')->getPattern(), '->addPrefix() adds a prefix to all routes');
$this->assertEquals(array('admin' => 'admin'), $collection->get('foo')->getDefaults(), '->addPrefix() adds a prefix to all routes'); $this->assertEquals(array('admin' => 'admin'), $collection->get('foo')->getDefaults(), '->addPrefix() adds a prefix to all routes');
$this->assertEquals(array('admin' => 'admin'), $collection->get('bar')->getDefaults(), '->addPrefix() adds a prefix to all routes'); $this->assertEquals(array('admin' => 'admin'), $collection->get('bar')->getDefaults(), '->addPrefix() adds a prefix to all routes');
$this->assertEquals(array('admin' => '\d+'), $collection->get('foo')->getRequirements(), '->addPrefix() adds a prefix to all routes'); $this->assertEquals(array('admin' => '\d+'), $collection->get('foo')->getRequirements(), '->addPrefix() adds a prefix to all routes');
$this->assertEquals(array('admin' => '\d+'), $collection->get('bar')->getRequirements(), '->addPrefix() adds a prefix to all routes'); $this->assertEquals(array('admin' => '\d+'), $collection->get('bar')->getRequirements(), '->addPrefix() adds a prefix to all routes');
$this->assertEquals(
array('foo' => 'bar', 'compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler'),
$collection->get('foo')->getOptions(), '->addPrefix() adds an option to all routes'
);
$this->assertEquals(
array('foo' => 'bar', 'compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler'),
$collection->get('bar')->getOptions(), '->addPrefix() adds an option to all routes'
);
} }


public function testAddPrefixOverridesDefaultsAndRequirements() public function testAddPrefixOverridesDefaultsAndRequirements()
Expand Down
11 changes: 5 additions & 6 deletions src/Symfony/Component/Routing/Tests/RouteTest.php
Expand Up @@ -44,14 +44,13 @@ public function testOptions()
'compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler', 'compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler',
), array('foo' => 'bar')), $route->getOptions(), '->setOptions() sets the options'); ), array('foo' => 'bar')), $route->getOptions(), '->setOptions() sets the options');
$this->assertEquals($route, $route->setOptions(array()), '->setOptions() implements a fluent interface'); $this->assertEquals($route, $route->setOptions(array()), '->setOptions() implements a fluent interface');

$route->setOptions(array('foo' => 'foo'));
$route->addOptions(array('bar' => 'bar'));
$this->assertEquals($route, $route->addOptions(array()), '->addOptions() implements a fluent interface');
$this->assertEquals(array('foo' => 'foo', 'bar' => 'bar', 'compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler'), $route->getOptions(), '->addDefaults() keep previous defaults');
} }


/**
* @covers Symfony\Component\Routing\Route::setDefaults
* @covers Symfony\Component\Routing\Route::getDefaults
* @covers Symfony\Component\Routing\Route::setDefault
* @covers Symfony\Component\Routing\Route::getDefault
*/
public function testDefaults() public function testDefaults()
{ {
$route = new Route('/{foo}'); $route = new Route('/{foo}');
Expand Down

0 comments on commit 71c9dc3

Please sign in to comment.