Updating Media dependent modules to versions compatible with core Media.
[yaffs-website] / vendor / symfony / http-kernel / EventListener / RouterListener.php
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\HttpFoundation\Response;
16 use Symfony\Component\HttpKernel\Event\GetResponseEvent;
17 use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
18 use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
19 use Symfony\Component\HttpKernel\Kernel;
20 use Symfony\Component\HttpKernel\KernelEvents;
21 use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
22 use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
23 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
24 use Symfony\Component\HttpFoundation\RequestStack;
25 use Symfony\Component\Routing\Exception\MethodNotAllowedException;
26 use Symfony\Component\Routing\Exception\NoConfigurationException;
27 use Symfony\Component\Routing\Exception\ResourceNotFoundException;
28 use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
29 use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
30 use Symfony\Component\Routing\RequestContext;
31 use Symfony\Component\Routing\RequestContextAwareInterface;
32 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
33 use Symfony\Component\HttpFoundation\Request;
34
35 /**
36  * Initializes the context from the request and sets request attributes based on a matching route.
37  *
38  * @author Fabien Potencier <fabien@symfony.com>
39  * @author Yonel Ceruto <yonelceruto@gmail.com>
40  */
41 class RouterListener implements EventSubscriberInterface
42 {
43     private $matcher;
44     private $context;
45     private $logger;
46     private $requestStack;
47     private $projectDir;
48     private $debug;
49
50     /**
51      * @param UrlMatcherInterface|RequestMatcherInterface $matcher      The Url or Request matcher
52      * @param RequestStack                                $requestStack A RequestStack instance
53      * @param RequestContext|null                         $context      The RequestContext (can be null when $matcher implements RequestContextAwareInterface)
54      * @param LoggerInterface|null                        $logger       The logger
55      * @param string                                      $projectDir
56      * @param bool                                        $debug
57      *
58      * @throws \InvalidArgumentException
59      */
60     public function __construct($matcher, RequestStack $requestStack, RequestContext $context = null, LoggerInterface $logger = null, $projectDir = null, $debug = true)
61     {
62         if (!$matcher instanceof UrlMatcherInterface && !$matcher instanceof RequestMatcherInterface) {
63             throw new \InvalidArgumentException('Matcher must either implement UrlMatcherInterface or RequestMatcherInterface.');
64         }
65
66         if (null === $context && !$matcher instanceof RequestContextAwareInterface) {
67             throw new \InvalidArgumentException('You must either pass a RequestContext or the matcher must implement RequestContextAwareInterface.');
68         }
69
70         $this->matcher = $matcher;
71         $this->context = $context ?: $matcher->getContext();
72         $this->requestStack = $requestStack;
73         $this->logger = $logger;
74         $this->projectDir = $projectDir;
75         $this->debug = $debug;
76     }
77
78     private function setCurrentRequest(Request $request = null)
79     {
80         if (null !== $request) {
81             try {
82                 $this->context->fromRequest($request);
83             } catch (\UnexpectedValueException $e) {
84                 throw new BadRequestHttpException($e->getMessage(), $e, $e->getCode());
85             }
86         }
87     }
88
89     /**
90      * After a sub-request is done, we need to reset the routing context to the parent request so that the URL generator
91      * operates on the correct context again.
92      *
93      * @param FinishRequestEvent $event
94      */
95     public function onKernelFinishRequest(FinishRequestEvent $event)
96     {
97         $this->setCurrentRequest($this->requestStack->getParentRequest());
98     }
99
100     public function onKernelRequest(GetResponseEvent $event)
101     {
102         $request = $event->getRequest();
103
104         $this->setCurrentRequest($request);
105
106         if ($request->attributes->has('_controller')) {
107             // routing is already done
108             return;
109         }
110
111         // add attributes based on the request (routing)
112         try {
113             // matching a request is more powerful than matching a URL path + context, so try that first
114             if ($this->matcher instanceof RequestMatcherInterface) {
115                 $parameters = $this->matcher->matchRequest($request);
116             } else {
117                 $parameters = $this->matcher->match($request->getPathInfo());
118             }
119
120             if (null !== $this->logger) {
121                 $this->logger->info('Matched route "{route}".', array(
122                     'route' => isset($parameters['_route']) ? $parameters['_route'] : 'n/a',
123                     'route_parameters' => $parameters,
124                     'request_uri' => $request->getUri(),
125                     'method' => $request->getMethod(),
126                 ));
127             }
128
129             $request->attributes->add($parameters);
130             unset($parameters['_route'], $parameters['_controller']);
131             $request->attributes->set('_route_params', $parameters);
132         } catch (ResourceNotFoundException $e) {
133             $message = sprintf('No route found for "%s %s"', $request->getMethod(), $request->getPathInfo());
134
135             if ($referer = $request->headers->get('referer')) {
136                 $message .= sprintf(' (from "%s")', $referer);
137             }
138
139             throw new NotFoundHttpException($message, $e);
140         } catch (MethodNotAllowedException $e) {
141             $message = sprintf('No route found for "%s %s": Method Not Allowed (Allow: %s)', $request->getMethod(), $request->getPathInfo(), implode(', ', $e->getAllowedMethods()));
142
143             throw new MethodNotAllowedHttpException($e->getAllowedMethods(), $message, $e);
144         }
145     }
146
147     public function onKernelException(GetResponseForExceptionEvent $event)
148     {
149         if (!$this->debug || !($e = $event->getException()) instanceof NotFoundHttpException) {
150             return;
151         }
152
153         if ($e->getPrevious() instanceof NoConfigurationException) {
154             $event->setResponse($this->createWelcomeResponse());
155         }
156     }
157
158     public static function getSubscribedEvents()
159     {
160         return array(
161             KernelEvents::REQUEST => array(array('onKernelRequest', 32)),
162             KernelEvents::FINISH_REQUEST => array(array('onKernelFinishRequest', 0)),
163             KernelEvents::EXCEPTION => array('onKernelException', -64),
164         );
165     }
166
167     private function createWelcomeResponse()
168     {
169         $version = Kernel::VERSION;
170         $baseDir = realpath($this->projectDir).DIRECTORY_SEPARATOR;
171         $docVersion = substr(Kernel::VERSION, 0, 3);
172
173         ob_start();
174         include __DIR__.'/../Resources/welcome.html.php';
175
176         return new Response(ob_get_clean(), Response::HTTP_NOT_FOUND);
177     }
178 }