diff --git a/CHANGELOG-2.1.md b/CHANGELOG-2.1.md
index 048a42938a..03506f01da 100644
--- a/CHANGELOG-2.1.md
+++ b/CHANGELOG-2.1.md
@@ -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
* 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
### Security
diff --git a/src/Symfony/Component/Routing/Loader/XmlFileLoader.php b/src/Symfony/Component/Routing/Loader/XmlFileLoader.php
index 913deab43b..8f27b03c30 100644
--- a/src/Symfony/Component/Routing/Loader/XmlFileLoader.php
+++ b/src/Symfony/Component/Routing/Loader/XmlFileLoader.php
@@ -79,6 +79,7 @@ class XmlFileLoader extends FileLoader
$defaults = array();
$requirements = array();
+ $options = array();
foreach ($node->childNodes as $n) {
if (!$n instanceof \DOMElement) {
@@ -92,13 +93,16 @@ class XmlFileLoader extends FileLoader
case 'requirement':
$requirements[(string) $n->getAttribute('key')] = trim((string) $n->nodeValue);
break;
+ case 'option':
+ $options[(string) $n->getAttribute('key')] = trim((string) $n->nodeValue);
+ break;
default:
throw new \InvalidArgumentException(sprintf('Unable to parse tag "%s"', $n->tagName));
}
}
$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;
default:
throw new \InvalidArgumentException(sprintf('Unable to parse tag "%s"', $node->tagName));
diff --git a/src/Symfony/Component/Routing/Loader/YamlFileLoader.php b/src/Symfony/Component/Routing/Loader/YamlFileLoader.php
index 5d8f02a268..1f9d711f81 100644
--- a/src/Symfony/Component/Routing/Loader/YamlFileLoader.php
+++ b/src/Symfony/Component/Routing/Loader/YamlFileLoader.php
@@ -69,9 +69,10 @@ class YamlFileLoader extends FileLoader
$prefix = isset($config['prefix']) ? $config['prefix'] : null;
$defaults = isset($config['defaults']) ? $config['defaults'] : array();
$requirements = isset($config['requirements']) ? $config['requirements'] : array();
+ $options = isset($config['options']) ? $config['options'] : array();
$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 {
$this->parseRoute($collection, $name, $config, $path);
}
diff --git a/src/Symfony/Component/Routing/Loader/schema/routing/routing-1.0.xsd b/src/Symfony/Component/Routing/Loader/schema/routing/routing-1.0.xsd
index 3b8fa3db9a..b8571e661d 100644
--- a/src/Symfony/Component/Routing/Loader/schema/routing/routing-1.0.xsd
+++ b/src/Symfony/Component/Routing/Loader/schema/routing/routing-1.0.xsd
@@ -29,6 +29,7 @@
+
diff --git a/src/Symfony/Component/Routing/Route.php b/src/Symfony/Component/Routing/Route.php
index 02131f4309..933dbced47 100644
--- a/src/Symfony/Component/Routing/Route.php
+++ b/src/Symfony/Component/Routing/Route.php
@@ -107,9 +107,27 @@ class Route
*/
public function setOptions(array $options)
{
- $this->options = array_merge(array(
+ $this->options = array(
'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;
}
diff --git a/src/Symfony/Component/Routing/RouteCollection.php b/src/Symfony/Component/Routing/RouteCollection.php
index 400cfb8978..beebd1253c 100644
--- a/src/Symfony/Component/Routing/RouteCollection.php
+++ b/src/Symfony/Component/Routing/RouteCollection.php
@@ -179,13 +179,14 @@ class RouteCollection implements \IteratorAggregate
* @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 $requirements An array of requirements
+ * @param array $options An array of options
*
* @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->addPrefix($prefix, $defaults, $requirements);
+ $collection->addPrefix($prefix, $defaults, $requirements, $options);
// remove all routes with the same name in all existing collections
foreach (array_keys($collection->all()) as $name) {
@@ -201,10 +202,11 @@ class RouteCollection implements \IteratorAggregate
* @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 $requirements An array of requirements
+ * @param array $options An array of options
*
* @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
$prefix = rtrim($prefix, '/');
@@ -218,11 +220,12 @@ class RouteCollection implements \IteratorAggregate
foreach ($this->routes as $name => $route) {
if ($route instanceof RouteCollection) {
- $route->addPrefix($prefix, $defaults, $requirements);
+ $route->addPrefix($prefix, $defaults, $requirements, $options);
} else {
$route->setPattern($prefix.$route->getPattern());
$route->addDefaults($defaults);
$route->addRequirements($requirements);
+ $route->addOptions($options);
}
}
}
diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/validresource.xml b/src/Symfony/Component/Routing/Tests/Fixtures/validresource.xml
index 72856b8161..14ac0fc331 100644
--- a/src/Symfony/Component/Routing/Tests/Fixtures/validresource.xml
+++ b/src/Symfony/Component/Routing/Tests/Fixtures/validresource.xml
@@ -7,5 +7,6 @@
foo
\d+
+
diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/validresource.yml b/src/Symfony/Component/Routing/Tests/Fixtures/validresource.yml
index c36dea5c4f..e66f37613b 100644
--- a/src/Symfony/Component/Routing/Tests/Fixtures/validresource.yml
+++ b/src/Symfony/Component/Routing/Tests/Fixtures/validresource.yml
@@ -3,3 +3,4 @@ blog_show:
prefix: /{foo}
defaults: { 'foo': 'foo' }
requirements: { 'foo': '\d+' }
+ options: { 'foo': 'bar' }
diff --git a/src/Symfony/Component/Routing/Tests/Loader/XmlFileLoaderTest.php b/src/Symfony/Component/Routing/Tests/Loader/XmlFileLoaderTest.php
index e47d1b3ec8..554ee1a88b 100644
--- a/src/Symfony/Component/Routing/Tests/Loader/XmlFileLoaderTest.php
+++ b/src/Symfony/Component/Routing/Tests/Loader/XmlFileLoaderTest.php
@@ -61,6 +61,7 @@ class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
$this->assertContainsOnly('Symfony\Component\Routing\Route', $routes);
$this->assertEquals('foo', $routes['blog_show']->getDefault('foo'));
$this->assertEquals('\d+', $routes['blog_show']->getRequirement('foo'));
+ $this->assertEquals('bar', $routes['blog_show']->getOption('foo'));
}
/**
diff --git a/src/Symfony/Component/Routing/Tests/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/Routing/Tests/Loader/YamlFileLoaderTest.php
index 79668e27bc..0c870e667a 100644
--- a/src/Symfony/Component/Routing/Tests/Loader/YamlFileLoaderTest.php
+++ b/src/Symfony/Component/Routing/Tests/Loader/YamlFileLoaderTest.php
@@ -101,6 +101,7 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
$this->assertContainsOnly('Symfony\Component\Routing\Route', $routes);
$this->assertEquals('foo', $routes['blog_show']->getDefault('foo'));
$this->assertEquals('\d+', $routes['blog_show']->getRequirement('foo'));
+ $this->assertEquals('bar', $routes['blog_show']->getOption('foo'));
}
/**
diff --git a/src/Symfony/Component/Routing/Tests/RouteCollectionTest.php b/src/Symfony/Component/Routing/Tests/RouteCollectionTest.php
index 917d666d1a..3e73065d0b 100644
--- a/src/Symfony/Component/Routing/Tests/RouteCollectionTest.php
+++ b/src/Symfony/Component/Routing/Tests/RouteCollectionTest.php
@@ -107,10 +107,14 @@ class RouteCollectionTest extends \PHPUnit_Framework_TestCase
$collection->add('foo', $foo = new Route('/foo'));
$collection1 = new RouteCollection();
$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(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' => 'bar', 'compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler'),
+ $collection->get('foo')->getOptions(), '->addCollection() can add an option to all merged routes'
+ );
$collection = new RouteCollection();
$collection->addResource($foo = new FileResource(__DIR__.'/Fixtures/foo.xml'));
@@ -125,13 +129,21 @@ class RouteCollectionTest extends \PHPUnit_Framework_TestCase
$collection = new RouteCollection();
$collection->add('foo', $foo = new Route('/foo'));
$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}/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('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('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()
diff --git a/src/Symfony/Component/Routing/Tests/RouteTest.php b/src/Symfony/Component/Routing/Tests/RouteTest.php
index 5acb64eb07..1295bc43c0 100644
--- a/src/Symfony/Component/Routing/Tests/RouteTest.php
+++ b/src/Symfony/Component/Routing/Tests/RouteTest.php
@@ -44,14 +44,13 @@ class RouteTest extends \PHPUnit_Framework_TestCase
'compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler',
), array('foo' => 'bar')), $route->getOptions(), '->setOptions() sets the options');
$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()
{
$route = new Route('/{foo}');