2010-02-17 13:53:31 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/*
|
2011-01-15 13:29:43 +00:00
|
|
|
* This file is part of the Symfony package.
|
2010-02-17 13:53:31 +00:00
|
|
|
*
|
2011-03-06 11:40:06 +00:00
|
|
|
* (c) Fabien Potencier <fabien@symfony.com>
|
2010-02-17 13:53:31 +00:00
|
|
|
*
|
2011-01-15 13:29:43 +00:00
|
|
|
* For the full copyright and license information, please view the LICENSE
|
|
|
|
* file that was distributed with this source code.
|
2010-02-17 13:53:31 +00:00
|
|
|
*/
|
|
|
|
|
2011-01-15 13:29:43 +00:00
|
|
|
namespace Symfony\Component\Routing;
|
|
|
|
|
2011-02-10 15:15:51 +00:00
|
|
|
use Symfony\Component\Config\Resource\ResourceInterface;
|
2011-01-15 13:29:43 +00:00
|
|
|
|
2010-02-17 13:53:31 +00:00
|
|
|
/**
|
|
|
|
* A RouteCollection represents a set of Route instances.
|
|
|
|
*
|
2011-09-30 08:20:51 +01:00
|
|
|
* When adding a route, it overrides existing routes with the
|
|
|
|
* same name defined in theinstance or its children and parents.
|
|
|
|
*
|
2011-03-06 11:40:06 +00:00
|
|
|
* @author Fabien Potencier <fabien@symfony.com>
|
2011-06-14 14:35:32 +01:00
|
|
|
*
|
|
|
|
* @api
|
2010-02-17 13:53:31 +00:00
|
|
|
*/
|
2011-04-25 16:39:10 +01:00
|
|
|
class RouteCollection implements \IteratorAggregate
|
2010-02-17 13:53:31 +00:00
|
|
|
{
|
2011-03-23 18:24:18 +00:00
|
|
|
private $routes;
|
|
|
|
private $resources;
|
2011-04-25 16:39:10 +01:00
|
|
|
private $prefix;
|
2011-09-30 08:20:51 +01:00
|
|
|
private $parent;
|
2010-02-17 13:53:31 +00:00
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
/**
|
|
|
|
* Constructor.
|
2011-06-14 14:35:32 +01:00
|
|
|
*
|
|
|
|
* @api
|
2010-05-06 12:25:53 +01:00
|
|
|
*/
|
|
|
|
public function __construct()
|
2010-02-17 13:53:31 +00:00
|
|
|
{
|
2010-05-06 12:25:53 +01:00
|
|
|
$this->routes = array();
|
|
|
|
$this->resources = array();
|
2011-04-25 16:39:10 +01:00
|
|
|
$this->prefix = '';
|
|
|
|
}
|
|
|
|
|
2011-09-30 08:20:51 +01:00
|
|
|
/**
|
|
|
|
* Gets the parent RouteCollection.
|
|
|
|
*
|
|
|
|
* @return RouteCollection The parent RouteCollection
|
|
|
|
*/
|
|
|
|
public function getParent()
|
|
|
|
{
|
|
|
|
return $this->parent;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the parent RouteCollection.
|
|
|
|
*
|
|
|
|
* @param RouteCollection $parent The parent RouteCollection
|
|
|
|
*/
|
|
|
|
public function setParent(RouteCollection $parent)
|
|
|
|
{
|
|
|
|
$this->parent = $parent;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the current RouteCollection as an Iterator.
|
|
|
|
*
|
|
|
|
* @return \ArrayIterator An \ArrayIterator interface
|
|
|
|
*/
|
2011-04-25 16:39:10 +01:00
|
|
|
public function getIterator()
|
|
|
|
{
|
|
|
|
return new \ArrayIterator($this->routes);
|
2010-02-17 13:53:31 +00:00
|
|
|
}
|
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
/**
|
|
|
|
* Adds a route.
|
|
|
|
*
|
|
|
|
* @param string $name The route name
|
|
|
|
* @param Route $route A Route instance
|
|
|
|
*
|
|
|
|
* @throws \InvalidArgumentException When route name contains non valid characters
|
2011-06-14 14:35:32 +01:00
|
|
|
*
|
|
|
|
* @api
|
2010-05-06 12:25:53 +01:00
|
|
|
*/
|
2010-11-23 08:42:19 +00:00
|
|
|
public function add($name, Route $route)
|
2010-05-06 12:25:53 +01:00
|
|
|
{
|
2010-12-12 07:53:18 +00:00
|
|
|
if (!preg_match('/^[a-z0-9A-Z_.]+$/', $name)) {
|
2010-05-06 12:25:53 +01:00
|
|
|
throw new \InvalidArgumentException(sprintf('Name "%s" contains non valid characters for a route name.', $name));
|
|
|
|
}
|
2010-02-17 13:53:31 +00:00
|
|
|
|
2011-09-30 08:20:51 +01:00
|
|
|
$parent = $this;
|
|
|
|
while ($parent->getParent()) {
|
|
|
|
$parent = $parent->getParent();
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($parent) {
|
|
|
|
$parent->remove($name);
|
|
|
|
}
|
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
$this->routes[$name] = $route;
|
|
|
|
}
|
2010-02-17 13:53:31 +00:00
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
/**
|
|
|
|
* Returns the array of routes.
|
|
|
|
*
|
|
|
|
* @return array An array of routes
|
|
|
|
*/
|
2010-11-23 08:42:19 +00:00
|
|
|
public function all()
|
2010-02-17 13:53:31 +00:00
|
|
|
{
|
2011-04-25 16:39:10 +01:00
|
|
|
$routes = array();
|
|
|
|
foreach ($this->routes as $name => $route) {
|
|
|
|
if ($route instanceof RouteCollection) {
|
|
|
|
$routes = array_merge($routes, $route->all());
|
|
|
|
} else {
|
|
|
|
$routes[$name] = $route;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $routes;
|
2010-02-17 13:53:31 +00:00
|
|
|
}
|
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
/**
|
|
|
|
* Gets a route by name.
|
|
|
|
*
|
|
|
|
* @param string $name The route name
|
|
|
|
*
|
|
|
|
* @return Route $route A Route instance
|
|
|
|
*/
|
2010-11-23 08:42:19 +00:00
|
|
|
public function get($name)
|
2010-05-06 12:25:53 +01:00
|
|
|
{
|
2011-04-25 16:39:10 +01:00
|
|
|
// get the latest defined route
|
|
|
|
foreach (array_reverse($this->routes) as $routes) {
|
|
|
|
if (!$routes instanceof RouteCollection) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (null !== $route = $routes->get($name)) {
|
|
|
|
return $route;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isset($this->routes[$name])) {
|
|
|
|
return $this->routes[$name];
|
2011-05-23 22:39:25 +01:00
|
|
|
}
|
2010-05-06 12:25:53 +01:00
|
|
|
}
|
2010-02-17 13:53:31 +00:00
|
|
|
|
2011-09-30 08:20:51 +01:00
|
|
|
/**
|
|
|
|
* Removes a route by name.
|
|
|
|
*
|
|
|
|
* @param string $name The route name
|
|
|
|
*/
|
|
|
|
public function remove($name)
|
|
|
|
{
|
|
|
|
if (isset($this->routes[$name])) {
|
|
|
|
unset($this->routes[$name]);
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach ($this->routes as $routes) {
|
|
|
|
if ($routes instanceof RouteCollection) {
|
|
|
|
$routes->remove($name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
/**
|
|
|
|
* Adds a route collection to the current set of routes (at the end of the current set).
|
|
|
|
*
|
2011-10-23 10:56:23 +01:00
|
|
|
* @param RouteCollection $collection A RouteCollection instance
|
|
|
|
* @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
|
2011-06-14 14:35:32 +01:00
|
|
|
*
|
|
|
|
* @api
|
2010-05-06 12:25:53 +01:00
|
|
|
*/
|
2011-10-23 10:56:23 +01:00
|
|
|
public function addCollection(RouteCollection $collection, $prefix = '', $defaults = array(), $requirements = array())
|
2010-02-17 13:53:31 +00:00
|
|
|
{
|
2011-09-30 08:20:51 +01:00
|
|
|
$collection->setParent($this);
|
2011-10-23 10:56:23 +01:00
|
|
|
$collection->addPrefix($prefix, $defaults, $requirements);
|
2010-05-06 12:25:53 +01:00
|
|
|
|
2011-09-30 08:20:51 +01:00
|
|
|
// remove all routes with the same name in all existing collections
|
|
|
|
foreach (array_keys($collection->all()) as $name) {
|
|
|
|
$this->remove($name);
|
|
|
|
}
|
|
|
|
|
2011-04-25 16:39:10 +01:00
|
|
|
$this->routes[] = $collection;
|
2010-02-17 13:53:31 +00:00
|
|
|
}
|
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
/**
|
|
|
|
* Adds a prefix to all routes in the current set.
|
|
|
|
*
|
2011-10-23 10:56:23 +01:00
|
|
|
* @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
|
2011-06-14 14:35:32 +01:00
|
|
|
*
|
|
|
|
* @api
|
2010-05-06 12:25:53 +01:00
|
|
|
*/
|
2011-10-23 10:56:23 +01:00
|
|
|
public function addPrefix($prefix, $defaults = array(), $requirements = array())
|
2010-02-17 13:53:31 +00:00
|
|
|
{
|
2011-04-26 13:26:29 +01:00
|
|
|
// a prefix must not end with a slash
|
|
|
|
$prefix = rtrim($prefix, '/');
|
|
|
|
|
2010-05-07 15:09:11 +01:00
|
|
|
if (!$prefix) {
|
2010-05-06 12:25:53 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-04-26 13:26:29 +01:00
|
|
|
// a prefix must start with a slash
|
|
|
|
if ('/' !== $prefix[0]) {
|
|
|
|
$prefix = '/'.$prefix;
|
|
|
|
}
|
|
|
|
|
2011-04-25 16:39:10 +01:00
|
|
|
$this->prefix = $prefix.$this->prefix;
|
|
|
|
|
2011-05-04 22:29:47 +01:00
|
|
|
foreach ($this->routes as $name => $route) {
|
|
|
|
if ($route instanceof RouteCollection) {
|
2011-10-23 10:56:23 +01:00
|
|
|
$route->addPrefix($prefix, $defaults, $requirements);
|
2011-05-04 22:29:47 +01:00
|
|
|
} else {
|
|
|
|
$route->setPattern($prefix.$route->getPattern());
|
2011-10-23 10:56:23 +01:00
|
|
|
$route->addDefaults($defaults);
|
|
|
|
$route->addRequirements($requirements);
|
2011-05-04 22:29:47 +01:00
|
|
|
}
|
2010-05-06 12:25:53 +01:00
|
|
|
}
|
2010-02-17 13:53:31 +00:00
|
|
|
}
|
|
|
|
|
2011-04-25 16:39:10 +01:00
|
|
|
public function getPrefix()
|
|
|
|
{
|
|
|
|
return $this->prefix;
|
|
|
|
}
|
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
/**
|
|
|
|
* Returns an array of resources loaded to build this collection.
|
|
|
|
*
|
|
|
|
* @return ResourceInterface[] An array of resources
|
|
|
|
*/
|
|
|
|
public function getResources()
|
|
|
|
{
|
2011-04-25 16:39:10 +01:00
|
|
|
$resources = $this->resources;
|
|
|
|
foreach ($this as $routes) {
|
|
|
|
if ($routes instanceof RouteCollection) {
|
|
|
|
$resources = array_merge($resources, $routes->getResources());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return array_unique($resources);
|
2010-05-06 12:25:53 +01:00
|
|
|
}
|
2010-02-17 13:53:31 +00:00
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
/**
|
|
|
|
* Adds a resource for this collection.
|
|
|
|
*
|
|
|
|
* @param ResourceInterface $resource A resource instance
|
|
|
|
*/
|
|
|
|
public function addResource(ResourceInterface $resource)
|
|
|
|
{
|
|
|
|
$this->resources[] = $resource;
|
|
|
|
}
|
2010-02-17 13:53:31 +00:00
|
|
|
}
|