2ff1eb53fb4baa9a6ce21b427411c6dae3158d36
[core.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, 2009 - 2012 Core Developer Team
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          * The real class name
28          */
29         private $realClass = 'BaseFrameworkSystem';
30
31         /**
32          * Instance of a request class
33          */
34         private $requestInstance = NULL;
35
36         /**
37          * Instance of a response class
38          */
39         private $responseInstance = NULL;
40
41         /**
42          * Search criteria instance
43          */
44         private $searchInstance = NULL;
45
46         /**
47          * Update criteria instance
48          */
49         private $updateInstance = 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          * Template engine instance
63          */
64         private $templateInstance = NULL;
65
66         /**
67          * Database result instance
68          */
69         private $resultInstance = NULL;
70
71         /**
72          * Instance for user class
73          */
74         private $userInstance = NULL;
75
76         /**
77          * A controller instance
78          */
79         private $controllerInstance = NULL;
80
81         /**
82          * Instance of a RNG
83          */
84         private $rngInstance = NULL;
85
86         /**
87          * Instance of a crypto helper
88          */
89         private $cryptoInstance = NULL;
90
91         /**
92          * Instance of an Iterator class
93          */
94         private $iteratorInstance = NULL;
95
96         /**
97          * Instance of the list
98          */
99         private $listInstance = NULL;
100
101         /**
102          * Instance of a menu
103          */
104         private $menuInstance = NULL;
105
106         /**
107          * Instance of the image
108          */
109         private $imageInstance = NULL;
110
111         /**
112          * Instance of the stacker
113          */
114         private $stackerInstance = NULL;
115
116         /**
117          * A Compressor instance
118          */
119         private $compressorInstance = NULL;
120
121         /**
122          * A Parseable instance
123          */
124         private $parserInstance = NULL;
125
126         /**
127          * A ProtocolHandler instance
128          */
129         private $protocolInstance = NULL;
130
131         /**
132          * A database wrapper instance
133          */
134         private $databaseInstance = NULL;
135
136         /**
137          * A helper instance for the form
138          */
139         private $helperInstance = NULL;
140
141         /**
142          * An instance of a Sourceable class
143          */
144         private $sourceInstance = NULL;
145
146         /**
147          * An instance of a InputStreamable class
148          */
149         private $inputStreamInstance = NULL;
150
151         /**
152          * An instance of a OutputStreamable class
153          */
154         private $outputStreamInstance = NULL;
155
156         /**
157          * Networkable handler instance
158          */
159         private $handlerInstance = NULL;
160
161         /**
162          * Visitor handler instance
163          */
164         private $visitorInstance = NULL;
165
166         /**
167          * DHT instance
168          */
169         private $dhtInstance = NULL;
170
171         /**
172          * An instance of a database wrapper class
173          */
174         private $wrapperInstance = NULL;
175
176         /**
177          * Thousands separator
178          */
179         private $thousands = '.'; // German
180
181         /**
182          * Decimal separator
183          */
184         private $decimals  = ','; // German
185
186         /**
187          * Socket resource
188          */
189         private $socketResource = false;
190
191         /**
192          * Package data
193          */
194         private $packageData = array();
195
196         /***********************
197          * Exception codes.... *
198          ***********************/
199
200         // @todo Try to clean these constants up
201         const EXCEPTION_IS_NULL_POINTER              = 0x001;
202         const EXCEPTION_IS_NO_OBJECT                 = 0x002;
203         const EXCEPTION_IS_NO_ARRAY                  = 0x003;
204         const EXCEPTION_MISSING_METHOD               = 0x004;
205         const EXCEPTION_CLASSES_NOT_MATCHING         = 0x005;
206         const EXCEPTION_INDEX_OUT_OF_BOUNDS          = 0x006;
207         const EXCEPTION_DIMENSION_ARRAY_INVALID      = 0x007;
208         const EXCEPTION_ITEM_NOT_TRADEABLE           = 0x008;
209         const EXCEPTION_ITEM_NOT_IN_PRICE_LIST       = 0x009;
210         const EXCEPTION_GENDER_IS_WRONG              = 0x00a;
211         const EXCEPTION_BIRTH_DATE_IS_INVALID        = 0x00b;
212         const EXCEPTION_EMPTY_STRUCTURES_ARRAY       = 0x00c;
213         const EXCEPTION_HAS_ALREADY_PERSONELL_LIST   = 0x00d;
214         const EXCEPTION_NOT_ENOUGTH_UNEMPLOYEES      = 0x00e;
215         const EXCEPTION_TOTAL_PRICE_NOT_CALCULATED   = 0x00f;
216         const EXCEPTION_HARBOR_HAS_NO_SHIPYARDS      = 0x010;
217         const EXCEPTION_CONTRACT_PARTNER_INVALID     = 0x011;
218         const EXCEPTION_CONTRACT_PARTNER_MISMATCH    = 0x012;
219         const EXCEPTION_CONTRACT_ALREADY_SIGNED      = 0x013;
220         const EXCEPTION_UNEXPECTED_EMPTY_STRING      = 0x014;
221         const EXCEPTION_PATH_NOT_FOUND               = 0x015;
222         const EXCEPTION_INVALID_PATH_NAME            = 0x016;
223         const EXCEPTION_READ_PROTECED_PATH           = 0x017;
224         const EXCEPTION_WRITE_PROTECED_PATH          = 0x018;
225         const EXCEPTION_DIR_POINTER_INVALID          = 0x019;
226         const EXCEPTION_FILE_POINTER_INVALID         = 0x01a;
227         const EXCEPTION_INVALID_RESOURCE             = 0x01b;
228         const EXCEPTION_UNEXPECTED_OBJECT            = 0x01c;
229         const EXCEPTION_LIMIT_ELEMENT_IS_UNSUPPORTED = 0x01d;
230         const EXCEPTION_GETTER_IS_MISSING            = 0x01e;
231         const EXCEPTION_ARRAY_EXPECTED               = 0x01f;
232         const EXCEPTION_ARRAY_HAS_INVALID_COUNT      = 0x020;
233         const EXCEPTION_ID_IS_INVALID_FORMAT         = 0x021;
234         const EXCEPTION_MD5_CHECKSUMS_MISMATCH       = 0x022;
235         const EXCEPTION_UNEXPECTED_STRING_SIZE       = 0x023;
236         const EXCEPTION_SIMULATOR_ID_INVALID         = 0x024;
237         const EXCEPTION_MISMATCHING_COMPRESSORS      = 0x025;
238         const EXCEPTION_CONTAINER_ITEM_IS_NULL       = 0x026;
239         const EXCEPTION_ITEM_IS_NO_ARRAY             = 0x027;
240         const EXCEPTION_CONTAINER_MAYBE_DAMAGED      = 0x028;
241         const EXCEPTION_INVALID_STRING               = 0x029;
242         const EXCEPTION_VARIABLE_NOT_SET             = 0x02a;
243         const EXCEPTION_ATTRIBUTES_ARE_MISSING       = 0x02b;
244         const EXCEPTION_ARRAY_ELEMENTS_MISSING       = 0x02c;
245         const EXCEPTION_TEMPLATE_ENGINE_UNSUPPORTED  = 0x02d;
246         const EXCEPTION_UNSPPORTED_OPERATION         = 0x02e;
247         const EXCEPTION_MISSING_ELEMENT              = 0x030;
248         const EXCEPTION_HEADERS_ALREADY_SENT         = 0x031;
249         const EXCEPTION_DEFAULT_CONTROLLER_GONE      = 0x032;
250         const EXCEPTION_CLASS_NOT_FOUND              = 0x033;
251         const EXCEPTION_REQUIRED_INTERFACE_MISSING   = 0x034;
252         const EXCEPTION_FATAL_ERROR                  = 0x035;
253         const EXCEPTION_FILE_NOT_FOUND               = 0x036;
254         const EXCEPTION_ASSERTION_FAILED             = 0x037;
255         const EXCEPTION_FILE_CANNOT_BE_READ          = 0x038;
256         const EXCEPTION_DATABASE_UPDATED_NOT_ALLOWED = 0x039;
257         const EXCEPTION_FILTER_CHAIN_INTERCEPTED     = 0x040;
258
259         /**
260          * Hexadecimal->Decimal translation array
261          */
262         private static $hexdec = array(
263                 '0' => 0,
264                 '1' => 1,
265                 '2' => 2,
266                 '3' => 3,
267                 '4' => 4,
268                 '5' => 5,
269                 '6' => 6,
270                 '7' => 7,
271                 '8' => 8,
272                 '9' => 9,
273                 'a' => 10,
274                 'b' => 11,
275                 'c' => 12,
276                 'd' => 13,
277                 'e' => 14,
278                 'f' => 15
279         );
280
281         /**
282          * Decimal->hexadecimal translation array
283          */
284         private static $dechex = array(
285                  0 => '0',
286                  1 => '1',
287                  2 => '2',
288                  3 => '3',
289                  4 => '4',
290                  5 => '5',
291                  6 => '6',
292                  7 => '7',
293                  8 => '8',
294                  9 => '9',
295                 10 => 'a',
296                 11 => 'b',
297                 12 => 'c',
298                 13 => 'd',
299                 14 => 'e',
300                 15 => 'f'
301         );
302
303         /**
304          * Startup time in miliseconds
305          */
306         private static $startupTime = 0;
307
308         /**
309          * Protected super constructor
310          *
311          * @param       $className      Name of the class
312          * @return      void
313          */
314         protected function __construct ($className) {
315                 // Set real class
316                 $this->setRealClass($className);
317
318                 // Set configuration instance if no registry ...
319                 if (!$this instanceof Register) {
320                         // ... because registries doesn't need to be configured
321                         $this->setConfigInstance(FrameworkConfiguration::getSelfInstance());
322                 } // END - if
323
324                 // Is the startup time set? (0 cannot be true anymore)
325                 if (self::$startupTime == 0) {
326                         // Then set it
327                         self::$startupTime = microtime(true);
328                 } // END - if
329         }
330
331         /**
332          * Destructor for all classes
333          *
334          * @return      void
335          */
336         public function __destruct () {
337                 // Flush any updated entries to the database
338                 $this->flushPendingUpdates();
339
340                 // Is this object already destroyed?
341                 if ($this->__toString() != 'DestructedObject') {
342                         // Destroy all informations about this class but keep some text about it alive
343                         $this->setRealClass('DestructedObject');
344                 } elseif ((defined('DEBUG_DESTRUCTOR')) && (is_object($this->getDebugInstance()))) {
345                         // Already destructed object
346                         self::createDebugInstance(__CLASS__)->debugOutput(sprintf("[%s:] The object <span class=\"object_name\">%s</span> is already destroyed.",
347                                 __CLASS__,
348                                 $this->__toString()
349                         ));
350                 }
351         }
352
353         /**
354          * The __call() method where all non-implemented methods end up
355          *
356          * @param       $methodName             Name of the missing method
357          * @args        $args                   Arguments passed to the method
358          * @return      void
359          */
360         public final function __call ($methodName, $args) {
361                 return self::__callStatic($methodName, $args);
362         }
363
364         /**
365          * The __callStatic() method where all non-implemented static methods end up
366          *
367          * @param       $methodName             Name of the missing method
368          * @args        $args                   Arguments passed to the method
369          * @return      void
370          */
371         public static final function __callStatic ($methodName, $args) {
372                 // Init argument string
373                 $argsString = '';
374
375                 // Is it empty or an array?
376                 if (empty($args)) {
377                         // No arguments
378                         $argsString = 'NULL';
379                 } elseif (is_array($args)) {
380                         // Some arguments are there
381                         foreach ($args as $arg) {
382                                 // Add the value itself if not array. This prevents 'array to string conversion' message
383                                 if (is_array($arg)) {
384                                         $argsString .= 'Array';
385                                 } else {
386                                         $argsString .= $arg;
387                                 }
388
389                                 // Add data about the argument
390                                 $argsString .= ' (' . gettype($arg);
391
392                                 if (is_string($arg)) {
393                                         // Add length for strings
394                                         $argsString .= ', ' . strlen($arg);
395                                 } elseif (is_array($arg)) {
396                                         // .. or size if array
397                                         $argsString .= ', ' . count($arg);
398                                 } elseif ($arg === true) {
399                                         // ... is boolean 'true'
400                                         $argsString .= ', true';
401                                 } elseif ($arg === false) {
402                                         // ... is boolean 'true'
403                                         $argsString .= ', false';
404                                 }
405
406                                 // Closing bracket
407                                 $argsString .= '), ';
408                         } // END - foreach
409
410                         // Remove last comma
411                         if (substr($argsString, -2, 1) == ',') {
412                                 $argsString = substr($argsString, 0, -2);
413                         } // END - if
414                 } else {
415                         // Invalid arguments!
416                         $argsString = '!INVALID:' . gettype($args) . '!';
417                 }
418
419                 // Output stub message
420                 // @TODO __CLASS__ does always return BaseFrameworkSystem but not the extending (=child) class
421                 self::createDebugInstance(__CLASS__)->debugOutput(sprintf("[unknown::%s:] Stub! Args: %s",
422                         $methodName,
423                         $argsString
424                 ));
425
426                 // Return nothing
427                 return NULL;
428         }
429
430         /**
431          * Getter for $realClass
432          *
433          * @return      $realClass The name of the real class (not BaseFrameworkSystem)
434          */
435         public function __toString () {
436                 return $this->realClass;
437         }
438
439         /**
440          * Magic function to catch setting of missing but set class fields/attributes
441          *
442          * @param       $name   Name of the field/attribute
443          * @param       $value  Value to store
444          * @return      void
445          */
446         public final function __set ($name, $value) {
447                 $this->debugBackTrace(sprintf("Tried to set a missing field. name=%s, value[%s]=%s",
448                         $name,
449                         gettype($value),
450                         $value
451                 ));
452         }
453
454         /**
455          * Magic function to catch getting of missing fields/attributes
456          *
457          * @param       $name   Name of the field/attribute
458          * @return      void
459          */
460         public final function __get ($name) {
461                 $this->debugBackTrace(sprintf("Tried to get a missing field. name=%s",
462                         $name
463                 ));
464         }
465
466         /**
467          * Magic function to catch unsetting of missing fields/attributes
468          *
469          * @param       $name   Name of the field/attribute
470          * @return      void
471          */
472         public final function __unset ($name) {
473                 $this->debugBackTrace(sprintf("Tried to unset a missing field. name=%s",
474                         $name
475                 ));
476         }
477
478         /**
479          * Setter for the real class name
480          *
481          * @param       $realClass      Class name (string)
482          * @return      void
483          */
484         public final function setRealClass ($realClass) {
485                 // Set real class
486                 $this->realClass = (string) $realClass;
487         }
488
489         /**
490          * Setter for database result instance
491          *
492          * @param       $resultInstance         An instance of a database result class
493          * @return      void
494          * @todo        SearchableResult and UpdateableResult shall have a super interface to use here
495          */
496         protected final function setResultInstance (SearchableResult $resultInstance) {
497                 $this->resultInstance =  $resultInstance;
498         }
499
500         /**
501          * Getter for database result instance
502          *
503          * @return      $resultInstance         An instance of a database result class
504          */
505         public final function getResultInstance () {
506                 return $this->resultInstance;
507         }
508
509         /**
510          * Setter for template engine instances
511          *
512          * @param       $templateInstance       An instance of a template engine class
513          * @return      void
514          */
515         protected final function setTemplateInstance (CompileableTemplate $templateInstance) {
516                 $this->templateInstance = $templateInstance;
517         }
518
519         /**
520          * Getter for template engine instances
521          *
522          * @return      $templateInstance       An instance of a template engine class
523          */
524         protected final function getTemplateInstance () {
525                 return $this->templateInstance;
526         }
527
528         /**
529          * Setter for search instance
530          *
531          * @param       $searchInstance         Searchable criteria instance
532          * @return      void
533          */
534         public final function setSearchInstance (LocalSearchCriteria $searchInstance) {
535                 $this->searchInstance = $searchInstance;
536         }
537
538         /**
539          * Getter for search instance
540          *
541          * @return      $searchInstance         Searchable criteria instance
542          */
543         public final function getSearchInstance () {
544                 return $this->searchInstance;
545         }
546
547         /**
548          * Setter for update instance
549          *
550          * @param       $updateInstance         Searchable criteria instance
551          * @return      void
552          */
553         public final function setUpdateInstance (LocalUpdateCriteria $updateInstance) {
554                 $this->updateInstance = $updateInstance;
555         }
556
557         /**
558          * Getter for update instance
559          *
560          * @return      $updateInstance         Updateable criteria instance
561          */
562         public final function getUpdateInstance () {
563                 return $this->updateInstance;
564         }
565
566         /**
567          * Setter for resolver instance
568          *
569          * @param       $resolverInstance       Instance of a command resolver class
570          * @return      void
571          */
572         public final function setResolverInstance (Resolver $resolverInstance) {
573                 $this->resolverInstance = $resolverInstance;
574         }
575
576         /**
577          * Getter for resolver instance
578          *
579          * @return      $resolverInstance       Instance of a command resolver class
580          */
581         public final function getResolverInstance () {
582                 return $this->resolverInstance;
583         }
584
585         /**
586          * Setter for language instance
587          *
588          * @param       $configInstance         The configuration instance which shall
589          *                                                              be FrameworkConfiguration
590          * @return      void
591          */
592         public final function setConfigInstance (FrameworkConfiguration $configInstance) {
593                 Registry::getRegistry()->addInstance('config', $configInstance);
594         }
595
596         /**
597          * Getter for configuration instance
598          *
599          * @return      $configInstance         Configuration instance
600          */
601         public final function getConfigInstance () {
602                 $configInstance = Registry::getRegistry()->getInstance('config');
603                 return $configInstance;
604         }
605
606         /**
607          * Setter for debug instance
608          *
609          * @param       $debugInstance  The instance for debug output class
610          * @return      void
611          */
612         public final function setDebugInstance (DebugMiddleware $debugInstance) {
613                 Registry::getRegistry()->addInstance('debug', $debugInstance);
614         }
615
616         /**
617          * Getter for debug instance
618          *
619          * @return      $debugInstance  Instance to class DebugConsoleOutput or DebugWebOutput
620          */
621         public final function getDebugInstance () {
622                 // Get debug instance
623                 $debugInstance = Registry::getRegistry()->getInstance('debug');
624
625                 // Return it
626                 return $debugInstance;
627         }
628
629         /**
630          * Setter for web output instance
631          *
632          * @param       $webInstance    The instance for web output class
633          * @return      void
634          */
635         public final function setWebOutputInstance (OutputStreamer $webInstance) {
636                 Registry::getRegistry()->addInstance('web_output', $webInstance);
637         }
638
639         /**
640          * Getter for web output instance
641          *
642          * @return      $webOutputInstance - Instance to class WebOutput
643          */
644         public final function getWebOutputInstance () {
645                 $webOutputInstance = Registry::getRegistry()->getInstance('web_output');
646                 return $webOutputInstance;
647         }
648
649         /**
650          * Setter for database instance
651          *
652          * @param       $databaseInstance       The instance for the database connection (forced DatabaseConnection)
653          * @return      void
654          */
655         public final function setDatabaseInstance (DatabaseConnection $databaseInstance) {
656                 Registry::getRegistry()->addInstance('db_instance', $databaseInstance);
657         }
658
659         /**
660          * Getter for database layer
661          *
662          * @return      $databaseInstance       The database layer instance
663          */
664         public final function getDatabaseInstance () {
665                 // Get instance
666                 $databaseInstance = Registry::getRegistry()->getInstance('db_instance');
667
668                 // Return instance
669                 return $databaseInstance;
670         }
671
672         /**
673          * Setter for compressor channel
674          *
675          * @param       $compressorInstance             An instance of CompressorChannel
676          * @return      void
677          */
678         public final function setCompressorChannel (CompressorChannel $compressorInstance) {
679                 Registry::getRegistry()->addInstance('compressor', $compressorInstance);
680         }
681
682         /**
683          * Getter for compressor channel
684          *
685          * @return      $compressorInstance             The compressor channel
686          */
687         public final function getCompressorChannel () {
688                 $compressorInstance = Registry::getRegistry()->getInstance('compressor');
689                 return $compressorInstance;
690         }
691
692         /**
693          * Protected getter for a manageable application helper class
694          *
695          * @return      $applicationInstance    An instance of a manageable application helper class
696          */
697         protected final function getApplicationInstance () {
698                 $applicationInstance = Registry::getRegistry()->getInstance('application');
699                 return $applicationInstance;
700         }
701
702         /**
703          * Setter for a manageable application helper class
704          *
705          * @param       $applicationInstance    An instance of a manageable application helper class
706          * @return      void
707          */
708         public final function setApplicationInstance (ManageableApplication $applicationInstance) {
709                 Registry::getRegistry()->addInstance('application', $applicationInstance);
710         }
711
712         /**
713          * Setter for request instance
714          *
715          * @param       $requestInstance        An instance of a Requestable class
716          * @return      void
717          */
718         public final function setRequestInstance (Requestable $requestInstance) {
719                 $this->requestInstance = $requestInstance;
720         }
721
722         /**
723          * Getter for request instance
724          *
725          * @return      $requestInstance        An instance of a Requestable class
726          */
727         public final function getRequestInstance () {
728                 return $this->requestInstance;
729         }
730
731         /**
732          * Setter for response instance
733          *
734          * @param       $responseInstance       An instance of a Responseable class
735          * @return      void
736          */
737         public final function setResponseInstance (Responseable $responseInstance) {
738                 $this->responseInstance = $responseInstance;
739         }
740
741         /**
742          * Getter for response instance
743          *
744          * @return      $responseInstance       An instance of a Responseable class
745          */
746         public final function getResponseInstance () {
747                 return $this->responseInstance;
748         }
749
750         /**
751          * Private getter for language instance
752          *
753          * @return      $langInstance   An instance to the language sub-system
754          */
755         protected final function getLanguageInstance () {
756                 $langInstance = Registry::getRegistry()->getInstance('language');
757                 return $langInstance;
758         }
759
760         /**
761          * Setter for language instance
762          *
763          * @param       $langInstance   An instance to the language sub-system
764          * @return      void
765          * @see         LanguageSystem
766          */
767         public final function setLanguageInstance (ManageableLanguage $langInstance) {
768                 Registry::getRegistry()->addInstance('language', $langInstance);
769         }
770
771         /**
772          * Private getter for file IO instance
773          *
774          * @return      $fileIoInstance         An instance to the file I/O sub-system
775          */
776         protected final function getFileIoInstance () {
777                 return $this->fileIoInstance;
778         }
779
780         /**
781          * Setter for file I/O instance
782          *
783          * @param       $fileIoInstance         An instance to the file I/O sub-system
784          * @return      void
785          */
786         public final function setFileIoInstance (FileIoHandler $fileIoInstance) {
787                 $this->fileIoInstance = $fileIoInstance;
788         }
789
790         /**
791          * Protected setter for user instance
792          *
793          * @param       $userInstance   An instance of a user class
794          * @return      void
795          */
796         protected final function setUserInstance (ManageableAccount $userInstance) {
797                 $this->userInstance = $userInstance;
798         }
799
800         /**
801          * Getter for user instance
802          *
803          * @return      $userInstance   An instance of a user class
804          */
805         public final function getUserInstance () {
806                 return $this->userInstance;
807         }
808
809         /**
810          * Setter for controller instance (this surely breaks a bit the MVC patterm)
811          *
812          * @param       $controllerInstance             An instance of the controller
813          * @return      void
814          */
815         public final function setControllerInstance (Controller $controllerInstance) {
816                 $this->controllerInstance = $controllerInstance;
817         }
818
819         /**
820          * Getter for controller instance (this surely breaks a bit the MVC patterm)
821          *
822          * @return      $controllerInstance             An instance of the controller
823          */
824         public final function getControllerInstance () {
825                 return $this->controllerInstance;
826         }
827
828         /**
829          * Setter for RNG instance
830          *
831          * @param       $rngInstance    An instance of a random number generator (RNG)
832          * @return      void
833          */
834         protected final function setRngInstance (RandomNumberGenerator $rngInstance) {
835                 $this->rngInstance = $rngInstance;
836         }
837
838         /**
839          * Getter for RNG instance
840          *
841          * @return      $rngInstance    An instance of a random number generator (RNG)
842          */
843         public final function getRngInstance () {
844                 return $this->rngInstance;
845         }
846
847         /**
848          * Setter for Cryptable instance
849          *
850          * @param       $cryptoInstance An instance of a Cryptable class
851          * @return      void
852          */
853         protected final function setCryptoInstance (Cryptable $cryptoInstance) {
854                 $this->cryptoInstance = $cryptoInstance;
855         }
856
857         /**
858          * Getter for Cryptable instance
859          *
860          * @return      $cryptoInstance An instance of a Cryptable class
861          */
862         public final function getCryptoInstance () {
863                 return $this->cryptoInstance;
864         }
865
866         /**
867          * Setter for the list instance
868          *
869          * @param       $listInstance   A list of Listable
870          * @return      void
871          */
872         protected final function setListInstance (Listable $listInstance) {
873                 $this->listInstance = $listInstance;
874         }
875
876         /**
877          * Getter for the list instance
878          *
879          * @return      $listInstance   A list of Listable
880          */
881         protected final function getListInstance () {
882                 return $this->listInstance;
883         }
884
885         /**
886          * Setter for the menu instance
887          *
888          * @param       $menuInstance   A RenderableMenu instance
889          * @return      void
890          */
891         protected final function setMenuInstance (RenderableMenu $menuInstance) {
892                 $this->menuInstance = $menuInstance;
893         }
894
895         /**
896          * Getter for the menu instance
897          *
898          * @return      $menuInstance   A RenderableMenu instance
899          */
900         protected final function getMenuInstance () {
901                 return $this->menuInstance;
902         }
903
904         /**
905          * Setter for image instance
906          *
907          * @param       $imageInstance  An instance of an image
908          * @return      void
909          */
910         public final function setImageInstance (BaseImage $imageInstance) {
911                 $this->imageInstance = $imageInstance;
912         }
913
914         /**
915          * Getter for image instance
916          *
917          * @return      $imageInstance  An instance of an image
918          */
919         public final function getImageInstance () {
920                 return $this->imageInstance;
921         }
922
923         /**
924          * Setter for stacker instance
925          *
926          * @param       $stackerInstance        An instance of an stacker
927          * @return      void
928          */
929         public final function setStackerInstance (Stackable $stackerInstance) {
930                 $this->stackerInstance = $stackerInstance;
931         }
932
933         /**
934          * Getter for stacker instance
935          *
936          * @return      $stackerInstance        An instance of an stacker
937          */
938         public final function getStackerInstance () {
939                 return $this->stackerInstance;
940         }
941
942         /**
943          * Setter for compressor instance
944          *
945          * @param       $compressorInstance     An instance of an compressor
946          * @return      void
947          */
948         public final function setCompressorInstance (Compressor $compressorInstance) {
949                 $this->compressorInstance = $compressorInstance;
950         }
951
952         /**
953          * Getter for compressor instance
954          *
955          * @return      $compressorInstance     An instance of an compressor
956          */
957         public final function getCompressorInstance () {
958                 return $this->compressorInstance;
959         }
960
961         /**
962          * Setter for Parseable instance
963          *
964          * @param       $parserInstance An instance of an Parseable
965          * @return      void
966          */
967         public final function setParserInstance (Parseable $parserInstance) {
968                 $this->parserInstance = $parserInstance;
969         }
970
971         /**
972          * Getter for Parseable instance
973          *
974          * @return      $parserInstance An instance of an Parseable
975          */
976         public final function getParserInstance () {
977                 return $this->parserInstance;
978         }
979
980         /**
981          * Setter for ProtocolHandler instance
982          *
983          * @param       $protocolInstance       An instance of an ProtocolHandler
984          * @return      void
985          */
986         public final function setProtocolInstance (ProtocolHandler $protocolInstance = NULL) {
987                 $this->protocolInstance = $protocolInstance;
988         }
989
990         /**
991          * Getter for ProtocolHandler instance
992          *
993          * @return      $protocolInstance       An instance of an ProtocolHandler
994          */
995         public final function getProtocolInstance () {
996                 return $this->protocolInstance;
997         }
998
999         /**
1000          * Setter for DatabaseWrapper instance
1001          *
1002          * @param       $wrapperInstance        An instance of an DatabaseWrapper
1003          * @return      void
1004          */
1005         public final function setWrapperInstance (DatabaseWrapper $wrapperInstance) {
1006                 $this->wrapperInstance = $wrapperInstance;
1007         }
1008
1009         /**
1010          * Getter for DatabaseWrapper instance
1011          *
1012          * @return      $wrapperInstance        An instance of an DatabaseWrapper
1013          */
1014         public final function getWrapperInstance () {
1015                 return $this->wrapperInstance;
1016         }
1017
1018         /**
1019          * Setter for socket resource
1020          *
1021          * @param       $socketResource         A valid socket resource
1022          * @return      void
1023          */
1024         public final function setSocketResource ($socketResource) {
1025                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput($this->__toString() . '::' . __FUNCTION__ . ': socketResource=' . $socketResource . ',previous[' . gettype($this->socketResource) . ']=' . $this->socketResource);
1026                 $this->socketResource = $socketResource;
1027         }
1028
1029         /**
1030          * Getter for socket resource
1031          *
1032          * @return      $socketResource         A valid socket resource
1033          */
1034         public final function getSocketResource () {
1035                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput($this->__toString() . '::' . __FUNCTION__ . ': socketResource[' . gettype($this->socketResource) . ']=' . $this->socketResource);
1036                 return $this->socketResource;
1037         }
1038
1039         /**
1040          * Setter for helper instance
1041          *
1042          * @param       $helperInstance         An instance of a helper class
1043          * @return      void
1044          */
1045         protected final function setHelperInstance (Helper $helperInstance) {
1046                 $this->helperInstance = $helperInstance;
1047         }
1048
1049         /**
1050          * Getter for helper instance
1051          *
1052          * @return      $helperInstance         An instance of a helper class
1053          */
1054         public final function getHelperInstance () {
1055                 return $this->helperInstance;
1056         }
1057
1058         /**
1059          * Setter for a Sourceable instance
1060          *
1061          * @param       $sourceInstance The Sourceable instance
1062          * @return      void
1063          */
1064         protected final function setSourceInstance (Sourceable $sourceInstance) {
1065                 $this->sourceInstance = $sourceInstance;
1066         }
1067
1068         /**
1069          * Getter for a Sourceable instance
1070          *
1071          * @return      $sourceInstance The Sourceable instance
1072          */
1073         protected final function getSourceInstance () {
1074                 return $this->sourceInstance;
1075         }
1076
1077         /**
1078          * Getter for a InputStreamable instance
1079          *
1080          * @param       $inputStreamInstance    The InputStreamable instance
1081          */
1082         protected final function getInputStreamInstance () {
1083                 return $this->inputStreamInstance;
1084         }
1085
1086         /**
1087          * Setter for a InputStreamable instance
1088          *
1089          * @param       $inputStreamInstance    The InputStreamable instance
1090          * @return      void
1091          */
1092         protected final function setInputStreamInstance (InputStreamable $inputStreamInstance) {
1093                 $this->inputStreamInstance = $inputStreamInstance;
1094         }
1095
1096         /**
1097          * Getter for a OutputStreamable instance
1098          *
1099          * @param       $outputStreamInstance   The OutputStreamable instance
1100          */
1101         protected final function getOutputStreamInstance () {
1102                 return $this->outputStreamInstance;
1103         }
1104
1105         /**
1106          * Setter for a OutputStreamable instance
1107          *
1108          * @param       $outputStreamInstance   The OutputStreamable instance
1109          * @return      void
1110          */
1111         protected final function setOutputStreamInstance (OutputStreamable $outputStreamInstance) {
1112                 $this->outputStreamInstance = $outputStreamInstance;
1113         }
1114
1115         /**
1116          * Setter for handler instance
1117          *
1118          * @param       $handlerInstance        An instance of a Handleable class
1119          * @return      void
1120          */
1121         protected final function setHandlerInstance (Handleable $handlerInstance) {
1122                 $this->handlerInstance = $handlerInstance;
1123         }
1124
1125         /**
1126          * Getter for handler instance
1127          *
1128          * @return      $handlerInstance        A Networkable instance
1129          */
1130         protected final function getHandlerInstance () {
1131                 return $this->handlerInstance;
1132         }
1133
1134         /**
1135          * Setter for visitor instance
1136          *
1137          * @param       $visitorInstance        A Visitor instance
1138          * @return      void
1139          */
1140         protected final function setVisitorInstance (Visitor $visitorInstance) {
1141                 $this->visitorInstance = $visitorInstance;
1142         }
1143
1144         /**
1145          * Getter for visitor instance
1146          *
1147          * @return      $visitorInstance        A Visitor instance
1148          */
1149         protected final function getVisitorInstance () {
1150                 return $this->visitorInstance;
1151         }
1152
1153         /**
1154          * Setter for DHT instance
1155          *
1156          * @param       $dhtInstance    A Distributable instance
1157          * @return      void
1158          */
1159         protected final function setDhtInstance (Distributable $dhtInstance) {
1160                 $this->dhtInstance = $dhtInstance;
1161         }
1162
1163         /**
1164          * Getter for DHT instance
1165          *
1166          * @return      $dhtInstance    A Distributable instance
1167          */
1168         protected final function getDhtInstance () {
1169                 return $this->dhtInstance;
1170         }
1171
1172         /**
1173          * Setter for raw package Data
1174          *
1175          * @param       $packageData    Raw package Data
1176          * @return      void
1177          */
1178         public final function setPackageData (array $packageData) {
1179                 $this->packageData = $packageData;
1180         }
1181
1182         /**
1183          * Getter for raw package Data
1184          *
1185          * @return      $packageData    Raw package Data
1186          */
1187         public function getPackageData () {
1188                 return $this->packageData;
1189         }
1190
1191
1192         /**
1193          * Setter for Iterator instance
1194          *
1195          * @param       $iteratorInstance       An instance of an Iterator
1196          * @return      void
1197          */
1198         protected final function setIteratorInstance (Iterator $iteratorInstance) {
1199                 $this->iteratorInstance = $iteratorInstance;
1200         }
1201
1202         /**
1203          * Getter for Iterator instance
1204          *
1205          * @return      $iteratorInstance       An instance of an Iterator
1206          */
1207         public final function getIteratorInstance () {
1208                 return $this->iteratorInstance;
1209         }
1210
1211         /**
1212          * Checks whether an object equals this object. You should overwrite this
1213          * method to implement own equality checks
1214          *
1215          * @param       $objectInstance         An instance of a FrameworkInterface object
1216          * @return      $equals                         Whether both objects equals
1217          */
1218         public function equals (FrameworkInterface $objectInstance) {
1219                 // Now test it
1220                 $equals = ((
1221                         $this->__toString() == $objectInstance->__toString()
1222                 ) && (
1223                         $this->hashCode() == $objectInstance->hashCode()
1224                 ));
1225
1226                 // Return the result
1227                 return $equals;
1228         }
1229
1230         /**
1231          * Generates a generic hash code of this class. You should really overwrite
1232          * this method with your own hash code generator code. But keep KISS in mind.
1233          *
1234          * @return      $hashCode       A generic hash code respresenting this whole class
1235          */
1236         public function hashCode () {
1237                 // Simple hash code
1238                 return crc32($this->__toString());
1239         }
1240
1241         /**
1242          * Formats computer generated price values into human-understandable formats
1243          * with thousand and decimal separators.
1244          *
1245          * @param       $value          The in computer format value for a price
1246          * @param       $currency       The currency symbol (use HTML-valid characters!)
1247          * @param       $decNum         Number of decimals after commata
1248          * @return      $price          The for the current language formated price string
1249          * @throws      MissingDecimalsThousandsSeparatorException      If decimals or
1250          *                                                                                              thousands separator
1251          *                                                                                              is missing
1252          */
1253         public function formatCurrency ($value, $currency = '&euro;', $decNum = 2) {
1254                 // Are all required attriutes set?
1255                 if ((!isset($this->decimals)) || (!isset($this->thousands))) {
1256                         // Throw an exception
1257                         throw new MissingDecimalsThousandsSeparatorException($this, self::EXCEPTION_ATTRIBUTES_ARE_MISSING);
1258                 } // END - if
1259
1260                 // Cast the number
1261                 $value = (float) $value;
1262
1263                 // Reformat the US number
1264                 $price = number_format($value, $decNum, $this->decimals, $this->thousands) . $currency;
1265
1266                 // Return as string...
1267                 return $price;
1268         }
1269
1270         /**
1271          * Appends a trailing slash to a string
1272          *
1273          * @param       $str    A string (maybe) without trailing slash
1274          * @return      $str    A string with an auto-appended trailing slash
1275          */
1276         public final function addMissingTrailingSlash ($str) {
1277                 // Is there a trailing slash?
1278                 if (substr($str, -1, 1) != '/') {
1279                         $str .= '/';
1280                 } // END - if
1281
1282                 // Return string with trailing slash
1283                 return $str;
1284         }
1285
1286         /**
1287          * Prepare the template engine (WebTemplateEngine by default) for a given
1288          * application helper instance (ApplicationHelper by default).
1289          *
1290          * @param               $applicationInstance    An application helper instance or
1291          *                                                                              null if we shall use the default
1292          * @return              $templateInstance               The template engine instance
1293          * @throws              NullPointerException    If the discovered application
1294          *                                                                              instance is still null
1295          */
1296         protected function prepareTemplateInstance (ManageableApplication $applicationInstance = NULL) {
1297                 // Is the application instance set?
1298                 if (is_null($applicationInstance)) {
1299                         // Get the current instance
1300                         $applicationInstance = $this->getApplicationInstance();
1301
1302                         // Still null?
1303                         if (is_null($applicationInstance)) {
1304                                 // Thrown an exception
1305                                 throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
1306                         } // END - if
1307                 } // END - if
1308
1309                 // Initialize the template engine
1310                 $templateInstance = ObjectFactory::createObjectByConfiguredName('web_template_class');
1311
1312                 // Return the prepared instance
1313                 return $templateInstance;
1314         }
1315
1316         /**
1317          * Debugs this instance by putting out it's full content
1318          *
1319          * @param       $message        Optional message to show in debug output
1320          * @return      void
1321          */
1322         public final function debugInstance ($message = '') {
1323                 // Restore the error handler to avoid trouble with missing array elements or undeclared variables
1324                 restore_error_handler();
1325
1326                 // Init content
1327                 $content = '';
1328
1329                 // Is a message set?
1330                 if (!empty($message)) {
1331                         // Construct message
1332                         $content = sprintf("<div class=\"debug_message\">Message: %s</div>\n", $message);
1333                 } // END - if
1334
1335                 // Generate the output
1336                 $content .= sprintf("<pre>%s</pre>",
1337                         trim(
1338                                 htmlentities(
1339                                         print_r($this, true)
1340                                 )
1341                         )
1342                 );
1343
1344                 // Output it
1345                 ApplicationEntryPoint::app_exit(sprintf("<div class=\"debug_header\">%s debug output:</div><div class=\"debug_content\">%s</div>\nLoaded includes: <div class=\"debug_include_list\">%s</div>",
1346                         $this->__toString(),
1347                         $content,
1348                         ClassLoader::getSelfInstance()->getPrintableIncludeList()
1349                 ));
1350         }
1351
1352         /**
1353          * Replaces control characters with printable output
1354          *
1355          * @param       $str    String with control characters
1356          * @return      $str    Replaced string
1357          */
1358         protected function replaceControlCharacters ($str) {
1359                 // Replace them
1360                 $str = str_replace(
1361                         chr(13), '[r]', str_replace(
1362                         chr(10), '[n]', str_replace(
1363                         chr(9) , '[t]',
1364                         $str
1365                 )));
1366
1367                 // Return it
1368                 return $str;
1369         }
1370
1371         /**
1372          * Output a partial stub message for the caller method
1373          *
1374          * @param       $message        An optional message to display
1375          * @return      void
1376          */
1377         protected function partialStub ($message = '') {
1378                 // Get the backtrace
1379                 $backtrace = debug_backtrace();
1380
1381                 // Generate the class::method string
1382                 $methodName = 'UnknownClass-&gt;unknownMethod';
1383                 if ((isset($backtrace[1]['class'])) && (isset($backtrace[1]['function']))) {
1384                         $methodName = $backtrace[1]['class'] . '-&gt;' . $backtrace[1]['function'];
1385                 } // END - if
1386
1387                 // Construct the full message
1388                 $stubMessage = sprintf('[%s:] Partial stub!',
1389                         $methodName
1390                 );
1391
1392                 // Is the extra message given?
1393                 if (!empty($message)) {
1394                         // Then add it as well
1395                         $stubMessage .= ' Message: ' . $message;
1396                 } // END - if
1397
1398                 // Debug instance is there?
1399                 if (!is_null($this->getDebugInstance())) {
1400                         // Output stub message
1401                         self::createDebugInstance(__CLASS__)->debugOutput($stubMessage);
1402                 } else {
1403                         // Trigger an error
1404                         trigger_error($stubMessage);
1405                 }
1406         }
1407
1408         /**
1409          * Outputs a debug backtrace and stops further script execution
1410          *
1411          * @param       $message        An optional message to output
1412          * @param       $doExit         Whether exit the program (true is default)
1413          * @return      void
1414          */
1415         public function debugBackTrace ($message = '', $doExit = true) {
1416                 // Sorry, there is no other way getting this nice backtrace
1417                 if (!empty($message)) {
1418                         // Output message
1419                         printf('Message: %s<br />' . chr(10), $message);
1420                 } // END - if
1421
1422                 print('<pre>');
1423                 debug_print_backtrace();
1424                 print('</pre>');
1425
1426                 // Exit program?
1427                 if ($doExit === true) {
1428                         exit();
1429                 } // END - if
1430         }
1431
1432         /**
1433          * Creates an instance of a debugger instance
1434          *
1435          * @param       $className              Name of the class (currently unsupported)
1436          * @return      $debugInstance  An instance of a debugger class
1437          */
1438         public final static function createDebugInstance ($className) {
1439                 // Init debug instance
1440                 $debugInstance = NULL;
1441
1442                 // Try it
1443                 try {
1444                         // Get a debugger instance
1445                         $debugInstance = DebugMiddleware::createDebugMiddleware(FrameworkConfiguration::getSelfInstance()->getConfigEntry('debug_class'));
1446                 } catch (NullPointerException $e) {
1447                         // Didn't work, no instance there
1448                         exit('Cannot create debugInstance! Exception=' . $e->__toString() . ', message=' . $e->getMessage());
1449                 }
1450
1451                 // Empty string should be ignored and used for testing the middleware
1452                 DebugMiddleware::getSelfInstance()->output('');
1453
1454                 // Return it
1455                 return $debugInstance;
1456         }
1457
1458         /**
1459          * Outputs a debug message whether to debug instance (should be set!) or
1460          * dies with or ptints the message. Do NEVER EVER rewrite the exit() call to
1461          * ApplicationEntryPoint::app_exit(), this would cause an endless loop.
1462          *
1463          * @param       $message        Message we shall send out...
1464          * @param       $doPrint        Whether print or die here (default: print)
1465          * @paran       $stripTags      Whether to strip tags (default: false)
1466          * @return      void
1467          */
1468         public function debugOutput ($message, $doPrint = true, $stripTags = false) {
1469                 // Set debug instance to NULL
1470                 $debugInstance = NULL;
1471
1472                 // Try it:
1473                 try {
1474                         // Get debug instance
1475                         $debugInstance = $this->getDebugInstance();
1476                 } catch (NullPointerException $e) {
1477                         // The debug instance is not set (yet)
1478                 }
1479
1480                 // Is the debug instance there?
1481                 if (is_object($debugInstance)) {
1482                         // Use debug output handler
1483                         $debugInstance->output($message, $stripTags);
1484
1485                         if ($doPrint === false) {
1486                                 // Die here if not printed
1487                                 exit();
1488                         } // END - if
1489                 } else {
1490                         // Are debug times enabled?
1491                         if ($this->getConfigInstance()->getConfigEntry('debug_output_timings') == 'Y') {
1492                                 // Prepent it
1493                                 $message = $this->getPrintableExecutionTime() . $message;
1494                         } // END - if
1495
1496                         // Put directly out
1497                         if ($doPrint === true) {
1498                                 // Print message
1499                                 print($message . chr(10));
1500                         } else {
1501                                 // Die here
1502                                 exit($message);
1503                         }
1504                 }
1505         }
1506
1507         /**
1508          * Converts e.g. a command from URL to a valid class by keeping out bad characters
1509          *
1510          * @param       $str            The string, what ever it is needs to be converted
1511          * @return      $className      Generated class name
1512          */
1513         public function convertToClassName ($str) {
1514                 // Init class name
1515                 $className = '';
1516
1517                 // Convert all dashes in underscores
1518                 $str = $this->convertDashesToUnderscores($str);
1519
1520                 // Now use that underscores to get classname parts for hungarian style
1521                 foreach (explode('_', $str) as $strPart) {
1522                         // Make the class name part lower case and first upper case
1523                         $className .= ucfirst(strtolower($strPart));
1524                 } // END - foreach
1525
1526                 // Return class name
1527                 return $className;
1528         }
1529
1530         /**
1531          * Converts dashes to underscores, e.g. useable for configuration entries
1532          *
1533          * @param       $str    The string with maybe dashes inside
1534          * @return      $str    The converted string with no dashed, but underscores
1535          */
1536         public final function convertDashesToUnderscores ($str) {
1537                 // Convert them all
1538                 $str = str_replace('-', '_', $str);
1539
1540                 // Return converted string
1541                 return $str;
1542         }
1543
1544         /**
1545          * Marks up the code by adding e.g. line numbers
1546          *
1547          * @param       $phpCode                Unmarked PHP code
1548          * @return      $markedCode             Marked PHP code
1549          */
1550         public function markupCode ($phpCode) {
1551                 // Init marked code
1552                 $markedCode = '';
1553
1554                 // Get last error
1555                 $errorArray = error_get_last();
1556
1557                 // Init the code with error message
1558                 if (is_array($errorArray)) {
1559                         // Get error infos
1560                         $markedCode = sprintf('<div id="error_header">File: <span id="error_data">%s</span>, Line: <span id="error_data">%s</span>, Message: <span id="error_data">%s</span>, Type: <span id="error_data">%s</span></div>',
1561                                 basename($errorArray['file']),
1562                                 $errorArray['line'],
1563                                 $errorArray['message'],
1564                                 $errorArray['type']
1565                         );
1566                 } // END - if
1567
1568                 // Add line number to the code
1569                 foreach (explode(chr(10), $phpCode) as $lineNo => $code) {
1570                         // Add line numbers
1571                         $markedCode .= sprintf('<span id="code_line">%s</span>: %s' . chr(10),
1572                                 ($lineNo + 1),
1573                                 htmlentities($code, ENT_QUOTES)
1574                         );
1575                 } // END - foreach
1576
1577                 // Return the code
1578                 return $markedCode;
1579         }
1580
1581         /**
1582          * Filter a given GMT timestamp (non Uni* stamp!) to make it look more
1583          * beatiful for web-based front-ends. If null is given a message id
1584          * null_timestamp will be resolved and returned.
1585          *
1586          * @param       $timestamp      Timestamp to prepare (filter) for display
1587          * @return      $readable       A readable timestamp
1588          */
1589         public function doFilterFormatTimestamp ($timestamp) {
1590                 // Default value to return
1591                 $readable = '???';
1592
1593                 // Is the timestamp null?
1594                 if (is_null($timestamp)) {
1595                         // Get a message string
1596                         $readable = $this->getLanguageInstance()->getMessage('null_timestamp');
1597                 } else {
1598                         switch ($this->getLanguageInstance()->getLanguageCode()) {
1599                                 case 'de': // German format is a bit different to default
1600                                         // Split the GMT stamp up
1601                                         $dateTime  = explode(' ', $timestamp  );
1602                                         $dateArray = explode('-', $dateTime[0]);
1603                                         $timeArray = explode(':', $dateTime[1]);
1604
1605                                         // Construct the timestamp
1606                                         $readable = sprintf($this->getConfigInstance()->getConfigEntry('german_date_time'),
1607                                                 $dateArray[0],
1608                                                 $dateArray[1],
1609                                                 $dateArray[2],
1610                                                 $timeArray[0],
1611                                                 $timeArray[1],
1612                                                 $timeArray[2]
1613                                         );
1614                                         break;
1615
1616                                 default: // Default is pass-through
1617                                         $readable = $timestamp;
1618                                         break;
1619                         } // END - switch
1620                 }
1621
1622                 // Return the stamp
1623                 return $readable;
1624         }
1625
1626         /**
1627          * Filter a given number into a localized number
1628          *
1629          * @param       $value          The raw value from e.g. database
1630          * @return      $localized      Localized value
1631          */
1632         public function doFilterFormatNumber ($value) {
1633                 // Generate it from config and localize dependencies
1634                 switch ($this->getLanguageInstance()->getLanguageCode()) {
1635                         case 'de': // German format is a bit different to default
1636                                 $localized = number_format($value, $this->getConfigInstance()->getConfigEntry('decimals'), ',', '.');
1637                                 break;
1638
1639                         default: // US, etc.
1640                                 $localized = number_format($value, $this->getConfigInstance()->getConfigEntry('decimals'), '.', ',');
1641                                 break;
1642                 } // END - switch
1643
1644                 // Return it
1645                 return $localized;
1646         }
1647
1648         /**
1649          * "Getter" for databse entry
1650          *
1651          * @return      $entry  An array with database entries
1652          * @throws      NullPointerException    If the database result is not found
1653          * @throws      InvalidDatabaseResultException  If the database result is invalid
1654          */
1655         protected final function getDatabaseEntry () {
1656                 // Is there an instance?
1657                 if (is_null($this->getResultInstance())) {
1658                         // Throw an exception here
1659                         throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
1660                 } // END - if
1661
1662                 // Rewind it
1663                 $this->getResultInstance()->rewind();
1664
1665                 // Do we have an entry?
1666                 if ($this->getResultInstance()->valid() === false) {
1667                         throw new InvalidDatabaseResultException(array($this, $this->getResultInstance()), DatabaseResult::EXCEPTION_INVALID_DATABASE_RESULT);
1668                 } // END - if
1669
1670                 // Get next entry
1671                 $this->getResultInstance()->next();
1672
1673                 // Fetch it
1674                 $entry = $this->getResultInstance()->current();
1675
1676                 // And return it
1677                 return $entry;
1678         }
1679
1680         /**
1681          * Getter for field name
1682          *
1683          * @param       $fieldName              Field name which we shall get
1684          * @return      $fieldValue             Field value from the user
1685          * @throws      NullPointerException    If the result instance is null
1686          */
1687         public final function getField ($fieldName) {
1688                 // Default field value
1689                 $fieldValue = NULL;
1690
1691                 // Get result instance
1692                 $resultInstance = $this->getResultInstance();
1693
1694                 // Is this instance null?
1695                 if (is_null($resultInstance)) {
1696                         // Then the user instance is no longer valid (expired cookies?)
1697                         throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
1698                 } // END - if
1699
1700                 // Get current array
1701                 $fieldArray = $resultInstance->current();
1702                 //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput($fieldName.':<pre>'.print_r($fieldArray, true).'</pre>');
1703
1704                 // Convert dashes to underscore
1705                 $fieldName = $this->convertDashesToUnderscores($fieldName);
1706
1707                 // Does the field exist?
1708                 if (isset($fieldArray[$fieldName])) {
1709                         // Get it
1710                         $fieldValue = $fieldArray[$fieldName];
1711                 } else {
1712                         // Missing field entry, may require debugging
1713                         self::createDebugInstance(__CLASS__)->debugOutput($this->__toString() . ':fieldname=' . $fieldName . ' not found!');
1714                 }
1715
1716                 // Return it
1717                 return $fieldValue;
1718         }
1719
1720         /**
1721          * Flushs all pending updates to the database layer
1722          *
1723          * @return      void
1724          */
1725         public function flushPendingUpdates () {
1726                 // Get result instance
1727                 $resultInstance = $this->getResultInstance();
1728
1729                 // Do we have data to update?
1730                 if ((is_object($resultInstance)) && ($resultInstance->ifDataNeedsFlush())) {
1731                         // Get wrapper class name config entry
1732                         $configEntry = $resultInstance->getUpdateInstance()->getWrapperConfigEntry();
1733
1734                         // Create object instance
1735                         $wrapperInstance = ObjectFactory::createObjectByConfiguredName($configEntry);
1736
1737                         // Yes, then send the whole result to the database layer
1738                         $wrapperInstance->doUpdateByResult($this->getResultInstance());
1739                 } // END - if
1740         }
1741
1742         /**
1743          * Outputs a deprecation warning to the developer.
1744          *
1745          * @param       $message        The message we shall output to the developer
1746          * @return      void
1747          * @todo        Write a logging mechanism for productive mode
1748          */
1749         public function deprecationWarning ($message) {
1750                 // Is developer mode active?
1751                 if (defined('DEVELOPER')) {
1752                         // Debug instance is there?
1753                         if (!is_null($this->getDebugInstance())) {
1754                                 // Output stub message
1755                                 self::createDebugInstance(__CLASS__)->debugOutput($message);
1756                         } else {
1757                                 // Trigger an error
1758                                 trigger_error($message . "<br />\n");
1759                         }
1760                 } else {
1761                         // @TODO Finish this part!
1762                         $this->partialStub('Developer mode inactive. Message:' . $message);
1763                 }
1764         }
1765
1766         /**
1767          * Checks whether the given PHP extension is loaded
1768          *
1769          * @param       $phpExtension   The PHP extension we shall check
1770          * @return      $isLoaded       Whether the PHP extension is loaded
1771          */
1772         public final function isPhpExtensionLoaded ($phpExtension) {
1773                 // Is it loaded?
1774                 $isLoaded = in_array($phpExtension, get_loaded_extensions());
1775
1776                 // Return result
1777                 return $isLoaded;
1778         }
1779
1780         /**
1781          * "Getter" as a time() replacement but with milliseconds. You should use this
1782          * method instead of the encapsulated getimeofday() function.
1783          *
1784          * @return      $milliTime      Timestamp with milliseconds
1785          */
1786         public function getMilliTime () {
1787                 // Get the time of day as float
1788                 $milliTime = gettimeofday(true);
1789
1790                 // Return it
1791                 return $milliTime;
1792         }
1793
1794         /**
1795          * Idles (sleeps) for given milliseconds
1796          *
1797          * @return      $hasSlept       Whether it goes fine
1798          */
1799         public function idle ($milliSeconds) {
1800                 // Sleep is fine by default
1801                 $hasSlept = true;
1802
1803                 // Idle so long with found function
1804                 if (function_exists('time_sleep_until')) {
1805                         // Get current time and add idle time
1806                         $sleepUntil = $this->getMilliTime() + abs($milliSeconds) / 1000;
1807
1808                         // New PHP 5.1.0 function found, ignore errors
1809                         $hasSlept = @time_sleep_until($sleepUntil);
1810                 } else {
1811                         /*
1812                          * My Sun station doesn't have that function even with latest PHP
1813                          * package. :(
1814                          */
1815                         usleep($milliSeconds * 1000);
1816                 }
1817
1818                 // Return result
1819                 return $hasSlept;
1820         }
1821         /**
1822          * Converts a hexadecimal string, even with negative sign as first string to
1823          * a decimal number using BC functions.
1824          *
1825          * This work is based on comment #86673 on php.net documentation page at:
1826          * <http://de.php.net/manual/en/function.dechex.php#86673>
1827          *
1828          * @param       $hex    Hexadecimal string
1829          * @return      $dec    Decimal number
1830          */
1831         protected function hex2dec ($hex) {
1832                 // Convert to all lower-case
1833                 $hex = strtolower($hex);
1834
1835                 // Detect sign (negative/positive numbers)
1836                 $sign = '';
1837                 if (substr($hex, 0, 1) == '-') {
1838                         $sign = '-';
1839                         $hex = substr($hex, 1);
1840                 } // END - if
1841
1842                 // Decode the hexadecimal string into a decimal number
1843                 $dec = 0;
1844                 for ($i = strlen($hex) - 1, $e = 1; $i >= 0; $i--, $e = bcmul($e, 16)) {
1845                         $factor = self::$hexdec[substr($hex, $i, 1)];
1846                         $dec = bcadd($dec, bcmul($factor, $e));
1847                 } // END - for
1848
1849                 // Return the decimal number
1850                 return $sign . $dec;
1851         }
1852
1853         /**
1854          * Converts even very large decimal numbers, also signed, to a hexadecimal
1855          * string.
1856          *
1857          * This work is based on comment #97756 on php.net documentation page at:
1858          * <http://de.php.net/manual/en/function.hexdec.php#97756>
1859          *
1860          * @param       $dec            Decimal number, even with negative sign
1861          * @param       $maxLength      Optional maximum length of the string
1862          * @return      $hex    Hexadecimal string
1863          */
1864         protected function dec2hex ($dec, $maxLength = 0) {
1865                 // maxLength can be zero or devideable by 2
1866                 assert(($maxLength == 0) || (($maxLength % 2) == 0));
1867
1868                 // Detect sign (negative/positive numbers)
1869                 $sign = '';
1870                 if ($dec < 0) {
1871                         $sign = '-';
1872                         $dec = abs($dec);
1873                 } // END - if
1874
1875                 // Encode the decimal number into a hexadecimal string
1876                 $hex = '';
1877                 do {
1878                         $hex = self::$dechex[($dec % (2 ^ 4))] . $hex;
1879                         $dec /= (2 ^ 4);
1880                 } while ($dec >= 1);
1881
1882                 /*
1883                  * Leading zeros are required for hex-decimal "numbers". In some
1884                  * situations more leading zeros are wanted, so check for both
1885                  * conditions.
1886                  */
1887                 if ($maxLength > 0) {
1888                         // Prepend more zeros
1889                         $hex = str_pad($hex, $maxLength, '0', STR_PAD_LEFT);
1890                 } elseif ((strlen($hex) % 2) != 0) {
1891                         // Only make string's length dividable by 2
1892                         $hex = '0' . $hex;
1893                 }
1894
1895                 // Return the hexadecimal string
1896                 return $sign . $hex;
1897         }
1898
1899         /**
1900          * Converts a ASCII string (0 to 255) into a decimal number.
1901          *
1902          * @param       $asc    The ASCII string to be converted
1903          * @return      $dec    Decimal number
1904          */
1905         protected function asc2dec ($asc) {
1906                 // Convert it into a hexadecimal number
1907                 $hex = bin2hex($asc);
1908
1909                 // And back into a decimal number
1910                 $dec = $this->hex2dec($hex);
1911
1912                 // Return it
1913                 return $dec;
1914         }
1915
1916         /**
1917          * Converts a decimal number into an ASCII string.
1918          *
1919          * @param       $dec            Decimal number
1920          * @return      $asc    An ASCII string
1921          */
1922         protected function dec2asc ($dec) {
1923                 // First convert the number into a hexadecimal string
1924                 $hex = $this->dec2hex($dec);
1925
1926                 // Then convert it into the ASCII string
1927                 $asc = $this->hex2asc($hex);
1928
1929                 // Return it
1930                 return $asc;
1931         }
1932
1933         /**
1934          * Converts a hexadecimal number into an ASCII string. Negative numbers
1935          * are not allowed.
1936          *
1937          * @param       $hex    Hexadecimal string
1938          * @return      $asc    An ASCII string
1939          */
1940         protected function hex2asc ($hex) {
1941                 // Check for length, it must be devideable by 2
1942                 //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('hex='.$hex);
1943                 assert((strlen($hex) % 2) == 0);
1944
1945                 // Walk the string
1946                 $asc = '';
1947                 for ($idx = 0; $idx < strlen($hex); $idx+=2) {
1948                         // Get the decimal number of the chunk
1949                         $part = hexdec(substr($hex, $idx, 2));
1950
1951                         // Add it to the final string
1952                         $asc .= chr($part);
1953                 } // END - for
1954
1955                 // Return the final string
1956                 return $asc;
1957         }
1958
1959         /**
1960          * Checks whether the given encoded data was encoded with Base64
1961          *
1962          * @param       $encodedData    Encoded data we shall check
1963          * @return      $isBase64               Whether the encoded data is Base64
1964          */
1965         protected function isBase64Encoded ($encodedData) {
1966                 // Determine it
1967                 $isBase64 = (@base64_decode($encodedData, true) !== false);
1968
1969                 // Return it
1970                 return $isBase64;
1971         }
1972
1973         /**
1974          * "Getter" to get response/request type from analysis of the system.
1975          *
1976          * @return      $responseType   Analyzed response type
1977          */
1978         protected function getResponseTypeFromSystem () {
1979                 // Default is console
1980                 $responseType = 'console';
1981
1982                 // Is 'HTTP_HOST' set?
1983                 if (isset($_SERVER['HTTP_HOST'])) {
1984                         // Then it is a HTTP response/request
1985                         $responseType = 'http';
1986                 } // END - if
1987
1988                 // Return it
1989                 return $responseType;
1990         }
1991
1992         /**
1993          * Gets a cache key from Criteria instance
1994          *
1995          * @param       $criteriaInstance       An instance of a Criteria class
1996          * @param       $onlyKeys                       Only use these keys for a cache key
1997          * @return      $cacheKey                       A cache key suitable for lookup/storage purposes
1998          */
1999         protected function getCacheKeyByCriteria (Criteria $criteriaInstance, array $onlyKeys = array()) {
2000                 // Generate it
2001                 $cacheKey = sprintf("%s@%s",
2002                         $this->__toString(),
2003                         $criteriaInstance->getCacheKey($onlyKeys)
2004                 );
2005
2006                 // And return it
2007                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput($this->__toString() . ': cacheKey=' . $cacheKey);
2008                 return $cacheKey;
2009         }
2010
2011         /**
2012          * Getter for startup time in miliseconds
2013          *
2014          * @return      $startupTime    Startup time in miliseconds
2015          */
2016         protected function getStartupTime () {
2017                 return self::$startupTime;
2018         }
2019
2020         /**
2021          * "Getter" for a printable currently execution time in nice braces
2022          *
2023          * @return      $executionTime  Current execution time in nice braces
2024          */
2025         protected function getPrintableExecutionTime () {
2026                 // Caculate the execution time
2027                 $executionTime = microtime(true) - $this->getStartupTime();
2028
2029                 // Pack it in nice braces
2030                 $executionTime = sprintf('[ %01.5f ] ', $executionTime);
2031
2032                 // And return it
2033                 return $executionTime;
2034         }
2035
2036         /**
2037          * Hashes a given string with a simple but stronger hash function (no salts)
2038          *
2039          * @param       $str    The string to be hashed
2040          * @return      $hash   The hash from string $str
2041          */
2042         public function hashString ($str) {
2043                 // Hash given string with (better secure) hasher
2044                 $hash = mhash(MHASH_SHA256, $str);
2045
2046                 // Return it
2047                 return $hash;
2048         }
2049
2050         /**
2051          * Checks whether the given number is really a number (only chars 0-9).
2052          *
2053          * @param       $num            A string consisting only chars between 0 and 9
2054          * @param       $castValue      Whether to cast the value to double. Do only use this to secure numbers from Requestable classes.
2055          * @param       $assertMismatch         Whether to assert mismatches
2056          * @return      $ret            The (hopefully) secured numbered value
2057          */
2058         public function bigintval ($num, $castValue = true, $assertMismatch = false) {
2059                 // Filter all numbers out
2060                 $ret = preg_replace('/[^0123456789]/', '', $num);
2061
2062                 // Shall we cast?
2063                 if ($castValue === true) {
2064                         // Cast to biggest numeric type
2065                         $ret = (double) $ret;
2066                 } // END - if
2067
2068                 // Assert only if requested
2069                 if ($assertMismatch === true) {
2070                         // Has the whole value changed?
2071                         assert(('' . $ret . '' != '' . $num . '') && (!is_null($num)));
2072                 } // END - if
2073
2074                 // Return result
2075                 return $ret;
2076         }
2077
2078         /**
2079          * Checks whether the given hexadecimal number is really a hex-number (only chars 0-9,a-f).
2080          *
2081          * @param       $num    A string consisting only chars between 0 and 9
2082          * @param       $assertMismatch         Whether to assert mismatches
2083          * @return      $ret    The (hopefully) secured hext-numbered value
2084          */
2085         public function hexval ($num, $assertMismatch = false) {
2086                 // Filter all numbers out
2087                 $ret = preg_replace('/[^0123456789abcdefABCDEF]/', '', $num);
2088
2089                 // Assert only if requested
2090                 if ($assertMismatch === true) {
2091                         // Has the whole value changed?
2092                         assert(('' . $ret . '' != '' . $num . '') && (!is_null($num)));
2093                 } // END - if
2094
2095                 // Return result
2096                 return $ret;
2097         }
2098
2099         /**
2100          * Checks whether start/end marker are set
2101          *
2102          * @param       $data   Data to be checked
2103          * @return      $isset  Whether start/end marker are set
2104          */
2105         public final function ifStartEndMarkersSet ($data) {
2106                 // Determine it
2107                 $isset = ((substr($data, 0, strlen(BaseRawDataHandler::STREAM_START_MARKER)) == BaseRawDataHandler::STREAM_START_MARKER) && (substr($data, -1 * strlen(BaseRawDataHandler::STREAM_END_MARKER), strlen(BaseRawDataHandler::STREAM_END_MARKER)) == BaseRawDataHandler::STREAM_END_MARKER));
2108
2109                 // ... and return it
2110                 return $isset;
2111         }
2112 }
2113
2114 // [EOF]
2115 ?>