upgrade debugbar to avoid php 8.1 warnings

This commit is contained in:
Frédéric FRANCE
2023-03-14 23:58:03 +01:00
parent 68a2131ae6
commit 7df3b849d2
44 changed files with 3350 additions and 254 deletions

View File

@@ -57,9 +57,9 @@ class MonologCollector extends AbstractProcessingHandler implements DataCollecto
}
/**
* @param array $record
* @param array|\Monolog\LogRecord $record
*/
protected function write(array $record)
protected function write($record): void
{
$this->records[] = array(
'message' => $record['formatted'],

View File

@@ -0,0 +1,204 @@
<?php
declare(strict_types=1);
namespace DebugBar\Bridge;
use DebugBar\DataCollector\AssetProvider;
use DebugBar\DataCollector\DataCollector;
use DebugBar\DataCollector\Renderable;
use Twig\Environment;
use Twig\Loader\LoaderInterface;
use Twig\Profiler\Dumper\HtmlDumper;
use Twig\Profiler\Profile;
/**
* Collects data about rendered templates
*
* http://twig.sensiolabs.org/
*
* A \Twig\Profiler\Profile should be added to your \Twig\Environment
* The root-Twig\Profiler\Profile-object should then be injected into this collector
*
* you can optionally provide the \Twig\Environment or the \Twig\Loader to also create
* debug-links.
*
* @see \Twig\Extension\ProfilerExtension, \Twig\Profiler\Profile
*
* <code>
* $env = new \Twig\Environment($loader); // Or from a PSR11-container
* $profile = new \Twig\Profiler\Profile();
* $env->addExtension(new \Twig\Extension\ProfilerExtension($profile));
* $debugbar->addCollector(new ModernTwigProfileCollector($profile, $env));
* // or: $debugbar->addCollector(new ModernTwigProfileCollector($profile, $loader));
* </code>
*/
class NamespacedTwigProfileCollector extends DataCollector implements Renderable, AssetProvider
{
/**
* @var Profile
*/
private $profile;
/**
* @var LoaderInterface|Environment|null
*/
private $loader;
/**
* @var int
*/
private $templateCount;
/**
* @var int
*/
private $blockCount;
/**
* @var int
*/
private $macroCount;
/**
* @var array[] {
* @var string $name
* @var int $render_time
* @var string $render_time_str
* @var string $memory_str
* @var string $xdebug_link
* }
*/
private $templates;
/**
* TwigProfileCollector constructor.
*
* @param Profile $profile
* @param LoaderInterface|Environment $loaderOrEnv
*/
public function __construct(Profile $profile, $loaderOrEnv = null)
{
$this->profile = $profile;
if ($loaderOrEnv instanceof Environment) {
$loaderOrEnv = $loaderOrEnv->getLoader();
}
$this->loader = $loaderOrEnv;
}
/**
* Returns a hash where keys are control names and their values
* an array of options as defined in {@see \DebugBar\JavascriptRenderer::addControl()}
*
* @return array
*/
public function getWidgets()
{
return [
'twig' => [
'icon' => 'leaf',
'widget' => 'PhpDebugBar.Widgets.TemplatesWidget',
'map' => 'twig',
'default' => json_encode(['templates' => []]),
],
'twig:badge' => [
'map' => 'twig.badge',
'default' => 0,
],
];
}
/**
* @return array
*/
public function getAssets()
{
return [
'css' => 'widgets/templates/widget.css',
'js' => 'widgets/templates/widget.js',
];
}
/**
* Called by the DebugBar when data needs to be collected
*
* @return array Collected data
*/
public function collect()
{
$this->templateCount = $this->blockCount = $this->macroCount = 0;
$this->templates = [];
$this->computeData($this->profile);
return [
'nb_templates' => $this->templateCount,
'nb_blocks' => $this->blockCount,
'nb_macros' => $this->macroCount,
'templates' => $this->templates,
'accumulated_render_time' => $this->profile->getDuration(),
'accumulated_render_time_str' => $this->getDataFormatter()->formatDuration($this->profile->getDuration()),
'memory_usage_str' => $this->getDataFormatter()->formatBytes($this->profile->getMemoryUsage()),
'callgraph' => $this->getHtmlCallGraph(),
'badge' => implode(
'/',
[
$this->templateCount,
$this->blockCount,
$this->macroCount,
]
),
];
}
/**
* Returns the unique name of the collector
*
* @return string
*/
public function getName()
{
return 'twig';
}
public function getHtmlCallGraph()
{
$dumper = new HtmlDumper();
return $dumper->dump($this->profile);
}
/**
* Get an Xdebug Link to a file
*
* @return array {
* @var string url
* @var bool ajax
* }
*/
public function getXdebugLink($template, $line = 1)
{
if (is_null($this->loader)) {
return null;
}
$file = $this->loader->getSourceContext($template)->getPath();
return parent::getXdebugLink($file, $line);
}
private function computeData(Profile $profile)
{
$this->templateCount += ($profile->isTemplate() ? 1 : 0);
$this->blockCount += ($profile->isBlock() ? 1 : 0);
$this->macroCount += ($profile->isMacro() ? 1 : 0);
if ($profile->isTemplate()) {
$this->templates[] = [
'name' => $profile->getName(),
'render_time' => $profile->getDuration(),
'render_time_str' => $this->getDataFormatter()->formatDuration($profile->getDuration()),
'memory_str' => $this->getDataFormatter()->formatBytes($profile->getMemoryUsage()),
'xdebug_link' => $this->getXdebugLink($profile->getTemplate()),
];
}
foreach ($profile as $p) {
$this->computeData($p);
}
}
}

View File

@@ -34,7 +34,16 @@ class SwiftLogCollector extends MessagesCollector implements Swift_Plugins_Logge
public function dump()
{
return implode(PHP_EOL, $this->_log);
$dump = '';
foreach ($this->messages as $message) {
if (!$message['is_string']) {
continue;
}
$dump .= $message['message'] . PHP_EOL;
}
return $dump;
}
public function getName()

View File

@@ -57,4 +57,4 @@ class TimeableTwigExtensionProfiler extends \Twig_Extension_Profiler
$this->timeDataCollector->stopMeasure($profile->getName());
}
}
}
}

View File

@@ -24,6 +24,8 @@ use Twig_TokenStream;
/**
* Wrapped a Twig Environment to provide profiling features
*
* @deprecated
*/
class TraceableTwigEnvironment extends Twig_Environment
{

View File

@@ -15,6 +15,8 @@ use Twig_TemplateInterface;
/**
* Wraps a Twig_Template to add profiling features
*
* @deprecated
*/
class TraceableTwigTemplate extends Twig_Template implements Twig_TemplateInterface
{

View File

@@ -26,6 +26,8 @@ use DebugBar\DataCollector\Renderable;
* $env = new TraceableTwigEnvironment(new Twig_Environment($loader));
* $debugbar->addCollector(new TwigCollector($env));
* </code>
*
* @deprecated use DebugBar\Bridge\TwigProfileCollector instead
*/
class TwigCollector extends DataCollector implements Renderable, AssetProvider
{

View File

@@ -34,6 +34,8 @@ use DebugBar\DataCollector\Renderable;
* $debugbar->addCollector(new TwigProfileCollector($profile, $env));
* // or: $debugbar->addCollector(new TwigProfileCollector($profile, $loader));
* </code>
*
* @deprecated Use `\Debugbar\Bridge\NamespacedTwigProfileCollector` instead for Twig 2.x and 3.x
*/
class TwigProfileCollector extends DataCollector implements Renderable, AssetProvider
{

View File

@@ -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;
}
@@ -155,7 +155,7 @@ class AggregatedCollector implements DataCollectorInterface, ArrayAccess
* @param mixed $value
* @throws DebugBarException
*/
public function offsetSet($key, $value)
public function offsetSet($key, $value): void
{
throw new DebugBarException("AggregatedCollector[] is read-only");
}
@@ -164,6 +164,7 @@ class AggregatedCollector implements DataCollectorInterface, ArrayAccess
* @param mixed $key
* @return mixed
*/
#[\ReturnTypeWillChange]
public function offsetGet($key)
{
return $this->collectors[$key];
@@ -173,7 +174,7 @@ class AggregatedCollector implements DataCollectorInterface, ArrayAccess
* @param mixed $key
* @return bool
*/
public function offsetExists($key)
public function offsetExists($key): bool
{
return isset($this->collectors[$key]);
}
@@ -182,7 +183,7 @@ class AggregatedCollector implements DataCollectorInterface, ArrayAccess
* @param mixed $key
* @throws DebugBarException
*/
public function offsetUnset($key)
public function offsetUnset($key): void
{
throw new DebugBarException("AggregatedCollector[] is read-only");
}

View File

@@ -21,6 +21,10 @@ class ExceptionsCollector extends DataCollector implements Renderable
protected $exceptions = array();
protected $chainExceptions = false;
// The HTML var dumper requires debug bar users to support the new inline assets, which not all
// may support yet - so return false by default for now.
protected $useHtmlVarDumper = false;
/**
* Adds an exception to be profiled in the debug bar
*
@@ -65,6 +69,30 @@ class ExceptionsCollector extends DataCollector implements Renderable
return $this->exceptions;
}
/**
* Sets a flag indicating whether the Symfony HtmlDumper will be used to dump variables for
* rich variable rendering.
*
* @param bool $value
* @return $this
*/
public function useHtmlVarDumper($value = true)
{
$this->useHtmlVarDumper = $value;
return $this;
}
/**
* Indicates whether the Symfony HtmlDumper will be used to dump variables for rich variable
* rendering.
*
* @return mixed
*/
public function isHtmlVarDumperUsed()
{
return $this->useHtmlVarDumper;
}
public function collect()
{
return array(
@@ -102,6 +130,11 @@ class ExceptionsCollector extends DataCollector implements Renderable
$lines = array("Cannot open the file ($filePath) in which the exception occurred ");
}
$traceHtml = null;
if ($this->isHtmlVarDumperUsed()) {
$traceHtml = $this->getVarDumper()->renderVar($e->getTrace());
}
return array(
'type' => get_class($e),
'message' => $e->getMessage(),
@@ -109,6 +142,7 @@ class ExceptionsCollector extends DataCollector implements Renderable
'file' => $filePath,
'line' => $e->getLine(),
'stack_trace' => $e->getTraceAsString(),
'stack_trace_html' => $traceHtml,
'surrounding_lines' => $lines,
'xdebug_link' => $this->getXdebugLink($filePath, $e->getLine())
);

View File

@@ -67,7 +67,7 @@ class MemoryCollector extends DataCollector implements Renderable
$this->updatePeakUsage();
return array(
'peak_usage' => $this->peakUsage,
'peak_usage_str' => $this->getDataFormatter()->formatBytes($this->peakUsage)
'peak_usage_str' => $this->getDataFormatter()->formatBytes($this->peakUsage, 0)
);
}

View File

@@ -183,11 +183,37 @@ class MessagesCollector extends AbstractLogger implements DataCollectorInterface
* @param $message
* @param array $context
*/
public function log($level, $message, array $context = array())
public function log($level, $message, array $context = array()): void
{
// For string messages, interpolate the context following PSR-3
if (is_string($message)) {
$message = $this->interpolate($message, $context);
}
$this->addMessage($message, $level);
}
/**
* Interpolates context values into the message placeholders.
*
* @param $message
* @param array $context
* @return string
*/
function interpolate($message, array $context = array())
{
// build a replacement array with braces around the context keys
$replace = array();
foreach ($context as $key => $val) {
// check that the value can be cast to string
if (!is_array($val) && (!is_object($val) || method_exists($val, '__toString'))) {
$replace['{' . $key . '}'] = $val;
}
}
// interpolate replacement values into the message and return
return strtr($message, $replace);
}
/**
* Deletes all messages
*/

View File

@@ -21,10 +21,10 @@ class PDOCollector extends DataCollector implements Renderable, AssetProvider
protected $sqlQuotationChar = '<>';
/**
* @param TraceablePDO $pdo
* @param \PDO $pdo
* @param TimeDataCollector $timeCollector
*/
public function __construct(TraceablePDO $pdo = null, TimeDataCollector $timeCollector = null)
public function __construct(\PDO $pdo = null, TimeDataCollector $timeCollector = null)
{
$this->timeCollector = $timeCollector;
if ($pdo !== null) {
@@ -65,11 +65,14 @@ class PDOCollector extends DataCollector implements Renderable, AssetProvider
* @param TraceablePDO $pdo
* @param string $name Optional connection name
*/
public function addConnection(TraceablePDO $pdo, $name = null)
public function addConnection(\PDO $pdo, $name = null)
{
if ($name === null) {
$name = spl_object_hash($pdo);
}
if (!($pdo instanceof TraceablePDO)) {
$pdo = new TraceablePDO($pdo);
}
$this->connections[$name] = $pdo;
}

View File

@@ -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,36 +117,41 @@ 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=&gt;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=&gt;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
* @return TraceablePDOStatement|bool PDO::query returns a PDOStatement object, or FALSE on
* failure.
*/
public function query($statement)
/**
* 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());
}
@@ -158,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);
@@ -169,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();
}
@@ -182,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);
}
@@ -195,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);
@@ -226,7 +236,7 @@ class TraceablePDO extends PDO
*
* @param TracedStatement $stmt
*/
public function addExecutedStatement(TracedStatement $stmt)
public function addExecutedStatement(TracedStatement $stmt) : void
{
$this->executedStatements[] = $stmt;
}
@@ -234,9 +244,9 @@ 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(); });
}
@@ -246,7 +256,7 @@ 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(); });
}
@@ -256,7 +266,7 @@ 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; });
}
@@ -266,7 +276,7 @@ class TraceablePDO extends PDO
*
* @return TracedStatement[]
*/
public function getExecutedStatements()
public function getExecutedStatements() : array
{
return $this->executedStatements;
}
@@ -276,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(); });
}

View File

@@ -39,6 +39,7 @@ 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;
@@ -61,7 +62,7 @@ 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));
@@ -80,7 +81,7 @@ 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());
@@ -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;

View File

@@ -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() : '';
}

View File

@@ -29,7 +29,7 @@ class PhpInfoCollector extends DataCollector implements Renderable
public function collect()
{
return array(
'version' => PHP_VERSION,
'version' => implode('.', [PHP_MAJOR_VERSION, PHP_MINOR_VERSION, PHP_RELEASE_VERSION]),
'interface' => PHP_SAPI
);
}

View File

@@ -134,6 +134,7 @@ class TimeDataCollector extends DataCollector implements Renderable
* @param string $label
* @param \Closure $closure
* @param string|null $collector
* @return mixed
*/
public function measure($label, \Closure $closure, $collector = null)
{
@@ -142,6 +143,7 @@ class TimeDataCollector extends DataCollector implements Renderable
$result = $closure();
$params = is_array($result) ? $result : array();
$this->stopMeasure($name, $params);
return $result;
}
/**

View File

@@ -15,6 +15,10 @@ use Symfony\Component\VarDumper\Dumper\CliDumper;
class DataFormatter implements DataFormatterInterface
{
public $cloner;
public $dumper;
/**
* DataFormatter constructor.
*/
@@ -54,8 +58,10 @@ class DataFormatter implements DataFormatterInterface
{
if ($seconds < 0.001) {
return round($seconds * 1000000) . 'μs';
} elseif ($seconds < 1) {
} elseif ($seconds < 0.1) {
return round($seconds * 1000, 2) . 'ms';
} elseif ($seconds < 1) {
return round($seconds * 1000) . 'ms';
}
return round($seconds, 2) . 's';
}
@@ -76,6 +82,6 @@ class DataFormatter implements DataFormatterInterface
$base = log($size) / log(1024);
$suffixes = array('B', 'KB', 'MB', 'GB', 'TB');
return $sign . round(pow(1024, $base - floor($base)), $precision) . $suffixes[floor($base)];
return $sign . round(pow(1024, $base - floor($base)), $precision) . $suffixes[(int) floor($base)];
}
}

View File

@@ -18,7 +18,7 @@ interface DataFormatterInterface
/**
* Transforms a PHP variable to a string representation
*
* @param mixed $var
* @param mixed $data
* @return string
*/
function formatVar($data);

View File

@@ -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());
}
@@ -285,7 +283,7 @@ class DebugBarVarDumper implements AssetProvider
*/
public function getAssets() {
$dumper = $this->getDumper();
$dumper->setDumpHeader(null); // this will cause the default dump header to regenerate
$dumper->resetDumpHeader(); // this will cause the default dump header to regenerate
return array(
'inline_head' => array(
'html_var_dumper' => $dumper->getDumpHeaderByDebugBar(),

View File

@@ -10,6 +10,14 @@ use Symfony\Component\VarDumper\Dumper\HtmlDumper;
*/
class DebugBarHtmlDumper extends HtmlDumper
{
/**
* Resets an HTML header.
*/
public function resetDumpHeader()
{
$this->dumpHeader = null;
}
public function getDumpHeaderByDebugBar() {
// getDumpHeader is protected:
return str_replace('pre.sf-dump', '.phpdebugbar pre.sf-dump', $this->getDumpHeader());

View File

@@ -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);
}
}

View File

@@ -471,21 +471,25 @@ class DebugBar implements ArrayAccess
// --------------------------------------------
// ArrayAccess implementation
#[\ReturnTypeWillChange]
public function offsetSet($key, $value)
{
throw new DebugBarException("DebugBar[] is read-only");
}
#[\ReturnTypeWillChange]
public function offsetGet($key)
{
return $this->getCollector($key);
}
#[\ReturnTypeWillChange]
public function offsetExists($key)
{
return $this->hasCollector($key);
}
#[\ReturnTypeWillChange]
public function offsetUnset($key)
{
throw new DebugBarException("DebugBar[] is read-only");

View File

@@ -82,6 +82,8 @@ class JavascriptRenderer
protected $openHandlerUrl;
protected $cspNonce;
/**
* @param \DebugBar\DebugBar $debugBar
* @param string $baseUrl
@@ -183,6 +185,9 @@ class JavascriptRenderer
if (array_key_exists('open_handler_url', $options)) {
$this->setOpenHandlerUrl($options['open_handler_url']);
}
if (array_key_exists('csp_nonce', $options)) {
$this->setCspNonce($options['csp_nonce']);
}
}
/**
@@ -606,6 +611,28 @@ class JavascriptRenderer
return $this->openHandlerUrl;
}
/**
* Sets the CSP Nonce (or remove it by setting to null)
*
* @param string|null $nonce
* @return $this
*/
public function setCspNonce($nonce = null)
{
$this->cspNonce = $nonce;
return $this;
}
/**
* Get the CSP Nonce
*
* @return string|null
*/
public function getCspNonce()
{
return $this->cspNonce;
}
/**
* Add assets stored in files to render in the head
*
@@ -692,8 +719,8 @@ class JavascriptRenderer
}
foreach ($additionalAssets as $assets) {
$basePath = isset($assets['base_path']) ? $assets['base_path'] : null;
$baseUrl = isset($assets['base_url']) ? $assets['base_url'] : null;
$basePath = isset($assets['base_path']) ? $assets['base_path'] : '';
$baseUrl = isset($assets['base_url']) ? $assets['base_url'] : '';
$root = $this->getRelativeRoot($relativeTo,
$this->makeUriRelativeTo($basePath, $this->basePath),
$this->makeUriRelativeTo($baseUrl, $this->baseUrl));
@@ -719,7 +746,7 @@ class JavascriptRenderer
$cssFiles = array_unique($cssFiles);
$jsFiles = array_unique($jsFiles);
return $this->filterAssetArray(array($cssFiles, $jsFiles, $inlineCss, $inlineJs, $inlineHead), $type);
return $this->filterAssetArray(array($cssFiles, $jsFiles, $inlineCss, $inlineJs, $inlineHead), $type ?? '');
}
/**
@@ -762,7 +789,9 @@ class JavascriptRenderer
return $uris;
}
if ($uri && (substr($uri, 0, 1) === '/' || preg_match('/^([a-zA-Z]+:\/\/|[a-zA-Z]:\/|[a-zA-Z]:\\\)/', $uri))) {
$uri = $uri ?? '';
if (substr($uri, 0, 1) === '/' || preg_match('/^([a-zA-Z]+:\/\/|[a-zA-Z]:\/|[a-zA-Z]:\\\)/', $uri)) {
return $uri;
}
return rtrim($root, '/') . "/$uri";
@@ -775,10 +804,10 @@ class JavascriptRenderer
* @param string $type 'css', 'js', 'inline_css', 'inline_js', 'inline_head', or null for all
* @return array
*/
protected function filterAssetArray($array, $type = null)
protected function filterAssetArray($array, $type = '')
{
$types = array('css', 'js', 'inline_css', 'inline_js', 'inline_head');
$typeIndex = is_null($type) ? false : array_search(strtolower($type), $types);
$typeIndex = array_search(strtolower($type ?? ''), $types);
return $typeIndex !== false ? $array[$typeIndex] : $array;
}
@@ -905,6 +934,8 @@ class JavascriptRenderer
list($cssFiles, $jsFiles, $inlineCss, $inlineJs, $inlineHead) = $this->getAssets(null, self::RELATIVE_URL);
$html = '';
$nonce = $this->getNonceAttribute();
foreach ($cssFiles as $file) {
$html .= sprintf('<link rel="stylesheet" type="text/css" href="%s">' . "\n", $file);
}
@@ -918,7 +949,7 @@ class JavascriptRenderer
}
foreach ($inlineJs as $content) {
$html .= sprintf('<script type="text/javascript">%s</script>' . "\n", $content);
$html .= sprintf('<script type="text/javascript"%s>%s</script>' . "\n", $nonce, $content);
}
foreach ($inlineHead as $content) {
@@ -926,7 +957,7 @@ class JavascriptRenderer
}
if ($this->enableJqueryNoConflict && !$this->useRequireJs) {
$html .= '<script type="text/javascript">jQuery.noConflict(true);</script>' . "\n";
$html .= '<script type="text/javascript"' . $nonce . '>jQuery.noConflict(true);</script>' . "\n";
}
return $html;
@@ -1013,10 +1044,12 @@ class JavascriptRenderer
$suffix = !$initialize ? '(ajax)' : null;
$js .= $this->getAddDatasetCode($this->debugBar->getCurrentRequestId(), $this->debugBar->getData(), $suffix);
$nonce = $this->getNonceAttribute();
if ($this->useRequireJs){
return "<script type=\"text/javascript\">\nrequire(['debugbar'], function(PhpDebugBar){ $js });\n</script>\n";
return "<script type=\"text/javascript\"{$nonce}>\nrequire(['debugbar'], function(PhpDebugBar){ $js });\n</script>\n";
} else {
return "<script type=\"text/javascript\">\n$js\n</script>\n";
return "<script type=\"text/javascript\"{$nonce}>\n$js\n</script>\n";
}
}
@@ -1149,4 +1182,17 @@ class JavascriptRenderer
);
return $js;
}
/**
* If a nonce it set, create the correct attribute
* @return string
*/
protected function getNonceAttribute()
{
if ($nonce = $this->getCspNonce()) {
return ' nonce="' . $nonce .'"';
}
return '';
}
}

View File

@@ -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;
}

View File

@@ -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);
@@ -944,6 +948,7 @@ if (typeof(PhpDebugBar) == 'undefined') {
var self = this;
this.openHandler.load(id, function(data) {
self.addDataSet(data, id, suffix, show);
self.resize();
callback && callback(data);
});
},
@@ -1160,7 +1165,7 @@ if (typeof(PhpDebugBar) == 'undefined') {
var self = this;
var proxied = window.fetch;
if (proxied === undefined && proxied.polyfill !== undefined) {
if (proxied !== undefined && proxied.polyfill !== undefined) {
return;
}
@@ -1169,8 +1174,6 @@ if (typeof(PhpDebugBar) == 'undefined') {
promise.then(function (response) {
self.handle(response);
}, function (e) {
self.handle(response);
});
return promise;
@@ -1204,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);

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 434 KiB

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,125 @@
/*
github.com style (c) Vasily Polovnyov <vast@whiteants.net>
*/
div.phpdebugbar .hljs {
display: block; padding: 0.5em;
color: #333;
background: #f8f8f8
}
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-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-number,
div.phpdebugbar .hljs-hexcolor,
div.phpdebugbar .ruby .hljs-constant {
color: #099;
}
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-regexp {
color: #009926
}
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-built_in,
div.phpdebugbar .lisp .hljs-title,
div.phpdebugbar .clojure .hljs-built_in {
color: #0086b3
}
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-deletion {
background: #fdd
}
div.phpdebugbar .hljs-addition {
background: #dfd
}
div.phpdebugbar .diff .hljs-change {
background: #0086b3
}
div.phpdebugbar .hljs-chunk {
color: #aaa
}

File diff suppressed because one or more lines are too long

View File

@@ -216,11 +216,11 @@ if (typeof(PhpDebugBar) == 'undefined') {
});
// ------------------------------------------------------------------
/**
* An extension of KVListWidget where the data represents a list
* of variables
*
*
* Options:
* - data
*/
@@ -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);
@@ -468,7 +468,7 @@ if (typeof(PhpDebugBar) == 'undefined') {
m.appendTo(li);
this.$el.append(li);
if (measure.params && !$.isEmptyObject(measure.params)) {
var table = $('<table><tr><th colspan="2">Params</th></tr></table>').addClass(csscls('params')).appendTo(li);
for (var key in measure.params) {
@@ -518,7 +518,7 @@ if (typeof(PhpDebugBar) == 'undefined') {
});
// ------------------------------------------------------------------
/**
* Widget for the displaying exceptions
*
@@ -550,20 +550,26 @@ if (typeof(PhpDebugBar) == 'undefined') {
}
if (e.surrounding_lines) {
var pre = createCodeBlock(e.surrounding_lines.join(""), 'php').addClass(csscls('file')).appendTo(li);
li.click(function() {
if (pre.is(':visible')) {
pre.hide();
} else {
pre.show();
}
});
if (!e.stack_trace_html) {
// This click event makes the var-dumper hard to use.
li.click(function () {
if (pre.is(':visible')) {
pre.hide();
} else {
pre.show();
}
});
}
}
if (e.stack_trace) {
e.stack_trace.split("\n").forEach(function(trace) {
var $traceLine = $('<div />');
$('<span />').addClass(csscls('filename')).text(trace).appendTo($traceLine);
$traceLine.appendTo(li);
});
if (e.stack_trace_html) {
var $trace = $('<span />').addClass(csscls('filename')).html(e.stack_trace_html);
$trace.appendTo(li);
} else if (e.stack_trace) {
e.stack_trace.split("\n").forEach(function (trace) {
var $traceLine = $('<div />');
$('<span />').addClass(csscls('filename')).text(trace).appendTo($traceLine);
$traceLine.appendTo(li);
});
}
}});
this.$list.$el.appendTo(this.$el);
@@ -578,6 +584,6 @@ if (typeof(PhpDebugBar) == 'undefined') {
}
});
})(PhpDebugBar.$);

View File

@@ -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: #ffffff;
}
div.phpdebugbar-widgets-templates span.phpdebugbar-widgets-render-time:before {
content: "\f017";
}

View File

@@ -39,6 +39,9 @@
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 +'" />').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) {

View File

@@ -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.

View File

@@ -15,13 +15,15 @@ namespace DebugBar\Storage;
*/
class RedisStorage implements StorageInterface
{
/** @var \Predis\Client|\Redis */
protected $redis;
/** @var string */
protected $hash;
/**
* @param \Predis\Client $redis Redis Client
* @param string $hash
* @param \Predis\Client|\Redis $redis Redis Client
* @param string $hash
*/
public function __construct($redis, $hash = 'phpdebugbar')
{
@@ -34,9 +36,9 @@ class RedisStorage implements StorageInterface
*/
public function save($id, $data)
{
$this->redis->hset("$this->hash:meta", $id, serialize($data['__meta']));
$this->redis->hSet("$this->hash:meta", $id, serialize($data['__meta']));
unset($data['__meta']);
$this->redis->hset("$this->hash:data", $id, serialize($data));
$this->redis->hSet("$this->hash:data", $id, serialize($data));
}
/**
@@ -44,19 +46,25 @@ class RedisStorage implements StorageInterface
*/
public function get($id)
{
return array_merge(unserialize($this->redis->hget("$this->hash:data", $id)),
array('__meta' => unserialize($this->redis->hget("$this->hash:meta", $id))));
return array_merge(unserialize($this->redis->hGet("$this->hash:data", $id)),
array('__meta' => unserialize($this->redis->hGet("$this->hash:meta", $id))));
}
/**
* {@inheritdoc}
*/
public function find(array $filters = array(), $max = 20, $offset = 0)
public function find(array $filters = [], $max = 20, $offset = 0)
{
$results = array();
$results = [];
$cursor = "0";
$isPhpRedis = get_class($this->redis) === 'Redis';
do {
list($cursor, $data) = $this->redis->hscan("$this->hash:meta", $cursor);
if ($isPhpRedis) {
$data = $this->redis->hScan("$this->hash:meta", $cursor);
} else {
[$cursor, $data] = $this->redis->hScan("$this->hash:meta", $cursor);
}
foreach ($data as $meta) {
if ($meta = unserialize($meta)) {
@@ -66,11 +74,11 @@ class RedisStorage implements StorageInterface
}
}
} while($cursor);
usort($results, function ($a, $b) {
return $a['utime'] < $b['utime'];
usort($results, static function ($a, $b) {
return $b['utime'] <=> $a['utime'];
});
return array_slice($results, $offset, $max);
}
@@ -92,6 +100,7 @@ class RedisStorage implements StorageInterface
*/
public function clear()
{
$this->redis->del($this->hash);
$this->redis->del("$this->hash:data");
$this->redis->del("$this->hash:meta");
}
}