Test Failed
Push — master ( de213d...3f2a8b )
by Jonathan-Paul
06:06
created

MongoDbServiceProvider::__construct()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 8
cts 8
cp 1
rs 9.6666
c 0
b 0
f 0
cc 3
eloc 5
nc 4
nop 2
crap 3
1
<?php
2
/**
3
 * MongoDB service provider for the Silex micro-framework.
4
 *
5
 * @see http://php.net/manual/set.mongodb.php
6
 */
7
8
namespace LiquidBox\Silex\Provider;
9
10
use MongoDB;
11
use Pimple\Container;
12
use Pimple\ServiceProviderInterface;
13
14
/**
15
 * MongoDb Provider.
16
 *
17
 * @author Jonathan-Paul Marois <[email protected]>
18
 */
19
class MongoDbServiceProvider implements ServiceProviderInterface
20
{
21
    /**
22
     * @var array Buffer.
23
     */
24
    private $args = array();
25
26
    /**
27
     * @var array
28
     */
29
    private $defaultArgs = array(
30
        'uri_options' => array(),
31
        'driver_options' => array(),
32
    );
33
34
    /**
35
     * @var int|string
36
     */
37
    private $defaultConnection = 0;
38
39
    /**
40
     * @var string
41
     */
42
    private $id = 'mongodb';
43
44
    /**
45
     * @var string
46
     */
47
    private $instances = 'mongodb.clients';
48
49
    /**
50
     * @var bool
51
     */
52
    private $isLoaded = false;
53
54
    /**
55
     * @var array
56
     */
57
    private $parameters = array();
58
59
    /**
60
     * @param string $id
61
     * @param string $instances
62
     */
63 5
    public function __construct($id = null, $instances = null)
64
    {
65 5
        if (strlen($id)) {
66 1
            $this->id = $id;
67 1
        }
68 5
        if (strlen($instances)) {
69 1
            $this->instances = $instances;
70 1
        }
71 5
    }
72
73
    /**
74
     * @return string
75
     */
76 5
    private function buildConnectionString(array $connection)
77
    {
78 5
        if (isset($connection[0]) && count($connection) == 1) {
79 1
            return '//' . $this->sanitizeUri($connection[0]);
80
        }
81
82 4
        $uri = '//' . $this->getArgConnectionAuthority($connection);
83
84 4
        if (!empty($connection['db'])) {
85
            $uri .= '/' . $connection['db'];
86
87
            if (!empty($connection['options'])) {
88
                $uri .= '?' . http_build_query($connection['options']);
89
            }
90 4
        } elseif (!empty($connection['options'])) {
91 1
            $uri .= '/?' . http_build_query($connection['options']);
92 1
        }
93
94 4
        return $uri;
95
    }
96
97
    /**
98
     * @param array|string $connection
99
     *
100
     * @return string
101
     */
102 5
    private function buildUri($connection)
103
    {
104 5
        var_export('mongodb:' . $this->buildConnectionString(is_array($connection) ? $connection : array($connection)));
105 5
        return 'mongodb:' . $this->buildConnectionString(is_array($connection) ? $connection : array($connection));
106
    }
107
108
    /**
109
     * @param \Pimple\Container $app
110
     * @param string            $name
111
     *
112
     * @return string
113
     */
114 5
    private function getArg(Container $app, $name)
115
    {
116 5
        return isset($this->args[$name]) ? $this->args[$name] : $this->getDefaultArg($app, $name);
117
    }
118
119 4
    private function getArgConnectionAuthority(array $connection)
120
    {
121 4
        $authority = '';
122
123 4
        if (!empty($connection['pwd'])) {
124 1
            $authority .= $connection['user'] . ':' . rawurlencode($connection['pwd']) . '@';
125 4
        } elseif (!empty($connection['user'])) {
126
            $authority .= $connection['user'] . '@';
127
        }
128
129 4
        $authority .= $this->getArgConnectionHost($connection);
130
131 4
        return $authority;
132
    }
133
134
    /**
135
     * @return string
136
     */
137 4
    private function getArgConnectionHost(array $connection = array())
138
    {
139 4
        if (empty($connection['host'])) {
140 4
            $connection['host'] = '127.0.0.1';
141 4
        }
142
143 4
        return empty($connection['port']) ? $connection['host'] : $connection['host'] . ':' . $connection['port'];
144
    }
145
146
    private function getArgConnectionHosts(array $connection)
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
147
    {
148
        if (empty($connection['hosts'])) {
149
            return getArgConnectionHost($connection);
150
        }
151
152
        return implode(',', array_map(function ($connection) {
153
            return is_array($connection) ? getArgConnectionHost($connection) : $host;
0 ignored issues
show
Bug introduced by
The variable $host does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
154
        }, $connection['hosts']));
155
    }
156
157
    /**
158
     * @return string
159
     */
160 5
    private function getArgUri()
161
    {
162 5
        if (!empty($this->args['uri'])) {
163 1
            return $this->args['uri'];
164 4
        } elseif (!empty($this->args['connection'])) {
165 2
            return $this->args['connection'];
166
        }
167 2
    }
168
169
    /**
170
     * @param \Pimple\Container $app
171
     * @param string            $name
172
     *
173
     * @return string|array
174
     */
175 5
    private function getDefaultArg(Container $app, $name)
176
    {
177 5
        if (!isset($this->defaultArgs[$name])) {
178
            $this->setDefaultArg($app, $name);
179
        }
180
181 5
        return $this->defaultArgs[$name];
182
    }
183
184 5
    private function loadParameters(Container $app)
185
    {
186 5
        if ($this->isLoaded) {
187 5
            return;
188
        }
189
190 5
        $this->isLoaded = true;
191
192 5
        if (empty($app['mongodb.uri']) || !is_array($app['mongodb.uri'])) {
193 4
            $this->loadSingletonParameters($app);
194 4
        } else {
195 1
            $this->parameters = $app['mongodb.uri'];
196 1
            $this->defaultConnection = array_keys($this->parameters)[0];
197
        }
198 5
    }
199
200 4
    private function loadSingletonParameters(Container $app)
201
    {
202 4
        $this->parameters[0] = array();
203
204 4
        if (!empty($app['mongodb.uri'])) {
205 1
            $this->parameters[0]['uri'] = $app['mongodb.uri'];
206 4
        } elseif (!empty($app['mongodb.connection'])) {
207 1
            $this->parameters[0]['connection'] = $app['mongodb.connection'];
208 1
        }
209
210 4
        if (!empty($app['mongodb.uri_options'])) {
211
            $this->parameters[0]['uri_options'] = $app['mongodb.uri_options'];
212
        }
213 4
        if (!empty($app['mongodb.driver_options'])) {
214
            $this->parameters[0]['driver_options'] = $app['mongodb.driver_options'];
215
        }
216 4
    }
217
218
    /**
219
     * @param string $uri
220
     *
221
     * @return string
222
     */
223 1
    private function sanitizeUri($uri)
224
    {
225 1
        if ('mongodb:' == substr($uri, 0, 8)) {
226 1
            $uri = substr($uri, 8);
227 1
        }
228
229 1
        return ('//' == substr($uri, 0, 2)) ? substr($uri, 2) : $uri;
230
    }
231
232
    /**
233
     * @param \Pimple\Container $app
234
     * @param string            $name
235
     */
236
    private function setDefaultArg(Container $app, $name)
237
    {
238
        $this->defaultArgs[$name] = empty($app['mongodb.' . $name]) ?
239
            array('uri_options' => array(), 'driver_options' => array())[$name] :
240
            $app['mongodb.' . $name];
241
    }
242
243 5
    public function register(Container $app)
244
    {
245
        $app[$this->id] = function () use ($app) {
246 5
            $this->loadParameters($app);
247
248 5
            return $app[$this->instances][$this->defaultConnection];
249
        };
250
        $app[$this->instances] = function () use ($app) {
251 5
            $this->loadParameters($app);
252
253 5
            $instances = new Container();
254 5
            foreach ($this->parameters as $client => $this->args) {
255
                $instances[$client] = function () use ($app) {
256 5
                    return $app['mongodb.client'](
257 5
                        $this->getArgUri(),
258 5
                        $this->getArg($app, 'uri_options'),
259 5
                        $this->getArg($app, 'driver_options')
260 5
                    );
261
                };
262 5
            }
263
264 5
            return $instances;
265
        };
266
267 5
        $app['mongodb.client'] = $app->protect(
268 5
            function ($uri = null, array $uriOptions = array(), array $driverOptions = array()) {
269 5
                return new MongoDB\Client($this->buildUri($uri), $uriOptions, $driverOptions);
270
            }
271 5
        );
272 5
    }
273
}
274