[TASK] Show not empty databases in install tool
[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 * Copyright notice
6 *
7 * (c) 2013 Christian Kuhn <lolli@schwarzbu.ch>
8 * All rights reserved
9 *
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 *
19 * This script is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * This copyright notice MUST APPEAR in all copies of the script!
25 ***************************************************************/
26
27 use TYPO3\CMS\Install\Controller\Action;
28
29 /**
30 * Database select step.
31 * This step is only rendered if database is mysql. With dbal,
32 * database name is submitted by previous step already.
33 */
34 class DatabaseSelect extends Action\AbstractAction implements StepInterface {
35
36 /**
37 * @var \TYPO3\CMS\Core\Database\DatabaseConnection
38 */
39 protected $databaseConnection = NULL;
40
41 /**
42 * Create database if needed, save selected db name in configuration
43 *
44 * @return array<\TYPO3\CMS\Install\Status\StatusInterface>
45 */
46 public function execute() {
47 $result = array();
48 $this->initializeDatabaseConnection();
49 $postValues = $this->postValues['values'];
50 $localConfigurationPathValuePairs = array();
51 /** @var $configurationManager \TYPO3\CMS\Core\Configuration\ConfigurationManager */
52 $configurationManager = $this->objectManager->get('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager');
53 if ($postValues['type'] === 'new') {
54 $newDatabaseName = $postValues['new'];
55 if (strlen($newDatabaseName) <= 50) {
56 $createDatabaseResult = $this->databaseConnection->admin_query('CREATE DATABASE ' . $newDatabaseName . ' CHARACTER SET utf8');
57 if ($createDatabaseResult) {
58 $localConfigurationPathValuePairs['DB/database'] = $newDatabaseName;
59 } else {
60 /** @var $errorStatus \TYPO3\CMS\Install\Status\ErrorStatus */
61 $errorStatus = $this->objectManager->get('TYPO3\\CMS\\Install\\Status\\ErrorStatus');
62 $errorStatus->setTitle('Unable to create database');
63 $errorStatus->setMessage(
64 'Database with name ' . $newDatabaseName . ' could not be created.' .
65 ' Either your database name contains special chars (only alphanumeric characters are allowed)' .
66 ' or your database user probably has no sufficient permissions to create it.' .
67 ' Please choose an existing (empty) database or contact administration.'
68 );
69 $result[] = $errorStatus;
70 }
71 } else {
72 /** @var $errorStatus \TYPO3\CMS\Install\Status\ErrorStatus */
73 $errorStatus = $this->objectManager->get('TYPO3\\CMS\\Install\\Status\\ErrorStatus');
74 $errorStatus->setTitle('Database name not valid');
75 $errorStatus->setMessage('Given database name must be shorter than fifty characters.');
76 $result[] = $errorStatus;
77 }
78 } elseif ($postValues['type'] === 'existing') {
79 // Only store database information when it's empty
80 $this->databaseConnection->setDatabaseName($postValues['existing']);
81 $this->databaseConnection->sql_select_db();
82 $existingTables = $this->databaseConnection->admin_get_tables();
83 $isInitialInstallation = $configurationManager->getConfigurationValueByPath('SYS/isInitialInstallationInProgress');
84 if (!$isInitialInstallation || count($existingTables) === 0) {
85 $localConfigurationPathValuePairs['DB/database'] = $postValues['existing'];
86 }
87 }
88
89 if (!empty($localConfigurationPathValuePairs)) {
90 $configurationManager->setLocalConfigurationValuesByPathValuePairs($localConfigurationPathValuePairs);
91 }
92
93 return $result;
94 }
95
96 /**
97 * Step needs to be executed if database is not set or can
98 * not be selected.
99 *
100 * @return boolean
101 */
102 public function needsExecution() {
103 $this->initializeDatabaseConnection();
104 $result = TRUE;
105 if (strlen($GLOBALS['TYPO3_CONF_VARS']['DB']['database']) > 0) {
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 * Render this step
120 *
121 * @return string
122 */
123 public function handle() {
124 $this->initializeHandle();
125 /** @var $configurationManager \TYPO3\CMS\Core\Configuration\ConfigurationManager */
126 $configurationManager = $this->objectManager->get('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager');
127 $isInitialInstallationInProgress = $configurationManager->getConfigurationValueByPath('SYS/isInitialInstallationInProgress');
128 $this->view->assign('databaseList', $this->getDatabaseList($isInitialInstallationInProgress));
129 $this->view->assign('isInitialInstallationInProgress', $isInitialInstallationInProgress);
130 return $this->view->render();
131 }
132
133 /**
134 * Returns list of available databases (with access-check based on username/password)
135 *
136 * @param boolean $initialInstallation TRUE if first installation is in progress, FALSE if upgrading or usual access
137 * @return array List of available databases
138 */
139 protected function getDatabaseList($initialInstallation) {
140 $this->initializeDatabaseConnection();
141 $databaseArray = $this->databaseConnection->admin_get_dbs();
142 // Remove mysql organizational tables from database list
143 $reservedDatabaseNames = array('mysql', 'information_schema', 'performance_schema');
144 $allPossibleDatabases = array_diff($databaseArray, $reservedDatabaseNames);
145
146 // If we are upgrading we show *all* databases the user has access to
147 if ($initialInstallation === FALSE) {
148 return $allPossibleDatabases;
149 } else {
150 // In first installation we show all databases but disable not empty ones (with tables)
151 $databases = array();
152 foreach ($allPossibleDatabases as $database) {
153 $this->databaseConnection->setDatabaseName($database);
154 $this->databaseConnection->sql_select_db();
155 $existingTables = $this->databaseConnection->admin_get_tables();
156 $databases[] = array(
157 'name' => $database,
158 'tables' => count($existingTables),
159 );
160 }
161 return $databases;
162 }
163 }
164
165 /**
166 * Initialize database connection
167 *
168 * @return void
169 */
170 protected function initializeDatabaseConnection() {
171 $this->databaseConnection = $this->objectManager->get('TYPO3\\CMS\\Core\\Database\\DatabaseConnection');
172 $this->databaseConnection->setDatabaseUsername($GLOBALS['TYPO3_CONF_VARS']['DB']['username']);
173 $this->databaseConnection->setDatabasePassword($GLOBALS['TYPO3_CONF_VARS']['DB']['password']);
174 $this->databaseConnection->setDatabaseHost($GLOBALS['TYPO3_CONF_VARS']['DB']['host']);
175 $this->databaseConnection->setDatabasePort($GLOBALS['TYPO3_CONF_VARS']['DB']['port']);
176 $this->databaseConnection->setDatabaseSocket($GLOBALS['TYPO3_CONF_VARS']['DB']['socket']);
177 $this->databaseConnection->sql_pconnect();
178 }
179 }