‪TYPO3CMS  ‪main
Check.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
25 
44 class ‪Check implements ‪CheckInterface
45 {
49  protected ‪$messageQueue;
50 
54  protected ‪$requiredPhpExtensions = [
55  'filter',
56  'gd',
57  'intl',
58  'json',
59  'libxml',
60  'mbstring',
61  'PDO',
62  'session',
63  'SPL',
64  'standard',
65  'tokenizer',
66  'xml',
67  'zip',
68  'zlib',
69  ];
70 
74  protected ‪$suggestedPhpExtensions = [
75  'exif' => 'This extension is used to detect the orientation of uploaded images.',
76  'fileinfo' => 'This extension is used for proper file type detection in the File Abstraction Layer.',
77  'openssl' => 'This extension is used for sending SMTP mails over an encrypted channel endpoint.',
78  ];
79 
80  public function ‪__construct()
81  {
82  $this->messageQueue = new ‪FlashMessageQueue('install');
83  }
84 
85  public function ‪getMessageQueue(): ‪FlashMessageQueue
86  {
88  }
89 
93  public function ‪getStatus(): FlashMessageQueue
94  {
98  $this->‪checkMemorySettings();
99  $this->‪checkPhpVersion();
100  $this->‪checkMaxExecutionTime();
101  $this->‪checkDisableFunctions();
102  $this->‪checkDocRoot();
103  $this->‪checkOpenBaseDir();
105 
106  $this->‪checkMaxInputVars();
109 
110  foreach ($this->requiredPhpExtensions as $extension) {
111  $this->‪checkPhpExtension($extension);
112  }
113 
114  foreach ($this->suggestedPhpExtensions as $extension => $purpose) {
115  $this->‪checkPhpExtension($extension, false, $purpose);
116  }
117 
118  $this->‪checkPcreVersion();
120  $this->‪checkGdLibGifSupport();
121  $this->‪checkGdLibJpgSupport();
122  $this->‪checkGdLibPngSupport();
124 
125  return ‪$this->messageQueue;
126  }
127 
131  protected function ‪checkCurrentDirectoryIsInIncludePath()
132  {
133  $includePath = (string)ini_get('include_path');
134  $delimiter = $this->‪isWindowsOs() ? ';' : ':';
135  $pathArray = ‪GeneralUtility::trimExplode($delimiter, $includePath, true);
136  if (!in_array('.', $pathArray)) {
137  $this->messageQueue->enqueue(new FlashMessage(
138  'include_path = ' . implode(' ', $pathArray) . LF
139  . 'Normally the current path \'.\' is included in the'
140  . ' include_path of PHP. Although TYPO3 does not rely on this,'
141  . ' it is an unusual setting that may introduce problems for'
142  . ' some extensions.',
143  'Current directory (./) is not within PHP include path',
144  ContextualFeedbackSeverity::WARNING
145  ));
146  } else {
147  $this->messageQueue->enqueue(new FlashMessage(
148  '',
149  'Current directory (./) is within PHP include path.'
150  ));
151  }
152  }
153 
157  protected function ‪checkFileUploadEnabled()
158  {
159  if (!ini_get('file_uploads')) {
160  $this->messageQueue->enqueue(new FlashMessage(
161  'file_uploads=' . ini_get('file_uploads') . LF
162  . 'TYPO3 uses the ability to upload files from the browser in various cases.'
163  . ' If this flag is disabled in PHP, you won\'t be able to upload files.'
164  . ' But it doesn\'t end here, because not only are files not accepted by'
165  . ' the server - ALL content in the forms are discarded and therefore'
166  . ' nothing at all will be editable if you don\'t set this flag!',
167  'File uploads not allowed in PHP',
168  ContextualFeedbackSeverity::ERROR
169  ));
170  } else {
171  $this->messageQueue->enqueue(new FlashMessage(
172  '',
173  'File uploads allowed in PHP'
174  ));
175  }
176  }
177 
182  {
183  $maximumUploadFilesize = $this->‪getBytesFromSizeMeasurement((string)ini_get('upload_max_filesize'));
184  $maximumPostSize = $this->‪getBytesFromSizeMeasurement((string)ini_get('post_max_size'));
185  if ($maximumPostSize > 0 && $maximumPostSize < $maximumUploadFilesize) {
186  $this->messageQueue->enqueue(new FlashMessage(
187  'upload_max_filesize=' . ini_get('upload_max_filesize') . LF
188  . 'post_max_size=' . ini_get('post_max_size') . LF
189  . 'You have defined a maximum size for file uploads in PHP which'
190  . ' exceeds the allowed size for POST requests. Therefore the'
191  . ' file uploads can also not be larger than ' . ini_get('post_max_size') . '.',
192  'Maximum size for POST requests is smaller than maximum upload filesize in PHP',
193  ContextualFeedbackSeverity::ERROR
194  ));
195  } elseif ($maximumPostSize === $maximumUploadFilesize) {
196  $this->messageQueue->enqueue(new FlashMessage(
197  'The maximum size for file uploads is set to ' . ini_get('upload_max_filesize'),
198  'Maximum post upload size correlates with maximum upload file size in PHP'
199  ));
200  } else {
201  $this->messageQueue->enqueue(new FlashMessage(
202  'The maximum size for file uploads is set to ' . ini_get('upload_max_filesize'),
203  'Maximum post upload size is higher than maximum upload file size in PHP, which is fine.'
204  ));
205  }
206  }
207 
211  protected function ‪checkMemorySettings()
212  {
213  $minimumMemoryLimit = 64;
214  $recommendedMemoryLimit = 128;
215  $memoryLimit = $this->‪getBytesFromSizeMeasurement((string)ini_get('memory_limit'));
216  if ($memoryLimit <= 0) {
217  $this->messageQueue->enqueue(new FlashMessage(
218  'PHP is configured not to limit memory usage at all. This is a risk'
219  . ' and should be avoided in production setup. In general it\'s best practice to limit this.'
220  . ' To be safe, set a limit in PHP, but with a minimum of ' . $recommendedMemoryLimit . 'MB:' . LF
221  . 'memory_limit=' . $recommendedMemoryLimit . 'M',
222  'Unlimited memory limit for PHP',
223  ContextualFeedbackSeverity::WARNING
224  ));
225  } elseif ($memoryLimit < 1024 * 1024 * $minimumMemoryLimit) {
226  $this->messageQueue->enqueue(new FlashMessage(
227  'memory_limit=' . ini_get('memory_limit') . LF
228  . 'Your system is configured to enforce a memory limit for PHP scripts lower than '
229  . $minimumMemoryLimit . 'MB. It is required to raise the limit.'
230  . ' We recommend a minimum PHP memory limit of ' . $recommendedMemoryLimit . 'MB:' . LF
231  . 'memory_limit=' . $recommendedMemoryLimit . 'M',
232  'PHP Memory limit below ' . $minimumMemoryLimit . 'MB',
233  ContextualFeedbackSeverity::ERROR
234  ));
235  } elseif ($memoryLimit < 1024 * 1024 * $recommendedMemoryLimit) {
236  $this->messageQueue->enqueue(new FlashMessage(
237  'memory_limit=' . ini_get('memory_limit') . LF
238  . 'Your system is configured to enforce a memory limit for PHP scripts lower than '
239  . $recommendedMemoryLimit . 'MB.'
240  . ' A slim TYPO3 instance without many extensions will probably work, but you should monitor your'
241  . ' system for "allowed memory size of X bytes exhausted" messages, especially if using the backend.'
242  . ' To be on the safe side, we recommend a minimum PHP memory limit of '
243  . $recommendedMemoryLimit . 'MB:' . LF
244  . 'memory_limit=' . $recommendedMemoryLimit . 'M',
245  'PHP Memory limit below ' . $recommendedMemoryLimit . 'MB',
246  ContextualFeedbackSeverity::WARNING
247  ));
248  } else {
249  $this->messageQueue->enqueue(new FlashMessage(
250  '',
251  'PHP Memory limit is equal to or more than ' . $recommendedMemoryLimit . 'MB'
252  ));
253  }
254  }
255 
259  protected function ‪checkPhpVersion()
260  {
261  $minimumPhpVersion = '8.1.0';
262  $currentPhpVersion = PHP_VERSION;
263  if (version_compare($currentPhpVersion, $minimumPhpVersion) < 0) {
264  $this->messageQueue->enqueue(new FlashMessage(
265  'Your PHP version ' . $currentPhpVersion . ' is too old. TYPO3 CMS does not run'
266  . ' with this version. Update to at least PHP ' . $minimumPhpVersion,
267  'PHP version too low',
268  ContextualFeedbackSeverity::ERROR
269  ));
270  } else {
271  $this->messageQueue->enqueue(new FlashMessage(
272  '',
273  'PHP version is fine'
274  ));
275  }
276  }
277 
281  protected function ‪checkPcreVersion()
282  {
283  $minimumPcreVersion = '8.38';
284  if (!extension_loaded('pcre')) {
285  $this->messageQueue->enqueue(new FlashMessage(
286  'TYPO3 CMS uses PHP extension pcre but it is not loaded'
287  . ' in your environment. Change your environment to provide this extension'
288  . ' in with minimum version ' . $minimumPcreVersion . '.',
289  'PHP extension pcre not loaded',
290  ContextualFeedbackSeverity::ERROR
291  ));
292  } else {
293  $installedPcreVersionString = trim(PCRE_VERSION); // '8.39 2016-06-14'
294  $mainPcreVersionString = explode(' ', $installedPcreVersionString);
295  $mainPcreVersionString = $mainPcreVersionString[0]; // '8.39'
296  if (version_compare($mainPcreVersionString, $minimumPcreVersion) < 0) {
297  $this->messageQueue->enqueue(new FlashMessage(
298  'Your PCRE version ' . PCRE_VERSION . ' is too old. TYPO3 CMS may trigger PHP segmentantion'
299  . ' faults with this version. Update to at least PCRE ' . $minimumPcreVersion,
300  'PCRE version too low',
301  ContextualFeedbackSeverity::ERROR
302  ));
303  } else {
304  $this->messageQueue->enqueue(new FlashMessage(
305  '',
306  'PHP extension PCRE is loaded and version is fine'
307  ));
308  }
309  }
310  }
311 
315  protected function ‪checkMaxExecutionTime()
316  {
317  $minimumMaximumExecutionTime = 30;
318  $recommendedMaximumExecutionTime = 240;
319  $currentMaximumExecutionTime = ini_get('max_execution_time');
320  if ($currentMaximumExecutionTime == 0) {
321  $this->messageQueue->enqueue(new FlashMessage(
322  'max_execution_time=0' . LF
323  . 'While TYPO3 is fine with this, you risk a denial-of-service for your system if for whatever'
324  . ' reason some script hangs in an infinite loop. You are usually on the safe side '
325  . ' if it is reduced to ' . $recommendedMaximumExecutionTime . ' seconds:' . LF
326  . 'max_execution_time=' . $recommendedMaximumExecutionTime,
327  'Infinite PHP script execution time',
328  ContextualFeedbackSeverity::WARNING
329  ));
330  } elseif ($currentMaximumExecutionTime < $minimumMaximumExecutionTime) {
331  $this->messageQueue->enqueue(new FlashMessage(
332  'max_execution_time=' . $currentMaximumExecutionTime . LF
333  . 'Your max_execution_time is too low. Some expensive operations in TYPO3 can take longer than that.'
334  . ' It is recommended to raise the limit to ' . $recommendedMaximumExecutionTime . ' seconds:' . LF
335  . 'max_execution_time=' . $recommendedMaximumExecutionTime,
336  'Low PHP script execution time',
337  ContextualFeedbackSeverity::ERROR
338  ));
339  } elseif ($currentMaximumExecutionTime < $recommendedMaximumExecutionTime) {
340  $this->messageQueue->enqueue(new FlashMessage(
341  'max_execution_time=' . $currentMaximumExecutionTime . LF
342  . 'Your max_execution_time is low. While TYPO3 often runs without problems'
343  . ' with ' . $minimumMaximumExecutionTime . ' seconds,'
344  . ' it may still happen that script execution is stopped before finishing'
345  . ' calculations. You should monitor the system for messages in this area'
346  . ' and maybe raise the limit to ' . $recommendedMaximumExecutionTime . ' seconds:' . LF
347  . 'max_execution_time=' . $recommendedMaximumExecutionTime,
348  'Low PHP script execution time',
349  ContextualFeedbackSeverity::WARNING
350  ));
351  } else {
352  $this->messageQueue->enqueue(new FlashMessage(
353  '',
354  'Maximum PHP script execution time is equal to or more than ' . $recommendedMaximumExecutionTime
355  ));
356  }
357  }
358 
362  protected function ‪checkDisableFunctions()
363  {
364  $disabledFunctions = trim((string)ini_get('disable_functions'));
365 
366  // Filter "disable_functions"
367  $disabledFunctionsArray = ‪GeneralUtility::trimExplode(',', $disabledFunctions, true);
368 
369  // Array with strings to find
370  $findStrings = [
371  // Disabled by default on Ubuntu OS but this is okay since the Core does not use them
372  'pcntl_',
373  ];
374  foreach ($disabledFunctionsArray as $key => $disabledFunction) {
375  foreach ($findStrings as $findString) {
376  if (str_contains($disabledFunction, $findString)) {
377  unset($disabledFunctionsArray[$key]);
378  }
379  }
380  }
381 
382  if ($disabledFunctions !== '') {
383  if (!empty($disabledFunctionsArray)) {
384  $this->messageQueue->enqueue(new FlashMessage(
385  'disable_functions=' . implode(' ', explode(',', $disabledFunctions)) . LF
386  . 'These function(s) are disabled. TYPO3 uses some of those, so there might be trouble.'
387  . ' TYPO3 is designed to use the default set of PHP functions plus some common extensions.'
388  . ' Possibly these functions are disabled'
389  . ' due to security considerations and most likely the list would include a function like'
390  . ' exec() which is used by TYPO3 at various places. Depending on which exact functions'
391  . ' are disabled, some parts of the system may just break without further notice.',
392  'Some PHP functions disabled',
393  ContextualFeedbackSeverity::ERROR
394  ));
395  } else {
396  $this->messageQueue->enqueue(new FlashMessage(
397  'disable_functions=' . implode(' ', explode(',', $disabledFunctions)) . LF
398  . 'These function(s) are disabled. TYPO3 uses currently none of those, so you are good to go.',
399  'Some PHP functions currently disabled but OK'
400  ));
401  }
402  } else {
403  $this->messageQueue->enqueue(new FlashMessage(
404  '',
405  'No disabled PHP functions'
406  ));
407  }
408  }
409 
413  protected function ‪checkDocRoot()
414  {
415  $docRootSetting = trim((string)ini_get('doc_root'));
416  if ($docRootSetting !== '') {
417  $this->messageQueue->enqueue(new FlashMessage(
418  'doc_root=' . $docRootSetting . LF
419  . 'PHP cannot execute scripts'
420  . ' outside this directory. This setting is seldom used and must correlate'
421  . ' with your actual document root. You might be in trouble if your'
422  . ' TYPO3 CMS core code is linked to some different location.'
423  . ' If that is a problem, the setting must be changed.',
424  'doc_root is set',
425  ContextualFeedbackSeverity::NOTICE
426  ));
427  } else {
428  $this->messageQueue->enqueue(new FlashMessage(
429  '',
430  'PHP doc_root is not set'
431  ));
432  }
433  }
434 
438  protected function ‪checkOpenBaseDir()
439  {
440  $openBaseDirSetting = trim((string)ini_get('open_basedir'));
441  if ($openBaseDirSetting !== '') {
442  $this->messageQueue->enqueue(new FlashMessage(
443  'open_basedir = ' . ini_get('open_basedir') . LF
444  . 'This restricts TYPO3 to open and include files only in this'
445  . ' path. Please make sure that this does not prevent TYPO3 from running,'
446  . ' if for example your TYPO3 CMS core is linked to a different directory'
447  . ' not included in this path.',
448  'PHP open_basedir is set',
449  ContextualFeedbackSeverity::NOTICE
450  ));
451  } else {
452  $this->messageQueue->enqueue(new FlashMessage(
453  '',
454  'PHP open_basedir is off'
455  ));
456  }
457  }
458 
462  protected function ‪checkXdebugMaxNestingLevel()
463  {
464  if (extension_loaded('xdebug')) {
465  $recommendedMaxNestingLevel = 400;
466  $errorThreshold = 250;
467  $currentMaxNestingLevel = ini_get('xdebug.max_nesting_level');
468  if ($currentMaxNestingLevel < $errorThreshold) {
469  $this->messageQueue->enqueue(new FlashMessage(
470  'xdebug.max_nesting_level=' . $currentMaxNestingLevel . LF
471  . 'This setting controls the maximum number of nested function calls to protect against'
472  . ' infinite recursion. The current value is too low for TYPO3 CMS and must'
473  . ' be either raised or xdebug has to be unloaded. A value of ' . $recommendedMaxNestingLevel
474  . ' is recommended. Warning: Expect fatal PHP errors in central parts of the CMS'
475  . ' if the value is not raised significantly to:' . LF
476  . 'xdebug.max_nesting_level=' . $recommendedMaxNestingLevel,
477  'PHP xdebug.max_nesting_level is critically low',
478  ContextualFeedbackSeverity::ERROR
479  ));
480  } elseif ($currentMaxNestingLevel < $recommendedMaxNestingLevel) {
481  $this->messageQueue->enqueue(new FlashMessage(
482  'xdebug.max_nesting_level=' . $currentMaxNestingLevel . LF
483  . 'This setting controls the maximum number of nested function calls to protect against'
484  . ' infinite recursion. The current value is high enough for the TYPO3 CMS core to work'
485  . ' fine, but still some extensions could raise fatal PHP errors if the setting is not'
486  . ' raised further. A value of ' . $recommendedMaxNestingLevel . ' is recommended.' . LF
487  . 'xdebug.max_nesting_level=' . $recommendedMaxNestingLevel,
488  'PHP xdebug.max_nesting_level is low',
489  ContextualFeedbackSeverity::WARNING
490  ));
491  } else {
492  $this->messageQueue->enqueue(new FlashMessage(
493  '',
494  'PHP xdebug.max_nesting_level ok'
495  ));
496  }
497  } else {
498  $this->messageQueue->enqueue(new FlashMessage(
499  '',
500  'PHP xdebug extension not loaded'
501  ));
502  }
503  }
504 
508  protected function ‪checkMaxInputVars()
509  {
510  $recommendedMaxInputVars = 1500;
511  $minimumMaxInputVars = 1000;
512  $currentMaxInputVars = ini_get('max_input_vars');
513 
514  if ($currentMaxInputVars < $minimumMaxInputVars) {
515  $this->messageQueue->enqueue(new FlashMessage(
516  'max_input_vars=' . $currentMaxInputVars . LF
517  . 'This setting can lead to lost information if submitting forms with lots of data in TYPO3 CMS'
518  . ' (as the install tool does). It is highly recommended to raise this'
519  . ' to at least ' . $recommendedMaxInputVars . ':' . LF
520  . 'max_input_vars=' . $recommendedMaxInputVars,
521  'PHP max_input_vars too low',
522  ContextualFeedbackSeverity::ERROR
523  ));
524  } elseif ($currentMaxInputVars < $recommendedMaxInputVars) {
525  $this->messageQueue->enqueue(new FlashMessage(
526  'max_input_vars=' . $currentMaxInputVars . LF
527  . 'This setting can lead to lost information if submitting forms with lots of data in TYPO3 CMS'
528  . ' (as the install tool does). It is highly recommended to raise this'
529  . ' to at least ' . $recommendedMaxInputVars . ':' . LF
530  . 'max_input_vars=' . $recommendedMaxInputVars,
531  'PHP max_input_vars very low',
532  ContextualFeedbackSeverity::WARNING
533  ));
534  } else {
535  $this->messageQueue->enqueue(new FlashMessage(
536  '',
537  'PHP max_input_vars ok'
538  ));
539  }
540  }
541 
545  protected function ‪checkReflectionDocComment()
546  {
547  $testReflection = new \ReflectionMethod(static::class, __FUNCTION__);
548  if ($testReflection->getDocComment() === false) {
549  $this->messageQueue->enqueue(new FlashMessage(
550  'TYPO3 CMS core extensions like extbase and fluid heavily rely on method'
551  . ' comment parsing to fetch annotations and add magic belonging to them.'
552  . ' This does not work in the current environment and so we cannot install'
553  . ' TYPO3 CMS.' . LF
554  . ' Here are some possibilities: ' . LF
555  . '* In Zend OPcache you can disable saving/loading comments. If you are using'
556  . ' Zend OPcache (included since PHP 5.5) then check your php.ini settings for'
557  . ' opcache.save_comments and opcache.load_comments and enable them.' . LF
558  . '* In Zend Optimizer+ you can disable saving comments. If you are using'
559  . ' Zend Optimizer+ then check your php.ini settings for'
560  . ' zend_optimizerplus.save_comments and enable it.' . LF
561  . '* The PHP extension eaccelerator is known to break this if'
562  . ' it is compiled without --with-eaccelerator-doc-comment-inclusion flag.'
563  . ' This compile flag must be specified, otherwise TYPO3 CMS will not work.' . LF
564  . 'For more information take a look in our documentation ' . ‪Typo3Information::URL_OPCACHE . '.',
565  'PHP Doc comment reflection broken',
566  ContextualFeedbackSeverity::ERROR
567  ));
568  } else {
569  $this->messageQueue->enqueue(new FlashMessage(
570  '',
571  'PHP Doc comment reflection works'
572  ));
573  }
574  }
575 
579  protected function ‪checkWindowsApacheThreadStackSize()
580  {
581  if ($this->‪isWindowsOs()
582  && str_starts_with(‪$_SERVER['SERVER_SOFTWARE'], 'Apache')
583  ) {
584  $this->messageQueue->enqueue(new FlashMessage(
585  'This current value cannot be checked by the system, so please ignore this warning if it'
586  . ' is already taken care of: Fluid uses complex regular expressions which require a lot'
587  . ' of stack space during the first processing.'
588  . ' On Windows the default stack size for Apache is a lot smaller than on UNIX.'
589  . ' You can increase the size to 8MB (default on UNIX) by adding the following configuration'
590  . ' to httpd.conf and restarting Apache afterwards:' . LF
591  . '<IfModule mpm_winnt_module>ThreadStackSize 8388608</IfModule>',
592  'Windows apache thread stack size',
593  ContextualFeedbackSeverity::WARNING
594  ));
595  } else {
596  $this->messageQueue->enqueue(new FlashMessage(
597  '',
598  'Apache ThreadStackSize is not an issue on UNIX systems'
599  ));
600  }
601  }
602 
606  public function ‪checkPhpExtension(string $extension, bool $required = true, string $purpose = '')
607  {
608  if (!extension_loaded($extension)) {
609  $this->messageQueue->enqueue(new FlashMessage(
610  'TYPO3 uses the PHP extension "' . $extension . '" but it is not loaded'
611  . ' in your environment. Change your environment to provide this extension. '
612  . $purpose,
613  'PHP extension "' . $extension . '" not loaded',
614  $required ? ContextualFeedbackSeverity::ERROR : ContextualFeedbackSeverity::WARNING
615  ));
616  } else {
617  $this->messageQueue->enqueue(new FlashMessage(
618  '',
619  'PHP extension "' . $extension . '" loaded'
620  ));
621  }
622  }
623 
627  protected function ‪checkGdLibTrueColorSupport()
628  {
629  if (function_exists('imagecreatetruecolor')) {
630  $imageResource = @imagecreatetruecolor(50, 100);
631  if ($this->‪checkImageResource($imageResource)) {
632  imagedestroy($imageResource);
633  $this->messageQueue->enqueue(new FlashMessage(
634  '',
635  'PHP GD library true color works'
636  ));
637  } else {
638  $this->messageQueue->enqueue(new FlashMessage(
639  'GD is loaded, but calling imagecreatetruecolor() fails.'
640  . ' This must be fixed, TYPO3 CMS won\'t work well otherwise.',
641  'PHP GD library true color support broken',
642  ContextualFeedbackSeverity::ERROR
643  ));
644  }
645  } else {
646  $this->messageQueue->enqueue(new FlashMessage(
647  'Gdlib is essential for TYPO3 CMS to work properly.',
648  'PHP GD library true color support missing',
649  ContextualFeedbackSeverity::ERROR
650  ));
651  }
652  }
653 
657  protected function ‪checkGdLibGifSupport()
658  {
659  if (function_exists('imagecreatefromgif')
660  && function_exists('imagegif')
661  && (imagetypes() & IMG_GIF)
662  ) {
663  // Do not use data:// wrapper to be independent of allow_url_fopen
664  $imageResource = @imagecreatefromgif(__DIR__ . '/../../Resources/Public/Images/TestInput/Test.gif');
665  if ($this->‪checkImageResource($imageResource)) {
666  imagedestroy($imageResource);
667  $this->messageQueue->enqueue(new FlashMessage(
668  '',
669  'PHP GD library has gif support'
670  ));
671  } else {
672  $this->messageQueue->enqueue(new FlashMessage(
673  'GD is loaded, but calling imagecreatefromgif() fails. This must be fixed, TYPO3 CMS won\'t work well otherwise.',
674  'PHP GD library gif support broken',
675  ContextualFeedbackSeverity::ERROR
676  ));
677  }
678  } else {
679  $this->messageQueue->enqueue(new FlashMessage(
680  'GD must be compiled with gif support. This is essential for TYPO3 CMS to work properly.',
681  'PHP GD library gif support missing',
682  ContextualFeedbackSeverity::ERROR
683  ));
684  }
685  }
686 
690  protected function ‪checkGdLibJpgSupport()
691  {
692  if (function_exists('imagecreatefromjpeg')
693  && function_exists('imagejpeg')
694  && (imagetypes() & IMG_JPG)
695  ) {
696  $this->messageQueue->enqueue(new FlashMessage(
697  '',
698  'PHP GD library has jpg support'
699  ));
700  } else {
701  $this->messageQueue->enqueue(new FlashMessage(
702  'GD must be compiled with jpg support. This is essential for TYPO3 CMS to work properly.',
703  'PHP GD library jpg support missing',
704  ContextualFeedbackSeverity::ERROR
705  ));
706  }
707  }
708 
712  protected function ‪checkGdLibPngSupport()
713  {
714  if (function_exists('imagecreatefrompng')
715  && function_exists('imagepng')
716  && (imagetypes() & IMG_PNG)
717  ) {
718  // Do not use data:// wrapper to be independent of allow_url_fopen
719  $imageResource = @imagecreatefrompng(__DIR__ . '/../../Resources/Public/Images/TestInput/Test.png');
720  if ($this->‪checkImageResource($imageResource)) {
721  imagedestroy($imageResource);
722  $this->messageQueue->enqueue(new FlashMessage(
723  '',
724  'PHP GD library has png support'
725  ));
726  } else {
727  $this->messageQueue->enqueue(new FlashMessage(
728  'GD is compiled with png support, but calling imagecreatefrompng() fails.'
729  . ' Check your environment and fix it, png in GD lib is important'
730  . ' for TYPO3 CMS to work properly.',
731  'PHP GD library png support broken',
732  ContextualFeedbackSeverity::ERROR
733  ));
734  }
735  } else {
736  $this->messageQueue->enqueue(new FlashMessage(
737  'GD must be compiled with png support. This is essential for TYPO3 CMS to work properly',
738  'PHP GD library png support missing',
739  ContextualFeedbackSeverity::ERROR
740  ));
741  }
742  }
743 
747  protected function ‪checkGdLibFreeTypeSupport()
748  {
749  if (function_exists('imagettftext')) {
750  $this->messageQueue->enqueue(new FlashMessage(
751  'There is a difference between the font size setting which the GD'
752  . ' library should be supplied with. If installation is completed'
753  . ' a test in the install tool helps to find out the value you need.',
754  'PHP GD library has freetype font support'
755  ));
756  } else {
757  $this->messageQueue->enqueue(new FlashMessage(
758  'Some core functionality and extension rely on the GD'
759  . ' to render fonts on images. This support is missing'
760  . ' in your environment. Install it.',
761  'PHP GD library freetype support missing',
762  ContextualFeedbackSeverity::ERROR
763  ));
764  }
765  }
766 
777  protected function ‪isValidIp($ip)
778  {
779  return filter_var($ip, FILTER_VALIDATE_IP) !== false;
780  }
781 
787  protected function ‪isWindowsOs()
788  {
789  $windowsOs = false;
790  if (stripos(PHP_OS, 'darwin') === false && stripos(PHP_OS, 'win') !== false) {
791  $windowsOs = true;
792  }
793  return $windowsOs;
794  }
795 
802  protected function ‪getBytesFromSizeMeasurement($measurement)
803  {
804  $bytes = (float)$measurement;
805  if (stripos($measurement, 'G')) {
806  $bytes *= 1024 * 1024 * 1024;
807  } elseif (stripos($measurement, 'M')) {
808  $bytes *= 1024 * 1024;
809  } elseif (stripos($measurement, 'K')) {
810  $bytes *= 1024;
811  }
812  return (int)$bytes;
813  }
814 
815  private function ‪checkImageResource($imageResource): bool
816  {
817  return $imageResource instanceof \GdImage;
818  }
819 }
‪TYPO3\CMS\Install\SystemEnvironment\Check\checkXdebugMaxNestingLevel
‪checkXdebugMaxNestingLevel()
Definition: Check.php:459
‪TYPO3\CMS\Install\SystemEnvironment\Check\$suggestedPhpExtensions
‪string[] $suggestedPhpExtensions
Definition: Check.php:71
‪TYPO3\CMS\Install\SystemEnvironment\Check\checkMaxExecutionTime
‪checkMaxExecutionTime()
Definition: Check.php:312
‪TYPO3\CMS\Core\Information\Typo3Information
Definition: Typo3Information.php:28
‪TYPO3\CMS\Install\SystemEnvironment\Check\$requiredPhpExtensions
‪array $requiredPhpExtensions
Definition: Check.php:52
‪TYPO3\CMS\Install\SystemEnvironment\Check\checkDisableFunctions
‪checkDisableFunctions()
Definition: Check.php:359
‪TYPO3\CMS\Install\SystemEnvironment\CheckInterface
Definition: CheckInterface.php:31
‪TYPO3\CMS\Install\SystemEnvironment\Check\checkGdLibTrueColorSupport
‪checkGdLibTrueColorSupport()
Definition: Check.php:624
‪TYPO3\CMS\Install\SystemEnvironment\Check\checkMaxInputVars
‪checkMaxInputVars()
Definition: Check.php:505
‪TYPO3\CMS\Install\SystemEnvironment\Check\checkReflectionDocComment
‪checkReflectionDocComment()
Definition: Check.php:542
‪TYPO3\CMS\Install\SystemEnvironment\Check\checkCurrentDirectoryIsInIncludePath
‪checkCurrentDirectoryIsInIncludePath()
Definition: Check.php:128
‪TYPO3\CMS\Install\SystemEnvironment\Check\checkFileUploadEnabled
‪checkFileUploadEnabled()
Definition: Check.php:154
‪TYPO3\CMS\Install\SystemEnvironment\Check\getStatus
‪getStatus()
Definition: Check.php:90
‪TYPO3\CMS\Install\SystemEnvironment\Check\checkPostUploadSizeIsHigherOrEqualMaximumFileUploadSize
‪checkPostUploadSizeIsHigherOrEqualMaximumFileUploadSize()
Definition: Check.php:178
‪TYPO3\CMS\Install\SystemEnvironment\Check\checkGdLibGifSupport
‪checkGdLibGifSupport()
Definition: Check.php:654
‪TYPO3\CMS\Install\SystemEnvironment\Check\getBytesFromSizeMeasurement
‪int getBytesFromSizeMeasurement($measurement)
Definition: Check.php:799
‪TYPO3\CMS\Install\SystemEnvironment\Check\isWindowsOs
‪bool isWindowsOs()
Definition: Check.php:784
‪TYPO3\CMS\Core\Type\ContextualFeedbackSeverity
‪ContextualFeedbackSeverity
Definition: ContextualFeedbackSeverity.php:25
‪TYPO3\CMS\Install\SystemEnvironment\Check\__construct
‪__construct()
Definition: Check.php:77
‪TYPO3\CMS\Install\SystemEnvironment\Check\checkWindowsApacheThreadStackSize
‪checkWindowsApacheThreadStackSize()
Definition: Check.php:576
‪TYPO3\CMS\Install\SystemEnvironment
Definition: Check.php:18
‪TYPO3\CMS\Install\SystemEnvironment\Check\checkGdLibFreeTypeSupport
‪checkGdLibFreeTypeSupport()
Definition: Check.php:744
‪$_SERVER
‪$_SERVER['TYPO3_DEPRECATED_ENTRYPOINT']
Definition: legacy-backend.php:20
‪TYPO3\CMS\Install\SystemEnvironment\Check\checkGdLibPngSupport
‪checkGdLibPngSupport()
Definition: Check.php:709
‪TYPO3\CMS\Install\SystemEnvironment\Check\$messageQueue
‪FlashMessageQueue $messageQueue
Definition: Check.php:48
‪TYPO3\CMS\Install\SystemEnvironment\Check\checkImageResource
‪checkImageResource($imageResource)
Definition: Check.php:812
‪TYPO3\CMS\Install\SystemEnvironment\Check\checkPhpVersion
‪checkPhpVersion()
Definition: Check.php:256
‪TYPO3\CMS\Install\SystemEnvironment\Check\checkGdLibJpgSupport
‪checkGdLibJpgSupport()
Definition: Check.php:687
‪TYPO3\CMS\Core\Messaging\FlashMessage
Definition: FlashMessage.php:27
‪TYPO3\CMS\Install\SystemEnvironment\Check
Definition: Check.php:45
‪TYPO3\CMS\Install\SystemEnvironment\Check\checkPcreVersion
‪checkPcreVersion()
Definition: Check.php:278
‪TYPO3\CMS\Install\SystemEnvironment\Check\isValidIp
‪bool isValidIp($ip)
Definition: Check.php:774
‪TYPO3\CMS\Install\SystemEnvironment\Check\checkOpenBaseDir
‪checkOpenBaseDir()
Definition: Check.php:435
‪TYPO3\CMS\Core\Information\Typo3Information\URL_OPCACHE
‪const URL_OPCACHE
Definition: Typo3Information.php:33
‪TYPO3\CMS\Install\SystemEnvironment\Check\checkMemorySettings
‪checkMemorySettings()
Definition: Check.php:208
‪TYPO3\CMS\Install\SystemEnvironment\Check\getMessageQueue
‪getMessageQueue()
Definition: Check.php:82
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Install\SystemEnvironment\Check\checkPhpExtension
‪checkPhpExtension(string $extension, bool $required=true, string $purpose='')
Definition: Check.php:603
‪TYPO3\CMS\Core\Messaging\FlashMessageQueue
Definition: FlashMessageQueue.php:29
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static list< string > trimExplode(string $delim, string $string, bool $removeEmptyValues=false, int $limit=0)
Definition: GeneralUtility.php:822
‪TYPO3\CMS\Install\SystemEnvironment\Check\checkDocRoot
‪checkDocRoot()
Definition: Check.php:410