TYPO3 CMS  TYPO3_8-7
SetupCheck.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 
20 
30 class SetupCheck implements CheckInterface
31 {
37  public function getStatus(): array
38  {
39  $status = [];
40 
41  $status[] = $this->checkTrustedHostPattern();
42  $status[] = $this->checkDownloadsPossible();
43  $status[] = $this->checkSystemLocale();
44  $status[] = $this->checkLocaleWithUTF8filesystem();
45  $status[] = $this->checkSomePhpOpcodeCacheIsLoaded();
46  $status[] = $this->isTrueTypeFontWorking();
47  $status[] = $this->checkLibXmlBug();
48 
49  return $status;
50  }
51 
57  protected function checkTrustedHostPattern()
58  {
59  if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['trustedHostsPattern'] === GeneralUtility::ENV_TRUSTED_HOSTS_PATTERN_ALLOW_ALL) {
60  $status = new Status\WarningStatus();
61  $status->setTitle('Trusted hosts pattern is insecure');
62  $status->setMessage('Trusted hosts pattern is configured to allow all header values. Check the pattern defined in Install Tool -> All configuration -> System -> trustedHostsPattern and adapt it to expected host value(s).');
63  } else {
65  $status = new Status\OkStatus();
66  $status->setTitle('Trusted hosts pattern is configured to allow current host value.');
67  } else {
68  $status = new Status\ErrorStatus();
69  $status->setTitle('Trusted hosts pattern mismatch');
70  $defaultPort = GeneralUtility::getIndpEnv('TYPO3_SSL') ? '443' : '80';
71  $status->setMessage(
72  'The trusted hosts pattern will be configured to allow all header values. This is because your $SERVER_NAME:[defaultPort]'
73  . ' is "' . htmlspecialchars($_SERVER['SERVER_NAME']) . ':' . $defaultPort . '" while your HTTP_HOST:SERVER_PORT is "'
74  . htmlspecialchars($_SERVER['HTTP_HOST']) . ':' . htmlspecialchars($_SERVER['SERVER_PORT'])
75  . '". Check the pattern defined in Install Tool -> All'
76  . ' configuration -> System -> trustedHostsPattern and adapt it to expected host value(s).'
77  );
78  }
79  }
80 
81  return $status;
82  }
83 
90  protected function checkDownloadsPossible()
91  {
92  $allowUrlFopen = (bool)ini_get('allow_url_fopen');
93  $curlEnabled = function_exists('curl_version');
94  if ($allowUrlFopen || $curlEnabled) {
95  $status = new Status\OkStatus();
96  $status->setTitle('Fetching external URLs is allowed');
97  } else {
98  $status = new Status\WarningStatus();
99  $status->setTitle('Fetching external URLs is not allowed');
100  $status->setMessage(
101  'Either enable PHP runtime setting "allow_url_fopen"' . LF . 'or compile curl into your PHP with --with-curl.'
102  );
103  }
104 
105  return $status;
106  }
107 
113  protected function checkSystemLocale()
114  {
115  $currentLocale = setlocale(LC_CTYPE, 0);
116 
117  // On Windows an empty locale value uses the regional settings from the Control Panel
118  if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale'] === '' && TYPO3_OS !== 'WIN') {
119  $status = new Status\InfoStatus();
120  $status->setTitle('Empty systemLocale setting');
121  $status->setMessage(
122  '$GLOBALS[TYPO3_CONF_VARS][SYS][systemLocale] is not set. This is fine as long as no UTF-8' .
123  ' file system is used.'
124  );
125  } elseif (setlocale(LC_CTYPE, $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale']) === false) {
126  $status = new Status\ErrorStatus();
127  $status->setTitle('Incorrect systemLocale setting');
128  $status->setMessage(
129  'Current value of the $GLOBALS[TYPO3_CONF_VARS][SYS][systemLocale] is incorrect. A locale with' .
130  ' this name doesn\'t exist in the operating system.'
131  );
132  setlocale(LC_CTYPE, $currentLocale);
133  } else {
134  $status = new Status\OkStatus();
135  $status->setTitle('System locale is correct');
136  }
137 
138  return $status;
139  }
140 
147  protected function checkLocaleWithUTF8filesystem()
148  {
149  if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['UTF8filesystem']) {
150  // On Windows an empty local value uses the regional settings from the Control Panel
151  if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale'] === '' && TYPO3_OS !== 'WIN') {
152  $status = new Status\ErrorStatus();
153  $status->setTitle('System locale not set on UTF-8 file system');
154  $status->setMessage(
155  '$GLOBALS[TYPO3_CONF_VARS][SYS][UTF8filesystem] is set, but $GLOBALS[TYPO3_CONF_VARS][SYS][systemLocale]' .
156  ' is empty. Make sure a valid locale which supports UTF-8 is set.'
157  );
158  } else {
159  $testString = 'ÖöĄĆŻĘĆćążąęó.jpg';
160  $currentLocale = setlocale(LC_CTYPE, 0);
161  $quote = TYPO3_OS === 'WIN' ? '"' : '\'';
162  setlocale(LC_CTYPE, $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale']);
163  if (escapeshellarg($testString) === $quote . $testString . $quote) {
164  $status = new Status\OkStatus();
165  $status->setTitle('File names with UTF-8 characters can be used.');
166  } else {
167  $status = new Status\ErrorStatus();
168  $status->setTitle('System locale setting doesn\'t support UTF-8 file names.');
169  $status->setMessage(
170  'Please check your $GLOBALS[TYPO3_CONF_VARS][SYS][systemLocale] setting.'
171  );
172  }
173  setlocale(LC_CTYPE, $currentLocale);
174  }
175  } else {
176  $status = new Status\OkStatus();
177  $status->setTitle('Skipping test, as UTF8filesystem is not enabled.');
178  }
179 
180  return $status;
181  }
182 
188  protected function checkSomePhpOpcodeCacheIsLoaded()
189  {
190  // Link to our wiki page, so we can update opcode cache issue information independent of TYPO3 CMS releases.
191  $wikiLink = 'For more information take a look in our wiki ' . TYPO3_URL_WIKI_OPCODECACHE . '.';
192  $opcodeCaches = GeneralUtility::makeInstance(OpcodeCacheService::class)->getAllActive();
193  if (empty($opcodeCaches)) {
194  // Set status to notice. It needs to be notice so email won't be triggered.
195  $status = new Status\NoticeStatus();
196  $status->setTitle('No PHP opcode cache loaded');
197  $status->setMessage(
198  'PHP opcode caches hold a compiled version of executed PHP scripts in' .
199  ' memory and do not require to recompile a script each time it is accessed.' .
200  ' This can be a massive performance improvement and can reduce the load on a' .
201  ' server in general. A parse time reduction by factor three for fully cached' .
202  ' pages can be achieved easily if using an opcode cache.' .
203  LF . $wikiLink
204  );
205  } else {
206  $status = new Status\OkStatus();
207  $message = '';
208  foreach ($opcodeCaches as $opcodeCache => $properties) {
209  $message .= 'Name: ' . $opcodeCache . ' Version: ' . $properties['version'];
210  $message .= LF;
211  if ($properties['error']) {
212  // Set status to error if not already set
213  if ($status->getSeverity() !== 'error') {
214  $status = new Status\ErrorStatus();
215  }
216  $message .= ' This opcode cache is marked as malfunctioning by the TYPO3 CMS Team.';
217  } elseif ($properties['canInvalidate']) {
218  $message .= ' This opcode cache should work correctly and has good performance.';
219  } else {
220  // Set status to notice if not already error set. It needs to be notice so email won't be triggered.
221  if ($status->getSeverity() !== 'error' || $status->getSeverity() !== 'warning') {
222  $status = new Status\NoticeStatus();
223  }
224  $message .= ' This opcode cache may work correctly but has medium performance.';
225  }
226  $message .= LF;
227  }
228  $message .= $wikiLink;
229  // Set title of status depending on serverity
230  switch ($status->getSeverity()) {
231  case 'error':
232  $status->setTitle('A possibly malfunctioning PHP opcode cache is loaded');
233  break;
234  case 'warning':
235  $status->setTitle('A PHP opcode cache is loaded which may cause problems');
236  break;
237  case 'ok':
238  default:
239  $status->setTitle('A PHP opcode cache is loaded');
240  break;
241  }
242  $status->setMessage($message);
243  }
244 
245  return $status;
246  }
247 
253  protected function isTrueTypeFontWorking()
254  {
255  if (function_exists('imageftbbox')) {
256  // 20 Pixels at 96 DPI
257  $fontSize = (20 / 96 * 72);
258  $textDimensions = @imageftbbox(
259  $fontSize,
260  0,
261  __DIR__ . '/../../Resources/Private/Font/vera.ttf',
262  'Testing true type support'
263  );
264  $fontBoxWidth = $textDimensions[2] - $textDimensions[0];
265  if ($fontBoxWidth < 300 && $fontBoxWidth > 200) {
266  $status = new Status\OkStatus();
267  $status->setTitle('FreeType True Type Font DPI');
268  $status->setMessage('Fonts are rendered by FreeType library. ' .
269  'We need to ensure that the final dimensions are as expected. ' .
270  'This server renderes fonts based on 96 DPI correctly');
271  } else {
272  $status = new Status\NoticeStatus();
273  $status->setTitle('FreeType True Type Font DPI');
274  $status->setMessage('Fonts are rendered by FreeType library. ' .
275  'This server does not render fonts as expected. ' .
276  'Please check your FreeType 2 module.');
277  }
278  } else {
279  $status = new Status\ErrorStatus();
280  $status->setTitle('PHP GD library freetype2 support missing');
281  $status->setMessage(
282  'The core relies on GD library compiled into PHP with freetype2' .
283  ' support. This is missing on your system. Please install it.'
284  );
285  }
286 
287  return $status;
288  }
289 
295  protected function checkLibXmlBug()
296  {
297  $sampleArray = ['Test>><<Data'];
298  $xmlContent = '<numIndex index="0">Test&gt;&gt;&lt;&lt;Data</numIndex>' . LF;
299  $xml = GeneralUtility::array2xml($sampleArray, '', -1);
300 
301  if ($xmlContent !== $xml) {
302  $status = new Status\ErrorStatus();
303  $status->setTitle('PHP libxml bug present');
304  $status->setMessage(
305  'Some hosts have problems saving ">><<" in a flexform.' .
306  ' To fix this, enable [BE][flexformForceCDATA] in' .
307  ' All Configuration.'
308  );
309  } else {
310  $status = new Status\OkStatus();
311  $status->setTitle('PHP libxml bug not present');
312  }
313 
314  return $status;
315  }
316 }
static array2xml(array $array, $NSprefix='', $level=0, $docTag='phparray', $spaceInd=0, array $options=[], array $stackData=[])
static makeInstance($className,... $constructorArguments)
static hostHeaderValueMatchesTrustedHostsPattern($hostHeaderValue)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']