Issues (21)

src/Services/ClientRegistry.php (3 issues)

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Facile\MongoDbBundle\Services;
6
7
use Facile\MongoDbBundle\Capsule\Client as BundleClient;
8
use Facile\MongoDbBundle\Event\ConnectionEvent;
9
use Facile\MongoDbBundle\Models\ClientConfiguration;
10
use Facile\MongoDbBundle\Services\DriverOptions\DriverOptionsInterface;
11
use MongoDB\Client;
12
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
13
use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy;
14
15
/**
16
 * Class ClientRegistry.
17
 *
18
 * @internal
19
 */
20
final class ClientRegistry
21
{
22
    /** @var Client[] */
23
    private $clients;
24
25
    /** @var ClientConfiguration[] */
26
    private $configurations;
27
28
    /** @var bool */
29
    private $debug;
30
31
    /** @var EventDispatcherInterface */
32
    private $eventDispatcher;
33
34
    /** @var DriverOptionsInterface */
35
    private $driverOptionsService;
36
37
    public function __construct(
38 31
        EventDispatcherInterface $eventDispatcher,
39
        bool $debug,
40 31
        ?DriverOptionsInterface $driverOptionsService
41 31
    ) {
42 31
        $this->clients = [];
43 31
        $this->configurations = [];
44 31
        $this->debug = $debug;
45
        $this->eventDispatcher = $eventDispatcher;
46
        $this->driverOptionsService = $driverOptionsService;
47
    }
48
49 31
    public function addClientsConfigurations(array $configurations): void
50
    {
51 31
        foreach ($configurations as $name => $conf) {
52 31
            $this->configurations[$name] = $this->buildClientConfiguration($conf);
53
        }
54 31
    }
55
56
    /**
57
     * @param array $conf
58
     *
59
     * @return ClientConfiguration
60 31
     */
61
    private function buildClientConfiguration(array $conf): ClientConfiguration
62 31
    {
63 31
        if (! $conf['uri']) {
64
            $conf['uri'] = self::buildConnectionUri($conf['hosts']);
65
        }
66
67
        $conf['driverOptions'] = [];
68
        if ($this->driverOptionsService instanceof DriverOptionsInterface) {
0 ignored issues
show
$this->driverOptionsService is always a sub-type of Facile\MongoDbBundle\Ser...\DriverOptionsInterface.
Loading history...
69
            $conf['driverOptions'] = $this->driverOptionsService->buildDriverOptions($conf);
70 31
        }
71
72 31
        return new ClientConfiguration(
73 30
            $conf['uri'],
74
            $conf['username'],
75
            $conf['password'],
76 31
            $conf['authSource'],
77 31
            [
78 31
                'replicaSet' => $conf['replicaSet'],
79 31
                'ssl' => $conf['ssl'],
80 31
                'connectTimeoutMS' => $conf['connectTimeoutMS'],
81
                'readPreference' => $conf['readPreference'],
82 31
            ],
83 31
            $conf['driverOptions']
84 31
        );
85 31
    }
86
87
    private static function buildConnectionUri(array $hosts): string
88
    {
89
        return 'mongodb://' . implode(
90
            ',',
91
            array_map(
92
                static function (array $host): string {
93
                    return sprintf('%s:%d', $host['host'], $host['port']);
94
                },
95 30
                $hosts
96
            )
97 30
        );
98 30
    }
99 30
100 30
    public function getClientForDatabase(string $name, string $databaseName): Client
101 30
    {
102 30
        return $this->getClient($name, $databaseName);
103 30
    }
104
105
    public function getClientNames(): array
106
    {
107
        return array_keys($this->clients);
108
    }
109
110
    public function getClient(string $name, ?string $databaseName = null): Client
111
    {
112
        $clientKey = null !== $databaseName ? $name . '.' . $databaseName : $name;
113
114 11
        if (! isset($this->clients[$clientKey])) {
115
            $conf = $this->configurations[$name];
116 11
            $options = array_merge(
117
                ['database' => $databaseName],
118
                $conf->getAuthSource() !== null ? ['authSource' => $conf->getAuthSource()] : [],
119
                $conf->getOptions()
120
            );
121
            $this->clients[$clientKey] = $this->buildClient($name, $conf->getUri(), $options, $conf->getDriverOptions());
122 2
123
            $event = new ConnectionEvent($clientKey);
124 2
            if (class_exists(LegacyEventDispatcherProxy::class)) {
125
                $this->eventDispatcher->dispatch($event, ConnectionEvent::CLIENT_CREATED);
0 ignored issues
show
The call to Symfony\Contracts\EventD...erInterface::dispatch() has too many arguments starting with Facile\MongoDbBundle\Eve...onEvent::CLIENT_CREATED. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

125
                $this->eventDispatcher->/** @scrutinizer ignore-call */ 
126
                                        dispatch($event, ConnectionEvent::CLIENT_CREATED);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
126
            } else {
127
                $this->eventDispatcher->dispatch(ConnectionEvent::CLIENT_CREATED, $event);
0 ignored issues
show
Facile\MongoDbBundle\Eve...onEvent::CLIENT_CREATED of type string is incompatible with the type object expected by parameter $event of Symfony\Contracts\EventD...erInterface::dispatch(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

127
                $this->eventDispatcher->dispatch(/** @scrutinizer ignore-type */ ConnectionEvent::CLIENT_CREATED, $event);
Loading history...
128
            }
129
        }
130
131
        return $this->clients[$clientKey];
132
    }
133 29
134
    /**
135 29
     * @param string $clientName
136
     * @param string $uri
137 29
     * @param array  $options
138 29
     * @param array  $driverOptions
139 29
     *
140
     * @return Client
141 29
     */
142 29
    private function buildClient(string $clientName, string $uri, array $options, array $driverOptions): Client
143
    {
144 29
        if (true === $this->debug) {
145
            return new BundleClient($uri, $options, $driverOptions, $clientName, $this->eventDispatcher);
146 29
        }
147
148 29
        return new Client($uri, $options, $driverOptions);
149 29
    }
150
}
151