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