TYPO3 CMS  TYPO3_8-7
ExtensionCompatibilityTester.php
Go to the documentation of this file.
1 <?php
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 
19 
29 {
35  protected $protocolFile = '';
36 
42  protected $errorProtocolFile = '';
43 
49  protected $logError = false;
50 
55  public function __construct()
56  {
57  $this->protocolFile = PATH_site . 'typo3temp/assets/ExtensionCompatibilityTester.txt';
58  $this->errorProtocolFile = PATH_site . 'typo3temp/assets/ExtensionCompatibilityTesterErrors.json';
59  }
60 
68  protected function executeAction()
69  {
70  register_shutdown_function([$this, 'logError']);
71  $getVars = GeneralUtility::_GET('install');
72  if (isset($getVars['extensionCompatibilityTester']) && isset($getVars['extensionCompatibilityTester']['forceCheck']) && ($getVars['extensionCompatibilityTester']['forceCheck'] == 1)) {
73  $this->deleteProtocolFile();
74  }
76  return 'OK';
77  }
78 
82  protected function deleteProtocolFile()
83  {
84  if (file_exists($this->protocolFile)) {
85  unlink($this->protocolFile);
86  }
87  if (file_exists($this->errorProtocolFile)) {
88  unlink($this->errorProtocolFile);
89  }
90  }
91 
99  protected function getExtensionsToLoad()
100  {
101  $extensionsToLoad = [];
102  $extensionsToExclude = $this->getExtensionsToExclude();
103  foreach ($GLOBALS['TYPO3_LOADED_EXT'] as $key => $extension) {
104  if (!in_array($key, $extensionsToExclude)) {
105  $extensionsToLoad[$key] = $extension;
106  }
107  }
108  return $extensionsToLoad;
109  }
110 
118  protected function getExtensionsToExclude()
119  {
120  if (is_file($this->protocolFile)) {
121  $exclude = (string)file_get_contents($this->protocolFile);
122  return GeneralUtility::trimExplode(',', $exclude);
123  }
124  return [];
125  }
126 
134  protected function tryToLoadExtLocalconfAndExtTablesOfExtensions(array $extensions)
135  {
136  foreach ($extensions as $extensionKey => $extension) {
137  $this->writeCurrentExtensionToFile($extensionKey);
138  $this->loadExtLocalconfForExtension($extensionKey, $extension);
139  $this->removeCurrentExtensionFromFile($extensionKey);
140  }
141  ExtensionManagementUtility::loadBaseTca(false);
142  foreach ($extensions as $extensionKey => $extension) {
143  $this->writeCurrentExtensionToFile($extensionKey);
144  $this->loadExtTablesForExtension($extensionKey, $extension);
145  $this->removeCurrentExtensionFromFile($extensionKey);
146  }
147  }
148 
156  protected function loadExtTablesForExtension($extensionKey, array $extension)
157  {
158  // In general it is recommended to not rely on it to be globally defined in that
159  // scope, but we can not prohibit this without breaking backwards compatibility
160  global $T3_SERVICES, $T3_VAR, $TYPO3_CONF_VARS;
161  global $TBE_MODULES, $TBE_MODULES_EXT, $TCA;
162  global $PAGES_TYPES, $TBE_STYLES;
163  global $_EXTKEY;
164  // Load each ext_tables.php file of loaded extensions
165  $_EXTKEY = $extensionKey;
166  if (isset($extension['ext_tables.php']) && $extension['ext_tables.php']) {
167  // $_EXTKEY and $_EXTCONF are available in ext_tables.php
168  // and are explicitly set in cached file as well
169  $_EXTCONF = $GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][$_EXTKEY];
170  require $extension['ext_tables.php'];
171  }
172  }
173 
181  protected function loadExtLocalconfForExtension($extensionKey, array $extension)
182  {
183  // This is the main array meant to be manipulated in the ext_localconf.php files
184  // In general it is recommended to not rely on it to be globally defined in that
185  // scope but to use $GLOBALS['TYPO3_CONF_VARS'] instead.
186  // Nevertheless we define it here as global for backwards compatibility.
187  global $TYPO3_CONF_VARS;
188  $_EXTKEY = $extensionKey;
189  if (isset($extension['ext_localconf.php']) && $extension['ext_localconf.php']) {
190  // $_EXTKEY and $_EXTCONF are available in ext_localconf.php
191  // and are explicitly set in cached file as well
192  $_EXTCONF = $GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][$_EXTKEY];
193  require $extension['ext_localconf.php'];
194  }
195  }
196 
203  protected function writeCurrentExtensionToFile($extensionKey)
204  {
205  $incompatibleExtensions = $this->getExtensionsToExclude();
206  $incompatibleExtensions = array_filter($incompatibleExtensions);
207  $incompatibleExtensions = array_merge($incompatibleExtensions, [$extensionKey]);
208  GeneralUtility::writeFileToTypo3tempDir($this->protocolFile, implode(', ', $incompatibleExtensions));
209  $this->logError = true;
210  }
211 
217  protected function removeCurrentExtensionFromFile($extensionKey)
218  {
219  $extensionsInFile = $this->getExtensionsToExclude();
220  $extensionsInFile = array_filter($extensionsInFile);
221  $extensionsByKey = array_flip($extensionsInFile);
222  unset($extensionsByKey[$extensionKey]);
223  $extensionsForFile = array_flip($extensionsByKey);
224  GeneralUtility::writeFile($this->protocolFile, implode(', ', $extensionsForFile));
225  $this->logError = false;
226  }
227 
231  public function logError()
232  {
233  $errors = [];
234 
235  // Logging is disabled.
236  if (!$this->logError) {
237  // Create an empty file to avoid 404 errors
238  if (!is_file($this->errorProtocolFile)) {
239  GeneralUtility::writeFileToTypo3tempDir($this->errorProtocolFile, json_encode($errors));
240  }
241  return;
242  }
243 
244  // Fetch existing errors, add last one and write to file again.
245  $lastError = error_get_last();
246 
247  if (file_exists($this->errorProtocolFile)) {
248  $errors = json_decode(file_get_contents($this->errorProtocolFile));
249  }
250  switch ($lastError['type']) {
251  case E_ERROR:
252  $lastError['type'] = 'E_ERROR';
253  break;
254  case E_WARNING:
255  $lastError['type'] = 'E_WARNING';
256  break;
257  case E_PARSE:
258  $lastError['type'] = 'E_PARSE';
259  break;
260  case E_NOTICE:
261  $lastError['type'] = 'E_NOTICE';
262  break;
263  }
264  $errors[] = $lastError;
265 
266  GeneralUtility::writeFileToTypo3tempDir($this->errorProtocolFile, json_encode($errors));
267  }
268 }
static writeFileToTypo3tempDir($filepath, $content)
static trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']
static writeFile($file, $content, $changePermissions=false)