0713404559e7bafbf00423f17ccc623e5c211112
[Packages/TYPO3.CMS.git] / typo3 / sysext / install / Classes / SystemEnvironment / DatabaseCheck.php
1 <?php
2 namespace TYPO3\CMS\Install\SystemEnvironment;
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
17 use TYPO3\CMS\Core\Utility\GeneralUtility;
18 use TYPO3\CMS\Install\Status;
19
20 /**
21 * Check database configuration status
22 *
23 * This class is a hardcoded requirement check for the database server.
24 *
25 * The status messages and title *must not* include HTML, use plain
26 * text only. The return values of this class are not bound to HTML
27 * and can be used in different scopes (eg. as json array).
28 */
29 class DatabaseCheck
30 {
31 /**
32 * List of MySQL modes that are incompatible with TYPO3 CMS
33 *
34 * @var array
35 */
36 protected $incompatibleSqlModes = array(
37 'STRICT_ALL_TABLES',
38 'STRICT_TRANS_TABLES',
39 'NO_BACKSLASH_ESCAPES'
40 );
41
42 /**
43 * Get all status information as array with status objects
44 *
45 * @return array<\TYPO3\CMS\Install\Status\StatusInterface>
46 */
47 public function getStatus()
48 {
49 $statusArray = array();
50 if ($this->isDbalEnabled() || !$this->getDatabaseConnection()) {
51 return $statusArray;
52 }
53 $statusArray[] = $this->checkMysqlVersion();
54 $statusArray[] = $this->checkInvalidSqlModes();
55 return $statusArray;
56 }
57
58 /**
59 * Check if any SQL mode is set which is not compatible with TYPO3
60 *
61 * @return Status\StatusInterface
62 */
63 protected function checkInvalidSqlModes()
64 {
65 $detectedIncompatibleSqlModes = $this->getIncompatibleSqlModes();
66 if (!empty($detectedIncompatibleSqlModes)) {
67 $status = new Status\ErrorStatus();
68 $status->setTitle('Incompatible SQL modes found!');
69 $status->setMessage(
70 'Incompatible SQL modes have been detected:' .
71 ' ' . implode(', ', $detectedIncompatibleSqlModes) . '.' .
72 ' The listed modes are not compatible with TYPO3 CMS.' .
73 ' You have to change that setting in your MySQL environment' .
74 ' or in $GLOBALS[\'TYPO3_CONF_VARS\'][\'SYS\'][\'setDBinit\']'
75 );
76 } else {
77 $status = new Status\OkStatus();
78 $status->setTitle('No incompatible SQL modes found.');
79 }
80
81 return $status;
82 }
83
84 /**
85 * Check minimum MySQL version
86 *
87 * @return Status\StatusInterface
88 */
89 protected function checkMysqlVersion()
90 {
91 $minimumMysqlVersion = '5.5.0';
92 $currentMysqlVersion = '';
93 $resource = $this->getDatabaseConnection()->sql_query('SHOW VARIABLES LIKE \'version\';');
94 if ($resource !== false) {
95 $result = $this->getDatabaseConnection()->sql_fetch_row($resource);
96 if (isset($result[1])) {
97 $currentMysqlVersion = $result[1];
98 }
99 }
100 if (version_compare($currentMysqlVersion, $minimumMysqlVersion) < 0) {
101 $status = new Status\ErrorStatus();
102 $status->setTitle('MySQL version too low');
103 $status->setMessage(
104 'Your MySQL version ' . $currentMysqlVersion . ' is too old. TYPO3 CMS does not run' .
105 ' with this version. Update to at least MySQL ' . $minimumMysqlVersion
106 );
107 } else {
108 $status = new Status\OkStatus();
109 $status->setTitle('MySQL version is fine');
110 }
111
112 return $status;
113 }
114
115 /**
116 * Returns an array with the current sql mode settings
117 *
118 * @return array Contains all configured SQL modes that are incompatible
119 */
120 protected function getIncompatibleSqlModes()
121 {
122 $sqlModes = array();
123 $resource = $this->getDatabaseConnection()->sql_query('SELECT @@SESSION.sql_mode;');
124 if ($resource !== false) {
125 $result = $this->getDatabaseConnection()->sql_fetch_row($resource);
126 if (isset($result[0])) {
127 $sqlModes = explode(',', $result[0]);
128 }
129 }
130 return array_intersect($this->incompatibleSqlModes, $sqlModes);
131 }
132
133 /**
134 * Get database instance.
135 * Will be initialized if it does not exist yet.
136 *
137 * @return \TYPO3\CMS\Core\Database\DatabaseConnection
138 */
139 protected function getDatabaseConnection()
140 {
141 static $database;
142 if (!is_object($database)) {
143 /** @var \TYPO3\CMS\Core\Database\DatabaseConnection $database */
144 $database = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Database\DatabaseConnection::class);
145 $database->setDatabaseUsername($GLOBALS['TYPO3_CONF_VARS']['DB']['username']);
146 $database->setDatabasePassword($GLOBALS['TYPO3_CONF_VARS']['DB']['password']);
147 $database->setDatabaseHost($GLOBALS['TYPO3_CONF_VARS']['DB']['host']);
148 $database->setDatabasePort($GLOBALS['TYPO3_CONF_VARS']['DB']['port']);
149 $database->setDatabaseSocket($GLOBALS['TYPO3_CONF_VARS']['DB']['socket']);
150 $database->setDatabaseName($GLOBALS['TYPO3_CONF_VARS']['DB']['database']);
151 $database->initialize();
152 $database->connectDB();
153 }
154 return $database;
155 }
156
157 /**
158 * Checks if DBAL is enabled for the database connection
159 *
160 * @return bool
161 */
162 protected function isDbalEnabled()
163 {
164 return \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('dbal');
165 }
166 }