2010-06-16 09:38:41 +01:00
< ? php
2011-01-15 13:29:43 +00:00
/*
* This file is part of the Symfony package .
*
2011-03-06 11:40:06 +00:00
* ( c ) Fabien Potencier < fabien @ symfony . com >
2011-01-15 13:29:43 +00:00
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
2010-08-20 22:09:55 +01:00
namespace Symfony\Component\HttpKernel\Profiler ;
2010-06-16 09:38:41 +01:00
2016-05-02 13:34:55 +01:00
use Symfony\Component\HttpFoundation\Exception\ConflictingHeadersException ;
2010-08-28 14:23:21 +01:00
use Symfony\Component\HttpFoundation\Request ;
2010-08-20 22:09:55 +01:00
use Symfony\Component\HttpFoundation\Response ;
2010-08-28 14:23:21 +01:00
use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface ;
2013-09-30 06:59:16 +01:00
use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface ;
2013-01-09 09:41:17 +00:00
use Psr\Log\LoggerInterface ;
2010-06-16 09:38:41 +01:00
/**
* Profiler .
*
2011-03-06 11:40:06 +00:00
* @ author Fabien Potencier < fabien @ symfony . com >
2010-06-16 09:38:41 +01:00
*/
2010-08-28 14:23:21 +01:00
class Profiler
2010-06-16 09:38:41 +01:00
{
2012-11-01 15:08:59 +00:00
/**
* @ var ProfilerStorageInterface
*/
2011-03-23 18:47:16 +00:00
private $storage ;
2012-11-01 15:08:59 +00:00
/**
* @ var DataCollectorInterface []
*/
private $collectors = array ();
/**
* @ var LoggerInterface
*/
2011-03-23 18:47:16 +00:00
private $logger ;
2012-11-01 15:08:59 +00:00
2017-10-05 10:48:08 +01:00
/**
* @ var bool
*/
private $initiallyEnabled = true ;
2012-11-01 15:08:59 +00:00
/**
2014-04-16 11:30:19 +01:00
* @ var bool
2012-11-01 15:08:59 +00:00
*/
private $enabled = true ;
2010-06-16 09:38:41 +01:00
2010-08-28 14:23:21 +01:00
/**
* @ param ProfilerStorageInterface $storage A ProfilerStorageInterface instance
* @ param LoggerInterface $logger A LoggerInterface instance
2017-10-05 10:48:08 +01:00
* @ param bool $enable The initial enabled state
2010-08-28 14:23:21 +01:00
*/
2017-10-05 10:48:08 +01:00
public function __construct ( ProfilerStorageInterface $storage , LoggerInterface $logger = null , $enable = true )
2010-06-16 09:38:41 +01:00
{
2010-08-28 14:23:21 +01:00
$this -> storage = $storage ;
2010-06-16 09:38:41 +01:00
$this -> logger = $logger ;
2017-10-05 10:48:08 +01:00
$this -> initiallyEnabled = $this -> enabled = ( bool ) $enable ;
2010-06-16 09:38:41 +01:00
}
2010-06-16 14:45:20 +01:00
/**
2010-08-28 14:23:21 +01:00
* Disables the profiler .
2010-06-16 14:45:20 +01:00
*/
2010-08-28 14:23:21 +01:00
public function disable ()
2010-06-16 09:38:41 +01:00
{
2010-08-28 14:23:21 +01:00
$this -> enabled = false ;
2010-06-16 09:38:41 +01:00
}
2012-07-13 14:39:54 +01:00
/**
* Enables the profiler .
*/
public function enable ()
{
$this -> enabled = true ;
}
2010-06-16 14:45:20 +01:00
/**
2011-05-30 17:54:40 +01:00
* Loads the Profile for the given Response .
2010-06-16 14:45:20 +01:00
*
2010-07-27 14:33:28 +01:00
* @ param Response $response A Response instance
2010-06-16 14:45:20 +01:00
*
2016-09-02 19:13:13 +01:00
* @ return Profile | false A Profile instance
2010-06-16 14:45:20 +01:00
*/
2011-05-30 17:54:40 +01:00
public function loadProfileFromResponse ( Response $response )
2010-06-16 09:38:41 +01:00
{
2010-06-16 14:45:20 +01:00
if ( ! $token = $response -> headers -> get ( 'X-Debug-Token' )) {
2011-05-30 17:54:40 +01:00
return false ;
2010-06-16 14:45:20 +01:00
}
2011-05-30 17:54:40 +01:00
return $this -> loadProfile ( $token );
2010-06-16 09:38:41 +01:00
}
2010-06-16 14:45:20 +01:00
/**
2011-05-30 17:54:40 +01:00
* Loads the Profile for the given token .
2010-06-16 14:45:20 +01:00
*
* @ param string $token A token
*
2011-05-30 17:54:40 +01:00
* @ return Profile A Profile instance
2010-06-16 14:45:20 +01:00
*/
2011-05-30 17:54:40 +01:00
public function loadProfile ( $token )
2010-06-16 09:38:41 +01:00
{
2011-05-30 17:54:40 +01:00
return $this -> storage -> read ( $token );
}
2010-06-16 09:38:41 +01:00
2011-05-30 17:54:40 +01:00
/**
* Saves a Profile .
*
2011-07-04 12:53:57 +01:00
* @ param Profile $profile A Profile instance
2011-05-30 17:54:40 +01:00
*
2014-04-16 11:30:19 +01:00
* @ return bool
2011-05-30 17:54:40 +01:00
*/
public function saveProfile ( Profile $profile )
{
2013-09-30 06:59:16 +01:00
// late collect
foreach ( $profile -> getCollectors () as $collector ) {
if ( $collector instanceof LateDataCollectorInterface ) {
$collector -> lateCollect ();
}
}
2011-06-02 23:00:41 +01:00
if ( ! ( $ret = $this -> storage -> write ( $profile )) && null !== $this -> logger ) {
2015-01-15 09:04:56 +00:00
$this -> logger -> warning ( 'Unable to store the profiler information.' , array ( 'configured_storage' => get_class ( $this -> storage )));
2011-05-30 17:54:40 +01:00
}
return $ret ;
2010-06-16 09:38:41 +01:00
}
2010-09-01 07:21:38 +01:00
/**
* Purges all data from the storage .
*/
public function purge ()
{
$this -> storage -> purge ();
}
2010-06-16 14:45:20 +01:00
/**
2010-08-28 14:23:21 +01:00
* Finds profiler tokens for the given criteria .
2010-06-16 14:45:20 +01:00
*
2015-10-15 14:41:23 +01:00
* @ param string $ip The IP
* @ param string $url The URL
* @ param string $limit The maximum number of tokens to return
* @ param string $method The request method
* @ param string $start The start date to search from
* @ param string $end The end date to search to
* @ param string $statusCode The request status code
2010-08-28 14:23:21 +01:00
*
* @ return array An array of tokens
2012-12-16 08:41:40 +00:00
*
2014-04-09 16:49:50 +01:00
* @ see http :// php . net / manual / en / datetime . formats . php for the supported date / time formats
2010-06-16 14:45:20 +01:00
*/
2015-10-15 14:41:23 +01:00
public function find ( $ip , $url , $limit , $method , $start , $end , $statusCode = null )
2010-06-16 13:19:46 +01:00
{
2015-10-15 14:41:23 +01:00
return $this -> storage -> find ( $ip , $url , $limit , $method , $this -> getTimestamp ( $start ), $this -> getTimestamp ( $end ), $statusCode );
2010-06-16 13:19:46 +01:00
}
2010-06-16 14:45:20 +01:00
/**
2010-08-28 14:23:21 +01:00
* Collects data for the given Response .
2010-06-16 14:45:20 +01:00
*
2010-08-28 14:23:21 +01:00
* @ param Request $request A Request instance
* @ param Response $response A Response instance
* @ param \Exception $exception An exception instance if the request threw one
2011-05-30 17:54:40 +01:00
*
2012-01-30 15:14:38 +00:00
* @ return Profile | null A Profile instance or null if the profiler is disabled
2010-06-16 14:45:20 +01:00
*/
2010-08-28 14:23:21 +01:00
public function collect ( Request $request , Response $response , \Exception $exception = null )
2010-06-16 13:19:46 +01:00
{
2010-08-28 14:23:21 +01:00
if ( false === $this -> enabled ) {
return ;
}
2013-07-30 13:08:17 +01:00
$profile = new Profile ( substr ( hash ( 'sha256' , uniqid ( mt_rand (), true )), 0 , 6 ));
2011-05-30 17:54:40 +01:00
$profile -> setTime ( time ());
$profile -> setUrl ( $request -> getUri ());
2011-07-04 12:53:57 +01:00
$profile -> setMethod ( $request -> getMethod ());
2014-12-19 02:18:31 +00:00
$profile -> setStatusCode ( $response -> getStatusCode ());
2016-05-02 13:34:55 +01:00
try {
$profile -> setIp ( $request -> getClientIp ());
} catch ( ConflictingHeadersException $e ) {
$profile -> setIp ( 'Unknown' );
}
2010-08-28 14:23:21 +01:00
2011-05-30 17:54:40 +01:00
$response -> headers -> set ( 'X-Debug-Token' , $profile -> getToken ());
2010-08-28 14:23:21 +01:00
2011-07-04 12:53:57 +01:00
foreach ( $this -> collectors as $collector ) {
2011-05-30 17:54:40 +01:00
$collector -> collect ( $request , $response , $exception );
2011-01-18 14:41:19 +00:00
2013-09-29 16:17:25 +01:00
// we need to clone for sub-requests
$profile -> addCollector ( clone $collector );
2010-08-28 14:23:21 +01:00
}
2011-05-30 17:54:40 +01:00
return $profile ;
2010-06-16 13:19:46 +01:00
}
2017-10-05 10:48:08 +01:00
public function reset ()
{
foreach ( $this -> collectors as $collector ) {
if ( ! method_exists ( $collector , 'reset' )) {
continue ;
}
$collector -> reset ();
}
$this -> enabled = $this -> initiallyEnabled ;
}
2010-06-16 14:45:20 +01:00
/**
* Gets the Collectors associated with this profiler .
*
* @ return array An array of collectors
*/
2010-09-01 15:53:28 +01:00
public function all ()
2010-06-16 09:38:41 +01:00
{
return $this -> collectors ;
}
2010-06-16 14:45:20 +01:00
/**
* Sets the Collectors associated with this profiler .
*
2012-11-01 15:08:59 +00:00
* @ param DataCollectorInterface [] $collectors An array of collectors
2010-06-16 14:45:20 +01:00
*/
2010-09-01 15:53:28 +01:00
public function set ( array $collectors = array ())
2010-06-16 13:19:46 +01:00
{
$this -> collectors = array ();
2010-11-06 15:47:49 +00:00
foreach ( $collectors as $collector ) {
2010-09-01 15:53:28 +01:00
$this -> add ( $collector );
2010-06-16 13:19:46 +01:00
}
}
2010-06-16 14:45:20 +01:00
/**
* Adds a Collector .
*
2010-07-27 14:33:28 +01:00
* @ param DataCollectorInterface $collector A DataCollectorInterface instance
2010-06-16 14:45:20 +01:00
*/
2010-09-01 15:53:28 +01:00
public function add ( DataCollectorInterface $collector )
2010-06-16 13:19:46 +01:00
{
2017-10-05 10:48:08 +01:00
if ( ! method_exists ( $collector , 'reset' )) {
@ trigger_error ( sprintf ( 'Implementing "%s" without the "reset()" method is deprecated since version 3.4 and will be unsupported in 4.0 for class "%s".' , DataCollectorInterface :: class , \get_class ( $collector )), E_USER_DEPRECATED );
}
2010-06-16 14:45:20 +01:00
$this -> collectors [ $collector -> getName ()] = $collector ;
2010-06-16 13:19:46 +01:00
}
2010-06-16 14:45:20 +01:00
/**
* Returns true if a Collector for the given name exists .
*
* @ param string $name A collector name
2011-07-04 12:53:57 +01:00
*
2014-04-16 11:30:19 +01:00
* @ return bool
2010-06-16 14:45:20 +01:00
*/
2010-09-01 15:53:28 +01:00
public function has ( $name )
2010-06-16 09:38:41 +01:00
{
return isset ( $this -> collectors [ $name ]);
}
2010-06-16 14:45:20 +01:00
/**
* Gets a Collector by name .
*
* @ param string $name A collector name
*
2010-07-27 14:33:28 +01:00
* @ return DataCollectorInterface A DataCollectorInterface instance
2010-06-16 14:45:20 +01:00
*
* @ throws \InvalidArgumentException if the collector does not exist
*/
2010-09-01 15:53:28 +01:00
public function get ( $name )
2010-06-16 09:38:41 +01:00
{
if ( ! isset ( $this -> collectors [ $name ])) {
throw new \InvalidArgumentException ( sprintf ( 'Collector "%s" does not exist.' , $name ));
}
return $this -> collectors [ $name ];
}
2014-04-09 16:49:50 +01:00
private function getTimestamp ( $value )
{
if ( null === $value || '' == $value ) {
2014-04-16 08:15:58 +01:00
return ;
2014-04-09 16:49:50 +01:00
}
try {
$value = new \DateTime ( is_numeric ( $value ) ? '@' . $value : $value );
} catch ( \Exception $e ) {
2014-04-16 08:15:58 +01:00
return ;
2014-04-09 16:49:50 +01:00
}
return $value -> getTimestamp ();
}
2010-06-16 09:38:41 +01:00
}