1
0
mirror of https://github.com/maximebf/php-debugbar.git synced 2025-07-24 18:22:03 +02:00

Multiple counters on ObjectCountCollector, generic widget TableVariableListWidget (#764)

* Multiple counters on ObjectCountCollector, generic widget TableVariableListWidget

* Fix editor link css

* Fix descendent sort
This commit is contained in:
erikn69
2025-04-11 02:44:08 -05:00
committed by GitHub
parent f7b12b3cb3
commit af30cf6814
4 changed files with 133 additions and 16 deletions

View File

@@ -17,9 +17,11 @@ $debugbar['messages']->addMessage(array('toto' => array('titi', 'tata')));
$debugbar['messages']->addMessage('oups', 'error');
$classDemo = array('FirstClass', 'SecondClass', 'ThirdClass');
$classEvent = array('Retrieved', 'Saved', 'Deleted');
$debugbar->addCollector(new \DebugBar\DataCollector\ObjectCountCollector());
$debugbar['counter']->setKeyMap($classEvent);
for ($i = 0; $i <=20; $i++) {
$debugbar['counter']->countClass($classDemo[rand(0, 2)]);
$debugbar['counter']->countClass($classDemo[rand(0, 2)], 1, $classEvent[rand(0, 2)]);
}
$debugbar['time']->startMeasure('render');

View File

@@ -19,6 +19,8 @@ class ObjectCountCollector extends DataCollector implements DataCollectorInterfa
protected $classCount = 0;
/** @var array */
protected $classList = [];
/** @var array */
protected $keyMap = ['value' => 'Count'];
/**
* @param string $name
@@ -30,16 +32,29 @@ class ObjectCountCollector extends DataCollector implements DataCollectorInterfa
$this->icon = $icon;
}
/**
* Allows to define an array to map internal keys to human-readable labels
*/
public function setKeyMap(array $keyMap)
{
$this->keyMap = $keyMap;
}
/**
* @param string|mixed $class
* @param int $count
* @param string $key
*/
public function countClass($class, $count = 1) {
public function countClass($class, $count = 1, $key = 'value') {
if (! is_string($class)) {
$class = get_class($class);
}
$this->classList[$class] = ($this->classList[$class] ?? 0) + $count;
if (!isset($this->classList[$class])) {
$this->classList[$class] = [];
}
$this->classList[$class][$key] = ($this->classList[$class][$key] ?? 0) + $count;
$this->classCount += $count;
}
@@ -48,27 +63,28 @@ class ObjectCountCollector extends DataCollector implements DataCollectorInterfa
*/
public function collect()
{
arsort($this->classList, SORT_NUMERIC);
uasort($this->classList, fn($a, $b) => array_sum($b) <=> array_sum($a));
$collect = [
'data' => $this->classList,
'count' => $this->classCount,
'key_map' => $this->keyMap,
'is_counter' => true
];
if (! $this->getXdebugLinkTemplate()) {
return ['data' => $this->classList, 'count' => $this->classCount, 'is_counter' => true];
return $collect;
}
$data = [];
foreach ($this->classList as $class => $count) {
$reflector = class_exists($class) ? new \ReflectionClass($class) : null;
if ($reflector && $link = $this->getXdebugLink($reflector->getFileName())) {
$data[$class] = [
'value' => $count,
'xdebug_link' => $link,
];
} else {
$data[$class] = $count;
$collect['data'][$class]['xdebug_link'] = $link;
}
}
return ['data' => $data, 'count' => $this->classCount, 'is_counter' => true];
return $collect;
}
/**
@@ -89,8 +105,8 @@ class ObjectCountCollector extends DataCollector implements DataCollectorInterfa
return [
"$name" => [
'icon' => $this->icon,
'widget' => 'PhpDebugBar.Widgets.HtmlVariableListWidget',
'map' => "$name.data",
'widget' => 'PhpDebugBar.Widgets.TableVariableListWidget',
'map' => "$name",
'default' => '{}'
],
"$name:badge" => [

View File

@@ -32,7 +32,8 @@ pre.phpdebugbar-widgets-code-block {
}
.phpdebugbar-widgets-kvlist span.phpdebugbar-widgets-filename,
li.phpdebugbar-widgets-list-item span.phpdebugbar-widgets-filename {
li.phpdebugbar-widgets-list-item span.phpdebugbar-widgets-filename,
table.phpdebugbar-widgets-tablevar span.phpdebugbar-widgets-filename {
display: block;
font-style: italic;
float: right;
@@ -315,3 +316,32 @@ ul.phpdebugbar-widgets-timeline table.phpdebugbar-widgets-params {
width: 99%;
}
table.phpdebugbar-widgets-tablevar {
width: 100%;
table-layout: auto;
}
table.phpdebugbar-widgets-tablevar td:first-child {
width: 150px;
white-space: nowrap;
font-family: var(--debugbar-font-mono);
}
table.phpdebugbar-widgets-tablevar td.phpdebugbar-widgets-editor {
width: 5%;
white-space: nowrap;
text-align: right;
}
table.phpdebugbar-widgets-tablevar tr:first-child td{
font-weight: bold;
}
table.phpdebugbar-widgets-tablevar td {
padding: 2px 4px;
border-bottom: 1px solid var(--debugbar-border);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-weight: normal;
}

View File

@@ -283,6 +283,75 @@ if (typeof(PhpDebugBar) == 'undefined') {
// ------------------------------------------------------------------
/**
* Displays array element in a <table> list, columns keys map
* useful for showing a multiple values table
*
* Options:
* - data
* - key_map: list of keys to be displayed with an optional label
* example: {key1: label1, key2: label2} or [key1, key2]
*/
var TableVariableListWidget = PhpDebugBar.Widgets.TableVariableListWidget = PhpDebugBar.Widget.extend({
tagName: 'div',
className: csscls('tablevarlist'),
render: function() {
this.bindAttr('data', function(data) {
this.$el.empty();
if (!this.has('data')) {
return;
}
this.$table = $('<table />').addClass(csscls('tablevar')).appendTo(this.$el);
var $header = $('<tr />').append('<td />').appendTo(this.$table);
var key_map = data.key_map || {value: 'Value'};
$.each(key_map, function(key, label) {
$header.append($('<td />').text(label || key))
});
var self = this;
$.each(data.data, function(key, values) {
var $tr = $('<tr />').addClass(csscls('item')).appendTo(self.$table);
$('<td />').addClass(csscls('key')).text(key).appendTo($tr);
if (typeof values !== 'object' || values === null) {
$('<td />').addClass(csscls('value')).text(values ?? '').appendTo($tr);
return;
}
$.each(Array.isArray(key_map) ? key_map : Object.keys(key_map), function(i, key) {
$('<td />').addClass(csscls('value')).text(values[key] ?? '').appendTo($tr);
});
if (values.xdebug_link) {
var filename = $('<span />').addClass(csscls('filename'))
.text(values.xdebug_link.filename + ( values.xdebug_link.line ? "#" + values.xdebug_link.line : ''))
.appendTo($('<td />').addClass(csscls('editor')).appendTo($tr));
if (values.xdebug_link.ajax) {
$('<a title="' + values.xdebug_link.url + '"></a>').on('click', function () {
$.ajax(values.xdebug_link.url);
}).addClass(csscls('editor-link')).appendTo(filename);
} else {
$('<a href="' + values.xdebug_link.url + '"></a>').addClass(csscls('editor-link')).appendTo(filename);
}
if (!data.xdebug_link) {
data.xdebug_link = true;
$header.append($('<td />'));
}
}
});
});
}
});
// ------------------------------------------------------------------
/**
* Iframe widget
*