Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 560c5f8

Browse files
committed
don't use deprecated and internal Twig functions
1 parent 52839be commit 560c5f8

File tree

4 files changed

+87
-23
lines changed

4 files changed

+87
-23
lines changed

src/Symfony/Bridge/Twig/Node/SearchAndRenderBlockNode.php

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111

1212
namespace Symfony\Bridge\Twig\Node;
1313

14+
use Symfony\Bridge\Twig\Extension\FormExtension;
1415
use Twig\Compiler;
16+
use Twig\Extension\CoreExtension;
1517
use Twig\Node\Expression\ArrayExpression;
1618
use Twig\Node\Expression\ConstantExpression;
1719
use Twig\Node\Expression\FunctionExpression;
@@ -50,7 +52,7 @@ public function compile(Compiler $compiler): void
5052
$labelIsExpression = false;
5153

5254
// Only insert the label into the array if it is not empty
53-
if (!twig_test_empty($label->getAttribute('value'))) {
55+
if (!self::isEmpty($label->getAttribute('value'))) {
5456
$originalVariables = $variables;
5557
$variables = new ArrayExpression([], $lineno);
5658
$labelKey = new ConstantExpression('label', $lineno);
@@ -97,7 +99,12 @@ public function compile(Compiler $compiler): void
9799

98100
// Check at runtime whether the label is empty.
99101
// If not, add it to the array at runtime.
100-
$compiler->raw('(twig_test_empty($_label_ = ');
102+
if (method_exists(CoreExtension::class, 'testEmpty')) {
103+
$compiler->raw('(Twig\Extension\CoreExtension::testEmpty($_label_ = ');
104+
} else {
105+
$compiler->raw('(twig_test_empty($_label_ = ');
106+
}
107+
101108
$compiler->subcompile($label);
102109
$compiler->raw(') ? [] : ["label" => $_label_])');
103110
}
@@ -107,4 +114,24 @@ public function compile(Compiler $compiler): void
107114

108115
$compiler->raw(')');
109116
}
117+
118+
/**
119+
* @see \Twig\Extension\CoreExtension::testEmpty()
120+
*/
121+
private static function isEmpty($value): bool
122+
{
123+
if ($value instanceof \Countable) {
124+
return 0 === \count($value);
125+
}
126+
127+
if ($value instanceof \Traversable) {
128+
return !iterator_count($value);
129+
}
130+
131+
if (\is_object($value) && method_exists($value, '__toString')) {
132+
return '' === (string) $value;
133+
}
134+
135+
return '' === $value || false === $value || null === $value || [] === $value;
136+
}
110137
}

src/Symfony/Bridge/Twig/Tests/Node/SearchAndRenderBlockNodeTest.php

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode;
1616
use Twig\Compiler;
1717
use Twig\Environment;
18+
use Twig\Extension\CoreExtension;
1819
use Twig\Loader\LoaderInterface;
1920
use Twig\Node\Expression\ArrayExpression;
2021
use Twig\Node\Expression\ConditionalExpression;
@@ -224,13 +225,11 @@ public function testCompileLabelWithLabelThatEvaluatesToNull()
224225
// "label" => null must not be included in the output!
225226
// Otherwise the default label is overwritten with null.
226227
// https://github.com/symfony/symfony/issues/5029
227-
$this->assertEquals(
228-
sprintf(
229-
'$this->env->getRuntime(\'Symfony\Component\Form\FormRenderer\')->searchAndRenderBlock(%s, \'label\', (twig_test_empty($_label_ = ((true) ? (null) : (null))) ? [] : ["label" => $_label_]))',
230-
$this->getVariableGetter('form')
231-
),
232-
trim($compiler->compile($node)->getSource())
233-
);
228+
if (method_exists(CoreExtension::class, 'testEmpty')) {
229+
$this->assertEquals(sprintf('$this->env->getRuntime(\'Symfony\Component\Form\FormRenderer\')->searchAndRenderBlock(%s, \'label\', (Twig\Extension\CoreExtension::testEmpty($_label_ = ((true) ? (null) : (null))) ? [] : ["label" => $_label_]))', $this->getVariableGetter('form')), trim($compiler->compile($node)->getSource()));
230+
} else {
231+
$this->assertEquals(sprintf('$this->env->getRuntime(\'Symfony\Component\Form\FormRenderer\')->searchAndRenderBlock(%s, \'label\', (twig_test_empty($_label_ = ((true) ? (null) : (null))) ? [] : ["label" => $_label_]))', $this->getVariableGetter('form')), trim($compiler->compile($node)->getSource()));
232+
}
234233
}
235234

236235
public function testCompileLabelWithLabelThatEvaluatesToNullAndAttributes()
@@ -261,13 +260,11 @@ public function testCompileLabelWithLabelThatEvaluatesToNullAndAttributes()
261260
// "label" => null must not be included in the output!
262261
// Otherwise the default label is overwritten with null.
263262
// https://github.com/symfony/symfony/issues/5029
264-
$this->assertEquals(
265-
sprintf(
266-
'$this->env->getRuntime(\'Symfony\Component\Form\FormRenderer\')->searchAndRenderBlock(%s, \'label\', ["foo" => "bar", "label" => "value in attributes"] + (twig_test_empty($_label_ = ((true) ? (null) : (null))) ? [] : ["label" => $_label_]))',
267-
$this->getVariableGetter('form')
268-
),
269-
trim($compiler->compile($node)->getSource())
270-
);
263+
if (method_exists(CoreExtension::class, 'testEmpty')) {
264+
$this->assertEquals(sprintf('$this->env->getRuntime(\'Symfony\Component\Form\FormRenderer\')->searchAndRenderBlock(%s, \'label\', ["foo" => "bar", "label" => "value in attributes"] + (Twig\Extension\CoreExtension::testEmpty($_label_ = ((true) ? (null) : (null))) ? [] : ["label" => $_label_]))', $this->getVariableGetter('form')), trim($compiler->compile($node)->getSource()));
265+
} else {
266+
$this->assertEquals(sprintf('$this->env->getRuntime(\'Symfony\Component\Form\FormRenderer\')->searchAndRenderBlock(%s, \'label\', ["foo" => "bar", "label" => "value in attributes"] + (twig_test_empty($_label_ = ((true) ? (null) : (null))) ? [] : ["label" => $_label_]))', $this->getVariableGetter('form')), trim($compiler->compile($node)->getSource()));
267+
}
271268
}
272269

273270
protected function getVariableGetter($name)

src/Symfony/Bundle/WebProfilerBundle/Tests/Twig/WebProfilerExtensionTest.php

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
use Symfony\Bundle\WebProfilerBundle\Twig\WebProfilerExtension;
1616
use Symfony\Component\VarDumper\Cloner\VarCloner;
1717
use Twig\Environment;
18-
use Twig\Extension\CoreExtension;
19-
use Twig\Extension\EscaperExtension;
2018

2119
class WebProfilerExtensionTest extends TestCase
2220
{
@@ -25,9 +23,6 @@ class WebProfilerExtensionTest extends TestCase
2523
*/
2624
public function testDumpHeaderIsDisplayed(string $message, array $context, bool $dump1HasHeader, bool $dump2HasHeader)
2725
{
28-
class_exists(CoreExtension::class); // Load twig_convert_encoding()
29-
class_exists(EscaperExtension::class); // Load twig_escape_filter()
30-
3126
$twigEnvironment = $this->mockTwigEnvironment();
3227
$varCloner = new VarCloner();
3328

src/Symfony/Bundle/WebProfilerBundle/Twig/WebProfilerExtension.php

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,12 @@ public function dumpData(Environment $env, Data $data, int $maxDepth = 0)
8787

8888
public function dumpLog(Environment $env, string $message, Data $context = null)
8989
{
90-
$message = twig_escape_filter($env, $message);
90+
$message = self::escape($message, $env->getCharset());
9191
$message = preg_replace('/&quot;(.*?)&quot;/', '&quot;<b>$1</b>&quot;', $message);
9292

9393
$replacements = [];
9494
foreach ($context ?? [] as $k => $v) {
95-
$k = '{'.twig_escape_filter($env, $k).'}';
95+
$k = '{'.self::escape($k, $env->getCharset()).'}';
9696
if (str_contains($message, $k)) {
9797
$replacements[$k] = $v;
9898
}
@@ -116,4 +116,49 @@ public function getName()
116116
{
117117
return 'profiler';
118118
}
119+
120+
/**
121+
* @see \Twig\Extension\EscaperExtension::escape()
122+
*/
123+
private static function escape(string $s, string $charset): string
124+
{
125+
if ('' === $s) {
126+
return '';
127+
}
128+
129+
// see https://www.php.net/htmlspecialchars
130+
131+
// Using a static variable to avoid initializing the array
132+
// each time the function is called. Moving the declaration on the
133+
// top of the function slow downs other escaping strategies.
134+
static $htmlspecialcharsCharsets = [
135+
'ISO-8859-1' => true, 'ISO8859-1' => true,
136+
'ISO-8859-15' => true, 'ISO8859-15' => true,
137+
'utf-8' => true, 'UTF-8' => true,
138+
'CP866' => true, 'IBM866' => true, '866' => true,
139+
'CP1251' => true, 'WINDOWS-1251' => true, 'WIN-1251' => true,
140+
'1251' => true,
141+
'CP1252' => true, 'WINDOWS-1252' => true, '1252' => true,
142+
'KOI8-R' => true, 'KOI8-RU' => true, 'KOI8R' => true,
143+
'BIG5' => true, '950' => true,
144+
'GB2312' => true, '936' => true,
145+
'BIG5-HKSCS' => true,
146+
'SHIFT_JIS' => true, 'SJIS' => true, '932' => true,
147+
'EUC-JP' => true, 'EUCJP' => true,
148+
'ISO8859-5' => true, 'ISO-8859-5' => true, 'MACROMAN' => true,
149+
];
150+
151+
if (isset($htmlspecialcharsCharsets[$charset])) {
152+
return htmlspecialchars($s, \ENT_QUOTES | \ENT_SUBSTITUTE, $charset);
153+
}
154+
155+
if (isset($htmlspecialcharsCharsets[strtoupper($charset)])) {
156+
// cache the lowercase variant for future iterations
157+
$htmlspecialcharsCharsets[$charset] = true;
158+
159+
return htmlspecialchars($s, \ENT_QUOTES | \ENT_SUBSTITUTE, $charset);
160+
}
161+
162+
return iconv('UTF-8', $charset, htmlspecialchars(iconv($s, $charset, 'UTF-8'), \ENT_QUOTES | \ENT_SUBSTITUTE, 'UTF-8'));
163+
}
119164
}

0 commit comments

Comments
 (0)