* @copyright four for business AG * @license http://www.contenido.org/license/LIZENZ.txt * @link http://www.4fb.de * @link http://www.contenido.org * @since file available since CONTENIDO release 4.9.0 * * {@internal * created 2010-12-27 * $Id$: * }} */ if (!defined('CON_FRAMEWORK')) { die('Illegal call'); } class cAutoload { const ERROR_FILE_NOT_FOUND = 'file_not_found'; const ERROR_CLASS_EXISTS = 'class_exists'; /** * CONTENIDO root path. Path to the folder which contains the CONTENIDO installation. * * @var string */ private static $_conRootPath = null; /** * Array of interface/class names with related files to include * * @var array */ private static $_includeFiles = null; /** * Flag containing initialized status * * @var bool */ private static $_initialized = null; /** * Array to store loaded classnames and the paths to the class files. * $_loadedClasses['classname'] = '/path/to/the/class.php'; * * @var array */ private static $_loadedClasses = array(); /** * Array to store invalid classnames and the paths to the class files. * $_errors[pos] = array('class' => classname, 'file' => file, 'error' => errorType); * * @var array */ private static $_errors = array(); /** * Initialization of CONTENIDO autoloader, is to call at least once. * * Registers itself as a __autoload implementation, includes the class map file, * and if exists, the user defined class map file, containing the includes. * * @param array $cfg The CONTENIDO cfg array * @return void */ public static function initialize(array $cfg) { if (self::$_initialized == true) { return; } self::$_initialized = true; self::$_conRootPath = str_replace('\\', '/', realpath($cfg['path']['contenido'] . '/../')) . '/'; spl_autoload_register(array(__CLASS__, 'autoload')); // load n' store autoloader class map file $file = $cfg['path']['config'] . 'config.autoloader.php'; if ($arr = include_once($file)) { self::$_includeFiles = $arr; } // load n' store additional autoloader class map file, if exists $file = $cfg['path']['config'] . 'config.autoloader.local.php'; if (is_file($file)) { self::addClassmapConfigFile($file); } } /** * Adding additional autoloader class map configuration. * NOTE: * Since this autoloader is implemented for CONTENIDO, it doesn't support to * load classfiles being located outside of the CONTENIDO installation folder. * * @param array $config Assoziative class map array as follows: *
     * // Structure is: "Classname" => "Path to classfile from CONTENIDO installation folder"
     * $config = array(
     *     'myPluginsClass' => 'contenido/plugins/myplugin/classes/class.myPluginClass.php',
     *     'myPluginsOtherClass' => 'contenido/plugins/myplugin/classes/class.myPluginsOtherClass.php',
     * );
     * 
* @return void */ public static function addClassmapConfig(array $config) { self::$_includeFiles = array_merge(self::$_includeFiles, $config); } /** * Adding additional autoloader class map configuration file. * NOTE: * Since this autoloader is implemented for CONTENIDO, it doesn't support to * load classfiles being located outside of the CONTENIDO installation folder. * * @param string $configFile Full path to class map configuration file. * The provided file must return a class map configuration array as follows: *
     * // Structure is: "Classname" => "Path to classfile from CONTENIDO installation folder"
     * return array(
     *     'myPluginsClass' => 'contenido/plugins/myplugin/classes/class.myPluginClass.php',
     *     'myPluginsOtherClass' => 'contenido/plugins/myplugin/classes/class.myPluginsOtherClass.php',
     *     'myCmsClass' => 'cms/includes/class.myCmsClass.php',
     * );
     * 
* @return void */ public static function addClassmapConfigFile($configFile) { if (is_file($configFile)) { if ($arr = include_once($configFile)) { if(is_array($arr)) { self::addClassmapConfig($arr); } } } } /** * The main __autoload() implementation. * Tries to include the file of passed classname. * * @param string $className The classname * @return void * @throws Exception If autoloader wasn't initialized before */ public static function autoload($className) { if (self::$_initialized !== true) { throw new Exception("Autoloader has to be initialized by calling method initialize()"); } if (isset(self::$_loadedClasses[$className])) { return; } $file = ''; if ($file = self::_getContenidoClassFile($className)) { // load class file from class map self::_loadFile($file); } self::$_loadedClasses[$className] = str_replace(self::$_conRootPath, '', $file); } /** * Checks, if passed filename is a file, which will be included by the autoloader. * * @param string $file Filename or Filename with a part of the path, e. g. * - class.foobar.php * - classes/class.foobar.php * - contenido/classes/class.foobar.php * @return bool */ public static function isAutoloadable($file) { foreach (self::$_includeFiles as $className => $includeFile) { if (strpos($includeFile, $file) !== false) { return true; } } return false; } /** * Returns the loaded classes (@see cAutoload::$_loadedClasses) * * @return array */ public static function getLoadedClasses() { return self::$_loadedClasses; } /** * Returns the errorlist containing invalid classes (@see cAutoload::$_errors) * * @return array */ public static function getErrors() { return self::$_errors; } /** * Returns the path to a CONTENIDO class file by processing the given classname * * @param string $className * @return (string|null) Path and filename or null */ private static function _getContenidoClassFile($className) { $file = isset(self::$_includeFiles[$className]) ? self::$_conRootPath . self::$_includeFiles[$className] : null; return self::_validateClassAndFile($className, $file); } /** * Validates the given class and the file * * @param string $className * @param string $filePathName * @return (string|null) The file if validation was successfull, otherwhise null */ private static function _validateClassAndFile($className, $filePathName) { if (class_exists($className)) { self::$_errors[] = array( 'class' => $className, 'file' => str_replace(self::$_conRootPath, '', $filePathName), 'error' => self::ERROR_CLASS_EXISTS ); return null; } elseif (!is_file($filePathName)) { self::$_errors[] = array( 'class' => $className, 'file' => str_replace(self::$_conRootPath, '', $filePathName), 'error' => self::ERROR_FILE_NOT_FOUND ); return null; } return $filePathName; } /** * Loads the desired file by invoking require_once method * * @param string $filePathName * @param bool $beQuiet Flag to prevent thrown warnings/errors by using * the error control operator @ * @return void */ private static function _loadFile($filePathName, $beQuiet = false) { if ($beQuiet) { @require_once($filePathName); } else { require_once($filePathName); } } }