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