[TASK] Removes extra empty lines
[Packages/TYPO3.CMS.git] / typo3 / sysext / install / Classes / Controller / Action / Step / DatabaseSelect.php
1 <?php
2 namespace TYPO3\CMS\Install\Controller\Action\Step;
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 /**
18 * Database select step.
19 * This step is only rendered if database is mysql. With dbal,
20 * database name is submitted by previous step already.
21 */
22 class DatabaseSelect extends AbstractStepAction
23 {
24 /**
25 * @var \TYPO3\CMS\Core\Database\DatabaseConnection
26 */
27 protected $databaseConnection = null;
28
29 /**
30 * Create database if needed, save selected db name in configuration
31 *
32 * @return array<\TYPO3\CMS\Install\Status\StatusInterface>
33 */
34 public function execute()
35 {
36 $result = array();
37 $this->initializeDatabaseConnection();
38 $postValues = $this->postValues['values'];
39 $localConfigurationPathValuePairs = array();
40 /** @var $configurationManager \TYPO3\CMS\Core\Configuration\ConfigurationManager */
41 $configurationManager = $this->objectManager->get(\TYPO3\CMS\Core\Configuration\ConfigurationManager::class);
42 if ($postValues['type'] === 'new') {
43 $newDatabaseName = $postValues['new'];
44 if ($this->isValidDatabaseName($newDatabaseName)) {
45 $createDatabaseResult = $this->databaseConnection->admin_query('CREATE DATABASE ' . $newDatabaseName . ' CHARACTER SET utf8');
46 if ($createDatabaseResult) {
47 $localConfigurationPathValuePairs['DB/database'] = $newDatabaseName;
48 } else {
49 /** @var $errorStatus \TYPO3\CMS\Install\Status\ErrorStatus */
50 $errorStatus = $this->objectManager->get(\TYPO3\CMS\Install\Status\ErrorStatus::class);
51 $errorStatus->setTitle('Unable to create database');
52 $errorStatus->setMessage(
53 'Database with name ' . $newDatabaseName . ' could not be created.' .
54 ' Either your database name contains a reserved keyword or your database' .
55 ' user does not have sufficient permissions to create it.' .
56 ' Please choose an existing (empty) database or contact administration.'
57 );
58 $result[] = $errorStatus;
59 }
60 } else {
61 /** @var $errorStatus \TYPO3\CMS\Install\Status\ErrorStatus */
62 $errorStatus = $this->objectManager->get(\TYPO3\CMS\Install\Status\ErrorStatus::class);
63 $errorStatus->setTitle('Database name not valid');
64 $errorStatus->setMessage(
65 'Given database name must be shorter than fifty characters' .
66 ' and consist solely of basic latin letters (a-z), digits (0-9), dollar signs ($)' .
67 ' and underscores (_).'
68 );
69 $result[] = $errorStatus;
70 }
71 } elseif ($postValues['type'] === 'existing' && !empty($postValues['existing'])) {
72 // Only store database information when it's empty
73 $this->databaseConnection->setDatabaseName($postValues['existing']);
74 $this->databaseConnection->sql_select_db();
75 $existingTables = $this->databaseConnection->admin_get_tables();
76 $isInitialInstallation = $configurationManager->getConfigurationValueByPath('SYS/isInitialInstallationInProgress');
77 if (!$isInitialInstallation || empty($existingTables)) {
78 $localConfigurationPathValuePairs['DB/database'] = $postValues['existing'];
79 }
80 } else {
81 /** @var $errorStatus \TYPO3\CMS\Install\Status\ErrorStatus */
82 $errorStatus = $this->objectManager->get(\TYPO3\CMS\Install\Status\ErrorStatus::class);
83 $errorStatus->setTitle('No Database selected');
84 $errorStatus->setMessage('You must select a database.');
85 $result[] = $errorStatus;
86 }
87
88 if (!empty($localConfigurationPathValuePairs)) {
89 $configurationManager->setLocalConfigurationValuesByPathValuePairs($localConfigurationPathValuePairs);
90 }
91
92 return $result;
93 }
94
95 /**
96 * Step needs to be executed if database is not set or can
97 * not be selected.
98 *
99 * @return bool
100 */
101 public function needsExecution()
102 {
103 $this->initializeDatabaseConnection();
104 $result = true;
105 if ((string)$GLOBALS['TYPO3_CONF_VARS']['DB']['database'] !== '') {
106 $this->databaseConnection->setDatabaseName($GLOBALS['TYPO3_CONF_VARS']['DB']['database']);
107 try {
108 $selectResult = $this->databaseConnection->sql_select_db();
109 if ($selectResult === true) {
110 $result = false;
111 }
112 } catch (\RuntimeException $e) {
113 }
114 }
115 return $result;
116 }
117
118 /**
119 * Executes the step
120 *
121 * @return string Rendered content
122 */
123 protected function executeAction()
124 {
125 /** @var $configurationManager \TYPO3\CMS\Core\Configuration\ConfigurationManager */
126 $configurationManager = $this->objectManager->get(\TYPO3\CMS\Core\Configuration\ConfigurationManager::class);
127 $isInitialInstallationInProgress = $configurationManager->getConfigurationValueByPath('SYS/isInitialInstallationInProgress');
128 $this->view->assign('databaseList', $this->getDatabaseList($isInitialInstallationInProgress));
129 $this->view->assign('isInitialInstallationInProgress', $isInitialInstallationInProgress);
130 $this->assignSteps();
131 return $this->view->render();
132 }
133
134 /**
135 * Returns list of available databases (with access-check based on username/password)
136 *
137 * @param bool $initialInstallation TRUE if first installation is in progress, FALSE if upgrading or usual access
138 * @return array List of available databases
139 */
140 protected function getDatabaseList($initialInstallation)
141 {
142 $this->initializeDatabaseConnection();
143 $databaseArray = $this->databaseConnection->admin_get_dbs();
144 // Remove mysql organizational tables from database list
145 $reservedDatabaseNames = array('mysql', 'information_schema', 'performance_schema');
146 $allPossibleDatabases = array_diff($databaseArray, $reservedDatabaseNames);
147
148 // If we are upgrading we show *all* databases the user has access to
149 if ($initialInstallation === false) {
150 return $allPossibleDatabases;
151 } else {
152 // In first installation we show all databases but disable not empty ones (with tables)
153 $databases = array();
154 foreach ($allPossibleDatabases as $database) {
155 $this->databaseConnection->setDatabaseName($database);
156 $this->databaseConnection->sql_select_db();
157 $existingTables = $this->databaseConnection->admin_get_tables();
158 $databases[] = array(
159 'name' => $database,
160 'tables' => count($existingTables),
161 );
162 }
163 return $databases;
164 }
165 }
166
167 /**
168 * Initialize database connection
169 *
170 * @return void
171 */
172 protected function initializeDatabaseConnection()
173 {
174 $this->databaseConnection = $this->objectManager->get(\TYPO3\CMS\Core\Database\DatabaseConnection::class);
175 $this->databaseConnection->setDatabaseUsername($GLOBALS['TYPO3_CONF_VARS']['DB']['username']);
176 $this->databaseConnection->setDatabasePassword($GLOBALS['TYPO3_CONF_VARS']['DB']['password']);
177 $this->databaseConnection->setDatabaseHost($GLOBALS['TYPO3_CONF_VARS']['DB']['host']);
178 $this->databaseConnection->setDatabasePort($GLOBALS['TYPO3_CONF_VARS']['DB']['port']);
179 $this->databaseConnection->setDatabaseSocket($GLOBALS['TYPO3_CONF_VARS']['DB']['socket']);
180 $this->databaseConnection->sql_pconnect();
181 }
182
183 /**
184 * Validate the database name against the lowest common denominator of valid identifiers across different DBMS
185 *
186 * @param string $databaseName
187 * @return bool
188 */
189 protected function isValidDatabaseName($databaseName)
190 {
191 return strlen($databaseName) <= 50 && preg_match('/^[a-zA-Z0-9\$_]*$/', $databaseName);
192 }
193 }