[BUGFIX] Install Tool fatal with Oracle database
[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 does not have 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' && !empty($postValues['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 } else {
88 /** @var $errorStatus \TYPO3\CMS\Install\Status\ErrorStatus */
89 $errorStatus = $this->objectManager->get('TYPO3\\CMS\\Install\\Status\\ErrorStatus');
90 $errorStatus->setTitle('No Database selected');
91 $errorStatus->setMessage('You have to select a database.');
92 $result[] = $errorStatus;
93 }
94
95 if (!empty($localConfigurationPathValuePairs)) {
96 $configurationManager->setLocalConfigurationValuesByPathValuePairs($localConfigurationPathValuePairs);
97 }
98
99 return $result;
100 }
101
102 /**
103 * Step needs to be executed if database is not set or can
104 * not be selected.
105 *
106 * @return boolean
107 */
108 public function needsExecution() {
109 $this->initializeDatabaseConnection();
110 $result = TRUE;
111 if (strlen($GLOBALS['TYPO3_CONF_VARS']['DB']['database']) > 0) {
112 $this->databaseConnection->setDatabaseName($GLOBALS['TYPO3_CONF_VARS']['DB']['database']);
113 try {
114 $selectResult = $this->databaseConnection->sql_select_db();
115 if ($selectResult === TRUE) {
116 $result = FALSE;
117 }
118 } catch (\RuntimeException $e) {
119 }
120 }
121 return $result;
122 }
123
124 /**
125 * Render this step
126 *
127 * @return string
128 */
129 public function handle() {
130 $this->initializeHandle();
131 /** @var $configurationManager \TYPO3\CMS\Core\Configuration\ConfigurationManager */
132 $configurationManager = $this->objectManager->get('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager');
133 $isInitialInstallationInProgress = $configurationManager->getConfigurationValueByPath('SYS/isInitialInstallationInProgress');
134 $this->view->assign('databaseList', $this->getDatabaseList($isInitialInstallationInProgress));
135 $this->view->assign('isInitialInstallationInProgress', $isInitialInstallationInProgress);
136 return $this->view->render();
137 }
138
139 /**
140 * Returns list of available databases (with access-check based on username/password)
141 *
142 * @param boolean $initialInstallation TRUE if first installation is in progress, FALSE if upgrading or usual access
143 * @return array List of available databases
144 */
145 protected function getDatabaseList($initialInstallation) {
146 $this->initializeDatabaseConnection();
147 $databaseArray = $this->databaseConnection->admin_get_dbs();
148 // Remove mysql organizational tables from database list
149 $reservedDatabaseNames = array('mysql', 'information_schema', 'performance_schema');
150 $allPossibleDatabases = array_diff($databaseArray, $reservedDatabaseNames);
151
152 // If we are upgrading we show *all* databases the user has access to
153 if ($initialInstallation === FALSE) {
154 return $allPossibleDatabases;
155 } else {
156 // In first installation we show all databases but disable not empty ones (with tables)
157 $databases = array();
158 foreach ($allPossibleDatabases as $database) {
159 $this->databaseConnection->setDatabaseName($database);
160 $this->databaseConnection->sql_select_db();
161 $existingTables = $this->databaseConnection->admin_get_tables();
162 $databases[] = array(
163 'name' => $database,
164 'tables' => count($existingTables),
165 );
166 }
167 return $databases;
168 }
169 }
170
171 /**
172 * Initialize database connection
173 *
174 * @return void
175 */
176 protected function initializeDatabaseConnection() {
177 $this->databaseConnection = $this->objectManager->get('TYPO3\\CMS\\Core\\Database\\DatabaseConnection');
178 $this->databaseConnection->setDatabaseUsername($GLOBALS['TYPO3_CONF_VARS']['DB']['username']);
179 $this->databaseConnection->setDatabasePassword($GLOBALS['TYPO3_CONF_VARS']['DB']['password']);
180 $this->databaseConnection->setDatabaseHost($GLOBALS['TYPO3_CONF_VARS']['DB']['host']);
181 $this->databaseConnection->setDatabasePort($GLOBALS['TYPO3_CONF_VARS']['DB']['port']);
182 $this->databaseConnection->setDatabaseSocket($GLOBALS['TYPO3_CONF_VARS']['DB']['socket']);
183 $this->databaseConnection->sql_pconnect();
184 }
185 }