Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 6f08630

Browse filesBrowse files
committed
bug #30660 [Bridge][Twig] DebugCommand - fix escaping and filter (SpacePossum)
This PR was squashed before being merged into the 3.4 branch (closes #30660). Discussion ---------- [Bridge][Twig] DebugCommand - fix escaping and filter | Q | A | ------------- | --- | Branch? | 3.4 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | License | MIT The PR fixes: - output escaping was not done for decorated consoles - filter was not applied when using format json + added some tests for paths currently not tested Commits ------- 7bdb066 [Bridge][Twig] DebugCommand - fix escaping and filter
2 parents e3bbf8d + 7bdb066 commit 6f08630
Copy full SHA for 6f08630

File tree

Expand file treeCollapse file tree

3 files changed

+69
-11
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+69
-11
lines changed

‎src/Symfony/Bridge/Twig/Command/DebugCommand.php

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/Twig/Command/DebugCommand.php
+19-9Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Bridge\Twig\Command;
1313

1414
use Symfony\Component\Console\Command\Command;
15+
use Symfony\Component\Console\Formatter\OutputFormatter;
1516
use Symfony\Component\Console\Input\InputArgument;
1617
use Symfony\Component\Console\Input\InputInterface;
1718
use Symfony\Component\Console\Input\InputOption;
@@ -100,6 +101,7 @@ protected function configure()
100101
protected function execute(InputInterface $input, OutputInterface $output)
101102
{
102103
$io = new SymfonyStyle($input, $output);
104+
$decorated = $io->isDecorated();
103105

104106
// BC to be removed in 4.0
105107
if (__CLASS__ !== \get_class($this)) {
@@ -114,29 +116,35 @@ protected function execute(InputInterface $input, OutputInterface $output)
114116
throw new \RuntimeException('The Twig environment needs to be set.');
115117
}
116118

119+
$filter = $input->getArgument('filter');
117120
$types = ['functions', 'filters', 'tests', 'globals'];
118121

119122
if ('json' === $input->getOption('format')) {
120123
$data = [];
121124
foreach ($types as $type) {
122125
foreach ($this->twig->{'get'.ucfirst($type)}() as $name => $entity) {
123-
$data[$type][$name] = $this->getMetadata($type, $entity);
126+
if (!$filter || false !== strpos($name, $filter)) {
127+
$data[$type][$name] = $this->getMetadata($type, $entity);
128+
}
124129
}
125130
}
126-
$data['tests'] = array_keys($data['tests']);
131+
132+
if (isset($data['tests'])) {
133+
$data['tests'] = array_keys($data['tests']);
134+
}
135+
127136
$data['loader_paths'] = $this->getLoaderPaths();
128-
$io->writeln(json_encode($data));
137+
$data = json_encode($data, JSON_PRETTY_PRINT);
138+
$io->writeln($decorated ? OutputFormatter::escape($data) : $data);
129139

130140
return 0;
131141
}
132142

133-
$filter = $input->getArgument('filter');
134-
135143
foreach ($types as $index => $type) {
136144
$items = [];
137145
foreach ($this->twig->{'get'.ucfirst($type)}() as $name => $entity) {
138146
if (!$filter || false !== strpos($name, $filter)) {
139-
$items[$name] = $name.$this->getPrettyMetadata($type, $entity);
147+
$items[$name] = $name.$this->getPrettyMetadata($type, $entity, $decorated);
140148
}
141149
}
142150

@@ -262,7 +270,7 @@ private function getMetadata($type, $entity)
262270
}
263271
}
264272

265-
private function getPrettyMetadata($type, $entity)
273+
private function getPrettyMetadata($type, $entity, $decorated)
266274
{
267275
if ('tests' === $type) {
268276
return '';
@@ -274,15 +282,17 @@ private function getPrettyMetadata($type, $entity)
274282
return '(unknown?)';
275283
}
276284
} catch (\UnexpectedValueException $e) {
277-
return ' <error>'.$e->getMessage().'</error>';
285+
return sprintf(' <error>%s</error>', $decorated ? OutputFormatter::escape($e->getMessage()) : $e->getMessage());
278286
}
279287

280288
if ('globals' === $type) {
281289
if (\is_object($meta)) {
282290
return ' = object('.\get_class($meta).')';
283291
}
284292

285-
return ' = '.substr(@json_encode($meta), 0, 50);
293+
$description = substr(@json_encode($meta), 0, 50);
294+
295+
return sprintf(' = %s', $decorated ? OutputFormatter::escape($description) : $description);
286296
}
287297

288298
if ('functions' === $type) {

‎src/Symfony/Bridge/Twig/Tests/Command/DebugCommandTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/Twig/Tests/Command/DebugCommandTest.php
+46-2Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,59 @@ public function testLineSeparatorInLoaderPaths()
6262
$this->assertContains($loaderPaths, trim($tester->getDisplay(true)));
6363
}
6464

65-
private function createCommandTester(array $paths = [])
65+
public function testWithGlobals()
66+
{
67+
$message = '<error>foo</error>';
68+
$tester = $this->createCommandTester([], ['message' => $message]);
69+
$tester->execute([], ['decorated' => true]);
70+
71+
$display = $tester->getDisplay();
72+
73+
$this->assertContains(\json_encode($message), $display);
74+
}
75+
76+
public function testWithGlobalsJson()
77+
{
78+
$globals = ['message' => '<error>foo</error>'];
79+
80+
$tester = $this->createCommandTester([], $globals);
81+
$tester->execute(['--format' => 'json'], ['decorated' => true]);
82+
83+
$display = $tester->getDisplay();
84+
$display = \json_decode($display, true);
85+
86+
$this->assertSame($globals, $display['globals']);
87+
}
88+
89+
public function testWithFilter()
90+
{
91+
$tester = $this->createCommandTester([]);
92+
$tester->execute(['--format' => 'json'], ['decorated' => false]);
93+
$display = $tester->getDisplay();
94+
$display1 = \json_decode($display, true);
95+
96+
$tester->execute(['filter' => 'date', '--format' => 'json'], ['decorated' => false]);
97+
$display = $tester->getDisplay();
98+
$display2 = \json_decode($display, true);
99+
100+
$this->assertNotSame($display1, $display2);
101+
}
102+
103+
private function createCommandTester(array $paths = [], array $globals = [])
66104
{
67105
$filesystemLoader = new FilesystemLoader([], \dirname(__DIR__).'/Fixtures');
68106
foreach ($paths as $namespace => $relDirs) {
69107
foreach ($relDirs as $relDir) {
70108
$filesystemLoader->addPath($relDir, $namespace);
71109
}
72110
}
73-
$command = new DebugCommand(new Environment($filesystemLoader));
111+
112+
$environment = new Environment($filesystemLoader);
113+
foreach ($globals as $name => $value) {
114+
$environment->addGlobal($name, $value);
115+
}
116+
117+
$command = new DebugCommand($environment);
74118

75119
$application = new Application();
76120
$application->add($command);

‎src/Symfony/Component/Console/Tester/CommandTester.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Tester/CommandTester.php
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ public function execute(array $input, array $options = [])
8787
*/
8888
public function getDisplay($normalize = false)
8989
{
90+
if (null === $this->output) {
91+
throw new \RuntimeException('Output not initialized, did you execute the command before requesting the display?');
92+
}
93+
9094
rewind($this->output->getStream());
9195

9296
$display = stream_get_contents($this->output->getStream());

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.