Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
76.36% covered (warning)
76.36%
42 / 55
25.00% covered (danger)
25.00%
1 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
connection_factory
76.36% covered (warning)
76.36%
42 / 55
25.00% covered (danger)
25.00%
1 / 4
16.59
0.00% covered (danger)
0.00%
0 / 1
 get_connection
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
1
 get_connection_from_params
84.21% covered (warning)
84.21%
16 / 19
0.00% covered (danger)
0.00%
0 / 1
4.06
 to_doctrine_driver
57.14% covered (warning)
57.14%
12 / 21
0.00% covered (danger)
0.00%
0 / 1
13.04
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 *
4 * This file is part of the phpBB Forum Software package.
5 *
6 * @copyright (c) phpBB Limited <https://www.phpbb.com>
7 * @license GNU General Public License, version 2 (GPL-2.0)
8 *
9 * For full copyright and license information, please see
10 * the docs/CREDITS.txt file.
11 *
12 */
13
14namespace phpbb\db\doctrine;
15
16use Doctrine\DBAL\Connection;
17use Doctrine\DBAL\DriverManager;
18use Doctrine\DBAL\Exception;
19use Doctrine\DBAL\Types\Type;
20use InvalidArgumentException;
21use phpbb\config_php_file;
22use phpbb\exception\runtime_exception;
23
24/**
25 * Doctrine DBAL connection factory.
26 */
27class connection_factory
28{
29    /**
30     * Creates a Doctrine DBAL connection from phpBB configuration.
31     *
32     * @param config_php_file $config Config PHP file wrapper.
33     *
34     * @return Connection Doctrine DBAL connection.
35     *
36     * @throws runtime_exception        If the database connection could not be established.
37     * @throws InvalidArgumentException    If the provided driver name is not a valid phpBB database driver.
38     */
39    public static function get_connection(config_php_file $config): Connection
40    {
41        $driver = $config->get('dbms');
42        $host = $config->get('dbhost');
43        $user = $config->get('dbuser');
44        $pass = $config->get('dbpasswd');
45        $name = $config->get('dbname');
46        $port = $config->get('dbport');
47
48        return self::get_connection_from_params(
49            $driver,
50            $host,
51            $user,
52            $pass,
53            $name,
54            $port
55        );
56    }
57
58    /**
59     * Creates a database connection from the specified parameters.
60     *
61     * @param string      $driver   Driver name.
62     * @param string      $host     Hostname.
63     * @param string|null $user     Username.
64     * @param string|null $password Password.
65     * @param string|null $name     Database name.
66     * @param string|null $port     Database port.
67     *
68     * @return Connection Doctrine DBAL connection.
69     *
70     * @throws runtime_exception        If the database connection could not be established.
71     * @throws InvalidArgumentException    If $driver is not a valid phpBB database driver.
72     */
73    public static function get_connection_from_params(
74        string $driver,
75        string $host,
76        ?string $user = null,
77        ?string $password = null,
78        ?string $name = null,
79        ?string $port = null): Connection
80    {
81        $available_drivers = DriverManager::getAvailableDrivers();
82        if (!in_array($driver, $available_drivers))
83        {
84            $driver = config_php_file::convert_30_dbms_to_31($driver);
85            $driver = self::to_doctrine_driver($driver);
86        }
87
88        $params = connection_parameter_factory::get_configuration(
89            $driver,
90            $host,
91            $user,
92            $password,
93            $name,
94            $port
95        );
96
97        try
98        {
99            $connection = DriverManager::getConnection($params);
100            if (!Type::hasType(case_insensitive_string::CASE_INSENSITIVE_STRING))
101            {
102                Type::addType(case_insensitive_string::CASE_INSENSITIVE_STRING, case_insensitive_string::class);
103            }
104            $connection->getDatabasePlatform()->registerDoctrineTypeMapping('varchar_ci', case_insensitive_string::CASE_INSENSITIVE_STRING);
105            return $connection;
106        }
107        catch (Exception $e)
108        {
109            throw new runtime_exception('DB_CONNECTION_FAILED', [], $e);
110        }
111    }
112
113    /**
114     * Converts phpBB driver names to Doctrine's equivalent.
115     *
116     * @param string $driver_name phpBB database driver name.
117     *
118     * @return string Doctrine DBAL's driver name.
119     *
120     * @throws InvalidArgumentException If $driver_name is not a valid phpBB database driver.
121     */
122    private static function to_doctrine_driver(string $driver_name): string
123    {
124        // Normalize driver name.
125        $name = str_replace('phpbb\db\driver', '', $driver_name);
126        $name = preg_replace('/mysql$/i', 'mysqli', $name);
127        $name = trim($name, '\\');
128
129        switch ($name)
130        {
131            case 'mssql_odbc':
132            case 'mssqlnative':
133                $name = 'pdo_sqlsrv';
134            break;
135
136            case 'mysqli':
137                $name = 'pdo_mysql';
138            break;
139
140            case 'oracle':
141                $name = 'oci8';
142            break;
143
144            case 'postgres':
145                $name = 'pdo_pgsql';
146            break;
147
148            case 'sqlite3':
149                $name = 'pdo_sqlite';
150            break;
151
152            default:
153                throw new InvalidArgumentException('Invalid phpBB database driver provided: ' . $driver_name);
154        }
155
156        return $name;
157    }
158
159    /*
160     * Disable constructor.
161     */
162    private function __construct()
163    {
164    }
165}