@@ -33,6 +33,15 @@ class AbstractBlock extends AbstractTag
33
33
*/
34
34
protected static $ trimWhitespace = false ;
35
35
36
+
37
+ private ?string $ whitespaceControl ;
38
+
39
+ private ?Regexp $ startRegexp ;
40
+ private ?Regexp $ tagRegexp ;
41
+ private ?Regexp $ variableStartRegexp ;
42
+
43
+ private ?Regexp $ variableRegexp ;
44
+
36
45
/**
37
46
* @return array
38
47
*/
@@ -51,16 +60,25 @@ public function getNodelist()
51
60
*/
52
61
public function parse (array &$ tokens )
53
62
{
54
- $ startRegexp = new Regexp ('/^ ' . Liquid::get ('TAG_START ' ) . '/ ' );
55
- $ tagRegexp = new Regexp ('/^ ' . Liquid::get ('TAG_START ' ) . Liquid::get ('WHITESPACE_CONTROL ' ) . '?\s*(\w+)\s*(.*?) ' . Liquid::get ('WHITESPACE_CONTROL ' ) . '? ' . Liquid::get ('TAG_END ' ) . '$/s ' );
56
- $ variableStartRegexp = new Regexp ('/^ ' . Liquid::get ('VARIABLE_START ' ) . '/ ' );
63
+ // Constructor is not reliably called by subclasses, so we need to ensure these are set
64
+ $ this ->startRegexp ??= new Regexp ('/^ ' . Liquid::get ('TAG_START ' ) . '/ ' );
65
+ $ this ->tagRegexp ??= new Regexp ('/^ ' . Liquid::get ('TAG_START ' ) . Liquid::get ('WHITESPACE_CONTROL ' ) . '?\s*(\w+)\s*(.*?) ' . Liquid::get ('WHITESPACE_CONTROL ' ) . '? ' . Liquid::get ('TAG_END ' ) . '$/s ' );
66
+ $ this ->variableStartRegexp ??= new Regexp ('/^ ' . Liquid::get ('VARIABLE_START ' ) . '/ ' );
67
+
68
+ $ startRegexp = $ this ->startRegexp ;
69
+ $ tagRegexp = $ this ->tagRegexp ;
70
+ $ variableStartRegexp = $ this ->variableStartRegexp ;
57
71
58
72
$ this ->nodelist = [];
59
73
60
74
$ tags = Template::getTags ();
61
75
62
- while (count ($ tokens )) {
63
- $ token = array_shift ($ tokens );
76
+ for ($ i = 0 , $ n = count ($ tokens ); $ i < $ n ; $ i ++) {
77
+ if ($ tokens [$ i ] === null ) {
78
+ continue ;
79
+ }
80
+ $ token = $ tokens [$ i ];
81
+ $ tokens [$ i ] = null ;
64
82
65
83
if ($ startRegexp ->match ($ token )) {
66
84
$ this ->whitespaceHandler ($ token );
@@ -114,11 +132,13 @@ public function parse(array &$tokens)
114
132
*/
115
133
protected function whitespaceHandler ($ token )
116
134
{
135
+ $ this ->whitespaceControl ??= Liquid::get ('WHITESPACE_CONTROL ' );
136
+
117
137
/*
118
138
* This assumes that TAG_START is always '{%', and a whitespace control indicator
119
139
* is exactly one character long, on a third position.
120
140
*/
121
- if (mb_substr ( $ token, 2 , 1 ) === Liquid:: get ( ' WHITESPACE_CONTROL ' ) ) {
141
+ if ($ token[ 2 ] === $ this -> whitespaceControl ) {
122
142
$ previousToken = end ($ this ->nodelist );
123
143
if (is_string ($ previousToken )) { // this can also be a tag or a variable
124
144
$ this ->nodelist [key ($ this ->nodelist )] = rtrim ($ previousToken );
@@ -129,7 +149,7 @@ protected function whitespaceHandler($token)
129
149
* This assumes that TAG_END is always '%}', and a whitespace control indicator
130
150
* is exactly one character long, on a third position from the end.
131
151
*/
132
- self ::$ trimWhitespace = mb_substr ( $ token, - 3 , 1 ) === Liquid:: get ( ' WHITESPACE_CONTROL ' ) ;
152
+ self ::$ trimWhitespace = $ token[- 3 ] === $ this -> whitespaceControl ;
133
153
}
134
154
135
155
/**
@@ -254,9 +274,10 @@ private function blockName()
254
274
*/
255
275
private function createVariable ($ token )
256
276
{
257
- $ variableRegexp = new Regexp ('/^ ' . Liquid::get ('VARIABLE_START ' ) . Liquid::get ('WHITESPACE_CONTROL ' ) . '?(.*?) ' . Liquid::get ('WHITESPACE_CONTROL ' ) . '? ' . Liquid::get ('VARIABLE_END ' ) . '$/s ' );
258
- if ($ variableRegexp ->match ($ token )) {
259
- return new Variable ($ variableRegexp ->matches [1 ]);
277
+ $ this ->variableRegexp ??= new Regexp ('/^ ' . Liquid::get ('VARIABLE_START ' ) . Liquid::get ('WHITESPACE_CONTROL ' ) . '?(.*?) ' . Liquid::get ('WHITESPACE_CONTROL ' ) . '? ' . Liquid::get ('VARIABLE_END ' ) . '$/s ' );
278
+
279
+ if ($ this ->variableRegexp ->match ($ token )) {
280
+ return new Variable ($ this ->variableRegexp ->matches [1 ]);
260
281
}
261
282
262
283
throw new ParseException ("Variable $ token was not properly terminated " );
0 commit comments