[TASK] Clean up XCLASS handling and comments
authorChristian Kuhn <lolli@schwarzbu.ch>
Sun, 29 Apr 2012 10:45:30 +0000 (12:45 +0200)
committerChristian Kuhn <lolli@schwarzbu.ch>
Sun, 29 Apr 2012 11:07:15 +0000 (13:07 +0200)
Clean up some of the comments of the new XCLASS handling, separate
the deprecation handling to an own method and add a NEWS.txt entry.

Change-Id: I16a828e15c8e3d347b8b331ffb554ac42aa82644
Resolves: #36698
Related: #31893
Releases: 6.0
Reviewed-on: http://review.typo3.org/10865
Reviewed-by: Christian Kuhn
Tested-by: Christian Kuhn
NEWS.txt
t3lib/cache/class.t3lib_cache_factory.php
t3lib/class.t3lib_autoloader.php
t3lib/class.t3lib_cache.php
t3lib/class.t3lib_div.php
t3lib/config_default.php

index 00a91a3..e9a0133 100644 (file)
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -27,6 +27,18 @@ functionality is now encapsulated in EXT:belog itself. Since it is very
 unlikely that the class was used by other external extensions, the file was
 removed instead of deprecating it.
 
+* New XCLASS handling
+
+The old way of registering XCLASSes in $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS'] is
+deprecated. XCLASSES can now be registered by adding a 'ux_' prefixed entry of
+the base class to the ext_autoload.php file providing the XCLASS path. The
+deprecation layer for old class registration can potentially calculate a wrong
+path so the XCLASS registration can fail now. This can be fixed by addiononally
+using the new registration scheme through ext_autoload.
+Extension authors are advised to remove the three line XCLASS statement at the
+bottom of class files now for any extension with a compatibility for 6.0 and above.
+More information can be found at http://wiki.typo3.org/Autoload
+
 Removed Functionality
 -------------------------------------------------------------------------------
 
index 3f1f939..6036886 100644 (file)
@@ -80,8 +80,12 @@ class t3lib_cache_Factory implements t3lib_Singleton {
         * @api
         */
        public function create($cacheIdentifier, $cacheObjectName, $backendObjectName, array $backendOptions = array()) {
+                       // This class is required so early during bootstrap that makeInstance()
+                       // can not be used, so new operator is used directly and the class
+                       // lookup entry is added manually to the makeInstanceCache
                $backend = new $backendObjectName($this->context, $backendOptions);
                t3lib_div::addClassNameToMakeInstanceCache($backendObjectName, $backendObjectName);
+
                if (!$backend instanceof t3lib_cache_backend_Backend) {
                        throw new t3lib_cache_exception_InvalidBackend(
                                '"' . $backendObjectName . '" is not a valid cache backend object.',
@@ -92,8 +96,10 @@ class t3lib_cache_Factory implements t3lib_Singleton {
                        $backend->initializeObject();
                }
 
+                       // new used on purpose, see comment above
                $cache = new $cacheObjectName($cacheIdentifier, $backend);
                t3lib_div::addClassNameToMakeInstanceCache($cacheObjectName, $cacheObjectName);
+
                if (!$cache instanceof t3lib_cache_frontend_Frontend) {
                        throw new t3lib_cache_exception_InvalidCache(
                                '"' . $cacheObjectName . '" is not a valid cache frontend object.',
index 66b68fc..1d7e5ef 100644 (file)
@@ -31,6 +31,7 @@
  * - The core of TYPO3
  * - All extensions with an ext_autoload.php file
  * - All extensions that stick to the 'extbase' like naming convention
+ * - Resolves registered XCLASSes
  *
  * @author Dmitry Dulepov <dmitry@typo3.org>
  * @author Martin Kutschker <masi@typo3.org>
@@ -94,9 +95,8 @@ class t3lib_autoloader {
                $classPath = self::getClassPathByRegistryLookup($className);
 
                if ($classPath) {
-                               // include the required file that holds the class
+                               // Include the required file that holds the class
                        t3lib_div::requireFile($classPath);
-
                } else {
                        try {
                                        // Regular expression for a valid classname taken from
@@ -118,7 +118,7 @@ class t3lib_autoloader {
        protected static function loadCoreAndExtensionRegistry() {
                $phpCodeCache = $GLOBALS['typo3CacheManager']->getCache('cache_phpcode');
 
-                       // Create autoloader cache file if it does not exist yet
+                       // Create autoload cache file if it does not exist yet
                if (!$phpCodeCache->has(self::getAutoloadCacheIdentifier())) {
                        $classRegistry = self::createCoreAndExtensionRegistry();
                        self::updateRegistryCacheEntry($classRegistry);
@@ -144,52 +144,44 @@ class t3lib_autoloader {
         * Get the full path to a class by looking it up in the registry.
         * If not found, returns NULL.
         *
+        * Warning: This method is public as it is needed by t3lib_div::makeInstance(),
+        * but it is _not_ part of the public API and should not be used in own extensions!
+        *
         * @param string $className Class name to find source file of
         * @return mixed If String: Full name of the file where $className is declared, NULL if no entry is found
+        * @internal
         */
        public static function getClassPathByRegistryLookup($className) {
                $classPath = NULL;
                $classNameLower = strtolower($className);
 
+                       // Try to resolve extbase naming scheme if class is not already in cache file
                if (!array_key_exists($classNameLower, self::$classNameToFileMapping)) {
                        self::attemptToLoadRegistryWithNamingConventionForGivenClassName($className);
                }
 
+                       // Look up class name in cache file
                if (array_key_exists($classNameLower, self::$classNameToFileMapping)) {
                        $classPath = self::$classNameToFileMapping[$classNameLower];
                }
 
-               /***************************************************************************
-                * The following source is only to support the old way of XCLASS inclusions
-                *
-                * Backwards-compatibility layer to include old XCLASS statements
-                * that are set via TYPO3_CONF_VARS[TYPO3_MODE][relativePathToFile] = extPath
-                **************************************************************************/
-                       // @todo Add ALL classes (like EXT:about/mod/index.php to the autoloader
-                       // Problem: EXT:about cannot be XCLASSed because the autoloader is not able to find the right path
-                       // Solution:
-                       //              - typo3/sysext/about/mod/index.php must be added to typo3/sysext/about/mod/ext_autoload.php
-                       //              - Have a look at the end of typo3/sysext/about/mod/index.php for the right XCLASS inclusion code
-                       //                      and replace it in this autoload logic. Have a look where is $relativeClassPath build
-                       //                      e.g. sysext/about/mod => typo3/mod/help/about'
+                       // Handle deprecated XCLASS lookups
+               $classPath = self::classPathForDeprecatedXclassHandling($classPath, $classNameLower);
 
-                       // If an XCLASS was requested for autoloading, the autoloader has to know which class will be extended
-                       // only with this information it is possible to get the "relative path" of the extended class.
-                       // The "relative path" is needed to simulate the correct path for $GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS'][$relativePath]
-                       // "relative path" is in quotes, because this is not every time the case. Often we have special cases like EXT:about
-                       // The old way to include an XCLASS is defined by such a piece of code at the end of a class:
-                       //
-                       // if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_beuserauth.php'])) {
-                       //              include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_beuserauth.php']);
-                       // }
-                       //
-                       // This kind of XCLASS inclusion is deprecated now and can be deleted in TYPO3 6.2.
-                       // The whole XCLASS magic is AFTER the autoloading magic from Extbase, because Extbase classes are extended
-                       // by another way
+               return $classPath;
+       }
 
-                       // If a class could not be found in the autoloader cache AND an XCLASS is requested by the autoloader
-                       // remove the first XCLASS prefix ("ux_") to get the class which will be extended.
-                       // With this way we support recursive XCLASSing ("ux_ux_ux_...").
+       /**
+        * Resolve 'old' XCLASS registrations from TYPO3_CONF_VARS
+        *
+        * @param string $classPath The current class path from previous lookup
+        * @param string $classNameLower Lower cased class name to be looked up
+        * @return string Class path
+        * @deprecated since 6.0, deprecation log is handled in config_default. This method and the call can be safely removed in two versions
+        */
+       protected static function classPathForDeprecatedXclassHandling($classPath, $classNameLower) {
+                       // Start XCLASS handling if the requested class starts with 'ux_'
+                       // If so, we need to resolve the base class first
                        // e.g. ux_t3lib_beuserauth => t3lib_beuserauth
                $baseClassOfXClass = NULL;
                $xClassRequested = FALSE;
@@ -198,29 +190,31 @@ class t3lib_autoloader {
                        $xClassRequested = TRUE;
                }
 
-                       // At this point we know the class which will be extended by the XCLASS and
-                       // try to find the base class in the autoloader again.
-                       // This has to be the second try, because at the first time (a few lines before)
-                       // try to find the XCLASS in the autoloader cache
+                       // If a XCLASS was requested for autoloading, the autoloader has to know which class will be extended.
+                       // only with this information it is possible to get the "relative path" of the extended class.
+                       // The "relative path" is needed to simulate the correct path for $GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS'][$relativePath]
+                       // "relative path" is in quotes, because this is not every time the case.
+                       // The old way to include an XCLASS is defined by such a piece of code at the end of a class:
+                       //
+                       // if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_beuserauth.php'])) {
+                       //              include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_beuserauth.php']);
+                       // }
                if ($classPath === NULL && array_key_exists($baseClassOfXClass, self::$classNameToFileMapping)) {
                        $classPath = self::$classNameToFileMapping[$baseClassOfXClass];
                }
 
-                       // If we got a physical path of the base class which will be extended by the requested XCLASS
-                       // AND an XCLASS is requested by the autoloader
-                       // AND in this TYPO3 installation make use of XCLASSes in general
-                       // then we try to determine the "relative path" for the old XCLASS way
-                       // e.g. "t3lib/class.t3lib_beuserauth.php" of
+                       // Try to determine the relative class for the old XCLASS, if:
+                       // - We got a physical path for the base class
+                       // - An xclass was requested
+                       // - The old way of xclassing is still used
                        // $GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_beuserauth.php']
                if ($classPath !== NULL && $xClassRequested === TRUE && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS'])) {
 
                                // Check if the XCLASS for the requested path is set  a transformation for some paths needs to be done
                        $relativeClassPath = substr($classPath, strlen(PATH_site));
 
-                               // @todo the complete replacing list is not complete right now. e.g. typo3/systext/filelist, ...
-
-                               // Replacement for sysext "about"
-                               // @todo Which modules are affected? Which modules was moved from typo3/mod to another location?
+                               // Replacements for some special cases
+                               // @TODO: This layer should be adapted / finished for further special core cases
                        $relativeClassPath = str_replace(
                                array(
                                        'sysext/about/mod',
@@ -238,41 +232,37 @@ class t3lib_autoloader {
                        );
 
                        if (isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS'][$relativeClassPath])) {
+                                       // If a class path was found: Set it and add to cache file
                                $classPath = $GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS'][$relativeClassPath];
                                self::addClassToCache(PATH_site . $classPath, $classNameLower);
                        } else {
-
-                                       // If an XCLASS is requested (this is the normal case, for every class min. one time,
-                                       // see t3lib_div::getClassName for more information) AND no XLASS was definied
+                                       // If an XCLASS was requested AND no XLASS was found,
                                        // $classPath is filled with the path of the class which will be extended.
-                                       // Because withoud the $classPath of base class, we can not determine the "relative path"
-                                       // to find the correct XCLASS.
                                        //
                                        // If no XCLASS is defined, we set $classPath to NULL, because otherwise the autoloader will
-                                       // be load the same class twice (the autoloader use "require" instead of "require_once")
+                                       // load the same class twice
                                        //
-                                       // A small example:
-                                       // Something requested ux_t3lib_l10n_locales. This class will be not find in the autoloader cache.
+                                       // Example:
+                                       // Autoload ux_t3lib_l10n_locales. This class will be not find in the autoloader cache.
                                        // After this, we try to determine the path of base class, in our case t3lib_l10n_locales
                                        // (to determine the relative class for old XCLASS inclusion).
                                        // So we determine the relative path ob the base class ('t3lib/l10n/class.t3lib_l10n_locales.php')
-                                       // and have a look up for definied XCLASSes of t3lib_l10n_locales
+                                       // and have a look up for defined XCLASSes of t3lib_l10n_locales
                                        // ($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/l10n/class.t3lib_l10n_locales.php'])
                                        // If we found one XCLASS, we will return the physical path of this class
                                        // If no XCLASS was found, we MUST set $classPath to NULL
                                        // Without this step the physical path of t3lib_l10n_locales will be returned and a
-                                       // "Cannot redeclear class t3lib_l10n_locales"-Error will occur
+                                       // "Cannot re-declare class t3lib_l10n_locales"-Error will occur
                                $classPath = NULL;
                        }
                }
-
                return $classPath;
        }
 
        /**
         * Find all ext_autoload files and merge with core_autoload.
         *
-        * @return void
+        * @return array
         */
        protected static function createCoreAndExtensionRegistry() {
                $classRegistry = require(PATH_t3lib . 'core_autoload.php');
index a09be08..855bf5b 100644 (file)
@@ -44,10 +44,12 @@ class t3lib_cache {
         */
        public static function initializeCachingFramework() {
                if (!self::isCachingFrameworkInitialized()) {
+                               // new operator used on purpose, makeInstance() is not ready to be used so early in bootstrap
                        $GLOBALS['typo3CacheManager'] = new t3lib_cache_Manager();
                        t3lib_div::setSingletonInstance('t3lib_cache_Manager', $GLOBALS['typo3CacheManager']);
                        t3lib_div::addClassNameToMakeInstanceCache('t3lib_cache_Manager', 't3lib_cache_Manager');
                        $GLOBALS['typo3CacheManager']->setCacheConfigurations($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']);
+                               // new operator used on purpose, makeInstance() is not ready to be used so early in bootstrap
                        $GLOBALS['typo3CacheFactory'] = new t3lib_cache_Factory('production', $GLOBALS['typo3CacheManager']);
                        t3lib_div::setSingletonInstance('t3lib_cache_Factory', $GLOBALS['typo3CacheFactory']);
                        t3lib_div::addClassNameToMakeInstanceCache('t3lib_cache_Factory', 't3lib_cache_Factory');
index 7eac225..b12a8e3 100644 (file)
@@ -4541,12 +4541,15 @@ final class t3lib_div {
         * If this function is called multiple times for the same $className,
         * makeInstance will return the last set instance.
         *
+        * Warning: This is _not_ a public API method and must not be used in own extensions!
+        *
         * @see makeInstance
         * @param string $className
         *        the name of the class to set, must not be empty
         * @param t3lib_Singleton $instance
         *        the instance to set, must be an instance of $className
         * @return void
+        * @internal
         */
        public static function setSingletonInstance($className, t3lib_Singleton $instance) {
                self::checkInstanceClassName($className, $instance);
@@ -4557,11 +4560,13 @@ final class t3lib_div {
         * Adds a $className / $finalClassName to the cache register.
         * This register is used to determine the final class name only once instead of multiple times.
         *
-        * @static
+        * Warning: This is _not_ a public API method and must not be used in own extensions!
+        *
         * @see makeInstance
         * @param string $className the name of the class to set, must not be empty
         * @param string $finalClassName the name of the final class which will be loaded in case of $className
         * @return void
+        * @internal
         */
        public static function addClassNameToMakeInstanceCache($className, $finalClassName) {
                self::$finalClassNameRegister[$className] = $finalClassName;
index 70cfb7e..c44453b 100644 (file)
@@ -1083,15 +1083,8 @@ if ($TYPO3_LOADED_EXT['_CACHEFILE'])     {
        }
 }
 
-       // Here we check if this TYPO3 installation uses XCLASSes via the deprecated way
-       // If is this the case throw deprecation warning, as the ext_autoload.php way is the preferred way now
-       // This deprecation warning must be thrown here, because of two points
-       // 1. Only one warning will be called per page impression. If you throw this warning in
-       //        t3lib_autoloader::getClassPathByRegistryLookup, it will be thrown for EVERY requested class
-       // 2. It is not possible to throw this warning in t3lib_autoloader::getClassPathByRegistryLookup
-       //        because t3lib_div::deprecationLog use t3lib_div::makeInstance again and will be call
-       //        t3lib_autoloader::getClassPathByRegistryLookup again. This will be end in an endlessloop.
-       // So, after loading all ext_localconf.php`s it will be clear if XCLASSes are used by the old way.
+       // Write deprecation log  the TYPO3 instance uses deprecated XCLASSes registrations
+       // via the deprecated way $GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']
 if(isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']) === TRUE) {
        t3lib_div::deprecationLog('This installation runs with extensions that use XCLASSing by setting the XCLASS path in ext_localconf.php. This backwards compatibility will be removed in TYPO3 6.2 and later. It is preferred to define XCLASSes in ext_autoload.php instead.');
 }