TYPO3CMS  8
 All Classes Namespaces Files Functions Variables Pages
ClassLoadingInformation.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Core\Core;
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
17 use Composer\Autoload\ClassLoader;
18 use TYPO3\ClassAliasLoader\ClassAliasMap;
22 
32 {
36  const AUTOLOAD_INFO_DIR = 'typo3conf/autoload/';
37 
41  const AUTOLOAD_INFO_DIR_TESTS = 'typo3conf/autoload-tests/';
42 
46  const AUTOLOAD_CLASSMAP_FILENAME = 'autoload_classmap.php';
47 
51  const AUTOLOAD_PSR4_FILENAME = 'autoload_psr4.php';
52 
56  const AUTOLOAD_CLASSALIASMAP_FILENAME = 'autoload_classaliasmap.php';
57 
64  public static function isClassLoadingInformationAvailable()
65  {
66  return !self::isTestingContext() && file_exists(self::getClassLoadingInformationDirectory() . self::AUTOLOAD_CLASSMAP_FILENAME);
67  }
68 
72  public static function dumpClassLoadingInformation()
73  {
74  self::ensureAutoloadInfoDirExists();
75  $composerClassLoader = static::getClassLoader();
76  $activeExtensionPackages = static::getActiveExtensionPackages();
77 
79  $generator = GeneralUtility::makeInstance(ClassLoadingInformationGenerator::class, $composerClassLoader, $activeExtensionPackages, PATH_site, self::isTestingContext());
80  $classInfoFiles = $generator->buildAutoloadInformationFiles();
81  GeneralUtility::writeFile(self::getClassLoadingInformationDirectory() . self::AUTOLOAD_CLASSMAP_FILENAME, $classInfoFiles['classMapFile']);
82  GeneralUtility::writeFile(self::getClassLoadingInformationDirectory() . self::AUTOLOAD_PSR4_FILENAME, $classInfoFiles['psr-4File']);
83 
84  $classAliasMapFile = $generator->buildClassAliasMapFile();
85  GeneralUtility::writeFile(self::getClassLoadingInformationDirectory() . self::AUTOLOAD_CLASSALIASMAP_FILENAME, $classAliasMapFile);
86  }
87 
92  public static function registerClassLoadingInformation()
93  {
94  $composerClassLoader = static::getClassLoader();
95 
96  $dynamicClassAliasMapFile = self::getClassLoadingInformationDirectory() . self::AUTOLOAD_CLASSALIASMAP_FILENAME;
97  if (file_exists($dynamicClassAliasMapFile)) {
98  $classAliasMap = require $dynamicClassAliasMapFile;
99  if (is_array($classAliasMap) && !empty($classAliasMap['aliasToClassNameMapping']) && !empty($classAliasMap['classNameToAliasMapping'])) {
100  ClassAliasMap::addAliasMap($classAliasMap);
101  }
102  }
103 
104  $dynamicClassMapFile = self::getClassLoadingInformationDirectory() . self::AUTOLOAD_CLASSMAP_FILENAME;
105  if (file_exists($dynamicClassMapFile)) {
106  $classMap = require $dynamicClassMapFile;
107  if (!empty($classMap) && is_array($classMap)) {
108  $composerClassLoader->addClassMap($classMap);
109  }
110  }
111 
112  $dynamicPsr4File = self::getClassLoadingInformationDirectory() . self::AUTOLOAD_PSR4_FILENAME;
113  if (file_exists($dynamicPsr4File)) {
114  $psr4 = require $dynamicPsr4File;
115  if (is_array($psr4)) {
116  foreach ($psr4 as $prefix => $paths) {
117  $composerClassLoader->setPsr4($prefix, $paths);
118  }
119  }
120  }
121  }
122 
129  public static function registerTransientClassLoadingInformationForPackage(PackageInterface $package)
130  {
131  $composerClassLoader = static::getClassLoader();
132  $activeExtensionPackages = static::getActiveExtensionPackages();
133 
135  $generator = GeneralUtility::makeInstance(ClassLoadingInformationGenerator::class, $composerClassLoader, $activeExtensionPackages, PATH_site, self::isTestingContext());
136 
137  $classInformation = $generator->buildClassLoadingInformationForPackage($package);
138  $composerClassLoader->addClassMap($classInformation['classMap']);
139  foreach ($classInformation['psr-4'] as $prefix => $paths) {
140  $composerClassLoader->setPsr4($prefix, $paths);
141  }
142  $classAliasMap = $generator->buildClassAliasMapForPackage($package);
143  if (is_array($classAliasMap) && !empty($classAliasMap['aliasToClassNameMapping']) && !empty($classAliasMap['classNameToAliasMapping'])) {
144  ClassAliasMap::addAliasMap($classAliasMap);
145  }
146  }
147 
151  protected static function getClassLoadingInformationDirectory()
152  {
153  if (self::isTestingContext()) {
154  return PATH_site . self::AUTOLOAD_INFO_DIR_TESTS;
155  } else {
156  return PATH_site . self::AUTOLOAD_INFO_DIR;
157  }
158  }
159 
166  public static function getClassNameForAlias($alias)
167  {
168  return ClassAliasMap::getClassNameForAlias($alias);
169  }
170 
175  protected static function ensureAutoloadInfoDirExists()
176  {
177  $autoloadInfoDir = self::getClassLoadingInformationDirectory();
178  if (!file_exists($autoloadInfoDir)) {
179  GeneralUtility::mkdir_deep($autoloadInfoDir);
180  }
181  }
182 
189  protected static function getClassLoader()
190  {
191  return Bootstrap::getInstance()->getEarlyInstance(ClassLoader::class);
192  }
193 
200  protected static function isTestingContext()
201  {
202  return Bootstrap::getInstance()->getApplicationContext()->isTesting();
203  }
204 
210  protected static function getActiveExtensionPackages()
211  {
212  $activeExtensionPackages = [];
214  $packageManager = Bootstrap::getInstance()->getEarlyInstance(PackageManager::class);
215  foreach ($packageManager->getActivePackages() as $package) {
216  if ($package->getValueFromComposerManifest('type') === 'typo3-cms-framework') {
217  // Skip all core packages as the class loading info is prepared for them already
218  continue;
219  }
220  $activeExtensionPackages[] = $package;
221  }
222  return $activeExtensionPackages;
223  }
224 }
static mkdir_deep($directory, $deepDirectory= '')
static writeFile($file, $content, $changePermissions=false)
static makeInstance($className,...$constructorArguments)