[ Index ] |
|
Code source de eZ Publish 3.9.0 |
1 <?php 2 // 3 // Definition of eZTemplateElementParser class 4 // 5 // Created on: <27-Nov-2002 10:53:36 amos> 6 // 7 // SOFTWARE NAME: eZ publish 8 // SOFTWARE RELEASE: 3.9.0 9 // BUILD VERSION: 17785 10 // COPYRIGHT NOTICE: Copyright (C) 1999-2006 eZ systems AS 11 // SOFTWARE LICENSE: GNU General Public License v2.0 12 // NOTICE: > 13 // This program is free software; you can redistribute it and/or 14 // modify it under the terms of version 2.0 of the GNU General 15 // Public License as published by the Free Software Foundation. 16 // 17 // This program is distributed in the hope that it will be useful, 18 // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 // GNU General Public License for more details. 21 // 22 // You should have received a copy of version 2.0 of the GNU General 23 // Public License along with this program; if not, write to the Free 24 // Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 25 // MA 02110-1301, USA. 26 // 27 // 28 29 /*! \file eztemplateelementparser.php 30 */ 31 32 /*! 33 \class eZTemplateElementParser eztemplateelementparser.php 34 \brief The class eZTemplateElementParser does 35 36 */ 37 38 include_once ( 'lib/eztemplate/classes/eztemplate.php' ); 39 40 class eZTemplateElementParser 41 { 42 /*! 43 Constructor 44 */ 45 function eZTemplateElementParser() 46 { 47 } 48 49 function templateTypeName( $type ) 50 { 51 switch ( $type ) 52 { 53 case EZ_TEMPLATE_TYPE_STRING: 54 return "string"; 55 case EZ_TEMPLATE_TYPE_NUMERIC: 56 return "numeric"; 57 case EZ_TEMPLATE_TYPE_IDENTIFIER: 58 return "identifier"; 59 case EZ_TEMPLATE_TYPE_VARIABLE: 60 return "variable"; 61 case EZ_TEMPLATE_TYPE_ATTRIBUTE: 62 return "attribute"; 63 } 64 return null; 65 } 66 67 /*! 68 Parses the variable and operators into a structure. 69 */ 70 function parseVariableTag( &$tpl, $relatedTemplateName, &$text, $startPosition, &$endPosition, $textLength, $defaultNamespace, 71 $allowedType = false, $maxElements = false, $endMarker = false, 72 $undefinedType = EZ_TEMPLATE_TYPE_ATTRIBUTE ) 73 { 74 $currentPosition = $startPosition; 75 $elements = array(); 76 $lastPosition = false; 77 if ( $allowedType === false ) 78 $allowedType = EZ_TEMPLATE_TYPE_BASIC; 79 while ( $currentPosition < $textLength and 80 ( $maxElements === false or 81 count( $elements ) < $maxElements ) ) 82 { 83 if ( $lastPosition !== false and 84 $lastPosition == $currentPosition ) 85 { 86 $tpl->error( "ElementParser::parseVariableTag", "parser error @ $relatedTemplateName[$currentPosition]\n" . 87 "Parser position did not move, this is most likely a bug in the template parser." ); 88 break; 89 } 90 $lastPosition = $currentPosition; 91 $currentPosition = $this->whitespaceEndPos( $tpl, $text, $currentPosition, $textLength ); 92 if ( $currentPosition >= $textLength ) 93 continue; 94 if ( $endMarker !== false ) 95 { 96 if ( $currentPosition < $textLength and 97 strpos( $endMarker, $text[$currentPosition] ) !== false ) 98 break; 99 } 100 if ( $text[$currentPosition] == '|' ) 101 { 102 if ( !( $allowedType & EZ_TEMPLATE_TYPE_OPERATOR_BIT ) ) 103 { 104 $currentPosition = $lastPosition; 105 break; 106 } 107 $maxOperatorElements = 1; 108 $operatorEndMarker = false; 109 $currentOperatorPosition = $currentPosition + 1; 110 $operatorEndPosition = false; 111 $operatorElements = $this->parseVariableTag( $tpl, $relatedTemplateName, $text, $currentOperatorPosition, $operatorEndPosition, $textLength, $defaultNamespace, 112 EZ_TEMPLATE_TYPE_OPERATOR_BIT, $maxOperatorElements, $operatorEndMarker, EZ_TEMPLATE_TYPE_OPERATOR ); 113 if ( $operatorEndPosition > $currentOperatorPosition ) 114 { 115 $elements = array_merge( $elements, $operatorElements ); 116 $currentPosition = $operatorEndPosition; 117 } 118 } 119 else if ( $text[$currentPosition] == '.' or 120 $text[$currentPosition] == '[' ) 121 { 122 if ( !( $allowedType & EZ_TEMPLATE_TYPE_ATTRIBUTE_BIT ) ) 123 { 124 $currentPosition = $lastPosition; 125 break; 126 } 127 $maxAttributeElements = 1; 128 $attributeEndMarker = false; 129 if ( $text[$currentPosition] == '[' ) 130 { 131 $maxAttributeElements = false; 132 $attributeEndMarker = ']'; 133 } 134 ++$currentPosition; 135 $attributeEndPosition = false; 136 $attributeElements = $this->parseVariableTag( $tpl, $relatedTemplateName, $text, $currentPosition, $attributeEndPosition, $textLength, $defaultNamespace, 137 EZ_TEMPLATE_TYPE_BASIC, $maxAttributeElements, $attributeEndMarker ); 138 if ( $attributeEndPosition > $currentPosition ) 139 { 140 $element = array( EZ_TEMPLATE_TYPE_ATTRIBUTE, // type 141 $attributeElements, // content 142 false // debug 143 ); 144 $elements[] = $element; 145 if ( $attributeEndMarker !== false ) 146 $attributeEndPosition += strlen( $attributeEndMarker ); 147 $currentPosition = $attributeEndPosition; 148 } 149 } 150 else if ( $text[$currentPosition] == "$" ) 151 { 152 if ( !( $allowedType & EZ_TEMPLATE_TYPE_VARIABLE_BIT ) ) 153 { 154 $currentPosition = $lastPosition; 155 break; 156 } 157 ++$currentPosition; 158 $variableEndPosition = $this->variableEndPos( $tpl, $relatedTemplateName, $text, $currentPosition, $textLength, 159 $variableNamespace, $variableName, $namespaceScope ); 160 if ( $variableEndPosition > $currentPosition ) 161 { 162 $element = array( EZ_TEMPLATE_TYPE_VARIABLE, // type 163 array( $variableNamespace, 164 $namespaceScope, 165 $variableName ), // content 166 false // debug 167 ); 168 $elements[] = $element; 169 $currentPosition = $variableEndPosition; 170 $allowedType = EZ_TEMPLATE_TYPE_MODIFIER_MASK; 171 } 172 } 173 else if ( $text[$currentPosition] == "'" or 174 $text[$currentPosition] == '"' ) 175 { 176 if ( !( $allowedType & EZ_TEMPLATE_TYPE_STRING_BIT) ) 177 { 178 $currentPosition = $lastPosition; 179 break; 180 } 181 $quote = $text[$currentPosition]; 182 ++$currentPosition; 183 $quoteEndPosition = $this->quoteEndPos( $tpl, $text, $currentPosition, $textLength, $quote ); 184 $string = substr( $text, $currentPosition, $quoteEndPosition - $currentPosition ); 185 $string = $this->unescapeCharacters( $string ); 186 $element = array( EZ_TEMPLATE_TYPE_STRING, // type 187 $string, // content 188 false // debug 189 ); 190 $elements[] = $element; 191 $currentPosition = $quoteEndPosition + 1; 192 $allowedType = EZ_TEMPLATE_TYPE_OPERATOR_BIT; 193 } 194 else 195 { 196 $float = true; 197 $numericEndPosition = $this->numericEndPos( $tpl, $text, $currentPosition, $textLength, $float ); 198 if ( $numericEndPosition > $currentPosition ) 199 { 200 if ( !( $allowedType & EZ_TEMPLATE_TYPE_NUMERIC_BIT ) ) 201 { 202 $currentPosition = $lastPosition; 203 break; 204 } 205 // We got a number 206 $number = substr( $text, $currentPosition, $numericEndPosition - $currentPosition ); 207 if ( $float ) 208 $number = (float)$number; 209 else 210 $number = (int)$number; 211 $element = array( EZ_TEMPLATE_TYPE_NUMERIC, // type 212 $number, // content 213 false // debug 214 ); 215 $elements[] = $element; 216 $currentPosition = $numericEndPosition; 217 $allowedType = EZ_TEMPLATE_TYPE_OPERATOR_BIT; 218 } 219 else 220 { 221 $identifierEndPosition = $this->identifierEndPosition( $tpl, $text, $currentPosition, $textLength ); 222 if ( $currentPosition == $identifierEndPosition ) 223 { 224 $currentPosition = $lastPosition; 225 break; 226 } 227 if ( ( $identifierEndPosition < $textLength and 228 $text[$identifierEndPosition] == '(' ) or 229 $undefinedType == EZ_TEMPLATE_TYPE_OPERATOR ) 230 { 231 if ( !( $allowedType & EZ_TEMPLATE_TYPE_OPERATOR_BIT ) ) 232 { 233 $currentPosition = $lastPosition; 234 break; 235 } 236 $operatorName = substr( $text, $currentPosition, $identifierEndPosition - $currentPosition ); 237 $operatorParameterElements = array( $operatorName ); 238 239 if ( $identifierEndPosition < $textLength and 240 $text[$identifierEndPosition] == '(' ) 241 { 242 $currentPosition = $identifierEndPosition + 1; 243 $currentOperatorPosition = $currentPosition; 244 $operatorDone = false; 245 $parameterCount = 0; 246 while ( !$operatorDone ) 247 { 248 $operatorEndPosition = false; 249 $operatorParameterElement = $this->parseVariableTag( $tpl, $relatedTemplateName, $text, $currentOperatorPosition, $operatorEndPosition, $textLength, $defaultNamespace, 250 EZ_TEMPLATE_TYPE_BASIC, false, ',)' ); 251 if ( $operatorEndPosition < $textLength and 252 $text[$operatorEndPosition] == ',' ) 253 { 254 if ( $operatorEndPosition == $currentOperatorPosition ) 255 { 256 $operatorParameterElements[] = null; 257 } 258 else 259 $operatorParameterElements[] = $operatorParameterElement; 260 ++$parameterCount; 261 $currentOperatorPosition = $operatorEndPosition + 1; 262 } 263 else if ( $operatorEndPosition < $textLength and 264 $text[$operatorEndPosition] == ')' ) 265 { 266 $operatorDone = true; 267 if ( $operatorEndPosition == $currentOperatorPosition ) 268 { 269 if ( $parameterCount > 0 ) 270 { 271 $operatorParameterElements[] = null; 272 ++$parameterCount; 273 } 274 } 275 else 276 { 277 $operatorParameterElements[] = $operatorParameterElement; 278 ++$parameterCount; 279 } 280 ++$operatorEndPosition; 281 } 282 else 283 { 284 $currentPosition = $lastPosition; 285 break; 286 } 287 } 288 if ( !$operatorDone ) 289 break; 290 } 291 else 292 { 293 $operatorEndPosition = $identifierEndPosition; 294 } 295 296 $element = array( EZ_TEMPLATE_TYPE_OPERATOR, // type 297 $operatorParameterElements, // content 298 false // debug 299 ); 300 $elements[] = $element; 301 $currentPosition = $operatorEndPosition; 302 $allowedType = EZ_TEMPLATE_TYPE_MODIFIER_MASK; 303 } 304 else 305 { 306 if ( !( $allowedType & EZ_TEMPLATE_TYPE_IDENTIFIER_BIT ) ) 307 { 308 $currentPosition = $lastPosition; 309 break; 310 } 311 $identifier = substr( $text, $currentPosition, $identifierEndPosition - $currentPosition ); 312 $element = array( EZ_TEMPLATE_TYPE_IDENTIFIER, // type 313 $identifier, // content 314 false // debug 315 ); 316 $elements[] = $element; 317 $currentPosition = $identifierEndPosition; 318 $allowedType = EZ_TEMPLATE_TYPE_NONE; 319 } 320 } 321 } 322 } 323 $endPosition = $currentPosition; 324 return $elements; 325 } 326 327 /*! 328 Returns the end position of the variable. 329 */ 330 function variableEndPos( &$tpl, $relatedTemplateName, &$text, $startPosition, $textLength, 331 &$namespace, &$name, &$scope ) 332 { 333 $currentPosition = $startPosition; 334 $namespaces = array(); 335 $variableName = false; 336 $lastPosition = false; 337 $scopeType = EZ_TEMPLATE_NAMESPACE_SCOPE_LOCAL; 338 $scopeRead = false; 339 while ( $currentPosition < $textLength ) 340 { 341 if ( $lastPosition !== false and 342 $lastPosition == $currentPosition ) 343 { 344 $tpl->error( "ElementParser::variableEndPos", "parser error @ $relatedTemplateName\[" . $currentPosition . "]\n" . 345 "Parser position did not move, this is most likely a bug in the template parser." ); 346 break; 347 } 348 $lastPosition = $currentPosition; 349 if ( $text[$currentPosition] == '#' ) 350 { 351 if ( $scopeRead ) 352 { 353 $tpl->error( "ElementParser::variableEndPos", "parser error @ $relatedTemplateName\[" . $currentPosition . "]\n" . 354 "Namespace scope already declared, cannot set to global." ); 355 } 356 else 357 { 358 $scopeType = EZ_TEMPLATE_NAMESPACE_SCOPE_GLOBAL; 359 } 360 $scopeRead = true; 361 ++$currentPosition; 362 } 363 else if ( $text[$currentPosition] == ':' ) 364 { 365 if ( $scopeRead ) 366 { 367 $tpl->error( "ElementParser::variableEndPos", "parser error @ $relatedTemplateName\[" . $currentPosition . "]\n" . 368 "Namespace scope already declared, cannot set to relative." ); 369 } 370 else 371 { 372 $scopeType = EZ_TEMPLATE_NAMESPACE_SCOPE_RELATIVE; 373 } 374 $scopeRead = true; 375 ++$currentPosition; 376 } 377 else 378 { 379 $identifierEndPosition = $this->identifierEndPosition( $tpl, $text, $currentPosition, $textLength ); 380 if ( $identifierEndPosition > $currentPosition ) 381 { 382 $identifier = substr( $text, $currentPosition, $identifierEndPosition - $currentPosition ); 383 $currentPosition = $identifierEndPosition; 384 if ( $identifierEndPosition < $textLength and 385 $text[$identifierEndPosition] == ':' ) 386 { 387 $namespaces[] = $identifier; 388 ++$currentPosition; 389 } 390 else 391 $variableName = $identifier; 392 } 393 else if ( $identifierEndPosition < $textLength and 394 ( $text[$identifierEndPosition] != ":" and 395 $text[$identifierEndPosition] != "#" ) ) 396 { 397 if ( $variableName === false ) 398 { 399 $tpl->error( "ElementParser::variableEndPos", "parser error @ $relatedTemplateName\[" . $currentPosition . "]\n" . 400 "No variable name found, this is most likely a bug in the template parser." ); 401 return $startPosition; 402 } 403 break; 404 } 405 else 406 { 407 $tpl->error( "ElementParser::variableEndPos", "parser error @ $relatedTemplateName\[" . $currentPosition . "]\n" . 408 "Missing identifier for variable name or namespace, this is most likely a bug in the template parser." ); 409 return $startPosition; 410 } 411 } 412 } 413 $scope = $scopeType; 414 $namespace = implode( ':', $namespaces ); 415 $name = $variableName; 416 return $currentPosition; 417 } 418 419 /*! 420 Finds any escaped characters and unescapes them if they are one of: 421 - \n - A newline 422 - \r - A carriage return 423 - \t - A tab 424 - \' - A single quote 425 - \" - A double quote 426 427 If the escaped character is not known it keeps both characters (escape + character). 428 \return The transformed string without escape characters. 429 */ 430 function unescapeCharacters( $string ) 431 { 432 $newString = ''; 433 $len = strlen( $string ); 434 435 // Fix escaped characters (double-quote, single-quote, newline, carriage-return, tab) 436 for ( $i = 0; $i < $len; ++$i ) 437 { 438 $c = $string[$i]; 439 440 // If we don't have an escape character we keep it as-is 441 if ( $c != "\\" ) 442 { 443 $newString .= $c; 444 continue; 445 } 446 447 // If this is the last character we keep it as-is 448 if ( $i + 1 >= $len ) 449 { 450 $newString .= $c; 451 break; 452 } 453 454 $c2 = $string[++$i]; 455 switch ( $c2 ) 456 { 457 case 'n': 458 { 459 $newString .= "\n"; 460 } break; 461 462 case 'r': 463 { 464 $newString .= "\r"; 465 } break; 466 467 case 't': 468 { 469 $newString .= "\t"; 470 } break; 471 472 case "'": 473 case '"': 474 case '\\': 475 { 476 $newString .= $c2; 477 } break; 478 479 // If it is not known we keep the characters. 480 default: 481 { 482 $newString .= $c . $c2; 483 } 484 } 485 } 486 return $newString; 487 } 488 489 /*! 490 Returns the end position of the identifier. 491 If no identifier was found the end position is returned. 492 */ 493 function identifierEndPosition( &$tpl, &$text, $start_pos, $len ) 494 { 495 $pos = $start_pos; 496 while ( $pos < $len ) 497 { 498 if ( !preg_match( "/^[a-zA-Z0-9_-]$/", $text[$pos] ) ) 499 { 500 return $pos; 501 } 502 ++$pos; 503 } 504 return $pos; 505 } 506 507 /*! 508 Returns the end position of the quote $quote. 509 If no quote was found the end position is returned. 510 */ 511 function quoteEndPos( &$tpl, &$text, $startPosition, $textLength, $quote ) 512 { 513 $currentPosition = $startPosition; 514 while ( $currentPosition < $textLength ) 515 { 516 if ( $text[$currentPosition] == "\\" ) 517 ++$currentPosition; 518 else if ( $text[$currentPosition] == $quote ) 519 return $currentPosition; 520 ++$currentPosition; 521 } 522 return $currentPosition; 523 } 524 525 /*! 526 Returns the end position of the numeric. 527 If no numeric was found the end position is returned. 528 */ 529 function numericEndPos( &$tpl, &$text, $start_pos, $len, 530 &$float ) 531 { 532 $pos = $start_pos; 533 $has_comma = false; 534 $numberPos = $pos; 535 if ( $pos < $len ) 536 { 537 if ( $text[$pos] == '-' ) 538 { 539 ++$pos; 540 $numberPos = $pos; 541 } 542 } 543 while ( $pos < $len ) 544 { 545 if ( $text[$pos] == "." and $float ) 546 { 547 if ( $has_comma ) 548 { 549 if ( !$has_comma and 550 $float ) 551 $float = false; 552 return $pos; 553 } 554 $has_comma = $pos; 555 } 556 else if ( $text[$pos] < '0' or $text[$pos] > '9' ) 557 { 558 if ( !$has_comma and 559 $float ) 560 $float = false; 561 if ( $pos < $len and 562 $has_comma and 563 $pos == $has_comma + 1 ) 564 { 565 return $start_pos; 566 } 567 if ( $pos == $numberPos ) 568 { 569 return $start_pos; 570 } 571 return $pos; 572 } 573 ++$pos; 574 } 575 if ( !$has_comma and 576 $float ) 577 $float = false; 578 if ( $has_comma and 579 $start_pos + 1 == $pos ) 580 { 581 return $start_pos; 582 } 583 return $pos; 584 } 585 586 /*! 587 Returns the position of the first non-whitespace characters. 588 */ 589 function whitespaceEndPos( &$tpl, &$text, $currentPosition, $textLength ) 590 { 591 if ( $currentPosition >= $textLength ) 592 return $currentPosition; 593 while( $currentPosition < $textLength and 594 preg_match( "/[ \t\r\n]/", $text[$currentPosition] ) ) 595 { 596 ++$currentPosition; 597 } 598 return $currentPosition; 599 } 600 601 /*! 602 Returns the position of the first non-whitespace characters. 603 */ 604 function isWhitespace( &$tpl, &$text, $startPosition ) 605 { 606 return preg_match( "/[ \t\r\n]/", $text[$startPosition] ); 607 } 608 609 function &instance() 610 { 611 $instance =& $GLOBALS['eZTemplateElementParserInstance']; 612 if ( get_class( $instance ) != 'eztemplateelementparser' ) 613 { 614 $instance = new eZTemplateElementParser(); 615 } 616 return $instance; 617 } 618 619 } 620 621 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sat Feb 24 10:30:04 2007 | par Balluche grâce à PHPXref 0.7 |