diff --git a/src/Factory/DbServiceFactory.php b/src/Factory/DbServiceFactory.php index 94aec47d..b9888e21 100644 --- a/src/Factory/DbServiceFactory.php +++ b/src/Factory/DbServiceFactory.php @@ -201,7 +201,7 @@ private function getAdapterClass(string $phptype): string */ private function buildConnectionConfig(array $sqlConfig): array { - return [ + $config = [ 'username' => $sqlConfig['username'] ?? '', 'password' => $sqlConfig['password'] ?? '', 'database' => $sqlConfig['database'] ?? $sqlConfig['dbname'] ?? '', @@ -209,5 +209,17 @@ private function buildConnectionConfig(array $sqlConfig): array 'port' => $sqlConfig['port'] ?? 3306, 'charset' => $sqlConfig['charset'] ?? 'UTF-8', ]; + + // Preserve Unix-socket connection settings when the config asks + // for them; without this the adapter falls back to the TCP + // host/port defaults above and breaks socket deployments. + if (isset($sqlConfig['protocol'])) { + $config['protocol'] = $sqlConfig['protocol']; + } + if (isset($sqlConfig['socket'])) { + $config['socket'] = $sqlConfig['socket']; + } + + return $config; } } diff --git a/test/Unit/Factory/DbServiceFactoryTest.php b/test/Unit/Factory/DbServiceFactoryTest.php new file mode 100644 index 00000000..ead2ac7d --- /dev/null +++ b/test/Unit/Factory/DbServiceFactoryTest.php @@ -0,0 +1,84 @@ + + * @category Horde + * @package Core + * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 + */ + +namespace Horde\Core\Test\Unit\Factory; + +use Horde\Core\Factory\DbServiceFactory; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\TestCase; +use ReflectionClass; + +#[CoversClass(DbServiceFactory::class)] +final class DbServiceFactoryTest extends TestCase +{ + public function testBuildConnectionConfigPreservesUnixProtocol(): void + { + $config = $this->buildConnectionConfig([ + 'username' => 'horde', + 'password' => 'secret', + 'protocol' => 'unix', + 'socket' => '/var/run/postgresql/.s.PGSQL.5432', + 'database' => 'horde', + 'phptype' => 'pgsql', + ]); + + // The unix-socket keys reach the adapter untouched. + self::assertSame('unix', $config['protocol']); + self::assertSame('/var/run/postgresql/.s.PGSQL.5432', $config['socket']); + self::assertSame('horde', $config['database']); + } + + public function testBuildConnectionConfigRenamesHostspecToHost(): void + { + $config = $this->buildConnectionConfig([ + 'username' => 'horde', + 'password' => 'secret', + 'hostspec' => 'db.example.test', + 'port' => 5433, + 'database' => 'horde', + 'phptype' => 'pgsql', + ]); + + self::assertSame('db.example.test', $config['host']); + self::assertArrayNotHasKey('hostspec', $config); + self::assertSame(5433, $config['port']); + } + + public function testBuildConnectionConfigDefaultsCharset(): void + { + $config = $this->buildConnectionConfig([ + 'username' => 'horde', + 'password' => 'secret', + 'database' => 'horde', + 'phptype' => 'mysqli', + ]); + + self::assertSame('UTF-8', $config['charset']); + } + + /** + * @param array $sqlConfig + * @return array + */ + private function buildConnectionConfig(array $sqlConfig): array + { + $factory = new DbServiceFactory(); + $method = (new ReflectionClass($factory))->getMethod('buildConnectionConfig'); + $method->setAccessible(true); + + return $method->invoke($factory, $sqlConfig); + } +}