From f022f412b0f0f5c268eb97b75f8a0bf495c734ee Mon Sep 17 00:00:00 2001 From: WouterJ Date: Sun, 14 Aug 2016 15:24:11 +0200 Subject: [PATCH] Implemented VarDumper component in the Profiler --- .../Twig/WebProfilerExtension.php | 23 ++++++++++++++ .../DataCollector/DataCollector.php | 31 +++++++++++++++++++ .../DataCollector/RequestDataCollector.php | 6 ++-- .../RequestDataCollectorTest.php | 13 +++++--- 4 files changed, 65 insertions(+), 8 deletions(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Twig/WebProfilerExtension.php b/src/Symfony/Bundle/WebProfilerBundle/Twig/WebProfilerExtension.php index 13df2f443e9f0..08ada7e52e363 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Twig/WebProfilerExtension.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Twig/WebProfilerExtension.php @@ -12,6 +12,8 @@ namespace Symfony\Bundle\WebProfilerBundle\Twig; use Symfony\Component\HttpKernel\DataCollector\Util\ValueExporter; +use Symfony\Component\VarDumper\Cloner\Data; +use Symfony\Component\VarDumper\Dumper\HtmlDumper; /** * Twig extension for the profiler. @@ -24,6 +26,15 @@ class WebProfilerExtension extends \Twig_Extension * @var ValueExporter */ private $valueExporter; + /** + * @var HtmlDumper + */ + private $dumper; + + public function __construct(HtmlDumper $dumper = null) + { + $this->dumper = $dumper ?: new HtmlDumper(); + } /** * {@inheritdoc} @@ -37,6 +48,18 @@ public function getFunctions() public function dumpValue($value) { + if ($value instanceof Data) { + $dump = fopen('php://memory', 'r+b'); + $prevOutput = $this->dumper->setOutput($dump); + + $this->dumper->setOutput($prevOutput); + rewind($dump); + + return stream_get_contents($dump); + } + + @trigger_error('Dumping non-cloned data is deprecated since version 3.2 and will be removed in 4.0. Use DataCollector::cloneVar().', E_USER_DEPRECATED); + if (null === $this->valueExporter) { $this->valueExporter = new ValueExporter(); } diff --git a/src/Symfony/Component/HttpKernel/DataCollector/DataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/DataCollector.php index 5dca65298d059..7f2030df0427b 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/DataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/DataCollector.php @@ -12,6 +12,9 @@ namespace Symfony\Component\HttpKernel\DataCollector; use Symfony\Component\HttpKernel\DataCollector\Util\ValueExporter; +use Symfony\Component\VarDumper\Cloner\ClonerInterface; +use Symfony\Component\VarDumper\Cloner\Data; +use Symfony\Component\VarDumper\Cloner\VarCloner; /** * DataCollector. @@ -30,6 +33,11 @@ abstract class DataCollector implements DataCollectorInterface, \Serializable */ private $valueExporter; + /** + * @var ClonerInterface + */ + private $cloner; + public function serialize() { return serialize($this->data); @@ -40,15 +48,38 @@ public function unserialize($data) $this->data = unserialize($data); } + /** + * Converts the variable into a serializable Data instance. + * + * This array can be displayed in the template using + * the VarDumper component. + * + * @param mixed $var + * + * @return Data + */ + protected function cloneVar($var) + { + if (null === $this->cloner) { + $this->cloner = new VarCloner(); + } + + return $this->cloner->cloneVar($var); + } + /** * Converts a PHP variable to a string. * * @param mixed $var A PHP variable * * @return string The string representation of the variable + * + * @deprecated Deprecated since version 3.2, to be removed in 4.0. Use cloneVar() instead. */ protected function varToString($var) { + @trigger_error(__METHOD__.' is deprecated since version 3.2 and will be removed in 4.0. Use cloneVar() instead.', E_USER_DEPRECATED); + if (null === $this->valueExporter) { $this->valueExporter = new ValueExporter(); } diff --git a/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php index fd66b38cd2592..b511f13eaf54f 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php @@ -54,15 +54,15 @@ public function collect(Request $request, Response $response, \Exception $except $attributes = array(); foreach ($request->attributes->all() as $key => $value) { if ('_route' === $key && is_object($value)) { - $attributes[$key] = $this->varToString($value->getPath()); + $attributes[$key] = $this->cloneVar($value->getPath()); } elseif ('_route_params' === $key) { // we need to keep route params as an array (see getRouteParams()) foreach ($value as $k => $v) { - $value[$k] = $this->varToString($v); + $value[$k] = $this->cloneVar($v); } $attributes[$key] = $value; } else { - $attributes[$key] = $this->varToString($value); + $attributes[$key] = $this->cloneVar($value); } } diff --git a/src/Symfony/Component/HttpKernel/Tests/DataCollector/RequestDataCollectorTest.php b/src/Symfony/Component/HttpKernel/Tests/DataCollector/RequestDataCollectorTest.php index eef00d4a024dd..3fb7fe98e9a6c 100644 --- a/src/Symfony/Component/HttpKernel/Tests/DataCollector/RequestDataCollectorTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/DataCollector/RequestDataCollectorTest.php @@ -23,6 +23,8 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Cookie; use Symfony\Component\EventDispatcher\EventDispatcher; +use Symfony\Component\VarDumper\Cloner\Data; +use Symfony\Component\VarDumper\Cloner\VarCloner; class RequestDataCollectorTest extends \PHPUnit_Framework_TestCase { @@ -30,8 +32,9 @@ public function testCollect() { $c = new RequestDataCollector(); - $c->collect($this->createRequest(), $this->createResponse()); + $c->collect($request = $this->createRequest(), $this->createResponse()); + $cloner = new VarCloner(); $attributes = $c->getRequestAttributes(); $this->assertSame('request', $c->getName()); @@ -42,12 +45,12 @@ public function testCollect() $this->assertInstanceOf('Symfony\Component\HttpFoundation\ParameterBag', $c->getRequestRequest()); $this->assertInstanceOf('Symfony\Component\HttpFoundation\ParameterBag', $c->getRequestQuery()); $this->assertSame('html', $c->getFormat()); - $this->assertSame('foobar', $c->getRoute()); - $this->assertSame(array('name' => 'foo'), $c->getRouteParams()); + $this->assertEquals(new Data([['foobar']]), $c->getRoute()); + $this->assertEquals(array('name' => new Data([['foo']])), $c->getRouteParams()); $this->assertSame(array(), $c->getSessionAttributes()); $this->assertSame('en', $c->getLocale()); - $this->assertRegExp('/Resource\(stream#\d+\)/', $attributes->get('resource')); - $this->assertSame('Object(stdClass)', $attributes->get('object')); + $this->assertEquals($cloner->cloneVar($request->attributes->get('resource')), $attributes->get('resource')); + $this->assertEquals($cloner->cloneVar($request->attributes->get('object')), $attributes->get('object')); $this->assertInstanceOf('Symfony\Component\HttpFoundation\HeaderBag', $c->getResponseHeaders()); $this->assertSame('OK', $c->getStatusText());