Exponential 6.0.13 Exponential Enterprise Open Source CMS - PHP Class Reference

eztemplateelementparser.php
Go to the documentation of this file.
1 <?php
17 class eZTemplateElementParser
18 {
19 function templateTypeName( $type )
20 {
21 switch ( $type )
22 {
23 case eZTemplate::TYPE_STRING:
24 return "string";
25 case eZTemplate::TYPE_NUMERIC:
26 return "numeric";
27 case eZTemplate::TYPE_IDENTIFIER:
28 return "identifier";
29 case eZTemplate::TYPE_VARIABLE:
30 return "variable";
31 case eZTemplate::TYPE_ATTRIBUTE:
32 return "attribute";
33 }
34 return null;
35 }
36
40 function parseVariableTag( $tpl, $relatedTemplateName, &$text, $startPosition, &$endPosition, $textLength, $defaultNamespace,
41 $allowedType = false, $maxElements = false, $endMarker = false,
42 $undefinedType = eZTemplate::TYPE_ATTRIBUTE )
43 {
44 $currentPosition = $startPosition;
45 $elements = array();
46 $lastPosition = false;
47 if ( $allowedType === false )
48 $allowedType = eZTemplate::TYPE_BASIC;
49 while ( $currentPosition < $textLength and
50 ( $maxElements === false or
51 count( $elements ) < $maxElements ) )
52 {
53 if ( $lastPosition !== false and
54 $lastPosition == $currentPosition )
55 {
56 $tpl->error( "ElementParser::parseVariableTag", "parser error @ $relatedTemplateName[$currentPosition]\n" .
57 "Parser position did not move, this is most likely a bug in the template parser." );
58 break;
59 }
60 $lastPosition = $currentPosition;
61 $currentPosition = $this->whitespaceEndPos( $tpl, $text, $currentPosition, $textLength );
62 if ( $currentPosition >= $textLength )
63 continue;
64 if ( $endMarker !== false )
65 {
66 if ( $currentPosition < $textLength and
67 strpos( $endMarker, $text[$currentPosition] ) !== false )
68 break;
69 }
70 if ( $text[$currentPosition] == '|' )
71 {
72 if ( !( $allowedType & eZTemplate::TYPE_OPERATOR_BIT ) )
73 {
74 $currentPosition = $lastPosition;
75 break;
76 }
77 $maxOperatorElements = 1;
78 $operatorEndMarker = false;
79 $currentOperatorPosition = $currentPosition + 1;
80 $operatorEndPosition = false;
81 $operatorElements = $this->parseVariableTag( $tpl, $relatedTemplateName, $text, $currentOperatorPosition, $operatorEndPosition, $textLength, $defaultNamespace,
82 eZTemplate::TYPE_OPERATOR_BIT, $maxOperatorElements, $operatorEndMarker, eZTemplate::TYPE_OPERATOR );
83 if ( $operatorEndPosition > $currentOperatorPosition )
84 {
85 $elements = array_merge( $elements, $operatorElements );
86 $currentPosition = $operatorEndPosition;
87 }
88 }
89 else if ( $text[$currentPosition] == '.' or
90 $text[$currentPosition] == '[' )
91 {
92 if ( !( $allowedType & eZTemplate::TYPE_ATTRIBUTE_BIT ) )
93 {
94 $currentPosition = $lastPosition;
95 break;
96 }
97 $maxAttributeElements = 1;
98 $attributeEndMarker = false;
99 if ( $text[$currentPosition] == '[' )
100 {
101 $maxAttributeElements = false;
102 $attributeEndMarker = ']';
103 }
104 ++$currentPosition;
105 $attributeEndPosition = false;
106 $attributeElements = $this->parseVariableTag( $tpl, $relatedTemplateName, $text, $currentPosition, $attributeEndPosition, $textLength, $defaultNamespace,
107 eZTemplate::TYPE_BASIC, $maxAttributeElements, $attributeEndMarker );
108 if ( $attributeEndPosition > $currentPosition )
109 {
110 $element = array( eZTemplate::TYPE_ATTRIBUTE, // type
111 $attributeElements, // content
112 false // debug
113 );
114 $elements[] = $element;
115 if ( $attributeEndMarker !== false )
116 $attributeEndPosition += strlen( $attributeEndMarker );
117 $currentPosition = $attributeEndPosition;
118 }
119 }
120 else if ( $text[$currentPosition] == "$" )
121 {
122 if ( !( $allowedType & eZTemplate::TYPE_VARIABLE_BIT ) )
123 {
124 $currentPosition = $lastPosition;
125 break;
126 }
127 ++$currentPosition;
128 $variableEndPosition = $this->variableEndPos( $tpl, $relatedTemplateName, $text, $currentPosition, $textLength,
129 $variableNamespace, $variableName, $namespaceScope );
130 if ( $variableEndPosition > $currentPosition )
131 {
132 $element = array( eZTemplate::TYPE_VARIABLE, // type
133 array( $variableNamespace,
134 $namespaceScope,
135 $variableName ), // content
136 false // debug
137 );
138 $elements[] = $element;
139 $currentPosition = $variableEndPosition;
140 $allowedType = eZTemplate::TYPE_MODIFIER_MASK;
141 }
142 }
143 else if ( $text[$currentPosition] == "'" or
144 $text[$currentPosition] == '"' )
145 {
146 if ( !( $allowedType & eZTemplate::TYPE_STRING_BIT) )
147 {
148 $currentPosition = $lastPosition;
149 break;
150 }
151 $quote = $text[$currentPosition];
152 ++$currentPosition;
153 $quoteEndPosition = $this->quoteEndPos( $tpl, $text, $currentPosition, $textLength, $quote );
154 $string = substr( $text, $currentPosition, $quoteEndPosition - $currentPosition );
155 $string = $this->unescapeCharacters( $string );
156 $element = array( eZTemplate::TYPE_STRING, // type
157 $string, // content
158 false // debug
159 );
160 $elements[] = $element;
161 $currentPosition = $quoteEndPosition + 1;
162 $allowedType = eZTemplate::TYPE_OPERATOR_BIT;
163 }
164 else
165 {
166 $float = true;
167 $numericEndPosition = $this->numericEndPos( $tpl, $text, $currentPosition, $textLength, $float );
168 if ( $numericEndPosition > $currentPosition )
169 {
170 if ( !( $allowedType & eZTemplate::TYPE_NUMERIC_BIT ) )
171 {
172 $currentPosition = $lastPosition;
173 break;
174 }
175 // We got a number
176 $number = substr( $text, $currentPosition, $numericEndPosition - $currentPosition );
177 if ( $float )
178 $number = (float)$number;
179 else
180 $number = (int)$number;
181 $element = array( eZTemplate::TYPE_NUMERIC, // type
182 $number, // content
183 false // debug
184 );
185 $elements[] = $element;
186 $currentPosition = $numericEndPosition;
187 $allowedType = eZTemplate::TYPE_OPERATOR_BIT;
188 }
189 else
190 {
191 $identifierEndPosition = $this->identifierEndPosition( $tpl, $text, $currentPosition, $textLength );
192 if ( $currentPosition == $identifierEndPosition )
193 {
194 $currentPosition = $lastPosition;
195 break;
196 }
197 if ( ( $identifierEndPosition < $textLength and
198 $text[$identifierEndPosition] == '(' ) or
199 $undefinedType == eZTemplate::TYPE_OPERATOR )
200 {
201 if ( !( $allowedType & eZTemplate::TYPE_OPERATOR_BIT ) )
202 {
203 $currentPosition = $lastPosition;
204 break;
205 }
206 $operatorName = substr( $text, $currentPosition, $identifierEndPosition - $currentPosition );
207 $operatorParameterElements = array( $operatorName );
208
209 if ( $identifierEndPosition < $textLength and
210 $text[$identifierEndPosition] == '(' )
211 {
212 $currentPosition = $identifierEndPosition + 1;
213 $currentOperatorPosition = $currentPosition;
214 $operatorDone = false;
215 $parameterCount = 0;
216 while ( !$operatorDone )
217 {
218 $operatorEndPosition = false;
219 $operatorParameterElement = $this->parseVariableTag( $tpl, $relatedTemplateName, $text, $currentOperatorPosition, $operatorEndPosition, $textLength, $defaultNamespace,
220 eZTemplate::TYPE_BASIC, false, ',)' );
221 if ( $operatorEndPosition < $textLength and
222 $text[$operatorEndPosition] == ',' )
223 {
224 if ( $operatorEndPosition == $currentOperatorPosition )
225 {
226 $operatorParameterElements[] = null;
227 }
228 else
229 $operatorParameterElements[] = $operatorParameterElement;
230 ++$parameterCount;
231 $currentOperatorPosition = $operatorEndPosition + 1;
232 }
233 else if ( $operatorEndPosition < $textLength and
234 $text[$operatorEndPosition] == ')' )
235 {
236 $operatorDone = true;
237 if ( $operatorEndPosition == $currentOperatorPosition )
238 {
239 if ( $parameterCount > 0 )
240 {
241 $operatorParameterElements[] = null;
242 ++$parameterCount;
243 }
244 }
245 else
246 {
247 $operatorParameterElements[] = $operatorParameterElement;
248 ++$parameterCount;
249 }
250 ++$operatorEndPosition;
251 }
252 else
253 {
254 $currentPosition = $lastPosition;
255 break;
256 }
257 }
258 if ( !$operatorDone )
259 break;
260 }
261 else
262 {
263 $operatorEndPosition = $identifierEndPosition;
264 }
265
266 $element = array( eZTemplate::TYPE_OPERATOR, // type
267 $operatorParameterElements, // content
268 false // debug
269 );
270 $elements[] = $element;
271 $currentPosition = $operatorEndPosition;
272 $allowedType = eZTemplate::TYPE_MODIFIER_MASK;
273 }
274 else
275 {
276 if ( !( $allowedType & eZTemplate::TYPE_IDENTIFIER_BIT ) )
277 {
278 $currentPosition = $lastPosition;
279 break;
280 }
281 $identifier = substr( $text, $currentPosition, $identifierEndPosition - $currentPosition );
282 $element = array( eZTemplate::TYPE_IDENTIFIER, // type
283 $identifier, // content
284 false // debug
285 );
286 $elements[] = $element;
287 $currentPosition = $identifierEndPosition;
288 $allowedType = eZTemplate::TYPE_NONE;
289 }
290 }
291 }
292 }
293 $endPosition = $currentPosition;
294 return $elements;
295 }
296
300 function variableEndPos( $tpl, $relatedTemplateName, &$text, $startPosition, $textLength,
301 &$namespace, &$name, &$scope )
302 {
303 $currentPosition = $startPosition;
304 $namespaces = array();
305 $variableName = false;
306 $lastPosition = false;
307 $scopeType = eZTemplate::NAMESPACE_SCOPE_LOCAL;
308 $scopeRead = false;
309 while ( $currentPosition < $textLength )
310 {
311 if ( $lastPosition !== false and
312 $lastPosition == $currentPosition )
313 {
314 $tpl->error( "ElementParser::variableEndPos", "parser error @ $relatedTemplateName\[" . $currentPosition . "]\n" .
315 "Parser position did not move, this is most likely a bug in the template parser." );
316 break;
317 }
318 $lastPosition = $currentPosition;
319 if ( $text[$currentPosition] == '#' )
320 {
321 if ( $scopeRead )
322 {
323 $tpl->error( "ElementParser::variableEndPos", "parser error @ $relatedTemplateName\[" . $currentPosition . "]\n" .
324 "Namespace scope already declared, cannot set to global." );
325 }
326 else
327 {
328 $scopeType = eZTemplate::NAMESPACE_SCOPE_GLOBAL;
329 }
330 $scopeRead = true;
331 ++$currentPosition;
332 }
333 else if ( $text[$currentPosition] == ':' )
334 {
335 if ( $scopeRead )
336 {
337 $tpl->error( "ElementParser::variableEndPos", "parser error @ $relatedTemplateName\[" . $currentPosition . "]\n" .
338 "Namespace scope already declared, cannot set to relative." );
339 }
340 else
341 {
342 $scopeType = eZTemplate::NAMESPACE_SCOPE_RELATIVE;
343 }
344 $scopeRead = true;
345 ++$currentPosition;
346 }
347 else
348 {
349 $identifierEndPosition = $this->identifierEndPosition( $tpl, $text, $currentPosition, $textLength );
350 if ( $identifierEndPosition > $currentPosition )
351 {
352 $identifier = substr( $text, $currentPosition, $identifierEndPosition - $currentPosition );
353 $currentPosition = $identifierEndPosition;
354 if ( $identifierEndPosition < $textLength and
355 $text[$identifierEndPosition] == ':' )
356 {
357 $namespaces[] = $identifier;
358 ++$currentPosition;
359 }
360 else
361 $variableName = $identifier;
362 }
363 else if ( $identifierEndPosition < $textLength and
364 ( $text[$identifierEndPosition] != ":" and
365 $text[$identifierEndPosition] != "#" ) )
366 {
367 if ( $variableName === false )
368 {
369 $tpl->error( "ElementParser::variableEndPos", "parser error @ $relatedTemplateName\[" . $currentPosition . "]\n" .
370 "No variable name found, this is most likely a bug in the template parser." );
371 return $startPosition;
372 }
373 break;
374 }
375 else
376 {
377 $tpl->error( "ElementParser::variableEndPos", "parser error @ $relatedTemplateName\[" . $currentPosition . "]\n" .
378 "Missing identifier for variable name or namespace, this is most likely a bug in the template parser." );
379 return $startPosition;
380 }
381 }
382 }
383 $scope = $scopeType;
384 $namespace = implode( ':', $namespaces );
385 $name = $variableName;
386 return $currentPosition;
387 }
388
400 function unescapeCharacters( $string )
401 {
402 $newString = '';
403 $len = strlen( $string );
404
405 // Fix escaped characters (double-quote, single-quote, newline, carriage-return, tab)
406 for ( $i = 0; $i < $len; ++$i )
407 {
408 $c = $string[$i];
409
410 // If we don't have an escape character we keep it as-is
411 if ( $c != "\\" )
412 {
413 $newString .= $c;
414 continue;
415 }
416
417 // If this is the last character we keep it as-is
418 if ( $i + 1 >= $len )
419 {
420 $newString .= $c;
421 break;
422 }
423
424 $c2 = $string[++$i];
425 switch ( $c2 )
426 {
427 case 'n':
428 {
429 $newString .= "\n";
430 } break;
431
432 case 'r':
433 {
434 $newString .= "\r";
435 } break;
436
437 case 't':
438 {
439 $newString .= "\t";
440 } break;
441
442 case "'":
443 case '"':
444 case '\\':
445 {
446 $newString .= $c2;
447 } break;
448
449 // If it is not known we keep the characters.
450 default:
451 {
452 $newString .= $c . $c2;
453 }
454 }
455 }
456 return $newString;
457 }
458
463 function identifierEndPosition( $tpl, &$text, $start_pos, $len )
464 {
465 $pos = $start_pos;
466 while ( $pos < $len )
467 {
468 if ( !preg_match( "/^[a-zA-Z0-9_-]$/", $text[$pos] ) )
469 {
470 return $pos;
471 }
472 ++$pos;
473 }
474 return $pos;
475 }
476
481 function quoteEndPos( $tpl, &$text, $startPosition, $textLength, $quote )
482 {
483 $currentPosition = $startPosition;
484 while ( $currentPosition < $textLength )
485 {
486 if ( $text[$currentPosition] == "\\" )
487 ++$currentPosition;
488 else if ( $text[$currentPosition] == $quote )
489 return $currentPosition;
490 ++$currentPosition;
491 }
492 return $currentPosition;
493 }
494
499 function numericEndPos( $tpl, &$text, $start_pos, $len,
500 &$float )
501 {
502 $pos = $start_pos;
503 $has_comma = false;
504 $numberPos = $pos;
505 if ( $pos < $len )
506 {
507 if ( $text[$pos] == '-' )
508 {
509 ++$pos;
510 $numberPos = $pos;
511 }
512 }
513 while ( $pos < $len )
514 {
515 if ( $text[$pos] == "." and $float )
516 {
517 if ( $has_comma )
518 {
519 if ( !$has_comma and
520 $float )
521 $float = false;
522 return $pos;
523 }
524 $has_comma = $pos;
525 }
526 else if ( $text[$pos] < '0' or $text[$pos] > '9' )
527 {
528 if ( !$has_comma and
529 $float )
530 $float = false;
531 if ( $pos < $len and
532 $has_comma and
533 $pos == $has_comma + 1 )
534 {
535 return $start_pos;
536 }
537 if ( $pos == $numberPos )
538 {
539 return $start_pos;
540 }
541 return $pos;
542 }
543 ++$pos;
544 }
545 if ( !$has_comma and
546 $float )
547 $float = false;
548 if ( $has_comma and
549 $start_pos + 1 == $pos )
550 {
551 return $start_pos;
552 }
553 return $pos;
554 }
555
559 function whitespaceEndPos( $tpl, &$text, $currentPosition, $textLength )
560 {
561 if ( $currentPosition >= $textLength )
562 return $currentPosition;
563 while( $currentPosition < $textLength and
564 ( $text[$currentPosition] === ' '
565 or $text[$currentPosition] === "\n"
566 or $text[$currentPosition] === "\t"
567 or $text[$currentPosition] === "\r" ) )
568 {
569 ++$currentPosition;
570 }
571 return $currentPosition;
572 }
573
577 function isWhitespace( $tpl, &$text, $startPosition )
578 {
579 return ( $text[$startPosition] === ' '
580 or $text[$startPosition] === "\n"
581 or $text[$startPosition] === "\t"
582 or $text[$startPosition] === "\r" );
583 }
584
590 static function instance()
591 {
592 if ( !isset( $GLOBALS['eZTemplateElementParserInstance'] ) ||
593 !( $GLOBALS['eZTemplateElementParserInstance'] instanceof eZTemplateElementParser ) )
594 {
595 $GLOBALS['eZTemplateElementParserInstance'] = new eZTemplateElementParser();
596 }
597
598 return $GLOBALS['eZTemplateElementParserInstance'];
599 }
600
601 }
602
603 ?>
eZTemplateElementParser
The class eZTemplateElementParser does.
Definition: eztemplateelementparser.php:18
eZTemplateElementParser\identifierEndPosition
identifierEndPosition( $tpl, &$text, $start_pos, $len)
Definition: eztemplateelementparser.php:463
eZTemplateElementParser\whitespaceEndPos
whitespaceEndPos( $tpl, &$text, $currentPosition, $textLength)
Definition: eztemplateelementparser.php:559
eZTemplateElementParser\unescapeCharacters
unescapeCharacters( $string)
Definition: eztemplateelementparser.php:400
eZTemplateElementParser\variableEndPos
variableEndPos( $tpl, $relatedTemplateName, &$text, $startPosition, $textLength, &$namespace, &$name, &$scope)
Definition: eztemplateelementparser.php:300
eZTemplateElementParser\parseVariableTag
parseVariableTag( $tpl, $relatedTemplateName, &$text, $startPosition, &$endPosition, $textLength, $defaultNamespace, $allowedType=false, $maxElements=false, $endMarker=false, $undefinedType=eZTemplate::TYPE_ATTRIBUTE)
Definition: eztemplateelementparser.php:40
eZTemplateElementParser\quoteEndPos
quoteEndPos( $tpl, &$text, $startPosition, $textLength, $quote)
Definition: eztemplateelementparser.php:481
eZTemplateElementParser\templateTypeName
templateTypeName( $type)
Definition: eztemplateelementparser.php:19
eZTemplateElementParser\instance
static instance()
Definition: eztemplateelementparser.php:590
eZTemplateElementParser\isWhitespace
isWhitespace( $tpl, &$text, $startPosition)
Definition: eztemplateelementparser.php:577
eZTemplateElementParser\numericEndPos
numericEndPos( $tpl, &$text, $start_pos, $len, &$float)
Definition: eztemplateelementparser.php:499
eZTemplate\NAMESPACE_SCOPE_RELATIVE
const NAMESPACE_SCOPE_RELATIVE
Definition: eztemplate.php:286
eZTemplate\TYPE_OPERATOR
const TYPE_OPERATOR
Definition: eztemplate.php:252
eZTemplate\TYPE_VARIABLE
const TYPE_VARIABLE
Definition: eztemplate.php:250
eZTemplate\TYPE_NONE
const TYPE_NONE
Definition: eztemplate.php:276
eZTemplate\NAMESPACE_SCOPE_GLOBAL
const NAMESPACE_SCOPE_GLOBAL
Definition: eztemplate.php:284
eZTemplate\TYPE_STRING_BIT
const TYPE_STRING_BIT
Definition: eztemplate.php:269
eZTemplate\TYPE_IDENTIFIER_BIT
const TYPE_IDENTIFIER_BIT
Definition: eztemplate.php:271
eZTemplate\NAMESPACE_SCOPE_LOCAL
const NAMESPACE_SCOPE_LOCAL
Definition: eztemplate.php:285
eZTemplate\TYPE_NUMERIC_BIT
const TYPE_NUMERIC_BIT
Definition: eztemplate.php:270
eZTemplate\TYPE_ATTRIBUTE_BIT
const TYPE_ATTRIBUTE_BIT
Definition: eztemplate.php:273
eZTemplate\TYPE_BASIC
const TYPE_BASIC
Definition: eztemplate.php:280
eZTemplate\TYPE_ATTRIBUTE
const TYPE_ATTRIBUTE
Definition: eztemplate.php:251
eZTemplate\TYPE_IDENTIFIER
const TYPE_IDENTIFIER
Definition: eztemplate.php:249
eZTemplate\TYPE_NUMERIC
const TYPE_NUMERIC
Definition: eztemplate.php:248
eZTemplate\TYPE_STRING
const TYPE_STRING
Definition: eztemplate.php:247
eZTemplate\TYPE_OPERATOR_BIT
const TYPE_OPERATOR_BIT
Definition: eztemplate.php:274
eZTemplate\TYPE_MODIFIER_MASK
const TYPE_MODIFIER_MASK
Definition: eztemplate.php:282
eZTemplate\TYPE_VARIABLE_BIT
const TYPE_VARIABLE_BIT
Definition: eztemplate.php:272
Copyright © 1998 – 2026 7x. All rights reserved. Licensed under the GNU GPLv2+.