2 namespace TYPO3\ClassAliasLoader;
13 use Composer\Composer;
15 use Composer\IO\IOInterface;
16 use Composer\IO\NullIO;
17 use Composer\Package\PackageInterface;
18 use Composer\Util\Filesystem;
51 $this->IO =
$IO ?:
new NullIO();
59 public function generateAliasMap()
61 $config = $this->composer->getConfig();
63 $filesystem =
new Filesystem();
64 $filesystem->ensureDirectoryExists($config->get(
'vendor-dir'));
66 $vendorPath = $filesystem->normalizePath(realpath($config->get(
'vendor-dir')));
67 $targetDir = $vendorPath .
'/composer';
68 $filesystem->ensureDirectoryExists($targetDir);
70 $mainPackage = $this->composer->getPackage();
71 $autoLoadGenerator = $this->composer->getAutoloadGenerator();
72 $localRepo = $this->composer->getRepositoryManager()->getLocalRepository();
73 $packageMap = $autoLoadGenerator->buildPackageMap($this->composer->getInstallationManager(), $mainPackage, $localRepo->getCanonicalPackages());
75 $aliasToClassNameMapping = array();
76 $classNameToAliasMapping = array();
77 $classAliasMappingFound =
false;
79 foreach ($packageMap as $item) {
81 list($package, $installPath) = $item;
82 $aliasLoaderConfig = new \TYPO3\ClassAliasLoader\Config($package, $this->IO);
83 if ($aliasLoaderConfig->get(
'class-alias-maps') !== null) {
84 if (!is_array($aliasLoaderConfig->get(
'class-alias-maps'))) {
85 throw new \Exception(
'Configuration option "class-alias-maps" must be an array');
87 foreach ($aliasLoaderConfig->get(
'class-alias-maps') as $mapFile) {
88 $mapFilePath = ($installPath ?: $basePath) .
'/' . $filesystem->normalizePath($mapFile);
89 if (!is_file($mapFilePath)) {
90 $this->IO->writeError(sprintf(
'The class alias map file "%s" configured in package "%s" was not found!', $mapFile, $package->getName()));
92 $packageAliasMap = require $mapFilePath;
93 if (!is_array($packageAliasMap)) {
94 throw new \Exception(
'Class alias map files must return an array', 1422625075);
96 if (!empty($packageAliasMap)) {
97 $classAliasMappingFound =
true;
99 foreach ($packageAliasMap as $aliasClassName => $className) {
100 $lowerCasedAliasClassName = strtolower($aliasClassName);
101 $aliasToClassNameMapping[$lowerCasedAliasClassName] = $className;
102 $classNameToAliasMapping[$className][$lowerCasedAliasClassName] = $lowerCasedAliasClassName;
109 $mainPackageAliasLoaderConfig = new \TYPO3\ClassAliasLoader\Config($mainPackage);
110 $alwaysAddAliasLoader = $mainPackageAliasLoaderConfig->get(
'always-add-alias-loader');
111 $caseSensitiveClassLoading = $mainPackageAliasLoaderConfig->get(
'autoload-case-sensitivity');
113 if (!$alwaysAddAliasLoader && !$classAliasMappingFound && $caseSensitiveClassLoading) {
119 $caseSensitiveClassLoadingString = $caseSensitiveClassLoading ?
'true' :
'false';
120 $this->IO->write(
'<info>Generating ' . ($classAliasMappingFound ?
' ' :
'empty ') .
'class alias map file</info>');
124 if (!$config->get(
'autoloader-suffix') && is_readable($vendorPath .
'/autoload.php')) {
125 $content = file_get_contents($vendorPath .
'/autoload.php');
126 if (preg_match(
'{ComposerAutoloaderInit([^:\s]+)::}', $content, $match)) {
132 $suffix = $config->get(
'autoloader-suffix') ?: md5(uniqid(
'',
true));
135 $prependAutoloader = $config->get(
'prepend-autoloader') ===
false ?
'false' :
'true';
137 $aliasLoaderInitClassContent = <<<EOF
142 class ClassAliasLoaderInit$suffix {
144 private static \$loader;
146 public static function initializeClassAliasLoader(\$composerClassLoader) {
147 if (null !==
self::\$loader) {
148 return self::\$loader;
150 self::\$loader = \$composerClassLoader;
152 \$classAliasMap = require __DIR__ .
'/autoload_classaliasmap.php';
154 \$classAliasLoader->setAliasMap(\$classAliasMap);
155 \$classAliasLoader->setCaseSensitiveClassLoading($caseSensitiveClassLoadingString);
156 \$classAliasLoader->register($prependAutoloader);
158 TYPO3\ClassAliasLoader\ClassAliasMap::setClassAliasLoader(\$classAliasLoader);
160 return self::\$loader;
165 file_put_contents($targetDir .
'/autoload_alias_loader_real.php', $aliasLoaderInitClassContent);
167 if (!$caseSensitiveClassLoading) {
168 $this->IO->write(
'<info>Re-writing class map to support case insensitive class loading</info>');
169 if (!$this->optimizeAutoloadFiles) {
170 $this->IO->write(
'<warning>Case insensitive class loading only works reliably if you use the optimize class loading feature of composer</warning>');
175 $this->IO->write(
'<info>Inserting class alias loader into main autoload.php file</info>');
187 $originalAutoloadFileContent = file_get_contents($autoloadFile);
188 preg_match(
'/return ComposerAutoloaderInit[^;]*;/', $originalAutoloadFileContent, $matches);
189 $originalAutoloadFileContent = str_replace($matches[0],
'', $originalAutoloadFileContent);
190 $composerClassLoaderInit = str_replace(array(
'return ',
';'),
'', $matches[0]);
191 $autoloadFileContent = <<<EOF
192 $originalAutoloadFileContent
196 require_once __DIR__ .
'/composer/autoload_alias_loader_real.php';
198 return ClassAliasLoaderInit$suffix::initializeClassAliasLoader($composerClassLoaderInit);
202 file_put_contents($autoloadFile, $autoloadFileContent);
211 protected function generateAliasMapFile(array $aliasToClassNameMapping, array $classNameToAliasMapping, $targetDir)
213 $exportArray = array(
214 'aliasToClassNameMapping' => $aliasToClassNameMapping,
215 'classNameToAliasMapping' => $classNameToAliasMapping
218 $fileContent =
'<?php' . chr(10) .
'return ';
219 $fileContent .= var_export($exportArray,
true);
222 file_put_contents($targetDir .
'/autoload_classaliasmap.php', $fileContent);
233 $classMapContents = file_get_contents($targetDir .
'/autoload_classmap.php');
234 $classMapContents = preg_replace_callback(
'/ \'[^\']*\' => /',
function ($match) {
235 return strtolower($match[0]);
236 }, $classMapContents);
237 file_put_contents($targetDir .
'/autoload_classmap.php', $classMapContents);
248 $reflectionClass = new \ReflectionClass($config);
249 $reflectionProperty = $reflectionClass->getProperty(
'baseDir');
250 $reflectionProperty->setAccessible(
true);
251 return $reflectionProperty->getValue($config);