class RouteCollection

A RouteCollection represents a set of Route instances as a tree structure.

When adding a route, it overrides existing routes with the same name defined in the instance or its children and parents.

@author Fabien Potencier <fabien@symfony.com> @author Tobias Schultze <http://tobion.de>

@api

Hierarchy

  • class \Symfony\Component\Routing\RouteCollection implements \Symfony\Component\Routing\IteratorAggregate, \Symfony\Component\Routing\Countable

Expanded class hierarchy of RouteCollection

43 files declare their use of RouteCollection
AccessManager.php in drupal/core/lib/Drupal/Core/Access/AccessManager.php
Contains Drupal\Core\Access\AccessManager.
AnnotationClassLoader.php in drupal/core/vendor/symfony/routing/Symfony/Component/Routing/Loader/AnnotationClassLoader.php
AnnotationDirectoryLoader.php in drupal/core/vendor/symfony/routing/Symfony/Component/Routing/Loader/AnnotationDirectoryLoader.php
AnnotationFileLoader.php in drupal/core/vendor/symfony/routing/Symfony/Component/Routing/Loader/AnnotationFileLoader.php
ApacheMatcherDumperTest.php in drupal/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Matcher/Dumper/ApacheMatcherDumperTest.php

... See full list

File

drupal/core/vendor/symfony/routing/Symfony/Component/Routing/RouteCollection.php, line 27

Namespace

Symfony\Component\Routing
View source
class RouteCollection implements \IteratorAggregate, \Countable {
  private $routes;
  private $resources;
  private $prefix;
  private $parent;

  /**
   * Constructor.
   *
   * @api
   */
  public function __construct() {
    $this->routes = array();
    $this->resources = array();
    $this->prefix = '';
  }
  public function __clone() {
    foreach ($this->routes as $name => $route) {
      $this->routes[$name] = clone $route;
      if ($route instanceof RouteCollection) {
        $this->routes[$name]
          ->setParent($this);
      }
    }
  }

  /**
   * Gets the parent RouteCollection.
   *
   * @return RouteCollection|null The parent RouteCollection or null when it's the root
   */
  public function getParent() {
    return $this->parent;
  }

  /**
   * Gets the root RouteCollection of the tree.
   *
   * @return RouteCollection The root RouteCollection
   */
  public function getRoot() {
    $parent = $this;
    while ($parent
      ->getParent()) {
      $parent = $parent
        ->getParent();
    }
    return $parent;
  }

  /**
   * Gets the current RouteCollection as an Iterator that includes all routes and child route collections.
   *
   * @return \ArrayIterator An \ArrayIterator interface
   */
  public function getIterator() {
    return new \ArrayIterator($this->routes);
  }

  /**
   * Gets the number of Routes in this collection.
   *
   * @return int The number of routes in this collection, including nested collections
   */
  public function count() {
    $count = 0;
    foreach ($this->routes as $route) {
      $count += $route instanceof RouteCollection ? count($route) : 1;
    }
    return $count;
  }

  /**
   * Adds a route.
   *
   * @param string $name  The route name
   * @param Route  $route A Route instance
   *
   * @throws \InvalidArgumentException When route name contains non valid characters
   *
   * @api
   */
  public function add($name, Route $route) {
    if (!preg_match('/^[a-z0-9A-Z_.]+$/', $name)) {
      throw new \InvalidArgumentException(sprintf('The provided route name "%s" contains non valid characters. A route name must only contain digits (0-9), letters (a-z and A-Z), underscores (_) and dots (.).', $name));
    }
    $this
      ->remove($name);
    $this->routes[$name] = $route;
  }

  /**
   * Returns all routes in this collection and its children.
   *
   * @return array An array of routes
   */
  public function all() {
    $routes = array();
    foreach ($this->routes as $name => $route) {
      if ($route instanceof RouteCollection) {
        $routes = array_merge($routes, $route
          ->all());
      }
      else {
        $routes[$name] = $route;
      }
    }
    return $routes;
  }

  /**
   * Gets a route by name defined in this collection or its children.
   *
   * @param string $name The route name
   *
   * @return Route|null A Route instance or null when not found
   */
  public function get($name) {
    if (isset($this->routes[$name])) {
      return $this->routes[$name] instanceof RouteCollection ? null : $this->routes[$name];
    }
    foreach ($this->routes as $routes) {
      if ($routes instanceof RouteCollection && null !== ($route = $routes
        ->get($name))) {
        return $route;
      }
    }
    return null;
  }

  /**
   * Removes a route or an array of routes by name from all connected
   * collections (this instance and all parents and children).
   *
   * @param string|array $name The route name or an array of route names
   */
  public function remove($name) {
    $root = $this
      ->getRoot();
    foreach ((array) $name as $n) {
      $root
        ->removeRecursively($n);
    }
  }

  /**
   * Adds a route collection to the current set of routes (at the end of the current set).
   *
   * @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
   * @param array           $options      An array of options
   *
   * @throws \InvalidArgumentException When the RouteCollection already exists in the tree
   *
   * @api
   */
  public function addCollection(RouteCollection $collection, $prefix = '', $defaults = array(), $requirements = array(), $options = array()) {

    // prevent infinite loops by recursive referencing
    $root = $this
      ->getRoot();
    if ($root === $collection || $root
      ->hasCollection($collection)) {
      throw new \InvalidArgumentException('The RouteCollection already exists in the tree.');
    }

    // remove all routes with the same names in all existing collections
    $this
      ->remove(array_keys($collection
      ->all()));
    $collection
      ->setParent($this);

    // the sub-collection must have the prefix of the parent (current instance) prepended because it does not
    // necessarily already have it applied (depending on the order RouteCollections are added to each other)
    $collection
      ->addPrefix($this
      ->getPrefix() . $prefix, $defaults, $requirements, $options);
    $this->routes[] = $collection;
  }

  /**
   * Adds a prefix to all routes in the current set.
   *
   * @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(), $options = array()) {

    // a prefix must not end with a slash
    $prefix = rtrim($prefix, '/');
    if ('' === $prefix && empty($defaults) && empty($requirements) && empty($options)) {
      return;
    }

    // a prefix must start with a slash
    if ('' !== $prefix && '/' !== $prefix[0]) {
      $prefix = '/' . $prefix;
    }
    $this->prefix = $prefix . $this->prefix;
    foreach ($this->routes as $route) {
      if ($route instanceof RouteCollection) {
        $route
          ->addPrefix($prefix, $defaults, $requirements, $options);
      }
      else {
        $route
          ->setPattern($prefix . $route
          ->getPattern());
        $route
          ->addDefaults($defaults);
        $route
          ->addRequirements($requirements);
        $route
          ->addOptions($options);
      }
    }
  }

  /**
   * Returns the prefix that may contain placeholders.
   *
   * @return string The prefix
   */
  public function getPrefix() {
    return $this->prefix;
  }

  /**
   * Returns an array of resources loaded to build this collection.
   *
   * @return ResourceInterface[] An array of resources
   */
  public function getResources() {
    $resources = $this->resources;
    foreach ($this as $routes) {
      if ($routes instanceof RouteCollection) {
        $resources = array_merge($resources, $routes
          ->getResources());
      }
    }
    return array_unique($resources);
  }

  /**
   * Adds a resource for this collection.
   *
   * @param ResourceInterface $resource A resource instance
   */
  public function addResource(ResourceInterface $resource) {
    $this->resources[] = $resource;
  }

  /**
   * Sets the parent RouteCollection. It's only used internally from one RouteCollection
   * to another. It makes no sense to be available as part of the public API.
   *
   * @param RouteCollection $parent The parent RouteCollection
   */
  private function setParent(RouteCollection $parent) {
    $this->parent = $parent;
  }

  /**
   * Removes a route by name from this collection and its children recursively.
   *
   * @param string $name The route name
   *
   * @return Boolean true when found
   */
  private function removeRecursively($name) {

    // It is ensured by the adders (->add and ->addCollection) that there can
    // only be one route per name in all connected collections. So we can stop
    // iterating recursively on the first hit.
    if (isset($this->routes[$name])) {
      unset($this->routes[$name]);
      return true;
    }
    foreach ($this->routes as $routes) {
      if ($routes instanceof RouteCollection && $routes
        ->removeRecursively($name)) {
        return true;
      }
    }
    return false;
  }

  /**
   * Checks whether the given RouteCollection is already set in any child of the current instance.
   *
   * @param RouteCollection $collection A RouteCollection instance
   *
   * @return Boolean
   */
  private function hasCollection(RouteCollection $collection) {
    foreach ($this->routes as $routes) {
      if ($routes === $collection || $routes instanceof RouteCollection && $routes
        ->hasCollection($collection)) {
        return true;
      }
    }
    return false;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
RouteCollection::$parent private property
RouteCollection::$prefix private property
RouteCollection::$resources private property
RouteCollection::$routes private property
RouteCollection::add public function Adds a route.
RouteCollection::addCollection public function Adds a route collection to the current set of routes (at the end of the current set).
RouteCollection::addPrefix public function Adds a prefix to all routes in the current set.
RouteCollection::addResource public function Adds a resource for this collection.
RouteCollection::all public function Returns all routes in this collection and its children.
RouteCollection::count public function Gets the number of Routes in this collection.
RouteCollection::get public function Gets a route by name defined in this collection or its children.
RouteCollection::getIterator public function Gets the current RouteCollection as an Iterator that includes all routes and child route collections.
RouteCollection::getParent public function Gets the parent RouteCollection.
RouteCollection::getPrefix public function Returns the prefix that may contain placeholders.
RouteCollection::getResources public function Returns an array of resources loaded to build this collection.
RouteCollection::getRoot public function Gets the root RouteCollection of the tree.
RouteCollection::hasCollection private function Checks whether the given RouteCollection is already set in any child of the current instance.
RouteCollection::remove public function Removes a route or an array of routes by name from all connected collections (this instance and all parents and children).
RouteCollection::removeRecursively private function Removes a route by name from this collection and its children recursively.
RouteCollection::setParent private function Sets the parent RouteCollection. It's only used internally from one RouteCollection to another. It makes no sense to be available as part of the public API.
RouteCollection::__clone public function
RouteCollection::__construct public function Constructor.