--- /dev/null
+<?php
+/**
+ * The simulator system class is the super class of all other classes. This
+ * class handles saving of games etc.
+ */
+class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
+ /**
+ * The instance to the debug output handler (should be DebugConsoleOutput or DebugWebOutput)
+ *
+ * @see DebugConsoleOutput
+ * @see DebugWebOutput
+ */
+ private static $debug = null;
+
+ /**
+ * The instance to the web output handler (should be WebOutput)
+ *
+ * @see WebOutput
+ */
+ private static $webOutput = null;
+
+ /**
+ * The instance to the compression layer which should be CompressorChannel
+ */
+ private static $compressor = null;
+
+ /**
+ * The configuration instance which shall be FrameworkConfiguration
+ */
+ private static $cfgInstance = null;
+
+ /**
+ * The instance to the database layer which should be DatabaseConnection
+ */
+ private $dbInstance = null;
+
+ /**
+ * The real class name
+ */
+ private $realClass = "FrameworkSystem";
+
+ /**
+ * A human-readable description for this simulator part
+ */
+ private $partDescr = "Namenlose Framework-Einheit";
+
+ /**
+ * The unique ID string for identifying all type of classes
+ */
+ private $uniqueID = "";
+
+ /**
+ * Thousands seperator
+ */
+ private $thousands = "."; // German
+
+ /**
+ * Decimal seperator
+ */
+ private $decimals = ","; // German
+
+ /***********************
+ * Exception codes.... *
+ ***********************/
+
+ 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_DIRECTORY_POINTER = 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_NOT_CONSTRUCTABLE = 0x02d;
+
+ /**
+ * In the super constructor these system classes shall be ignored or else
+ * we would get an endless calling loop.
+ *
+ *--------------------------------------------------------------------*
+ * ATTENTION: IF YOU REMOVE ONE OF THEM YOU WILL SHOOT YOUR SERVER!!! *
+ *--------------------------------------------------------------------*
+ */
+ private $systemClasses = array(
+ "DebugMiddleware", // Debug middleware output sub-system
+ "DebugWebOutput", // Debug web output sub-system
+ "DebugConsoleOutput", // Debug console output sub-system
+ "DebugErrorLogOutput", // Debug error_log() output sub-system
+ "CompressorChannel", // Compressor sub-system
+ "FrameworkDirectoryPointer", // Directory handler sub-system
+ "NullCompressor", // Null compressor
+ "Bzip2Compressor", // BZIP2 compressor
+ "GzipCompressor", // GZIP compressor
+ "WebOutput", // Web output sub-system
+ );
+
+ /**
+ * Private super constructor
+ *
+ * @return void
+ */
+ private function __construct ($class) {
+ // Set real class
+ $this->setRealClass($class);
+ }
+
+ /**
+ * Destructor reached...
+ *
+ * @return void
+ */
+ public function __destruct() {
+ // Is this object already destroyed?
+ if ($this->__toString() != "DestructedObject") {
+ // Debug message
+ if ((defined('DEBUG_DESTRUCTOR')) && (is_object($this->getDebugInstance()))) {
+ $this->getDebugInstance()->output(sprintf("[%s:] Das Objekt <strong>%s</strong> wird zerstört.<br />\n",
+ __CLASS__, $this->__toString()
+ ));
+ }
+
+ // Destroy all informations about this class but keep some text about it alive
+ $this->setPartDescr(sprintf("Entferntes Objekt <em>%s</em>", $this->__toString()));
+ $this->setRealClass("DestructedObject");
+ $this->resetUniqueID();
+ } elseif ((defined('DEBUG_DESTRUCTOR')) && (is_object($this->getDebugInstance()))) {
+ // Already destructed object
+ $this->getDebugInstance()->output(sprintf("[%s:] Das Objekt <strong>%s</strong> wurde bereits zerstört.<br />\n",
+ __CLASS__, $this->__toString()
+ ));
+ }
+ }
+
+ /**
+ * The call method where all non-implemented methods end up
+ *
+ * @return void
+ */
+ public final function __call ($methodName, $args) {
+ // Implode all given arguments
+ $argsString = implode("|", $args);
+ if (empty($argsString)) $argsString = "NULL";
+
+ $this->getDebugInstance()->output(sprintf("[%s::%s] Stub! Args: %s",
+ $this->__toString(),
+ $methodName,
+ $argsString
+ ));
+
+ // Return nothing
+ return null;
+ }
+
+ /**
+ * Public constructor (for initializing things, etc.)
+ *
+ * @return void
+ */
+ public function constructor ($class) {
+ // Call constructor
+ $this->__construct($class);
+
+ // Get the current (singleton) configuration instance
+ $this->setConfigInstance(FrameworkConfiguration::createFrameworkConfiguration());
+
+ // Is the class weather debug nor compressor channel?
+ if (!in_array($class, $this->systemClasses)) {
+ // Initialize debug instance
+ if (is_null($this->getDebugInstance())) {
+ // Set the debug output system if it is not debug class ;)
+ $this->setDebugInstance(DebugMiddleware::createDebugMiddleware($this->getConfigInstance()->readConfig("debug_engine")));
+ }
+
+ // Initialize web instance
+ if (is_null($this->getWebOutputInstance())) {
+ // Generate the eval() command
+ $eval = sprintf("\$this->setWebOutputInstance(%s::create%s(\"%s\"));",
+ $this->getConfigInstance()->readConfig("web_engine"),
+ $this->getConfigInstance()->readConfig("web_engine"),
+ $this->getConfigInstance()->readConfig("web_content_type")
+ );
+
+ // Debug message
+ if ((defined('DEBUG_EVAL')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:] Konstruierte PHP-Anweisung: <pre><em>%s</em></pre><br />\n",
+ $this->__toString(),
+ htmlentities($eval)
+ ));
+
+ // Run the command
+ eval($eval);
+ }
+
+ // Initialize compressor channel
+ if (is_null($this->getCompressorChannel())) {
+ // Set the compressor channel
+ $this->setCompressorChannel(CompressorChannel::createCompressorChannel(sprintf("%s%s",
+ PATH,
+ $this->getConfigInstance()->readConfig("compressor_base_path")
+ )));
+ }
+
+ // Initialize database middleware
+ if (is_null($this->getDatabaseInstance())) {
+ // Get the middleware instance
+ $db = DatabaseConnection::getInstance();
+ if (is_object($db)) {
+ // Set the database middleware
+ $this->setDatabaseInstance($db);
+ }
+ }
+
+ // Debug output
+ if ((defined('DEBUG_SYSTEM')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] Alle Sub-Systeme sind initialisiert.<br />\n",
+ $this->__toString()
+ ));
+ }
+ }
+
+ /**
+ * Setter for language instance
+ *
+ * @param $configInstance The configuration instance which shall
+ * be FrameworkConfiguration
+ * @return void
+ */
+ public final function setConfigInstance (FrameworkConfiguration $configInstance) {
+ $this->cfgInstance = $configInstance;
+ if ((defined('DEBUG_SYSTEM')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] Konfigurations-Handler auf <strong>%s</strong> gesetzt.<br />\n",
+ $this->__toString(),
+ $configInstance->__toString()
+ ));
+ }
+
+ /**
+ * Getter for configuration instance
+ *
+ * @return $cfhInstance - Configuration instance
+ */
+ public final function getConfigInstance () {
+ if ((defined('DEBUG_SYSTEM')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] Konfigurations-Handler <strong>%s</strong> angefordert.<br />\n",
+ $this->__toString(),
+ $this->cfgInstance->__toString()
+ ));
+ return $this->cfgInstance;
+ }
+
+ /**
+ * Setter for debug instance
+ *
+ * @param $debugInstance The instance for debug output class
+ * @return void
+ */
+ public final function setDebugInstance (DebugMiddleware $debugInstance) {
+ self::$debug = $debugInstance;
+ if ((defined('DEBUG_SYSTEM')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] Debug-Handler auf <strong>%s</strong> gesetzt.<br />\n",
+ $this->__toString(),
+ $this->getDebugInstance()->__toString()
+ ));
+ }
+
+ /**
+ * Getter for debug instance
+ *
+ * @return $debug - Instance to class DebugConsoleOutput or DebugWebOutput
+ */
+ public final function getDebugInstance () {
+ return self::$debug;
+ }
+
+ /**
+ * Setter for web output instance
+ *
+ * @param $webInstance The instance for web output class
+ * @return void
+ */
+ public final function setWebOutputInstance (OutputStreamer $webInstance) {
+ self::$webOutput = $webInstance;
+ if ((defined('DEBUG_SYSTEM')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] Web-Handler auf <strong>%s</strong> gesetzt.<br />\n",
+ $this->__toString(),
+ $this->getWebOutputInstance()->__toString()
+ ));
+ }
+
+ /**
+ * Getter for web output instance
+ *
+ * @return $webOutput - Instance to class WebOutput
+ */
+ public final function getWebOutputInstance () {
+ return self::$webOutput;
+ }
+
+ /**
+ * Static setter for database instance
+ *
+ * @param $dbInstance The instance for the database connection
+ * (forced DatabaseConnection)
+ * @return void
+ */
+ public final function setDatabaseInstance (DatabaseConnection $dbInstance) {
+ if ((defined('DEBUG_SYSTEM')) && (is_object($dbInstance->getDebugInstance()))) $dbInstance->getDebugInstance()->output(sprintf("[%s:] Datenbankschicht gesetzt.<br />\n",
+ $dbInstance->__toString()
+ ));
+ $this->dbInstance = $dbInstance;
+ }
+
+ /**
+ * Getter for $realClass
+ *
+ * @return $realClass The name of the real class (not BaseFrameworkSystem)
+ */
+ public final function __toString () {
+ if ((defined('DEBUG_SYSTEM')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] __toString() erreicht.<br />\n",
+ $this->realClass
+ ));
+ return $this->realClass;
+ }
+
+ /**
+ * Setter for the real class name
+ *
+ * @param $realClass Class name (string)
+ * @return void
+ */
+ public final function setRealClass ($realClass) {
+ // Cast to string
+ $realClass = (string) $realClass;
+
+ // Set real class
+ $this->realClass = $realClass;
+ }
+
+ /**
+ * Generate unique ID from a lot entropy
+ *
+ * @return void
+ */
+ public final function createUniqueID () {
+ if ((defined('DEBUG_SYSTEM')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] createUniqueID aufgerufen.<br />\n",
+ $this->__toString()
+ ));
+
+ // Existiert noch keine?
+ if (empty($this->uniqueID)) {
+ if ((defined('DEBUG_SYSTEM')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] createUniqueID erzeugt neue Unique-ID.<br />\n",
+ $this->__toString()
+ ));
+
+ // Correct missing class name
+ $corrected = false;
+ if ($this->__toString() == "") {
+ $this->setRealClass(__CLASS__);
+ $corrected = true;
+ }
+
+ // Neue ID erstellen
+ $tempID = false;
+ while (true) {
+ // Generate a unique ID number
+ $tempID = $this->generateIdNumber();
+ $isUsed = false;
+
+ // Try to figure out if the ID number is not yet used
+ try {
+ if (is_object($this->getDatabaseInstance())) {
+ $isUsed = $this->getDatabaseInstance()->isUniqueIdUsed($tempID, true);
+ }
+ } catch (FrameworkException $e) {
+ // Catches all and ignores all ;-)
+ }
+
+ if (
+ (
+ $tempID !== false
+ ) && (
+ (
+ $this->getDatabaseInstance() === null
+ ) || (
+ (
+ is_object($this->getDatabaseInstance())
+ ) && (
+ !$isUsed
+ )
+ )
+ )
+ ) {
+ // Abort the loop
+ break;
+ }
+ }
+
+ // Debug message
+ if ((defined('DEBUG_SYSTEM')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] uniqueID ist auf <strong>%s</strong> gesetzt.<br />\n",
+ $this->__toString(),
+ $tempID
+ ));
+
+ // Apply the new ID
+ $this->setUniqueID($tempID);
+
+ // Revert maybe corrected class name
+ if ($corrected) {
+ $this->setRealClass("");
+ }
+
+ // Remove system classes if we are in a system class
+ if ((isset($this->systemClasses)) && (in_array($this->__toString(), $this->systemClasses))) {
+ // This may save some RAM...
+ $this->removeSystemArray();
+ }
+ }
+ }
+
+ /**
+ * Generates a new ID number for classes based from the class' real name,
+ * the description and some random data
+ *
+ * @return $tempID The new (temporary) ID number
+ */
+ private final function generateIdNumber () {
+ return sprintf("%s@%s",
+ $this->__toString(),
+ md5(sprintf("%s:%s:%s:%s:%s:%s",
+ $this->__toString(),
+ $this->getPartDescr(),
+ time(),
+ getenv('REMOTE_ADDR'),
+ getenv('SERVER_ADDR'),
+ mt_rand()
+ ))
+ );
+ }
+
+ /**
+ * Setter for unique ID
+ *
+ * @param $uniqueID The newly generated unique ID number
+ * @return void
+ */
+ private final function setUniqueID ($uniqueID) {
+ // Cast to string
+ $uniqueID = (string) $uniqueID;
+
+ // Debug message
+ if ((defined('DEBUG_SYSTEM')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] Unique-ID gesetzt auf <u>%s</u>.<br />\n",
+ $this->__toString(),
+ $uniqueID
+ ));
+
+ // Set the ID number
+ $this->uniqueID = $uniqueID;
+ }
+
+ /**
+ * Getter for unique ID
+ *
+ * @return $uniqueID The unique ID of this class
+ */
+ public final function getUniqueID () {
+ if ((defined('DEBUG_SYSTEM')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] Unique-ID angefordert.<br />\n",
+ $this->__toString()
+ ));
+ return $this->uniqueID;
+ }
+
+ /**
+ * Resets or recreates the unique ID number
+ *
+ * @return void
+ */
+ public final function resetUniqueID() {
+ // Sweet and simple... ;-)
+ $newUniqueID = $this->generateIdNumber();
+ if ((defined('DEBUG_SYSTEM')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] Unique-ID zurückgesetzt auf <u>%s</u>.<br />\n",
+ $this->__toString(),
+ $newUniqueID
+ ));
+ $this->setUniqueID($newUniqueID);
+ }
+
+ /**
+ * Getter for simulator description
+ *
+ * @return $partDescr The description of this simulation part
+ */
+ public final function getPartDescr () {
+ if ((defined('DEBUG_SYSTEM')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] getPartDescr erreicht.<br />\n",
+ $this->__toString()
+ ));
+ if (isset($this->partDescr)) {
+ return $this->partDescr;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Setter for simulation part description
+ *
+ * @param $partDescr The description as string for this simulation part
+ * @return void
+ */
+ public final function setPartDescr ($partDescr) {
+ $this->partDescr = (String) $partDescr;
+ if ((defined('DEBUG_SYSTEM')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] Teilbeschreibung wird auf <strong>%s</strong> gesetzt.<br />\n",
+ $this->__toString(),
+ $this->partDescr
+ ));
+ }
+
+ /**
+ * Validate if given object is the same as current
+ *
+ * @param $object An object instance for comparison with this class
+ * @return boolean The result of comparing both's unique ID
+ */
+ public final function equals ($object) {
+ if ((defined('DEBUG_SYSTEM')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] Ist <strong>%s</strong>=<strong>%s</strong>?<br />\n",
+ $this->__toString(),
+ $this->__toString(),
+ $object->__toString()
+ ));
+ return ($this->getUniqueID() == $object->getUniqueID());
+ }
+
+ /**
+ * Compare if both simulation part description and class name matches
+ * (shall be enougth)
+ *
+ * @param $itemInstance An object instance to an other class
+ * @return boolean The result of comparing class name simulation part description
+ */
+ public function itemMatches ($itemInstance) {
+ return (
+ ($this->__toString() == $itemInstance->__toString())
+ && ($this->getPartDescr() == $itemInstance->getPartDescr())
+ );
+ }
+
+ /**
+ * Compare class name of this and given class name
+ *
+ * @param $class The class name as string from the other class
+ * @return boolean The result of comparing both class names
+ */
+ public final function isClass ($class) {
+ if ((defined('DEBUG_SYSTEM')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] <strong>%s</strong>=<strong>%s</strong>?<br />\n",
+ $this->__toString(),
+ $this->__toString(),
+ $class
+ ));
+ return ($this->__toString() == $class);
+ }
+
+ /**
+ * Stub method (only real cabins shall override it)
+ *
+ * @return boolean false = is no cabin, true = is a cabin
+ */
+ public function isCabin () {
+ return false;
+ }
+
+ /**
+ * Stub method for tradeable objects
+ *
+ * @return boolean false = is not tradeable by the Merchant class,
+ * true = is a tradeable object
+ */
+ public function isTradeable () {
+ return false;
+ }
+
+ /**
+ * Formats computer generated price values into human-understandable formats
+ * with thousand and decimal seperators.
+ *
+ * @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 MissingDecimalsThousandsSeperatorException If decimals or
+ * thousands seperator
+ * 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 MissingDecimalsThousandsSeperatorException($this, self::EXCEPTION_ATTRIBUTES_ARE_MISSING);
+ }
+
+ // Cast the number
+ $value = (float) $value;
+ if (defined('DEBUG_CORE') && is_object($this->getDebugInstance())) $this->getDebugInstance()->output(sprintf("[%s:] <strong>%d</strong> wird umformatiert.<br />\n",
+ $this->__toString(),
+ $value
+ ));
+
+ // Reformat the US number
+ $price = sprintf("%s %s",
+ number_format($value, $decNum, $this->decimals, $this->thousands),
+ $currency
+ );
+
+ // Return as string...
+ return $price;
+ }
+
+ /**
+ * Removes number formating characters
+ *
+ * @return void
+ */
+ public final function removeNumberFormaters () {
+ if (defined('DEBUG_CORE') && is_object($this->getDebugInstance())) $this->getDebugInstance()->output(sprintf("[%s:] Zahlenumformatierungszeichen werden entfernt.<br />\n",
+ $this->__toString()
+ ));
+ unset($this->thousands);
+ unset($this->decimals);
+ }
+
+ /**
+ * Getter for database layer
+ *
+ * @return $dbInstance The database layer instance
+ */
+ public final function getDatabaseInstance () {
+ if (defined('DEBUG_CORE') && is_object($this->getDebugInstance())) $this->getDebugInstance()->output(sprintf("[%s:] Datenbank-Instanz <u>%s</u> angefordert.<br />\n",
+ $this->__toString(),
+ $this->dbInstance
+ ));
+ return $this->dbInstance;
+ }
+
+ /**
+ * Setter for compressor channel
+ *
+ * @param $compressorChannel An instance of CompressorChannel
+ * @return void
+ */
+ public final function setCompressorChannel (CompressorChannel $compressorChannel) {
+ self::$compressor = $compressorChannel;
+ }
+
+ /**
+ * Getter for compressor channel
+ *
+ * @return $compressor The compressor channel
+ */
+ public final function getCompressorChannel () {
+ return self::$compressor;
+ }
+
+ /**
+ * Remove the $systemClasses array from memory
+ *
+ * @return void
+ */
+ public final function removeSystemArray () {
+ unset($this->systemClasses);
+ }
+
+ /**
+ * Create a file name and path name from the object's unique ID number.
+ * The left part of the ID shall always be a valid class name and the
+ * right part an ID number.
+ *
+ * @return $pfn The file name with a prepended path name
+ * @throws NoArrayCreatedException If explode() fails to create an array
+ * @throws InvalidArrayCountException If the array contains less or
+ * more than two elements
+ */
+ public function getPathFileNameFromObject () {
+ // Get the main object's unique ID. We use this as a path/filename combination
+ $pathFile = $this->getUniqueID();
+
+ // Split it up in path and file name
+ $pathFile = explode("@", $pathFile);
+
+ // Are there two elements? Index 0 is the path, 1 the file name + global extension
+ if (!is_array($pathFile)) {
+ // No array found
+ throw new NoArrayCreatedException(array($this, "pathFile"), self::EXCEPTION_ARRAY_EXPECTED);
+ } elseif (count($pathFile) != 2) {
+ // Invalid ID returned!
+ throw new InvalidArrayCountException(array($this, "pathFile", count($pathFile), 2), self::EXCEPTION_ARRAY_HAS_INVALID_COUNT);
+ }
+
+ // Auto-append missing trailing slash
+ $pathFile[0] = $this->addMissingTrailingSlash($pathFile[0]);
+
+ // Create the file name and return it
+ $pfn = ($pathFile[0] . $pathFile[1]);
+ return $pfn;
+ }
+
+ /**
+ * 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 .= "/";
+ return $str;
+ }
+}
+
+// [EOF]
+?>