* @version 0.0.0
* @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2020 Core Developer Team
* @license GNU GPL 3.0 or any newer version
* @link http://www.shipsimu.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
abstract class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
/**
* Length of output from hash()
*/
private static $hashLength = NULL;
/**
* Self-referencing instance
*/
private static $instance = NULL;
/**
* The real class name
*/
private $realClass = 'BaseFrameworkSystem';
/**
* Search criteria instance
*/
private $searchInstance = NULL;
/**
* Update criteria instance
*/
private $updateInstance = NULL;
/**
* The file I/O instance for the template loader
*/
private $fileIoInstance = NULL;
/**
* Resolver instance
*/
private $resolverInstance = NULL;
/**
* Template engine instance
*/
private $templateInstance = NULL;
/**
* Database result instance
*/
private $resultInstance = NULL;
/**
* Instance for user class
*/
private $userInstance = NULL;
/**
* A controller instance
*/
private $controllerInstance = NULL;
/**
* Instance of a RNG
*/
private $rngInstance = NULL;
/**
* Instance of a crypto helper
*/
private $cryptoInstance = NULL;
/**
* Instance of an Iterator class
*/
private $iteratorInstance = NULL;
/**
* Instance of the list
*/
private $listInstance = NULL;
/**
* Instance of a menu
*/
private $menuInstance = NULL;
/**
* Instance of the image
*/
private $imageInstance = NULL;
/**
* Instance of the stacker
*/
private $stackInstance = NULL;
/**
* A Compressor instance
*/
private $compressorInstance = NULL;
/**
* A Parseable instance
*/
private $parserInstance = NULL;
/**
* A database wrapper instance
*/
private $databaseInstance = NULL;
/**
* A helper instance for the form
*/
private $helperInstance = NULL;
/**
* An instance of a InputStream class
*/
private $inputStreamInstance = NULL;
/**
* An instance of a OutputStream class
*/
private $outputStreamInstance = NULL;
/**
* Handler instance
*/
private $handlerInstance = NULL;
/**
* Visitor handler instance
*/
private $visitorInstance = NULL;
/**
* An instance of a database wrapper class
*/
private $wrapperInstance = NULL;
/**
* An instance of a file I/O pointer class (not handler)
*/
private $pointerInstance = NULL;
/**
* An instance of an Indexable class
*/
private $indexInstance = NULL;
/**
* An instance of a Block class
*/
private $blockInstance = NULL;
/**
* A Minable instance
*/
private $minableInstance = NULL;
/**
* A FrameworkDirectory instance
*/
private $directoryInstance = NULL;
/**
* The concrete output instance
*/
private $outputInstance = NULL;
/**
* State instance
*/
private $stateInstance = NULL;
/**
* Registry instance (implementing Register)
*/
private $registryInstance = NULL;
/**
* Call-back instance
*/
private $callbackInstance = NULL;
/**
* Thousands separator
*/
private $thousands = '.'; // German
/**
* Decimal separator
*/
private $decimals = ','; // German
/**
* Socket resource
*/
private $socketResource = false;
/**
* Generic array
*/
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 = false;
/***********************
* Exception codes.... *
***********************/
// @todo Try to clean these constants up
const EXCEPTION_IS_NULL_POINTER = 0x001;
const EXCEPTION_IS_NO_OBJECT = 0x002;
const EXCEPTION_IS_NO_ARRAY = 0x003;
const EXCEPTION_MISSING_METHOD = 0x004;
const EXCEPTION_CLASSES_NOT_MATCHING = 0x005;
const EXCEPTION_INDEX_OUT_OF_BOUNDS = 0x006;
const EXCEPTION_DIMENSION_ARRAY_INVALID = 0x007;
const EXCEPTION_ITEM_NOT_TRADEABLE = 0x008;
const EXCEPTION_ITEM_NOT_IN_PRICE_LIST = 0x009;
const EXCEPTION_GENDER_IS_WRONG = 0x00a;
const EXCEPTION_BIRTH_DATE_IS_INVALID = 0x00b;
const EXCEPTION_EMPTY_STRUCTURES_ARRAY = 0x00c;
const EXCEPTION_HAS_ALREADY_PERSONELL_LIST = 0x00d;
const EXCEPTION_NOT_ENOUGTH_UNEMPLOYEES = 0x00e;
const EXCEPTION_TOTAL_PRICE_NOT_CALCULATED = 0x00f;
const EXCEPTION_HARBOR_HAS_NO_SHIPYARDS = 0x010;
const EXCEPTION_CONTRACT_PARTNER_INVALID = 0x011;
const EXCEPTION_CONTRACT_PARTNER_MISMATCH = 0x012;
const EXCEPTION_CONTRACT_ALREADY_SIGNED = 0x013;
const EXCEPTION_UNEXPECTED_EMPTY_STRING = 0x014;
const EXCEPTION_PATH_NOT_FOUND = 0x015;
const EXCEPTION_INVALID_PATH_NAME = 0x016;
const EXCEPTION_READ_PROTECED_PATH = 0x017;
const EXCEPTION_WRITE_PROTECED_PATH = 0x018;
const EXCEPTION_DIR_POINTER_INVALID = 0x019;
const EXCEPTION_FILE_POINTER_INVALID = 0x01a;
const EXCEPTION_INVALID_RESOURCE = 0x01b;
const EXCEPTION_UNEXPECTED_OBJECT = 0x01c;
const EXCEPTION_LIMIT_ELEMENT_IS_UNSUPPORTED = 0x01d;
const EXCEPTION_GETTER_IS_MISSING = 0x01e;
const EXCEPTION_ARRAY_EXPECTED = 0x01f;
const EXCEPTION_ARRAY_HAS_INVALID_COUNT = 0x020;
const EXCEPTION_ID_IS_INVALID_FORMAT = 0x021;
const EXCEPTION_MD5_CHECKSUMS_MISMATCH = 0x022;
const EXCEPTION_UNEXPECTED_STRING_SIZE = 0x023;
const EXCEPTION_SIMULATOR_ID_INVALID = 0x024;
const EXCEPTION_MISMATCHING_COMPRESSORS = 0x025;
const EXCEPTION_CONTAINER_ITEM_IS_NULL = 0x026;
const EXCEPTION_ITEM_IS_NO_ARRAY = 0x027;
const EXCEPTION_CONTAINER_MAYBE_DAMAGED = 0x028;
const EXCEPTION_INVALID_STRING = 0x029;
const EXCEPTION_VARIABLE_NOT_SET = 0x02a;
const EXCEPTION_ATTRIBUTES_ARE_MISSING = 0x02b;
const EXCEPTION_ARRAY_ELEMENTS_MISSING = 0x02c;
const EXCEPTION_TEMPLATE_ENGINE_UNSUPPORTED = 0x02d;
const EXCEPTION_UNSPPORTED_OPERATION = 0x02e;
const EXCEPTION_FACTORY_REQUIRE_PARAMETER = 0x02f;
const EXCEPTION_MISSING_ELEMENT = 0x030;
const EXCEPTION_HEADERS_ALREADY_SENT = 0x031;
const EXCEPTION_DEFAULT_CONTROLLER_GONE = 0x032;
const EXCEPTION_CLASS_NOT_FOUND = 0x033;
const EXCEPTION_REQUIRED_INTERFACE_MISSING = 0x034;
const EXCEPTION_FATAL_ERROR = 0x035;
const EXCEPTION_FILE_NOT_FOUND = 0x036;
const EXCEPTION_ASSERTION_FAILED = 0x037;
const EXCEPTION_FILE_NOT_REACHABLE = 0x038;
const EXCEPTION_FILE_CANNOT_BE_READ = 0x039;
const EXCEPTION_FILE_CANNOT_BE_WRITTEN = 0x03a;
const EXCEPTION_PATH_CANNOT_BE_WRITTEN = 0x03b;
const EXCEPTION_DATABASE_UPDATED_NOT_ALLOWED = 0x03c;
const EXCEPTION_FILTER_CHAIN_INTERCEPTED = 0x03d;
const EXCEPTION_INVALID_SOCKET = 0x03e;
const EXCEPTION_SELF_INSTANCE = 0x03f;
/**
* Hexadecimal->Decimal translation array
*/
private static $hexdec = array(
'0' => 0,
'1' => 1,
'2' => 2,
'3' => 3,
'4' => 4,
'5' => 5,
'6' => 6,
'7' => 7,
'8' => 8,
'9' => 9,
'a' => 10,
'b' => 11,
'c' => 12,
'd' => 13,
'e' => 14,
'f' => 15
);
/**
* Decimal->hexadecimal translation array
*/
private static $dechex = array(
0 => '0',
1 => '1',
2 => '2',
3 => '3',
4 => '4',
5 => '5',
6 => '6',
7 => '7',
8 => '8',
9 => '9',
10 => 'a',
11 => 'b',
12 => 'c',
13 => 'd',
14 => 'e',
15 => 'f'
);
/**
* Startup time in miliseconds
*/
private static $startupTime = 0;
/**
* Protected super constructor
*
* @param $className Name of the class
* @return void
*/
protected function __construct ($className) {
// Set real class
$this->setRealClass($className);
// Set configuration instance if no registry ...
if (!$this instanceof Register) {
// ... because registries doesn't need to be configured
$this->setConfigInstance(FrameworkBootstrap::getConfigurationInstance());
} // END - if
// Is the startup time set? (0 cannot be true anymore)
if (self::$startupTime == 0) {
// Then set it
self::$startupTime = microtime(true);
} // END - if
// Set array element
$this->archArrayElement = (PHP_INT_SIZE === 8 ? 64 : 32);
}
/**
* Destructor for all classes. You should not call this method on your own.
*
* @return void
*/
public function __destruct () {
// Flush any updated entries to the database
$this->flushPendingUpdates();
// Is this object already destroyed?
if ($this->__toString() != 'DestructedObject') {
// Destroy all informations about this class but keep some text about it alive
$this->setRealClass('DestructedObject');
} elseif ((defined('DEBUG_DESTRUCTOR')) && (is_object($this->getDebugInstance()))) {
// Already destructed object
self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('The object %s is already destroyed.',
$this->__toString()
));
} else {
// Do not call this twice
trigger_error(__METHOD__ . ': Called twice.');
exit;
}
}
/**
* The __call() method where all non-implemented methods end up
*
* @param $methodName Name of the missing method
* @args $args Arguments passed to the method
* @return void
*/
public final function __call ($methodName, $args) {
// Set self-instance
self::$instance = $this;
// Call static method
self::__callStatic($methodName, $args);
// Clear self-instance
self::$instance = NULL;
}
/**
* The __callStatic() method where all non-implemented static methods end up
*
* @param $methodName Name of the missing method
* @param $args Arguments passed to the method
* @return void
* @throws InvalidArgumentException If self::$instance is not a framework's own object
*/
public static final function __callStatic ($methodName, $args) {
// Trace message
//* PRINT-DEBUG: */ printf('[%s:%d]: methodName=%s,args[]=%s - CALLED!' . PHP_EOL, __METHOD__, __LINE__, $methodName, gettype($args));
// Init argument string and class name
$argsString = '';
$className = 'unknown';
// Is self-instance set?
if (self::$instance instanceof FrameworkInterface) {
// Framework's own instance
$className = self::$instance->__toString();
} elseif (!is_null(self::$instance)) {
// Invalid argument!
throw new InvalidArgumentException(sprintf('self::instance[%s] is not expected.', gettype(self::$instance)), self::EXCEPTION_SELF_INSTANCE);
}
// Is it NULL, empty or an array?
if (is_null($args)) {
// No arguments
$argsString = 'NULL';
} elseif (is_array($args)) {
// Start braces
$argsString = '(';
// Some arguments are there
foreach ($args as $arg) {
// Add data about the argument
$argsString .= gettype($arg) . ':';
if (is_null($arg)) {
// Found a NULL argument
$argsString .= 'NULL';
} elseif (is_string($arg)) {
// Add length for strings
$argsString .= strlen($arg);
} elseif ((is_int($arg)) || (is_float($arg))) {
// ... integer/float
$argsString .= $arg;
} elseif (is_array($arg)) {
// .. or size if array
$argsString .= count($arg);
} elseif (is_object($arg)) {
// Get reflection
$reflection = new ReflectionClass($arg);
// Is an other object, maybe no __toString() available
$argsString .= $reflection->getName();
} elseif ($arg === true) {
// ... is boolean 'true'
$argsString .= 'true';
} elseif ($arg === false) {
// ... is boolean 'false'
$argsString .= 'false';
}
// Comma for next one
$argsString .= ', ';
} // END - foreach
// Last comma found?
if (substr($argsString, -2, 1) == ',') {
// Remove last comma
$argsString = substr($argsString, 0, -2);
} // END - if
// Close braces
$argsString .= ')';
} else {
// Invalid arguments!
$argsString = sprintf('!INVALID:%s!', gettype($args));
}
// Output stub message
// @TODO __CLASS__ does always return BaseFrameworkSystem but not the extending (=child) class
self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('[%s::%s]: Stub! Args: %s',
$className,
$methodName,
$argsString
));
// Return nothing
return NULL;
}
/**
* Getter for $realClass
*
* @return $realClass The name of the real class (not BaseFrameworkSystem)
*/
public function __toString () {
return $this->realClass;
}
/**
* Magic method to catch setting of missing but set class fields/attributes
*
* @param $name Name of the field/attribute
* @param $value Value to store
* @return void
*/
public final function __set ($name, $value) {
$this->debugBackTrace(sprintf('Tried to set a missing field. name=%s, value[%s]=%s',
$name,
gettype($value),
print_r($value, true)
));
}
/**
* Magic method to catch getting of missing fields/attributes
*
* @param $name Name of the field/attribute
* @return void
*/
public final function __get ($name) {
$this->debugBackTrace(sprintf('Tried to get a missing field. name=%s',
$name
));
}
/**
* Magic method to catch unsetting of missing fields/attributes
*
* @param $name Name of the field/attribute
* @return void
*/
public final function __unset ($name) {
$this->debugBackTrace(sprintf('Tried to unset a missing field. name=%s',
$name
));
}
/**
* 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 $realClass Class name (string)
* @return void
*/
public final function setRealClass ($realClass) {
// Set real class
$this->realClass = (string) $realClass;
}
/**
* Setter for database result instance
*
* @param $resultInstance An instance of a database result class
* @return void
* @todo SearchableResult and UpdateableResult shall have a super interface to use here
*/
protected final function setResultInstance (SearchableResult $resultInstance) {
$this->resultInstance = $resultInstance;
}
/**
* Getter for database result instance
*
* @return $resultInstance An instance of a database result class
*/
public final function getResultInstance () {
return $this->resultInstance;
}
/**
* Setter for template engine instances
*
* @param $templateInstance An instance of a template engine class
* @return void
*/
protected final function setTemplateInstance (CompileableTemplate $templateInstance) {
$this->templateInstance = $templateInstance;
}
/**
* Getter for template engine instances
*
* @return $templateInstance An instance of a template engine class
*/
protected final function getTemplateInstance () {
return $this->templateInstance;
}
/**
* Setter for search instance
*
* @param $searchInstance Searchable criteria instance
* @return void
*/
public final function setSearchInstance (LocalSearchCriteria $searchInstance) {
$this->searchInstance = $searchInstance;
}
/**
* Getter for search instance
*
* @return $searchInstance Searchable criteria instance
*/
public final function getSearchInstance () {
return $this->searchInstance;
}
/**
* Setter for update instance
*
* @param $updateInstance An instance of a LocalUpdateCriteria clase
* @return void
*/
public final function setUpdateInstance (LocalUpdateCriteria $updateInstance) {
$this->updateInstance = $updateInstance;
}
/**
* Getter for update instance
*
* @return $updateInstance Updateable criteria instance
*/
public final function getUpdateInstance () {
return $this->updateInstance;
}
/**
* Setter for resolver instance
*
* @param $resolverInstance Instance of a command resolver class
* @return void
*/
public final function setResolverInstance (Resolver $resolverInstance) {
$this->resolverInstance = $resolverInstance;
}
/**
* Getter for resolver instance
*
* @return $resolverInstance Instance of a command resolver class
*/
public final function getResolverInstance () {
return $this->resolverInstance;
}
/**
* Setter for language instance
*
* @param $configInstance The configuration instance which shall
* be FrameworkConfiguration
* @return void
*/
public final function setConfigInstance (FrameworkConfiguration $configInstance) {
GenericRegistry::getRegistry()->addInstance('config', $configInstance);
}
/**
* Getter for configuration instance
*
* @return $configInstance Configuration instance
*/
public final function getConfigInstance () {
$configInstance = GenericRegistry::getRegistry()->getInstance('config');
return $configInstance;
}
/**
* Setter for debug instance
*
* @param $debugInstance The instance for debug output class
* @return void
*/
public final function setDebugInstance (DebugMiddleware $debugInstance) {
GenericRegistry::getRegistry()->addInstance('debug', $debugInstance);
}
/**
* Getter for debug instance
*
* @return $debugInstance Instance to class DebugConsoleOutput or DebugWebOutput
*/
public final function getDebugInstance () {
// Get debug instance
$debugInstance = GenericRegistry::getRegistry()->getInstance('debug');
// Return it
return $debugInstance;
}
/**
* Setter for web output instance
*
* @param $webInstance The instance for web output class
* @return void
*/
public final function setWebOutputInstance (OutputStreamer $webInstance) {
GenericRegistry::getRegistry()->addInstance('web_output', $webInstance);
}
/**
* Getter for web output instance
*
* @return $webOutputInstance - Instance to class WebOutput
*/
public final function getWebOutputInstance () {
$webOutputInstance = GenericRegistry::getRegistry()->getInstance('web_output');
return $webOutputInstance;
}
/**
* Setter for database instance
*
* @param $databaseInstance The instance for the database connection (forced DatabaseConnection)
* @return void
*/
public final function setDatabaseInstance (DatabaseConnection $databaseInstance) {
GenericRegistry::getRegistry()->addInstance('db_instance', $databaseInstance);
}
/**
* Getter for database layer
*
* @return $databaseInstance The database layer instance
*/
public final function getDatabaseInstance () {
// Get instance
$databaseInstance = GenericRegistry::getRegistry()->getInstance('db_instance');
// Return instance
return $databaseInstance;
}
/**
* Setter for compressor channel
*
* @param $compressorInstance An instance of CompressorChannel
* @return void
*/
public final function setCompressorChannel (CompressorChannel $compressorInstance) {
GenericRegistry::getRegistry()->addInstance('compressor', $compressorInstance);
}
/**
* Getter for compressor channel
*
* @return $compressorInstance The compressor channel
*/
public final function getCompressorChannel () {
$compressorInstance = GenericRegistry::getRegistry()->getInstance('compressor');
return $compressorInstance;
}
/**
* Private getter for language instance
*
* @return $langInstance An instance to the language sub-system
*/
protected final function getLanguageInstance () {
$langInstance = GenericRegistry::getRegistry()->getInstance('language');
return $langInstance;
}
/**
* Setter for language instance
*
* @param $langInstance An instance to the language sub-system
* @return void
* @see LanguageSystem
*/
public final function setLanguageInstance (ManageableLanguage $langInstance) {
GenericRegistry::getRegistry()->addInstance('language', $langInstance);
}
/**
* Private getter for file IO instance
*
* @return $fileIoInstance An instance to the file I/O sub-system
*/
protected final function getFileIoInstance () {
return $this->fileIoInstance;
}
/**
* Setter for file I/O instance
*
* @param $fileIoInstance An instance to the file I/O sub-system
* @return void
*/
public final function setFileIoInstance (IoHandler $fileIoInstance) {
$this->fileIoInstance = $fileIoInstance;
}
/**
* Protected setter for user instance
*
* @param $userInstance An instance of a user class
* @return void
*/
protected final function setUserInstance (ManageableAccount $userInstance) {
$this->userInstance = $userInstance;
}
/**
* Getter for user instance
*
* @return $userInstance An instance of a user class
*/
public final function getUserInstance () {
return $this->userInstance;
}
/**
* Setter for controller instance (this surely breaks a bit the MVC patterm)
*
* @param $controllerInstance An instance of the controller
* @return void
*/
public final function setControllerInstance (Controller $controllerInstance) {
$this->controllerInstance = $controllerInstance;
}
/**
* Getter for controller instance (this surely breaks a bit the MVC patterm)
*
* @return $controllerInstance An instance of the controller
*/
public final function getControllerInstance () {
return $this->controllerInstance;
}
/**
* Setter for RNG instance
*
* @param $rngInstance An instance of a random number generator (RNG)
* @return void
*/
protected final function setRngInstance (RandomNumberGenerator $rngInstance) {
$this->rngInstance = $rngInstance;
}
/**
* Getter for RNG instance
*
* @return $rngInstance An instance of a random number generator (RNG)
*/
public final function getRngInstance () {
return $this->rngInstance;
}
/**
* Setter for Cryptable instance
*
* @param $cryptoInstance An instance of a Cryptable class
* @return void
*/
protected final function setCryptoInstance (Cryptable $cryptoInstance) {
$this->cryptoInstance = $cryptoInstance;
}
/**
* Getter for Cryptable instance
*
* @return $cryptoInstance An instance of a Cryptable class
*/
public final function getCryptoInstance () {
return $this->cryptoInstance;
}
/**
* Setter for the list instance
*
* @param $listInstance A list of Listable
* @return void
*/
protected final function setListInstance (Listable $listInstance) {
$this->listInstance = $listInstance;
}
/**
* Getter for the list instance
*
* @return $listInstance A list of Listable
*/
protected final function getListInstance () {
return $this->listInstance;
}
/**
* Setter for the menu instance
*
* @param $menuInstance A RenderableMenu instance
* @return void
*/
protected final function setMenuInstance (RenderableMenu $menuInstance) {
$this->menuInstance = $menuInstance;
}
/**
* Getter for the menu instance
*
* @return $menuInstance A RenderableMenu instance
*/
protected final function getMenuInstance () {
return $this->menuInstance;
}
/**
* Setter for image instance
*
* @param $imageInstance An instance of an image
* @return void
*/
public final function setImageInstance (BaseImage $imageInstance) {
$this->imageInstance = $imageInstance;
}
/**
* Getter for image instance
*
* @return $imageInstance An instance of an image
*/
public final function getImageInstance () {
return $this->imageInstance;
}
/**
* Setter for stacker instance
*
* @param $stackInstance An instance of an stacker
* @return void
*/
public final function setStackInstance (Stackable $stackInstance) {
$this->stackInstance = $stackInstance;
}
/**
* Getter for stacker instance
*
* @return $stackInstance An instance of an stacker
*/
public final function getStackInstance () {
return $this->stackInstance;
}
/**
* Setter for compressor instance
*
* @param $compressorInstance An instance of an compressor
* @return void
*/
public final function setCompressorInstance (Compressor $compressorInstance) {
$this->compressorInstance = $compressorInstance;
}
/**
* Getter for compressor instance
*
* @return $compressorInstance An instance of an compressor
*/
public final function getCompressorInstance () {
return $this->compressorInstance;
}
/**
* Setter for Parseable instance
*
* @param $parserInstance An instance of an Parseable
* @return void
*/
public final function setParserInstance (Parseable $parserInstance) {
$this->parserInstance = $parserInstance;
}
/**
* Getter for Parseable instance
*
* @return $parserInstance An instance of an Parseable
*/
public final function getParserInstance () {
return $this->parserInstance;
}
/**
* Setter for DatabaseWrapper instance
*
* @param $wrapperInstance An instance of an DatabaseWrapper
* @return void
*/
public final function setWrapperInstance (DatabaseWrapper $wrapperInstance) {
$this->wrapperInstance = $wrapperInstance;
}
/**
* Getter for DatabaseWrapper instance
*
* @return $wrapperInstance An instance of an DatabaseWrapper
*/
public final function getWrapperInstance () {
return $this->wrapperInstance;
}
/**
* Setter for socket resource
*
* @param $socketResource A valid socket resource
* @return void
*/
public final function setSocketResource ($socketResource) {
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($this->__toString() . '::' . __FUNCTION__ . ': socketResource=' . $socketResource . ',previous[' . gettype($this->socketResource) . ']=' . $this->socketResource);
$this->socketResource = $socketResource;
}
/**
* Getter for socket resource
*
* @return $socketResource A valid socket resource
*/
public final function getSocketResource () {
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($this->__toString() . '::' . __FUNCTION__ . ': socketResource[' . gettype($this->socketResource) . ']=' . $this->socketResource);
return $this->socketResource;
}
/**
* Setter for helper instance
*
* @param $helperInstance An instance of a helper class
* @return void
*/
protected final function setHelperInstance (Helper $helperInstance) {
$this->helperInstance = $helperInstance;
}
/**
* Getter for helper instance
*
* @return $helperInstance An instance of a helper class
*/
public final function getHelperInstance () {
return $this->helperInstance;
}
/**
* Getter for a InputStream instance
*
* @param $inputStreamInstance The InputStream instance
*/
protected final function getInputStreamInstance () {
return $this->inputStreamInstance;
}
/**
* Setter for a InputStream instance
*
* @param $inputStreamInstance The InputStream instance
* @return void
*/
protected final function setInputStreamInstance (InputStream $inputStreamInstance) {
$this->inputStreamInstance = $inputStreamInstance;
}
/**
* Getter for a OutputStream instance
*
* @param $outputStreamInstance The OutputStream instance
*/
protected final function getOutputStreamInstance () {
return $this->outputStreamInstance;
}
/**
* Setter for a OutputStream instance
*
* @param $outputStreamInstance The OutputStream instance
* @return void
*/
protected final function setOutputStreamInstance (OutputStream $outputStreamInstance) {
$this->outputStreamInstance = $outputStreamInstance;
}
/**
* Setter for handler instance
*
* @param $handlerInstance An instance of a Handleable class
* @return void
*/
protected final function setHandlerInstance (Handleable $handlerInstance) {
$this->handlerInstance = $handlerInstance;
}
/**
* Getter for handler instance
*
* @return $handlerInstance A Handleable instance
*/
protected final function getHandlerInstance () {
return $this->handlerInstance;
}
/**
* 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 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;
}
/**
* Setter for FilePointer instance
*
* @param $pointerInstance An instance of an FilePointer class
* @return void
*/
protected final function setPointerInstance (FilePointer $pointerInstance) {
$this->pointerInstance = $pointerInstance;
}
/**
* Getter for FilePointer instance
*
* @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
*
* @param $indexInstance An instance of an Indexable class
* @return void
*/
protected final function setIndexInstance (Indexable $indexInstance) {
$this->indexInstance = $indexInstance;
}
/**
* Getter for Indexable instance
*
* @return $indexInstance An instance of an Indexable class
*/
public final function getIndexInstance () {
return $this->indexInstance;
}
/**
* Setter for Block instance
*
* @param $blockInstance An instance of an Block class
* @return void
*/
protected final function setBlockInstance (Block $blockInstance) {
$this->blockInstance = $blockInstance;
}
/**
* Getter for Block instance
*
* @return $blockInstance An instance of an Block class
*/
public final function getBlockInstance () {
return $this->blockInstance;
}
/**
* Setter for Minable instance
*
* @param $minableInstance A Minable instance
* @return void
*/
protected final function setMinableInstance (Minable $minableInstance) {
$this->minableInstance = $minableInstance;
}
/**
* Getter for minable instance
*
* @return $minableInstance A Minable instance
*/
protected final function getMinableInstance () {
return $this->minableInstance;
}
/**
* Setter for FrameworkDirectory instance
*
* @param $directoryInstance A FrameworkDirectory instance
* @return void
*/
protected final function setDirectoryInstance (FrameworkDirectory $directoryInstance) {
$this->directoryInstance = $directoryInstance;
}
/**
* Getter for FrameworkDirectory instance
*
* @return $directoryInstance A FrameworkDirectory instance
*/
protected final function getDirectoryInstance () {
return $this->directoryInstance;
}
/**
* Setter for state instance
*
* @param $stateInstance A Stateable instance
* @return void
*/
public final function setStateInstance (Stateable $stateInstance) {
$this->stateInstance = $stateInstance;
}
/**
* Getter for state instance
*
* @return $stateInstance A Stateable instance
*/
public final function getStateInstance () {
return $this->stateInstance;
}
/**
* Setter for output instance
*
* @param $outputInstance The debug output instance
* @return void
*/
public final function setOutputInstance (OutputStreamer $outputInstance) {
$this->outputInstance = $outputInstance;
}
/**
* Getter for output instance
*
* @return $outputInstance The debug output instance
*/
public final function getOutputInstance () {
return $this->outputInstance;
}
/**
* Setter for registry instance
*
* @param $registryInstance An instance of a Register class
* @return void
*/
protected final function setRegistryInstance (Register $registryInstance) {
$this->registryInstance = $registryInstance;
}
/**
* Getter for registry instance
*
* @return $registryInstance The debug registry instance
*/
public final function getRegistryInstance () {
return $this->registryInstance;
}
/**
* Setter for call-back instance
*
* @param $callbackInstance An instance of a FrameworkInterface class
* @return void
*/
public final function setCallbackInstance (FrameworkInterface $callbackInstance) {
$this->callbackInstance = $callbackInstance;
}
/**
* Getter for call-back instance
*
* @return $callbackInstance An instance of a FrameworkInterface class
*/
protected final function getCallbackInstance () {
return $this->callbackInstance;
}
/**
* 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
*
* @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 (HtmlTemplateEngine 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 = GenericRegistry::getRegistry()->getInstance('application');
// 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('html_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('
Message: %s
' . PHP_EOL, $message);
} // END - if
// Generate the output
$content .= sprintf('%s
',
trim(
htmlentities(
print_r($this, true)
)
)
);
// Output it
ApplicationEntryPoint::exitApplication(sprintf('
%s
Loaded includes:
%s
',
$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 = '') {
// Init variable
$stubMessage = 'Partial stub!';
// Is an 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__, __LINE__)->debugOutput($stubMessage);
} else {
// Trigger an error
trigger_error($stubMessage);
exit;
}
}
/**
* 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
' . PHP_EOL, $message);
} // END - if
print('');
debug_print_backtrace();
print('
');
// Exit program?
if ($doExit === true) {
exit();
} // END - if
}
/**
* Creates an instance of a debugger instance
*
* @param $className Name of the class (currently unsupported)
* @param $lineNumber Line number where the call was made
* @return $debugInstance An instance of a debugger class
* @deprecated Not fully, as the new Logger facilities are not finished yet.
*/
public final static function createDebugInstance ($className, $lineNumber = NULL) {
// Is the instance set?
if (!GenericRegistry::getRegistry()->instanceExists('debug')) {
// Init debug instance
$debugInstance = NULL;
// Try it
try {
// Get a debugger instance
$debugInstance = DebugMiddleware::createDebugMiddleware(FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('debug_' . FrameworkBootstrap::getRequestTypeFromSystem() . '_class'), $className);
} catch (NullPointerException $e) {
// Didn't work, no instance there
exit(sprintf('Cannot create debugInstance! Exception=%s,message=%s,className=%s,lineNumber=%d' . PHP_EOL, $e->__toString(), $e->getMessage(), $className, $lineNumber));
}
// Empty string should be ignored and used for testing the middleware
DebugMiddleware::getSelfInstance()->output('');
// Set it in registry
GenericRegistry::getRegistry()->addInstance('debug', $debugInstance);
} else {
// Get instance from registry
$debugInstance = GenericRegistry::getRegistry()->getDebugInstance();
}
// Return it
return $debugInstance;
}
/**
* Simple output of a message with line-break
*
* @param $message Message to output
* @return void
*/
public function outputLine ($message) {
// Simply output it
print($message . PHP_EOL);
}
/**
* 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;
// Get backtrace
$backtrace = debug_backtrace(!DEBUG_BACKTRACE_PROVIDE_OBJECT);
// Is function partialStub/__callStatic ?
if (in_array($backtrace[1]['function'], array('partialStub', '__call', '__callStatic'))) {
// Prepend class::function:line from 3rd element
$message = sprintf('[%s::%s:%d]: %s',
$backtrace[2]['class'],
$backtrace[2]['function'],
(isset($backtrace[2]['line']) ? $backtrace[2]['line'] : '0'),
$message
);
} else {
// Prepend class::function:line from 2nd element
$message = sprintf('[%s::%s:%d]: %s',
$backtrace[1]['class'],
$backtrace[1]['function'],
(isset($backtrace[1]['line']) ? $backtrace[1]['line'] : '0'),
$message
);
}
// 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_' . FrameworkBootstrap::getRequestTypeFromSystem() . '_output_timings') == 'Y') {
// Prepent it
$message = $this->getPrintableExecutionTime() . $message;
} // END - if
// Put directly out
if ($doPrint === true) {
// Print message
$this->outputLine($message);
} 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 static final function convertToClassName ($str) {
// Init class name
$className = '';
// Convert all dashes in underscores
$str = StringUtils::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;
}
/**
* 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('',
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('%s: %s' . PHP_EOL,
($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 (!$this->getResultInstance() instanceof SearchableResult) {
// 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) {
// @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
$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__, __LINE__)->debugOutput($fieldName.':'.print_r($fieldArray, true).'
');
// Convert dashes to underscore
$fieldName2 = StringUtils::convertDashesToUnderscores($fieldName);
// Does the field exist?
if ($this->isFieldSet($fieldName)) {
// Get it
$fieldValue = $fieldArray[$fieldName2];
} elseif (defined('DEVELOPER')) {
// Missing field entry, may require debugging
self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']:fieldArray=' . print_r($fieldArray, true) . '
,fieldName=' . $fieldName . ' not found!');
} else {
// Missing field entry, may require debugging
self::createDebugInstance(__CLASS__, __LINE__)->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__, __LINE__)->debugOutput('[' . $this->__toString() . ':' . __LINE__ . '] fieldName=' . $fieldName . ',fieldArray='.print_r($fieldArray, true).'
');
// Convert dashes to underscore
$fieldName = StringUtils::convertDashesToUnderscores($fieldName);
// Determine it
$isSet = isset($fieldArray[$fieldName]);
// Return result
return $isSet;
}
/**
* 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 = DatabaseWrapperFactory::createWrapperByConfiguredName($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__, __LINE__)->debugOutput($message);
} else {
// Trigger an error
trigger_error($message . "
\n");
exit;
}
} else {
// @TODO Finish this part!
$this->partialStub('Developer mode inactive. Message:' . $message);
}
}
/**
* Checks whether the given PHP extension is loaded
*
* @param $phpExtension The PHP extension we shall check
* @return $isLoaded Whether the PHP extension is loaded
*/
public final function isPhpExtensionLoaded ($phpExtension) {
// Is it loaded?
$isLoaded = in_array($phpExtension, get_loaded_extensions());
// Return result
return $isLoaded;
}
/**
* "Getter" as a time() replacement but with milliseconds. You should use this
* method instead of the encapsulated getimeofday() function.
*
* @return $milliTime Timestamp with milliseconds
*/
public function getMilliTime () {
// Get the time of day as float
$milliTime = gettimeofday(true);
// Return it
return $milliTime;
}
/**
* Idles (sleeps) for given milliseconds
*
* @return $hasSlept Whether it goes fine
*/
public function idle ($milliSeconds) {
// Sleep is fine by default
$hasSlept = true;
// Idle so long with found function
if (function_exists('time_sleep_until')) {
// Get current time and add idle time
$sleepUntil = $this->getMilliTime() + abs($milliSeconds) / 1000;
// New PHP 5.1.0 function found, ignore errors
$hasSlept = @time_sleep_until($sleepUntil);
} else {
/*
* My Sun station doesn't have that function even with latest PHP
* package. :(
*/
usleep($milliSeconds * 1000);
}
// Return result
return $hasSlept;
}
/**
* Converts a hexadecimal string, even with negative sign as first string to
* a decimal number using BC functions.
*
* This work is based on comment #86673 on php.net documentation page at:
*
*
* @param $hex Hexadecimal string
* @return $dec Decimal number
*/
protected function hex2dec ($hex) {
// Convert to all lower-case
$hex = strtolower($hex);
// Detect sign (negative/positive numbers)
$sign = '';
if (substr($hex, 0, 1) == '-') {
$sign = '-';
$hex = substr($hex, 1);
} // END - if
// Decode the hexadecimal string into a decimal number
$dec = 0;
for ($i = strlen($hex) - 1, $e = 1; $i >= 0; $i--, $e = bcmul($e, 16)) {
$factor = self::$hexdec[substr($hex, $i, 1)];
$dec = bcadd($dec, bcmul($factor, $e));
} // END - for
// Return the decimal number
return $sign . $dec;
}
/**
* Converts even very large decimal numbers, also signed, to a hexadecimal
* string.
*
* This work is based on comment #97756 on php.net documentation page at:
*
*
* @param $dec Decimal number, even with negative sign
* @param $maxLength Optional maximum length of the string
* @return $hex Hexadecimal string
*/
protected function dec2hex ($dec, $maxLength = 0) {
// maxLength can be zero or devideable by 2
assert(($maxLength == 0) || (($maxLength % 2) == 0));
// Detect sign (negative/positive numbers)
$sign = '';
if ($dec < 0) {
$sign = '-';
$dec = abs($dec);
} // END - if
// Encode the decimal number into a hexadecimal string
$hex = '';
do {
$hex = self::$dechex[($dec % (2 ^ 4))] . $hex;
$dec /= (2 ^ 4);
} while ($dec >= 1);
/*
* Leading zeros are required for hex-decimal "numbers". In some
* situations more leading zeros are wanted, so check for both
* conditions.
*/
if ($maxLength > 0) {
// Prepend more zeros
$hex = str_pad($hex, $maxLength, '0', STR_PAD_LEFT);
} elseif ((strlen($hex) % 2) != 0) {
// Only make string's length dividable by 2
$hex = '0' . $hex;
}
// Return the hexadecimal string
return $sign . $hex;
}
/**
* Converts a ASCII string (0 to 255) into a decimal number.
*
* @param $asc The ASCII string to be converted
* @return $dec Decimal number
*/
protected function asc2dec ($asc) {
// Convert it into a hexadecimal number
$hex = bin2hex($asc);
// And back into a decimal number
$dec = $this->hex2dec($hex);
// Return it
return $dec;
}
/**
* Converts a decimal number into an ASCII string.
*
* @param $dec Decimal number
* @return $asc An ASCII string
*/
protected function dec2asc ($dec) {
// First convert the number into a hexadecimal string
$hex = $this->dec2hex($dec);
// Then convert it into the ASCII string
$asc = $this->hex2asc($hex);
// Return it
return $asc;
}
/**
* Converts a hexadecimal number into an ASCII string. Negative numbers
* are not allowed.
*
* @param $hex Hexadecimal string
* @return $asc An ASCII string
*/
protected function hex2asc ($hex) {
// Check for length, it must be devideable by 2
//* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('hex='.$hex);
assert((strlen($hex) % 2) == 0);
// Walk the string
$asc = '';
for ($idx = 0; $idx < strlen($hex); $idx+=2) {
// Get the decimal number of the chunk
$part = hexdec(substr($hex, $idx, 2));
// Add it to the final string
$asc .= chr($part);
} // END - for
// Return the final string
return $asc;
}
/**
* Checks whether the given encoded data was encoded with Base64
*
* @param $encodedData Encoded data we shall check
* @return $isBase64 Whether the encoded data is Base64
*/
protected function isBase64Encoded ($encodedData) {
// Determine it
$isBase64 = (@base64_decode($encodedData, true) !== false);
// Return it
return $isBase64;
}
/**
* Gets a cache key from Criteria instance
*
* @param $criteriaInstance An instance of a Criteria class
* @param $onlyKeys Only use these keys for a cache key
* @return $cacheKey A cache key suitable for lookup/storage purposes
*/
protected function getCacheKeyByCriteria (Criteria $criteriaInstance, array $onlyKeys = array()) {
// Generate it
$cacheKey = sprintf('%s@%s',
$this->__toString(),
$criteriaInstance->getCacheKey($onlyKeys)
);
// And return it
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($this->__toString() . ': cacheKey=' . $cacheKey);
return $cacheKey;
}
/**
* Getter for startup time in miliseconds
*
* @return $startupTime Startup time in miliseconds
*/
protected function getStartupTime () {
return self::$startupTime;
}
/**
* "Getter" for a printable currently execution time in nice braces
*
* @return $executionTime Current execution time in nice braces
*/
protected function getPrintableExecutionTime () {
// Caculate the execution time
$executionTime = microtime(true) - $this->getStartupTime();
// Pack it in nice braces
$executionTime = sprintf('[ %01.5f ] ', $executionTime);
// And return it
return $executionTime;
}
/**
* Hashes a given string with a simple but stronger hash function (no salt)
* and hex-encode it.
*
* @param $str The string to be hashed
* @return $hash The hash from string $str
*/
public static final function hash ($str) {
// Hash given string with (better secure) hasher
$hash = bin2hex(mhash(MHASH_SHA256, $str));
// Return it
return $hash;
}
/**
* "Getter" for length of hash() output. This will be "cached" to speed up
* things.
*
* @return $length Length of hash() output
*/
public static final function getHashLength () {
// Is it cashed?
if (is_null(self::$hashLength)) {
// No, then hash a string and save its length.
self::$hashLength = strlen(self::hash('abc123'));
} // END - if
// Return it
return self::$hashLength;
}
/**
* Checks whether the given number is really a number (only chars 0-9).
*
* @param $num A string consisting only chars between 0 and 9
* @param $castValue Whether to cast the value to double. Do only use this to secure numbers from Requestable classes.
* @param $assertMismatch Whether to assert mismatches
* @return $ret The (hopefully) secured numbered value
*/
public function bigintval ($num, $castValue = true, $assertMismatch = false) {
// Filter all numbers out
$ret = preg_replace('/[^0123456789]/', '', $num);
// Shall we cast?
if ($castValue === true) {
// Cast to biggest numeric type
$ret = (double) $ret;
} // END - if
// Assert only if requested
if ($assertMismatch === true) {
// Has the whole value changed?
assert(('' . $ret . '' != '' . $num . '') && (!is_null($num)));
} // END - if
// Return result
return $ret;
}
/**
* Checks whether the given hexadecimal number is really a hex-number (only chars 0-9,a-f).
*
* @param $num A string consisting only chars between 0 and 9
* @param $assertMismatch Whether to assert mismatches
* @return $ret The (hopefully) secured hext-numbered value
*/
public function hexval ($num, $assertMismatch = false) {
// Filter all numbers out
$ret = preg_replace('/[^0123456789abcdefABCDEF]/', '', $num);
// Assert only if requested
if ($assertMismatch === true) {
// Has the whole value changed?
assert(('' . $ret . '' != '' . $num . '') && (!is_null($num)));
} // END - if
// Return result
return $ret;
}
/**
* Determines if an element is set in the generic array
*
* @param $keyGroup Main group for the key
* @param $subGroup Sub group for the key
* @param $key Key to check
* @param $element Element to check
* @return $isset Whether the given key is set
*/
protected final function isGenericArrayElementSet ($keyGroup, $subGroup, $key, $element) {
// Debug message
//* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element);
// Is it there?
$isset = isset($this->genericArray[$keyGroup][$subGroup][$key][$element]);
// Return it
return $isset;
}
/**
* Determines if a key is set in the generic array
*
* @param $keyGroup Main group for the key
* @param $subGroup Sub group for the key
* @param $key Key to check
* @return $isset Whether the given key is set
*/
protected final function isGenericArrayKeySet ($keyGroup, $subGroup, $key) {
// Debug message
//* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
// Is it there?
$isset = isset($this->genericArray[$keyGroup][$subGroup][$key]);
// Return it
return $isset;
}
/**
* Determines if a group is set in the generic array
*
* @param $keyGroup Main group
* @param $subGroup Sub group
* @return $isset Whether the given group is set
*/
protected final function isGenericArrayGroupSet ($keyGroup, $subGroup) {
// Debug message
//* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup);
// Is it there?
$isset = isset($this->genericArray[$keyGroup][$subGroup]);
// Return it
return $isset;
}
/**
* Getter for sub key group
*
* @param $keyGroup Main key group
* @param $subGroup Sub key group
* @return $array An array with all array elements
*/
protected final function getGenericSubArray ($keyGroup, $subGroup) {
// Is it there?
if (!$this->isGenericArrayGroupSet($keyGroup, $subGroup)) {
// No, then abort here
trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ' not found.');
exit;
} // END - if
// Debug message
//* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',value=' . print_r($this->genericArray[$keyGroup][$subGroup], true));
// Return it
return $this->genericArray[$keyGroup][$subGroup];
}
/**
* Unsets a given key in generic array
*
* @param $keyGroup Main group for the key
* @param $subGroup Sub group for the key
* @param $key Key to unset
* @return void
*/
protected final function unsetGenericArrayKey ($keyGroup, $subGroup, $key) {
// Debug message
//* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
// Remove it
unset($this->genericArray[$keyGroup][$subGroup][$key]);
}
/**
* Unsets a given element in generic array
*
* @param $keyGroup Main group for the key
* @param $subGroup Sub group for the key
* @param $key Key to unset
* @param $element Element to unset
* @return void
*/
protected final function unsetGenericArrayElement ($keyGroup, $subGroup, $key, $element) {
// Debug message
//* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element);
// Remove it
unset($this->genericArray[$keyGroup][$subGroup][$key][$element]);
}
/**
* Append a string to a given generic array key
*
* @param $keyGroup Main group for the key
* @param $subGroup Sub group for the key
* @param $key Key to unset
* @param $value Value to add/append
* @return void
*/
protected final function appendStringToGenericArrayKey ($keyGroup, $subGroup, $key, $value, $appendGlue = '') {
// Debug message
//* NOISY-DEBUG: */ if (!is_object($value)) $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',value[' . gettype($value) . ']=' . print_r($value, true) . ',appendGlue=' . $appendGlue);
// Is it already there?
if ($this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
// Append it
$this->genericArray[$keyGroup][$subGroup][$key] .= $appendGlue . (string) $value;
} else {
// Add it
$this->genericArray[$keyGroup][$subGroup][$key] = (string) $value;
}
}
/**
* Append a string to a given generic array element
*
* @param $keyGroup Main group for the key
* @param $subGroup Sub group for the key
* @param $key Key to unset
* @param $element Element to check
* @param $value Value to add/append
* @return void
*/
protected final function appendStringToGenericArrayElement ($keyGroup, $subGroup, $key, $element, $value, $appendGlue = '') {
// Debug message
//* NOISY-DEBUG: */ if (!is_object($value)) $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element . ',value[' . gettype($value) . ']=' . print_r($value, true) . ',appendGlue=' . $appendGlue);
// Is it already there?
if ($this->isGenericArrayElementSet($keyGroup, $subGroup, $key, $element)) {
// Append it
$this->genericArray[$keyGroup][$subGroup][$key][$element] .= $appendGlue . (string) $value;
} else {
// Add it
$this->setStringGenericArrayElement($keyGroup, $subGroup, $key, $element, $value);
}
}
/**
* Sets a string in a given generic array element
*
* @param $keyGroup Main group for the key
* @param $subGroup Sub group for the key
* @param $key Key to unset
* @param $element Element to check
* @param $value Value to add/append
* @return void
*/
protected final function setStringGenericArrayElement ($keyGroup, $subGroup, $key, $element, $value, $appendGlue = '') {
// Debug message
//* NOISY-DEBUG: */ if (!is_object($value)) $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element . ',value[' . gettype($value) . ']=' . print_r($value, true) . ',appendGlue=' . $appendGlue);
// Set it
$this->genericArray[$keyGroup][$subGroup][$key][$element] = (string) $value;
}
/**
* Initializes given generic array group
*
* @param $keyGroup Main group for the key
* @param $subGroup Sub group for the key
* @param $key Key to use
* @param $forceInit Optionally force initialization
* @return void
*/
protected final function initGenericArrayGroup ($keyGroup, $subGroup, $forceInit = false) {
// Debug message
//* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',forceInit=' . intval($forceInit));
// Is it already set?
if (($forceInit === false) && ($this->isGenericArrayGroupSet($keyGroup, $subGroup))) {
// Already initialized
trigger_error(__METHOD__ . ':keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ' already initialized.');
exit;
} // END - if
// Initialize it
$this->genericArray[$keyGroup][$subGroup] = array();
}
/**
* Initializes given generic array key
*
* @param $keyGroup Main group for the key
* @param $subGroup Sub group for the key
* @param $key Key to use
* @param $forceInit Optionally force initialization
* @return void
*/
protected final function initGenericArrayKey ($keyGroup, $subGroup, $key, $forceInit = false) {
// Debug message
//* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',forceInit=' . intval($forceInit));
// Is it already set?
if (($forceInit === false) && ($this->isGenericArrayKeySet($keyGroup, $subGroup, $key))) {
// Already initialized
trigger_error(__METHOD__ . ':keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ' already initialized.');
exit;
} // END - if
// Initialize it
$this->genericArray[$keyGroup][$subGroup][$key] = array();
}
/**
* Initializes given generic array element
*
* @param $keyGroup Main group for the key
* @param $subGroup Sub group for the key
* @param $key Key to use
* @param $element Element to use
* @param $forceInit Optionally force initialization
* @return void
*/
protected final function initGenericArrayElement ($keyGroup, $subGroup, $key, $element, $forceInit = false) {
// Debug message
//* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element . ',forceInit=' . intval($forceInit));
// Is it already set?
if (($forceInit === false) && ($this->isGenericArrayElementSet($keyGroup, $subGroup, $key, $element))) {
// Already initialized
trigger_error(__METHOD__ . ':keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element . ' already initialized.');
exit;
} // END - if
// Initialize it
$this->genericArray[$keyGroup][$subGroup][$key][$element] = array();
}
/**
* Pushes an element to a generic key
*
* @param $keyGroup Main group for the key
* @param $subGroup Sub group for the key
* @param $key Key to use
* @param $value Value to add/append
* @return $count Number of array elements
*/
protected final function pushValueToGenericArrayKey ($keyGroup, $subGroup, $key, $value) {
// Debug message
//* NOISY-DEBUG: */ if (!is_object($value)) $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',value[' . gettype($value) . ']=' . print_r($value, true));
// Is it set?
if (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
// Initialize array
$this->initGenericArrayKey($keyGroup, $subGroup, $key);
} // END - if
// Then push it
$count = array_push($this->genericArray[$keyGroup][$subGroup][$key], $value);
// Return count
//* DEBUG: */ print(__METHOD__ . ': genericArray=' . print_r($this->genericArray[$keyGroup][$subGroup][$key], true));
//* DEBUG: */ print(__METHOD__ . ': count=' . $count . PHP_EOL);
return $count;
}
/**
* Pushes an element to a generic array element
*
* @param $keyGroup Main group for the key
* @param $subGroup Sub group for the key
* @param $key Key to use
* @param $element Element to check
* @param $value Value to add/append
* @return $count Number of array elements
*/
protected final function pushValueToGenericArrayElement ($keyGroup, $subGroup, $key, $element, $value) {
// Debug message
//* NOISY-DEBUG: */ if (!is_object($value)) $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element . ',value[' . gettype($value) . ']=' . print_r($value, true));
// Is it set?
if (!$this->isGenericArrayElementSet($keyGroup, $subGroup, $key, $element)) {
// Initialize array
$this->initGenericArrayElement($keyGroup, $subGroup, $key, $element);
} // END - if
// Then push it
$count = array_push($this->genericArray[$keyGroup][$subGroup][$key][$element], $value);
// Return count
//* DEBUG: */ print(__METHOD__ . ': genericArray=' . print_r($this->genericArray[$keyGroup][$subGroup][$key], true));
//* DEBUG: */ print(__METHOD__ . ': count=' . $count . PHP_EOL);
return $count;
}
/**
* Pops an element from a generic group
*
* @param $keyGroup Main group for the key
* @param $subGroup Sub group for the key
* @param $key Key to unset
* @return $value Last "popped" value
*/
protected final function popGenericArrayElement ($keyGroup, $subGroup, $key) {
// Debug message
//* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
// Is it set?
if (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
// Not found
trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ' not found.');
exit;
} // END - if
// Then "pop" it
$value = array_pop($this->genericArray[$keyGroup][$subGroup][$key]);
// Return value
//* DEBUG: */ print(__METHOD__ . ': genericArray=' . print_r($this->genericArray[$keyGroup][$subGroup][$key], true));
//* DEBUG: */ print(__METHOD__ . ': value[' . gettype($value) . ']=' . print_r($value, true) . PHP_EOL);
return $value;
}
/**
* Shifts an element from a generic group
*
* @param $keyGroup Main group for the key
* @param $subGroup Sub group for the key
* @param $key Key to unset
* @return $value Last "popped" value
*/
protected final function shiftGenericArrayElement ($keyGroup, $subGroup, $key) {
// Debug message
//* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
// Is it set?
if (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
// Not found
trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ' not found.');
exit;
} // END - if
// Then "shift" it
$value = array_shift($this->genericArray[$keyGroup][$subGroup][$key]);
// Return value
//* DEBUG: */ print(__METHOD__ . ': genericArray=' . print_r($this->genericArray[$keyGroup][$subGroup][$key], true));
//* DEBUG: */ print(__METHOD__ . ': value[' . gettype($value) . ']=' . print_r($value, true) . PHP_EOL);
return $value;
}
/**
* Count generic array group
*
* @param $keyGroup Main group for the key
* @return $count Count of given group
*/
protected final function countGenericArray ($keyGroup) {
// Debug message
//* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup);
// Is it there?
if (!isset($this->genericArray[$keyGroup])) {
// Abort here
trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ' not found.');
exit;
} // END - if
// Then count it
$count = count($this->genericArray[$keyGroup]);
// Debug message
//* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',count=' . $count);
// Return it
return $count;
}
/**
* Count generic array sub group
*
* @param $keyGroup Main group for the key
* @param $subGroup Sub group for the key
* @return $count Count of given group
*/
protected final function countGenericArrayGroup ($keyGroup, $subGroup) {
// Debug message
//* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup);
// Is it there?
if (!$this->isGenericArrayGroupSet($keyGroup, $subGroup)) {
// Abort here
trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ' not found.');
exit;
} // END - if
// Then count it
$count = count($this->genericArray[$keyGroup][$subGroup]);
// Debug message
//* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',count=' . $count);
// Return it
return $count;
}
/**
* Count generic array elements
*
* @param $keyGroup Main group for the key
* @param $subGroup Sub group for the key
* @para $key Key to count
* @return $count Count of given key
*/
protected final function countGenericArrayElements ($keyGroup, $subGroup, $key) {
// Debug message
//* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
// Is it there?
if (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
// Abort here
trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ' not found.');
exit;
} elseif (!$this->isValidGenericArrayGroup($keyGroup, $subGroup)) {
// Not valid
trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ' is not an array.');
exit;
}
// Then count it
$count = count($this->genericArray[$keyGroup][$subGroup][$key]);
// Debug message
//* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',count=' . $count);
// Return it
return $count;
}
/**
* Getter for whole generic group array
*
* @param $keyGroup Key group to get
* @return $array Whole generic array group
*/
protected final function getGenericArray ($keyGroup) {
// Debug message
//* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup);
// Is it there?
if (!isset($this->genericArray[$keyGroup])) {
// Then abort here
trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ' does not exist.');
exit;
} // END - if
// Return it
return $this->genericArray[$keyGroup];
}
/**
* Setter for generic array key
*
* @param $keyGroup Key group to get
* @param $subGroup Sub group for the key
* @param $key Key to unset
* @param $value Mixed value from generic array element
* @return void
*/
protected final function setGenericArrayKey ($keyGroup, $subGroup, $key, $value) {
// Debug message
//* NOISY-DEBUG: */ if (!is_object($value)) $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',value[' . gettype($value) . ']=' . print_r($value, true));
// Set value here
$this->genericArray[$keyGroup][$subGroup][$key] = $value;
}
/**
* Getter for generic array key
*
* @param $keyGroup Key group to get
* @param $subGroup Sub group for the key
* @param $key Key to unset
* @return $value Mixed value from generic array element
*/
protected final function getGenericArrayKey ($keyGroup, $subGroup, $key) {
// Debug message
//* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
// Is it there?
if (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
// Then abort here
trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ' does not exist.');
exit;
} // END - if
// Return it
return $this->genericArray[$keyGroup][$subGroup][$key];
}
/**
* Sets a value in given generic array key/element
*
* @param $keyGroup Main group for the key
* @param $subGroup Sub group for the key
* @param $key Key to set
* @param $element Element to set
* @param $value Value to set
* @return void
*/
protected final function setGenericArrayElement ($keyGroup, $subGroup, $key, $element, $value) {
// Debug message
//* NOISY-DEBUG: */ if (!is_object($value)) $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element . ',value[' . gettype($value) . ']=' . print_r($value, true));
// Then set it
$this->genericArray[$keyGroup][$subGroup][$key][$element] = $value;
}
/**
* Getter for generic array element
*
* @param $keyGroup Key group to get
* @param $subGroup Sub group for the key
* @param $key Key to look for
* @param $element Element to look for
* @return $value Mixed value from generic array element
*/
protected final function getGenericArrayElement ($keyGroup, $subGroup, $key, $element) {
// Debug message
//* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element);
// Is it there?
if (!$this->isGenericArrayElementSet($keyGroup, $subGroup, $key, $element)) {
// Then abort here
trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element . ' does not exist.');
exit;
} // END - if
// Return it
return $this->genericArray[$keyGroup][$subGroup][$key][$element];
}
/**
* Checks if a given sub group is valid (array)
*
* @param $keyGroup Key group to get
* @param $subGroup Sub group for the key
* @return $isValid Whether given sub group is valid
*/
protected final function isValidGenericArrayGroup ($keyGroup, $subGroup) {
// Debug message
//* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup);
// Determine it
$isValid = (($this->isGenericArrayGroupSet($keyGroup, $subGroup)) && (is_array($this->getGenericSubArray($keyGroup, $subGroup))));
// Return it
return $isValid;
}
/**
* Checks if a given key is valid (array)
*
* @param $keyGroup Key group to get
* @param $subGroup Sub group for the key
* @param $key Key to check
* @return $isValid Whether given sub group is valid
*/
protected final function isValidGenericArrayKey ($keyGroup, $subGroup, $key) {
// Debug message
//* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
// Determine it
$isValid = (($this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) && (is_array($this->getGenericArrayKey($keyGroup, $subGroup, $key))));
// Return it
return $isValid;
}
/**
* Initializes the web output instance
*
* @return void
*/
protected function initWebOutputInstance () {
// Get application instance
$applicationInstance = GenericRegistry::getRegistry()->getInstance('application');
// 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'
*
* @param $boolean Boolean value
* @return $translated Translated boolean value
*/
public static final function translateBooleanToYesNo ($boolean) {
// Make sure it is really boolean
assert(is_bool($boolean));
// "Translate" it
$translated = ($boolean === true) ? 'Y' : '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__, __LINE__)->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__, __LINE__)->debugOutput('packed=' . $packed . ' - EXIT!');
return $packed;
}
/**
* Creates a full-qualified file name (FQFN) for given file name by adding
* a configured temporary file path to it.
*
* @param $infoInstance An instance of a SplFileInfo class
* @return $tempInstance An instance of a SplFileInfo class (temporary file)
* @throw PathWriteProtectedException If the path in 'temp_file_path' is write-protected
* @throws FileIoException If the file cannot be written
*/
protected static function createTempPathForFile (SplFileInfo $infoInstance) {
// Get config entry
$basePath = FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('temp_file_path');
// Is the path writeable?
if (!is_writable($basePath)) {
// Path is write-protected
throw new PathWriteProtectedException($infoInstance, self::EXCEPTION_PATH_CANNOT_BE_WRITTEN);
} // END - if
// Add it
$tempInstance = new SplFileInfo($basePath . DIRECTORY_SEPARATOR . $infoInstance->getBasename());
// Is it reachable?
if (!FrameworkBootstrap::isReachableFilePath($tempInstance)) {
// Not reachable
throw new FileIoException($tempInstance, self::EXCEPTION_FILE_NOT_REACHABLE);
} // END - if
// Return it
return $tempInstance;
}
/**
* "Getter" for a printable state name
*
* @return $stateName Name of the node's state in a printable format
*/
public final function getPrintableState () {
// Default is 'null'
$stateName = 'null';
// Get the state instance
$stateInstance = $this->getStateInstance();
// Is it an instance of Stateable?
if ($stateInstance instanceof Stateable) {
// Then use that state name
$stateName = $stateInstance->getStateName();
} // END - if
// Return result
return $stateName;
}
}