e29cc9da4ddea87c31106434681e125066751da8
[yaffs-website] / vendor / symfony / http-kernel / DataCollector / RequestDataCollector.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\DataCollector;
13
14 use Symfony\Component\HttpFoundation\ParameterBag;
15 use Symfony\Component\HttpFoundation\Request;
16 use Symfony\Component\HttpFoundation\Response;
17 use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
18 use Symfony\Component\HttpKernel\KernelEvents;
19 use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
20 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
21
22 /**
23  * RequestDataCollector.
24  *
25  * @author Fabien Potencier <fabien@symfony.com>
26  */
27 class RequestDataCollector extends DataCollector implements EventSubscriberInterface
28 {
29     /** @var \SplObjectStorage */
30     protected $controllers;
31
32     public function __construct()
33     {
34         $this->controllers = new \SplObjectStorage();
35     }
36
37     /**
38      * {@inheritdoc}
39      */
40     public function collect(Request $request, Response $response, \Exception $exception = null)
41     {
42         $responseHeaders = $response->headers->all();
43         foreach ($response->headers->getCookies() as $cookie) {
44             $responseHeaders['set-cookie'][] = (string) $cookie;
45         }
46
47         // attributes are serialized and as they can be anything, they need to be converted to strings.
48         $attributes = array();
49         $route = '';
50         foreach ($request->attributes->all() as $key => $value) {
51             if ('_route' === $key) {
52                 $route = is_object($value) ? $value->getPath() : $value;
53                 $attributes[$key] = $route;
54             } else {
55                 $attributes[$key] = $value;
56             }
57         }
58
59         $content = null;
60         try {
61             $content = $request->getContent();
62         } catch (\LogicException $e) {
63             // the user already got the request content as a resource
64             $content = false;
65         }
66
67         $sessionMetadata = array();
68         $sessionAttributes = array();
69         $session = null;
70         $flashes = array();
71         if ($request->hasSession()) {
72             $session = $request->getSession();
73             if ($session->isStarted()) {
74                 $sessionMetadata['Created'] = date(DATE_RFC822, $session->getMetadataBag()->getCreated());
75                 $sessionMetadata['Last used'] = date(DATE_RFC822, $session->getMetadataBag()->getLastUsed());
76                 $sessionMetadata['Lifetime'] = $session->getMetadataBag()->getLifetime();
77                 $sessionAttributes = $session->all();
78                 $flashes = $session->getFlashBag()->peekAll();
79             }
80         }
81
82         $statusCode = $response->getStatusCode();
83
84         $this->data = array(
85             'method' => $request->getMethod(),
86             'format' => $request->getRequestFormat(),
87             'content' => $content,
88             'content_type' => $response->headers->get('Content-Type', 'text/html'),
89             'status_text' => isset(Response::$statusTexts[$statusCode]) ? Response::$statusTexts[$statusCode] : '',
90             'status_code' => $statusCode,
91             'request_query' => $request->query->all(),
92             'request_request' => $request->request->all(),
93             'request_headers' => $request->headers->all(),
94             'request_server' => $request->server->all(),
95             'request_cookies' => $request->cookies->all(),
96             'request_attributes' => $attributes,
97             'route' => $route,
98             'response_headers' => $responseHeaders,
99             'session_metadata' => $sessionMetadata,
100             'session_attributes' => $sessionAttributes,
101             'flashes' => $flashes,
102             'path_info' => $request->getPathInfo(),
103             'controller' => 'n/a',
104             'locale' => $request->getLocale(),
105         );
106
107         if (isset($this->data['request_headers']['php-auth-pw'])) {
108             $this->data['request_headers']['php-auth-pw'] = '******';
109         }
110
111         if (isset($this->data['request_server']['PHP_AUTH_PW'])) {
112             $this->data['request_server']['PHP_AUTH_PW'] = '******';
113         }
114
115         if (isset($this->data['request_request']['_password'])) {
116             $this->data['request_request']['_password'] = '******';
117         }
118
119         foreach ($this->data as $key => $value) {
120             if (!is_array($value)) {
121                 continue;
122             }
123             if ('request_headers' === $key || 'response_headers' === $key) {
124                 $value = array_map(function ($v) { return isset($v[0]) && !isset($v[1]) ? $v[0] : $v; }, $value);
125             }
126             if ('request_server' !== $key && 'request_cookies' !== $key) {
127                 $this->data[$key] = array_map(array($this, 'cloneVar'), $value);
128             }
129         }
130
131         if (isset($this->controllers[$request])) {
132             $this->data['controller'] = $this->parseController($this->controllers[$request]);
133             unset($this->controllers[$request]);
134         }
135
136         if (null !== $session && $session->isStarted()) {
137             if ($request->attributes->has('_redirected')) {
138                 $this->data['redirect'] = $session->remove('sf_redirect');
139             }
140
141             if ($response->isRedirect()) {
142                 $session->set('sf_redirect', array(
143                     'token' => $response->headers->get('x-debug-token'),
144                     'route' => $request->attributes->get('_route', 'n/a'),
145                     'method' => $request->getMethod(),
146                     'controller' => $this->parseController($request->attributes->get('_controller')),
147                     'status_code' => $statusCode,
148                     'status_text' => Response::$statusTexts[(int) $statusCode],
149                 ));
150             }
151         }
152     }
153
154     public function getMethod()
155     {
156         return $this->data['method'];
157     }
158
159     public function getPathInfo()
160     {
161         return $this->data['path_info'];
162     }
163
164     public function getRequestRequest()
165     {
166         return new ParameterBag($this->data['request_request']);
167     }
168
169     public function getRequestQuery()
170     {
171         return new ParameterBag($this->data['request_query']);
172     }
173
174     public function getRequestHeaders()
175     {
176         return new ParameterBag($this->data['request_headers']);
177     }
178
179     public function getRequestServer($raw = false)
180     {
181         return new ParameterBag($raw ? $this->data['request_server'] : array_map(array($this, 'cloneVar'), $this->data['request_server']));
182     }
183
184     public function getRequestCookies($raw = false)
185     {
186         return new ParameterBag($raw ? $this->data['request_cookies'] : array_map(array($this, 'cloneVar'), $this->data['request_cookies']));
187     }
188
189     public function getRequestAttributes()
190     {
191         return new ParameterBag($this->data['request_attributes']);
192     }
193
194     public function getResponseHeaders()
195     {
196         return new ParameterBag($this->data['response_headers']);
197     }
198
199     public function getSessionMetadata()
200     {
201         return $this->data['session_metadata'];
202     }
203
204     public function getSessionAttributes()
205     {
206         return $this->data['session_attributes'];
207     }
208
209     public function getFlashes()
210     {
211         return $this->data['flashes'];
212     }
213
214     public function getContent()
215     {
216         return $this->data['content'];
217     }
218
219     public function getContentType()
220     {
221         return $this->data['content_type'];
222     }
223
224     public function getStatusText()
225     {
226         return $this->data['status_text'];
227     }
228
229     public function getStatusCode()
230     {
231         return $this->data['status_code'];
232     }
233
234     public function getFormat()
235     {
236         return $this->data['format'];
237     }
238
239     public function getLocale()
240     {
241         return $this->data['locale'];
242     }
243
244     /**
245      * Gets the route name.
246      *
247      * The _route request attributes is automatically set by the Router Matcher.
248      *
249      * @return string The route
250      */
251     public function getRoute()
252     {
253         return $this->data['route'];
254     }
255
256     public function getIdentifier()
257     {
258         return $this->data['route'] ?: (is_array($this->data['controller']) ? $this->data['controller']['class'].'::'.$this->data['controller']['method'].'()' : $this->data['controller']);
259     }
260
261     /**
262      * Gets the route parameters.
263      *
264      * The _route_params request attributes is automatically set by the RouterListener.
265      *
266      * @return array The parameters
267      */
268     public function getRouteParams()
269     {
270         if (!isset($this->data['request_attributes']['_route_params'])) {
271             return array();
272         }
273
274         $data = $this->data['request_attributes']['_route_params'];
275         $rawData = $data->getRawData();
276         if (!isset($rawData[1])) {
277             return array();
278         }
279
280         $params = array();
281         foreach ($rawData[1] as $k => $v) {
282             $params[$k] = $data->seek($k);
283         }
284
285         return $params;
286     }
287
288     /**
289      * Gets the parsed controller.
290      *
291      * @return array|string The controller as a string or array of data
292      *                      with keys 'class', 'method', 'file' and 'line'
293      */
294     public function getController()
295     {
296         return $this->data['controller'];
297     }
298
299     /**
300      * Gets the previous request attributes.
301      *
302      * @return array|bool A legacy array of data from the previous redirection response
303      *                    or false otherwise
304      */
305     public function getRedirect()
306     {
307         return isset($this->data['redirect']) ? $this->data['redirect'] : false;
308     }
309
310     public function onKernelController(FilterControllerEvent $event)
311     {
312         $this->controllers[$event->getRequest()] = $event->getController();
313     }
314
315     public function onKernelResponse(FilterResponseEvent $event)
316     {
317         if (!$event->isMasterRequest() || !$event->getRequest()->hasSession() || !$event->getRequest()->getSession()->isStarted()) {
318             return;
319         }
320
321         if ($event->getRequest()->getSession()->has('sf_redirect')) {
322             $event->getRequest()->attributes->set('_redirected', true);
323         }
324     }
325
326     public static function getSubscribedEvents()
327     {
328         return array(
329             KernelEvents::CONTROLLER => 'onKernelController',
330             KernelEvents::RESPONSE => 'onKernelResponse',
331         );
332     }
333
334     /**
335      * {@inheritdoc}
336      */
337     public function getName()
338     {
339         return 'request';
340     }
341
342     /**
343      * Parse a controller.
344      *
345      * @param mixed $controller The controller to parse
346      *
347      * @return array|string An array of controller data or a simple string
348      */
349     protected function parseController($controller)
350     {
351         if (is_string($controller) && false !== strpos($controller, '::')) {
352             $controller = explode('::', $controller);
353         }
354
355         if (is_array($controller)) {
356             try {
357                 $r = new \ReflectionMethod($controller[0], $controller[1]);
358
359                 return array(
360                     'class' => is_object($controller[0]) ? get_class($controller[0]) : $controller[0],
361                     'method' => $controller[1],
362                     'file' => $r->getFileName(),
363                     'line' => $r->getStartLine(),
364                 );
365             } catch (\ReflectionException $e) {
366                 if (is_callable($controller)) {
367                     // using __call or  __callStatic
368                     return array(
369                         'class' => is_object($controller[0]) ? get_class($controller[0]) : $controller[0],
370                         'method' => $controller[1],
371                         'file' => 'n/a',
372                         'line' => 'n/a',
373                     );
374                 }
375             }
376         }
377
378         if ($controller instanceof \Closure) {
379             $r = new \ReflectionFunction($controller);
380
381             return array(
382                 'class' => $r->getName(),
383                 'method' => null,
384                 'file' => $r->getFileName(),
385                 'line' => $r->getStartLine(),
386             );
387         }
388
389         if (is_object($controller)) {
390             $r = new \ReflectionClass($controller);
391
392             return array(
393                 'class' => $r->getName(),
394                 'method' => null,
395                 'file' => $r->getFileName(),
396                 'line' => $r->getStartLine(),
397             );
398         }
399
400         return is_string($controller) ? $controller : 'n/a';
401     }
402 }