Framework Update
This commit is contained in:
+2
-2
@@ -19,10 +19,10 @@
|
||||
"require": {
|
||||
"php": "^7.1|^8",
|
||||
"psr/log": "^1|^2|^3",
|
||||
"symfony/var-dumper": "^2.6|^3|^4|^5|^6"
|
||||
"symfony/var-dumper": "^4|^5|^6"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7.5.20 || ^9.4.2",
|
||||
"phpunit/phpunit": ">=7.5.20 <10.0",
|
||||
"twig/twig": "^1.38|^2.7|^3.0"
|
||||
},
|
||||
"autoload": {
|
||||
|
||||
@@ -57,9 +57,9 @@ class MonologCollector extends AbstractProcessingHandler implements DataCollecto
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $record
|
||||
* @param array|\Monolog\LogRecord $record
|
||||
*/
|
||||
protected function write(array $record): void
|
||||
protected function write($record): void
|
||||
{
|
||||
$this->records[] = array(
|
||||
'message' => $record['formatted'],
|
||||
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace DebugBar\Bridge\Symfony;
|
||||
|
||||
use DebugBar\DataCollector\AssetProvider;
|
||||
use DebugBar\DataCollector\DataCollector;
|
||||
use DebugBar\DataCollector\Renderable;
|
||||
|
||||
/**
|
||||
* Collects data about sent mail events
|
||||
*
|
||||
* https://github.com/symfony/mailer
|
||||
*/
|
||||
class SymfonyMailCollector extends DataCollector implements Renderable, AssetProvider
|
||||
{
|
||||
/** @var array */
|
||||
private $messages = array();
|
||||
|
||||
/** @var bool */
|
||||
private $showDetailed = false;
|
||||
|
||||
/** @param \Symfony\Component\Mailer\SentMessage $message */
|
||||
public function addSymfonyMessage($message)
|
||||
{
|
||||
$this->messages[] = $message->getOriginalMessage();
|
||||
}
|
||||
|
||||
public function showMessageDetail()
|
||||
{
|
||||
$this->showDetailed = true;
|
||||
}
|
||||
|
||||
public function collect()
|
||||
{
|
||||
$mails = array();
|
||||
|
||||
foreach ($this->messages as $message) {
|
||||
/* @var \Symfony\Component\Mime\Message $message */
|
||||
$mails[] = array(
|
||||
'to' => array_map(function ($address) {
|
||||
/* @var \Symfony\Component\Mime\Address $address */
|
||||
return $address->toString();
|
||||
}, $message->getTo()),
|
||||
'subject' => $message->getSubject(),
|
||||
'headers' => ($this->showDetailed ? $message : $message->getHeaders())->toString(),
|
||||
);;
|
||||
}
|
||||
|
||||
return array(
|
||||
'count' => count($mails),
|
||||
'mails' => $mails,
|
||||
);
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'symfonymailer_mails';
|
||||
}
|
||||
|
||||
public function getWidgets()
|
||||
{
|
||||
return array(
|
||||
'emails' => array(
|
||||
'icon' => 'inbox',
|
||||
'widget' => 'PhpDebugBar.Widgets.MailsWidget',
|
||||
'map' => 'symfonymailer_mails.mails',
|
||||
'default' => '[]',
|
||||
'title' => 'Mails'
|
||||
),
|
||||
'emails:badge' => array(
|
||||
'map' => 'symfonymailer_mails.count',
|
||||
'default' => 'null'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function getAssets()
|
||||
{
|
||||
return array(
|
||||
'css' => 'widgets/mails/widget.css',
|
||||
'js' => 'widgets/mails/widget.js'
|
||||
);
|
||||
}
|
||||
}
|
||||
+8
-9
@@ -48,7 +48,7 @@ class AggregatedCollector implements DataCollectorInterface, ArrayAccess
|
||||
/**
|
||||
* @param DataCollectorInterface $collector
|
||||
*/
|
||||
public function addCollector(DataCollectorInterface $collector)
|
||||
public function addCollector(DataCollectorInterface $collector) : void
|
||||
{
|
||||
$this->collectors[$collector->getName()] = $collector;
|
||||
}
|
||||
@@ -56,7 +56,7 @@ class AggregatedCollector implements DataCollectorInterface, ArrayAccess
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getCollectors()
|
||||
public function getCollectors() : array
|
||||
{
|
||||
return $this->collectors;
|
||||
}
|
||||
@@ -66,7 +66,7 @@ class AggregatedCollector implements DataCollectorInterface, ArrayAccess
|
||||
*
|
||||
* @param string $property
|
||||
*/
|
||||
public function setMergeProperty($property)
|
||||
public function setMergeProperty($property) : void
|
||||
{
|
||||
$this->mergeProperty = $property;
|
||||
}
|
||||
@@ -74,7 +74,7 @@ class AggregatedCollector implements DataCollectorInterface, ArrayAccess
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getMergeProperty()
|
||||
public function getMergeProperty() : string
|
||||
{
|
||||
return $this->mergeProperty;
|
||||
}
|
||||
@@ -87,7 +87,7 @@ class AggregatedCollector implements DataCollectorInterface, ArrayAccess
|
||||
*
|
||||
* @param bool|string $sort
|
||||
*/
|
||||
public function setSort($sort)
|
||||
public function setSort($sort) : void
|
||||
{
|
||||
$this->sort = $sort;
|
||||
}
|
||||
@@ -103,7 +103,7 @@ class AggregatedCollector implements DataCollectorInterface, ArrayAccess
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function collect()
|
||||
public function collect() : array
|
||||
{
|
||||
$aggregate = array();
|
||||
foreach ($this->collectors as $collector) {
|
||||
@@ -123,7 +123,7 @@ class AggregatedCollector implements DataCollectorInterface, ArrayAccess
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
protected function sort($data)
|
||||
protected function sort($data) : array
|
||||
{
|
||||
if (is_string($this->sort)) {
|
||||
$p = $this->sort;
|
||||
@@ -142,7 +142,7 @@ class AggregatedCollector implements DataCollectorInterface, ArrayAccess
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
public function getName() : string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
@@ -164,7 +164,6 @@ class AggregatedCollector implements DataCollectorInterface, ArrayAccess
|
||||
* @param mixed $key
|
||||
* @return mixed
|
||||
*/
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetGet($key)
|
||||
{
|
||||
|
||||
@@ -74,6 +74,32 @@ abstract class DataCollector implements DataCollectorInterface
|
||||
return $this->dataFormater;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shorten the file path by removing the xdebug path replacements
|
||||
*
|
||||
* @param string $file
|
||||
* @return string
|
||||
*/
|
||||
public function normalizeFilePath($file)
|
||||
{
|
||||
if (empty($file)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (file_exists($file)) {
|
||||
$file = realpath($file);
|
||||
}
|
||||
|
||||
foreach (array_keys($this->xdebugReplacements) as $path) {
|
||||
if (strpos($file, $path) === 0) {
|
||||
$file = substr($file, strlen($path));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ltrim(str_replace('\\', '/', $file), '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an Xdebug Link to a file
|
||||
*
|
||||
@@ -87,8 +113,19 @@ abstract class DataCollector implements DataCollectorInterface
|
||||
*/
|
||||
public function getXdebugLink($file, $line = 1)
|
||||
{
|
||||
if (count($this->xdebugReplacements)) {
|
||||
$file = strtr($file, $this->xdebugReplacements);
|
||||
if (empty($file)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (file_exists($file)) {
|
||||
$file = realpath($file);
|
||||
}
|
||||
|
||||
foreach ($this->xdebugReplacements as $path => $replacement) {
|
||||
if (strpos($file, $path) === 0) {
|
||||
$file = $replacement . substr($file, strlen($path));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$url = strtr($this->getXdebugLinkTemplate(), ['%f' => $file, '%l' => $line]);
|
||||
@@ -182,6 +219,39 @@ abstract class DataCollector implements DataCollectorInterface
|
||||
return $this->xdebugLinkTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $editor
|
||||
*/
|
||||
public function setEditorLinkTemplate($editor)
|
||||
{
|
||||
$editorLinkTemplates = array(
|
||||
'sublime' => 'subl://open?url=file://%f&line=%l',
|
||||
'textmate' => 'txmt://open?url=file://%f&line=%l',
|
||||
'emacs' => 'emacs://open?url=file://%f&line=%l',
|
||||
'macvim' => 'mvim://open/?url=file://%f&line=%l',
|
||||
'phpstorm' => 'phpstorm://open?file=%f&line=%l',
|
||||
'phpstorm-remote' => 'javascript:let r=new XMLHttpRequest;' .
|
||||
'r.open("get","http://localhost:63342/api/file/%f:%l");r.send()',
|
||||
'idea' => 'idea://open?file=%f&line=%l',
|
||||
'idea-remote' => 'javascript:let r=new XMLHttpRequest;' .
|
||||
'r.open("get","http://localhost:63342/api/file/?file=%f&line=%l");r.send()',
|
||||
'vscode' => 'vscode://file/%f:%l',
|
||||
'vscode-insiders' => 'vscode-insiders://file/%f:%l',
|
||||
'vscode-remote' => 'vscode://vscode-remote/%f:%l',
|
||||
'vscode-insiders-remote' => 'vscode-insiders://vscode-remote/%f:%l',
|
||||
'vscodium' => 'vscodium://file/%f:%l',
|
||||
'nova' => 'nova://core/open/file?filename=%f&line=%l',
|
||||
'xdebug' => 'xdebug://%f@%l',
|
||||
'atom' => 'atom://core/open/file?filename=%f&line=%l',
|
||||
'espresso' => 'x-espresso://open?filepath=%f&lines=%l',
|
||||
'netbeans' => 'netbeans://open/?f=%f:%l',
|
||||
);
|
||||
|
||||
if (is_string($editor) && isset($editorLinkTemplates[$editor])) {
|
||||
$this->setXdebugLinkTemplate($editorLinkTemplates[$editor]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $xdebugLinkTemplate
|
||||
* @param bool $shouldUseAjax
|
||||
@@ -219,6 +289,16 @@ abstract class DataCollector implements DataCollectorInterface
|
||||
return $this->xdebugReplacements;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $xdebugReplacements
|
||||
*/
|
||||
public function addXdebugReplacements($xdebugReplacements)
|
||||
{
|
||||
foreach ($xdebugReplacements as $serverPath => $replacement) {
|
||||
$this->setXdebugReplacement($serverPath, $replacement);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $xdebugReplacements
|
||||
*/
|
||||
@@ -227,6 +307,10 @@ abstract class DataCollector implements DataCollectorInterface
|
||||
$this->xdebugReplacements = $xdebugReplacements;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $serverPath
|
||||
* @param string $replacement
|
||||
*/
|
||||
public function setXdebugReplacement($serverPath, $replacement)
|
||||
{
|
||||
$this->xdebugReplacements[$serverPath] = $replacement;
|
||||
|
||||
+23
-3
@@ -113,6 +113,26 @@ class ExceptionsCollector extends DataCollector implements Renderable
|
||||
return $this->formatThrowableData($e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Throwable trace as an formated array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function formatTrace(array $trace)
|
||||
{
|
||||
return $trace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Throwable data as an string
|
||||
*
|
||||
* @param \Throwable $e
|
||||
* @return string
|
||||
*/
|
||||
public function formatTraceAsString($e)
|
||||
{
|
||||
return $e->getTraceAsString();
|
||||
}
|
||||
/**
|
||||
* Returns Throwable data as an array
|
||||
*
|
||||
@@ -132,16 +152,16 @@ class ExceptionsCollector extends DataCollector implements Renderable
|
||||
|
||||
$traceHtml = null;
|
||||
if ($this->isHtmlVarDumperUsed()) {
|
||||
$traceHtml = $this->getVarDumper()->renderVar($e->getTrace());
|
||||
$traceHtml = $this->getVarDumper()->renderVar($this->formatTrace($e->getTrace()));
|
||||
}
|
||||
|
||||
return array(
|
||||
'type' => get_class($e),
|
||||
'message' => $e->getMessage(),
|
||||
'code' => $e->getCode(),
|
||||
'file' => $filePath,
|
||||
'file' => $this->normalizeFilePath($filePath),
|
||||
'line' => $e->getLine(),
|
||||
'stack_trace' => $e->getTraceAsString(),
|
||||
'stack_trace' => $this->formatTraceAsString($e),
|
||||
'stack_trace_html' => $traceHtml,
|
||||
'surrounding_lines' => $lines,
|
||||
'xdebug_link' => $this->getXdebugLink($filePath, $e->getLine())
|
||||
|
||||
@@ -17,6 +17,10 @@ class MemoryCollector extends DataCollector implements Renderable
|
||||
{
|
||||
protected $realUsage = false;
|
||||
|
||||
protected $memoryRealStart = 0;
|
||||
|
||||
protected $memoryStart = 0;
|
||||
|
||||
protected $peakUsage = 0;
|
||||
|
||||
/**
|
||||
@@ -41,6 +45,17 @@ class MemoryCollector extends DataCollector implements Renderable
|
||||
$this->realUsage = $realUsage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset memory baseline, to measure multiple requests in a long running process
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function resetMemoryBaseline()
|
||||
{
|
||||
$this->memoryStart = memory_get_usage(false);
|
||||
$this->memoryRealStart = memory_get_usage(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the peak memory usage
|
||||
*
|
||||
@@ -48,7 +63,7 @@ class MemoryCollector extends DataCollector implements Renderable
|
||||
*/
|
||||
public function getPeakUsage()
|
||||
{
|
||||
return $this->peakUsage;
|
||||
return $this->peakUsage - ($this->realUsage ? $this->memoryRealStart : $this->memoryStart);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,8 +81,8 @@ class MemoryCollector extends DataCollector implements Renderable
|
||||
{
|
||||
$this->updatePeakUsage();
|
||||
return array(
|
||||
'peak_usage' => $this->peakUsage,
|
||||
'peak_usage_str' => $this->getDataFormatter()->formatBytes($this->peakUsage, 0)
|
||||
'peak_usage' => $this->getPeakUsage(),
|
||||
'peak_usage_str' => $this->getDataFormatter()->formatBytes($this->getPeakUsage(), 0)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,13 +23,13 @@ class TraceablePDO extends PDO
|
||||
$this->pdo->setAttribute(PDO::ATTR_STATEMENT_CLASS, [TraceablePDOStatement::class, [$this]]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiates a transaction
|
||||
*
|
||||
* @link http://php.net/manual/en/pdo.begintransaction.php
|
||||
* @return bool TRUE on success or FALSE on failure.
|
||||
*/
|
||||
public function beginTransaction()
|
||||
/**
|
||||
* Initiates a transaction
|
||||
*
|
||||
* @link http://php.net/manual/en/pdo.begintransaction.php
|
||||
* @return bool TRUE on success or FALSE on failure.
|
||||
*/
|
||||
public function beginTransaction() : bool
|
||||
{
|
||||
return $this->pdo->beginTransaction();
|
||||
}
|
||||
@@ -40,7 +40,7 @@ class TraceablePDO extends PDO
|
||||
* @link http://php.net/manual/en/pdo.commit.php
|
||||
* @return bool TRUE on success or FALSE on failure.
|
||||
*/
|
||||
public function commit()
|
||||
public function commit() : bool
|
||||
{
|
||||
return $this->pdo->commit();
|
||||
}
|
||||
@@ -51,6 +51,7 @@ class TraceablePDO extends PDO
|
||||
* @link http://php.net/manual/en/pdo.errorinfo.php
|
||||
* @return array PDO::errorInfo returns an array of error information
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function errorCode()
|
||||
{
|
||||
return $this->pdo->errorCode();
|
||||
@@ -62,7 +63,7 @@ class TraceablePDO extends PDO
|
||||
* @link http://php.net/manual/en/pdo.errorinfo.php
|
||||
* @return array PDO::errorInfo returns an array of error information
|
||||
*/
|
||||
public function errorInfo()
|
||||
public function errorInfo() : array
|
||||
{
|
||||
return $this->pdo->errorInfo();
|
||||
}
|
||||
@@ -77,6 +78,7 @@ class TraceablePDO extends PDO
|
||||
* return Boolean FALSE, but may also return a non-Boolean value which evaluates to FALSE.
|
||||
* Please read the section on Booleans for more information
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function exec($statement)
|
||||
{
|
||||
return $this->profileCall('exec', $statement, func_get_args());
|
||||
@@ -90,6 +92,7 @@ class TraceablePDO extends PDO
|
||||
* @return mixed A successful call returns the value of the requested PDO attribute.
|
||||
* An unsuccessful call returns null.
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function getAttribute($attribute)
|
||||
{
|
||||
return $this->pdo->getAttribute($attribute);
|
||||
@@ -101,7 +104,7 @@ class TraceablePDO extends PDO
|
||||
* @link http://php.net/manual/en/pdo.intransaction.php
|
||||
* @return bool TRUE if a transaction is currently active, and FALSE if not.
|
||||
*/
|
||||
public function inTransaction()
|
||||
public function inTransaction() : bool
|
||||
{
|
||||
return $this->pdo->inTransaction();
|
||||
}
|
||||
@@ -114,37 +117,40 @@ class TraceablePDO extends PDO
|
||||
* @return string If a sequence name was not specified for the name parameter, PDO::lastInsertId
|
||||
* returns a string representing the row ID of the last row that was inserted into the database.
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function lastInsertId($name = null)
|
||||
{
|
||||
return $this->pdo->lastInsertId($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares a statement for execution and returns a statement object
|
||||
*
|
||||
* @link http://php.net/manual/en/pdo.prepare.php
|
||||
* @param string $statement This must be a valid SQL statement template for the target DB server.
|
||||
* @param array $driver_options [optional] This array holds one or more key=>value pairs to
|
||||
* set attribute values for the PDOStatement object that this method returns.
|
||||
* @return TraceablePDOStatement|bool If the database server successfully prepares the statement,
|
||||
* PDO::prepare returns a PDOStatement object. If the database server cannot successfully prepare
|
||||
* the statement, PDO::prepare returns FALSE or emits PDOException (depending on error handling).
|
||||
*/
|
||||
/**
|
||||
* Prepares a statement for execution and returns a statement object
|
||||
*
|
||||
* @link http://php.net/manual/en/pdo.prepare.php
|
||||
* @param string $statement This must be a valid SQL statement template for the target DB server.
|
||||
* @param array $driver_options [optional] This array holds one or more key=>value pairs to
|
||||
* set attribute values for the PDOStatement object that this method returns.
|
||||
* @return TraceablePDOStatement|bool If the database server successfully prepares the statement,
|
||||
* PDO::prepare returns a PDOStatement object. If the database server cannot successfully prepare
|
||||
* the statement, PDO::prepare returns FALSE or emits PDOException (depending on error handling).
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function prepare($statement, $driver_options = [])
|
||||
{
|
||||
return $this->pdo->prepare($statement, $driver_options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes an SQL statement, returning a result set as a PDOStatement object
|
||||
*
|
||||
* @link http://php.net/manual/en/pdo.query.php
|
||||
* @param string $statement
|
||||
* @param int $fetchMode
|
||||
* @param mixed ...$fetchModeArgs
|
||||
* @return TraceablePDOStatement|bool PDO::query returns a PDOStatement object, or FALSE on
|
||||
* failure.
|
||||
*/
|
||||
/**
|
||||
* Executes an SQL statement, returning a result set as a PDOStatement object
|
||||
*
|
||||
* @link http://php.net/manual/en/pdo.query.php
|
||||
* @param string $statement
|
||||
* @param int $fetchMode
|
||||
* @param mixed ...$fetchModeArgs
|
||||
* @return TraceablePDOStatement|bool PDO::query returns a PDOStatement object, or FALSE on
|
||||
* failure.
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function query($statement, $fetchMode = null, ...$fetchModeArgs)
|
||||
{
|
||||
return $this->profileCall('query', $statement, func_get_args());
|
||||
@@ -160,6 +166,7 @@ class TraceablePDO extends PDO
|
||||
* @return string|bool A quoted string that is theoretically safe to pass into an SQL statement.
|
||||
* Returns FALSE if the driver does not support quoting in this way.
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function quote($string, $parameter_type = PDO::PARAM_STR)
|
||||
{
|
||||
return $this->pdo->quote($string, $parameter_type);
|
||||
@@ -171,7 +178,7 @@ class TraceablePDO extends PDO
|
||||
* @link http://php.net/manual/en/pdo.rollback.php
|
||||
* @return bool TRUE on success or FALSE on failure.
|
||||
*/
|
||||
public function rollBack()
|
||||
public function rollBack() : bool
|
||||
{
|
||||
return $this->pdo->rollBack();
|
||||
}
|
||||
@@ -184,7 +191,7 @@ class TraceablePDO extends PDO
|
||||
* @param mixed $value
|
||||
* @return bool TRUE on success or FALSE on failure.
|
||||
*/
|
||||
public function setAttribute($attribute, $value)
|
||||
public function setAttribute($attribute, $value) : bool
|
||||
{
|
||||
return $this->pdo->setAttribute($attribute, $value);
|
||||
}
|
||||
@@ -197,6 +204,7 @@ class TraceablePDO extends PDO
|
||||
* @param array $args
|
||||
* @return mixed The result of the call
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
protected function profileCall($method, $sql, array $args)
|
||||
{
|
||||
$trace = new TracedStatement($sql);
|
||||
@@ -228,7 +236,7 @@ class TraceablePDO extends PDO
|
||||
*
|
||||
* @param TracedStatement $stmt
|
||||
*/
|
||||
public function addExecutedStatement(TracedStatement $stmt)
|
||||
public function addExecutedStatement(TracedStatement $stmt) : void
|
||||
{
|
||||
$this->executedStatements[] = $stmt;
|
||||
}
|
||||
@@ -236,11 +244,11 @@ class TraceablePDO extends PDO
|
||||
/**
|
||||
* Returns the accumulated execution time of statements
|
||||
*
|
||||
* @return int
|
||||
* @return float
|
||||
*/
|
||||
public function getAccumulatedStatementsDuration()
|
||||
public function getAccumulatedStatementsDuration() : float
|
||||
{
|
||||
return array_reduce($this->executedStatements, function ($v, $s) { return $v + $s->getDuration(); });
|
||||
return array_reduce($this->executedStatements, function ($v, $s) { return $v + $s->getDuration(); }, 0.0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -248,9 +256,9 @@ class TraceablePDO extends PDO
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getMemoryUsage()
|
||||
public function getMemoryUsage() : int
|
||||
{
|
||||
return array_reduce($this->executedStatements, function ($v, $s) { return $v + $s->getMemoryUsage(); });
|
||||
return array_reduce($this->executedStatements, function ($v, $s) { return $v + $s->getMemoryUsage(); }, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -258,9 +266,9 @@ class TraceablePDO extends PDO
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getPeakMemoryUsage()
|
||||
public function getPeakMemoryUsage() : int
|
||||
{
|
||||
return array_reduce($this->executedStatements, function ($v, $s) { $m = $s->getEndMemory(); return $m > $v ? $m : $v; });
|
||||
return array_reduce($this->executedStatements, function ($v, $s) { $m = $s->getEndMemory(); return $m > $v ? $m : $v; }, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -268,7 +276,7 @@ class TraceablePDO extends PDO
|
||||
*
|
||||
* @return TracedStatement[]
|
||||
*/
|
||||
public function getExecutedStatements()
|
||||
public function getExecutedStatements() : array
|
||||
{
|
||||
return $this->executedStatements;
|
||||
}
|
||||
@@ -278,7 +286,7 @@ class TraceablePDO extends PDO
|
||||
*
|
||||
* @return TracedStatement[]
|
||||
*/
|
||||
public function getFailedExecutedStatements()
|
||||
public function getFailedExecutedStatements() : array
|
||||
{
|
||||
return array_filter($this->executedStatements, function ($s) { return !$s->isSuccess(); });
|
||||
}
|
||||
|
||||
+7
-6
@@ -39,11 +39,12 @@ class TraceablePDOStatement extends PDOStatement
|
||||
* @param mixed $driverdata [optional] Optional parameter(s) for the driver.
|
||||
* @return bool TRUE on success or FALSE on failure.
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function bindColumn($column, &$param, $type = null, $maxlen = null, $driverdata = null)
|
||||
{
|
||||
$this->boundParameters[$column] = $param;
|
||||
$args = array_merge([$column, &$param], array_slice(func_get_args(), 2));
|
||||
return call_user_func_array(['parent', 'bindColumn'], $args);
|
||||
return parent::bindColumn(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,11 +62,11 @@ class TraceablePDOStatement extends PDOStatement
|
||||
* @param mixed $driver_options [optional]
|
||||
* @return bool TRUE on success or FALSE on failure.
|
||||
*/
|
||||
public function bindParam($parameter, &$variable, $data_type = PDO::PARAM_STR, $length = null, $driver_options = null)
|
||||
public function bindParam($parameter, &$variable, $data_type = PDO::PARAM_STR, $length = null, $driver_options = null) : bool
|
||||
{
|
||||
$this->boundParameters[$parameter] = $variable;
|
||||
$args = array_merge([$parameter, &$variable], array_slice(func_get_args(), 2));
|
||||
return call_user_func_array(['parent', 'bindParam'], $args);
|
||||
return parent::bindParam(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,10 +81,10 @@ class TraceablePDOStatement extends PDOStatement
|
||||
* constants.
|
||||
* @return bool TRUE on success or FALSE on failure.
|
||||
*/
|
||||
public function bindValue($parameter, $value, $data_type = PDO::PARAM_STR)
|
||||
public function bindValue($parameter, $value, $data_type = PDO::PARAM_STR) : bool
|
||||
{
|
||||
$this->boundParameters[$parameter] = $value;
|
||||
return call_user_func_array(['parent', 'bindValue'], func_get_args());
|
||||
return parent::bindValue(...func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,7 +97,7 @@ class TraceablePDOStatement extends PDOStatement
|
||||
* @throws PDOException
|
||||
* @return bool TRUE on success or FALSE on failure.
|
||||
*/
|
||||
public function execute($input_parameters = null)
|
||||
public function execute($input_parameters = null) : bool
|
||||
{
|
||||
$preparedId = spl_object_hash($this);
|
||||
$boundParameters = $this->boundParameters;
|
||||
|
||||
+31
-25
@@ -27,12 +27,14 @@ class TracedStatement
|
||||
|
||||
protected $exception;
|
||||
|
||||
protected $preparedId;
|
||||
|
||||
/**
|
||||
* @param string $sql
|
||||
* @param array $params
|
||||
* @param string $preparedId
|
||||
* @param null|string $preparedId
|
||||
*/
|
||||
public function __construct($sql, array $params = [], $preparedId = null)
|
||||
public function __construct(string $sql, array $params = [], ?string $preparedId = null)
|
||||
{
|
||||
$this->sql = $sql;
|
||||
$this->parameters = $this->checkParameters($params);
|
||||
@@ -43,7 +45,7 @@ class TracedStatement
|
||||
* @param null $startTime
|
||||
* @param null $startMemory
|
||||
*/
|
||||
public function start($startTime = null, $startMemory = null)
|
||||
public function start($startTime = null, $startMemory = null) : void
|
||||
{
|
||||
$this->startTime = $startTime ?: microtime(true);
|
||||
$this->startMemory = $startMemory ?: memory_get_usage(false);
|
||||
@@ -55,7 +57,7 @@ class TracedStatement
|
||||
* @param float $endTime
|
||||
* @param int $endMemory
|
||||
*/
|
||||
public function end(\Exception $exception = null, $rowCount = 0, $endTime = null, $endMemory = null)
|
||||
public function end(\Exception $exception = null, int $rowCount = 0, float $endTime = null, int $endMemory = null) : void
|
||||
{
|
||||
$this->endTime = $endTime ?: microtime(true);
|
||||
$this->duration = $this->endTime - $this->startTime;
|
||||
@@ -71,10 +73,10 @@ class TracedStatement
|
||||
* @param array $params
|
||||
* @return array
|
||||
*/
|
||||
public function checkParameters($params)
|
||||
public function checkParameters(array $params) : array
|
||||
{
|
||||
foreach ($params as &$param) {
|
||||
if (!mb_check_encoding($param, 'UTF-8')) {
|
||||
if (!mb_check_encoding($param ?? '', 'UTF-8')) {
|
||||
$param = '[BINARY DATA]';
|
||||
}
|
||||
}
|
||||
@@ -86,7 +88,7 @@ class TracedStatement
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSql()
|
||||
public function getSql() : string
|
||||
{
|
||||
return $this->sql;
|
||||
}
|
||||
@@ -97,7 +99,7 @@ class TracedStatement
|
||||
* @param string $quotationChar
|
||||
* @return string
|
||||
*/
|
||||
public function getSqlWithParams($quotationChar = '<>')
|
||||
public function getSqlWithParams(string $quotationChar = '<>') : string
|
||||
{
|
||||
if (($l = strlen($quotationChar)) > 1) {
|
||||
$quoteLeft = substr($quotationChar, 0, $l / 2);
|
||||
@@ -123,7 +125,11 @@ class TracedStatement
|
||||
}
|
||||
|
||||
$matchRule = "/({$marker}(?!\w))(?=(?:[^$quotationChar]|[$quotationChar][^$quotationChar]*[$quotationChar])*$)/";
|
||||
for ($i = 0; $i <= mb_substr_count($sql, $k); $i++) {
|
||||
$count = mb_substr_count($sql, $k);
|
||||
if ($count < 1) {
|
||||
$count = mb_substr_count($sql, $matchRule);
|
||||
}
|
||||
for ($i = 0; $i <= $count; $i++) {
|
||||
$sql = preg_replace($matchRule, $v, $sql, 1);
|
||||
}
|
||||
}
|
||||
@@ -138,7 +144,7 @@ class TracedStatement
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getRowCount()
|
||||
public function getRowCount() : int
|
||||
{
|
||||
return $this->rowCount;
|
||||
}
|
||||
@@ -148,11 +154,11 @@ class TracedStatement
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getParameters()
|
||||
public function getParameters() : array
|
||||
{
|
||||
$params = [];
|
||||
foreach ($this->parameters as $name => $param) {
|
||||
$params[$name] = htmlentities($param, ENT_QUOTES, 'UTF-8', false);
|
||||
$params[$name] = htmlentities($param?:"", ENT_QUOTES, 'UTF-8', false);
|
||||
}
|
||||
return $params;
|
||||
}
|
||||
@@ -160,9 +166,9 @@ class TracedStatement
|
||||
/**
|
||||
* Returns the prepared statement id
|
||||
*
|
||||
* @return string
|
||||
* @return null|string
|
||||
*/
|
||||
public function getPreparedId()
|
||||
public function getPreparedId() : ?string
|
||||
{
|
||||
return $this->preparedId;
|
||||
}
|
||||
@@ -172,7 +178,7 @@ class TracedStatement
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isPrepared()
|
||||
public function isPrepared() : bool
|
||||
{
|
||||
return $this->preparedId !== null;
|
||||
}
|
||||
@@ -180,7 +186,7 @@ class TracedStatement
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getStartTime()
|
||||
public function getStartTime() : float
|
||||
{
|
||||
return $this->startTime;
|
||||
}
|
||||
@@ -188,7 +194,7 @@ class TracedStatement
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getEndTime()
|
||||
public function getEndTime() : float
|
||||
{
|
||||
return $this->endTime;
|
||||
}
|
||||
@@ -198,7 +204,7 @@ class TracedStatement
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getDuration()
|
||||
public function getDuration() : float
|
||||
{
|
||||
return $this->duration;
|
||||
}
|
||||
@@ -206,7 +212,7 @@ class TracedStatement
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getStartMemory()
|
||||
public function getStartMemory() : int
|
||||
{
|
||||
return $this->startMemory;
|
||||
}
|
||||
@@ -214,7 +220,7 @@ class TracedStatement
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getEndMemory()
|
||||
public function getEndMemory() : int
|
||||
{
|
||||
return $this->endMemory;
|
||||
}
|
||||
@@ -224,7 +230,7 @@ class TracedStatement
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getMemoryUsage()
|
||||
public function getMemoryUsage() : int
|
||||
{
|
||||
return $this->memoryDelta;
|
||||
}
|
||||
@@ -234,7 +240,7 @@ class TracedStatement
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isSuccess()
|
||||
public function isSuccess() : bool
|
||||
{
|
||||
return $this->exception === null;
|
||||
}
|
||||
@@ -244,8 +250,8 @@ class TracedStatement
|
||||
*
|
||||
* @return \Exception
|
||||
*/
|
||||
public function getException()
|
||||
{
|
||||
public function getException() : \Exception
|
||||
{
|
||||
return $this->exception;
|
||||
}
|
||||
|
||||
@@ -264,7 +270,7 @@ class TracedStatement
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getErrorMessage()
|
||||
public function getErrorMessage() : string
|
||||
{
|
||||
return $this->exception !== null ? $this->exception->getMessage() : '';
|
||||
}
|
||||
|
||||
@@ -38,6 +38,11 @@ class TimeDataCollector extends DataCollector implements Renderable
|
||||
*/
|
||||
protected $measures = array();
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $memoryMeasure = false;
|
||||
|
||||
/**
|
||||
* @param float $requestStartTime
|
||||
*/
|
||||
@@ -53,6 +58,14 @@ class TimeDataCollector extends DataCollector implements Renderable
|
||||
$this->requestStartTime = (float)$requestStartTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts memory measuring
|
||||
*/
|
||||
public function showMemoryUsage()
|
||||
{
|
||||
$this->memoryMeasure = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a measure
|
||||
*
|
||||
@@ -66,6 +79,7 @@ class TimeDataCollector extends DataCollector implements Renderable
|
||||
$this->startedMeasures[$name] = array(
|
||||
'label' => $label ?: $name,
|
||||
'start' => $start,
|
||||
'memory' => $this->memoryMeasure ? memory_get_usage(false) : null,
|
||||
'collector' => $collector
|
||||
);
|
||||
}
|
||||
@@ -94,6 +108,9 @@ class TimeDataCollector extends DataCollector implements Renderable
|
||||
if (!$this->hasStartedMeasure($name)) {
|
||||
throw new DebugBarException("Failed stopping measure '$name' because it hasn't been started");
|
||||
}
|
||||
if (! is_null($this->startedMeasures[$name]['memory'])) {
|
||||
$params['memoryUsage'] = memory_get_usage(false) - $this->startedMeasures[$name]['memory'];
|
||||
}
|
||||
$this->addMeasure(
|
||||
$this->startedMeasures[$name]['label'],
|
||||
$this->startedMeasures[$name]['start'],
|
||||
@@ -115,6 +132,11 @@ class TimeDataCollector extends DataCollector implements Renderable
|
||||
*/
|
||||
public function addMeasure($label, $start, $end, $params = array(), $collector = null)
|
||||
{
|
||||
if (isset($params['memoryUsage'])) {
|
||||
$memory = $this->memoryMeasure ? $params['memoryUsage'] : 0;
|
||||
unset($params['memoryUsage']);
|
||||
}
|
||||
|
||||
$this->measures[] = array(
|
||||
'label' => $label,
|
||||
'start' => $start,
|
||||
@@ -123,6 +145,8 @@ class TimeDataCollector extends DataCollector implements Renderable
|
||||
'relative_end' => $end - $this->requestEndTime,
|
||||
'duration' => $end - $start,
|
||||
'duration_str' => $this->getDataFormatter()->formatDuration($end - $start),
|
||||
'memory' => $memory ?? 0,
|
||||
'memory_str' => $this->getDataFormatter()->formatBytes($memory ?? 0),
|
||||
'params' => $params,
|
||||
'collector' => $collector
|
||||
);
|
||||
|
||||
@@ -15,6 +15,10 @@ use Symfony\Component\VarDumper\Dumper\CliDumper;
|
||||
|
||||
class DataFormatter implements DataFormatterInterface
|
||||
{
|
||||
public $cloner;
|
||||
|
||||
public $dumper;
|
||||
|
||||
/**
|
||||
* DataFormatter constructor.
|
||||
*/
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace DebugBar\DataFormatter;
|
||||
|
||||
use DebugBar\DataCollector\AssetProvider;
|
||||
use DebugBar\DataFormatter\VarDumper\DebugBarHtmlDumper;
|
||||
use DebugBar\DataFormatter\VarDumper\SeekingData;
|
||||
use Symfony\Component\VarDumper\Cloner\Data\SeekingData;
|
||||
use Symfony\Component\VarDumper\Cloner\Data;
|
||||
use Symfony\Component\VarDumper\Cloner\VarCloner;
|
||||
|
||||
@@ -254,8 +254,6 @@ class DebugBarVarDumper implements AssetProvider
|
||||
public function renderCapturedVar($capturedData, $seekPath = array())
|
||||
{
|
||||
$data = unserialize($capturedData);
|
||||
// The seek method was added in Symfony 3.2; emulate the behavior via SeekingData for older
|
||||
// Symfony versions.
|
||||
if (!method_exists($data, 'seek')) {
|
||||
$data = new SeekingData($data->getRawData());
|
||||
}
|
||||
|
||||
-103
@@ -1,103 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace DebugBar\DataFormatter\VarDumper;
|
||||
|
||||
use Symfony\Component\VarDumper\Cloner\Cursor;
|
||||
use Symfony\Component\VarDumper\Cloner\Data;
|
||||
use Symfony\Component\VarDumper\Cloner\DumperInterface;
|
||||
use Symfony\Component\VarDumper\Cloner\Stub;
|
||||
|
||||
/**
|
||||
* This class backports the seek() function from Symfony 3.2 to older versions - up to v2.6. The
|
||||
* class should not be used with newer Symfony versions that provide the seek function, as it relies
|
||||
* on a lot of undocumented functionality.
|
||||
*/
|
||||
class SeekingData extends Data
|
||||
{
|
||||
// Because the class copies/pastes the seek() implementation from Symfony 3.2, we reproduce its
|
||||
// copyright here; this class is subject to the following additional copyright:
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Fabien Potencier
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is furnished
|
||||
* to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
private $position = 0;
|
||||
private $key = 0;
|
||||
|
||||
/**
|
||||
* Seeks to a specific key in nested data structures.
|
||||
*
|
||||
* @param string|int $key The key to seek to
|
||||
*
|
||||
* @return self|null A clone of $this of null if the key is not set
|
||||
*/
|
||||
public function seek($key)
|
||||
{
|
||||
$thisData = $this->getRawData();
|
||||
$item = $thisData[$this->position][$this->key];
|
||||
|
||||
if (!$item instanceof Stub || !$item->position) {
|
||||
return;
|
||||
}
|
||||
$keys = array($key);
|
||||
|
||||
switch ($item->type) {
|
||||
case Stub::TYPE_OBJECT:
|
||||
$keys[] = "\0+\0".$key;
|
||||
$keys[] = "\0*\0".$key;
|
||||
$keys[] = "\0~\0".$key;
|
||||
$keys[] = "\0$item->class\0$key";
|
||||
case Stub::TYPE_ARRAY:
|
||||
case Stub::TYPE_RESOURCE:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
$data = null;
|
||||
$children = $thisData[$item->position];
|
||||
|
||||
foreach ($keys as $key) {
|
||||
if (isset($children[$key]) || array_key_exists($key, $children)) {
|
||||
$data = clone $this;
|
||||
$data->key = $key;
|
||||
$data->position = $item->position;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function dump(DumperInterface $dumper)
|
||||
{
|
||||
// Override the base class dump to use the position and key
|
||||
$refs = array(0);
|
||||
$class = new \ReflectionClass($this);
|
||||
$dumpItem = $class->getMethod('dumpItem');
|
||||
$dumpItem->setAccessible(true);
|
||||
$data = $this->getRawData();
|
||||
$args = array($dumper, new Cursor(), &$refs, $data[$this->position][$this->key]);
|
||||
$dumpItem->invokeArgs($this, $args);
|
||||
}
|
||||
}
|
||||
@@ -1046,6 +1046,10 @@ class JavascriptRenderer
|
||||
|
||||
$nonce = $this->getNonceAttribute();
|
||||
|
||||
if ($nonce != '') {
|
||||
$js = preg_replace("/<script>/", "<script nonce='{$this->cspNonce}'>", $js);
|
||||
}
|
||||
|
||||
if ($this->useRequireJs){
|
||||
return "<script type=\"text/javascript\"{$nonce}>\nrequire(['debugbar'], function(PhpDebugBar){ $js });\n</script>\n";
|
||||
} else {
|
||||
|
||||
@@ -116,11 +116,10 @@ div.phpdebugbar-closed, div.phpdebugbar-minimized{
|
||||
}
|
||||
/* -------------------------------------- */
|
||||
|
||||
div.phpdebugbar-header, a.phpdebugbar-restore-btn {
|
||||
a.phpdebugbar-restore-btn {
|
||||
background: #efefef url(data:image/svg+xml,%3Csvg%20viewBox%3D%220%200%2020%2020%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Ccircle%20fill%3D%22%23000%22%20cx%3D%2210%22%20cy%3D%2210%22%20r%3D%229%22%2F%3E%3Cpath%20d%3D%22M6.039%208.342c.463%200%20.772.084.927.251.154.168.191.455.11.862-.084.424-.247.727-.487.908-.241.182-.608.272-1.1.272h-.743l.456-2.293h.837zm-2.975%204.615h1.22l.29-1.457H5.62c.461%200%20.84-.047%201.139-.142.298-.095.569-.254.812-.477.205-.184.37-.387.497-.608.127-.222.217-.466.27-.734.13-.65.032-1.155-.292-1.518-.324-.362-.84-.543-1.545-.543H4.153l-1.089%205.479zM9.235%206.02h1.21l-.289%201.458h1.079c.679%200%201.147.115%201.405.347.258.231.335.607.232%201.125l-.507%202.55h-1.23l.481-2.424c.055-.276.035-.464-.06-.565-.095-.1-.298-.15-.608-.15H9.98L9.356%2011.5h-1.21l1.089-5.48M15.566%208.342c.464%200%20.773.084.928.251.154.168.19.455.11.862-.084.424-.247.727-.488.908-.24.182-.607.272-1.1.272h-.742l.456-2.293h.836zm-2.974%204.615h1.22l.29-1.457h1.046c.461%200%20.84-.047%201.139-.142.298-.095.569-.254.812-.477.205-.184.37-.387.497-.608.127-.222.217-.466.27-.734.129-.65.032-1.155-.292-1.518-.324-.362-.84-.543-1.545-.543H13.68l-1.089%205.479z%22%20fill%3D%22%23FFF%22%2F%3E%3C%2Fsvg%3E) no-repeat 5px 4px / 20px 20px;
|
||||
}
|
||||
div.phpdebugbar-header {
|
||||
padding-left: 29px;
|
||||
min-height: 26px;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
@@ -477,6 +477,10 @@ if (typeof(PhpDebugBar) == 'undefined') {
|
||||
this.$dragCapture = $('<div />').addClass(csscls('drag-capture')).appendTo(this.$el);
|
||||
this.$resizehdle = $('<div />').addClass(csscls('resize-handle')).appendTo(this.$el);
|
||||
this.$header = $('<div />').addClass(csscls('header')).appendTo(this.$el);
|
||||
this.$headerBtn = $('<a />').addClass(csscls('restore-btn')).appendTo(this.$header);
|
||||
this.$headerBtn.click(function() {
|
||||
self.close();
|
||||
});
|
||||
this.$headerLeft = $('<div />').addClass(csscls('header-left')).appendTo(this.$header);
|
||||
this.$headerRight = $('<div />').addClass(csscls('header-right')).appendTo(this.$header);
|
||||
var $body = this.$body = $('<div />').addClass(csscls('body')).appendTo(this.$el);
|
||||
@@ -1203,7 +1207,9 @@ if (typeof(PhpDebugBar) == 'undefined') {
|
||||
var xhr = this;
|
||||
this.addEventListener("readystatechange", function() {
|
||||
var skipUrl = self.debugbar.openHandler ? self.debugbar.openHandler.get('url') : null;
|
||||
if (xhr.readyState == 4 && url.indexOf(skipUrl) !== 0) {
|
||||
var href = (typeof url === 'string') ? url : url.href;
|
||||
|
||||
if (xhr.readyState == 4 && href.indexOf(skipUrl) !== 0) {
|
||||
self.handle(xhr);
|
||||
}
|
||||
}, false);
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+61
-104
@@ -3,123 +3,80 @@
|
||||
github.com style (c) Vasily Polovnyov <vast@whiteants.net>
|
||||
|
||||
*/
|
||||
|
||||
div.phpdebugbar pre code.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 1em;
|
||||
}
|
||||
div.phpdebugbar code.hljs {
|
||||
padding: 3px 5px;
|
||||
}
|
||||
div.phpdebugbar .hljs {
|
||||
display: block; padding: 0.5em;
|
||||
color: #333;
|
||||
background: #f8f8f8
|
||||
background: #f3f3f3;
|
||||
color: #444;
|
||||
}
|
||||
|
||||
div.phpdebugbar .hljs-comment,
|
||||
div.phpdebugbar .hljs-template_comment,
|
||||
div.phpdebugbar .diff .hljs-header,
|
||||
div.phpdebugbar .hljs-javadoc {
|
||||
color: #998;
|
||||
font-style: italic
|
||||
div.phpdebugbar .hljs-comment {
|
||||
color: #697070;
|
||||
}
|
||||
|
||||
div.phpdebugbar .hljs-keyword,
|
||||
div.phpdebugbar .css .rule .hljs-keyword,
|
||||
div.phpdebugbar .hljs-winutils,
|
||||
div.phpdebugbar .javascript .hljs-title,
|
||||
div.phpdebugbar .nginx .hljs-title,
|
||||
div.phpdebugbar .hljs-subst,
|
||||
div.phpdebugbar .hljs-request,
|
||||
div.phpdebugbar .hljs-status {
|
||||
color: #333;
|
||||
font-weight: bold
|
||||
div.phpdebugbar .hljs-punctuation,
|
||||
div.phpdebugbar .hljs-tag {
|
||||
color: #444a;
|
||||
}
|
||||
|
||||
div.phpdebugbar .hljs-number,
|
||||
div.phpdebugbar .hljs-hexcolor,
|
||||
div.phpdebugbar .ruby .hljs-constant {
|
||||
color: #099;
|
||||
div.phpdebugbar .hljs-tag .hljs-attr,
|
||||
div.phpdebugbar .hljs-tag .hljs-name {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
div.phpdebugbar .hljs-string,
|
||||
div.phpdebugbar .hljs-tag .hljs-value,
|
||||
div.phpdebugbar .hljs-phpdoc,
|
||||
div.phpdebugbar .tex .hljs-formula {
|
||||
color: #d14
|
||||
}
|
||||
|
||||
div.phpdebugbar .hljs-title,
|
||||
div.phpdebugbar .hljs-id,
|
||||
div.phpdebugbar .coffeescript .hljs-params,
|
||||
div.phpdebugbar .scss .hljs-preprocessor {
|
||||
color: #900;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
div.phpdebugbar .javascript .hljs-title,
|
||||
div.phpdebugbar .lisp .hljs-title,
|
||||
div.phpdebugbar .clojure .hljs-title,
|
||||
div.phpdebugbar .hljs-subst {
|
||||
font-weight: normal
|
||||
}
|
||||
|
||||
div.phpdebugbar .hljs-class .hljs-title,
|
||||
div.phpdebugbar .haskell .hljs-type,
|
||||
div.phpdebugbar .vhdl .hljs-literal,
|
||||
div.phpdebugbar .tex .hljs-command {
|
||||
color: #458;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
div.phpdebugbar .hljs-tag,
|
||||
div.phpdebugbar .hljs-tag .hljs-title,
|
||||
div.phpdebugbar .hljs-rules .hljs-property,
|
||||
div.phpdebugbar .django .hljs-tag .hljs-keyword {
|
||||
color: #000080;
|
||||
font-weight: normal
|
||||
}
|
||||
|
||||
div.phpdebugbar .hljs-attribute,
|
||||
div.phpdebugbar .hljs-variable,
|
||||
div.phpdebugbar .lisp .hljs-body {
|
||||
color: #008080
|
||||
div.phpdebugbar .hljs-doctag,
|
||||
div.phpdebugbar .hljs-keyword,
|
||||
div.phpdebugbar .hljs-meta .hljs-keyword,
|
||||
div.phpdebugbar .hljs-name,
|
||||
div.phpdebugbar .hljs-selector-tag {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
div.phpdebugbar .hljs-regexp {
|
||||
color: #009926
|
||||
div.phpdebugbar .hljs-deletion,
|
||||
div.phpdebugbar .hljs-number,
|
||||
div.phpdebugbar .hljs-quote,
|
||||
div.phpdebugbar .hljs-selector-class,
|
||||
div.phpdebugbar .hljs-selector-id,
|
||||
div.phpdebugbar .hljs-string,
|
||||
div.phpdebugbar .hljs-template-tag,
|
||||
div.phpdebugbar .hljs-type {
|
||||
color: #800;
|
||||
}
|
||||
|
||||
div.phpdebugbar .hljs-section,
|
||||
div.phpdebugbar .hljs-title {
|
||||
color: #800;
|
||||
font-weight: 700;
|
||||
}
|
||||
div.phpdebugbar .hljs-link,
|
||||
div.phpdebugbar .hljs-operator,
|
||||
div.phpdebugbar .hljs-regexp,
|
||||
div.phpdebugbar .hljs-selector-attr,
|
||||
div.phpdebugbar .hljs-selector-pseudo,
|
||||
div.phpdebugbar .hljs-symbol,
|
||||
div.phpdebugbar .ruby .hljs-symbol .hljs-string,
|
||||
div.phpdebugbar .lisp .hljs-keyword,
|
||||
div.phpdebugbar .tex .hljs-special,
|
||||
div.phpdebugbar .hljs-prompt {
|
||||
color: #990073
|
||||
div.phpdebugbar .hljs-template-variable,
|
||||
div.phpdebugbar .hljs-variable {
|
||||
color: #ab5656;
|
||||
}
|
||||
|
||||
div.phpdebugbar .hljs-literal {
|
||||
color: #695;
|
||||
}
|
||||
div.phpdebugbar .hljs-addition,
|
||||
div.phpdebugbar .hljs-built_in,
|
||||
div.phpdebugbar .lisp .hljs-title,
|
||||
div.phpdebugbar .clojure .hljs-built_in {
|
||||
color: #0086b3
|
||||
div.phpdebugbar .hljs-bullet,
|
||||
div.phpdebugbar .hljs-code {
|
||||
color: #397300;
|
||||
}
|
||||
|
||||
div.phpdebugbar .hljs-preprocessor,
|
||||
div.phpdebugbar .hljs-pragma,
|
||||
div.phpdebugbar .hljs-pi,
|
||||
div.phpdebugbar .hljs-doctype,
|
||||
div.phpdebugbar .hljs-shebang,
|
||||
div.phpdebugbar .hljs-cdata {
|
||||
color: #999;
|
||||
font-weight: bold
|
||||
div.phpdebugbar .hljs-meta {
|
||||
color: #1f7199;
|
||||
}
|
||||
|
||||
div.phpdebugbar .hljs-deletion {
|
||||
background: #fdd
|
||||
div.phpdebugbar .hljs-meta .hljs-string {
|
||||
color: #38a;
|
||||
}
|
||||
|
||||
div.phpdebugbar .hljs-addition {
|
||||
background: #dfd
|
||||
div.phpdebugbar .hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
div.phpdebugbar .diff .hljs-change {
|
||||
background: #0086b3
|
||||
}
|
||||
|
||||
div.phpdebugbar .hljs-chunk {
|
||||
color: #aaa
|
||||
div.phpdebugbar .hljs-strong {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
+2
-2
File diff suppressed because one or more lines are too long
@@ -232,6 +232,10 @@ div.phpdebugbar-widgets-exceptions li.phpdebugbar-widgets-list-item {
|
||||
color: #555;
|
||||
}
|
||||
|
||||
div.phpdebugbar-widgets-exceptions li.phpdebugbar-widgets-list-item a.phpdebugbar-widgets-editor-link:hover {
|
||||
color: #aaaaaa;
|
||||
}
|
||||
|
||||
div.phpdebugbar-widgets-exceptions li.phpdebugbar-widgets-list-item span.phpdebugbar-widgets-type {
|
||||
display: block;
|
||||
position: absolute;
|
||||
@@ -259,3 +263,9 @@ div.phpdebugbar-widgets-exceptions a.phpdebugbar-widgets-editor-link:before {
|
||||
content: "\f08e";
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
ul.phpdebugbar-widgets-timeline table.phpdebugbar-widgets-params {
|
||||
display: table;
|
||||
border: 0;
|
||||
width: 99%;
|
||||
}
|
||||
|
||||
+27
-10
@@ -54,13 +54,13 @@ if (typeof(PhpDebugBar) == 'undefined') {
|
||||
return htmlize(code);
|
||||
}
|
||||
if (lang) {
|
||||
return hljs.highlight(lang, code).value;
|
||||
return hljs.highlight(code, {language: lang}).value;
|
||||
}
|
||||
return hljs.highlightAuto(code).value;
|
||||
}
|
||||
|
||||
if (typeof(hljs) === 'object') {
|
||||
code.each(function(i, e) { hljs.highlightBlock(e); });
|
||||
code.each(function(i, e) { hljs.highlightElement(e); });
|
||||
}
|
||||
return code;
|
||||
};
|
||||
@@ -263,7 +263,7 @@ if (typeof(PhpDebugBar) == 'undefined') {
|
||||
className: csscls('kvlist htmlvarlist'),
|
||||
|
||||
itemRenderer: function(dt, dd, key, value) {
|
||||
$('<span />').attr('title', key).text(key).appendTo(dt);
|
||||
$('<span />').attr('title', $('<i />').html(key || '').text()).html(key || '').appendTo(dt);
|
||||
dd.html(value);
|
||||
}
|
||||
|
||||
@@ -353,7 +353,7 @@ if (typeof(PhpDebugBar) == 'undefined') {
|
||||
this.$list.$el.appendTo(this.$el);
|
||||
this.$toolbar = $('<div><i class="phpdebugbar-fa phpdebugbar-fa-search"></i></div>').addClass(csscls('toolbar')).appendTo(this.$el);
|
||||
|
||||
$('<input type="text" />')
|
||||
$('<input type="text" aria-label="Search" placeholder="Search" />')
|
||||
.on('change', function() { self.set('search', this.value); })
|
||||
.appendTo(this.$toolbar);
|
||||
|
||||
@@ -438,6 +438,19 @@ if (typeof(PhpDebugBar) == 'undefined') {
|
||||
return (seconds).toFixed(2) + 's';
|
||||
};
|
||||
|
||||
// ported from php DataFormatter
|
||||
var formatBytes = function formatBytes(size) {
|
||||
if (size === 0 || size === null) {
|
||||
return '0B';
|
||||
}
|
||||
|
||||
var sign = size < 0 ? '-' : '',
|
||||
size = Math.abs(size),
|
||||
base = Math.log(size) / Math.log(1024),
|
||||
suffixes = ['B', 'KB', 'MB', 'GB', 'TB'];
|
||||
return sign + (Math.round(Math.pow(1024, base - Math.floor(base)) * 100) / 100) + suffixes[Math.floor(base)];
|
||||
}
|
||||
|
||||
this.$el.empty();
|
||||
if (data.measures) {
|
||||
var aggregate = {};
|
||||
@@ -446,10 +459,11 @@ if (typeof(PhpDebugBar) == 'undefined') {
|
||||
var measure = data.measures[i];
|
||||
|
||||
if(!aggregate[measure.label])
|
||||
aggregate[measure.label] = { count: 0, duration: 0 };
|
||||
aggregate[measure.label] = { count: 0, duration: 0, memory : 0 };
|
||||
|
||||
aggregate[measure.label]['count'] += 1;
|
||||
aggregate[measure.label]['duration'] += measure.duration;
|
||||
aggregate[measure.label]['memory'] += (measure.memory || 0);
|
||||
|
||||
var m = $('<div />').addClass(csscls('measure')),
|
||||
li = $('<li />'),
|
||||
@@ -460,7 +474,8 @@ if (typeof(PhpDebugBar) == 'undefined') {
|
||||
left: left + "%",
|
||||
width: width + "%"
|
||||
}));
|
||||
m.append($('<span />').addClass(csscls('label')).text(measure.label + " (" + measure.duration_str + ")"));
|
||||
m.append($('<span />').addClass(csscls('label'))
|
||||
.text(measure.label + " (" + measure.duration_str +(measure.memory ? '/' + measure.memory_str: '') + ")"));
|
||||
|
||||
if (measure.collector) {
|
||||
$('<span />').addClass(csscls('collector')).text(measure.collector).appendTo(m);
|
||||
@@ -499,15 +514,17 @@ if (typeof(PhpDebugBar) == 'undefined') {
|
||||
});
|
||||
|
||||
// build table and add
|
||||
var aggregateTable = $('<table style="display: table; border: 0; width: 99%"></table>').addClass(csscls('params'));
|
||||
var aggregateTable = $('<table></table>').addClass(csscls('params'));
|
||||
$.each(aggregate, function(i, aggregate) {
|
||||
width = Math.min((aggregate.data.duration * 100 / data.duration).toFixed(2), 100);
|
||||
|
||||
aggregateTable.append('<tr><td class="' + csscls('name') + '">' + aggregate.data.count + ' x ' + aggregate.label + ' (' + width + '%)</td><td class="' + csscls('value') + '">' +
|
||||
aggregateTable.append('<tr><td class="' + csscls('name') + '">' +
|
||||
aggregate.data.count + ' x ' + $('<i />').text(aggregate.label).html() + ' (' + width + '%)</td><td class="' + csscls('value') + '">' +
|
||||
'<div class="' + csscls('measure') +'">' +
|
||||
'<span class="' + csscls('value') + '" style="width:' + width + '%"></span>' +
|
||||
'<span class="' + csscls('label') + '">' + formatDuration(aggregate.data.duration) + '</span>' +
|
||||
'<span class="' + csscls('value') + '"></span>' +
|
||||
'<span class="' + csscls('label') + '">' + formatDuration(aggregate.data.duration) + (aggregate.data.memory ? '/' + formatBytes(aggregate.data.memory) : '') + '</span>' +
|
||||
'</div></td></tr>');
|
||||
aggregateTable.find('span.' + csscls('value') + ':last').css({width: width + "%" });
|
||||
});
|
||||
|
||||
this.$el.append('<li/>').find('li:last').append(aggregateTable);
|
||||
|
||||
@@ -11,6 +11,7 @@ div.phpdebugbar-widgets-templates div.phpdebugbar-widgets-status {
|
||||
div.phpdebugbar-widgets-templates span.phpdebugbar-widgets-render-time,
|
||||
div.phpdebugbar-widgets-templates span.phpdebugbar-widgets-memory,
|
||||
div.phpdebugbar-widgets-templates span.phpdebugbar-widgets-param-count,
|
||||
div.phpdebugbar-widgets-templates a.phpdebugbar-widgets-editor-link,
|
||||
div.phpdebugbar-widgets-templates span.phpdebugbar-widgets-type {
|
||||
float: right;
|
||||
margin-left: 8px;
|
||||
@@ -19,6 +20,7 @@ div.phpdebugbar-widgets-templates span.phpdebugbar-widgets-type {
|
||||
div.phpdebugbar-widgets-templates div.phpdebugbar-widgets-status span.phpdebugbar-widgets-render-time,
|
||||
div.phpdebugbar-widgets-templates div.phpdebugbar-widgets-status span.phpdebugbar-widgets-memory,
|
||||
div.phpdebugbar-widgets-templates div.phpdebugbar-widgets-status span.phpdebugbar-widgets-param-count,
|
||||
div.phpdebugbar-widgets-templates div.phpdebugbar-widgets-status a.phpdebugbar-widgets-editor-link,
|
||||
div.phpdebugbar-widgets-templates div.phpdebugbar-widgets-status span.phpdebugbar-widgets-type {
|
||||
color: #555;
|
||||
}
|
||||
@@ -26,12 +28,17 @@ div.phpdebugbar-widgets-templates span.phpdebugbar-widgets-render-time:before,
|
||||
div.phpdebugbar-widgets-templates span.phpdebugbar-widgets-memory:before,
|
||||
div.phpdebugbar-widgets-templates span.phpdebugbar-widgets-param-count:before,
|
||||
div.phpdebugbar-widgets-templates span.phpdebugbar-widgets-type:before,
|
||||
div.phpdebugbar-widgets-templates a.phpdebugbar-widgets-editor-link:before,
|
||||
div.phpdebugbar-widgets-templates a.phpdebugbar-widgets-editor-link:before
|
||||
{
|
||||
font-family: PhpDebugbarFontAwesome;
|
||||
margin-right: 4px;
|
||||
font-size: 12px;
|
||||
}
|
||||
div.phpdebugbar-widgets-templates a.phpdebugbar-widgets-editor-link:hover
|
||||
{
|
||||
color: #aaaaaa;
|
||||
}
|
||||
div.phpdebugbar-widgets-templates span.phpdebugbar-widgets-render-time:before {
|
||||
content: "\f017";
|
||||
}
|
||||
|
||||
+10
-2
@@ -20,11 +20,14 @@
|
||||
|
||||
if (typeof tpl.xdebug_link !== 'undefined' && tpl.xdebug_link !== null) {
|
||||
if (tpl.xdebug_link.ajax) {
|
||||
$('<a title="' + tpl.xdebug_link.url + '"></a>').on('click', function () {
|
||||
$('<a title="' + tpl.xdebug_link.url + '"></a>').on('click', function (event) {
|
||||
event.stopPropagation();
|
||||
$.ajax(tpl.xdebug_link.url);
|
||||
}).addClass(csscls('editor-link')).appendTo(li);
|
||||
} else {
|
||||
$('<a href="' + tpl.xdebug_link.url + '"></a>').addClass(csscls('editor-link')).appendTo(li);
|
||||
$('<a href="' + tpl.xdebug_link.url + '"></a>').on('click', function (event) {
|
||||
event.stopPropagation();
|
||||
}).addClass(csscls('editor-link')).appendTo(li);
|
||||
}
|
||||
}
|
||||
if (tpl.render_time_str) {
|
||||
@@ -39,6 +42,11 @@
|
||||
if (typeof(tpl.type) != 'undefined' && tpl.type) {
|
||||
$('<span title="Type" />').addClass(csscls('type')).text(tpl.type).appendTo(li);
|
||||
}
|
||||
if (typeof(tpl.editorLink) != 'undefined' && tpl.editorLink) {
|
||||
$('<a href="'+ tpl.editorLink +'" />').on('click', function (event) {
|
||||
event.stopPropagation();
|
||||
}).addClass(csscls('editor-link')).text('file').appendTo(li);
|
||||
}
|
||||
if (tpl.params && !$.isEmptyObject(tpl.params)) {
|
||||
var table = $('<table><tr><th colspan="2">Params</th></tr></table>').addClass(csscls('params')).appendTo(li);
|
||||
for (var key in tpl.params) {
|
||||
|
||||
@@ -62,7 +62,7 @@ class FileStorage implements StorageInterface
|
||||
|
||||
//Sort the files, newest first
|
||||
usort($files, function ($a, $b) {
|
||||
return $a['time'] < $b['time'];
|
||||
return $a['time'] <=> $b['time'];
|
||||
});
|
||||
|
||||
//Load the metadata and filter the results.
|
||||
|
||||
@@ -57,7 +57,7 @@ class RedisStorage implements StorageInterface
|
||||
{
|
||||
$results = [];
|
||||
$cursor = "0";
|
||||
$isPhpRedis = get_class($this->redis) === 'Redis';
|
||||
$isPhpRedis = get_class($this->redis) === 'Redis' || get_class($this->redis) === 'RedisCluster';
|
||||
|
||||
do {
|
||||
if ($isPhpRedis) {
|
||||
|
||||
Reference in New Issue
Block a user