8000 [DebugBundle] dump() + better Symfony glue · symfony/symfony@eb98c81 · GitHub
[go: up one dir, main page]

Skip to content

Commit eb98c81

Browse files
[DebugBundle] dump() + better Symfony glue
1 parent 9dea601 commit eb98c81

File tree

11 files changed

+599
-66
lines changed

11 files changed

+599
-66
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@
8787
],
8888
"files": [
8989
"src/Symfony/Component/Intl/Resources/stubs/functions.php",
90-
"src/Symfony/Bundle/DebugBundle/Resources/functions/debug.php"
90+
"src/Symfony/Bundle/DebugBundle/Resources/functions/dump.php"
9191
]
9292
},
9393
"minimum-stability": "dev",
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\Twig\Extension;
13+
14+
use Symfony\Bridge\Twig\TokenParser\DumpTokenParser;
15+
16+
/**
17+
* Provides integration of the dump() function with Twig.
18+
*
19+
* @author Nicolas Grekas <p@tchwork.com>
20+
*/
21+
class DumpExtension extends \Twig_Extension
22+
{
23+
public function getTokenParsers()
24+
{
25+
return array(new DumpTokenParser());
26+
}
27+
28+
public function getName()
29+
{
30+
return 'dump';
31+
}
32+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\Twig\Node;
13+
14+
/**
15+
* @author Julien Galenski <julien.galenski@gmail.com>
16+
*/
17+
class DumpNode extends \Twig_Node
18+
{
19+
public function __construct(\Twig_NodeInterface $values = null, $lineno, $tag = null)
20+
{
21+
parent::__construct(array('values' => $values), array(), $lineno, $tag);
22+
}
23+
24+
/**
25+
* {@inheritdoc}
26+
*/
27+
public function compile(\Twig_Compiler $compiler)
28+
{
29+
$compiler
30+
->write("if (\$this->env->isDebug()) {\n")
31+
->indent()
32+
;
33+
34+
$values = $this->getNode('values');
35+
36+
if (null === $values) {
37+
// remove embedded templates (macros) from the context
38+
$compiler
39+
->write("\$vars = array();\n")
40+
->write("foreach (\$context as \$key => \$value) {\n")
41+
->indent()
42+
->write("if (!\$value instanceof Twig_Template) {\n")
43+
->indent()
44+
->write("\$vars[\$key] = \$value;\n")
45+
->outdent()
46+
->write("}\n")
47+
->outdent()
48+
->write("}\n")
49+
->addDebugInfo($this)
50+
->write('\Symfony\Component\Debug\Debug::dump($vars);'."\n")
51+
;
52+
} elseif (1 === $values->count()) {
53+
$compiler
54+
->addDebugInfo($this)
55+
->write('\Symfony\Component\Debug\Debug::dump(')
56+
->subcompile($values->getNode(0))
57+
->raw(");\n")
58+
;
59+
} else {
60+
$compiler
61+
->addDebugInfo($this)
62+
->write('\Symfony\Component\Debug\Debug::dump(array(')
63+
->indent()
64+
;
65+
foreach ($values as $node) {
66+
$compiler->addIndentation();
67+
if ($node->hasAttribute('name')) {
68+
$compiler
69+
->string($node->getAttribute('name'))
70+
->raw(' => ')
71+
;
72+
}
73+
$compiler
74+
->subcompile($node)
75+
->raw(",\n")
76+
;
77+
}
78+
$compiler
79+
->outdent()
80+
->raw("));\n")
81+
;
82+
}
83+
84+
$compiler
85+
->outdent()
86+
->write("}\n")
87+
;
88+
}
89+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\Twig\TokenParser;
13+
14+
use Symfony\Bridge\Twig\Node\DumpNode;
15+
16+
/**
17+
* Token Parser for the 'dump' tag.
18+
*
19+
* Dump variables with:
20+
* <pre>
21+
* {% dump %}
22+
* {% dump foo %}
23+
* {% dump foo, bar %}
24+
* </pre>
25+
*
26+
* @author Julien Galenski <julien.galenski@gmail.com>
27+
*/
28+
class DumpTokenParser extends \Twig_TokenParser
29+
{
30+
/**
31+
* {@inheritdoc}
32+
*/
33+
public function parse(\Twig_Token $token)
34+
{
35+
$values = null;
36+
if (!$this->parser->getStream()->test(\Twig_Token::BLOCK_END_TYPE)) {
37+
$values = $this->parser->getExpressionParser()->parseMultitargetExpression();
38+
}
39+
$this->parser->getStream()->expect(\Twig_Token::BLOCK_END_TYPE);
40+
41+
return new DumpNode($values, $token->getLine(), $this->getTag());
42+
}
43+
44+
/**
45+
* {@inheritdoc}
46+
*/
47+
public function getTag()
48+
{
49+
return 'dump';
50+
}
51+
}

src/Symfony/Bridge/Twig/composer.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"symfony/security": "~2.4",
3131
"symfony/stopwatch": "~2.2",
3232
"symfony/console": "~2.2",
33+
"symfony/var-dumper": "~2.6",
3334
"symfony/expression-language": "~2.4"
3435
},
3536
"suggest": {
@@ -41,6 +42,7 @@
4142
"symfony/yaml": "For using the YamlExtension",
4243
"symfony/security": "For using the SecurityExtension",
4344
"symfony/stopwatch": "For using the StopwatchExtension",
45+
"symfony/var-dumper": "For using the DumpExtension",
4446
"symfony/expression-language": "For using the ExpressionExtension"
4547
},
4648
"autoload": {

src/Symfony/Component/Debug/Debug.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@
1111

1212
namespace Symfony\Component\Debug;
1313

14+
use Symfony\Component\VarDumper\Cloner\ExtCloner;
15+
use Symfony\Component\VarDumper\Cloner\PhpCloner;
16+
use Symfony\Component\VarDumper\Dumper\CliDumper;
17+
use Symfony\Component\VarDumper\Dumper\HtmlDumper;
18+
1419
/**
1520
* Registers all the debug tools.
1621
*
@@ -19,6 +24,7 @@
1924
class Debug
2025
{
2126
private static $enabled = false;
27+
private static $dumpHandler;
2228

2329
/**
2430
* Enables the debug tools.
@@ -59,4 +65,42 @@ public static function enable($errorReportingLevel = null, $displayErrors = true
5965

6066
DebugClassLoader::enable();
6167
}
68+
69+
public static function dump($var)
70+
{
71+
if (null === self::$dumpHandler) {
72+
$cloner = extension_loaded('symfony_debug') ? new ExtCloner() : new PhpCloner();
73+
$dumper = 'cli' === PHP_SAPI ? new CliDumper() : new HtmlDumper();
74+
self::$dumpHandler = function ($var) use ($cloner, $dumper) {
75+
$dumper->dump($cloner->cloneVar($var));
76+
};
77+
}
78+
79+
$h = self::$dumpHandler;
80+
81+
if (is_array($h)) {
82+
return $h[0]->{$h[1]}($var);
83+
}
84+
85+
return $h($var);
86+
}
87+
88+
public static function setDumpHandler($callable)
89+
{
90+
if (!is_callable($callable)) {
91+
throw new \InvalidArgumentException('Invalid PHP callback.');
92+
}
93+
94+
$prevHandler = self::$dumpHandler;
95+
96+
if (is_array($callable)) {
97+
if (!is_object($callable[0])) {
98+
self::$dumpHandler = $callable[0].'::'.$callable[1];
99+
}
100+
} else {
101+
self::$dumpHandler = $callable;
102+
}
103+
104+
return $prevHandler;
105+
}
62106
}

src/Symfony/Component/Debug/composer.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,12 @@
2020
"psr/log": "~1.0"
2121
},
2222
"require-dev": {
23+
"symfony/var-dumper": "~2.6",
2324
"symfony/http-kernel": "~2.1",
2425
"symfony/http-foundation": "~2.1"
2526
},
2627
"suggest": {
28+
"symfony/var-dumper": "For using Debug::dump()",
2729
"symfony/http-foundation": "",
2830
"symfony/http-kernel": ""
2931
},

0 commit comments

Comments
 (0)
0