[ Index ]
 

Code source de eZ Publish 3.9.0

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/lib/eztemplate/classes/ -> eztemplateelementparser.php (source)

   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  ?>


Généré le : Sat Feb 24 10:30:04 2007 par Balluche grâce à PHPXref 0.7