-
-
Notifications
You must be signed in to change notification settings - Fork 9.8k
VarDumper and DebugBundle #10640
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
VarDumper and DebugBundle #10640
Changes from 1 commit
eec5c92
4bf9300
07135a0
5b7ae28
3ddbf4b
c91bc83
da3e50a
0a92c08
c426d8b
0266072
1d5e3f4
fa81544
e6dde33
5eaa187
a69e962
297d373
9dea601
eb98c81
8d5d970
c8746a4
0d8a942
081363c
49f13c6
de05cd9
e4e00ef
5f59811
a8d81e4
d43ae82
0f8d30f
2e167ba
80fd736
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| <?php | ||
|
|
||
| /* | ||
| * This file is part of the Symfony package. | ||
| * | ||
| * (c) Fabien Potencier <[email protected]> | ||
| * | ||
| * For the full copyright and license information, please view the LICENSE | ||
| * file that was distributed with this source code. | ||
| */ | ||
|
|
||
| namespace Symfony\Bridge\Twig\Extension; | ||
|
|
||
| use Symfony\Bridge\Twig\TokenParser\DumpTokenParser; | ||
|
|
||
| /** | ||
| * Provides integration of the dump() function with Twig. | ||
| * | ||
| * @author Nicolas Grekas <[email protected]> | ||
| */ | ||
| class DumpExtension extends \Twig_Extension | ||
| { | ||
| public function getTokenParsers() | ||
| { | ||
| return array(new DumpTokenParser()); | ||
| } | ||
|
|
||
| public function getName() | ||
| { | ||
| return 'dump'; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| <?php | ||
|
|
||
| /* | ||
| * This file is part of the Symfony package. | ||
| * | ||
| * (c) Fabien Potencier <[email protected]> | ||
| * | ||
| * For the full copyright and license information, please view the LICENSE | ||
| * file that was distributed with this source code. | ||
| */ | ||
|
|
||
| namespace Symfony\Bridge\Twig\Node; | ||
|
|
||
| /** | ||
| * @author Julien Galenski <[email protected]> | ||
| */ | ||
| class DumpNode extends \Twig_Node | ||
| { | ||
| public function __construct(\Twig_NodeInterface $values = null, $lineno, $tag = null) | ||
| { | ||
| parent::__construct(array('values' => $values), array(), $lineno, $tag); | ||
| } | ||
|
|
||
| /** | ||
| * {@inheritdoc} | ||
| */ | ||
| public function compile(\Twig_Compiler $compiler) | ||
| { | ||
| $compiler | ||
| ->write("if (\$this->env->isDebug()) {\n") | ||
| ->indent() | ||
| ; | ||
|
|
||
| $values = $this->getNode('values'); | ||
|
|
||
| if (null === $values) { | ||
| // remove embedded templates (macros) from the context | ||
| $compiler | ||
| ->write("\$vars = array();\n") | ||
| ->write("foreach (\$context as \$key => \$value) {\n") | ||
| ->indent() | ||
| ->write("if (!\$value instanceof Twig_Template) {\n") | ||
| ->indent() | ||
| ->write("\$vars[\$key] = \$value;\n") | ||
| ->outdent() | ||
| ->write("}\n") | ||
| ->outdent() | ||
| ->write("}\n") | ||
| ->addDebugInfo($this) | ||
| ->write('\Symfony\Component\Debug\Debug::dump($vars);'."\n") | ||
| ; | ||
| } elseif (1 === $values->count()) { | ||
| $compiler | ||
| ->addDebugInfo($this) | ||
| ->write('\Symfony\Component\Debug\Debug::dump(') | ||
| ->subcompile($values->getNode(0)) | ||
| ->raw(");\n") | ||
| ; | ||
| } else { | ||
| $compiler | ||
| ->addDebugInfo($this) | ||
| ->write('\Symfony\Component\Debug\Debug::dump(array(') | ||
| ->indent() | ||
| ; | ||
| foreach ($values as $node) { | ||
| $compiler->addIndentation(); | ||
| if ($node->hasAttribute('name')) { | ||
| $compiler | ||
| ->string($node->getAttribute('name')) | ||
| ->raw(' => ') | ||
| ; | ||
| } | ||
| $compiler | ||
| ->subcompile($node) | ||
| ->raw(",\n") | ||
| ; | ||
| } | ||
| $compiler | ||
| ->outdent() | ||
| ->raw("));\n") | ||
| ; | ||
| } | ||
|
|
||
| $compiler | ||
| ->outdent() | ||
| ->write("}\n") | ||
| ; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| <?php | ||
|
|
||
| /* | ||
| * This file is part of the Symfony package. | ||
| * | ||
| * (c) Fabien Potencier <[email protected]> | ||
| * | ||
| * For the full copyright and license information, please view the LICENSE | ||
| * file that was distributed with this source code. | ||
| */ | ||
|
|
||
| namespace Symfony\Bridge\Twig\TokenParser; | ||
|
|
||
| use Symfony\Bridge\Twig\Node\DumpNode; | ||
|
|
||
| /** | ||
| * Token Parser for the 'dump' tag. | ||
| * | ||
| * Dump variables with: | ||
| * <pre> | ||
| * {% dump %} | ||
| * {% dump foo %} | ||
| * {% dump foo, bar %} | ||
| * </pre> | ||
| * | ||
| * @author Julien Galenski <[email protected]> | ||
| */ | ||
| class DumpTokenParser extends \Twig_TokenParser | ||
| { | ||
| /** | ||
| * {@inheritdoc} | ||
| */ | ||
| public function parse(\Twig_Token $token) | ||
| { | ||
| $values = null; | ||
| if (!$this->parser->getStream()->test(\Twig_Token::BLOCK_END_TYPE)) { | ||
| $values = $this->parser->getExpressionParser()->parseMultitargetExpression(); | ||
| } | ||
| $this->parser->getStream()->expect(\Twig_Token::BLOCK_END_TYPE); | ||
|
|
||
| return new DumpNode($values, $token->getLine(), $this->getTag()); | ||
| } | ||
|
|
||
| /** | ||
| * {@inheritdoc} | ||
| */ | ||
| public function getTag() | ||
| { | ||
| return 'dump'; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We already have a
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about replacing the existing dump function also? Using the tag would feed the profiler panel, and using the function would do the same as the current dump function: inline dump of vars, with a better output format.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sounds like a good idea. |
||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,11 @@ | |
|
|
||
| namespace Symfony\Component\Debug; | ||
|
|
||
| use Symfony\Component\VarDumper\Cloner\ExtCloner; | ||
| use Symfony\Component\VarDumper\Cloner\PhpCloner; | ||
| use Symfony\Component\VarDumper\Dumper\CliDumper; | ||
| use Symfony\Component\VarDumper\Dumper\HtmlDumper; | ||
|
|
||
| /** | ||
| * Registers all the debug tools. | ||
| * | ||
|
|
@@ -19,6 +24,7 @@ | |
| class Debug | ||
| { | ||
| private static $enabled = false; | ||
| private static $dumpHandler; | ||
|
|
||
| /** | ||
| * Enables the debug tools. | ||
|
|
@@ -59,4 +65,42 @@ public static function enable($errorReportingLevel = null, $displayErrors = true | |
|
|
||
| DebugClassLoader::enable(); | ||
| } | ||
|
|
||
| public static function dump($var) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why putting this command in the |
||
| { | ||
| if (null === self::$dumpHandler) { | ||
| $cloner = extension_loaded('symfony_debug') ? new ExtCloner() : new PhpCloner(); | ||
| $dumper = 'cli' === PHP_SAPI ? new CliDumper() : new HtmlDumper(); | ||
| self::$dumpHandler = function ($var) use ($cloner, $dumper) { | ||
| $dumper->dump($cloner->cloneVar($var)); | ||
| }; | ||
| } | ||
|
|
||
| $h = self::$dumpHandler; | ||
|
|
||
| if (is_array($h)) { | ||
| return $h[0]->{$h[1]}($var); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why not just using |
||
| } | ||
|
|
||
| return $h($var); | ||
| } | ||
|
|
||
| public static function setDumpHandler($callable) | ||
| { | ||
| if (!is_callable($callable)) { | ||
| throw new \InvalidArgumentException('Invalid PHP callback.'); | ||
| } | ||
|
|
||
| $prevHandler = self::$dumpHandler; | ||
|
|
||
| if (is_array($callable)) { | ||
| if (!is_object($callable[0])) { | ||
| self::$dumpHandler = $callable[0].'::'.$callable[1]; | ||
| } | ||
| } else { | ||
| self::$dumpHandler = $callable; | ||
| } | ||
|
|
||
| return $prevHandler; | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you should not name it
$vars. It could conflict with other stuff in the compiled template. Instead, you should generate a var name.In Twig master, there is
$compiler->getVarName()generating one, but it is not available in released versions. In stable version, only the Twig_Parser has the method. So a solution is to have theDumpTokenParsersetting a var name in theDumpNodewhen parsing it. This is exactly how the StopwatchNode is implemented currently