From 2a0307adddf2fea0e24d1682ed9efe9d1df30ead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Bourgier?= Date: Fri, 20 Nov 2020 19:51:04 +0100 Subject: [PATCH 1/2] Fix TemplateProcessor::fixBrokenMacros to handle whitespaces --- src/PhpWord/TemplateProcessor.php | 6 +++++- tests/PhpWordTests/TemplateProcessorTest.php | 15 ++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/PhpWord/TemplateProcessor.php b/src/PhpWord/TemplateProcessor.php index 1ad901d480..288255aac0 100644 --- a/src/PhpWord/TemplateProcessor.php +++ b/src/PhpWord/TemplateProcessor.php @@ -1070,7 +1070,11 @@ protected function fixBrokenMacros($documentPart) return preg_replace_callback( '/\\' . $brokenMacroOpeningChars . '(?:\\' . $endMacroOpeningChars . '|[^{$]*\>\{)[^' . $macroClosingChars . '$]*\}/U', function ($match) { - return strip_tags($match[0]); + preg_match_all('/<.+?\s*\/?\s*>/si', $match[0], $tags); + $tags = implode('', $tags[0]); + $tags = str_replace('', '', $tags); + + return strip_tags($match[0]) . $tags; }, $documentPart ); diff --git a/tests/PhpWordTests/TemplateProcessorTest.php b/tests/PhpWordTests/TemplateProcessorTest.php index f2d2cfbf13..657ca3595b 100644 --- a/tests/PhpWordTests/TemplateProcessorTest.php +++ b/tests/PhpWordTests/TemplateProcessorTest.php @@ -1253,19 +1253,28 @@ public function testFixBrokenMacros(): void self::assertEquals('${documentContent}', $fixed); $fixed = $templateProcessor->fixBrokenMacros('${documentContent}'); - self::assertEquals('${documentContent}', $fixed); + self::assertEquals('${documentContent}', $fixed); $fixed = $templateProcessor->fixBrokenMacros('$1500${documentContent}'); self::assertEquals('$1500${documentContent}', $fixed); $fixed = $templateProcessor->fixBrokenMacros('$1500${documentContent}'); - self::assertEquals('$1500${documentContent}', $fixed); + self::assertEquals('$1500${documentContent}', $fixed); $fixed = $templateProcessor->fixBrokenMacros('25$ plus some info {hint}'); self::assertEquals('25$ plus some info {hint}', $fixed); $fixed = $templateProcessor->fixBrokenMacros('$15,000.00. ${variable_name}'); - self::assertEquals('$15,000.00. ${variable_name}', $fixed); + self::assertEquals('$15,000.00. ${variable_name}', $fixed); + + $fixed = $templateProcessor->fixBrokenMacros('before ${variable} after'); + self::assertEquals('before ${variable} after', $fixed); + + $fixed = $templateProcessor->fixBrokenMacros('before ${variable} after'); + self::assertEquals('before ${variable} after', $fixed); + + $fixed = $templateProcessor->fixBrokenMacros('${variable1} ${variable2}'); + self::assertEquals('${variable1} ${variable2}', $fixed); } /** From 838b63ed3c4685c21ca4e94d90e9e2b87f7d9124 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Bourgier?= Date: Fri, 1 Dec 2023 11:47:24 +0100 Subject: [PATCH 2/2] Handle custom macro chars Update main regexp so that the full macro is matched (only `{{var}` was matched instead of `{{var}}`, which is a problem because we want to move tags after the whole macro) --- src/PhpWord/TemplateProcessor.php | 22 ++++++++++++++------ tests/PhpWordTests/TemplateProcessorTest.php | 18 +++++++++++++--- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/PhpWord/TemplateProcessor.php b/src/PhpWord/TemplateProcessor.php index 288255aac0..20cbb38bff 100644 --- a/src/PhpWord/TemplateProcessor.php +++ b/src/PhpWord/TemplateProcessor.php @@ -1063,14 +1063,24 @@ public function saveAs($fileName): void */ protected function fixBrokenMacros($documentPart) { - $brokenMacroOpeningChars = substr(self::$macroOpeningChars, 0, 1); - $endMacroOpeningChars = substr(self::$macroOpeningChars, 1); - $macroClosingChars = self::$macroClosingChars; - return preg_replace_callback( - '/\\' . $brokenMacroOpeningChars . '(?:\\' . $endMacroOpeningChars . '|[^{$]*\>\{)[^' . $macroClosingChars . '$]*\}/U', + sprintf( + '/%s.+%s/U', + implode('', array_map( + function (string $char) { + return preg_quote($char) . '(?:<[^>]+>)*'; + }, + str_split(self::$macroOpeningChars) + )), + implode('', array_map( + function (string $char) { + return '(?:<[^>]+>)*' . preg_quote($char); + }, + str_split(self::$macroClosingChars) + )) + ), function ($match) { - preg_match_all('/<.+?\s*\/?\s*>/si', $match[0], $tags); + preg_match_all('/<[^>]+>/s', $match[0], $tags); $tags = implode('', $tags[0]); $tags = str_replace('', '', $tags); diff --git a/tests/PhpWordTests/TemplateProcessorTest.php b/tests/PhpWordTests/TemplateProcessorTest.php index 657ca3595b..5c11d3dd3d 100644 --- a/tests/PhpWordTests/TemplateProcessorTest.php +++ b/tests/PhpWordTests/TemplateProcessorTest.php @@ -1294,19 +1294,31 @@ public function testFixBrokenMacrosWithCustomMacro(): void self::assertEquals('{{documentContent}}', $fixed); $fixed = $templateProcessor->fixBrokenMacros('{{documentContent}}'); - self::assertEquals('{{documentContent}}', $fixed); + self::assertEquals('{{documentContent}}', $fixed); + + $fixed = $templateProcessor->fixBrokenMacros('{{documentContent}}'); + self::assertEquals('{{documentContent}}', $fixed); $fixed = $templateProcessor->fixBrokenMacros('$1500{{documentContent}}'); self::assertEquals('$1500{{documentContent}}', $fixed); $fixed = $templateProcessor->fixBrokenMacros('$1500{{documentContent}}'); - self::assertEquals('$1500{{documentContent}}', $fixed); + self::assertEquals('$1500{{documentContent}}', $fixed); $fixed = $templateProcessor->fixBrokenMacros('25$ plus some info {hint}'); self::assertEquals('25$ plus some info {hint}', $fixed); $fixed = $templateProcessor->fixBrokenMacros('$15,000.00. {{variable_name}}'); - self::assertEquals('$15,000.00. {{variable_name}}', $fixed); + self::assertEquals('$15,000.00. {{variable_name}}', $fixed); + + $fixed = $templateProcessor->fixBrokenMacros('before {{variable}} after'); + self::assertEquals('before {{variable}} after', $fixed); + + $fixed = $templateProcessor->fixBrokenMacros('before {{variable}} after'); + self::assertEquals('before {{variable}} after', $fixed); + + $fixed = $templateProcessor->fixBrokenMacros('{{variable1}} {{variable2}}'); + self::assertEquals('{{variable1}} {{variable2}}', $fixed); } /**