2011-07-23 19:05:48 +01: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\Profiler ;
class MongoDbProfilerStorage implements ProfilerStorageInterface
{
protected $dsn ;
2011-09-19 21:37:12 +01:00
protected $lifetime ;
2011-07-24 19:45:33 +01:00
private $mongo ;
2011-07-23 19:05:48 +01:00
/**
* Constructor .
*
2012-01-11 14:52:51 +00:00
* @ param string $dsn A data source name
* @ param string $username Not used
* @ param string $password Not used
* @ param integer $lifetime The lifetime to use for the purge
2011-07-23 19:05:48 +01:00
*/
2011-09-19 21:37:12 +01:00
public function __construct ( $dsn , $username = '' , $password = '' , $lifetime = 86400 )
2011-07-23 19:05:48 +01:00
{
$this -> dsn = $dsn ;
2011-09-19 21:37:12 +01:00
$this -> lifetime = ( int ) $lifetime ;
2011-07-23 19:05:48 +01:00
}
/**
2012-11-01 15:08:59 +00:00
* { @ inheritdoc }
2011-07-23 19:05:48 +01:00
*/
2012-11-25 17:16:08 +00:00
public function find ( $ip , $url , $limit , $method , $start = null , $end = null )
2011-07-23 19:05:48 +01:00
{
2012-11-25 17:16:08 +00:00
$cursor = $this -> getMongo () -> find ( $this -> buildQuery ( $ip , $url , $method , $start , $end ), array ( '_id' , 'parent' , 'ip' , 'method' , 'url' , 'time' )) -> sort ( array ( 'time' => - 1 )) -> limit ( $limit );
2011-09-14 21:15:57 +01:00
$tokens = array ();
2011-07-23 19:05:48 +01:00
foreach ( $cursor as $profile ) {
2011-09-14 21:15:57 +01:00
$tokens [] = $this -> getData ( $profile );
2011-07-23 19:05:48 +01:00
}
2011-07-24 19:45:33 +01:00
2011-09-14 21:15:57 +01:00
return $tokens ;
2011-07-23 19:05:48 +01:00
}
/**
2012-11-01 15:08:59 +00:00
* { @ inheritdoc }
2011-07-23 19:05:48 +01:00
*/
2011-07-24 19:45:33 +01:00
public function purge ()
2011-07-23 19:05:48 +01:00
{
2011-07-24 19:45:33 +01:00
$this -> getMongo () -> remove ( array ());
2011-07-23 19:05:48 +01:00
}
/**
2012-11-01 15:08:59 +00:00
* { @ inheritdoc }
2011-07-23 19:05:48 +01:00
*/
2011-07-24 19:45:33 +01:00
public function read ( $token )
2011-07-23 19:05:48 +01:00
{
2011-09-14 21:15:57 +01:00
$profile = $this -> getMongo () -> findOne ( array ( '_id' => $token , 'data' => array ( '$exists' => true )));
if ( null !== $profile ) {
$profile = $this -> createProfileFromData ( $this -> getData ( $profile ));
}
2011-07-24 19:45:33 +01:00
2011-09-14 21:15:57 +01:00
return $profile ;
2011-07-23 19:05:48 +01:00
}
/**
2012-11-01 15:08:59 +00:00
* { @ inheritdoc }
2011-07-23 19:05:48 +01:00
*/
2011-07-24 19:45:33 +01:00
public function write ( Profile $profile )
2011-07-23 19:05:48 +01:00
{
2011-09-19 21:37:12 +01:00
$this -> cleanup ();
2011-09-14 21:15:57 +01:00
$record = array (
2011-09-07 19:49:37 +01:00
'_id' => $profile -> getToken (),
2011-12-23 08:39:25 +00:00
'parent' => $profile -> getParentToken (),
2012-09-19 20:00:52 +01:00
'data' => base64_encode ( serialize ( $profile -> getCollectors ())),
2011-09-04 13:38:29 +01:00
'ip' => $profile -> getIp (),
2011-09-24 10:20:46 +01:00
'method' => $profile -> getMethod (),
2011-09-14 21:15:57 +01:00
'url' => $profile -> getUrl (),
'time' => $profile -> getTime ()
);
2012-12-13 20:52:09 +00:00
$result = $this -> getMongo () -> update ( array ( '_id' => $profile -> getToken ()), array_filter ( $record , function ( $v ) { return ! empty ( $v ); }), array ( 'upsert' => true ));
2012-12-13 21:40:17 +00:00
return ( boolean ) ( isset ( $result [ 'ok' ]) ? $result [ 'ok' ] : $result );
2011-07-23 19:05:48 +01:00
}
2011-07-24 19:45:33 +01:00
/**
* Internal convenience method that returns the instance of the MongoDB Collection
*
* @ return \MongoCollection
2012-12-16 12:02:54 +00:00
*
* @ throws \RuntimeException
2011-07-24 19:45:33 +01:00
*/
protected function getMongo ()
{
if ( $this -> mongo === null ) {
2011-09-11 12:38:37 +01:00
if ( preg_match ( '#^(mongodb://.*)/(.*)/(.*)$#' , $this -> dsn , $matches )) {
2013-04-02 10:39:57 +01:00
$server = $matches [ 1 ] . ( ! empty ( $matches [ 2 ]) ? '/' . $matches [ 2 ] : '' );
2011-09-11 12:38:37 +01:00
$database = $matches [ 2 ];
$collection = $matches [ 3 ];
2012-12-13 20:52:09 +00:00
$mongoClass = ( version_compare ( phpversion ( 'mongo' ), '1.3.0' , '<' )) ? '\Mongo' : '\MongoClient' ;
$mongo = new $mongoClass ( $server );
2011-09-11 12:38:37 +01:00
$this -> mongo = $mongo -> selectCollection ( $database , $collection );
} else {
2012-12-13 20:52:09 +00:00
throw new \RuntimeException ( sprintf ( 'Please check your configuration. You are trying to use MongoDB with an invalid dsn "%s". The expected format is "mongodb://[user:pass@]host/database/collection"' , $this -> dsn ));
2011-09-11 12:38:37 +01:00
}
2011-07-24 19:45:33 +01:00
}
2011-09-07 19:49:37 +01:00
2011-07-24 19:45:33 +01:00
return $this -> mongo ;
}
2011-09-07 21:32:54 +01:00
2011-09-14 21:15:57 +01:00
/**
* @ param array $data
2012-12-11 10:49:22 +00:00
*
2011-09-14 21:15:57 +01:00
* @ return Profile
*/
protected function createProfileFromData ( array $data )
{
$profile = $this -> getProfile ( $data );
if ( $data [ 'parent' ]) {
$parent = $this -> getMongo () -> findOne ( array ( '_id' => $data [ 'parent' ], 'data' => array ( '$exists' => true )));
if ( $parent ) {
$profile -> setParent ( $this -> getProfile ( $this -> getData ( $parent )));
}
}
$profile -> setChildren ( $this -> readChildren ( $data [ 'token' ]));
return $profile ;
}
/**
* @ param string $token
2012-12-11 10:49:22 +00:00
*
2012-11-01 15:08:59 +00:00
* @ return Profile [] An array of Profile instances
2011-09-14 21:15:57 +01:00
*/
protected function readChildren ( $token )
{
$profiles = array ();
$cursor = $this -> getMongo () -> find ( array ( 'parent' => $token , 'data' => array ( '$exists' => true )));
foreach ( $cursor as $d ) {
$profiles [] = $this -> getProfile ( $this -> getData ( $d ));
}
return $profiles ;
}
2011-09-19 21:37:12 +01:00
protected function cleanup ()
{
$this -> getMongo () -> remove ( array ( 'time' => array ( '$lt' => time () - $this -> lifetime )));
}
2011-09-07 21:32:54 +01:00
/**
* @ param string $ip
* @ param string $url
2011-09-24 10:20:46 +01:00
* @ param string $method
2012-11-25 17:16:08 +00:00
* @ param int $start
* @ param int $end
2012-12-11 10:49:22 +00:00
*
2011-09-07 21:32:54 +01:00
* @ return array
*/
2012-11-25 17:16:08 +00:00
private function buildQuery ( $ip , $url , $method , $start , $end )
2011-09-07 21:32:54 +01:00
{
$query = array ();
if ( ! empty ( $ip )) {
$query [ 'ip' ] = $ip ;
}
if ( ! empty ( $url )) {
$query [ 'url' ] = $url ;
}
2011-09-24 10:20:46 +01:00
if ( ! empty ( $method )) {
$query [ 'method' ] = $method ;
}
2012-12-15 21:37:18 +00:00
if ( ! empty ( $start ) || ! empty ( $end )) {
$query [ 'time' ] = array ();
}
if ( ! empty ( $start )) {
$query [ 'time' ][ '$gte' ] = $start ;
}
if ( ! empty ( $end )) {
$query [ 'time' ][ '$lte' ] = $end ;
}
2011-09-07 21:32:54 +01:00
return $query ;
}
2011-09-14 21:15:57 +01:00
/**
* @ param array $data
2012-12-11 10:49:22 +00:00
*
2011-09-14 21:15:57 +01:00
* @ return array
*/
private function getData ( array $data )
{
return array (
'token' => $data [ '_id' ],
'parent' => isset ( $data [ 'parent' ]) ? $data [ 'parent' ] : null ,
'ip' => isset ( $data [ 'ip' ]) ? $data [ 'ip' ] : null ,
2011-09-24 10:20:46 +01:00
'method' => isset ( $data [ 'method' ]) ? $data [ 'method' ] : null ,
2011-09-14 21:15:57 +01:00
'url' => isset ( $data [ 'url' ]) ? $data [ 'url' ] : null ,
'time' => isset ( $data [ 'time' ]) ? $data [ 'time' ] : null ,
'data' => isset ( $data [ 'data' ]) ? $data [ 'data' ] : null ,
);
}
/**
* @ param array $data
2012-12-11 10:49:22 +00:00
*
2011-09-14 21:15:57 +01:00
* @ return Profile
*/
private function getProfile ( array $data )
{
$profile = new Profile ( $data [ 'token' ]);
$profile -> setIp ( $data [ 'ip' ]);
2011-09-24 10:20:46 +01:00
$profile -> setMethod ( $data [ 'method' ]);
2011-09-14 21:15:57 +01:00
$profile -> setUrl ( $data [ 'url' ]);
$profile -> setTime ( $data [ 'time' ]);
2012-09-19 20:00:52 +01:00
$profile -> setCollectors ( unserialize ( base64_decode ( $data [ 'data' ])));
2011-09-14 21:15:57 +01:00
return $profile ;
}
2011-09-07 19:49:37 +01:00
}