From 9090ae4bf58c131a4f500a894909fc21b91dec37 Mon Sep 17 00:00:00 2001
From: Christian Kuhn <lolli@schwarzbu.ch>
Date: Fri, 11 May 2012 19:52:04 +0200
Subject: [PATCH] [FEATURE] Allow camelCased class names in ext_autoload

Remove the hurdle that class names in ext_autoload (the key part of
the returned array) have to be lower cased.

The patch adds two tests, the first one expects that a case sensitive
class name in ext_autoload.php in actually lowercases before it is
written to the autoload cache file. It fails if the autoloader patch
is not applied.
The second tests that camel cased classes can be successfully autoloaded.

Change-Id: I2ccf916d43a288a520f6f89e9002bdc4df2da0b2
Resolves: #37110
Releases: 6.0
Reviewed-on: http://review.typo3.org/11148
Reviewed-by: Tolleiv Nietsch
Tested-by: Tolleiv Nietsch
Reviewed-by: Philipp Gampe
Reviewed-by: Benjamin Mack
Tested-by: Benjamin Mack
---
 t3lib/class.t3lib_autoloader.php              |  2 +-
 .../Unit/t3lib/class.t3lib_autoloaderTest.php | 58 +++++++++++++++++++
 2 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/t3lib/class.t3lib_autoloader.php b/t3lib/class.t3lib_autoloader.php
index fc432268a4a1..f641ae01b0e2 100644
--- a/t3lib/class.t3lib_autoloader.php
+++ b/t3lib/class.t3lib_autoloader.php
@@ -324,7 +324,7 @@ class t3lib_autoloader {
 	protected static function updateRegistryCacheEntry(array $registry) {
 		$cachedFileContent = 'return array(';
 		foreach ($registry as $className => $classLocation) {
-			$cachedFileContent .= LF . '\'' . $className . '\' => \'' . $classLocation . '\',';
+			$cachedFileContent .= LF . '\'' . strtolower($className) . '\' => \'' . $classLocation . '\',';
 		}
 		$cachedFileContent .= LF . ');';
 		$GLOBALS['typo3CacheManager']->getCache('cache_phpcode')->set(
diff --git a/tests/Unit/t3lib/class.t3lib_autoloaderTest.php b/tests/Unit/t3lib/class.t3lib_autoloaderTest.php
index 4ddd0fa09bfb..aae0643883dc 100644
--- a/tests/Unit/t3lib/class.t3lib_autoloaderTest.php
+++ b/tests/Unit/t3lib/class.t3lib_autoloaderTest.php
@@ -161,6 +161,64 @@ class t3lib_autoloaderTest extends Tx_Phpunit_TestCase {
 		t3lib_autoloader::autoload($class);
 	}
 
+	/**
+	 * @test
+	 */
+	public function autoloadWritesLowerCasedClassFileToCache() {
+		$extKey = $this->createFakeExtension();
+		$extPath = PATH_site . "typo3temp/$extKey/";
+		$autoloaderFile = $extPath . "ext_autoload.php";
+
+			// A case sensitive key (FooBar) in ext_autoload file
+		$class = "tx_${extKey}_" . uniqid('FooBar');
+		$file = $extPath . uniqid('') . '.php';
+
+		file_put_contents($autoloaderFile, "<?php\n\nreturn array('$class' => '$file');\n\n?>");
+
+			// Inject a dummy for the core_phpcode cache to force the autoloader
+			// to re calculate the registry
+		$mockCache = $this->getMock('t3lib_cache_frontend_AbstractFrontend', array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'), array(), '', FALSE);
+		$GLOBALS['typo3CacheManager'] = $this->getMock('t3lib_cache_Manager', array('getCache'));
+		$GLOBALS['typo3CacheManager']->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
+
+			// Expect that the lower case version of the class name is written to cache
+		$mockCache->expects($this->once())->method('set')->with($this->anything(), $this->stringContains(strtolower($class), FALSE));
+
+			// Re-initialize autoloader registry to force it to recognize the new extension
+		t3lib_autoloader::unregisterAutoloader();
+		t3lib_autoloader::registerAutoloader();
+	}
+
+	/**
+	 * @test
+	 * @expectedException RuntimeException
+	 */
+	public function autoloadFindsCamelCasedClassFileIfExtAutoloadEntryIsLowerCased() {
+		$extKey = $this->createFakeExtension();
+		$extPath = PATH_site . "typo3temp/$extKey/";
+
+			// A case sensitive key (FooBar) in ext_autoload file
+		$class = "tx_${extKey}_" . uniqid('FooBar');
+		$file = $extPath . uniqid('') . '.php';
+
+		file_put_contents($file, "<?php\n\nthrow new RuntimeException('', 1336756850);\n\n?>");
+
+			// Inject a dummy for the core_phpcode cache to force the autoloader
+			// to re calculate the registry
+		$mockCache = $this->getMock('t3lib_cache_frontend_AbstractFrontend', array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'), array(), '', FALSE);
+		$GLOBALS['typo3CacheManager'] = $this->getMock('t3lib_cache_Manager', array('getCache'));
+		$GLOBALS['typo3CacheManager']->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
+
+			// Let cache access give back lowercased class name
+		$mockCache->expects($this->any())->method('has')->will($this->returnValue(TRUE));
+		$mockCache->expects($this->once())->method('requireOnce')->will($this->returnValue(array(strtolower($class) => $file)));
+
+			// Re-initialize autoloader registry to force it to recognize the new extension
+		t3lib_autoloader::unregisterAutoloader();
+		t3lib_autoloader::registerAutoloader();
+		t3lib_autoloader::autoload($class);
+	}
+
 	/**
 	 * @test
 	 */
-- 
GitLab