Some updates:
[core.git] / framework / main / classes / template / menu / class_MenuTemplateEngine.php
1 <?php
2 // Own namespace
3 namespace Org\Mxchange\CoreFramework\Template\Engine;
4
5 // Import framework stuff
6 use Org\Mxchange\CoreFramework\Factory\ObjectFactory;
7 use Org\Mxchange\CoreFramework\Filesystem\InvalidDirectoryException;
8 use Org\Mxchange\CoreFramework\Parser\Xml\XmlParser;
9 use Org\Mxchange\CoreFramework\Registry\Registry;
10 use Org\Mxchange\CoreFramework\Template\CompileableTemplate;
11 use Org\Mxchange\CoreFramework\Template\Engine\BaseTemplateEngine;
12
13 // Import SPL stuff
14 use \SplFileInfo;
15 use \UnexpectedValueException;
16
17 /**
18  * A Menu template engine class
19  *
20  * @author              Roland Haeder <webmaster@shipsimu.org>
21  * @version             0.0.0
22 <<<<<<< HEAD:framework/main/classes/template/menu/class_MenuTemplateEngine.php
23  * @copyright   Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2017 Core Developer Team
24 =======
25  * @copyright   Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2016 Core Developer Team
26 >>>>>>> Some updates::inc/main/classes/template/menu/class_MenuTemplateEngine.php
27  * @license             GNU GPL 3.0 or any newer version
28  * @link                http://www.shipsimu.org
29  *
30  * This program is free software: you can redistribute it and/or modify
31  * it under the terms of the GNU General Public License as published by
32  * the Free Software Foundation, either version 3 of the License, or
33  * (at your option) any later version.
34  *
35  * This program is distributed in the hope that it will be useful,
36  * but WITHOUT ANY WARRANTY; without even the implied warranty of
37  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
38  * GNU General Public License for more details.
39  *
40  * You should have received a copy of the GNU General Public License
41  * along with this program. If not, see <http://www.gnu.org/licenses/>.
42  */
43 class MenuTemplateEngine extends BaseTemplateEngine implements CompileableTemplate {
44         /**
45          * Main nodes in the XML tree ('menu' is ignored)
46          */
47         private $mainNodes = array(
48                 'block-list',
49         );
50
51         /**
52          * Sub nodes in the XML tree
53          */
54         private $subNodes = array(
55                 'entry-list',
56                 'entry',
57                 'entry-id',
58                 'entries-content',
59                 'block-header',
60                 'block-footer',
61                 'footer-id',
62                 'footer-class',
63                 'footer-text',
64                 'block',
65                 'title',
66                 'title-id',
67                 'title-class',
68                 'title-text',
69                 'design',
70                 'text',
71                 'advert',
72                 'anchor',
73                 'anchor-id',
74                 'anchor-text',
75                 'anchor-title',
76                 'anchor-href',
77         );
78
79         /**
80          * Variables for a menu entry
81          */
82         private $menuEntryVariables = array(
83                 // List entry
84                 'entry_id',
85                 // Anchor
86                 'anchor-id',
87                 'anchor-text',
88                 'anchor-title',
89                 'anchor-href',
90         );
91
92         /**
93          * Variables for a menu block
94          */
95         private $menuBlockVariables = array(
96                 // Title
97                 'title_id',
98                 'title_class',
99                 'title_text',
100                 // Content is taken from menuEntries
101                 // Footer
102                 'footer_id',
103                 'footer_class',
104                 'footer_text',
105         );
106
107         /**
108          * Rendered menu entries
109          */
110         private $menuEntries = array();
111
112         /**
113          * Rendered menu blocks
114          */
115         private $menuBlocks = array();
116
117         /**
118          * Menu instance
119          */
120         private $menuInstance = NULL;
121
122         /**
123          * Current main node
124          */
125         private $curr = array();
126
127         /**
128          * Content from dependency
129          */
130         private $dependencyContent = array();
131
132         /**
133          * Protected constructor
134          *
135          * @return      void
136          */
137         protected function __construct () {
138                 // Call parent constructor
139                 parent::__construct(__CLASS__);
140         }
141
142         /**
143          * Creates an instance of the class TemplateEngine and prepares it for usage
144          *
145          * @param       $menuInstance                   A RenderableMenu instance
146          * @return      $templateInstance               An instance of TemplateEngine
147          * @throws      UnexpectedValueException                If the found $templateBasePath is empty or not a string
148          * @throws      InvalidDirectoryException       If $templateBasePath is no directory or not found
149          * @throws      BasePathReadProtectedException  If $templateBasePath is
150          *                                                                                      read-protected
151          */
152         public static final function createMenuTemplateEngine (RenderableMenu $menuInstance) {
153                 // Get a new instance
154                 $templateInstance = new MenuTemplateEngine();
155
156                 // Get the application instance from registry
157                 $applicationInstance = Registry::getRegistry()->getInstance('app');
158
159                 // Determine base path
160                 $templateBasePath = $templateInstance->getConfigInstance()->getConfigEntry('application_base_path') . $applicationInstance->getAppShortName(). '/';
161
162                 // Is the base path valid?
163                 if (empty($templateBasePath)) {
164                         // Base path is empty
165                         throw new UnexpectedValueException(sprintf('[%s:%d] Variable templateBasePath is empty.', $templateInstance->__toString(), __LINE__), self::EXCEPTION_UNEXPECTED_EMPTY_STRING);
166                 } elseif (!is_string($templateBasePath)) {
167                         // Is not a string
168                         throw new UnexpectedValueException(sprintf('[%s:%d] %s is not a string with a base path.', $templateInstance->__toString(), __LINE__, $templateBasePath), self::EXCEPTION_INVALID_STRING);
169                 } elseif (!is_dir($templateBasePath)) {
170                         // Is not a path
171                         throw new InvalidDirectoryException(array($templateInstance, $templateBasePath), self::EXCEPTION_INVALID_PATH_NAME);
172                 } elseif (!is_readable($templateBasePath)) {
173                         // Is not readable
174                         throw new BasePathReadProtectedException(array($templateInstance, $templateBasePath), self::EXCEPTION_READ_PROTECED_PATH);
175                 }
176
177                 // Set the base path
178                 $templateInstance->setTemplateBasePath($templateBasePath);
179
180                 // Set template extensions
181                 $templateInstance->setRawTemplateExtension($templateInstance->getConfigInstance()->getConfigEntry('raw_template_extension'));
182                 $templateInstance->setCodeTemplateExtension($templateInstance->getConfigInstance()->getConfigEntry('menu_template_extension'));
183
184                 // Absolute output path for compiled templates
185                 $templateInstance->setCompileOutputPath(sprintf('%s%s/',
186                         $templateBasePath,
187                         $templateInstance->getConfigInstance()->getConfigEntry('compile_output_path')
188                 ));
189
190                 // Set the menu instance
191                 $templateInstance->setMenuInstance($menuInstance);
192
193                 // Init a variable stacker
194                 $stackInstance = ObjectFactory::createObjectByConfiguredName('menu_stacker_class');
195
196                 // Set it
197                 $templateInstance->setStackInstance($stackInstance);
198
199                 // Return the prepared instance
200                 return $templateInstance;
201         }
202
203         /**
204          * Load a specified menu template into the engine
205          *
206          * @param       $template       The menu template we shall load which is
207          *                                              located in 'menu' by default
208          * @return      void
209          */
210         public function loadMenuTemplate ($template) {
211                 // Set template type
212                 $this->setTemplateType($this->getConfigInstance()->getConfigEntry('menu_template_type'));
213
214                 // Load the special template
215                 $this->loadTemplate($template);
216         }
217
218         /**
219          * Getter for current main node
220          *
221          * @return      $currMainNode   Current main node
222          */
223         public final function getCurrMainNode () {
224                 return $this->curr['main_node'];
225         }
226
227         /**
228          * Setter for current main node
229          *
230          * @param       $element                Element name to set as current main node
231          * @return      $currMainNode   Current main node
232          */
233         private final function setCurrMainNode ($element) {
234                 $this->curr['main_node'] = (string) $element;
235         }
236
237         /**
238          * Getter for main node array
239          *
240          * @return      $mainNodes      Array with valid main node names
241          */
242         public final function getMainNodes () {
243                 return $this->mainNodes;
244         }
245
246         /**
247          * Getter for sub node array
248          *
249          * @return      $subNodes       Array with valid sub node names
250          */
251         public final function getSubNodes () {
252                 return $this->subNodes;
253         }
254
255         /**
256          * Handles the start element of an XML resource
257          *
258          * @param       $resource               XML parser resource (currently ignored)
259          * @param       $element                The element we shall handle
260          * @param       $attributes             All attributes
261          * @return      void
262          * @throws      InvalidXmlNodeException         If an unknown/invalid XML node name was found
263          */
264         public function startElement ($resource, $element, array $attributes) {
265                 // Initial method name which will never be called...
266                 $methodName = 'initMenu';
267
268                 // Make the element name lower-case
269                 $element = strtolower($element);
270
271                 // Is the element a main node?
272                 //* DEBUG: */ echo "START: &gt;".$element."&lt;<br />\n";
273                 if (in_array($element, $this->getMainNodes())) {
274                         // Okay, main node found!
275                         $methodName = 'start' . self::convertToClassName($element);
276
277                         // Set it
278                         $this->setCurrMainNode($element);
279                 } elseif (in_array($element, $this->getSubNodes())) {
280                         // Sub node found
281                         $methodName = 'start' . self::convertToClassName($element);
282                 } elseif ($element != 'menu') {
283                         // Invalid node name found
284                         throw new InvalidXmlNodeException(array($this, $element, $attributes), XmlParser::EXCEPTION_XML_NODE_UNKNOWN);
285                 }
286
287                 // Call method
288                 //* DEBUG: */ echo "call: ".$methodName."<br />\n";
289                 call_user_func_array(array($this, $methodName), $attributes);
290         }
291
292         /**
293          * Ends the main or sub node by sending out the gathered data
294          *
295          * @param       $resource       An XML resource pointer (currently ignored)
296          * @param       $nodeName       Name of the node we want to finish
297          * @return      void
298          * @throws      XmlNodeMismatchException        If current main node mismatches the closing one
299          */
300         public function finishElement ($resource, $nodeName) {
301                 // Make all lower-case
302                 $nodeName = strtolower($nodeName);
303
304                 // Does this match with current main node?
305                 //* DEBUG: */ echo "END: &gt;".$nodeName."&lt;<br />\n";
306                 if (($nodeName != $this->getCurrMainNode()) && (in_array($nodeName, $this->getMainNodes()))) {
307                         // Did not match!
308                         throw new XmlNodeMismatchException (array($this, $nodeName, $this->getCurrMainNode()), XmlParser::EXCEPTION_XML_NODE_MISMATCH);
309                 } // END - if
310
311                 // Construct method name
312                 $methodName = 'finish' . self::convertToClassName($nodeName);
313
314                 // Call the corresponding method
315                 //* DEBUG: */ echo "call: ".$methodName."<br />\n";
316                 call_user_func_array(array($this, $methodName), array());
317         }
318
319         /**
320          * Currently not used
321          *
322          * @param       $resource               XML parser resource (currently ignored)
323          * @param       $characters             Characters to handle
324          * @return      void
325          * @todo        Find something useful with this!
326          */
327         public function characterHandler ($resource, $characters) {
328                 // Trim all spaces away
329                 $characters = trim($characters);
330
331                 // Is this string empty?
332                 if (empty($characters)) {
333                         // Then skip it silently
334                         return;
335                 } // END - if
336
337                 // Assign the found characters to variable and use the last entry from
338                 // stack as the name
339                 parent::assignVariable($this->getStackInstance()->getNamed('current_node'), $characters);
340         }
341
342         /**
343          * Handles the template dependency for given node
344          *
345          * @param       $node                                   The node we should load a dependency template
346          * @param       $templateDependency             A template to load to satisfy dependencies
347          * @return      void
348          */
349         private function handleTemplateDependency ($node, $templateDependency) {
350                 // Is the template dependency set?
351                 if ((!empty($templateDependency)) && (!isset($this->dependencyContent[$node]))) {
352                         // Get a temporay menu template instance
353                         $templateInstance = ObjectFactory::createObjectByConfiguredName('menu_template_class', array($this->getMenuInstance()));
354
355                         // Then load it
356                         $templateInstance->loadMenuTemplate($templateDependency);
357
358                         // Parse the XML content
359                         $templateInstance->renderXmlContent();
360
361                         // Save the parsed raw content in our dependency array
362                         $this->dependencyContent[$node] = $templateInstance->getRawTemplateData();
363                 } // END - if
364         }
365
366         /**
367          * Intializes the menu
368          *
369          * @param       $templateDependency             A template to load to satisfy dependencies
370          * @return      void
371          * @todo        Add cache creation here
372          */
373         private function initMenu ($templateDependency = '') {
374                 // Get web template engine
375                 $this->setTemplateInstance(ObjectFactory::createObjectByConfiguredName('html_template_class', array(Registry::getRegistry()->getInstance('app'))));
376
377                 // Handle the dependency template
378                 $this->handleTemplateDependency('menu', $templateDependency);
379
380                 // Push the node name on the stacker
381                 $this->getStackInstance()->pushNamed('current_node', 'menu');
382         }
383
384         /**
385          * Starts the menu entries
386          *
387          * @param       $templateDependency             A template to load to satisfy dependencies
388          * @return      void
389          */
390         private function startEntryList () {
391                 // Push the node name on the stacker
392                 $this->getStackInstance()->pushNamed('current_node', 'entry-list');
393         }
394
395         /**
396          * Starts the menu block header
397          *
398          * @return      void
399          */
400         private function startBlockHeader () {
401                 // Push the node name on the stacker
402                 $this->getStackInstance()->pushNamed('current_node', 'block-header');
403         }
404
405         /**
406          * Starts the menu block footer
407          *
408          * @return      void
409          */
410         private function startBlockFooter () {
411                 // Push the node name on the stacker
412                 $this->getStackInstance()->pushNamed('current_node', 'block-footer');
413         }
414
415         /**
416          * Starts the menu property 'block-list'
417          *
418          * @return      void
419          */
420         private function startBlockList () {
421                 // Push the node name on the stacker
422                 $this->getStackInstance()->pushNamed('current_node', 'block-list');
423         }
424
425         /**
426          * Starts the menu property 'block'
427          *
428          * @return      void
429          */
430         private function startBlock () {
431                 // Push the node name on the stacker
432                 $this->getStackInstance()->pushNamed('current_node', 'block');
433         }
434
435         /**
436          * Starts the menu property 'title'
437          *
438          * @return      void
439          */
440         private function startTitle () {
441                 // Push the node name on the stacker
442                 $this->getStackInstance()->pushNamed('current_node', 'title');
443         }
444
445         /**
446          * Starts the menu property 'title-id'
447          *
448          * @return      void
449          */
450         private function startTitleId () {
451                 // Push the node name on the stacker
452                 $this->getStackInstance()->pushNamed('current_node', 'title-id');
453         }
454
455         /**
456          * Starts the menu property 'title-class'
457          *
458          * @return      void
459          */
460         private function startTitleClass () {
461                 // Push the node name on the stacker
462                 $this->getStackInstance()->pushNamed('current_node', 'title-class');
463         }
464
465         /**
466          * Starts the menu property 'title-text'
467          *
468          * @return      void
469          */
470         private function startTitleText () {
471                 // Push the node name on the stacker
472                 $this->getStackInstance()->pushNamed('current_node', 'title-text');
473         }
474
475         /**
476          * Starts the menu property 'entry'
477          *
478          * @return      void
479          */
480         private function startEntry () {
481                 // Push the node name on the stacker
482                 $this->getStackInstance()->pushNamed('current_node', 'entry');
483         }
484
485         /**
486          * Starts the menu property 'entry-id'
487          *
488          * @return      void
489          */
490         private function startEntryId () {
491                 // Push the node name on the stacker
492                 $this->getStackInstance()->pushNamed('current_node', 'entry-id');
493         }
494
495         /**
496          * Starts the menu property 'anchor'
497          *
498          * @return      void
499          */
500         private function startAnchor () {
501                 // Push the node name on the stacker
502                 $this->getStackInstance()->pushNamed('current_node', 'anchor');
503         }
504
505         /**
506          * Starts the menu property 'anchor-id'
507          *
508          * @return      void
509          */
510         private function startAnchorId () {
511                 // Push the node name on the stacker
512                 $this->getStackInstance()->pushNamed('current_node', 'anchor-id');
513         }
514
515         /**
516          * Starts the menu property 'anchor-text'
517          *
518          * @return      void
519          */
520         private function startAnchorText () {
521                 // Push the node name on the stacker
522                 $this->getStackInstance()->pushNamed('current_node', 'anchor-text');
523         }
524
525         /**
526          * Starts the menu property 'anchor-title'
527          *
528          * @return      void
529          */
530         private function startAnchorTitle () {
531                 // Push the node name on the stacker
532                 $this->getStackInstance()->pushNamed('current_node', 'anchor-title');
533         }
534
535         /**
536          * Starts the menu property 'anchor-href'
537          *
538          * @return      void
539          */
540         private function startAnchorHref () {
541                 // Push the node name on the stacker
542                 $this->getStackInstance()->pushNamed('current_node', 'anchor-href');
543         }
544
545         /**
546          * Starts the menu property 'footer-id'
547          *
548          * @return      void
549          */
550         private function startFooterId () {
551                 // Push the node name on the stacker
552                 $this->getStackInstance()->pushNamed('current_node', 'footer-id');
553         }
554
555         /**
556          * Starts the menu property 'footer-class'
557          *
558          * @return      void
559          */
560         private function startFooterClass () {
561                 // Push the node name on the stacker
562                 $this->getStackInstance()->pushNamed('current_node', 'footer-class');
563         }
564
565         /**
566          * Starts the menu property 'footer-text'
567          *
568          * @return      void
569          */
570         private function startFooterText () {
571                 // Push the node name on the stacker
572                 $this->getStackInstance()->pushNamed('current_node', 'footer-text');
573         }
574
575         /**
576          * Finishes the title node by added another template to the menu
577          *
578          * @return      void
579          */
580         private function finishTitle () {
581                 // Pop the last entry
582                 $this->getStackInstance()->popNamed('current_node');
583         }
584
585         /**
586          * Finishes the title-id node by
587          *
588          * @return      void
589          */
590         private function finishTitleId () {
591                 // Pop the last entry
592                 $this->getStackInstance()->popNamed('current_node');
593         }
594
595         /**
596          * Finishes the title-class node
597          *
598          * @return      void
599          */
600         private function finishTitleClass () {
601                 // Pop the last entry
602                 $this->getStackInstance()->popNamed('current_node');
603         }
604
605         /**
606          * Finishes the title-class node
607          *
608          * @return      void
609          */
610         private function finishTitleText () {
611                 // Pop the last entry
612                 $this->getStackInstance()->popNamed('current_node');
613         }
614
615         /**
616          * Finishes the footer-text node
617          *
618          * @return      void
619          */
620         private function finishFooterText () {
621                 // Pop the last entry
622                 $this->getStackInstance()->popNamed('current_node');
623         }
624
625         /**
626          * Finishes the footer-class node
627          *
628          * @return      void
629          */
630         private function finishFooterClass () {
631                 // Pop the last entry
632                 $this->getStackInstance()->popNamed('current_node');
633         }
634
635         /**
636          * Finishes the footer-id node
637          *
638          * @return      void
639          */
640         private function finishFooterId () {
641                 // Pop the last entry
642                 $this->getStackInstance()->popNamed('current_node');
643         }
644
645         /**
646          * Finishes the anchor-href node
647          *
648          * @return      void
649          */
650         private function finishAnchorHref () {
651                 // Pop the last entry
652                 $this->getStackInstance()->popNamed('current_node');
653         }
654
655         /**
656          * Finishes the anchor-title node
657          *
658          * @return      void
659          */
660         private function finishAnchorTitle () {
661                 // Pop the last entry
662                 $this->getStackInstance()->popNamed('current_node');
663         }
664
665         /**
666          * Finishes the anchor-text node
667          *
668          * @return      void
669          */
670         private function finishAnchorText () {
671                 // Pop the last entry
672                 $this->getStackInstance()->popNamed('current_node');
673         }
674
675         /**
676          * Finishes the anchor-id node
677          *
678          * @return      void
679          */
680         private function finishAnchorId () {
681                 // Pop the last entry
682                 $this->getStackInstance()->popNamed('current_node');
683         }
684
685         /**
686          * Finishes the anchor node
687          *
688          * @return      void
689          */
690         private function finishAnchor () {
691                 // Pop the last entry
692                 $this->getStackInstance()->popNamed('current_node');
693         }
694
695         /**
696          * Finishes the entry-id node
697          *
698          * @return      void
699          */
700         private function finishEntryId () {
701                 // Pop the last entry
702                 $this->getStackInstance()->popNamed('current_node');
703         }
704
705         /**
706          * Finishes the entry node
707          *
708          * @return      void
709          */
710         private function finishEntry () {
711                 // Pop the last entry
712                 $this->getStackInstance()->popNamed('current_node');
713
714                 // Render this menu entry
715                 $this->renderMenuEntry();
716         }
717
718         /**
719          * Finishes the block node
720          *
721          * @return      void
722          */
723         private function finishBlock () {
724                 // Pop the last entry
725                 $this->getStackInstance()->popNamed('current_node');
726
727                 // Render this menu block
728                 $this->renderMenuBlock();
729         }
730
731         /**
732          * Finishes the block-list node
733          *
734          * @return      void
735          */
736         private function finishBlockList () {
737                 // Pop the last entry
738                 $this->getStackInstance()->popNamed('current_node');
739         }
740
741         /**
742          * Finishes the menu entries
743          *
744          * @return      void
745          */
746         private function finishEntryList () {
747                 // Pop the last entry
748                 $this->getStackInstance()->popNamed('current_node');
749         }
750
751         /**
752          * Finishes the menu block header
753          *
754          * @return      void
755          */
756         private function finishBlockHeader () {
757                 // Pop the last entry
758                 $this->getStackInstance()->popNamed('current_node');
759         }
760
761         /**
762          * Finishes the menu block footer
763          *
764          * @return      void
765          */
766         private function finishBlockFooter () {
767                 // Pop the last entry
768                 $this->getStackInstance()->popNamed('current_node');
769         }
770
771         /**
772          * Finishes the menu
773          *
774          * @return      void
775          */
776         private function finishMenu () {
777                 // Pop the last entry
778                 $this->getStackInstance()->popNamed('current_node');
779         }
780
781         /**
782          * Renders this menu entry, as every block all variables got overwritten
783          * with data from next entry.
784          *
785          * @return      void
786          */
787         private function renderMenuEntry () {
788                 // Prepare template engine
789                 $templateInstance = $this->prepareTemplateInstance();
790
791                 // Load menu entry template
792                 $templateInstance->loadCodeTemplate('menu_entry');
793
794                 // Copy all variables over to it
795                 foreach ($this->menuEntryVariables as $variableName) {
796                         // Copy variable
797                         $variableValue = $this->readVariable($variableName);
798
799                         // Is the key 'anchor-href'?
800                         if ($variableName == 'anchor-href') {
801                                 // Expand variable with URL then
802                                 $variableValue = '{?base_url?}/' . $variableValue;
803                         } // END - if
804
805                         // ... into the instance
806                         $templateInstance->assignVariable($variableName, $variableValue);
807                 } // END - foreach
808
809                 // Compile template + variables
810                 $templateInstance->compileTemplate();
811                 $templateInstance->compileVariables();
812
813                 // Remember it here
814                 $this->menuEntries[$this->readVariable('entry_id')] = $templateInstance->getRawTemplateData();
815         }
816
817         /**
818          * Renders this menu block, as next block all data is overwritten with
819          * next block.
820          *
821          * @return      void
822          */
823         private function renderMenuBlock () {
824                 // Init block content
825                 $blockContent = implode('', $this->menuEntries);
826
827                 // Prepare template engine
828                 $templateInstance = $this->prepareTemplateInstance();
829
830                 // Load menu entry template
831                 $templateInstance->loadCodeTemplate('menu_block');
832
833                 // Copy all variables over to it
834                 foreach ($this->menuBlockVariables as $variableName) {
835                         // Copy variable
836                         $variableValue = $this->readVariable($variableName);
837
838                         // ... into the instance
839                         $templateInstance->assignVariable($variableName, $variableValue);
840                 } // END - foreach
841
842                 // Assign block content
843                 $templateInstance->assignVariable('block_content', $blockContent);
844
845                 // Compile template + variables
846                 $templateInstance->compileTemplate();
847                 $templateInstance->compileVariables();
848
849                 // Remember it here
850                 array_push($this->menuBlocks, $templateInstance->getRawTemplateData());
851
852                 // Reset rendered menu entries array
853                 $this->menuEntries = array();
854         }
855
856         /**
857          * "Getter" for menu content
858          *
859          * @return      $menuContent    Returned menu content
860          */
861         public function getMenuContent () {
862                 // Implode menuBlocks
863                 $menuContent = implode('', $this->menuBlocks);
864
865                 // Clean variable
866                 $this->menuBlocks = array();
867
868                 // And return it
869                 return $menuContent;
870         }
871
872         /**
873          * Getter for menu cache file instance
874          *
875          * @return      $fileInstance   Full-qualified file name of the menu cache
876          */
877         public function getMenuCacheFile () {
878                 // Get the application instance from registry
879                 $applicationInstance = Registry::getRegistry()->getInstance('app');
880
881                 // Get the file instance ready
882                 $fileInstance = new SplFileInfo(sprintf('%s%smenus/_cache/%s.%s',
883                         $this->getConfigInstance()->getConfigEntry('application_base_path'),
884                         $applicationInstance->getAppShortName(),
885                         md5(
886                                 $this->getMenuInstance()->getMenuName() . ':' .
887                                 $this->__toString() . ':' .
888                                 $this->getMenuInstance()->__toString()
889                         ),
890                         $this->getMenuInstance()->getMenuType()
891                 ));
892
893                 // Return it
894                 return $fileInstance;
895         }
896
897 }