More exceptions added, init of template engine moved to base class, entryPoint()...
[shipsimu.git] / inc / classes / main / class_BaseFrameworkSystem.php
1 <?php
2 /**
3  * The simulator system class is the super class of all other classes. This
4  * class handles saving of games etc.
5  *
6  * @author              Roland Haeder <webmaster@ship-simu.org>
7  * @version             0.3.0
8  * @copyright   Copyright(c) 2007, 2008 Roland Haeder, this is free software
9  * @license             GNU GPL 3.0 or any newer version
10  * @link                http://www.mxchange.org
11  *
12  * This program is free software: you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation, either version 3 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24  */
25 class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
26         /**
27          * The instance to the debug output handler (should be DebugConsoleOutput or DebugWebOutput)
28          *
29          * @see         DebugConsoleOutput
30          * @see         DebugWebOutput
31          */
32         private static $debug       = null;
33
34         /**
35          * The instance to the web output handler (should be WebOutput)
36          *
37          * @see         WebOutput
38          */
39         private static $webOutput   = null;
40
41         /**
42          * The instance to the compression layer which should be CompressorChannel
43          */
44         private static $compressor  = null;
45
46         /**
47          * The configuration instance which shall be FrameworkConfiguration
48          */
49         private static $cfgInstance = null;
50
51         /**
52          * The instance to the database layer which should be DatabaseConnection
53          */
54         private $dbInstance  = null;
55
56         /**
57          * The real class name
58          */
59         private $realClass      = "FrameworkSystem";
60
61         /**
62          * A human-readable description for this simulator part
63          */
64         private $partDescr      = "Namenlose Framework-Einheit";
65
66         /**
67          * The unique ID string for identifying all type of classes
68          */
69         private $uniqueID = "";
70
71         /**
72          * Thousands seperator
73          */
74         private $thousands = "."; // German
75
76         /**
77          * Decimal seperator
78          */
79         private $decimals  = ","; // German
80
81         /**
82          * The language instance for the template loader
83          */
84         private $langInstance = null;
85
86         /**
87          * The file I/O instance for the template loader
88          */
89         private $fileIOInstance = null;
90
91         /***********************
92          * Exception codes.... *
93          ***********************/
94
95         const EXCEPTION_IS_NULL_POINTER              = 0x001;
96         const EXCEPTION_IS_NO_OBJECT                 = 0x002;
97         const EXCEPTION_IS_NO_ARRAY                  = 0x003;
98         const EXCEPTION_MISSING_METHOD               = 0x004;
99         const EXCEPTION_CLASSES_NOT_MATCHING         = 0x005;
100         const EXCEPTION_INDEX_OUT_OF_BOUNDS          = 0x006;
101         const EXCEPTION_DIMENSION_ARRAY_INVALID      = 0x007;
102         const EXCEPTION_ITEM_NOT_TRADEABLE           = 0x008;
103         const EXCEPTION_ITEM_NOT_IN_PRICE_LIST       = 0x009;
104         const EXCEPTION_GENDER_IS_WRONG              = 0x00a;
105         const EXCEPTION_BIRTH_DATE_IS_INVALID        = 0x00b;
106         const EXCEPTION_EMPTY_STRUCTURES_ARRAY       = 0x00c;
107         const EXCEPTION_HAS_ALREADY_PERSONELL_LIST   = 0x00d;
108         const EXCEPTION_NOT_ENOUGTH_UNEMPLOYEES      = 0x00e;
109         const EXCEPTION_TOTAL_PRICE_NOT_CALCULATED   = 0x00f;
110         const EXCEPTION_HARBOR_HAS_NO_SHIPYARDS      = 0x010;
111         const EXCEPTION_CONTRACT_PARTNER_INVALID     = 0x011;
112         const EXCEPTION_CONTRACT_PARTNER_MISMATCH    = 0x012;
113         const EXCEPTION_CONTRACT_ALREADY_SIGNED      = 0x013;
114         const EXCEPTION_UNEXPECTED_EMPTY_STRING      = 0x014;
115         const EXCEPTION_PATH_NOT_FOUND               = 0x015;
116         const EXCEPTION_INVALID_PATH_NAME            = 0x016;
117         const EXCEPTION_READ_PROTECED_PATH           = 0x017;
118         const EXCEPTION_WRITE_PROTECED_PATH          = 0x018;
119         const EXCEPTION_DIR_POINTER_INVALID          = 0x019;
120         const EXCEPTION_FILE_POINTER_INVALID         = 0x01a;
121         const EXCEPTION_INVALID_DIRECTORY_POINTER    = 0x01b;
122         const EXCEPTION_UNEXPECTED_OBJECT            = 0x01c;
123         const EXCEPTION_LIMIT_ELEMENT_IS_UNSUPPORTED = 0x01d;
124         const EXCEPTION_GETTER_IS_MISSING            = 0x01e;
125         const EXCEPTION_ARRAY_EXPECTED               = 0x01f;
126         const EXCEPTION_ARRAY_HAS_INVALID_COUNT      = 0x020;
127         const EXCEPTION_ID_IS_INVALID_FORMAT         = 0x021;
128         const EXCEPTION_MD5_CHECKSUMS_MISMATCH       = 0x022;
129         const EXCEPTION_UNEXPECTED_STRING_SIZE       = 0x023;
130         const EXCEPTION_SIMULATOR_ID_INVALID         = 0x024;
131         const EXCEPTION_MISMATCHING_COMPRESSORS      = 0x025;
132         const EXCEPTION_CONTAINER_ITEM_IS_NULL       = 0x026;
133         const EXCEPTION_ITEM_IS_NO_ARRAY             = 0x027;
134         const EXCEPTION_CONTAINER_MAYBE_DAMAGED      = 0x028;
135         const EXCEPTION_INVALID_STRING               = 0x029;
136         const EXCEPTION_VARIABLE_NOT_SET             = 0x02a;
137         const EXCEPTION_ATTRIBUTES_ARE_MISSING       = 0x02b;
138         const EXCEPTION_ARRAY_ELEMENTS_MISSING       = 0x02c;
139         const EXCEPTION_TEMPLATE_ENGINE_UNSUPPORTED  = 0x02d;
140         const EXCEPTION_MISSING_LANGUAGE_HANDLER     = 0x02e;
141         const EXCEPTION_MISSING_FILE_IO_HANDLER      = 0x02f;
142
143         /**
144          * In the super constructor these system classes shall be ignored or else
145          * we would get an endless calling loop.
146          *
147          *--------------------------------------------------------------------*
148          * ATTENTION: IF YOU REMOVE ONE OF THEM YOU WILL SHOOT YOUR SERVER!!! *
149          *--------------------------------------------------------------------*
150          */
151         private $systemClasses = array(
152                 "DebugMiddleware",                      // Debug middleware output sub-system
153                 "DebugWebOutput",                       // Debug web output sub-system
154                 "DebugConsoleOutput",           // Debug console output sub-system
155                 "DebugErrorLogOutput",          // Debug error_log() output sub-system
156                 "CompressorChannel",            // Compressor sub-system
157                 "FrameworkDirectoryPointer",    // Directory handler sub-system
158                 "NullCompressor",                       // Null compressor
159                 "Bzip2Compressor",                      // BZIP2 compressor
160                 "GzipCompressor",                       // GZIP compressor
161                 "WebOutput",                            // Web output sub-system
162         );
163
164         /**
165          * Private super constructor
166          *
167          * @return      void
168          */
169         private function __construct ($class) {
170                 // Set real class
171                 $this->setRealClass($class);
172         }
173
174         /**
175          * Destructor reached...
176          *
177          * @return      void
178          */
179         public function __destruct() {
180                 // Is this object already destroyed?
181                 if ($this->__toString() != "DestructedObject") {
182                         // Debug message
183                         if ((defined('DEBUG_DESTRUCTOR')) && (is_object($this->getDebugInstance()))) {
184                                 $this->getDebugInstance()->output(sprintf("[%s:] Das Objekt <strong>%s</strong> wird zerst&ouml;rt.<br />\n",
185                                         __CLASS__, $this->__toString()
186                                 ));
187                         }
188
189                         // Destroy all informations about this class but keep some text about it alive
190                         $this->setPartDescr(sprintf("Entferntes Objekt <em>%s</em>", $this->__toString()));
191                         $this->setRealClass("DestructedObject");
192                         $this->resetUniqueID();
193                 } elseif ((defined('DEBUG_DESTRUCTOR')) && (is_object($this->getDebugInstance()))) {
194                         // Already destructed object
195                         $this->getDebugInstance()->output(sprintf("[%s:] Das Objekt <strong>%s</strong> wurde bereits zerst&ouml;rt.<br />\n",
196                                 __CLASS__, $this->__toString()
197                         ));
198                 }
199         }
200
201         /**
202          * The call method where all non-implemented methods end up
203          *
204          * @return      void
205          */
206         public final function __call ($methodName, $args) {
207                 // Implode all given arguments
208                 $argsString = implode("|", $args);
209                 if (empty($argsString)) $argsString = "NULL";
210
211                 $this->getDebugInstance()->output(sprintf("[%s::%s] Stub! Args: %s",
212                         $this->__toString(),
213                         $methodName,
214                         $argsString
215                 ));
216
217                 // Return nothing
218                 return null;
219         }
220
221         /**
222          * Public constructor (for initializing things, etc.)
223          *
224          * @return      void
225          */
226         public function constructor ($class) {
227                 // Call constructor
228                 $this->__construct($class);
229
230                 // Get the current (singleton) configuration instance
231                 $this->setConfigInstance(FrameworkConfiguration::createFrameworkConfiguration());
232
233                 // Is the class weather debug nor compressor channel?
234                 if (!in_array($class, $this->systemClasses)) {
235                         // Initialize debug instance
236                         if (is_null($this->getDebugInstance())) {
237                                 // Set the debug output system if it is not debug class ;)
238                                 $this->setDebugInstance(DebugMiddleware::createDebugMiddleware($this->getConfigInstance()->readConfig("debug_engine")));
239                         }
240
241                         // Initialize web instance
242                         if (is_null($this->getWebOutputInstance())) {
243                                 // Generate the eval() command
244                                 $eval = sprintf("\$this->setWebOutputInstance(%s::create%s(\"%s\"));",
245                                         $this->getConfigInstance()->readConfig("web_engine"),
246                                         $this->getConfigInstance()->readConfig("web_engine"),
247                                         $this->getConfigInstance()->readConfig("web_content_type")
248                                 );
249
250                                 // Debug message
251                                 if ((defined('DEBUG_EVAL')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:] Konstruierte PHP-Anweisung: <pre><em>%s</em></pre><br />\n",
252                                         $this->__toString(),
253                                         htmlentities($eval)
254                                 ));
255
256                                 // Run the command
257                                 eval($eval);
258                         }
259
260                         // Initialize compressor channel
261                         if (is_null($this->getCompressorChannel())) {
262                                 // Set the compressor channel
263                                 $this->setCompressorChannel(CompressorChannel::createCompressorChannel(sprintf("%s%s",
264                                         PATH,
265                                         $this->getConfigInstance()->readConfig("compressor_base_path")
266                                 )));
267                         }
268
269                         // Initialize database middleware
270                         if (is_null($this->getDatabaseInstance())) {
271                                 // Get the middleware instance
272                                 $db = DatabaseConnection::getInstance();
273                                 if (is_object($db)) {
274                                         // Set the database middleware
275                                         $this->setDatabaseInstance($db);
276                                 }
277                         }
278
279                         // Debug output
280                         if ((defined('DEBUG_SYSTEM')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] Alle Sub-Systeme sind initialisiert.<br />\n",
281                                 $this->__toString()
282                         ));
283                 }
284         }
285
286         /**
287          * Setter for language instance
288          *
289          * @param               $configInstance The configuration instance which shall
290          *                                                      be FrameworkConfiguration
291          * @return      void
292          */
293         public final function setConfigInstance (FrameworkConfiguration $configInstance) {
294                 $this->cfgInstance = $configInstance;
295                 if ((defined('DEBUG_SYSTEM')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] Konfigurations-Handler auf <strong>%s</strong> gesetzt.<br />\n",
296                         $this->__toString(),
297                         $configInstance->__toString()
298                 ));
299         }
300
301         /**
302          * Getter for configuration instance
303          *
304          * @return      $cfhInstance - Configuration instance
305          */
306         public final function getConfigInstance () {
307                 if ((defined('DEBUG_SYSTEM')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] Konfigurations-Handler <strong>%s</strong> angefordert.<br />\n",
308                         $this->__toString(),
309                         $this->cfgInstance->__toString()
310                 ));
311                 return $this->cfgInstance;
312         }
313
314         /**
315          * Setter for debug instance
316          *
317          * @param               $debugInstance  The instance for debug output class
318          * @return      void
319          */
320         public final function setDebugInstance (DebugMiddleware $debugInstance) {
321                 self::$debug = $debugInstance;
322                 if ((defined('DEBUG_SYSTEM')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] Debug-Handler auf <strong>%s</strong> gesetzt.<br />\n",
323                         $this->__toString(),
324                         $this->getDebugInstance()->__toString()
325                 ));
326         }
327
328         /**
329          * Getter for debug instance
330          *
331          * @return      $debug - Instance to class DebugConsoleOutput or DebugWebOutput
332          */
333         public final function getDebugInstance () {
334                 return self::$debug;
335         }
336
337         /**
338          * Setter for web output instance
339          *
340          * @param               $webInstance    The instance for web output class
341          * @return      void
342          */
343         public final function setWebOutputInstance (OutputStreamer $webInstance) {
344                 self::$webOutput = $webInstance;
345                 if ((defined('DEBUG_SYSTEM')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] Web-Handler auf <strong>%s</strong> gesetzt.<br />\n",
346                         $this->__toString(),
347                         $this->getWebOutputInstance()->__toString()
348                 ));
349         }
350
351         /**
352          * Getter for web output instance
353          *
354          * @return      $webOutput - Instance to class WebOutput
355          */
356         public final function getWebOutputInstance () {
357                 return self::$webOutput;
358         }
359
360         /**
361          * Static setter for database instance
362          *
363          * @param               $dbInstance     The instance for the database connection
364          *                                      (forced DatabaseConnection)
365          * @return      void
366          */
367         public final function setDatabaseInstance (DatabaseConnection $dbInstance) {
368                 if ((defined('DEBUG_SYSTEM')) && (is_object($dbInstance->getDebugInstance()))) $dbInstance->getDebugInstance()->output(sprintf("[%s:] Datenbankschicht gesetzt.<br />\n",
369                         $dbInstance->__toString()
370                 ));
371                 $this->dbInstance = $dbInstance;
372         }
373
374         /**
375          * Getter for $realClass
376          *
377          * @return      $realClass The name of the real class (not BaseFrameworkSystem)
378          */
379         public final function __toString () {
380                 if ((defined('DEBUG_SYSTEM')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] __toString() erreicht.<br />\n",
381                         $this->realClass
382                 ));
383                 return $this->realClass;
384         }
385
386         /**
387          * Setter for the real class name
388          *
389          * @param               $realClass      Class name (string)
390          * @return      void
391          */
392         public final function setRealClass ($realClass) {
393                 // Cast to string
394                 $realClass = (string) $realClass;
395
396                 // Set real class
397                 $this->realClass = $realClass;
398         }
399
400         /**
401          * Generate unique ID from a lot entropy
402          *
403          * @return      void
404          */
405         public final function createUniqueID () {
406                 if ((defined('DEBUG_SYSTEM')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] createUniqueID aufgerufen.<br />\n",
407                         $this->__toString()
408                 ));
409
410                 // Existiert noch keine?
411                 if (empty($this->uniqueID)) {
412                         if ((defined('DEBUG_SYSTEM')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] createUniqueID erzeugt neue Unique-ID.<br />\n",
413                                 $this->__toString()
414                         ));
415
416                         // Correct missing class name
417                         $corrected = false;
418                         if ($this->__toString() == "") {
419                                 $this->setRealClass(__CLASS__);
420                                 $corrected = true;
421                         }
422
423                         // Neue ID erstellen
424                         $tempID = false;
425                         while (true) {
426                                 // Generate a unique ID number
427                                 $tempID = $this->generateIdNumber();
428                                 $isUsed = false;
429
430                                 // Try to figure out if the ID number is not yet used
431                                 try {
432                                         if (is_object($this->getDatabaseInstance())) {
433                                                 $isUsed = $this->getDatabaseInstance()->isUniqueIdUsed($tempID, true);
434                                         }
435                                 } catch (FrameworkException $e) {
436                                         // Catches all and ignores all ;-)
437                                 }
438
439                                 if (
440                                         (
441                                                 $tempID !== false
442                                         ) && (
443                                                 (
444                                                         $this->getDatabaseInstance() === null
445                                                 ) || (
446                                                         (
447                                                                 is_object($this->getDatabaseInstance())
448                                                         ) && (
449                                                                 !$isUsed
450                                                         )
451                                                 )
452                                         )
453                                 ) {
454                                         // Abort the loop
455                                         break;
456                                 }
457                         }
458
459                         // Debug message
460                         if ((defined('DEBUG_SYSTEM')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] uniqueID ist auf <strong>%s</strong> gesetzt.<br />\n",
461                                 $this->__toString(),
462                                 $tempID
463                         ));
464
465                         // Apply the new ID
466                         $this->setUniqueID($tempID);
467
468                         // Revert maybe corrected class name
469                         if ($corrected) {
470                                 $this->setRealClass("");
471                         }
472
473                         // Remove system classes if we are in a system class
474                         if ((isset($this->systemClasses)) && (in_array($this->__toString(), $this->systemClasses))) {
475                                 // This may save some RAM...
476                                 $this->removeSystemArray();
477                         }
478                 }
479         }
480
481         /**
482          * Generates a new ID number for classes based from the class' real name,
483          * the description and some random data
484          *
485          * @return      $tempID The new (temporary) ID number
486          */
487         private final function generateIdNumber () {
488                 return sprintf("%s@%s",
489                         $this->__toString(),
490                         md5(sprintf("%s:%s:%s:%s:%s:%s",
491                                 $this->__toString(),
492                                 $this->getPartDescr(),
493                                 time(),
494                                 getenv('REMOTE_ADDR'),
495                                 getenv('SERVER_ADDR'),
496                                 mt_rand()
497                         ))
498                 );
499         }
500
501         /**
502          * Setter for unique ID
503          *
504          * @param               $uniqueID               The newly generated unique ID number
505          * @return      void
506          */
507         private final function setUniqueID ($uniqueID) {
508                 // Cast to string
509                 $uniqueID = (string) $uniqueID;
510
511                 // Debug message
512                 if ((defined('DEBUG_SYSTEM')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] Unique-ID gesetzt auf <u>%s</u>.<br />\n",
513                         $this->__toString(),
514                         $uniqueID
515                 ));
516
517                 // Set the ID number
518                 $this->uniqueID = $uniqueID;
519         }
520
521         /**
522          * Getter for unique ID
523          *
524          * @return      $uniqueID               The unique ID of this class
525          */
526         public final function getUniqueID () {
527                 if ((defined('DEBUG_SYSTEM')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] Unique-ID angefordert.<br />\n",
528                         $this->__toString()
529                 ));
530                 return $this->uniqueID;
531         }
532
533         /**
534          * Resets or recreates the unique ID number
535          *
536          * @return      void
537          */
538         public final function resetUniqueID() {
539                 // Sweet and simple... ;-)
540                 $newUniqueID = $this->generateIdNumber();
541                 if ((defined('DEBUG_SYSTEM')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] Unique-ID zur&uuml;ckgesetzt auf <u>%s</u>.<br />\n",
542                         $this->__toString(),
543                         $newUniqueID
544                 ));
545                 $this->setUniqueID($newUniqueID);
546         }
547
548         /**
549          * Getter for simulator description
550          *
551          * @return      $partDescr      The description of this simulation part
552          */
553         public final function getPartDescr () {
554                 if ((defined('DEBUG_SYSTEM')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] getPartDescr erreicht.<br />\n",
555                         $this->__toString()
556                 ));
557                 if (isset($this->partDescr)) {
558                         return $this->partDescr;
559                 } else {
560                         return null;
561                 }
562         }
563
564         /**
565          * Setter for simulation part description
566          *
567          * @param               $partDescr      The description as string for this simulation part
568          * @return      void
569          */
570         public final function setPartDescr ($partDescr) {
571                 $this->partDescr = (String) $partDescr;
572                 if ((defined('DEBUG_SYSTEM')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] Teilbeschreibung wird auf <strong>%s</strong> gesetzt.<br />\n",
573                         $this->__toString(),
574                         $this->partDescr
575                 ));
576         }
577
578         /**
579          * Validate if given object is the same as current
580          *
581          * @param               $object An object instance for comparison with this class
582          * @return      boolean The result of comparing both's unique ID
583          */
584         public final function equals ($object) {
585                 return ($this->getUniqueID() == $object->getUniqueID());
586         }
587
588         /**
589          * Compare if both simulation part description and class name matches
590          * (shall be enougth)
591          *
592          * @param               $itemInstance   An object instance to an other class
593          * @return      boolean         The result of comparing class name simulation part description
594          */
595         public function itemMatches ($itemInstance) {
596                 return (
597                         (
598                                 $this->__toString()   == $itemInstance->__toString()
599                         ) && (
600                                 $this->getPartDescr() == $itemInstance->getPartDescr()
601                         )
602                 );
603         }
604
605         /**
606          * Compare class name of this and given class name
607          *
608          * @param               $class  The class name as string from the other class
609          * @return      boolean The result of comparing both class names
610          */
611         public final function isClass ($class) {
612                 if ((defined('DEBUG_SYSTEM')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] <strong>%s</strong>=<strong>%s</strong>?<br />\n",
613                         $this->__toString(),
614                         $this->__toString(),
615                         $class
616                 ));
617                 return ($this->__toString() == $class);
618         }
619
620         /**
621          * Stub method (only real cabins shall override it)
622          *
623          * @return      boolean false = is no cabin, true = is a cabin
624          */
625         public function isCabin () {
626                 return false;
627         }
628
629         /**
630          * Stub method for tradeable objects
631          *
632          * @return      boolean false = is not tradeable by the Merchant class,
633          *                                      true  = is a tradeable object
634          */
635         public function isTradeable () {
636                 return false;
637         }
638
639         /**
640          * Formats computer generated price values into human-understandable formats
641          * with thousand and decimal seperators.
642          *
643          * @param               $value  The in computer format value for a price
644          * @param               $currency       The currency symbol (use HTML-valid characters!)
645          * @param               $decNum Number of decimals after commata
646          * @return      $price  The for the current language formated price string
647          * @throws      MissingDecimalsThousandsSeperatorException      If decimals or
648          *                                                                                              thousands seperator
649          *                                                                                              is missing
650          */
651         public function formatCurrency ($value, $currency = "&euro;", $decNum = 2) {
652                 // Are all required attriutes set?
653                 if ((!isset($this->decimals)) || (!isset($this->thousands))) {
654                         // Throw an exception
655                         throw new MissingDecimalsThousandsSeperatorException($this, self::EXCEPTION_ATTRIBUTES_ARE_MISSING);
656                 }
657
658                 // Cast the number
659                 $value = (float) $value;
660                 if (defined('DEBUG_CORE') && is_object($this->getDebugInstance())) $this->getDebugInstance()->output(sprintf("[%s:] <strong>%d</strong> wird umformatiert.<br />\n",
661                         $this->__toString(),
662                         $value
663                 ));
664
665                 // Reformat the US number
666                 $price = sprintf("%s %s",
667                         number_format($value, $decNum, $this->decimals, $this->thousands),
668                         $currency
669                 );
670
671                 // Return as string...
672                 return $price;
673         }
674
675         /**
676          * Removes number formating characters
677          *
678          * @return      void
679          */
680         public final function removeNumberFormaters () {
681                 if (defined('DEBUG_CORE') && is_object($this->getDebugInstance())) $this->getDebugInstance()->output(sprintf("[%s:] Zahlenumformatierungszeichen werden entfernt.<br />\n",
682                         $this->__toString()
683                 ));
684                 unset($this->thousands);
685                 unset($this->decimals);
686         }
687
688         /**
689          * Getter for database layer
690          *
691          * @return      $dbInstance     The database layer instance
692          */
693         public final function getDatabaseInstance () {
694                 if (defined('DEBUG_CORE') && is_object($this->getDebugInstance())) $this->getDebugInstance()->output(sprintf("[%s:] Datenbank-Instanz <u>%s</u> angefordert.<br />\n",
695                         $this->__toString(),
696                         $this->dbInstance
697                 ));
698                 return $this->dbInstance;
699         }
700
701         /**
702          * Setter for compressor channel
703          *
704          * @param               $compressorChannel      An instance of CompressorChannel
705          * @return      void
706          */
707         public final function setCompressorChannel (CompressorChannel $compressorChannel) {
708                 self::$compressor = $compressorChannel;
709         }
710
711         /**
712          * Getter for compressor channel
713          *
714          * @return      $compressor     The compressor channel
715          */
716         public final function getCompressorChannel () {
717                 return self::$compressor;
718         }
719
720         /**
721          * Remove the $systemClasses array from memory
722          *
723          * @return      void
724          */
725         public final function removeSystemArray () {
726                 unset($this->systemClasses);
727         }
728
729         /**
730          * Create a file name and path name from the object's unique ID number.
731          * The left part of the ID shall always be a valid class name and the
732          * right part an ID number.
733          *
734          * @return      $pfn            The file name with a prepended path name
735          * @throws      NoArrayCreatedException If explode() fails to create an array
736          * @throws      InvalidArrayCountException      If the array contains less or
737          *                                                                      more than two elements
738          */
739         public final function getPathFileNameFromObject () {
740                 // Get the main object's unique ID. We use this as a path/filename combination
741                 $pathFile = $this->getUniqueID();
742
743                 // Split it up in path and file name
744                 $pathFile = explode("@", $pathFile);
745
746                 // Are there two elements? Index 0 is the path, 1 the file name + global extension
747                 if (!is_array($pathFile)) {
748                         // No array found
749                         throw new NoArrayCreatedException(array($this, "pathFile"), self::EXCEPTION_ARRAY_EXPECTED);
750                 } elseif (count($pathFile) != 2) {
751                         // Invalid ID returned!
752                         throw new InvalidArrayCountException(array($this, "pathFile", count($pathFile), 2), self::EXCEPTION_ARRAY_HAS_INVALID_COUNT);
753                 }
754
755                 // Auto-append missing trailing slash
756                 $pathFile[0] = $this->addMissingTrailingSlash($pathFile[0]);
757
758                 // Create the file name and return it
759                 $pfn = ($pathFile[0] . $pathFile[1]);
760                 return $pfn;
761         }
762
763         /**
764          * Appends a trailing slash to a string
765          *
766          * @param       $str            A string (maybe) without trailing slash
767          * @return      $str            A string with an auto-appended trailing slash
768          */
769         public final function addMissingTrailingSlash ($str) {
770                 // Is there a trailing slash?
771                 if (substr($str, -1, 1) != "/") $str .= "/";
772                 return $str;
773         }
774
775         /**
776          * Private getter for language instance
777          *
778          * @return      $langInstance   An instance to the language sub-system
779          */
780         protected final function getLanguageInstance () {
781                 return $this->langInstance;
782         }
783
784         /**
785          * Setter for language instance
786          *
787          * @param       $langInstance   An instance to the language sub-system
788          * @return      void
789          * @see         LanguageSystem
790          */
791         public final function setLanguageInstance (ManageableLanguage $langInstance) {
792                 $this->langInstance = $langInstance;
793         }
794
795         /**
796          * Private getter for file IO instance
797          *
798          * @return      $fileIOInstance An instance to the file I/O sub-system
799          */
800         protected final function getFileIOInstance () {
801                 return $this->fileIOInstance;
802         }
803
804         /**
805          * Setter for file I/O instance
806          *
807          * @param       $fileIOInstance An instance to the file I/O sub-system
808          * @return      void
809          */
810         public final function setFileIOInstance (FileIOHandler $fileIOInstance) {
811                 $this->fileIOInstance = $fileIOInstance;
812         }
813
814         /**
815          * Prepare the template engine (TemplateEngine by default) for a given
816          * application helper instance (ApplicationHelper by default).
817          *
818          * @param               $appInstance                    An application helper instance
819          * @return              $tplEngine                              The template engine instance
820          * @throws              NullPointerException    If the template engine could not
821          *                                                                              be initialized
822          * @throws              UnsupportedTemplateEngineException      If $tplEngine is an
823          *                                                                              unsupported template engine
824          * @throws              MissingLanguageHandlerException If the language sub-system
825          *                                                                              is not yet initialized
826          */
827         protected function prepareTemplateEngine (BaseFrameworkSystem $appInstance) {
828                 // Generate FQFN for all application templates
829                 $fqfn = sprintf("%s%s/%s/%s",
830                         PATH,
831                         $this->getConfigInstance()->readConfig("application_path"),
832                         strtolower($appInstance->getAppShortName()),
833                         $this->getConfigInstance()->readConfig("tpl_base_path")
834                 );
835
836                 // Are both instances set?
837                 if ($appInstance->getLanguageInstance() === null) {
838                         // Invalid language instance
839                         throw new MissingLanguageHandlerException($appInstance, self::EXCEPTION_MISSING_LANGUAGE_HANDLER);
840                 } elseif ($appInstance->getFileIOInstance() === null) {
841                         // Invalid language instance
842                         throw new MissingFileIoHandlerException($appInstance, self::EXCEPTION_MISSING_FILE_IO_HANDLER);
843                 }
844
845                 // Initialize the template engine
846                 $tplEngine = null;
847                 $eval = sprintf("\$tplEngine = %s::create%s(
848         \"%s\",
849         \$appInstance->getLanguageInstance(),
850         \$appInstance->getFileIOInstance()
851 );",
852                         $this->getConfigInstance()->readConfig("tpl_engine"),
853                         $this->getConfigInstance()->readConfig("tpl_engine"),
854                         $fqfn
855                 );
856
857                 // Debug message
858                 if ((!is_null($this->getDebugInstance())) && (defined('DEBUG_EVAL'))) {
859                         $this->getDebugInstance()->output(sprintf("[%s:] Konstruierte PHP-Anweisung: <pre><em>%s</em></pre><br />\n",
860                                 $this->__toString(),
861                                 htmlentities($eval)
862                         ));
863                 }
864
865                 // Run the command
866                 eval($eval);
867
868                 // Is it a valid instance?
869                 if (is_null($tplEngine)) {
870                         // No class returned
871                         throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
872                 } elseif (!$tplEngine instanceof CompileableTemplate) {
873                         // Not an object! ;-(
874                         throw new UnsupportedTemplateEngineException($tplEngine, self::EXCEPTION_TEMPLATE_ENGINE_UNSUPPORTED);
875                 }
876
877                 // Return the prepared instance
878                 return $tplEngine;
879         }
880 }
881
882 // [EOF]
883 ?>