| Current Path : /var/www/surf/TYPO3/vendor/typo3/cms-install/Classes/SystemEnvironment/ |
| Current File : /var/www/surf/TYPO3/vendor/typo3/cms-install/Classes/SystemEnvironment/Check.php |
<?php
declare(strict_types=1);
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
namespace TYPO3\CMS\Install\SystemEnvironment;
use TYPO3\CMS\Core\Information\Typo3Information;
use TYPO3\CMS\Core\Messaging\FlashMessage;
use TYPO3\CMS\Core\Messaging\FlashMessageQueue;
use TYPO3\CMS\Core\Type\ContextualFeedbackSeverity;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* Check system environment status.
*
* This class is a hardcoded requirement check of the underlying
* server and PHP system.
*
* The class *must not* check for any TYPO3 specific things like
* specific configuration values or directories.
*
* This class is instantiated as a very early during installation.
*
* Be picky with dependencies here:
* * No hooks or anything like that
* * No localization
* * Only low level ext:core classes if free of side effects
*
* @internal This class is only meant to be used within EXT:install and is not part of the TYPO3 Core API.
*/
class Check implements CheckInterface
{
/**
* @var FlashMessageQueue
*/
protected $messageQueue;
/**
* @var array List of required PHP extensions
*/
protected $requiredPhpExtensions = [
'filter',
'gd',
'intl',
'json',
'libxml',
'mbstring',
'PDO',
'session',
'SPL',
'standard',
'tokenizer',
'xml',
'zip',
'zlib',
];
/**
* @var string[]
*/
protected $suggestedPhpExtensions = [
'fileinfo' => 'This extension is used for proper file type detection in the File Abstraction Layer.',
'openssl' => 'This extension is used for sending SMTP mails over an encrypted channel endpoint.',
];
public function __construct()
{
$this->messageQueue = new FlashMessageQueue('install');
}
public function getMessageQueue(): FlashMessageQueue
{
return $this->messageQueue;
}
/**
* Get all status information as array with status objects
*/
public function getStatus(): FlashMessageQueue
{
$this->checkCurrentDirectoryIsInIncludePath();
$this->checkFileUploadEnabled();
$this->checkPostUploadSizeIsHigherOrEqualMaximumFileUploadSize();
$this->checkMemorySettings();
$this->checkPhpVersion();
$this->checkMaxExecutionTime();
$this->checkDisableFunctions();
$this->checkDocRoot();
$this->checkOpenBaseDir();
$this->checkXdebugMaxNestingLevel();
$this->checkMaxInputVars();
$this->checkReflectionDocComment();
$this->checkWindowsApacheThreadStackSize();
foreach ($this->requiredPhpExtensions as $extension) {
$this->checkPhpExtension($extension);
}
foreach ($this->suggestedPhpExtensions as $extension => $purpose) {
$this->checkPhpExtension($extension, false, $purpose);
}
$this->checkPcreVersion();
$this->checkGdLibTrueColorSupport();
$this->checkGdLibGifSupport();
$this->checkGdLibJpgSupport();
$this->checkGdLibPngSupport();
$this->checkGdLibFreeTypeSupport();
return $this->messageQueue;
}
/**
* Checks if current directory (.) is in PHP include path
*/
protected function checkCurrentDirectoryIsInIncludePath()
{
$includePath = (string)ini_get('include_path');
$delimiter = $this->isWindowsOs() ? ';' : ':';
$pathArray = GeneralUtility::trimExplode($delimiter, $includePath, true);
if (!in_array('.', $pathArray)) {
$this->messageQueue->enqueue(new FlashMessage(
'include_path = ' . implode(' ', $pathArray) . LF
. 'Normally the current path \'.\' is included in the'
. ' include_path of PHP. Although TYPO3 does not rely on this,'
. ' it is an unusual setting that may introduce problems for'
. ' some extensions.',
'Current directory (./) is not within PHP include path',
ContextualFeedbackSeverity::WARNING
));
} else {
$this->messageQueue->enqueue(new FlashMessage(
'',
'Current directory (./) is within PHP include path.'
));
}
}
/**
* Check if file uploads are enabled in PHP
*/
protected function checkFileUploadEnabled()
{
if (!ini_get('file_uploads')) {
$this->messageQueue->enqueue(new FlashMessage(
'file_uploads=' . ini_get('file_uploads') . LF
. 'TYPO3 uses the ability to upload files from the browser in various cases.'
. ' If this flag is disabled in PHP, you won\'t be able to upload files.'
. ' But it doesn\'t end here, because not only are files not accepted by'
. ' the server - ALL content in the forms are discarded and therefore'
. ' nothing at all will be editable if you don\'t set this flag!',
'File uploads not allowed in PHP',
ContextualFeedbackSeverity::ERROR
));
} else {
$this->messageQueue->enqueue(new FlashMessage(
'',
'File uploads allowed in PHP'
));
}
}
/**
* Check maximum post upload size correlates with maximum file upload
*/
protected function checkPostUploadSizeIsHigherOrEqualMaximumFileUploadSize()
{
$maximumUploadFilesize = $this->getBytesFromSizeMeasurement((string)ini_get('upload_max_filesize'));
$maximumPostSize = $this->getBytesFromSizeMeasurement((string)ini_get('post_max_size'));
if ($maximumPostSize > 0 && $maximumPostSize < $maximumUploadFilesize) {
$this->messageQueue->enqueue(new FlashMessage(
'upload_max_filesize=' . ini_get('upload_max_filesize') . LF
. 'post_max_size=' . ini_get('post_max_size') . LF
. 'You have defined a maximum size for file uploads in PHP which'
. ' exceeds the allowed size for POST requests. Therefore the'
. ' file uploads can also not be larger than ' . ini_get('post_max_size') . '.',
'Maximum size for POST requests is smaller than maximum upload filesize in PHP',
ContextualFeedbackSeverity::ERROR
));
} elseif ($maximumPostSize === $maximumUploadFilesize) {
$this->messageQueue->enqueue(new FlashMessage(
'The maximum size for file uploads is set to ' . ini_get('upload_max_filesize'),
'Maximum post upload size correlates with maximum upload file size in PHP'
));
} else {
$this->messageQueue->enqueue(new FlashMessage(
'The maximum size for file uploads is set to ' . ini_get('upload_max_filesize'),
'Maximum post upload size is higher than maximum upload file size in PHP, which is fine.'
));
}
}
/**
* Check memory settings
*/
protected function checkMemorySettings()
{
$minimumMemoryLimit = 64;
$recommendedMemoryLimit = 128;
$memoryLimit = $this->getBytesFromSizeMeasurement((string)ini_get('memory_limit'));
if ($memoryLimit <= 0) {
$this->messageQueue->enqueue(new FlashMessage(
'PHP is configured not to limit memory usage at all. This is a risk'
. ' and should be avoided in production setup. In general it\'s best practice to limit this.'
. ' To be safe, set a limit in PHP, but with a minimum of ' . $recommendedMemoryLimit . 'MB:' . LF
. 'memory_limit=' . $recommendedMemoryLimit . 'M',
'Unlimited memory limit for PHP',
ContextualFeedbackSeverity::WARNING
));
} elseif ($memoryLimit < 1024 * 1024 * $minimumMemoryLimit) {
$this->messageQueue->enqueue(new FlashMessage(
'memory_limit=' . ini_get('memory_limit') . LF
. 'Your system is configured to enforce a memory limit for PHP scripts lower than '
. $minimumMemoryLimit . 'MB. It is required to raise the limit.'
. ' We recommend a minimum PHP memory limit of ' . $recommendedMemoryLimit . 'MB:' . LF
. 'memory_limit=' . $recommendedMemoryLimit . 'M',
'PHP Memory limit below ' . $minimumMemoryLimit . 'MB',
ContextualFeedbackSeverity::ERROR
));
} elseif ($memoryLimit < 1024 * 1024 * $recommendedMemoryLimit) {
$this->messageQueue->enqueue(new FlashMessage(
'memory_limit=' . ini_get('memory_limit') . LF
. 'Your system is configured to enforce a memory limit for PHP scripts lower than '
. $recommendedMemoryLimit . 'MB.'
. ' A slim TYPO3 instance without many extensions will probably work, but you should monitor your'
. ' system for "allowed memory size of X bytes exhausted" messages, especially if using the backend.'
. ' To be on the safe side, we recommend a minimum PHP memory limit of '
. $recommendedMemoryLimit . 'MB:' . LF
. 'memory_limit=' . $recommendedMemoryLimit . 'M',
'PHP Memory limit below ' . $recommendedMemoryLimit . 'MB',
ContextualFeedbackSeverity::WARNING
));
} else {
$this->messageQueue->enqueue(new FlashMessage(
'',
'PHP Memory limit is equal to or more than ' . $recommendedMemoryLimit . 'MB'
));
}
}
/**
* Check minimum PHP version
*/
protected function checkPhpVersion()
{
$minimumPhpVersion = '8.1.0';
$currentPhpVersion = PHP_VERSION;
if (version_compare($currentPhpVersion, $minimumPhpVersion) < 0) {
$this->messageQueue->enqueue(new FlashMessage(
'Your PHP version ' . $currentPhpVersion . ' is too old. TYPO3 CMS does not run'
. ' with this version. Update to at least PHP ' . $minimumPhpVersion,
'PHP version too low',
ContextualFeedbackSeverity::ERROR
));
} else {
$this->messageQueue->enqueue(new FlashMessage(
'',
'PHP version is fine'
));
}
}
/**
* Check PRCE module is loaded and minimum version
*/
protected function checkPcreVersion()
{
$minimumPcreVersion = '8.38';
if (!extension_loaded('pcre')) {
$this->messageQueue->enqueue(new FlashMessage(
'TYPO3 CMS uses PHP extension pcre but it is not loaded'
. ' in your environment. Change your environment to provide this extension'
. ' in with minimum version ' . $minimumPcreVersion . '.',
'PHP extension pcre not loaded',
ContextualFeedbackSeverity::ERROR
));
} else {
$installedPcreVersionString = trim(PCRE_VERSION); // '8.39 2016-06-14'
$mainPcreVersionString = explode(' ', $installedPcreVersionString);
$mainPcreVersionString = $mainPcreVersionString[0]; // '8.39'
if (version_compare($mainPcreVersionString, $minimumPcreVersion) < 0) {
$this->messageQueue->enqueue(new FlashMessage(
'Your PCRE version ' . PCRE_VERSION . ' is too old. TYPO3 CMS may trigger PHP segmentantion'
. ' faults with this version. Update to at least PCRE ' . $minimumPcreVersion,
'PCRE version too low',
ContextualFeedbackSeverity::ERROR
));
} else {
$this->messageQueue->enqueue(new FlashMessage(
'',
'PHP extension PCRE is loaded and version is fine'
));
}
}
}
/**
* Check maximum execution time
*/
protected function checkMaxExecutionTime()
{
$minimumMaximumExecutionTime = 30;
$recommendedMaximumExecutionTime = 240;
$currentMaximumExecutionTime = ini_get('max_execution_time');
if ($currentMaximumExecutionTime == 0) {
$this->messageQueue->enqueue(new FlashMessage(
'max_execution_time=0' . LF
. 'While TYPO3 is fine with this, you risk a denial-of-service for your system if for whatever'
. ' reason some script hangs in an infinite loop. You are usually on the safe side '
. ' if it is reduced to ' . $recommendedMaximumExecutionTime . ' seconds:' . LF
. 'max_execution_time=' . $recommendedMaximumExecutionTime,
'Infinite PHP script execution time',
ContextualFeedbackSeverity::WARNING
));
} elseif ($currentMaximumExecutionTime < $minimumMaximumExecutionTime) {
$this->messageQueue->enqueue(new FlashMessage(
'max_execution_time=' . $currentMaximumExecutionTime . LF
. 'Your max_execution_time is too low. Some expensive operations in TYPO3 can take longer than that.'
. ' It is recommended to raise the limit to ' . $recommendedMaximumExecutionTime . ' seconds:' . LF
. 'max_execution_time=' . $recommendedMaximumExecutionTime,
'Low PHP script execution time',
ContextualFeedbackSeverity::ERROR
));
} elseif ($currentMaximumExecutionTime < $recommendedMaximumExecutionTime) {
$this->messageQueue->enqueue(new FlashMessage(
'max_execution_time=' . $currentMaximumExecutionTime . LF
. 'Your max_execution_time is low. While TYPO3 often runs without problems'
. ' with ' . $minimumMaximumExecutionTime . ' seconds,'
. ' it may still happen that script execution is stopped before finishing'
. ' calculations. You should monitor the system for messages in this area'
. ' and maybe raise the limit to ' . $recommendedMaximumExecutionTime . ' seconds:' . LF
. 'max_execution_time=' . $recommendedMaximumExecutionTime,
'Low PHP script execution time',
ContextualFeedbackSeverity::WARNING
));
} else {
$this->messageQueue->enqueue(new FlashMessage(
'',
'Maximum PHP script execution time is equal to or more than ' . $recommendedMaximumExecutionTime
));
}
}
/**
* Check for disabled functions
*/
protected function checkDisableFunctions()
{
$disabledFunctions = trim((string)ini_get('disable_functions'));
// Filter "disable_functions"
$disabledFunctionsArray = GeneralUtility::trimExplode(',', $disabledFunctions, true);
// Array with strings to find
$findStrings = [
// Disabled by default on Ubuntu OS but this is okay since the Core does not use them
'pcntl_',
];
foreach ($disabledFunctionsArray as $key => $disabledFunction) {
foreach ($findStrings as $findString) {
if (str_contains($disabledFunction, $findString)) {
unset($disabledFunctionsArray[$key]);
}
}
}
if ($disabledFunctions !== '') {
if (!empty($disabledFunctionsArray)) {
$this->messageQueue->enqueue(new FlashMessage(
'disable_functions=' . implode(' ', explode(',', $disabledFunctions)) . LF
. 'These function(s) are disabled. TYPO3 uses some of those, so there might be trouble.'
. ' TYPO3 is designed to use the default set of PHP functions plus some common extensions.'
. ' Possibly these functions are disabled'
. ' due to security considerations and most likely the list would include a function like'
. ' exec() which is used by TYPO3 at various places. Depending on which exact functions'
. ' are disabled, some parts of the system may just break without further notice.',
'Some PHP functions disabled',
ContextualFeedbackSeverity::ERROR
));
} else {
$this->messageQueue->enqueue(new FlashMessage(
'disable_functions=' . implode(' ', explode(',', $disabledFunctions)) . LF
. 'These function(s) are disabled. TYPO3 uses currently none of those, so you are good to go.',
'Some PHP functions currently disabled but OK'
));
}
} else {
$this->messageQueue->enqueue(new FlashMessage(
'',
'No disabled PHP functions'
));
}
}
/**
* Check for doc_root ini setting
*/
protected function checkDocRoot()
{
$docRootSetting = trim((string)ini_get('doc_root'));
if ($docRootSetting !== '') {
$this->messageQueue->enqueue(new FlashMessage(
'doc_root=' . $docRootSetting . LF
. 'PHP cannot execute scripts'
. ' outside this directory. This setting is seldom used and must correlate'
. ' with your actual document root. You might be in trouble if your'
. ' TYPO3 CMS core code is linked to some different location.'
. ' If that is a problem, the setting must be changed.',
'doc_root is set',
ContextualFeedbackSeverity::NOTICE
));
} else {
$this->messageQueue->enqueue(new FlashMessage(
'',
'PHP doc_root is not set'
));
}
}
/**
* Check open_basedir
*/
protected function checkOpenBaseDir()
{
$openBaseDirSetting = trim((string)ini_get('open_basedir'));
if ($openBaseDirSetting !== '') {
$this->messageQueue->enqueue(new FlashMessage(
'open_basedir = ' . ini_get('open_basedir') . LF
. 'This restricts TYPO3 to open and include files only in this'
. ' path. Please make sure that this does not prevent TYPO3 from running,'
. ' if for example your TYPO3 CMS core is linked to a different directory'
. ' not included in this path.',
'PHP open_basedir is set',
ContextualFeedbackSeverity::NOTICE
));
} else {
$this->messageQueue->enqueue(new FlashMessage(
'',
'PHP open_basedir is off'
));
}
}
/**
* If xdebug is loaded, the default max_nesting_level of 100 must be raised
*/
protected function checkXdebugMaxNestingLevel()
{
if (extension_loaded('xdebug')) {
$recommendedMaxNestingLevel = 400;
$errorThreshold = 250;
$currentMaxNestingLevel = ini_get('xdebug.max_nesting_level');
if ($currentMaxNestingLevel < $errorThreshold) {
$this->messageQueue->enqueue(new FlashMessage(
'xdebug.max_nesting_level=' . $currentMaxNestingLevel . LF
. 'This setting controls the maximum number of nested function calls to protect against'
. ' infinite recursion. The current value is too low for TYPO3 CMS and must'
. ' be either raised or xdebug has to be unloaded. A value of ' . $recommendedMaxNestingLevel
. ' is recommended. Warning: Expect fatal PHP errors in central parts of the CMS'
. ' if the value is not raised significantly to:' . LF
. 'xdebug.max_nesting_level=' . $recommendedMaxNestingLevel,
'PHP xdebug.max_nesting_level is critically low',
ContextualFeedbackSeverity::ERROR
));
} elseif ($currentMaxNestingLevel < $recommendedMaxNestingLevel) {
$this->messageQueue->enqueue(new FlashMessage(
'xdebug.max_nesting_level=' . $currentMaxNestingLevel . LF
. 'This setting controls the maximum number of nested function calls to protect against'
. ' infinite recursion. The current value is high enough for the TYPO3 CMS core to work'
. ' fine, but still some extensions could raise fatal PHP errors if the setting is not'
. ' raised further. A value of ' . $recommendedMaxNestingLevel . ' is recommended.' . LF
. 'xdebug.max_nesting_level=' . $recommendedMaxNestingLevel,
'PHP xdebug.max_nesting_level is low',
ContextualFeedbackSeverity::WARNING
));
} else {
$this->messageQueue->enqueue(new FlashMessage(
'',
'PHP xdebug.max_nesting_level ok'
));
}
} else {
$this->messageQueue->enqueue(new FlashMessage(
'',
'PHP xdebug extension not loaded'
));
}
}
/**
* Get max_input_vars status
*/
protected function checkMaxInputVars()
{
$recommendedMaxInputVars = 1500;
$minimumMaxInputVars = 1000;
$currentMaxInputVars = ini_get('max_input_vars');
if ($currentMaxInputVars < $minimumMaxInputVars) {
$this->messageQueue->enqueue(new FlashMessage(
'max_input_vars=' . $currentMaxInputVars . LF
. 'This setting can lead to lost information if submitting forms with lots of data in TYPO3 CMS'
. ' (as the install tool does). It is highly recommended to raise this'
. ' to at least ' . $recommendedMaxInputVars . ':' . LF
. 'max_input_vars=' . $recommendedMaxInputVars,
'PHP max_input_vars too low',
ContextualFeedbackSeverity::ERROR
));
} elseif ($currentMaxInputVars < $recommendedMaxInputVars) {
$this->messageQueue->enqueue(new FlashMessage(
'max_input_vars=' . $currentMaxInputVars . LF
. 'This setting can lead to lost information if submitting forms with lots of data in TYPO3 CMS'
. ' (as the install tool does). It is highly recommended to raise this'
. ' to at least ' . $recommendedMaxInputVars . ':' . LF
. 'max_input_vars=' . $recommendedMaxInputVars,
'PHP max_input_vars very low',
ContextualFeedbackSeverity::WARNING
));
} else {
$this->messageQueue->enqueue(new FlashMessage(
'',
'PHP max_input_vars ok'
));
}
}
/**
* Check doc comments can be fetched by reflection
*/
protected function checkReflectionDocComment()
{
$testReflection = new \ReflectionMethod(static::class, __FUNCTION__);
if ($testReflection->getDocComment() === false) {
$this->messageQueue->enqueue(new FlashMessage(
'TYPO3 CMS core extensions like extbase and fluid heavily rely on method'
. ' comment parsing to fetch annotations and add magic belonging to them.'
. ' This does not work in the current environment and so we cannot install'
. ' TYPO3 CMS.' . LF
. ' Here are some possibilities: ' . LF
. '* In Zend OPcache you can disable saving/loading comments. If you are using'
. ' Zend OPcache (included since PHP 5.5) then check your php.ini settings for'
. ' opcache.save_comments and opcache.load_comments and enable them.' . LF
. '* In Zend Optimizer+ you can disable saving comments. If you are using'
. ' Zend Optimizer+ then check your php.ini settings for'
. ' zend_optimizerplus.save_comments and enable it.' . LF
. '* The PHP extension eaccelerator is known to break this if'
. ' it is compiled without --with-eaccelerator-doc-comment-inclusion flag.'
. ' This compile flag must be specified, otherwise TYPO3 CMS will not work.' . LF
. 'For more information take a look in our documentation ' . Typo3Information::URL_OPCACHE . '.',
'PHP Doc comment reflection broken',
ContextualFeedbackSeverity::ERROR
));
} else {
$this->messageQueue->enqueue(new FlashMessage(
'',
'PHP Doc comment reflection works'
));
}
}
/**
* Checks thread stack size if on windows with apache
*/
protected function checkWindowsApacheThreadStackSize()
{
if ($this->isWindowsOs()
&& str_starts_with($_SERVER['SERVER_SOFTWARE'], 'Apache')
) {
$this->messageQueue->enqueue(new FlashMessage(
'This current value cannot be checked by the system, so please ignore this warning if it'
. ' is already taken care of: Fluid uses complex regular expressions which require a lot'
. ' of stack space during the first processing.'
. ' On Windows the default stack size for Apache is a lot smaller than on UNIX.'
. ' You can increase the size to 8MB (default on UNIX) by adding the following configuration'
. ' to httpd.conf and restarting Apache afterwards:' . LF
. '<IfModule mpm_winnt_module>ThreadStackSize 8388608</IfModule>',
'Windows apache thread stack size',
ContextualFeedbackSeverity::WARNING
));
} else {
$this->messageQueue->enqueue(new FlashMessage(
'',
'Apache ThreadStackSize is not an issue on UNIX systems'
));
}
}
/**
* Checks if a specific PHP extension is loaded.
*/
public function checkPhpExtension(string $extension, bool $required = true, string $purpose = '')
{
if (!extension_loaded($extension)) {
$this->messageQueue->enqueue(new FlashMessage(
'TYPO3 uses the PHP extension "' . $extension . '" but it is not loaded'
. ' in your environment. Change your environment to provide this extension. '
. $purpose,
'PHP extension "' . $extension . '" not loaded',
$required ? ContextualFeedbackSeverity::ERROR : ContextualFeedbackSeverity::WARNING
));
} else {
$this->messageQueue->enqueue(new FlashMessage(
'',
'PHP extension "' . $extension . '" loaded'
));
}
}
/**
* Check imagecreatetruecolor to verify gdlib works as expected
*/
protected function checkGdLibTrueColorSupport()
{
if (function_exists('imagecreatetruecolor')) {
$imageResource = @imagecreatetruecolor(50, 100);
if ($this->checkImageResource($imageResource)) {
imagedestroy($imageResource);
$this->messageQueue->enqueue(new FlashMessage(
'',
'PHP GD library true color works'
));
} else {
$this->messageQueue->enqueue(new FlashMessage(
'GD is loaded, but calling imagecreatetruecolor() fails.'
. ' This must be fixed, TYPO3 CMS won\'t work well otherwise.',
'PHP GD library true color support broken',
ContextualFeedbackSeverity::ERROR
));
}
} else {
$this->messageQueue->enqueue(new FlashMessage(
'Gdlib is essential for TYPO3 CMS to work properly.',
'PHP GD library true color support missing',
ContextualFeedbackSeverity::ERROR
));
}
}
/**
* Check gif support of GD library
*/
protected function checkGdLibGifSupport()
{
if (function_exists('imagecreatefromgif')
&& function_exists('imagegif')
&& (imagetypes() & IMG_GIF)
) {
// Do not use data:// wrapper to be independent of allow_url_fopen
$imageResource = @imagecreatefromgif(__DIR__ . '/../../Resources/Public/Images/TestInput/Test.gif');
if ($this->checkImageResource($imageResource)) {
imagedestroy($imageResource);
$this->messageQueue->enqueue(new FlashMessage(
'',
'PHP GD library has gif support'
));
} else {
$this->messageQueue->enqueue(new FlashMessage(
'GD is loaded, but calling imagecreatefromgif() fails. This must be fixed, TYPO3 CMS won\'t work well otherwise.',
'PHP GD library gif support broken',
ContextualFeedbackSeverity::ERROR
));
}
} else {
$this->messageQueue->enqueue(new FlashMessage(
'GD must be compiled with gif support. This is essential for TYPO3 CMS to work properly.',
'PHP GD library gif support missing',
ContextualFeedbackSeverity::ERROR
));
}
}
/**
* Check jpg support of GD library
*/
protected function checkGdLibJpgSupport()
{
if (function_exists('imagecreatefromjpeg')
&& function_exists('imagejpeg')
&& (imagetypes() & IMG_JPG)
) {
$this->messageQueue->enqueue(new FlashMessage(
'',
'PHP GD library has jpg support'
));
} else {
$this->messageQueue->enqueue(new FlashMessage(
'GD must be compiled with jpg support. This is essential for TYPO3 CMS to work properly.',
'PHP GD library jpg support missing',
ContextualFeedbackSeverity::ERROR
));
}
}
/**
* Check png support of GD library
*/
protected function checkGdLibPngSupport()
{
if (function_exists('imagecreatefrompng')
&& function_exists('imagepng')
&& (imagetypes() & IMG_PNG)
) {
// Do not use data:// wrapper to be independent of allow_url_fopen
$imageResource = @imagecreatefrompng(__DIR__ . '/../../Resources/Public/Images/TestInput/Test.png');
if ($this->checkImageResource($imageResource)) {
imagedestroy($imageResource);
$this->messageQueue->enqueue(new FlashMessage(
'',
'PHP GD library has png support'
));
} else {
$this->messageQueue->enqueue(new FlashMessage(
'GD is compiled with png support, but calling imagecreatefrompng() fails.'
. ' Check your environment and fix it, png in GD lib is important'
. ' for TYPO3 CMS to work properly.',
'PHP GD library png support broken',
ContextualFeedbackSeverity::ERROR
));
}
} else {
$this->messageQueue->enqueue(new FlashMessage(
'GD must be compiled with png support. This is essential for TYPO3 CMS to work properly',
'PHP GD library png support missing',
ContextualFeedbackSeverity::ERROR
));
}
}
/**
* Check gdlib supports freetype
*/
protected function checkGdLibFreeTypeSupport()
{
if (function_exists('imagettftext')) {
$this->messageQueue->enqueue(new FlashMessage(
'There is a difference between the font size setting which the GD'
. ' library should be supplied with. If installation is completed'
. ' a test in the install tool helps to find out the value you need.',
'PHP GD library has freetype font support'
));
} else {
$this->messageQueue->enqueue(new FlashMessage(
'Some core functionality and extension rely on the GD'
. ' to render fonts on images. This support is missing'
. ' in your environment. Install it.',
'PHP GD library freetype support missing',
ContextualFeedbackSeverity::ERROR
));
}
}
/**
* Helper methods
*/
/**
* Validate a given IP address.
*
* @param string $ip IP address to be tested
* @return bool
*/
protected function isValidIp($ip)
{
return filter_var($ip, FILTER_VALIDATE_IP) !== false;
}
/**
* Test if this instance runs on windows OS
*
* @return bool TRUE if operating system is windows
*/
protected function isWindowsOs()
{
$windowsOs = false;
if (stripos(PHP_OS, 'darwin') === false && stripos(PHP_OS, 'win') !== false) {
$windowsOs = true;
}
return $windowsOs;
}
/**
* Helper method to get the bytes value from a measurement string like "100k".
*
* @param string $measurement The measurement (e.g. "100k")
* @return int The bytes value (e.g. 102400)
*/
protected function getBytesFromSizeMeasurement($measurement)
{
$bytes = (float)$measurement;
if (stripos($measurement, 'G')) {
$bytes *= 1024 * 1024 * 1024;
} elseif (stripos($measurement, 'M')) {
$bytes *= 1024 * 1024;
} elseif (stripos($measurement, 'K')) {
$bytes *= 1024;
}
return (int)$bytes;
}
private function checkImageResource($imageResource): bool
{
return $imageResource instanceof \GdImage;
}
}