[ Index ]
 

Code source de eZ Publish 3.9.0

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

title

Body

[fermer]

/kernel/classes/datatypes/ezxmltext/ -> ezxmloutputhandler.php (source)

   1  <?php
   2  //
   3  // Definition of eZXMLOutputHandler class
   4  //
   5  // Created on: <06-Nov-2002 15:10:02 wy>
   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 ezxmloutputhandler.php
  30  */
  31  
  32  /*!
  33    \class eZXMLOutputHandler ezxmloutputhandler
  34    \ingroup eZDatatype
  35    \brief The class eZXMLOutputHandler does
  36  
  37  */
  38  
  39  include_once ( "lib/ezxml/classes/ezxml.php" );
  40  
  41  include_once ( 'kernel/classes/datatypes/ezurl/ezurl.php' );
  42  include_once ( 'lib/eztemplate/classes/eztemplateincludefunction.php' );
  43  
  44  include_once ( "lib/ezxml/classes/ezxml.php" );
  45  
  46  if ( !class_exists( 'eZXMLSchema' ) )
  47      include_once ( 'kernel/classes/datatypes/ezxmltext/ezxmlschema.php' );
  48  
  49  class eZXMLOutputHandler
  50  {
  51      /*!
  52       Constructor
  53      */
  54      function eZXMLOutputHandler( &$xmlData, $aliasedType, $contentObjectAttribute = null )
  55      {
  56          $this->XMLData =& $xmlData;
  57          $this->AliasedType = $aliasedType;
  58          $this->AliasedHandler = null;
  59  
  60          if ( is_object( $contentObjectAttribute ) )
  61          {
  62              $this->ContentObjectAttribute =& $contentObjectAttribute;
  63              $this->ObjectAttributeID = $contentObjectAttribute->attribute( 'id' );
  64          }
  65  
  66          $ini =& eZINI::instance( 'ezxml.ini' );
  67          if ( $ini->hasVariable( 'InputSettings', 'AllowMultipleSpaces' ) )
  68          {
  69              $allowMultipleSpaces = $ini->variable( 'InputSettings', 'AllowMultipleSpaces' );
  70              $this->AllowMultipleSpaces = $allowMultipleSpaces == 'true' ? true : false;
  71          }
  72          if ( $ini->hasVariable( 'InputSettings', 'AllowNumericEntities' ) )
  73          {
  74              $allowNumericEntities = $ini->variable( 'InputSettings', 'AllowNumericEntities' );
  75              $this->AllowNumericEntities = $allowNumericEntities == 'true' ? true : false;
  76          }
  77      }
  78  
  79      /*!
  80       \return an array with attribute names.
  81      */
  82      function attributes()
  83      {
  84          return array( 'output_text',
  85                        'aliased_type',
  86                        'aliased_handler',
  87                        'view_template_name' );
  88      }
  89  
  90      /*!
  91       \return true if the attribute \a $name exists.
  92      */
  93      function hasAttribute( $name )
  94      {
  95          return in_array( $name, $this->attributes() );
  96      }
  97  
  98      /*!
  99       \return the value of the attribute \a $name if it exists, if not returns \c null.
 100      */
 101      function &attribute( $name )
 102      {
 103          switch ( $name )
 104          {
 105              case 'output_text':
 106              {
 107                  $retValue =& $this->outputText();
 108              } break;
 109              case 'aliased_type':
 110              {
 111                  return $this->AliasedType;
 112              } break;
 113              case 'view_template_name':
 114              {
 115                  $retValue =& $this->viewTemplateName();
 116              } break;
 117              case 'aliased_handler':
 118              {
 119                  if ( $this->AliasedType !== false and
 120                       $this->AliasHandler === null )
 121                  {
 122                      $this->AliasedHandler =& eZXMLText::inputHandler( $this->XMLData,
 123                                                                        $this->AliasedType,
 124                                                                        false );
 125                  }
 126                  return $this->AliasedHandler;
 127              } break;
 128              default:
 129              {
 130                  eZDebug::writeError( "Attribute '$name' does not exist", 'eZXMLOutputHandler::attribute' );
 131                  $retValue = null;
 132              } break;
 133          }
 134          return $retValue;
 135      }
 136  
 137      /*!
 138       \return the template name for this input handler, includes the edit suffix if any.
 139      */
 140      function &viewTemplateName()
 141      {
 142          $name = 'ezxmltext';
 143          $suffix = $this->viewTemplateSuffix();
 144          if ( $suffix !== false )
 145              $name .= '_' . $suffix;
 146          return $name;
 147      }
 148  
 149      /*!
 150       \virtual
 151       \return true if the output handler is considered valid, if not the handler will not be used.
 152       \note Default returns true
 153      */
 154      function isValid()
 155      {
 156          return true;
 157      }
 158  
 159      /*!
 160       \pure
 161       \return the suffix for the attribute template, if false it is ignored.
 162      */
 163      function &viewTemplateSuffix( &$contentobjectAttribute )
 164      {
 165          $suffix = false;
 166          return $suffix;
 167      }
 168  
 169      /*!
 170       \return the xml data as text.
 171      */
 172      function xmlData()
 173      {
 174          return $this->XMLData;
 175      }
 176  
 177      /*!
 178       Returns the output text representation of the XML structure
 179       Default implementation uses default mechanism of rules and tag handlers to render tags.
 180       */
 181      function &outputText()
 182      {
 183          $this->Tpl =& templateInit();
 184          $this->Res =& eZTemplateDesignResource::instance();
 185          if ( $this->ContentObjectAttribute )
 186          {
 187              $this->Res->setKeys( array( array( 'attribute_identifier', $this->ContentObjectAttribute->attribute( 'contentclass_attribute_identifier' ) ) ) );
 188          }
 189  
 190          $xml = new eZXML();
 191          $this->Document =& $xml->domTree( $this->XMLData, array( "TrimWhiteSpace" => false, "SetParentNode" => true ) );
 192          if ( !$this->Document )
 193          {
 194              $this->Output = '';
 195              return $this->Output;
 196          }
 197  
 198          $this->prefetch();
 199  
 200          $this->XMLSchema =& eZXMLSchema::instance();
 201  
 202          // Add missing elements to the OutputTags array
 203          foreach( $this->XMLSchema->availableElements() as $element )
 204          {
 205              if ( !isset( $this->OutputTags[$element] ) )
 206                   $this->OutputTags[$element] = array();
 207          }
 208  
 209          $this->NestingLevel = 0;
 210          $params = array();
 211  
 212          $output = $this->outputTag( $this->Document->Root, $params );
 213          $this->Output = $output[1];
 214  
 215          $this->Document->cleanup();
 216  
 217          unset( $this->Document );
 218          unset( $this->XMLData );
 219  
 220          $this->Res->removeKey( 'attribute_identifier' );
 221          return $this->Output;
 222      }
 223  
 224      // Prefetch objects, nodes and urls for further rendering
 225      function prefetch()
 226      {
 227          $relatedObjectIDArray = array();
 228          $nodeIDArray = array();
 229  
 230          // Fetch all links and cache urls
 231          $links =& $this->Document->elementsByName( "link" );
 232  
 233          if ( count( $links ) > 0 )
 234          {
 235              $linkIDArray = array();
 236              // Find all Link ids
 237              foreach ( $links as $link )
 238              {
 239                  $linkID = $link->attributeValue( 'url_id' );
 240                  if ( $linkID && !in_array( $linkID, $linkIDArray ) )
 241                          $linkIDArray[] = $linkID;
 242  
 243                  $objectID = $link->attributeValue( 'object_id' );
 244                  if ( $objectID && !in_array( $objectID, $relatedObjectIDArray ) )
 245                          $relatedObjectIDArray[] = $objectID;
 246  
 247                  $nodeID = $link->attributeValue( 'node_id' );
 248                  if ( $nodeID && !in_array( $nodeID, $nodeIDArray ) )
 249                          $nodeIDArray[] = $nodeID;
 250              }
 251  
 252              if ( count( $linkIDArray ) > 0 )
 253              {
 254                  $inIDSQL = implode( ', ', $linkIDArray );
 255  
 256                  $db =& eZDB::instance();
 257                  $linkArray = $db->arrayQuery( "SELECT * FROM ezurl WHERE id IN ( $inIDSQL ) " );
 258  
 259                  foreach ( $linkArray as $linkRow )
 260                  {
 261                      $this->LinkArray[$linkRow['id']] = $linkRow['url'];
 262                  }
 263              }
 264          }
 265  
 266          // Fetch all embeded objects and cache by ID
 267          $objectArray =& $this->Document->elementsByName( "object" );
 268  
 269          if ( count( $objectArray ) > 0 )
 270          {
 271              foreach ( $objectArray as $object )
 272              {
 273                  $objectID = $object->attributeValue( 'id' );
 274                  if ( $objectID != null && !in_array( $objectID, $relatedObjectIDArray ) )
 275                          $relatedObjectIDArray[] = $objectID;
 276              }
 277          }
 278  
 279          $embedTagArray =& $this->Document->elementsByName( "embed" );
 280          $embedInlineTagArray =& $this->Document->elementsByName( "embed-inline" );
 281  
 282          $embedTags = array_merge( $embedTagArray, $embedInlineTagArray );
 283  
 284          if ( count( $embedTags ) > 0 )
 285          {
 286              foreach ( $embedTags as $embedTag )
 287              {
 288                  $objectID = $embedTag->attributeValue( 'object_id' );
 289                  if ( $objectID && !in_array( $objectID, $relatedObjectIDArray ) )
 290                          $relatedObjectIDArray[] = $objectID;
 291  
 292                  $nodeID = $embedTag->attributeValue( 'node_id' );
 293                  if ( $nodeID && !in_array( $nodeID, $nodeIDArray ) )
 294                          $nodeIDArray[] = $nodeID;
 295              }
 296          }
 297  
 298          if ( $relatedObjectIDArray != null )
 299              $this->ObjectArray =& eZContentObject::fetchIDArray( $relatedObjectIDArray );
 300  
 301          if ( $nodeIDArray != null )
 302          {
 303              $nodes = eZContentObjectTreeNode::fetch( $nodeIDArray );
 304  
 305              if ( is_array( $nodes ) )
 306              {
 307                  foreach( $nodes as $node )
 308                  {
 309                      $nodeID = $node->attribute( 'node_id' );
 310                      $this->NodeArray["$nodeID"] = $node;
 311                  }
 312              }
 313              elseif ( $nodes )
 314              {
 315                  $node =& $nodes;
 316                  $nodeID = $node->attribute( 'node_id' );
 317                  $this->NodeArray["$nodeID"] = $node;
 318              }
 319          }
 320      }
 321  
 322      // Main recursive functions for rendering tags
 323      //  $element        - current element
 324      //  $sibilingParams - array of parameters that are passed by reference to all the children of the
 325      //                    current tag to provide a way to "communicate" between their handlers.
 326      //                    This array is empty for the first child.
 327      //  $parentParams   - parameter passed to this tag handler by the parent tag's handler.
 328      //                    This array is passed with no reference. Can by modified in tag's handler
 329      //                    for subordinate tags.
 330  
 331      function outputTag( &$element, &$sibilingParams, $parentParams = array() )
 332      {
 333          $tagName = $element->nodeName;
 334          if ( isset( $this->OutputTags[$tagName] ) )
 335          {
 336              $currentTag =& $this->OutputTags[$tagName];
 337          }
 338          else
 339              $currentTag = null;
 340  
 341          // Prepare attributes array
 342          $attributeNodes = $element->attributes();
 343          $attributes = array();
 344          foreach( $attributeNodes as $attrNode )
 345          {
 346              if ( $attrNode->Prefix && $attrNode->Prefix != 'custom' )
 347                  $attrName = $attrNode->Prefix . ':' . $attrNode->LocalName;
 348              else
 349                  $attrName = $attrNode->nodeName;
 350  
 351              // classes check
 352              if ( $attrName == 'class' )
 353              {
 354                  $classesList = $this->XMLSchema->getClassesList( $tagName );
 355                  if ( !in_array( $attrNode->value, $classesList ) )
 356                  {
 357                      eZDebug::writeWarning( "Using tag '$tagName' with class '$attrNode->value' is not allowed.", 'XML output handler' );
 358                      return array( true, '' );
 359                  }
 360              }
 361  
 362              $attributes[$attrName] = $attrNode->value;
 363          }
 364  
 365          // Set default attribute values if not present in the input
 366          $attrDefaults = $this->XMLSchema->attrDefaultValues( $tagName );
 367          foreach( $attrDefaults as $name=>$value )
 368          {
 369              if ( !isset( $attributes[$name] ) )
 370                  $attributes[$name] = $value;
 371          }
 372  
 373          // Init handler returns an array that may contain the following items:
 374          //
 375          // 'no_render'       (boolean) :
 376          //                   If false tag will not be rendered, only it's children (if any).
 377          // 'design_keys'     array( 'design_key_name_1' => 'value_1', 'design_key_name_2'=>'value_2', ... ) :
 378          //                   An array of additional design keys.
 379          // 'tpl_vars'        array( 'var_name_1' => 'value_1', 'var_name_2' => 'value_2', ... ) :
 380          //                   An array of additional template variables.
 381          // 'template_name'   (string) :
 382          //                   Overrides tag template name.
 383  
 384          $result = $this->callTagInitHandler( 'initHandler', $element, $attributes, $sibilingParams, $parentParams );
 385  
 386          // Process children
 387          $childrenOutput = array();
 388          if ( $element->hasChildNodes() )
 389          {
 390              // Initialize sibiling parameters array for the next level children
 391              // Parent parameters for the children may be modified in the current tag handler.
 392              $nextSibilingParams = array();
 393              
 394              $this->NestingLevel++;
 395              foreach( array_keys( $element->Children ) as $key )
 396              {
 397                  $child =& $element->Children[$key];
 398                  $childOutput = $this->outputTag( $child, $nextSibilingParams, $parentParams );
 399  
 400                  if ( is_array( $childOutput[0] ) )
 401                      $childrenOutput = array_merge( $childrenOutput, $childOutput );
 402                  else
 403                      $childrenOutput[] = $childOutput;
 404              }
 405              $this->NestingLevel--;
 406          }
 407          else
 408          {
 409              $childrenOutput = array( array( true, '' ) );
 410          }
 411  
 412          if ( isset( $result['no_render'] ) && $result['no_render'] )
 413          {
 414              return $childrenOutput;
 415          }
 416  
 417          // Set tpl variables by attributes and rename rules
 418          $vars = array();
 419  
 420          if ( !isset( $currentTag['quickRender'] ) && isset( $currentTag['attrNamesTemplate'] ) )
 421              $attrRenameRules =& $currentTag['attrNamesTemplate'];
 422          elseif ( isset( $currentTag['quickRender'] ) && isset( $currentTag['attrNamesQuick'] ) )
 423              $attrRenameRules =& $currentTag['attrNamesQuick'];
 424          else
 425              $attrRenameRules = array();
 426  
 427          foreach( $attributes as $name=>$value )
 428          {
 429              if ( isset( $attrRenameRules[$name] ) )
 430              {
 431                  $vars[$attrRenameRules[$name]] = $value;
 432                  continue;
 433              }
 434  
 435              if ( substr( $name, 0, 6 ) == 'custom:' )
 436                  $name = substr( $name, strpos( $name, ':' ) + 1 );
 437  
 438              $vars[$name] = $value;
 439          }
 440  
 441          // set missing variables that have rename rules defined
 442          // but were not present in the element
 443          foreach( $attrRenameRules as $attrName=>$varName )
 444          {
 445              if ( !isset( $attributes[$attrName] ) )
 446                  $vars[$varName] = '';
 447          }
 448  
 449          $this->TemplateUri = '';
 450  
 451          // In quick render mode we does not use templates and
 452          // render template variables as tag attributes
 453          if ( !isset( $currentTag['quickRender'] ) )
 454          {
 455              // Set additional variables passed by tag handler
 456              if ( isset( $result['tpl_vars'] ) )
 457              {
 458                  $vars = array_merge( $vars, $result['tpl_vars'] );
 459              }
 460  
 461              foreach( $vars as $name=>$value )
 462              {
 463                  $this->Tpl->setVariable( $name, $value, 'xmltagns' );
 464              }
 465  
 466              // Create design keys array
 467              $designKeys = array();
 468              if ( isset( $currentTag['attrDesignKeys'] ) )
 469              {
 470                  foreach( $currentTag['attrDesignKeys'] as $attrName=>$keyName )
 471                  {
 472                      if ( isset( $attributes[$attrName] ) && $attributes[$attrName] )
 473                          $designKeys[$keyName] = $attributes[$attrName];
 474                  }
 475              }
 476              // Set additional design keys passed by tag handler
 477              if ( isset( $result['design_keys'] ) )
 478              {
 479                  $designKeys = array_merge( $designKeys, $result['design_keys'] );
 480              }
 481  
 482              $existingKeys = $this->Res->keys();
 483              $savedKeys = array();
 484  
 485              // Save old keys values and set new design keys
 486              foreach( $designKeys as $key=>$value )
 487              {
 488                  if ( isset( $existingKeys[$key] ) )
 489                  {
 490                      $savedKeys[$key] = $existingKeys[$key];
 491                  }
 492                  $this->Res->setKeys( array( array( $key, $value ) ) );
 493              }
 494  
 495              // Template name
 496              if ( isset( $result['template_name'] ) )
 497              {
 498                  $templateName = $result['template_name'];
 499              }
 500              else
 501              {
 502                  $templateName = $element->nodeName;
 503              }
 504              $this->TemplateUri = $this->TemplatesPath . $templateName . '.tpl';
 505          }
 506  
 507          $output = $this->callTagRenderHandler( 'renderHandler', $element, $childrenOutput, $vars );
 508  
 509          if ( !isset( $currentTag['quickRender'] ) )
 510          {
 511              // Restore saved template override keys and remove others
 512              foreach( $designKeys as $key=>$value )
 513              {
 514                  if ( isset( $savedKeys[$key] ) )
 515                      $this->Res->setKeys( array( array( $key, $savedKeys[$key] ) ) );
 516                  else
 517                      $this->Res->removeKey( $key );
 518              }
 519  
 520              // Unset variables
 521              foreach( $vars as $name=>$value )
 522              {
 523                  if ( $this->Tpl->hasVariable( $name, 'xmltagns' ) )
 524                      $this->Tpl->unsetVariable( $name, 'xmltagns' );
 525              }
 526          }
 527  
 528          return $output;
 529      }
 530  
 531      function renderTag( &$element, $content, $vars )
 532      {
 533          $currentTag =& $this->OutputTags[$element->nodeName];
 534          if ( $currentTag && isset( $currentTag['quickRender'] ) )
 535          {
 536              $renderedTag = '';
 537              $attrString = '';
 538              foreach( $vars as $name=>$value )
 539              {
 540                  if ( $value != '' )
 541                      $attrString .= " $name=\"$value\"";
 542              }
 543  
 544              if ( isset( $currentTag['quickRender'][0] ) && $currentTag['quickRender'][0] )
 545                  $renderedTag = '<' . $currentTag['quickRender'][0] . "$attrString>" . $content . '</' . $currentTag['quickRender'][0] . '>';
 546              else
 547                  $renderedTag = $content;
 548  
 549              if ( isset( $currentTag['quickRender'][1] ) && $currentTag['quickRender'][1] )
 550                  $renderedTag .= $currentTag['quickRender'][1];
 551          }
 552          else
 553          {
 554              if ( isset( $currentTag['contentVarName'] ) )
 555                  $contentVarName = $currentTag['contentVarName'];
 556              else
 557                  $contentVarName = 'content';
 558  
 559              $this->Tpl->setVariable( $contentVarName, $content, 'xmltagns' );
 560              eZTemplateIncludeFunction::handleInclude( $textElements, $this->TemplateUri, $this->Tpl, 'foo', 'xmltagns' );
 561              $renderedTag = is_array( $textElements ) ? implode( '', $textElements ) : '';
 562          }
 563          return $renderedTag;
 564      }
 565  
 566      // Default render handler
 567      // Renders all the content of children tags inside the current tag
 568      function renderAll( &$element, $childrenOutput, $vars )
 569      {
 570          $tagText = '';
 571          foreach( $childrenOutput as $childOutput )
 572          {
 573              $tagText .= $childOutput[1];
 574          }
 575          $tagText = $this->renderTag( $element, $tagText, $vars );
 576          return array( false, $tagText );
 577      }
 578  
 579      function callTagInitHandler( $handlerName, &$element, &$attributes, &$sibilingParams, &$parentParams )
 580      {
 581          $result = array();
 582          $thisOutputTag =& $this->OutputTags[$element->nodeName];
 583          if ( isset( $thisOutputTag[$handlerName] ) )
 584          {
 585              if ( is_callable( array( $this, $thisOutputTag[$handlerName] ) ) )
 586                  eval( '$result = $this->' . $thisOutputTag[$handlerName] . '( $element, $attributes, $sibilingParams, $parentParams );' );
 587          }
 588          return $result;
 589      }
 590  
 591      function callTagRenderHandler( $handlerName, &$element, $childrenOutput, $vars )
 592      {
 593          $result = array();
 594          $thisOutputTag =& $this->OutputTags[$element->nodeName];
 595          if ( isset( $thisOutputTag[$handlerName] ) )
 596              $handlerFunction = $thisOutputTag[$handlerName];
 597          else
 598              $handlerFunction = 'renderAll';
 599  
 600          if ( is_callable( array( $this, $handlerFunction ) ) )
 601              eval( '$result = $this->' . $handlerFunction . '( $element, $childrenOutput, $vars );' );
 602          else
 603              eZDebug::writeWarning( "'$handlerName' render handler for tag <$element->nodeName> doesn't exist: '" . $thisOutputTag[$handlerName] . "'.", 'eZXML converter' );
 604          return $result;
 605      }
 606  
 607      // This array should be overriden in derived class with the set of rules
 608      // for outputting tags.
 609      var $OutputTags = array();
 610  
 611      // Path to tags' templates
 612      var $TemplatesPath = 'design:content/datatype/view/ezxmltags/';
 613  
 614      /// Contains the XML data as text
 615      var $XMLData;
 616      var $Document;
 617  
 618      var $XMLSchema;
 619  
 620      var $AliasedType;
 621      var $AliasedHandler;
 622  
 623      var $Output = '';
 624      var $Tpl;
 625      var $TemplateURI = '';
 626      var $Res;
 627  
 628      var $AllowMultipleSpaces = false;
 629      var $AllowNumericEntities = false;
 630  
 631      var $ContentObjectAttribute;
 632      var $ObjectAttributeID;
 633  
 634      /// Contains the URL's for <link> tags hashed by ID
 635      var $LinkArray = array();
 636      /// Contains the Objects hashed by ID
 637      var $ObjectArray = array();
 638      /// Contains the Nodes hashed by ID
 639      var $NodeArray = array();
 640  
 641      var $NestingLevel = 0;
 642  }
 643  
 644  ?>


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