]> git.mxchange.org Git - core.git/blob - framework/main/classes/template/image/class_ImageTemplateEngine.php
Continued:
[core.git] / framework / main / classes / template / image / class_ImageTemplateEngine.php
1 <?php
2 // Own namespace
3 namespace Org\Mxchange\CoreFramework\Template\Engine;
4
5 // Import framework stuff
6 use Org\Mxchange\CoreFramework\Bootstrap\FrameworkBootstrap;
7 use Org\Mxchange\CoreFramework\Factory\ObjectFactory;
8 use Org\Mxchange\CoreFramework\Filesystem\InvalidDirectoryException;
9 use Org\Mxchange\CoreFramework\Parser\Xml\XmlParser;
10 use Org\Mxchange\CoreFramework\Registry\GenericRegistry;
11 use Org\Mxchange\CoreFramework\Response\Responseable;
12 use Org\Mxchange\CoreFramework\Template\CompileableTemplate;
13 use Org\Mxchange\CoreFramework\Template\Engine\BaseTemplateEngine;
14
15 // Import SPL stuff
16 use \SplFileInfo;
17 use \UnexpectedValueException;
18
19 /**
20  * The own template engine for loading caching and sending out images
21  *
22  * @author              Roland Haeder <webmaster@shipsimu.org>
23  * @version             0.0.0
24  * @copyright   Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2020 Core Developer Team
25  * @license             GNU GPL 3.0 or any newer version
26  * @link                http://www.shipsimu.org
27  *
28  * This program is free software: you can redistribute it and/or modify
29  * it under the terms of the GNU General Public License as published by
30  * the Free Software Foundation, either version 3 of the License, or
31  * (at your option) any later version.
32  *
33  * This program is distributed in the hope that it will be useful,
34  * but WITHOUT ANY WARRANTY; without even the implied warranty of
35  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
36  * GNU General Public License for more details.
37  *
38  * You should have received a copy of the GNU General Public License
39  * along with this program. If not, see <http://www.gnu.org/licenses/>.
40  */
41 class ImageTemplateEngine extends BaseTemplateEngine implements CompileableTemplate {
42         /**
43          * Main nodes in the XML tree ('image' is ignored)
44          */
45         private $mainNodes = array(
46                 'base',
47                 'type',
48                 'resolution',
49                 'background-color',
50                 'foreground-color',
51                 'image-string'
52         );
53
54         /**
55          * Sub nodes in the XML tree
56          */
57         private $subNodes = array(
58                 'name',
59                 'string-name',
60                 'x',
61                 'y',
62                 'font-size',
63                 'width',
64                 'height',
65                 'red',
66                 'green',
67                 'blue',
68                 'text'
69         );
70
71         /**
72          * Current main node
73          */
74         private $currMainNode = '';
75
76         /**
77          * Protected constructor
78          *
79          * @return      void
80          */
81         protected function __construct () {
82                 // Call parent constructor
83                 parent::__construct(__CLASS__);
84         }
85
86         /**
87          * Creates an instance of the class TemplateEngine and prepares it for usage
88          *
89          * @return      $templateInstance               An instance of TemplateEngine
90          * @throws      UnexpectedValueException                If the provided $templateBasePath is empty or no string
91          * @throws      InvalidDirectoryException       If $templateBasePath is no
92          *                                                                                      directory or not found
93          * @throws      BasePathReadProtectedException  If $templateBasePath is
94          *                                                                                      read-protected
95          */
96         public static final function createImageTemplateEngine () {
97                 // Get a new instance
98                 $templateInstance = new ImageTemplateEngine();
99
100                 // Get the application instance from registry
101                 $applicationInstance = GenericRegistry::getRegistry()->getInstance('application');
102
103                 // Determine base path
104                 $templateBasePath = FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('application_base_path') . $applicationInstance->getAppShortName(). '/';
105
106                 // Is the base path valid?
107                 if (empty($templateBasePath)) {
108                         // Base path is empty
109                         throw new UnexpectedValueException(sprintf('[%s:%d] Variable templateBasePath is empty.', $templateInstance->__toString(), __LINE__), self::EXCEPTION_UNEXPECTED_EMPTY_STRING);
110                 } elseif (!is_string($templateBasePath)) {
111                         // Is not a string
112                         throw new UnexpectedValueException(sprintf('[%s:%d] %s is not a string with a base path.', $templateInstance->__toString(), __LINE__, $templateBasePath), self::EXCEPTION_INVALID_STRING);
113                 } elseif (!is_dir($templateBasePath)) {
114                         // Is not a path
115                         throw new InvalidDirectoryException(array($templateInstance, $templateBasePath), self::EXCEPTION_INVALID_PATH_NAME);
116                 } elseif (!is_readable($templateBasePath)) {
117                         // Is not readable
118                         throw new BasePathReadProtectedException(array($templateInstance, $templateBasePath), self::EXCEPTION_READ_PROTECED_PATH);
119                 }
120
121                 // Set the base path
122                 $templateInstance->setTemplateBasePath($templateBasePath);
123
124                 // Set template extensions
125                 $templateInstance->setRawTemplateExtension(FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('raw_template_extension'));
126                 $templateInstance->setCodeTemplateExtension(FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('code_template_extension'));
127
128                 // Absolute output path for compiled templates
129                 $templateInstance->setCompileOutputPath(sprintf('%s%s/',
130                         $templateBasePath,
131                         FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('compile_output_path')
132                 ));
133
134                 // Return the prepared instance
135                 return $templateInstance;
136         }
137
138         /**
139          * Getter for current main node
140          *
141          * @return      $currMainNode   Current main node
142          */
143         public final function getCurrMainNode () {
144                 return $this->currMainNode;
145         }
146
147         /**
148          * Getter for main node array
149          *
150          * @return      $mainNodes      Array with valid main node names
151          */
152         public final function getMainNodes () {
153                 return $this->mainNodes;
154         }
155
156         /**
157          * Getter for sub node array
158          *
159          * @return      $subNodes       Array with valid sub node names
160          */
161         public final function getSubNodes () {
162                 return $this->subNodes;
163         }
164
165         /**
166          * Handles the start element of an XML resource
167          *
168          * @param       $resource               XML parser resource (currently ignored)
169          * @param       $element                The element we shall handle
170          * @param       $attributes             All attributes
171          * @return      void
172          * @throws      InvalidXmlNodeException         If an unknown/invalid XML node name was found
173          */
174         public function startElement ($resource, $element, array $attributes) {
175                 // Initial method name which will never be called...
176                 $methodName = 'initImage';
177
178                 // Make the element name lower-case
179                 $element = strtolower($element);
180
181                 // Is the element a main node?
182                 //* DEBUG: */ echo "START: &gt;".$element."&lt;<br />\n";
183                 if (in_array($element, $this->mainNodes)) {
184                         // Okay, main node found!
185                         $methodName = 'setImage' . self::convertToClassName($element);
186                 } elseif (in_array($element, $this->subNodes)) {
187                         // Sub node found
188                         $methodName = 'setImageProperty' . self::convertToClassName($element);
189                 } elseif ($element != 'image') {
190                         // Invalid node name found
191                         throw new InvalidXmlNodeException(array($this, $element, $attributes), XmlParser::EXCEPTION_XML_NODE_UNKNOWN);
192                 }
193
194                 // Call method
195                 //* DEBUG: */ echo "call: ".$methodName."<br />\n";
196                 call_user_func_array(array($this, $methodName), $attributes);
197         }
198
199         /**
200          * Ends the main or sub node by sending out the gathered data
201          *
202          * @param       $resource       An XML resource pointer (currently ignored)
203          * @param       $nodeName       Name of the node we want to finish
204          * @return      void
205          * @throws      XmlNodeMismatchException        If current main node mismatches the closing one
206          */
207         public function finishElement ($resource, $nodeName) {
208                 // Make all lower-case
209                 $nodeName = strtolower($nodeName);
210
211                 // Does this match with current main node?
212                 //* DEBUG: */ echo "END: &gt;".$nodeName."&lt;<br />\n";
213                 if (($nodeName != $this->getCurrMainNode()) && (in_array($nodeName, $this->getMainNodes()))) {
214                         // Did not match!
215                         throw new XmlNodeMismatchException (array($this, $nodeName, $this->getCurrMainNode()), XmlParser::EXCEPTION_XML_NODE_MISMATCH);
216                 } elseif (in_array($nodeName, $this->getSubNodes())) {
217                         // Silently ignore sub nodes
218                         return;
219                 }
220
221                 // Construct method name
222                 $methodName = 'finish' . self::convertToClassName($nodeName);
223
224                 // Call the corresponding method
225                 call_user_func_array(array($this->getImageInstance(), $methodName), array());
226         }
227
228         /**
229          * Currently not used
230          *
231          * @param       $resource               XML parser resource (currently ignored)
232          * @param       $characters             Characters to handle
233          * @return      void
234          * @todo        Find something usefull with this!
235          */
236         public function characterHandler ($resource, $characters) {
237                 // Trim all spaces away
238                 $characters = trim($characters);
239
240                 // Is this string empty?
241                 if (empty($characters)) {
242                         // Then skip it silently
243                         return;
244                 } // END - if
245
246                 // Unfinished work!
247                 $this->partialStub('Handling extra characters is not yet supported!');
248         }
249
250         /**
251          * Intializes the image
252          *
253          * @return      void
254          * @todo        Add cache creation here
255          */
256         private function initImage () {
257                 // Unfinished work!
258         }
259
260         /**
261          * Set the image type
262          *
263          * @param       $imageType      Code fragment or direct value holding the image type
264          * @return      void
265          */
266         private function setImageType ($imageType) {
267                 // Set group to general
268                 $this->setVariableGroup('general');
269
270                 // Try to compile it first to get the value from variable stack
271                 $imageType = $this->compileRawCode($imageType);
272
273                 // Now make a class name of it
274                 $className = self::convertToClassName($imageType.'_image');
275
276                 // And try to initiate it
277                 $this->setImageInstance(ObjectFactory::createObjectByName($className, array($this)));
278
279                 // Set current main node to type
280                 $this->currMainNode = 'type';
281         }
282
283         /**
284          * "Setter" for resolution, we first need to collect the resolution from the
285          * sub-nodes. So first, this method will prepare an array for it
286          *
287          * @return      void
288          */
289         private function setImageResolution () {
290                 // Call the image class
291                 $this->getImageInstance()->initResolution();
292
293                 // Current main node is resolution
294                 $this->currMainNode = 'resolution';
295         }
296
297         /**
298          * "Setter" for base information. For more details see above method!
299          *
300          * @return      void
301          * @see         ImageTemplateEngine::setImageResolution
302          */
303         private function setImageBase () {
304                 // Call the image class
305                 $this->getImageInstance()->initBase();
306
307                 // Current main node is resolution
308                 $this->currMainNode = 'base';
309         }
310
311         /**
312          * "Setter" for background-color. For more details see above method!
313          *
314          * @return      void
315          * @see         ImageTemplateEngine::setImageResolution
316          */
317         private function setImageBackgroundColor () {
318                 // Call the image class
319                 $this->getImageInstance()->initBackgroundColor();
320
321                 // Current main node is background-color
322                 $this->currMainNode = 'background-color';
323         }
324
325         /**
326          * "Setter" for foreground-color. For more details see above method!
327          *
328          * @return      void
329          * @see         ImageTemplateEngine::setImageResolution
330          */
331         private function setImageForegroundColor () {
332                 // Call the image class
333                 $this->getImageInstance()->initForegroundColor();
334
335                 // Current main node is foreground-color
336                 $this->currMainNode = 'foreground-color';
337         }
338
339         /**
340          * "Setter" for image-string. For more details see above method!
341          *
342          * @param       $groupable      Whether this image string is groupable
343          * @return      void
344          * @see         ImageTemplateEngine::setImageResolution
345          */
346         private function setImageImageString ($groupable = 'single') {
347                 // Call the image class
348                 $this->getImageInstance()->initImageString($groupable);
349
350                 // Current main node is foreground-color
351                 $this->currMainNode = 'image-string';
352         }
353
354         /**
355          * Setter for image name
356          *
357          * @param       $imageName      Name of the image
358          * @return      void
359          */
360         private function setImagePropertyName ($imageName) {
361                 // Call the image class
362                 $this->getImageInstance()->setImageName($imageName);
363         }
364
365         /**
366          * Setter for image width
367          *
368          * @param       $width  Width of the image or variable
369          * @return      void
370          */
371         private function setImagePropertyWidth ($width) {
372                 // Call the image class
373                 $this->getImageInstance()->setWidth($width);
374         }
375
376         /**
377          * Setter for image height
378          *
379          * @param       $height Height of the image or variable
380          * @return      void
381          */
382         private function setImagePropertyHeight ($height) {
383                 // Call the image class
384                 $this->getImageInstance()->setHeight($height);
385         }
386
387         /**
388          * Setter for image red color
389          *
390          * @param       $red    Red color value
391          * @return      void
392          */
393         private function setImagePropertyRed ($red) {
394                 // Call the image class
395                 $this->getImageInstance()->setRed($red);
396         }
397
398         /**
399          * Setter for image green color
400          *
401          * @param       $green  Green color value
402          * @return      void
403          */
404         private function setImagePropertyGreen ($green) {
405                 // Call the image class
406                 $this->getImageInstance()->setGreen($green);
407         }
408
409         /**
410          * Setter for image blue color
411          *
412          * @param       $blue   Blue color value
413          * @return      void
414          */
415         private function setImagePropertyBlue ($blue) {
416                 // Call the image class
417                 $this->getImageInstance()->setBlue($blue);
418         }
419
420         /**
421          * Setter for string name (identifier)
422          *
423          * @param       $stringName             String name (identifier)
424          * @return      void
425          */
426         private function setImagePropertyStringName ($stringName) {
427                 // Call the image class
428                 $this->getImageInstance()->setStringName($stringName);
429         }
430
431         /**
432          * Setter for font size
433          *
434          * @param       $fontSize       Size of the font
435          * @return      void
436          */
437         private function setImagePropertyFontSize ($fontSize) {
438                 // Call the image class
439                 $this->getImageInstance()->setFontSize($fontSize);
440         }
441
442         /**
443          * Setter for image string
444          *
445          * @param       $imageString    Image string to set
446          * @return      void
447          */
448         private function setImagePropertyText ($imageString) {
449                 // Call the image class
450                 $this->getImageInstance()->setString($imageString);
451         }
452
453         /**
454          * Setter for X coordinate
455          *
456          * @param       $x      X coordinate
457          * @return      void
458          */
459         private function setImagePropertyX ($x) {
460                 // Call the image class
461                 $this->getImageInstance()->setX($x);
462         }
463
464         /**
465          * Setter for Y coordinate
466          *
467          * @param       $y      Y coordinate
468          * @return      void
469          */
470         private function setImagePropertyY ($y) {
471                 // Call the image class
472                 $this->getImageInstance()->setY($y);
473         }
474
475         /**
476          * Getter for image cache file instance
477          *
478          * @return      $fileInstance   An instance of a SplFileInfo class
479          */
480         public function getImageCacheFile () {
481                 // Get the instance ready
482                 $fileInstance = new SplFileInfo(sprintf('%s%s%s/%s.%s',
483                         FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('root_base_path'),
484                         $this->getGenericBasePath(),
485                         'images/_cache',
486                         md5(
487                                 $this->getImageInstance()->getImageName() . ':' . $this->__toString() . ':' . $this->getImageInstance()->__toString()
488                         ),
489                         $this->getImageInstance()->getImageType()
490                 ));
491
492                 // Return it
493                 return $fileInstance;
494         }
495
496         /**
497          * Outputs the image to the world
498          *
499          * @param       $responseInstance       An instance of a Responseable class
500          * @return      void
501          */
502         public function transferToResponse (Responseable $responseInstance) {
503                 // Set the image instance
504                 $responseInstance->setImageInstance($this->getImageInstance());
505         }
506
507         /**
508          * Load a specified image template into the engine
509          *
510          * @param       $template       The image template we shall load which is
511          *                                              located in 'image' by default
512          * @return      void
513          */
514         public function loadImageTemplate ($template) {
515                 // Set template type
516                 $this->setTemplateType(FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('image_template_type'));
517
518                 // Load the special template
519                 $this->loadTemplate($template);
520         }
521
522 }