class RouteCompiler

Same name in this branch

Compiler to generate derived information from a Route necessary for matching.

Hierarchy

Expanded class hierarchy of RouteCompiler

7 string references to 'RouteCompiler'
PhpFileLoaderTest::testLoadWithRoute in drupal/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Loader/PhpFileLoaderTest.php
RouteTest::getValidParameters in drupal/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Annotation/RouteTest.php
validpattern.php in drupal/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/validpattern.php
validpattern.yml in drupal/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/validpattern.yml
drupal/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/validpattern.yml
XmlFileLoaderTest::testLoadWithNamespacePrefix in drupal/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Loader/XmlFileLoaderTest.php

... See full list

File

drupal/core/lib/Drupal/Core/Routing/RouteCompiler.php, line 17
Definition of Drupal\Core\Routing\RouteCompiler.

Namespace

Drupal\Core\Routing
View source
class RouteCompiler extends SymfonyRouteCompiler implements RouteCompilerInterface {

  /**
   * The maximum number of path elements for a route pattern;
   */
  const MAX_PARTS = 9;

  /**
   * Utility constant to use for regular expressions against the path.
   */
  const REGEX_DELIMITER = '#';

  /**
   * Compiles the current route instance.
   *
   * Because so much of the parent class is private, we need to call the parent
   * class's compile() method and then dissect its return value to build our
   * new compiled object.  If upstream gets refactored so we can subclass more
   * easily then this may not be necessary.
   *
   * @param \Symfony\Component\Routing\Route $route
   *   A Route instance.
   *
   * @return \Drupal\Core\Routing\CompiledRoute
   *   A CompiledRoute instance.
   */
  public static function compile(Route $route) {
    $symfony_compiled = parent::compile($route);

    // The Drupal-specific compiled information.
    $stripped_path = static::getPathWithoutDefaults($route);
    $fit = static::getFit($stripped_path);
    $pattern_outline = static::getPatternOutline($stripped_path);
    $num_parts = count(explode('/', trim($pattern_outline, '/')));
    return new CompiledRoute($route, $fit, $pattern_outline, $num_parts, $symfony_compiled
      ->getStaticPrefix(), $symfony_compiled
      ->getRegex(), $symfony_compiled
      ->getTokens(), $symfony_compiled
      ->getPathVariables(), $symfony_compiled
      ->getHostRegex(), $symfony_compiled
      ->getHostTokens(), $symfony_compiled
      ->getHostVariables(), $symfony_compiled
      ->getVariables());
  }

  /**
   * Returns the pattern outline.
   *
   * The pattern outline is the path pattern but normalized so that all
   * placeholders are equal strings and default values are removed.
   *
   * @param string $path
   *   The path for which we want the normalized outline.
   *
   * @return string
   *   The path pattern outline.
   */
  public static function getPatternOutline($path) {
    return preg_replace('#\\{\\w+\\}#', '%', $path);
  }

  /**
   * Determines the fitness of the provided path.
   *
   * @param string $path
   *   The path whose fitness we want.
   *
   * @return int
   *   The fitness of the path, as an integer.
   */
  public static function getFit($path) {
    $parts = explode('/', trim($path, '/'), static::MAX_PARTS);
    $number_parts = count($parts);

    // We store the highest index of parts here to save some work in the fit
    // calculation loop.
    $slashes = $number_parts - 1;
    $fit = 0;
    foreach ($parts as $k => $part) {
      if (strpos($part, '{') === FALSE) {
        $fit |= 1 << $slashes - $k;
      }
    }
    return $fit;
  }

  /**
   * Returns the path of the route, without placeholders with a default value.
   *
   * When computing the path outline and fit, we want to skip default-value
   * placeholders.  If we didn't, the path would never match.  Note that this
   * only works for placeholders at the end of the path. Infix placeholders
   * with default values don't make sense anyway, so that should not be a
   * problem.
   *
   * @param \Symfony\Component\Routing\Route $route
   *   The route to have the placeholders removed from.
   *
   * @return string
   *   The path string, stripped of placeholders that have default values.
   */
  protected static function getPathWithoutDefaults(Route $route) {
    $path = $route
      ->getPattern();
    $defaults = $route
      ->getDefaults();

    // Remove placeholders with default values from the outline, so that they
    // will still match.
    $remove = array_map(function ($a) {
      return '/{' . $a . '}';
    }, array_keys($defaults));
    $path = str_replace($remove, '', $path);
    return $path;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
RouteCompiler::compile public static function Compiles the current route instance. Overrides RouteCompiler::compile
RouteCompiler::compilePattern private static function
RouteCompiler::computeRegexp private static function Computes the regexp used to match a specific token. It can be static text or a subpattern.
RouteCompiler::findNextSeparator private static function Returns the next static character in the Route pattern that will serve as a separator.
RouteCompiler::getFit public static function Determines the fitness of the provided path.
RouteCompiler::getPathWithoutDefaults protected static function Returns the path of the route, without placeholders with a default value.
RouteCompiler::getPatternOutline public static function Returns the pattern outline.
RouteCompiler::MAX_PARTS constant The maximum number of path elements for a route pattern;
RouteCompiler::REGEX_DELIMITER constant Utility constant to use for regular expressions against the path. Overrides RouteCompiler::REGEX_DELIMITER
RouteCompiler::SEPARATORS constant This string defines the characters that are automatically considered separators in front of optional placeholders (with default and no static text following). Such a single separator can be left out together with the optional placeholder from matching…