From b6c96c541c1c0508c1e5d503a67d3867fa236dea Mon Sep 17 00:00:00 2001 From: Yury Pikhtarev Date: Wed, 18 Jun 2025 23:58:11 +0400 Subject: [PATCH] refactor(legacy): enhance IF statement conversion with block context awareness - Reorder conversion process to handle legacy blocks before IF statements, ensuring proper nested structure handling. - Introduce new methods for converting IF statements with block context, improving compatibility with existing templates. - Maintain backward compatibility while enhancing the conversion logic for legacy syntax. --- .../Extensions/LegacySyntaxExtension.php | 71 +++++++++++++++++-- 1 file changed, 66 insertions(+), 5 deletions(-) diff --git a/src/Template/Extensions/LegacySyntaxExtension.php b/src/Template/Extensions/LegacySyntaxExtension.php index 015ee9b26..6756227c8 100644 --- a/src/Template/Extensions/LegacySyntaxExtension.php +++ b/src/Template/Extensions/LegacySyntaxExtension.php @@ -55,13 +55,12 @@ class LegacySyntaxExtension extends AbstractExtension // Convert legacy includes first (simplest) $content = $this->convertIncludes($content); - // Convert legacy IF statements first - they have the most complex structure - // This ensures nested structures are properly handled - $content = $this->convertIfStatements($content); - - // Convert legacy blocks (BEGIN/END) + // Convert legacy blocks (BEGIN/END) - this will also handle IF statements within block context $content = $this->convertBlocks($content); + // Convert any remaining IF statements that are not within blocks + $content = $this->convertIfStatements($content); + // Convert legacy variables last $content = $this->convertVariables($content); @@ -285,6 +284,9 @@ class LegacySyntaxExtension extends AbstractExtension $currentBlockStack = array_merge($parentBlocks, [$blockName]); $body = $this->convertBlocksRecursive($body, $currentBlockStack); + // Convert IF statements with block context BEFORE converting variables + $body = $this->convertIfStatementsWithContext($body, $currentBlockStack); + // Convert variables for this block level $body = $this->convertBlockVariables($body, $blockName, $parentBlocks); @@ -342,6 +344,65 @@ class LegacySyntaxExtension extends AbstractExtension return $content; } + /** + * Convert IF statements with block context awareness + */ + private function convertIfStatementsWithContext(string $content, array $blockStack): string + { + $iterations = 0; + $maxIterations = 50; + + do { + $previousContent = $content; + + // Convert complete IF...ELSE...ENDIF structures with context + $content = preg_replace_callback('/((?:(?!((?:(?!/s', function($matches) use ($blockStack) { + $condition = $this->convertConditionWithContext(trim($matches[1]), $blockStack); + $ifBody = $matches[2]; + $elseBody = $matches[3]; + return "{% if $condition %}$ifBody{% else %}$elseBody{% endif %}"; + }, $content); + + // Convert simple IF...ENDIF structures with context + $content = preg_replace_callback('/((?:(?!/s', function($matches) use ($blockStack) { + $condition = $this->convertConditionWithContext(trim($matches[1]), $blockStack); + $body = $matches[2]; + return "{% if $condition %}$body{% endif %}"; + }, $content); + + $iterations++; + } while ($content !== $previousContent && $iterations < $maxIterations); + + return $content; + } + + /** + * Convert condition with block context awareness + */ + private function convertConditionWithContext(string $condition, array $blockStack): string + { + $condition = trim($condition); + + // If we're in a block context, convert block variables appropriately + if (!empty($blockStack)) { + $currentBlock = end($blockStack); + $fullBlockPath = implode('.', $blockStack); + + // Convert variables like c.f.POSTS to f_item.POSTS when in f block + // This handles the pattern where the full path refers to the current block item + $condition = preg_replace_callback('/\b' . preg_quote($fullBlockPath) . '\.([A-Z0-9_]+)\b/', function($matches) use ($currentBlock) { + $varName = $matches[1]; + return "{$currentBlock}_item.$varName"; + }, $condition); + + // Don't auto-convert standalone variables - let the main variable conversion handle them + // This prevents global variables like SHOW_LAST_TOPIC from being incorrectly converted to block variables + } + + // Apply standard condition conversions + return $this->convertCondition($condition); + } + /** * Convert legacy includes to Twig includes */