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