mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-01-03 08:41:39 +09:00
Exclude functions and closures from scope conversion #2617
This commit is contained in:
parent
50dd010e2d
commit
8e5480674d
4 changed files with 88 additions and 0 deletions
|
|
@ -1084,6 +1084,37 @@ class TemplateParser_v2
|
||||||
*/
|
*/
|
||||||
protected function _convertVariableScope(string $content): string
|
protected function _convertVariableScope(string $content): string
|
||||||
{
|
{
|
||||||
|
// Pre-escape function declarations and closures so that variables inside them are not converted.
|
||||||
|
$used_vars = [];
|
||||||
|
$function_regexp = '#\b(function(?:\s+[a-zA-Z_][a-zA-Z0-9_]*)?)' .
|
||||||
|
'(\s*)(' . self::_getRegexpForParentheses(3) . ')' .
|
||||||
|
'(\s*)(use\s*\([^()]+\))?' .
|
||||||
|
'(\s*:\s*\w+)?' .
|
||||||
|
'(\s*)(' . self::_getRegexpForCurlyBraces(8) . ')#';
|
||||||
|
$content = preg_replace_callback($function_regexp, function($match) use (&$used_vars) {
|
||||||
|
$fn = $match[1] . $match[2] . self::_escapeVars($match[3]) .
|
||||||
|
$match[4] . self::_escapeVars($match[5]) .
|
||||||
|
$match[6] . $match[7] . self::_escapeVars($match[8]);
|
||||||
|
if (str_starts_with($match[5], 'use'))
|
||||||
|
{
|
||||||
|
preg_match_all('#\$([a-zA-Z_][a-zA-Z0-9_]*)#', $match[5], $uses);
|
||||||
|
foreach ($uses[1] as $var)
|
||||||
|
{
|
||||||
|
$used_vars[$var] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $fn;
|
||||||
|
}, $content);
|
||||||
|
if (count($used_vars))
|
||||||
|
{
|
||||||
|
$prefix = ' ';
|
||||||
|
foreach ($used_vars as $var => $unused)
|
||||||
|
{
|
||||||
|
$prefix .= self::_escapeVars('$' . $var) . ' = &$__Context->' . $var . '; ';
|
||||||
|
}
|
||||||
|
$content = $prefix . $content;
|
||||||
|
}
|
||||||
|
|
||||||
// Replace variables that need to be enclosed in curly braces, using temporary entities to prevent double-replacement.
|
// Replace variables that need to be enclosed in curly braces, using temporary entities to prevent double-replacement.
|
||||||
$content = preg_replace_callback('#(?<!\$__Context)->\$([a-zA-Z_][a-zA-Z0-9_]*)#', function($match) {
|
$content = preg_replace_callback('#(?<!\$__Context)->\$([a-zA-Z_][a-zA-Z0-9_]*)#', function($match) {
|
||||||
return '->' . self::_escapeCurly('{') . '$__Context->' . $match[1] . self::_escapeCurly('}');
|
return '->' . self::_escapeCurly('{') . '$__Context->' . $match[1] . self::_escapeCurly('}');
|
||||||
|
|
@ -1144,6 +1175,17 @@ class TemplateParser_v2
|
||||||
return '\([^)(]*+(?:(?' . $position_in_regexp . ')[^)(]*)*+\)';
|
return '\([^)(]*+(?:(?' . $position_in_regexp . ')[^)(]*)*+\)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same as above, but for curly braces.
|
||||||
|
*
|
||||||
|
* @param int $position_in_regexp
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected static function _getRegexpForCurlyBraces(int $position_in_regexp): string
|
||||||
|
{
|
||||||
|
return '\{[^}{]*+(?:(?' . $position_in_regexp . ')[^}{]*)*+\}';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Escape curly braces so that they will not be interpreted as echo statements.
|
* Escape curly braces so that they will not be interpreted as echo statements.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,27 @@
|
||||||
<span<?php echo $this->_v2_buildAttribute('style', ['a' => false, 'b' => false]); ?>></span>
|
<span<?php echo $this->_v2_buildAttribute('style', ['a' => false, 'b' => false]); ?>></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<?php $suffix = &$__Context->suffix;
|
||||||
|
$__Context->employees = [
|
||||||
|
['name' => 'Alice', 'age' => 30],
|
||||||
|
['name' => 'Bob', 'age' => 25],
|
||||||
|
['name' => 'Charlie', 'age' => 35],
|
||||||
|
];
|
||||||
|
$__Context->suffix = '님';
|
||||||
|
$__Context->names = array_map(function($e, $key = 'name') use ($suffix) {
|
||||||
|
return $e[$key] . $suffix;
|
||||||
|
}, $__Context->employees);
|
||||||
|
function convert_names(array $names = array()): array
|
||||||
|
{
|
||||||
|
return array_map(function($name) {
|
||||||
|
return ucfirst($name);
|
||||||
|
}, $names);
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<div class="employees">
|
||||||
|
<?php echo $this->config->context === 'HTML' ? htmlspecialchars(implode(', ', convert_names($__Context->names)), \ENT_QUOTES, 'UTF-8', false) : $this->_v2_escape(implode(', ', convert_names($__Context->names))); ?> welcome!
|
||||||
|
</div>
|
||||||
|
|
||||||
<script type="text/javascript"<?php $this->config->context = 'JS'; ?>>
|
<script type="text/javascript"<?php $this->config->context = 'JS'; ?>>
|
||||||
const foo = '<?php echo $this->config->context === 'HTML' ? htmlspecialchars($__Context->foo ?? '', \ENT_QUOTES, 'UTF-8', false) : $this->_v2_escape($__Context->foo ?? ''); ?>';
|
const foo = '<?php echo $this->config->context === 'HTML' ? htmlspecialchars($__Context->foo ?? '', \ENT_QUOTES, 'UTF-8', false) : $this->_v2_escape($__Context->foo ?? ''); ?>';
|
||||||
const bar = <?php echo $this->config->context === 'JS' ? json_encode($__Context->bar, self::$_json_options2) : htmlspecialchars(json_encode($__Context->bar, self::$_json_options), \ENT_QUOTES, 'UTF-8', false); ?>;
|
const bar = <?php echo $this->config->context === 'JS' ? json_encode($__Context->bar, self::$_json_options2) : htmlspecialchars(json_encode($__Context->bar, self::$_json_options), \ENT_QUOTES, 'UTF-8', false); ?>;
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,10 @@
|
||||||
<span></span>
|
<span></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="employees">
|
||||||
|
Alice님, Bob님, Charlie님 welcome!
|
||||||
|
</div>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
const foo = 'FOOFOO\u003C\u0022FOO\u0022\u003EBAR';
|
const foo = 'FOOFOO\u003C\u0022FOO\u0022\u003EBAR';
|
||||||
const bar = ["Rhy","miX","is","da","BEST!"];
|
const bar = ["Rhy","miX","is","da","BEST!"];
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,27 @@
|
||||||
<span @style(['a' => false, 'b' => false])></span>
|
<span @style(['a' => false, 'b' => false])></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@php
|
||||||
|
$employees = [
|
||||||
|
['name' => 'Alice', 'age' => 30],
|
||||||
|
['name' => 'Bob', 'age' => 25],
|
||||||
|
['name' => 'Charlie', 'age' => 35],
|
||||||
|
];
|
||||||
|
$suffix = '님';
|
||||||
|
$names = array_map(function($e, $key = 'name') use ($suffix) {
|
||||||
|
return $e[$key] . $suffix;
|
||||||
|
}, $employees);
|
||||||
|
function convert_names(array $names = array()): array
|
||||||
|
{
|
||||||
|
return array_map(function($name) {
|
||||||
|
return ucfirst($name);
|
||||||
|
}, $names);
|
||||||
|
}
|
||||||
|
@endphp
|
||||||
|
<div class="employees">
|
||||||
|
{{ implode(', ', convert_names($names)) }} welcome!
|
||||||
|
</div>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
const foo = '{{ $foo }}';
|
const foo = '{{ $foo }}';
|
||||||
const bar = @json($bar);
|
const bar = @json($bar);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue