Fixed bug #13487: No alternative icon returned from 'getIcon' (thanks to Stephan...
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_autoloader.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2008-2009 Dmitry Dulepov <dmitry@typo3.org>
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 /**
28 * Contains TYPO3 autoloader
29 *
30 * $Id$
31 *
32 * @author Dmitry Dulepov <dmitry@typo3.org>
33 * @author Martin Kutschker <masi@typo3.org>
34 * @author Oliver Hader <oliver@typo3.org>
35 * @author Sebastian Kurfuerst <sebastian@typo3.org>
36 */
37
38 /**
39 * This class contains TYPO3 autoloader for classes.
40 * It handles:
41 * - the core of TYPO3
42 * - all extensions with an ext_autoload.php file
43 */
44 class t3lib_autoloader {
45
46 /**
47 * Class name to file mapping. Key: class name. Value: fully qualified file name.
48 *
49 * @var array
50 */
51 protected static $classNameToFileMapping = array();
52
53 /**
54 * Associative array which sets for each extension which was attempted to load if it has an autoload configuration
55 *
56 * Key: extension key
57 * Value: TRUE, if extension has an ext_autoload.php and this is already part of $classNameToFileMapping
58 * FALSE, if extension has no ext_autoload.php
59 *
60 * @var array
61 */
62 protected static $extensionHasAutoloadConfiguration = array();
63
64 /**
65 * The autoloader is static, thus we do not allow instances of this class.
66 */
67 private function __construct() {
68 }
69
70 /**
71 * Installs TYPO3 autoloader, and loads the autoload registry for the core.
72 *
73 * @return boolean true in case of success
74 */
75 static public function registerAutoloader() {
76 self::loadCoreRegistry();
77 self::$extensionHasAutoloadConfiguration = array();
78 return spl_autoload_register('t3lib_autoloader::autoload');
79 }
80
81 /**
82 * Uninstalls TYPO3 autoloader. This function is for the sake of completeness.
83 * It is never called by the TYPO3 core.
84 *
85 * @return boolean true in case of success
86 */
87 static public function unregisterAutoloader() {
88 return spl_autoload_unregister('t3lib_autoloader::autoload');
89 }
90
91 /**
92 * Autoload function for TYPO3.
93 *
94 * This method looks up class names in the registry
95 * (which contains extensions and core files)
96 *
97 * @param string $className Class name
98 * @return void
99 */
100 static public function autoload($className) {
101 $classPath = false;
102
103 // use core and extension registry
104 $classPath = self::getClassPathByRegistryLookup($className);
105
106 if ($classPath && file_exists($classPath)) {
107 t3lib_div::requireFile($classPath);
108 } else {
109 try {
110 spl_autoload($className);
111 } catch (LogicException $exception) {
112 }
113 }
114
115 if (!class_exists($className, false) && !interface_exists($className, false)) {
116 self::logLoadingFailure($className);
117 }
118 }
119
120 /**
121 * Load the core registry into $classNameToFileMapping, effectively overriding
122 * the whole contents of $classNameToFileMapping.
123 *
124 * @return void
125 */
126 static protected function loadCoreRegistry() {
127 self::$classNameToFileMapping = require(PATH_t3lib . 'core_autoload.php');
128 }
129
130 /**
131 * Get the full path to a class by looking it up in the registry. If not found, returns NULL.
132 *
133 * @param string $className Class name
134 * @return string full name of the file where $className is declared, or NULL if no entry found in registry.
135 */
136 static protected function getClassPathByRegistryLookup($className) {
137 $className = strtolower($className);
138 if (!array_key_exists($className, self::$classNameToFileMapping)) {
139 self::attemptToLoadRegistryForGivenClassName($className);
140 }
141 if (array_key_exists($className, self::$classNameToFileMapping)) {
142 return self::$classNameToFileMapping[$className];
143 } else {
144 return NULL;
145 }
146 }
147
148 /**
149 * Try to load the entries for a given class name into the registry.
150 *
151 * First, figures out the extension the class belongs to.
152 * Then, tries to load the ext_autoload.php file inside the extension directory, and adds its contents to the $classNameToFileMapping.
153 *
154 * @param string $className Class Name
155 */
156 static protected function attemptToLoadRegistryForGivenClassName($className) {
157 $classNameParts = explode('_', $className);
158 $extensionPrefix = array_shift($classNameParts) . '_' . array_shift($classNameParts);
159 $extensionKey = t3lib_extMgm::getExtensionKeyByPrefix($extensionPrefix);
160
161 if (!$extensionKey || array_key_exists($extensionKey, self::$extensionHasAutoloadConfiguration)) {
162 // extension key could not be determined or we already tried to load the extension's autoload configuration
163 return;
164 }
165 $possibleAutoloadConfigurationFileName = t3lib_extMgm::extPath($extensionKey) . 'ext_autoload.php';
166 if (file_exists($possibleAutoloadConfigurationFileName)) {
167 self::$extensionHasAutoloadConfiguration[$extensionKey] = TRUE;
168 $extensionClassNameToFileMapping = require($possibleAutoloadConfigurationFileName);
169 self::$classNameToFileMapping = array_merge($extensionClassNameToFileMapping, self::$classNameToFileMapping);
170 } else {
171 self::$extensionHasAutoloadConfiguration[$extensionKey] = FALSE;
172 }
173 }
174
175 /**
176 * Logs error message about failed autoloading
177 *
178 * @param string $className Class name
179 * @param string $filePath File name
180 * @return void
181 */
182 static protected function logLoadingFailure($className) {
183 $message = sprintf('Unable to autoload class "%s"', $className);
184 t3lib_div::sysLog($message, 'Core', 4);
185 if (TYPO3_DLOG) {
186 t3lib_div::devLog($message, 'Core', 3);
187 }
188 }
189 }
190
191
192 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_autoload.php']) {
193 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_autoload.php']);
194 }
195
196 ?>