class_BaseTemplateEngine.php

Go to the documentation of this file.
00001 <?php
00024 class BaseTemplateEngine extends BaseFrameworkSystem {
00030         private $basePath = "";
00031 
00035         private $templateType = "html";
00036 
00040         private $templateExtension = ".tpl";
00041 
00045         private $codeExtension = ".ctp";
00046 
00050         private $compileOutputPath = "templates/_compiled";
00051 
00055         private $rawTemplateData = "";
00056 
00060         private $compiledData = "";
00061 
00065         private $lastTemplate = "";
00066 
00070         private $varStack = array();
00071 
00075         private $loadedTemplates = array();
00076 
00080         private $compiledTemplates = array();
00081 
00085         private $loadedRawData = null;
00086 
00090         private $rawTemplates = null;
00091 
00095         private $regExpVarValue = '/([\w_]+)(="([^"]*)"|=([\w_]+))?/';
00096 
00102         private $regExpCodeTags = '/\{\?([a-z_]+)(:("[^"]+"|[^?}]+)+)?\?\}/';
00103 
00107         private $helpers = array();
00108 
00112         private $currGroup = 'general';
00113 
00117         private $varGroups = array();
00118 
00119         // Exception codes for the template engine
00120         const EXCEPTION_TEMPLATE_TYPE_IS_UNEXPECTED   = 0x110;
00121         const EXCEPTION_TEMPLATE_CONTAINS_INVALID_VAR = 0x111;
00122         const EXCEPTION_INVALID_VIEW_HELPER           = 0x112;
00123 
00130         protected function __construct ($className) {
00131                 // Call parent constructor
00132                 parent::__construct($className);
00133 
00134                 // Clean up a little
00135                 $this->removeNumberFormaters();
00136                 $this->removeSystemArray();
00137         }
00138 
00145         private function isVariableAlreadySet ($var) {
00146                 // First everything is not found
00147                 $found = false;
00148 
00149                 // Is the group there?
00150                 if (isset($this->varStack[$this->currGroup])) {
00151                         // Now search for it
00152                         foreach ($this->varStack[$this->currGroup] as $idx => $currEntry) {
00153                                 //* DEBUG: */ echo __METHOD__.":currGroup={$this->currGroup},idx={$idx},currEntry={$currEntry['name']},var={$var}<br />\n";
00154                                 // Is the entry found?
00155                                 if ($currEntry['name'] == $var) {
00156                                         // Found!
00157                                         //* DEBUG: */ echo __METHOD__.":FOUND!<br />\n";
00158                                         $found = $idx;
00159                                         break;
00160                                 } // END - if
00161                         } // END - foreach
00162                 } // END - if
00163 
00164                 // Return the current position
00165                 return $found;
00166         }
00167 
00174         protected function readVariable ($var) {
00175                 // First everything is not found
00176                 $content = null;
00177 
00178                 // Get variable index
00179                 $found = $this->isVariableAlreadySet($var);
00180 
00181                 // Is the variable found?
00182                 if ($found !== false) {
00183                         // Read it
00184                         $found = $this->varStack[$this->currGroup][$found]['value'];
00185                 } // END - if
00186 
00187                 //* DEBUG: */ echo __METHOD__.": group=".$this->currGroup.",var=".$var.", found=".$found."<br />\n";
00188 
00189                 // Return the current position
00190                 return $found;
00191         }
00192 
00200         private function addVariable ($var, $value) {
00201                 // Set general variable group
00202                 $this->setVariableGroup('general');
00203 
00204                 // Add it to the stack
00205                 $this->addGroupVariable($var, $value);
00206         }
00207 
00213         private function readCurrentGroup () {
00214                 // Default is not found
00215                 $result = array();
00216 
00217                 // Is the group there?
00218                 if (isset($this->varStack[$this->currGroup])) {
00219                         // Then use it
00220                         $result = $this->varStack[$this->currGroup];
00221                 } // END - if
00222 
00223                 // Return result
00224                 return $result;
00225         }
00226 
00234         public function setVariableGroup ($groupName, $add = true) {
00235                 // Set group name
00236                 //* DEBIG: */ echo __METHOD__.": currGroup=".$groupName."<br />\n";
00237                 $this->currGroup = $groupName;
00238 
00239                 // Skip group 'general'
00240                 if (($groupName != 'general') && ($add === true)) {
00241                         $this->varGroups[$groupName] = 'OK';
00242                 } // END - if
00243         }
00244 
00245 
00253         public function addGroupVariable ($var, $value) {
00254                 //* DEBUG: */ echo __METHOD__.": group=".$this->currGroup.", var=".$var.", value=".$value."<br />\n";
00255 
00256                 // Get current variables in group
00257                 $currVars = $this->readCurrentGroup();
00258 
00259                 // Append our variable
00260                 $currVars[] = array(
00261                         'name'  => $var,
00262                         'value' => $value
00263                 );
00264 
00265                 // Add it to the stack
00266                 $this->varStack[$this->currGroup] = $currVars;
00267         }
00268 
00276         private function modifyVariable ($var, $value) {
00277                 // Get index for variable
00278                 $idx = $this->isVariableAlreadySet($var);
00279 
00280                 // Is the variable set?
00281                 if ($idx !== false) {
00282                         // Then modify it
00283                         $this->varStack[$this->currGroup][$idx]['value'] = $value;
00284                 } // END - if
00285         }
00286 
00294         private final function setTemplateType ($templateType) {
00295                 $this->templateType = (string) $templateType;
00296         }
00297 
00304         private final function setLastTemplate ($template) {
00305                 $this->lastTemplate = (string) $template;
00306         }
00307 
00313         private final function getLastTemplate () {
00314                 return $this->lastTemplate;
00315         }
00316 
00323         public final function setBasePath ($basePath) {
00324                 // And set it
00325                 $this->basePath = (string) $basePath;
00326         }
00327 
00333         public final function getBasePath () {
00334                 // And set it
00335                 return $this->basePath;
00336         }
00337 
00345         public final function setRawTemplateExtension ($templateExtension) {
00346                 // And set it
00347                 $this->templateExtension = (string) $templateExtension;
00348         }
00349 
00357         public final function setCodeTemplateExtension ($codeExtension) {
00358                 // And set it
00359                 $this->codeExtension = (string) $codeExtension;
00360         }
00361 
00368         public final function getRawTemplateExtension () {
00369                 // And set it
00370                 return $this->templateExtension;
00371         }
00372 
00379         public final function getCodeTemplateExtension () {
00380                 // And set it
00381                 return $this->codeExtension;
00382         }
00383 
00391         public final function setCompileOutputPath ($compileOutputPath) {
00392                 // And set it
00393                 $this->compileOutputPath = (string) $compileOutputPath;
00394         }
00395 
00401         public final function getTemplateType () {
00402                 return $this->templateType;
00403         }
00404 
00413         public final function assignVariable ($var, $value) {
00414                 // Trim spaces of variable name
00415                 $var = trim($var);
00416 
00417                 // Empty variable found?
00418                 if (empty($var)) {
00419                         // Throw an exception
00420                         throw new EmptyVariableException(array($this, 'var'), self::EXCEPTION_UNEXPECTED_EMPTY_STRING);
00421                 } // END - if
00422 
00423                 // First search for the variable if it was already added
00424                 $idx = $this->isVariableAlreadySet($var);
00425 
00426                 // Was it found?
00427                 if ($idx === false) {
00428                         // Add it to the stack
00429                         //* DEBUG: */ echo "ADD: ".$var."<br />\n";
00430                         $this->addVariable($var, $value);
00431                 } elseif (!empty($value)) {
00432                         // Modify the stack entry
00433                         //* DEBUG: */ echo "MOD: ".$var."<br />\n";
00434                         $this->modifyVariable($var, $value);
00435                 }
00436         }
00437 
00444         public final function removeVariable ($var) {
00445                 // First search for the variable if it was already added
00446                 $idx = $this->isVariableAlreadySet($var);
00447 
00448                 // Was it found?
00449                 if ($idx !== false) {
00450                         // Remove this variable
00451                         $this->varStack->offsetUnset($idx);
00452                 }
00453         }
00454 
00461         protected final function setRawTemplateData ($rawTemplateData) {
00462                 // And store it in this class
00463                 //* DEBUG: */ echo __METHOD__.":".$this->getUniqueId().": ".strlen($rawTemplateData)." Bytes set.<br />\n";
00464                 //* DEBUG: */ echo $this->currGroup." variables: ".count($this->varStack[$this->currGroup]).", groups=".count($this->varStack)."<br />\n";
00465                 $this->rawTemplateData = (string) $rawTemplateData;
00466         }
00467 
00473         public final function getRawTemplateData () {
00474                 //* DEBUG: */ echo __METHOD__.":".$this->getUniqueId().": ".strlen($this->rawTemplateData)." Bytes read.<br />\n";
00475                 return $this->rawTemplateData;
00476         }
00477 
00483         private final function setCompiledData ($compiledData) {
00484                 // And store it in this class
00485                 //* DEBUG: */ echo __METHOD__.":".$this->getUniqueId().": ".strlen($compiledData)." Bytes set.<br />\n";
00486                 $this->compiledData = (string) $compiledData;
00487         }
00488 
00494         public final function getCompiledData () {
00495                 //* DEBUG: */ echo __METHOD__.":".$this->getUniqueId().": ".strlen($this->compiledData)." Bytes read.<br />\n";
00496                 return $this->compiledData;
00497         }
00498 
00505         private function loadTemplate ($template) {
00506                 // Get extension for the template
00507                 $ext = $this->getRawTemplateExtension();
00508 
00509                 // If we shall load a code-template we need to switch the file extension
00510                 if ($this->getTemplateType() == $this->getConfigInstance()->readConfig('code_template_type')) {
00511                         // Switch over to the code-template extension
00512                         $ext = $this->getCodeTemplateExtension();
00513                 } // END - if
00514 
00515                 // Construct the FQFN for the template by honoring the current language
00516                 $fqfn = sprintf("%s%s/%s/%s%s",
00517                         $this->getBasePath(),
00518                         $this->getLanguageInstance()->getLanguageCode(),
00519                         $this->getTemplateType(),
00520                         (string) $template,
00521                         $ext
00522                 );
00523 
00524                 // Load the raw template data
00525                 $this->loadRawTemplateData($fqfn);
00526         }
00527 
00534         private function loadRawTemplateData ($fqfn) {
00535                 // Get a input/output instance from the middleware
00536                 $ioInstance = $this->getFileIoInstance();
00537 
00538                 // Some debug code to look on the file which is being loaded
00539                 //* DEBUG: */ echo __METHOD__.": FQFN=".$fqfn."<br />\n";
00540 
00541                 // Load the raw template
00542                 $rawTemplateData = $ioInstance->loadFileContents($fqfn);
00543 
00544                 // Store the template's contents into this class
00545                 $this->setRawTemplateData($rawTemplateData);
00546 
00547                 // Remember the template's FQFN
00548                 $this->setLastTemplate($fqfn);
00549         }
00550 
00559         private function assignTemplateVariable ($varName, $var) {
00560                 // Is it not a config variable?
00561                 if ($varName != 'config') {
00562                         // Regular template variables
00563                         $this->assignVariable($var, "");
00564                 } else {
00565                         // Configuration variables
00566                         $this->assignConfigVariable($var);
00567                 }
00568         }
00569 
00576         private function extractVariablesFromRawData ($rawData) {
00577                 // Cast to string
00578                 $rawData = (string) $rawData;
00579 
00580                 // Search for variables
00581                 @preg_match_all('/\$(\w+)(\[(\w+)\])?/', $rawData, $variableMatches);
00582 
00583                 // Did we find some variables?
00584                 if ((is_array($variableMatches)) && (count($variableMatches) == 4) && (count($variableMatches[0]) > 0)) {
00585                         // Initialize all missing variables
00586                         foreach ($variableMatches[3] as $key => $var) {
00587                                 // Variable name
00588                                 $varName = $variableMatches[1][$key];
00589 
00590                                 // Workarround: Do not assign empty variables
00591                                 if (!empty($var)) {
00592                                         // Try to assign it, empty strings are being ignored
00593                                         $this->assignTemplateVariable($varName, $var);
00594                                 } // END - if
00595                         } // END - foreach
00596                 } // END - if
00597         }
00598 
00613         private function analyzeTemplate (array $templateMatches) {
00614                 // Backup raw template data
00615                 $backup = $this->getRawTemplateData();
00616 
00617                 // Initialize some arrays
00618                 if (is_null($this->loadedRawData)) { $this->loadedRawData = array(); $this->rawTemplates = array(); }
00619 
00620                 // Load all requested templates
00621                 foreach ($templateMatches[1] as $template) {
00622 
00623                         // Load and compile only templates which we have not yet loaded
00624                         // RECURSIVE PROTECTION! BE CAREFUL HERE!
00625                         if ((!isset($this->loadedRawData[$template])) && (!in_array($template, $this->loadedTemplates))) {
00626 
00627                                 // Template not found, but maybe variable assigned?
00628                                 //* DEBUG: */ echo __METHOD__.":template={$template}<br />\n";
00629                                 if ($this->isVariableAlreadySet($template) !== false) {
00630                                         // Use that content here
00631                                         $this->loadedRawData[$template] = $this->readVariable($template);
00632 
00633                                         // Recursive protection:
00634                                         $this->loadedTemplates[] = $template;
00635                                 } elseif (isset($this->varStack['config'][$template])) {
00636                                         // Use that content here
00637                                         $this->loadedRawData[$template] = $this->varStack['config'][$template];
00638 
00639                                         // Recursive protection:
00640                                         $this->loadedTemplates[] = $template;
00641                                 } else {
00642                                         // Then try to search for code-templates
00643                                         try {
00644                                                 // Load the code template and remember it's contents
00645                                                 $this->loadCodeTemplate($template);
00646                                                 $this->loadedRawData[$template] = $this->getRawTemplateData();
00647 
00648                                                 // Remember this template for recursion detection
00649                                                 // RECURSIVE PROTECTION!
00650                                                 $this->loadedTemplates[] = $template;
00651                                         } catch (FileNotFoundException $e) {
00652                                                 // Even this is not done... :/
00653                                                 $this->rawTemplates[] = $template;
00654                                         } catch (FilePointerNotOpenedException $e) {
00655                                                 // Even this is not done... :/
00656                                                 $this->rawTemplates[] = $template;
00657                                         }
00658                                 }
00659                         } // END - if
00660                 } // END - foreach
00661 
00662                 // Restore the raw template data
00663                 $this->setRawTemplateData($backup);
00664         }
00665 
00673         private function compileCode ($code, $template) {
00674                 // Is this template already compiled?
00675                 if (in_array($template, $this->compiledTemplates)) {
00676                         // Abort here...
00677                         return;
00678                 } // END - if
00679 
00680                 // Remember this template being compiled
00681                 $this->compiledTemplates[] = $template;
00682 
00683                 // Compile the loaded code in five steps:
00684                 //
00685                 // 1. Backup current template data
00686                 $backup = $this->getRawTemplateData();
00687 
00688                 // 2. Set the current template's raw data as the new content
00689                 $this->setRawTemplateData($code);
00690 
00691                 // 3. Compile the template data
00692                 $this->compileTemplate();
00693 
00694                 // 4. Remember it's contents
00695                 $this->loadedRawData[$template] = $this->getRawTemplateData();
00696 
00697                 // 5. Restore the previous raw content from backup variable
00698                 $this->setRawTemplateData($backup);
00699         }
00700 
00708         private function insertAllTemplates (array $templateMatches) {
00709                 // Run through all loaded codes
00710                 foreach ($this->loadedRawData as $template => $code) {
00711 
00712                         // Search for the template
00713                         $foundIndex = array_search($template, $templateMatches[1]);
00714 
00715                         // Lookup the matching template replacement
00716                         if (($foundIndex !== false) && (isset($templateMatches[0][$foundIndex]))) {
00717 
00718                                 // Get the current raw template
00719                                 $rawData = $this->getRawTemplateData();
00720 
00721                                 // Replace the space holder with the template code
00722                                 $rawData = str_replace($templateMatches[0][$foundIndex], $code, $rawData);
00723 
00724                                 // Set the new raw data
00725                                 $this->setRawTemplateData($rawData);
00726                         } // END - if
00727                 } // END - foreach
00728         }
00729 
00735         private function loadExtraRawTemplates () {
00736                 // Are there some raw templates we need to load?
00737                 if (count($this->rawTemplates) > 0) {
00738                         // Try to load all raw templates
00739                         foreach ($this->rawTemplates as $key => $template) {
00740                                 try {
00741                                         // Load the template
00742                                         $this->loadWebTemplate($template);
00743 
00744                                         // Remember it's contents
00745                                         $this->rawTemplates[$template] = $this->getRawTemplateData();
00746 
00747                                         // Remove it from the loader list
00748                                         unset($this->rawTemplates[$key]);
00749 
00750                                         // Remember this template for recursion detection
00751                                         // RECURSIVE PROTECTION!
00752                                         $this->loadedTemplates[] = $template;
00753                                 } catch (FileNotFoundException $e) {
00754                                         // This template was never found. We silently ignore it
00755                                         unset($this->rawTemplates[$key]);
00756                                 } catch (FilePointerNotOpenedException $e) {
00757                                         // This template was never found. We silently ignore it
00758                                         unset($this->rawTemplates[$key]);
00759                                 }
00760                         } // END - foreach
00761                 } // END - if
00762         }
00763 
00771         private function assignAllVariables (array $varMatches) {
00772                 // Search for all variables
00773                 foreach ($varMatches[1] as $key => $var) {
00774 
00775                         // Detect leading equals
00776                         if (substr($varMatches[2][$key], 0, 1) == "=") {
00777                                 // Remove and cast it
00778                                 $varMatches[2][$key] = (string) substr($varMatches[2][$key], 1);
00779                         }
00780 
00781                         // Do we have some quotes left and right side? Then it is free text
00782                         if ((substr($varMatches[2][$key], 0, 1) == "\"") && (substr($varMatches[2][$key], -1, 1) == "\"")) {
00783                                 // Free string detected! Which we can assign directly
00784                                 $this->assignVariable($var, $varMatches[3][$key]);
00785                         } elseif (!empty($varMatches[2][$key])) {
00786                                 // Non-string found so we need some deeper analysis...
00787                                 die("Deeper analysis not yet implemented!");
00788                         }
00789 
00790                 } // for ($varMatches ...
00791         }
00798         private function compileRawTemplateData (array $templateMatches) {
00799                 // Are some code-templates found which we need to compile?
00800                 if (count($this->loadedRawData) > 0) {
00801 
00802                         // Then compile all!
00803                         foreach ($this->loadedRawData as $template => $code) {
00804 
00805                                 // Is this template already compiled?
00806                                 if (in_array($template, $this->compiledTemplates)) {
00807                                         // Then skip it
00808                                         continue;
00809                                 }
00810 
00811                                 // Search for the template
00812                                 $foundIndex = array_search($template, $templateMatches[1]);
00813 
00814                                 // Lookup the matching variable data
00815                                 if (($foundIndex !== false) && (isset($templateMatches[3][$foundIndex]))) {
00816 
00817                                         // Split it up with another reg. exp. into variable=value pairs
00818                                         preg_match_all($this->regExpVarValue, $templateMatches[3][$foundIndex], $varMatches);
00819 
00820                                         // Assign all variables
00821                                         $this->assignAllVariables($varMatches);
00822 
00823                                 } // END - if (isset($templateMatches ...
00824 
00825                                 // Compile the loaded template
00826                                 $this->compileCode($code, $template);
00827 
00828                         } // END - foreach ($this->loadedRawData ...
00829 
00830                         // Insert all templates
00831                         $this->insertAllTemplates($templateMatches);
00832 
00833                 } // END - if (count($this->loadedRawData) ...
00834         }
00835 
00841         private function insertRawTemplates () {
00842                 // Load all templates
00843                 foreach ($this->rawTemplates as $template => $content) {
00844                         // Set the template as a variable with the content
00845                         $this->assignVariable($template, $content);
00846                 }
00847         }
00848 
00854         private function finalizeVariableCompilation () {
00855                 // Get the content
00856                 $content = $this->getRawTemplateData();
00857                 //* DEBUG: */ echo __METHOD__.": content before=".strlen($content)." (".md5($content).")<br />\n";
00858 
00859                 // Walk through all variables
00860                 foreach ($this->varStack['general'] as $currEntry) {
00861                         //* DEBUG: */ echo __METHOD__.": name=".$currEntry['name'].", value=<pre>".htmlentities($currEntry['value'])."</pre>\n";
00862                         // Replace all [$var] or {?$var?} with the content
00863                         // Old behaviour, will become obsolete!
00864                         $content = str_replace("\$content[".$currEntry['name']."]", $currEntry['value'], $content);
00865 
00866                         // Yet another old way
00867                         $content = str_replace("[".$currEntry['name']."]", $currEntry['value'], $content);
00868 
00869                         // The new behaviour
00870                         $content = str_replace("{?".$currEntry['name']."?}", $currEntry['value'], $content);
00871                 } // END - for
00872 
00873                 //* DEBUG: */ echo __METHOD__.": content after=".strlen($content)." (".md5($content).")<br />\n";
00874 
00875                 // Set the content back
00876                 $this->setRawTemplateData($content);
00877         }
00878 
00886         public function loadWebTemplate ($template) {
00887                 // Set template type
00888                 $this->setTemplateType($this->getConfigInstance()->readConfig('web_template_type'));
00889 
00890                 // Load the special template
00891                 $this->loadTemplate($template);
00892         }
00893 
00900         public function assignConfigVariable ($var) {
00901                 // Sweet and simple...
00902                 //* DEBUG: */ echo __METHOD__.":var={$var}<br />\n";
00903                 $this->varStack['config'][$var] = $this->getConfigInstance()->readConfig($var);
00904         }
00905 
00913         public function loadEmailTemplate ($template) {
00914                 // Set template type
00915                 $this->setTemplateType($this->getConfigInstance()->readConfig('email_template_type'));
00916 
00917                 // Load the special template
00918                 $this->loadTemplate($template);
00919         }
00920 
00928         public function loadCodeTemplate ($template) {
00929                 // Set template type
00930                 $this->setTemplateType($this->getConfigInstance()->readConfig('code_template_type'));
00931 
00932                 // Load the special template
00933                 $this->loadTemplate($template);
00934         }
00935 
00942         public final function compileVariables () {
00943                 // Initialize the $content array
00944                 $validVar = $this->getConfigInstance()->readConfig('tpl_valid_var');
00945                 $dummy = array();
00946 
00947                 // Iterate through all general variables
00948                 foreach ($this->varStack['general'] as $currVariable) {
00949                         // Transfer it's name/value combination to the $content array
00950                         //* DEBUG: */ echo $currVariable['name']."=<pre>".htmlentities($currVariable['value'])."</pre>\n";
00951                         $dummy[$currVariable['name']] = $currVariable['value'];
00952                 }// END - if
00953 
00954                 // Set the new variable (don't remove the second dollar!)
00955                 $$validVar = $dummy;
00956 
00957                 // Prepare all configuration variables
00958                 $config = null;
00959                 if (isset($this->varStack['config'])) {
00960                         $config = $this->varStack['config'];
00961                 } // END - if
00962 
00963                 // Remove some variables
00964                 unset($idx);
00965                 unset($currVariable);
00966 
00967                 // Run the compilation twice to get content from helper classes in
00968                 $cnt = 0;
00969                 while ($cnt < 3) {
00970                         // Finalize the compilation of template variables
00971                         $this->finalizeVariableCompilation();
00972 
00973                         // Prepare the eval() command for comiling the template
00974                         $eval = sprintf("\$result = \"%s\";",
00975                                 addslashes($this->getRawTemplateData())
00976                         );
00977 
00978                         // This loop does remove the backslashes (\) in PHP parameters
00979                         while (strpos($eval, "<?php") !== false) {
00980                                 // Get left part before "<?"
00981                                 $evalLeft = substr($eval, 0, strpos($eval, "<?php"));
00982 
00983                                 // Get all from right of "<?"
00984                                 $evalRight = substr($eval, (strpos($eval, "<?php") + 5));
00985 
00986                                 // Cut middle part out and remove escapes
00987                                 $evalMiddle = trim(substr($evalRight, 0, strpos($evalRight, "?>")));
00988                                 $evalMiddle = stripslashes($evalMiddle);
00989 
00990                                 // Remove the middle part from right one
00991                                 $evalRight = substr($evalRight, (strpos($evalRight, "?>") + 2));
00992 
00993                                 // And put all together
00994                                 $eval = sprintf("%s<%%php %s %%>%s", $evalLeft, $evalMiddle, $evalRight);
00995                         } // END - while
00996 
00997                         // Prepare PHP code for eval() command
00998                         $eval = str_replace(
00999                                 "<%php", "\";",
01000                                 str_replace(
01001                                         "%>", "\n\$result .= \"", $eval
01002                                 )
01003                         );
01004 
01005                         // Run the constructed command. This will "compile" all variables in
01006                         @eval($eval);
01007 
01008                         // Goes something wrong?
01009                         if (!isset($result)) {
01010                                 // Output eval command
01011                                 $this->debugOutput(sprintf("Failed eval() code: <pre>%s</pre>", $this->markupCode($eval, true)), true);
01012 
01013                                 // Output backtrace here
01014                                 $this->debugBackTrace();
01015                         } // END - if
01016 
01017                         // Set raw template data
01018                         $this->setRawTemplateData($result);
01019                         $cnt++;
01020                 } // END - while
01021 
01022                 // Final variable assignment
01023                 $this->finalizeVariableCompilation();
01024 
01025                 // Set the new content
01026                 $this->setCompiledData($this->getRawTemplateData());
01027         }
01028 
01038         public function compileTemplate () {
01039                 // We will only work with template type "code" from configuration
01040                 if ($this->getTemplateType() != $this->getConfigInstance()->readConfig('code_template_type')) {
01041                         // Abort here
01042                         throw new UnexpectedTemplateTypeException(array($this, $this->getTemplateType(), $this->getConfigInstance()->readConfig('code_template_type')), self::EXCEPTION_TEMPLATE_TYPE_IS_UNEXPECTED);
01043                 } // END - if
01044 
01045                 // Get the raw data.
01046                 $rawData = $this->getRawTemplateData();
01047 
01048                 // Remove double spaces and trim leading/trailing spaces
01049                 $rawData = trim(str_replace("  ", " ", $rawData));
01050 
01051                 // Search for raw variables
01052                 $this->extractVariablesFromRawData($rawData);
01053 
01054                 // Search for code-tags which are {? ?}
01055                 preg_match_all($this->regExpCodeTags, $rawData, $templateMatches);
01056 
01057                 // Analyze the matches array
01058                 if ((is_array($templateMatches)) && (count($templateMatches) == 4) && (count($templateMatches[0]) > 0)) {
01059                         // Entries are found:
01060                         //
01061                         // The main analysis
01062                         $this->analyzeTemplate($templateMatches);
01063 
01064                         // Compile raw template data
01065                         $this->compileRawTemplateData($templateMatches);
01066 
01067                         // Are there some raw templates left for loading?
01068                         $this->loadExtraRawTemplates();
01069 
01070                         // Are some raw templates found and loaded?
01071                         if (count($this->rawTemplates) > 0) {
01072 
01073                                 // Insert all raw templates
01074                                 $this->insertRawTemplates();
01075 
01076                                 // Remove the raw template content as well
01077                                 $this->setRawTemplateData("");
01078 
01079                         } // END - if
01080 
01081                 } // END - if($templateMatches ...
01082         }
01083 
01091         public function output () {
01092                 // Check which type of template we have
01093                 switch ($this->getTemplateType()) {
01094                 case "html": // Raw HTML templates can be send to the output buffer
01095                         // Quick-N-Dirty:
01096                         $this->getWebOutputInstance()->output($this->getCompiledData());
01097                         break;
01098 
01099                 default: // Unknown type found
01100                         // Construct message
01101                         $msg = sprintf("[%s-&gt;%s] Unknown/unsupported template type <span class=\"data\">%s</span> detected.",
01102                                 $this->__toString(),
01103                                 __FUNCTION__,
01104                                 $this->getTemplateType()
01105                         );
01106 
01107                         // Write the problem to the world...
01108                         $this->debugOutput($msg);
01109                         break;
01110                 }
01111         }
01112 
01120         protected function loadViewHelper ($helperName) {
01121                 // Make first character upper case, rest low
01122                 $helperName = ucfirst($helperName);
01123 
01124                 // Is this view helper loaded?
01125                 if (!isset($this->helpers[$helperName])) {
01126                         // Create a class name
01127                         $className = "{$helperName}ViewHelper";
01128 
01129                         // Does this class exists?
01130                         if (!class_exists($className)) {
01131                                 // Abort here!
01132                                 throw new ViewHelperNotFoundException(array($this, $helperName), self::EXCEPTION_INVALID_VIEW_HELPER);
01133                         } // END - if
01134 
01135                         // Generate new instance
01136                         $eval = sprintf("\$this->helpers[%s] = %s::create%s();",
01137                                 $helperName,
01138                                 $className,
01139                                 $className
01140                         );
01141 
01142                         // Run the code
01143                         eval($eval);
01144                 } // END - if
01145 
01146                 // Return the requested instance
01147                 return $this->helpers[$helperName];
01148         }
01149 
01157         public function assignTemplateWithVariable ($templateName, $variableName) {
01158                 // Get the content from last loaded raw template
01159                 $content = $this->getRawTemplateData();
01160 
01161                 // Assign the variable
01162                 $this->assignVariable($variableName, $content);
01163 
01164                 // Purge raw content
01165                 $this->setRawTemplateData("");
01166         }
01167 
01174         public function transferToResponse (Responseable $responseInstance) {
01175                 // Get the content and set it in response class
01176                 $responseInstance->writeToBody($this->getCompiledData());
01177         }
01178 
01185         public function assignApplicationData (ManageableApplication $appInstance) {
01186                 // Get long name and assign it
01187                 $this->assignVariable('app_full_name' , $appInstance->getAppName());
01188 
01189                 // Get short name and assign it
01190                 $this->assignVariable('app_short_name', $appInstance->getAppShortName());
01191 
01192                 // Get version number and assign it
01193                 $this->assignVariable('app_version'   , $appInstance->getAppVersion());
01194 
01195                 // Assign extra application-depending data
01196                 $appInstance->assignExtraTemplateData($this);
01197         }
01198 
01205         public function compileRawCode ($rawCode) {
01206                 // Find the variables
01207                 //* DEBUG: */ echo "rawCode=<pre>".htmlentities($rawCode)."</pre>\n";
01208                 preg_match_all($this->regExpVarValue, $rawCode, $varMatches);
01209 
01210                 // Compile all variables
01211                 //* DEBUG: */ echo "<pre>".print_r($varMatches, true)."</pre>";
01212                 foreach ($varMatches[0] as $match) {
01213                         // Add variable tags around it
01214                         $varCode = "{?".$match."?}";
01215 
01216                         // Is the variable found in code? (safes some calls)
01217                         if (strpos($rawCode, $varCode) !== false) {
01218                                 // Replace the variable with it's value, if found
01219                                 //* DEBUG: */ echo __METHOD__.": match=".$match."<br />\n";
01220                                 $rawCode = str_replace($varCode, $this->readVariable($match), $rawCode);
01221                         } // END - if
01222                 } // END - foreach
01223 
01224                 // Return the compiled data
01225                 return $rawCode;
01226         }
01227 
01233         public final function getVariableGroups () {
01234                 return $this->varGroups;
01235         }
01236 
01244         public function renameVariable ($oldName, $newName) {
01245                 //* DEBUG: */ echo __METHOD__.": oldName={$oldName}, newName={$newName}<br />\n";
01246                 // Get raw template code
01247                 $rawData = $this->getRawTemplateData();
01248 
01249                 // Replace it
01250                 $rawData = str_replace($oldName, $newName, $rawData);
01251 
01252                 // Set the code back
01253                 $this->setRawTemplateData($rawData);
01254         }
01255 
01263         public final function renderXmlContent ($content = null) {
01264                 // Is the content set?
01265                 if (is_null($content)) {
01266                         // Get current content
01267                         $content = $this->getRawTemplateData();
01268                 } // END - if
01269 
01270                 // Convert all to UTF8
01271                 $content = recode("html..utf8", $content);
01272 
01273                 // Get an XML parser
01274                 $xmlParser = xml_parser_create();
01275 
01276                 // Force case-folding to on
01277                 xml_parser_set_option($xmlParser, XML_OPTION_CASE_FOLDING, true);
01278 
01279                 // Set object
01280                 xml_set_object($xmlParser, $this);
01281 
01282                 // Set handler call-backs
01283                 xml_set_element_handler($xmlParser, 'startElement', 'endElement');
01284                 xml_set_character_data_handler($xmlParser, 'characterHandler');
01285 
01286                 // Now parse the XML tree
01287                 if (!xml_parse($xmlParser, $content)) {
01288                         // Error found in XML!
01289                         //die("<pre>".htmlentities($content)."</pre>");
01290                         throw new XmlParserException(array($this, $xmlParser), BaseHelper::EXCEPTION_XML_PARSER_ERROR);
01291                 } // END - if
01292 
01293                 // Free the parser
01294                 xml_parser_free($xmlParser);
01295         }
01296 }
01297 
01298 // [EOF]
01299 ?>

Generated on Mon Dec 8 01:06:46 2008 for Ship-Simulator by  doxygen 1.5.6