[ Index ]

PHP Cross Reference of phpBB-3.2.11-deutsch

title

Body

[close]

/vendor/symfony/routing/Matcher/ -> UrlMatcher.php (source)

   1  <?php
   2  
   3  /*
   4   * This file is part of the Symfony package.
   5   *
   6   * (c) Fabien Potencier <fabien@symfony.com>
   7   *
   8   * For the full copyright and license information, please view the LICENSE
   9   * file that was distributed with this source code.
  10   */
  11  
  12  namespace Symfony\Component\Routing\Matcher;
  13  
  14  use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
  15  use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
  16  use Symfony\Component\HttpFoundation\Request;
  17  use Symfony\Component\Routing\Exception\MethodNotAllowedException;
  18  use Symfony\Component\Routing\Exception\ResourceNotFoundException;
  19  use Symfony\Component\Routing\RequestContext;
  20  use Symfony\Component\Routing\Route;
  21  use Symfony\Component\Routing\RouteCollection;
  22  
  23  /**
  24   * UrlMatcher matches URL based on a set of routes.
  25   *
  26   * @author Fabien Potencier <fabien@symfony.com>
  27   */
  28  class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
  29  {
  30      const REQUIREMENT_MATCH = 0;
  31      const REQUIREMENT_MISMATCH = 1;
  32      const ROUTE_MATCH = 2;
  33  
  34      protected $context;
  35      protected $allow = array();
  36      protected $routes;
  37      protected $request;
  38      protected $expressionLanguage;
  39  
  40      /**
  41       * @var ExpressionFunctionProviderInterface[]
  42       */
  43      protected $expressionLanguageProviders = array();
  44  
  45      public function __construct(RouteCollection $routes, RequestContext $context)
  46      {
  47          $this->routes = $routes;
  48          $this->context = $context;
  49      }
  50  
  51      /**
  52       * {@inheritdoc}
  53       */
  54      public function setContext(RequestContext $context)
  55      {
  56          $this->context = $context;
  57      }
  58  
  59      /**
  60       * {@inheritdoc}
  61       */
  62      public function getContext()
  63      {
  64          return $this->context;
  65      }
  66  
  67      /**
  68       * {@inheritdoc}
  69       */
  70      public function match($pathinfo)
  71      {
  72          $this->allow = array();
  73  
  74          if ($ret = $this->matchCollection(rawurldecode($pathinfo), $this->routes)) {
  75              return $ret;
  76          }
  77  
  78          throw 0 < \count($this->allow)
  79              ? new MethodNotAllowedException(array_unique($this->allow))
  80              : new ResourceNotFoundException(sprintf('No routes found for "%s".', $pathinfo));
  81      }
  82  
  83      /**
  84       * {@inheritdoc}
  85       */
  86      public function matchRequest(Request $request)
  87      {
  88          $this->request = $request;
  89  
  90          $ret = $this->match($request->getPathInfo());
  91  
  92          $this->request = null;
  93  
  94          return $ret;
  95      }
  96  
  97      public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider)
  98      {
  99          $this->expressionLanguageProviders[] = $provider;
 100      }
 101  
 102      /**
 103       * Tries to match a URL with a set of routes.
 104       *
 105       * @param string          $pathinfo The path info to be parsed
 106       * @param RouteCollection $routes   The set of routes
 107       *
 108       * @return array An array of parameters
 109       *
 110       * @throws ResourceNotFoundException If the resource could not be found
 111       * @throws MethodNotAllowedException If the resource was found but the request method is not allowed
 112       */
 113      protected function matchCollection($pathinfo, RouteCollection $routes)
 114      {
 115          foreach ($routes as $name => $route) {
 116              $compiledRoute = $route->compile();
 117  
 118              // check the static prefix of the URL first. Only use the more expensive preg_match when it matches
 119              if ('' !== $compiledRoute->getStaticPrefix() && 0 !== strpos($pathinfo, $compiledRoute->getStaticPrefix())) {
 120                  continue;
 121              }
 122  
 123              if (!preg_match($compiledRoute->getRegex(), $pathinfo, $matches)) {
 124                  continue;
 125              }
 126  
 127              $hostMatches = array();
 128              if ($compiledRoute->getHostRegex() && !preg_match($compiledRoute->getHostRegex(), $this->context->getHost(), $hostMatches)) {
 129                  continue;
 130              }
 131  
 132              $status = $this->handleRouteRequirements($pathinfo, $name, $route);
 133  
 134              if (self::REQUIREMENT_MISMATCH === $status[0]) {
 135                  continue;
 136              }
 137  
 138              // check HTTP method requirement
 139              if ($requiredMethods = $route->getMethods()) {
 140                  // HEAD and GET are equivalent as per RFC
 141                  if ('HEAD' === $method = $this->context->getMethod()) {
 142                      $method = 'GET';
 143                  }
 144  
 145                  if (!\in_array($method, $requiredMethods)) {
 146                      if (self::REQUIREMENT_MATCH === $status[0]) {
 147                          $this->allow = array_merge($this->allow, $requiredMethods);
 148                      }
 149  
 150                      continue;
 151                  }
 152              }
 153  
 154              if (self::ROUTE_MATCH === $status[0]) {
 155                  return $status[1];
 156              }
 157  
 158              return $this->getAttributes($route, $name, array_replace($matches, $hostMatches));
 159          }
 160      }
 161  
 162      /**
 163       * Returns an array of values to use as request attributes.
 164       *
 165       * As this method requires the Route object, it is not available
 166       * in matchers that do not have access to the matched Route instance
 167       * (like the PHP and Apache matcher dumpers).
 168       *
 169       * @param Route  $route      The route we are matching against
 170       * @param string $name       The name of the route
 171       * @param array  $attributes An array of attributes from the matcher
 172       *
 173       * @return array An array of parameters
 174       */
 175      protected function getAttributes(Route $route, $name, array $attributes)
 176      {
 177          $attributes['_route'] = $name;
 178  
 179          return $this->mergeDefaults($attributes, $route->getDefaults());
 180      }
 181  
 182      /**
 183       * Handles specific route requirements.
 184       *
 185       * @param string $pathinfo The path
 186       * @param string $name     The route name
 187       * @param Route  $route    The route
 188       *
 189       * @return array The first element represents the status, the second contains additional information
 190       */
 191      protected function handleRouteRequirements($pathinfo, $name, Route $route)
 192      {
 193          // expression condition
 194          if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), array('context' => $this->context, 'request' => $this->request ?: $this->createRequest($pathinfo)))) {
 195              return array(self::REQUIREMENT_MISMATCH, null);
 196          }
 197  
 198          // check HTTP scheme requirement
 199          $scheme = $this->context->getScheme();
 200          $status = $route->getSchemes() && !$route->hasScheme($scheme) ? self::REQUIREMENT_MISMATCH : self::REQUIREMENT_MATCH;
 201  
 202          return array($status, null);
 203      }
 204  
 205      /**
 206       * Get merged default parameters.
 207       *
 208       * @param array $params   The parameters
 209       * @param array $defaults The defaults
 210       *
 211       * @return array Merged default parameters
 212       */
 213      protected function mergeDefaults($params, $defaults)
 214      {
 215          foreach ($params as $key => $value) {
 216              if (!\is_int($key)) {
 217                  $defaults[$key] = $value;
 218              }
 219          }
 220  
 221          return $defaults;
 222      }
 223  
 224      protected function getExpressionLanguage()
 225      {
 226          if (null === $this->expressionLanguage) {
 227              if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) {
 228                  throw new \RuntimeException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.');
 229              }
 230              $this->expressionLanguage = new ExpressionLanguage(null, $this->expressionLanguageProviders);
 231          }
 232  
 233          return $this->expressionLanguage;
 234      }
 235  
 236      /**
 237       * @internal
 238       */
 239      protected function createRequest($pathinfo)
 240      {
 241          if (!class_exists('Symfony\Component\HttpFoundation\Request')) {
 242              return null;
 243          }
 244  
 245          return Request::create($this->context->getScheme().'://'.$this->context->getHost().$this->context->getBaseUrl().$pathinfo, $this->context->getMethod(), $this->context->getParameters(), array(), array(), array(
 246              'SCRIPT_FILENAME' => $this->context->getBaseUrl(),
 247              'SCRIPT_NAME' => $this->context->getBaseUrl(),
 248          ));
 249      }
 250  }


Generated: Wed Nov 11 20:33:01 2020 Cross-referenced by PHPXref 0.7.1