Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Force loading of all aliases at startup #4

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
36 changes: 34 additions & 2 deletions src/ClassAliasLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ class ClassAliasLoader
*/
protected $caseSensitiveClassLoading = true;

/**
* @var bool
*/
protected $forceAliasLoading = false;

/**
* @param ComposerClassLoader $composerClassLoader
*/
Expand All @@ -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
*
Expand Down Expand Up @@ -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);
}
}

/**
Expand All @@ -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()
*
Expand Down
10 changes: 8 additions & 2 deletions src/ClassAliasMapGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 = <<<EOF
<?php

Expand All @@ -153,6 +158,7 @@ public static function initializeClassAliasLoader(\$composerClassLoader) {
\$classAliasLoader = new TYPO3\ClassAliasLoader\ClassAliasLoader(\$composerClassLoader);
\$classAliasLoader->setAliasMap(\$classAliasMap);
\$classAliasLoader->setCaseSensitiveClassLoading($caseSensitiveClassLoadingString);
\$classAliasLoader->setForceAliasLoading($forceAliasLoadingString);
\$classAliasLoader->register($prependAutoloader);

TYPO3\ClassAliasLoader\ClassAliasMap::setClassAliasLoader(\$classAliasLoader);
Expand Down
67 changes: 51 additions & 16 deletions src/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -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',
);

/**
Expand Down Expand Up @@ -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;
}
}
}

Expand All @@ -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(
'<warning>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!</warning>',
$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(
'<warning>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!</warning>',
$package->getName()
Expand Down
4 changes: 4 additions & 0 deletions tests/Unit/ConfigTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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'));
}

/**
Expand Down Expand Up @@ -113,6 +114,7 @@ public function otherConfigIsExtracted()
'typo3/class-alias-loader' => array(
'always-add-alias-loader' => true,
'autoload-case-sensitivity' => false,
'autoload-mode' => 'test',
)
)
);
Expand All @@ -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'));
}

/**
Expand All @@ -133,6 +136,7 @@ public function otherConfigIsExtractedFromDeprecatedKey()
'helhum/class-alias-loader' => array(
'always-add-alias-loader' => true,
'autoload-case-sensitivity' => false,

)
)
);
Expand Down