*
* @author Roland Haeder <webmaster@shipsimu.org>
* @version 0.0.0
- * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2014 Core Developer Team
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2015 Core Developer Team
* @license GNU GPL 3.0 or any newer version
* @link http://www.shipsimu.org
*
private $helperInstance = NULL;
/**
- * An instance of a Sourceable class
+ * An instance of a Source class
*/
private $sourceInstance = NULL;
+ /**
+ * An instance of a UrlSource class
+ */
+ private $urlSourceInstance = NULL;
+
/**
* An instance of a InputStream class
*/
*/
private $socketResource = FALSE;
+ /**
+ * Regular expression to use for validation
+ */
+ private $regularExpression = '';
+
/**
* Package data
*/
*/
private $genericArray = array();
+ /**
+ * Command name
+ */
+ private $commandName = '';
+
+ /**
+ * Controller name
+ */
+ private $controllerName = '';
+
+ /**
+ * Array with bitmasks and such for pack/unpack methods to support both
+ * 32-bit and 64-bit systems
+ */
+ private $packingData = array(
+ 32 => array(
+ 'step' => 3,
+ 'left' => 0xffff0000,
+ 'right' => 0x0000ffff,
+ 'factor' => 16,
+ 'format' => 'II',
+ ),
+ 64 => array(
+ 'step' => 7,
+ 'left' => 0xffffffff00000000,
+ 'right' => 0x00000000ffffffff,
+ 'factor' => 32,
+ 'format' => 'NN'
+ )
+ );
+
+ /**
+ * Simple 64-bit check, thanks to "Salman A" from stackoverflow.com:
+ *
+ * The integer size is 4 bytes on 32-bit and 8 bytes on a 64-bit system.
+ */
+ private $archArrayElement = (PHP_INT_SIZE === 8 ? 64 : 32);
+
/***********************
* Exception codes.... *
***********************/
}
/**
- * Magic function to catch setting of missing but set class fields/attributes
+ * Magic method to catch setting of missing but set class fields/attributes
*
* @param $name Name of the field/attribute
* @param $value Value to store
}
/**
- * Magic function to catch getting of missing fields/attributes
+ * Magic method to catch getting of missing fields/attributes
*
* @param $name Name of the field/attribute
* @return void
}
/**
- * Magic function to catch unsetting of missing fields/attributes
+ * Magic method to catch unsetting of missing fields/attributes
*
* @param $name Name of the field/attribute
* @return void
));
}
+ /**
+ * Magic method to catch object serialization
+ *
+ * @return $unsupported Unsupported method
+ * @throws UnsupportedOperationException Objects of this framework cannot be serialized
+ */
+ public final function __sleep () {
+ throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION);
+ }
+
+ /**
+ * Magic method to catch object deserialization
+ *
+ * @return $unsupported Unsupported method
+ * @throws UnsupportedOperationException Objects of this framework cannot be serialized
+ */
+ public final function __wakeup () {
+ throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION);
+ }
+
+ /**
+ * Magic method to catch calls when an object instance is called
+ *
+ * @return $unsupported Unsupported method
+ * @throws UnsupportedOperationException Objects of this framework cannot be serialized
+ */
+ public final function __invoke () {
+ throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION);
+ }
+
/**
* Setter for the real class name
*
* @param $protocolInstance An instance of an HandleableProtocol
* @return void
*/
- public final function setProtocolInstance (HandleableProtocol $protocolInstance = NULL) {
+ public final function setProtocolInstance (HandleableProtocol $protocolInstance) {
$this->protocolInstance = $protocolInstance;
}
return $this->socketResource;
}
+ /**
+ * Setter for regular expression
+ *
+ * @param $regularExpression A valid regular expression
+ * @return void
+ */
+ public final function setRegularExpression ($regularExpression) {
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput($this->__toString() . '::' . __FUNCTION__ . ': regularExpression=' . $regularExpression . ',previous[' . gettype($this->regularExpression) . ']=' . $this->regularExpression);
+ $this->regularExpression = $regularExpression;
+ }
+
+ /**
+ * Getter for regular expression
+ *
+ * @return $regularExpression A valid regular expression
+ */
+ public final function getRegularExpression () {
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput($this->__toString() . '::' . __FUNCTION__ . ': regularExpression[' . gettype($this->regularExpression) . ']=' . $this->regularExpression);
+ return $this->regularExpression;
+ }
+
/**
* Setter for helper instance
*
}
/**
- * Setter for a Sourceable instance
+ * Setter for a Source instance
*
- * @param $sourceInstance The Sourceable instance
+ * @param $sourceInstance An instance of a Source class
* @return void
*/
- protected final function setSourceInstance (Sourceable $sourceInstance) {
+ protected final function setSourceInstance (Source $sourceInstance) {
$this->sourceInstance = $sourceInstance;
}
/**
- * Getter for a Sourceable instance
+ * Getter for a Source instance
*
- * @return $sourceInstance The Sourceable instance
+ * @return $sourceInstance An instance of a Source class
*/
protected final function getSourceInstance () {
return $this->sourceInstance;
}
+ /**
+ * Setter for a UrlSource instance
+ *
+ * @param $sourceInstance An instance of a UrlSource class
+ * @return void
+ */
+ protected final function setUrlSourceInstance (UrlSource $urlSourceInstance) {
+ $this->urlSourceInstance = $urlSourceInstance;
+ }
+
+ /**
+ * Getter for a UrlSource instance
+ *
+ * @return $urlSourceInstance An instance of a UrlSource class
+ */
+ protected final function getUrlSourceInstance () {
+ return $this->urlSourceInstance;
+ }
+
/**
* Getter for a InputStream instance
*
}
/**
- * Setter for InputOutputPointer instance
+ * Setter for FilePointer instance
*
- * @param $pointerInstance An instance of an InputOutputPointer class
+ * @param $pointerInstance An instance of an FilePointer class
* @return void
*/
- protected final function setPointerInstance (InputOutputPointer $pointerInstance) {
+ protected final function setPointerInstance (FilePointer $pointerInstance) {
$this->pointerInstance = $pointerInstance;
}
/**
- * Getter for InputOutputPointer instance
+ * Getter for FilePointer instance
*
- * @return $pointerInstance An instance of an InputOutputPointer class
+ * @return $pointerInstance An instance of an FilePointer class
*/
public final function getPointerInstance () {
return $this->pointerInstance;
}
+ /**
+ * Unsets pointer instance which triggers a call of __destruct() if the
+ * instance is still there. This is surely not fatal on already "closed"
+ * file pointer instances.
+ *
+ * I don't want to mess around with above setter by giving it a default
+ * value NULL as setter should always explicitly only set (existing) object
+ * instances and NULL is NULL.
+ *
+ * @return void
+ */
+ protected final function unsetPointerInstance () {
+ // Simply it to NULL
+ $this->pointerInstance = NULL;
+ }
+
/**
* Setter for Indexable instance
*
return $this->listenerInstance;
}
+ /**
+ * Setter for command name
+ *
+ * @param $commandName Last validated command name
+ * @return void
+ */
+ protected final function setCommandName ($commandName) {
+ $this->commandName = $commandName;
+ }
+
+ /**
+ * Getter for command name
+ *
+ * @return $commandName Last validated command name
+ */
+ protected final function getCommandName () {
+ return $this->commandName;
+ }
+
+ /**
+ * Setter for controller name
+ *
+ * @param $controllerName Last validated controller name
+ * @return void
+ */
+ protected final function setControllerName ($controllerName) {
+ $this->controllerName = $controllerName;
+ }
+
+ /**
+ * Getter for controller name
+ *
+ * @return $controllerName Last validated controller name
+ */
+ protected final function getControllerName () {
+ return $this->controllerName;
+ }
+
/**
* Checks whether an object equals this object. You should overwrite this
* method to implement own equality checks
}
/**
- * Prepare the template engine (WebTemplateEngine by default) for a given
+ * Prepare the template engine (HtmlTemplateEngine by default) for a given
* application helper instance (ApplicationHelper by default).
*
* @param $applicationInstance An application helper instance or
} // END - if
// Initialize the template engine
- $templateInstance = ObjectFactory::createObjectByConfiguredName('web_template_class');
+ $templateInstance = ObjectFactory::createObjectByConfiguredName('html_template_class');
// Return the prepared instance
return $templateInstance;
// Try it
try {
// Get a debugger instance
- $debugInstance = DebugMiddleware::createDebugMiddleware(FrameworkConfiguration::getSelfInstance()->getConfigEntry('debug_class'));
+ $debugInstance = DebugMiddleware::createDebugMiddleware(FrameworkConfiguration::getSelfInstance()->getConfigEntry('debug_' . self::getResponseTypeFromSystem() . '_class'));
} catch (NullPointerException $e) {
// Didn't work, no instance there
exit('Cannot create debugInstance! Exception=' . $e->__toString() . ', message=' . $e->getMessage());
*/
protected final function getDatabaseEntry () {
// Is there an instance?
- if (is_null($this->getResultInstance())) {
+ if (!$this->getResultInstance() instanceof SearchableResult) {
// Throw an exception here
throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
} // END - if
// Do we have an entry?
if ($this->getResultInstance()->valid() === FALSE) {
- throw new InvalidDatabaseResultException(array($this, $this->getResultInstance()), DatabaseResult::EXCEPTION_INVALID_DATABASE_RESULT);
+ // @TODO Move the constant to e.g. BaseDatabaseResult when there is a non-cached database result available
+ throw new InvalidDatabaseResultException(array($this, $this->getResultInstance()), CachedDatabaseResult::EXCEPTION_INVALID_DATABASE_RESULT);
} // END - if
// Get next entry
//* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput($fieldName.':<pre>'.print_r($fieldArray, TRUE).'</pre>');
// Convert dashes to underscore
- $fieldName = $this->convertDashesToUnderscores($fieldName);
+ $fieldName2 = $this->convertDashesToUnderscores($fieldName);
// Does the field exist?
- if (isset($fieldArray[$fieldName])) {
+ if ($this->isFieldSet($fieldName)) {
// Get it
- $fieldValue = $fieldArray[$fieldName];
+ $fieldValue = $fieldArray[$fieldName2];
+ } elseif (defined('DEVELOPER')) {
+ // Missing field entry, may require debugging
+ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']:fieldArray<pre>=' . print_r($fieldArray, TRUE) . '</pre>,fieldName=' . $fieldName . ' not found!');
} else {
// Missing field entry, may require debugging
- self::createDebugInstance(__CLASS__)->debugOutput($this->__toString() . ':fieldname=' . $fieldName . ' not found!');
+ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']:fieldName=' . $fieldName . ' not found!');
}
// Return it
return $fieldValue;
}
+ /**
+ * Checks if given field is set
+ *
+ * @param $fieldName Field name to check
+ * @return $isSet Whether the given field name is set
+ * @throws NullPointerException If the result instance is null
+ */
+ public function isFieldSet ($fieldName) {
+ // 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();
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . $this->__toString() . ':' . __LINE__ . '] fieldName=' . $fieldName . ',fieldArray=<pre>'.print_r($fieldArray, TRUE).'</pre>');
+
+ // Convert dashes to underscore
+ $fieldName = $this->convertDashesToUnderscores($fieldName);
+
+ // Determine it
+ $isSet = isset($fieldArray[$fieldName]);
+
+ // Return result
+ return $isSet;
+ }
+
/**
* Flushs all pending updates to the database layer
*
*
* @return $responseType Analyzed response type
*/
- protected function getResponseTypeFromSystem () {
+ protected static function getResponseTypeFromSystem () {
// Default is console
$responseType = 'console';
// Is 'HTTP_HOST' set?
if (isset($_SERVER['HTTP_HOST'])) {
- // Then it is a HTTP response/request
- $responseType = 'http';
+ /*
+ * Then it is a HTML response/request as RSS and so on may be
+ * transfered over HTTP as well.
+ */
+ $responseType = 'html';
} // END - if
// Return it
return $isValid;
}
+ /**
+ * Initializes the web output instance
+ *
+ * @return void
+ */
+ protected function initWebOutputInstance () {
+ // Get application instance
+ $applicationInstance = Registry::getRegistry()->getInstance('app');
+
+ // Is this a response instance?
+ if ($this instanceof Responseable) {
+ // Then set it in application instance
+ $applicationInstance->setResponseInstance($this);
+ } // END - if
+
+ // Init web output instance
+ $outputInstance = ObjectFactory::createObjectByConfiguredName('output_class', array($applicationInstance));
+
+ // Set it locally
+ $this->setWebOutputInstance($outputInstance);
+ }
+
/**
* Translates boolean TRUE to 'Y' and FALSE to 'N'
*
// ... and return it
return $translated;
}
+
+ /**
+ * Encodes raw data (almost any type) by "serializing" it and then pack it
+ * into a "binary format".
+ *
+ * @param $rawData Raw data (almost any type)
+ * @return $encoded Encoded data
+ */
+ protected function encodeData ($rawData) {
+ // Make sure no objects or resources pass through
+ assert(!is_object($rawData));
+ assert(!is_resource($rawData));
+
+ // First "serialize" it (json_encode() is faster than serialize())
+ $encoded = $this->packString(json_encode($rawData));
+
+ // And return it
+ return $encoded;
+ }
+
+ /**
+ * Pack a string into a "binary format". Please execuse me that this is
+ * widely undocumented. :-(
+ *
+ * @param $str Unpacked string
+ * @return $packed Packed string
+ * @todo Improve documentation
+ */
+ protected function packString ($str) {
+ // Debug message
+ //* NOISY-DEBUG */ self::createDebugInstance(__CLASS__)->debugOutput('str=' . $str . ' - CALLED!');
+
+ // First compress the string (gzcompress is okay)
+ $str = gzcompress($str);
+
+ // Init variable
+ $packed = '';
+
+ // And start the "encoding" loop
+ for ($idx = 0; $idx < strlen($str); $idx += $this->packingData[$this->archArrayElement]['step']) {
+ $big = 0;
+ for ($i = 0; $i < $this->packingData[$this->archArrayElement]['step']; $i++) {
+ $factor = ($this->packingData[$this->archArrayElement]['step'] - 1 - $i);
+
+ if (($idx + $i) <= strlen($str)) {
+ $ord = ord(substr($str, ($idx + $i), 1));
+
+ $add = $ord * pow(256, $factor);
+
+ $big += $add;
+
+ //print 'idx=' . $idx . ',i=' . $i . ',ord=' . $ord . ',factor=' . $factor . ',add=' . $add . ',big=' . $big . PHP_EOL;
+ } // END - if
+ } // END - for
+
+ $l = ($big & $this->packingData[$this->archArrayElement]['left']) >>$this->packingData[$this->archArrayElement]['factor'];
+ $r = $big & $this->packingData[$this->archArrayElement]['right'];
+
+ $chunk = str_pad(pack($this->packingData[$this->archArrayElement]['format'], $l, $r), 8, '0', STR_PAD_LEFT);
+ //* NOISY-DEBUG */ print 'big=' . $big . ',chunk('.strlen($chunk) . ')='.md5($chunk).PHP_EOL;
+
+ $packed .= $chunk;
+ } // END - for
+
+ // Return it
+ //* NOISY-DEBUG */ self::createDebugInstance(__CLASS__)->debugOutput('packed=' . $packed . ' - EXIT!');
+ return $packed;
+ }
}
// [EOF]