diff --git a/README.md b/README.md index 13bebdc..332f692 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,18 @@ Therefore it is possible to set the following option in your *root* `composer.js }, ``` +In cases where another autoloader conflicts with the alias autoloader, you may find it helpful to bypass the autoloader +entirely, and choose to instead force the loading of all known aliases at boot. + +``` + "extra": { + "typo3/class-alias-loader": { + "autoloader-mode": "force-alias-loading" + } + }, +``` +This method of loading aliases may incur a significant performance hit if you have a large number of classes aliased. +The class aliases are also established without loading the classes themselves. ## Using the API diff --git a/src/ClassAliasLoader.php b/src/ClassAliasLoader.php index df4bbd5..475fa35 100644 --- a/src/ClassAliasLoader.php +++ b/src/ClassAliasLoader.php @@ -36,6 +36,11 @@ class ClassAliasLoader */ protected $caseSensitiveClassLoading = true; + /** + * @var bool + */ + protected $forceAliasLoading = false; + /** * @param ComposerClassLoader $composerClassLoader */ @@ -62,6 +67,14 @@ public function setCaseSensitiveClassLoading($caseSensitiveClassLoading) $this->caseSensitiveClassLoading = $caseSensitiveClassLoading; } + /** + * @param boolean $forceAliasLoading + */ + public function setForceAliasLoading($forceAliasLoading) + { + $this->forceAliasLoading = $forceAliasLoading; + } + /** * Adds an alias map and merges it with already available map * @@ -96,8 +109,12 @@ public function getClassNameForAlias($aliasOrClassName) */ public function register($prepend = false) { - $this->composerClassLoader->unregister(); - spl_autoload_register(array($this, 'loadClassWithAlias'), true, $prepend); + if ($this->forceAliasLoading) { + $this->registerAllAliases(); + } else { + $this->composerClassLoader->unregister(); + spl_autoload_register(array($this, 'loadClassWithAlias'), true, $prepend); + } } /** @@ -108,6 +125,21 @@ public function unregister() spl_autoload_unregister(array($this, 'loadClassWithAlias')); } + /** + * Alternative to using as an autoloader, which pre-loads all aliases. + * This does NOT perform any checks against the RealClassName, as classes are not auto-loaded with this function. + */ + public function registerAllAliases() + { + foreach($this->aliasMap['classNameToAliasMapping'] as $originalClassName => $maps) { + foreach ($maps as $aliasClassName) { + if (!$this->classOrInterfaceExists($aliasClassName)) { + class_alias($originalClassName, $aliasClassName); + } + } + } + } + /** * Main class loading method registered with spl_autoload_register() * diff --git a/src/ClassAliasMapGenerator.php b/src/ClassAliasMapGenerator.php index 18113c1..482faa2 100644 --- a/src/ClassAliasMapGenerator.php +++ b/src/ClassAliasMapGenerator.php @@ -107,8 +107,8 @@ public function generateAliasMap() } $mainPackageAliasLoaderConfig = new \TYPO3\ClassAliasLoader\Config($mainPackage); - $alwaysAddAliasLoader = $mainPackageAliasLoaderConfig->get('always-add-alias-loader'); - $caseSensitiveClassLoading = $mainPackageAliasLoaderConfig->get('autoload-case-sensitivity'); + $alwaysAddAliasLoader = $mainPackageAliasLoaderConfig->get(\TYPO3\ClassAliasLoader\Config::OPTION_ALWAYS_ADD_ALIAS_LOADER); + $caseSensitiveClassLoading = $mainPackageAliasLoaderConfig->get(\TYPO3\ClassAliasLoader\Config::OPTION_AUTOLOAD_IS_CASE_SENSITIVE); if (!$alwaysAddAliasLoader && !$classAliasMappingFound && $caseSensitiveClassLoading) { // No mapping found in any package and no insensitive class loading active. We return early and skip rewriting @@ -134,6 +134,11 @@ public function generateAliasMap() $prependAutoloader = $config->get('prepend-autoloader') === false ? 'false' : 'true'; + // Autoloader mode check + $autoloadMode = $mainPackageAliasLoaderConfig->get(\TYPO3\ClassAliasLoader\Config::OPTION_AUTOLOAD_MODE); + $forceAliasLoading = ($autoloadMode == \TYPO3\ClassAliasLoader\Config::AUTOLOAD_MODE_FORCE_ALIAS_LOADING); + $forceAliasLoadingString = $forceAliasLoading ? 'true' : 'false'; + $aliasLoaderInitClassContent = <<setAliasMap(\$classAliasMap); \$classAliasLoader->setCaseSensitiveClassLoading($caseSensitiveClassLoadingString); + \$classAliasLoader->setForceAliasLoading($forceAliasLoadingString); \$classAliasLoader->register($prependAutoloader); TYPO3\ClassAliasLoader\ClassAliasMap::setClassAliasLoader(\$classAliasLoader); diff --git a/src/Config.php b/src/Config.php index 0ef37a1..4113bbc 100644 --- a/src/Config.php +++ b/src/Config.php @@ -19,15 +19,36 @@ */ class Config { + const OPTION_CLASS_ALIAS_MAPS = 'class-alias-maps'; + const OPTION_ALWAYS_ADD_ALIAS_LOADER = 'always-add-alias-loader'; + const OPTION_AUTOLOAD_IS_CASE_SENSITIVE = 'autoload-case-sensitivity'; + const OPTION_AUTOLOAD_MODE = 'autoload-mode'; + + const AUTOLOAD_MODE_NORMAL = 'normal'; + const AUTOLOAD_MODE_FORCE_ALIAS_LOADING = 'force-alias-loading'; + /** - * Default values + * Default config values * * @var array */ protected $config = array( - 'class-alias-maps' => null, - 'always-add-alias-loader' => false, - 'autoload-case-sensitivity' => true + self::OPTION_CLASS_ALIAS_MAPS => null, + self::OPTION_ALWAYS_ADD_ALIAS_LOADER => false, + self::OPTION_AUTOLOAD_IS_CASE_SENSITIVE => true, + self::OPTION_AUTOLOAD_MODE => self::AUTOLOAD_MODE_NORMAL, + ); + + /** + * Config cast types + * + * @var array + */ + protected $configCastType = array( + self::OPTION_CLASS_ALIAS_MAPS => 'array', + self::OPTION_ALWAYS_ADD_ALIAS_LOADER => 'bool', + self::OPTION_AUTOLOAD_IS_CASE_SENSITIVE => 'bool', + self::OPTION_AUTOLOAD_MODE => 'string', ); /** @@ -76,14 +97,28 @@ public function get($configKey) protected function setAliasLoaderConfigFromPackage(PackageInterface $package) { $extraConfig = $this->handleDeprecatedConfigurationInPackage($package); - if (isset($extraConfig['typo3/class-alias-loader']['class-alias-maps'])) { - $this->config['class-alias-maps'] = (array)$extraConfig['typo3/class-alias-loader']['class-alias-maps']; - } - if (isset($extraConfig['typo3/class-alias-loader']['always-add-alias-loader'])) { - $this->config['always-add-alias-loader'] = (bool)$extraConfig['typo3/class-alias-loader']['always-add-alias-loader']; - } - if (isset($extraConfig['typo3/class-alias-loader']['autoload-case-sensitivity'])) { - $this->config['autoload-case-sensitivity'] = (bool)$extraConfig['typo3/class-alias-loader']['autoload-case-sensitivity']; + + foreach ($this->configCastType as $key => $type) { + + if (isset($extraConfig['typo3/class-alias-loader'][$key])) { + $value = $extraConfig['typo3/class-alias-loader'][$key]; + + // Cast correct type + switch ($type) { + case 'bool': + $value = (bool) $value; + break; + case 'array': + $value = (array) $value; + break; + case 'string': + $value = (string) $value; + break; + } + + // Save value + $this->config[$key] = $value; + } } } @@ -106,15 +141,15 @@ protected function handleDeprecatedConfigurationInPackage(PackageInterface $pack ); } else { $extraConfig['typo3/class-alias-loader'] = array(); - if (isset($extraConfig['class-alias-maps'])) { - $extraConfig['typo3/class-alias-loader']['class-alias-maps'] = $extraConfig['class-alias-maps']; + if (isset($extraConfig[self::OPTION_CLASS_ALIAS_MAPS])) { + $extraConfig['typo3/class-alias-loader'][self::OPTION_CLASS_ALIAS_MAPS] = $extraConfig[self::OPTION_CLASS_ALIAS_MAPS]; $messages[] = sprintf( 'The package "%s" uses "class-alias-maps" section on top level, which is deprecated. Please move this config below the top level key "typo3/class-alias-loader" instead!', $package->getName() ); } - if (isset($extraConfig['autoload-case-sensitivity'])) { - $extraConfig['typo3/class-alias-loader']['autoload-case-sensitivity'] = $extraConfig['autoload-case-sensitivity']; + if (isset($extraConfig[self::OPTION_AUTOLOAD_IS_CASE_SENSITIVE])) { + $extraConfig['typo3/class-alias-loader'][self::OPTION_AUTOLOAD_IS_CASE_SENSITIVE] = $extraConfig[self::OPTION_AUTOLOAD_IS_CASE_SENSITIVE]; $messages[] = sprintf( 'The package "%s" uses "autoload-case-sensitivity" section on top level, which is deprecated. Please move this config below the top level key "typo3/class-alias-loader" instead!', $package->getName() diff --git a/tests/Unit/ConfigTest.php b/tests/Unit/ConfigTest.php index ed9d8ef..be5b961 100644 --- a/tests/Unit/ConfigTest.php +++ b/tests/Unit/ConfigTest.php @@ -60,6 +60,7 @@ public function defaultConfigIsAppliedWhenNothingIsConfiguredInPackage() $this->assertFalse($this->subject->get('always-add-alias-loader')); $this->assertTrue($this->subject->get('autoload-case-sensitivity')); $this->assertNull($this->subject->get('class-alias-maps')); + $this->assertEquals('normal', $this->subject->get('autoload-mode')); } /** @@ -113,6 +114,7 @@ public function otherConfigIsExtracted() 'typo3/class-alias-loader' => array( 'always-add-alias-loader' => true, 'autoload-case-sensitivity' => false, + 'autoload-mode' => 'test', ) ) ); @@ -121,6 +123,7 @@ public function otherConfigIsExtracted() $this->assertTrue($subject->get('always-add-alias-loader')); $this->assertFalse($subject->get('autoload-case-sensitivity')); + $this->assertEquals('test', $subject->get('autoload-mode')); } /** @@ -133,6 +136,7 @@ public function otherConfigIsExtractedFromDeprecatedKey() 'helhum/class-alias-loader' => array( 'always-add-alias-loader' => true, 'autoload-case-sensitivity' => false, + ) ) );