[BUGFIX] Fix broken link to anchor
[Packages/TYPO3.CMS.git] / typo3 / contrib / vendor / helhum / class-alias-loader / Classes / Composer / ClassAliasGenerator.php
1 <?php
2 namespace Helhum\ClassAliasLoader\Composer;
3
4 /*
5 * This file is part of the class alias loader package.
6 *
7 * (c) Helmut Hummel <info@helhum.io>
8 *
9 * For the full copyright and license information, please view the LICENSE
10 * file that was distributed with this source code.
11 */
12
13 use Composer\Package\RootPackageInterface;
14 use Composer\Util\Filesystem;
15
16 /**
17 * Class ClassAliasLoader
18 */
19 class ClassAliasGenerator {
20
21 /**
22 * @param \Composer\Script\Event $event
23 * @param bool $calledByPlugin
24 * @return bool
25 * @throws \Exception
26 */
27 static public function generateAliasMap(\Composer\Script\Event $event, $calledByPlugin = false) {
28 if (!$calledByPlugin) {
29 $event->getIO()->write('
30 <warning>Please remove the section "post-autoload-dump": "Helhum\\ClassAliasLoader\\Composer\\ClassAliasGenerator::generateAliasMap" from your composer.json! It is obsolete.</warning>
31 ');
32 return false;
33 }
34 $event->getIO()->write('<info>Generating class alias map files</info>');
35
36 $composer = $event->getComposer();
37 $config = $composer->getConfig();
38
39 $filesystem = new Filesystem();
40 $filesystem->ensureDirectoryExists($config->get('vendor-dir'));
41 $basePath = $filesystem->normalizePath(realpath(getcwd()));
42 $vendorPath = $filesystem->normalizePath(realpath($config->get('vendor-dir')));
43 $targetDir = $vendorPath . '/composer';
44 $filesystem->ensureDirectoryExists($targetDir);
45
46 $mainPackage = $composer->getPackage();
47 $autoLoadGenerator = $composer->getAutoloadGenerator();
48 $localRepo = $composer->getRepositoryManager()->getLocalRepository();
49 $packageMap = $autoLoadGenerator->buildPackageMap($composer->getInstallationManager(), $mainPackage, $localRepo->getCanonicalPackages());
50
51 $caseSensitiveClassLoading = self::caseSensitiveClassLoading($mainPackage, $targetDir) ? 'true' : 'false';
52
53 $aliasToClassNameMapping = array();
54 $classNameToAliasMapping = array();
55 $mappingFound = false;
56
57 foreach ($packageMap as $item) {
58 list($package, $installPath) = $item;
59 $extra = $package->getExtra();
60 if (!empty($extra['class-alias-maps'])) {
61 if (!is_array($extra['class-alias-maps'])) {
62 throw new \Exception('"class-alias-maps" must be an array');
63 }
64 foreach ($extra['class-alias-maps'] as $mapFile) {
65 $mapFilePath = ($installPath ?: $basePath) . '/' . $filesystem->normalizePath($mapFile);
66 if (is_file($mapFilePath)) {
67 $packageAliasMap = require $mapFilePath;
68 if (!is_array($packageAliasMap)) {
69 throw new \Exception('"class alias maps" must return an array', 1422625075);
70 }
71 if (!empty($packageAliasMap)) {
72 $mappingFound = true;
73 }
74 foreach ($packageAliasMap as $aliasClassName => $className) {
75 $lowerCasedAliasClassName = strtolower($aliasClassName);
76 $aliasToClassNameMapping[$lowerCasedAliasClassName] = $className;
77 $classNameToAliasMapping[$className][$lowerCasedAliasClassName] = $lowerCasedAliasClassName;
78 }
79 }
80 }
81 }
82 }
83
84 if (!$mappingFound) {
85 return false;
86 }
87
88 $exportArray = array(
89 'aliasToClassNameMapping' => $aliasToClassNameMapping,
90 'classNameToAliasMapping' => $classNameToAliasMapping
91 );
92
93 $fileContent = '<?php' . chr(10) . 'return ';
94 $fileContent .= var_export($exportArray, true);
95 $fileContent .= ';';
96
97 file_put_contents($targetDir . '/autoload_classaliasmap.php', $fileContent);
98 $originalAutoloadFileContent = file_get_contents($vendorPath . '/autoload.php');
99 preg_match('/return ComposerAutoloaderInit[^;]*;/', $originalAutoloadFileContent, $matches);
100 $originalAutoloadFileContent = str_replace($matches[0], '', $originalAutoloadFileContent);
101 $composerClassLoaderInit = str_replace(array('return ', ';'), '', $matches[0]);
102 $autoloadFileContent = <<<EOF
103 $originalAutoloadFileContent
104
105 // autoload.php @generated by Helhum/ClassAliasLoader
106
107 return call_user_func(function() {
108 \$composerClassLoader = $composerClassLoaderInit;
109 \$aliasClassLoader = new Helhum\ClassAliasLoader\Composer\ClassAliasLoader(\$composerClassLoader);
110
111 \$classAliasMap = require __DIR__ . '/composer/autoload_classaliasmap.php';
112 \$aliasClassLoader->setAliasMap(\$classAliasMap);
113 \$aliasClassLoader->setCaseSensitiveClassLoading($caseSensitiveClassLoading);
114 spl_autoload_register(array(\$aliasClassLoader, 'loadClassWithAlias'), true, true);
115
116 return \$aliasClassLoader;
117 });
118
119 EOF;
120
121 file_put_contents($vendorPath . '/autoload.php', $autoloadFileContent);
122
123 return true;
124 }
125
126 /**
127 * Rewrites the class map to have lowercased keys to be able to load classes with wrong casing
128 * Defaults to case sensitivity (composer loader default)
129 *
130 * @param RootPackageInterface $mainPackage
131 * @param string $targetDir
132 * @return bool
133 */
134 static protected function caseSensitiveClassLoading(RootPackageInterface $mainPackage, $targetDir) {
135 $extra = $mainPackage->getExtra();
136 $caseSensitiveClassLoading = true;
137 if (isset($extra['autoload-case-sensitivity'])) {
138 $caseSensitiveClassLoading = (bool)$extra['autoload-case-sensitivity'];
139 }
140 if (!$caseSensitiveClassLoading) {
141 $classMapContents = file_get_contents($targetDir . '/autoload_classmap.php');
142 $classMapContents = preg_replace_callback(
143 '/ \'[^\']*\' => /',
144 function($match) {
145 return strtolower($match[0]);
146 },
147 $classMapContents
148 );
149 file_put_contents($targetDir . '/autoload_classmap.php', $classMapContents);
150 }
151 return $caseSensitiveClassLoading;
152 }
153 }