2 namespace TYPO3\CMS\Install\Controller\Action\Step
;
5 * This file is part of the TYPO3 CMS project.
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.
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
14 * The TYPO3 project - inspiring people to share!
17 use TYPO3\CMS\Core\Utility\GeneralUtility
;
20 * Database select step.
21 * This step is only rendered if database is mysql. With dbal,
22 * database name is submitted by previous step already.
24 class DatabaseSelect
extends AbstractStepAction
27 * @var \TYPO3\CMS\Core\Database\DatabaseConnection
29 protected $databaseConnection = null;
32 * Create database if needed, save selected db name in configuration
34 * @return array<\TYPO3\CMS\Install\Status\StatusInterface>
36 public function execute()
39 $this->initializeDatabaseConnection();
40 $postValues = $this->postValues
['values'];
41 $localConfigurationPathValuePairs = array();
42 /** @var $configurationManager \TYPO3\CMS\Core\Configuration\ConfigurationManager */
43 $configurationManager = GeneralUtility
::makeInstance(\TYPO3\CMS\Core\Configuration\ConfigurationManager
::class);
44 if ($postValues['type'] === 'new') {
45 $newDatabaseName = $postValues['new'];
46 if ($this->isValidDatabaseName($newDatabaseName)) {
47 $createDatabaseResult = $this->databaseConnection
->admin_query('CREATE DATABASE ' . $newDatabaseName . ' CHARACTER SET utf8');
48 if ($createDatabaseResult) {
49 $localConfigurationPathValuePairs['DB/database'] = $newDatabaseName;
51 /** @var $errorStatus \TYPO3\CMS\Install\Status\ErrorStatus */
52 $errorStatus = GeneralUtility
::makeInstance(\TYPO3\CMS\Install\Status\ErrorStatus
::class);
53 $errorStatus->setTitle('Unable to create database');
54 $errorStatus->setMessage(
55 'Database with name ' . $newDatabaseName . ' could not be created.' .
56 ' Either your database name contains a reserved keyword or your database' .
57 ' user does not have sufficient permissions to create it.' .
58 ' Please choose an existing (empty) database or contact administration.'
60 $result[] = $errorStatus;
63 /** @var $errorStatus \TYPO3\CMS\Install\Status\ErrorStatus */
64 $errorStatus = GeneralUtility
::makeInstance(\TYPO3\CMS\Install\Status\ErrorStatus
::class);
65 $errorStatus->setTitle('Database name not valid');
66 $errorStatus->setMessage(
67 'Given database name must be shorter than fifty characters' .
68 ' and consist solely of basic latin letters (a-z), digits (0-9), dollar signs ($)' .
69 ' and underscores (_).'
71 $result[] = $errorStatus;
73 } elseif ($postValues['type'] === 'existing' && !empty($postValues['existing'])) {
74 // Only store database information when it's empty
75 $this->databaseConnection
->setDatabaseName($postValues['existing']);
76 $this->databaseConnection
->sql_select_db();
77 $existingTables = $this->databaseConnection
->admin_get_tables();
78 $isInitialInstallation = $configurationManager->getConfigurationValueByPath('SYS/isInitialInstallationInProgress');
79 if (!$isInitialInstallation ||
empty($existingTables)) {
80 $localConfigurationPathValuePairs['DB/database'] = $postValues['existing'];
83 /** @var $errorStatus \TYPO3\CMS\Install\Status\ErrorStatus */
84 $errorStatus = GeneralUtility
::makeInstance(\TYPO3\CMS\Install\Status\ErrorStatus
::class);
85 $errorStatus->setTitle('No Database selected');
86 $errorStatus->setMessage('You must select a database.');
87 $result[] = $errorStatus;
90 if (!empty($localConfigurationPathValuePairs)) {
91 $configurationManager->setLocalConfigurationValuesByPathValuePairs($localConfigurationPathValuePairs);
98 * Step needs to be executed if database is not set or can
103 public function needsExecution()
105 $this->initializeDatabaseConnection();
107 if ((string)$GLOBALS['TYPO3_CONF_VARS']['DB']['database'] !== '') {
108 $this->databaseConnection
->setDatabaseName($GLOBALS['TYPO3_CONF_VARS']['DB']['database']);
110 $selectResult = $this->databaseConnection
->sql_select_db();
111 if ($selectResult === true) {
114 } catch (\RuntimeException
$e) {
123 * @return string Rendered content
125 protected function executeAction()
127 /** @var $configurationManager \TYPO3\CMS\Core\Configuration\ConfigurationManager */
128 $configurationManager = GeneralUtility
::makeInstance(\TYPO3\CMS\Core\Configuration\ConfigurationManager
::class);
129 $isInitialInstallationInProgress = $configurationManager->getConfigurationValueByPath('SYS/isInitialInstallationInProgress');
130 $this->view
->assign('databaseList', $this->getDatabaseList($isInitialInstallationInProgress));
131 $this->view
->assign('isInitialInstallationInProgress', $isInitialInstallationInProgress);
132 $this->assignSteps();
133 return $this->view
->render();
137 * Returns list of available databases (with access-check based on username/password)
139 * @param bool $initialInstallation TRUE if first installation is in progress, FALSE if upgrading or usual access
140 * @return array List of available databases
142 protected function getDatabaseList($initialInstallation)
144 $this->initializeDatabaseConnection();
145 $databaseArray = $this->databaseConnection
->admin_get_dbs();
146 // Remove mysql organizational tables from database list
147 $reservedDatabaseNames = array('mysql', 'information_schema', 'performance_schema');
148 $allPossibleDatabases = array_diff($databaseArray, $reservedDatabaseNames);
150 // If we are upgrading we show *all* databases the user has access to
151 if ($initialInstallation === false) {
152 return $allPossibleDatabases;
154 // In first installation we show all databases but disable not empty ones (with tables)
155 $databases = array();
156 foreach ($allPossibleDatabases as $database) {
157 $this->databaseConnection
->setDatabaseName($database);
158 $this->databaseConnection
->sql_select_db();
159 $existingTables = $this->databaseConnection
->admin_get_tables();
160 $databases[] = array(
162 'tables' => count($existingTables),
170 * Initialize database connection
174 protected function initializeDatabaseConnection()
176 $this->databaseConnection
= GeneralUtility
::makeInstance(\TYPO3\CMS\Core\Database\DatabaseConnection
::class);
177 $this->databaseConnection
->setDatabaseUsername($GLOBALS['TYPO3_CONF_VARS']['DB']['username']);
178 $this->databaseConnection
->setDatabasePassword($GLOBALS['TYPO3_CONF_VARS']['DB']['password']);
179 $this->databaseConnection
->setDatabaseHost($GLOBALS['TYPO3_CONF_VARS']['DB']['host']);
180 $this->databaseConnection
->setDatabasePort($GLOBALS['TYPO3_CONF_VARS']['DB']['port']);
181 $this->databaseConnection
->setDatabaseSocket($GLOBALS['TYPO3_CONF_VARS']['DB']['socket']);
182 $this->databaseConnection
->sql_pconnect();
186 * Validate the database name against the lowest common denominator of valid identifiers across different DBMS
188 * @param string $databaseName
191 protected function isValidDatabaseName($databaseName)
193 return strlen($databaseName) <= 50 && preg_match('/^[a-zA-Z0-9\$_]*$/', $databaseName);