3 namespace Org\Mxchange\CoreFramework\Object;
5 // Import framework stuff
6 use Org\Mxchange\CoreFramework\Bootstrap\FrameworkBootstrap;
7 use Org\Mxchange\CoreFramework\EntryPoint\ApplicationEntryPoint;
8 use Org\Mxchange\CoreFramework\Factory\Object\ObjectFactory;
9 use Org\Mxchange\CoreFramework\Filesystem\FileIoException;
10 use Org\Mxchange\CoreFramework\Filesystem\PathWriteProtectedException;
11 use Org\Mxchange\CoreFramework\Generic\FrameworkInterface;
12 use Org\Mxchange\CoreFramework\Generic\NullPointerException;
13 use Org\Mxchange\CoreFramework\Generic\UnsupportedOperationException;
14 use Org\Mxchange\CoreFramework\Helper\Application\ApplicationHelper;
15 use Org\Mxchange\CoreFramework\Loader\ClassLoader;
16 use Org\Mxchange\CoreFramework\Manager\ManageableApplication;
17 use Org\Mxchange\CoreFramework\Middleware\Debug\DebugMiddleware;
18 use Org\Mxchange\CoreFramework\Registry\Object\ObjectRegistry;
19 use Org\Mxchange\CoreFramework\Result\Database\CachedDatabaseResult;
20 use Org\Mxchange\CoreFramework\State\Stateable;
21 use Org\Mxchange\CoreFramework\Stream\Output\OutputStreamer;
22 use Org\Mxchange\CoreFramework\Utils\Strings\StringUtils;
25 use \BadMethodCallException;
26 use \InvalidArgumentException;
32 * The simulator system class is the super class of all other classes. This
33 * class handles saving of games etc.
35 * @author Roland Haeder <webmaster@shipsimu.org>
37 * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2023 Core Developer Team
38 * @license GNU GPL 3.0 or any newer version
39 * @link http://www.shipsimu.org
41 * This program is free software: you can redistribute it and/or modify
42 * it under the terms of the GNU General Public License as published by
43 * the Free Software Foundation, either version 3 of the License, or
44 * (at your option) any later version.
46 * This program is distributed in the hope that it will be useful,
47 * but WITHOUT ANY WARRANTY; without even the implied warranty of
48 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
49 * GNU General Public License for more details.
51 * You should have received a copy of the GNU General Public License
52 * along with this program. If not, see <http://www.gnu.org/licenses/>.
54 abstract class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
56 * Self-referencing instance
58 private static $selfInstance = NULL;
63 private static $debugInstance = NULL;
68 private static $stubMethods = [
69 'partialStub' => true,
71 '__callStatic' => true,
77 private $realClass = __CLASS__;
82 private $callbackInstance = NULL;
87 private $genericArray = [];
89 /***********************
90 * Exception codes.... *
91 ***********************/
93 // @todo Try to clean these constants up
94 const EXCEPTION_IS_NO_OBJECT = 0x002;
95 const EXCEPTION_IS_NO_ARRAY = 0x003;
96 const EXCEPTION_MISSING_METHOD = 0x004;
97 const EXCEPTION_CLASSES_NOT_MATCHING = 0x005;
98 const EXCEPTION_INDEX_OUT_OF_BOUNDS = 0x006;
99 const EXCEPTION_DIMENSION_ARRAY_INVALID = 0x007;
100 const EXCEPTION_ITEM_NOT_TRADEABLE = 0x008;
101 const EXCEPTION_ITEM_NOT_IN_PRICE_LIST = 0x009;
102 const EXCEPTION_GENDER_IS_WRONG = 0x00a;
103 const EXCEPTION_BIRTH_DATE_IS_INVALID = 0x00b;
104 const EXCEPTION_EMPTY_STRUCTURES_ARRAY = 0x00c;
105 const EXCEPTION_HAS_ALREADY_PERSONELL_LIST = 0x00d;
106 const EXCEPTION_NOT_ENOUGTH_UNEMPLOYEES = 0x00e;
107 const EXCEPTION_TOTAL_PRICE_NOT_CALCULATED = 0x00f;
108 const EXCEPTION_HARBOR_HAS_NO_SHIPYARDS = 0x010;
109 const EXCEPTION_CONTRACT_PARTNER_INVALID = 0x011;
110 const EXCEPTION_CONTRACT_PARTNER_MISMATCH = 0x012;
111 const EXCEPTION_CONTRACT_ALREADY_SIGNED = 0x013;
112 const EXCEPTION_UNEXPECTED_EMPTY_STRING = 0x014;
113 const EXCEPTION_PATH_NOT_FOUND = 0x015;
114 const EXCEPTION_INVALID_PATH_NAME = 0x016;
115 const EXCEPTION_READ_PROTECED_PATH = 0x017;
116 const EXCEPTION_WRITE_PROTECED_PATH = 0x018;
117 const EXCEPTION_DIR_POINTER_INVALID = 0x019;
118 const EXCEPTION_FILE_POINTER_INVALID = 0x01a;
119 const EXCEPTION_INVALID_RESOURCE = 0x01b;
120 const EXCEPTION_LIMIT_ELEMENT_IS_UNSUPPORTED = 0x01d;
121 const EXCEPTION_GETTER_IS_MISSING = 0x01e;
122 const EXCEPTION_ARRAY_EXPECTED = 0x01f;
123 const EXCEPTION_ARRAY_HAS_INVALID_COUNT = 0x020;
124 const EXCEPTION_ID_IS_INVALID_FORMAT = 0x021;
125 const EXCEPTION_MD5_CHECKSUMS_MISMATCH = 0x022;
126 const EXCEPTION_UNEXPECTED_STRING_SIZE = 0x023;
127 const EXCEPTION_SIMULATOR_ID_INVALID = 0x024;
128 const EXCEPTION_MISMATCHING_COMPRESSORS = 0x025;
129 const EXCEPTION_CONTAINER_ITEM_IS_NULL = 0x026;
130 const EXCEPTION_ITEM_IS_NO_ARRAY = 0x027;
131 const EXCEPTION_CONTAINER_MAYBE_DAMAGED = 0x028;
132 const EXCEPTION_INVALID_STRING = 0x029;
133 const EXCEPTION_VARIABLE_NOT_SET = 0x02a;
134 const EXCEPTION_ATTRIBUTES_ARE_MISSING = 0x02b;
135 const EXCEPTION_ARRAY_ELEMENTS_MISSING = 0x02c;
136 const EXCEPTION_TEMPLATE_ENGINE_UNSUPPORTED = 0x02d;
137 const EXCEPTION_FACTORY_REQUIRE_PARAMETER = 0x02e;
138 const EXCEPTION_MISSING_ELEMENT = 0x02f;
139 const EXCEPTION_HEADERS_ALREADY_SENT = 0x030;
140 const EXCEPTION_DEFAULT_CONTROLLER_GONE = 0x031;
141 const EXCEPTION_REQUIRED_INTERFACE_MISSING = 0x033;
142 const EXCEPTION_FATAL_ERROR = 0x034;
143 const EXCEPTION_FILE_NOT_FOUND = 0x035;
144 const EXCEPTION_ASSERTION_FAILED = 0x036;
145 const EXCEPTION_FILE_NOT_REACHABLE = 0x037;
146 const EXCEPTION_FILE_CANNOT_BE_READ = 0x038;
147 const EXCEPTION_FILE_CANNOT_BE_WRITTEN = 0x039;
148 const EXCEPTION_PATH_CANNOT_BE_WRITTEN = 0x03a;
149 const EXCEPTION_DATABASE_UPDATED_NOT_ALLOWED = 0x03b;
150 const EXCEPTION_FILTER_CHAIN_INTERCEPTED = 0x03c;
151 const EXCEPTION_INVALID_SOCKET = 0x03d;
152 const EXCEPTION_SELF_INSTANCE = 0x03e;
155 * Startup time in miliseconds
157 private static $startupTime = 0;
160 * Protected super constructor
162 * @param $className Name of the class
165 protected function __construct (string $className) {
167 $this->setRealClass($className);
169 // Is the startup time set? (0 cannot be true anymore)
170 if (self::$startupTime == 0) {
172 self::$startupTime = microtime(true);
177 * Destructor for all classes. You should not call this method on your own.
181 public function __destruct () {
182 // Is this object already destroyed?
183 if ($this->__toString() != 'DestructedObject') {
184 // Destroy all informations about this class but keep some text about it alive
185 $this->setRealClass('DestructedObject');
186 } elseif ((defined('DEBUG_DESTRUCTOR')) && (is_object($this->getDebugInstance()))) {
187 // Already destructed object
188 self::createDebugInstance(__CLASS__, __LINE__)->warningMessage(sprintf('The object <span class="object_name">%s</span> is already destroyed.',
192 // Do not call this twice
193 trigger_error(__METHOD__ . ': Called twice.');
199 * The __call() method where all non-implemented methods end up
201 * @param $methodName Name of the missing method
202 * @args $args Arguments passed to the method
205 public final function __call (string $methodName, array $args = NULL) {
207 self::$selfInstance = $this;
209 // Call static method
210 self::__callStatic($methodName, $args);
212 // Clear self-instance
213 self::$selfInstance = NULL;
217 * The __callStatic() method where all non-implemented static methods end up
219 * @param $methodName Name of the missing method
220 * @param $args Arguments passed to the method
222 * @throws InvalidArgumentException If self::$selfInstance is not a framework's own object
224 public static final function __callStatic (string $methodName, array $args = NULL) {
225 // Init argument string and class name
226 //* PRINT-DEBUG: */ printf('[%s:%d]: methodName=%s,args[]=%s - CALLED!' . PHP_EOL, __METHOD__, __LINE__, $methodName, gettype($args));
228 $className = 'unknown';
230 // Is self-instance set?
231 if (self::$selfInstance instanceof FrameworkInterface) {
232 // Framework's own instance
233 $className = self::$selfInstance->__toString();
234 } elseif (!is_null(self::$selfInstance)) {
236 throw new InvalidArgumentException(sprintf('self::instance[%s] is not expected.', gettype(self::$selfInstance)), self::EXCEPTION_SELF_INSTANCE);
239 // Is it NULL, empty or an array?
240 if (is_null($args)) {
242 $argsString = 'NULL';
243 } elseif (is_array($args)) {
247 // Some arguments are there
248 foreach ($args as $arg) {
249 // Add data about the argument
250 $argsString .= gettype($arg) . ':';
253 // Found a NULL argument
254 $argsString .= 'NULL';
255 } elseif (is_string($arg)) {
256 // Add length for strings
257 $argsString .= strlen($arg);
258 } elseif ((is_int($arg)) || (is_float($arg))) {
261 } elseif (is_array($arg)) {
262 // .. or size if array
263 $argsString .= count($arg);
264 } elseif (is_object($arg)) {
266 $reflection = new ReflectionClass($arg);
268 // Is an other object, maybe no __toString() available
269 $argsString .= $reflection->getName();
270 } elseif ($arg === true) {
271 // ... is boolean 'true'
272 $argsString .= 'true';
273 } elseif ($arg === false) {
274 // ... is boolean 'false'
275 $argsString .= 'false';
278 // Comma for next one
283 if (substr($argsString, -2, 1) == ',') {
285 $argsString = substr($argsString, 0, -2);
292 // Output stub message
293 // @TODO __CLASS__ does always return BaseFrameworkSystem but not the extending (=child) class
294 self::createDebugInstance(__CLASS__, __LINE__)->warningMessage(sprintf('[%s::%s]: Stub! Args: %s',
305 * Getter for $realClass
307 * @return $realClass The name of the real class (not BaseFrameworkSystem)
309 public function __toString () {
310 return $this->realClass;
314 * Magic method to catch setting of missing but set class fields/attributes
316 * @param $name Name of the field/attribute
317 * @param $value Value to store
320 public final function __set (string $name, $value) {
321 $this->debugBackTrace(sprintf('Tried to set a missing field. name=%s, value[%s]=%s',
324 print_r($value, true)
329 * Magic method to catch getting of missing fields/attributes
331 * @param $name Name of the field/attribute
334 public final function __get (string $name) {
335 $this->debugBackTrace(sprintf('Tried to get a missing field. name=%s',
341 * Magic method to catch unsetting of missing fields/attributes
343 * @param $name Name of the field/attribute
346 public final function __unset (string $name) {
347 $this->debugBackTrace(sprintf('Tried to unset a missing field. name=%s',
353 * Magic method to catch object serialization
355 * @return $unsupported Unsupported method
356 * @throws UnsupportedOperationException Objects of this framework cannot be serialized
358 public final function __sleep () {
359 throw new UnsupportedOperationException([$this, __FUNCTION__], FrameworkInterface::EXCEPTION_UNSPPORTED_OPERATION);
363 * Magic method to catch object deserialization
365 * @return $unsupported Unsupported method
366 * @throws UnsupportedOperationException Objects of this framework cannot be serialized
368 public final function __wakeup () {
369 throw new UnsupportedOperationException([$this, __FUNCTION__], FrameworkInterface::EXCEPTION_UNSPPORTED_OPERATION);
373 * Magic method to catch calls when an object instance is called
375 * @return $unsupported Unsupported method
376 * @throws UnsupportedOperationException Objects of this framework cannot be serialized
378 public final function __invoke () {
379 throw new UnsupportedOperationException([$this, __FUNCTION__], FrameworkInterface::EXCEPTION_UNSPPORTED_OPERATION);
383 * Setter for the real class name
385 * @param $realClass Class name (string)
388 public final function setRealClass (string $realClass) {
390 $this->realClass = $realClass;
394 * Setter for debug instance
396 * @param $debugInstance The instance for debug output class
399 public final function setDebugInstance (DebugMiddleware $debugInstance) {
400 self::$debugInstance = $debugInstance;
404 * Getter for debug instance
406 * @return $debugInstance Instance to class DebugConsoleOutput or DebugWebOutput
408 public final function getDebugInstance () {
409 return self::$debugInstance;
413 * Setter for web output instance
415 * @param $webInstance The instance for web output class
418 public final function setWebOutputInstance (OutputStreamer $webInstance) {
419 ObjectRegistry::getRegistry('generic')->addInstance('web_output', $webInstance);
423 * Getter for web output instance
425 * @return $webOutputInstance - Instance to class WebOutput
427 public final function getWebOutputInstance () {
428 return ObjectRegistry::getRegistry('generic')->getInstance('web_output');
432 * Setter for call-back instance
434 * @param $callbackInstance An instance of a FrameworkInterface class
437 public final function setCallbackInstance (FrameworkInterface $callbackInstance) {
438 $this->callbackInstance = $callbackInstance;
442 * Getter for call-back instance
444 * @return $callbackInstance An instance of a FrameworkInterface class
446 protected final function getCallbackInstance () {
447 return $this->callbackInstance;
451 * Checks whether an object equals this object. You should overwrite this
452 * method to implement own equality checks
454 * @param $objectInstance An instance of a FrameworkInterface object
455 * @return $equals Whether both objects equals
457 public function equals (FrameworkInterface $objectInstance) {
460 $this->__toString() == $objectInstance->__toString()
462 $this->hashCode() == $objectInstance->hashCode()
470 * Generates a generic hash code of this class. You should really overwrite
471 * this method with your own hash code generator code. But keep KISS in mind.
473 * @return $hashCode A generic hash code respresenting this whole class
475 public function hashCode () {
477 return crc32($this->__toString());
481 * Appends a trailing slash to a string
483 * @param $str A string (maybe) without trailing slash
484 * @return $str A string with an auto-appended trailing slash
485 * @throws InvalidArgumentException If a paramter has an invalid value
487 public final function addMissingTrailingSlash (string $str) {
489 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: str=%s - CALLED!', $str));
492 throw new InvalidArgumentException('Parameter "str" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
495 // Is there a trailing slash?
496 if (substr($str, -1, 1) != '/') {
500 // Return string with trailing slash
501 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: str=%s - EXIT!', $str));
506 * Debugs this instance by putting out it's full content
508 * @param $message Optional message to show in debug output
510 * @throws InvalidArgumentException If a paramter has an invalid value
512 public final function debugInstance (string $message = '') {
514 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: message=%s - CALLED!', $message));
515 if (empty($message)) {
517 throw new InvalidArgumentException('Parameter "message" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
520 // Restore the error handler to avoid trouble with missing array elements or undeclared variables
521 restore_error_handler();
527 if (!empty($message)) {
529 $content = sprintf('<div class="debug_message">
531 </div>' . PHP_EOL, $message);
534 // Generate the output
535 $content .= sprintf('<pre>%s</pre>',
544 ApplicationEntryPoint::exitApplication(sprintf('<div class="debug_header">
547 <div class="debug_content">
551 <div class="debug_include_list">
556 ClassLoader::getSelfInstance()->getPrintableIncludeList()
561 * Outputs a debug backtrace and stops further script execution
563 * @param $message An optional message to output
564 * @param $doExit Whether exit the program (true is default)
566 * @throws InvalidArgumentException If a paramter has an invalid value
568 public function debugBackTrace (string $message = '', bool $doExit = true) {
570 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: message=%s,doExit=%d - CALLED!', $message, intval($doExit)));
571 if (empty($message)) {
573 throw new InvalidArgumentException('Parameter "message" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
576 // Sorry, there is no other way getting this nice backtrace
577 if (!empty($message)) {
579 printf('Message: %s<br />' . PHP_EOL, $message);
583 debug_print_backtrace();
587 if ($doExit === true) {
588 // Yes, with error code
594 * Creates an instance of a debugger instance
596 * @param $className Name of the class (currently unsupported)
597 * @param $lineNumber Line number where the call was made
598 * @return $debugInstance An instance of a debugger class
599 * @throws InvalidArgumentException If a parameter has an invalid value
600 * @deprecated Not fully, as the new Logger facilities are not finished yet.
602 public final static function createDebugInstance (string $className, int $lineNumber = NULL) {
603 // Validate parameter
604 //* NOISY-DEBUG: */ printf('[%s:%d]: className=%s,lineNumber[%s]=%d - CALLED!' . PHP_EOL, __METHOD__, __LINE__, $className, gettype($lineNumber), $lineNumber);
605 if (empty($className)) {
607 throw new InvalidArgumentException('Parameter "className" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
610 // Is the debug instance set?
611 //* NOISY-DEBUG: */ printf('[%s:%d]: self::debugInstance[]=%s' . PHP_EOL, __METHOD__, __LINE__, gettype(self::$debugInstance));
612 if (is_null(self::$debugInstance)) {
613 // Init debug instance
614 self::$debugInstance = NULL;
618 // Get a debugger instance
619 //* NOISY-DEBUG: */ printf('[%s:%d]: className=%s' . PHP_EOL, __METHOD__, __LINE__, $className);
620 self::$debugInstance = DebugMiddleware::createDebugMiddleware(FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('debug_' . FrameworkBootstrap::getRequestTypeFromSystem() . '_class'), $className);
621 } catch (NullPointerException $e) {
622 // Didn't work, no instance there
623 exit(sprintf('[%s:%d]: Cannot create debugInstance! Exception=%s,message=%s,className=%s,lineNumber=%d' . PHP_EOL, __METHOD__, __LINE__, $e->__toString(), $e->getMessage(), $className, $lineNumber));
628 //* NOISY-DEBUG: */ printf('[%s:%d]: self::debugInstance=%s - EXIT!' . PHP_EOL, __METHOD__, __LINE__, self::$debugInstance->__toString());
629 return self::$debugInstance;
633 * Simple output of a message with line-break
635 * @param $message Message to output
637 * @throws InvalidArgumentException If a paramter has an invalid value
639 public function outputLine (string $message) {
641 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: message=%s - CALLED!', $message));
642 if (empty($message)) {
644 throw new InvalidArgumentException('Parameter "message" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
648 print($message . PHP_EOL);
652 * Marks up the code by adding e.g. line numbers
654 * @param $phpCode Unmarked PHP code
655 * @return $markedCode Marked PHP code
656 * @throws InvalidArgumentException If a paramter has an invalid value
658 public function markupCode (string $phpCode) {
660 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: phpCode=%s - CALLED!', $phpCode));
661 if (empty($phpCode)) {
663 throw new InvalidArgumentException('Parameter "phpCode" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
670 $errorArray = error_get_last();
672 // Init the code with error message
673 if (is_array($errorArray)) {
675 $markedCode = sprintf('<div id="error_header">File: <span id="error_data">%s</span>, Line: <span id="error_data">%s</span>, Message: <span id="error_data">%s</span>, Type: <span id="error_data">%s</span></div>',
676 basename($errorArray['file']),
678 $errorArray['message'],
683 // Add line number to the code
684 foreach (explode(chr(10), $phpCode) as $lineNo => $code) {
686 $markedCode .= sprintf('<span id="code_line">%s</span>: %s' . PHP_EOL,
688 htmlentities($code, ENT_QUOTES)
697 * "Getter" for databse entry
699 * @return $entry An array with database entries
700 * @throws NullPointerException If the database result is not found
701 * @throws InvalidDatabaseResultException If the database result is invalid
702 * @deprecated Monolithic method, should be moved to proper classes
704 protected final function getDatabaseEntry () {
705 // This method is deprecated
706 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: CALLED!');
707 $this->deprecationWarning('Monolithic method, should be moved to proper classes');
709 // Is there an instance?
710 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: this->resultInstance[]=%s', gettype($this->getResultInstance())));
711 if (!$this->getResultInstance() instanceof SearchableResult) {
712 // Throw an exception here
713 throw new NullPointerException($this, FrameworkInterface::EXCEPTION_IS_NULL_POINTER);
717 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: Invoking this->resultInstance->rewind() ...');
718 $this->getResultInstance()->rewind();
720 // Do we have an entry?
721 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: this->resultInstance->isValid()=%d', intval($this->getResultInstance()->isValid())));
722 if ($this->getResultInstance()->valid() === false) {
723 // @TODO Move the constant to e.g. BaseDatabaseResult when there is a non-cached database result available
724 throw new InvalidDatabaseResultException(array($this, $this->getResultInstance()), CachedDatabaseResult::EXCEPTION_INVALID_DATABASE_RESULT);
728 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: Invoking this->resultInstance->next() ...');
729 $this->getResultInstance()->next();
732 $entry = $this->getResultInstance()->current();
735 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: entry[]=%s - EXIT!', gettype($entry)));
740 * Getter for field name
742 * @param $fieldName Field name which we shall get
743 * @return $fieldValue Field value from the user
744 * @throws NullPointerException If the result instance is null
745 * @throws InvalidArgumentException If a parameter is not valid
746 * @deprecated Monolithic method, should be moved to proper classes
748 public final function getField (string $fieldName) {
750 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: fieldName=%s - CALLED!', $fieldName));
751 if (empty($fieldName)) {
753 throw new InvalidArgumentException('Parameter "fieldName" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
756 // This method is deprecated
757 $this->deprecationWarning('Monolithic method, should be moved to proper classes');
759 // Default field value
762 // Get result instance
763 $resultInstance = $this->getResultInstance();
765 // Is this instance null?
766 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: resultInstance[]=%s', gettype($resultInstance)));
767 if (is_null($resultInstance)) {
768 // Then the user instance is no longer valid (expired cookies?)
769 throw new NullPointerException($this, FrameworkInterface::EXCEPTION_IS_NULL_POINTER);
773 $fieldArray = $resultInstance->current();
775 // Convert dashes to underscore
776 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: fieldArray()=%d', count($fieldArray)));
777 $fieldName2 = StringUtils::convertDashesToUnderscores($fieldName);
779 // Does the field exist?
780 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: fieldName2=%s', $fieldName2));
781 if ($this->isFieldSet($fieldName)) {
783 $fieldValue = $fieldArray[$fieldName2];
784 } elseif (FrameworkBootstrap::getConfigurationInstance()->isEnabled('developer_mode')) {
785 // Missing field entry, may require debugging
786 self::createDebugInstance(__CLASS__, __LINE__)->warningMessage('BASE-FRAMEWORK-SYSTEM: fieldArray<pre>=' . print_r($fieldArray, true) . '</pre>,fieldName=' . $fieldName . ' not found!');
788 // Missing field entry, may require debugging
789 self::createDebugInstance(__CLASS__, __LINE__)->warningMessage('BASE-FRAMEWORK-SYSTEM: fieldName=' . $fieldName . ' not found!');
793 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: fieldValue[]=%s - EXIT!', gettype($fieldValue)));
798 * Checks if given field is set
800 * @param $fieldName Field name to check
801 * @return $isSet Whether the given field name is set
802 * @throws NullPointerException If the result instance is null
803 * @throws InvalidArgumentException If a parameter is not valid
805 public function isFieldSet (string $fieldName) {
807 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: fieldName=%s - CALLED!', $fieldName));
808 if (empty($fieldName)) {
810 throw new InvalidArgumentException('Parameter "fieldName" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
813 // Get result instance
814 $resultInstance = $this->getResultInstance();
816 // Is this instance null?
817 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: resultInstance[]=%s', gettype($resultInstance)));
818 if (is_null($resultInstance)) {
819 // Then the user instance is no longer valid (expired cookies?)
820 throw new NullPointerException($this, FrameworkInterface::EXCEPTION_IS_NULL_POINTER);
824 $fieldArray = $resultInstance->current();
826 // Convert dashes to underscore
827 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: fieldArray()=%d,fieldName=%s - BEFORE!', count($fieldArray), $fieldName));
828 $fieldName = StringUtils::convertDashesToUnderscores($fieldName);
831 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: fieldName=%s - AFTER!', $fieldName));
832 $isset = isset($fieldArray[$fieldName]);
835 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: isset=%d - EXIT!', intval($isset)));
840 * Outputs a deprecation warning to the developer.
842 * @param $message The message we shall output to the developer
844 * @throws InvalidArgumentException If a paramter has an invalid value
845 * @todo Write a logging mechanism for productive mode
847 public function deprecationWarning (string $message) {
849 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: message=%s - CALLED!', $message));
850 if (empty($message)) {
852 throw new InvalidArgumentException('Parameter "message" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
855 // Is developer mode active?
856 if (FrameworkBootstrap::getConfigurationInstance()->isEnabled('developer_mode')) {
857 // Debug instance is there?
858 if (!is_null($this->getDebugInstance())) {
859 // Output stub message
860 self::createDebugInstance(__CLASS__, __LINE__)->warningMessage($message);
863 trigger_error($message . "<br />\n");
867 // @TODO Finish this part!
868 DebugMiddleware::getSelfInstance()->partialStub('Developer mode inactive. Message:' . $message);
872 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: EXIT!');
876 * Checks whether the given PHP extension is loaded
878 * @param $phpExtension The PHP extension we shall check
879 * @return $isLoaded Whether the PHP extension is loaded
880 * @throws InvalidArgumentException If a parameter is not valid
882 public final function isPhpExtensionLoaded (string $phpExtension) {
884 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: phpExtension=%s - CALLED!', $phpExtension));
885 if (empty($phpExtension)) {
887 throw new InvalidArgumentException('Parameter "phpExtension" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
891 $isLoaded = in_array($phpExtension, get_loaded_extensions());
894 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: isLoaded=%d - EXIT!', intval($isLoaded)));
899 * "Getter" as a time() replacement but with milliseconds. You should use this
900 * method instead of the encapsulated getimeofday() function.
902 * @return $milliTime Timestamp with milliseconds
904 public function getMilliTime () {
905 // Get the time of day as float
906 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: CALLED!');
907 $milliTime = gettimeofday(true);
910 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: milliTime=%s - EXIT!', $milliTime));
915 * Idles (sleeps) for given milliseconds
917 * @return $hasSlept Whether it goes fine
918 * @throws InvalidArgumentException If a parameter is not valid
920 public function idle (int $milliSeconds) {
922 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: milliSeconds=%s - CALLED!', $milliSeconds));
923 if ($milliSeconds < 1) {
925 throw new InvalidArgumentException(sprintf('milliSeconds=%d are not a reasonable value to idle', $milliSeconds));
928 // Sleep is fine by default
931 // Idle so long with found function
932 if (function_exists('time_sleep_until')) {
933 // Get current time and add idle time
934 $sleepUntil = $this->getMilliTime() + abs($milliSeconds) / 1000;
936 // New PHP 5.1.0 function found, ignore errors
937 $hasSlept = @time_sleep_until($sleepUntil);
940 * My Sun station doesn't have that function even with latest PHP
943 usleep($milliSeconds * 1000);
947 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: hasSlept=%d - EXIT!', intval($hasSlept)));
952 * Checks whether the given encoded data was encoded with Base64
954 * @param $encodedData Encoded data we shall check
955 * @return $isBase64 Whether the encoded data is Base64
956 * @throws InvalidArgumentException If a parameter is not valid
958 protected function isBase64Encoded (string $encodedData) {
960 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: encodedData=%s - CALLED!', $encodedData));
961 if (empty($encodedData)) {
963 throw new InvalidArgumentException('Parameter "encodedData" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
967 $isBase64 = (@base64_decode($encodedData, true) !== false);
970 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: isBase64=%d - EXIT!', intval($isBase64)));
975 * Getter for startup time in miliseconds
977 * @return $startupTime Startup time in miliseconds
979 protected function getStartupTime () {
980 return self::$startupTime;
984 * "Getter" for a printable currently execution time in nice braces
986 * @return $executionTime Current execution time in nice braces
988 protected function getPrintableExecutionTime () {
989 // Calculate execution time and pack it in nice braces
990 $executionTime = sprintf('[ %01.5f ] ', (microtime(true) - $this->getStartupTime()));
993 return $executionTime;
997 * Determines if an element is set in the generic array
999 * @param $keyGroup Main group for the key
1000 * @param $subGroup Sub group for the key
1001 * @param $key Key to check
1002 * @param $element Element to check
1003 * @return $isset Whether the given key is set
1004 * @throws InvalidArgumentException If a parameter is not valid
1006 protected final function isGenericArrayElementSet (string $keyGroup, string $subGroup, string $key, string $element) {
1008 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s,element=%s - CALLED!', $keyGroup, $subGroup, $key, $element));
1009 if (empty($keyGroup)) {
1011 throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1012 } elseif (empty($subGroup)) {
1014 throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1015 } elseif (empty($key)) {
1017 throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1018 } elseif ($element === '') {
1020 throw new InvalidArgumentException('Parameter "element" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1024 $isset = isset($this->genericArray[$keyGroup][$subGroup][$key][$element]);
1027 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: isset=%d - EXIT!', intval($isset)));
1031 * Determines if a key is set in the generic array
1033 * @param $keyGroup Main group for the key
1034 * @param $subGroup Sub group for the key
1035 * @param $key Key to check
1036 * @return $isset Whether the given key is set
1037 * @throws InvalidArgumentException If a parameter is not valid
1039 protected final function isGenericArrayKeySet (string $keyGroup, string $subGroup, string $key) {
1041 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s - CALLED!', $keyGroup, $subGroup, $key));
1042 if (empty($keyGroup)) {
1044 throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1045 } elseif (empty($subGroup)) {
1047 throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1048 } elseif (empty($key)) {
1050 throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1054 $isset = isset($this->genericArray[$keyGroup][$subGroup][$key]);
1057 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: isset=%d - EXIT!', intval($isset)));
1062 * Determines if a group is set in the generic array
1064 * @param $keyGroup Main group
1065 * @param $subGroup Sub group
1066 * @return $isset Whether the given group is set
1067 * @throws InvalidArgumentException If a parameter is not valid
1069 protected final function isGenericArrayGroupSet (string $keyGroup, string $subGroup) {
1071 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s - CALLED!', $keyGroup, $subGroup));
1072 if (empty($keyGroup)) {
1074 throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1075 } elseif (empty($subGroup)) {
1077 throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1081 $isset = isset($this->genericArray[$keyGroup][$subGroup]);
1084 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: isset=%d - EXIT!', intval($isset)));
1089 * Getter for sub key group
1091 * @param $keyGroup Main key group
1092 * @param $subGroup Sub key group
1093 * @return $array An array with all array elements
1094 * @throws InvalidArgumentException If a parameter is not valid
1095 * @throws BadMethodCallException If key/sub group isn't there but this method is invoked
1097 protected final function getGenericSubArray (string $keyGroup, string $subGroup) {
1099 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s - CALLED!', $keyGroup, $subGroup));
1100 if (empty($keyGroup)) {
1102 throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1103 } elseif (empty($subGroup)) {
1105 throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1106 } elseif (!$this->isGenericArrayGroupSet($keyGroup, $subGroup)) {
1107 // No, then abort here
1108 throw new BadMethodCallException(sprintf('keyGroup=%s,subGroup=%s not found.', $keyGroup, $subGroup), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
1112 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: this->genericArray[%s][%s][]=%s - EXIT!', $keyGroup, $subGroup, gettype($this->genericArray[$keyGroup][$subGroup])));
1113 return $this->genericArray[$keyGroup][$subGroup];
1117 * Unsets a given key in generic array
1119 * @param $keyGroup Main group for the key
1120 * @param $subGroup Sub group for the key
1121 * @param $key Key to unset
1123 * @throws InvalidArgumentException If a parameter is not valid
1125 protected final function unsetGenericArrayKey (string $keyGroup, string $subGroup, string $key) {
1127 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s - CALLED!', $keyGroup, $subGroup, $key));
1128 if (empty($keyGroup)) {
1130 throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1131 } elseif (empty($subGroup)) {
1133 throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1134 } elseif (empty($key)) {
1136 throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1140 unset($this->genericArray[$keyGroup][$subGroup][$key]);
1143 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: EXIT!');
1147 * Unsets a given element in generic array
1149 * @param $keyGroup Main group for the key
1150 * @param $subGroup Sub group for the key
1151 * @param $key Key to unset
1152 * @param $element Element to unset
1154 * @throws InvalidArgumentException If a parameter is not valid
1156 protected final function unsetGenericArrayElement (string $keyGroup, string $subGroup, string $key, string $element) {
1158 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s,element=%s - CALLED!', $keyGroup, $subGroup, $key, $element));
1159 if (empty($keyGroup)) {
1161 throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1162 } elseif (empty($subGroup)) {
1164 throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1165 } elseif (empty($key)) {
1167 throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1168 } elseif ($element === '') {
1170 throw new InvalidArgumentException('Parameter "element" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1174 unset($this->genericArray[$keyGroup][$subGroup][$key][$element]);
1177 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: EXIT!');
1181 * Append a string to a given generic array key
1183 * @param $keyGroup Main group for the key
1184 * @param $subGroup Sub group for the key
1185 * @param $key Key to unset
1186 * @param $value Value to add/append
1188 * @throws InvalidArgumentException If a parameter is not valid
1190 protected final function appendStringToGenericArrayKey (string $keyGroup, string $subGroup, string $key, string $value, string $appendGlue = '') {
1192 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s,value=%s,appendGlue=%s - CALLED!', $keyGroup, $subGroup, $key, $value, $appendGlue));
1193 if (empty($keyGroup)) {
1195 throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1196 } elseif (empty($subGroup)) {
1198 throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1199 } elseif (empty($key)) {
1201 throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1204 // Is it already there?
1205 if ($this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
1207 $this->genericArray[$keyGroup][$subGroup][$key] .= $appendGlue . $value;
1210 $this->genericArray[$keyGroup][$subGroup][$key] = $value;
1214 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: EXIT!');
1218 * Append a string to a given generic array element
1220 * @param $keyGroup Main group for the key
1221 * @param $subGroup Sub group for the key
1222 * @param $key Key to unset
1223 * @param $element Element to check
1224 * @param $value Value to add/append
1226 * @throws InvalidArgumentException If a parameter is not valid
1228 protected final function appendStringToGenericArrayElement (string $keyGroup, string $subGroup, string $key, string $element, string $value, string $appendGlue = '') {
1230 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s,element=%s,value=%s,appendGlue=%s - CALLED!', $keyGroup, $subGroup, $key, $element, $value, $appendGlue));
1231 if (empty($keyGroup)) {
1233 throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1234 } elseif (empty($subGroup)) {
1236 throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1237 } elseif (empty($key)) {
1239 throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1240 } elseif ($element === '') {
1242 throw new InvalidArgumentException('Parameter "element" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1245 // Is it already there?
1246 if ($this->isGenericArrayElementSet($keyGroup, $subGroup, $key, $element)) {
1248 $this->genericArray[$keyGroup][$subGroup][$key][$element] .= $appendGlue . $value;
1251 $this->setGenericArrayElement($keyGroup, $subGroup, $key, $element, $value);
1255 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: EXIT!');
1259 * Initializes given generic array group
1261 * @param $keyGroup Main group for the key
1262 * @param $subGroup Sub group for the key
1263 * @param $key Key to use
1264 * @param $forceInit Optionally force initialization
1266 * @throws InvalidArgumentException If a parameter is not valid
1267 * @throws BadMethodCallException If key/sub group has already been initialized
1269 protected final function initGenericArrayGroup (string $keyGroup, string $subGroup, bool $forceInit = false) {
1271 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,forceInit=%d - CALLED!', $keyGroup, $subGroup, intval($forceInit)));
1272 if (empty($keyGroup)) {
1274 throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1275 } elseif (empty($subGroup)) {
1277 throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1278 } elseif (($forceInit === false) && ($this->isGenericArrayGroupSet($keyGroup, $subGroup))) {
1279 // Already initialized
1280 throw new BadMethodCallException(sprintf('keyGroup=%s,subGroup=%s already initialized.', $keyGroup, $subGroup), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
1284 $this->genericArray[$keyGroup][$subGroup] = [];
1287 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: EXIT!');
1291 * Initializes given generic array key
1293 * @param $keyGroup Main group for the key
1294 * @param $subGroup Sub group for the key
1295 * @param $key Key to use
1296 * @param $forceInit Optionally force initialization
1298 * @throws InvalidArgumentException If a parameter is not valid
1299 * @throws BadMethodCallException If key/sub group has already been initialized
1301 protected final function initGenericArrayKey (string $keyGroup, string $subGroup, string $key, bool $forceInit = false) {
1303 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s,forceInit=%d - CALLED!', $keyGroup, $subGroup, $key, intval($forceInit)));
1304 if (empty($keyGroup)) {
1306 throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1307 } elseif (empty($subGroup)) {
1309 throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1310 } elseif (empty($key)) {
1312 throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1313 } elseif (($forceInit === false) && ($this->isGenericArrayKeySet($keyGroup, $subGroup, $key))) {
1314 // Already initialized
1315 throw new BadMethodCallException(sprintf('keyGroup=%s,subGroup=%s,key[%s]=%s already initialized.', $keyGroup, $subGroup, gettype($key), $key), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
1319 $this->genericArray[$keyGroup][$subGroup][$key] = [];
1322 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: EXIT!');
1326 * Initializes given generic array element
1328 * @param $keyGroup Main group for the key
1329 * @param $subGroup Sub group for the key
1330 * @param $key Key to use
1331 * @param $element Element to use
1332 * @param $forceInit Optionally force initialization
1334 * @throws InvalidArgumentException If a parameter is not valid
1335 * @throws BadMethodCallException If key/sub group isn't there but this method is invoked
1337 protected final function initGenericArrayElement (string $keyGroup, string $subGroup, string $key, string $element, bool $forceInit = false) {
1339 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s,element=%s,forceInit=%d - CALLED!', $keyGroup, $subGroup, $key, $element, intval($forceInit)));
1340 if (empty($keyGroup)) {
1342 throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1343 } elseif (empty($subGroup)) {
1345 throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1346 } elseif (empty($key)) {
1348 throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1349 } elseif ($element === '') {
1351 throw new InvalidArgumentException('Parameter "element" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1352 } elseif (($forceInit === false) && ($this->isGenericArrayElementSet($keyGroup, $subGroup, $key, $element))) {
1353 // Already initialized
1354 throw new BadMethodCallException(sprintf('keyGroup=%s,subGroup=%s,key[%s]=%s,element[%s]=%s already initialized.', $keyGroup, $subGroup, gettype($key), $key, gettype($element), $element), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
1358 $this->genericArray[$keyGroup][$subGroup][$key][$element] = [];
1361 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: EXIT!');
1365 * Pushes an element to a generic key. If the key isn't found, it will be initialized.
1367 * @param $keyGroup Main group for the key
1368 * @param $subGroup Sub group for the key
1369 * @param $key Key to use
1370 * @param $value Value to add/append
1371 * @return $count Number of array elements
1372 * @throws InvalidArgumentException If a parameter is not valid
1374 protected final function pushValueToGenericArrayKey (string $keyGroup, string $subGroup, string $key, $value) {
1376 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s,value[]=%s - CALLED!', $keyGroup, $subGroup, $key, gettype($value)));
1377 if (empty($keyGroup)) {
1379 throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1380 } elseif (empty($subGroup)) {
1382 throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1383 } elseif (empty($key)) {
1385 throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1386 } elseif (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
1388 $this->initGenericArrayKey($keyGroup, $subGroup, $key);
1392 $count = array_push($this->genericArray[$keyGroup][$subGroup][$key], $value);
1395 //* DEBUG: */ print(__METHOD__ . ': genericArray=' . print_r($this->genericArray[$keyGroup][$subGroup][$key], true));
1396 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: count=%d - EXIT!', $count));
1401 * Pushes an element to a generic array element. If the key isn't found, it will be initialized.
1403 * @param $keyGroup Main group for the key
1404 * @param $subGroup Sub group for the key
1405 * @param $key Key to use
1406 * @param $element Element to check
1407 * @param $value Value to add/append
1408 * @return $count Number of array elements
1409 * @throws InvalidArgumentException If a parameter is not valid
1411 protected final function pushValueToGenericArrayElement (string $keyGroup, string $subGroup, string $key, string $element, $value) {
1413 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s,element=%s,value[]=%s - CALLED!', $keyGroup, $subGroup, $key, $element, gettype($value)));
1414 if (empty($keyGroup)) {
1416 throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1417 } elseif (empty($subGroup)) {
1419 throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1420 } elseif (empty($key)) {
1422 throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1423 } elseif ($element === '') {
1425 throw new InvalidArgumentException('Parameter "element" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1426 } elseif (!$this->isGenericArrayElementSet($keyGroup, $subGroup, $key, $element)) {
1428 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: Invoking this->initGenericArrayElement(%s,%s,%s,%s) ...', $keyGroup, $subGroup, $key, $element));
1429 $this->initGenericArrayElement($keyGroup, $subGroup, $key, $element);
1433 $count = array_push($this->genericArray[$keyGroup][$subGroup][$key][$element], $value);
1436 //* DEBUG: */ print(__METHOD__ . ': genericArray=' . print_r($this->genericArray[$keyGroup][$subGroup][$key], true));
1437 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: count=%d - EXIT!', $count));
1442 * Pops an element from a generic group
1444 * @param $keyGroup Main group for the key
1445 * @param $subGroup Sub group for the key
1446 * @param $key Key to unset
1447 * @return $value Last "popped" value
1448 * @throws InvalidArgumentException If a parameter is not valid
1449 * @throws BadMethodCallException If key/sub group isn't there but this method is invoked
1451 protected final function popGenericArrayElement (string $keyGroup, string $subGroup, string $key) {
1453 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s - CALLED!', $keyGroup, $subGroup, $key));
1454 if (empty($keyGroup)) {
1456 throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1457 } elseif (empty($subGroup)) {
1459 throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1460 } elseif (empty($key)) {
1462 throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1463 } elseif (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
1465 throw new BadMethodCallException(sprintf('keyGroup=%s,subGroup=%s,key[%s]=%s not found.', $keyGroup, $subGroup, gettype($key), $key), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
1469 $value = array_pop($this->genericArray[$keyGroup][$subGroup][$key]);
1472 //* DEBUG: */ print(__METHOD__ . ': genericArray=' . print_r($this->genericArray[$keyGroup][$subGroup][$key], true));
1473 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: value[]=%s - EXIT!', gettype($value)));
1478 * Shifts an element from a generic group
1480 * @param $keyGroup Main group for the key
1481 * @param $subGroup Sub group for the key
1482 * @param $key Key to unset
1483 * @return $value Last "shifted" value
1484 * @throws InvalidArgumentException If a parameter is not valid
1485 * @throws BadMethodCallException If key/sub group isn't there but this method is invoked
1487 protected final function shiftGenericArrayElement (string $keyGroup, string $subGroup, string $key) {
1489 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s - CALLED!', $keyGroup, $subGroup, $key));
1490 if (empty($keyGroup)) {
1492 throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1493 } elseif (empty($subGroup)) {
1495 throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1496 } elseif (empty($key)) {
1498 throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1499 } elseif (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
1501 throw new BadMethodCallException(sprintf('keyGroup=%s,subGroup=%s,key[%s]=%s not found.', $keyGroup, $subGroup, gettype($key), $key), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
1505 $value = array_shift($this->genericArray[$keyGroup][$subGroup][$key]);
1508 //* DEBUG: */ print(__METHOD__ . ': genericArray=' . print_r($this->genericArray[$keyGroup][$subGroup][$key], true));
1509 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: value[]=%s - EXIT!', gettype($value)));
1514 * Count generic array group
1516 * @param $keyGroup Main group for the key
1517 * @return $count Count of given group
1518 * @throws InvalidArgumentException If a parameter is not valid
1519 * @throws BadMethodCallException If key group isn't there but this method is invoked
1521 protected final function countGenericArray (string $keyGroup) {
1523 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s - CALLED!', $keyGroup));
1524 if (empty($keyGroup)) {
1526 throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1527 } elseif (!isset($this->genericArray[$keyGroup])) {
1529 throw new BadMethodCallException(sprintf('keyGroup=%s not found.', $keyGroup), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
1533 $count = count($this->genericArray[$keyGroup]);
1536 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: count=%d - EXIT!', $count));
1541 * Count generic array sub group
1543 * @param $keyGroup Main group for the key
1544 * @param $subGroup Sub group for the key
1545 * @return $count Count of given group
1546 * @throws InvalidArgumentException If a parameter is not valid
1547 * @throws BadMethodCallException If key/sub group isn't there but this method is invoked
1549 protected final function countGenericArrayGroup (string $keyGroup, string $subGroup) {
1551 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s - CALLED!', $keyGroup, $subGroup));
1552 if (empty($keyGroup)) {
1554 throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1555 } elseif (empty($subGroup)) {
1557 throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1558 } elseif (!$this->isGenericArrayGroupSet($keyGroup, $subGroup)) {
1560 throw new BadMethodCallException(sprintf('keyGroup=%s,subGroup=%s not found.', $keyGroup, $subGroup), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
1564 $count = count($this->genericArray[$keyGroup][$subGroup]);
1567 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: count=%d - EXIT!', $count));
1572 * Count generic array elements
1574 * @param $keyGroup Main group for the key
1575 * @param $subGroup Sub group for the key
1576 * @param $key Key to count
1577 * @return $count Count of given key
1578 * @throws InvalidArgumentException If a parameter is not valid
1579 * @throws BadMethodCallException If key/sub group isn't there but this method is invoked
1581 protected final function countGenericArrayElements (string $keyGroup, string $subGroup, string $key) {
1583 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s - CALLED!', $keyGroup, $subGroup, $key));
1584 if (empty($keyGroup)) {
1586 throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1587 } elseif (empty($subGroup)) {
1589 throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1590 } elseif (empty($key)) {
1592 throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1593 } elseif (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
1595 throw new BadMethodCallException(sprintf('keyGroup=%s,subGroup=%s,key[%s]=%s not found.', $keyGroup, $subGroup, gettype($key), $key), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
1596 } elseif (!$this->isValidGenericArrayGroup($keyGroup, $subGroup)) {
1598 throw new BadMethodCallException(sprintf('keyGroup=%s,subGroup=%s is not a valid key/sub group.', $keyGroup, $subGroup), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
1602 $count = count($this->genericArray[$keyGroup][$subGroup][$key]);
1605 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: count=%d - EXIT!', $count));
1610 * Getter for whole generic group array
1612 * @param $keyGroup Key group to get
1613 * @return $array Whole generic array group
1614 * @throws InvalidArgumentException If a parameter is not valid
1615 * @throws BadMethodCallException If key/sub group isn't there but this method is invoked
1617 protected final function getGenericArray (string $keyGroup) {
1619 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s - CALLED!', $keyGroup));
1620 if (empty($keyGroup)) {
1622 throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1623 } elseif (!isset($this->genericArray[$keyGroup])) {
1625 throw new BadMethodCallException(sprintf('keyGroup=%s not found', $keyGroup), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
1629 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: this->genericArray[%s][]=%s - EXIT!', $keyGroup, gettype($this->genericArray[$keyGroup])));
1630 return $this->genericArray[$keyGroup];
1634 * Setter for generic array key
1636 * @param $keyGroup Key group to get
1637 * @param $subGroup Sub group for the key
1638 * @param $key Key to unset
1639 * @param $value Mixed value from generic array element
1641 * @throws InvalidArgumentException If a parameter is not valid
1642 * @throws BadMethodCallException If key/sub group isn't there but this method is invoked
1644 protected final function setGenericArrayKey (string $keyGroup, string $subGroup, string $key, $value) {
1646 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s,value[]=%s - CALLED!', $keyGroup, $subGroup, $key, gettype($value)));
1647 if (empty($keyGroup)) {
1649 throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1650 } elseif (empty($subGroup)) {
1652 throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1653 } elseif (empty($key)) {
1655 throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1656 } elseif (!$this->isValidGenericArrayGroup($keyGroup, $subGroup)) {
1658 throw new BadMethodCallException(sprintf('keyGroup=%s,subGroup=%s not found', $keyGroup), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
1662 $this->genericArray[$keyGroup][$subGroup][$key] = $value;
1665 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: EXIT!');
1669 * Getter for generic array key
1671 * @param $keyGroup Key group to get
1672 * @param $subGroup Sub group for the key
1673 * @param $key Key to unset
1674 * @return $value Mixed value from generic array element
1675 * @throws InvalidArgumentException If a parameter is not valid
1676 * @throws BadMethodCallException If key/sub group isn't there but this method is invoked
1678 protected final function getGenericArrayKey (string $keyGroup, string $subGroup, string $key) {
1680 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s - CALLED!', $keyGroup, $subGroup, $key));
1681 if (empty($keyGroup)) {
1683 throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1684 } elseif (empty($subGroup)) {
1686 throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1687 } elseif (empty($key)) {
1689 throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1690 } elseif (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
1692 throw new BadMethodCallException(sprintf('keyGroup=%s,subGroup=%s,key[%s]=%s not found.', $keyGroup, $subGroup, gettype($key), $key), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
1696 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: this->genericArray[%s][%s][%s][]=%s - EXIT!', $keyGroup, $subGroup, $key, gettype($this->genericArray[$keyGroup][$subGroup][$key])));
1697 return $this->genericArray[$keyGroup][$subGroup][$key];
1701 * Sets a value in given generic array key/element
1703 * @param $keyGroup Main group for the key
1704 * @param $subGroup Sub group for the key
1705 * @param $key Key to set
1706 * @param $element Element to set
1707 * @param $value Value to set
1709 * @throws InvalidArgumentException If a parameter is not valid
1711 protected final function setGenericArrayElement (string $keyGroup, string $subGroup, string $key, string $element, $value) {
1713 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s,element=%s,value[]=%s - CALLED!', $keyGroup, $subGroup, $key, $element, gettype($value)));
1714 if (empty($keyGroup)) {
1716 throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1717 } elseif (empty($subGroup)) {
1719 throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1720 } elseif (empty($key)) {
1722 throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1723 } elseif ($element === '') {
1725 throw new InvalidArgumentException('Parameter "element" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1726 } elseif (!$this->isGenericArrayElementSet($keyGroup, $subGroup, $key, $element)) {
1728 $this->initGenericArrayElement($keyGroup, $subGroup, $key, $element);
1732 $this->genericArray[$keyGroup][$subGroup][$key][$element] = $value;
1735 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: EXIT!');
1739 * Getter for generic array element
1741 * @param $keyGroup Key group to get
1742 * @param $subGroup Sub group for the key
1743 * @param $key Key to look for
1744 * @param $element Element to look for
1745 * @return $value Mixed value from generic array element
1746 * @throws InvalidArgumentException If a parameter is not valid
1747 * @throws BadMethodCallException If key/sub group isn't there but this method is invoked
1749 protected final function getGenericArrayElement (string $keyGroup, string $subGroup, string $key, string $element) {
1751 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s,element=%s - CALLED!', $keyGroup, $subGroup, $key, $element));
1752 if (empty($keyGroup)) {
1754 throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1755 } elseif (empty($subGroup)) {
1757 throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1758 } elseif (empty($key)) {
1760 throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1761 } elseif ($element === '') {
1763 throw new InvalidArgumentException('Parameter "element" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1764 } elseif (!$this->isGenericArrayElementSet($keyGroup, $subGroup, $key, $element)) {
1766 throw new BadMethodCallException(sprintf('keyGroup=%s,subGroup=%s,key[%s]=%s,element[%s]=%s not found.', $keyGroup, $subGroup, gettype($key), $key, gettype($element), $element), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
1770 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: this->genericArray[%s][%s][%s][%s][]=%s - EXIT!', $keyGroup, $subGroup, $key, gettype($this->genericArray[$keyGroup][$subGroup][$key][$element])));
1771 return $this->genericArray[$keyGroup][$subGroup][$key][$element];
1775 * Checks if a given sub group is valid (array)
1777 * @param $keyGroup Key group to get
1778 * @param $subGroup Sub group for the key
1779 * @return $isValid Whether given sub group is valid
1780 * @throws InvalidArgumentException If a parameter is not valid
1782 protected final function isValidGenericArrayGroup (string $keyGroup, string $subGroup) {
1784 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s - CALLED!', $keyGroup, $subGroup));
1785 if (empty($keyGroup)) {
1787 throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1788 } elseif (empty($subGroup)) {
1790 throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1794 $isValid = (($this->isGenericArrayGroupSet($keyGroup, $subGroup)) && (is_array($this->getGenericSubArray($keyGroup, $subGroup))));
1797 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: isValid=%d - EXIT!', intval($isValid)));
1802 * Checks if a given key is valid (array)
1804 * @param $keyGroup Key group to get
1805 * @param $subGroup Sub group for the key
1806 * @param $key Key to check
1807 * @return $isValid Whether given sub group is valid
1809 protected final function isValidGenericArrayKey (string $keyGroup, string $subGroup, string $key) {
1811 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s - CALLED!', $keyGroup, $subGroup, $key));
1812 if (empty($keyGroup)) {
1814 throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1815 } elseif (empty($subGroup)) {
1817 throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1818 } elseif (empty($key)) {
1820 throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1824 $isValid = (($this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) && (is_array($this->getGenericArrayKey($keyGroup, $subGroup, $key))));
1827 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: isValid=%d - EXIT!', intval($isValid)));
1832 * Initializes the web output instance
1836 protected function initWebOutputInstance () {
1837 // Init web output instance
1838 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: CALLED!');
1839 $outputInstance = ObjectFactory::createObjectByConfiguredName('output_class');
1842 $this->setWebOutputInstance($outputInstance);
1845 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: EXIT!');
1849 * Translates boolean true to 'Y' and false to 'N'
1851 * @param $boolean Boolean value
1852 * @return $translated Translated boolean value
1854 public static final function translateBooleanToYesNo (bool $boolean) {
1856 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: boolean=%d - CALLED!', intval($boolean)));
1857 $translated = ($boolean === true) ? 'Y' : 'N';
1859 // ... and return it
1860 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: translated=%s - EXIT!', $translated));
1865 * Creates a full-qualified file name (FQFN) for given file name by adding
1866 * a configured temporary file path to it.
1868 * @param $infoInstance An instance of a SplFileInfo class
1869 * @return $fileInfoInstance An instance of a SplFileInfo class (temporary file)
1870 * @throw PathWriteProtectedException If the path in 'temp_file_path' is write-protected
1871 * @throws FileIoException If the file cannot be written
1873 protected static function createTempPathForFile (SplFileInfo $infoInstance) {
1875 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: infoInstance=%s - CALLED!', $infoInstance->__toString()));
1876 $basePath = FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('temp_file_path');
1878 // Is the path writeable?
1879 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: basePath=%s', $basePath));
1880 if (!is_writable($basePath)) {
1881 // Path is write-protected
1882 throw new PathWriteProtectedException($infoInstance, self::EXCEPTION_PATH_CANNOT_BE_WRITTEN);
1886 $fileInfoInstance = new SplFileInfo($basePath . DIRECTORY_SEPARATOR . $infoInstance->getBasename());
1889 if (!FrameworkBootstrap::isReachableFilePath($fileInfoInstance)) {
1891 throw new FileIoException($fileInfoInstance, self::EXCEPTION_FILE_NOT_REACHABLE);
1895 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: fileInfoInstance=%s - EXIT!', $fileInfoInstance->__toString()));
1896 return $fileInfoInstance;
1900 * "Getter" for a printable state name
1902 * @return $stateName Name of the node's state in a printable format
1903 * @throws BadMethodCallException If this instance doesn't have a callable getter for stateInstance
1904 * @todo Move this class away from this monolithic place (not whole class is monolithic)
1906 public final function getPrintableState () {
1907 // Check if getter is there
1908 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: CALLED!');
1909 if (!is_callable($this, 'getStateInstance')) {
1911 throw new BadMethodCallException(sprintf('this=%s has no callable getter for stateInstance', $this->__toString()), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
1914 // Default is 'null'
1915 $stateName = 'null';
1917 // Get the state instance
1918 $stateInstance = $this->getStateInstance();
1920 // Is it an instance of Stateable?
1921 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: stateInstance[]=%s', gettype($stateInstance)));
1922 if ($stateInstance instanceof Stateable) {
1923 // Then use that state name
1924 $stateName = $stateInstance->getStateName();
1928 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: stateName=%s - EXIT!', $stateName));