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