2015-08-17 17:00:26 -07:00
< ? php
/*
* This file is part of the Symfony package .
*
* ( c ) Fabien Potencier < fabien @ symfony . com >
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
namespace Symfony\Component\HttpKernel\DataCollector ;
2018-11-23 12:29:20 +00:00
use Symfony\Component\EventDispatcher\EventSubscriberInterface ;
use Symfony\Component\HttpFoundation\Cookie ;
2015-08-17 17:00:26 -07:00
use Symfony\Component\HttpFoundation\ParameterBag ;
use Symfony\Component\HttpFoundation\Request ;
use Symfony\Component\HttpFoundation\Response ;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent ;
2018-11-23 12:29:20 +00:00
use Symfony\Component\HttpKernel\Event\FilterResponseEvent ;
use Symfony\Component\HttpKernel\KernelEvents ;
2015-08-17 17:00:26 -07:00
/**
* @ author Fabien Potencier < fabien @ symfony . com >
*/
2018-11-23 12:29:20 +00:00
class RequestDataCollector extends DataCollector implements EventSubscriberInterface , LateDataCollectorInterface
2015-08-17 17:00:26 -07:00
{
protected $controllers ;
public function __construct ()
{
$this -> controllers = new \SplObjectStorage ();
}
/**
* { @ inheritdoc }
*/
public function collect ( Request $request , Response $response , \Exception $exception = null )
{
// attributes are serialized and as they can be anything, they need to be converted to strings.
$attributes = array ();
2018-11-23 12:29:20 +00:00
$route = '' ;
2015-08-17 17:00:26 -07:00
foreach ( $request -> attributes -> all () as $key => $value ) {
2018-11-23 12:29:20 +00:00
if ( '_route' === $key ) {
$route = \is_object ( $value ) ? $value -> getPath () : $value ;
$attributes [ $key ] = $route ;
2015-08-17 17:00:26 -07:00
} else {
2018-11-23 12:29:20 +00:00
$attributes [ $key ] = $value ;
2015-08-17 17:00:26 -07:00
}
}
$content = null ;
try {
$content = $request -> getContent ();
} catch ( \LogicException $e ) {
// the user already got the request content as a resource
$content = false ;
}
$sessionMetadata = array ();
$sessionAttributes = array ();
2018-11-23 12:29:20 +00:00
$session = null ;
2015-08-17 17:00:26 -07:00
$flashes = array ();
if ( $request -> hasSession ()) {
$session = $request -> getSession ();
if ( $session -> isStarted ()) {
$sessionMetadata [ 'Created' ] = date ( DATE_RFC822 , $session -> getMetadataBag () -> getCreated ());
$sessionMetadata [ 'Last used' ] = date ( DATE_RFC822 , $session -> getMetadataBag () -> getLastUsed ());
$sessionMetadata [ 'Lifetime' ] = $session -> getMetadataBag () -> getLifetime ();
$sessionAttributes = $session -> all ();
$flashes = $session -> getFlashBag () -> peekAll ();
}
}
$statusCode = $response -> getStatusCode ();
2018-11-23 12:29:20 +00:00
$responseCookies = array ();
foreach ( $response -> headers -> getCookies () as $cookie ) {
$responseCookies [ $cookie -> getName ()] = $cookie ;
}
2015-08-17 17:00:26 -07:00
$this -> data = array (
2018-11-23 12:29:20 +00:00
'method' => $request -> getMethod (),
2015-08-17 17:00:26 -07:00
'format' => $request -> getRequestFormat (),
'content' => $content ,
'content_type' => $response -> headers -> get ( 'Content-Type' , 'text/html' ),
'status_text' => isset ( Response :: $statusTexts [ $statusCode ]) ? Response :: $statusTexts [ $statusCode ] : '' ,
'status_code' => $statusCode ,
'request_query' => $request -> query -> all (),
'request_request' => $request -> request -> all (),
'request_headers' => $request -> headers -> all (),
'request_server' => $request -> server -> all (),
'request_cookies' => $request -> cookies -> all (),
'request_attributes' => $attributes ,
2018-11-23 12:29:20 +00:00
'route' => $route ,
'response_headers' => $response -> headers -> all (),
'response_cookies' => $responseCookies ,
2015-08-17 17:00:26 -07:00
'session_metadata' => $sessionMetadata ,
'session_attributes' => $sessionAttributes ,
'flashes' => $flashes ,
'path_info' => $request -> getPathInfo (),
'controller' => 'n/a' ,
'locale' => $request -> getLocale (),
);
if ( isset ( $this -> data [ 'request_headers' ][ 'php-auth-pw' ])) {
$this -> data [ 'request_headers' ][ 'php-auth-pw' ] = '******' ;
}
if ( isset ( $this -> data [ 'request_server' ][ 'PHP_AUTH_PW' ])) {
$this -> data [ 'request_server' ][ 'PHP_AUTH_PW' ] = '******' ;
}
if ( isset ( $this -> data [ 'request_request' ][ '_password' ])) {
$this -> data [ 'request_request' ][ '_password' ] = '******' ;
}
2017-02-02 16:28:38 -08:00
foreach ( $this -> data as $key => $value ) {
2018-11-23 12:29:20 +00:00
if ( ! \is_array ( $value )) {
2017-02-02 16:28:38 -08:00
continue ;
}
if ( 'request_headers' === $key || 'response_headers' === $key ) {
2018-11-23 12:29:20 +00:00
$this -> data [ $key ] = array_map ( function ( $v ) { return isset ( $v [ 0 ]) && ! isset ( $v [ 1 ]) ? $v [ 0 ] : $v ; }, $value );
2017-02-02 16:28:38 -08:00
}
}
2015-08-17 17:00:26 -07:00
if ( isset ( $this -> controllers [ $request ])) {
2018-11-23 12:29:20 +00:00
$this -> data [ 'controller' ] = $this -> parseController ( $this -> controllers [ $request ]);
2015-08-17 17:00:26 -07:00
unset ( $this -> controllers [ $request ]);
}
2018-11-23 12:29:20 +00:00
if ( $request -> attributes -> has ( '_redirected' ) && $redirectCookie = $request -> cookies -> get ( 'sf_redirect' )) {
$this -> data [ 'redirect' ] = json_decode ( $redirectCookie , true );
$response -> headers -> clearCookie ( 'sf_redirect' );
}
if ( $response -> isRedirect ()) {
$response -> headers -> setCookie ( new Cookie (
'sf_redirect' ,
json_encode ( array (
'token' => $response -> headers -> get ( 'x-debug-token' ),
'route' => $request -> attributes -> get ( '_route' , 'n/a' ),
'method' => $request -> getMethod (),
'controller' => $this -> parseController ( $request -> attributes -> get ( '_controller' )),
'status_code' => $statusCode ,
'status_text' => Response :: $statusTexts [( int ) $statusCode ],
))
));
}
$this -> data [ 'identifier' ] = $this -> data [ 'route' ] ? : ( \is_array ( $this -> data [ 'controller' ]) ? $this -> data [ 'controller' ][ 'class' ] . '::' . $this -> data [ 'controller' ][ 'method' ] . '()' : $this -> data [ 'controller' ]);
}
public function lateCollect ()
{
$this -> data = $this -> cloneVar ( $this -> data );
}
public function reset ()
{
$this -> data = array ();
$this -> controllers = new \SplObjectStorage ();
}
public function getMethod ()
{
return $this -> data [ 'method' ];
2015-08-17 17:00:26 -07:00
}
public function getPathInfo ()
{
return $this -> data [ 'path_info' ];
}
public function getRequestRequest ()
{
2018-11-23 12:29:20 +00:00
return new ParameterBag ( $this -> data [ 'request_request' ] -> getValue ());
2015-08-17 17:00:26 -07:00
}
public function getRequestQuery ()
{
2018-11-23 12:29:20 +00:00
return new ParameterBag ( $this -> data [ 'request_query' ] -> getValue ());
2015-08-17 17:00:26 -07:00
}
public function getRequestHeaders ()
{
2018-11-23 12:29:20 +00:00
return new ParameterBag ( $this -> data [ 'request_headers' ] -> getValue ());
2015-08-17 17:00:26 -07:00
}
2018-11-23 12:29:20 +00:00
public function getRequestServer ( $raw = false )
2015-08-17 17:00:26 -07:00
{
2018-11-23 12:29:20 +00:00
return new ParameterBag ( $this -> data [ 'request_server' ] -> getValue ( $raw ));
2015-08-17 17:00:26 -07:00
}
2018-11-23 12:29:20 +00:00
public function getRequestCookies ( $raw = false )
2015-08-17 17:00:26 -07:00
{
2018-11-23 12:29:20 +00:00
return new ParameterBag ( $this -> data [ 'request_cookies' ] -> getValue ( $raw ));
2015-08-17 17:00:26 -07:00
}
public function getRequestAttributes ()
{
2018-11-23 12:29:20 +00:00
return new ParameterBag ( $this -> data [ 'request_attributes' ] -> getValue ());
2015-08-17 17:00:26 -07:00
}
public function getResponseHeaders ()
{
2018-11-23 12:29:20 +00:00
return new ParameterBag ( $this -> data [ 'response_headers' ] -> getValue ());
}
public function getResponseCookies ()
{
return new ParameterBag ( $this -> data [ 'response_cookies' ] -> getValue ());
2015-08-17 17:00:26 -07:00
}
public function getSessionMetadata ()
{
2018-11-23 12:29:20 +00:00
return $this -> data [ 'session_metadata' ] -> getValue ();
2015-08-17 17:00:26 -07:00
}
public function getSessionAttributes ()
{
2018-11-23 12:29:20 +00:00
return $this -> data [ 'session_attributes' ] -> getValue ();
2015-08-17 17:00:26 -07:00
}
public function getFlashes ()
{
2018-11-23 12:29:20 +00:00
return $this -> data [ 'flashes' ] -> getValue ();
2015-08-17 17:00:26 -07:00
}
public function getContent ()
{
return $this -> data [ 'content' ];
}
public function getContentType ()
{
return $this -> data [ 'content_type' ];
}
public function getStatusText ()
{
return $this -> data [ 'status_text' ];
}
public function getStatusCode ()
{
return $this -> data [ 'status_code' ];
}
public function getFormat ()
{
return $this -> data [ 'format' ];
}
public function getLocale ()
{
return $this -> data [ 'locale' ];
}
/**
* Gets the route name .
*
* The _route request attributes is automatically set by the Router Matcher .
*
* @ return string The route
*/
public function getRoute ()
{
2018-11-23 12:29:20 +00:00
return $this -> data [ 'route' ];
}
public function getIdentifier ()
{
return $this -> data [ 'identifier' ];
2015-08-17 17:00:26 -07:00
}
/**
* Gets the route parameters .
*
* The _route_params request attributes is automatically set by the RouterListener .
*
* @ return array The parameters
*/
public function getRouteParams ()
{
2018-11-23 12:29:20 +00:00
return isset ( $this -> data [ 'request_attributes' ][ '_route_params' ]) ? $this -> data [ 'request_attributes' ][ '_route_params' ] -> getValue () : array ();
2015-08-17 17:00:26 -07:00
}
/**
2018-11-23 12:29:20 +00:00
* Gets the parsed controller .
2015-08-17 17:00:26 -07:00
*
2018-11-23 12:29:20 +00:00
* @ return array | string The controller as a string or array of data
* with keys 'class' , 'method' , 'file' and 'line'
2015-08-17 17:00:26 -07:00
*/
public function getController ()
{
return $this -> data [ 'controller' ];
}
2018-11-23 12:29:20 +00:00
/**
* Gets the previous request attributes .
*
* @ return array | bool A legacy array of data from the previous redirection response
* or false otherwise
*/
public function getRedirect ()
{
return isset ( $this -> data [ 'redirect' ]) ? $this -> data [ 'redirect' ] : false ;
}
2015-08-17 17:00:26 -07:00
public function onKernelController ( FilterControllerEvent $event )
{
$this -> controllers [ $event -> getRequest ()] = $event -> getController ();
}
2018-11-23 12:29:20 +00:00
public function onKernelResponse ( FilterResponseEvent $event )
{
if ( ! $event -> isMasterRequest ()) {
return ;
}
if ( $event -> getRequest () -> cookies -> has ( 'sf_redirect' )) {
$event -> getRequest () -> attributes -> set ( '_redirected' , true );
}
}
2015-08-17 17:00:26 -07:00
public static function getSubscribedEvents ()
{
2018-11-23 12:29:20 +00:00
return array (
KernelEvents :: CONTROLLER => 'onKernelController' ,
KernelEvents :: RESPONSE => 'onKernelResponse' ,
);
2015-08-17 17:00:26 -07:00
}
/**
* { @ inheritdoc }
*/
public function getName ()
{
return 'request' ;
}
2018-11-23 12:29:20 +00:00
/**
* Parse a controller .
*
* @ param mixed $controller The controller to parse
*
* @ return array | string An array of controller data or a simple string
*/
protected function parseController ( $controller )
{
if ( \is_string ( $controller ) && false !== strpos ( $controller , '::' )) {
$controller = explode ( '::' , $controller );
}
if ( \is_array ( $controller )) {
try {
$r = new \ReflectionMethod ( $controller [ 0 ], $controller [ 1 ]);
return array (
'class' => \is_object ( $controller [ 0 ]) ? \get_class ( $controller [ 0 ]) : $controller [ 0 ],
'method' => $controller [ 1 ],
'file' => $r -> getFileName (),
'line' => $r -> getStartLine (),
);
} catch ( \ReflectionException $e ) {
if ( \is_callable ( $controller )) {
// using __call or __callStatic
return array (
'class' => \is_object ( $controller [ 0 ]) ? \get_class ( $controller [ 0 ]) : $controller [ 0 ],
'method' => $controller [ 1 ],
'file' => 'n/a' ,
'line' => 'n/a' ,
);
}
}
}
if ( $controller instanceof \Closure ) {
$r = new \ReflectionFunction ( $controller );
2019-01-24 08:00:03 +00:00
$controller = array (
2018-11-23 12:29:20 +00:00
'class' => $r -> getName (),
'method' => null ,
'file' => $r -> getFileName (),
'line' => $r -> getStartLine (),
);
2019-01-24 08:00:03 +00:00
if ( false !== strpos ( $r -> name , '{closure}' )) {
return $controller ;
}
$controller [ 'method' ] = $r -> name ;
if ( $class = $r -> getClosureScopeClass ()) {
$controller [ 'class' ] = $class -> name ;
} else {
return $r -> name ;
}
return $controller ;
2018-11-23 12:29:20 +00:00
}
if ( \is_object ( $controller )) {
$r = new \ReflectionClass ( $controller );
return array (
'class' => $r -> getName (),
'method' => null ,
'file' => $r -> getFileName (),
'line' => $r -> getStartLine (),
);
}
return \is_string ( $controller ) ? $controller : 'n/a' ;
}
2015-08-17 17:00:26 -07:00
}