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