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
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 include_once( "lib/ezutils/classes/ezdebug.php" );
00223
00224 include_once( "lib/eztemplate/classes/eztemplatefileresource.php" );
00225
00226 include_once( "lib/eztemplate/classes/eztemplateroot.php" );
00227 include_once( "lib/eztemplate/classes/eztemplatetextelement.php" );
00228 include_once( "lib/eztemplate/classes/eztemplatevariableelement.php" );
00229 include_once( "lib/eztemplate/classes/eztemplateoperatorelement.php" );
00230 include_once( "lib/eztemplate/classes/eztemplatefunctionelement.php" );
00231
00232 define( "EZ_RESOURCE_FETCH", 1 );
00233 define( "EZ_RESOURCE_QUERY", 2 );
00234
00235 define( "EZ_ELEMENT_TEXT", 1 );
00236 define( "EZ_ELEMENT_SINGLE_TAG", 2 );
00237 define( "EZ_ELEMENT_NORMAL_TAG", 3 );
00238 define( "EZ_ELEMENT_END_TAG", 4 );
00239 define( "EZ_ELEMENT_VARIABLE", 5 );
00240 define( "EZ_ELEMENT_COMMENT", 6 );
00241
00242 define( "EZ_TEMPLATE_NODE_ROOT", 1 );
00243 define( "EZ_TEMPLATE_NODE_TEXT", 2 );
00244 define( "EZ_TEMPLATE_NODE_VARIABLE", 3 );
00245 define( "EZ_TEMPLATE_NODE_FUNCTION", 4 );
00246 define( "EZ_TEMPLATE_NODE_OPERATOR", 5 );
00247
00248
00249 define( "EZ_TEMPLATE_NODE_INTERNAL", 100 );
00250 define( "EZ_TEMPLATE_NODE_INTERNAL_CODE_PIECE", 101 );
00251
00252 define( "EZ_TEMPLATE_NODE_INTERNAL_VARIABLE_SET", 105 );
00253 define( "EZ_TEMPLATE_NODE_INTERNAL_VARIABLE_UNSET", 102 );
00254
00255 define( "EZ_TEMPLATE_NODE_INTERNAL_NAMESPACE_CHANGE", 103 );
00256 define( "EZ_TEMPLATE_NODE_INTERNAL_NAMESPACE_RESTORE", 104 );
00257
00258 define( "EZ_TEMPLATE_NODE_INTERNAL_WARNING", 120 );
00259 define( "EZ_TEMPLATE_NODE_INTERNAL_ERROR", 121 );
00260
00261 define( "EZ_TEMPLATE_NODE_INTERNAL_RESOURCE_ACQUISITION", 140 );
00262 define( "EZ_TEMPLATE_NODE_OPTIMIZED_RESOURCE_ACQUISITION", 141 );
00263
00264 define( "EZ_TEMPLATE_NODE_INTERNAL_OUTPUT_ASSIGN", 150 );
00265 define( "EZ_TEMPLATE_NODE_INTERNAL_OUTPUT_READ", 151 );
00266 define( "EZ_TEMPLATE_NODE_INTERNAL_OUTPUT_INCREASE", 152 );
00267 define( "EZ_TEMPLATE_NODE_INTERNAL_OUTPUT_DECREASE", 153 );
00268
00269 define( "EZ_TEMPLATE_NODE_INTERNAL_SPACING_INCREASE", 160 );
00270 define( "EZ_TEMPLATE_NODE_INTERNAL_SPACING_DECREASE", 161 );
00271
00272 define( "EZ_TEMPLATE_NODE_OPTIMIZED_INIT", 201 );
00273
00274
00275 define( "EZ_TEMPLATE_NODE_USER_CUSTOM", 1000 );
00276
00277
00278 define( "EZ_TEMPLATE_TYPE_VOID", 0 );
00279 define( "EZ_TEMPLATE_TYPE_STRING", 1 );
00280 define( "EZ_TEMPLATE_TYPE_NUMERIC", 2 );
00281 define( "EZ_TEMPLATE_TYPE_IDENTIFIER", 3 );
00282 define( "EZ_TEMPLATE_TYPE_VARIABLE", 4 );
00283 define( "EZ_TEMPLATE_TYPE_ATTRIBUTE", 5 );
00284 define( "EZ_TEMPLATE_TYPE_OPERATOR", 6 );
00285 define( "EZ_TEMPLATE_TYPE_BOOLEAN", 7 );
00286 define( "EZ_TEMPLATE_TYPE_ARRAY", 8 );
00287 define( "EZ_TEMPLATE_TYPE_DYNAMIC_ARRAY", 9 );
00288
00289 define( "EZ_TEMPLATE_TYPE_INTERNAL", 100 );
00290 define( "EZ_TEMPLATE_TYPE_INTERNAL_CODE_PIECE", 101 );
00291 define( "EZ_TEMPLATE_TYPE_PHP_VARIABLE", 102 );
00292
00293 define( "EZ_TEMPLATE_TYPE_OPTIMIZED_NODE", 201 );
00294 define( "EZ_TEMPLATE_TYPE_OPTIMIZED_ARRAY_LOOKUP", 202 );
00295 define( "EZ_TEMPLATE_TYPE_OPTIMIZED_CONTENT_CALL", 203 );
00296 define( "EZ_TEMPLATE_TYPE_OPTIMIZED_ATTRIBUTE_LOOKUP", 204 );
00297
00298 define( "EZ_TEMPLATE_TYPE_INTERNAL_STOP", 999 );
00299
00300
00301 define( "EZ_TEMPLATE_TYPE_STRING_BIT", (1 << (EZ_TEMPLATE_TYPE_STRING - 1)) );
00302 define( "EZ_TEMPLATE_TYPE_NUMERIC_BIT", (1 << (EZ_TEMPLATE_TYPE_NUMERIC - 1)) );
00303 define( "EZ_TEMPLATE_TYPE_IDENTIFIER_BIT", (1 << (EZ_TEMPLATE_TYPE_IDENTIFIER - 1)) );
00304 define( "EZ_TEMPLATE_TYPE_VARIABLE_BIT", (1 << (EZ_TEMPLATE_TYPE_VARIABLE - 1)) );
00305 define( "EZ_TEMPLATE_TYPE_ATTRIBUTE_BIT", (1 << (EZ_TEMPLATE_TYPE_ATTRIBUTE - 1)) );
00306 define( "EZ_TEMPLATE_TYPE_OPERATOR_BIT", (1 << (EZ_TEMPLATE_TYPE_OPERATOR - 1)) );
00307
00308 define( "EZ_TEMPLATE_TYPE_NONE", 0 );
00309
00310 define( "EZ_TEMPLATE_TYPE_ALL", (EZ_TEMPLATE_TYPE_STRING_BIT |
00311 EZ_TEMPLATE_TYPE_NUMERIC_BIT |
00312 EZ_TEMPLATE_TYPE_IDENTIFIER_BIT |
00313 EZ_TEMPLATE_TYPE_VARIABLE_BIT |
00314 EZ_TEMPLATE_TYPE_ATTRIBUTE_BIT |
00315 EZ_TEMPLATE_TYPE_OPERATOR_BIT ) );
00316
00317 define( "EZ_TEMPLATE_TYPE_BASIC", (EZ_TEMPLATE_TYPE_STRING_BIT |
00318 EZ_TEMPLATE_TYPE_NUMERIC_BIT |
00319 EZ_TEMPLATE_TYPE_IDENTIFIER_BIT |
00320 EZ_TEMPLATE_TYPE_VARIABLE_BIT |
00321 EZ_TEMPLATE_TYPE_OPERATOR_BIT ) );
00322
00323 define( "EZ_TEMPLATE_TYPE_MODIFIER_MASK", (EZ_TEMPLATE_TYPE_ATTRIBUTE_BIT |
00324 EZ_TEMPLATE_TYPE_OPERATOR_BIT) );
00325
00326 define( "EZ_TEMPLATE_NAMESPACE_SCOPE_GLOBAL", 1 );
00327 define( "EZ_TEMPLATE_NAMESPACE_SCOPE_LOCAL", 2 );
00328 define( "EZ_TEMPLATE_NAMESPACE_SCOPE_RELATIVE", 3 );
00329
00330 define( "EZ_TEMPLATE_DEBUG_INTERNALS", false );
00331
00332 define( 'EZ_ERROR_TEMPLATE_FILE_ERRORS', 1 );
00333
00334 class eZTemplate
00335 {
00336
00337
00338
00339
00340 function eZTemplate()
00341 {
00342 $this->Tree = array( EZ_TEMPLATE_NODE_ROOT, false );
00343 $this->LDelim = "{";
00344 $this->RDelim = "}";
00345
00346 $this->IncludeText = array();
00347 $this->IncludeOutput = array();
00348
00349 $this->registerLiteral( "literal" );
00350
00351 $res = new eZTemplateFileResource();
00352 $this->DefaultResource =& $res;
00353 $this->registerResource( $res );
00354
00355 $this->Resources = array();
00356 $this->Text = null;
00357
00358 $this->IsCachingAllowed = true;
00359
00360 $this->resetErrorLog();
00361
00362 $this->AutoloadPathList = array( 'lib/eztemplate/classes/' );
00363 $this->Variables = array();
00364 $this->LocalVariablesNamesStack = array();
00365 $this->CurrentLocalVariablesNames = null;
00366 $this->Functions = array();
00367 $this->FunctionAttributes = array();
00368
00369 $this->TestCompile = false;
00370
00371 $ini = eZINI::instance( 'template.ini' );
00372 if ( $ini->hasVariable( 'ControlSettings', 'MaxLevel' ) )
00373 $this->MaxLevel = $ini->variable( 'ControlSettings', 'MaxLevel' );
00374 include_once('kernel/common/i18n.php');
00375 $this->MaxLevelWarning = ezi18n( 'lib/template',
00376 'The maximum nesting level of %max has been reached. The execution is stopped to avoid infinite recursion.',
00377 '',
00378 array( '%max' => $this->MaxLevel ) );
00379 eZDebug::createAccumulatorGroup( 'template_total', 'Template Total' );
00380
00381 $this->TemplatesUsageStatistics = array();
00382
00383 $this->TemplateFetchList = array();
00384
00385 $this->ForeachCounter = 0;
00386 $this->ForCounter = 0;
00387 $this->WhileCounter = 0;
00388 $this->DoCounter = 0;
00389 $this->ElseifCounter = 0;
00390 }
00391
00392
00393
00394
00395 function leftDelimiter()
00396 {
00397 return $this->LDelim;
00398 }
00399
00400
00401
00402
00403 function rightDelimiter()
00404 {
00405 return $this->RDelim;
00406 }
00407
00408
00409
00410
00411 function setLeftDelimiter( $delim )
00412 {
00413 $this->LDelim = $delim;
00414 }
00415
00416
00417
00418
00419 function setRightDelimiter( $delim )
00420 {
00421 $this->RDelim = $delim;
00422 }
00423
00424
00425
00426
00427
00428 function display( $template = false, $extraParameters = false )
00429 {
00430 $output =& $this->fetch( $template, $extraParameters );
00431 if ( $this->ShowDetails )
00432 {
00433 echo '<h1>Result:</h1>' . "\n";
00434 echo '<hr/>' . "\n";
00435 }
00436 echo "$output";
00437 if ( $this->ShowDetails )
00438 {
00439 echo '<hr/>' . "\n";
00440 }
00441 if ( $this->ShowDetails )
00442 {
00443 echo "<h1>Template data:</h1>";
00444 echo "<p class=\"filename\">" . $template . "</p>";
00445 echo "<pre class=\"example\">" . htmlspecialchars( $this->Text ) . "</pre>";
00446 reset( $this->IncludeText );
00447 while ( ( $key = key( $this->IncludeText ) ) !== null )
00448 {
00449 $item =& $this->IncludeText[$key];
00450 echo "<p class=\"filename\">" . $key . "</p>";
00451 echo "<pre class=\"example\">" . htmlspecialchars( $item ) . "</pre>";
00452 next( $this->IncludeText );
00453 }
00454 echo "<h1>Result text:</h1>";
00455 echo "<p class=\"filename\">" . $template . "</p>";
00456 echo "<pre class=\"example\">" . htmlspecialchars( $output ) . "</pre>";
00457 reset( $this->IncludeOutput );
00458 while ( ( $key = key( $this->IncludeOutput ) ) !== null )
00459 {
00460 $item =& $this->IncludeOutput[$key];
00461 echo "<p class=\"filename\">" . $key . "</p>";
00462 echo "<pre class=\"example\">" . htmlspecialchars( $item ) . "</pre>";
00463 next( $this->IncludeOutput );
00464 }
00465 }
00466 }
00467
00468
00469
00470
00471
00472 function createLocalVariablesList()
00473 {
00474 $this->LocalVariablesNamesStack[] = array();
00475 $this->CurrentLocalVariablesNames =& $this->LocalVariablesNamesStack[ count( $this->LocalVariablesNamesStack ) - 1];
00476 }
00477
00478
00479
00480
00481 function hasLocalVariable( $varName, $rootNamespace )
00482 {
00483 return ( array_key_exists( $rootNamespace, $this->CurrentLocalVariablesNames ) &&
00484 array_key_exists( $varName, $this->CurrentLocalVariablesNames[$rootNamespace] ) );
00485 }
00486
00487
00488
00489
00490 function setLocalVariable( $varName, $varValue, $rootNamespace )
00491 {
00492 $this->CurrentLocalVariablesNames[$rootNamespace][$varName] = 1;
00493 $this->setVariable( $varName, $varValue, $rootNamespace );
00494 }
00495
00496
00497
00498
00499 function unsetLocalVariable( $varName, $rootNamespace )
00500 {
00501 if ( !$this->hasLocalVariable( $varName, $rootNamespace ) )
00502 return;
00503
00504 $this->unsetVariable( $varName, $rootNamespace );
00505 unset( $this->CurrentLocalVariablesNames[$rootNamespace][$varName] );
00506 }
00507
00508
00509
00510
00511 function unsetLocalVariables()
00512 {
00513 foreach ( $this->CurrentLocalVariablesNames as $ns => $vars )
00514 {
00515 foreach ( $vars as $var => $val )
00516 $this->unsetLocalVariable( $var, $ns );
00517 }
00518 }
00519
00520
00521
00522
00523 function destroyLocalVariablesList()
00524 {
00525 array_pop( $this->LocalVariablesNamesStack );
00526
00527 if ( $this->LocalVariablesNamesStack )
00528 $this->CurrentLocalVariablesNames =& $this->LocalVariablesNamesStack[ count( $this->LocalVariablesNamesStack ) - 1];
00529 else
00530 unset( $this->CurrentLocalVariablesNames );
00531 }
00532
00533
00534
00535
00536
00537 function &fetch( $template = false, $extraParameters = false, $returnResourceData = false )
00538 {
00539 $this->resetErrorLog();
00540
00541 $this->TemplateFetchList = array();
00542
00543 eZDebug::accumulatorStart( 'template_total' );
00544 eZDebug::accumulatorStart( 'template_load', 'template_total', 'Template load' );
00545 $root = null;
00546 if ( is_string( $template ) )
00547 {
00548 $resourceData =& $this->loadURIRoot( $template, true, $extraParameters );
00549 if ( $resourceData and
00550 $resourceData['root-node'] !== null )
00551 $root =& $resourceData['root-node'];
00552 }
00553 eZDebug::accumulatorStop( 'template_load' );
00554 if ( $resourceData['locales'] && count( $resourceData['locales'] ) )
00555 {
00556 $savedLocale = setlocale( LC_CTYPE, null );
00557 setlocale( LC_CTYPE, $resourceData['locales'] );
00558 }
00559
00560 $text = "";
00561
00562 if ( $root !== null or
00563 $resourceData['compiled-template'] )
00564 {
00565 if ( $this->ShowDetails )
00566 eZDebug::addTimingPoint( "Process" );
00567 eZDebug::accumulatorStart( 'template_processing', 'template_total', 'Template processing' );
00568
00569 $templateCompilationUsed = false;
00570 if ( $resourceData['compiled-template'] )
00571 {
00572 $textElements = array();
00573 if ( $this->executeCompiledTemplate( $resourceData, $textElements, "", "", $extraParameters ) )
00574 {
00575 $text = implode( '', $textElements );
00576 $templateCompilationUsed = true;
00577 }
00578 }
00579 if ( !$templateCompilationUsed )
00580 {
00581 if ( eZTemplate::isDebugEnabled() )
00582 {
00583 $fname = $resourceData['template-filename'];
00584 eZDebug::writeDebug( "FETCH START URI: $template, $fname" );
00585 }
00586 $this->process( $root, $text, "", "" );
00587 if ( eZTemplate::isDebugEnabled() )
00588 eZDebug::writeDebug( "FETCH END URI: $template, $fname" );
00589 }
00590
00591 eZDebug::accumulatorStop( 'template_processing' );
00592 if ( $this->ShowDetails )
00593 eZDebug::addTimingPoint( "Process done" );
00594 }
00595
00596 eZDebug::accumulatorStop( 'template_total' );
00597
00598 if ( $resourceData['locales'] && count( $resourceData['locales'] ) )
00599 {
00600 setlocale( LC_CTYPE, $savedLocale );
00601 }
00602
00603 if ( $returnResourceData )
00604 {
00605 $resourceData['result_text'] = $text;
00606 return $resourceData;
00607 }
00608 return $text;
00609 }
00610
00611 function process( &$root, &$text, $rootNamespace, $currentNamespace )
00612 {
00613 $this->createLocalVariablesList();
00614
00615 $textElements = array();
00616 $this->processNode( $root, $textElements, $rootNamespace, $currentNamespace );
00617 if ( is_array( $textElements ) )
00618 $text = implode( '', $textElements );
00619 else
00620 $text = $textElements;
00621
00622 $this->unsetLocalVariables();
00623 $this->destroyLocalVariablesList();
00624 }
00625
00626 function processNode( &$node, &$textElements, $rootNamespace, $currentNamespace )
00627 {
00628 $rslt = null;
00629 $nodeType = $node[0];
00630 if ( $nodeType == EZ_TEMPLATE_NODE_ROOT )
00631 {
00632 $children = $node[1];
00633 if ( $children )
00634 {
00635 foreach ( $children as $child )
00636 {
00637 $this->processNode( $child, $textElements, $rootNamespace, $currentNamespace );
00638 if ( !is_array( $textElements ) )
00639 eZDebug::writeError( "Textelements is no longer array: '$textElements'",
00640 'eztemplate::processNode::root' );
00641 }
00642 }
00643 }
00644 else if ( $nodeType == EZ_TEMPLATE_NODE_TEXT )
00645 {
00646 $textElements[] = $node[2];
00647 }
00648 else if ( $nodeType == EZ_TEMPLATE_NODE_VARIABLE )
00649 {
00650 $variableData = $node[2];
00651 $variablePlacement = $node[3];
00652 $rslt = $this->processVariable( $textElements, $variableData, $variablePlacement, $rootNamespace, $currentNamespace );
00653 if ( !is_array( $textElements ) )
00654 eZDebug::writeError( "Textelements is no longer array: '$textElements'",
00655 'eztemplate::processNode::variable' );
00656 }
00657 else if ( $nodeType == EZ_TEMPLATE_NODE_FUNCTION )
00658 {
00659 $functionChildren = $node[1];
00660 $functionName = $node[2];
00661 $functionParameters = $node[3];
00662 $functionPlacement = $node[4];
00663 $rslt = $this->processFunction( $functionName, $textElements, $functionChildren, $functionParameters, $functionPlacement, $rootNamespace, $currentNamespace );
00664 if ( !is_array( $textElements ) )
00665 eZDebug::writeError( "Textelements is no longer array: '$textElements'",
00666 "eztemplate::processNode::function( '$functionName' )" );
00667 }
00668
00669 return $rslt;
00670 }
00671
00672 function processVariable( &$textElements, $variableData, $variablePlacement, $rootNamespace, $currentNamespace )
00673 {
00674 $value = $this->elementValue( $variableData, $rootNamespace, $currentNamespace, $variablePlacement );
00675 $this->appendElementText( $textElements, $value, $rootNamespace, $currentNamespace );
00676 }
00677
00678 function processFunction( $functionName, &$textElements, $functionChildren, $functionParameters, $functionPlacement, $rootNamespace, $currentNamespace )
00679 {
00680
00681
00682 $func =& $this->Functions[$functionName];
00683 if ( is_array( $func ) )
00684 {
00685 $this->loadAndRegisterFunctions( $this->Functions[$functionName] );
00686 $func =& $this->Functions[$functionName];
00687 }
00688 if ( isset( $func ) and
00689 is_object( $func ) )
00690 {
00691 if ( eZTemplate::isMethodDebugEnabled() )
00692 eZDebug::writeDebug( "START FUNCTION: $functionName" );
00693 $value = $func->process( $this, $textElements, $functionName, $functionChildren, $functionParameters, $functionPlacement, $rootNamespace, $currentNamespace );
00694 if ( eZTemplate::isMethodDebugEnabled() )
00695 eZDebug::writeDebug( "END FUNCTION: $functionName" );
00696 return $value;
00697 }
00698 else
00699 {
00700 $this->warning( "", "Function \"$functionName\" is not registered" );
00701 }
00702 }
00703
00704 function fetchFunctionObject( $functionName )
00705 {
00706 $func =& $this->Functions[$functionName];
00707 if ( is_array( $func ) )
00708 {
00709 $this->loadAndRegisterFunctions( $this->Functions[$functionName] );
00710 $func =& $this->Functions[$functionName];
00711 }
00712 return $func;
00713 }
00714
00715
00716
00717
00718
00719
00720 function &load( $uri, $extraParameters = false, $returnResourceData = false )
00721 {
00722 $resourceData =& $this->loadURIRoot( $uri, true, $extraParameters );
00723 if ( !$resourceData or
00724 $resourceData['root-node'] === null )
00725 {
00726 $retValue = null;
00727 return $retValue;
00728 }
00729 else
00730 return $resourceData['root-node'];
00731 }
00732
00733 function parse( &$sourceText, &$rootElement, $rootNamespace, &$resourceData )
00734 {
00735 include_once( 'lib/eztemplate/classes/eztemplatemultipassparser.php' );
00736 $parser =& eZTemplateMultiPassParser::instance();
00737 $parser->parse( $this, $sourceText, $rootElement, $rootNamespace, $resourceData );
00738 }
00739
00740 function &loadURIData( &$resourceObject, $uri, $resourceName, $template, &$extraParameters, $displayErrors = true )
00741 {
00742 $resourceData = $this->resourceData( $resourceObject, $uri, $resourceName, $template );
00743
00744 $resourceData['text'] = null;
00745 $resourceData['root-node'] = null;
00746 $resourceData['compiled-template'] = false;
00747 $resourceData['time-stamp'] = null;
00748 $resourceData['key-data'] = null;
00749 $resourceData['locales'] = null;
00750
00751 if ( !$resourceObject->handleResource( $this, $resourceData, EZ_RESOURCE_FETCH, $extraParameters ) )
00752 {
00753 $resourceData = null;
00754 if ( $displayErrors )
00755 $this->warning( "", "No template could be loaded for \"$template\" using resource \"$resourceName\"" );
00756 }
00757 return $resourceData;
00758 }
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768 function resourceData( &$resourceObject, $uri, $resourceName, $templateName )
00769 {
00770 $resourceData = array();
00771 $resourceData['uri'] = $uri;
00772 $resourceData['resource'] = $resourceName;
00773 $resourceData['template-name'] = $templateName;
00774 $resourceData['template-filename'] = $templateName;
00775 $resourceData['handler'] =& $resourceObject;
00776 $resourceData['test-compile'] = $this->TestCompile;
00777 return $resourceData;
00778 }
00779
00780
00781
00782
00783
00784
00785
00786
00787 function &loadURIRoot( $uri, $displayErrors = true, &$extraParameters )
00788 {
00789 $res = "";
00790 $template = "";
00791 $resobj =& $this->resourceFor( $uri, $res, $template );
00792
00793 if ( !is_object( $resobj ) )
00794 {
00795 if ( $displayErrors )
00796 $this->warning( "", "No resource handler for \"$res\" and no default resource handler, aborting." );
00797 return null;
00798 }
00799
00800 $canCache = true;
00801 if ( !$resobj->servesStaticData() )
00802 $canCache = false;
00803 if ( !$this->isCachingAllowed() )
00804 $canCache = false;
00805
00806 $resourceData =& $this->loadURIData( $resobj, $uri, $res, $template, $extraParameters, $displayErrors );
00807
00808 if ( $resourceData )
00809 {
00810 $root = null;
00811 eZTemplate::appendTemplateToStatisticsIfNeeded( $resourceData['template-name'], $resourceData['template-filename'] );
00812 $this->appendTemplateFetch( $resourceData['template-filename'] );
00813
00814 if ( !$resourceData['compiled-template'] and
00815 $resourceData['root-node'] === null )
00816 {
00817 $root =& $resourceData['root-node'];
00818 $root = array( EZ_TEMPLATE_NODE_ROOT, false );
00819 $templateText =& $resourceData["text"];
00820 $keyData = $resourceData['key-data'];
00821 $this->setIncludeText( $uri, $templateText );
00822 $rootNamespace = '';
00823 $this->parse( $templateText, $root, $rootNamespace, $resourceData );
00824
00825 if ( eZTemplate::isDebugEnabled() )
00826 {
00827 $this->appendDebugNodes( $root, $resourceData );
00828 }
00829
00830 if ( $canCache )
00831 $resobj->setCachedTemplateTree( $keyData, $uri, $res, $template, $extraParameters, $root );
00832 }
00833 if ( !$resourceData['compiled-template'] and
00834 $canCache and
00835 $this->canCompileTemplate( $resourceData, $extraParameters ) )
00836 {
00837 $generateStatus = $this->compileTemplate( $resourceData, $extraParameters );
00838 if ( $generateStatus )
00839 $resourceData['compiled-template'] = true;
00840 }
00841 }
00842
00843 return $resourceData;
00844 }
00845
00846 function processURI( $uri, $displayErrors = true, &$extraParameters,
00847 &$textElements, $rootNamespace, $currentNamespace )
00848 {
00849 $this->Level++;
00850 if ( $this->Level > $this->MaxLevel )
00851 {
00852 eZDebug::writeError( $this->MaxLevelWarning, "eZTemplate:processURI Level: $this->Level @ $uri" );
00853 $textElements[] = $this->MaxLevelWarning;
00854 $this->Level--;
00855 return;
00856 }
00857 $resourceData =& $this->loadURIRoot( $uri, $displayErrors, $extraParameters );
00858 if ( !$resourceData or
00859 ( !$resourceData['compiled-template'] and
00860 $resourceData['root-node'] === null ) )
00861 {
00862 $this->Level--;
00863 return;
00864 }
00865
00866 $templateCompilationUsed = false;
00867
00868 if ( $resourceData['locales'] && count( $resourceData['locales'] ) )
00869 {
00870 $savedLocale = setlocale( LC_CTYPE, null );
00871 setlocale( LC_CTYPE, $resourceData['locales'] );
00872 }
00873
00874 if ( $resourceData['compiled-template'] )
00875 {
00876 if ( $this->executeCompiledTemplate( $resourceData, $textElements, $rootNamespace, $currentNamespace, $extraParameters ) )
00877 $templateCompilationUsed = true;
00878 }
00879 if ( !$templateCompilationUsed )
00880 {
00881 $root =& $resourceData['root-node'];
00882 $text = null;
00883 if ( eZTemplate::isDebugEnabled() )
00884 {
00885 $fname = $resourceData['template-filename'];
00886 eZDebug::writeDebug( "START URI: $uri, $fname" );
00887 }
00888 $this->process( $root, $text, $rootNamespace, $currentNamespace );
00889 if ( eZTemplate::isDebugEnabled() )
00890 eZDebug::writeDebug( "END URI: $uri, $fname" );
00891 $this->setIncludeOutput( $uri, $text );
00892 $textElements[] = $text;
00893 }
00894
00895 if ( $resourceData['locales'] && count( $resourceData['locales'] ) )
00896 {
00897 setlocale( LC_CTYPE, $savedLocale );
00898 }
00899 $this->Level--;
00900
00901 }
00902
00903 function canCompileTemplate( &$resourceData, &$extraParameters )
00904 {
00905 $resourceObject =& $resourceData['handler'];
00906 if ( !$resourceObject )
00907 return false;
00908 $canGenerate = $resourceObject->canCompileTemplate( $this, $resourceData, $extraParameters );
00909 return $canGenerate;
00910 }
00911
00912
00913
00914
00915
00916
00917 function validateTemplateFile( $file, $returnResourceData = false )
00918 {
00919 $this->resetErrorLog();
00920
00921 if ( !file_exists( $file ) )
00922 return false;
00923 $resourceHandler =& $this->resourceFor( $file, $resourceName, $templateName );
00924 if ( !$resourceHandler )
00925 return false;
00926 $resourceData = $this->resourceData( $resourceHandler, $file, $resourceName, $templateName );
00927 $keyData =& $resourceData['key-data'];
00928 $keyData = "file:" . $file;
00929 $key = md5( $keyData );
00930 $extraParameters = array();
00931
00932
00933
00934 $isCachingAllowed = $this->IsCachingAllowed;
00935 $this->IsCachingAllowed = false;
00936
00937 $resourceHandler->handleResource( $this, $resourceData, EZ_RESOURCE_FETCH, $extraParameters );
00938
00939
00940 $this->IsCachingAllowed = $isCachingAllowed;
00941
00942 $root =& $resourceData['root-node'];
00943 $root = array( EZ_TEMPLATE_NODE_ROOT, false );
00944 $templateText =& $resourceData["text"];
00945 $rootNamespace = '';
00946 $this->parse( $templateText, $root, $rootNamespace, $resourceData );
00947 if ( eZTemplate::isDebugEnabled() )
00948 {
00949 $this->appendDebugNodes( $root, $resourceData );
00950 }
00951
00952 $result = !$this->hasErrors() and !$this->hasWarnings();
00953 if ( $returnResourceData )
00954 {
00955 $resourceData['result'] = $result;
00956 return $resourceData;
00957 }
00958 return $result;
00959 }
00960
00961
00962
00963
00964
00965
00966 function compileTemplateFile( $file, $returnResourceData = false )
00967 {
00968 $this->resetErrorLog();
00969
00970 if ( !file_exists( $file ) )
00971 return false;
00972 $resourceHandler =& $this->resourceFor( $file, $resourceName, $templateName );
00973 if ( !$resourceHandler )
00974 return false;
00975 $resourceData = $this->resourceData( $resourceHandler, $file, $resourceName, $templateName );
00976 $keyData =& $resourceData['key-data'];
00977 $keyData = "file:" . $file;
00978 $key = md5( $keyData );
00979 $extraParameters = array();
00980 $resourceHandler->handleResource( $this, $resourceData, EZ_RESOURCE_FETCH, $extraParameters );
00981
00982 $isCompiled = false;
00983 if ( isset( $resourceData['compiled-template'] ) )
00984 $isCompiled = $resourceData['compiled-template'];
00985
00986 if ( !$isCompiled )
00987 {
00988 $root =& $resourceData['root-node'];
00989 $root = array( EZ_TEMPLATE_NODE_ROOT, false );
00990 $templateText =& $resourceData["text"];
00991 $rootNamespace = '';
00992 $this->parse( $templateText, $root, $rootNamespace, $resourceData );
00993 if ( eZTemplate::isDebugEnabled() )
00994 {
00995 $this->appendDebugNodes( $root, $resourceData );
00996 }
00997
00998 $result = eZTemplateCompiler::compileTemplate( $this, $key, $resourceData );
00999 }
01000 else
01001 {
01002 $result = true;
01003 }
01004
01005 if ( $returnResourceData )
01006 {
01007 $resourceData['result'] = $result;
01008 return $resourceData;
01009 }
01010 return $result;
01011 }
01012
01013 function compileTemplate( &$resourceData, &$extraParameters )
01014 {
01015 $resourceObject =& $resourceData['handler'];
01016 if ( !$resourceObject )
01017 return false;
01018 $keyData = $resourceData['key-data'];
01019 $uri = $resourceData['uri'];
01020 $resourceName = $resourceData['resource'];
01021 $templatePath = $resourceData['template-name'];
01022 return $resourceObject->compileTemplate( $this, $keyData, $uri, $resourceName, $templatePath, $extraParameters, $resourceData );
01023 }
01024
01025 function executeCompiledTemplate( &$resourceData, &$textElements, $rootNamespace, $currentNamespace, &$extraParameters )
01026 {
01027 $resourceObject =& $resourceData['handler'];
01028 if ( !$resourceObject )
01029 return false;
01030 $keyData = $resourceData['key-data'];
01031 $uri = $resourceData['uri'];
01032 $resourceName = $resourceData['resource'];
01033 $templatePath = $resourceData['template-name'];
01034 $timestamp = $resourceData['time-stamp'];
01035 return $resourceObject->executeCompiledTemplate( $this, $textElements,
01036 $keyData, $uri, $resourceData, $templatePath,
01037 $extraParameters, $timestamp,
01038 $rootNamespace, $currentNamespace );
01039 }
01040
01041
01042
01043
01044
01045
01046
01047
01048 function &resourceFor( &$uri, &$res, &$template )
01049 {
01050 $args = explode( ":", $uri );
01051 if ( count( $args ) > 1 )
01052 {
01053 $res = $args[0];
01054 $template = $args[1];
01055 }
01056 else
01057 $template = $uri;
01058 if ( eZTemplate::isDebugEnabled() )
01059 eZDebug::writeNotice( "eZTemplate: Loading template \"$template\" with resource \"$res\"" );
01060 $resobj =& $this->DefaultResource;
01061 if ( isset( $this->Resources[$res] ) and is_object( $this->Resources[$res] ) )
01062 {
01063 $resobj =& $this->Resources[$res];
01064 }
01065 return $resobj;
01066 }
01067
01068
01069
01070
01071
01072 function &resourceHandler( $resourceName )
01073 {
01074 $resource =& $this->DefaultResource;
01075 if ( isset( $this->Resources[$resourceName] ) and
01076 is_object( $this->Resources[$resourceName] ) )
01077 {
01078 $resource =& $this->Resources[$resourceName];
01079 }
01080 return $resource;
01081 }
01082
01083 function hasChildren( &$function, $functionName )
01084 {
01085 $hasChildren = $function->hasChildren();
01086 if ( is_array( $hasChildren ) )
01087 return $hasChildren[$functionName];
01088 else
01089 return $hasChildren;
01090 }
01091
01092
01093
01094
01095 function emptyVariable()
01096 {
01097 return array( "type" => "null" );
01098 }
01099
01100
01101
01102
01103 function mergeNamespace( $rootNamespace, $additionalNamespace )
01104 {
01105 $namespace = $rootNamespace;
01106 if ( $namespace == '' )
01107 $namespace = $additionalNamespace;
01108 else if ( $additionalNamespace != '' )
01109 $namespace = "$namespace:$additionalNamespace";
01110 return $namespace;
01111 }
01112
01113
01114
01115
01116 function &elementValue( &$dataElements, $rootNamespace, $currentNamespace, $placement = false,
01117 $checkExistance = false, $checkForProxy = false )
01118 {
01119
01120
01121
01122
01123
01124
01125
01126
01127 $value = null;
01128 if ( !is_array( $dataElements ) )
01129 {
01130 $this->error( "elementValue",
01131 "Missing array data structure, got " . gettype( $dataElements ) );
01132 $retVal = null;
01133 return $retVal;
01134 }
01135 foreach ( $dataElements as $dataElement )
01136 {
01137 if ( is_null( $dataElement ) )
01138 {
01139 $retVal = null;
01140 return $retVal;
01141 }
01142 $dataType = $dataElement[0];
01143 switch ( $dataType )
01144 {
01145 case EZ_TEMPLATE_TYPE_VOID:
01146 {
01147 if ( !$checkExistance )
01148 $this->warning( 'elementValue',
01149 'Found void datatype, should not be used' );
01150 else
01151 {
01152 $retVal = null;
01153 return $retVal;
01154 }
01155 } break;
01156 case EZ_TEMPLATE_TYPE_STRING:
01157 case EZ_TEMPLATE_TYPE_NUMERIC:
01158 case EZ_TEMPLATE_TYPE_IDENTIFIER:
01159 case EZ_TEMPLATE_TYPE_BOOLEAN:
01160 case EZ_TEMPLATE_TYPE_ARRAY:
01161 {
01162 $value = $dataElement[1];
01163 } break;
01164 case EZ_TEMPLATE_TYPE_VARIABLE:
01165 {
01166 $variableData = $dataElement[1];
01167 $variableNamespace = $variableData[0];
01168 $variableNamespaceScope = $variableData[1];
01169 $variableName = $variableData[2];
01170 if ( $variableNamespaceScope == EZ_TEMPLATE_NAMESPACE_SCOPE_GLOBAL )
01171 $namespace = $variableNamespace;
01172 else if ( $variableNamespaceScope == EZ_TEMPLATE_NAMESPACE_SCOPE_LOCAL )
01173 $namespace = $this->mergeNamespace( $rootNamespace, $variableNamespace );
01174 else if ( $variableNamespaceScope == EZ_TEMPLATE_NAMESPACE_SCOPE_RELATIVE )
01175 $namespace = $this->mergeNamespace( $currentNamespace, $variableNamespace );
01176 else
01177 $namespace = false;
01178 if ( $this->hasVariable( $variableName, $namespace ) )
01179 {
01180 $value = $this->variable( $variableName, $namespace );
01181 }
01182 else
01183 {
01184 if ( !$checkExistance )
01185 $this->error( '', "Unknown template variable '$variableName' in namespace '$namespace'", $placement );
01186 {
01187 $retVal = null;
01188 return $retVal;
01189 }
01190 }
01191 } break;
01192 case EZ_TEMPLATE_TYPE_ATTRIBUTE:
01193 {
01194 $attributeData = $dataElement[1];
01195 $attributeValue = $this->elementValue( $attributeData, $rootNamespace, $currentNamespace, false, $checkExistance );
01196
01197 if ( !is_null( $attributeValue ) )
01198 {
01199 if ( !is_numeric( $attributeValue ) and
01200 !is_string( $attributeValue ) and
01201 !is_bool( $attributeValue ) )
01202 {
01203 if ( !$checkExistance )
01204 $this->error( "",
01205 "Cannot use type " . gettype( $attributeValue ) . " for attribute lookup", $placement );
01206 {
01207 $retVal = null;
01208 return $retVal;
01209 }
01210 }
01211 if ( is_array( $value ) )
01212 {
01213 if ( array_key_exists( $attributeValue, $value ) )
01214 {
01215 unset( $tempValue );
01216 $tempValue =& $value[$attributeValue];
01217 unset( $value );
01218 $value =& $tempValue;
01219 }
01220 else
01221 {
01222 if ( !$checkExistance )
01223 {
01224 $arrayAttributeList = array_keys( $value );
01225 $arrayCount = count( $arrayAttributeList );
01226 $errorMessage = "No such attribute for array($arrayCount): $attributeValue";
01227 $chooseText = "Choose one of following: ";
01228 $errorMessage .= "\n$chooseText";
01229 $errorMessage .= $this->expandAttributes( $arrayAttributeList, $chooseText, 25 );
01230 $this->error( "",
01231 $errorMessage, $placement );
01232 }
01233 $retVal = null;
01234 return $retVal;
01235 }
01236 }
01237 else if ( is_object( $value ) )
01238 {
01239 if ( method_exists( $value, "attribute" ) and
01240 method_exists( $value, "hasattribute" ) )
01241 {
01242 if ( $value->hasAttribute( $attributeValue ) )
01243 {
01244 unset( $tempValue );
01245 $tempValue =& $value->attribute( $attributeValue );
01246 unset( $value );
01247 $value =& $tempValue;
01248 }
01249 else
01250 {
01251 if ( !$checkExistance )
01252 {
01253 $objectAttributeList = array();
01254 if ( method_exists( $value, 'attributes' ) )
01255 $objectAttributeList = $value->attributes();
01256 $objectClass= get_class( $value );
01257 $errorMessage = "No such attribute for object($objectClass): $attributeValue";
01258 $chooseText = "Choose one of following: ";
01259 $errorMessage .= "\n$chooseText";
01260 $errorMessage .= $this->expandAttributes( $objectAttributeList, $chooseText, 25 );
01261 $this->error( "",
01262 $errorMessage, $placement );
01263 }
01264 $retVal = null;
01265 return $retVal;
01266 }
01267 }
01268 else
01269 {
01270 if ( !$checkExistance )
01271 $this->error( "",
01272 "Cannot retrieve attribute of object(" . get_class( $value ) .
01273 "), no attribute functions available",
01274 $placement );
01275 $retVal = null;
01276 return $retVal;
01277 }
01278 }
01279 else
01280 {
01281 if ( !$checkExistance )
01282 $this->error( "",
01283 "Cannot retrieve attribute of a " . gettype( $value ),
01284 $placement );
01285 $retVal = null;
01286 return $retVal;
01287 }
01288 }
01289 else
01290 {
01291 if ( !$checkExistance )
01292 $this->error( '',
01293 'Attribute value was null, cannot get attribute',
01294 $placement );
01295 $retVal = null;
01296 return $retVal;
01297 }
01298 } break;
01299 case EZ_TEMPLATE_TYPE_OPERATOR:
01300 {
01301 $operatorParameters = $dataElement[1];
01302 $operatorName = $operatorParameters[0];
01303 $operatorParameters = array_splice( $operatorParameters, 1 );
01304 if ( is_object( $value ) and
01305 method_exists( $value, 'templateValue' ) )
01306 {
01307 if ( $checkForProxy )
01308 $dataElements['proxy-object-found'] = true;
01309 $value = $value->templateValue();
01310 }
01311 $valueData = array( 'value' => $value );
01312 $this->processOperator( $operatorName, $operatorParameters, $rootNamespace, $currentNamespace,
01313 $valueData, $placement, $checkExistance );
01314 unset( $value );
01315 $value = $valueData['value'];
01316 } break;
01317 default:
01318 {
01319 if ( !$checkExistance )
01320 $this->error( "elementValue",
01321 "Unknown data type: '$dataType'" );
01322 $retVal = null;
01323 return $retVal;
01324 }
01325 }
01326 }
01327 if ( is_object( $value ) and
01328 method_exists( $value, 'templateValue' ) )
01329 {
01330 if ( $checkForProxy )
01331 $dataElements['proxy-object-found'] = true;
01332 $retVal = $value->templateValue();
01333 return $retVal;
01334 }
01335 return $value;
01336 }
01337
01338 function expandAttributes( $attributeList, $chooseText, $maxThreshold, $minThreshold = 1 )
01339 {
01340 $errorMessage = '';
01341 $attributeCount = count( $attributeList );
01342 if ( $attributeCount < $minThreshold )
01343 return $errorMessage;
01344 if ( $attributeCount < $maxThreshold )
01345 {
01346 $chooseLength = strlen( $chooseText );
01347 $attributeText = '';
01348 $i = 0;
01349 foreach ( $attributeList as $attributeName )
01350 {
01351 if ( $i > 0 )
01352 $attributeText .= ",";
01353 if ( strlen( $attributeText ) > 40 )
01354 {
01355 $attributeText .= "\n";
01356 $errorMessage .= $attributeText;
01357 $errorMessage .= str_repeat( ' ', $chooseLength );
01358 $attributeText = '';
01359 }
01360 else if ( $i > 0 )
01361 $attributeText .= " ";
01362 $attributeText .= $attributeName;
01363 ++$i;
01364 }
01365 $errorMessage .= $attributeText;
01366 }
01367 return $errorMessage;
01368 }
01369
01370 function processOperator( $operatorName, $operatorParameters, $rootNamespace, $currentNamespace,
01371 &$valueData, $placement = false, $checkExistance = false )
01372 {
01373 $namedParameters = array();
01374 $operatorParameterDefinition = $this->operatorParameterList( $operatorName );
01375 $i = 0;
01376 foreach ( $operatorParameterDefinition as $parameterName => $parameterType )
01377 {
01378 if ( !isset( $operatorParameters[$i] ) or
01379 !isset( $operatorParameters[$i][0] ) or
01380 $operatorParameters[$i][0] == EZ_TEMPLATE_TYPE_VOID )
01381 {
01382 if ( $parameterType["required"] )
01383 {
01384 if ( !$checkExistance )
01385 $this->warning( "eZTemplateOperatorElement", "Parameter '$parameterName' ($i) missing",
01386 $placement );
01387 $namedParameters[$parameterName] = $parameterType["default"];
01388 }
01389 else
01390 {
01391 $namedParameters[$parameterName] = $parameterType["default"];
01392 }
01393 }
01394 else
01395 {
01396 $parameterData = $operatorParameters[$i];
01397 $namedParameters[$parameterName] = $this->elementValue( $parameterData, $rootNamespace, $currentNamespace, false, $checkExistance );
01398 }
01399 ++$i;
01400 }
01401
01402 if ( is_array( $this->Operators[$operatorName] ) )
01403 {
01404 $this->loadAndRegisterOperators( $this->Operators[$operatorName] );
01405 }
01406 $op =& $this->Operators[$operatorName];
01407 if ( isset( $op ) )
01408 {
01409 if ( is_object( $op ) and method_exists( $op, 'modify' ) )
01410 {
01411 $value = $valueData['value'];
01412 if ( eZTemplate::isMethodDebugEnabled() )
01413 eZDebug::writeDebug( "START OPERATOR: $operatorName" );
01414 $op->modify( $this, $operatorName, $operatorParameters, $rootNamespace, $currentNamespace, $value, $namedParameters,
01415 $placement );
01416 if ( eZTemplate::isMethodDebugEnabled() )
01417 eZDebug::writeDebug( "END OPERATOR: $operatorName" );
01418 $valueData['value'] = $value;
01419 }
01420 else
01421 $this->error( '', "Object problem with operator '$operatorName' ",
01422 $placement );
01423 }
01424 else if ( !$checkExistance )
01425 $this->warning( "", "Operator '$operatorName' is not registered",
01426 $placement );
01427 }
01428
01429
01430
01431
01432 function &variableElementValue( &$data, $def_nspace )
01433 {
01434 if ( $data["type"] != "variable" )
01435 {
01436 $retValue = null;
01437 return $retValue;
01438 }
01439
01440 $nspace = $data["namespace"];
01441 if ( $nspace === false )
01442 $nspace = $def_nspace;
01443 else
01444 {
01445 if ( $def_nspace != "" )
01446 $nspace = $def_nspace . ':' . $nspace;
01447 }
01448 $name = $data["name"];
01449 if ( !$this->hasVariable( $name, $nspace ) )
01450 {
01451 $var_name = $name;
01452 $this->warning( "", "Undefined variable: \"$var_name\"" . ( $nspace != "" ? " in namespace \"$nspace\"" : "" ) );
01453 $retValue = null;
01454 return $retValue;
01455 }
01456 $value =& $this->variable( $name, $nspace );
01457 $return_value =& $value;
01458 $attrs = $data["attributes"];
01459 if ( count( $attrs ) > 0 )
01460 {
01461 foreach( $attrs as $key => $attr )
01462 {
01463 $attr_value = $this->attributeValue( $attr, $def_nspace );
01464 if ( !is_null( $attr_value ) )
01465 {
01466 if ( !is_numeric( $attr_value ) and
01467 !is_string( $attr_value ) )
01468 {
01469 $this->error( "",
01470 "Cannot use type " . gettype( $attr_value ) . " for attribute lookup" );
01471 $retValue = null;
01472 return $retValue;
01473 }
01474 if ( is_array( $return_value ) )
01475 {
01476 if ( isset( $return_value[$attr_value] ) )
01477 $return_value =& $return_value[$attr_value];
01478 else
01479 {
01480 $this->error( "",
01481 "No such attribute for array: $attr_value" );
01482 $retValue = null;
01483 return $retValue;
01484 }
01485 }
01486 else if ( is_object( $return_value ) )
01487 {
01488 if ( method_exists( $return_value, "attribute" ) and
01489 method_exists( $return_value, "hasattribute" ) )
01490 {
01491 if ( $return_value->hasAttribute( $attr_value ) )
01492 {
01493 unset( $return_attribute_value );
01494 $return_attribute_value =& $return_value->attribute( $attr_value );
01495 unset( $return_value );
01496 $return_value =& $return_attribute_value;
01497 }
01498 else
01499 {
01500 $this->error( "",
01501 "No such attribute for object: $attr_value" );
01502 $retValue = null;
01503 return $retValue;
01504 }
01505 }
01506 else
01507 {
01508 $this->error( "",
01509 "Cannot retrieve attribute of object(" . get_class( $return_value ) .
01510 "), no attribute functions available." );
01511 $retValue = null;
01512 return $retValue;
01513 }
01514 }
01515 else
01516 {
01517 $this->error( "",
01518 "Cannot retrieve attribute of a " . gettype( $return_value ) );
01519 $retValue = null;
01520 return $retValue;
01521 }
01522 }
01523 else
01524 {
01525 $retValue = null;
01526 return $retValue;
01527 }
01528 }
01529 }
01530 return $return_value;
01531 }
01532
01533
01534
01535
01536 function attributeValue( &$data, $nspace )
01537 {
01538 switch ( $data["type"] )
01539 {
01540 case "map":
01541 {
01542 return $data["content"];
01543 } break;
01544 case "index":
01545 {
01546 return $data["content"];
01547 } break;
01548 case "variable":
01549 {
01550 return $this->elementValue( $data["content"], $nspace );
01551 } break;
01552 default:
01553 {
01554 $this->error( "attributeValue()", "Unknown attribute type: " . $data["type"] );
01555 return null;
01556 }
01557 }
01558 }
01559
01560
01561
01562
01563 function variableText( $var, $namespace = "", $attrs = array() )
01564 {
01565 $txt = "$";
01566 if ( $namespace != "" )
01567 $txt .= "$namespace:";
01568 $txt .= $var;
01569 if ( count( $attrs ) > 0 )
01570 $txt .= "." . implode( ".", $attrs );
01571 return $txt;
01572 }
01573
01574
01575
01576
01577 function operatorParameterList( $name )
01578 {
01579 $param_list = array();
01580 if ( isset( $this->Operators[$name] ) and
01581 is_array( $this->Operators[$name] ) )
01582 {
01583 $this->loadAndRegisterOperators( $this->Operators[$name] );
01584 }
01585 $op =& $this->Operators[$name];
01586 if ( isset( $op ) and
01587 method_exists( $op, "namedparameterlist" ) )
01588 {
01589 $param_list = $op->namedParameterList();
01590 if ( method_exists( $op, "namedparameterperoperator" ) and
01591 $op->namedParameterPerOperator() )
01592 {
01593 if ( !isset( $param_list[$name] ) )
01594 return array();
01595 $param_list = $param_list[$name];
01596 }
01597 }
01598 return $param_list;
01599 }
01600
01601
01602
01603
01604
01605 function doOperator( &$element, &$namespace, &$current_nspace, &$value, &$operatorName, &$operatorParameters, &$named_params )
01606 {
01607 if ( is_array( $this->Operators[$operatorName] ) )
01608 {
01609 $this->loadAndRegisterOperators( $this->Operators[$operatorName] );
01610 }
01611 $op =& $this->Operators[$operatorName];
01612 if ( isset( $op ) )
01613 {
01614 $op->modify( $element, $this, $operatorName, $operatorParameters, $namespace, $current_nspace, $value, $named_params );
01615 }
01616 else
01617 $this->warning( "", "Operator \"$operatorName\" is not registered" );
01618 }
01619
01620
01621
01622
01623 function doFunction( &$name, &$func_obj, $nspace, $current_nspace )
01624 {
01625 $func =& $this->Functions[$name];
01626 if ( is_array( $func ) )
01627 {
01628 $this->loadAndRegisterFunctions( $this->Functions[$name] );
01629 $func =& $this->Functions[$name];
01630 }
01631 if ( isset( $func ) and
01632 is_object( $func ) )
01633 {
01634 return $func->process( $this, $name, $func_obj, $nspace, $current_nspace );
01635 }
01636 else
01637 {
01638 $this->warning( "", "Function \"$name\" is not registered" );
01639 return false;
01640 }
01641 }
01642
01643
01644
01645
01646
01647 function setVariable( $var, $val, $namespace = "" )
01648 {
01649 if ( array_key_exists( $namespace, $this->Variables ) and
01650 array_key_exists( $var, $this->Variables[$namespace] ) )
01651 unset( $this->Variables[$namespace][$var] );
01652 $this->Variables[$namespace][$var] = $val;
01653 }
01654
01655
01656
01657
01658
01659
01660 function setVariableRef( $var, &$val, $namespace = "" )
01661 {
01662 if ( array_key_exists( $namespace, $this->Variables ) and
01663 array_key_exists( $var, $this->Variables[$namespace] ) )
01664 unset( $this->Variables[$namespace][$var] );
01665 $this->Variables[$namespace][$var] =& $val;
01666 }
01667
01668
01669
01670
01671 function unsetVariable( $var, $namespace = "" )
01672 {
01673 if ( array_key_exists( $namespace, $this->Variables ) and
01674 array_key_exists( $var, $this->Variables[$namespace] ) )
01675 unset( $this->Variables[$namespace][$var] );
01676 else
01677 $this->warning( "unsetVariable()", "Undefined Variable: \$$namespace:$var, cannot unset" );
01678 }
01679
01680
01681
01682
01683
01684 function hasVariable( $var, $namespace = "", $attrs = array() )
01685 {
01686 $exists = ( array_key_exists( $namespace, $this->Variables ) and
01687 array_key_exists( $var, $this->Variables[$namespace] ) );
01688 if ( $exists and count( $attrs ) > 0 )
01689 {
01690 $ptr =& $this->Variables[$namespace][$var];
01691 foreach( $attrs as $attr )
01692 {
01693 unset( $tmp );
01694 if ( is_object( $ptr ) )
01695 {
01696 if ( $ptr->hasAttribute( $attr ) )
01697 $tmp =& $ptr->attribute( $attr );
01698 else
01699 return false;
01700 }
01701 else if ( is_array( $ptr ) )
01702 {
01703 if ( array_key_exists( $attr, $ptr ) )
01704 $tmp =& $ptr[$attr];
01705 else
01706 return false;
01707 }
01708 else
01709 {
01710 return false;
01711 }
01712 unset( $ptr );
01713 $ptr =& $tmp;
01714 }
01715 }
01716 return $exists;
01717 }
01718
01719
01720
01721
01722
01723 function &variable( $var, $namespace = "", $attrs = array() )
01724 {
01725 $val = null;
01726 $exists = ( array_key_exists( $namespace, $this->Variables ) and
01727 array_key_exists( $var, $this->Variables[$namespace] ) );
01728 if ( $exists )
01729 {
01730 if ( count( $attrs ) > 0 )
01731 {
01732 $ptr =& $this->Variables[$namespace][$var];
01733 foreach( $attrs as $attr )
01734 {
01735 unset( $tmp );
01736 if ( is_object( $ptr ) )
01737 {
01738 if ( $ptr->hasAttribute( $attr ) )
01739 $tmp =& $ptr->attribute( $attr );
01740 else
01741 return $val;
01742 }
01743 else if ( is_array( $ptr ) )
01744 {
01745 if ( array_key_exists( $attr, $ptr ) )
01746 $tmp =& $ptr[$attr];
01747 else
01748 return $val;
01749 }
01750 else
01751 return $val;
01752 unset( $ptr );
01753 $ptr =& $tmp;
01754 }
01755 if ( isset( $ptr ) )
01756 return $ptr;
01757 }
01758 else
01759 {
01760 $val =& $this->Variables[$namespace][$var];
01761 }
01762 }
01763 return $val;
01764 }
01765
01766
01767
01768
01769
01770 function &variableAttribute( &$var, $attrs )
01771 {
01772 $val = null;
01773 if ( count( $attrs ) > 0 )
01774 {
01775 $ptr =& $var;
01776 foreach( $attrs as $attr )
01777 {
01778 unset( $tmp );
01779 if ( is_object( $ptr ) )
01780 {
01781 if ( $ptr->hasAttribute( $attr ) )
01782 $tmp =& $ptr->attribute( $attr );
01783 else
01784 return $val;
01785 }
01786 else if ( is_array( $ptr ) )
01787 {
01788 if ( isset( $ptr[$attr] ) )
01789 $tmp =& $ptr[$attr];
01790 else
01791 return $val;
01792 }
01793 else
01794 return $val;
01795 unset( $ptr );
01796 $ptr =& $tmp;
01797 }
01798 if ( isset( $ptr ) )
01799 return $ptr;
01800 }
01801 return $val;
01802 }
01803
01804
01805
01806 function appendElement( &$text, &$item, $nspace, $name )
01807 {
01808 $this->appendElementText( $textElements, $item, $nspace, $name );
01809 $text .= implode( '', $textElements );
01810 }
01811
01812
01813
01814 function appendElementText( &$textElements, &$item, $nspace, $name )
01815 {
01816 if ( !is_array( $textElements ) )
01817 $textElements = array();
01818 if ( is_object( $item ) and
01819 method_exists( $item, 'templateValue' ) )
01820 {
01821 $item = $item->templateValue();
01822 $textElements[] = "$item";
01823 }
01824 else if ( is_object( $item ) )
01825 {
01826 $hasTemplateData = false;
01827 if ( method_exists( $item, 'templateData' ) )
01828 {
01829 $templateData = $item->templateData();
01830 if ( is_array( $templateData ) and
01831 isset( $templateData['type'] ) )
01832 {
01833 $templateType =& $templateData['type'];
01834 if ( $templateType == 'template' and
01835 isset( $templateData['uri'] ) and
01836 isset( $templateData['template_variable_name'] ) )
01837 {
01838 $templateURI =& $templateData['uri'];
01839 $templateVariableName =& $templateData['template_variable_name'];
01840 $templateText = '';
01841 include_once( 'lib/eztemplate/classes/eztemplateincludefunction.php' );
01842 $this->setVariableRef( $templateVariableName, $item, $name );
01843 eZTemplateIncludeFunction::handleInclude( $textElements, $templateURI, $this, $nspace, $name );
01844 $hasTemplateData = true;
01845 }
01846 }
01847 }
01848 if ( !$hasTemplateData )
01849 $textElements[] = 'Object(' . get_class( $item ) . ')';
01850 }
01851 else
01852 $textElements[] = "$item";
01853 return $textElements;
01854 }
01855
01856
01857
01858
01859
01860
01861
01862 function appendDebugNodes( &$root, &$resourceData )
01863 {
01864 $path = $resourceData['template-filename'];
01865 $uri = $resourceData['uri'];
01866 $preText = "\n<!-- START: including template: $path ($uri) -->\n";
01867 if ( eZTemplate::isXHTMLCodeIncluded() )
01868 $preText .= "<p class=\"small\">$path</p><br/>\n";
01869 $postText = "\n<!-- STOP: including template: $path ($uri) -->\n";
01870 include_once( 'lib/eztemplate/classes/eztemplatenodetool.php' );
01871 $root[1] = array_merge( array( eZTemplateNodeTool::createTextNode( $preText ) ), $root[1] );
01872 $root[1][] = eZTemplateNodeTool::createTextNode( $postText );
01873 }
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885 function registerFunctions( &$functionObject )
01886 {
01887 $this->registerFunctionsInternal( $functionObject );
01888 }
01889
01890
01891
01892 function registerAutoloadFunctions( $functionDefinition )
01893 {
01894 if ( ( ( isset( $functionDefinition['function'] ) or
01895 ( isset( $functionDefinition['script'] ) and
01896 isset( $functionDefinition['class'] ) ) ) and
01897 ( isset( $functionDefinition['function_names_function'] ) or
01898 isset( $functionDefinition['function_names'] ) ) ) )
01899 {
01900 if ( isset( $functionDefinition['function_names_function'] ) )
01901 {
01902 $functionNamesFunction = $functionDefinition['function_names_function'];
01903 if ( !function_exists( $functionNamesFunction ) )
01904 {
01905 $this->error( 'registerFunctions', "Cannot register function definition, missing function names function '$functionNamesFunction'" );
01906 return;
01907 }
01908 $functionNames = $operatorNamesFunction();
01909 }
01910 else
01911 $functionNames = $functionDefinition['function_names'];
01912 foreach ( $functionNames as $functionName )
01913 {
01914 $this->Functions[$functionName] =& $functionDefinition;
01915 }
01916 if ( isset( $functionDefinition['function_attributes'] ) )
01917 {
01918 foreach ( $functionDefinition['function_attributes'] as $functionAttributeName )
01919 {
01920 unset( $this->FunctionAttributes[$functionAttributeName] );
01921 $this->FunctionAttributes[$functionAttributeName] =& $functionDefinition;
01922 }
01923 }
01924 }
01925 else
01926 $this->error( 'registerFunctions', 'Cannot register function definition, missing data' );
01927 }
01928
01929 function loadAndRegisterFunctions( $functionDefinition )
01930 {
01931 eZDebug::accumulatorStart( 'template_register_function', 'template_total', 'Template load and register function' );
01932 $functionObject = null;
01933 if ( isset( $functionDefinition['function'] ) )
01934 {
01935 $function = $functionDefinition['function'];
01936
01937 if ( function_exists( $function ) )
01938 $functionObject = $function();
01939 }
01940 else if ( isset( $functionDefinition['script'] ) )
01941 {
01942 $script = $functionDefinition['script'];
01943 $class = $functionDefinition['class'];
01944
01945 include_once( $script );
01946 if ( class_exists( $class ) )
01947 $functionObject = new $class();
01948 }
01949 eZDebug::accumulatorStop( 'template_register_function' );
01950 if ( is_object( $functionObject ) )
01951 {
01952 $this->registerFunctionsInternal( $functionObject, true );
01953 return true;
01954 }
01955 return false;
01956 }
01957
01958
01959
01960
01961 function registerFunctionsInternal( &$functionObject, $debug = false )
01962 {
01963 if ( !is_object( $functionObject ) or
01964 !method_exists( $functionObject, 'functionList' ) )
01965 return false;
01966 foreach ( $functionObject->functionList() as $functionName )
01967 {
01968 $this->Functions[$functionName] =& $functionObject;
01969 }
01970 if ( method_exists( $functionObject, "attributeList" ) )
01971 {
01972 $functionAttributes = $functionObject->attributeList();
01973 foreach ( $functionAttributes as $attributeName => $hasChildren )
01974 {
01975 unset( $this->FunctionAttributes[$attributeName] );
01976 $this->FunctionAttributes[$attributeName] = $hasChildren;
01977 }
01978 }
01979 return true;
01980 }
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990 function registerFunction( $func_name, &$func_obj )
01991 {
01992 $this->Functions[$func_name] =& $func_obj;
01993 if ( method_exists( $func_obj, "attributeList" ) )
01994 {
01995 $attrs = $func_obj->attributeList();
01996 while ( list( $attr_name, $has_children ) = each( $attrs ) )
01997 {
01998 $this->FunctionAttributes[$attr_name] = $has_children;
01999 }
02000 }
02001 }
02002
02003
02004
02005
02006
02007 function registerLiteral( $func_name )
02008 {
02009 $this->Literals[$func_name] = true;
02010 }
02011
02012
02013
02014
02015 function unregisterLiteral( $func_name )
02016 {
02017 unset( $this->Literals[$func_name] );
02018 }
02019
02020
02021
02022 function registerAutoloadOperators( $operatorDefinition )
02023 {
02024 if ( ( ( isset( $operatorDefinition['function'] ) or
02025 ( isset( $operatorDefinition['script'] ) and
02026 isset( $operatorDefinition['class'] ) ) ) and
02027 ( isset( $operatorDefinition['operator_names_function'] ) or
02028 isset( $operatorDefinition['operator_names'] ) ) ) )
02029 {
02030 if ( isset( $operatorDefinition['operator_names_function'] ) )
02031 {
02032 $operatorNamesFunction = $operatorDefinition['operator_names_function'];
02033 if ( !function_exists( $operatorNamesFunction ) )
02034 {
02035 $this->error( 'registerOperators', "Cannot register operator definition, missing operator names function '$operatorNamesFunction'" );
02036 return;
02037 }
02038 $operatorNames = $operatorNamesFunction();
02039 }
02040 else
02041 $operatorNames = $operatorDefinition['operator_names'];
02042 foreach ( $operatorNames as $operatorName )
02043 {
02044 $this->Operators[$operatorName] =& $operatorDefinition;
02045 }
02046 }
02047 else
02048 $this->error( 'registerOperators', 'Cannot register operator definition, missing data' );
02049 }
02050
02051 function loadAndRegisterOperators( $operatorDefinition )
02052 {
02053 $operatorObject = null;
02054 if ( isset( $operatorDefinition['function'] ) )
02055 {
02056 $function = $operatorDefinition['function'];
02057
02058 if ( function_exists( $function ) )
02059 $operatorObject =& $function();
02060 }
02061 else if ( isset( $operatorDefinition['script'] ) )
02062 {
02063 $script = $operatorDefinition['script'];
02064 $class = $operatorDefinition['class'];
02065
02066 include_once( $script );
02067 if ( class_exists( $class ) )
02068 {
02069 if ( isset( $operatorDefinition['class_parameter'] ) )
02070 $operatorObject = new $class( $operatorDefinition['class_parameter'] );
02071 else
02072 $operatorObject = new $class();
02073 }
02074 }
02075 if ( is_object( $operatorObject ) )
02076 {
02077 $this->registerOperatorsInternal( $operatorObject, true );
02078 return true;
02079 }
02080 return false;
02081 }
02082
02083
02084
02085
02086
02087 function registerOperators( &$operatorObject )
02088 {
02089 $this->registerOperatorsInternal( $operatorObject );
02090 }
02091
02092
02093
02094 function registerOperatorsInternal( &$operatorObject, $debug = false )
02095 {
02096 if ( !is_object( $operatorObject ) or
02097 !method_exists( $operatorObject, 'operatorList' ) )
02098 return false;
02099 foreach( $operatorObject->operatorList() as $operatorName )
02100 {
02101 $this->Operators[$operatorName] =& $operatorObject;
02102 }
02103 }
02104
02105
02106
02107
02108 function registerOperator( $op_name, &$op_obj )
02109 {
02110 $this->Operators[$op_name] =& $op_obj;
02111 }
02112
02113
02114
02115
02116 function unregisterOperator( $op_name )
02117 {
02118 if ( is_array( $op_name ) )
02119 {
02120 foreach ( $op_name as $op )
02121 {
02122 $this->unregisterOperator( $op_name );
02123 }
02124 }
02125 else if ( isset( $this->Operators ) )
02126 unset( $this->Operators[$op_name] );
02127 else
02128 $this->warning( "unregisterOpearator()", "Operator $op_name is not registered, cannot unregister" );
02129 }
02130
02131
02132
02133
02134 function registerFilter()
02135 {
02136 }
02137
02138
02139
02140
02141
02142 function registerResource( &$res )
02143 {
02144 if ( is_object( $res ) )
02145 $this->Resources[$res->resourceName()] =& $res;
02146 else
02147 $this->warning( "registerResource()", "Supplied argument is not a resource object" );
02148 }
02149
02150
02151
02152
02153 function unregisterResource( $res_name )
02154 {
02155 if ( is_array( $res_name ) )
02156 {
02157 foreach ( $res_name as $res )
02158 {
02159 $this->unregisterResource( $res );
02160 }
02161 }
02162 else if ( isset( $this->Resources[$res_name] ) )
02163 unset( $this->Resources[$res_name] );
02164 else
02165 $this->warning( "unregisterResource()", "Resource $res_name is not registered, cannot unregister" );
02166 }
02167
02168
02169
02170
02171
02172
02173 function setShowDetails( $show )
02174 {
02175 $this->ShowDetails = $show;
02176 }
02177
02178
02179
02180
02181 function missingParameter( $name, $param )
02182 {
02183 $this->warning( $name, "Missing parameter $param" );
02184 }
02185
02186
02187
02188
02189 function extraParameters( $name, $count, $maxCount )
02190 {
02191 $this->warning( $name, "Passed $count parameters but correct count is $maxCount" );
02192 }
02193
02194
02195
02196
02197 function undefinedVariable( $name, $var )
02198 {
02199 $this->warning( $name, "Undefined variable: $var" );
02200 }
02201
02202
02203
02204
02205 function undefinedFunction( $func_name )
02206 {
02207 $this->error( "", "Undefined function: $func_name" );
02208 }
02209
02210
02211
02212
02213
02214 function placementText( $placement = false )
02215 {
02216 $placementText = false;
02217 if ( $placement !== false )
02218 {
02219 if ( isset( $placement['start'] ) and
02220 isset( $placement['stop'] ) and
02221 isset( $placement['templatefile'] ) )
02222 {
02223 $line = $placement['start']['line'];
02224 $column = $placement['start']['column'];
02225 $templateFile = $placement['templatefile'];
02226 }
02227 else
02228 {
02229 $line = $placement[0][0];
02230 $column = $placement[0][1];
02231 $templateFile = $placement[2];
02232 }
02233
02234 $placementText = " @ $templateFile:$line" . "[$column]";
02235 }
02236 return $placementText;
02237 }
02238
02239
02240
02241
02242 function warning( $name, $txt, $placement = false )
02243 {
02244 $this->WarningLog[] = array( 'name' => $name,
02245 'text' => $txt,
02246 'placement' => $placement );
02247
02248 if ( !is_string( $placement ) )
02249 $placementText = $this->placementText( $placement );
02250 else
02251 $placementText = $placement;
02252 $placementText = $this->placementText( $placement );
02253 if ( $name != "" )
02254 eZDebug::writeWarning( $txt, "eZTemplate:$name" . $placementText );
02255 else
02256 eZDebug::writeWarning( $txt, "eZTemplate" . $placementText );
02257 }
02258
02259
02260
02261
02262 function error( $name, $txt, $placement = false )
02263 {
02264 $this->ErrorLog[] = array( 'name' => $name,
02265 'text' => $txt,
02266 'placement' => $placement );
02267
02268 if ( !is_string( $placement ) )
02269 $placementText = $this->placementText( $placement );
02270 else
02271 $placementText = $placement;
02272 if ( $name != "" )
02273 $nameText = "eZTemplate:$name";
02274 else
02275 $nameText = "eZTemplate";
02276 eZDebug::writeError( $txt, $nameText . $placementText );
02277 $hasAppendWarning =& $GLOBALS['eZTemplateHasAppendWarning'];
02278 $ini =& $this->ini();
02279 if ( $ini->variable( 'ControlSettings', 'DisplayWarnings' ) == 'enabled' )
02280 {
02281 if ( !isset( $hasAppendWarning ) or
02282 !$hasAppendWarning )
02283 {
02284 if ( function_exists( 'eZAppendWarningItem' ) )
02285 {
02286 eZAppendWarningItem( array( 'error' => array( 'type' => 'template',
02287 'number' => EZ_ERROR_TEMPLATE_FILE_ERRORS ),
02288 'text' => ezi18n( 'lib/eztemplate', 'Some template errors occured, see debug for more information.' ) ) );
02289 $hasAppendWarning = true;
02290 }
02291 }
02292 }
02293 }
02294
02295
02296 function operatorInputSupported( $operatorName )
02297 {
02298 }
02299
02300
02301
02302
02303 function setIncludeText( $uri, &$text )
02304 {
02305 $this->IncludeText[$uri] =& $text;
02306 }
02307
02308
02309
02310
02311 function setIncludeOutput( $uri, &$output )
02312 {
02313 $this->IncludeOutput[$uri] =& $output;
02314 }
02315
02316
02317
02318
02319 function autoloadPathList()
02320 {
02321 return $this->AutoloadPathList;
02322 }
02323
02324
02325
02326
02327 function setAutoloadPathList( $pathList )
02328 {
02329 $this->AutoloadPathList = $pathList;
02330 }
02331
02332
02333
02334
02335
02336 function autoload()
02337 {
02338 $pathList = $this->autoloadPathList();
02339 foreach ( $pathList as $path )
02340 {
02341 $autoloadFile = $path . '/eztemplateautoload.php';
02342 if ( file_exists( $autoloadFile ) )
02343 {
02344 unset( $eZTemplateOperatorArray );
02345 unset( $eZTemplateFunctionArray );
02346 include( $autoloadFile );
02347 if ( isset( $eZTemplateOperatorArray ) and
02348 is_array( $eZTemplateOperatorArray ) )
02349 {
02350 foreach ( $eZTemplateOperatorArray as $operatorDefinition )
02351 {
02352 $this->registerAutoloadOperators( $operatorDefinition );
02353 }
02354 }
02355 if ( isset( $eZTemplateFunctionArray ) and
02356 is_array( $eZTemplateFunctionArray ) )
02357 {
02358 foreach ( $eZTemplateFunctionArray as $functionDefinition )
02359 {
02360 $this->registerAutoloadFunctions( $functionDefinition );
02361 }
02362 }
02363 }
02364 }
02365 }
02366
02367
02368
02369
02370 function resetVariables()
02371 {
02372 $this->Variables = array();
02373 }
02374
02375
02376
02377
02378
02379 function resetElements()
02380 {
02381 foreach ( array_keys( $this->Functions ) as $functionName )
02382 {
02383 $functionObject =& $this->Functions[$functionName];
02384 if ( is_object( $functionObject ) and
02385 method_exists( $functionObject, 'resetFunction' ) )
02386 {
02387 $functionObject->resetFunction( $functionName );
02388 }
02389 }
02390
02391 foreach ( array_keys( $this->Operators ) as $operatorName )
02392 {
02393 $operatorObject =& $this->Operators[$operatorName];
02394 if ( is_object( $operatorObject ) and
02395 method_exists( $operatorObject, 'resetOperator' ) )
02396 {
02397 $operatorObject->resetOperator( $operatorName );
02398 }
02399 }
02400 }
02401
02402
02403
02404
02405 function reset()
02406 {
02407 $this->resetVariables();
02408 $this->resetElements();
02409 $this->IsCachingAllowed = true;
02410
02411 $this->resetErrorLog();
02412
02413 $this->TemplatesUsageStatistics = array();
02414 $this->TemplateFetchList = array();
02415 }
02416
02417
02418
02419
02420
02421 function errorCount()
02422 {
02423 return count( $this->ErrorLog );
02424 }
02425
02426
02427
02428
02429
02430 function hasErrors()
02431 {
02432 return $this->errorCount() > 0;
02433 }
02434
02435
02436
02437
02438
02439 function errorLog()
02440 {
02441 return $this->ErrorLog;
02442 }
02443
02444
02445
02446
02447
02448 function warningCount()
02449 {
02450 return count( $this->WarningLog );
02451 }
02452
02453
02454
02455
02456
02457 function hasWarnings()
02458 {
02459 return $this->warningCount() > 0;
02460 }
02461
02462
02463
02464
02465
02466 function warningLog()
02467 {
02468 return $this->WarningLog;
02469 }
02470
02471
02472
02473
02474 function &instance()
02475 {
02476 $tpl =& $GLOBALS["eZTemplateInstance"];
02477 if ( get_class( $tpl ) != "eztemplate" )
02478 {
02479 $tpl = new eZTemplate();
02480 }
02481
02482 return $tpl;
02483 }
02484
02485
02486
02487
02488 function &ini()
02489 {
02490 include_once( "lib/ezutils/classes/ezini.php" );
02491 $ini =& eZINI::instance( "template.ini" );
02492 return $ini;
02493 }
02494
02495
02496
02497
02498
02499
02500
02501 function isXHTMLCodeIncluded()
02502 {
02503 if ( !isset( $GLOBALS['eZTemplateDebugXHTMLCodeEnabled'] ) )
02504 {
02505 $ini =& eZINI::instance();
02506 $GLOBALS['eZTemplateDebugXHTMLCodeEnabled'] = $ini->variable( 'TemplateSettings', 'ShowXHTMLCode' ) == 'enabled';
02507 }
02508 return $GLOBALS['eZTemplateDebugXHTMLCodeEnabled'];
02509 }
02510
02511
02512
02513
02514
02515 function isMethodDebugEnabled()
02516 {
02517 if ( !isset( $GLOBALS['eZTemplateDebugMethodEnabled'] ) )
02518 {
02519 $ini =& eZINI::instance();
02520 $GLOBALS['eZTemplateDebugMethodEnabled'] = $ini->variable( 'TemplateSettings', 'ShowMethodDebug' ) == 'enabled';
02521 }
02522 return $GLOBALS['eZTemplateDebugMethodEnabled'];
02523 }
02524
02525
02526
02527
02528
02529
02530
02531 function isDebugEnabled()
02532 {
02533 if ( !isset( $GLOBALS['eZTemplateDebugInternalsEnabled'] ) )
02534 $GLOBALS['eZTemplateDebugInternalsEnabled'] = EZ_TEMPLATE_DEBUG_INTERNALS;
02535 return $GLOBALS['eZTemplateDebugInternalsEnabled'];
02536 }
02537
02538
02539
02540
02541
02542 function setIsDebugEnabled( $debug )
02543 {
02544 $GLOBALS['eZTemplateDebugInternalsEnabled'] = $debug;
02545 }
02546
02547
02548
02549
02550
02551
02552 function isCachingAllowed()
02553 {
02554 return $this->IsCachingAllowed;
02555 }
02556
02557
02558
02559
02560
02561
02562
02563
02564 function setIsCachingAllowed( $allowed )
02565 {
02566 $this->IsCachingAllowed = $allowed;
02567 }
02568
02569
02570
02571
02572
02573 function isTemplatesUsageStatisticsEnabled()
02574 {
02575 if ( !isset( $GLOBALS['eZTemplateDebugTemplatesUsageStatisticsEnabled'] ) )
02576 {
02577 $ini =& eZINI::instance();
02578 $GLOBALS['eZTemplateDebugTemplatesUsageStatisticsEnabled'] = $ini->variable( 'TemplateSettings', 'ShowUsedTemplates' ) == 'enabled';
02579 }
02580 return ( $GLOBALS['eZTemplateDebugTemplatesUsageStatisticsEnabled'] );
02581 }
02582
02583
02584
02585
02586
02587
02588 function setIsTemplatesUsageStatisticsEnabled( $enabled )
02589 {
02590 $wasEnabled = false;
02591 if( isset( $GLOBALS['eZTemplateDebugTemplatesUsageStatisticsEnabled'] ) )
02592 $wasEnabled = $GLOBALS['eZTemplateDebugTemplatesUsageStatisticsEnabled'];
02593
02594 $GLOBALS['eZTemplateDebugTemplatesUsageStatisticsEnabled'] = $enabled;
02595 return $wasEnabled;
02596 }
02597
02598
02599
02600
02601
02602 function appendTemplateToStatisticsIfNeeded( &$templateName, &$templateFileName )
02603 {
02604 if ( eZTemplate::isTemplatesUsageStatisticsEnabled() )
02605 eZTemplate::appendTemplateToStatistics( $templateName, $templateFileName );
02606 }
02607
02608
02609
02610
02611
02612 function appendTemplateToStatistics( &$templateName, &$templateFileName )
02613 {
02614 $actualTemplateName = preg_replace( "#^[\w/]+templates/#", '', $templateFileName );
02615 $requestedTemplateName = preg_replace( "#^[\w/]+templates/#", '', $templateName );
02616
02617 $tpl =& eZTemplate::instance();
02618 $needToAppend = true;
02619
02620
02621 $statsSize = count( $tpl->TemplatesUsageStatistics );
02622 if ( $statsSize > 0 )
02623 {
02624 $lastTemplateInfo =& $tpl->TemplatesUsageStatistics[$statsSize-1];
02625 if ( $lastTemplateInfo['actual-template-name'] === $actualTemplateName &&
02626 $lastTemplateInfo['requested-template-name'] === $requestedTemplateName &&
02627 $lastTemplateInfo['template-filename'] === $templateFileName )
02628 {
02629 $needToAppend = false;
02630 }
02631 }
02632
02633 if ( $needToAppend )
02634 {
02635 $templateInfo = array( 'actual-template-name' => $actualTemplateName,
02636 'requested-template-name' => $requestedTemplateName,
02637 'template-filename' => $templateFileName );
02638
02639 $tpl->TemplatesUsageStatistics[] = $templateInfo;
02640 }
02641 }
02642
02643
02644
02645
02646 function appendTemplateFetch( $actualTemplateName )
02647 {
02648 $this->TemplateFetchList[] = $actualTemplateName;
02649 $this->TemplateFetchList = array_unique( $this->TemplateFetchList );
02650 }
02651
02652
02653
02654
02655 function resetErrorLog()
02656 {
02657 $this->ErrorLog = array();
02658 $this->WarningLog = array();
02659 }
02660
02661
02662
02663
02664
02665 function &templatesUsageStatistics()
02666 {
02667 $tpl =& eZTemplate::instance();
02668 return $tpl->TemplatesUsageStatistics;
02669 }
02670
02671
02672
02673
02674 function templateFetchList()
02675 {
02676 return $this->TemplateFetchList;
02677 }
02678
02679
02680
02681
02682
02683
02684
02685 function setCompileTest( $val )
02686 {
02687 $this->TestCompile = $val;
02688 }
02689
02690
02691
02692
02693 function testCompile()
02694 {
02695 return $this->TestCompile;
02696 }
02697
02698
02699
02700 var $Resources;
02701
02702 var $DefaultResource;
02703
02704 var $Text;
02705
02706 var $IncludeText;
02707
02708 var $IncludeOutput;
02709
02710 var $TimeStamp;
02711
02712 var $LDelim;
02713
02714 var $RDelim;
02715
02716
02717 var $Tree;
02718
02719 var $Variables;
02720
02721
02722
02723
02724
02725 var $LocalVariablesNamesStack;
02726
02727 var $CurrentLocalVariablesNames;
02728
02729 var $Operators;
02730
02731 var $Functions;
02732
02733 var $FunctionAttributes;
02734
02735 var $Literals;
02736
02737 var $ShowDetails = false;
02738
02739 var $IsCachingAllowed;
02740
02741
02742 var $ErrorLog;
02743
02744 var $WarningLog;
02745
02746 var $AutoloadPathList;
02747
02748 var $Level = 0;
02749 var $MaxLevel = 40;
02750
02751
02752 var $TemplatesUsageStatistics;
02753
02754
02755 var $ForeachCounter;
02756 var $ForCounter;
02757 var $WhileCounter;
02758 var $DoCounter;
02759 var $ElseifCounter;
02760
02761
02762 var $TestCompile;
02763
02764
02765
02766 }
02767
02768 ?>