]> git.mxchange.org Git - mailer.git/blobdiff - inc/loader/class_ClassLoader.php
0.3.0 inital import
[mailer.git] / inc / loader / class_ClassLoader.php
diff --git a/inc/loader/class_ClassLoader.php b/inc/loader/class_ClassLoader.php
new file mode 100644 (file)
index 0000000..faee2d4
--- /dev/null
@@ -0,0 +1,260 @@
+<?php
+/**
+ * This class loads class include files with a specific prefix and suffix
+ *
+ * @author     Roland Haeder <roland __NOSPAM__ [at] __REMOVE_ME__ mxchange [dot] org>
+ * @version    1.1
+ *
+ * ----------------------------------
+ * 1.1
+ *  - loadClasses rewritten to fix some notices
+ * 1.0
+ *  - Initial release
+ * ----------------------------------
+ */
+class ClassLoader {
+       /**
+        * Configuration array
+        */
+       private $cfg = array();
+
+       /**
+        * An ArrayObject for found classes
+        */
+       private $classes = null;
+
+       /**
+        * Suffix with extension for all class files
+        */
+       private $prefix = "class_";
+
+       /**
+        * Suffix with extension for all class files
+        */
+       private $suffix = ".php";
+
+       /**
+        * Length of the suffix. Will be overwritten later.
+        */
+       private $sufLen = 0;
+
+       /**
+        * Length of the prefix. Will be overwritten later.
+        */
+       private $preLen = 0;
+
+       /**
+        * A list for directory names (no leading/trailing slashes!) which not be scanned by the path scanner
+        * @see scanLocalPath
+        */
+       private $ignoreList = array();
+
+       /**
+        * An ArrayList object for include directories
+        */
+       private $dirList = null;
+
+       /**
+        * Debug this class loader? (true = yes, false = no)
+        */
+       private $debug = false;
+
+       /**
+        * Counter for scanned directories (debug output)
+        */
+       private $dirCnt = 0;
+
+       /**
+        * Counter for loaded classes (debug output)
+        */
+       private $classCnt = 0;
+
+       /**
+        * Instance of this class
+        */
+       private static $thisInstance = null;
+
+       /**
+        * The *public* constructor
+        *
+        * @param               $cfgInstance            Configuration class instance
+        * @return      void
+        */
+       public function __construct (FrameworkConfiguration $cfgInstance) {
+               // Init the array list
+               $this->dirList = new ArrayObject();
+
+               // Set suffix and prefix from configuration
+               $this->suffix = $cfgInstance->readConfig("class_suffix");
+               $this->prefix = $cfgInstance->readConfig("class_prefix");
+
+               // Estimate length of prefix and suffix for substr() function (cache)
+               $this->sufLen = strlen($this->suffix);
+               $this->preLen = strlen($this->prefix);
+
+               // Set configuration instance
+               $this->cfgInstance = $cfgInstance;
+
+               // Initialize the classes list
+               $this->classes = new ArrayObject();
+
+               // Set own instance
+               self::$thisInstance = $this;
+       }
+
+       /**
+        * Getter for an instance of this class
+        *
+        * @return      $thisInstance           An instance of this class
+        */
+       public final static function getInstance () {
+               return self::$thisInstance;
+       }
+
+       /**
+        * Scans recursively a local path for class files which must have a prefix and a suffix as given by $this->suffix and $this->prefix
+        *
+        * @param               $basePath               The relative base path to PATH constant for all classes
+        * @param               $ignoreList     An optional list (array or string) of directory names which shall be ignored
+        * @return      void
+        */
+       public function loadClasses ($basePath, $ignoreList = array() ) {
+               // Convert string to array
+               if (!is_array($ignoreList)) $ignoreList = array($ignoreList);
+
+               // Directories which our class loader ignores by default while
+               // deep-scanning the directory structure. See scanLocalPath() for
+               // details.
+               $ignoreList[] = ".";
+               $ignoreList[] = "..";
+               $ignoreList[] = ".htaccess";
+
+               // Keep it in class for later usage
+               $this->ignoreList = $ignoreList;
+
+               // Set base directory which holds all our classes, we should use an
+               // absolute path here so is_dir(), is_file() and so on will always
+               // find the correct files and dirs.
+               $basePath2 = realpath($basePath);
+
+               // If the basePath is false it is invalid
+               if ($basePath2 === false) {
+                       // TODO: Do not die here.
+                       die("Cannot read {$basePath} !");
+               } else {
+                       // Set base path
+                       $basePath = $basePath2;
+               }
+
+               // Load all super classes (backward, why ever this name... :-? )
+               // We don't support sub directories here...
+               $this->scanLocalPath($basePath);
+
+               // While there are directories in our list scan them for classes
+               $cnt = 0;
+               while ($cnt != $this->dirList->count()) {
+                       for ($idx = $this->dirList->getIterator(); $idx->valid(); $idx->next()) {
+                               // Get current path
+                               $currPath = $idx->current();
+
+                               // Remove the current entry or else this will lead into a infinite loop
+                               $this->dirList->offsetSet($idx->key(), "");
+
+                               // Scan the directory
+                               $this->scanLocalPath($currPath);
+                       }
+
+                       // Check if we can leave
+                       $cnt = 0;
+                       for ($idx = $this->dirList->getIterator(); $idx->valid(); $idx->next()) {
+                               if ($idx->current() == "") $cnt++;
+                       }
+               }
+       }
+
+       /**
+       * The local path scanner. A found class will be loaded immediately
+       * @param                $localPath      The local path which shall be recursively scanned for include files
+       * @return               void
+       */
+       private function scanLocalPath ($localPath) {
+               // Empty path names will be silently ignored
+               if (empty($localPath)) return;
+
+               // TODO: No dies here, mayybe this should be rewritten to throw an exception?
+               $dirInstance = FrameworkDirectoryPointer::createFrameworkDirectoryPointer($localPath);
+               while ($dirClass = $dirInstance->readDirectoryExcept($this->ignoreList)) {
+                       // We need the relative dir name as an array index some lines below
+                       $dirClass2 = $dirClass;
+
+                       // A nice replacement for a simple dot ;)
+                       $dirClass = sprintf("%s/%s", $localPath, $dirClass);
+
+                       // Is a readable file with configured prefix and suffix? All other
+                       // files will silently be ignored!
+                       //* DEBUG: */ print "Prefix=".$this->prefix."(".substr($dirClass2, 0 , $this->preLen).")\n";
+                       //* DEBUG: */ print "Suffix=".$this->suffix."(".substr($dirClass2, -$this->sufLen, $this->sufLen).")\n";
+                       //* DEBUG: */ print "ENTRY={$dirClass}\n";
+                       if (
+                          (is_file($dirClass))
+                       && (is_readable($dirClass))
+                       && (substr($dirClass2, 0 , $this->preLen) == $this->prefix)
+                       && (substr($dirClass2, -$this->sufLen, $this->sufLen) == $this->suffix)
+                       ) {
+                               // Class found so load it instantly
+                               //* DEBUG: */ print "CLASS={$dirClass}\n";
+                               $this->classes->append($dirClass);
+                               $this->classCnt++;
+                       } elseif (is_dir($dirClass) && !in_array($dirClass2, $this->ignoreList)) {
+                               // Directory found and added to list
+                               //* DEBUG: */ print "DIR={$dirClass}\n";
+                               if ($dirClass2 == "interfaces") {
+                                       $this->scanLocalPath($dirClass);
+                               } else {
+                                       $this->dirList->append($dirClass);
+                               }
+                               $this->dirCnt++;
+                       }
+                       //* DEBUG: */ print "LOOP!\n";
+               } // END - while
+
+               // Close directory handler
+               $dirInstance->closeDirectory();
+
+               // Output counter in debug mode
+               if (defined('DEBUG_MODE')) print(sprintf("[%s:] <strong>%d</strong> Klassendateien in <strong>%d</strong> Verzeichnissen gefunden und geladen.<br />\n",
+                       __CLASS__,
+                       $this->classCnt,
+                       $this->dirCnt
+               ));
+       }
+
+       /**
+        * Includes all found classes
+        * @return      void
+        */
+       public function includeAllClasses () {
+               if (is_object($this->classes)) {
+                       // Load all classes
+                       for ($idx = $this->classes->getIterator(); $idx->valid(); $idx->next()) {
+                               // Load current class
+                               //* DEBUG: */ print "Class=".$idx->current()."\n";
+                               require_once($idx->current());
+                       }
+
+                       // Re-initialize the classes list
+                       $this->classes = new ArrayObject();
+               }
+       }
+}
+
+// Initial load of core classes and the FrameworkDirectoryPointer class
+require_once(sprintf("%sinc/classes/interfaces/class_FrameworkInterface%s", PATH, FrameworkConfiguration::getInstance()->readConfig("php_extension")));
+require_once(sprintf("%sinc/classes/main/class_BaseFrameworkSystem%s", PATH, FrameworkConfiguration::getInstance()->readConfig("php_extension")));
+require_once(sprintf("%sinc/classes/main/io/class_FrameworkDirectoryPointer%s", PATH, FrameworkConfiguration::getInstance()->readConfig("php_extension")));
+
+// Initialize the class loader
+$loader = new ClassLoader(FrameworkConfiguration::getInstance());
+
+// [EOF]
+?>