X-Git-Url: https://git.mxchange.org/?p=core.git;a=blobdiff_plain;f=framework%2Floader%2Fclass_ClassLoader.php;h=5035d3f83cce41ea94ec6edf90f4a824a67f15e6;hp=939d3559db61dc439ffdd572eb669278849ee228;hb=868c877607670760eb36e63ebeb1a04237907be9;hpb=6acaeb0b08448f701ca13f50aec3ee89ba6ab948 diff --git a/framework/loader/class_ClassLoader.php b/framework/loader/class_ClassLoader.php index 939d3559..5035d3f8 100644 --- a/framework/loader/class_ClassLoader.php +++ b/framework/loader/class_ClassLoader.php @@ -1,15 +1,16 @@ listCached === FALSE) { + if ($this->listCached === false) { // Writes the cache file of our list away $cacheContent = json_encode($this->foundClasses); - file_put_contents($this->listCacheFQFN, $cacheContent); + + // Open cache instance + $fileObject = $this->listCacheFile->openFile('w'); + + // And write whole list + $fileObject->fwrite($cacheContent); } // END - if // Skip here if already cached - if ($this->classesCached === FALSE) { + if ($this->classesCached === false) { // Generate a full-cache of all classes $cacheContent = ''; - foreach (array_keys($this->loadedClasses) as $fqfn) { + foreach (array_keys($this->loadedClasses) as $fileInstance) { + // Open file + $fileObject = $fileInstance->openFile('r'); + // Load the file - $cacheContent .= file_get_contents($fqfn); + // @TODO Add some uglifying code (compress) here + $cacheContent .= $fileObject->fread($fileInstance->getSize()); } // END - foreach + // Open file + $fileObject = $this->classCacheFile->openFile('w'); + // And write it away - file_put_contents($this->classCacheFQFN, $cacheContent); + $fileObject->fwrite($cacheContent); } // END - if } @@ -207,7 +220,7 @@ class ClassLoader { $loaderInstance = self::getSelfInstance(); // Get config instance - $cfg = FrameworkConfiguration::getSelfInstance(); + $configInstance = FrameworkBootstrap::getConfigurationInstance(); // Load all classes foreach (self::$frameworkPaths as $shortPath) { @@ -215,26 +228,28 @@ class ClassLoader { //* NOISY-DEBUG: */ printf('[%s:%d]: shortPath=%s' . PHP_EOL, __METHOD__, __LINE__, $shortPath); // Generate full path from it - $pathName = realpath(sprintf( - '%smain/%s/', - $cfg->getConfigEntry('framework_base_path'), - $shortPath + $realPathName = realpath(sprintf( + '%smain%s%s%s', + $configInstance->getConfigEntry('framework_base_path'), + DIRECTORY_SEPARATOR, + $shortPath, + DIRECTORY_SEPARATOR )); // Debug message - //* NOISY-DEBUG: */ printf('[%s:%d]: pathName=%s' . PHP_EOL, __METHOD__, __LINE__, $pathName); + //* NOISY-DEBUG: */ printf('[%s:%d]: realPathName=%s' . PHP_EOL, __METHOD__, __LINE__, $realPathName); - // Is it not FALSE and accessible? - if (is_bool($pathName)) { + // Is it not false and accessible? + if (is_bool($realPathName)) { // Skip this continue; - } elseif (!is_readable($pathName)) { + } elseif (!is_readable($realPathName)) { // @TODO Throw exception instead of break break; } // Try to load the framework classes - $loaderInstance->scanClassPath($pathName); + $loaderInstance->scanClassPath($realPathName); } // END - foreach // Trace message @@ -254,7 +269,7 @@ class ClassLoader { $loaderInstance = self::getSelfInstance(); // Get config instance - $cfg = FrameworkConfiguration::getSelfInstance(); + $configInstance = FrameworkBootstrap::getConfigurationInstance(); // Load all classes for the application foreach (self::$frameworkPaths as $shortPath) { @@ -263,9 +278,11 @@ class ClassLoader { // Create path name $pathName = realpath(sprintf( - '%s/%s/%s', - $cfg->getConfigEntry('application_base_path'), - $cfg->getConfigEntry('app_name'), + '%s%s%s%s%s', + $configInstance->getConfigEntry('application_base_path'), + DIRECTORY_SEPARATOR, + $configInstance->getConfigEntry('detected_app_name'), + DIRECTORY_SEPARATOR, $shortPath )); @@ -293,27 +310,34 @@ class ClassLoader { //* NOISY-DEBUG: */ printf('[%s:%d]: CALLED!' . PHP_EOL, __METHOD__, __LINE__); // Get config instance - $cfg = FrameworkConfiguration::getSelfInstance(); + $configInstance = FrameworkBootstrap::getConfigurationInstance(); // Load all classes for the application foreach (self::$testPaths as $shortPath) { // Debug message //* NOISY-DEBUG: */ printf('[%s:%d]: shortPath=%s' . PHP_EOL, __METHOD__, __LINE__, $shortPath); - // Create path name - $pathName = realpath(sprintf( - '%s/%s', - $cfg->getConfigEntry('framework_base_path'), + // Construct path name + $pathName = sprintf( + '%s%s%s', + $configInstance->getConfigEntry('root_base_path'), + DIRECTORY_SEPARATOR, $shortPath - )); + ); // Debug message - //* NOISY-DEBUG: */ printf('[%s:%d]: pathName[%s]=%s' . PHP_EOL, __METHOD__, __LINE__, gettype($pathName), $pathName); + //* NOISY-DEBUG: */ printf('[%s:%d]: pathName[%s]=%s - BEFORE!' . PHP_EOL, __METHOD__, __LINE__, gettype($pathName), $pathName); + + // Try to find it + $realPathName = realpath($pathName); + + // Debug message + //* NOISY-DEBUG: */ printf('[%s:%d]: realPathName[%s]=%s - AFTER!' . PHP_EOL, __METHOD__, __LINE__, gettype($realPathName), $realPathName); // Is the path readable? - if (is_dir($pathName)) { + if ((is_dir($realPathName)) && (is_readable($realPathName))) { // Try to load the application classes - ClassLoader::getSelfInstance()->scanClassPath($pathName); + ClassLoader::getSelfInstance()->scanClassPath($realPathName); } // END - if } // END - foreach @@ -324,11 +348,11 @@ class ClassLoader { /** * Enables or disables strict naming-convention tests on class loading * - * @param $strictNamingConventionCheck Whether to strictly check naming-convention + * @param $strictNamingConvention Whether to strictly check naming-convention * @return void */ - public static function enableStrictNamingConventionCheck ($strictNamingConventionCheck = TRUE) { - self::$strictNamingConventionCheck = $strictNamingConventionCheck; + public static function enableStrictNamingConventionCheck ($strictNamingConvention = true) { + self::$strictNamingConvention = $strictNamingConvention; } /** @@ -339,8 +363,14 @@ class ClassLoader { * @return void */ public static function registerTestsPath ($relativePath) { + // Trace message + //* NOISY-DEBUG: */ printf('[%s:%d]: relativePath=%s - CALLED!' . PHP_EOL, __METHOD__, __LINE__, $relativePath); + // "Register" it self::$testPaths[$relativePath] = $relativePath; + + // Trace message + //* NOISY-DEBUG: */ printf('[%s:%d]: EXIT!' . PHP_EOL, __METHOD__, __LINE__); } /** @@ -350,8 +380,14 @@ class ClassLoader { * @return void */ public static function autoLoad ($className) { + // Trace message + //* NOISY-DEBUG: */ printf('[%s:%d]: className=%s - CALLED!' . PHP_EOL, __METHOD__, __LINE__, $className); + // Try to include this class self::getSelfInstance()->loadClassFile($className); + + // Trace message + //* NOISY-DEBUG: */ printf('[%s:%d]: EXIT!' . PHP_EOL, __METHOD__, __LINE__); } /** @@ -363,7 +399,7 @@ class ClassLoader { // Is the instance there? if (is_null(self::$selfInstance)) { // Get a new one - self::$selfInstance = ClassLoader::createClassLoader(FrameworkConfiguration::getSelfInstance()); + self::$selfInstance = ClassLoader::createClassLoader(FrameworkBootstrap::getConfigurationInstance()); } // END - if // Return the instance @@ -379,7 +415,7 @@ class ClassLoader { */ public function scanClassPath ($basePath, array $ignoreList = array() ) { // Is a list has been restored from cache, don't read it again - if ($this->listCached === TRUE) { + if ($this->listCached === true) { // Abort here return; } // END - if @@ -400,8 +436,8 @@ class ClassLoader { */ $basePath2 = realpath($basePath); - // If the basePath is FALSE it is invalid - if ($basePath2 === FALSE) { + // If the basePath is false it is invalid + if ($basePath2 === false) { /* @TODO: Do not exit here. */ exit(__METHOD__ . ': Cannot read ' . $basePath . ' !' . PHP_EOL); } else { @@ -418,14 +454,11 @@ class ClassLoader { // Get current entry $currentEntry = $iteratorInstance->current(); - // Get filename from iterator - $fileName = $currentEntry->getFileName(); + // Get filename from iterator which is the class' name (according naming-convention) + $fileName = $currentEntry->getFilename(); - // Get the "FQFN" (path and file name) - $fqfn = $currentEntry->getRealPath(); - - // Current entry must be a file, not smaller than 100 bytes and not on ignore list - if ((!$currentEntry->isFile()) || (in_array($fileName, $this->ignoreList)) || (filesize($fqfn) < 100)) { + // Current entry must be a file, not smaller than 100 bytes and not on ignore list + if ((!$currentEntry->isFile()) || (in_array($fileName, $this->ignoreList)) || ($currentEntry->getSize() < 100)) { // Advance to next entry $iteratorInstance->next(); @@ -438,11 +471,11 @@ class ClassLoader { //* NOISY-DEBUG: */ printf('[%s:%d] FOUND: %s' . PHP_EOL, __METHOD__, __LINE__, $fileName); if ((substr($fileName, 0, strlen($this->prefix)) == $this->prefix) && (substr($fileName, -strlen($this->suffix), strlen($this->suffix)) == $this->suffix)) { // Add it to the list - //* NOISY-DEBUG: */ printf('[%s:%d] ADD: %s,fqfn=%s' . PHP_EOL, __METHOD__, __LINE__, $fileName, $fqfn); - $this->foundClasses[$fileName] = $fqfn; + //* NOISY-DEBUG: */ printf('[%s:%d] ADD: %s,currentEntry=%s' . PHP_EOL, __METHOD__, __LINE__, $fileName, $currentEntry); + $this->foundClasses[$fileName] = $currentEntry; } else { // Not added - //* NOISY-DEBUG: */ printf('[%s:%d] NOT ADDED: %s,fqfn=%s' . PHP_EOL, __METHOD__, __LINE__, $fileName, $fqfn); + //* NOISY-DEBUG: */ printf('[%s:%d] NOT ADDED: %s,currentEntry=%s' . PHP_EOL, __METHOD__, __LINE__, $fileName, $currentEntry); } // Advance to next entry @@ -452,28 +485,28 @@ class ClassLoader { } /** - * Load extra config files + * Getter for total include counter * - * @return void + * @return $total Total loaded include files */ - public function loadExtraConfigs () { - // Backup old prefix - $oldPrefix = $this->prefix; - - // Set new prefix (temporary!) - $this->prefix = 'config-'; - - // Set base directory - $basePath = $this->configInstance->getConfigEntry('framework_base_path') . 'config/'; - - // Load all classes from the config directory - $this->scanClassPath($basePath); + public final function getTotal () { + return $this->total; + } - // Include these extra configs now - $this->includeExtraConfigs(); + /** + * Getter for a printable list of included main/interfaces/exceptions + * + * @param $includeList A printable include list + */ + public function getPrintableIncludeList () { + // Prepare the list + $includeList = ''; + foreach ($this->loadedClasses as $classFile) { + $includeList .= basename($classFile) . '
' . PHP_EOL; + } // END - foreach - // Set back the old prefix - $this->prefix = $oldPrefix; + // And return it + return $includeList; } /** @@ -488,8 +521,8 @@ class ClassLoader { // Construct the FQFN for the cache if (!defined('DEVELOPER')) { - $this->listCacheFQFN = $this->configInstance->getConfigEntry('local_database_path') . 'list-' . $this->configInstance->getConfigEntry('app_name') . '.cache'; - $this->classCacheFQFN = $this->configInstance->getConfigEntry('local_database_path') . 'class-' . $this->configInstance->getConfigEntry('app_name') . '.cache'; + $this->listCacheFile = new SplFileInfo($this->configInstance->getConfigEntry('local_database_path') . 'list-' . $this->configInstance->getConfigEntry('detected_app_name') . '.cache'); + $this->classCacheFile = new SplFileInfo($this->configInstance->getConfigEntry('local_database_path') . 'class-' . $this->configInstance->getConfigEntry('detected_app_name') . '.cache'); } // END - if // Set suffix and prefix from configuration @@ -504,25 +537,22 @@ class ClassLoader { return; } // END - if - // IS the cache there? - if (BaseFrameworkSystem::isReadableFile($this->listCacheFQFN)) { - // Get content - $cacheContent = file_get_contents($this->listCacheFQFN); - - // And convert it - $this->foundClasses = json_decode($cacheContent); + // Is the cache there? + if (FrameworkBootstrap::isReadableFile($this->listCacheFile)) { + // Load and convert it + $this->foundClasses = json_decode(file_get_contents($this->listCacheFile->getPathname())); // List has been restored from cache! - $this->listCached = TRUE; + $this->listCached = true; } // END - if // Does the class cache exist? - if (BaseFrameworkSystem::isReadableFile($this->listCacheFQFN)) { + if (FrameworkBootstrap::isReadableFile($this->classCacheFile)) { // Then include it - require $this->classCacheFQFN; + FrameworkBootstrap::loadInclude($this->classCacheFile); // Mark the class cache as loaded - $this->classesCached = TRUE; + $this->classesCached = true; } // END - if } @@ -533,7 +563,7 @@ class ClassLoader { * * @param $className The class that shall be loaded * @return void - * @throws InvalidArgumentException If strict-checking is enabled and class name is not following naming convention + * @throws InvalidArgumentException If strict-checking is enabled and class name is not following naming-convention */ private function loadClassFile ($className) { // Trace message @@ -543,30 +573,30 @@ class ClassLoader { $classNameParts = explode("\\", $className); // At least 3 parts should be there - if ((self::$strictNamingConventionCheck === TRUE) && (count($classNameParts) < 3)) { + if ((self::$strictNamingConvention === true) && (count($classNameParts) < 5)) { // Namespace scheme is: Project\Package[\SubPackage...] - throw new InvalidArgumentException(sprintf('Class name "%s" is not conform to naming-convention: Project\Package[\SubPackage...]\SomeFooBar', $className)); + throw new InvalidArgumentException(sprintf('Class name "%s" is not conform to naming-convention: Tld\Domain\Project\Package[\SubPackage...]\SomeFooBar', $className)); } // END - if // Get last element $shortClassName = array_pop($classNameParts); // Create a name with prefix and suffix - $fileName = $this->prefix . $shortClassName . $this->suffix; + $fileName = sprintf('%s%s%s', $this->prefix, $shortClassName, $this->suffix); // Now look it up in our index //* NOISY-DEBUG: */ printf('[%s:%d] ISSET: %s' . PHP_EOL, __METHOD__, __LINE__, $fileName); - if ((isset($this->foundClasses[$fileName])) && (!isset($this->loadedClasses[$this->foundClasses[$fileName]]))) { + if ((isset($this->foundClasses[$fileName])) && (!isset($this->loadedClasses[$this->foundClasses[$fileName]->getPathname()]))) { // File is found and not loaded so load it only once //* NOISY-DEBUG: */ printf('[%s:%d] LOAD: %s - START' . PHP_EOL, __METHOD__, __LINE__, $fileName); - require $this->foundClasses[$fileName]; + FrameworkBootstrap::loadInclude($this->foundClasses[$fileName]); //* NOISY-DEBUG: */ printf('[%s:%d] LOAD: %s - END' . PHP_EOL, __METHOD__, __LINE__, $fileName); // Count this loaded class/interface/exception $this->total++; // Mark this class as loaded for other purposes than loading it. - $this->loadedClasses[$this->foundClasses[$fileName]] = TRUE; + $this->loadedClasses[$this->foundClasses[$fileName]->getPathname()] = true; // Remove it from classes list so it won't be found twice. //* NOISY-DEBUG: */ printf('[%s:%d] UNSET: %s' . PHP_EOL, __METHOD__, __LINE__, $fileName); @@ -575,8 +605,8 @@ class ClassLoader { // Developer mode excludes caching (better debugging) if (!defined('DEVELOPER')) { // Reset cache - //* NOISY-DEBUG: */ printf('[%s:%d] classesCached=FALSE' . PHP_EOL, __METHOD__, __LINE__); - $this->classesCached = FALSE; + //* NOISY-DEBUG: */ printf('[%s:%d] classesCached=false' . PHP_EOL, __METHOD__, __LINE__); + $this->classesCached = false; } // END - if } else { // Not found @@ -584,51 +614,4 @@ class ClassLoader { } } - /** - * Includes all extra config files - * - * @return void - */ - private function includeExtraConfigs () { - // Run through all class names (should not be much) - foreach ($this->foundClasses as $fileName => $fqfn) { - // Is this a config? - if (substr($fileName, 0, strlen($this->prefix)) == $this->prefix) { - // Then include it - //* NOISY-DEBUG: */ printf('[%s:%d] LOAD: %s - START' . PHP_EOL, __METHOD__, __LINE__, $fileName); - require $fqfn; - //* NOISY-DEBUG: */ printf('[%s:%d] LOAD: %s - END' . PHP_EOL, __METHOD__, __LINE__, $fileName); - - // Remove it from the list - //* NOISY-DEBUG: */ printf('[%s:%d] UNSET: %s' . PHP_EOL, __METHOD__, __LINE__, $fileName); - unset($this->foundClasses[$fileName]); - } // END - if - } // END - foreach - } - - /** - * Getter for total include counter - * - * @return $total Total loaded include files - */ - public final function getTotal () { - return $this->total; - } - - /** - * Getter for a printable list of included main/interfaces/exceptions - * - * @param $includeList A printable include list - */ - public function getPrintableIncludeList () { - // Prepare the list - $includeList = ''; - foreach ($this->loadedClasses as $classFile) { - $includeList .= basename($classFile) . '
' . PHP_EOL; - } // END - foreach - - // And return it - return $includeList; - } - }