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