mirror of
https://github.com/maximebf/php-debugbar.git
synced 2025-05-05 22:45:17 +02:00
added Exceptions and PDO collectors
This commit is contained in:
parent
79295b0c4b
commit
4a29e38cea
@ -5,7 +5,7 @@ include 'bootstrap.php';
|
|||||||
try {
|
try {
|
||||||
throw new Exception('Something failed!');
|
throw new Exception('Something failed!');
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$debugbar['messages']->addMessage($e, 'error');
|
$debugbar['exceptions']->addException($e);
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
34
demo/demo_pdo.php
Normal file
34
demo/demo_pdo.php
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
include 'bootstrap.php';
|
||||||
|
|
||||||
|
use DebugBar\DataCollector\PDO\TraceablePDO;
|
||||||
|
use DebugBar\DataCollector\PDO\PDOCollector;
|
||||||
|
|
||||||
|
$pdo = new TraceablePDO(new PDO('sqlite::memory:'));
|
||||||
|
$debugbar->addCollector(new PDOCollector($pdo));
|
||||||
|
|
||||||
|
$pdo->exec('create table users (name varchar)');
|
||||||
|
$stmt = $pdo->prepare('insert into users (name) values (?)');
|
||||||
|
$stmt->execute(array('foo'));
|
||||||
|
$stmt->execute(array('bar'));
|
||||||
|
|
||||||
|
$users = $pdo->query('select * from users')->fetchAll();
|
||||||
|
$stmt = $pdo->prepare('select * from users where name=?');
|
||||||
|
$stmt->execute(array('foo'));
|
||||||
|
$foo = $stmt->fetch();
|
||||||
|
|
||||||
|
$pdo->exec('delete from titi');
|
||||||
|
|
||||||
|
?>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<?php echo $debugbarRenderer->renderHead() ?>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p>PhpDebugBar PDO Demo</p>
|
||||||
|
<?php
|
||||||
|
echo $debugbarRenderer->render();
|
||||||
|
?>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -35,7 +35,10 @@ class MonologCollector extends AbstractProcessingHandler implements DataCollecto
|
|||||||
|
|
||||||
public function collect()
|
public function collect()
|
||||||
{
|
{
|
||||||
return $this->records;
|
return array(
|
||||||
|
'count' => count($this->records),
|
||||||
|
'records' => $this->records
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getName()
|
public function getName()
|
||||||
@ -48,8 +51,12 @@ class MonologCollector extends AbstractProcessingHandler implements DataCollecto
|
|||||||
return array(
|
return array(
|
||||||
"logs" => array(
|
"logs" => array(
|
||||||
"widget" => "PhpDebugBar.Widgets.MessagesWidget",
|
"widget" => "PhpDebugBar.Widgets.MessagesWidget",
|
||||||
"map" => "monolog",
|
"map" => "monolog.records",
|
||||||
"default" => "[]"
|
"default" => "[]"
|
||||||
|
),
|
||||||
|
"logs:badge" => array(
|
||||||
|
"map" => "monolog.count",
|
||||||
|
"default" => "null"
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,36 @@ abstract class DataCollector implements DataCollectorInterface
|
|||||||
* @param mixed $var
|
* @param mixed $var
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function varToString($var)
|
public function formatVar($var)
|
||||||
{
|
{
|
||||||
return print_r($var, true);
|
return print_r($var, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transforms a duration in seconds in a readable string
|
||||||
|
*
|
||||||
|
* @param float $value
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function formatDuration($seconds)
|
||||||
|
{
|
||||||
|
return round($seconds * 1000) . 'ms';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transforms a size in bytes to a human readable string
|
||||||
|
*
|
||||||
|
* @param string $size
|
||||||
|
* @param integer $precision
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function formatBytes($size, $precision = 2)
|
||||||
|
{
|
||||||
|
if ($size === 0) {
|
||||||
|
return "0B";
|
||||||
|
}
|
||||||
|
$base = log($size) / log(1024);
|
||||||
|
$suffixes = array('', 'KB', 'MB', 'GB', 'TB');
|
||||||
|
return round(pow(1024, $base - floor($base)), $precision) . $suffixes[floor($base)];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*
|
|
||||||
* This file is part of the DebugBar package.
|
|
||||||
*
|
|
||||||
* (c) 2013 Maxime Bouroumeau-Fuseau
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please view the LICENSE
|
|
||||||
* file that was distributed with this source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace DebugBar\DataCollector;
|
|
||||||
|
|
||||||
class DependencyCollector extends DataCollector
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public function collect()
|
|
||||||
{
|
|
||||||
return array();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public function getName()
|
|
||||||
{
|
|
||||||
return 'dependency';
|
|
||||||
}
|
|
||||||
}
|
|
100
src/DebugBar/DataCollector/ExceptionsCollector.php
Normal file
100
src/DebugBar/DataCollector/ExceptionsCollector.php
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of the DebugBar package.
|
||||||
|
*
|
||||||
|
* (c) 2013 Maxime Bouroumeau-Fuseau
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace DebugBar\DataCollector;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collects info about exceptions
|
||||||
|
*/
|
||||||
|
class ExceptionsCollector extends DataCollector implements Renderable
|
||||||
|
{
|
||||||
|
protected $exceptions = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an exception to be profiled in the debug bar
|
||||||
|
*
|
||||||
|
* @param Exception $e
|
||||||
|
*/
|
||||||
|
public function addException(Exception $e)
|
||||||
|
{
|
||||||
|
$this->exceptions[] = $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the list of exceptions being profiled
|
||||||
|
*
|
||||||
|
* @return array[Exception]
|
||||||
|
*/
|
||||||
|
public function getExceptions()
|
||||||
|
{
|
||||||
|
return $this->exceptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function collect()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
'count' => count($this->exceptions),
|
||||||
|
'exceptions' => array_map(array($this, 'formatExceptionData'), $this->exceptions)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns exception data as an array
|
||||||
|
*
|
||||||
|
* @param Exception $e
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function formatExceptionData(Exception $e)
|
||||||
|
{
|
||||||
|
$lines = file($e->getFile());
|
||||||
|
$start = $e->getLine() - 4;
|
||||||
|
$lines = array_slice($lines, $start < 0 ? 0 : $start, 7);
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'type' => get_class($e),
|
||||||
|
'message' => $e->getMessage(),
|
||||||
|
'code' => $e->getCode(),
|
||||||
|
'file' => $e->getFile(),
|
||||||
|
'line' => $e->getLine(),
|
||||||
|
'surrounding_lines' => $lines
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return 'exceptions';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function getWidgets()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
'exceptions' => array(
|
||||||
|
'widget' => 'PhpDebugBar.Widgets.ExceptionsWidget',
|
||||||
|
'map' => 'exceptions.exceptions',
|
||||||
|
'default' => '[]'
|
||||||
|
),
|
||||||
|
'exceptions:badge' => array(
|
||||||
|
'map' => 'exceptions.count',
|
||||||
|
'default' => 'null'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -35,20 +35,6 @@ class MemoryCollector extends DataCollector implements Renderable
|
|||||||
$this->peakUsage = memory_get_peak_usage(true);
|
$this->peakUsage = memory_get_peak_usage(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Transforms a size in bytes to a human readable string
|
|
||||||
*
|
|
||||||
* @param string $size
|
|
||||||
* @param integer $precision
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function toReadableString($size, $precision = 2)
|
|
||||||
{
|
|
||||||
$base = log($size) / log(1024);
|
|
||||||
$suffixes = array('', 'KB', 'MB', 'GB', 'TB');
|
|
||||||
return round(pow(1024, $base - floor($base)), $precision) . $suffixes[floor($base)];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@ -57,7 +43,7 @@ class MemoryCollector extends DataCollector implements Renderable
|
|||||||
$this->updatePeakUsage();
|
$this->updatePeakUsage();
|
||||||
return array(
|
return array(
|
||||||
'peak_usage' => $this->peakUsage,
|
'peak_usage' => $this->peakUsage,
|
||||||
'peak_usage_str' => $this->toReadableString($this->peakUsage)
|
'peak_usage_str' => $this->formatBytes($this->peakUsage)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ class MessagesCollector extends DataCollector implements Renderable
|
|||||||
public function addMessage($message, $label = 'info')
|
public function addMessage($message, $label = 'info')
|
||||||
{
|
{
|
||||||
$this->messages[] = array(
|
$this->messages[] = array(
|
||||||
'message' => $this->varToString($message),
|
'message' => $this->formatVar($message),
|
||||||
'is_string' => is_string($message),
|
'is_string' => is_string($message),
|
||||||
'label' => $label,
|
'label' => $label,
|
||||||
'time' => microtime(true),
|
'time' => microtime(true),
|
||||||
@ -52,7 +52,10 @@ class MessagesCollector extends DataCollector implements Renderable
|
|||||||
*/
|
*/
|
||||||
public function collect()
|
public function collect()
|
||||||
{
|
{
|
||||||
return $this->messages;
|
return array(
|
||||||
|
'count' => count($this->messages),
|
||||||
|
'messages' => $this->messages
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -71,8 +74,12 @@ class MessagesCollector extends DataCollector implements Renderable
|
|||||||
return array(
|
return array(
|
||||||
"messages" => array(
|
"messages" => array(
|
||||||
"widget" => "PhpDebugBar.Widgets.MessagesWidget",
|
"widget" => "PhpDebugBar.Widgets.MessagesWidget",
|
||||||
"map" => "messages",
|
"map" => "messages.messages",
|
||||||
"default" => "[]"
|
"default" => "[]"
|
||||||
|
),
|
||||||
|
"messages:badge" => array(
|
||||||
|
"map" => "messages.count",
|
||||||
|
"default" => "null"
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
65
src/DebugBar/DataCollector/PDO/PDOCollector.php
Normal file
65
src/DebugBar/DataCollector/PDO/PDOCollector.php
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace DebugBar\DataCollector\PDO;
|
||||||
|
|
||||||
|
use DebugBar\DataCollector\DataCollector;
|
||||||
|
use DebugBar\DataCollector\Renderable;
|
||||||
|
|
||||||
|
class PDOCollector extends DataCollector implements Renderable
|
||||||
|
{
|
||||||
|
public function __construct(TraceablePDO $pdo)
|
||||||
|
{
|
||||||
|
$this->pdo = $pdo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function collect()
|
||||||
|
{
|
||||||
|
$stmts = array();
|
||||||
|
foreach ($this->pdo->getExecutedStatements() as $stmt) {
|
||||||
|
$stmts[] = array(
|
||||||
|
'sql' => $stmt->getSqlWithParams(),
|
||||||
|
'row_count' => $stmt->getRowCount(),
|
||||||
|
'stmt_id' => $stmt->getPreparedId(),
|
||||||
|
'prepared_stmt' => $stmt->getSql(),
|
||||||
|
'params' => $stmt->getParameters(),
|
||||||
|
'duration' => $stmt->getDuration(),
|
||||||
|
'duration_str' => $this->formatDuration($stmt->getDuration()),
|
||||||
|
'memory' => $stmt->getMemoryUsage(),
|
||||||
|
'memory_str' => $this->formatBytes($stmt->getMemoryUsage()),
|
||||||
|
'is_success' => $stmt->isSuccess(),
|
||||||
|
'error_code' => $stmt->getErrorCode(),
|
||||||
|
'error_message' => $stmt->getErrorMessage()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'nb_statements' => count($stmts),
|
||||||
|
'nb_failed_statements' => count($this->pdo->getFailedExecutedStatements()),
|
||||||
|
'accumulated_duration' => $this->pdo->getAccumulatedStatementsDuration(),
|
||||||
|
'accumulated_duration_str' => $this->formatDuration($this->pdo->getAccumulatedStatementsDuration()),
|
||||||
|
'peak_memory_usage' => $this->pdo->getPeakMemoryUsage(),
|
||||||
|
'peak_memory_usage_str' => $this->formatBytes($this->pdo->getPeakMemoryUsage()),
|
||||||
|
'statements' => $stmts
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return 'pdo';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getWidgets()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
"database" => array(
|
||||||
|
"widget" => "PhpDebugBar.Widgets.SQLQueriesWidget",
|
||||||
|
"map" => "pdo",
|
||||||
|
"default" => "[]"
|
||||||
|
),
|
||||||
|
"database:badge" => array(
|
||||||
|
"map" => "pdo.nb_statements",
|
||||||
|
"default" => 0
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
211
src/DebugBar/DataCollector/PDO/TraceablePDO.php
Normal file
211
src/DebugBar/DataCollector/PDO/TraceablePDO.php
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace DebugBar\DataCollector\PDO;
|
||||||
|
|
||||||
|
use PDO;
|
||||||
|
use PDOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A PDO proxy which traces statements
|
||||||
|
*/
|
||||||
|
class TraceablePDO extends PDO
|
||||||
|
{
|
||||||
|
protected $pdo;
|
||||||
|
|
||||||
|
protected $executedStatements = array();
|
||||||
|
|
||||||
|
public function __construct(PDO $pdo)
|
||||||
|
{
|
||||||
|
$this->pdo = $pdo;
|
||||||
|
$this->pdo->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('DebugBar\DataCollector\PDO\TraceablePDOStatement', array($this)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function beginTransaction()
|
||||||
|
{
|
||||||
|
return $this->pdo->beginTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function commit()
|
||||||
|
{
|
||||||
|
return $this->pdo->commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function errorCode()
|
||||||
|
{
|
||||||
|
return $this->pdo->errorCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function errorInfo()
|
||||||
|
{
|
||||||
|
return $this->errorInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function exec($sql)
|
||||||
|
{
|
||||||
|
return $this->profileCall('exec', $sql, func_get_args());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function getAttribute($attr)
|
||||||
|
{
|
||||||
|
return $this->pdo->getAttribute($attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function inTransaction()
|
||||||
|
{
|
||||||
|
return $this->pdo->inTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function lastInsertId($name = null)
|
||||||
|
{
|
||||||
|
return $this->pdo->lastInsertId($name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function prepare($sql, $driver_options = array())
|
||||||
|
{
|
||||||
|
return $this->pdo->prepare($sql, $driver_options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function query($sql)
|
||||||
|
{
|
||||||
|
return $this->profileCall('query', $sql, func_get_args());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function quote($expr, $parameter_type = PDO::PARAM_STR)
|
||||||
|
{
|
||||||
|
return $this->pdo->quote($expr, $parameter_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function rollBack()
|
||||||
|
{
|
||||||
|
return $this->pdo->rollBack();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function setAttribute($attr, $value)
|
||||||
|
{
|
||||||
|
return $this->pdo->setAttribute($attr, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Profiles a call to a PDO method
|
||||||
|
*
|
||||||
|
* @param string $method
|
||||||
|
* @param string $sql
|
||||||
|
* @param array $args
|
||||||
|
* @return mixed The result of the call
|
||||||
|
*/
|
||||||
|
protected function profileCall($method, $sql, array $args)
|
||||||
|
{
|
||||||
|
$start = microtime(true);
|
||||||
|
$ex = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$result = call_user_func_array(array($this->pdo, $method), $args);
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$ex = $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
$duration = microtime(true) - $start;
|
||||||
|
$memoryUsage = memory_get_peak_usage(true);
|
||||||
|
if ($this->pdo->getAttribute(PDO::ATTR_ERRMODE) !== PDO::ERRMODE_EXCEPTION && $result === false) {
|
||||||
|
$error = $this->pdo->errorInfo();
|
||||||
|
$ex = new PDOException($error[2], $error[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$tracedStmt = new TracedStatement($sql, array(), null, 0, $duration, $memoryUsage, $ex);
|
||||||
|
$this->addExecutedStatement($tracedStmt);
|
||||||
|
|
||||||
|
if ($this->pdo->getAttribute(PDO::ATTR_ERRMODE) === PDO::ERRMODE_EXCEPTION && $ex !== null) {
|
||||||
|
throw $ex;
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an executed TracedStatement
|
||||||
|
*
|
||||||
|
* @param TracedStatement $stmt
|
||||||
|
*/
|
||||||
|
public function addExecutedStatement(TracedStatement $stmt)
|
||||||
|
{
|
||||||
|
$this->executedStatements[] = $stmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the accumulated execution time of statements
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getAccumulatedStatementsDuration()
|
||||||
|
{
|
||||||
|
return array_reduce($this->executedStatements, function($v, $s) { return $v + $s->getDuration(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the peak memory usage while performing statements
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getPeakMemoryUsage()
|
||||||
|
{
|
||||||
|
return array_reduce($this->executedStatements, function($v, $s) { $m = $s->getMemoryUsage(); return $m > $v ? $m : $v; });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the list of executed statements as TracedStatement objects
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getExecutedStatements()
|
||||||
|
{
|
||||||
|
return $this->executedStatements;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the list of failed statements
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getFailedExecutedStatements()
|
||||||
|
{
|
||||||
|
return array_filter($this->executedStatements, function($s) { return !$s->isSuccess(); });
|
||||||
|
}
|
||||||
|
}
|
81
src/DebugBar/DataCollector/PDO/TraceablePDOStatement.php
Normal file
81
src/DebugBar/DataCollector/PDO/TraceablePDOStatement.php
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace DebugBar\DataCollector\PDO;
|
||||||
|
|
||||||
|
use PDO;
|
||||||
|
use PDOStatement;
|
||||||
|
use PDOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A traceable PDO statement to use with Traceablepdo
|
||||||
|
*/
|
||||||
|
class TraceablePDOStatement extends PDOStatement
|
||||||
|
{
|
||||||
|
protected $pdo;
|
||||||
|
|
||||||
|
protected $boundParameters = array();
|
||||||
|
|
||||||
|
protected function __construct(TraceablePDO $pdo)
|
||||||
|
{
|
||||||
|
$this->pdo = $pdo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function bindColumn($column, &$param) {
|
||||||
|
$this->boundParameters[$column] = $param;
|
||||||
|
$args = array_merge(array($column, &$param), array_slice(func_get_args(), 2));
|
||||||
|
return call_user_func_array(array("parent", 'bindColumn'), $args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function bindParam($param, &$var) {
|
||||||
|
$this->boundParameters[$param] = $var;
|
||||||
|
$args = array_merge(array($param, &$var), array_slice(func_get_args(), 2));
|
||||||
|
return call_user_func_array(array("parent", 'bindParam'), $args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function bindValue($param, $value) {
|
||||||
|
$this->boundParameters[$param] = $value;
|
||||||
|
return call_user_func_array(array("parent", 'bindValue'), func_get_args());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function execute($params = array())
|
||||||
|
{
|
||||||
|
$start = microtime(true);
|
||||||
|
$ex = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$result = parent::execute($params);
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$ex = $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
$preparedId = spl_object_hash($this);
|
||||||
|
$boundParameters = array_merge($this->boundParameters, $params);
|
||||||
|
$duration = microtime(true) - $start;
|
||||||
|
$memoryUsage = memory_get_peak_usage(true);
|
||||||
|
if ($this->pdo->getAttribute(PDO::ATTR_ERRMODE) !== PDO::ERRMODE_EXCEPTION && $result === false) {
|
||||||
|
$error = $this->errorInfo();
|
||||||
|
$ex = new PDOException($error[2], $error[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$tracedStmt = new TracedStatement($this->queryString, $boundParameters,
|
||||||
|
$preparedId, $this->rowCount(), $duration, $memoryUsage, $ex);
|
||||||
|
$this->pdo->addExecutedStatement($tracedStmt);
|
||||||
|
|
||||||
|
if ($this->pdo->getAttribute(PDO::ATTR_ERRMODE) === PDO::ERRMODE_EXCEPTION && $ex !== null) {
|
||||||
|
throw $ex;
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
}
|
189
src/DebugBar/DataCollector/PDO/TracedStatement.php
Normal file
189
src/DebugBar/DataCollector/PDO/TracedStatement.php
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace DebugBar\DataCollector\PDO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds information about a statement
|
||||||
|
*/
|
||||||
|
class TracedStatement
|
||||||
|
{
|
||||||
|
protected $sql;
|
||||||
|
|
||||||
|
protected $rowCount;
|
||||||
|
|
||||||
|
protected $parameters;
|
||||||
|
|
||||||
|
protected $duration;
|
||||||
|
|
||||||
|
protected $memoryUsage;
|
||||||
|
|
||||||
|
protected $exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Traces a call and returns a TracedStatement
|
||||||
|
*
|
||||||
|
* @param callback $callback
|
||||||
|
* @param array $args Callback args
|
||||||
|
* @param string $sql The SQL query string
|
||||||
|
* @return TracedStatement
|
||||||
|
*/
|
||||||
|
public static function traceCall($callback, array $args, $sql = '')
|
||||||
|
{
|
||||||
|
$start = microtime(true);
|
||||||
|
$result = call_user_func_array($callback, $args);
|
||||||
|
$duration = microtime(true) - $start;
|
||||||
|
$memoryUsage = memory_get_peak_usage(true);
|
||||||
|
$tracedStmt = new TracedStatement($sql, array(), null, 0, $duration, $memoryUsage);
|
||||||
|
return array($tracedStmt, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sql
|
||||||
|
* @param array $params
|
||||||
|
* @param string $preparedId
|
||||||
|
* @param integer $rowCount
|
||||||
|
* @param integer $duration
|
||||||
|
* @param integer $memoryUsage
|
||||||
|
* @param \Exception $e
|
||||||
|
*/
|
||||||
|
public function __construct($sql, array $params = array(), $preparedId = null, $rowCount = 0, $duration = 0, $memoryUsage = 0, \Exception $e = null)
|
||||||
|
{
|
||||||
|
$this->sql = $sql;
|
||||||
|
$this->rowCount = $rowCount;
|
||||||
|
$this->parameters = $params;
|
||||||
|
$this->preparedId = $preparedId;
|
||||||
|
$this->duration = $duration;
|
||||||
|
$this->memoryUsage = $memoryUsage;
|
||||||
|
$this->exception = $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the SQL string used for the query
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getSql()
|
||||||
|
{
|
||||||
|
return $this->sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the SQL string with any parameters used embedded
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getSqlWithParams()
|
||||||
|
{
|
||||||
|
$sql = $this->sql;
|
||||||
|
foreach ($this->parameters as $k => $v) {
|
||||||
|
$v = sprintf('<%s>', $v);
|
||||||
|
if (!is_numeric($k)) {
|
||||||
|
$sql = str_replace($k, $v, $sql);
|
||||||
|
} else {
|
||||||
|
$p = strpos($sql, '?');
|
||||||
|
$sql = substr($sql, 0, $p) . $v. substr($sql, $p + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of rows affected/returned
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getRowCount()
|
||||||
|
{
|
||||||
|
return $this->rowCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array of parameters used with the query
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getParameters()
|
||||||
|
{
|
||||||
|
return $this->parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the prepared statement id
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getPreparedId()
|
||||||
|
{
|
||||||
|
return $this->preparedId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if this is a prepared statement
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function isPrepared()
|
||||||
|
{
|
||||||
|
return $this->preparedId !== null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the duration in seconds of the execution
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getDuration()
|
||||||
|
{
|
||||||
|
return $this->duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the peak memory usage during the execution
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getMemoryUsage()
|
||||||
|
{
|
||||||
|
return $this->memoryUsage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the statement was successful
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function isSuccess()
|
||||||
|
{
|
||||||
|
return $this->exception === null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the exception triggered
|
||||||
|
*
|
||||||
|
* @return \Exception
|
||||||
|
*/
|
||||||
|
public function getException()
|
||||||
|
{
|
||||||
|
return $this->exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the exception's code
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getErrorCode()
|
||||||
|
{
|
||||||
|
return $this->exception !== null ? $this->exception->getCode() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the exception's message
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getErrorMessage()
|
||||||
|
{
|
||||||
|
return $this->exception !== null ? $this->exception->getMessage() : '';
|
||||||
|
}
|
||||||
|
}
|
@ -25,7 +25,7 @@ class RequestDataCollector extends DataCollector implements Renderable
|
|||||||
|
|
||||||
foreach ($vars as $var) {
|
foreach ($vars as $var) {
|
||||||
if (isset($GLOBALS[$var])) {
|
if (isset($GLOBALS[$var])) {
|
||||||
$data["$" . $var] = $this->varToString($GLOBALS[$var]);
|
$data["$" . $var] = $this->formatVar($GLOBALS[$var]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ class TimeDataCollector extends DataCollector implements Renderable
|
|||||||
$this->measures[$name]['end'] = $end;
|
$this->measures[$name]['end'] = $end;
|
||||||
$this->measures[$name]['relative_end'] = $end - $this->requestEndTime;
|
$this->measures[$name]['relative_end'] = $end - $this->requestEndTime;
|
||||||
$this->measures[$name]['duration'] = $end - $this->measures[$name]['start'];
|
$this->measures[$name]['duration'] = $end - $this->measures[$name]['start'];
|
||||||
$this->measures[$name]['duration_str'] = $this->toReadableString($this->measures[$name]['duration']);
|
$this->measures[$name]['duration_str'] = $this->formatDuration($this->measures[$name]['duration']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -123,17 +123,6 @@ class TimeDataCollector extends DataCollector implements Renderable
|
|||||||
return microtime(true) - $this->requestStartTime;
|
return microtime(true) - $this->requestStartTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Transforms a duration in seconds in a readable string
|
|
||||||
*
|
|
||||||
* @param float $value
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function toReadableString($value)
|
|
||||||
{
|
|
||||||
return round($value * 1000) . 'ms';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@ -150,7 +139,7 @@ class TimeDataCollector extends DataCollector implements Renderable
|
|||||||
'start' => $this->requestStartTime,
|
'start' => $this->requestStartTime,
|
||||||
'end' => $this->requestEndTime,
|
'end' => $this->requestEndTime,
|
||||||
'duration' => $this->getRequestDuration(),
|
'duration' => $this->getRequestDuration(),
|
||||||
'duration_str' => $this->toReadableString($this->getRequestDuration()),
|
'duration_str' => $this->formatDuration($this->getRequestDuration()),
|
||||||
'measures' => array_values($this->measures)
|
'measures' => array_values($this->measures)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -205,6 +205,7 @@ class JavascriptRenderer
|
|||||||
* - icon: icon name
|
* - icon: icon name
|
||||||
* - tooltip: string
|
* - tooltip: string
|
||||||
* - widget: widget class name
|
* - widget: widget class name
|
||||||
|
* - title: tab title
|
||||||
* - map: a property name from the data to map the control to
|
* - map: a property name from the data to map the control to
|
||||||
* - default: a js string, default value of the data map
|
* - default: a js string, default value of the data map
|
||||||
*
|
*
|
||||||
@ -375,12 +376,13 @@ class JavascriptRenderer
|
|||||||
|
|
||||||
foreach ($controls as $name => $options) {
|
foreach ($controls as $name => $options) {
|
||||||
if (isset($options['widget'])) {
|
if (isset($options['widget'])) {
|
||||||
$js .= sprintf("%s.createTab(\"%s\", new %s());\n",
|
$js .= sprintf("%s.createTab(\"%s\", new %s()%s);\n",
|
||||||
$varname,
|
$varname,
|
||||||
$name,
|
$name,
|
||||||
$options['widget']
|
$options['widget'],
|
||||||
|
isset($options['title']) ? sprintf(', "%s"', $options['title']) : ''
|
||||||
);
|
);
|
||||||
} else {
|
} else if (strpos($name, ':') === false) {
|
||||||
$js .= sprintf("%s.createIndicator(\"%s\", \"%s\", \"%s\");\n",
|
$js .= sprintf("%s.createIndicator(\"%s\", \"%s\", \"%s\");\n",
|
||||||
$varname,
|
$varname,
|
||||||
$name,
|
$name,
|
||||||
|
@ -15,6 +15,7 @@ use DebugBar\DataCollector\MessagesCollector;
|
|||||||
use DebugBar\DataCollector\TimeDataCollector;
|
use DebugBar\DataCollector\TimeDataCollector;
|
||||||
use DebugBar\DataCollector\RequestDataCollector;
|
use DebugBar\DataCollector\RequestDataCollector;
|
||||||
use DebugBar\DataCollector\MemoryCollector;
|
use DebugBar\DataCollector\MemoryCollector;
|
||||||
|
use DebugBar\DataCollector\ExceptionsCollector;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Debug bar subclass which adds all included collectors
|
* Debug bar subclass which adds all included collectors
|
||||||
@ -31,5 +32,6 @@ class StandardDebugBar extends DebugBar
|
|||||||
$this->addCollector(new RequestDataCollector());
|
$this->addCollector(new RequestDataCollector());
|
||||||
$this->addCollector(new TimeDataCollector());
|
$this->addCollector(new TimeDataCollector());
|
||||||
$this->addCollector(new MemoryCollector());
|
$this->addCollector(new MemoryCollector());
|
||||||
|
$this->addCollector(new ExceptionsCollector());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
101
web/debugbar.css
101
web/debugbar.css
@ -51,6 +51,19 @@
|
|||||||
background-image: -ms-linear-gradient(bottom, rgb(173,173,173) 41%, rgb(209,209,209) 71%);
|
background-image: -ms-linear-gradient(bottom, rgb(173,173,173) 41%, rgb(209,209,209) 71%);
|
||||||
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.41, rgb(173,173,173)), color-stop(0.71, rgb(209,209,209)));
|
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.41, rgb(173,173,173)), color-stop(0.71, rgb(209,209,209)));
|
||||||
}
|
}
|
||||||
|
.phpdebugbar-tab .badge {
|
||||||
|
display: none;
|
||||||
|
margin-left: 5px;
|
||||||
|
font-size: 11px;
|
||||||
|
padding: 1px 6px;
|
||||||
|
background: #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
.phpdebugbar-tab .badge.important {
|
||||||
|
background: #ed6868;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
.phpdebugbar-close-btn {
|
.phpdebugbar-close-btn {
|
||||||
display: none;
|
display: none;
|
||||||
@ -126,6 +139,7 @@
|
|||||||
.phpdebugbar-widgets-list .list-item {
|
.phpdebugbar-widgets-list .list-item {
|
||||||
padding: 3px 6px;
|
padding: 3px 6px;
|
||||||
border-bottom: 1px solid #eee;
|
border-bottom: 1px solid #eee;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
.phpdebugbar-widgets-list .list-item:hover {
|
.phpdebugbar-widgets-list .list-item:hover {
|
||||||
background: #fafafa;
|
background: #fafafa;
|
||||||
@ -249,3 +263,90 @@
|
|||||||
top: 5px;
|
top: 5px;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------- */
|
||||||
|
|
||||||
|
.phpdebugbar-widgets-exceptions .list-item {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.phpdebugbar-widgets-exceptions .list-item .message {
|
||||||
|
display: block;
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.phpdebugbar-widgets-exceptions .list-item .filename {
|
||||||
|
display: block;
|
||||||
|
font-style: italic;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
.phpdebugbar-widgets-exceptions .list-item .type {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
right: 4px;
|
||||||
|
top: 4px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.phpdebugbar-widgets-exceptions .list-item .file {
|
||||||
|
display: none;
|
||||||
|
margin: 10px;
|
||||||
|
padding: 5px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------- */
|
||||||
|
|
||||||
|
.phpdebugbar-widgets-sqlqueries .status {
|
||||||
|
font-family: monospace;
|
||||||
|
padding: 6px 6px;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #555;
|
||||||
|
background: #fafafa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.phpdebugbar-widgets-sqlqueries .list-item.error {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.phpdebugbar-widgets-sqlqueries .duration,
|
||||||
|
.phpdebugbar-widgets-sqlqueries .memory,
|
||||||
|
.phpdebugbar-widgets-sqlqueries .row-count,
|
||||||
|
.phpdebugbar-widgets-sqlqueries .stmt-id {
|
||||||
|
float: right;
|
||||||
|
margin-left: 8px;
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
.phpdebugbar-widgets-sqlqueries .status .duration,
|
||||||
|
.phpdebugbar-widgets-sqlqueries .status .memory,
|
||||||
|
.phpdebugbar-widgets-sqlqueries .status .row-count,
|
||||||
|
.phpdebugbar-widgets-sqlqueries .status .stmt-id {
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
.phpdebugbar-widgets-sqlqueries .duration:before,
|
||||||
|
.phpdebugbar-widgets-sqlqueries .memory:before,
|
||||||
|
.phpdebugbar-widgets-sqlqueries .row-count:before,
|
||||||
|
.phpdebugbar-widgets-sqlqueries .stmt-id:before {
|
||||||
|
font-family: FontAwesome;
|
||||||
|
margin-right: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
.phpdebugbar-widgets-sqlqueries .duration:before {
|
||||||
|
content: "\f017";
|
||||||
|
}
|
||||||
|
.phpdebugbar-widgets-sqlqueries .memory:before {
|
||||||
|
content: "\f085";
|
||||||
|
}
|
||||||
|
.phpdebugbar-widgets-sqlqueries .row-count:before {
|
||||||
|
content: "\f0ce";
|
||||||
|
}
|
||||||
|
.phpdebugbar-widgets-sqlqueries .stmt-id:before {
|
||||||
|
content: "\f08d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.phpdebugbar-widgets-sqlqueries .list-item .error {
|
||||||
|
display: block;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
@ -62,7 +62,9 @@ PhpDebugBar.DebugBar = (function($) {
|
|||||||
* @param {Object} widget
|
* @param {Object} widget
|
||||||
*/
|
*/
|
||||||
var Tab = function(title, widget) {
|
var Tab = function(title, widget) {
|
||||||
this.tab = $('<a href="javascript:" class="phpdebugbar-tab" />').text(title);
|
this.tab = $('<a href="javascript:" class="phpdebugbar-tab" />')
|
||||||
|
this.tabText = $('<span class="text" />').text(title).appendTo(this.tab);
|
||||||
|
this.badge = $('<span class="badge" />').appendTo(this.tab);
|
||||||
this.panel = $('<div class="phpdebugbar-panel" />');
|
this.panel = $('<div class="phpdebugbar-panel" />');
|
||||||
this.replaceWidget(widget);
|
this.replaceWidget(widget);
|
||||||
};
|
};
|
||||||
@ -77,6 +79,20 @@ PhpDebugBar.DebugBar = (function($) {
|
|||||||
this.tab.text(text);
|
this.tab.text(text);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the badge value of the tab
|
||||||
|
*
|
||||||
|
* @this {Tab}
|
||||||
|
* @param {String} value
|
||||||
|
*/
|
||||||
|
Tab.prototype.setBadgeValue = function(value) {
|
||||||
|
if (value === null) {
|
||||||
|
this.badge.hide();
|
||||||
|
} else {
|
||||||
|
this.badge.text(value).show();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replaces the widget inside the panel
|
* Replaces the widget inside the panel
|
||||||
*
|
*
|
||||||
@ -544,7 +560,10 @@ PhpDebugBar.DebugBar = (function($) {
|
|||||||
var self = this;
|
var self = this;
|
||||||
$.each(this.dataMap, function(key, def) {
|
$.each(this.dataMap, function(key, def) {
|
||||||
var d = getDictValue(data, def[0], def[1]);
|
var d = getDictValue(data, def[0], def[1]);
|
||||||
if (self.isIndicator(key)) {
|
if (key.indexOf(':') != -1) {
|
||||||
|
key = key.split(':')[0];
|
||||||
|
self.getTab(key).setBadgeValue(d);
|
||||||
|
} else if (self.isIndicator(key)) {
|
||||||
self.getIndicator(key).setText(d);
|
self.getIndicator(key).setText(d);
|
||||||
} else {
|
} else {
|
||||||
self.getTab(key).widget.setData(d);
|
self.getTab(key).widget.setData(d);
|
||||||
|
@ -354,6 +354,92 @@ PhpDebugBar.Widgets = (function($) {
|
|||||||
|
|
||||||
widgets.TimelineWidget = TimelineWidget;
|
widgets.TimelineWidget = TimelineWidget;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Widget for the displaying exceptions
|
||||||
|
*
|
||||||
|
* @this {ExceptionsWidget}
|
||||||
|
* @constructor
|
||||||
|
* @param {Object} data
|
||||||
|
*/
|
||||||
|
var ExceptionsWidget = function(data) {
|
||||||
|
this.element = $('<div class="phpdebugbar-widgets-exceptions" />');
|
||||||
|
|
||||||
|
this.list = new ListWidget(null, function(li, e) {
|
||||||
|
$('<span class="message" />').text(e.message).appendTo(li);
|
||||||
|
$('<span class="filename" />').text(e.file + "#" + e.line).appendTo(li);
|
||||||
|
$('<span class="type" />').text(e.type).appendTo(li);
|
||||||
|
var file = $('<div class="file" />').html(htmlize(e.surrounding_lines.join(""))).appendTo(li);
|
||||||
|
|
||||||
|
li.click(function() {
|
||||||
|
if (file.is(':visible')) {
|
||||||
|
file.hide();
|
||||||
|
} else {
|
||||||
|
file.show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
this.element.append(this.list.element);
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
this.setData(data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ExceptionsWidget.prototype.setData = function(data) {
|
||||||
|
this.list.setData(data);
|
||||||
|
if (data.length == 1) {
|
||||||
|
this.list.element.children().first().find('.file').show();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
widgets.ExceptionsWidget = ExceptionsWidget;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Widget for the displaying sql queries
|
||||||
|
*
|
||||||
|
* @this {SQLQueriesWidget}
|
||||||
|
* @constructor
|
||||||
|
* @param {Object} data
|
||||||
|
*/
|
||||||
|
var SQLQueriesWidget = function(data) {
|
||||||
|
this.element = $('<div class="phpdebugbar-widgets-sqlqueries" />');
|
||||||
|
this.status = $('<div class="status" />').appendTo(this.element);
|
||||||
|
|
||||||
|
this.list = new ListWidget(null, function(li, stmt) {
|
||||||
|
$('<span class="sql" />').text(stmt.sql).appendTo(li);
|
||||||
|
$('<span class="duration" title="Duration (s)" />').text(stmt.duration_str).appendTo(li);
|
||||||
|
$('<span class="memory" title="Peak memory usage" />').text(stmt.memory_str).appendTo(li);
|
||||||
|
if (!stmt.is_success) {
|
||||||
|
li.addClass('error');
|
||||||
|
li.append($('<span class="error" />').text("[" + stmt.error_code + "] " + stmt.error_message));
|
||||||
|
} else {
|
||||||
|
$('<span class="row-count" title="Row count" />').text(stmt.row_count).appendTo(li);
|
||||||
|
}
|
||||||
|
if (stmt.stmt_id) {
|
||||||
|
$('<span class="stmt-id" title="Prepared statement ID" />').text(stmt.stmt_id).appendTo(li);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.element.append(this.list.element);
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
this.setData(data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
SQLQueriesWidget.prototype.setData = function(data) {
|
||||||
|
this.list.setData(data.statements);
|
||||||
|
this.status.empty()
|
||||||
|
.append($('<span />').text(data.nb_statements + " statements were executed" + (data.nb_failed_statements > 0 ? (", " + data.nb_failed_statements + " of which failed") : "")))
|
||||||
|
.append($('<span class="duration" title="Accumulated duration (s)" />').text(data.accumulated_duration_str))
|
||||||
|
.append($('<span class="memory" title="Peak memory usage" />').text(data.peak_memory_usage_str));
|
||||||
|
};
|
||||||
|
|
||||||
|
widgets.SQLQueriesWidget = SQLQueriesWidget;
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
|
|
||||||
return widgets;
|
return widgets;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user