00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 define( 'EZ_TEMPLATE_BLOCK_SCOPE_RELATIVE', 1 );
00070 define( 'EZ_TEMPLATE_BLOCK_SCOPE_ROOT', 2 );
00071 define( 'EZ_TEMPLATE_BLOCK_SCOPE_GLOBAL', 3 );
00072
00073
00074 class eZTemplateBlockFunction
00075 {
00076
00077
00078
00079 function eZTemplateBlockFunction( $blockName = 'set-block',
00080 $appendBlockName = 'append-block',
00081 $onceName = 'run-once' )
00082 {
00083 $this->BlockName = $blockName;
00084 $this->AppendBlockName = $appendBlockName;
00085 $this->OnceName = $onceName;
00086 }
00087
00088
00089
00090
00091
00092 function functionList()
00093 {
00094 return array( $this->BlockName, $this->AppendBlockName, $this->OnceName );
00095 }
00096
00097 function functionTemplateHints()
00098 {
00099 return array( $this->BlockName => array( 'parameters' => true,
00100 'static' => false,
00101 'transform-children' => true,
00102 'tree-transformation' => true,
00103 'transform-parameters' => true ),
00104 $this->AppendBlockName => array( 'parameters' => true,
00105 'static' => false,
00106 'transform-children' => true,
00107 'tree-transformation' => true,
00108 'transform-parameters' => true ),
00109 $this->OnceName => array( 'parameters' => false,
00110 'static' => false,
00111 'transform-children' => true,
00112 'tree-transformation' => true ) );
00113 }
00114
00115 function templateNodeTransformation( $functionName, &$node,
00116 &$tpl, $parameters, $privateData )
00117 {
00118 if ( $functionName == $this->BlockName or
00119 $functionName == $this->AppendBlockName )
00120 {
00121 if ( !isset( $parameters['variable'] ) )
00122 return false;
00123
00124 $scope = EZ_TEMPLATE_NAMESPACE_SCOPE_RELATIVE;
00125 if ( isset( $parameters['scope'] ) )
00126 {
00127 if ( !eZTemplateNodeTool::isStaticElement( $parameters['scope'] ) )
00128 return false;
00129 $scopeText = eZTemplateNodeTool::elementStaticValue( $parameters['scope'] );
00130 if ( $scopeText == 'relative' )
00131 $scope = EZ_TEMPLATE_NAMESPACE_SCOPE_RELATIVE;
00132 else if ( $scopeText == 'root' )
00133 $scope = EZ_TEMPLATE_NAMESPACE_SCOPE_LOCAL;
00134 else if ( $scopeText == 'global' )
00135 $scope = EZ_TEMPLATE_NAMESPACE_SCOPE_GLOBAL;
00136 }
00137
00138 $name = '';
00139 if ( isset( $parameters['name'] ) )
00140 {
00141 if ( !eZTemplateNodeTool::isStaticElement( $parameters['name'] ) )
00142 return false;
00143 $name = eZTemplateNodeTool::elementStaticValue( $parameters['name'] );
00144 }
00145 $variableName = eZTemplateNodeTool::elementStaticValue( $parameters['variable'] );
00146
00147 $newNodes = array();
00148
00149 $children = eZTemplateNodeTool::extractFunctionNodeChildren( $node );
00150
00151 $newNodes[] = eZTemplateNodeTool::createOutputVariableIncreaseNode();
00152 $newNodes = array_merge( $newNodes, $children );
00153 $newNodes[] = eZTemplateNodeTool::createAssignFromOutputVariableNode( 'blockText' );
00154 if ( $functionName == $this->AppendBlockName )
00155 {
00156 $data = array( eZTemplateNodeTool::createVariableElement( $variableName, $name, $scope ) );
00157 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, $data, false, array(),
00158 'blockData' );
00159
00160
00161
00162
00163 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( is_null ( \$blockData ) ) \$blockData = array();" );
00164 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( is_array ( \$blockData ) ) \$blockData[] = \$blockText;" );
00165 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "else eZDebug::writeError( \"Variable '$variableName' is already in use.\" );" );
00166 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, 'blockData', false, array(),
00167 array( $name, $scope, $variableName ), false, true, true );
00168 $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( 'blockData' );
00169 }
00170 else
00171 {
00172 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, 'blockText', false, array(),
00173 array( $name, $scope, $variableName ), false, true, true );
00174 }
00175 $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( 'blockText' );
00176 $newNodes[] = eZTemplateNodeTool::createOutputVariableDecreaseNode();
00177
00178 return $newNodes;
00179 }
00180 else if ( $functionName == $this->OnceName )
00181 {
00182 $functionPlacement = eZTemplateNodeTool::extractFunctionNodePlacement( $node );
00183 $key = $this->placementKey( $functionPlacement );
00184 $newNodes = array();
00185 if ( $key !== false )
00186 {
00187 $keyText = eZPHPCreator::variableText( $key, 0, 0, false );
00188 $placementText = eZPHPCreator::variableText( $functionPlacement, 0, 0, false );
00189 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( !isset( \$GLOBALS['eZTemplateRunOnceKeys'][$keyText] ) )\n" .
00190 "{\n" .
00191 " \$GLOBALS['eZTemplateRunOnceKeys'][$keyText] = $placementText;" );
00192 $children = eZTemplateNodeTool::extractFunctionNodeChildren( $node );
00193 $newNodes[] = eZTemplateNodeTool::createSpacingIncreaseNode( 4 );
00194 $newNodes = array_merge( $newNodes, $children );
00195 $newNodes[] = eZTemplateNodeTool::createSpacingDecreaseNode( 4 );
00196 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "}" );
00197 }
00198 return $newNodes;
00199 }
00200 return false;
00201 }
00202
00203
00204
00205
00206 function process( &$tpl, &$textElements, $functionName, $functionChildren, $functionParameters, $functionPlacement, $rootNamespace, $currentNamespace )
00207 {
00208 switch ( $functionName )
00209 {
00210 case $this->BlockName:
00211 case $this->AppendBlockName:
00212 {
00213 $children = $functionChildren;
00214 $parameters = $functionParameters;
00215
00216 $scope = EZ_TEMPLATE_BLOCK_SCOPE_RELATIVE;
00217 if ( isset( $parameters["scope"] ) )
00218 {
00219 $scopeText = $tpl->elementValue( $parameters["scope"], $rootNamespace, $currentNamespace, $functionPlacement );
00220 if ( $scopeText == 'relative' )
00221 $scope = EZ_TEMPLATE_BLOCK_SCOPE_RELATIVE;
00222 else if ( $scopeText == 'root' )
00223 $scope = EZ_TEMPLATE_BLOCK_SCOPE_ROOT;
00224 else if ( $scopeText == 'global' )
00225 $scope = EZ_TEMPLATE_BLOCK_SCOPE_GLOBAL;
00226 else
00227 $tpl->warning( $functionName, "Scope value '$scopeText' is not valid, use either 'relative', 'root' or 'global'", $functionPlacement );
00228 }
00229
00230 $name = null;
00231 if ( isset( $parameters["name"] ) )
00232 $name = $tpl->elementValue( $parameters["name"], $rootNamespace, $currentNamespace, $functionPlacement );
00233 if ( $name === null )
00234 {
00235 if ( $scope == EZ_TEMPLATE_BLOCK_SCOPE_RELATIVE )
00236 $name = $currentNamespace;
00237 else if ( $scope == EZ_TEMPLATE_BLOCK_SCOPE_ROOT )
00238 $name = $rootNamespace;
00239 else
00240 $name = '';
00241 }
00242 else
00243 {
00244 if ( $scope == EZ_TEMPLATE_BLOCK_SCOPE_RELATIVE and
00245 $currentNamespace != '' )
00246 $name = "$currentNamespace:$name";
00247 else if ( $scope == EZ_TEMPLATE_BLOCK_SCOPE_ROOT and
00248 $rootNamespace != '' )
00249 $name = "$rootNamespace:$name";
00250 }
00251 $variableItem = null;
00252 if ( isset( $parameters["variable"] ) )
00253 {
00254 $hasLoopItemParameter = true;
00255 $variableItem =& $tpl->elementValue( $parameters["variable"], $rootNamespace, $currentNamespace, $functionPlacement );
00256 }
00257 else
00258 {
00259 $tpl->missingParameter( $functionName, 'variable' );
00260 return;
00261 }
00262
00263 $childTextElements = array();
00264 if ( is_array( $children ) )
00265 {
00266 foreach ( array_keys( $children ) as $childKey )
00267 {
00268 $child =& $children[$childKey];
00269 $tpl->processNode( $child, $childTextElements, $rootNamespace, $name );
00270 }
00271 }
00272 $text = implode( '', $childTextElements );
00273 if ( $functionName == $this->AppendBlockName )
00274 {
00275 $textArray = array();
00276 if ( $tpl->hasVariable( $variableItem, $name ) )
00277 {
00278 $textArray = $tpl->variable( $variableItem, $name );
00279 if ( !is_array( $textArray ) )
00280 {
00281 $tpl->warning( $functionName, "Variable '$variableItem' is already in use.", $functionPlacement );
00282 return;
00283 }
00284 }
00285 $textArray[] = $text;
00286 $tpl->setVariable( $variableItem, $textArray, $name );
00287 }
00288 else
00289 $tpl->setVariable( $variableItem, $text, $name );
00290 } break;
00291
00292 case $this->OnceName:
00293 {
00294 $key = $this->placementKey( $functionPlacement );
00295 if ( $key !== false and !$this->hasPlacementKey( $key ) )
00296 {
00297 $this->registerPlacementKey( $key, $functionPlacement );
00298
00299 if ( is_array( $functionChildren ) )
00300 {
00301 foreach ( array_keys( $functionChildren ) as $childKey )
00302 {
00303 $child =& $functionChildren[$childKey];
00304 $tpl->processNode( $child, $textElements, $rootNamespace, $currentNamespace );
00305 }
00306 }
00307 }
00308 } break;
00309 }
00310 }
00311
00312 function resetFunction( $functionName )
00313 {
00314 if ( $functionName == $this->OnceName )
00315 {
00316 unset( $GLOBALS['eZTemplateRunOnceKeys'] );
00317 }
00318 }
00319
00320
00321
00322
00323
00324 function placementKey( $placement )
00325 {
00326 if ( isset( $placement[0] ) and
00327 isset( $placement[1] ) and
00328 isset( $placement[2] ) )
00329 {
00330 $input = $placement[0][0] . ',' . $placement[0][1] . "\n";
00331 $input .= $placement[1][0] . ',' . $placement[1][1] . "\n";
00332 $input .= $placement[2];
00333 return md5( $input );
00334 }
00335 return false;
00336 }
00337
00338
00339
00340
00341 function hasPlacementKey( $key )
00342 {
00343 return isset( $GLOBALS['eZTemplateRunOnceKeys'][$key] );
00344 }
00345
00346
00347
00348
00349 function registerPlacementKey( $key, $placement )
00350 {
00351 return $GLOBALS['eZTemplateRunOnceKeys'][$key] = $placement;
00352 }
00353
00354
00355
00356
00357 function hasChildren()
00358 {
00359 return true;
00360 }
00361
00362
00363
00364 var $BlockName;
00365 var $AppendBlockName;
00366 var $OnceName;
00367 }
00368
00369 ?>