New field/attribute 'cryptoInstance' introduced:
[core.git] / inc / classes / main / class_BaseFrameworkSystem.php
1 <?php
2 /**
3  * The simulator system class is the super class of all other classes. This
4  * class handles saving of games etc.
5  *
6  * @author              Roland Haeder <webmaster@ship-simu.org>
7  * @version             0.0.0
8  * @copyright   Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2011 Core Developer Team
9  * @license             GNU GPL 3.0 or any newer version
10  * @link                http://www.ship-simu.org
11  *
12  * This program is free software: you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation, either version 3 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program. If not, see <http://www.gnu.org/licenses/>.
24  */
25 class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
26         /**
27          * Instance of a request class
28          */
29         private $requestInstance = null;
30
31         /**
32          * Instance of a response class
33          */
34         private $responseInstance = null;
35
36         /**
37          * Search criteria instance
38          */
39         private $searchInstance = null;
40
41         /**
42          * Update criteria instance
43          */
44         private $updateInstance = null;
45
46         /**
47          * The file I/O instance for the template loader
48          */
49         private $fileIoInstance = null;
50
51         /**
52          * Resolver instance
53          */
54         private $resolverInstance = null;
55
56         /**
57          * Template engine instance
58          */
59         private $templateInstance = null;
60
61         /**
62          * Database result instance
63          */
64         private $resultInstance = null;
65
66         /**
67          * Instance for user class
68          */
69         private $userInstance = null;
70
71         /**
72          * A controller instance
73          */
74         private $controllerInstance = null;
75
76         /**
77          * Instance of a RNG
78          */
79         private $rngInstance = null;
80
81         /**
82          * Instance of a crypto helper
83          */
84         private $cryptoInstance = null;
85
86         /**
87          * Instance of an Iterator class
88          */
89         private $iteratorInstance = null;
90
91         /**
92          * Instance of the list
93          */
94         private $listInstance = null;
95
96         /**
97          * Instance of a menu
98          */
99         private $menuInstance = null;
100
101         /**
102          * Instance of the image
103          */
104         private $imageInstance = null;
105
106         /**
107          * Instance of the stacker
108          */
109         private $stackerInstance = null;
110
111         /**
112          * A Compressor instance
113          */
114         private $compressorInstance = null;
115
116         /**
117          * A Parseable instance
118          */
119         private $parserInstance = null;
120
121         /**
122          * A ProtocolHandler instance
123          */
124         private $protocolInstance = null;
125
126         /**
127          * A database wrapper instance
128          */
129         private $databaseInstance = null;
130
131         /**
132          * The real class name
133          */
134         private $realClass = 'BaseFrameworkSystem';
135
136         /**
137          * Thousands seperator
138          */
139         private $thousands = '.'; // German
140
141         /**
142          * Decimal seperator
143          */
144         private $decimals  = ','; // German
145
146         /**
147          * Socket resource
148          */
149         private $socketResource = false;
150
151         /**
152          * Package data
153          */
154         private $packageData = array();
155
156         /***********************
157          * Exception codes.... *
158          ***********************/
159         // @todo Try to clean these constants up
160         const EXCEPTION_IS_NULL_POINTER              = 0x001;
161         const EXCEPTION_IS_NO_OBJECT                 = 0x002;
162         const EXCEPTION_IS_NO_ARRAY                  = 0x003;
163         const EXCEPTION_MISSING_METHOD               = 0x004;
164         const EXCEPTION_CLASSES_NOT_MATCHING         = 0x005;
165         const EXCEPTION_INDEX_OUT_OF_BOUNDS          = 0x006;
166         const EXCEPTION_DIMENSION_ARRAY_INVALID      = 0x007;
167         const EXCEPTION_ITEM_NOT_TRADEABLE           = 0x008;
168         const EXCEPTION_ITEM_NOT_IN_PRICE_LIST       = 0x009;
169         const EXCEPTION_GENDER_IS_WRONG              = 0x00a;
170         const EXCEPTION_BIRTH_DATE_IS_INVALID        = 0x00b;
171         const EXCEPTION_EMPTY_STRUCTURES_ARRAY       = 0x00c;
172         const EXCEPTION_HAS_ALREADY_PERSONELL_LIST   = 0x00d;
173         const EXCEPTION_NOT_ENOUGTH_UNEMPLOYEES      = 0x00e;
174         const EXCEPTION_TOTAL_PRICE_NOT_CALCULATED   = 0x00f;
175         const EXCEPTION_HARBOR_HAS_NO_SHIPYARDS      = 0x010;
176         const EXCEPTION_CONTRACT_PARTNER_INVALID     = 0x011;
177         const EXCEPTION_CONTRACT_PARTNER_MISMATCH    = 0x012;
178         const EXCEPTION_CONTRACT_ALREADY_SIGNED      = 0x013;
179         const EXCEPTION_UNEXPECTED_EMPTY_STRING      = 0x014;
180         const EXCEPTION_PATH_NOT_FOUND               = 0x015;
181         const EXCEPTION_INVALID_PATH_NAME            = 0x016;
182         const EXCEPTION_READ_PROTECED_PATH           = 0x017;
183         const EXCEPTION_WRITE_PROTECED_PATH          = 0x018;
184         const EXCEPTION_DIR_POINTER_INVALID          = 0x019;
185         const EXCEPTION_FILE_POINTER_INVALID         = 0x01a;
186         const EXCEPTION_INVALID_RESOURCE             = 0x01b;
187         const EXCEPTION_UNEXPECTED_OBJECT            = 0x01c;
188         const EXCEPTION_LIMIT_ELEMENT_IS_UNSUPPORTED = 0x01d;
189         const EXCEPTION_GETTER_IS_MISSING            = 0x01e;
190         const EXCEPTION_ARRAY_EXPECTED               = 0x01f;
191         const EXCEPTION_ARRAY_HAS_INVALID_COUNT      = 0x020;
192         const EXCEPTION_ID_IS_INVALID_FORMAT         = 0x021;
193         const EXCEPTION_MD5_CHECKSUMS_MISMATCH       = 0x022;
194         const EXCEPTION_UNEXPECTED_STRING_SIZE       = 0x023;
195         const EXCEPTION_SIMULATOR_ID_INVALID         = 0x024;
196         const EXCEPTION_MISMATCHING_COMPRESSORS      = 0x025;
197         const EXCEPTION_CONTAINER_ITEM_IS_NULL       = 0x026;
198         const EXCEPTION_ITEM_IS_NO_ARRAY             = 0x027;
199         const EXCEPTION_CONTAINER_MAYBE_DAMAGED      = 0x028;
200         const EXCEPTION_INVALID_STRING               = 0x029;
201         const EXCEPTION_VARIABLE_NOT_SET             = 0x02a;
202         const EXCEPTION_ATTRIBUTES_ARE_MISSING       = 0x02b;
203         const EXCEPTION_ARRAY_ELEMENTS_MISSING       = 0x02c;
204         const EXCEPTION_TEMPLATE_ENGINE_UNSUPPORTED  = 0x02d;
205         const EXCEPTION_MISSING_ELEMENT              = 0x030;
206         const EXCEPTION_HEADERS_ALREADY_SENT         = 0x031;
207         const EXCEPTION_DEFAULT_CONTROLLER_GONE      = 0x032;
208         const EXCEPTION_CLASS_NOT_FOUND              = 0x033;
209         const EXCEPTION_REQUIRED_INTERFACE_MISSING   = 0x034;
210         const EXCEPTION_FATAL_ERROR                  = 0x035;
211         const EXCEPTION_FILE_NOT_FOUND               = 0x036;
212         const EXCEPTION_ASSERTION_FAILED             = 0x037;
213         const EXCEPTION_FILE_CANNOT_BE_READ          = 0x038;
214         const EXCEPTION_DATABASE_UPDATED_NOT_ALLOWED = 0x039;
215         const EXCEPTION_FILTER_CHAIN_INTERCEPTED     = 0x040;
216
217         /**
218          * Protected super constructor
219          *
220          * @param       $className      Name of the class
221          * @return      void
222          */
223         protected function __construct ($className) {
224                 // Set real class
225                 $this->setRealClass($className);
226
227                 // Set configuration instance if no registry ...
228                 if (!$this instanceof Register) {
229                         // ... because registries doesn't need to be configured
230                         $this->setConfigInstance(FrameworkConfiguration::getInstance());
231                 } // END - if
232         }
233
234         /**
235          * Destructor reached...
236          *
237          * @return      void
238          */
239         public function __destruct() {
240                 // Flush any updated entries to the database
241                 $this->flushPendingUpdates();
242
243                 // Is this object already destroyed?
244                 if ($this->__toString() != 'DestructedObject') {
245                         // Destroy all informations about this class but keep some text about it alive
246                         $this->setRealClass('DestructedObject');
247                 } elseif ((defined('DEBUG_DESTRUCTOR')) && (is_object($this->getDebugInstance()))) {
248                         // Already destructed object
249                         $this->debugOutput(sprintf("[%s:] The object <span class=\"object_name\">%s</span> is already destroyed.",
250                                 __CLASS__,
251                                 $this->__toString()
252                         ));
253                 }
254         }
255
256         /**
257          * The __call() method where all non-implemented methods end up
258          *
259          * @param       $methodName             Name of the missing method
260          * @args        $args                   Arguments passed to the method
261          * @return      void
262          */
263         public final function __call ($methodName, $args) {
264                 // Implode all given arguments
265                 $argsString = '';
266                 if (empty($args)) {
267                         // No arguments
268                         $argsString = 'NULL';
269                 } elseif (is_array($args)) {
270                         // Some arguments are there
271                         foreach ($args as $arg) {
272                                 // Add the type
273                                 $argsString .= $this->replaceControlCharacters($arg) . ' (' . gettype($arg);
274
275                                 // Add length if type is string
276                                 if (is_string($arg)) {
277                                         $argsString .= ', '.strlen($arg);
278                                 } // END - if
279
280                                 // Closing bracket
281                                 $argsString .= '), ';
282                         } // END - foreach
283
284                         // Remove last comma
285                         if (substr($argsString, -2, 1) == ',') {
286                                 $argsString = substr($argsString, 0, -2);
287                         } // END - if
288                 } else {
289                         // Invalid arguments!
290                         $argsString = '!INVALID:' . gettype($args) . '!';
291                 }
292
293                 // Output stub message
294                 $this->debugOutput(sprintf("[%s-&gt;%s] Stub! Args: %s",
295                         $this->__toString(),
296                         $methodName,
297                         $argsString
298                 ));
299
300                 // Return nothing
301                 return null;
302         }
303
304         /**
305          * Getter for $realClass
306          *
307          * @return      $realClass The name of the real class (not BaseFrameworkSystem)
308          */
309         public function __toString () {
310                 return $this->realClass;
311         }
312
313         /**
314          * Setter for database result instance
315          *
316          * @param       $resultInstance         An instance of a database result class
317          * @return      void
318          * @todo        SearchableResult and UpdateableResult shall have a super interface to use here
319          */
320         protected final function setResultInstance (SearchableResult $resultInstance) {
321                 $this->resultInstance =  $resultInstance;
322         }
323
324         /**
325          * Getter for database result instance
326          *
327          * @return      $resultInstance         An instance of a database result class
328          */
329         public final function getResultInstance () {
330                 return $this->resultInstance;
331         }
332
333         /**
334          * Setter for template engine instances
335          *
336          * @param       $templateInstance       An instance of a template engine class
337          * @return      void
338          */
339         protected final function setTemplateInstance (CompileableTemplate $templateInstance) {
340                 $this->templateInstance = $templateInstance;
341         }
342
343         /**
344          * Getter for template engine instances
345          *
346          * @return      $templateInstance       An instance of a template engine class
347          */
348         protected final function getTemplateInstance () {
349                 return $this->templateInstance;
350         }
351
352         /**
353          * Setter for search instance
354          *
355          * @param       $searchInstance         Searchable criteria instance
356          * @return      void
357          */
358         public final function setSearchInstance (LocalSearchCriteria $searchInstance) {
359                 $this->searchInstance = $searchInstance;
360         }
361
362         /**
363          * Getter for search instance
364          *
365          * @return      $searchInstance         Searchable criteria instance
366          */
367         public final function getSearchInstance () {
368                 return $this->searchInstance;
369         }
370
371         /**
372          * Setter for update instance
373          *
374          * @param       $updateInstance         Searchable criteria instance
375          * @return      void
376          */
377         public final function setUpdateInstance (LocalUpdateCriteria $updateInstance) {
378                 $this->updateInstance = $updateInstance;
379         }
380
381         /**
382          * Getter for update instance
383          *
384          * @return      $updateInstance         Updateable criteria instance
385          */
386         public final function getUpdateInstance () {
387                 return $this->updateInstance;
388         }
389
390         /**
391          * Setter for resolver instance
392          *
393          * @param       $resolverInstance       Instance of a command resolver class
394          * @return      void
395          */
396         public final function setResolverInstance (Resolver $resolverInstance) {
397                 $this->resolverInstance = $resolverInstance;
398         }
399
400         /**
401          * Getter for resolver instance
402          *
403          * @return      $resolverInstance       Instance of a command resolver class
404          */
405         public final function getResolverInstance () {
406                 return $this->resolverInstance;
407         }
408
409         /**
410          * Setter for language instance
411          *
412          * @param       $configInstance         The configuration instance which shall
413          *                                                              be FrameworkConfiguration
414          * @return      void
415          */
416         public final function setConfigInstance (FrameworkConfiguration $configInstance) {
417                 Registry::getRegistry()->addInstance('config', $configInstance);
418         }
419
420         /**
421          * Getter for configuration instance
422          *
423          * @return      $configInstance         Configuration instance
424          */
425         public final function getConfigInstance () {
426                 $configInstance = Registry::getRegistry()->getInstance('config');
427                 return $configInstance;
428         }
429
430         /**
431          * Setter for debug instance
432          *
433          * @param       $debugInstance  The instance for debug output class
434          * @return      void
435          */
436         public final function setDebugInstance (DebugMiddleware $debugInstance) {
437                 Registry::getRegistry()->addInstance('debug', $debugInstance);
438         }
439
440         /**
441          * Getter for debug instance
442          *
443          * @return      $debugInstance  Instance to class DebugConsoleOutput or DebugWebOutput
444          */
445         public final function getDebugInstance () {
446                 // Get debug instance
447                 $debugInstance = Registry::getRegistry()->getInstance('debug');
448
449                 // Return it
450                 return $debugInstance;
451         }
452
453         /**
454          * Setter for web output instance
455          *
456          * @param               $webInstance    The instance for web output class
457          * @return      void
458          */
459         public final function setWebOutputInstance (OutputStreamer $webInstance) {
460                 Registry::getRegistry()->addInstance('web_output', $webInstance);
461         }
462
463         /**
464          * Getter for web output instance
465          *
466          * @return      $webOutputInstance - Instance to class WebOutput
467          */
468         public final function getWebOutputInstance () {
469                 $webOutputInstance = Registry::getRegistry()->getInstance('web_output');
470                 return $webOutputInstance;
471         }
472
473         /**
474          * Setter for database instance
475          *
476          * @param               $dbInstance     The instance for the database connection (forced DatabaseConnection)
477          * @return      void
478          */
479         public final function setDatabaseInstance (DatabaseConnection $dbInstance) {
480                 Registry::getRegistry()->addInstance('db_instance', $dbInstance);
481         }
482
483         /**
484          * Getter for database layer
485          *
486          * @return      $dbInstance     The database layer instance
487          */
488         public final function getDatabaseInstance () {
489                 // Get instance
490                 $dbInstance = Registry::getRegistry()->getInstance('db_instance');
491
492                 // Return instance
493                 return $dbInstance;
494         }
495
496         /**
497          * Setter for compressor channel
498          *
499          * @param               $compressorInstance             An instance of CompressorChannel
500          * @return      void
501          */
502         public final function setCompressorChannel (CompressorChannel $compressorInstance) {
503                 Registry::getRegistry()->addInstance('compressor', $compressorInstance);
504         }
505
506         /**
507          * Getter for compressor channel
508          *
509          * @return      $compressorInstance             The compressor channel
510          */
511         public final function getCompressorChannel () {
512                 $compressorInstance = Registry::getRegistry()->getInstance('compressor');
513                 return $compressorInstance;
514         }
515
516         /**
517          * Protected getter for a manageable application helper class
518          *
519          * @return      $applicationInstance    An instance of a manageable application helper class
520          */
521         protected final function getApplicationInstance () {
522                 $applicationInstance = Registry::getRegistry()->getInstance('application');
523                 return $applicationInstance;
524         }
525
526         /**
527          * Setter for a manageable application helper class
528          *
529          * @param       $applicationInstance    An instance of a manageable application helper class
530          * @return      void
531          */
532         public final function setApplicationInstance (ManageableApplication $applicationInstance) {
533                 Registry::getRegistry()->addInstance('application', $applicationInstance);
534         }
535
536         /**
537          * Setter for request instance
538          *
539          * @param       $requestInstance        An instance of a Requestable class
540          * @return      void
541          */
542         public final function setRequestInstance (Requestable $requestInstance) {
543                 $this->requestInstance = $requestInstance;
544         }
545
546         /**
547          * Getter for request instance
548          *
549          * @return      $requestInstance        An instance of a Requestable class
550          */
551         public final function getRequestInstance () {
552                 return $this->requestInstance;
553         }
554
555         /**
556          * Setter for response instance
557          *
558          * @param       $responseInstance       An instance of a Responseable class
559          * @return      void
560          */
561         public final function setResponseInstance (Responseable $responseInstance) {
562                 $this->responseInstance = $responseInstance;
563         }
564
565         /**
566          * Getter for response instance
567          *
568          * @return      $responseInstance       An instance of a Responseable class
569          */
570         public final function getResponseInstance () {
571                 return $this->responseInstance;
572         }
573
574         /**
575          * Setter for the real class name
576          *
577          * @param               $realClass      Class name (string)
578          * @return      void
579          */
580         public final function setRealClass ($realClass) {
581                 // Cast to string
582                 $realClass = (string) $realClass;
583
584                 // Set real class
585                 $this->realClass = $realClass;
586         }
587
588         /**
589          * Checks wether an object equals this object. You should overwrite this
590          * method to implement own equality checks
591          *
592          * @param       $objectInstance         An instance of a FrameworkInterface object
593          * @return      $equals                         Wether both objects equals
594          */
595         public function equals (FrameworkInterface $objectInstance) {
596                 // Now test it
597                 $equals = ((
598                         $this->__toString() == $objectInstance->__toString()
599                 ) && (
600                         $this->hashCode() == $objectInstance->hashCode()
601                 ));
602
603                 // Return the result
604                 return $equals;
605         }
606
607         /**
608          * Generates a generic hash code of this class. You should really overwrite
609          * this method with your own hash code generator code. But keep KISS in mind.
610          *
611          * @return      $hashCode       A generic hash code respresenting this whole class
612          */
613         public function hashCode () {
614                 // Simple hash code
615                 return crc32($this->__toString());
616         }
617
618         /**
619          * Formats computer generated price values into human-understandable formats
620          * with thousand and decimal seperators.
621          *
622          * @param       $value          The in computer format value for a price
623          * @param       $currency       The currency symbol (use HTML-valid characters!)
624          * @param       $decNum         Number of decimals after commata
625          * @return      $price          The for the current language formated price string
626          * @throws      MissingDecimalsThousandsSeperatorException      If decimals or
627          *                                                                                              thousands seperator
628          *                                                                                              is missing
629          */
630         public function formatCurrency ($value, $currency = '&euro;', $decNum = 2) {
631                 // Are all required attriutes set?
632                 if ((!isset($this->decimals)) || (!isset($this->thousands))) {
633                         // Throw an exception
634                         throw new MissingDecimalsThousandsSeperatorException($this, self::EXCEPTION_ATTRIBUTES_ARE_MISSING);
635                 } // END - if
636
637                 // Cast the number
638                 $value = (float) $value;
639
640                 // Reformat the US number
641                 $price = number_format($value, $decNum, $this->decimals, $this->thousands) . $currency;
642
643                 // Return as string...
644                 return $price;
645         }
646
647         /**
648          * Private getter for language instance
649          *
650          * @return      $langInstance   An instance to the language sub-system
651          */
652         protected final function getLanguageInstance () {
653                 $langInstance = Registry::getRegistry()->getInstance('language');
654                 return $langInstance;
655         }
656
657         /**
658          * Setter for language instance
659          *
660          * @param       $langInstance   An instance to the language sub-system
661          * @return      void
662          * @see         LanguageSystem
663          */
664         public final function setLanguageInstance (ManageableLanguage $langInstance) {
665                 Registry::getRegistry()->addInstance('language', $langInstance);
666         }
667
668         /**
669          * Appends a trailing slash to a string
670          *
671          * @param       $str            A string (maybe) without trailing slash
672          * @return      $str            A string with an auto-appended trailing slash
673          */
674         public final function addMissingTrailingSlash ($str) {
675                 // Is there a trailing slash?
676                 if (substr($str, -1, 1) != '/') {
677                         $str .= '/';
678                 } // END - if
679
680                 // Return string with trailing slash
681                 return $str;
682         }
683
684         /**
685          * Private getter for file IO instance
686          *
687          * @return      $fileIoInstance An instance to the file I/O sub-system
688          */
689         protected final function getFileIoInstance () {
690                 return $this->fileIoInstance;
691         }
692
693         /**
694          * Setter for file I/O instance
695          *
696          * @param       $fileIoInstance An instance to the file I/O sub-system
697          * @return      void
698          */
699         public final function setFileIoInstance (FileIoHandler $fileIoInstance) {
700                 $this->fileIoInstance = $fileIoInstance;
701         }
702
703         /**
704          * Prepare the template engine (WebTemplateEngine by default) for a given
705          * application helper instance (ApplicationHelper by default).
706          *
707          * @param               $applicationInstance    An application helper instance or
708          *                                                                              null if we shall use the default
709          * @return              $templateInstance               The template engine instance
710          * @throws              NullPointerException    If the discovered application
711          *                                                                              instance is still null
712          */
713         protected function prepareTemplateInstance (ManageableApplication $applicationInstance = null) {
714                 // Is the application instance set?
715                 if (is_null($applicationInstance)) {
716                         // Get the current instance
717                         $applicationInstance = $this->getApplicationInstance();
718
719                         // Still null?
720                         if (is_null($applicationInstance)) {
721                                 // Thrown an exception
722                                 throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
723                         } // END - if
724                 } // END - if
725
726                 // Initialize the template engine
727                 $templateInstance = ObjectFactory::createObjectByConfiguredName('web_template_class');
728
729                 // Return the prepared instance
730                 return $templateInstance;
731         }
732
733         /**
734          * Debugs this instance by putting out it's full content
735          *
736          * @param       $message        Optional message to show in debug output
737          * @return      void
738          */
739         public final function debugInstance ($message = '') {
740                 // Restore the error handler to avoid trouble with missing array elements or undeclared variables
741                 restore_error_handler();
742
743                 // Init content
744                 $content = '';
745
746                 // Is a message set?
747                 if (!empty($message)) {
748                         // Construct message
749                         $content = sprintf("<div class=\"debug_message\">Message: %s</div>\n", $message);
750                 } // END - if
751
752                 // Generate the output
753                 $content .= sprintf("<pre>%s</pre>",
754                         trim(
755                                 htmlentities(
756                                         print_r($this, true)
757                                 )
758                         )
759                 );
760
761                 // Output it
762                 ApplicationEntryPoint::app_die(sprintf("<div class=\"debug_header\">%s debug output:</div><div class=\"debug_content\">%s</div>\nLoaded includes: <div class=\"debug_include_list\">%s</div>",
763                         $this->__toString(),
764                         $content,
765                         ClassLoader::getInstance()->getPrintableIncludeList()
766                 ));
767         }
768
769         /**
770          * Replaces control characters with printable output
771          *
772          * @param       $str    String with control characters
773          * @return      $str    Replaced string
774          */
775         protected function replaceControlCharacters ($str) {
776                 // Replace them
777                 $str = str_replace(
778                         "\r", '[r]', str_replace(
779                         "\n", '[n]', str_replace(
780                         "\t", '[t]',
781                         $str
782                 )));
783
784                 // Return it
785                 return $str;
786         }
787
788         /**
789          * Output a partial stub message for the caller method
790          *
791          * @param       $message        An optional message to display
792          * @return      void
793          */
794         protected function partialStub ($message = '') {
795                 // Get the backtrace
796                 $backtrace = debug_backtrace();
797
798                 // Generate the class::method string
799                 $methodName = 'UnknownClass-&gt;unknownMethod';
800                 if ((isset($backtrace[1]['class'])) && (isset($backtrace[1]['function']))) {
801                         $methodName = $backtrace[1]['class'] . '-&gt;' . $backtrace[1]['function'];
802                 } // END - if
803
804                 // Construct the full message
805                 $stubMessage = sprintf("[%s:] Partial stub!",
806                         $methodName
807                 );
808
809                 // Is the extra message given?
810                 if (!empty($message)) {
811                         // Then add it as well
812                         $stubMessage .= sprintf(" Message: <span id=\"stub_message\">%s</span>", $message);
813                 } // END - if
814
815                 // Debug instance is there?
816                 if (!is_null($this->getDebugInstance())) {
817                         // Output stub message
818                         $this->debugOutput($stubMessage);
819                 } else {
820                         // Trigger an error
821                         trigger_error($stubMessage . "<br />\n");
822                 }
823         }
824
825         /**
826          * Outputs a debug backtrace and stops further script execution
827          *
828          * @return      void
829          */
830         public function debugBackTrace () {
831                 // Sorry, there is no other way getting this nice backtrace
832                 print("<pre>\n");
833                 debug_print_backtrace();
834                 print("</pre>");
835                 exit();
836         }
837
838         /**
839          * Outputs a debug message wether to debug instance (should be set!) or dies with or pints the message
840          *
841          * @param       $message        Message we shall send out...
842          * @param       $doPrint        Wether we shall print or die here which first is the default
843          * @return      void
844          */
845         public function debugOutput ($message, $doPrint = true) {
846                 // Get debug instance
847                 $debugInstance = $this->getDebugInstance();
848
849                 // Is the debug instance there?
850                 if (is_object($debugInstance)) {
851                         // Use debug output handler
852                         $debugInstance->output($message);
853
854                         if ($doPrint === false) {
855                                 // Die here if not printed
856                                 die();
857                         } // END - if
858                 } else {
859                         // Put directly out
860                         if ($doPrint === true) {
861                                 print($message);
862                         } else {
863                                 // DO NOT REWRITE THIS TO app_die() !!!
864                                 die($message);
865                         }
866                 }
867         }
868
869         /**
870          * Converts e.g. a command from URL to a valid class by keeping out bad characters
871          *
872          * @param       $str            The string, what ever it is needs to be converted
873          * @return      $className      Generated class name
874          */
875         public function convertToClassName ($str) {
876                 // Init class name
877                 $className = '';
878
879                 // Convert all dashes in underscores
880                 $str = $this->convertDashesToUnderscores($str);
881
882                 // Now use that underscores to get classname parts for hungarian style
883                 foreach (explode('_', $str) as $strPart) {
884                         // Make the class name part lower case and first upper case
885                         $className .= ucfirst(strtolower($strPart));
886                 } // END - foreach
887
888                 // Return class name
889                 return $className;
890         }
891
892         /**
893          * Converts dashes to underscores, e.g. useable for configuration entries
894          *
895          * @param       $str    The string with maybe dashes inside
896          * @return      $str    The converted string with no dashed, but underscores
897          */
898         public final function convertDashesToUnderscores ($str) {
899                 // Convert them all
900                 $str = str_replace('-', '_', $str);
901
902                 // Return converted string
903                 return $str;
904         }
905
906         /**
907          * Marks up the code by adding e.g. line numbers
908          *
909          * @param       $phpCode                Unmarked PHP code
910          * @return      $markedCode             Marked PHP code
911          */
912         public function markupCode ($phpCode) {
913                 // Init marked code
914                 $markedCode = '';
915
916                 // Get last error
917                 $errorArray = error_get_last();
918
919                 // Init the code with error message
920                 if (is_array($errorArray)) {
921                         // Get error infos
922                         $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>",
923                                 basename($errorArray['file']),
924                                 $errorArray['line'],
925                                 $errorArray['message'],
926                                 $errorArray['type']
927                         );
928                 } // END - if
929
930                 // Add line number to the code
931                 foreach (explode("\n", $phpCode) as $lineNo => $code) {
932                         // Add line numbers
933                         $markedCode .= sprintf("<span id=\"code_line\">%s</span>: %s\n",
934                                 ($lineNo + 1),
935                                 htmlentities($code, ENT_QUOTES)
936                         );
937                 } // END - foreach
938
939                 // Return the code
940                 return $markedCode;
941         }
942
943         /**
944          * Filter a given GMT timestamp (non Uni* stamp!) to make it look more
945          * beatiful for web-based front-ends. If null is given a message id
946          * null_timestamp will be resolved and returned.
947          *
948          * @param       $timestamp      Timestamp to prepare (filter) for display
949          * @return      $readable       A readable timestamp
950          */
951         public function doFilterFormatTimestamp ($timestamp) {
952                 // Default value to return
953                 $readable = '???';
954
955                 // Is the timestamp null?
956                 if (is_null($timestamp)) {
957                         // Get a message string
958                         $readable = $this->getLanguageInstance()->getMessage('null_timestamp');
959                 } else {
960                         switch ($this->getLanguageInstance()->getLanguageCode()) {
961                                 case 'de': // German format is a bit different to default
962                                         // Split the GMT stamp up
963                                         $dateTime  = explode(' ', $timestamp  );
964                                         $dateArray = explode('-', $dateTime[0]);
965                                         $timeArray = explode(':', $dateTime[1]);
966
967                                         // Construct the timestamp
968                                         $readable = sprintf($this->getConfigInstance()->getConfigEntry('german_date_time'),
969                                                 $dateArray[0],
970                                                 $dateArray[1],
971                                                 $dateArray[2],
972                                                 $timeArray[0],
973                                                 $timeArray[1],
974                                                 $timeArray[2]
975                                         );
976                                         break;
977
978                                 default: // Default is pass-through
979                                         $readable = $timestamp;
980                                         break;
981                         } // END - switch
982                 }
983
984                 // Return the stamp
985                 return $readable;
986         }
987
988         /**
989          * Filter a given number into a localized number
990          *
991          * @param       $value          The raw value from e.g. database
992          * @return      $localized      Localized value
993          */
994         public function doFilterFormatNumber ($value) {
995                 // Generate it from config and localize dependencies
996                 switch ($this->getLanguageInstance()->getLanguageCode()) {
997                         case 'de': // German format is a bit different to default
998                                 $localized = number_format($value, $this->getConfigInstance()->getConfigEntry('decimals'), ',', '.');
999                                 break;
1000
1001                         default: // US, etc.
1002                                 $localized = number_format($value, $this->getConfigInstance()->getConfigEntry('decimals'), '.', ',');
1003                                 break;
1004                 } // END - switch
1005
1006                 // Return it
1007                 return $localized;
1008         }
1009
1010         /**
1011          * "Getter" for databse entry
1012          *
1013          * @return      $entry  An array with database entries
1014          * @throws      NullPointerException    If the database result is not found
1015          * @throws      InvalidDatabaseResultException  If the database result is invalid
1016          */
1017         protected final function getDatabaseEntry () {
1018                 // Is there an instance?
1019                 if (is_null($this->getResultInstance())) {
1020                         // Throw an exception here
1021                         throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
1022                 } // END - if
1023
1024                 // Rewind it
1025                 $this->getResultInstance()->rewind();
1026
1027                 // Do we have an entry?
1028                 if ($this->getResultInstance()->valid() === false) {
1029                         throw new InvalidDatabaseResultException(array($this, $this->getResultInstance()), DatabaseResult::EXCEPTION_INVALID_DATABASE_RESULT);
1030                 } // END - if
1031
1032                 // Get next entry
1033                 $this->getResultInstance()->next();
1034
1035                 // Fetch it
1036                 $entry = $this->getResultInstance()->current();
1037
1038                 // And return it
1039                 return $entry;
1040         }
1041
1042         /**
1043          * Getter for field name
1044          *
1045          * @param       $fieldName              Field name which we shall get
1046          * @return      $fieldValue             Field value from the user
1047          * @throws      NullPointerException    If the result instance is null
1048          */
1049         public final function getField ($fieldName) {
1050                 // Default field value
1051                 $fieldValue = null;
1052
1053                 // Get result instance
1054                 $resultInstance = $this->getResultInstance();
1055
1056                 // Is this instance null?
1057                 if (is_null($resultInstance)) {
1058                         // Then the user instance is no longer valid (expired cookies?)
1059                         throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
1060                 } // END - if
1061
1062                 // Get current array
1063                 $fieldArray = $resultInstance->current();
1064                 //* DEBUG: */ $this->debugOutput($fieldName.':<pre>'.print_r($fieldArray, true).'</pre>');
1065
1066                 // Does the field exist?
1067                 if (isset($fieldArray[$fieldName])) {
1068                         // Get it
1069                         $fieldValue = $fieldArray[$fieldName];
1070                 } // END - if
1071
1072                 // Return it
1073                 return $fieldValue;
1074         }
1075
1076         /**
1077          * Protected setter for user instance
1078          *
1079          * @param       $userInstance   An instance of a user class
1080          * @return      void
1081          */
1082         protected final function setUserInstance (ManageableAccount $userInstance) {
1083                 $this->userInstance = $userInstance;
1084         }
1085
1086         /**
1087          * Getter for user instance
1088          *
1089          * @return      $userInstance   An instance of a user class
1090          */
1091         public final function getUserInstance () {
1092                 return $this->userInstance;
1093         }
1094
1095         /**
1096          * Setter for controller instance (this surely breaks a bit the MVC patterm)
1097          *
1098          * @param       $controllerInstance             An instance of the controller
1099          * @return      void
1100          */
1101         public final function setControllerInstance (Controller $controllerInstance) {
1102                 $this->controllerInstance = $controllerInstance;
1103         }
1104
1105         /**
1106          * Getter for controller instance (this surely breaks a bit the MVC patterm)
1107          *
1108          * @return      $controllerInstance             An instance of the controller
1109          */
1110         public final function getControllerInstance () {
1111                 return $this->controllerInstance;
1112         }
1113
1114         /**
1115          * Flushs all pending updates to the database layer
1116          *
1117          * @return      void
1118          */
1119         public function flushPendingUpdates () {
1120                 // Get result instance
1121                 $resultInstance = $this->getResultInstance();
1122
1123                 // Do we have data to update?
1124                 if ((is_object($resultInstance)) && ($resultInstance->ifDataNeedsFlush())) {
1125                         // Get wrapper class name config entry
1126                         $configEntry = $resultInstance->getUpdateInstance()->getWrapperConfigEntry();
1127
1128                         // Create object instance
1129                         $wrapperInstance = ObjectFactory::createObjectByConfiguredName($configEntry);
1130
1131                         // Yes, then send the whole result to the database layer
1132                         $wrapperInstance->doUpdateByResult($this->getResultInstance());
1133                 } // END - if
1134         }
1135
1136         /**
1137          * Outputs a deprecation warning to the developer.
1138          *
1139          * @param       $message        The message we shall output to the developer
1140          * @return      void
1141          * @todo        Write a logging mechanism for productive mode
1142          */
1143         public function deprecationWarning ($message) {
1144                 // Is developer mode active?
1145                 if (defined('DEVELOPER')) {
1146                         // Debug instance is there?
1147                         if (!is_null($this->getDebugInstance())) {
1148                                 // Output stub message
1149                                 $this->debugOutput($message);
1150                         } else {
1151                                 // Trigger an error
1152                                 trigger_error($message . "<br />\n");
1153                         }
1154                 } else {
1155                         // @TODO Finish this part!
1156                         $this->partialStub('Developer mode inactive. Message:' . $message);
1157                 }
1158         }
1159
1160         /**
1161          * Checks wether the given PHP extension is loaded
1162          *
1163          * @param       $phpExtension   The PHP extension we shall check
1164          * @return      $isLoaded       Wether the PHP extension is loaded
1165          */
1166         public final function isPhpExtensionLoaded ($phpExtension) {
1167                 // Is it loaded?
1168                 $isLoaded = in_array($phpExtension, get_loaded_extensions());
1169
1170                 // Return result
1171                 return $isLoaded;
1172         }
1173
1174         /**
1175          * Setter for RNG instance
1176          *
1177          * @param       $rngInstance    An instance of a random number generator (RNG)
1178          * @return      void
1179          */
1180         protected final function setRngInstance (RandomNumberGenerator $rngInstance) {
1181                 $this->rngInstance = $rngInstance;
1182         }
1183
1184         /**
1185          * Getter for RNG instance
1186          *
1187          * @return      $rngInstance    An instance of a random number generator (RNG)
1188          */
1189         public final function getRngInstance () {
1190                 return $this->rngInstance;
1191         }
1192
1193         /**
1194          * Setter for Cryptable instance
1195          *
1196          * @param       $cryptoInstance An instance of a Cryptable class
1197          * @return      void
1198          */
1199         protected final function setCryptoInstance (Cryptable $cryptoInstance) {
1200                 $this->cryptoInstance = $cryptoInstance;
1201         }
1202
1203         /**
1204          * Getter for Cryptable instance
1205          *
1206          * @return      $cryptoInstance An instance of a Cryptable class
1207          */
1208         public final function getCryptoInstance () {
1209                 return $this->cryptoInstance;
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          * "Getter" as a time() replacement but with milliseconds. You should use this
1233          * method instead of the encapsulated getimeofday() function.
1234          *
1235          * @return      $milliTime      Timestamp with milliseconds
1236          */
1237         public function getMilliTime () {
1238                 // Get the time of day as float
1239                 $milliTime = gettimeofday(true);
1240
1241                 // Return it
1242                 return $milliTime;
1243         }
1244
1245         /**
1246          * Idles (sleeps) for given milliseconds
1247          *
1248          * @return      $hasSlept       Wether it goes fine
1249          */
1250         public function idle ($milliSeconds) {
1251                 // Sleep is fine by default
1252                 $hasSlept = true;
1253
1254                 // Idle so long with found function
1255                 if (function_exists('time_sleep_until')) {
1256                         // Get current time and add idle time
1257                         $sleepUntil = $this->getMilliTime() + abs($milliSeconds) / 1000;
1258
1259                         // New PHP 5.1.0 function found
1260                         $hasSlept = time_sleep_until($sleepUntil);
1261                 } else {
1262                         // My Sun Station doesn't have that function even with latest PHP
1263                         // package. :(
1264                         usleep($milliSeconds * 1000);
1265                 }
1266
1267                 // Return result
1268                 return $hasSlept;
1269         }
1270
1271         /**
1272          * Setter for the list instance
1273          *
1274          * @param       $listInstance   A list of Listable
1275          * @return      void
1276          */
1277         protected final function setListInstance (Listable $listInstance) {
1278                 $this->listInstance = $listInstance;
1279         }
1280
1281         /**
1282          * Getter for the list instance
1283          *
1284          * @return      $listInstance   A list of Listable
1285          */
1286         protected final function getListInstance () {
1287                 return $this->listInstance;
1288         }
1289
1290         /**
1291          * Setter for the menu instance
1292          *
1293          * @param       $menuInstance   A RenderableMenu instance
1294          * @return      void
1295          */
1296         protected final function setMenuInstance (RenderableMenu $menuInstance) {
1297                 $this->menuInstance = $menuInstance;
1298         }
1299
1300         /**
1301          * Getter for the menu instance
1302          *
1303          * @return      $menuInstance   A RenderableMenu instance
1304          */
1305         protected final function getMenuInstance () {
1306                 return $this->menuInstance;
1307         }
1308
1309         /**
1310          * Setter for image instance
1311          *
1312          * @param       $imageInstance  An instance of an image
1313          * @return      void
1314          */
1315         public final function setImageInstance (BaseImage $imageInstance) {
1316                 $this->imageInstance = $imageInstance;
1317         }
1318
1319         /**
1320          * Getter for image instance
1321          *
1322          * @return      $imageInstance  An instance of an image
1323          */
1324         public final function getImageInstance () {
1325                 return $this->imageInstance;
1326         }
1327
1328         /**
1329          * Setter for stacker instance
1330          *
1331          * @param       $stackerInstance        An instance of an stacker
1332          * @return      void
1333          */
1334         public final function setStackerInstance (Stackable $stackerInstance) {
1335                 $this->stackerInstance = $stackerInstance;
1336         }
1337
1338         /**
1339          * Getter for stacker instance
1340          *
1341          * @return      $stackerInstance        An instance of an stacker
1342          */
1343         public final function getStackerInstance () {
1344                 return $this->stackerInstance;
1345         }
1346
1347         /**
1348          * Setter for compressor instance
1349          *
1350          * @param       $compressorInstance     An instance of an compressor
1351          * @return      void
1352          */
1353         public final function setCompressorInstance (Compressor $compressorInstance) {
1354                 $this->compressorInstance = $compressorInstance;
1355         }
1356
1357         /**
1358          * Getter for compressor instance
1359          *
1360          * @return      $compressorInstance     An instance of an compressor
1361          */
1362         public final function getCompressorInstance () {
1363                 return $this->compressorInstance;
1364         }
1365
1366         /**
1367          * Setter for Parseable instance
1368          *
1369          * @param       $parserInstance An instance of an Parseable
1370          * @return      void
1371          */
1372         public final function setParserInstance (Parseable $parserInstance) {
1373                 $this->parserInstance = $parserInstance;
1374         }
1375
1376         /**
1377          * Getter for Parseable instance
1378          *
1379          * @return      $parserInstance An instance of an Parseable
1380          */
1381         public final function getParserInstance () {
1382                 return $this->parserInstance;
1383         }
1384
1385         /**
1386          * Setter for ProtocolHandler instance
1387          *
1388          * @param       $protocolInstance       An instance of an ProtocolHandler
1389          * @return      void
1390          */
1391         public final function setProtocolInstance (ProtocolHandler $protocolInstance) {
1392                 $this->protocolInstance = $protocolInstance;
1393         }
1394
1395         /**
1396          * Getter for ProtocolHandler instance
1397          *
1398          * @return      $protocolInstance       An instance of an ProtocolHandler
1399          */
1400         public final function getProtocolInstance () {
1401                 return $this->protocolInstance;
1402         }
1403
1404         /**
1405          * Setter for BaseDatabaseWrapper instance
1406          *
1407          * @param       $wrapperInstance        An instance of an BaseDatabaseWrapper
1408          * @return      void
1409          */
1410         public final function setWrapperInstance (BaseDatabaseWrapper $wrapperInstance) {
1411                 $this->wrapperInstance = $wrapperInstance;
1412         }
1413
1414         /**
1415          * Getter for BaseDatabaseWrapper instance
1416          *
1417          * @return      $wrapperInstance        An instance of an BaseDatabaseWrapper
1418          */
1419         public final function getWrapperInstance () {
1420                 return $this->wrapperInstance;
1421         }
1422
1423         /**
1424          * Setter for socket resource
1425          *
1426          * @param       $socketResource         A valid socket resource
1427          * @return      void
1428          */
1429         public final function setSocketResource ($socketResource) {
1430                 $this->socketResource = $socketResource;
1431         }
1432
1433         /**
1434          * Getter for socket resource
1435          *
1436          * @return      $socketResource         A valid socket resource
1437          */
1438         public function getSocketResource () {
1439                 return $this->socketResource;
1440         }
1441
1442         /**
1443          * Setter for raw package Data
1444          *
1445          * @param       $packageData    Raw package Data
1446          * @return      void
1447          */
1448         public final function setPackageData (array $packageData) {
1449                 $this->packageData = $packageData;
1450         }
1451
1452         /**
1453          * Getter for raw package Data
1454          *
1455          * @return      $packageData    Raw package Data
1456          */
1457         public function getPackageData () {
1458                 return $this->packageData;
1459         }
1460 }
1461
1462 // [EOF]
1463 ?>