[ Index ]

PHP Cross Reference of phpBB-3.2.11-deutsch

title

Body

[close]

/vendor/symfony/http-kernel/EventListener/ -> RouterListener.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\HttpKernel\EventListener;
  13  
  14  use Psr\Log\LoggerInterface;
  15  use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  16  use Symfony\Component\HttpFoundation\Request;
  17  use Symfony\Component\HttpFoundation\RequestStack;
  18  use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
  19  use Symfony\Component\HttpKernel\Event\GetResponseEvent;
  20  use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
  21  use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
  22  use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  23  use Symfony\Component\HttpKernel\KernelEvents;
  24  use Symfony\Component\Routing\Exception\MethodNotAllowedException;
  25  use Symfony\Component\Routing\Exception\ResourceNotFoundException;
  26  use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
  27  use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
  28  use Symfony\Component\Routing\RequestContext;
  29  use Symfony\Component\Routing\RequestContextAwareInterface;
  30  
  31  /**
  32   * Initializes the context from the request and sets request attributes based on a matching route.
  33   *
  34   * This listener works in 2 modes:
  35   *
  36   *  * 2.3 compatibility mode where you must call setRequest whenever the Request changes.
  37   *  * 2.4+ mode where you must pass a RequestStack instance in the constructor.
  38   *
  39   * @author Fabien Potencier <fabien@symfony.com>
  40   */
  41  class RouterListener implements EventSubscriberInterface
  42  {
  43      private $matcher;
  44      private $context;
  45      private $logger;
  46      private $request;
  47      private $requestStack;
  48  
  49      /**
  50       * RequestStack will become required in 3.0.
  51       *
  52       * @param UrlMatcherInterface|RequestMatcherInterface $matcher      The Url or Request matcher
  53       * @param RequestStack                                $requestStack A RequestStack instance
  54       * @param RequestContext|null                         $context      The RequestContext (can be null when $matcher implements RequestContextAwareInterface)
  55       * @param LoggerInterface|null                        $logger       The logger
  56       *
  57       * @throws \InvalidArgumentException
  58       */
  59      public function __construct($matcher, $requestStack = null, $context = null, $logger = null)
  60      {
  61          if ($requestStack instanceof RequestContext || $context instanceof LoggerInterface || $logger instanceof RequestStack) {
  62              $tmp = $requestStack;
  63              $requestStack = $logger;
  64              $logger = $context;
  65              $context = $tmp;
  66  
  67              @trigger_error('The '.__METHOD__.' method now requires a RequestStack to be given as second argument as '.__CLASS__.'::setRequest method will not be supported anymore in 3.0.', E_USER_DEPRECATED);
  68          } elseif (!$requestStack instanceof RequestStack) {
  69              @trigger_error('The '.__METHOD__.' method now requires a RequestStack instance as '.__CLASS__.'::setRequest method will not be supported anymore in 3.0.', E_USER_DEPRECATED);
  70          }
  71  
  72          if (null !== $requestStack && !$requestStack instanceof RequestStack) {
  73              throw new \InvalidArgumentException('RequestStack instance expected.');
  74          }
  75          if (null !== $context && !$context instanceof RequestContext) {
  76              throw new \InvalidArgumentException('RequestContext instance expected.');
  77          }
  78          if (null !== $logger && !$logger instanceof LoggerInterface) {
  79              throw new \InvalidArgumentException('Logger must implement LoggerInterface.');
  80          }
  81  
  82          if (!$matcher instanceof UrlMatcherInterface && !$matcher instanceof RequestMatcherInterface) {
  83              throw new \InvalidArgumentException('Matcher must either implement UrlMatcherInterface or RequestMatcherInterface.');
  84          }
  85  
  86          if (null === $context && !$matcher instanceof RequestContextAwareInterface) {
  87              throw new \InvalidArgumentException('You must either pass a RequestContext or the matcher must implement RequestContextAwareInterface.');
  88          }
  89  
  90          $this->matcher = $matcher;
  91          $this->context = $context ?: $matcher->getContext();
  92          $this->requestStack = $requestStack;
  93          $this->logger = $logger;
  94      }
  95  
  96      /**
  97       * Sets the current Request.
  98       *
  99       * This method was used to synchronize the Request, but as the HttpKernel
 100       * is doing that automatically now, you should never call it directly.
 101       * It is kept public for BC with the 2.3 version.
 102       *
 103       * @param Request|null $request A Request instance
 104       *
 105       * @deprecated since version 2.4, to be removed in 3.0.
 106       */
 107      public function setRequest(Request $request = null)
 108      {
 109          @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.4 and will be made private in 3.0.', E_USER_DEPRECATED);
 110  
 111          $this->setCurrentRequest($request);
 112      }
 113  
 114      private function setCurrentRequest(Request $request = null)
 115      {
 116          if (null !== $request && $this->request !== $request) {
 117              try {
 118                  $this->context->fromRequest($request);
 119              } catch (\UnexpectedValueException $e) {
 120                  throw new BadRequestHttpException($e->getMessage(), $e, $e->getCode());
 121              }
 122          }
 123  
 124          $this->request = $request;
 125      }
 126  
 127      public function onKernelFinishRequest(FinishRequestEvent $event)
 128      {
 129          if (null === $this->requestStack) {
 130              return; // removed when requestStack is required
 131          }
 132  
 133          $this->setCurrentRequest($this->requestStack->getParentRequest());
 134      }
 135  
 136      public function onKernelRequest(GetResponseEvent $event)
 137      {
 138          $request = $event->getRequest();
 139  
 140          // initialize the context that is also used by the generator (assuming matcher and generator share the same context instance)
 141          // we call setCurrentRequest even if most of the time, it has already been done to keep compatibility
 142          // with frameworks which do not use the Symfony service container
 143          // when we have a RequestStack, no need to do it
 144          if (null !== $this->requestStack) {
 145              $this->setCurrentRequest($request);
 146          }
 147  
 148          if ($request->attributes->has('_controller')) {
 149              // routing is already done
 150              return;
 151          }
 152  
 153          // add attributes based on the request (routing)
 154          try {
 155              // matching a request is more powerful than matching a URL path + context, so try that first
 156              if ($this->matcher instanceof RequestMatcherInterface) {
 157                  $parameters = $this->matcher->matchRequest($request);
 158              } else {
 159                  $parameters = $this->matcher->match($request->getPathInfo());
 160              }
 161  
 162              if (null !== $this->logger) {
 163                  $this->logger->info(sprintf('Matched route "%s".', isset($parameters['_route']) ? $parameters['_route'] : 'n/a'), array(
 164                      'route_parameters' => $parameters,
 165                      'request_uri' => $request->getUri(),
 166                  ));
 167              }
 168  
 169              $request->attributes->add($parameters);
 170              unset($parameters['_route'], $parameters['_controller']);
 171              $request->attributes->set('_route_params', $parameters);
 172          } catch (ResourceNotFoundException $e) {
 173              $message = sprintf('No route found for "%s %s"', $request->getMethod(), $request->getPathInfo());
 174  
 175              if ($referer = $request->headers->get('referer')) {
 176                  $message .= sprintf(' (from "%s")', $referer);
 177              }
 178  
 179              throw new NotFoundHttpException($message, $e);
 180          } catch (MethodNotAllowedException $e) {
 181              $message = sprintf('No route found for "%s %s": Method Not Allowed (Allow: %s)', $request->getMethod(), $request->getPathInfo(), implode(', ', $e->getAllowedMethods()));
 182  
 183              throw new MethodNotAllowedHttpException($e->getAllowedMethods(), $message, $e);
 184          }
 185      }
 186  
 187      public static function getSubscribedEvents()
 188      {
 189          return array(
 190              KernelEvents::REQUEST => array(array('onKernelRequest', 32)),
 191              KernelEvents::FINISH_REQUEST => array(array('onKernelFinishRequest', 0)),
 192          );
 193      }
 194  }


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