* @license GNU General Public License version 2 or later; see LICENSE */ namespace Joomla\CMS\Service\Provider; use Joomla\Database\DatabaseDriver; use Joomla\Database\DatabaseInterface; use Joomla\Database\Mysql\MysqlDriver; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Service provider for the application's database dependency * * @since 4.0.0 */ class Database implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.0.0 */ public function register(Container $container) { $container->alias('db', DatabaseInterface::class) ->alias('DatabaseDriver', DatabaseInterface::class) ->alias(DatabaseDriver::class, DatabaseInterface::class) ->share( DatabaseInterface::class, function (Container $container) { $conf = $container->get('config'); /** * @todo: This 'sensible' default is required in the installer for now. Eventually we need to * refactor the installer so it is not required */ $dbtype = $conf->get('dbtype', 'mysqli'); /* * In Joomla! 3.x and earlier the `mysql` type was used for the `ext/mysql` PHP extension, which is no longer supported. * The `pdomysql` type represented the PDO MySQL adapter. With the Framework's package in use, the PDO MySQL adapter * is now the `mysql` type. Therefore, we check two conditions: * * 1) Is the type `pdomysql`, if so switch to `mysql` * 2) Is the type `mysql`, if so make sure PDO MySQL is supported and if not switch to `mysqli` * * For these cases, if a connection cannot be made with MySQLi, the database API will handle throwing an Exception * so we don't need to make any additional checks for MySQLi. */ if (strtolower($dbtype) === 'pdomysql') { $dbtype = 'mysql'; } if (strtolower($dbtype) === 'mysql') { if (!MysqlDriver::isSupported()) { $dbtype = 'mysqli'; } } /* * Joomla! 4.0 removes support for the `ext/pgsql` PHP extension. To help with the migration, we will migrate the configuration * to the PDO PostgreSQL driver regardless of if the environment supports it. Instead of getting a "driver not found" type of * error, this will instead force the API to report that the driver is not supported. */ if (strtolower($dbtype) === 'postgresql') { $dbtype = 'pgsql'; } $options = [ 'driver' => $dbtype, 'host' => $conf->get('host'), 'user' => $conf->get('user'), 'password' => $conf->get('password'), 'database' => $conf->get('db'), 'prefix' => $conf->get('dbprefix'), ]; if ((int) $conf->get('dbencryption') !== 0) { $options['ssl'] = [ 'enable' => true, 'verify_server_cert' => (bool) $conf->get('dbsslverifyservercert'), ]; foreach (['cipher', 'ca', 'key', 'cert'] as $value) { $confVal = trim($conf->get('dbssl' . $value, '')); if ($confVal !== '') { $options['ssl'][$value] = $confVal; } } } // Enable utf8mb4 connections for mysql adapters if (strtolower($dbtype) === 'mysqli') { $options['utf8mb4'] = true; } if (strtolower($dbtype) === 'mysql') { $options['charset'] = 'utf8mb4'; } if (JDEBUG) { $options['monitor'] = new \Joomla\Database\Monitor\DebugMonitor(); } try { $db = DatabaseDriver::getInstance($options); } catch (\RuntimeException $e) { if (!headers_sent()) { header('HTTP/1.1 500 Internal Server Error'); } jexit('Database Error: ' . $e->getMessage()); } $db->setDispatcher($container->get(DispatcherInterface::class)); return $db; }, true ); } }