From 35fa8abe90d9af7adb33eb8fa80f8f2904df68c2 Mon Sep 17 00:00:00 2001 From: James Johnston Date: Fri, 21 Jul 2017 04:35:58 -0700 Subject: [PATCH] Use new HtmlVariableListWidget with collectors (#346) Introduce a new HtmlVariableListWidget that is similar to VariableListWidget but for variables with HTML contents. Update the collectors that use the existing VariableListWidget to use DebugBarVarDumper to dump the variables using the VarDumper HtmlDumper. Because many debug bar users may not yet support inline static assets, default to use the old VariableListWidget for now. Updated collectors: * ConfigCollector * RequestDataCollector --- docs/base_collectors.md | 18 +++++-- .../DataCollector/ConfigCollector.php | 46 +++++++++++++++-- .../DataCollector/RequestDataCollector.php | 49 +++++++++++++++++-- src/DebugBar/Resources/widgets.css | 6 ++- src/DebugBar/Resources/widgets.js | 23 ++++++++- .../DataCollector/ConfigCollectorTest.php | 28 +++++++++++ 6 files changed, 158 insertions(+), 12 deletions(-) diff --git a/docs/base_collectors.md b/docs/base_collectors.md index 012d036..cf096f5 100644 --- a/docs/base_collectors.md +++ b/docs/base_collectors.md @@ -90,16 +90,26 @@ If you want to see your PDO requests in the TimeDataCollector, you must add the ## RequestData -Collects the data of PHP's global variables +Collects the data of PHP's global variables. You can call the `useHtmlVarDumper()` function to use +VarDumper's interactive HTML dumper for rendering the variables. If you do that, you must properly +render [inline assets](rendering.html#assets) when rendering the debug bar in addition to the normal +js/css static assets. - $debugbar->addCollector(new DebugBar\DataCollector\RequestDataCollector()); + $requestDataCollector = new DebugBar\DataCollector\RequestDataCollector(); + $requestDataCollector->useHtmlVarDumper(); + $debugbar->addCollector($requestDataCollector); ## Config -Used to display any key/value pairs array +Used to display any key/value pairs array. You can call the `useHtmlVarDumper()` function to use +VarDumper's interactive HTML dumper for rendering the variables. If you do that, you must properly +render [inline assets](rendering.html#assets) when rendering the debug bar in addition to the normal +js/css static assets. $data = array('foo' => 'bar'); - $debugbar->addCollector(new DebugBar\DataCollector\ConfigCollector($data)); + $configCollector = new DebugBar\DataCollector\ConfigCollector($data); + $configCollector->useHtmlVarDumper(); + $debugbar->addCollector($configCollector); You can provide a different name for this collector in the second argument of the constructor. diff --git a/src/DebugBar/DataCollector/ConfigCollector.php b/src/DebugBar/DataCollector/ConfigCollector.php index 692b547..75817ba 100644 --- a/src/DebugBar/DataCollector/ConfigCollector.php +++ b/src/DebugBar/DataCollector/ConfigCollector.php @@ -13,12 +13,40 @@ namespace DebugBar\DataCollector; /** * Collects array data */ -class ConfigCollector extends DataCollector implements Renderable +class ConfigCollector extends DataCollector implements Renderable, AssetProvider { protected $name; protected $data; + // 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; + + /** + * 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; + } + /** * @param array $data * @param string $name @@ -46,7 +74,9 @@ class ConfigCollector extends DataCollector implements Renderable { $data = array(); foreach ($this->data as $k => $v) { - if (!is_string($v)) { + if ($this->isHtmlVarDumperUsed()) { + $v = $this->getVarDumper()->renderVar($v); + } else if (!is_string($v)) { $v = $this->getDataFormatter()->formatVar($v); } $data[$k] = $v; @@ -62,16 +92,26 @@ class ConfigCollector extends DataCollector implements Renderable return $this->name; } + /** + * @return array + */ + public function getAssets() { + return $this->isHtmlVarDumperUsed() ? $this->getVarDumper()->getAssets() : array(); + } + /** * @return array */ public function getWidgets() { $name = $this->getName(); + $widget = $this->isHtmlVarDumperUsed() + ? "PhpDebugBar.Widgets.HtmlVariableListWidget" + : "PhpDebugBar.Widgets.VariableListWidget"; return array( "$name" => array( "icon" => "gear", - "widget" => "PhpDebugBar.Widgets.VariableListWidget", + "widget" => $widget, "map" => "$name", "default" => "{}" ) diff --git a/src/DebugBar/DataCollector/RequestDataCollector.php b/src/DebugBar/DataCollector/RequestDataCollector.php index 6306e48..6bd781e 100644 --- a/src/DebugBar/DataCollector/RequestDataCollector.php +++ b/src/DebugBar/DataCollector/RequestDataCollector.php @@ -13,8 +13,36 @@ namespace DebugBar\DataCollector; /** * Collects info about the current request */ -class RequestDataCollector extends DataCollector implements Renderable +class RequestDataCollector extends DataCollector implements Renderable, AssetProvider { + // 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; + + /** + * 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; + } + /** * @return array */ @@ -25,7 +53,12 @@ class RequestDataCollector extends DataCollector implements Renderable foreach ($vars as $var) { if (isset($GLOBALS[$var])) { - $data["$" . $var] = $this->getDataFormatter()->formatVar($GLOBALS[$var]); + $key = "$" . $var; + if ($this->isHtmlVarDumperUsed()) { + $data[$key] = $this->getVarDumper()->renderVar($GLOBALS[$var]); + } else { + $data[$key] = $this->getDataFormatter()->formatVar($GLOBALS[$var]); + } } } @@ -40,15 +73,25 @@ class RequestDataCollector extends DataCollector implements Renderable return 'request'; } + /** + * @return array + */ + public function getAssets() { + return $this->isHtmlVarDumperUsed() ? $this->getVarDumper()->getAssets() : array(); + } + /** * @return array */ public function getWidgets() { + $widget = $this->isHtmlVarDumperUsed() + ? "PhpDebugBar.Widgets.HtmlVariableListWidget" + : "PhpDebugBar.Widgets.VariableListWidget"; return array( "request" => array( "icon" => "tags", - "widget" => "PhpDebugBar.Widgets.VariableListWidget", + "widget" => $widget, "map" => "request", "default" => "{}" ) diff --git a/src/DebugBar/Resources/widgets.css b/src/DebugBar/Resources/widgets.css index d91a399..a11b733 100644 --- a/src/DebugBar/Resources/widgets.css +++ b/src/DebugBar/Resources/widgets.css @@ -149,9 +149,13 @@ dl.phpdebugbar-widgets-kvlist { /* -------------------------------------- */ -dl.phpdebugbar-widgets-varlist { +dl.phpdebugbar-widgets-varlist, +dl.phpdebugbar-widgets-htmlvarlist { font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace; } + dl.phpdebugbar-widgets-htmlvarlist dd { + cursor: initial; + } /* -------------------------------------- */ diff --git a/src/DebugBar/Resources/widgets.js b/src/DebugBar/Resources/widgets.js index 8077782..ca34516 100644 --- a/src/DebugBar/Resources/widgets.js +++ b/src/DebugBar/Resources/widgets.js @@ -249,7 +249,28 @@ if (typeof(PhpDebugBar) == 'undefined') { }); // ------------------------------------------------------------------ - + + /** + * An extension of KVListWidget where the data represents a list + * of variables whose contents are HTML; this is useful for showing + * variable output from VarDumper's HtmlDumper. + * + * Options: + * - data + */ + var HtmlVariableListWidget = PhpDebugBar.Widgets.HtmlVariableListWidget = KVListWidget.extend({ + + className: csscls('kvlist htmlvarlist'), + + itemRenderer: function(dt, dd, key, value) { + $('').attr('title', key).text(key).appendTo(dt); + dd.html(value); + } + + }); + + // ------------------------------------------------------------------ + /** * Iframe widget * diff --git a/tests/DebugBar/Tests/DataCollector/ConfigCollectorTest.php b/tests/DebugBar/Tests/DataCollector/ConfigCollectorTest.php index ce97d8d..b1142d9 100644 --- a/tests/DebugBar/Tests/DataCollector/ConfigCollectorTest.php +++ b/tests/DebugBar/Tests/DataCollector/ConfigCollectorTest.php @@ -25,4 +25,32 @@ class ConfigCollectorTest extends DebugBarTestCase $this->assertEquals('foo', $c->getName()); $this->assertArrayHasKey('foo', $c->getWidgets()); } + + public function testAssets() + { + $c = new ConfigCollector(); + $this->assertEmpty($c->getAssets()); + + $c->useHtmlVarDumper(); + $this->assertNotEmpty($c->getAssets()); + } + + public function testHtmlRendering() + { + $c = new ConfigCollector(array('k' => array('one', 'two'))); + + $this->assertFalse($c->isHtmlVarDumperUsed()); + $data = $c->collect(); + $this->assertEquals(array('k'), array_keys($data)); + $this->assertContains('one', $data['k']); + $this->assertContains('two', $data['k']); + $this->assertNotContains('span', $data['k']); + + $c->useHtmlVarDumper(); + $data = $c->collect(); + $this->assertEquals(array('k'), array_keys($data)); + $this->assertContains('one', $data['k']); + $this->assertContains('two', $data['k']); + $this->assertContains('span', $data['k']); + } }