]> git.mxchange.org Git - core.git/blob - inc/classes/main/class_BaseFrameworkSystem.php
47282b389ad847ce13769c57fce125fb019a8386
[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@shipsimu.org>
7  * @version             0.0.0
8  * @copyright   Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2013 Core Developer Team
9  * @license             GNU GPL 3.0 or any newer version
10  * @link                http://www.shipsimu.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 InputStream class
148          */
149         private $inputStreamInstance = NULL;
150
151         /**
152          * An instance of a OutputStream 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          * An instance of a file I/O pointer class (not handler)
178          */
179         private $pointerInstance = NULL;
180
181         /**
182          * Thousands separator
183          */
184         private $thousands = '.'; // German
185
186         /**
187          * Decimal separator
188          */
189         private $decimals  = ','; // German
190
191         /**
192          * Socket resource
193          */
194         private $socketResource = FALSE;
195
196         /**
197          * Package data
198          */
199         private $packageData = array();
200
201         /**
202          * Generic array
203          */
204         private $genericArray = array();
205
206         /**
207          * Length of output from hash()
208          */
209         private static $hashLength = NULL;
210
211         /***********************
212          * Exception codes.... *
213          ***********************/
214
215         // @todo Try to clean these constants up
216         const EXCEPTION_IS_NULL_POINTER              = 0x001;
217         const EXCEPTION_IS_NO_OBJECT                 = 0x002;
218         const EXCEPTION_IS_NO_ARRAY                  = 0x003;
219         const EXCEPTION_MISSING_METHOD               = 0x004;
220         const EXCEPTION_CLASSES_NOT_MATCHING         = 0x005;
221         const EXCEPTION_INDEX_OUT_OF_BOUNDS          = 0x006;
222         const EXCEPTION_DIMENSION_ARRAY_INVALID      = 0x007;
223         const EXCEPTION_ITEM_NOT_TRADEABLE           = 0x008;
224         const EXCEPTION_ITEM_NOT_IN_PRICE_LIST       = 0x009;
225         const EXCEPTION_GENDER_IS_WRONG              = 0x00a;
226         const EXCEPTION_BIRTH_DATE_IS_INVALID        = 0x00b;
227         const EXCEPTION_EMPTY_STRUCTURES_ARRAY       = 0x00c;
228         const EXCEPTION_HAS_ALREADY_PERSONELL_LIST   = 0x00d;
229         const EXCEPTION_NOT_ENOUGTH_UNEMPLOYEES      = 0x00e;
230         const EXCEPTION_TOTAL_PRICE_NOT_CALCULATED   = 0x00f;
231         const EXCEPTION_HARBOR_HAS_NO_SHIPYARDS      = 0x010;
232         const EXCEPTION_CONTRACT_PARTNER_INVALID     = 0x011;
233         const EXCEPTION_CONTRACT_PARTNER_MISMATCH    = 0x012;
234         const EXCEPTION_CONTRACT_ALREADY_SIGNED      = 0x013;
235         const EXCEPTION_UNEXPECTED_EMPTY_STRING      = 0x014;
236         const EXCEPTION_PATH_NOT_FOUND               = 0x015;
237         const EXCEPTION_INVALID_PATH_NAME            = 0x016;
238         const EXCEPTION_READ_PROTECED_PATH           = 0x017;
239         const EXCEPTION_WRITE_PROTECED_PATH          = 0x018;
240         const EXCEPTION_DIR_POINTER_INVALID          = 0x019;
241         const EXCEPTION_FILE_POINTER_INVALID         = 0x01a;
242         const EXCEPTION_INVALID_RESOURCE             = 0x01b;
243         const EXCEPTION_UNEXPECTED_OBJECT            = 0x01c;
244         const EXCEPTION_LIMIT_ELEMENT_IS_UNSUPPORTED = 0x01d;
245         const EXCEPTION_GETTER_IS_MISSING            = 0x01e;
246         const EXCEPTION_ARRAY_EXPECTED               = 0x01f;
247         const EXCEPTION_ARRAY_HAS_INVALID_COUNT      = 0x020;
248         const EXCEPTION_ID_IS_INVALID_FORMAT         = 0x021;
249         const EXCEPTION_MD5_CHECKSUMS_MISMATCH       = 0x022;
250         const EXCEPTION_UNEXPECTED_STRING_SIZE       = 0x023;
251         const EXCEPTION_SIMULATOR_ID_INVALID         = 0x024;
252         const EXCEPTION_MISMATCHING_COMPRESSORS      = 0x025;
253         const EXCEPTION_CONTAINER_ITEM_IS_NULL       = 0x026;
254         const EXCEPTION_ITEM_IS_NO_ARRAY             = 0x027;
255         const EXCEPTION_CONTAINER_MAYBE_DAMAGED      = 0x028;
256         const EXCEPTION_INVALID_STRING               = 0x029;
257         const EXCEPTION_VARIABLE_NOT_SET             = 0x02a;
258         const EXCEPTION_ATTRIBUTES_ARE_MISSING       = 0x02b;
259         const EXCEPTION_ARRAY_ELEMENTS_MISSING       = 0x02c;
260         const EXCEPTION_TEMPLATE_ENGINE_UNSUPPORTED  = 0x02d;
261         const EXCEPTION_UNSPPORTED_OPERATION         = 0x02e;
262         const EXCEPTION_FACTORY_REQUIRE_PARAMETER    = 0x02f;
263         const EXCEPTION_MISSING_ELEMENT              = 0x030;
264         const EXCEPTION_HEADERS_ALREADY_SENT         = 0x031;
265         const EXCEPTION_DEFAULT_CONTROLLER_GONE      = 0x032;
266         const EXCEPTION_CLASS_NOT_FOUND              = 0x033;
267         const EXCEPTION_REQUIRED_INTERFACE_MISSING   = 0x034;
268         const EXCEPTION_FATAL_ERROR                  = 0x035;
269         const EXCEPTION_FILE_NOT_FOUND               = 0x036;
270         const EXCEPTION_ASSERTION_FAILED             = 0x037;
271         const EXCEPTION_FILE_CANNOT_BE_READ          = 0x038;
272         const EXCEPTION_DATABASE_UPDATED_NOT_ALLOWED = 0x039;
273         const EXCEPTION_FILTER_CHAIN_INTERCEPTED     = 0x03a;
274
275         /**
276          * Hexadecimal->Decimal translation array
277          */
278         private static $hexdec = array(
279                 '0' => 0,
280                 '1' => 1,
281                 '2' => 2,
282                 '3' => 3,
283                 '4' => 4,
284                 '5' => 5,
285                 '6' => 6,
286                 '7' => 7,
287                 '8' => 8,
288                 '9' => 9,
289                 'a' => 10,
290                 'b' => 11,
291                 'c' => 12,
292                 'd' => 13,
293                 'e' => 14,
294                 'f' => 15
295         );
296
297         /**
298          * Decimal->hexadecimal translation array
299          */
300         private static $dechex = array(
301                  0 => '0',
302                  1 => '1',
303                  2 => '2',
304                  3 => '3',
305                  4 => '4',
306                  5 => '5',
307                  6 => '6',
308                  7 => '7',
309                  8 => '8',
310                  9 => '9',
311                 10 => 'a',
312                 11 => 'b',
313                 12 => 'c',
314                 13 => 'd',
315                 14 => 'e',
316                 15 => 'f'
317         );
318
319         /**
320          * Startup time in miliseconds
321          */
322         private static $startupTime = 0;
323
324         /**
325          * Protected super constructor
326          *
327          * @param       $className      Name of the class
328          * @return      void
329          */
330         protected function __construct ($className) {
331                 // Set real class
332                 $this->setRealClass($className);
333
334                 // Set configuration instance if no registry ...
335                 if (!$this instanceof Register) {
336                         // ... because registries doesn't need to be configured
337                         $this->setConfigInstance(FrameworkConfiguration::getSelfInstance());
338                 } // END - if
339
340                 // Is the startup time set? (0 cannot be TRUE anymore)
341                 if (self::$startupTime == 0) {
342                         // Then set it
343                         self::$startupTime = microtime(TRUE);
344                 } // END - if
345         }
346
347         /**
348          * Destructor for all classes
349          *
350          * @return      void
351          */
352         public function __destruct () {
353                 // Flush any updated entries to the database
354                 $this->flushPendingUpdates();
355
356                 // Is this object already destroyed?
357                 if ($this->__toString() != 'DestructedObject') {
358                         // Destroy all informations about this class but keep some text about it alive
359                         $this->setRealClass('DestructedObject');
360                 } elseif ((defined('DEBUG_DESTRUCTOR')) && (is_object($this->getDebugInstance()))) {
361                         // Already destructed object
362                         self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:] The object <span class="object_name">%s</span> is already destroyed.',
363                                 __CLASS__,
364                                 $this->__toString()
365                         ));
366                 } else {
367                         // Do not call this twice
368                         trigger_error(__METHOD__ . ': Called twice.');
369                         exit;
370                 }
371         }
372
373         /**
374          * The __call() method where all non-implemented methods end up
375          *
376          * @param       $methodName             Name of the missing method
377          * @args        $args                   Arguments passed to the method
378          * @return      void
379          */
380         public final function __call ($methodName, $args) {
381                 return self::__callStatic($methodName, $args);
382         }
383
384         /**
385          * The __callStatic() method where all non-implemented static methods end up
386          *
387          * @param       $methodName             Name of the missing method
388          * @args        $args                   Arguments passed to the method
389          * @return      void
390          */
391         public static final function __callStatic ($methodName, $args) {
392                 // Init argument string
393                 $argsString = '';
394
395                 // Is it empty or an array?
396                 if (empty($args)) {
397                         // No arguments
398                         $argsString = 'NULL';
399                 } elseif (is_array($args)) {
400                         // Some arguments are there
401                         foreach ($args as $arg) {
402                                 // Add the value itself if not array. This prevents 'array to string conversion' message
403                                 if (is_array($arg)) {
404                                         $argsString .= 'Array';
405                                 } else {
406                                         $argsString .= $arg;
407                                 }
408
409                                 // Add data about the argument
410                                 $argsString .= ' (' . gettype($arg);
411
412                                 if (is_string($arg)) {
413                                         // Add length for strings
414                                         $argsString .= ', ' . strlen($arg);
415                                 } elseif (is_array($arg)) {
416                                         // .. or size if array
417                                         $argsString .= ', ' . count($arg);
418                                 } elseif ($arg === TRUE) {
419                                         // ... is boolean 'TRUE'
420                                         $argsString .= ', TRUE';
421                                 } elseif ($arg === FALSE) {
422                                         // ... is boolean 'FALSE'
423                                         $argsString .= ', FALSE';
424                                 }
425
426                                 // Closing bracket
427                                 $argsString .= '), ';
428                         } // END - foreach
429
430                         // Remove last comma
431                         if (substr($argsString, -2, 1) == ',') {
432                                 $argsString = substr($argsString, 0, -2);
433                         } // END - if
434                 } else {
435                         // Invalid arguments!
436                         $argsString = '!INVALID:' . gettype($args) . '!';
437                 }
438
439                 // Output stub message
440                 // @TODO __CLASS__ does always return BaseFrameworkSystem but not the extending (=child) class
441                 self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[unknown::%s:] Stub! Args: %s',
442                         $methodName,
443                         $argsString
444                 ));
445
446                 // Return nothing
447                 return NULL;
448         }
449
450         /**
451          * Getter for $realClass
452          *
453          * @return      $realClass The name of the real class (not BaseFrameworkSystem)
454          */
455         public function __toString () {
456                 return $this->realClass;
457         }
458
459         /**
460          * Magic function to catch setting of missing but set class fields/attributes
461          *
462          * @param       $name   Name of the field/attribute
463          * @param       $value  Value to store
464          * @return      void
465          */
466         public final function __set ($name, $value) {
467                 $this->debugBackTrace(sprintf('Tried to set a missing field. name=%s, value[%s]=%s',
468                         $name,
469                         gettype($value),
470                         $value
471                 ));
472         }
473
474         /**
475          * Magic function to catch getting of missing fields/attributes
476          *
477          * @param       $name   Name of the field/attribute
478          * @return      void
479          */
480         public final function __get ($name) {
481                 $this->debugBackTrace(sprintf('Tried to get a missing field. name=%s',
482                         $name
483                 ));
484         }
485
486         /**
487          * Magic function to catch unsetting of missing fields/attributes
488          *
489          * @param       $name   Name of the field/attribute
490          * @return      void
491          */
492         public final function __unset ($name) {
493                 $this->debugBackTrace(sprintf('Tried to unset a missing field. name=%s',
494                         $name
495                 ));
496         }
497
498         /**
499          * Setter for the real class name
500          *
501          * @param       $realClass      Class name (string)
502          * @return      void
503          */
504         public final function setRealClass ($realClass) {
505                 // Set real class
506                 $this->realClass = (string) $realClass;
507         }
508
509         /**
510          * Setter for database result instance
511          *
512          * @param       $resultInstance         An instance of a database result class
513          * @return      void
514          * @todo        SearchableResult and UpdateableResult shall have a super interface to use here
515          */
516         protected final function setResultInstance (SearchableResult $resultInstance) {
517                 $this->resultInstance =  $resultInstance;
518         }
519
520         /**
521          * Getter for database result instance
522          *
523          * @return      $resultInstance         An instance of a database result class
524          */
525         public final function getResultInstance () {
526                 return $this->resultInstance;
527         }
528
529         /**
530          * Setter for template engine instances
531          *
532          * @param       $templateInstance       An instance of a template engine class
533          * @return      void
534          */
535         protected final function setTemplateInstance (CompileableTemplate $templateInstance) {
536                 $this->templateInstance = $templateInstance;
537         }
538
539         /**
540          * Getter for template engine instances
541          *
542          * @return      $templateInstance       An instance of a template engine class
543          */
544         protected final function getTemplateInstance () {
545                 return $this->templateInstance;
546         }
547
548         /**
549          * Setter for search instance
550          *
551          * @param       $searchInstance         Searchable criteria instance
552          * @return      void
553          */
554         public final function setSearchInstance (LocalSearchCriteria $searchInstance) {
555                 $this->searchInstance = $searchInstance;
556         }
557
558         /**
559          * Getter for search instance
560          *
561          * @return      $searchInstance         Searchable criteria instance
562          */
563         public final function getSearchInstance () {
564                 return $this->searchInstance;
565         }
566
567         /**
568          * Setter for update instance
569          *
570          * @param       $updateInstance         Searchable criteria instance
571          * @return      void
572          */
573         public final function setUpdateInstance (LocalUpdateCriteria $updateInstance) {
574                 $this->updateInstance = $updateInstance;
575         }
576
577         /**
578          * Getter for update instance
579          *
580          * @return      $updateInstance         Updateable criteria instance
581          */
582         public final function getUpdateInstance () {
583                 return $this->updateInstance;
584         }
585
586         /**
587          * Setter for resolver instance
588          *
589          * @param       $resolverInstance       Instance of a command resolver class
590          * @return      void
591          */
592         public final function setResolverInstance (Resolver $resolverInstance) {
593                 $this->resolverInstance = $resolverInstance;
594         }
595
596         /**
597          * Getter for resolver instance
598          *
599          * @return      $resolverInstance       Instance of a command resolver class
600          */
601         public final function getResolverInstance () {
602                 return $this->resolverInstance;
603         }
604
605         /**
606          * Setter for language instance
607          *
608          * @param       $configInstance         The configuration instance which shall
609          *                                                              be FrameworkConfiguration
610          * @return      void
611          */
612         public final function setConfigInstance (FrameworkConfiguration $configInstance) {
613                 Registry::getRegistry()->addInstance('config', $configInstance);
614         }
615
616         /**
617          * Getter for configuration instance
618          *
619          * @return      $configInstance         Configuration instance
620          */
621         public final function getConfigInstance () {
622                 $configInstance = Registry::getRegistry()->getInstance('config');
623                 return $configInstance;
624         }
625
626         /**
627          * Setter for debug instance
628          *
629          * @param       $debugInstance  The instance for debug output class
630          * @return      void
631          */
632         public final function setDebugInstance (DebugMiddleware $debugInstance) {
633                 Registry::getRegistry()->addInstance('debug', $debugInstance);
634         }
635
636         /**
637          * Getter for debug instance
638          *
639          * @return      $debugInstance  Instance to class DebugConsoleOutput or DebugWebOutput
640          */
641         public final function getDebugInstance () {
642                 // Get debug instance
643                 $debugInstance = Registry::getRegistry()->getInstance('debug');
644
645                 // Return it
646                 return $debugInstance;
647         }
648
649         /**
650          * Setter for web output instance
651          *
652          * @param       $webInstance    The instance for web output class
653          * @return      void
654          */
655         public final function setWebOutputInstance (OutputStreamer $webInstance) {
656                 Registry::getRegistry()->addInstance('web_output', $webInstance);
657         }
658
659         /**
660          * Getter for web output instance
661          *
662          * @return      $webOutputInstance - Instance to class WebOutput
663          */
664         public final function getWebOutputInstance () {
665                 $webOutputInstance = Registry::getRegistry()->getInstance('web_output');
666                 return $webOutputInstance;
667         }
668
669         /**
670          * Setter for database instance
671          *
672          * @param       $databaseInstance       The instance for the database connection (forced DatabaseConnection)
673          * @return      void
674          */
675         public final function setDatabaseInstance (DatabaseConnection $databaseInstance) {
676                 Registry::getRegistry()->addInstance('db_instance', $databaseInstance);
677         }
678
679         /**
680          * Getter for database layer
681          *
682          * @return      $databaseInstance       The database layer instance
683          */
684         public final function getDatabaseInstance () {
685                 // Get instance
686                 $databaseInstance = Registry::getRegistry()->getInstance('db_instance');
687
688                 // Return instance
689                 return $databaseInstance;
690         }
691
692         /**
693          * Setter for compressor channel
694          *
695          * @param       $compressorInstance             An instance of CompressorChannel
696          * @return      void
697          */
698         public final function setCompressorChannel (CompressorChannel $compressorInstance) {
699                 Registry::getRegistry()->addInstance('compressor', $compressorInstance);
700         }
701
702         /**
703          * Getter for compressor channel
704          *
705          * @return      $compressorInstance             The compressor channel
706          */
707         public final function getCompressorChannel () {
708                 $compressorInstance = Registry::getRegistry()->getInstance('compressor');
709                 return $compressorInstance;
710         }
711
712         /**
713          * Protected getter for a manageable application helper class
714          *
715          * @return      $applicationInstance    An instance of a manageable application helper class
716          */
717         protected final function getApplicationInstance () {
718                 $applicationInstance = Registry::getRegistry()->getInstance('application');
719                 return $applicationInstance;
720         }
721
722         /**
723          * Setter for a manageable application helper class
724          *
725          * @param       $applicationInstance    An instance of a manageable application helper class
726          * @return      void
727          */
728         public final function setApplicationInstance (ManageableApplication $applicationInstance) {
729                 Registry::getRegistry()->addInstance('application', $applicationInstance);
730         }
731
732         /**
733          * Setter for request instance
734          *
735          * @param       $requestInstance        An instance of a Requestable class
736          * @return      void
737          */
738         public final function setRequestInstance (Requestable $requestInstance) {
739                 $this->requestInstance = $requestInstance;
740         }
741
742         /**
743          * Getter for request instance
744          *
745          * @return      $requestInstance        An instance of a Requestable class
746          */
747         public final function getRequestInstance () {
748                 return $this->requestInstance;
749         }
750
751         /**
752          * Setter for response instance
753          *
754          * @param       $responseInstance       An instance of a Responseable class
755          * @return      void
756          */
757         public final function setResponseInstance (Responseable $responseInstance) {
758                 $this->responseInstance = $responseInstance;
759         }
760
761         /**
762          * Getter for response instance
763          *
764          * @return      $responseInstance       An instance of a Responseable class
765          */
766         public final function getResponseInstance () {
767                 return $this->responseInstance;
768         }
769
770         /**
771          * Private getter for language instance
772          *
773          * @return      $langInstance   An instance to the language sub-system
774          */
775         protected final function getLanguageInstance () {
776                 $langInstance = Registry::getRegistry()->getInstance('language');
777                 return $langInstance;
778         }
779
780         /**
781          * Setter for language instance
782          *
783          * @param       $langInstance   An instance to the language sub-system
784          * @return      void
785          * @see         LanguageSystem
786          */
787         public final function setLanguageInstance (ManageableLanguage $langInstance) {
788                 Registry::getRegistry()->addInstance('language', $langInstance);
789         }
790
791         /**
792          * Private getter for file IO instance
793          *
794          * @return      $fileIoInstance         An instance to the file I/O sub-system
795          */
796         protected final function getFileIoInstance () {
797                 return $this->fileIoInstance;
798         }
799
800         /**
801          * Setter for file I/O instance
802          *
803          * @param       $fileIoInstance         An instance to the file I/O sub-system
804          * @return      void
805          */
806         public final function setFileIoInstance (IoHandler $fileIoInstance) {
807                 $this->fileIoInstance = $fileIoInstance;
808         }
809
810         /**
811          * Protected setter for user instance
812          *
813          * @param       $userInstance   An instance of a user class
814          * @return      void
815          */
816         protected final function setUserInstance (ManageableAccount $userInstance) {
817                 $this->userInstance = $userInstance;
818         }
819
820         /**
821          * Getter for user instance
822          *
823          * @return      $userInstance   An instance of a user class
824          */
825         public final function getUserInstance () {
826                 return $this->userInstance;
827         }
828
829         /**
830          * Setter for controller instance (this surely breaks a bit the MVC patterm)
831          *
832          * @param       $controllerInstance             An instance of the controller
833          * @return      void
834          */
835         public final function setControllerInstance (Controller $controllerInstance) {
836                 $this->controllerInstance = $controllerInstance;
837         }
838
839         /**
840          * Getter for controller instance (this surely breaks a bit the MVC patterm)
841          *
842          * @return      $controllerInstance             An instance of the controller
843          */
844         public final function getControllerInstance () {
845                 return $this->controllerInstance;
846         }
847
848         /**
849          * Setter for RNG instance
850          *
851          * @param       $rngInstance    An instance of a random number generator (RNG)
852          * @return      void
853          */
854         protected final function setRngInstance (RandomNumberGenerator $rngInstance) {
855                 $this->rngInstance = $rngInstance;
856         }
857
858         /**
859          * Getter for RNG instance
860          *
861          * @return      $rngInstance    An instance of a random number generator (RNG)
862          */
863         public final function getRngInstance () {
864                 return $this->rngInstance;
865         }
866
867         /**
868          * Setter for Cryptable instance
869          *
870          * @param       $cryptoInstance An instance of a Cryptable class
871          * @return      void
872          */
873         protected final function setCryptoInstance (Cryptable $cryptoInstance) {
874                 $this->cryptoInstance = $cryptoInstance;
875         }
876
877         /**
878          * Getter for Cryptable instance
879          *
880          * @return      $cryptoInstance An instance of a Cryptable class
881          */
882         public final function getCryptoInstance () {
883                 return $this->cryptoInstance;
884         }
885
886         /**
887          * Setter for the list instance
888          *
889          * @param       $listInstance   A list of Listable
890          * @return      void
891          */
892         protected final function setListInstance (Listable $listInstance) {
893                 $this->listInstance = $listInstance;
894         }
895
896         /**
897          * Getter for the list instance
898          *
899          * @return      $listInstance   A list of Listable
900          */
901         protected final function getListInstance () {
902                 return $this->listInstance;
903         }
904
905         /**
906          * Setter for the menu instance
907          *
908          * @param       $menuInstance   A RenderableMenu instance
909          * @return      void
910          */
911         protected final function setMenuInstance (RenderableMenu $menuInstance) {
912                 $this->menuInstance = $menuInstance;
913         }
914
915         /**
916          * Getter for the menu instance
917          *
918          * @return      $menuInstance   A RenderableMenu instance
919          */
920         protected final function getMenuInstance () {
921                 return $this->menuInstance;
922         }
923
924         /**
925          * Setter for image instance
926          *
927          * @param       $imageInstance  An instance of an image
928          * @return      void
929          */
930         public final function setImageInstance (BaseImage $imageInstance) {
931                 $this->imageInstance = $imageInstance;
932         }
933
934         /**
935          * Getter for image instance
936          *
937          * @return      $imageInstance  An instance of an image
938          */
939         public final function getImageInstance () {
940                 return $this->imageInstance;
941         }
942
943         /**
944          * Setter for stacker instance
945          *
946          * @param       $stackerInstance        An instance of an stacker
947          * @return      void
948          */
949         public final function setStackerInstance (Stackable $stackerInstance) {
950                 $this->stackerInstance = $stackerInstance;
951         }
952
953         /**
954          * Getter for stacker instance
955          *
956          * @return      $stackerInstance        An instance of an stacker
957          */
958         public final function getStackerInstance () {
959                 return $this->stackerInstance;
960         }
961
962         /**
963          * Setter for compressor instance
964          *
965          * @param       $compressorInstance     An instance of an compressor
966          * @return      void
967          */
968         public final function setCompressorInstance (Compressor $compressorInstance) {
969                 $this->compressorInstance = $compressorInstance;
970         }
971
972         /**
973          * Getter for compressor instance
974          *
975          * @return      $compressorInstance     An instance of an compressor
976          */
977         public final function getCompressorInstance () {
978                 return $this->compressorInstance;
979         }
980
981         /**
982          * Setter for Parseable instance
983          *
984          * @param       $parserInstance An instance of an Parseable
985          * @return      void
986          */
987         public final function setParserInstance (Parseable $parserInstance) {
988                 $this->parserInstance = $parserInstance;
989         }
990
991         /**
992          * Getter for Parseable instance
993          *
994          * @return      $parserInstance An instance of an Parseable
995          */
996         public final function getParserInstance () {
997                 return $this->parserInstance;
998         }
999
1000         /**
1001          * Setter for ProtocolHandler instance
1002          *
1003          * @param       $protocolInstance       An instance of an ProtocolHandler
1004          * @return      void
1005          */
1006         public final function setProtocolInstance (ProtocolHandler $protocolInstance = NULL) {
1007                 $this->protocolInstance = $protocolInstance;
1008         }
1009
1010         /**
1011          * Getter for ProtocolHandler instance
1012          *
1013          * @return      $protocolInstance       An instance of an ProtocolHandler
1014          */
1015         public final function getProtocolInstance () {
1016                 return $this->protocolInstance;
1017         }
1018
1019         /**
1020          * Setter for DatabaseWrapper instance
1021          *
1022          * @param       $wrapperInstance        An instance of an DatabaseWrapper
1023          * @return      void
1024          */
1025         public final function setWrapperInstance (DatabaseWrapper $wrapperInstance) {
1026                 $this->wrapperInstance = $wrapperInstance;
1027         }
1028
1029         /**
1030          * Getter for DatabaseWrapper instance
1031          *
1032          * @return      $wrapperInstance        An instance of an DatabaseWrapper
1033          */
1034         public final function getWrapperInstance () {
1035                 return $this->wrapperInstance;
1036         }
1037
1038         /**
1039          * Setter for socket resource
1040          *
1041          * @param       $socketResource         A valid socket resource
1042          * @return      void
1043          */
1044         public final function setSocketResource ($socketResource) {
1045                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput($this->__toString() . '::' . __FUNCTION__ . ': socketResource=' . $socketResource . ',previous[' . gettype($this->socketResource) . ']=' . $this->socketResource);
1046                 $this->socketResource = $socketResource;
1047         }
1048
1049         /**
1050          * Getter for socket resource
1051          *
1052          * @return      $socketResource         A valid socket resource
1053          */
1054         public final function getSocketResource () {
1055                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput($this->__toString() . '::' . __FUNCTION__ . ': socketResource[' . gettype($this->socketResource) . ']=' . $this->socketResource);
1056                 return $this->socketResource;
1057         }
1058
1059         /**
1060          * Setter for helper instance
1061          *
1062          * @param       $helperInstance         An instance of a helper class
1063          * @return      void
1064          */
1065         protected final function setHelperInstance (Helper $helperInstance) {
1066                 $this->helperInstance = $helperInstance;
1067         }
1068
1069         /**
1070          * Getter for helper instance
1071          *
1072          * @return      $helperInstance         An instance of a helper class
1073          */
1074         public final function getHelperInstance () {
1075                 return $this->helperInstance;
1076         }
1077
1078         /**
1079          * Setter for a Sourceable instance
1080          *
1081          * @param       $sourceInstance The Sourceable instance
1082          * @return      void
1083          */
1084         protected final function setSourceInstance (Sourceable $sourceInstance) {
1085                 $this->sourceInstance = $sourceInstance;
1086         }
1087
1088         /**
1089          * Getter for a Sourceable instance
1090          *
1091          * @return      $sourceInstance The Sourceable instance
1092          */
1093         protected final function getSourceInstance () {
1094                 return $this->sourceInstance;
1095         }
1096
1097         /**
1098          * Getter for a InputStream instance
1099          *
1100          * @param       $inputStreamInstance    The InputStream instance
1101          */
1102         protected final function getInputStreamInstance () {
1103                 return $this->inputStreamInstance;
1104         }
1105
1106         /**
1107          * Setter for a InputStream instance
1108          *
1109          * @param       $inputStreamInstance    The InputStream instance
1110          * @return      void
1111          */
1112         protected final function setInputStreamInstance (InputStream $inputStreamInstance) {
1113                 $this->inputStreamInstance = $inputStreamInstance;
1114         }
1115
1116         /**
1117          * Getter for a OutputStream instance
1118          *
1119          * @param       $outputStreamInstance   The OutputStream instance
1120          */
1121         protected final function getOutputStreamInstance () {
1122                 return $this->outputStreamInstance;
1123         }
1124
1125         /**
1126          * Setter for a OutputStream instance
1127          *
1128          * @param       $outputStreamInstance   The OutputStream instance
1129          * @return      void
1130          */
1131         protected final function setOutputStreamInstance (OutputStream $outputStreamInstance) {
1132                 $this->outputStreamInstance = $outputStreamInstance;
1133         }
1134
1135         /**
1136          * Setter for handler instance
1137          *
1138          * @param       $handlerInstance        An instance of a Handleable class
1139          * @return      void
1140          */
1141         protected final function setHandlerInstance (Handleable $handlerInstance) {
1142                 $this->handlerInstance = $handlerInstance;
1143         }
1144
1145         /**
1146          * Getter for handler instance
1147          *
1148          * @return      $handlerInstance        A Networkable instance
1149          */
1150         protected final function getHandlerInstance () {
1151                 return $this->handlerInstance;
1152         }
1153
1154         /**
1155          * Setter for visitor instance
1156          *
1157          * @param       $visitorInstance        A Visitor instance
1158          * @return      void
1159          */
1160         protected final function setVisitorInstance (Visitor $visitorInstance) {
1161                 $this->visitorInstance = $visitorInstance;
1162         }
1163
1164         /**
1165          * Getter for visitor instance
1166          *
1167          * @return      $visitorInstance        A Visitor instance
1168          */
1169         protected final function getVisitorInstance () {
1170                 return $this->visitorInstance;
1171         }
1172
1173         /**
1174          * Setter for DHT instance
1175          *
1176          * @param       $dhtInstance    A Distributable instance
1177          * @return      void
1178          */
1179         protected final function setDhtInstance (Distributable $dhtInstance) {
1180                 $this->dhtInstance = $dhtInstance;
1181         }
1182
1183         /**
1184          * Getter for DHT instance
1185          *
1186          * @return      $dhtInstance    A Distributable instance
1187          */
1188         protected final function getDhtInstance () {
1189                 return $this->dhtInstance;
1190         }
1191
1192         /**
1193          * Setter for raw package Data
1194          *
1195          * @param       $packageData    Raw package Data
1196          * @return      void
1197          */
1198         public final function setPackageData (array $packageData) {
1199                 $this->packageData = $packageData;
1200         }
1201
1202         /**
1203          * Getter for raw package Data
1204          *
1205          * @return      $packageData    Raw package Data
1206          */
1207         public function getPackageData () {
1208                 return $this->packageData;
1209         }
1210
1211
1212         /**
1213          * Setter for Iterator instance
1214          *
1215          * @param       $iteratorInstance       An instance of an Iterator
1216          * @return      void
1217          */
1218         protected final function setIteratorInstance (Iterator $iteratorInstance) {
1219                 $this->iteratorInstance = $iteratorInstance;
1220         }
1221
1222         /**
1223          * Getter for Iterator instance
1224          *
1225          * @return      $iteratorInstance       An instance of an Iterator
1226          */
1227         public final function getIteratorInstance () {
1228                 return $this->iteratorInstance;
1229         }
1230
1231         /**
1232          * Setter for InputOutputPointer instance
1233          *
1234          * @param       $pointerInstance        An instance of an InputOutputPointer
1235          * @return      void
1236          */
1237         protected final function setPointerInstance (InputOutputPointer $pointerInstance) {
1238                 $this->pointerInstance = $pointerInstance;
1239         }
1240
1241         /**
1242          * Getter for InputOutputPointer instance
1243          *
1244          * @return      $pointerInstance        An instance of an InputOutputPointer
1245          */
1246         public final function getPointerInstance () {
1247                 return $this->pointerInstance;
1248         }
1249
1250         /**
1251          * Checks whether an object equals this object. You should overwrite this
1252          * method to implement own equality checks
1253          *
1254          * @param       $objectInstance         An instance of a FrameworkInterface object
1255          * @return      $equals                         Whether both objects equals
1256          */
1257         public function equals (FrameworkInterface $objectInstance) {
1258                 // Now test it
1259                 $equals = ((
1260                         $this->__toString() == $objectInstance->__toString()
1261                 ) && (
1262                         $this->hashCode() == $objectInstance->hashCode()
1263                 ));
1264
1265                 // Return the result
1266                 return $equals;
1267         }
1268
1269         /**
1270          * Generates a generic hash code of this class. You should really overwrite
1271          * this method with your own hash code generator code. But keep KISS in mind.
1272          *
1273          * @return      $hashCode       A generic hash code respresenting this whole class
1274          */
1275         public function hashCode () {
1276                 // Simple hash code
1277                 return crc32($this->__toString());
1278         }
1279
1280         /**
1281          * Formats computer generated price values into human-understandable formats
1282          * with thousand and decimal separators.
1283          *
1284          * @param       $value          The in computer format value for a price
1285          * @param       $currency       The currency symbol (use HTML-valid characters!)
1286          * @param       $decNum         Number of decimals after commata
1287          * @return      $price          The for the current language formated price string
1288          * @throws      MissingDecimalsThousandsSeparatorException      If decimals or
1289          *                                                                                              thousands separator
1290          *                                                                                              is missing
1291          */
1292         public function formatCurrency ($value, $currency = '&euro;', $decNum = 2) {
1293                 // Are all required attriutes set?
1294                 if ((!isset($this->decimals)) || (!isset($this->thousands))) {
1295                         // Throw an exception
1296                         throw new MissingDecimalsThousandsSeparatorException($this, self::EXCEPTION_ATTRIBUTES_ARE_MISSING);
1297                 } // END - if
1298
1299                 // Cast the number
1300                 $value = (float) $value;
1301
1302                 // Reformat the US number
1303                 $price = number_format($value, $decNum, $this->decimals, $this->thousands) . $currency;
1304
1305                 // Return as string...
1306                 return $price;
1307         }
1308
1309         /**
1310          * Appends a trailing slash to a string
1311          *
1312          * @param       $str    A string (maybe) without trailing slash
1313          * @return      $str    A string with an auto-appended trailing slash
1314          */
1315         public final function addMissingTrailingSlash ($str) {
1316                 // Is there a trailing slash?
1317                 if (substr($str, -1, 1) != '/') {
1318                         $str .= '/';
1319                 } // END - if
1320
1321                 // Return string with trailing slash
1322                 return $str;
1323         }
1324
1325         /**
1326          * Prepare the template engine (WebTemplateEngine by default) for a given
1327          * application helper instance (ApplicationHelper by default).
1328          *
1329          * @param               $applicationInstance    An application helper instance or
1330          *                                                                              null if we shall use the default
1331          * @return              $templateInstance               The template engine instance
1332          * @throws              NullPointerException    If the discovered application
1333          *                                                                              instance is still null
1334          */
1335         protected function prepareTemplateInstance (ManageableApplication $applicationInstance = NULL) {
1336                 // Is the application instance set?
1337                 if (is_null($applicationInstance)) {
1338                         // Get the current instance
1339                         $applicationInstance = $this->getApplicationInstance();
1340
1341                         // Still null?
1342                         if (is_null($applicationInstance)) {
1343                                 // Thrown an exception
1344                                 throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
1345                         } // END - if
1346                 } // END - if
1347
1348                 // Initialize the template engine
1349                 $templateInstance = ObjectFactory::createObjectByConfiguredName('web_template_class');
1350
1351                 // Return the prepared instance
1352                 return $templateInstance;
1353         }
1354
1355         /**
1356          * Debugs this instance by putting out it's full content
1357          *
1358          * @param       $message        Optional message to show in debug output
1359          * @return      void
1360          */
1361         public final function debugInstance ($message = '') {
1362                 // Restore the error handler to avoid trouble with missing array elements or undeclared variables
1363                 restore_error_handler();
1364
1365                 // Init content
1366                 $content = '';
1367
1368                 // Is a message set?
1369                 if (!empty($message)) {
1370                         // Construct message
1371                         $content = sprintf('<div class="debug_message">Message: %s</div>' . PHP_EOL, $message);
1372                 } // END - if
1373
1374                 // Generate the output
1375                 $content .= sprintf('<pre>%s</pre>',
1376                         trim(
1377                                 htmlentities(
1378                                         print_r($this, TRUE)
1379                                 )
1380                         )
1381                 );
1382
1383                 // Output it
1384                 ApplicationEntryPoint::app_exit(sprintf('<div class="debug_header">%s debug output:</div><div class="debug_content">%s</div>Loaded includes: <div class="debug_include_list">%s</div>',
1385                         $this->__toString(),
1386                         $content,
1387                         ClassLoader::getSelfInstance()->getPrintableIncludeList()
1388                 ));
1389         }
1390
1391         /**
1392          * Replaces control characters with printable output
1393          *
1394          * @param       $str    String with control characters
1395          * @return      $str    Replaced string
1396          */
1397         protected function replaceControlCharacters ($str) {
1398                 // Replace them
1399                 $str = str_replace(
1400                         chr(13), '[r]', str_replace(
1401                         chr(10), '[n]', str_replace(
1402                         chr(9) , '[t]',
1403                         $str
1404                 )));
1405
1406                 // Return it
1407                 return $str;
1408         }
1409
1410         /**
1411          * Output a partial stub message for the caller method
1412          *
1413          * @param       $message        An optional message to display
1414          * @return      void
1415          */
1416         protected function partialStub ($message = '') {
1417                 // Get the backtrace
1418                 $backtrace = debug_backtrace();
1419
1420                 // Generate the class::method string
1421                 $methodName = 'UnknownClass-&gt;unknownMethod';
1422                 if ((isset($backtrace[1]['class'])) && (isset($backtrace[1]['function']))) {
1423                         $methodName = $backtrace[1]['class'] . '-&gt;' . $backtrace[1]['function'];
1424                 } // END - if
1425
1426                 // Construct the full message
1427                 $stubMessage = sprintf('[%s:] Partial stub!',
1428                         $methodName
1429                 );
1430
1431                 // Is the extra message given?
1432                 if (!empty($message)) {
1433                         // Then add it as well
1434                         $stubMessage .= ' Message: ' . $message;
1435                 } // END - if
1436
1437                 // Debug instance is there?
1438                 if (!is_null($this->getDebugInstance())) {
1439                         // Output stub message
1440                         self::createDebugInstance(__CLASS__)->debugOutput($stubMessage);
1441                 } else {
1442                         // Trigger an error
1443                         trigger_error($stubMessage);
1444                         exit;
1445                 }
1446         }
1447
1448         /**
1449          * Outputs a debug backtrace and stops further script execution
1450          *
1451          * @param       $message        An optional message to output
1452          * @param       $doExit         Whether exit the program (TRUE is default)
1453          * @return      void
1454          */
1455         public function debugBackTrace ($message = '', $doExit = TRUE) {
1456                 // Sorry, there is no other way getting this nice backtrace
1457                 if (!empty($message)) {
1458                         // Output message
1459                         printf('Message: %s<br />' . chr(10), $message);
1460                 } // END - if
1461
1462                 print('<pre>');
1463                 debug_print_backtrace();
1464                 print('</pre>');
1465
1466                 // Exit program?
1467                 if ($doExit === TRUE) {
1468                         exit();
1469                 } // END - if
1470         }
1471
1472         /**
1473          * Creates an instance of a debugger instance
1474          *
1475          * @param       $className              Name of the class (currently unsupported)
1476          * @return      $debugInstance  An instance of a debugger class
1477          */
1478         public final static function createDebugInstance ($className) {
1479                 // Is the instance set?
1480                 if (!Registry::getRegistry()->instanceExists('debug')) {
1481                         // Init debug instance
1482                         $debugInstance = NULL;
1483
1484                         // Try it
1485                         try {
1486                                 // Get a debugger instance
1487                                 $debugInstance = DebugMiddleware::createDebugMiddleware(FrameworkConfiguration::getSelfInstance()->getConfigEntry('debug_class'));
1488                         } catch (NullPointerException $e) {
1489                                 // Didn't work, no instance there
1490                                 exit('Cannot create debugInstance! Exception=' . $e->__toString() . ', message=' . $e->getMessage());
1491                         }
1492
1493                         // Empty string should be ignored and used for testing the middleware
1494                         DebugMiddleware::getSelfInstance()->output('');
1495
1496                         // Set it in its own class. This will set it in the registry
1497                         $debugInstance->setDebugInstance($debugInstance);
1498                 } else {
1499                         // Get instance from registry
1500                         $debugInstance = Registry::getRegistry()->getDebugInstance();
1501                 }
1502
1503                 // Return it
1504                 return $debugInstance;
1505         }
1506
1507         /**
1508          * Simple output of a message with line-break
1509          *
1510          * @param       $message        Message to output
1511          * @return      void
1512          */
1513         public function outputLine ($message) {
1514                 // Simply output it
1515                 print($message . PHP_EOL);
1516         }
1517
1518         /**
1519          * Outputs a debug message whether to debug instance (should be set!) or
1520          * dies with or ptints the message. Do NEVER EVER rewrite the exit() call to
1521          * ApplicationEntryPoint::app_exit(), this would cause an endless loop.
1522          *
1523          * @param       $message        Message we shall send out...
1524          * @param       $doPrint        Whether print or die here (default: print)
1525          * @paran       $stripTags      Whether to strip tags (default: FALSE)
1526          * @return      void
1527          */
1528         public function debugOutput ($message, $doPrint = TRUE, $stripTags = FALSE) {
1529                 // Set debug instance to NULL
1530                 $debugInstance = NULL;
1531
1532                 // Try it:
1533                 try {
1534                         // Get debug instance
1535                         $debugInstance = $this->getDebugInstance();
1536                 } catch (NullPointerException $e) {
1537                         // The debug instance is not set (yet)
1538                 }
1539
1540                 // Is the debug instance there?
1541                 if (is_object($debugInstance)) {
1542                         // Use debug output handler
1543                         $debugInstance->output($message, $stripTags);
1544
1545                         if ($doPrint === FALSE) {
1546                                 // Die here if not printed
1547                                 exit();
1548                         } // END - if
1549                 } else {
1550                         // Are debug times enabled?
1551                         if ($this->getConfigInstance()->getConfigEntry('debug_output_timings') == 'Y') {
1552                                 // Prepent it
1553                                 $message = $this->getPrintableExecutionTime() . $message;
1554                         } // END - if
1555
1556                         // Put directly out
1557                         if ($doPrint === TRUE) {
1558                                 // Print message
1559                                 $this->outputLine($message);
1560                         } else {
1561                                 // Die here
1562                                 exit($message);
1563                         }
1564                 }
1565         }
1566
1567         /**
1568          * Converts e.g. a command from URL to a valid class by keeping out bad characters
1569          *
1570          * @param       $str            The string, what ever it is needs to be converted
1571          * @return      $className      Generated class name
1572          */
1573         public function convertToClassName ($str) {
1574                 // Init class name
1575                 $className = '';
1576
1577                 // Convert all dashes in underscores
1578                 $str = $this->convertDashesToUnderscores($str);
1579
1580                 // Now use that underscores to get classname parts for hungarian style
1581                 foreach (explode('_', $str) as $strPart) {
1582                         // Make the class name part lower case and first upper case
1583                         $className .= ucfirst(strtolower($strPart));
1584                 } // END - foreach
1585
1586                 // Return class name
1587                 return $className;
1588         }
1589
1590         /**
1591          * Converts dashes to underscores, e.g. useable for configuration entries
1592          *
1593          * @param       $str    The string with maybe dashes inside
1594          * @return      $str    The converted string with no dashed, but underscores
1595          */
1596         public final function convertDashesToUnderscores ($str) {
1597                 // Convert them all
1598                 $str = str_replace('-', '_', $str);
1599
1600                 // Return converted string
1601                 return $str;
1602         }
1603
1604         /**
1605          * Marks up the code by adding e.g. line numbers
1606          *
1607          * @param       $phpCode                Unmarked PHP code
1608          * @return      $markedCode             Marked PHP code
1609          */
1610         public function markupCode ($phpCode) {
1611                 // Init marked code
1612                 $markedCode = '';
1613
1614                 // Get last error
1615                 $errorArray = error_get_last();
1616
1617                 // Init the code with error message
1618                 if (is_array($errorArray)) {
1619                         // Get error infos
1620                         $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>',
1621                                 basename($errorArray['file']),
1622                                 $errorArray['line'],
1623                                 $errorArray['message'],
1624                                 $errorArray['type']
1625                         );
1626                 } // END - if
1627
1628                 // Add line number to the code
1629                 foreach (explode(chr(10), $phpCode) as $lineNo => $code) {
1630                         // Add line numbers
1631                         $markedCode .= sprintf('<span id="code_line">%s</span>: %s' . chr(10),
1632                                 ($lineNo + 1),
1633                                 htmlentities($code, ENT_QUOTES)
1634                         );
1635                 } // END - foreach
1636
1637                 // Return the code
1638                 return $markedCode;
1639         }
1640
1641         /**
1642          * Filter a given GMT timestamp (non Uni* stamp!) to make it look more
1643          * beatiful for web-based front-ends. If null is given a message id
1644          * null_timestamp will be resolved and returned.
1645          *
1646          * @param       $timestamp      Timestamp to prepare (filter) for display
1647          * @return      $readable       A readable timestamp
1648          */
1649         public function doFilterFormatTimestamp ($timestamp) {
1650                 // Default value to return
1651                 $readable = '???';
1652
1653                 // Is the timestamp null?
1654                 if (is_null($timestamp)) {
1655                         // Get a message string
1656                         $readable = $this->getLanguageInstance()->getMessage('null_timestamp');
1657                 } else {
1658                         switch ($this->getLanguageInstance()->getLanguageCode()) {
1659                                 case 'de': // German format is a bit different to default
1660                                         // Split the GMT stamp up
1661                                         $dateTime  = explode(' ', $timestamp  );
1662                                         $dateArray = explode('-', $dateTime[0]);
1663                                         $timeArray = explode(':', $dateTime[1]);
1664
1665                                         // Construct the timestamp
1666                                         $readable = sprintf($this->getConfigInstance()->getConfigEntry('german_date_time'),
1667                                                 $dateArray[0],
1668                                                 $dateArray[1],
1669                                                 $dateArray[2],
1670                                                 $timeArray[0],
1671                                                 $timeArray[1],
1672                                                 $timeArray[2]
1673                                         );
1674                                         break;
1675
1676                                 default: // Default is pass-through
1677                                         $readable = $timestamp;
1678                                         break;
1679                         } // END - switch
1680                 }
1681
1682                 // Return the stamp
1683                 return $readable;
1684         }
1685
1686         /**
1687          * Filter a given number into a localized number
1688          *
1689          * @param       $value          The raw value from e.g. database
1690          * @return      $localized      Localized value
1691          */
1692         public function doFilterFormatNumber ($value) {
1693                 // Generate it from config and localize dependencies
1694                 switch ($this->getLanguageInstance()->getLanguageCode()) {
1695                         case 'de': // German format is a bit different to default
1696                                 $localized = number_format($value, $this->getConfigInstance()->getConfigEntry('decimals'), ',', '.');
1697                                 break;
1698
1699                         default: // US, etc.
1700                                 $localized = number_format($value, $this->getConfigInstance()->getConfigEntry('decimals'), '.', ',');
1701                                 break;
1702                 } // END - switch
1703
1704                 // Return it
1705                 return $localized;
1706         }
1707
1708         /**
1709          * "Getter" for databse entry
1710          *
1711          * @return      $entry  An array with database entries
1712          * @throws      NullPointerException    If the database result is not found
1713          * @throws      InvalidDatabaseResultException  If the database result is invalid
1714          */
1715         protected final function getDatabaseEntry () {
1716                 // Is there an instance?
1717                 if (is_null($this->getResultInstance())) {
1718                         // Throw an exception here
1719                         throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
1720                 } // END - if
1721
1722                 // Rewind it
1723                 $this->getResultInstance()->rewind();
1724
1725                 // Do we have an entry?
1726                 if ($this->getResultInstance()->valid() === FALSE) {
1727                         throw new InvalidDatabaseResultException(array($this, $this->getResultInstance()), DatabaseResult::EXCEPTION_INVALID_DATABASE_RESULT);
1728                 } // END - if
1729
1730                 // Get next entry
1731                 $this->getResultInstance()->next();
1732
1733                 // Fetch it
1734                 $entry = $this->getResultInstance()->current();
1735
1736                 // And return it
1737                 return $entry;
1738         }
1739
1740         /**
1741          * Getter for field name
1742          *
1743          * @param       $fieldName              Field name which we shall get
1744          * @return      $fieldValue             Field value from the user
1745          * @throws      NullPointerException    If the result instance is null
1746          */
1747         public final function getField ($fieldName) {
1748                 // Default field value
1749                 $fieldValue = NULL;
1750
1751                 // Get result instance
1752                 $resultInstance = $this->getResultInstance();
1753
1754                 // Is this instance null?
1755                 if (is_null($resultInstance)) {
1756                         // Then the user instance is no longer valid (expired cookies?)
1757                         throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
1758                 } // END - if
1759
1760                 // Get current array
1761                 $fieldArray = $resultInstance->current();
1762                 //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput($fieldName.':<pre>'.print_r($fieldArray, TRUE).'</pre>');
1763
1764                 // Convert dashes to underscore
1765                 $fieldName = $this->convertDashesToUnderscores($fieldName);
1766
1767                 // Does the field exist?
1768                 if (isset($fieldArray[$fieldName])) {
1769                         // Get it
1770                         $fieldValue = $fieldArray[$fieldName];
1771                 } else {
1772                         // Missing field entry, may require debugging
1773                         self::createDebugInstance(__CLASS__)->debugOutput($this->__toString() . ':fieldname=' . $fieldName . ' not found!');
1774                 }
1775
1776                 // Return it
1777                 return $fieldValue;
1778         }
1779
1780         /**
1781          * Flushs all pending updates to the database layer
1782          *
1783          * @return      void
1784          */
1785         public function flushPendingUpdates () {
1786                 // Get result instance
1787                 $resultInstance = $this->getResultInstance();
1788
1789                 // Do we have data to update?
1790                 if ((is_object($resultInstance)) && ($resultInstance->ifDataNeedsFlush())) {
1791                         // Get wrapper class name config entry
1792                         $configEntry = $resultInstance->getUpdateInstance()->getWrapperConfigEntry();
1793
1794                         // Create object instance
1795                         $wrapperInstance = ObjectFactory::createObjectByConfiguredName($configEntry);
1796
1797                         // Yes, then send the whole result to the database layer
1798                         $wrapperInstance->doUpdateByResult($this->getResultInstance());
1799                 } // END - if
1800         }
1801
1802         /**
1803          * Outputs a deprecation warning to the developer.
1804          *
1805          * @param       $message        The message we shall output to the developer
1806          * @return      void
1807          * @todo        Write a logging mechanism for productive mode
1808          */
1809         public function deprecationWarning ($message) {
1810                 // Is developer mode active?
1811                 if (defined('DEVELOPER')) {
1812                         // Debug instance is there?
1813                         if (!is_null($this->getDebugInstance())) {
1814                                 // Output stub message
1815                                 self::createDebugInstance(__CLASS__)->debugOutput($message);
1816                         } else {
1817                                 // Trigger an error
1818                                 trigger_error($message . "<br />\n");
1819                                 exit;
1820                         }
1821                 } else {
1822                         // @TODO Finish this part!
1823                         $this->partialStub('Developer mode inactive. Message:' . $message);
1824                 }
1825         }
1826
1827         /**
1828          * Checks whether the given PHP extension is loaded
1829          *
1830          * @param       $phpExtension   The PHP extension we shall check
1831          * @return      $isLoaded       Whether the PHP extension is loaded
1832          */
1833         public final function isPhpExtensionLoaded ($phpExtension) {
1834                 // Is it loaded?
1835                 $isLoaded = in_array($phpExtension, get_loaded_extensions());
1836
1837                 // Return result
1838                 return $isLoaded;
1839         }
1840
1841         /**
1842          * "Getter" as a time() replacement but with milliseconds. You should use this
1843          * method instead of the encapsulated getimeofday() function.
1844          *
1845          * @return      $milliTime      Timestamp with milliseconds
1846          */
1847         public function getMilliTime () {
1848                 // Get the time of day as float
1849                 $milliTime = gettimeofday(TRUE);
1850
1851                 // Return it
1852                 return $milliTime;
1853         }
1854
1855         /**
1856          * Idles (sleeps) for given milliseconds
1857          *
1858          * @return      $hasSlept       Whether it goes fine
1859          */
1860         public function idle ($milliSeconds) {
1861                 // Sleep is fine by default
1862                 $hasSlept = TRUE;
1863
1864                 // Idle so long with found function
1865                 if (function_exists('time_sleep_until')) {
1866                         // Get current time and add idle time
1867                         $sleepUntil = $this->getMilliTime() + abs($milliSeconds) / 1000;
1868
1869                         // New PHP 5.1.0 function found, ignore errors
1870                         $hasSlept = @time_sleep_until($sleepUntil);
1871                 } else {
1872                         /*
1873                          * My Sun station doesn't have that function even with latest PHP
1874                          * package. :(
1875                          */
1876                         usleep($milliSeconds * 1000);
1877                 }
1878
1879                 // Return result
1880                 return $hasSlept;
1881         }
1882         /**
1883          * Converts a hexadecimal string, even with negative sign as first string to
1884          * a decimal number using BC functions.
1885          *
1886          * This work is based on comment #86673 on php.net documentation page at:
1887          * <http://de.php.net/manual/en/function.dechex.php#86673>
1888          *
1889          * @param       $hex    Hexadecimal string
1890          * @return      $dec    Decimal number
1891          */
1892         protected function hex2dec ($hex) {
1893                 // Convert to all lower-case
1894                 $hex = strtolower($hex);
1895
1896                 // Detect sign (negative/positive numbers)
1897                 $sign = '';
1898                 if (substr($hex, 0, 1) == '-') {
1899                         $sign = '-';
1900                         $hex = substr($hex, 1);
1901                 } // END - if
1902
1903                 // Decode the hexadecimal string into a decimal number
1904                 $dec = 0;
1905                 for ($i = strlen($hex) - 1, $e = 1; $i >= 0; $i--, $e = bcmul($e, 16)) {
1906                         $factor = self::$hexdec[substr($hex, $i, 1)];
1907                         $dec = bcadd($dec, bcmul($factor, $e));
1908                 } // END - for
1909
1910                 // Return the decimal number
1911                 return $sign . $dec;
1912         }
1913
1914         /**
1915          * Converts even very large decimal numbers, also signed, to a hexadecimal
1916          * string.
1917          *
1918          * This work is based on comment #97756 on php.net documentation page at:
1919          * <http://de.php.net/manual/en/function.hexdec.php#97756>
1920          *
1921          * @param       $dec            Decimal number, even with negative sign
1922          * @param       $maxLength      Optional maximum length of the string
1923          * @return      $hex    Hexadecimal string
1924          */
1925         protected function dec2hex ($dec, $maxLength = 0) {
1926                 // maxLength can be zero or devideable by 2
1927                 assert(($maxLength == 0) || (($maxLength % 2) == 0));
1928
1929                 // Detect sign (negative/positive numbers)
1930                 $sign = '';
1931                 if ($dec < 0) {
1932                         $sign = '-';
1933                         $dec = abs($dec);
1934                 } // END - if
1935
1936                 // Encode the decimal number into a hexadecimal string
1937                 $hex = '';
1938                 do {
1939                         $hex = self::$dechex[($dec % (2 ^ 4))] . $hex;
1940                         $dec /= (2 ^ 4);
1941                 } while ($dec >= 1);
1942
1943                 /*
1944                  * Leading zeros are required for hex-decimal "numbers". In some
1945                  * situations more leading zeros are wanted, so check for both
1946                  * conditions.
1947                  */
1948                 if ($maxLength > 0) {
1949                         // Prepend more zeros
1950                         $hex = str_pad($hex, $maxLength, '0', STR_PAD_LEFT);
1951                 } elseif ((strlen($hex) % 2) != 0) {
1952                         // Only make string's length dividable by 2
1953                         $hex = '0' . $hex;
1954                 }
1955
1956                 // Return the hexadecimal string
1957                 return $sign . $hex;
1958         }
1959
1960         /**
1961          * Converts a ASCII string (0 to 255) into a decimal number.
1962          *
1963          * @param       $asc    The ASCII string to be converted
1964          * @return      $dec    Decimal number
1965          */
1966         protected function asc2dec ($asc) {
1967                 // Convert it into a hexadecimal number
1968                 $hex = bin2hex($asc);
1969
1970                 // And back into a decimal number
1971                 $dec = $this->hex2dec($hex);
1972
1973                 // Return it
1974                 return $dec;
1975         }
1976
1977         /**
1978          * Converts a decimal number into an ASCII string.
1979          *
1980          * @param       $dec            Decimal number
1981          * @return      $asc    An ASCII string
1982          */
1983         protected function dec2asc ($dec) {
1984                 // First convert the number into a hexadecimal string
1985                 $hex = $this->dec2hex($dec);
1986
1987                 // Then convert it into the ASCII string
1988                 $asc = $this->hex2asc($hex);
1989
1990                 // Return it
1991                 return $asc;
1992         }
1993
1994         /**
1995          * Converts a hexadecimal number into an ASCII string. Negative numbers
1996          * are not allowed.
1997          *
1998          * @param       $hex    Hexadecimal string
1999          * @return      $asc    An ASCII string
2000          */
2001         protected function hex2asc ($hex) {
2002                 // Check for length, it must be devideable by 2
2003                 //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('hex='.$hex);
2004                 assert((strlen($hex) % 2) == 0);
2005
2006                 // Walk the string
2007                 $asc = '';
2008                 for ($idx = 0; $idx < strlen($hex); $idx+=2) {
2009                         // Get the decimal number of the chunk
2010                         $part = hexdec(substr($hex, $idx, 2));
2011
2012                         // Add it to the final string
2013                         $asc .= chr($part);
2014                 } // END - for
2015
2016                 // Return the final string
2017                 return $asc;
2018         }
2019
2020         /**
2021          * Checks whether the given encoded data was encoded with Base64
2022          *
2023          * @param       $encodedData    Encoded data we shall check
2024          * @return      $isBase64               Whether the encoded data is Base64
2025          */
2026         protected function isBase64Encoded ($encodedData) {
2027                 // Determine it
2028                 $isBase64 = (@base64_decode($encodedData, TRUE) !== FALSE);
2029
2030                 // Return it
2031                 return $isBase64;
2032         }
2033
2034         /**
2035          * "Getter" to get response/request type from analysis of the system.
2036          *
2037          * @return      $responseType   Analyzed response type
2038          */
2039         protected function getResponseTypeFromSystem () {
2040                 // Default is console
2041                 $responseType = 'console';
2042
2043                 // Is 'HTTP_HOST' set?
2044                 if (isset($_SERVER['HTTP_HOST'])) {
2045                         // Then it is a HTTP response/request
2046                         $responseType = 'http';
2047                 } // END - if
2048
2049                 // Return it
2050                 return $responseType;
2051         }
2052
2053         /**
2054          * Gets a cache key from Criteria instance
2055          *
2056          * @param       $criteriaInstance       An instance of a Criteria class
2057          * @param       $onlyKeys                       Only use these keys for a cache key
2058          * @return      $cacheKey                       A cache key suitable for lookup/storage purposes
2059          */
2060         protected function getCacheKeyByCriteria (Criteria $criteriaInstance, array $onlyKeys = array()) {
2061                 // Generate it
2062                 $cacheKey = sprintf('%s@%s',
2063                         $this->__toString(),
2064                         $criteriaInstance->getCacheKey($onlyKeys)
2065                 );
2066
2067                 // And return it
2068                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput($this->__toString() . ': cacheKey=' . $cacheKey);
2069                 return $cacheKey;
2070         }
2071
2072         /**
2073          * Getter for startup time in miliseconds
2074          *
2075          * @return      $startupTime    Startup time in miliseconds
2076          */
2077         protected function getStartupTime () {
2078                 return self::$startupTime;
2079         }
2080
2081         /**
2082          * "Getter" for a printable currently execution time in nice braces
2083          *
2084          * @return      $executionTime  Current execution time in nice braces
2085          */
2086         protected function getPrintableExecutionTime () {
2087                 // Caculate the execution time
2088                 $executionTime = microtime(TRUE) - $this->getStartupTime();
2089
2090                 // Pack it in nice braces
2091                 $executionTime = sprintf('[ %01.5f ] ', $executionTime);
2092
2093                 // And return it
2094                 return $executionTime;
2095         }
2096
2097         /**
2098          * Hashes a given string with a simple but stronger hash function (no salt)
2099          * and hex-encode it.
2100          *
2101          * @param       $str    The string to be hashed
2102          * @return      $hash   The hash from string $str
2103          */
2104         public static final function hash ($str) {
2105                 // Hash given string with (better secure) hasher
2106                 $hash = bin2hex(mhash(MHASH_SHA256, $str));
2107
2108                 // Return it
2109                 return $hash;
2110         }
2111
2112         /**
2113          * "Getter" for length of hash() output. This will be "cached" to speed up
2114          * things.
2115          *
2116          * @return      $length         Length of hash() output
2117          */
2118         public static final function getHashLength () {
2119                 // Is it cashed?
2120                 if (is_null(self::$hashLength)) {
2121                         // No, then hash a string and save its length.
2122                         self::$hashLength = strlen(self::hash('abc123'));
2123                 } // END - if
2124
2125                 // Return it
2126                 return self::$hashLength;
2127         }
2128
2129         /**
2130          * Checks whether the given number is really a number (only chars 0-9).
2131          *
2132          * @param       $num            A string consisting only chars between 0 and 9
2133          * @param       $castValue      Whether to cast the value to double. Do only use this to secure numbers from Requestable classes.
2134          * @param       $assertMismatch         Whether to assert mismatches
2135          * @return      $ret            The (hopefully) secured numbered value
2136          */
2137         public function bigintval ($num, $castValue = TRUE, $assertMismatch = FALSE) {
2138                 // Filter all numbers out
2139                 $ret = preg_replace('/[^0123456789]/', '', $num);
2140
2141                 // Shall we cast?
2142                 if ($castValue === TRUE) {
2143                         // Cast to biggest numeric type
2144                         $ret = (double) $ret;
2145                 } // END - if
2146
2147                 // Assert only if requested
2148                 if ($assertMismatch === TRUE) {
2149                         // Has the whole value changed?
2150                         assert(('' . $ret . '' != '' . $num . '') && (!is_null($num)));
2151                 } // END - if
2152
2153                 // Return result
2154                 return $ret;
2155         }
2156
2157         /**
2158          * Checks whether the given hexadecimal number is really a hex-number (only chars 0-9,a-f).
2159          *
2160          * @param       $num    A string consisting only chars between 0 and 9
2161          * @param       $assertMismatch         Whether to assert mismatches
2162          * @return      $ret    The (hopefully) secured hext-numbered value
2163          */
2164         public function hexval ($num, $assertMismatch = FALSE) {
2165                 // Filter all numbers out
2166                 $ret = preg_replace('/[^0123456789abcdefABCDEF]/', '', $num);
2167
2168                 // Assert only if requested
2169                 if ($assertMismatch === TRUE) {
2170                         // Has the whole value changed?
2171                         assert(('' . $ret . '' != '' . $num . '') && (!is_null($num)));
2172                 } // END - if
2173
2174                 // Return result
2175                 return $ret;
2176         }
2177
2178         /**
2179          * Checks whether start/end marker are set
2180          *
2181          * @param       $data   Data to be checked
2182          * @return      $isset  Whether start/end marker are set
2183          */
2184         public final function ifStartEndMarkersSet ($data) {
2185                 // Determine it
2186                 $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));
2187
2188                 // ... and return it
2189                 return $isset;
2190         }
2191
2192         /**
2193          * Determines if an element is set in the generic array
2194          *
2195          * @param       $keyGroup       Main group for the key
2196          * @param       $subGroup       Sub group for the key
2197          * @param       $key            Key to check
2198          * @param       $element        Element to check
2199          * @return      $isset          Whether the given key is set
2200          */
2201         protected final function isGenericArrayElementSet ($keyGroup, $subGroup, $key, $element) {
2202                 // Debug message
2203                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element);
2204
2205                 // Is it there?
2206                 $isset = isset($this->genericArray[$keyGroup][$subGroup][$key][$element]);
2207
2208                 // Return it
2209                 return $isset;
2210         }
2211         /**
2212          * Determines if a key is set in the generic array
2213          *
2214          * @param       $keyGroup       Main group for the key
2215          * @param       $subGroup       Sub group for the key
2216          * @param       $key            Key to check
2217          * @return      $isset          Whether the given key is set
2218          */
2219         protected final function isGenericArrayKeySet ($keyGroup, $subGroup, $key) {
2220                 // Debug message
2221                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
2222
2223                 // Is it there?
2224                 $isset = isset($this->genericArray[$keyGroup][$subGroup][$key]);
2225
2226                 // Return it
2227                 return $isset;
2228         }
2229
2230
2231         /**
2232          * Determines if a group is set in the generic array
2233          *
2234          * @param       $keyGroup       Main group
2235          * @param       $subGroup       Sub group
2236          * @return      $isset          Whether the given group is set
2237          */
2238         protected final function isGenericArrayGroupSet ($keyGroup, $subGroup) {
2239                 // Debug message
2240                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup);
2241
2242                 // Is it there?
2243                 $isset = isset($this->genericArray[$keyGroup][$subGroup]);
2244
2245                 // Return it
2246                 return $isset;
2247         }
2248
2249         /**
2250          * Getter for sub key group
2251          *
2252          * @param       $keyGroup       Main key group
2253          * @param       $subGroup       Sub key group
2254          * @return      $array          An array with all array elements
2255          */
2256         protected final function getGenericSubArray ($keyGroup, $subGroup) {
2257                 // Is it there?
2258                 if (!$this->isGenericArrayGroupSet($keyGroup, $subGroup)) {
2259                         // No, then abort here
2260                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ' not found.');
2261                         exit;
2262                 } // END - if
2263
2264                 // Debug message
2265                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',value=' . print_r($this->genericArray[$keyGroup][$subGroup], TRUE));
2266
2267                 // Return it
2268                 return $this->genericArray[$keyGroup][$subGroup];
2269         }
2270
2271         /**
2272          * Unsets a given key in generic array
2273          *
2274          * @param       $keyGroup       Main group for the key
2275          * @param       $subGroup       Sub group for the key
2276          * @param       $key            Key to unset
2277          * @return      void
2278          */
2279         protected final function unsetGenericArrayKey ($keyGroup, $subGroup, $key) {
2280                 // Debug message
2281                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
2282
2283                 // Remove it
2284                 unset($this->genericArray[$keyGroup][$subGroup][$key]);
2285         }
2286
2287         /**
2288          * Unsets a given element in generic array
2289          *
2290          * @param       $keyGroup       Main group for the key
2291          * @param       $subGroup       Sub group for the key
2292          * @param       $key            Key to unset
2293          * @param       $element        Element to unset
2294          * @return      void
2295          */
2296         protected final function unsetGenericArrayElement ($keyGroup, $subGroup, $key, $element) {
2297                 // Debug message
2298                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element);
2299
2300                 // Remove it
2301                 unset($this->genericArray[$keyGroup][$subGroup][$key][$element]);
2302         }
2303
2304         /**
2305          * Append a string to a given generic array key
2306          *
2307          * @param       $keyGroup       Main group for the key
2308          * @param       $subGroup       Sub group for the key
2309          * @param       $key            Key to unset
2310          * @param       $value          Value to add/append
2311          * @return      void
2312          */
2313         protected final function appendStringToGenericArrayKey ($keyGroup, $subGroup, $key, $value, $appendGlue = '') {
2314                 // Debug message
2315                 //* NOISY-DEBUG: */ if (!is_object($value)) $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',value[' . gettype($value) . ']=' . print_r($value, TRUE) . ',appendGlue=' . $appendGlue);
2316
2317                 // Is it already there?
2318                 if ($this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
2319                         // Append it
2320                         $this->genericArray[$keyGroup][$subGroup][$key] .= $appendGlue . (string) $value;
2321                 } else {
2322                         // Add it
2323                         $this->genericArray[$keyGroup][$subGroup][$key] = (string) $value;
2324                 }
2325         }
2326
2327         /**
2328          * Append a string to a given generic array element
2329          *
2330          * @param       $keyGroup       Main group for the key
2331          * @param       $subGroup       Sub group for the key
2332          * @param       $key            Key to unset
2333          * @param       $element        Element to check
2334          * @param       $value          Value to add/append
2335          * @return      void
2336          */
2337         protected final function appendStringToGenericArrayElement ($keyGroup, $subGroup, $key, $element, $value, $appendGlue = '') {
2338                 // Debug message
2339                 //* NOISY-DEBUG: */ if (!is_object($value)) $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element . ',value[' . gettype($value) . ']=' . print_r($value, TRUE) . ',appendGlue=' . $appendGlue);
2340
2341                 // Is it already there?
2342                 if ($this->isGenericArrayElementSet($keyGroup, $subGroup, $key, $element)) {
2343                         // Append it
2344                         $this->genericArray[$keyGroup][$subGroup][$key][$element] .= $appendGlue . (string) $value;
2345                 } else {
2346                         // Add it
2347                         $this->genericArray[$keyGroup][$subGroup][$key][$element] = (string) $value;
2348                 }
2349         }
2350
2351         /**
2352          * Initializes given generic array group
2353          *
2354          * @param       $keyGroup       Main group for the key
2355          * @param       $subGroup       Sub group for the key
2356          * @param       $key            Key to use
2357          * @param       $forceInit      Optionally force initialization
2358          * @return      void
2359          */
2360         protected final function initGenericArrayGroup ($keyGroup, $subGroup, $forceInit = FALSE) {
2361                 // Debug message
2362                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',forceInit=' . intval($forceInit));
2363
2364                 // Is it already set?
2365                 if (($forceInit === FALSE) && ($this->isGenericArrayGroupSet($keyGroup, $subGroup))) {
2366                         // Already initialized
2367                         trigger_error(__METHOD__ . ':keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ' already initialized.');
2368                         exit;
2369                 } // END - if
2370
2371                 // Initialize it
2372                 $this->genericArray[$keyGroup][$subGroup] = array();
2373         }
2374
2375         /**
2376          * Initializes given generic array key
2377          *
2378          * @param       $keyGroup       Main group for the key
2379          * @param       $subGroup       Sub group for the key
2380          * @param       $key            Key to use
2381          * @param       $forceInit      Optionally force initialization
2382          * @return      void
2383          */
2384         protected final function initGenericArrayKey ($keyGroup, $subGroup, $key, $forceInit = FALSE) {
2385                 // Debug message
2386                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',forceInit=' . intval($forceInit));
2387
2388                 // Is it already set?
2389                 if (($forceInit === FALSE) && ($this->isGenericArrayKeySet($keyGroup, $subGroup, $key))) {
2390                         // Already initialized
2391                         trigger_error(__METHOD__ . ':keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ' already initialized.');
2392                         exit;
2393                 } // END - if
2394
2395                 // Initialize it
2396                 $this->genericArray[$keyGroup][$subGroup][$key] = array();
2397         }
2398
2399         /**
2400          * Initializes given generic array element
2401          *
2402          * @param       $keyGroup       Main group for the key
2403          * @param       $subGroup       Sub group for the key
2404          * @param       $key            Key to use
2405          * @param       $element        Element to use
2406          * @param       $forceInit      Optionally force initialization
2407          * @return      void
2408          */
2409         protected final function initGenericArrayElement ($keyGroup, $subGroup, $key, $element, $forceInit = FALSE) {
2410                 // Debug message
2411                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element . ',forceInit=' . intval($forceInit));
2412
2413                 // Is it already set?
2414                 if (($forceInit === FALSE) && ($this->isGenericArrayElementSet($keyGroup, $subGroup, $key, $element))) {
2415                         // Already initialized
2416                         trigger_error(__METHOD__ . ':keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element . ' already initialized.');
2417                         exit;
2418                 } // END - if
2419
2420                 // Initialize it
2421                 $this->genericArray[$keyGroup][$subGroup][$key][$element] = array();
2422         }
2423
2424         /**
2425          * Pushes an element to a generic key
2426          *
2427          * @param       $keyGroup       Main group for the key
2428          * @param       $subGroup       Sub group for the key
2429          * @param       $key            Key to use
2430          * @param       $value          Value to add/append
2431          * @return      $count          Number of array elements
2432          */
2433         protected final function pushValueToGenericArrayKey ($keyGroup, $subGroup, $key, $value) {
2434                 // Debug message
2435                 //* NOISY-DEBUG: */ if (!is_object($value)) $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',value[' . gettype($value) . ']=' . print_r($value, TRUE));
2436
2437                 // Is it set?
2438                 if (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
2439                         // Initialize array
2440                         $this->initGenericArrayKey($keyGroup, $subGroup, $key);
2441                 } // END - if
2442
2443                 // Then push it
2444                 $count = array_push($this->genericArray[$keyGroup][$subGroup][$key], $value);
2445
2446                 // Return count
2447                 //* DEBUG: */ print(__METHOD__ . ': genericArray=' . print_r($this->genericArray[$keyGroup][$subGroup][$key], TRUE));
2448                 //* DEBUG: */ print(__METHOD__ . ': count=' . $count . PHP_EOL);
2449                 return $count;
2450         }
2451
2452         /**
2453          * Pushes an element to a generic array element
2454          *
2455          * @param       $keyGroup       Main group for the key
2456          * @param       $subGroup       Sub group for the key
2457          * @param       $key            Key to use
2458          * @param       $element        Element to check
2459          * @param       $value          Value to add/append
2460          * @return      $count          Number of array elements
2461          */
2462         protected final function pushValueToGenericArrayElement ($keyGroup, $subGroup, $key, $element, $value) {
2463                 // Debug message
2464                 //* NOISY-DEBUG: */ if (!is_object($value)) $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element . ',value[' . gettype($value) . ']=' . print_r($value, TRUE));
2465
2466                 // Is it set?
2467                 if (!$this->isGenericArrayElementSet($keyGroup, $subGroup, $key, $element)) {
2468                         // Initialize array
2469                         $this->initGenericArrayElement($keyGroup, $subGroup, $key, $element);
2470                 } // END - if
2471
2472                 // Then push it
2473                 $count = array_push($this->genericArray[$keyGroup][$subGroup][$key][$element], $value);
2474
2475                 // Return count
2476                 //* DEBUG: */ print(__METHOD__ . ': genericArray=' . print_r($this->genericArray[$keyGroup][$subGroup][$key], TRUE));
2477                 //* DEBUG: */ print(__METHOD__ . ': count=' . $count . PHP_EOL);
2478                 return $count;
2479         }
2480
2481         /**
2482          * Pops an element from  a generic group
2483          *
2484          * @param       $keyGroup       Main group for the key
2485          * @param       $subGroup       Sub group for the key
2486          * @param       $key            Key to unset
2487          * @return      $value          Last "popped" value
2488          */
2489         protected final function popGenericArrayElement ($keyGroup, $subGroup, $key) {
2490                 // Debug message
2491                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
2492
2493                 // Is it set?
2494                 if (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
2495                         // Not found
2496                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ' not found.');
2497                         exit;
2498                 } // END - if
2499
2500                 // Then "pop" it
2501                 $value = array_pop($this->genericArray[$keyGroup][$subGroup][$key]);
2502
2503                 // Return value
2504                 //* DEBUG: */ print(__METHOD__ . ': genericArray=' . print_r($this->genericArray[$keyGroup][$subGroup][$key], TRUE));
2505                 //* DEBUG: */ print(__METHOD__ . ': value[' . gettype($value) . ']=' . print_r($value, TRUE) . PHP_EOL);
2506                 return $value;
2507         }
2508
2509         /**
2510          * Shifts an element from  a generic group
2511          *
2512          * @param       $keyGroup       Main group for the key
2513          * @param       $subGroup       Sub group for the key
2514          * @param       $key            Key to unset
2515          * @return      $value          Last "popped" value
2516          */
2517         protected final function shiftGenericArrayElement ($keyGroup, $subGroup, $key) {
2518                 // Debug message
2519                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
2520
2521                 // Is it set?
2522                 if (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
2523                         // Not found
2524                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ' not found.');
2525                         exit;
2526                 } // END - if
2527
2528                 // Then "shift" it
2529                 $value = array_shift($this->genericArray[$keyGroup][$subGroup][$key]);
2530
2531                 // Return value
2532                 //* DEBUG: */ print(__METHOD__ . ': genericArray=' . print_r($this->genericArray[$keyGroup][$subGroup][$key], TRUE));
2533                 //* DEBUG: */ print(__METHOD__ . ': value[' . gettype($value) . ']=' . print_r($value, TRUE) . PHP_EOL);
2534                 return $value;
2535         }
2536
2537         /**
2538          * Count generic array group
2539          *
2540          * @param       $keyGroup       Main group for the key
2541          * @return      $count          Count of given group
2542          */
2543         protected final function countGenericArray ($keyGroup) {
2544                 // Debug message
2545                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup);
2546
2547                 // Is it there?
2548                 if (!isset($this->genericArray[$keyGroup])) {
2549                         // Abort here
2550                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ' not found.');
2551                         exit;
2552                 } // END - if
2553
2554                 // Then count it
2555                 $count = count($this->genericArray[$keyGroup]);
2556
2557                 // Debug message
2558                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',count=' . $count);
2559
2560                 // Return it
2561                 return $count;
2562         }
2563
2564         /**
2565          * Count generic array sub group
2566          *
2567          * @param       $keyGroup       Main group for the key
2568          * @param       $subGroup       Sub group for the key
2569          * @return      $count          Count of given group
2570          */
2571         protected final function countGenericArrayGroup ($keyGroup, $subGroup) {
2572                 // Debug message
2573                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup);
2574
2575                 // Is it there?
2576                 if (!$this->isGenericArrayGroupSet($keyGroup, $subGroup)) {
2577                         // Abort here
2578                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ' not found.');
2579                         exit;
2580                 } // END - if
2581
2582                 // Then count it
2583                 $count = count($this->genericArray[$keyGroup][$subGroup]);
2584
2585                 // Debug message
2586                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',count=' . $count);
2587
2588                 // Return it
2589                 return $count;
2590         }
2591
2592         /**
2593          * Count generic array elements
2594          *
2595          * @param       $keyGroup       Main group for the key
2596          * @param       $subGroup       Sub group for the key
2597          * @para        $key            Key to count
2598          * @return      $count          Count of given key
2599          */
2600         protected final function countGenericArrayElements ($keyGroup, $subGroup, $key) {
2601                 // Debug message
2602                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
2603
2604                 // Is it there?
2605                 if (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
2606                         // Abort here
2607                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ' not found.');
2608                         exit;
2609                 } elseif (!$this->isValidGenericArrayGroup($keyGroup, $subGroup)) {
2610                         // Not valid
2611                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ' is not an array.');
2612                         exit;
2613                 }
2614
2615                 // Then count it
2616                 $count = count($this->genericArray[$keyGroup][$subGroup][$key]);
2617
2618                 // Debug message
2619                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',count=' . $count);
2620
2621                 // Return it
2622                 return $count;
2623         }
2624
2625         /**
2626          * Getter for whole generic group array
2627          *
2628          * @param       $keyGroup       Key group to get
2629          * @return      $array          Whole generic array group
2630          */
2631         protected final function getGenericArray ($keyGroup) {
2632                 // Debug message
2633                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup);
2634
2635                 // Is it there?
2636                 if (!isset($this->genericArray[$keyGroup])) {
2637                         // Then abort here
2638                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ' does not exist.');
2639                         exit;
2640                 } // END - if
2641
2642                 // Return it
2643                 return $this->genericArray[$keyGroup];
2644         }
2645
2646         /**
2647          * Setter for generic array key
2648          *
2649          * @param       $keyGroup       Key group to get
2650          * @param       $subGroup       Sub group for the key
2651          * @param       $key            Key to unset
2652          * @param       $value          Mixed value from generic array element
2653          * @return      void
2654          */
2655         protected final function setGenericArrayKey ($keyGroup, $subGroup, $key, $value) {
2656                 // Debug message
2657                 //* NOISY-DEBUG: */ if (!is_object($value)) $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',value[' . gettype($value) . ']=' . print_r($value, TRUE));
2658
2659                 // Set value here
2660                 $this->genericArray[$keyGroup][$subGroup][$key] = $value;
2661         }
2662
2663         /**
2664          * Getter for generic array key
2665          *
2666          * @param       $keyGroup       Key group to get
2667          * @param       $subGroup       Sub group for the key
2668          * @param       $key            Key to unset
2669          * @return      $value          Mixed value from generic array element
2670          */
2671         protected final function getGenericArrayKey ($keyGroup, $subGroup, $key) {
2672                 // Debug message
2673                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
2674
2675                 // Is it there?
2676                 if (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
2677                         // Then abort here
2678                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ' does not exist.');
2679                         exit;
2680                 } // END - if
2681
2682                 // Return it
2683                 return $this->genericArray[$keyGroup][$subGroup][$key];
2684         }
2685
2686         /**
2687          * Sets a value in given generic array key/element
2688          *
2689          * @param       $keyGroup       Main group for the key
2690          * @param       $subGroup       Sub group for the key
2691          * @param       $key            Key to set
2692          * @param       $element        Element to set
2693          * @param       $value          Value to set
2694          * @return      void
2695          */
2696         protected final function setGenericArrayElement ($keyGroup, $subGroup, $key, $element, $value) {
2697                 // Debug message
2698                 //* NOISY-DEBUG: */ if (!is_object($value)) $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element . ',value[' . gettype($value) . ']=' . print_r($value, TRUE));
2699
2700                 // Then set it
2701                 $this->genericArray[$keyGroup][$subGroup][$key][$element] = $value;
2702         }
2703
2704         /**
2705          * Getter for generic array element
2706          *
2707          * @param       $keyGroup       Key group to get
2708          * @param       $subGroup       Sub group for the key
2709          * @param       $key            Key to look for
2710          * @param       $element        Element to look for
2711          * @return      $value          Mixed value from generic array element
2712          */
2713         protected final function getGenericArrayElement ($keyGroup, $subGroup, $key, $element) {
2714                 // Debug message
2715                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element);
2716
2717                 // Is it there?
2718                 if (!$this->isGenericArrayElementSet($keyGroup, $subGroup, $key, $element)) {
2719                         // Then abort here
2720                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element . ' does not exist.');
2721                         exit;
2722                 } // END - if
2723
2724                 // Return it
2725                 return $this->genericArray[$keyGroup][$subGroup][$key][$element];
2726         }
2727
2728         /**
2729          * Checks if a given sub group is valid (array)
2730          *
2731          * @param       $keyGroup       Key group to get
2732          * @param       $subGroup       Sub group for the key
2733          * @return      $isValid        Whether given sub group is valid
2734          */
2735         protected final function isValidGenericArrayGroup ($keyGroup, $subGroup) {
2736                 // Debug message
2737                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup);
2738
2739                 // Determine it
2740                 $isValid = (($this->isGenericArrayGroupSet($keyGroup, $subGroup)) && (is_array($this->getGenericSubArray($keyGroup, $subGroup))));
2741
2742                 // Return it
2743                 return $isValid;
2744         }
2745
2746         /**
2747          * Checks if a given key is valid (array)
2748          *
2749          * @param       $keyGroup       Key group to get
2750          * @param       $subGroup       Sub group for the key
2751          * @param       $key            Key to check
2752          * @return      $isValid        Whether given sub group is valid
2753          */
2754         protected final function isValidGenericArrayKey ($keyGroup, $subGroup, $key) {
2755                 // Debug message
2756                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
2757
2758                 // Determine it
2759                 $isValid = (($this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) && (is_array($this->getGenericArrayKey($keyGroup, $subGroup, $key))));
2760
2761                 // Return it
2762                 return $isValid;
2763         }
2764
2765         /**
2766          * Translates boolean TRUE to 'Y' and FALSE to 'N'
2767          *
2768          * @param       $boolean                Boolean value
2769          * @return      $translated             Translated boolean value
2770          */
2771         public static final function translateBooleanToYesNo ($boolean) {
2772                 // Make sure it is really boolean
2773                 assert(is_bool($boolean));
2774
2775                 // "Translate" it
2776                 $translated = ($boolean === TRUE) ? 'Y' : 'N';
2777
2778                 // ... and return it
2779                 return $translated;
2780         }
2781 }
2782
2783 // [EOF]
2784 ?>