43f1dc2f71bb11f121b46a5464c86c0ae17b9f54
[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 require $classPath;
108 } else {
109 spl_autoload($className);
110 }
111
112 if (!class_exists($className, false)) {
113 self::logLoadingFailure($className);
114 }
115 }
116
117 /**
118 * Load the core registry into $classNameToFileMapping, effectively overriding
119 * the whole contents of $classNameToFileMapping.
120 *
121 * @return void
122 */
123 static protected function loadCoreRegistry() {
124 self::$classNameToFileMapping = require(PATH_t3lib . 'core_autoload.php');
125 }
126
127 /**
128 * Get the full path to a class by looking it up in the registry. If not found, returns NULL.
129 *
130 * @param string $className Class name
131 * @return string full name of the file where $className is declared, or NULL if no entry found in registry.
132 */
133 static protected function getClassPathByRegistryLookup($className) {
134 $className = strtolower($className);
135 if (!array_key_exists($className, self::$classNameToFileMapping)) {
136 self::attemptToLoadRegistryForGivenClassName($className);
137 }
138 if (array_key_exists($className, self::$classNameToFileMapping)) {
139 return self::$classNameToFileMapping[$className];
140 } else {
141 return NULL;
142 }
143 }
144
145 /**
146 * Try to load the entries for a given class name into the registry.
147 *
148 * First, figures out the extension the class belongs to.
149 * Then, tries to load the ext_autoload.php file inside the extension directory, and adds its contents to the $classNameToFileMapping.
150 *
151 * @param string $className Class Name
152 */
153 static protected function attemptToLoadRegistryForGivenClassName($className) {
154 $classNameParts = explode('_', $className);
155 $extensionPrefix = array_shift($classNameParts) . '_' . array_shift($classNameParts);
156 $extensionKey = t3lib_extMgm::getExtensionKeyByPrefix($extensionPrefix);
157
158 if (!$extensionKey || array_key_exists($extensionKey, self::$extensionHasAutoloadConfiguration)) {
159 // extension key could not be determined or we already tried to load the extension's autoload configuration
160 return;
161 }
162 $possibleAutoloadConfigurationFileName = t3lib_extMgm::extPath($extensionKey) . 'ext_autoload.php';
163 if (file_exists($possibleAutoloadConfigurationFileName)) {
164 self::$extensionHasAutoloadConfiguration[$extensionKey] = TRUE;
165 $extensionClassNameToFileMapping = require($possibleAutoloadConfigurationFileName);
166 self::$classNameToFileMapping = array_merge($extensionClassNameToFileMapping, self::$classNameToFileMapping);
167 } else {
168 self::$extensionHasAutoloadConfiguration[$extensionKey] = FALSE;
169 }
170 }
171
172 /**
173 * Logs error message about failed autoloading
174 *
175 * @param string $className Class name
176 * @param string $filePath File name
177 * @return void
178 */
179 static protected function logLoadingFailure($className) {
180 $message = sprintf('Unable to autoload class "%s"', $className);
181 t3lib_div::sysLog($message, 'Core', 4);
182 if (TYPO3_DLOG) {
183 t3lib_div::devLog($message, 'Core', 3);
184 }
185 }
186 }
187
188
189 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_autoload.php']) {
190 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_autoload.php']);
191 }
192
193 ?>