‪TYPO3CMS  ‪main
SetupDatabaseService.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Doctrine\DBAL\DriverManager;
21 use Doctrine\DBAL\Exception as DBALException;
22 use Doctrine\DBAL\Exception\ConnectionException;
23 use Psr\Container\ContainerInterface;
24 use TYPO3\CMS\Core\Configuration\ConfigurationManager;
44 
52 {
53  protected array ‪$validDrivers = [
54  'mysqli',
55  'pdo_mysql',
56  'pdo_pgsql',
57  'pdo_sqlite',
58  ];
59 
60  public function ‪__construct(
61  private readonly ‪LateBootService $lateBootService,
62  private readonly ConfigurationManager $configurationManager,
63  private readonly ‪PermissionsCheck $databasePermissionsCheck,
64  private readonly ‪Registry $registry,
65  private readonly ‪SchemaMigrator $schemaMigrator,
66  ) {
67  }
68 
73  public function ‪setDefaultConnectionSettings(array $values): array
74  {
75  $messages = [];
76  if (($values['availableSet'] ?? '') === 'configurationFromEnvironment') {
77  $defaultConnectionSettings = $this->‪getDatabaseConfigurationFromEnvironment();
78  } else {
79  if (isset($values['driver'])) {
80  if (in_array($values['driver'], $this->validDrivers, true)) {
81  $defaultConnectionSettings['driver'] = $values['driver'];
82  } else {
83  $messages[] = new ‪FlashMessage(
84  'Given driver must be one of ' . implode(', ', $this->validDrivers),
85  'Database driver unknown',
86  ContextualFeedbackSeverity::ERROR
87  );
88  }
89  }
90  if (isset($values['username'])) {
91  $value = $values['username'];
92  if (strlen($value) <= 50) {
93  $defaultConnectionSettings['user'] = $value;
94  } else {
95  $messages[] = new ‪FlashMessage(
96  'Given username must be shorter than fifty characters.',
97  'Database username not valid',
98  ContextualFeedbackSeverity::ERROR
99  );
100  }
101  }
102  if (isset($values['password'])) {
103  $defaultConnectionSettings['password'] = $values['password'];
104  }
105  if (isset($values['host'])) {
106  $value = $values['host'];
107  if ($this->‪isValidDbHost($value)) {
108  $defaultConnectionSettings['host'] = $value;
109  } else {
110  $messages[] = new ‪FlashMessage(
111  'Given host is not alphanumeric (a-z, A-Z, 0-9 or _-.:) or longer than 255 characters.',
112  'Database host not valid',
113  ContextualFeedbackSeverity::ERROR
114  );
115  }
116  }
117  if (isset($values['port']) && $values['host'] !== 'localhost') {
118  $value = (int)$values['port'];
119  if ($this->‪isValidDbPort($value)) {
120  $defaultConnectionSettings['port'] = (int)$value;
121  } else {
122  $messages[] = new ‪FlashMessage(
123  'Given port is not numeric or within range 1 to 65535.',
124  'Database port not valid',
125  ContextualFeedbackSeverity::ERROR
126  );
127  }
128  }
129  if (isset($values['socket']) && $values['socket'] !== '') {
130  if (@file_exists($values['socket'])) {
131  $defaultConnectionSettings['unix_socket'] = $values['socket'];
132  } else {
133  $messages[] = new ‪FlashMessage(
134  'Given socket location does not exist on server.',
135  'Socket does not exist',
136  ContextualFeedbackSeverity::ERROR
137  );
138  }
139  }
140  if (isset($values['database'])) {
141  $value = $values['database'];
142  if ($this->‪isValidDbName($value)) {
143  $defaultConnectionSettings['dbname'] = $value;
144  } else {
145  $messages[] = new ‪FlashMessage(
146  'Given database name must be shorter than fifty characters.',
147  'Database name not valid',
148  ContextualFeedbackSeverity::ERROR
149  );
150  }
151  }
152  // For sqlite a db path is automatically calculated
153  if (isset($values['driver']) && $values['driver'] === 'pdo_sqlite') {
154  $dbFilename = '/cms-' . (new ‪Random())->generateRandomHexString(8) . '.sqlite';
155  // If the var/ folder exists outside of document root, put it into var/sqlite/
156  // Otherwise simply into typo3conf/
159  $defaultConnectionSettings['path'] = ‪Environment::getVarPath() . '/sqlite' . $dbFilename;
160  } else {
161  $defaultConnectionSettings['path'] = ‪Environment::getConfigPath() . $dbFilename;
162  }
163  }
164  // For mysql, set utf8mb4 as default charset
165  if (isset($values['driver']) && in_array($values['driver'], ['mysqli', 'pdo_mysql'])) {
166  $defaultConnectionSettings['charset'] = 'utf8mb4';
167  $defaultConnectionSettings['tableoptions'] = [
168  'charset' => 'utf8mb4',
169  'collate' => 'utf8mb4_unicode_ci',
170  ];
171  }
172  }
173 
174  $success = false;
175  if (!empty($defaultConnectionSettings)) {
176  // Test connection settings and write to config if connect is successful
177  try {
178  $connectionParams = $defaultConnectionSettings;
179  $connectionParams['wrapperClass'] = Connection::class;
180  if (!isset($connectionParams['charset'])) {
181  // utf-8 as default for non mysql
182  $connectionParams['charset'] = 'utf-8';
183  }
184  $connection = DriverManager::getConnection($connectionParams);
185  if ($connection->getWrappedConnection() !== null) {
186  $connection->executeQuery($connection->getDatabasePlatform()->getDummySelectSQL());
187  $success = true;
188  }
189  } catch (DBALException $e) {
190  $messages[] = new ‪FlashMessage(
191  'Connecting to the database with given settings failed: ' . $e->getMessage(),
192  'Database connect not successful',
193  ContextualFeedbackSeverity::ERROR
194  );
195  }
196  $localConfigurationPathValuePairs = [];
197  foreach ($defaultConnectionSettings as $settingsName => $value) {
198  $localConfigurationPathValuePairs['DB/Connections/Default/' . $settingsName] = $value;
199  }
200  // Remove full default connection array
201  $this->configurationManager->removeLocalConfigurationKeysByPath(['DB/Connections/Default']);
202  // Write new values
203  $this->configurationManager->setLocalConfigurationValuesByPathValuePairs($localConfigurationPathValuePairs);
204  }
205 
206  return [$success, $messages];
207  }
208 
215  {
217  $envCredentials = [];
218  foreach (['driver', 'host', 'user', 'password', 'port', 'dbname', 'unix_socket'] as $value) {
219  $envVar = 'TYPO3_INSTALL_DB_' . strtoupper($value);
220  if (getenv($envVar) !== false) {
221  $envCredentials[$value] = getenv($envVar);
222  }
223  }
224  if (!empty($envCredentials)) {
225  $connectionParams = $envCredentials;
226  $connectionParams['wrapperClass'] = Connection::class;
227  $connectionParams['charset'] = 'utf-8';
228  try {
229  $connection = DriverManager::getConnection($connectionParams);
230  if ($connection->getWrappedConnection() !== null) {
231  $connection->executeQuery($connection->getDatabasePlatform()->getDummySelectSQL());
232  return $envCredentials;
233  }
234  } catch (DBALException $e) {
235  return [];
236  }
237  }
238  return [];
239  }
240 
241  public function ‪isValidDbHost(string $name): bool
242  {
243  return preg_match('/^[a-zA-Z0-9_\\.-]+(:.+)?$/', $name) && strlen($name) <= 255;
244  }
245 
246  public function ‪isValidDbPort(int $number): bool
247  {
248  return preg_match('/^[0-9]+(:.+)?$/', (string)$number) && $number > 0 && $number <= 65535;
249  }
250 
251  public function ‪isValidDbName(string $name): bool
252  {
253  return strlen($name) <= 50;
254  }
255 
256  public function ‪getBackendUserPasswordValidationErrors(string $password): array
257  {
258  $passwordPolicy = ‪$GLOBALS['TYPO3_CONF_VARS']['BE']['passwordPolicy'] ?? 'default';
259  $passwordPolicyValidator = GeneralUtility::makeInstance(
260  PasswordPolicyValidator::class,
262  is_string($passwordPolicy) ? $passwordPolicy : ''
263  );
264  $contextData = new ‪ContextData();
265  $passwordPolicyValidator->isValidPassword($password, $contextData);
266 
267  return $passwordPolicyValidator->getValidationErrors();
268  }
269 
276  public function ‪getDatabaseList(): array
277  {
278  $connectionParams = ‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME];
279  unset($connectionParams['dbname']);
280 
281  // Establishing the connection using the Doctrine DriverManager directly
282  // as we need a connection without selecting a database right away. Otherwise
283  // an invalid database name would lead to exceptions which would prevent
284  // changing the currently configured database.
285  $connection = DriverManager::getConnection($connectionParams);
286  $databaseArray = $connection->createSchemaManager()->listDatabases();
287  $connection->close();
288 
289  // Remove organizational tables from database list
290  $reservedDatabaseNames = ['mysql', 'information_schema', 'performance_schema'];
291  $allPossibleDatabases = array_diff($databaseArray, $reservedDatabaseNames);
292 
293  // In first installation we show all databases but disable not empty ones (with tables)
294  $databases = [];
295  foreach ($allPossibleDatabases as $databaseName) {
296  // Reestablishing the connection for each database since there is no
297  // portable way to switch databases on the same Doctrine connection.
298  // Directly using the Doctrine DriverManager here to avoid messing with
299  // the $GLOBALS database configuration array.
300  try {
301  $connectionParams['dbname'] = $databaseName;
302  $connection = DriverManager::getConnection($connectionParams);
303 
304  $databases[] = [
305  'name' => $databaseName,
306  'tables' => count($connection->createSchemaManager()->listTableNames()),
307  'readonly' => false,
308  ];
309  $connection->close();
310  } catch (ConnectionException $exception) {
311  $databases[] = [
312  'name' => $databaseName,
313  'tables' => 0,
314  'readonly' => true,
315  ];
316  // we ignore a connection exception here.
317  // if this happens here, the show tables was successful
318  // but the connection failed because of missing permissions.
319  }
320  }
321 
322  return $databases;
323  }
324 
325  public function ‪checkDatabaseSelect(): bool
326  {
327  $success = false;
328  if ((string)(‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['dbname'] ?? '') !== ''
329  || (string)(‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['path'] ?? '') !== ''
330  ) {
331  try {
332  $connection = GeneralUtility::makeInstance(ConnectionPool::class)
333  ->getConnectionByName(‪ConnectionPool::DEFAULT_CONNECTION_NAME);
334  if ($connection->getWrappedConnection() !== null) {
335  $connection->executeQuery($connection->getDatabasePlatform()->getDummySelectSQL());
336  $success = true;
337  }
338  } catch (DBALException $e) {
339  }
340  }
341 
342  return $success;
343  }
344 
349  public function ‪createDatabase(string $name): void
350  {
351  $platform = GeneralUtility::makeInstance(ConnectionPool::class)
352  ->getConnectionByName(‪ConnectionPool::DEFAULT_CONNECTION_NAME)
353  ->getDatabasePlatform();
354  $connection = GeneralUtility::makeInstance(ConnectionPool::class)
355  ->getConnectionByName(‪ConnectionPool::DEFAULT_CONNECTION_NAME);
356  $connection->exec(
358  $platform,
359  $connection->quoteIdentifier($name)
360  )
361  );
362  $this->configurationManager
363  ->setLocalConfigurationValueByPath('DB/Connections/Default/dbname', $name);
364  }
365 
369  public function ‪isDatabaseConnectSuccessful(): bool
370  {
371  try {
372  $connection = GeneralUtility::makeInstance(ConnectionPool::class)
373  ->getConnectionByName(‪ConnectionPool::DEFAULT_CONNECTION_NAME);
374  if ($connection->getWrappedConnection() !== null) {
375  $connection->executeQuery($connection->getDatabasePlatform()->getDummySelectSQL());
376  return true;
377  }
378  } catch (DBALException $e) {
379  }
380  return false;
381  }
382 
390  public function ‪isDatabaseConfigurationComplete(): bool
391  {
392  $configurationComplete = true;
393  if (!isset(‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['user'])) {
394  $configurationComplete = false;
395  }
396  if (!isset(‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['password'])) {
397  $configurationComplete = false;
398  }
399  if (isset(‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['driver'])
400  && ‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['driver'] === 'pdo_sqlite'
401  && !empty(‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['path'])
402  ) {
403  $configurationComplete = true;
404  }
405  return $configurationComplete;
406  }
407 
411  public function ‪getDatabaseConfiguredMysqliSocket(): string
412  {
413  return $this->‪getDefaultSocketFor('mysqli.default_socket');
414  }
415 
419  public function ‪getDatabaseConfiguredPdoMysqlSocket(): string
420  {
421  return $this->‪getDefaultSocketFor('pdo_mysql.default_socket');
422  }
423 
427  private function ‪getDefaultSocketFor(string $phpIniSetting): string
428  {
429  $socket = ‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['unix_socket'] ?? '';
430  if ($socket === '') {
431  // If no configured socket, use default php socket
432  $defaultSocket = (string)ini_get($phpIniSetting);
433  if ($defaultSocket !== '') {
434  $socket = $defaultSocket;
435  }
436  }
437  return $socket;
438  }
439 
445  public function ‪createNewDatabase(string $dbName): ‪FlashMessage
446  {
447  try {
448  $this->‪createDatabase($dbName);
449  } catch (DBALException $e) {
450  return new ‪FlashMessage(
451  'Database with name "' . $dbName . '" could not be created.'
452  . ' Either your database name contains a reserved keyword or your database'
453  . ' user does not have sufficient permissions to create it or the database already exists.'
454  . ' Please choose an existing (empty) database, choose another name or contact administration.',
455  'Unable to create database',
456  ContextualFeedbackSeverity::ERROR
457  );
458  }
459  return new ‪FlashMessage(
460  '',
461  'Database created'
462  );
463  }
464 
472  public function ‪checkExistingDatabase(string $dbName): ‪FlashMessage
473  {
474  $result = new ‪FlashMessage('');
475  $localConfigurationPathValuePairs = [];
476 
477  ‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['dbname'] = $dbName;
478  try {
479  $connection = GeneralUtility::makeInstance(ConnectionPool::class)
480  ->getConnectionByName(‪ConnectionPool::DEFAULT_CONNECTION_NAME);
481 
482  if (!empty($connection->createSchemaManager()->listTableNames())) {
483  $result = new ‪FlashMessage(
484  sprintf('Cannot use database "%s"', $dbName)
485  . ', because it already contains tables. Please select a different database or choose to create one!',
486  'Selected database is not empty!',
487  ContextualFeedbackSeverity::ERROR
488  );
489  }
490  } catch (\‪Exception $e) {
491  $result = new ‪FlashMessage(
492  sprintf('Could not connect to database "%s"', $dbName)
493  . '! Make sure it really exists and your database user has the permissions to select it!',
494  'Could not connect to selected database!',
495  ContextualFeedbackSeverity::ERROR
496  );
497  }
498 
499  if ($result->getSeverity() === ContextualFeedbackSeverity::OK) {
500  $localConfigurationPathValuePairs['DB/Connections/Default/dbname'] = $dbName;
501 
502  $this->configurationManager->setLocalConfigurationValuesByPathValuePairs($localConfigurationPathValuePairs);
503  }
504 
505  return $result;
506  }
507 
513  public function ‪importDatabaseData(): array
514  {
515  // Will load ext_localconf and ext_tables. This is pretty safe here since we are
516  // in first install (database empty), so it is very likely that no extension is loaded
517  // that could trigger a fatal at this point.
518  $container = $this->lateBootService->loadExtLocalconfDatabaseAndExtTables();
519 
520  $sqlReader = $container->get(SqlReader::class);
521  $sqlCode = $sqlReader->getTablesDefinitionString(true);
522  $createTableStatements = $sqlReader->getCreateTableStatementArray($sqlCode);
523  $results = $this->schemaMigrator->install($createTableStatements);
524 
525  // Only keep statements with error messages
526  $results = array_filter($results);
527  if (count($results) === 0) {
528  $insertStatements = $sqlReader->getInsertStatementArray($sqlCode);
529  $results = $this->schemaMigrator->importStaticData($insertStatements);
530  }
531  foreach ($results as $statement => &$message) {
532  if ($message === '') {
533  unset($results[$statement]);
534  continue;
535  }
536 
537  $message = new ‪FlashMessage(
538  'Query:' . LF . ' ' . $statement . LF . 'Error:' . LF . ' ' . $message,
539  'Database query failed!',
540  ContextualFeedbackSeverity::ERROR
541  );
542  }
543  return array_values($results);
544  }
545 
546  public function ‪checkRequiredDatabasePermissions(): array
547  {
548  try {
549  return $this->databasePermissionsCheck
550  ->checkCreateAndDrop()
551  ->checkAlter()
552  ->checkIndex()
553  ->checkCreateTemporaryTable()
554  ->checkInsert()
555  ->checkSelect()
556  ->checkUpdate()
557  ->checkDelete()
558  ->getMessages();
559  } catch (‪Exception $exception) {
560  return $this->databasePermissionsCheck->getMessages();
561  }
562  }
563 
564  public function ‪checkDatabaseRequirementsForDriver(string $databaseDriverName): ‪FlashMessageQueue
565  {
566  $databaseCheck = GeneralUtility::makeInstance(DatabaseCheck::class);
567  try {
568  $databaseDriverClassName = ‪DatabaseCheck::retrieveDatabaseDriverClassByDriverName($databaseDriverName);
569 
570  $databaseCheck->checkDatabasePlatformRequirements($databaseDriverClassName);
571  $databaseCheck->checkDatabaseDriverRequirements($databaseDriverClassName);
572 
573  return $databaseCheck->getMessageQueue();
574  } catch (\‪TYPO3\CMS\Install\‪Exception $exception) {
575  $flashMessageQueue = new ‪FlashMessageQueue('database-check-requirements');
576  $flashMessageQueue->enqueue(
577  new ‪FlashMessage(
578  '',
579  $exception->getMessage(),
580  ContextualFeedbackSeverity::INFO
581  )
582  );
583  return $flashMessageQueue;
584  }
585  }
586 
587  public function ‪getDriverOptions(): array
588  {
589  $hasAtLeastOneOption = false;
590  $activeAvailableOption = '';
591 
592  $driverOptions = [];
593 
595  $hasAtLeastOneOption = true;
596  $driverOptions['hasMysqliManualConfiguration'] = true;
597  $mysqliManualConfigurationOptions = [
598  'driver' => 'mysqli',
599  'username' => ‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['user'] ?? '',
600  'password' => ‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['password'] ?? '',
601  'port' => ‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['port'] ?? 3306,
602  'database' => ‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['dbname'] ?? '',
603  ];
604  $host = ‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['host'] ?? '127.0.0.1';
605  if ($host === 'localhost') {
606  $host = '127.0.0.1';
607  }
608  $mysqliManualConfigurationOptions['host'] = $host;
609  $driverOptions['mysqliManualConfigurationOptions'] = $mysqliManualConfigurationOptions;
610  $activeAvailableOption = 'mysqliManualConfiguration';
611 
612  $driverOptions['hasMysqliSocketManualConfiguration'] = true;
613  $driverOptions['mysqliSocketManualConfigurationOptions'] = [
614  'driver' => 'mysqli',
615  'username' => ‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['user'] ?? '',
616  'password' => ‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['password'] ?? '',
617  'socket' => $this->‪getDatabaseConfiguredMysqliSocket(),
618  'database' => ‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['dbname'] ?? '',
619  ];
620  if ((‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['driver'] ?? '') === 'mysqli'
621  && (‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][ConnectionPool::DEFAULT_CONNECTION_NAME]['host'] ?? '') === 'localhost') {
622  $activeAvailableOption = 'mysqliSocketManualConfiguration';
623  }
624  }
625 
627  $hasAtLeastOneOption = true;
628  $driverOptions['hasPdoMysqlManualConfiguration'] = true;
629  $pdoMysqlManualConfigurationOptions = [
630  'driver' => 'pdo_mysql',
631  'username' => ‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['user'] ?? '',
632  'password' => ‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['password'] ?? '',
633  'port' => ‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['port'] ?? 3306,
634  'database' => ‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['dbname'] ?? '',
635  ];
636  $host = ‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['host'] ?? '127.0.0.1';
637  if ($host === 'localhost') {
638  $host = '127.0.0.1';
639  }
640  $pdoMysqlManualConfigurationOptions['host'] = $host;
641  $driverOptions['pdoMysqlManualConfigurationOptions'] = $pdoMysqlManualConfigurationOptions;
642 
643  // preselect PDO MySQL only if mysqli is not present
645  $activeAvailableOption = 'pdoMysqlManualConfiguration';
646  }
647 
648  $driverOptions['hasPdoMysqlSocketManualConfiguration'] = true;
649  $driverOptions['pdoMysqlSocketManualConfigurationOptions'] = [
650  'driver' => 'pdo_mysql',
651  'username' => ‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['user'] ?? '',
652  'password' => ‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['password'] ?? '',
653  'socket' => $this->‪getDatabaseConfiguredPdoMysqlSocket(),
654  'database' => ‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['dbname'] ?? '',
655  ];
656  if ((‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['driver'] ?? '') === 'pdo_mysql'
657  && ‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][ConnectionPool::DEFAULT_CONNECTION_NAME]['host'] === 'localhost') {
658  $activeAvailableOption = 'pdoMysqlSocketManualConfiguration';
659  }
660  }
661 
663  $hasAtLeastOneOption = true;
664  $driverOptions['hasPostgresManualConfiguration'] = true;
665  $driverOptions['postgresManualConfigurationOptions'] = [
666  'driver' => 'pdo_pgsql',
667  'username' => ‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['user'] ?? '',
668  'password' => ‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['password'] ?? '',
669  'host' => ‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['host'] ?? '127.0.0.1',
670  'port' => ‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['port'] ?? 5432,
671  'database' => ‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['dbname'] ?? '',
672  ];
673  if ((‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['driver'] ?? '') === 'pdo_pgsql') {
674  $activeAvailableOption = 'postgresManualConfiguration';
675  }
676  }
678  $hasAtLeastOneOption = true;
679  $driverOptions['hasSqliteManualConfiguration'] = true;
680  $driverOptions['sqliteManualConfigurationOptions'] = [
681  'driver' => 'pdo_sqlite',
682  ];
683  if ((‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][‪ConnectionPool::DEFAULT_CONNECTION_NAME]['driver'] ?? '') === 'pdo_sqlite') {
684  $activeAvailableOption = 'sqliteManualConfiguration';
685  }
686  }
687 
688  if (!empty($this->‪getDatabaseConfigurationFromEnvironment())) {
689  $hasAtLeastOneOption = true;
690  $activeAvailableOption = 'configurationFromEnvironment';
691  $driverOptions['hasConfigurationFromEnvironment'] = true;
692  }
693 
694  return array_merge($driverOptions, [
695  'hasAtLeastOneOption' => $hasAtLeastOneOption,
696  'activeAvailableOption' => $activeAvailableOption,
697  ]);
698  }
699 
700  public function ‪markWizardsDone(ContainerInterface $container): void
701  {
702  foreach ($container->get(UpgradeWizardsService::class)->getNonRepeatableUpgradeWizards() as $className) {
703  $this->registry->set('installUpdate', $className, 1);
704  }
705  $this->registry->set('installUpdateRows', 'rowUpdatersDone', GeneralUtility::makeInstance(DatabaseRowsUpdateWizard::class)->getAvailableRowUpdater());
706  }
707 }
‪TYPO3\CMS\Install\Service\SetupDatabaseService\isDatabaseConnectSuccessful
‪isDatabaseConnectSuccessful()
Definition: SetupDatabaseService.php:369
‪TYPO3\CMS\Install\Service\SetupDatabaseService\$validDrivers
‪array $validDrivers
Definition: SetupDatabaseService.php:53
‪TYPO3\CMS\Install\Service\SetupDatabaseService\createDatabase
‪createDatabase(string $name)
Definition: SetupDatabaseService.php:349
‪TYPO3\CMS\Install\Service\SetupDatabaseService\getDatabaseConfiguredMysqliSocket
‪getDatabaseConfiguredMysqliSocket()
Definition: SetupDatabaseService.php:411
‪TYPO3
‪TYPO3\CMS\Core\Core\Environment\getPublicPath
‪static getPublicPath()
Definition: Environment.php:187
‪TYPO3\CMS\Core\Registry
Definition: Registry.php:33
‪TYPO3\CMS\Install\SystemEnvironment\DatabaseCheck\isPdoSqlite
‪static isPdoSqlite()
Definition: DatabaseCheck.php:284
‪TYPO3\CMS\Install\Service\SetupDatabaseService\createNewDatabase
‪createNewDatabase(string $dbName)
Definition: SetupDatabaseService.php:445
‪TYPO3\CMS\Install\Service\SetupDatabaseService\checkDatabaseRequirementsForDriver
‪checkDatabaseRequirementsForDriver(string $databaseDriverName)
Definition: SetupDatabaseService.php:564
‪TYPO3\CMS\Install\Configuration\Exception
Definition: Exception.php:22
‪TYPO3\CMS\Core\Database\Schema\SqlReader
Definition: SqlReader.php:31
‪TYPO3\CMS\Install\Service\SetupDatabaseService\isValidDbHost
‪isValidDbHost(string $name)
Definition: SetupDatabaseService.php:241
‪TYPO3\CMS\Core\Core\Environment\getVarPath
‪static getVarPath()
Definition: Environment.php:197
‪TYPO3\CMS\Core\Database\ConnectionPool\DEFAULT_CONNECTION_NAME
‪const DEFAULT_CONNECTION_NAME
Definition: ConnectionPool.php:55
‪TYPO3\CMS\Core\Database\Schema\SchemaMigrator
Definition: SchemaMigrator.php:39
‪TYPO3\CMS\Core\Core\Environment\getConfigPath
‪static getConfigPath()
Definition: Environment.php:212
‪TYPO3\CMS\Install\Service\SetupDatabaseService\getDefaultSocketFor
‪getDefaultSocketFor(string $phpIniSetting)
Definition: SetupDatabaseService.php:427
‪TYPO3\CMS\Core\Type\ContextualFeedbackSeverity
‪ContextualFeedbackSeverity
Definition: ContextualFeedbackSeverity.php:25
‪TYPO3\CMS\Install\Updates\DatabaseRowsUpdateWizard
Definition: DatabaseRowsUpdateWizard.php:48
‪TYPO3\CMS\Install\SystemEnvironment\DatabaseCheck\retrieveDatabaseDriverClassByDriverName
‪static retrieveDatabaseDriverClassByDriverName(string $driverName)
Definition: DatabaseCheck.php:252
‪TYPO3\CMS\Core\Core\Environment\getProjectPath
‪static string getProjectPath()
Definition: Environment.php:160
‪TYPO3\CMS\Install\Service\SetupDatabaseService\isDatabaseConfigurationComplete
‪bool isDatabaseConfigurationComplete()
Definition: SetupDatabaseService.php:390
‪TYPO3\CMS\Core\Utility\GeneralUtility\mkdir_deep
‪static mkdir_deep($directory)
Definition: GeneralUtility.php:1638
‪TYPO3\CMS\Install\Service\SetupDatabaseService\checkDatabaseSelect
‪checkDatabaseSelect()
Definition: SetupDatabaseService.php:325
‪TYPO3\CMS\Install\Database\PermissionsCheck
Definition: PermissionsCheck.php:31
‪TYPO3\CMS\Core\PasswordPolicy\NEW_USER_PASSWORD
‪@ NEW_USER_PASSWORD
Definition: PasswordPolicyAction.php:27
‪TYPO3\CMS\Core\PasswordPolicy\PasswordPolicyValidator
Definition: PasswordPolicyValidator.php:27
‪TYPO3\CMS\Install\Service\SetupDatabaseService\getBackendUserPasswordValidationErrors
‪getBackendUserPasswordValidationErrors(string $password)
Definition: SetupDatabaseService.php:256
‪TYPO3\CMS\Install\Service\SetupDatabaseService\setDefaultConnectionSettings
‪array setDefaultConnectionSettings(array $values)
Definition: SetupDatabaseService.php:73
‪TYPO3\CMS\Install\Service\SetupDatabaseService\markWizardsDone
‪markWizardsDone(ContainerInterface $container)
Definition: SetupDatabaseService.php:700
‪TYPO3\CMS\Install\Service\LateBootService
Definition: LateBootService.php:27
‪TYPO3\CMS\Install\SystemEnvironment\DatabaseCheck
‪TYPO3\CMS\Install\Service\SetupDatabaseService
Definition: SetupDatabaseService.php:52
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:35
‪TYPO3\CMS\Install\Service\SetupDatabaseService\getDriverOptions
‪getDriverOptions()
Definition: SetupDatabaseService.php:587
‪TYPO3\CMS\Core\Messaging\FlashMessage
Definition: FlashMessage.php:27
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:41
‪TYPO3\CMS\Core\Database\Platform\PlatformInformation
Definition: PlatformInformation.php:32
‪TYPO3\CMS\Install\Service\SetupDatabaseService\getDatabaseConfiguredPdoMysqlSocket
‪getDatabaseConfiguredPdoMysqlSocket()
Definition: SetupDatabaseService.php:419
‪TYPO3\CMS\Core\PasswordPolicy\PasswordPolicyAction
‪PasswordPolicyAction
Definition: PasswordPolicyAction.php:24
‪TYPO3\CMS\Core\Crypto\Random
Definition: Random.php:27
‪TYPO3\CMS\Install\Service\SetupDatabaseService\__construct
‪__construct(private readonly LateBootService $lateBootService, private readonly ConfigurationManager $configurationManager, private readonly PermissionsCheck $databasePermissionsCheck, private readonly Registry $registry, private readonly SchemaMigrator $schemaMigrator,)
Definition: SetupDatabaseService.php:60
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:51
‪TYPO3\CMS\Install\SystemEnvironment\DatabaseCheck\isPdoMysql
‪static isPdoMysql()
Definition: DatabaseCheck.php:274
‪TYPO3\CMS\Install\Service\SetupDatabaseService\checkRequiredDatabasePermissions
‪checkRequiredDatabasePermissions()
Definition: SetupDatabaseService.php:546
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:51
‪TYPO3\CMS\Install\Service\SetupDatabaseService\getDatabaseList
‪array getDatabaseList()
Definition: SetupDatabaseService.php:276
‪TYPO3\CMS\Core\Database\Platform\PlatformInformation\getDatabaseCreateStatementWithCharset
‪static getDatabaseCreateStatementWithCharset(AbstractPlatform $platform, string $databaseName)
Definition: PlatformInformation.php:77
‪TYPO3\CMS\Install\Service\SetupDatabaseService\importDatabaseData
‪FlashMessage[] importDatabaseData()
Definition: SetupDatabaseService.php:513
‪TYPO3\CMS\Core\Messaging\FlashMessageQueue
Definition: FlashMessageQueue.php:30
‪TYPO3\CMS\Install\Service\SetupDatabaseService\getDatabaseConfigurationFromEnvironment
‪array getDatabaseConfigurationFromEnvironment()
Definition: SetupDatabaseService.php:214
‪TYPO3\CMS\Install\Service\SetupDatabaseService\checkExistingDatabase
‪checkExistingDatabase(string $dbName)
Definition: SetupDatabaseService.php:472
‪TYPO3\CMS\Install\Service
Definition: ClearCacheService.php:16
‪TYPO3\CMS\Install\Service\SetupDatabaseService\isValidDbPort
‪isValidDbPort(int $number)
Definition: SetupDatabaseService.php:246
‪TYPO3\CMS\Install\Service\SetupDatabaseService\isValidDbName
‪isValidDbName(string $name)
Definition: SetupDatabaseService.php:251
‪TYPO3\CMS\Install\SystemEnvironment\DatabaseCheck\isPdoPgsql
‪static isPdoPgsql()
Definition: DatabaseCheck.php:279
‪TYPO3\CMS\Core\PasswordPolicy\Validator\Dto\ContextData
Definition: ContextData.php:28
‪TYPO3\CMS\Install\SystemEnvironment\DatabaseCheck\isMysqli
‪static isMysqli()
Definition: DatabaseCheck.php:269