diff --git a/lib/Config/Env.php b/lib/Config/Env.php index c5e08b2856..e9553c7a27 100644 --- a/lib/Config/Env.php +++ b/lib/Config/Env.php @@ -26,6 +26,7 @@ class Env { static $plugin_prefix; static $db_prefix; static $db_host; + static $db_is_ipv6; static $db_socket; static $db_port; static $db_name; @@ -70,6 +71,7 @@ class Env { global $wpdb; self::$db_prefix = $wpdb->prefix . self::$plugin_prefix; self::$db_host = $host; + self::$db_is_ipv6 = $is_ipv6; self::$db_port = $port ?: 3306; self::$db_socket = $socket; self::$db_name = $db_name; diff --git a/lib/Doctrine/ConnectionFactory.php b/lib/Doctrine/ConnectionFactory.php index fe86e23f33..0439a53989 100644 --- a/lib/Doctrine/ConnectionFactory.php +++ b/lib/Doctrine/ConnectionFactory.php @@ -19,15 +19,20 @@ class ConnectionFactory { 'wrapperClass' => SerializableConnection::class, 'driver' => self::DRIVER, 'platform' => new $platform_class, - 'host' => Env::$db_host, - 'port' => Env::$db_port, - 'socket' => Env::$db_socket, 'user' => Env::$db_username, 'password' => Env::$db_password, 'charset' => Env::$db_charset, 'dbname' => Env::$db_name, 'driverOptions' => $this->getDriverOptions(Env::$db_timezone_offset, Env::$db_charset, Env::$db_collation), ]; + + if (!empty(Env::$db_socket)) { + $connection_params['unix_socket'] = Env::$db_socket; + } else { + $connection_params['host'] = Env::$db_is_ipv6 ? ('[' . Env::$db_host . ']') : Env::$db_host; + $connection_params['port'] = Env::$db_port; + } + return DriverManager::getConnection($connection_params); } diff --git a/tests/integration/Doctrine/ConnectionFactoryTest.php b/tests/integration/Doctrine/ConnectionFactoryTest.php index abef1f7804..2bc17a86db 100644 --- a/tests/integration/Doctrine/ConnectionFactoryTest.php +++ b/tests/integration/Doctrine/ConnectionFactoryTest.php @@ -10,6 +10,16 @@ use MailPoetVendor\Doctrine\DBAL\Platforms\MySqlPlatform; use PDO; class ConnectionFactoryTest extends \MailPoetTest { + private $env_backup = []; + + function _before() { + parent::_before(); + $this->env_backup['db_host'] = Env::$db_host; + $this->env_backup['db_is_ipv6'] = Env::$db_is_ipv6; + $this->env_backup['db_port'] = Env::$db_port; + $this->env_backup['db_socket'] = Env::$db_socket; + } + function testItSetsUpConnection() { $connection_factory = new ConnectionFactory(); $connection = $connection_factory->createConnection(); @@ -20,13 +30,46 @@ class ConnectionFactoryTest extends \MailPoetTest { expect($connection->getDatabasePlatform())->isInstanceOf(MySqlPlatform::class); expect($connection->getHost())->equals(Env::$db_host); expect($connection->getPort())->equals(Env::$db_port); - expect($connection->getParams()['socket'])->equals(Env::$db_socket); + expect($connection->getParams())->notContains('unix_socket'); expect($connection->getUsername())->equals(Env::$db_username); expect($connection->getPassword())->equals(Env::$db_password); expect($connection->getParams()['charset'])->equals(Env::$db_charset); expect($connection->getDatabase())->equals(Env::$db_name); } + function testItSetsUpSocket() { + Env::$db_host = null; + Env::$db_port = null; + Env::$db_socket = 'socket'; + $connection_factory = new ConnectionFactory(); + $connection = $connection_factory->createConnection(); + + expect($connection->getHost())->null(); + expect($connection->getPort())->null(); + expect($connection->getParams()['unix_socket'])->equals('socket'); + } + + function testItSetsUpIpV6() { + Env::$db_is_ipv6 = true; + + Env::$db_host = '::1'; + $connection_factory = new ConnectionFactory(); + $connection = $connection_factory->createConnection(); + expect($connection->getHost())->equals('[::1]'); + + Env::$db_host = 'b57e:9b70:ab96:6a0b:5ba2:49e3:ebba:a036'; + $connection_factory = new ConnectionFactory(); + $connection = $connection_factory->createConnection(); + expect($connection->getHost())->equals('[b57e:9b70:ab96:6a0b:5ba2:49e3:ebba:a036]'); + + // try to actually connect to the DB over IPv6 + Env::$db_host = '::ffff:' . gethostbyname($this->env_backup['db_host']); + $connection_factory = new ConnectionFactory(); + $connection = $connection_factory->createConnection(); + expect($connection->getWrappedConnection())->isInstanceOf(PDO::class); + expect($connection->executeQuery('SELECT 1')->fetchColumn())->same('1'); + } + function testItSetsDriverOptions() { $connection_factory = new ConnectionFactory(); $connection = $connection_factory->createConnection(); @@ -71,4 +114,12 @@ class ConnectionFactoryTest extends \MailPoetTest { $current = $connection->executeQuery('SELECT @@session.wait_timeout')->fetchColumn(); expect($current)->equals(999999); } + + function _after() { + parent::_after(); + Env::$db_host = $this->env_backup['db_host']; + Env::$db_port = $this->env_backup['db_port']; + Env::$db_is_ipv6 = $this->env_backup['db_is_ipv6']; + Env::$db_socket = $this->env_backup['db_socket']; + } }