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