<?php
+// Own namespace
+namespace CoreFramework\Loader;
+
+// Import framework stuff
+use CoreFramework\Configuration\FrameworkConfiguration;
+use CoreFramework\Object\BaseFrameworkSystem;
+
+// Import SPL stuff
+use \InvalidArgumentException;
+use \RecursiveDirectoryIterator;
+use \RecursiveIteratorIterator;
+
/**
* This class loads class include files with a specific prefix and suffix
*
* @author Roland Haeder <webmaster@shipsimu.org>
- * @version 0.0.0
+ * @version 1.5.0
* @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2017 Core Developer Team
* @license GNU GPL 3.0 or any newer version
* @link http://www.shipsimu.org
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ----------------------------------
+ * 1.5
+ * - Namespace scheme Project\Package[\SubPackage...] is fully supported and
+ * throws an InvalidArgumentException if not present. The last part will be
+ * always the class' name.
* 1.4
* - Some comments improved, other minor improvements
* 1.3
private static $selfInstance = NULL;
/**
- * Array with all classes
+ * Array with all found classes
*/
- private $classes = array();
+ private $foundClasses = array();
/**
* List of loaded classes
// Skip here if already cached
if ($this->listCached === FALSE) {
// Writes the cache file of our list away
- $cacheContent = json_encode($this->classes);
+ $cacheContent = json_encode($this->foundClasses);
file_put_contents($this->listCacheFQFN, $cacheContent);
} // END - if
if ($this->classesCached === FALSE) {
// Generate a full-cache of all classes
$cacheContent = '';
- foreach ($this->loadedClasses as $fqfn) {
+ foreach (array_keys($this->loadedClasses) as $fqfn) {
// Load the file
$cacheContent .= file_get_contents($fqfn);
} // END - foreach
* @return void
*/
public static function scanFrameworkClasses () {
+ // Trace message
+ /* NOISY-DEBUG: */ printf('[%s:%d]: CALLED!' . PHP_EOL, __METHOD__, __LINE__);
+
// Cache loader instance
$loaderInstance = self::getSelfInstance();
// Load all classes
foreach (self::$frameworkPaths as $pathName) {
+ // Debug message
+ /* NOISY-DEBUG: */ printf('[%s:%d]: pathName=%s' . PHP_EOL, __METHOD__, __LINE__, $pathName);
+
// Try to load the framework classes
$loaderInstance->scanClassPath('inc/main/' . $pathName . '/');
} // END - foreach
* @return void
*/
public static function scanApplicationClasses () {
+ // Trace message
+ /* NOISY-DEBUG: */ printf('[%s:%d]: CALLED!' . PHP_EOL, __METHOD__, __LINE__);
+
// Get config instance
$cfg = FrameworkConfiguration::getSelfInstance();
// Load all classes for the application
foreach (self::$frameworkPaths as $class) {
// Create path name
- $path = sprintf('%s/%s/%s', $cfg->getConfigEntry('application_path'), $cfg->getConfigEntry('app_name'), $class);
+ $pathName = sprintf('%s/%s/%s', $cfg->getConfigEntry('application_path'), $cfg->getConfigEntry('app_name'), $class);
+
+ // Debug message
+ /* NOISY-DEBUG: */ printf('[%s:%d]: pathName=%s' . PHP_EOL, __METHOD__, __LINE__, $pathName);
// Is the path readable?
- if (is_dir($path)) {
+ if (is_dir($pathName)) {
// Try to load the application classes
- ClassLoader::getSelfInstance()->scanClassPath($path);
+ ClassLoader::getSelfInstance()->scanClassPath($pathName);
} // END - if
} // END - foreach
}
$cacheContent = file_get_contents($this->listCacheFQFN);
// And convert it
- $this->classes = json_decode($cacheContent);
+ $this->foundClasses = json_decode($cacheContent);
// List has been restored from cache!
$this->listCached = TRUE;
*/
public static function autoLoad ($className) {
// Try to include this class
- //* NOISY-DEBUG: */ printf('[%s:%d] className=%s' . PHP_EOL, __METHOD__, __LINE__, $className);
- self::getSelfInstance()->includeClass($className);
+ self::getSelfInstance()->loadClassFile($className);
}
/**
}
// Get a new iterator
- //* NOISY-DEBUG: */ printf('[%s:%d] basePath=%s' . PHP_EOL, __METHOD__, __LINE__, $basePath);
+ /* NOISY-DEBUG: */ printf('[%s:%d] basePath=%s' . PHP_EOL, __METHOD__, __LINE__, $basePath);
$iteratorInstance = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($basePath), RecursiveIteratorIterator::CHILD_FIRST);
// Load all entries
$iteratorInstance->next();
// Skip non-file entries
- //* NOISY-DEBUG: */ printf('[%s:%d] SKIP: %s' . PHP_EOL, __METHOD__, __LINE__, $fileName);
+ /* NOISY-DEBUG: */ printf('[%s:%d] SKIP: %s' . PHP_EOL, __METHOD__, __LINE__, $fileName);
continue;
} // END - if
// Is this file wanted?
- //* NOISY-DEBUG: */ printf('[%s:%d] FOUND: %s' . PHP_EOL, __METHOD__, __LINE__, $fileName);
+ /* 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->classes[$fileName] = $fqfn;
+ /* NOISY-DEBUG: */ printf('[%s:%d] ADD: %s,fqfn=%s' . PHP_EOL, __METHOD__, __LINE__, $fileName, $fqfn);
+ $this->foundClasses[$fileName] = $fqfn;
} 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,fqfn=%s' . PHP_EOL, __METHOD__, __LINE__, $fileName, $fqfn);
}
// Advance to next entry
- //* NOISY-DEBUG: */ printf('[%s:%d] NEXT: %s' . PHP_EOL, __METHOD__, __LINE__, $fileName);
+ /* NOISY-DEBUG: */ printf('[%s:%d] NEXT: %s' . PHP_EOL, __METHOD__, __LINE__, $fileName);
$iteratorInstance->next();
} // END - while
}
* @param $className The class that shall be loaded
* @return void
*/
- public function includeClass ($className) {
+ private function loadClassFile ($className) {
+ // Trace message
+ /* NOISY-DEBUG: */ printf('[%s:%d] className=%s - CALLED!' . PHP_EOL, __METHOD__, __LINE__, $className);
+
+ // The class name should contain at least 2 back-slashes, so split at them
+ $classNameParts = explode("\\", $className);
+
+ // At least 3 parts should be there
+ if (count($classNameParts) < 3) {
+ // Namespace scheme is: Project\Package[\SubPackage...]
+ throw new InvalidArgumentException(sprintf('Class name "%s" is not conform to naming-convention: Project\Package[\SubPackage...]\SomeFooBar', $className));
+ } // END - if
+
+ // Get last element
+ $shortClassName = array_pop($classNameParts);
+
// Create a name with prefix and suffix
- $fileName = $this->prefix . $className . $this->suffix;
+ $fileName = $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->classes[$fileName])) && (!in_array($this->classes[$fileName], $this->loadedClasses))) {
+ /* NOISY-DEBUG: */ printf('[%s:%d] ISSET: %s' . PHP_EOL, __METHOD__, __LINE__, $fileName);
+ if ((isset($this->foundClasses[$fileName])) && (!isset($this->loadedClasses[$this->foundClasses[$fileName]]))) {
// 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->classes[$fileName]);
- //* NOISY-DEBUG: */ printf('[%s:%d] LOAD: %s - END' . PHP_EOL, __METHOD__, __LINE__, $fileName);
+ /* NOISY-DEBUG: */ printf('[%s:%d] LOAD: %s - START' . PHP_EOL, __METHOD__, __LINE__, $fileName);
+ require($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.
- array_push($this->loadedClasses, $this->classes[$fileName]);
+ $this->loadedClasses[$this->foundClasses[$fileName]] = 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);
- unset($this->classes[$fileName]);
+ /* NOISY-DEBUG: */ printf('[%s:%d] UNSET: %s' . PHP_EOL, __METHOD__, __LINE__, $fileName);
+ unset($this->foundClasses[$fileName]);
// Developer mode excludes caching (better debugging)
if (!defined('DEVELOPER')) {
// Reset cache
- //* NOISY-DEBUG: */ printf('[%s:%d] classesCached=FALSE' . PHP_EOL, __METHOD__, __LINE__);
+ /* NOISY-DEBUG: */ printf('[%s:%d] classesCached=FALSE' . PHP_EOL, __METHOD__, __LINE__);
$this->classesCached = FALSE;
} // END - if
} else {
// Not found
- //* NOISY-DEBUG: */ printf('[%s:%d] 404: %s' . PHP_EOL, __METHOD__, __LINE__, $fileName);
+ /* NOISY-DEBUG: */ printf('[%s:%d] 404: %s' . PHP_EOL, __METHOD__, __LINE__, $fileName);
}
}
*/
private function includeExtraConfigs () {
// Run through all class names (should not be much)
- foreach ($this->classes as $fileName => $fqfn) {
+ 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->classes[$fileName]);
+ /* NOISY-DEBUG: */ printf('[%s:%d] UNSET: %s' . PHP_EOL, __METHOD__, __LINE__, $fileName);
+ unset($this->foundClasses[$fileName]);
} // END - if
} // END - foreach
}
// And return it
return $includeList;
}
-}
-// [EOF]
-?>
+}