diff --git a/typo3/sysext/install/Classes/SystemEnvironment/Check.php b/typo3/sysext/install/Classes/SystemEnvironment/Check.php index 087d7c60babc118e244cd0d1146635192a1c0574..7760796a67aa506121213427eaaf418caea5d18c 100644 --- a/typo3/sysext/install/Classes/SystemEnvironment/Check.php +++ b/typo3/sysext/install/Classes/SystemEnvironment/Check.php @@ -44,7 +44,7 @@ use TYPO3\CMS\Install\Status; * text only. The return values of this class are not bound to HTML * and can be used in different scopes (eg. as json array). */ -class Check +class Check implements CheckInterface { /** * @var array List of required PHP extensions @@ -70,7 +70,7 @@ class Check * * @return array<\TYPO3\CMS\Install\Status\StatusInterface> */ - public function getStatus() + public function getStatus(): array { $status = []; $status[] = $this->checkCurrentDirectoryIsInIncludePath(); diff --git a/typo3/sysext/install/Classes/SystemEnvironment/CheckInterface.php b/typo3/sysext/install/Classes/SystemEnvironment/CheckInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..be33574859d74e4af2fafec83ba01b4be3a7501c --- /dev/null +++ b/typo3/sysext/install/Classes/SystemEnvironment/CheckInterface.php @@ -0,0 +1,36 @@ +<?php + +namespace TYPO3\CMS\Install\SystemEnvironment; + +/* + * 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! + */ + +/** + * Check system environment status + * + * This interface needs to be implemented by hardcoded requirement + * checks of the underlying server and PHP system. + * + * The status messages and title *must not* include HTML, use + * plain text only. The return values of this class can be used + * in different scopes (eg. as json array). + */ +interface CheckInterface +{ + /** + * Get all status information as array with status objects + * + * @return \TYPO3\CMS\Install\Status\StatusInterface[] + */ + public function getStatus(): array; +} diff --git a/typo3/sysext/install/Classes/SystemEnvironment/DatabaseCheck.php b/typo3/sysext/install/Classes/SystemEnvironment/DatabaseCheck.php index df6122b2e9cfc0329e6be58ccab341811f32862f..02db02f49f3c7f8437ab4d09d4a01f4f9ef836e0 100644 --- a/typo3/sysext/install/Classes/SystemEnvironment/DatabaseCheck.php +++ b/typo3/sysext/install/Classes/SystemEnvironment/DatabaseCheck.php @@ -13,12 +13,9 @@ namespace TYPO3\CMS\Install\SystemEnvironment; * * The TYPO3 project - inspiring people to share! */ - -use TYPO3\CMS\Core\Database\Connection; -use TYPO3\CMS\Core\Database\ConnectionPool; -use TYPO3\CMS\Core\Database\Query\QueryBuilder; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Install\Status; +use TYPO3\CMS\Install\SystemEnvironment\DatabasePlatform\MySqlCheck; +use TYPO3\CMS\Install\SystemEnvironment\DatabasePlatform\PostgreSqlCheck; /** * Check database configuration status @@ -29,135 +26,31 @@ use TYPO3\CMS\Install\Status; * text only. The return values of this class are not bound to HTML * and can be used in different scopes (eg. as json array). */ -class DatabaseCheck +class DatabaseCheck implements CheckInterface { /** - * List of MySQL modes that are incompatible with TYPO3 CMS + * List of database platforms to check * * @var array */ - protected $incompatibleSqlModes = [ - 'NO_BACKSLASH_ESCAPES' + protected $databasePlatformChecks = [ + MySqlCheck::class, + PostgreSqlCheck::class, ]; /** - * Get all status information as array with status objects + * Get status of each database platform defined in the list * - * @return \TYPO3\CMS\Install\Status\StatusInterface[] + * @return array + * @throws \InvalidArgumentException */ - public function getStatus() + public function getStatus(): array { - $statusArray = []; - $defaultConnection = GeneralUtility::makeInstance(ConnectionPool::class) - ->getConnectionByName(ConnectionPool::DEFAULT_CONNECTION_NAME); - if (strpos($defaultConnection->getServerVersion(), 'MySQL') !== 0) { - return $statusArray; - } - $statusArray[] = $this->checkMysqlVersion($defaultConnection); - $statusArray[] = $this->checkInvalidSqlModes($defaultConnection); - $statusArray[] = $this->checkMysqlDatabaseUtf8Status($defaultConnection); - return $statusArray; - } + $databaseStatus = []; - /** - * Check if any SQL mode is set which is not compatible with TYPO3 - * - * @param Connection Connection to the database to be checked - * @return Status\StatusInterface - */ - protected function checkInvalidSqlModes($connection) - { - $detectedIncompatibleSqlModes = $this->getIncompatibleSqlModes($connection); - if (!empty($detectedIncompatibleSqlModes)) { - $status = new Status\ErrorStatus(); - $status->setTitle('Incompatible SQL modes found!'); - $status->setMessage( - 'Incompatible SQL modes have been detected:' . - ' ' . implode(', ', $detectedIncompatibleSqlModes) . '.' . - ' The listed modes are not compatible with TYPO3 CMS.' . - ' You have to change that setting in your MySQL environment' . - ' or in $GLOBALS[\'TYPO3_CONF_VARS\'][\'SYS\'][\'setDBinit\']' - ); - } else { - $status = new Status\OkStatus(); - $status->setTitle('No incompatible SQL modes found.'); - } - - return $status; - } - - /** - * Check minimum MySQL version - * - * @param Connection Connection to the database to be checked - * @return Status\StatusInterface - */ - protected function checkMysqlVersion($connection) - { - $minimumMysqlVersion = '5.5.0'; - preg_match('/MySQL ((\d+\.)*(\d+\.)*\d+)/', $connection->getServerVersion(), $match); - $currentMysqlVersion = $match[1]; - if (version_compare($currentMysqlVersion, $minimumMysqlVersion) < 0) { - $status = new Status\ErrorStatus(); - $status->setTitle('MySQL version too low'); - $status->setMessage( - 'Your MySQL version ' . $currentMysqlVersion . ' is too old. TYPO3 CMS does not run' . - ' with this version. Update to at least MySQL ' . $minimumMysqlVersion - ); - } else { - $status = new Status\OkStatus(); - $status->setTitle('MySQL version is fine'); + foreach ($this->databasePlatformChecks as $databasePlatformCheckClass) { + $databaseStatus += GeneralUtility::makeInstance($databasePlatformCheckClass)->getStatus(); } - - return $status; - } - - /** - * Checks the character set of the database and reports an error if it is not utf-8. - * - * @param Connection $connection to the database to be checked - * @return Status\StatusInterface - */ - protected function checkMysqlDatabaseUtf8Status(Connection $connection) - { - /** @var QueryBuilder $queryBuilder */ - $queryBuilder = $connection->createQueryBuilder(); - $defaultDatabaseCharset = (string)$queryBuilder->select('DEFAULT_CHARACTER_SET_NAME') - ->from('information_schema.SCHEMATA') - ->where( - $queryBuilder->expr()->eq( - 'SCHEMA_NAME', - $queryBuilder->createNamedParameter($connection->getDatabase(), \PDO::PARAM_STR) - ) - ) - ->setMaxResults(1) - ->execute() - ->fetchColumn(); - // also allow utf8mb4 - if (strpos($defaultDatabaseCharset, 'utf8') !== 0) { - $status = new Status\ErrorStatus(); - $status->setTitle('MySQL database character set check failed'); - $status->setMessage( - 'Checking database character set failed, got key "' - . $defaultDatabaseCharset . '" instead of "utf8" or "utf8mb4"' - ); - } else { - $status = new Status\OkStatus(); - $status->setTitle('Your database uses utf-8. All good.'); - } - return $status; - } - - /** - * Returns an array with the current sql mode settings - * - * @param Connection Connection to the database to be checked - * @return array Contains all configured SQL modes that are incompatible - */ - protected function getIncompatibleSqlModes($connection) - { - $sqlModes = explode(',', $connection->executeQuery('SELECT @@SESSION.sql_mode;') - ->fetch(0)['@@SESSION.sql_mode']); - return array_intersect($this->incompatibleSqlModes, $sqlModes); + return $databaseStatus; } } diff --git a/typo3/sysext/install/Classes/SystemEnvironment/DatabasePlatform/MySqlCheck.php b/typo3/sysext/install/Classes/SystemEnvironment/DatabasePlatform/MySqlCheck.php new file mode 100644 index 0000000000000000000000000000000000000000..5699584b36fe31ef35efb2d1179648c03b15e6c1 --- /dev/null +++ b/typo3/sysext/install/Classes/SystemEnvironment/DatabasePlatform/MySqlCheck.php @@ -0,0 +1,173 @@ +<?php + +namespace TYPO3\CMS\Install\SystemEnvironment\DatabasePlatform; + +/* + * 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! + */ + +use TYPO3\CMS\Core\Database\Connection; +use TYPO3\CMS\Core\Database\ConnectionPool; +use TYPO3\CMS\Core\Database\Query\QueryBuilder; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Install\Status; +use TYPO3\CMS\Install\SystemEnvironment\CheckInterface; + +/** + * Check database configuration status for MySQL server + * + * This class is a hardcoded requirement check for the database server. + * + * The status messages and title *must not* include HTML, use plain + * text only. The return values of this class are not bound to HTML + * and can be used in different scopes (eg. as json array). + */ +class MySqlCheck implements CheckInterface +{ + /** + * Minimum supported MySQL version + * + * @var string + */ + protected $minimumMySQLVersion = '5.5.0'; + + /** + * List of MySQL modes that are incompatible with TYPO3 CMS + * + * @var array + */ + protected $incompatibleSqlModes = [ + 'NO_BACKSLASH_ESCAPES' + ]; + + /** + * Get all status information as array with status objects + * + * @return \TYPO3\CMS\Install\Status\StatusInterface[] + * @throws \InvalidArgumentException + * @throws \Doctrine\DBAL\DBALException + */ + public function getStatus(): array + { + $statusArray = []; + $defaultConnection = GeneralUtility::makeInstance(ConnectionPool::class) + ->getConnectionByName(ConnectionPool::DEFAULT_CONNECTION_NAME); + if (strpos($defaultConnection->getServerVersion(), 'MySQL') !== 0) { + return $statusArray; + } + $statusArray[] = $this->checkMysqlVersion($defaultConnection); + $statusArray[] = $this->checkInvalidSqlModes($defaultConnection); + $statusArray[] = $this->checkMysqlDatabaseUtf8Status($defaultConnection); + return $statusArray; + } + + /** + * Check if any SQL mode is set which is not compatible with TYPO3 + * + * @param Connection Connection to the database to be checked + * @return Status\StatusInterface + */ + protected function checkInvalidSqlModes($connection) + { + $detectedIncompatibleSqlModes = $this->getIncompatibleSqlModes($connection); + if (!empty($detectedIncompatibleSqlModes)) { + $status = new Status\ErrorStatus(); + $status->setTitle('Incompatible SQL modes found!'); + $status->setMessage( + 'Incompatible SQL modes have been detected:' . + ' ' . implode(', ', $detectedIncompatibleSqlModes) . '.' . + ' The listed modes are not compatible with TYPO3 CMS.' . + ' You have to change that setting in your MySQL environment' . + ' or in $GLOBALS[\'TYPO3_CONF_VARS\'][\'SYS\'][\'setDBinit\']' + ); + } else { + $status = new Status\OkStatus(); + $status->setTitle('No incompatible SQL modes found.'); + } + + return $status; + } + + /** + * Check minimum MySQL version + * + * @param Connection Connection to the database to be checked + * @return Status\StatusInterface + */ + protected function checkMysqlVersion($connection) + { + preg_match('/MySQL ((\d+\.)*(\d+\.)*\d+)/', $connection->getServerVersion(), $match); + $currentMysqlVersion = $match[1]; + if (version_compare($currentMysqlVersion, $this->minimumMySQLVersion, '<')) { + $status = new Status\ErrorStatus(); + $status->setTitle('MySQL version too low'); + $status->setMessage( + 'Your MySQL version ' . $currentMysqlVersion . ' is too old. TYPO3 CMS does not run' . + ' with this version. Update to at least MySQL ' . $this->minimumMySQLVersion + ); + } else { + $status = new Status\OkStatus(); + $status->setTitle('MySQL version is fine'); + } + + return $status; + } + + /** + * Checks the character set of the database and reports an error if it is not utf-8. + * + * @param Connection $connection to the database to be checked + * @return Status\StatusInterface + */ + protected function checkMysqlDatabaseUtf8Status(Connection $connection) + { + /** @var QueryBuilder $queryBuilder */ + $queryBuilder = $connection->createQueryBuilder(); + $defaultDatabaseCharset = (string)$queryBuilder->select('DEFAULT_CHARACTER_SET_NAME') + ->from('information_schema.SCHEMATA') + ->where( + $queryBuilder->expr()->eq( + 'SCHEMA_NAME', + $queryBuilder->createNamedParameter($connection->getDatabase(), \PDO::PARAM_STR) + ) + ) + ->setMaxResults(1) + ->execute() + ->fetchColumn(); + // also allow utf8mb4 + if (strpos($defaultDatabaseCharset, 'utf8') !== 0) { + $status = new Status\ErrorStatus(); + $status->setTitle('MySQL database character set check failed'); + $status->setMessage( + 'Checking database character set failed, got key "' + . $defaultDatabaseCharset . '" instead of "utf8" or "utf8mb4"' + ); + } else { + $status = new Status\OkStatus(); + $status->setTitle('Your database uses utf-8. All good.'); + } + return $status; + } + + /** + * Returns an array with the current sql mode settings + * + * @param Connection Connection to the database to be checked + * @return array Contains all configured SQL modes that are incompatible + */ + protected function getIncompatibleSqlModes($connection) + { + $sqlModes = explode(',', $connection->executeQuery('SELECT @@SESSION.sql_mode;') + ->fetch(0)['@@SESSION.sql_mode']); + return array_intersect($this->incompatibleSqlModes, $sqlModes); + } +} diff --git a/typo3/sysext/install/Classes/SystemEnvironment/DatabasePlatform/PostgreSqlCheck.php b/typo3/sysext/install/Classes/SystemEnvironment/DatabasePlatform/PostgreSqlCheck.php new file mode 100644 index 0000000000000000000000000000000000000000..98f8e0ec230cd318889327bb96d2f60f843a8424 --- /dev/null +++ b/typo3/sysext/install/Classes/SystemEnvironment/DatabasePlatform/PostgreSqlCheck.php @@ -0,0 +1,130 @@ +<?php + +namespace TYPO3\CMS\Install\SystemEnvironment\DatabasePlatform; + +/* + * 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! + */ + +use TYPO3\CMS\Core\Database\Connection; +use TYPO3\CMS\Core\Database\ConnectionPool; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Install\Status; +use TYPO3\CMS\Install\SystemEnvironment\CheckInterface; + +/** + * Check database configuration status for PostgreSQL + * + * This class is a hardcoded requirement check for the database server. + * + * The status messages and title *must not* include HTML, use plain + * text only. The return values of this class are not bound to HTML + * and can be used in different scopes (eg. as json array). + */ +class PostgreSqlCheck implements CheckInterface +{ + /** + * Minimum supported PostgreSQL Server version + * + * @var string + */ + protected $minimumPostgreSQLVerion = '9.2'; + + /** + * Minimum supported libpq version + * @var string + */ + protected $minimumLibPQVersion = '9.0'; + + /** + * Get all status information as array with status objects + * + * @return array + * @throws \Doctrine\DBAL\DBALException + * @throws \InvalidArgumentException + */ + public function getStatus(): array + { + $statusArray = []; + $defaultConnection = GeneralUtility::makeInstance(ConnectionPool::class) + ->getConnectionByName(ConnectionPool::DEFAULT_CONNECTION_NAME); + if (strpos($defaultConnection->getServerVersion(), 'PostgreSQL') !== 0) { + return $statusArray; + } + + $statusArray[] = $this->checkPostgreSqlVersion($defaultConnection); + $statusArray[] = $this->checkLibpqVersion(); + return $statusArray; + } + + /** + * Check minimum PostgreSQL version + * + * @param Connection Connection to the database to be checked + * @return Status\StatusInterface + */ + protected function checkPostgreSqlVersion($connection): Status\StatusInterface + { + preg_match('/PostgreSQL ((\d+\.)*(\d+\.)*\d+)/', $connection->getServerVersion(), $match); + $currentPostgreSqlVersion = $match[1]; + if (version_compare($currentPostgreSqlVersion, $this->minimumPostgreSQLVerion, '<')) { + $status = new Status\ErrorStatus(); + $status->setTitle('PostgreSQL Server version is unsupported'); + $status->setMessage( + 'Your PostgreSQL version ' . $currentPostgreSqlVersion . ' is not supported. TYPO3 CMS does not run' . + ' with this version. The minimum supported PostgreSQL version is ' . $this->minimumPostgreSQLVerion + ); + } else { + $status = new Status\OkStatus(); + $status->setTitle('PostgreSQL Server version is supported'); + } + + return $status; + } + + /** + * Check the version of ligpq within the PostgreSQL driver + * + * @return Status\StatusInterface + */ + protected function checkLibpqVersion(): Status\StatusInterface + { + if (!defined('PGSQL_LIBPQ_VERSION_STR')) { + $status = new Status\WarningStatus(); + $status->setTitle('PostgreSQL libpq version cannot be determined'); + $status->setMessage( + 'It is not possible to retrieve your PostgreSQL libpq version. Please check the version' . + ' in the "phpinfo" area of the "System environment" module in the install tool manually.' . + ' This should be found in section "pdo_pgsql".' . + ' You should have at least the following version of PostgreSQL libpq installed: ' . + $this->minimumLibPQVersion + ); + } else { + preg_match('/PostgreSQL ((\d+\.)*(\d+\.)*\d+)/', \PGSQL_LIBPQ_VERSION_STR, $match); + $currentPostgreSqlLibpqVersion = $match[1]; + + if (version_compare($currentPostgreSqlLibpqVersion, $this->minimumLibPQVersion, '<')) { + $status = new Status\ErrorStatus(); + $status->setTitle('PostgreSQL libpq version is unsupported'); + $status->setMessage( + 'Your PostgreSQL libpq version "' . $currentPostgreSqlLibpqVersion . '" is unsupported.' . + ' TYPO3 CMS does not run with this version. The minimum supported libpq version is ' . + $this->minimumLibPQVersion + ); + } else { + $status = new Status\OkStatus(); + $status->setTitle('PostgreSQL libpq version is supported'); + } + } + return $status; + } +} diff --git a/typo3/sysext/install/Classes/SystemEnvironment/SetupCheck.php b/typo3/sysext/install/Classes/SystemEnvironment/SetupCheck.php index 14c19c17d34173336eb4fc7f2d967852832bdc89..a9fa51ac6c6fb8b5ec7032f6a38b7acdeabfd617 100644 --- a/typo3/sysext/install/Classes/SystemEnvironment/SetupCheck.php +++ b/typo3/sysext/install/Classes/SystemEnvironment/SetupCheck.php @@ -27,14 +27,14 @@ use TYPO3\CMS\Install\Status; * text only. The return values of this class are not bound to HTML * and can be used in different scopes (eg. as json array). */ -class SetupCheck +class SetupCheck implements CheckInterface { /** * Get all status information as array with status objects * * @return array<\TYPO3\CMS\Install\Status\StatusInterface> */ - public function getStatus() + public function getStatus(): array { $status = [];