[TASK] Remove XCLASS definitions from cache classes
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_autoloader.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2008-2011 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 /**
29 * This class contains TYPO3 autoloader for classes.
30 * It handles:
31 * - the core of TYPO3
32 * - all extensions with an ext_autoload.php file
33 *
34 * @author Dmitry Dulepov <dmitry@typo3.org>
35 * @author Martin Kutschker <masi@typo3.org>
36 * @author Oliver Hader <oliver@typo3.org>
37 * @author Sebastian Kurf├╝rst <sebastian@typo3.org>
38 */
39 class t3lib_autoloader {
40
41 /**
42 * Class name to file mapping. Key: class name. Value: fully qualified file name.
43 *
44 * @var array
45 */
46 protected static $classNameToFileMapping = array();
47
48 /**
49 * The autoloader is static, thus we do not allow instances of this class.
50 */
51 private function __construct() {
52 }
53
54 /**
55 * Installs TYPO3 autoloader, and loads the autoload registry for the core.
56 *
57 * @return boolean TRUE in case of success
58 */
59 public static function registerAutoloader() {
60 self::loadCoreAndExtensionRegistry();
61 return spl_autoload_register('t3lib_autoloader::autoload', TRUE, TRUE);
62 }
63
64 /**
65 * Uninstalls TYPO3 autoloader. This function is for the sake of completeness.
66 * It is never called by the TYPO3 core.
67 *
68 * @return boolean TRUE in case of success
69 */
70 public static function unregisterAutoloader() {
71 return spl_autoload_unregister('t3lib_autoloader::autoload');
72 }
73
74 /**
75 * Autoload function for TYPO3.
76 *
77 * This method looks up class names in the registry
78 * (which contains extensions and core files)
79 *
80 * @param string $className Class name
81 * @return void
82 */
83 public static function autoload($className) {
84 // Use core and extension registry
85 $classPath = self::getClassPathByRegistryLookup($className);
86
87 if ($classPath) {
88 t3lib_div::requireFile($classPath);
89 } else {
90 try {
91 // Regular expression for a valid classname taken from
92 // http://www.php.net/manual/en/language.oop5.basic.php
93 if (preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $className)) {
94 spl_autoload($className);
95 }
96 } catch (LogicException $exception) {
97 }
98 }
99 }
100
101 /**
102 * Load registry from cache file if available or search
103 * for all loaded extensions and create a cache file
104 *
105 * @return void
106 */
107 public static function loadCoreAndExtensionRegistry() {
108 $phpCodeCache = $GLOBALS['typo3CacheManager']->getCache('cache_phpcode');
109 $autoloadCacheIdentifier = TYPO3_MODE === 'FE' ? 't3lib_autoload_FE' : 't3lib_autoload_BE';
110
111 // Create autoloader cache file if it does not exist yet
112 if (!$phpCodeCache->has($autoloadCacheIdentifier)) {
113 $classRegistry = self::createCoreAndExtensionRegistry();
114 $cachedFileContent = 'return array(';
115 foreach ($classRegistry as $className => $classLocation) {
116 $cachedFileContent .= chr(10) . '\'' . $className . '\' => \'' . $classLocation . '\',';
117 }
118 $cachedFileContent .= chr(10) . ');';
119 $phpCodeCache->set($autoloadCacheIdentifier, $cachedFileContent, array('t3lib_autoloader'));
120 }
121
122 // Require calculated cache file
123 $mappingArray = $phpCodeCache->requireOnce($autoloadCacheIdentifier);
124
125 // This can only happen if the autoloader was already registered
126 // in the same call once, the requireOnce of the cache file then
127 // does not give the cached array back. In this case we just read
128 // all cache entries manually again.
129 // This should only happen in unit tests
130 if (!is_array($mappingArray)) {
131 $mappingArray = self::createCoreAndExtensionRegistry();
132 }
133
134 self::$classNameToFileMapping = $mappingArray;
135 }
136
137 /**
138 * Get the full path to a class by looking it up in the registry.
139 * If not found, returns NULL.
140 *
141 * @param string $className Class name
142 * @return string Full name of the file where $className is declared, or NULL if no entry found in registry.
143 */
144 protected static function getClassPathByRegistryLookup($className) {
145 $className = strtolower($className);
146 if (array_key_exists($className, self::$classNameToFileMapping)) {
147 return self::$classNameToFileMapping[$className];
148 } else {
149 return NULL;
150 }
151 }
152
153 /**
154 * Find all ext_autoload files and merge with core_autoload.
155 *
156 * @return void
157 */
158 protected static function createCoreAndExtensionRegistry() {
159 $classRegistry = require(PATH_t3lib . 'core_autoload.php');
160 // At this point localconf.php was already initialized
161 // we have a current extList and extMgm is also known
162 $loadedExtensions = array_unique(t3lib_div::trimExplode(',', t3lib_extMgm::getEnabledExtensionList(), TRUE));
163 foreach ($loadedExtensions as $extensionKey) {
164 $extensionAutoloadFile = t3lib_extMgm::extPath($extensionKey, 'ext_autoload.php');
165 if (file_exists($extensionAutoloadFile)) {
166 $classRegistry = array_merge($classRegistry, require($extensionAutoloadFile));
167 }
168 }
169 return $classRegistry;
170 }
171 }
172 ?>