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