@@ -94,6 +94,10 @@ class TemplateProcessor
94
94
*/
95
95
protected $ tempDocumentNewImages = [];
96
96
97
+ protected static $ macroOpeningChars = '${ ' ;
98
+
99
+ protected static $ macroClosingChars = '} ' ;
100
+
97
101
/**
98
102
* @since 0.12.0 Throws CreateTemporaryFileException and CopyFileException instead of Exception
99
103
*
@@ -238,8 +242,8 @@ public function applyXslStyleSheet($xslDomDocument, $xslOptions = [], $xslOption
238
242
*/
239
243
protected static function ensureMacroCompleted ($ macro )
240
244
{
241
- if (substr ($ macro , 0 , 2 ) !== ' ${ ' && substr ($ macro , -1 ) !== ' } ' ) {
242
- $ macro = ' ${ ' . $ macro . ' } ' ;
245
+ if (substr ($ macro , 0 , 2 ) !== self :: $ macroOpeningChars && substr ($ macro , -1 ) !== self :: $ macroClosingChars ) {
246
+ $ macro = self :: $ macroOpeningChars . $ macro . self :: $ macroClosingChars ;
243
247
}
244
248
245
249
return $ macro ;
@@ -792,8 +796,12 @@ public function cloneBlock($blockname, $clones = 1, $replace = true, $indexVaria
792
796
{
793
797
$ xmlBlock = null ;
794
798
$ matches = [];
799
+ $ escapedMacroOpeningChars = self ::$ macroOpeningChars ;
800
+ $ escapedMacroClosingChars = self ::$ macroClosingChars ;
795
801
preg_match (
796
- '/(.*((?s)<w:p\b(?:(?!<w:p\b).)*?\${ ' . $ blockname . '}<\/w:.*?p>))(.*)((?s)<w:p\b(?:(?!<w:p\b).)[^$]*?\${\/ ' . $ blockname . '}<\/w:.*?p>)/is ' ,
802
+ //'/(.*((?s)<w:p\b(?:(?!<w:p\b).)*?\{{' . $blockname . '}<\/w:.*?p>))(.*)((?s)<w:p\b(?:(?!<w:p\b).)[^$]*?\{{\/' . $blockname . '}<\/w:.*?p>)/is',
803
+ '/(.*((?s)<w:p\b(?:(?!<w:p\b).)*? \\' . $ escapedMacroOpeningChars . $ blockname . $ escapedMacroClosingChars . '<\/w:.*?p>))(.*)((?s)<w:p\b(?:(?!<w:p\b).)[^$]*? \\' . $ escapedMacroOpeningChars . '\/ ' . $ blockname . $ escapedMacroClosingChars . '<\/w:.*?p>)/is ' ,
804
+ //'/(.*((?s)<w:p\b(?:(?!<w:p\b).)*?\\'. $escapedMacroOpeningChars . $blockname . '}<\/w:.*?p>))(.*)((?s)<w:p\b(?:(?!<w:p\b).)[^$]*?\\'.$escapedMacroOpeningChars.'\/' . $blockname . '}<\/w:.*?p>)/is',
797
805
$ this ->tempDocumentMainPart ,
798
806
$ matches
799
807
);
@@ -832,8 +840,10 @@ public function cloneBlock($blockname, $clones = 1, $replace = true, $indexVaria
832
840
public function replaceBlock ($ blockname , $ replacement ): void
833
841
{
834
842
$ matches = [];
843
+ $ escapedMacroOpeningChars = preg_quote (self ::$ macroOpeningChars );
844
+ $ escapedMacroClosingChars = preg_quote (self ::$ macroClosingChars );
835
845
preg_match (
836
- '/(<\?xml.*)(<w:p.*>\${ ' . $ blockname . ' } <\/w:.*?p>)(.*)(<w:p.*\${ \/ ' . $ blockname . ' } <\/w:.*?p>)/is ' ,
846
+ '/(<\?xml.*)(<w:p.*> ' . $ escapedMacroOpeningChars . $ blockname . $ escapedMacroClosingChars . ' <\/w:.*?p>)(.*)(<w:p.* ' . $ escapedMacroOpeningChars . ' \/ ' . $ blockname . $ escapedMacroClosingChars . ' <\/w:.*?p>)/is ' ,
837
847
$ this ->tempDocumentMainPart ,
838
848
$ matches
839
849
);
@@ -949,8 +959,12 @@ public function saveAs($fileName): void
949
959
*/
950
960
protected function fixBrokenMacros ($ documentPart )
951
961
{
962
+ $ brokenMacroOpeningChars = substr (self ::$ macroOpeningChars , 0 , 1 );
963
+ $ endMacroOpeningChars = substr (self ::$ macroOpeningChars , 1 );
964
+ $ macroClosingChars = self ::$ macroClosingChars ;
965
+
952
966
return preg_replace_callback (
953
- '/\$ (?:\{ |[^{$]*\>\{)[^} $]*\}/U ' ,
967
+ '/ \\' . $ brokenMacroOpeningChars . ' (?: \\' . $ endMacroOpeningChars . ' |[^{$]*\>\{)[^ ' . $ macroClosingChars . ' $]*\}/U ' ,
954
968
function ($ match ) {
955
969
return strip_tags ($ match [0 ]);
956
970
},
@@ -989,7 +1003,10 @@ protected function setValueForPart($search, $replace, $documentPartXML, $limit)
989
1003
protected function getVariablesForPart ($ documentPartXML )
990
1004
{
991
1005
$ matches = [];
992
- preg_match_all ('/\$\{(.*?)}/i ' , $ documentPartXML , $ matches );
1006
+ $ escapedMacroOpeningChars = preg_quote (self ::$ macroOpeningChars );
1007
+ $ escapedMacroClosingChars = preg_quote (self ::$ macroClosingChars );
1008
+
1009
+ preg_match_all ("/ $ escapedMacroOpeningChars(.*?) $ escapedMacroClosingChars/i " , $ documentPartXML , $ matches );
993
1010
994
1011
return $ matches [1 ];
995
1012
}
@@ -1141,8 +1158,11 @@ protected function getSlice($startPosition, $endPosition = 0)
1141
1158
protected function indexClonedVariables ($ count , $ xmlBlock )
1142
1159
{
1143
1160
$ results = [];
1161
+ $ escapedMacroOpeningChars = preg_quote (self ::$ macroOpeningChars );
1162
+ $ escapedMacroClosingChars = preg_quote (self ::$ macroClosingChars );
1163
+
1144
1164
for ($ i = 1 ; $ i <= $ count ; ++$ i ) {
1145
- $ results [] = preg_replace (' /\$\{ ([^:]*?)(:.*?)?\}/ ' , ' \${\ 1# ' . $ i . '\2} ' , $ xmlBlock );
1165
+ $ results [] = preg_replace (" / $ escapedMacroOpeningChars ([^:]*?)(:.*?)? $ escapedMacroClosingChars / " , self :: $ macroOpeningChars . ' \ 1# ' . $ i . '\2 ' . self :: $ macroClosingChars , $ xmlBlock );
1146
1166
}
1147
1167
1148
1168
return $ results ;
@@ -1297,7 +1317,7 @@ protected function splitTextIntoTexts($text)
1297
1317
}
1298
1318
1299
1319
$ unformattedText = preg_replace ('/>\s+</ ' , '>< ' , $ text );
1300
- $ result = str_replace ([' ${ ' , ' } ' ], ['</w:t></w:r><w:r> ' . $ extractedStyle . '<w:t xml:space="preserve">${ ' , ' } </w:t></w:r><w:r> ' . $ extractedStyle . '<w:t xml:space="preserve"> ' ], $ unformattedText );
1320
+ $ result = str_replace ([self :: $ macroOpeningChars , self :: $ macroClosingChars ], ['</w:t></w:r><w:r> ' . $ extractedStyle . '<w:t xml:space="preserve"> ' . self :: $ macroOpeningChars , self :: $ macroClosingChars . ' </w:t></w:r><w:r> ' . $ extractedStyle . '<w:t xml:space="preserve"> ' ], $ unformattedText );
1301
1321
1302
1322
return str_replace (['<w:r> ' . $ extractedStyle . '<w:t xml:space="preserve"></w:t></w:r> ' , '<w:r><w:t xml:space="preserve"></w:t></w:r> ' , '<w:t> ' ], ['' , '' , '<w:t xml:space="preserve"> ' ], $ result );
1303
1323
}
@@ -1311,6 +1331,25 @@ protected function splitTextIntoTexts($text)
1311
1331
*/
1312
1332
protected function textNeedsSplitting ($ text )
1313
1333
{
1314
- return preg_match ('/[^>]\${|}[^<]/i ' , $ text ) == 1 ;
1334
+ $ escapedMacroOpeningChars = preg_quote (self ::$ macroOpeningChars );
1335
+ $ escapedMacroClosingChars = preg_quote (self ::$ macroClosingChars );
1336
+
1337
+ return 1 === preg_match ('/[^>] ' . $ escapedMacroOpeningChars . '| ' . $ escapedMacroClosingChars . '[^<]/i ' , $ text );
1338
+ }
1339
+
1340
+ public function setMacroOpeningChars (string $ macroOpeningChars ): void
1341
+ {
1342
+ self ::$ macroOpeningChars = $ macroOpeningChars ;
1343
+ }
1344
+
1345
+ public function setMacroClosingChars (string $ macroClosingChars ): void
1346
+ {
1347
+ self ::$ macroClosingChars = $ macroClosingChars ;
1348
+ }
1349
+
1350
+ public function setMacroChars (string $ macroOpeningChars , string $ macroClosingChars ): void
1351
+ {
1352
+ self ::$ macroOpeningChars = $ macroOpeningChars ;
1353
+ self ::$ macroClosingChars = $ macroClosingChars ;
1315
1354
}
1316
1355
}
0 commit comments