class_ClassLoader.php

Go to the documentation of this file.
00001 <?php
00033 class ClassLoader {
00037         private static $selfInstance = null;
00038 
00042         private $cfg = array();
00043 
00047         private $classes = array();
00048 
00052         private $loadedClasses = array();
00053 
00057         private $prefix = "class_";
00058 
00062         private $suffix = ".php";
00063 
00067         private $suffixLen = 0;
00068 
00072         private $prefixLen = 0;
00073 
00078         private $ignoreList = array();
00079 
00083         private $debug = false;
00084 
00088         private $listCached = false;
00089 
00093         private $classesCached = false;
00094 
00098         private $listCacheFQFN = "";
00099 
00103         private $classCacheFQFN = "";
00104 
00108         private $total = 0;
00109 
00116         public function __construct (FrameworkConfiguration $cfgInstance) {
00117                 // Set configuration instance
00118                 $this->cfgInstance = $cfgInstance;
00119 
00120                 // Construct the FQFN for the cache
00121                 if (!defined('DEVELOPER')) {
00122                         $this->listCacheFQFN  = $this->cfgInstance->readConfig('local_db_path') . "list-" . $this->cfgInstance->readConfig('app_name') . ".cache";
00123                         $this->classCacheFQFN = $this->cfgInstance->readConfig('local_db_path') . "class-" . $this->cfgInstance->readConfig('app_name') . ".cache";
00124                 } // END - if
00125 
00126                 // Set suffix and prefix from configuration
00127                 $this->suffix = $cfgInstance->readConfig('class_suffix');
00128                 $this->prefix = $cfgInstance->readConfig('class_prefix');
00129 
00130                 // Estimate length of prefix and suffix for substr() function (cache)
00131                 $this->suffixLen = strlen($this->suffix);
00132                 $this->prefixLen = strlen($this->prefix);
00133 
00134                 // Set own instance
00135                 self::$selfInstance = $this;
00136 
00137                 // Skip here if no dev-mode
00138                 if (defined('DEVELOPER')) return;
00139 
00140                 // IS the cache there?
00141                 if (file_exists($this->listCacheFQFN)) {
00142                         // Get content
00143                         $cacheContent = file_get_contents($this->listCacheFQFN);
00144 
00145                         // And convert it
00146                         $this->classes = unserialize($cacheContent);
00147 
00148                         // List has been restored from cache!
00149                         $this->listCached = true;
00150                 } // END - if
00151 
00152                 // Does the class cache exist?
00153                 if (file_exists($this->classCacheFQFN)) {
00154                         // Then include it
00155                         require($this->classCacheFQFN);
00156 
00157                         // Mark the class cache as loaded
00158                         $this->classesCached = true;
00159                 } // END - if
00160         }
00161 
00167         public function __destruct () {
00168                 // Skip here if dev-mode
00169                 if (defined('DEVELOPER')) return;
00170 
00171                 // Skip here if already cached
00172                 if ($this->listCached === false) {
00173                         // Writes the cache file of our list away
00174                         $cacheContent = serialize($this->classes);
00175                         file_put_contents($this->listCacheFQFN, $cacheContent);
00176                 } // END - if
00177 
00178                 // Skip here if already cached
00179                 if ($this->classesCached === false) {
00180                         // Generate a full-cache of all classes
00181                         $cacheContent = "";
00182                         foreach ($this->loadedClasses as $fqfn) {
00183                                 // Load the file
00184                                 $cacheContent .= file_get_contents($fqfn);
00185                         } // END - foreach
00186 
00187                         // And write it away
00188                         file_put_contents($this->classCacheFQFN, $cacheContent);
00189                 } // END - if
00190         }
00191 
00197         public final static function getInstance () {
00198                 // Is the instance there?
00199                 if (is_null(self::$selfInstance)) {
00200                         // Get a new one
00201                         self::$selfInstance = new ClassLoader(FrameworkConfiguration::getInstance());
00202                 } // END - if
00203 
00204                 // Return the instance
00205                 return self::$selfInstance;
00206         }
00207 
00215         public function loadClasses ($basePath, $ignoreList = array() ) {
00216                 // Is a list has been restored from cache, don't read it again
00217                 if ($this->listCached === true) {
00218                         // Abort here
00219                         return;
00220                 }
00221 
00222                 // Convert string to array
00223                 if (!is_array($ignoreList)) $ignoreList = array($ignoreList);
00224 
00225                 // Directories which our class loader ignores by default while
00226                 // deep-scanning the directory structure. See scanLocalPath() for
00227                 // details.
00228                 $ignoreList[] = ".";
00229                 $ignoreList[] = "..";
00230                 $ignoreList[] = ".htaccess";
00231                 $ignoreList[] = ".svn";
00232 
00233                 // Keep it in class for later usage
00234                 $this->ignoreList = $ignoreList;
00235 
00236                 // Set base directory which holds all our classes, we should use an
00237                 // absolute path here so is_dir(), is_file() and so on will always
00238                 // find the correct files and dirs.
00239                 $basePath2 = realpath($basePath);
00240 
00241                 // If the basePath is false it is invalid
00242                 if ($basePath2 === false) {
00243                         /* @todo: Do not die here. */
00244                         die("Cannot read {$basePath} !");
00245                 } else {
00246                         // Set base path
00247                         $basePath = $basePath2;
00248                 }
00249 
00250                 // Get a new iterator
00251                 //* DEBUG: */ echo "<strong>Base path: {$basePath}</strong><br />\n";
00252                 $iterator = new RecursiveDirectoryIterator($basePath);
00253                 $recursive = new RecursiveIteratorIterator($iterator);
00254                 foreach ($recursive as $entry) {
00255                         // Get filename from iterator
00256                         $fileName = $entry->getFileName();
00257 
00258                         // Is this file wanted?
00259                         //* DEBUG: */ echo "FOUND:{$fileName}<br />\n";
00260                         if ((!in_array($fileName, $this->ignoreList)) && (substr($fileName, 0, $this->prefixLen) == $this->prefix) && (substr($fileName, -$this->suffixLen, $this->suffixLen) == $this->suffix)) {
00261                                 // Get the FQFN and add it to our class list
00262                                 $fqfn = $entry->getRealPath();
00263                                 //* DEBUG: */ echo "ADD: {$fileName}<br />\n";
00264                                 $this->classes[$fileName] = $fqfn;
00265                         } // END - if
00266                 } // END - foreach
00267         }
00268 
00274         public function loadExtraConfigs () {
00275                 // Backup old prefix
00276                 $oldPrefix = $this->prefix;
00277 
00278                 // Set new prefix (temporary!)
00279                 $this->prefix = "config-";
00280                 $this->prefixLen = strlen($this->prefix);
00281 
00282                 // Set base directory
00283                 $basePath = sprintf("%sinc/config/", $this->cfgInstance->readConfig('base_path'));
00284 
00285                 // Load all classes from the config directory
00286                 $this->loadClasses($basePath);
00287 
00288                 // Include these extra configs now
00289                 $this->includeExtraConfigs();
00290 
00291                 // Set the prefix back
00292                 $this->prefix = $oldPrefix;
00293                 $this->prefixLen = strlen($this->prefix);
00294 
00295         }
00296 
00305         public function includeClass ($className) {
00306                 // Create a name with prefix and suffix
00307                 $fileName = $this->prefix . $className . $this->suffix;
00308 
00309                 // Now look it up in our index
00310                 if (isset($this->classes[$fileName])) {
00311                         // File is found so load it only once
00312                         //* DEBUG: */ echo "LOAD: ".$fileName." - Start<br />\n";
00313                         require($this->classes[$fileName]);
00314                         //* DEBUG: */ echo "LOAD: ".$fileName." - End<br />\n";
00315 
00316                         // Count this include
00317                         $this->total++;
00318 
00319                         // Mark this class as loaded
00320                         $this->loadedClasses[] = $this->classes[$fileName];
00321 
00322                         // Developer mode excludes caching (better debugging)
00323                         if (!defined('DEVELOPER')) {
00324                                 // Reset cache
00325                                 $this->classesCached = false;
00326                         } // END - if
00327                 } // END - if
00328         }
00329 
00335         private function includeExtraConfigs () {
00336                 // Run through all class names (should not be much)
00337                 foreach ($this->classes as $fileName => $fqfn) {
00338                         // Is this a config?
00339                         if (substr($fileName, 0, $this->prefixLen) == $this->prefix) {
00340                                 // Then include it
00341                                 require($fqfn);
00342 
00343                                 // Remove it from the list
00344                                 unset($this->classes[$fileName]);
00345                         } // END - if
00346                 } // END - foreach
00347         }
00348 
00354         public final function getTotal () {
00355                 return $this->total;
00356         }
00357 
00363         public function getPrintableIncludeList () {
00364                 // Prepare the list
00365                 $includeList = "";
00366                 foreach ($this->loadedClasses as $classFile) {
00367                         $includeList .= basename($classFile)."<br />\n";
00368                 } // END - foreach
00369 
00370                 // And return it
00371                 return $includeList;
00372         }
00373 }
00374 
00375 // [EOF]
00376 ?>

Generated on Mon Dec 8 01:06:46 2008 for Ship-Simulator by  doxygen 1.5.6