]> git.mxchange.org Git - shipsimu.git/blob - inc/classes/main/class_BaseFrameworkSystem.php
Exceptions now with not so much underlines
[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.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  * @link                http://www.ship-simu.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          * Instance to an application helper class
28          */
29         private static $applicationInstance = null;
30
31         /**
32          * The language instance for the template loader
33          */
34         private static $langInstance = null;
35
36         /**
37          * Instance of a request class
38          */
39         private $requestInstance = null;
40
41         /**
42          * Instance of a response class
43          */
44         private $responseInstance = null;
45
46         /**
47          * Search criteria instance
48          */
49         private $searchInstance = null;
50
51         /**
52          * The file I/O instance for the template loader
53          */
54         private $fileIoInstance = null;
55
56         /**
57          * Resolver instance
58          */
59         private $resolverInstance = null;
60
61         /**
62          * The real class name
63          */
64         private $realClass      = "FrameworkSystem";
65
66         /**
67          * A human-readable description for this simulator part
68          */
69         private $objectDescription      = "Namenlose Framework-Einheit";
70
71         /**
72          * The unique ID string for identifying all type of classes
73          */
74         private $uniqueID = "";
75
76         /**
77          * Thousands seperator
78          */
79         private $thousands = "."; // German
80
81         /**
82          * Decimal seperator
83          */
84         private $decimals  = ","; // German
85
86         /***********************
87          * Exception codes.... *
88          ***********************/
89
90         const EXCEPTION_IS_NULL_POINTER              = 0x001;
91         const EXCEPTION_IS_NO_OBJECT                 = 0x002;
92         const EXCEPTION_IS_NO_ARRAY                  = 0x003;
93         const EXCEPTION_MISSING_METHOD               = 0x004;
94         const EXCEPTION_CLASSES_NOT_MATCHING         = 0x005;
95         const EXCEPTION_INDEX_OUT_OF_BOUNDS          = 0x006;
96         const EXCEPTION_DIMENSION_ARRAY_INVALID      = 0x007;
97         const EXCEPTION_ITEM_NOT_TRADEABLE           = 0x008;
98         const EXCEPTION_ITEM_NOT_IN_PRICE_LIST       = 0x009;
99         const EXCEPTION_GENDER_IS_WRONG              = 0x00a;
100         const EXCEPTION_BIRTH_DATE_IS_INVALID        = 0x00b;
101         const EXCEPTION_EMPTY_STRUCTURES_ARRAY       = 0x00c;
102         const EXCEPTION_HAS_ALREADY_PERSONELL_LIST   = 0x00d;
103         const EXCEPTION_NOT_ENOUGTH_UNEMPLOYEES      = 0x00e;
104         const EXCEPTION_TOTAL_PRICE_NOT_CALCULATED   = 0x00f;
105         const EXCEPTION_HARBOR_HAS_NO_SHIPYARDS      = 0x010;
106         const EXCEPTION_CONTRACT_PARTNER_INVALID     = 0x011;
107         const EXCEPTION_CONTRACT_PARTNER_MISMATCH    = 0x012;
108         const EXCEPTION_CONTRACT_ALREADY_SIGNED      = 0x013;
109         const EXCEPTION_UNEXPECTED_EMPTY_STRING      = 0x014;
110         const EXCEPTION_PATH_NOT_FOUND               = 0x015;
111         const EXCEPTION_INVALID_PATH_NAME            = 0x016;
112         const EXCEPTION_READ_PROTECED_PATH           = 0x017;
113         const EXCEPTION_WRITE_PROTECED_PATH          = 0x018;
114         const EXCEPTION_DIR_POINTER_INVALID          = 0x019;
115         const EXCEPTION_FILE_POINTER_INVALID         = 0x01a;
116         const EXCEPTION_INVALID_DIRECTORY_POINTER    = 0x01b;
117         const EXCEPTION_UNEXPECTED_OBJECT            = 0x01c;
118         const EXCEPTION_LIMIT_ELEMENT_IS_UNSUPPORTED = 0x01d;
119         const EXCEPTION_GETTER_IS_MISSING            = 0x01e;
120         const EXCEPTION_ARRAY_EXPECTED               = 0x01f;
121         const EXCEPTION_ARRAY_HAS_INVALID_COUNT      = 0x020;
122         const EXCEPTION_ID_IS_INVALID_FORMAT         = 0x021;
123         const EXCEPTION_MD5_CHECKSUMS_MISMATCH       = 0x022;
124         const EXCEPTION_UNEXPECTED_STRING_SIZE       = 0x023;
125         const EXCEPTION_SIMULATOR_ID_INVALID         = 0x024;
126         const EXCEPTION_MISMATCHING_COMPRESSORS      = 0x025;
127         const EXCEPTION_CONTAINER_ITEM_IS_NULL       = 0x026;
128         const EXCEPTION_ITEM_IS_NO_ARRAY             = 0x027;
129         const EXCEPTION_CONTAINER_MAYBE_DAMAGED      = 0x028;
130         const EXCEPTION_INVALID_STRING               = 0x029;
131         const EXCEPTION_VARIABLE_NOT_SET             = 0x02a;
132         const EXCEPTION_ATTRIBUTES_ARE_MISSING       = 0x02b;
133         const EXCEPTION_ARRAY_ELEMENTS_MISSING       = 0x02c;
134         const EXCEPTION_TEMPLATE_ENGINE_UNSUPPORTED  = 0x02d;
135         const EXCEPTION_MISSING_LANGUAGE_HANDLER     = 0x02e;
136         const EXCEPTION_MISSING_FILE_IO_HANDLER      = 0x02f;
137         const EXCEPTION_MISSING_ELEMENT              = 0x030;
138         const EXCEPTION_HEADERS_ALREADY_SENT         = 0x031;
139         const EXCEPTION_DEFAUL_CONTROLLER_GONE       = 0x032;
140         const EXCEPTION_CLASS_NOT_FOUND              = 0x033;
141         const EXCEPTION_REQUIRED_INTERFACE_MISSING   = 0x034;
142         const EXCEPTION_FATAL_ERROR                  = 0x035;
143         const EXCEPTION_FILE_NOT_FOUND               = 0x036;
144
145         /**
146          * In the super constructor these system classes shall be ignored or else
147          * we would get an endless calling loop.
148          *
149          *--------------------------------------------------------------------*
150          * ATTENTION: IF YOU REMOVE ONE OF THEM YOU WILL SHOOT YOUR SERVER!!! *
151          *--------------------------------------------------------------------*
152          */
153         private $systemClasses = array(
154                 "DebugMiddleware",                              // Debug middleware output sub-system
155                 "Registry",                                             // Object registry
156                 "ObjectFactory",                                // Object factory
157                 "DebugWebOutput",                               // Debug web output sub-system
158                 "WebOutput",                                    // Web output sub-system
159                 "CompressorChannel",                    // Compressor sub-system
160                 "DebugConsoleOutput",                   // Debug console output sub-system
161                 "DebugErrorLogOutput",                  // Debug error_log() output sub-system
162                 "FrameworkDirectoryPointer",    // Directory handler sub-system
163                 "NullCompressor",                               // Null compressor
164                 "Bzip2Compressor",                              // BZIP2 compressor
165                 "GzipCompressor",                               // GZIP compressor
166         );
167
168         /* No longer used:
169         */
170
171         /**
172          * Private super constructor
173          *
174          * @return      void
175          */
176         protected function __construct ($class) {
177                 // Set real class
178                 $this->setRealClass($class);
179
180                 // Initialize the class if the registry is there
181                 if ((class_exists('Registry')) && (Registry::isInitialized() === false)) {
182                         $this->initInstance();
183                 }
184         }
185
186         /**
187          * Destructor reached...
188          *
189          * @return      void
190          */
191         public function __destruct() {
192                 // Is this object already destroyed?
193                 if ($this->__toString() != "DestructedObject") {
194                         // Debug message
195                         if ((defined('DEBUG_DESTRUCTOR')) && (is_object($this->getDebugInstance()))) {
196                                 $this->getDebugInstance()->output(sprintf("[%s:] Das Objekt <strong>%s</strong> wird zerst&ouml;rt.<br />\n",
197                                         __CLASS__, $this->__toString()
198                                 ));
199                         }
200
201                         // Destroy all informations about this class but keep some text about it alive
202                         $this->setObjectDescription(sprintf("Entferntes Objekt <em>%s</em>", $this->__toString()));
203                         $this->setRealClass("DestructedObject");
204                         $this->resetUniqueID();
205                 } elseif ((defined('DEBUG_DESTRUCTOR')) && (is_object($this->getDebugInstance()))) {
206                         // Already destructed object
207                         $this->getDebugInstance()->output(sprintf("[%s:] Das Objekt <strong>%s</strong> wurde bereits zerst&ouml;rt.<br />\n",
208                                 __CLASS__, $this->__toString()
209                         ));
210                 }
211         }
212
213         /**
214          * The call method where all non-implemented methods end up
215          *
216          * @return      void
217          */
218         public final function __call ($methodName, $args) {
219                 // Implode all given arguments
220                 $argsString = "";
221                 if (empty($args)) {
222                         // No arguments
223                         $argsString = "NULL";
224                 } elseif (is_array($args)) {
225                         // Some arguments are there
226                         foreach ($args as $arg) {
227                                 // Check the type
228                                 if (is_bool($arg)) {
229                                         // Boolean!
230                                         if ($arg) $argsString .= "true(bool)"; else $argsString .= "false(bool)";
231                                 } elseif (is_int($arg)) {
232                                         // Integer
233                                         $argsString .= $arg."(int)";
234                                 } elseif (is_float($arg)) {
235                                         // Floating point
236                                         $argsString .= $arg."(float)";
237                                 } elseif ($arg instanceof BaseFrameworkSystem) {
238                                         // Own object instance
239                                         $argsString .= $arg->__toString()."(Object)";
240                                 } elseif (is_object($arg)) {
241                                         // External object
242                                         $argsString .= "unknown object(!)";
243                                 } elseif (is_array($arg)) {
244                                         // Array
245                                         $argsString .= "Array(array)";
246                                 } elseif (is_string($arg)) {
247                                         // String
248                                         $argsString .= "\"".$arg."\"(string)";
249                                 } elseif (is_null($arg)) {
250                                         // Null
251                                         $argsString .= "(null)";
252                                 } else {
253                                         // Unknown type (please report!)
254                                         $argsString .= $arg."(unknown!)";
255                                 }
256
257                                 // Add comma
258                                 $argsString .= ", ";
259                         }
260
261                         // Remove last comma
262                         if (substr($argsString, -2, 1) === ",") $argsString = substr($argsString, 0, -2);
263                 } else {
264                         // Invalid arguments!
265                         $argsString = sprintf("!INVALID:%s!", $args);
266                 }
267
268                 $this->getDebugInstance()->output(sprintf("[%s::%s] Stub! Args: %s",
269                         $this->__toString(),
270                         $methodName,
271                         $argsString
272                 ));
273
274                 // Return nothing
275                 return null;
276         }
277
278         /**
279          * Private initializer for this class
280          *
281          * @return      void
282          */
283         private final function initInstance () {
284                 // Is this a system class?
285                 if (!in_array($this->__toString(), $this->systemClasses)) {
286                         // Add application helper to our class
287                         $this->systemclasses[] = $this->getConfigInstance()->readConfig('app_helper_class');
288
289                         // Set debug instance
290                         $this->setDebugInstance(DebugMiddleware::createDebugMiddleware($this->getConfigInstance()->readConfig('debug_class')));
291
292                         // Get output instance and set it
293                         $outputInstance = ObjectFactory::createObjectByConfiguredName('web_engine', array($this->getConfigInstance()->readConfig('web_content_type')));
294                         $this->setWebOutputInstance($outputInstance);
295
296                         // Set the compressor channel
297                         $this->setCompressorChannel(CompressorChannel::createCompressorChannel(sprintf("%s%s",
298                                 PATH,
299                                 $this->getConfigInstance()->readConfig('compressor_base_path')
300                         )));
301
302                         // Initialization done! :D
303                         Registry::isInitialized("OK");
304                 } elseif ($this->__toString() == "DebugMiddleware") {
305                         // Set configuration instance
306                         $this->setConfigInstance(FrameworkConfiguration::createFrameworkConfiguration());
307                 }
308         }
309
310         /**
311          * Setter for language instance
312          *
313          * @param       $configInstance         The configuration instance which shall
314          *                                                              be FrameworkConfiguration
315          * @return      void
316          */
317         public final function setConfigInstance (FrameworkConfiguration $configInstance) {
318                 Registry::getRegistry()->addInstance('config', $configInstance);
319         }
320
321         /**
322          * Getter for configuration instance
323          *
324          * @return      $cfhInstance - Configuration instance
325          */
326         protected final function getConfigInstance () {
327                 return Registry::getRegistry()->getInstance('config');
328         }
329
330         /**
331          * Setter for debug instance
332          *
333          * @param               $debugInstance  The instance for debug output class
334          * @return      void
335          */
336         public final function setDebugInstance (DebugMiddleware $debugInstance) {
337                 Registry::getRegistry()->addInstance('debug', $debugInstance);
338         }
339
340         /**
341          * Getter for debug instance
342          *
343          * @return      $debug - Instance to class DebugConsoleOutput or DebugWebOutput
344          */
345         public final function getDebugInstance () {
346                 return Registry::getRegistry()->getInstance('debug');
347         }
348
349         /**
350          * Setter for web output instance
351          *
352          * @param               $webInstance    The instance for web output class
353          * @return      void
354          */
355         public final function setWebOutputInstance (OutputStreamer $webInstance) {
356                 Registry::getRegistry()->addInstance('web_output', $webInstance);
357         }
358
359         /**
360          * Getter for web output instance
361          *
362          * @return      $webOutput - Instance to class WebOutput
363          */
364         public final function getWebOutputInstance () {
365                 return Registry::getRegistry()->getInstance('web_output');
366         }
367
368         /**
369          * Setter for database instance
370          *
371          * @param               $dbInstance     The instance for the database connection
372          *                                      (forced DatabaseConnection)
373          * @return      void
374          */
375         public final function setDatabaseInstance (DatabaseConnection $dbInstance) {
376                 Registry::getRegistry()->addInstance('dbInstance', $dbInstance);
377         }
378
379         /**
380          * Getter for database layer
381          *
382          * @return      $dbInstance     The database layer instance
383          */
384         public final function getDatabaseInstance () {
385                 if ((class_exists('Registry')) && (Registry::isInitialized() === true)) {
386                         return Registry::getRegistry()->getInstance('dbInstance');
387                 } else {
388                         return null;
389                 }
390         }
391
392         /**
393          * Setter for compressor channel
394          *
395          * @param               $compressorChannel      An instance of CompressorChannel
396          * @return      void
397          */
398         public final function setCompressorChannel (CompressorChannel $compressorChannel) {
399                 Registry::getRegistry()->addInstance('compressor', $compressorChannel);
400         }
401
402         /**
403          * Getter for compressor channel
404          *
405          * @return      $compressor     The compressor channel
406          */
407         public final function getCompressorChannel () {
408                 return Registry::getRegistry()->getInstance('compressor');
409         }
410
411         /**
412          * Protected getter for a manageable application helper class
413          *
414          * @return      $applicationInstance    An instance of a manageable application helper class
415          */
416         protected final function getApplicationInstance () {
417                 return self::$applicationInstance;
418         }
419
420         /**
421          * Setter for a manageable application helper class
422          *
423          * @param       $applicationInstance    An instance of a manageable application helper class
424          * @return      void
425          */
426         public final function setApplicationInstance (ManageableApplication $applicationInstance) {
427                 self::$applicationInstance = $applicationInstance;
428         }
429
430         /**
431          * Setter for request instance
432          *
433          * @param       $requestInstance        An instance of a Requestable class
434          * @return      void
435          */
436         public final function setRequestInstance (Requestable $requestInstance) {
437                 $this->requestInstance = $requestInstance;
438         }
439
440         /**
441          * Getter for request instance
442          *
443          * @return      $requestInstance        An instance of a Requestable class
444          */
445         public final function getRequestInstance () {
446                 return $this->requestInstance;
447         }
448
449         /**
450          * Setter for response instance
451          *
452          * @param       $responseInstance       An instance of a Responseable class
453          * @return      void
454          */
455         public final function setResponseInstance (Responseable $responseInstance) {
456                 $this->responseInstance = $responseInstance;
457         }
458
459         /**
460          * Getter for response instance
461          *
462          * @return      $responseInstance       An instance of a Responseable class
463          */
464         public final function getResponseInstance () {
465                 return $this->responseInstance;
466         }
467
468         /**
469          * Getter for $realClass
470          *
471          * @return      $realClass The name of the real class (not BaseFrameworkSystem)
472          */
473         public final function __toString () {
474                 return $this->realClass;
475         }
476
477         /**
478          * Setter for the real class name
479          *
480          * @param               $realClass      Class name (string)
481          * @return      void
482          */
483         public final function setRealClass ($realClass) {
484                 // Cast to string
485                 $realClass = (string) $realClass;
486
487                 // Set real class
488                 $this->realClass = $realClass;
489         }
490
491         /**
492          * Generate unique ID from a lot entropy
493          *
494          * @return      void
495          */
496         public final function generateUniqueId () {
497                 // Is the id set for this class?
498                 if (empty($this->uniqueID)) {
499
500                         // Correct missing class name
501                         $corrected = false;
502                         if ($this->__toString() == "") {
503                                 $this->setRealClass(__CLASS__);
504                                 $corrected = true;
505                         }
506
507                         // Cache datbase instance
508                         $db = $this->getDatabaseInstance();
509
510                         // Generate new id
511                         $tempID = false;
512                         while (true) {
513                                 // Generate a unique ID number
514                                 $tempID = $this->generateIdNumber();
515                                 $isUsed = false;
516
517                                 // Try to figure out if the ID number is not yet used
518                                 try {
519                                         // Is this a registry?
520                                         if ($this->__toString() == "Registry") {
521                                                 // Registry, then abort here
522                                                 break;
523                                         } elseif (is_object($db)) {
524                                                 $isUsed = $db->isUniqueIdUsed($tempID, true);
525                                         }
526                                 } catch (FrameworkException $e) {
527                                         // Catches all and ignores all ;-)
528                                 }
529
530                                 if (
531                                         (
532                                                 $tempID !== false
533                                         ) && (
534                                                 (
535                                                         $db === null
536                                                 ) || (
537                                                         (
538                                                                 is_object($db)
539                                                         ) && (
540                                                                 !$isUsed
541                                                         )
542                                                 )
543                                         )
544                                 ) {
545                                         // Abort the loop
546                                         break;
547                                 }
548                         } // END - while
549
550                         // Apply the new ID
551                         $this->setUniqueID($tempID);
552
553                         // Revert maybe corrected class name
554                         if ($corrected) {
555                                 $this->setRealClass("");
556                         }
557
558                         // Remove system classes if we are in a system class
559                         if ((isset($this->systemClasses)) && (in_array($this->__toString(), $this->systemClasses))) {
560                                 // This may save some RAM...
561                                 $this->removeSystemArray();
562                         }
563                 }
564         }
565
566         /**
567          * Generates a new ID number for classes based from the class' real name,
568          * the description and some random data
569          *
570          * @return      $tempID The new (temporary) ID number
571          */
572         private final function generateIdNumber () {
573                 return sprintf("%s@%s",
574                         $this->__toString(),
575                         md5(sprintf("%s:%s:%s:%s:%s:%s",
576                                 $this->__toString(),
577                                 $this->getObjectDescription(),
578                                 time(),
579                                 getenv('REMOTE_ADDR'),
580                                 getenv('SERVER_ADDR'),
581                                 mt_rand()
582                         ))
583                 );
584         }
585
586         /**
587          * Setter for unique ID
588          *
589          * @param               $uniqueID               The newly generated unique ID number
590          * @return      void
591          */
592         private final function setUniqueID ($uniqueID) {
593                 // Cast to string
594                 $uniqueID = (string) $uniqueID;
595
596                 // Set the ID number
597                 $this->uniqueID = $uniqueID;
598         }
599
600         /**
601          * Getter for unique ID
602          *
603          * @return      $uniqueID               The unique ID of this class
604          */
605         public final function getUniqueID () {
606                 return $this->uniqueID;
607         }
608
609         /**
610          * Resets or recreates the unique ID number
611          *
612          * @return      void
613          */
614         public final function resetUniqueID() {
615                 // Sweet and simple... ;-)
616                 $newUniqueID = $this->generateIdNumber();
617                 $this->setUniqueID($newUniqueID);
618         }
619
620         /**
621          * Getter for simulator description
622          *
623          * @return      $objectDescription      The description of this simulation part
624          */
625         public final function getObjectDescription () {
626                 if (isset($this->objectDescription)) {
627                         return $this->objectDescription;
628                 } else {
629                         return null;
630                 }
631         }
632
633         /**
634          * Setter for simulation part description
635          *
636          * @param               $objectDescription      The description as string for this simulation part
637          * @return      void
638          */
639         public final function setObjectDescription ($objectDescription) {
640                 $this->objectDescription = (String) $objectDescription;
641         }
642
643         /**
644          * Validate if given object is the same as current
645          *
646          * @param               $object An object instance for comparison with this class
647          * @return      boolean The result of comparing both's unique ID
648          */
649         public final function equals ($object) {
650                 return ($this->getUniqueID() == $object->getUniqueID());
651         }
652
653         /**
654          * Compare if both simulation part description and class name matches
655          * (shall be enougth)
656          *
657          * @param               $itemInstance   An object instance to an other class
658          * @return      boolean         The result of comparing class name simulation part description
659          */
660         public function itemMatches ($itemInstance) {
661                 return (
662                         (
663                                 $this->__toString()   == $itemInstance->__toString()
664                         ) && (
665                                 $this->getObjectDescription() == $itemInstance->getObjectDescription()
666                         )
667                 );
668         }
669
670         /**
671          * Compare class name of this and given class name
672          *
673          * @param               $class  The class name as string from the other class
674          * @return      boolean The result of comparing both class names
675          */
676         public final function isClass ($class) {
677                 return ($this->__toString() == $class);
678         }
679
680         /**
681          * Stub method (only real cabins shall override it)
682          *
683          * @return      boolean false = is no cabin, true = is a cabin
684          */
685         public function isCabin () {
686                 return false;
687         }
688
689         /**
690          * Stub method for tradeable objects
691          *
692          * @return      boolean false = is not tradeable by the Merchant class,
693          *                                      true  = is a tradeable object
694          */
695         public function isTradeable () {
696                 return false;
697         }
698
699         /**
700          * Formats computer generated price values into human-understandable formats
701          * with thousand and decimal seperators.
702          *
703          * @param       $value          The in computer format value for a price
704          * @param       $currency       The currency symbol (use HTML-valid characters!)
705          * @param       $decNum         Number of decimals after commata
706          * @return      $price          The for the current language formated price string
707          * @throws      MissingDecimalsThousandsSeperatorException      If decimals or
708          *                                                                                              thousands seperator
709          *                                                                                              is missing
710          */
711         public function formatCurrency ($value, $currency = "&euro;", $decNum = 2) {
712                 // Are all required attriutes set?
713                 if ((!isset($this->decimals)) || (!isset($this->thousands))) {
714                         // Throw an exception
715                         throw new MissingDecimalsThousandsSeperatorException($this, self::EXCEPTION_ATTRIBUTES_ARE_MISSING);
716                 }
717
718                 // Cast the number
719                 $value = (float) $value;
720
721                 // Reformat the US number
722                 $price = sprintf("%s %s",
723                         number_format($value, $decNum, $this->decimals, $this->thousands),
724                         $currency
725                 );
726
727                 // Return as string...
728                 return $price;
729         }
730
731         /**
732          * Removes number formating characters
733          *
734          * @return      void
735          */
736         public final function removeNumberFormaters () {
737                 unset($this->thousands);
738                 unset($this->decimals);
739         }
740
741         /**
742          * Private getter for language instance
743          *
744          * @return      $langInstance   An instance to the language sub-system
745          */
746         protected final function getLanguageInstance () {
747                 return self::$langInstance;
748         }
749
750         /**
751          * Setter for language instance
752          *
753          * @param       $langInstance   An instance to the language sub-system
754          * @return      void
755          * @see         LanguageSystem
756          */
757         public final function setLanguageInstance (ManageableLanguage $langInstance) {
758                 self::$langInstance = $langInstance;
759         }
760
761         /**
762          * Remove the $systemClasses array from memory
763          *
764          * @return      void
765          */
766         public final function removeSystemArray () {
767                 unset($this->systemClasses);
768         }
769
770         /**
771          * Create a file name and path name from the object's unique ID number.
772          * The left part of the ID shall always be a valid class name and the
773          * right part an ID number.
774          *
775          * @return      $pfn            The file name with a prepended path name
776          * @throws      NoArrayCreatedException If explode() fails to create an array
777          * @throws      InvalidArrayCountException      If the array contains less or
778          *                                                                      more than two elements
779          */
780         public final function getPathFileNameFromObject () {
781                 // Get the main object's unique ID. We use this as a path/filename combination
782                 $pathFile = $this->getUniqueID();
783
784                 // Split it up in path and file name
785                 $pathFile = explode("@", $pathFile);
786
787                 // Are there two elements? Index 0 is the path, 1 the file name + global extension
788                 if (!is_array($pathFile)) {
789                         // No array found
790                         throw new NoArrayCreatedException(array($this, "pathFile"), self::EXCEPTION_ARRAY_EXPECTED);
791                 } elseif (count($pathFile) != 2) {
792                         // Invalid ID returned!
793                         throw new InvalidArrayCountException(array($this, "pathFile", count($pathFile), 2), self::EXCEPTION_ARRAY_HAS_INVALID_COUNT);
794                 }
795
796                 // Auto-append missing trailing slash
797                 $pathFile[0] = $this->addMissingTrailingSlash($pathFile[0]);
798
799                 // Create the file name and return it
800                 $pfn = ($pathFile[0] . $pathFile[1]);
801                 return $pfn;
802         }
803
804         /**
805          * Appends a trailing slash to a string
806          *
807          * @param       $str            A string (maybe) without trailing slash
808          * @return      $str            A string with an auto-appended trailing slash
809          */
810         public final function addMissingTrailingSlash ($str) {
811                 // Is there a trailing slash?
812                 if (substr($str, -1, 1) != "/") $str .= "/";
813                 return $str;
814         }
815
816         /**
817          * Private getter for file IO instance
818          *
819          * @return      $fileIoInstance An instance to the file I/O sub-system
820          */
821         protected final function getFileIoInstance () {
822                 return $this->fileIoInstance;
823         }
824
825         /**
826          * Setter for file I/O instance
827          *
828          * @param       $fileIoInstance An instance to the file I/O sub-system
829          * @return      void
830          */
831         public final function setFileIoInstance (FileIoHandler $fileIoInstance) {
832                 $this->fileIoInstance = $fileIoInstance;
833         }
834
835         /**
836          * Prepare the template engine (TemplateEngine by default) for a given
837          * application helper instance (ApplicationHelper by default).
838          *
839          * @param               $appInstance                    An application helper instance or
840          *                                                                              null if we shall use the default
841          * @return              $tplEngine                              The template engine instance
842          * @throws              NullPointerException    If the template engine could not
843          *                                                                              be initialized
844          * @throws              UnsupportedTemplateEngineException      If $tplEngine is an
845          *                                                                              unsupported template engine
846          * @throws              MissingLanguageHandlerException If the language sub-system
847          *                                                                              is not yet initialized
848          * @throws              NullPointerException    If the discovered application
849          *                                                                              instance is still null
850          */
851         protected function prepareTemplateEngine (BaseFrameworkSystem $appInstance=null) {
852                 // Is the application instance set?
853                 if (is_null($appInstance)) {
854                         // Get the current instance
855                         $appInstance = $this->getApplicationInstance();
856
857                         // Still null?
858                         if (is_null($appInstance)) {
859                                 // Thrown an exception
860                                 throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
861                         }
862                 }
863
864                 // Generate FQFN for all application templates
865                 $fqfn = sprintf("%s%s/%s/%s",
866                         PATH,
867                         $this->getConfigInstance()->readConfig('application_path'),
868                         strtolower($appInstance->getAppShortName()),
869                         $this->getConfigInstance()->readConfig('tpl_base_path')
870                 );
871
872                 // Are both instances set?
873                 if ($appInstance->getLanguageInstance() === null) {
874                         // Invalid language instance
875                         throw new MissingLanguageHandlerException($appInstance, self::EXCEPTION_MISSING_LANGUAGE_HANDLER);
876                 } elseif ($appInstance->getFileIoInstance() === null) {
877                         // Invalid language instance
878                         throw new MissingFileIoHandlerException($appInstance, self::EXCEPTION_MISSING_FILE_IO_HANDLER);
879                 }
880
881                 // Initialize the template engine
882                 $tplEngine = ObjectFactory::createObjectByConfiguredName('template_class', array($fqfn, $appInstance->getLanguageInstance(), $appInstance->getFileIoInstance()));
883
884                 // Return the prepared instance
885                 return $tplEngine;
886         }
887
888         /**
889          * Debugs this instance by putting out it's full content
890          *
891          * @return      void
892          */
893         public final function debugInstance () {
894                 // Generate the output
895                 $content = sprintf("<pre>%s</pre>",
896                         trim(print_r($this, true))
897                 );
898
899                 // Output it
900                 ApplicationEntryPoint::app_die(sprintf("<strong>%s debug output:</strong><div id=\"debug_content\">%s</div>Loaded includes: <div id=\"debug_include_list\">%s</div>",
901                         $this->__toString(),
902                         $content,
903                         ClassLoader::getInstance()->getPrintableIncludeList()
904                 ));
905         }
906
907         /**
908          * Output a partial stub message for the caller method
909          *
910          * @param       $message        An optional message to display
911          * @return      void
912          */
913         protected function partialStub ($message = "") {
914                 // Get the backtrace
915                 $backtrace = debug_backtrace();
916
917                 // Generate the class::method string
918                 $methodName = "UnknownClass::unknownMethod";
919                 if ((isset($backtrace[1]['class'])) && (isset($backtrace[1]['function']))) {
920                         $methodName = $backtrace[1]['class']."::".$backtrace[1]['function'];
921                 }
922
923                 // Construct the full message
924                 $stubMessage = sprintf("[%s:] Partial stub!",
925                         $methodName
926                 );
927
928                 // Is the extra message given?
929                 if (!empty($message)) {
930                         // Then add it as well
931                         $stubMessage .= sprintf(" Message: <span id=\"stub_message\">%s</span>", $message);
932                 }
933
934                 // Debug instance is there?
935                 if (!is_null($this->getDebugInstance())) {
936                         // Output stub message
937                         $this->getDebugInstance()->output($stubMessage);
938                 } else {
939                         // Trigger an error
940                         trigger_error($stubMessage."<br />\n");
941                 }
942         }
943
944         /**
945          * Converts e.g. a command from URL to a valid class by keeping out bad characters
946          *
947          * @param       $str            The string, what ever it is needs to be converted
948          * @return      $className      Generated class name
949          */
950         public function convertToClassName ($str) {
951                 // Init class name
952                 $className = "";
953
954                 // Convert all dashes in underscores
955                 $str = str_replace("-", "_", $str);
956
957                 // Now use that underscores to get classname parts for hungarian style
958                 foreach (explode("_", $str) as $strPart) {
959                         // Make the class name part lower case and first upper case
960                         $className .= ucfirst(strtolower($strPart));
961                 } // END - foreach
962
963                 // Return class name
964                 return $className;
965         }
966
967         /**
968          * Outputs a debug backtrace and stops further script execution
969          *
970          * @return      void
971          */
972         public function debugBacktrace () {
973                 // Sorry, there is no other way getting this nice backtrace
974                 print "<pre>\n";
975                 debug_print_backtrace();
976                 print "</pre>";
977                 exit;
978         }
979
980         /**
981          * Setter for search instance
982          *
983          * @param       $searchInstance         Searchable criteria instance
984          * @return      void
985          */
986         public final function setSearchInstance (LocalSearchCriteria $searchInstance) {
987                 $this->searchInstance = $searchInstance;
988         }
989
990         /**
991          * Getter for search instance
992          *
993          * @return      $searchInstance         Searchable criteria instance
994          */
995         public final function getSearchInstance () {
996                 return $this->searchInstance;
997         }
998
999         /**
1000          * Setter for resolver instance
1001          *
1002          * @param       $resolverInstance               Instance of a command resolver class
1003          * @return      void
1004          */
1005         public final function setResolverInstance (Resolver $resolverInstance) {
1006                 $this->resolverInstance = $resolverInstance;
1007         }
1008
1009         /**
1010          * Getter for resolver instance
1011          *
1012          * @return      $resolverInstance               Instance of a command resolver class
1013          */
1014         public final function getResolverInstance () {
1015                 return $this->resolverInstance;
1016         }
1017 }
1018
1019 // [EOF]
1020 ?>