Completed
Pull Request — master (#1070)
by
unknown
01:29
created

ConnectionFactory::createConnection()   B

Complexity

Conditions 7
Paths 12

Size

Total Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 30
rs 8.5066
c 0
b 0
f 0
cc 7
nc 12
nop 4
1
<?php
2
3
namespace Doctrine\Bundle\DoctrineBundle;
4
5
use Doctrine\Common\EventManager;
6
use Doctrine\DBAL\Configuration;
7
use Doctrine\DBAL\Connection;
8
use Doctrine\DBAL\DBALException;
9
use Doctrine\DBAL\Driver\AbstractMySQLDriver;
10
use Doctrine\DBAL\DriverManager;
11
use Doctrine\DBAL\Exception\DriverException;
12
use Doctrine\DBAL\Platforms\AbstractPlatform;
13
use Doctrine\DBAL\Types\Type;
14
15
class ConnectionFactory
16
{
17
    /** @var mixed[][] */
18
    private $typesConfig = [];
19
20
    /** @var bool */
21
    private $initialized = false;
22
23
    /**
24
     * @param mixed[][] $typesConfig
25
     */
26
    public function __construct(array $typesConfig)
27
    {
28
        $this->typesConfig = $typesConfig;
29
    }
30
31
    /**
32
     * Create a connection by name.
33
     *
34
     * @param mixed[]         $params
35
     * @param string[]|Type[] $mappingTypes
36
     *
37
     * @return Connection
38
     */
39
    public function createConnection(array $params, Configuration $config = null, EventManager $eventManager = null, array $mappingTypes = [])
40
    {
41
        if (! $this->initialized) {
42
            $this->initializeTypes();
43
        }
44
45
        $connection = DriverManager::getConnection($params, $config, $eventManager);
46
47
        if (!isset($params['pdo']) && !isset($params['charset'])) {
48
            $params = $connection->getParams();
49
            $params['charset'] = 'utf8';
50
51
            if ($connection instanceof AbstractMySQLDriver) {
52
                $params['charset'] = 'utf8mb4';
53
                $params['defaultTableOptions']['collate'] = $params['defaultTableOptions']['collate'] ?? 'utf8mb4_unicode_ci';
54
            }
55
56
            $connectionClass = \get_class($connection);
57
            $connection = new $connectionClass($params, $connection->getDriver(), $connection->getConfiguration(), $connection->getEventManager());
58
        }
59
60
        if (! empty($mappingTypes)) {
61
            $platform = $this->getDatabasePlatform($connection);
62
            foreach ($mappingTypes as $dbType => $doctrineType) {
63
                $platform->registerDoctrineTypeMapping($dbType, $doctrineType);
0 ignored issues
show
Bug introduced by
It seems like $doctrineType defined by $doctrineType on line 62 can also be of type object<Doctrine\DBAL\Types\Type>; however, Doctrine\DBAL\Platforms\...erDoctrineTypeMapping() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
64
            }
65
        }
66
67
        return $connection;
68
    }
69
70
    /**
71
     * Try to get the database platform.
72
     *
73
     * This could fail if types should be registered to an predefined/unused connection
74
     * and the platform version is unknown.
75
     * For details have a look at DoctrineBundle issue #673.
76
     *
77
     * @return AbstractPlatform
78
     *
79
     * @throws DBALException
80
     */
81
    private function getDatabasePlatform(Connection $connection)
82
    {
83
        try {
84
            return $connection->getDatabasePlatform();
85
        } catch (DriverException $driverException) {
86
            throw new DBALException(
87
                'An exception occured while establishing a connection to figure out your platform version.' . PHP_EOL .
88
                "You can circumvent this by setting a 'server_version' configuration value" . PHP_EOL . PHP_EOL .
89
                'For further information have a look at:' . PHP_EOL .
90
                'https://github.com/doctrine/DoctrineBundle/issues/673',
91
                0,
92
                $driverException
93
            );
94
        }
95
    }
96
97
    /**
98
     * initialize the types
99
     */
100
    private function initializeTypes()
101
    {
102
        foreach ($this->typesConfig as $typeName => $typeConfig) {
103
            if (Type::hasType($typeName)) {
104
                Type::overrideType($typeName, $typeConfig['class']);
105
            } else {
106
                Type::addType($typeName, $typeConfig['class']);
107
            }
108
        }
109
110
        $this->initialized = true;
111
    }
112
}
113