Chris@0: Chris@0: * Chris@0: * For the full copyright and license information, please view the LICENSE Chris@0: * file that was distributed with this source code. Chris@0: */ Chris@0: Chris@0: namespace Symfony\Component\Routing; Chris@0: Chris@0: use Symfony\Component\Config\Resource\ResourceInterface; Chris@0: Chris@0: /** Chris@0: * A RouteCollection represents a set of Route instances. Chris@0: * Chris@0: * When adding a route at the end of the collection, an existing route Chris@0: * with the same name is removed first. So there can only be one route Chris@0: * with a given name. Chris@0: * Chris@0: * @author Fabien Potencier Chris@0: * @author Tobias Schultze Chris@0: */ Chris@0: class RouteCollection implements \IteratorAggregate, \Countable Chris@0: { Chris@0: /** Chris@0: * @var Route[] Chris@0: */ Chris@17: private $routes = []; Chris@0: Chris@0: /** Chris@0: * @var array Chris@0: */ Chris@17: private $resources = []; Chris@0: Chris@0: public function __clone() Chris@0: { Chris@0: foreach ($this->routes as $name => $route) { Chris@0: $this->routes[$name] = clone $route; Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets the current RouteCollection as an Iterator that includes all routes. Chris@0: * Chris@0: * It implements \IteratorAggregate. Chris@0: * Chris@0: * @see all() Chris@0: * Chris@0: * @return \ArrayIterator|Route[] An \ArrayIterator object for iterating over routes Chris@0: */ Chris@0: public function getIterator() Chris@0: { Chris@0: return new \ArrayIterator($this->routes); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets the number of Routes in this collection. Chris@0: * Chris@0: * @return int The number of routes Chris@0: */ Chris@0: public function count() Chris@0: { Chris@17: return \count($this->routes); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Adds a route. Chris@0: * Chris@0: * @param string $name The route name Chris@0: * @param Route $route A Route instance Chris@0: */ Chris@0: public function add($name, Route $route) Chris@0: { Chris@0: unset($this->routes[$name]); Chris@0: Chris@0: $this->routes[$name] = $route; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Returns all routes in this collection. Chris@0: * Chris@0: * @return Route[] An array of routes Chris@0: */ Chris@0: public function all() Chris@0: { Chris@0: return $this->routes; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets a route by name. Chris@0: * Chris@0: * @param string $name The route name Chris@0: * Chris@0: * @return Route|null A Route instance or null when not found Chris@0: */ Chris@0: public function get($name) Chris@0: { Chris@0: return isset($this->routes[$name]) ? $this->routes[$name] : null; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Removes a route or an array of routes by name from the collection. Chris@0: * Chris@14: * @param string|string[] $name The route name or an array of route names Chris@0: */ Chris@0: public function remove($name) Chris@0: { Chris@0: foreach ((array) $name as $n) { Chris@0: unset($this->routes[$n]); Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Adds a route collection at the end of the current set by appending all Chris@0: * routes of the added collection. Chris@0: */ Chris@14: public function addCollection(self $collection) Chris@0: { Chris@0: // we need to remove all routes with the same names first because just replacing them Chris@0: // would not place the new route at the end of the merged array Chris@0: foreach ($collection->all() as $name => $route) { Chris@0: unset($this->routes[$name]); Chris@0: $this->routes[$name] = $route; Chris@0: } Chris@0: Chris@14: foreach ($collection->getResources() as $resource) { Chris@14: $this->addResource($resource); Chris@14: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Adds a prefix to the path of all child routes. Chris@0: * Chris@0: * @param string $prefix An optional prefix to add before each pattern of the route collection Chris@0: * @param array $defaults An array of default values Chris@0: * @param array $requirements An array of requirements Chris@0: */ Chris@17: public function addPrefix($prefix, array $defaults = [], array $requirements = []) Chris@0: { Chris@0: $prefix = trim(trim($prefix), '/'); Chris@0: Chris@0: if ('' === $prefix) { Chris@0: return; Chris@0: } Chris@0: Chris@0: foreach ($this->routes as $route) { Chris@0: $route->setPath('/'.$prefix.$route->getPath()); Chris@0: $route->addDefaults($defaults); Chris@0: $route->addRequirements($requirements); Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets the host pattern on all routes. Chris@0: * Chris@0: * @param string $pattern The pattern Chris@0: * @param array $defaults An array of default values Chris@0: * @param array $requirements An array of requirements Chris@0: */ Chris@17: public function setHost($pattern, array $defaults = [], array $requirements = []) Chris@0: { Chris@0: foreach ($this->routes as $route) { Chris@0: $route->setHost($pattern); Chris@0: $route->addDefaults($defaults); Chris@0: $route->addRequirements($requirements); Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets a condition on all routes. Chris@0: * Chris@0: * Existing conditions will be overridden. Chris@0: * Chris@0: * @param string $condition The condition Chris@0: */ Chris@0: public function setCondition($condition) Chris@0: { Chris@0: foreach ($this->routes as $route) { Chris@0: $route->setCondition($condition); Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Adds defaults to all routes. Chris@0: * Chris@0: * An existing default value under the same name in a route will be overridden. Chris@0: * Chris@0: * @param array $defaults An array of default values Chris@0: */ Chris@0: public function addDefaults(array $defaults) Chris@0: { Chris@0: if ($defaults) { Chris@0: foreach ($this->routes as $route) { Chris@0: $route->addDefaults($defaults); Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Adds requirements to all routes. Chris@0: * Chris@0: * An existing requirement under the same name in a route will be overridden. Chris@0: * Chris@0: * @param array $requirements An array of requirements Chris@0: */ Chris@0: public function addRequirements(array $requirements) Chris@0: { Chris@0: if ($requirements) { Chris@0: foreach ($this->routes as $route) { Chris@0: $route->addRequirements($requirements); Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Adds options to all routes. Chris@0: * Chris@0: * An existing option value under the same name in a route will be overridden. Chris@0: * Chris@0: * @param array $options An array of options Chris@0: */ Chris@0: public function addOptions(array $options) Chris@0: { Chris@0: if ($options) { Chris@0: foreach ($this->routes as $route) { Chris@0: $route->addOptions($options); Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets the schemes (e.g. 'https') all child routes are restricted to. Chris@0: * Chris@14: * @param string|string[] $schemes The scheme or an array of schemes Chris@0: */ Chris@0: public function setSchemes($schemes) Chris@0: { Chris@0: foreach ($this->routes as $route) { Chris@0: $route->setSchemes($schemes); Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets the HTTP methods (e.g. 'POST') all child routes are restricted to. Chris@0: * Chris@14: * @param string|string[] $methods The method or an array of methods Chris@0: */ Chris@0: public function setMethods($methods) Chris@0: { Chris@0: foreach ($this->routes as $route) { Chris@0: $route->setMethods($methods); Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Returns an array of resources loaded to build this collection. Chris@0: * Chris@0: * @return ResourceInterface[] An array of resources Chris@0: */ Chris@0: public function getResources() Chris@0: { Chris@14: return array_values($this->resources); Chris@0: } Chris@0: Chris@0: /** Chris@14: * Adds a resource for this collection. If the resource already exists Chris@14: * it is not added. Chris@0: */ Chris@0: public function addResource(ResourceInterface $resource) Chris@0: { Chris@14: $key = (string) $resource; Chris@14: Chris@14: if (!isset($this->resources[$key])) { Chris@14: $this->resources[$key] = $resource; Chris@14: } Chris@0: } Chris@0: }