--- /dev/null
+<?php
+/**
+ * The application selector class.
+ *
+ * Please remember that this include file is being loaded *before* the class
+ * loader is loading classes from "exceptions", "interfaces" and "main"!
+ *
+ * @todo Extend a later BaseFrameworkApplication class
+ *
+ * @author Roland Haeder <roland __NOSPAM__ [at] __REMOVE_ME__ mxchange [dot] org>
+ * @version 0.1
+ */
+class ApplicationSelector extends BaseFrameworkSystem {
+ /**
+ * An ArrayObject for all found applications
+ */
+ private $foundApps = null;
+
+ /**
+ * An array object for all loaded application templates (selector_app-name.tpl)
+ */
+ private $loadedTemplates = null;
+
+ /**
+ * The application selector's own template engine handler
+ */
+ private $selectorTplEngine = null;
+
+ /**
+ * A list of items we shall ignore while reading from directories
+ */
+ private $dirIgnoreList = array(
+ ".",
+ "..",
+ ".htaccess"
+ );
+
+ /**
+ * The language instance for the template loader
+ */
+ private $langInstance = null;
+
+ /**
+ * The file I/O instance for the template loader
+ */
+ private $fileIOInstance = null;
+
+ /**
+ * The private constructor. No direct instances can be created from this.
+ *
+ * @return void
+ */
+ private function __construct() {
+ // Call parent constructor
+ parent::constructor(__CLASS__);
+
+ // Set description
+ $this->setPartDescr("Applikationswechsler");
+
+ // Create unique ID number
+ $this->createUniqueID();
+
+ // Remove system array and thousand seperator
+ $this->removeSystemArray();
+ $this->removeNumberFormaters();
+
+ // Initialize the array lists
+ $this->initializeAppsList();
+ $this->initializeTemplatesList();
+ }
+
+ /**
+ * Create a prepared instance of ApplicationSelector
+ *
+ * @param $langInstance The language sub-system: LanguageSystem
+ * @param $fileIOInstance The file I/O instance
+ * @return $selInstance An instance of ApplicationSelector
+ */
+ public static function createApplicationSelector ($langInstance, $fileIOInstance) {
+ // Get a new instance
+ $selInstance = new ApplicationSelector();
+
+ // Get all applications
+ $selInstance->readApplicationDirectory();
+
+ // Set language and file I/O instances
+ $selInstance->setLanguageInstance($langInstance);
+ $selInstance->setFileIOInstance($fileIOInstance);
+
+ // Return the prepared instance
+ return $selInstance;
+ }
+
+ /**
+ * Initialize the application list
+ *
+ * @return void
+ */
+ private function initializeAppsList () {
+ $this->foundApps = new FrameworkArrayObject();
+ }
+
+ /**
+ * Initialize the loaded templates list
+ *
+ * @return void
+ */
+ private function initializeTemplatesList () {
+ $this->loadedTemplates = new FrameworkArrayObject();
+ }
+
+ /**
+ * Private getter for language instance
+ *
+ * @return $langInstance An instance to the language sub-system
+ */
+ private function getLanguageInstance () {
+ return $this->langInstance;
+ }
+
+ /**
+ * Private getter for file IO instance
+ *
+ * @return $fileIOInstance An instance to the file I/O sub-system
+ */
+ private function getFileIOInstance () {
+ return $this->fileIOInstance;
+ }
+
+ /**
+ * Prepare the template engine (TemplateEngine by default) for a give
+ * application helper instance (ApplicationHelper by default).
+ *
+ * @param $appInstance An application helper instance
+ * @return $tplEngine The template engine instance
+ * @throws NullPointerException If the template engine could not
+ * be initialized
+ * @throws NoObjectException If $tplEngine is not an object
+ * @throws MissingMethodException If $tplEngine misses a required
+ * method 'loadWebTemplate()'
+ */
+ private function prepareTemplateEngine ($appInstance) {
+ // Generate FQFN for all application templates
+ $fqfn = sprintf("%s%s/%s/%s",
+ PATH,
+ $this->getConfigInstance()->readConfig("application_path"),
+ strtolower($appInstance->getAppShortName()),
+ $this->getConfigInstance()->readConfig("tpl_base_path")
+ );
+
+ // Initialize the template engine
+ $tplEngine = null;
+ $eval = sprintf("\$tplEngine = %s::create%s(
+ \"%s\",
+ \$this->getLanguageInstance(),
+ \$this->getFileIOInstance()
+);",
+ $this->getConfigInstance()->readConfig("tpl_engine"),
+ $this->getConfigInstance()->readConfig("tpl_engine"),
+ $fqfn
+ );
+
+ // Debug message
+ if ((!is_null($this->getDebugInstance())) && (defined('DEBUG_EVAL'))) {
+ $this->getDebugInstance()->output(sprintf("[%s:] Konstruierte PHP-Anweisung: <pre><em>%s</em></pre><br />\n",
+ $this->__toString(),
+ htmlentities($eval)
+ ));
+ }
+
+ // Run the command
+ @eval($eval);
+
+ // Is it a valid instance?
+ if (is_null($tplEngine)) {
+ // No class returned
+ throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
+ } elseif (!is_object($tplEngine)) {
+ // Not an object! ;-(
+ throw new NoObjectException($tplEngine, self::EXCEPTION_IS_NO_OBJECT);
+ } elseif (!method_exists($tplEngine, 'loadWebTemplate')) {
+ // Nope, so throw exception
+ throw new MissingMethodException(array($tplEngine, 'loadWebTemplate'), self::EXCEPTION_MISSING_METHOD);
+ }
+
+ // Return the prepared instance
+ return $tplEngine;
+ }
+
+ /**
+ * Load the init.php script of an application and append the application
+ * instance to $foundApps
+ *
+ * @param $initScript The FQFN of init.php
+ * @param $appName The application's Uni* name
+ * @return void
+ * @throws AppVarIsNotSetException If 'app' is not set
+ * @throws NullPointerException If 'app' is null
+ * @throws NoObjectException If 'app' is not an object
+ * @throws MissingMethodException If a required method is missing
+ */
+ private function loadInitScript ($initScript, $appName) {
+ // Is it a file and readable?
+ if ((is_file($initScript)) && (is_readable($initScript))) {
+ // Then include it
+ include ($initScript);
+
+ // We now should have $app re-defined!
+ if (!isset($app)) {
+ // This application shall not be loaded
+ return;
+ } elseif (is_null($app)) {
+ // The class instance is null
+ throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
+ } elseif (!is_object($app)) {
+ // Not an object
+ throw new NoObjectException($app, self::EXCEPTION_IS_NO_OBJECT);
+ } elseif (!method_exists($app, $this->getConfigInstance()->readConfig("entry_method"))) {
+ // Method not found!
+ throw new MissingMethodException(array($app, $this->getConfigInstance()->readConfig("entry_method")), self::EXCEPTION_MISSING_METHOD);
+ }
+
+ // Add the current instance to the list
+ $this->foundApps->append($app);
+
+ } // END - if ((is_file(...
+ }
+
+ /**
+ * Setter for the selector's template engine instance
+ *
+ * @param $tplEngine An instance of TemplateEngine
+ */
+ private function setSelectorTemplateEngine ($tplEngine) {
+ $this->selectorTplEngine = $tplEngine;
+ }
+
+ /**
+ * Getter for the selector's template engine instance
+ *
+ * @return $selectTplEngine The selector's template engine
+ */
+ private function getSelectorTemplateEngine () {
+ return $this->selectorTplEngine;
+ }
+
+ /**
+ * Getter for the $loadedTemplates array object
+ *
+ * @return $loadedTemplates An array object holding all loaded
+ * application templates
+ */
+ private function getLoadedTemplates () {
+ return $this->loadedTemplates;
+ }
+
+ /**
+ * Method for compatiblity with prepareTemplateEngine()
+ *
+ * @return $shortName This selector's short name
+ */
+ private function getAppShortName() {
+ $shortName = $this->getConfigInstance()->readConfig("selector_path");
+ return $shortName;
+ }
+
+ /**
+ * Add a directory/file to the ignore list
+ *
+ * @param $ignoreItem The file/directory we shall ignore
+ * @return void
+ */
+ public function addDirIgnoreList ($ignoreItem) {
+ // Cast and add it
+ $ignoreItem = (string) $ignoreItem;
+ $this->dirIgnoreList[] = $ignoreItem;
+ }
+
+ /**
+ * Setter for language instance
+ *
+ * @param $langInstance An instance to the language sub-system
+ * @return void
+ * @see LanguageSystem
+ */
+ public function setLanguageInstance (ManageableLanguage $langInstance) {
+ $this->langInstance = $langInstance;
+ }
+
+ /**
+ * Setter for file I/O instance
+ *
+ * @param $fileIOInstance An instance to the file I/O sub-system
+ * @return void
+ */
+ public function setFileIOInstance (FileIOHandler $fileIOInstance) {
+ $this->fileIOInstance = $fileIOInstance;
+ }
+
+ /**
+ * Read the base path for all applications (application/) and create a
+ * list of all found applications
+ *
+ * @return void
+ */
+ public function readApplicationDirectory () {
+ // Generate the base path for all applications
+ $appBasePath = sprintf("%s%s/",
+ PATH,
+ $this->getConfigInstance()->readConfig("application_path")
+ );
+
+ // Add the selector path to the ignore list
+ $this->addDirIgnoreList($this->getConfigInstance()->readConfig("selector_path"));
+
+ // Get a directory pointer for the application path
+ $dirInstance = FrameworkDirectoryPointer::createFrameworkDirectoryPointer($appBasePath);
+
+ // Backup and remove the 'app' from global name space
+ /*$appBackup = $app;
+ unset($app);*/
+
+ // Read all directories&files except some parts
+ while ($appName = $dirInstance->readDirectoryExcept($this->dirIgnoreList)) {
+ // Generate FQFN for the application name (or better directory name)
+ $fqfn = sprintf("%s%s", $appBasePath, $appName);
+
+ // Is this a readable directory? (files will be ignored silently)
+ if ((is_dir($fqfn)) && (is_readable($fqfn))) {
+ // Then get the init.php script for analyzing
+ $initScript = sprintf("%s/init%s", $fqfn, $this->getConfigInstance()->readConfig("php_extension"));
+
+ // Load the application's init.php script and append the
+ // application to the ArrayObject
+ $this->loadInitScript($initScript, $appName);
+
+ } // END - if ((is_dir(...
+
+ } // END - while
+
+ // Close directory pointer
+ $dirInstance->closeDirectory();
+
+ // Restore old 'app' from backup
+ //$app = $appBackup;
+ }
+
+ /**
+ * Load all templates for found applications in previous scan
+ *
+ * @return void
+ */
+ public function loadApplicationTemplates () {
+ // Iterate through all applications
+ for ($idx = $this->foundApps->getIterator(); $idx->valid(); $idx->next()) {
+ // Get current application
+ $appInstance = $idx->current();
+
+ // Prepare the template engine for the current template
+ $tplEngine = $this->prepareTemplateEngine($appInstance);
+
+ // Try to load the web template
+ $tplEngine->loadWebTemplate(sprintf("%s_%s",
+ $this->getConfigInstance()->readConfig("tpl_selector_prefix"),
+ strtolower($appInstance->getAppShortName())
+ ));
+
+ // Remember this template and the application for later usage
+ $this->loadedTemplates->append(array(
+ 'tpl_engine' => $tplEngine,
+ 'app_instance' => $appInstance
+ ));
+ }
+
+ // Re-initialize the application list to avoid double loading
+ $this->initializeAppsList();
+ }
+
+ /**
+ * Removes $dirIgnoreList from the object to save some memory
+ *
+ * @return void
+ */
+ public function removeDirIgnoreList () {
+ unset($this->dirIgnoreList);
+ }
+
+ /**
+ * Loads the selector's own main template. This step is not linking the
+ * application's templates into the main one.
+ *
+ * @return void
+ */
+ public function loadSelectorTemplate () {
+ // Prepare the template engine
+ $tplEngine = $this->prepareTemplateEngine($this);
+
+ // Load the selector's template
+ $tplEngine->loadCodeTemplate($this->getConfigInstance()->readConfig("selector_main_tpl"));
+
+ // Now store it in the class
+ $this->setSelectorTemplateEngine($tplEngine);
+ }
+
+ /**
+ * Inserts all loaded application templates into the selector's template
+ *
+ * @return void
+ * @throws NullPointerException If $curr is null
+ * @throws NoArrayException If $curr is not an array
+ * @throws InvalidArrayCountException If $curr contains an
+ * unexpected count of elements
+ * @throws MissingArrayElementsException If $curr is missing expected
+ * array elements
+ */
+ public function insertApplicationTemplates () {
+ // First prepare the instance
+ $tplEngine = $this->prepareTemplateEngine($this);
+
+ // Load template which shall later hold all application templates
+ $tplEngine->loadCodeTemplate($this->getConfigInstance()->readConfig("selector_apps_tpl"));
+
+ // Add all loaded application templates together
+ $dummy = "";
+ for ($idx = $this->getLoadedTemplates()->getIterator(); $idx->valid(); $idx->next()) {
+ // Get current item from array object
+ $curr = $idx->current();
+
+ // Do some sanity checks on the loaded item
+ if (is_null($curr)) {
+ // $curr is null
+ throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
+ } elseif (!is_array($curr)) {
+ // Not an array
+ throw new NoArrayException($curr, self::EXCEPTION_IS_NO_ARRAY);
+ } elseif (count($curr) != 2) {
+ // Not expected count of entries
+ throw new InvalidArrayCountException(array($this, "curr", count($curr), 2), self::EXCEPTION_ARRAY_HAS_INVALID_COUNT);
+ } elseif (!isset($curr['tpl_engine']) || (!isset($curr['app_instance']))) {
+ // Expected entries missing
+ throw new MissingArrayElementsException(array($this, "curr", array('tpl_engine', 'app_instance')), self::EXCEPTION_ARRAY_ELEMENTS_MISSING);
+ }
+ die("<pre>".print_r($curr, true)."</pre>");
+
+ } // END - for
+ }
+
+ /**
+ * Stub!
+ */
+ public function saveObjectToDatabase () {
+ $this->getDebugInstance()->output(sprintf("[%s:] Stub <strong>%s</strong> erreicht.",
+ $this->__toString(),
+ __FUNCTION__
+ ));
+ }
+}
+
+// [EOF]
+?>