annotate vendor/symfony/http-kernel/DataCollector/RequestDataCollector.php @ 19:fa3358dc1485 tip

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