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