class UrlMatcher

UrlMatcher matches URL based on a set of routes.

@author Fabien Potencier <fabien@symfony.com>

@api

Hierarchy

Expanded class hierarchy of UrlMatcher

4 files declare their use of UrlMatcher
RedirectableUrlMatcher.php in drupal/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/RedirectableUrlMatcher.php
TraceableUrlMatcher.php in drupal/core/vendor/symfony/routing/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php
UrlMatcher.php in drupal/core/vendor/symfony-cmf/routing/Symfony/Cmf/Component/Routing/NestedMatcher/UrlMatcher.php
UrlMatcherTest.php in drupal/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php

File

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

Namespace

Symfony\Component\Routing\Matcher
View source
class UrlMatcher implements UrlMatcherInterface {
  const REQUIREMENT_MATCH = 0;
  const REQUIREMENT_MISMATCH = 1;
  const ROUTE_MATCH = 2;

  /**
   * @var RequestContext
   */
  protected $context;

  /**
   * @var array
   */
  protected $allow = array();

  /**
   * @var RouteCollection
   */
  protected $routes;

  /**
   * Constructor.
   *
   * @param RouteCollection $routes  A RouteCollection instance
   * @param RequestContext  $context The context
   *
   * @api
   */
  public function __construct(RouteCollection $routes, RequestContext $context) {
    $this->routes = $routes;
    $this->context = $context;
  }

  /**
   * {@inheritdoc}
   */
  public function setContext(RequestContext $context) {
    $this->context = $context;
  }

  /**
   * {@inheritdoc}
   */
  public function getContext() {
    return $this->context;
  }

  /**
   * {@inheritdoc}
   */
  public function match($pathinfo) {
    $this->allow = array();
    if ($ret = $this
      ->matchCollection(rawurldecode($pathinfo), $this->routes)) {
      return $ret;
    }
    throw 0 < count($this->allow) ? new MethodNotAllowedException(array_unique(array_map('strtoupper', $this->allow))) : new ResourceNotFoundException();
  }

  /**
   * Tries to match a URL with a set of routes.
   *
   * @param string          $pathinfo The path info to be parsed
   * @param RouteCollection $routes   The set of routes
   *
   * @return array An array of parameters
   *
   * @throws ResourceNotFoundException If the resource could not be found
   * @throws MethodNotAllowedException If the resource was found but the request method is not allowed
   */
  protected function matchCollection($pathinfo, RouteCollection $routes) {
    foreach ($routes as $name => $route) {
      $compiledRoute = $route
        ->compile();

      // check the static prefix of the URL first. Only use the more expensive preg_match when it matches
      if ('' !== $compiledRoute
        ->getStaticPrefix() && 0 !== strpos($pathinfo, $compiledRoute
        ->getStaticPrefix())) {
        continue;
      }
      if (!preg_match($compiledRoute
        ->getRegex(), $pathinfo, $matches)) {
        continue;
      }
      $hostMatches = array();
      if ($compiledRoute
        ->getHostRegex() && !preg_match($compiledRoute
        ->getHostRegex(), $this->context
        ->getHost(), $hostMatches)) {
        continue;
      }

      // check HTTP method requirement
      if ($req = $route
        ->getRequirement('_method')) {

        // HEAD and GET are equivalent as per RFC
        if ('HEAD' === ($method = $this->context
          ->getMethod())) {
          $method = 'GET';
        }
        if (!in_array($method, $req = explode('|', strtoupper($req)))) {
          $this->allow = array_merge($this->allow, $req);
          continue;
        }
      }
      $status = $this
        ->handleRouteRequirements($pathinfo, $name, $route);
      if (self::ROUTE_MATCH === $status[0]) {
        return $status[1];
      }
      if (self::REQUIREMENT_MISMATCH === $status[0]) {
        continue;
      }
      return $this
        ->getAttributes($route, $name, array_replace($matches, $hostMatches));
    }
  }

  /**
   * Returns an array of values to use as request attributes.
   *
   * As this method requires the Route object, it is not available
   * in matchers that do not have access to the matched Route instance
   * (like the PHP and Apache matcher dumpers).
   *
   * @param Route  $route      The route we are matching against
   * @param string $name       The name of the route
   * @param array  $attributes An array of attributes from the matcher
   *
   * @return array An array of parameters
   */
  protected function getAttributes(Route $route, $name, array $attributes) {
    $attributes['_route'] = $name;
    return $this
      ->mergeDefaults($attributes, $route
      ->getDefaults());
  }

  /**
   * Handles specific route requirements.
   *
   * @param string $pathinfo The path
   * @param string $name     The route name
   * @param Route  $route    The route
   *
   * @return array The first element represents the status, the second contains additional information
   */
  protected function handleRouteRequirements($pathinfo, $name, Route $route) {

    // check HTTP scheme requirement
    $scheme = $route
      ->getRequirement('_scheme');
    $status = $scheme && $scheme !== $this->context
      ->getScheme() ? self::REQUIREMENT_MISMATCH : self::REQUIREMENT_MATCH;
    return array(
      $status,
      null,
    );
  }

  /**
   * Get merged default parameters.
   *
   * @param array $params   The parameters
   * @param array $defaults The defaults
   *
   * @return array Merged default parameters
   */
  protected function mergeDefaults($params, $defaults) {
    foreach ($params as $key => $value) {
      if (!is_int($key)) {
        $defaults[$key] = $value;
      }
    }
    return $defaults;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
UrlMatcher::$allow protected property
UrlMatcher::$context protected property
UrlMatcher::$routes protected property
UrlMatcher::getAttributes protected function Returns an array of values to use as request attributes. 1
UrlMatcher::getContext public function Gets the request context. Overrides RequestContextAwareInterface::getContext
UrlMatcher::handleRouteRequirements protected function Handles specific route requirements. 1
UrlMatcher::match public function Tries to match a URL path with a set of routes. Overrides UrlMatcherInterface::match 5
UrlMatcher::matchCollection protected function Tries to match a URL with a set of routes. 1
UrlMatcher::mergeDefaults protected function Get merged default parameters.
UrlMatcher::REQUIREMENT_MATCH constant
UrlMatcher::REQUIREMENT_MISMATCH constant
UrlMatcher::ROUTE_MATCH constant
UrlMatcher::setContext public function Sets the request context. Overrides RequestContextAwareInterface::setContext
UrlMatcher::__construct public function Constructor. 4