[ 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/ -> eztemplateforeachfunction.php (source)

   1  <?php
   2  //
   3  // Definition of eZTemplateForeachFunction class
   4  //
   5  // Created on: <24-Feb-2005 15:47:35 vs>
   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  /*!
  30    \class eZTemplateForeachFunction eztemplateforeachfunction.php
  31    \ingroup eZTemplateFunctions
  32    \brief FOREACH loop
  33  
  34    Syntax:
  35  \code
  36      {foreach <array> as [$keyVar =>] $itemVar
  37               [sequence <array> as $sequenceVar]
  38               [offset <offset>]
  39              [max <max>]
  40              [reverse]}
  41  
  42          [{delimiter}...{/delimiter}]
  43          [{break}]
  44          [{continue}]
  45          [{skip}]
  46      {/foreach}
  47  \endcode
  48  
  49    Example:
  50  \code
  51      {foreach $objects as $object}
  52          <tr>
  53          {foreach $object.nodes as $node sequence array(dark,light) as $class}
  54              <td class=$class>
  55              {$node.name|wash}
  56              </td>
  57          {/foreach}
  58          </tr>
  59      {/foreach}
  60  \endcode
  61  */
  62  
  63  define ( 'EZ_TEMPLATE_FOREACH_FUNCTION_NAME', 'foreach' );
  64  class eZTemplateForeachFunction
  65  {
  66      /*!
  67       * Returns an array of the function names, required for eZTemplate::registerFunctions().
  68       */
  69      function &functionList()
  70      {
  71          $functionList = array( EZ_TEMPLATE_FOREACH_FUNCTION_NAME );
  72          return $functionList;
  73      }
  74  
  75      /*!
  76       * Returns the attribute list.
  77       * key:   parameter name
  78       * value: can have children
  79       */
  80      function attributeList()
  81      {
  82          return array( 'delimiter' => true,
  83                        'break'     => false,
  84                        'continue'  => false,
  85                        'skip'      => false );
  86      }
  87  
  88  
  89      /*!
  90       * Returns the array with hits for the template compiler.
  91       */
  92      function functionTemplateHints()
  93      {
  94          return array( EZ_TEMPLATE_FOREACH_FUNCTION_NAME => array( 'parameters' => true,
  95                                                                    'static' => false,
  96                                                                    'transform-parameters' => true,
  97                                                                    'tree-transformation' => true ) );
  98      }
  99  
 100      /*!
 101       * Compiles the function and its children into PHP code.
 102       */
 103      function templateNodeTransformation( $functionName, &$node,
 104                                           &$tpl, $parameters, $privateData )
 105      {
 106          /*
 107          {foreach <array> as [$keyVar =>] $itemVar
 108                   [sequence <array> as $sequenceVar]
 109                   [offset <offset>]
 110                   [max <max>]
 111                   [reverse]
 112          }
 113          */
 114  
 115          $tpl->ForeachCounter++;
 116          $newNodes            = array();
 117          $nodePlacement       = eZTemplateNodeTool::extractFunctionNodePlacement( $node );
 118          $uniqid              =  md5( $nodePlacement[2] ) . "_" . $tpl->ForeachCounter;
 119  
 120          require_once ( 'lib/eztemplate/classes/eztemplatecompiledloop.php' );
 121          $loop = new eZTemplateCompiledLoop( EZ_TEMPLATE_FOREACH_FUNCTION_NAME,
 122                                              $newNodes, $parameters, $nodePlacement, $uniqid,
 123                                              $node, $tpl, $privateData );
 124  
 125  
 126  
 127          $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "// foreach begins" );
 128  
 129          $loop->initVars();
 130  
 131          $array           = "fe_array_$uniqid";
 132          $arrayKeys       = "fe_array_keys_$uniqid";
 133          $nItems          = "fe_n_items_$uniqid";
 134          $nItemsProcessed = "fe_n_items_processed_$uniqid";
 135          $i               = "fe_i_$uniqid";
 136          $key             = "fe_key_$uniqid";
 137          $val             = "fe_val_$uniqid";
 138          $offset          = "fe_offset_$uniqid";
 139          $max             = "fe_max_$uniqid";
 140          $reverse         = "fe_reverse_$uniqid";
 141          $firstVal        = "fe_first_val_$uniqid";
 142          $lastVal         = "fe_last_val_$uniqid";
 143  
 144          $newNodes[] = eZTemplateNodeTool::createVariableNode( false, $parameters['array'], $nodePlacement, array( 'text-result' => false ), $array );
 145          $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$arrayKeys = is_array( \$$array ) ? array_keys( \$$array ) : array();" );
 146          $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$nItems = count( \$$arrayKeys );" );
 147          $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$nItemsProcessed = 0;" );
 148  
 149  
 150          // process offset, max and reverse parameters
 151          if ( isset( $parameters['offset'] ) )
 152              $newNodes[] = eZTemplateNodeTool::createVariableNode( false, $parameters['offset'], $nodePlacement, array( 'text-result' => false ), $offset );
 153          else
 154              $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$offset = 0;" );
 155  
 156          if ( isset( $parameters['max'] ) )
 157              $newNodes[] = eZTemplateNodeTool::createVariableNode( false, $parameters['max'], $nodePlacement, array( 'text-result' => false ), $max );
 158          else
 159              $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$max = \$$nItems - \$$offset;" );
 160  
 161          if ( isset( $parameters['reverse'] ) )
 162              $newNodes[] = eZTemplateNodeTool::createVariableNode( false, $parameters['reverse'], $nodePlacement, array( 'text-result' => false ), $reverse );
 163          else
 164              $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$reverse = false;" );
 165  
 166  
 167          // fix definitely incorrect offset
 168          $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( \$$offset < 0 || \$$offset >= \$$nItems )\n{\n".
 169                                                                 "    \$$offset = ( \$$offset < 0 ) ? 0 : \$$nItems;\n".
 170                                                                 "    if ( \$$nItems || \$$offset < 0 )\n {\n".
 171                                                                 "        eZDebug::writeWarning(\"Invalid 'offset' parameter specified.\");   \n}\n}" );
 172          // fix definitely incorrect max
 173          $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( \$$max < 0 || \$$offset + \$$max > \$$nItems )\n{\n".
 174                                                                 "    if ( \$$max < 0 )\n eZDebug::writeWarning(\"Invalid 'max' parameter specified.\");\n".
 175                                                                 "    \$$max = \$$nItems - \$$offset;\n}" );
 176  
 177          // initialize first and last indexes to iterate between them
 178          $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( \$$reverse )\n" .
 179                                                                 "{\n" .
 180                                                                 "    \$$firstVal = \$$nItems - 1 - \$$offset;\n" .
 181                                                                 "    \$$lastVal  = 0;\n" .
 182                                                                 "}\n" .
 183                                                                 "else\n" .
 184                                                                 "{\n" .
 185                                                                 "    \$$firstVal = \$$offset;\n" .
 186                                                                 "    \$$lastVal  = \$$nItems - 1;\n" .
 187                                                                 "}" );
 188  
 189          // generate loop header
 190          $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "// foreach" );
 191          $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "for ( \$$i = \$$firstVal; " .
 192                                                                 "\$$nItemsProcessed < \$$max && ( \$$reverse ? \$$i >= \$$lastVal : \$$i <= \$$lastVal ); " .
 193                                                                 "\$$reverse ? \$$i-- : \$$i++ )\n" .
 194                                                                 "{" );
 195          $newNodes[] = eZTemplateNodeTool::createSpacingIncreaseNode();
 196  
 197          $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$key = \$$arrayKeys}[\$$i];" );
 198          $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$val = \$$array}[\$$key];" );
 199  
 200          // export $itemVar
 201          $newNodes[] = eZTemplateNodeTool::createVariableNode( false, "$val", $nodePlacement, array(),
 202                                                                $parameters['item_var'][0][1],
 203                                                                false, true, true );
 204  
 205          // export $keyVar (if specified)
 206          if ( isset( $parameters['key_var'] ) )
 207          {
 208              $newNodes[] = eZTemplateNodeTool::createVariableNode( false, "$key", $nodePlacement, array(),
 209                                                                    $parameters['key_var'][0][1],
 210                                                                    false, true, true );
 211          }
 212  
 213          $loop->processBody();
 214  
 215          // generate loop footer
 216          $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$nItemsProcessed++;" );
 217          $newNodes[] = eZTemplateNodeTool::createSpacingDecreaseNode();
 218          $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "} // foreach" );
 219  
 220          $loop->cleanup();
 221  
 222          // unset the loop variables
 223          $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( $parameters['item_var'][0][1] );
 224          if ( isset( $parameters['key_var'] ) )
 225              $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( $parameters['key_var'][0][1] );
 226          $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( $array );
 227          $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( $arrayKeys );
 228          $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( $nItems );
 229          $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( $nItemsProcessed );
 230          $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( $i );
 231          $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( $key );
 232          $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( $val );
 233          $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( $offset );
 234          $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( $max );
 235          $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( $reverse );
 236          $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( $firstVal );
 237          $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( $lastVal );
 238  
 239          $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "// foreach ends" );
 240  
 241          return $newNodes;
 242      }
 243  
 244      /*!
 245       * Actually executes the function and its children (in processed mode).
 246       */
 247      function process( &$tpl, &$textElements, $functionName, $functionChildren, $functionParameters, $functionPlacement, $rootNamespace, $currentNamespace )
 248      {
 249          /*
 250          {foreach <array> as [$keyVar =>] $itemVar
 251                   [sequence <array> as $sequenceVar]
 252                   [offset <offset>]
 253                   [max <max>]
 254                   [reverse]
 255          }
 256          */
 257  
 258          //eZDebug::writeDebug( $functionParameters, '$functionParameters' );
 259  
 260          require_once ( 'lib/eztemplate/classes/eztemplateloop.php' );
 261          $loop = new eZTemplateLoop( EZ_TEMPLATE_FOREACH_FUNCTION_NAME,
 262                                      $functionParameters, $functionChildren, $functionPlacement,
 263                                      $tpl, $textElements, $rootNamespace, $currentNamespace );
 264  
 265          if ( !$loop->initialized() )
 266              return;
 267  
 268          $loop->parseParamValue( 'array', $array );
 269          if ( !is_array( $array ) )
 270          {
 271              $tpl->error( EZ_TEMPLATE_FOREACH_FUNCTION_NAME, "Missing/malformed array to iterate through." );
 272              return;
 273          }
 274  
 275          $loop->parseParamVarName( 'item_var', $itemVarName );
 276          if ( !$itemVarName )
 277          {
 278              $tpl->error( EZ_TEMPLATE_FOREACH_FUNCTION_NAME, "Missing/malformed item variable name." );
 279              return;
 280          }
 281  
 282          $loop->parseParamVarName( 'key_var', $keyVarName );
 283          $loop->parseParamValue( 'max',      $max     );
 284          $loop->parseParamValue( 'offset',   $offset  );
 285          $loop->parseParamValue( 'reverse',  $reverse );
 286  
 287          /*
 288           * run the loop itself
 289           */
 290  
 291          /*
 292              $offset and $max parameters must meet the following requirements:
 293               -  $offset + $max <= $nItems
 294               -  $offset >= 0
 295               -  $max    >= 0
 296              Otherwise they are not considered.
 297          */
 298  
 299          $arrayKeys       = array_keys( $array );
 300          $nItems          = count( $arrayKeys );
 301          $nItemsProcessed = 0;
 302  
 303          // do nothing in case of empty array
 304          if ( !$nItems )
 305              return;
 306  
 307          // fix definitely incorrect offset
 308          if ( is_null( $offset ) )
 309              $offset = 0;
 310          elseif ( $offset < 0 || $offset >= $nItems )
 311          {
 312              if ( $nItems || $offset < 0 )
 313              {
 314                  $tpl->warning( EZ_TEMPLATE_FOREACH_FUNCTION_NAME, "Invalid 'offset' parameter specified." );
 315              }
 316              $offset = ( $offset < 0 ) ? 0 : $nItems;
 317          }
 318  
 319          // fix definitely incorrect max
 320          if ( is_null( $max ) )
 321              $max = $nItems - $offset;
 322          elseif ( $max < 0 || $offset+$max > $nItems )
 323          {
 324              if ( $max <0 )
 325                  $tpl->warning( EZ_TEMPLATE_FOREACH_FUNCTION_NAME, "Invalid 'max' parameter specified." );
 326              $max = $nItems - $offset;
 327          }
 328  
 329          // process 'reverse' parameter
 330          if ( is_null( $reverse ) )
 331              $reverse = false;
 332          if ( $reverse )
 333          {
 334              $firstVal = $nItems - 1 - $offset;
 335              $lastVal  = 0;
 336          }
 337          else
 338          {
 339              $firstVal = $offset;
 340              $lastVal  = $nItems - 1;
 341          }
 342  
 343          if ( $firstVal < $lastVal )
 344          {
 345              if ( $keyVarName )
 346                  $loop->initLoopVariable( $keyVarName );
 347              $loop->initLoopVariable( $itemVarName );
 348          }
 349  
 350          for ( $i = $firstVal; $nItemsProcessed < $max && ( $reverse ? $i >= $lastVal : $i <= $lastVal ); )
 351          {
 352              $key =& $arrayKeys[$i];
 353              $val =& $array[$key];
 354  
 355              if ( $keyVarName )
 356                  $tpl->setVariable( $keyVarName, $key, $rootNamespace );
 357              $tpl->setVariable( $itemVarName, $val, $rootNamespace );
 358  
 359              $loop->setSequenceVar(); // set sequence variable (if specified)
 360              $loop->processDelimiter( $i );
 361              $loop->resetIteration();
 362  
 363              // process loop body
 364              if ( $loop->processChildren() )
 365                  break;
 366  
 367              // increment loop counter here for delimiter to be processed correctly
 368              $reverse ? $i-- : $i++;
 369  
 370              $loop->incrementSequence();
 371              $nItemsProcessed++;
 372          }
 373  
 374          $loop->cleanup();
 375      }
 376  
 377      /*!
 378       * Returns true, telling the template parser that the function can have children.
 379       */
 380      function hasChildren()
 381      {
 382          return true;
 383      }
 384  }
 385  
 386  ?>


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