+ * Setter for visitor instance
+ *
+ * @param $visitorInstance A Visitor instance
+ * @return void
+ */
+ protected final function setVisitorInstance (Visitor $visitorInstance) {
+ $this->visitorInstance = $visitorInstance;
+ }
+
+ /**
+ * Getter for visitor instance
+ *
+ * @return $visitorInstance A Visitor instance
+ */
+ protected final function getVisitorInstance () {
+ return $this->visitorInstance;
+ }
+
+ /**
+ * Setter for DHT instance
+ *
+ * @param $dhtInstance A Distributable instance
+ * @return void
+ */
+ protected final function setDhtInstance (Distributable $dhtInstance) {
+ $this->dhtInstance = $dhtInstance;
+ }
+
+ /**
+ * Getter for DHT instance
+ *
+ * @return $dhtInstance A Distributable instance
+ */
+ protected final function getDhtInstance () {
+ return $this->dhtInstance;
+ }
+
+ /**
+ * Setter for raw package Data
+ *
+ * @param $packageData Raw package Data
+ * @return void
+ */
+ public final function setPackageData (array $packageData) {
+ $this->packageData = $packageData;
+ }
+
+ /**
+ * Getter for raw package Data
+ *
+ * @return $packageData Raw package Data
+ */
+ public function getPackageData () {
+ return $this->packageData;
+ }
+
+
+ /**
+ * Setter for Iterator instance
+ *
+ * @param $iteratorInstance An instance of an Iterator
+ * @return void
+ */
+ protected final function setIteratorInstance (Iterator $iteratorInstance) {
+ $this->iteratorInstance = $iteratorInstance;
+ }
+
+ /**
+ * Getter for Iterator instance
+ *
+ * @return $iteratorInstance An instance of an Iterator
+ */
+ public final function getIteratorInstance () {
+ return $this->iteratorInstance;
+ }
+
+ /**
+ * Checks whether an object equals this object. You should overwrite this
+ * method to implement own equality checks
+ *
+ * @param $objectInstance An instance of a FrameworkInterface object
+ * @return $equals Whether both objects equals
+ */
+ public function equals (FrameworkInterface $objectInstance) {
+ // Now test it
+ $equals = ((
+ $this->__toString() == $objectInstance->__toString()
+ ) && (
+ $this->hashCode() == $objectInstance->hashCode()
+ ));
+
+ // Return the result
+ return $equals;
+ }
+
+ /**
+ * Generates a generic hash code of this class. You should really overwrite
+ * this method with your own hash code generator code. But keep KISS in mind.
+ *
+ * @return $hashCode A generic hash code respresenting this whole class
+ */
+ public function hashCode () {
+ // Simple hash code
+ return crc32($this->__toString());
+ }
+
+ /**
+ * Formats computer generated price values into human-understandable formats
+ * with thousand and decimal separators.
+ *
+ * @param $value The in computer format value for a price
+ * @param $currency The currency symbol (use HTML-valid characters!)
+ * @param $decNum Number of decimals after commata
+ * @return $price The for the current language formated price string
+ * @throws MissingDecimalsThousandsSeparatorException If decimals or
+ * thousands separator
+ * is missing
+ */
+ public function formatCurrency ($value, $currency = '€', $decNum = 2) {
+ // Are all required attriutes set?
+ if ((!isset($this->decimals)) || (!isset($this->thousands))) {
+ // Throw an exception
+ throw new MissingDecimalsThousandsSeparatorException($this, self::EXCEPTION_ATTRIBUTES_ARE_MISSING);
+ } // END - if
+
+ // Cast the number
+ $value = (float) $value;
+
+ // Reformat the US number
+ $price = number_format($value, $decNum, $this->decimals, $this->thousands) . $currency;
+
+ // Return as string...
+ return $price;
+ }
+
+ /**
+ * Appends a trailing slash to a string
+ *
+ * @param $str A string (maybe) without trailing slash
+ * @return $str A string with an auto-appended trailing slash
+ */
+ public final function addMissingTrailingSlash ($str) {
+ // Is there a trailing slash?
+ if (substr($str, -1, 1) != '/') {
+ $str .= '/';
+ } // END - if
+
+ // Return string with trailing slash
+ return $str;
+ }
+
+ /**
+ * Prepare the template engine (WebTemplateEngine by default) for a given
+ * application helper instance (ApplicationHelper by default).
+ *
+ * @param $applicationInstance An application helper instance or
+ * null if we shall use the default
+ * @return $templateInstance The template engine instance
+ * @throws NullPointerException If the discovered application
+ * instance is still null
+ */
+ protected function prepareTemplateInstance (ManageableApplication $applicationInstance = NULL) {
+ // Is the application instance set?
+ if (is_null($applicationInstance)) {
+ // Get the current instance
+ $applicationInstance = $this->getApplicationInstance();
+
+ // Still null?
+ if (is_null($applicationInstance)) {
+ // Thrown an exception
+ throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
+ } // END - if
+ } // END - if
+
+ // Initialize the template engine
+ $templateInstance = ObjectFactory::createObjectByConfiguredName('web_template_class');
+
+ // Return the prepared instance
+ return $templateInstance;
+ }
+
+ /**
+ * Debugs this instance by putting out it's full content
+ *
+ * @param $message Optional message to show in debug output
+ * @return void
+ */
+ public final function debugInstance ($message = '') {
+ // Restore the error handler to avoid trouble with missing array elements or undeclared variables
+ restore_error_handler();
+
+ // Init content
+ $content = '';
+
+ // Is a message set?
+ if (!empty($message)) {
+ // Construct message
+ $content = sprintf("<div class=\"debug_message\">Message: %s</div>\n", $message);
+ } // END - if
+
+ // Generate the output
+ $content .= sprintf("<pre>%s</pre>",
+ trim(
+ htmlentities(
+ print_r($this, true)
+ )
+ )
+ );
+
+ // Output it
+ ApplicationEntryPoint::app_exit(sprintf("<div class=\"debug_header\">%s debug output:</div><div class=\"debug_content\">%s</div>\nLoaded includes: <div class=\"debug_include_list\">%s</div>",
+ $this->__toString(),
+ $content,
+ ClassLoader::getSelfInstance()->getPrintableIncludeList()
+ ));
+ }
+
+ /**
+ * Replaces control characters with printable output
+ *
+ * @param $str String with control characters
+ * @return $str Replaced string
+ */
+ protected function replaceControlCharacters ($str) {
+ // Replace them
+ $str = str_replace(
+ chr(13), '[r]', str_replace(
+ chr(10), '[n]', str_replace(
+ chr(9) , '[t]',
+ $str
+ )));
+
+ // Return it
+ return $str;
+ }
+
+ /**
+ * Output a partial stub message for the caller method
+ *
+ * @param $message An optional message to display
+ * @return void
+ */
+ protected function partialStub ($message = '') {
+ // Get the backtrace
+ $backtrace = debug_backtrace();
+
+ // Generate the class::method string
+ $methodName = 'UnknownClass->unknownMethod';
+ if ((isset($backtrace[1]['class'])) && (isset($backtrace[1]['function']))) {
+ $methodName = $backtrace[1]['class'] . '->' . $backtrace[1]['function'];
+ } // END - if
+
+ // Construct the full message
+ $stubMessage = sprintf('[%s:] Partial stub!',
+ $methodName
+ );
+
+ // Is the extra message given?
+ if (!empty($message)) {
+ // Then add it as well
+ $stubMessage .= ' Message: ' . $message;
+ } // END - if
+
+ // Debug instance is there?
+ if (!is_null($this->getDebugInstance())) {
+ // Output stub message
+ self::createDebugInstance(__CLASS__)->debugOutput($stubMessage);
+ } else {
+ // Trigger an error
+ trigger_error($stubMessage);
+ }
+ }
+
+ /**
+ * Outputs a debug backtrace and stops further script execution
+ *
+ * @param $message An optional message to output
+ * @param $doExit Whether exit the program (true is default)
+ * @return void
+ */
+ public function debugBackTrace ($message = '', $doExit = TRUE) {
+ // Sorry, there is no other way getting this nice backtrace
+ if (!empty($message)) {
+ // Output message
+ printf('Message: %s<br />' . chr(10), $message);
+ } // END - if
+
+ print('<pre>');
+ debug_print_backtrace();
+ print('</pre>');
+
+ // Exit program?
+ if ($doExit === TRUE) {
+ exit();
+ } // END - if
+ }
+
+ /**
+ * Creates an instance of a debugger instance
+ *
+ * @param $className Name of the class (currently unsupported)
+ * @return $debugInstance An instance of a debugger class
+ */
+ public final static function createDebugInstance ($className) {
+ // Init debug instance
+ $debugInstance = NULL;
+
+ // Try it
+ try {
+ // Get a debugger instance
+ $debugInstance = DebugMiddleware::createDebugMiddleware(FrameworkConfiguration::getSelfInstance()->getConfigEntry('debug_class'));
+ } catch (NullPointerException $e) {
+ // Didn't work, no instance there
+ exit('Cannot create debugInstance! Exception=' . $e->__toString() . ', message=' . $e->getMessage());
+ }
+
+ // Empty string should be ignored and used for testing the middleware
+ DebugMiddleware::getSelfInstance()->output('');
+
+ // Return it
+ return $debugInstance;
+ }
+
+ /**
+ * Outputs a debug message whether to debug instance (should be set!) or
+ * dies with or ptints the message. Do NEVER EVER rewrite the exit() call to
+ * ApplicationEntryPoint::app_exit(), this would cause an endless loop.
+ *
+ * @param $message Message we shall send out...
+ * @param $doPrint Whether print or die here (default: print)
+ * @paran $stripTags Whether to strip tags (default: false)
+ * @return void
+ */
+ public function debugOutput ($message, $doPrint = TRUE, $stripTags = FALSE) {
+ // Set debug instance to NULL
+ $debugInstance = NULL;
+
+ // Try it:
+ try {
+ // Get debug instance
+ $debugInstance = $this->getDebugInstance();
+ } catch (NullPointerException $e) {
+ // The debug instance is not set (yet)
+ }
+
+ // Is the debug instance there?
+ if (is_object($debugInstance)) {
+ // Use debug output handler
+ $debugInstance->output($message, $stripTags);
+
+ if ($doPrint === FALSE) {
+ // Die here if not printed
+ exit();
+ } // END - if
+ } else {
+ // Are debug times enabled?
+ if ($this->getConfigInstance()->getConfigEntry('debug_output_timings') == 'Y') {
+ // Prepent it
+ $message = $this->getPrintableExecutionTime() . $message;
+ } // END - if
+
+ // Put directly out
+ if ($doPrint === TRUE) {
+ // Print message
+ print($message . chr(10));
+ } else {
+ // Die here
+ exit($message);
+ }
+ }
+ }
+
+ /**
+ * Converts e.g. a command from URL to a valid class by keeping out bad characters
+ *
+ * @param $str The string, what ever it is needs to be converted
+ * @return $className Generated class name
+ */
+ public function convertToClassName ($str) {
+ // Init class name
+ $className = '';
+
+ // Convert all dashes in underscores
+ $str = $this->convertDashesToUnderscores($str);
+
+ // Now use that underscores to get classname parts for hungarian style
+ foreach (explode('_', $str) as $strPart) {
+ // Make the class name part lower case and first upper case
+ $className .= ucfirst(strtolower($strPart));
+ } // END - foreach
+
+ // Return class name
+ return $className;
+ }
+
+ /**
+ * Converts dashes to underscores, e.g. useable for configuration entries
+ *
+ * @param $str The string with maybe dashes inside
+ * @return $str The converted string with no dashed, but underscores
+ */
+ public final function convertDashesToUnderscores ($str) {
+ // Convert them all
+ $str = str_replace('-', '_', $str);
+
+ // Return converted string
+ return $str;
+ }
+
+ /**
+ * Marks up the code by adding e.g. line numbers
+ *
+ * @param $phpCode Unmarked PHP code
+ * @return $markedCode Marked PHP code
+ */
+ public function markupCode ($phpCode) {
+ // Init marked code
+ $markedCode = '';
+
+ // Get last error
+ $errorArray = error_get_last();
+
+ // Init the code with error message
+ if (is_array($errorArray)) {
+ // Get error infos
+ $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>',
+ basename($errorArray['file']),
+ $errorArray['line'],
+ $errorArray['message'],
+ $errorArray['type']
+ );
+ } // END - if
+
+ // Add line number to the code
+ foreach (explode(chr(10), $phpCode) as $lineNo => $code) {
+ // Add line numbers
+ $markedCode .= sprintf('<span id="code_line">%s</span>: %s' . chr(10),
+ ($lineNo + 1),
+ htmlentities($code, ENT_QUOTES)
+ );
+ } // END - foreach
+
+ // Return the code
+ return $markedCode;
+ }
+
+ /**
+ * Filter a given GMT timestamp (non Uni* stamp!) to make it look more
+ * beatiful for web-based front-ends. If null is given a message id
+ * null_timestamp will be resolved and returned.
+ *
+ * @param $timestamp Timestamp to prepare (filter) for display
+ * @return $readable A readable timestamp
+ */
+ public function doFilterFormatTimestamp ($timestamp) {
+ // Default value to return
+ $readable = '???';
+
+ // Is the timestamp null?
+ if (is_null($timestamp)) {
+ // Get a message string
+ $readable = $this->getLanguageInstance()->getMessage('null_timestamp');
+ } else {
+ switch ($this->getLanguageInstance()->getLanguageCode()) {
+ case 'de': // German format is a bit different to default
+ // Split the GMT stamp up
+ $dateTime = explode(' ', $timestamp );
+ $dateArray = explode('-', $dateTime[0]);
+ $timeArray = explode(':', $dateTime[1]);
+
+ // Construct the timestamp
+ $readable = sprintf($this->getConfigInstance()->getConfigEntry('german_date_time'),
+ $dateArray[0],
+ $dateArray[1],
+ $dateArray[2],
+ $timeArray[0],
+ $timeArray[1],
+ $timeArray[2]
+ );
+ break;
+
+ default: // Default is pass-through
+ $readable = $timestamp;
+ break;
+ } // END - switch
+ }
+
+ // Return the stamp
+ return $readable;
+ }
+
+ /**
+ * Filter a given number into a localized number
+ *
+ * @param $value The raw value from e.g. database
+ * @return $localized Localized value
+ */
+ public function doFilterFormatNumber ($value) {
+ // Generate it from config and localize dependencies
+ switch ($this->getLanguageInstance()->getLanguageCode()) {
+ case 'de': // German format is a bit different to default
+ $localized = number_format($value, $this->getConfigInstance()->getConfigEntry('decimals'), ',', '.');
+ break;
+
+ default: // US, etc.
+ $localized = number_format($value, $this->getConfigInstance()->getConfigEntry('decimals'), '.', ',');
+ break;
+ } // END - switch
+
+ // Return it
+ return $localized;
+ }
+
+ /**
+ * "Getter" for databse entry
+ *
+ * @return $entry An array with database entries
+ * @throws NullPointerException If the database result is not found
+ * @throws InvalidDatabaseResultException If the database result is invalid
+ */
+ protected final function getDatabaseEntry () {
+ // Is there an instance?
+ if (is_null($this->getResultInstance())) {
+ // Throw an exception here
+ throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
+ } // END - if
+
+ // Rewind it
+ $this->getResultInstance()->rewind();
+
+ // Do we have an entry?
+ if ($this->getResultInstance()->valid() === FALSE) {
+ throw new InvalidDatabaseResultException(array($this, $this->getResultInstance()), DatabaseResult::EXCEPTION_INVALID_DATABASE_RESULT);
+ } // END - if
+
+ // Get next entry
+ $this->getResultInstance()->next();
+
+ // Fetch it
+ $entry = $this->getResultInstance()->current();
+
+ // And return it
+ return $entry;
+ }
+
+ /**
+ * Getter for field name
+ *
+ * @param $fieldName Field name which we shall get
+ * @return $fieldValue Field value from the user
+ * @throws NullPointerException If the result instance is null
+ */
+ public final function getField ($fieldName) {
+ // Default field value
+ $fieldValue = NULL;
+
+ // Get result instance
+ $resultInstance = $this->getResultInstance();
+
+ // Is this instance null?
+ if (is_null($resultInstance)) {
+ // Then the user instance is no longer valid (expired cookies?)
+ throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
+ } // END - if
+
+ // Get current array
+ $fieldArray = $resultInstance->current();
+ //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput($fieldName.':<pre>'.print_r($fieldArray, true).'</pre>');
+
+ // Convert dashes to underscore
+ $fieldName = $this->convertDashesToUnderscores($fieldName);
+
+ // Does the field exist?
+ if (isset($fieldArray[$fieldName])) {
+ // Get it
+ $fieldValue = $fieldArray[$fieldName];
+ } else {
+ // Missing field entry, may require debugging
+ self::createDebugInstance(__CLASS__)->debugOutput($this->__toString() . ':fieldname=' . $fieldName . ' not found!');
+ }
+
+ // Return it
+ return $fieldValue;
+ }
+
+ /**
+ * Flushs all pending updates to the database layer
+ *
+ * @return void
+ */
+ public function flushPendingUpdates () {
+ // Get result instance
+ $resultInstance = $this->getResultInstance();
+
+ // Do we have data to update?
+ if ((is_object($resultInstance)) && ($resultInstance->ifDataNeedsFlush())) {
+ // Get wrapper class name config entry
+ $configEntry = $resultInstance->getUpdateInstance()->getWrapperConfigEntry();
+
+ // Create object instance
+ $wrapperInstance = ObjectFactory::createObjectByConfiguredName($configEntry);
+
+ // Yes, then send the whole result to the database layer
+ $wrapperInstance->doUpdateByResult($this->getResultInstance());
+ } // END - if
+ }
+
+ /**
+ * Outputs a deprecation warning to the developer.
+ *
+ * @param $message The message we shall output to the developer
+ * @return void
+ * @todo Write a logging mechanism for productive mode
+ */
+ public function deprecationWarning ($message) {
+ // Is developer mode active?
+ if (defined('DEVELOPER')) {
+ // Debug instance is there?
+ if (!is_null($this->getDebugInstance())) {
+ // Output stub message
+ self::createDebugInstance(__CLASS__)->debugOutput($message);
+ } else {
+ // Trigger an error
+ trigger_error($message . "<br />\n");
+ }
+ } else {
+ // @TODO Finish this part!
+ $this->partialStub('Developer mode inactive. Message:' . $message);
+ }
+ }
+
+ /**
+ * Checks whether the given PHP extension is loaded