X-Git-Url: https://git.mxchange.org/?p=core.git;a=blobdiff_plain;f=inc%2Fclasses%2Fmain%2Ftemplate%2Fmenu%2Fclass_MenuTemplateEngine.php;h=4f1dd50dd2baed10de46227287fd4e644ba7d6ce;hp=9f179c0f4e8928e0d0c9f2272ea4bb5a8d159340;hb=c3021952494266e05bfa9046baf9bcd11bfe7d13;hpb=36e4d0eb331bd724db0bd23071271d5eaeb37b17 diff --git a/inc/classes/main/template/menu/class_MenuTemplateEngine.php b/inc/classes/main/template/menu/class_MenuTemplateEngine.php index 9f179c0f..4f1dd50d 100644 --- a/inc/classes/main/template/menu/class_MenuTemplateEngine.php +++ b/inc/classes/main/template/menu/class_MenuTemplateEngine.php @@ -2,11 +2,11 @@ /** * A Menu template engine class * - * @author Roland Haeder + * @author Roland Haeder * @version 0.0.0 - * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 Core Developer Team + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2015 Core Developer Team * @license GNU GPL 3.0 or any newer version - * @link http://www.ship-simu.org + * @link http://www.shipsimu.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 @@ -22,6 +22,56 @@ * along with this program. If not, see . */ class MenuTemplateEngine extends BaseTemplateEngine implements CompileableTemplate { + /** + * Main nodes in the XML tree ('menu' is ignored) + */ + private $mainNodes = array( + 'block-list', + ); + + /** + * Sub nodes in the XML tree + */ + private $subNodes = array( + 'entry-list', + 'entry', + 'entry-id', + 'entries-content', + 'block-header', + 'block-footer', + 'footer-id', + 'footer-class', + 'footer-text', + 'block', + 'title', + 'title-id', + 'title-class', + 'title-text', + 'design', + 'text', + 'advert', + 'anchor', + 'anchor-id', + 'anchor-text', + 'anchor-title', + 'anchor-href', + ); + + /** + * Menu instance + */ + private $menuInstance = NULL; + + /** + * Current main node + */ + private $curr = array(); + + /** + * Content from dependency + */ + private $dependencyContent = array(); + /** * Protected constructor * @@ -35,8 +85,8 @@ class MenuTemplateEngine extends BaseTemplateEngine implements CompileableTempla /** * Creates an instance of the class TemplateEngine and prepares it for usage * - * @param $appInstance A manageable application - * @return $tplInstance An instance of TemplateEngine + * @param $menuInstance A RenderableMenu instance + * @return $templateInstance An instance of TemplateEngine * @throws BasePathIsEmptyException If the provided $templateBasePath is empty * @throws InvalidBasePathStringException If $templateBasePath is no string * @throws BasePathIsNoDirectoryException If $templateBasePath is no @@ -44,51 +94,52 @@ class MenuTemplateEngine extends BaseTemplateEngine implements CompileableTempla * @throws BasePathReadProtectedException If $templateBasePath is * read-protected */ - public final static function createMenuTemplateEngine (ManageableApplication $appInstance) { + public static final function createMenuTemplateEngine (RenderableMenu $menuInstance) { // Get a new instance - $tplInstance = new MenuTemplateEngine(); + $templateInstance = new MenuTemplateEngine(); - // Get language and file I/O instances from application - $langInstance = $appInstance->getLanguageInstance(); - $ioInstance = $appInstance->getFileIoInstance(); + // Get the application instance from registry + $applicationInstance = Registry::getRegistry()->getInstance('app'); // Determine base path - $templateBasePath = $tplInstance->getConfigInstance()->getConfigEntry('application_base_path') . $appInstance->getRequestInstance()->getRequestElement('app') . '/'; + $templateBasePath = $templateInstance->getConfigInstance()->getConfigEntry('application_base_path') . $applicationInstance->getRequestInstance()->getRequestElement('app') . '/'; // Is the base path valid? if (empty($templateBasePath)) { // Base path is empty - throw new BasePathIsEmptyException($tplInstance, self::EXCEPTION_UNEXPECTED_EMPTY_STRING); + throw new BasePathIsEmptyException($templateInstance, self::EXCEPTION_UNEXPECTED_EMPTY_STRING); } elseif (!is_string($templateBasePath)) { // Is not a string - throw new InvalidBasePathStringException(array($tplInstance, $templateBasePath), self::EXCEPTION_INVALID_STRING); + throw new InvalidBasePathStringException(array($templateInstance, $templateBasePath), self::EXCEPTION_INVALID_STRING); } elseif (!is_dir($templateBasePath)) { // Is not a path - throw new BasePathIsNoDirectoryException(array($tplInstance, $templateBasePath), self::EXCEPTION_INVALID_PATH_NAME); + throw new BasePathIsNoDirectoryException(array($templateInstance, $templateBasePath), self::EXCEPTION_INVALID_PATH_NAME); } elseif (!is_readable($templateBasePath)) { // Is not readable - throw new BasePathReadProtectedException(array($tplInstance, $templateBasePath), self::EXCEPTION_READ_PROTECED_PATH); + throw new BasePathReadProtectedException(array($templateInstance, $templateBasePath), self::EXCEPTION_READ_PROTECED_PATH); } - // Get configuration instance - $configInstance = FrameworkConfiguration::getInstance(); - // Set the base path - $tplInstance->setTemplateBasePath($templateBasePath); - - // Set the language and IO instances - $tplInstance->setLanguageInstance($langInstance); - $tplInstance->setFileIoInstance($ioInstance); + $templateInstance->setTemplateBasePath($templateBasePath); // Set template extensions - $tplInstance->setRawTemplateExtension($configInstance->getConfigEntry('raw_template_extension')); - $tplInstance->setCodeTemplateExtension($configInstance->getConfigEntry('menu_template_extension')); + $templateInstance->setRawTemplateExtension($templateInstance->getConfigInstance()->getConfigEntry('raw_template_extension')); + $templateInstance->setCodeTemplateExtension($templateInstance->getConfigInstance()->getConfigEntry('menu_template_extension')); // Absolute output path for compiled templates - $tplInstance->setCompileOutputPath($configInstance->getConfigEntry('base_path') . $configInstance->getConfigEntry('compile_output_path')); + $templateInstance->setCompileOutputPath($templateInstance->getConfigInstance()->getConfigEntry('base_path') . $templateInstance->getConfigInstance()->getConfigEntry('compile_output_path')); + + // Set the menu instance + $templateInstance->setMenuInstance($menuInstance); + + // Init a variable stacker + $stackInstance = ObjectFactory::createObjectByConfiguredName('menu_stacker_class'); + + // Set it + $templateInstance->setStackInstance($stackInstance); // Return the prepared instance - return $tplInstance; + return $templateInstance; } /** @@ -105,6 +156,586 @@ class MenuTemplateEngine extends BaseTemplateEngine implements CompileableTempla // Load the special template $this->loadTemplate($template); } + + /** + * Getter for current main node + * + * @return $currMainNode Current main node + */ + public final function getCurrMainNode () { + return $this->curr['main_node']; + } + + /** + * Setter for current main node + * + * @param $element Element name to set as current main node + * @return $currMainNode Current main node + */ + private final function setCurrMainNode ($element) { + $this->curr['main_node'] = (string) $element; + } + + /** + * Getter for main node array + * + * @return $mainNodes Array with valid main node names + */ + public final function getMainNodes () { + return $this->mainNodes; + } + + /** + * Getter for sub node array + * + * @return $subNodes Array with valid sub node names + */ + public final function getSubNodes () { + return $this->subNodes; + } + + /** + * Handles the start element of an XML resource + * + * @param $resource XML parser resource (currently ignored) + * @param $element The element we shall handle + * @param $attributes All attributes + * @return void + * @throws InvalidXmlNodeException If an unknown/invalid XML node name was found + */ + public function startElement ($resource, $element, array $attributes) { + // Initial method name which will never be called... + $methodName = 'initMenu'; + + // Make the element name lower-case + $element = strtolower($element); + + // Is the element a main node? + //* DEBUG: */ echo "START: >".$element."<
\n"; + if (in_array($element, $this->getMainNodes())) { + // Okay, main node found! + $methodName = 'start' . $this->convertToClassName($element); + + // Set it + $this->setCurrMainNode($element); + } elseif (in_array($element, $this->getSubNodes())) { + // Sub node found + $methodName = 'start' . $this->convertToClassName($element); + } elseif ($element != 'menu') { + // Invalid node name found + throw new InvalidXmlNodeException(array($this, $element, $attributes), XmlParser::EXCEPTION_XML_NODE_UNKNOWN); + } + + // Call method + //* DEBUG: */ echo "call: ".$methodName."
\n"; + call_user_func_array(array($this, $methodName), $attributes); + } + + /** + * Ends the main or sub node by sending out the gathered data + * + * @param $resource An XML resource pointer (currently ignored) + * @param $nodeName Name of the node we want to finish + * @return void + * @throws XmlNodeMismatchException If current main node mismatches the closing one + */ + public function finishElement ($resource, $nodeName) { + // Make all lower-case + $nodeName = strtolower($nodeName); + + // Does this match with current main node? + //* DEBUG: */ echo "END: >".$nodeName."<
\n"; + if (($nodeName != $this->getCurrMainNode()) && (in_array($nodeName, $this->getMainNodes()))) { + // Did not match! + throw new XmlNodeMismatchException (array($this, $nodeName, $this->getCurrMainNode()), XmlParser::EXCEPTION_XML_NODE_MISMATCH); + } // END - if + + // Construct method name + $methodName = 'finish' . $this->convertToClassName($nodeName); + + // Call the corresponding method + //* DEBUG: */ echo "call: ".$methodName."
\n"; + call_user_func_array(array($this, $methodName), array()); + } + + /** + * Currently not used + * + * @param $resource XML parser resource (currently ignored) + * @param $characters Characters to handle + * @return void + * @todo Find something useful with this! + */ + public function characterHandler ($resource, $characters) { + // Trim all spaces away + $characters = trim($characters); + + // Is this string empty? + if (empty($characters)) { + // Then skip it silently + return; + } // END - if + + // Assign the found characters to variable and use the last entry from + // stack as the name + parent::assignVariable($this->getStackInstance()->getNamed('current_node'), $characters); + } + + /** + * Handles the template dependency for given node + * + * @param $node The node we should load a dependency template + * @param $templateDependency A template to load to satisfy dependencies + * @return void + */ + private function handleTemplateDependency ($node, $templateDependency) { + // Is the template dependency set? + if ((!empty($templateDependency)) && (!isset($this->dependencyContent[$node]))) { + // Get a temporay menu template instance + $templateInstance = ObjectFactory::createObjectByConfiguredName('menu_template_class', array($this->getMenuInstance())); + + // Then load it + $templateInstance->loadMenuTemplate($templateDependency); + + // Parse the XML content + $templateInstance->renderXmlContent(); + + // Save the parsed raw content in our dependency array + $this->dependencyContent[$node] = $templateInstance->getRawTemplateData(); + } // END - if + } + + /** + * Intializes the menu + * + * @param $templateDependency A template to load to satisfy dependencies + * @return void + * @todo Add cache creation here + */ + private function initMenu ($templateDependency = '') { + // Get web template engine + $this->setTemplateInstance(ObjectFactory::createObjectByConfiguredName('html_template_class', array($this->getApplicationInstance()))); + + // Handle the dependency template + $this->handleTemplateDependency('menu', $templateDependency); + + // Push the node name on the stacker + $this->getStackInstance()->pushNamed('current_node', 'menu'); + } + + /** + * Starts the menu entries + * + * @param $templateDependency A template to load to satisfy dependencies + * @return void + */ + private function startEntryList () { + // Push the node name on the stacker + $this->getStackInstance()->pushNamed('current_node', 'entry-list'); + } + + /** + * Starts the menu block header + * + * @return void + */ + private function startBlockHeader () { + // Push the node name on the stacker + $this->getStackInstance()->pushNamed('current_node', 'block-header'); + } + + /** + * Starts the menu block footer + * + * @return void + */ + private function startBlockFooter () { + // Push the node name on the stacker + $this->getStackInstance()->pushNamed('current_node', 'block-footer'); + } + + /** + * Starts the menu property 'block-list' + * + * @return void + */ + private function startBlockList () { + // Push the node name on the stacker + $this->getStackInstance()->pushNamed('current_node', 'block-list'); + } + + /** + * Starts the menu property 'block' + * + * @return void + */ + private function startBlock () { + // Push the node name on the stacker + $this->getStackInstance()->pushNamed('current_node', 'block'); + } + + /** + * Starts the menu property 'title' + * + * @return void + */ + private function startTitle () { + // Push the node name on the stacker + $this->getStackInstance()->pushNamed('current_node', 'title'); + } + + /** + * Starts the menu property 'title-id' + * + * @return void + */ + private function startTitleId () { + // Push the node name on the stacker + $this->getStackInstance()->pushNamed('current_node', 'title-id'); + } + + /** + * Starts the menu property 'title-class' + * + * @return void + */ + private function startTitleClass () { + // Push the node name on the stacker + $this->getStackInstance()->pushNamed('current_node', 'title-class'); + } + + /** + * Starts the menu property 'title-text' + * + * @return void + */ + private function startTitleText () { + // Push the node name on the stacker + $this->getStackInstance()->pushNamed('current_node', 'title-text'); + } + + /** + * Starts the menu property 'entry' + * + * @return void + */ + private function startEntry () { + // Push the node name on the stacker + $this->getStackInstance()->pushNamed('current_node', 'entry'); + } + + /** + * Starts the menu property 'entry-id' + * + * @return void + */ + private function startEntryId () { + // Push the node name on the stacker + $this->getStackInstance()->pushNamed('current_node', 'entry-id'); + } + + /** + * Starts the menu property 'anchor' + * + * @return void + */ + private function startAnchor () { + // Push the node name on the stacker + $this->getStackInstance()->pushNamed('current_node', 'anchor'); + } + + /** + * Starts the menu property 'anchor-id' + * + * @return void + */ + private function startAnchorId () { + // Push the node name on the stacker + $this->getStackInstance()->pushNamed('current_node', 'anchor-id'); + } + + /** + * Starts the menu property 'anchor-text' + * + * @return void + */ + private function startAnchorText () { + // Push the node name on the stacker + $this->getStackInstance()->pushNamed('current_node', 'anchor-text'); + } + + /** + * Starts the menu property 'anchor-title' + * + * @return void + */ + private function startAnchorTitle () { + // Push the node name on the stacker + $this->getStackInstance()->pushNamed('current_node', 'anchor-title'); + } + + /** + * Starts the menu property 'anchor-href' + * + * @return void + */ + private function startAnchorHref () { + // Push the node name on the stacker + $this->getStackInstance()->pushNamed('current_node', 'anchor-href'); + } + + /** + * Starts the menu property 'footer-id' + * + * @return void + */ + private function startFooterId () { + // Push the node name on the stacker + $this->getStackInstance()->pushNamed('current_node', 'footer-id'); + } + + /** + * Starts the menu property 'footer-class' + * + * @return void + */ + private function startFooterClass () { + // Push the node name on the stacker + $this->getStackInstance()->pushNamed('current_node', 'footer-class'); + } + + /** + * Starts the menu property 'footer-text' + * + * @return void + */ + private function startFooterText () { + // Push the node name on the stacker + $this->getStackInstance()->pushNamed('current_node', 'footer-text'); + } + + /** + * Finishes the title node by added another template to the menu + * + * @return void + */ + private function finishTitle () { + // Pop the last entry + $this->getStackInstance()->popNamed('current_node'); + } + + /** + * Finishes the title-id node by + * + * @return void + */ + private function finishTitleId () { + // Pop the last entry + $this->getStackInstance()->popNamed('current_node'); + } + + /** + * Finishes the title-class node + * + * @return void + */ + private function finishTitleClass () { + // Pop the last entry + $this->getStackInstance()->popNamed('current_node'); + } + + /** + * Finishes the title-class node + * + * @return void + */ + private function finishTitleText () { + // Pop the last entry + $this->getStackInstance()->popNamed('current_node'); + } + + /** + * Finishes the footer-text node + * + * @return void + */ + private function finishFooterText () { + // Pop the last entry + $this->getStackInstance()->popNamed('current_node'); + } + + /** + * Finishes the footer-class node + * + * @return void + */ + private function finishFooterClass () { + // Pop the last entry + $this->getStackInstance()->popNamed('current_node'); + } + + /** + * Finishes the footer-id node + * + * @return void + */ + private function finishFooterId () { + // Pop the last entry + $this->getStackInstance()->popNamed('current_node'); + } + + /** + * Finishes the anchor-href node + * + * @return void + */ + private function finishAnchorHref () { + // Pop the last entry + $this->getStackInstance()->popNamed('current_node'); + } + + /** + * Finishes the anchor-title node + * + * @return void + */ + private function finishAnchorTitle () { + // Pop the last entry + $this->getStackInstance()->popNamed('current_node'); + } + + /** + * Finishes the anchor-text node + * + * @return void + */ + private function finishAnchorText () { + // Pop the last entry + $this->getStackInstance()->popNamed('current_node'); + } + + /** + * Finishes the anchor-id node + * + * @return void + */ + private function finishAnchorId () { + // Pop the last entry + $this->getStackInstance()->popNamed('current_node'); + } + + /** + * Finishes the anchor node + * + * @return void + */ + private function finishAnchor () { + // Pop the last entry + $this->getStackInstance()->popNamed('current_node'); + } + + /** + * Finishes the entry-id node + * + * @return void + */ + private function finishEntryId () { + // Pop the last entry + $this->getStackInstance()->popNamed('current_node'); + } + + /** + * Finishes the entry node + * + * @return void + */ + private function finishEntry () { + // Pop the last entry + $this->getStackInstance()->popNamed('current_node'); + } + + /** + * Finishes the block node + * + * @return void + */ + private function finishBlock () { + // Pop the last entry + $this->getStackInstance()->popNamed('current_node'); + } + + /** + * Finishes the block-list node + * + * @return void + */ + private function finishBlockList () { + // Pop the last entry + $this->getStackInstance()->popNamed('current_node'); + } + + /** + * Finishes the menu entries + * + * @return void + */ + private function finishEntryList () { + // Pop the last entry + $this->getStackInstance()->popNamed('current_node'); + } + + /** + * Finishes the menu block header + * + * @return void + */ + private function finishBlockHeader () { + // Pop the last entry + $this->getStackInstance()->popNamed('current_node'); + } + + /** + * Finishes the menu block footer + * + * @return void + */ + private function finishBlockFooter () { + // Pop the last entry + $this->getStackInstance()->popNamed('current_node'); + } + + /** + * Finishes the menu + * + * @return void + */ + private function finishMenu () { + // Pop the last entry + $this->getStackInstance()->popNamed('current_node'); + } + + /** + * Getter for menu cache file (FQFN) + * + * @return $fqfn Full-qualified file name of the menu cache + */ + public function getMenuCacheFqfn () { + // Get the FQFN ready + $fqfn = sprintf('%s%s%s/%s.%s', + $this->getConfigInstance()->getConfigEntry('base_path'), + $this->getGenericBasePath(), + 'menus/_cache', + md5( + $this->getMenuInstance()->getMenuName() . ':' . + $this->__toString() . ':' . + $this->getMenuInstance()->__toString() + ), + $this->getMenuInstance()->getMenuType() + ); + + // Return it + return $fqfn; + } } // [EOF]