Fixed bug #15383: [Unit tests] Add tests for t3lib_div::validEmail
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_autoloader.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2008-2010 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 // Regular expression for a valid classname taken from
111 // http://www.php.net/manual/en/language.oop5.basic.php
112 if (preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $className)) {
113 spl_autoload($className);
114 }
115 } catch (LogicException $exception) {
116 }
117 }
118
119 if (!class_exists($className, false) && !interface_exists($className, false)) {
120 self::logLoadingFailure($className);
121 }
122 }
123
124 /**
125 * Load the core registry into $classNameToFileMapping, effectively overriding
126 * the whole contents of $classNameToFileMapping.
127 *
128 * @return void
129 */
130 static protected function loadCoreRegistry() {
131 self::$classNameToFileMapping = require(PATH_t3lib . 'core_autoload.php');
132 }
133
134 /**
135 * Get the full path to a class by looking it up in the registry. If not found, returns NULL.
136 *
137 * @param string $className Class name
138 * @return string full name of the file where $className is declared, or NULL if no entry found in registry.
139 */
140 static protected function getClassPathByRegistryLookup($className) {
141 $className = strtolower($className);
142 if (!array_key_exists($className, self::$classNameToFileMapping)) {
143 self::attemptToLoadRegistryForGivenClassName($className);
144 }
145 if (array_key_exists($className, self::$classNameToFileMapping)) {
146 return self::$classNameToFileMapping[$className];
147 } else {
148 return NULL;
149 }
150 }
151
152 /**
153 * Try to load the entries for a given class name into the registry.
154 *
155 * First, figures out the extension the class belongs to.
156 * Then, tries to load the ext_autoload.php file inside the extension directory, and adds its contents to the $classNameToFileMapping.
157 *
158 * @param string $className Class Name
159 */
160 static protected function attemptToLoadRegistryForGivenClassName($className) {
161 $classNameParts = explode('_', $className);
162 $extensionPrefix = array_shift($classNameParts) . '_' . array_shift($classNameParts);
163 $extensionKey = t3lib_extMgm::getExtensionKeyByPrefix($extensionPrefix);
164
165 if (!$extensionKey || array_key_exists($extensionKey, self::$extensionHasAutoloadConfiguration)) {
166 // extension key could not be determined or we already tried to load the extension's autoload configuration
167 return;
168 }
169 $possibleAutoloadConfigurationFileName = t3lib_extMgm::extPath($extensionKey) . 'ext_autoload.php';
170 if (file_exists($possibleAutoloadConfigurationFileName)) {
171 self::$extensionHasAutoloadConfiguration[$extensionKey] = TRUE;
172 $extensionClassNameToFileMapping = require($possibleAutoloadConfigurationFileName);
173 self::$classNameToFileMapping = array_merge($extensionClassNameToFileMapping, self::$classNameToFileMapping);
174 } else {
175 self::$extensionHasAutoloadConfiguration[$extensionKey] = FALSE;
176 }
177 }
178
179 /**
180 * Logs error message about failed autoloading
181 *
182 * @param string $className Class name
183 * @param string $filePath File name
184 * @return void
185 */
186 static protected function logLoadingFailure($className) {
187 $message = sprintf('Unable to autoload class "%s"', $className);
188 t3lib_div::sysLog($message, 'Core', 4);
189 if (TYPO3_DLOG) {
190 t3lib_div::devLog($message, 'Core', 3);
191 }
192 }
193 }
194
195
196 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_autoload.php']) {
197 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_autoload.php']);
198 }
199
200 ?>