|
eZ Publish
[4.0]
|
00001 <?php 00002 // 00003 // Definition of eZTemplateBlockFunction class 00004 // 00005 // Created on: <01-Mar-2002 13:50:33 amos> 00006 // 00007 // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ## 00008 // SOFTWARE NAME: eZ Publish 00009 // SOFTWARE RELEASE: 4.0.x 00010 // COPYRIGHT NOTICE: Copyright (C) 1999-2008 eZ Systems AS 00011 // SOFTWARE LICENSE: GNU General Public License v2.0 00012 // NOTICE: > 00013 // This program is free software; you can redistribute it and/or 00014 // modify it under the terms of version 2.0 of the GNU General 00015 // Public License as published by the Free Software Foundation. 00016 // 00017 // This program is distributed in the hope that it will be useful, 00018 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 // GNU General Public License for more details. 00021 // 00022 // You should have received a copy of version 2.0 of the GNU General 00023 // Public License along with this program; if not, write to the Free 00024 // Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00025 // MA 02110-1301, USA. 00026 // 00027 // 00028 // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ## 00029 // 00030 00031 /*! 00032 \class eZTemplateBlockFunction eztemplateblockfunction.php 00033 \ingroup eZTemplateFunctions 00034 \brief Advanced block handling 00035 00036 set-block 00037 Renders all it's children as text and sets it as a template variable. 00038 This is useful for allowing one template to return multiple text portions, 00039 for instance an email template could set subject as a block and return 00040 the rest as body. 00041 00042 \code 00043 {set-block name=Space scope=global variable=text} 00044 {$item} - {$item2} 00045 {/set-block} 00046 \endcode 00047 00048 append-block 00049 Similar to set-block but will make the variable an array where each append-block 00050 adds an item. 00051 00052 \code 00053 {append-block scope=global variable=extra_header_data} 00054 <script language=jscript src={"/extension/xmleditor/dhtml/ezeditor.js"|ezroot}></script> 00055 <link rel="stylesheet" type="text/css" href={"/extension/xmleditor/dhtml/toolbar.css"|ezroot}> 00056 {/append-block} 00057 \endcode 00058 00059 run-once 00060 Makes sure that the block is run only once. 00061 00062 \code 00063 {run-once} 00064 <p>This appears only one time</p> 00065 {/run-once} 00066 \endcode 00067 */ 00068 00069 class eZTemplateBlockFunction 00070 { 00071 const SCOPE_RELATIVE = 1; 00072 const SCOPE_ROOT = 2; 00073 const SCOPE_GLOBAL = 3; 00074 00075 /*! 00076 Initializes the object with names. 00077 */ 00078 function eZTemplateBlockFunction( $blockName = 'set-block', 00079 $appendBlockName = 'append-block', 00080 $onceName = 'run-once' ) 00081 { 00082 $this->BlockName = $blockName; 00083 $this->AppendBlockName = $appendBlockName; 00084 $this->OnceName = $onceName; 00085 } 00086 00087 /*! 00088 Returns an array containing the name of the block function, default is "block". 00089 The name is specified in the constructor. 00090 */ 00091 function functionList() 00092 { 00093 return array( $this->BlockName, $this->AppendBlockName, $this->OnceName ); 00094 } 00095 00096 function functionTemplateHints() 00097 { 00098 return array( $this->BlockName => array( 'parameters' => true, 00099 'static' => false, 00100 'transform-children' => true, 00101 'tree-transformation' => true, 00102 'transform-parameters' => true ), 00103 $this->AppendBlockName => array( 'parameters' => true, 00104 'static' => false, 00105 'transform-children' => true, 00106 'tree-transformation' => true, 00107 'transform-parameters' => true ), 00108 $this->OnceName => array( 'parameters' => false, 00109 'static' => false, 00110 'transform-children' => true, 00111 'tree-transformation' => true ) ); 00112 } 00113 00114 function templateNodeTransformation( $functionName, &$node, 00115 $tpl, $parameters, $privateData ) 00116 { 00117 if ( $functionName == $this->BlockName or 00118 $functionName == $this->AppendBlockName ) 00119 { 00120 if ( !isset( $parameters['variable'] ) ) 00121 return false; 00122 00123 $scope = eZTemplate::NAMESPACE_SCOPE_RELATIVE; 00124 if ( isset( $parameters['scope'] ) ) 00125 { 00126 if ( !eZTemplateNodeTool::isStaticElement( $parameters['scope'] ) ) 00127 return false; 00128 $scopeText = eZTemplateNodeTool::elementStaticValue( $parameters['scope'] ); 00129 if ( $scopeText == 'relative' ) 00130 $scope = eZTemplate::NAMESPACE_SCOPE_RELATIVE; 00131 else if ( $scopeText == 'root' ) 00132 $scope = eZTemplate::NAMESPACE_SCOPE_LOCAL; 00133 else if ( $scopeText == 'global' ) 00134 $scope = eZTemplate::NAMESPACE_SCOPE_GLOBAL; 00135 } 00136 00137 $name = ''; 00138 if ( isset( $parameters['name'] ) ) 00139 { 00140 if ( !eZTemplateNodeTool::isStaticElement( $parameters['name'] ) ) 00141 return false; 00142 $name = eZTemplateNodeTool::elementStaticValue( $parameters['name'] ); 00143 } 00144 $variableName = eZTemplateNodeTool::elementStaticValue( $parameters['variable'] ); 00145 00146 $newNodes = array(); 00147 00148 $children = eZTemplateNodeTool::extractFunctionNodeChildren( $node ); 00149 00150 $newNodes[] = eZTemplateNodeTool::createOutputVariableIncreaseNode(); 00151 $newNodes = array_merge( $newNodes, $children ); 00152 $newNodes[] = eZTemplateNodeTool::createAssignFromOutputVariableNode( 'blockText' ); 00153 if ( $functionName == $this->AppendBlockName ) 00154 { 00155 $data = array( eZTemplateNodeTool::createVariableElement( $variableName, $name, $scope ) ); 00156 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, $data, false, array(), 00157 'blockData' ); 00158 00159 // This block checks whether the append-block variable is an array or not. 00160 // TODO: This is a temporary solution and should also check whether the template variable exists. 00161 // This new solution requires probably writing the createVariableElement and createVariableNode your self. 00162 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( is_null ( \$blockData ) ) \$blockData = array();" ); 00163 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( is_array ( \$blockData ) ) \$blockData[] = \$blockText;" ); 00164 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "else eZDebug::writeError( \"Variable '$variableName' is already in use.\" );" ); 00165 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, 'blockData', false, array(), 00166 array( $name, $scope, $variableName ), false, true, true ); 00167 $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( 'blockData' ); 00168 } 00169 else 00170 { 00171 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, 'blockText', false, array(), 00172 array( $name, $scope, $variableName ), false, true, true ); 00173 } 00174 $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( 'blockText' ); 00175 $newNodes[] = eZTemplateNodeTool::createOutputVariableDecreaseNode(); 00176 00177 return $newNodes; 00178 } 00179 else if ( $functionName == $this->OnceName ) 00180 { 00181 $functionPlacement = eZTemplateNodeTool::extractFunctionNodePlacement( $node ); 00182 $key = $this->placementKey( $functionPlacement ); 00183 $newNodes = array(); 00184 if ( $key !== false ) 00185 { 00186 $keyText = eZPHPCreator::variableText( $key, 0, 0, false ); 00187 $placementText = eZPHPCreator::variableText( $functionPlacement, 0, 0, false ); 00188 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( !isset( \$GLOBALS['eZTemplateRunOnceKeys'][$keyText] ) )\n" . 00189 "{\n" . 00190 " \$GLOBALS['eZTemplateRunOnceKeys'][$keyText] = $placementText;" ); 00191 $children = eZTemplateNodeTool::extractFunctionNodeChildren( $node ); 00192 $newNodes[] = eZTemplateNodeTool::createSpacingIncreaseNode( 4 ); 00193 $newNodes = array_merge( $newNodes, $children ); 00194 $newNodes[] = eZTemplateNodeTool::createSpacingDecreaseNode( 4 ); 00195 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "}" ); 00196 } 00197 return $newNodes; 00198 } 00199 return false; 00200 } 00201 00202 /*! 00203 Processes the function with all it's children. 00204 */ 00205 function process( $tpl, &$textElements, $functionName, $functionChildren, $functionParameters, $functionPlacement, $rootNamespace, $currentNamespace ) 00206 { 00207 switch ( $functionName ) 00208 { 00209 case $this->BlockName: 00210 case $this->AppendBlockName: 00211 { 00212 $children = $functionChildren; 00213 $parameters = $functionParameters; 00214 00215 $scope = eZTemplateBlockFunction::SCOPE_RELATIVE; 00216 if ( isset( $parameters["scope"] ) ) 00217 { 00218 $scopeText = $tpl->elementValue( $parameters["scope"], $rootNamespace, $currentNamespace, $functionPlacement ); 00219 if ( $scopeText == 'relative' ) 00220 $scope = eZTemplateBlockFunction::SCOPE_RELATIVE; 00221 else if ( $scopeText == 'root' ) 00222 $scope = eZTemplateBlockFunction::SCOPE_ROOT; 00223 else if ( $scopeText == 'global' ) 00224 $scope = eZTemplateBlockFunction::SCOPE_GLOBAL; 00225 else 00226 $tpl->warning( $functionName, "Scope value '$scopeText' is not valid, use either 'relative', 'root' or 'global'", $functionPlacement ); 00227 } 00228 00229 $name = null; 00230 if ( isset( $parameters["name"] ) ) 00231 $name = $tpl->elementValue( $parameters["name"], $rootNamespace, $currentNamespace, $functionPlacement ); 00232 if ( $name === null ) 00233 { 00234 if ( $scope == eZTemplateBlockFunction::SCOPE_RELATIVE ) 00235 $name = $currentNamespace; 00236 else if ( $scope == eZTemplateBlockFunction::SCOPE_ROOT ) 00237 $name = $rootNamespace; 00238 else 00239 $name = ''; 00240 } 00241 else 00242 { 00243 if ( $scope == eZTemplateBlockFunction::SCOPE_RELATIVE and 00244 $currentNamespace != '' ) 00245 $name = "$currentNamespace:$name"; 00246 else if ( $scope == eZTemplateBlockFunction::SCOPE_ROOT and 00247 $rootNamespace != '' ) 00248 $name = "$rootNamespace:$name"; 00249 } 00250 $variableItem = null; 00251 if ( isset( $parameters["variable"] ) ) 00252 { 00253 $hasLoopItemParameter = true; 00254 $variableItem = $tpl->elementValue( $parameters["variable"], $rootNamespace, $currentNamespace, $functionPlacement ); 00255 } 00256 else 00257 { 00258 $tpl->missingParameter( $functionName, 'variable' ); 00259 return; 00260 } 00261 00262 $childTextElements = array(); 00263 if ( is_array( $children ) ) 00264 { 00265 foreach ( array_keys( $children ) as $childKey ) 00266 { 00267 $child =& $children[$childKey]; 00268 $tpl->processNode( $child, $childTextElements, $rootNamespace, $name ); 00269 } 00270 } 00271 $text = implode( '', $childTextElements ); 00272 if ( $functionName == $this->AppendBlockName ) 00273 { 00274 $textArray = array(); 00275 if ( $tpl->hasVariable( $variableItem, $name ) ) 00276 { 00277 $textArray = $tpl->variable( $variableItem, $name ); 00278 if ( !is_array( $textArray ) ) 00279 { 00280 $tpl->warning( $functionName, "Variable '$variableItem' is already in use.", $functionPlacement ); 00281 return; 00282 } 00283 } 00284 $textArray[] = $text; 00285 $tpl->setVariable( $variableItem, $textArray, $name ); 00286 } 00287 else 00288 $tpl->setVariable( $variableItem, $text, $name ); 00289 } break; 00290 00291 case $this->OnceName: 00292 { 00293 $key = $this->placementKey( $functionPlacement ); 00294 if ( $key !== false and !$this->hasPlacementKey( $key ) ) 00295 { 00296 $this->registerPlacementKey( $key, $functionPlacement ); 00297 00298 if ( is_array( $functionChildren ) ) 00299 { 00300 foreach ( array_keys( $functionChildren ) as $childKey ) 00301 { 00302 $child =& $functionChildren[$childKey]; 00303 $tpl->processNode( $child, $textElements, $rootNamespace, $currentNamespace ); 00304 } 00305 } 00306 } 00307 } break; 00308 } 00309 } 00310 00311 function resetFunction( $functionName ) 00312 { 00313 if ( $functionName == $this->OnceName ) 00314 { 00315 unset( $GLOBALS['eZTemplateRunOnceKeys'] ); 00316 } 00317 } 00318 00319 /*! 00320 Generates an md5 key from the start, stop and file of the template function and returns it. 00321 \return false if the key could not be made. 00322 */ 00323 function placementKey( $placement ) 00324 { 00325 if ( isset( $placement[0] ) and 00326 isset( $placement[1] ) and 00327 isset( $placement[2] ) ) 00328 { 00329 $input = $placement[0][0] . ',' . $placement[0][1] . "\n"; 00330 $input .= $placement[1][0] . ',' . $placement[1][1] . "\n"; 00331 $input .= $placement[2]; 00332 return md5( $input ); 00333 } 00334 return false; 00335 } 00336 00337 /*! 00338 \return true if the placement key is registered which means that the block has already been run. 00339 */ 00340 function hasPlacementKey( $key ) 00341 { 00342 return isset( $GLOBALS['eZTemplateRunOnceKeys'][$key] ); 00343 } 00344 00345 /*! 00346 Registers the placement key \a $key with the data \a $placement. 00347 */ 00348 function registerPlacementKey( $key, $placement ) 00349 { 00350 return $GLOBALS['eZTemplateRunOnceKeys'][$key] = $placement; 00351 } 00352 00353 /*! 00354 Returns true. 00355 */ 00356 function hasChildren() 00357 { 00358 return true; 00359 } 00360 00361 /// \privatesection 00362 /// Name of the function 00363 public $BlockName; 00364 public $AppendBlockName; 00365 public $OnceName; 00366 } 00367 00368 ?>