TYPO3 API  SVNRelease
class.t3lib_autoloader.php
Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003  *  Copyright notice
00004  *
00005  *  (c) 2008-2011 Dmitry Dulepov <dmitry@typo3.org>
00006  *  All rights reserved
00007  *
00008  *  This script is part of the TYPO3 project. The TYPO3 project is
00009  *  free software; you can redistribute it and/or modify
00010  *  it under the terms of the GNU General Public License as published by
00011  *  the Free Software Foundation; either version 2 of the License, or
00012  *  (at your option) any later version.
00013  *
00014  *  The GNU General Public License can be found at
00015  *  http://www.gnu.org/copyleft/gpl.html.
00016  *  A copy is found in the textfile GPL.txt and important notices to the license
00017  *  from the author is found in LICENSE.txt distributed with these scripts.
00018  *
00019  *
00020  *  This script is distributed in the hope that it will be useful,
00021  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023  *  GNU General Public License for more details.
00024  *
00025  *  This copyright notice MUST APPEAR in all copies of the script!
00026  ***************************************************************/
00027 /**
00028  * Contains TYPO3 autoloader
00029  *
00030  * $Id: class.t3lib_autoloader.php 10121 2011-01-18 20:15:30Z ohader $
00031  *
00032  * @author  Dmitry Dulepov  <dmitry@typo3.org>
00033  * @author  Martin Kutschker <masi@typo3.org>
00034  * @author  Oliver Hader <oliver@typo3.org>
00035  * @author  Sebastian Kurfürst <sebastian@typo3.org>
00036  */
00037 
00038 /**
00039  * This class contains TYPO3 autoloader for classes.
00040  * It handles:
00041  * - the core of TYPO3
00042  * - all extensions with an ext_autoload.php file
00043  */
00044 class t3lib_autoloader {
00045 
00046     /**
00047      * Class name to file mapping. Key: class name. Value: fully qualified file name.
00048      *
00049      * @var array
00050      */
00051     protected static $classNameToFileMapping = array();
00052 
00053     /**
00054      * Associative array which sets for each extension which was attempted to load if it has an autoload configuration
00055      *
00056      * Key: extension key
00057      * Value: TRUE, if extension has an ext_autoload.php and this is already part of $classNameToFileMapping
00058      *        FALSE, if extension has no ext_autoload.php
00059      *
00060      * @var array
00061      */
00062     protected static $extensionHasAutoloadConfiguration = array();
00063 
00064     /**
00065      * The autoloader is static, thus we do not allow instances of this class.
00066      */
00067     private function __construct() {
00068     }
00069 
00070     /**
00071      * Installs TYPO3 autoloader, and loads the autoload registry for the core.
00072      *
00073      * @return  boolean true in case of success
00074      */
00075     static public function registerAutoloader() {
00076         self::loadCoreRegistry();
00077         self::$extensionHasAutoloadConfiguration = array();
00078         return spl_autoload_register('t3lib_autoloader::autoload');
00079     }
00080 
00081     /**
00082      * Uninstalls TYPO3 autoloader. This function is for the sake of completeness.
00083      * It is never called by the TYPO3 core.
00084      *
00085      * @return  boolean true in case of success
00086      */
00087     static public function unregisterAutoloader() {
00088         return spl_autoload_unregister('t3lib_autoloader::autoload');
00089     }
00090 
00091     /**
00092      * Autoload function for TYPO3.
00093      *
00094      * This method looks up class names in the registry
00095      * (which contains extensions and core files)
00096      *
00097      * @param   string  $className  Class name
00098      * @return  void
00099      */
00100     static public function autoload($className) {
00101         $classPath = false;
00102 
00103             // use core and extension registry
00104         $classPath = self::getClassPathByRegistryLookup($className);
00105 
00106         if ($classPath && file_exists($classPath)) {
00107             t3lib_div::requireFile($classPath);
00108         } else {
00109             try {
00110                     // Regular expression for a valid classname taken from
00111                     // http://www.php.net/manual/en/language.oop5.basic.php
00112                 if (preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $className)) {
00113                     spl_autoload($className);
00114                 }
00115             } catch (LogicException $exception) {
00116             }
00117         }
00118     }
00119 
00120     /**
00121      * Load the core registry into $classNameToFileMapping, effectively overriding
00122      * the whole contents of $classNameToFileMapping.
00123      *
00124      * @return void
00125      */
00126     static protected function loadCoreRegistry() {
00127         self::$classNameToFileMapping = require(PATH_t3lib . 'core_autoload.php');
00128     }
00129 
00130     /**
00131      * Get the full path to a class by looking it up in the registry. If not found, returns NULL.
00132      *
00133      * @param   string  $className  Class name
00134      * @return  string  full name of the file where $className is declared, or NULL if no entry found in registry.
00135      */
00136     static protected function getClassPathByRegistryLookup($className) {
00137         $className = strtolower($className);
00138         if (!array_key_exists($className, self::$classNameToFileMapping)) {
00139             self::attemptToLoadRegistryForGivenClassName($className);
00140         }
00141         if (array_key_exists($className, self::$classNameToFileMapping)) {
00142             return self::$classNameToFileMapping[$className];
00143         } else {
00144             return NULL;
00145         }
00146     }
00147 
00148     /**
00149      * Try to load the entries for a given class name into the registry.
00150      *
00151      * First, figures out the extension the class belongs to.
00152      * Then, tries to load the ext_autoload.php file inside the extension directory, and adds its contents to the $classNameToFileMapping.
00153      *
00154      * @param   string  $className  Class Name
00155      */
00156     static protected function attemptToLoadRegistryForGivenClassName($className) {
00157         $classNameParts = explode('_', $className);
00158         $extensionPrefix = array_shift($classNameParts) . '_' . array_shift($classNameParts);
00159         $extensionKey = t3lib_extMgm::getExtensionKeyByPrefix($extensionPrefix);
00160 
00161         if (!$extensionKey || array_key_exists($extensionKey, self::$extensionHasAutoloadConfiguration)) {
00162                 // extension key could not be determined or we already tried to load the extension's autoload configuration
00163             return;
00164         }
00165         $possibleAutoloadConfigurationFileName = t3lib_extMgm::extPath($extensionKey) . 'ext_autoload.php';
00166         if (file_exists($possibleAutoloadConfigurationFileName)) {
00167             self::$extensionHasAutoloadConfiguration[$extensionKey] = TRUE;
00168             $extensionClassNameToFileMapping = require($possibleAutoloadConfigurationFileName);
00169             self::$classNameToFileMapping = array_merge($extensionClassNameToFileMapping, self::$classNameToFileMapping);
00170         } else {
00171             self::$extensionHasAutoloadConfiguration[$extensionKey] = FALSE;
00172         }
00173     }
00174 }
00175 ?>