Files merged from ship-simu project
[mailer.git] / inc / classes / main / template / class_TemplateEngine.php
index 44f374fc9efc26fa6611c227e0f010eea7b6c36d..e11b84d553c537104e487e13ade529ef7e0d28e6 100644 (file)
@@ -4,10 +4,10 @@
  * and emails.
  *
  * @author             Roland Haeder <webmaster@mxchange.org>
- * @version            0.3.0
+ * @version            0.0.0
  * @copyright  Copyright(c) 2007, 2008 Roland Haeder, this is free software
  * @license            GNU GPL 3.0 or any newer version
- * @link               http://www.mxchange.org
+ * @link               http://www.ship-simu.org
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 class TemplateEngine extends BaseFrameworkSystem implements CompileableTemplate {
        /**
@@ -114,13 +114,13 @@ class TemplateEngine extends BaseFrameworkSystem implements CompileableTemplate
        const EXCEPTION_INVALID_VIEW_HELPER           = 0xa02;
 
        /**
-        * Private constructor
+        * Protected constructor
         *
         * @return      void
         */
-       private final function __construct () {
+       protected function __construct () {
                // Call parent constructor
-               parent::constructor(__CLASS__);
+               parent::__construct(__CLASS__);
 
                // Set part description
                $this->setObjectDescription("Template-Engine");
@@ -194,7 +194,7 @@ class TemplateEngine extends BaseFrameworkSystem implements CompileableTemplate
         * Search for a variable in the stack
         *
         * @param               $var            The variable we are looking for
-        * @return      $idx            FALSE means not found, > 0 means found on a specific index
+        * @return      $idx            FALSE means not found, >=0 means found on a specific index
         */
        private function isVariableAlreadySet ($var) {
                // First everything is not found
@@ -217,6 +217,33 @@ class TemplateEngine extends BaseFrameworkSystem implements CompileableTemplate
                return $found;
        }
 
+       /**
+        * Return a content of a variable or null if not found
+        *
+        * @param       $var            The variable we are looking for
+        * @return      $content        Content of the variable or null if not found
+        */
+       private function readVariable ($var) {
+               // First everything is not found
+               $content = null;
+
+               // Now search for it
+               for ($idx = $this->varStack->getIterator(); $idx->valid(); $idx->next()) {
+                       // Get current item
+                       $currEntry = $idx->current();
+
+                       // Is the entry found?
+                       if ($currEntry['name'] == $var) {
+                               // Found!
+                               $content = $currEntry['value'];
+                               break;
+                       }
+               }
+
+               // Return the current position
+               return $content;
+       }
+
        /**
         * Add a variable to the stack
         *
@@ -227,8 +254,8 @@ class TemplateEngine extends BaseFrameworkSystem implements CompileableTemplate
        private function addVariable ($var, $value) {
                // Add it to the stack
                $this->varStack->append(array(
-                       'name'  => $var,
-                       'value' => $value
+                       'name'  => trim($var),
+                       'value' => trim($value)
                ));
        }
 
@@ -520,13 +547,6 @@ class TemplateEngine extends BaseFrameworkSystem implements CompileableTemplate
         *                                                              required method
         */
        private function loadRawTemplateData ($fqfn) {
-               // Debug message
-               if ((defined('DEBUG_TEMPLATE')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] Template <strong>%s</strong> vom Typ <strong>%s</strong> wird geladen.<br />\n",
-                       $this->__toString(),
-                       $template,
-                       $this->getTemplateType()
-               ));
-
                // Get a input/output instance from the middleware
                $ioInstance = $this->getFileIOInstance();
 
@@ -545,12 +565,6 @@ class TemplateEngine extends BaseFrameworkSystem implements CompileableTemplate
                // Load the raw template
                $rawTemplateData = $ioInstance->loadFileContents($fqfn);
 
-               // Debug message
-               if ((defined('DEBUG_TEMPLATE')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] <strong>%s</strong> Byte Rohdaten geladen.<br />\n",
-                       $this->__toString(),
-                       strlen($rawTemplateData)
-               ));
-
                // Store the template's contents into this class
                $this->setRawTemplateData($rawTemplateData);
 
@@ -623,7 +637,7 @@ class TemplateEngine extends BaseFrameworkSystem implements CompileableTemplate
         * [2] => Array - An array with right part of a match including ":"
         * [3] => Array - An array with right part of a match excluding ":"
         */
-       private function analyzeTemplate ($templateMatches) {
+       private function analyzeTemplate (array $templateMatches) {
                // Backup raw template data
                $backup = $this->getRawTemplateData();
 
@@ -647,8 +661,17 @@ class TemplateEngine extends BaseFrameworkSystem implements CompileableTemplate
                                        // RECURSIVE PROTECTION!
                                        $this->loadedTemplates[] = $template;
                                } catch (FilePointerNotOpenedException $e) {
-                                       // Template not found!
-                                       $this->rawTemplates[] = $template;
+                                       // Template not found, but maybe variable assigned?
+                                       if ($this->isVariableAlreadySet($template) !== false) {
+                                               // Use that content here
+                                               $this->loadedRawData[$template] = $this->readVariable($template);
+
+                                               // Recursive protection:
+                                               $this->loadedTemplates[] = $template;
+                                       } else {
+                                               // Even this is not done... :/
+                                               $this->rawTemplates[] = $template;
+                                       }
                                }
 
                        } // if ((!isset( ...
@@ -701,15 +724,15 @@ class TemplateEngine extends BaseFrameworkSystem implements CompileableTemplate
         * @param               $templateMatches        See method analyzeTemplate()
         * @return      void
         */
-       private function insertAllTemplates ($templateMatches) {
+       private function insertAllTemplates (array $templateMatches) {
                // Run through all loaded codes
-               foreach ($this->loadedRawData as $template => $code) {
+               foreach ($this->loadedRawData as $template=>$code) {
 
                        // Search for the template
                        $foundIndex = array_search($template, $templateMatches[1]);
 
                        // Lookup the matching template replacement
-                       if (isset($templateMatches[0][$foundIndex])) {
+                       if (($foundIndex !== false) && (isset($templateMatches[0][$foundIndex]))) {
 
                                // Get the current raw template
                                $rawData = $this->getRawTemplateData();
@@ -719,8 +742,10 @@ class TemplateEngine extends BaseFrameworkSystem implements CompileableTemplate
 
                                // Set the new raw data
                                $this->setRawTemplateData($rawData);
-                       }
-               }
+
+                       } // END - if
+
+               } // END - foreach
        }
 
        /**
@@ -760,7 +785,7 @@ class TemplateEngine extends BaseFrameworkSystem implements CompileableTemplate
         * @param               $varMatches     An array full of variable/value pairs.
         * @return      void
         */
-       private function assignAllVariables ($varMatches) {
+       private function assignAllVariables (array $varMatches) {
                // Search for all variables
                foreach ($varMatches[1] as $key=>$var) {
 
@@ -774,7 +799,7 @@ class TemplateEngine extends BaseFrameworkSystem implements CompileableTemplate
                        if ((substr($varMatches[2][$key], 0, 1) == "\"") && (substr($varMatches[2][$key], -1, 1) == "\"")) {
                                // Free string detected! Which we can assign directly
                                $this->assignVariable($var, $varMatches[3][$key]);
-                       } else {
+                       } elseif (!empty($varMatches[2][$key])) {
                                // Non-string found so we need some deeper analysis...
                                // @TODO Unfinished work or don't die here.
                                die("Deeper analysis not yet implemented!");
@@ -788,21 +813,27 @@ class TemplateEngine extends BaseFrameworkSystem implements CompileableTemplate
         * @param               $templateMatches        See method analyzeTemplate() for details
         * @return      void
         */
-       private function compileRawTemplateData ($templateMatches) {
+       private function compileRawTemplateData (array $templateMatches) {
                // Are some code-templates found which we need to compile?
                if (count($this->loadedRawData) > 0) {
 
                        // Then compile all!
-                       foreach ($this->loadedRawData as $template => $code) {
+                       foreach ($this->loadedRawData as $template=>$code) {
+
+                               // Is this template already compiled?
+                               if (in_array($template, $this->compiledTemplates)) {
+                                       // Then skip it
+                                       continue;
+                               }
 
                                // Search for the template
                                $foundIndex = array_search($template, $templateMatches[1]);
 
                                // Lookup the matching variable data
-                               if (isset($templateMatches[3][$foundIndex])) {
+                               if (($foundIndex !== false) && (isset($templateMatches[3][$foundIndex]))) {
 
                                        // Split it up with another reg. exp. into variable=value pairs
-                                       @preg_match_all($this->regExpVarValue, $templateMatches[3][$foundIndex], $varMatches);
+                                       preg_match_all($this->regExpVarValue, $templateMatches[3][$foundIndex], $varMatches);
 
                                        // Assign all variables
                                        $this->assignAllVariables($varMatches);
@@ -820,6 +851,44 @@ class TemplateEngine extends BaseFrameworkSystem implements CompileableTemplate
                } // END - if (count($this->loadedRawData) ...
        }
 
+       /**
+        * Inserts all raw templates into their respective variables
+        *
+        * @return      void
+        */
+       private function insertRawTemplates () {
+               // Load all templates
+               foreach ($this->rawTemplates as $template=>$content) {
+                       // Set the template as a variable with the content
+                       $this->assignVariable($template, $content);
+               }
+       }
+
+       /**
+        * Finalizes the compilation of all template variables
+        *
+        * @return      void
+        */
+       private function finalizeVariableCompilation () {
+               // Get the content
+               $content = $this->getRawTemplateData();
+
+               // Walk through all variables
+               for ($idx = $this->varStack->getIterator(); $idx->valid(); $idx->next()) {
+                       // Get current entry
+                       $currEntry = $idx->current();
+
+                       // Replace all [$var] or {?$var?} with the content
+                       //* DEBUG: */ echo "name=".$currEntry['name'].", value=<pre>".htmlentities($currEntry['value'])."</pre>\n";
+                       $content = str_replace("\$content[".$currEntry['name']."]", $currEntry['value'], $content);
+                       $content = str_replace("[".$currEntry['name']."]", $currEntry['value'], $content);
+                       $content = str_replace("{?".$currEntry['name']."?}", $currEntry['value'], $content);
+               } // END - for
+
+               // Set the content back
+               $this->setRawTemplateData($content);
+       }
+
        /**
         * Getter for raw template data
         *
@@ -893,12 +962,17 @@ class TemplateEngine extends BaseFrameworkSystem implements CompileableTemplate
 
                // Iterate through all variables
                for ($idx = $this->varStack->getIterator(); $idx->valid(); $idx->next()) {
+
                        // Get current variable from the stack
                        $currVariable = $idx->current();
 
                        // Transfer it's name/value combination to the $content array
+                       //* DEBUG: */ echo $currVariable['name']."=<pre>".htmlentities($currVariable['value'])."</pre>\n";
                        $dummy[$currVariable['name']] = $currVariable['value'];
-               }
+
+               }// END - if
+
+               // Set the new variable (don't remove the second dollar !)
                $$validVar = $dummy;
 
                // Prepare all configuration variables
@@ -908,19 +982,25 @@ class TemplateEngine extends BaseFrameworkSystem implements CompileableTemplate
                unset($idx);
                unset($currVariable);
 
+               // Finalize the compilation of template variables
+               $this->finalizeVariableCompilation();
+
                // Prepare the eval() command for comiling the template
-               $eval = sprintf("\$this->setCompiledData(\"%s\");",
+               $eval = sprintf("\$result = \"%s\";",
                        addslashes($this->getRawTemplateData())
                );
 
                // Debug message
-               if (((defined('DEBUG_EVAL')) || (defined('DEBUG_ALL'))) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] Konstruierte PHP-Anweisung: <pre><em>%s</em></pre><br />\n",
+               if ((defined('DEBUG_EVAL')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] Constructed PHP command: <pre><em>%s</em></pre><br />\n",
                        $this->__toString(),
                        htmlentities($eval)
                ));
 
                // Run the constructed command. This will "compile" all variables in
                eval($eval);
+
+               // Set the new content
+               $this->setCompiledData($result);
        }
 
        /**
@@ -937,11 +1017,9 @@ class TemplateEngine extends BaseFrameworkSystem implements CompileableTemplate
                if ($this->getTemplateType() != $this->getConfigInstance()->readConfig("code_template_type")) {
                        // Abort here
                        throw new UnexpectedTemplateTypeException(array($this, $this->getTemplateType(), $this->getConfigInstance()->readConfig("code_template_type")), self::EXCEPTION_TEMPLATE_TYPE_IS_UNEXPECTED);
-               }
+               } // END - if
 
-               // Get the raw data. Thanks to Flobee(R) for given me a hint using the
-               // modifier "m" in regular expressions. I had implemented a regex here
-               // like this: (\n|\r)
+               // Get the raw data.
                $rawData = $this->getRawTemplateData();
 
                // Remove double spaces and trim leading/trailing spaces
@@ -951,7 +1029,7 @@ class TemplateEngine extends BaseFrameworkSystem implements CompileableTemplate
                $this->extractVariablesFromRawData($rawData);
 
                // Search for code-tags which are {? ?}
-               @preg_match_all($this->regExpCodeTags, $rawData, $templateMatches);
+               preg_match_all($this->regExpCodeTags, $rawData, $templateMatches);
 
                // Analyze the matches array
                if ((is_array($templateMatches)) && (count($templateMatches) == 4) && (count($templateMatches[0]) > 0)) {
@@ -968,8 +1046,15 @@ class TemplateEngine extends BaseFrameworkSystem implements CompileableTemplate
 
                        // Are some raw templates found and loaded?
                        if (count($this->rawTemplates) > 0) {
-                               die("NOT YET IMPLEMENTED");
-                       }
+
+                               // Insert all raw templates
+                               $this->insertRawTemplates();
+
+                               // Remove the raw template content as well
+                               $this->setRawTemplateData("");
+
+                       } // END - if
+
                } // END - if($templateMatches ...
        }
 
@@ -989,20 +1074,20 @@ class TemplateEngine extends BaseFrameworkSystem implements CompileableTemplate
                        break;
 
                default: // Unknown type found
+                       // Construct message
+                       $msg = sprintf("[%s:] Unknown/unsupported template type <strong>%s</strong> detected.",
+                               $this->__toString(),
+                               $this->getTemplateType()
+                       );
+
                        if ((is_object($this->getDebugInstance())) && (method_exists($this->getDebugInstance(), 'output'))) {
                                // Use debug output handler
-                               $this->getDebugInstance()->output(sprintf("[%s:] Unbekannter Template-Typ <strong>%s</strong> erkannt.",
-                                       $this->__toString(),
-                                       $this->getTemplateType()
-                               ));
+                               $this->getDebugInstance()->output($msg);
                                die();
                        } else {
                                // Put directly out
                                // DO NOT REWRITE THIS TO app_die() !!!
-                               die(sprintf("[%s:] Unbekannter Template-Typ <strong>%s</strong> erkannt.",
-                                       $this->__toString(),
-                                       $this->getTemplateType()
-                               ));
+                               die($msg);
                        }
                        break;
                }
@@ -1038,12 +1123,41 @@ class TemplateEngine extends BaseFrameworkSystem implements CompileableTemplate
                        );
 
                        // Run the code
-                       @eval($eval);
+                       eval($eval);
                }
 
                // Return the requested instance
                return $this->helpers[$helperName];
        }
+
+       /**
+        * Assigns the last loaded raw template content with a given variable
+        *
+        * @param       $templateName   Name of the template we want to assign
+        * @param       $variableName   Name of the variable we want to assign
+        * @return      void
+        */
+       public function assignTemplateWithVariable ($templateName, $variableName) {
+               // Get the content from last loaded raw template
+               $content = $this->getRawTemplateData();
+
+               // Assign the variable
+               $this->assignVariable($variableName, $content);
+
+               // Purge raw content
+               $this->setRawTemplateData("");
+       }
+
+       /**
+        * Transfers the content of this template engine to a given response instance
+        *
+        * @param       $responseInstance       An instance of a response class
+        * @return      void
+        */
+       public function transferToResponse (Responseable $responseInstance) {
+               // Get the content and set it in the response class
+               $responseInstance->writeToBody($this->getCompiledData());
+       }
 }
 
 // [EOF]