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