Passed
Push — master ( 6d4b98...f525a3 )
by Jonathan-Paul
02:12
created

MongoDbServiceProvider::loadParameters()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 15
ccs 10
cts 10
cp 1
rs 9.2
c 0
b 0
f 0
cc 4
eloc 9
nc 3
nop 1
crap 4
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
31
    /**
32
     * @var int|string
33
     */
34
    private $defaultConnection = 0;
35
36
    /**
37
     * @var string
38
     */
39
    private $id = 'mongodb';
40
41
    /**
42
     * @var string
43
     */
44
    private $instances = 'mongodb.clients';
45
46
    /**
47
     * @var bool
48
     */
49
    private $isLoaded = false;
50
51
    /**
52
     * @var array
53
     */
54
    private $parameters = array();
55
56
    /**
57
     * @param string $id
58
     * @param string $instances
59
     */
60 11
    public function __construct($id = null, $instances = null)
61
    {
62 11
        if (strlen($id)) {
63 1
            $this->id = $id;
64 1
        }
65 11
        if (strlen($instances)) {
66 1
            $this->instances = $instances;
67 1
        }
68 11
    }
69
70
    /**
71
     * @return string
72
     */
73 5
    private function buildConnectionString(array $connection)
74
    {
75 5
        $uri = $this->getArgConnectionAuthority($connection) . '/';
76
77 5
        if (!empty($connection['db'])) {
78 3
            $uri .= $connection['db'];
79 3
        }
80 5
        if (!empty($connection['options'])) {
81 1
            $uri .= '?' . http_build_query($connection['options']);
82 1
        }
83
84 5
        return rtrim($uri, '/');
85
    }
86
87
    /**
88
     * @param array|string $connection
89
     *
90
     * @return string
91
     */
92 11
    private function buildUri($connection)
93
    {
94 11
        if (!empty($connection)) {
95
            return 'mongodb://' . (
96 10
                is_array($connection) ? $this->buildConnectionString($connection) : $this->sanitizeUri($connection)
97 10
            );
98
        }
99 1
    }
100
101
    /**
102
     * @param \Pimple\Container $app
103
     * @param string            $name
104
     *
105
     * @return string
106
     */
107 11
    private function getArg(Container $app, $name)
108
    {
109 11
        return isset($this->args[$name]) ? $this->args[$name] : $this->getDefaultArg($app, $name);
110
    }
111
112 5
    private function getArgConnectionAuthority(array $connection)
113
    {
114 5
        $authority = '';
115
116 5
        if (!empty($connection['user'])) {
117 3
            $authority .= $connection['user'] . ':' . rawurlencode($connection['pwd']) . '@';
118 3
        }
119
120 5
        $authority .= $this->getArgConnectionHost($connection);
121
122 5
        return $authority;
123
    }
124
125
    /**
126
     * @return string
127
     */
128 5
    private function getArgConnectionHost(array $connection = array())
129
    {
130 5
        if (!empty($connection['hosts'])) {
131 1
            return $this->getArgConnectionHosts($connection);
132
        }
133
134 5
        if (empty($connection['host'])) {
135 4
            $connection['host'] = '127.0.0.1';
136 4
        }
137
138 5
        return empty($connection['port']) ? $connection['host'] : $connection['host'] . ':' . $connection['port'];
139
    }
140
141 1
    private function getArgConnectionHosts(array $connection)
142
    {
143
        return implode(',', array_map(function ($hosts) {
144 1
            return $this->getArgConnectionHost(is_array($hosts) ? $hosts : array('host' => $hosts));
145 1
        }, $connection['hosts']));
146
    }
147
148
    /**
149
     * @return string
150
     */
151 11
    private function getArgUri()
152
    {
153 11
        if (!empty($this->args['uri'])) {
154 5
            return $this->args['uri'];
155 6
        } elseif (!empty($this->args['connection'])) {
156 5
            return $this->args['connection'];
157
        }
158 1
    }
159
160
    /**
161
     * @param \Pimple\Container $app
162
     * @param string            $name
163
     *
164
     * @return string|array
165
     */
166 11
    private function getDefaultArg(Container $app, $name)
167
    {
168 11
        if (!isset($this->defaultArgs[$name])) {
169 11
            $this->setDefaultArg($app, $name);
170 11
        }
171
172 11
        return $this->defaultArgs[$name];
173
    }
174
175 11
    private function loadParameters(Container $app)
176
    {
177 11
        if ($this->isLoaded) {
178 11
            return;
179
        }
180
181 11
        $this->isLoaded = true;
182
183 11
        if (empty($app['mongodb.uri']) || !is_array($app['mongodb.uri'])) {
184 10
            $this->loadSingletonParameters($app);
185 10
        } else {
186 1
            $this->parameters = $app['mongodb.uri'];
187 1
            $this->defaultConnection = array_keys($this->parameters)[0];
188
        }
189 11
    }
190
191 10
    private function loadSingletonParameters(Container $app)
192
    {
193 10
        $this->parameters[0] = array();
194
195 10
        if (!empty($app['mongodb.uri'])) {
196 5
            $this->parameters[0]['uri'] = $app['mongodb.uri'];
197 10
        } elseif (!empty($app['mongodb.connection'])) {
198 4
            $this->parameters[0]['connection'] = $app['mongodb.connection'];
199 4
        }
200
201 10
        if (!empty($app['mongodb.uri_options'])) {
202
            $this->parameters[0]['uri_options'] = $app['mongodb.uri_options'];
203
        }
204 10
        if (!empty($app['mongodb.driver_options'])) {
205
            $this->parameters[0]['driver_options'] = $app['mongodb.driver_options'];
206
        }
207 10
    }
208
209
    /**
210
     * @param string $uri
211
     *
212
     * @return string
213
     */
214 5
    private function sanitizeUri($uri)
215
    {
216 5
        if ('mongodb:' == substr($uri, 0, 8)) {
217 2
            $uri = substr($uri, 8);
218 2
        }
219
220 5
        return ('//' == substr($uri, 0, 2)) ? substr($uri, 2) : $uri;
221
    }
222
223
    /**
224
     * @param \Pimple\Container $app
225
     * @param string            $name
226
     */
227 11
    private function setDefaultArg(Container $app, $name)
228
    {
229 11
        $this->defaultArgs[$name] = empty($app['mongodb.' . $name]) ?
230 11
            array('uri_options' => array(), 'driver_options' => array())[$name] :
231 1
            $app['mongodb.' . $name];
232 11
    }
233
234 11
    public function register(Container $app)
235
    {
236
        $app[$this->id] = function () use ($app) {
237 11
            $this->loadParameters($app);
238
239 11
            return $app[$this->instances][$this->defaultConnection];
240
        };
241
        $app[$this->instances] = function () use ($app) {
242 11
            $this->loadParameters($app);
243
244 11
            $instances = new Container();
245 11
            foreach ($this->parameters as $client => $this->args) {
246
                $instances[$client] = function () use ($app) {
247 11
                    return $app['mongodb.client'](
248 11
                        $this->getArgUri(),
249 11
                        $this->getArg($app, 'uri_options'),
250 11
                        $this->getArg($app, 'driver_options')
251 11
                    );
252
                };
253 11
            }
254
255 11
            return $instances;
256
        };
257
258 11
        $app['mongodb.client'] = $app->protect(
259 11
            function ($uri = null, array $uriOptions = array(), array $driverOptions = array()) {
260 11
                return new MongoDB\Client($this->buildUri($uri), $uriOptions, $driverOptions);
261
            }
262 11
        );
263 11
    }
264
}
265