Index: branches/5.3.x/core/kernel/utility/factory.php =================================================================== diff -u -N -r15483 -r15902 --- branches/5.3.x/core/kernel/utility/factory.php (.../factory.php) (revision 15483) +++ branches/5.3.x/core/kernel/utility/factory.php (.../factory.php) (revision 15902) @@ -1,6 +1,6 @@ Files = $data['Factory.Files']; + $this->classMap = $data['Factory.Files']; $this->realClasses = $data['Factory.realClasses']; } /** * Performs automatic loading of classes registered with the factory * - * @param string $class_name - * @return void - * @throws kFactoryException + * @param string $class + * @return bool|null * @access public */ - public function autoload($class_name) + public function autoload($class) { - if ( !isset($this->Files[$class_name]) ) { - // class not from our factory -> let other autoloaders handle it - return; + $file = $this->findFile($class); + + if ( $file ) { + kUtil::includeOnce(FULL_PATH . $file); + + return true; } - if ( !file_exists(FULL_PATH . $this->Files[$class_name]) ) { - throw new kFactoryException('File ' . FULL_PATH . $this->Files[$class_name] . ' containing class ' . $class_name . ' definition not found'); + return null; + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * @return string|bool The path if found, false otherwise + * @access protected + */ + protected function findFile($class) + { + if ( $class[0] == '\\' ) { + $class = substr($class, 1); } - kUtil::includeOnce(FULL_PATH . $this->Files[$class_name]); + if ( isset($this->classMap[$class]) ) { + return $this->classMap[$class]; + } + + $pos = strrpos($class, '\\'); + + if ( $pos !== false ) { + // namespaced class name + $class_path = str_replace('\\', DIRECTORY_SEPARATOR, substr($class, 0, $pos)) . DIRECTORY_SEPARATOR; + $class_name = substr($class, $pos + 1); + } + else { + // PEAR-like class name + $class_path = null; + $class_name = $class; + } + + $class_path .= str_replace('_', DIRECTORY_SEPARATOR, $class_name) . '.php'; + + foreach ($this->Application->ModuleInfo as $module_name => $module_info) { + if ( $module_name == 'In-Portal' ) { + continue; + } + + if ( strpos($class, $module_info['ClassNamespace']) === 0 ) { + $test_class_path = str_replace( + str_replace('\\', DIRECTORY_SEPARATOR, $module_info['ClassNamespace']), + rtrim($module_info['Path'], '/'), + $class_path + ); + + if ( file_exists(FULL_PATH . DIRECTORY_SEPARATOR . $test_class_path) ) { + return DIRECTORY_SEPARATOR . $test_class_path; + } + } + } + + return $this->classMap[$class] = false; } /** @@ -95,7 +146,7 @@ public function getToCache() { return Array ( - 'Factory.Files' => $this->Files, + 'Factory.Files' => $this->classMap, 'Factory.realClasses' => $this->realClasses, ); } @@ -269,8 +320,8 @@ $pseudo_class = $real_class; } - if ( !isset($this->Files[$real_class]) ) { - $this->Files[$real_class] = preg_replace('/^' . preg_quote(FULL_PATH, '/') . '/', '', $file, 1); + if ( !isset($this->classMap[$real_class]) ) { + $this->classMap[$real_class] = preg_replace('/^' . preg_quote(FULL_PATH, '/') . '/', '', $file, 1); } $this->realClasses[$pseudo_class] = $real_class; @@ -286,7 +337,7 @@ */ public function unregisterClass($real_class, $pseudo_class = null) { - unset($this->Files[$real_class]); + unset($this->classMap[$real_class]); } }