Skip to content

Commit 6bf5331

Browse files
[VarDumper] Allow seamless use of Data clones
1 parent 06d6136 commit 6bf5331

11 files changed

+58
-128
lines changed

DataCollector/ConfigDataCollector.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\HttpKernel\Kernel;
1616
use Symfony\Component\HttpFoundation\Request;
1717
use Symfony\Component\HttpFoundation\Response;
18+
use Symfony\Component\VarDumper\Caster\LinkStub;
1819

1920
/**
2021
* ConfigDataCollector.
@@ -29,6 +30,7 @@ class ConfigDataCollector extends DataCollector
2930
private $kernel;
3031
private $name;
3132
private $version;
33+
private $hasVarDumper;
3234

3335
/**
3436
* Constructor.
@@ -40,6 +42,7 @@ public function __construct($name = null, $version = null)
4042
{
4143
$this->name = $name;
4244
$this->version = $version;
45+
$this->hasVarDumper = class_exists(LinkStub::class);
4346
}
4447

4548
/**
@@ -79,7 +82,7 @@ public function collect(Request $request, Response $response, \Exception $except
7982

8083
if (isset($this->kernel)) {
8184
foreach ($this->kernel->getBundles() as $name => $bundle) {
82-
$this->data['bundles'][$name] = $bundle->getPath();
85+
$this->data['bundles'][$name] = $this->hasVarDumper ? new LinkStub($bundle->getPath()) : $bundle->getPath();
8386
}
8487

8588
$this->data['symfony_state'] = $this->determineSymfonyState();
@@ -94,6 +97,7 @@ public function collect(Request $request, Response $response, \Exception $except
9497
$this->data['php_version'] = $matches[1];
9598
$this->data['php_version_extra'] = $matches[2];
9699
}
100+
$this->data = $this->cloneVar($this->data);
97101
}
98102

99103
public function getApplicationName()

DataCollector/DataCollector.php

Lines changed: 7 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,8 @@
1313

1414
use Symfony\Component\HttpKernel\DataCollector\Util\ValueExporter;
1515
use Symfony\Component\VarDumper\Caster\ClassStub;
16-
use Symfony\Component\VarDumper\Caster\LinkStub;
17-
use Symfony\Component\VarDumper\Caster\StubCaster;
1816
use Symfony\Component\VarDumper\Cloner\ClonerInterface;
1917
use Symfony\Component\VarDumper\Cloner\Data;
20-
use Symfony\Component\VarDumper\Cloner\Stub;
2118
use Symfony\Component\VarDumper\Cloner\VarCloner;
2219

2320
/**
@@ -40,7 +37,7 @@ abstract class DataCollector implements DataCollectorInterface, \Serializable
4037
/**
4138
* @var ClonerInterface
4239
*/
43-
private $cloner;
40+
private static $cloner;
4441

4542
private static $stubsCache = array();
4643

@@ -66,29 +63,24 @@ public function unserialize($data)
6663
*/
6764
protected function cloneVar($var)
6865
{
69-
if (null === $this->cloner) {
66+
if (null === self::$cloner) {
7067
if (class_exists(ClassStub::class)) {
71-
$this->cloner = new VarCloner();
72-
$this->cloner->setMaxItems(250);
73-
$this->cloner->addCasters(array(
74-
Stub::class => function (Stub $v, array $a, Stub $s, $isNested) {
75-
return $isNested ? $a : StubCaster::castStub($v, $a, $s, true);
76-
},
77-
));
68+
self::$cloner = new VarCloner();
69+
self::$cloner->setMaxItems(-1);
7870
} else {
7971
@trigger_error(sprintf('Using the %s() method without the VarDumper component is deprecated since version 3.2 and won\'t be supported in 4.0. Install symfony/var-dumper version 3.2 or above.', __METHOD__), E_USER_DEPRECATED);
80-
$this->cloner = false;
72+
self::$cloner = false;
8173
}
8274
}
83-
if (false === $this->cloner) {
75+
if (false === self::$cloner) {
8476
if (null === $this->valueExporter) {
8577
$this->valueExporter = new ValueExporter();
8678
}
8779

8880
return $this->valueExporter->exportValue($var);
8981
}
9082

91-
return $this->cloner->cloneVar($this->decorateVar($var));
83+
return self::$cloner->cloneVar($var);
9284
}
9385

9486
/**
@@ -110,36 +102,4 @@ protected function varToString($var)
110102

111103
return $this->valueExporter->exportValue($var);
112104
}
113-
114-
private function decorateVar($var)
115-
{
116-
if (is_array($var)) {
117-
if (isset($var[0], $var[1]) && is_callable($var)) {
118-
return ClassStub::wrapCallable($var);
119-
}
120-
foreach ($var as $k => $v) {
121-
if ($v !== $d = $this->decorateVar($v)) {
122-
$var[$k] = $d;
123-
}
124-
}
125-
126-
return $var;
127-
}
128-
if (is_string($var)) {
129-
if (isset(self::$stubsCache[$var])) {
130-
return self::$stubsCache[$var];
131-
}
132-
if (false !== strpos($var, '\\')) {
133-
$c = (false !== $i = strpos($var, '::')) ? substr($var, 0, $i) : $var;
134-
if (class_exists($c, false) || interface_exists($c, false) || trait_exists($c, false)) {
135-
return self::$stubsCache[$var] = new ClassStub($var);
136-
}
137-
}
138-
if (false !== strpos($var, DIRECTORY_SEPARATOR) && false === strpos($var, '://') && false === strpos($var, "\0") && @is_file($var)) {
139-
return self::$stubsCache[$var] = new LinkStub($var);
140-
}
141-
}
142-
143-
return $var;
144-
}
145105
}

DataCollector/EventDataCollector.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ public function lateCollect()
4747
$this->setCalledListeners($this->dispatcher->getCalledListeners());
4848
$this->setNotCalledListeners($this->dispatcher->getNotCalledListeners());
4949
}
50+
$this->data = $this->cloneVar($this->data);
5051
}
5152

5253
/**

DataCollector/LoggerDataCollector.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public function lateCollect()
4848
if (null !== $this->logger) {
4949
$this->data = $this->computeErrorsCount();
5050
$this->data['logs'] = $this->sanitizeLogs($this->logger->getLogs());
51+
$this->data = $this->cloneVar($this->data);
5152
}
5253
}
5354

@@ -100,7 +101,6 @@ private function sanitizeLogs($logs)
100101

101102
foreach ($logs as $log) {
102103
if (!$this->isSilencedOrDeprecationErrorLog($log)) {
103-
$log['context'] = $log['context'] ? $this->cloneVar($log['context']) : $log['context'];
104104
$sanitizedLogs[] = $log;
105105

106106
continue;
@@ -112,8 +112,6 @@ private function sanitizeLogs($logs)
112112
if (isset($sanitizedLogs[$errorId])) {
113113
++$sanitizedLogs[$errorId]['errorCount'];
114114
} else {
115-
$log['context'] = $log['context'] ? $this->cloneVar($log['context']) : $log['context'];
116-
117115
$log += array(
118116
'errorCount' => 1,
119117
'scream' => $exception instanceof SilencedErrorContext,

DataCollector/RequestDataCollector.php

Lines changed: 14 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,7 @@ public function collect(Request $request, Response $response, \Exception $except
116116
continue;
117117
}
118118
if ('request_headers' === $key || 'response_headers' === $key) {
119-
$value = array_map(function ($v) { return isset($v[0]) && !isset($v[1]) ? $v[0] : $v; }, $value);
120-
}
121-
if ('request_server' !== $key && 'request_cookies' !== $key) {
122-
$this->data[$key] = array_map(array($this, 'cloneVar'), $value);
119+
$this->data[$key] = array_map(function ($v) { return isset($v[0]) && !isset($v[1]) ? $v[0] : $v; }, $value);
123120
}
124121
}
125122

@@ -144,6 +141,8 @@ public function collect(Request $request, Response $response, \Exception $except
144141
));
145142
}
146143
}
144+
145+
$this->data = $this->cloneVar($this->data);
147146
}
148147

149148
public function getMethod()
@@ -158,52 +157,52 @@ public function getPathInfo()
158157

159158
public function getRequestRequest()
160159
{
161-
return new ParameterBag($this->data['request_request']);
160+
return new ParameterBag($this->data['request_request']->getValue());
162161
}
163162

164163
public function getRequestQuery()
165164
{
166-
return new ParameterBag($this->data['request_query']);
165+
return new ParameterBag($this->data['request_query']->getValue());
167166
}
168167

169168
public function getRequestHeaders()
170169
{
171-
return new ParameterBag($this->data['request_headers']);
170+
return new ParameterBag($this->data['request_headers']->getValue());
172171
}
173172

174173
public function getRequestServer($raw = false)
175174
{
176-
return new ParameterBag($raw ? $this->data['request_server'] : array_map(array($this, 'cloneVar'), $this->data['request_server']));
175+
return new ParameterBag($this->data['request_server']->getValue($raw));
177176
}
178177

179178
public function getRequestCookies($raw = false)
180179
{
181-
return new ParameterBag($raw ? $this->data['request_cookies'] : array_map(array($this, 'cloneVar'), $this->data['request_cookies']));
180+
return new ParameterBag($this->data['request_cookies']->getValue($raw));
182181
}
183182

184183
public function getRequestAttributes()
185184
{
186-
return new ParameterBag($this->data['request_attributes']);
185+
return new ParameterBag($this->data['request_attributes']->getValue());
187186
}
188187

189188
public function getResponseHeaders()
190189
{
191-
return new ParameterBag($this->data['response_headers']);
190+
return new ParameterBag($this->data['response_headers']->getValue());
192191
}
193192

194193
public function getSessionMetadata()
195194
{
196-
return $this->data['session_metadata'];
195+
return $this->data['session_metadata']->getValue();
197196
}
198197

199198
public function getSessionAttributes()
200199
{
201-
return $this->data['session_attributes'];
200+
return $this->data['session_attributes']->getValue();
202201
}
203202

204203
public function getFlashes()
205204
{
206-
return $this->data['flashes'];
205+
return $this->data['flashes']->getValue();
207206
}
208207

209208
public function getContent()
@@ -262,22 +261,7 @@ public function getIdentifier()
262261
*/
263262
public function getRouteParams()
264263
{
265-
if (!isset($this->data['request_attributes']['_route_params'])) {
266-
return array();
267-
}
268-
269-
$data = $this->data['request_attributes']['_route_params'];
270-
$rawData = $data->getRawData();
271-
if (!isset($rawData[1])) {
272-
return array();
273-
}
274-
275-
$params = array();
276-
foreach ($rawData[1] as $k => $v) {
277-
$params[$k] = $data->seek($k);
278-
}
279-
280-
return $params;
264+
return isset($this->data['request_attributes']['_route_params']) ? $this->data['request_attributes']['_route_params']->getValue() : array();
281265
}
282266

283267
/**

Tests/DataCollector/DataCollectorTest.php

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@
1515
use Symfony\Component\HttpFoundation\Request;
1616
use Symfony\Component\HttpFoundation\Response;
1717
use Symfony\Component\HttpKernel\Tests\Fixtures\DataCollector\CloneVarDataCollector;
18-
use Symfony\Component\VarDumper\Cloner\Stub;
1918
use Symfony\Component\VarDumper\Cloner\VarCloner;
20-
use Symfony\Component\VarDumper\Dumper\CliDumper;
2119

2220
class DataCollectorTest extends TestCase
2321
{
@@ -32,19 +30,9 @@ public function testCloneVarStringWithScheme()
3230

3331
public function testCloneVarExistingFilePath()
3432
{
35-
$c = new CloneVarDataCollector($filePath = tempnam(sys_get_temp_dir(), 'clone_var_data_collector_'));
33+
$c = new CloneVarDataCollector(array($filePath = tempnam(sys_get_temp_dir(), 'clone_var_data_collector_')));
3634
$c->collect(new Request(), new Response());
3735

38-
$data = $c->getData();
39-
$this->assertInstanceOf(Stub::class, $data->getRawData()[0][0]);
40-
$this->assertDumpEquals("\"$filePath\"", $data);
41-
}
42-
43-
private function assertDumpEquals($dump, $data, $message = '')
44-
{
45-
$dumper = new CliDumper();
46-
$dumper->setColors(false);
47-
48-
$this->assertSame(rtrim($dump), rtrim($dumper->dump($data, true)), $message);
36+
$this->assertSame($filePath, $c->getData()[0]);
4937
}
5038
}

Tests/DataCollector/LoggerDataCollectorTest.php

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,9 @@
1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\Debug\Exception\SilencedErrorContext;
1616
use Symfony\Component\HttpKernel\DataCollector\LoggerDataCollector;
17-
use Symfony\Component\VarDumper\Cloner\Data;
1817

1918
class LoggerDataCollectorTest extends TestCase
2019
{
21-
private static $data;
22-
2320
/**
2421
* @dataProvider getCollectTestData
2522
*/
@@ -29,31 +26,31 @@ public function testCollect($nb, $logs, $expectedLogs, $expectedDeprecationCount
2926
$logger->expects($this->once())->method('countErrors')->will($this->returnValue($nb));
3027
$logger->expects($this->exactly(2))->method('getLogs')->will($this->returnValue($logs));
3128

32-
// disable cloning the context, to ease fixtures creation.
33-
$c = $this->getMockBuilder(LoggerDataCollector::class)
34-
->setMethods(array('cloneVar'))
35-
->setConstructorArgs(array($logger))
36-
->getMock();
37-
$c->expects($this->any())->method('cloneVar')->willReturn(self::$data);
29+
$c = new LoggerDataCollector($logger);
3830
$c->lateCollect();
3931

4032
$this->assertEquals('logger', $c->getName());
4133
$this->assertEquals($nb, $c->countErrors());
42-
$this->assertEquals($expectedLogs, $c->getLogs());
34+
35+
$logs = array_map(function ($v) {
36+
if (isset($v['context']['exception'])) {
37+
$e = &$v['context']['exception'];
38+
$e = isset($e["\0*\0message"]) ? array($e["\0*\0message"], $e["\0*\0severity"]) : array($e["\0Symfony\Component\Debug\Exception\SilencedErrorContext\0severity"]);
39+
}
40+
41+
return $v;
42+
}, $c->getLogs()->getValue(true));
43+
$this->assertEquals($expectedLogs, $logs);
4344
$this->assertEquals($expectedDeprecationCount, $c->countDeprecations());
4445
$this->assertEquals($expectedScreamCount, $c->countScreams());
4546

4647
if (isset($expectedPriorities)) {
47-
$this->assertSame($expectedPriorities, $c->getPriorities());
48+
$this->assertSame($expectedPriorities, $c->getPriorities()->getValue(true));
4849
}
4950
}
5051

5152
public function getCollectTestData()
5253
{
53-
if (null === self::$data) {
54-
self::$data = new Data(array());
55-
}
56-
5754
yield 'simple log' => array(
5855
1,
5956
array(array('message' => 'foo', 'context' => array(), 'priority' => 100, 'priorityName' => 'DEBUG')),
@@ -65,7 +62,7 @@ public function getCollectTestData()
6562
yield 'log with a context' => array(
6663
1,
6764
array(array('message' => 'foo', 'context' => array('foo' => 'bar'), 'priority' => 100, 'priorityName' => 'DEBUG')),
68-
array(array('message' => 'foo', 'context' => self::$data, 'priority' => 100, 'priorityName' => 'DEBUG')),
65+
array(array('message' => 'foo', 'context' => array('foo' => 'bar'), 'priority' => 100, 'priorityName' => 'DEBUG')),
6966
0,
7067
0,
7168
);
@@ -82,9 +79,9 @@ public function getCollectTestData()
8279
array('message' => 'foo2', 'context' => array('exception' => new \ErrorException('deprecated', 0, E_USER_DEPRECATED)), 'priority' => 100, 'priorityName' => 'DEBUG'),
8380
),
8481
array(
85-
array('message' => 'foo3', 'context' => self::$data, 'priority' => 100, 'priorityName' => 'DEBUG'),
86-
array('message' => 'foo', 'context' => self::$data, 'priority' => 100, 'priorityName' => 'DEBUG', 'errorCount' => 1, 'scream' => false),
87-
array('message' => 'foo2', 'context' => self::$data, 'priority' => 100, 'priorityName' => 'DEBUG', 'errorCount' => 1, 'scream' => false),
82+
array('message' => 'foo3', 'context' => array('exception' => array('warning', E_USER_WARNING)), 'priority' => 100, 'priorityName' => 'DEBUG'),
83+
array('message' => 'foo', 'context' => array('exception' => array('deprecated', E_DEPRECATED)), 'priority' => 100, 'priorityName' => 'DEBUG', 'errorCount' => 1, 'scream' => false),
84+
array('message' => 'foo2', 'context' => array('exception' => array('deprecated', E_USER_DEPRECATED)), 'priority' => 100, 'priorityName' => 'DEBUG', 'errorCount' => 1, 'scream' => false),
8885
),
8986
2,
9087
0,
@@ -98,8 +95,8 @@ public function getCollectTestData()
9895
array('message' => 'foo3', 'context' => array('exception' => new SilencedErrorContext(E_USER_WARNING, __FILE__, __LINE__)), 'priority' => 100, 'priorityName' => 'DEBUG'),
9996
),
10097
array(
101-
array('message' => 'foo3', 'context' => self::$data, 'priority' => 100, 'priorityName' => 'DEBUG'),
102-
array('message' => 'foo3', 'context' => self::$data, 'priority' => 100, 'priorityName' => 'DEBUG', 'errorCount' => 1, 'scream' => true),
98+
array('message' => 'foo3', 'context' => array('exception' => array('warning', E_USER_WARNING)), 'priority' => 100, 'priorityName' => 'DEBUG'),
99+
array('message' => 'foo3', 'context' => array('exception' => array(E_USER_WARNING)), 'priority' => 100, 'priorityName' => 'DEBUG', 'errorCount' => 1, 'scream' => true),
103100
),
104101
0,
105102
1,

0 commit comments

Comments
 (0)