Test Failed
Push — master ( b65407...45c3a3 )
by Jonathan-Paul
01:45
created

MongoDbServiceProvider::buildAuthority()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 3
nop 1
dl 0
loc 14
rs 9.4285
c 0
b 0
f 0
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
    public function __construct($id = null, $instances = null)
64
    {
65
        if (strlen($id)) {
66
            $this->id = $id;
67
        }
68
        if (strlen($instances)) {
69
            $this->instances = $instances;
70
        }
71
    }
72
73
    private function buildAuthority(array $connection)
74
    {
75
        $authority = '';
76
77
        if (!empty($connection['password'])) {
78
            $authority .= $connection['username'] . ':' .$connection['password'] . '@';
79
        } elseif (!empty($connection['username'])) {
80
            $authority .= $connection['username'] . '@';
81
        }
82
83
        $authority .= $this->buildHost($connection);
84
85
        return $authority;
86
    }
87
88
    /**
89
     * @return string
90
     */
91
    private function buildConnectionString(array $connection)
92
    {
93
        $uri = '//';
94
95
        if (isset($connection[0]) && count($connection) == 1) {
96
            $uri .= $this->sanitizeUri($connection[0]);
97
        } else {
98
            $uri .= $this->buildAuthority($connection);
99
100
            if (!empty($connection['database'])) {
101
                $uri .= '/' . $connection['database'];
102
103
                if (!empty($connection['options'])) {
104
                    $uri .= '?' . http_build_query($connection['options']);
105
                }
106
            } elseif (!empty($connection['options'])) {
107
                $uri .= '/?' . http_build_query($connection['options']);
108
            }
109
        }
110
111
        return $uri;
112
    }
113
114
    private function buildHost(array $components)
115
    {
116
        $hosts = array();
117
118
        if (isset($components['hosts'])) {
119
            $hosts[] = $this->buildHost($components['hosts']);
120
        } else {
121
            $hosts[] = empty($components['host']) ? '127.0.0.1' : $components['host'];
122
        }
123
        
124
        foreach ($components as $component) {
125
            if (is_array($component)) {
126
                $hosts = empty($component['host']) ? '127.0.0.1' : $component['host'];
127
128
                if (!empty($component['port'])) {
129
                    $hosts .= ':' . $component['port'];
130
                }
131
            } else {
132
                $hosts[] = $component;
133
            }
134
        }
135
136
        return implode(',', $hosts);
137
    }
138
139
    /**
140
     * @return string
141
     */
142
    private function buildUri(array $connection)
143
    {
144
        return 'mongodb:' . $this->buildConnectionString($connection);
145
    }
146
147
    /**
148
     * @param \Pimple\Container $app
149
     * @param string            $name
150
     *
151
     * @return string
152
     */
153
    private function getArg(Container $app, $name)
154
    {
155
        return isset($this->args[$name]) ? $this->args[$name] : $this->getDefaultArg($app, $name);
156
    }
157
158
    /**
159
     * @return string
160
     */
161
    private function getArgUri(Container $app)
162
    {
163
        if (!empty($this->args['uri'])) {
164
            return $this->args['uri'];
165
        }
166
167
        return $this->buildUri(
168
            !is_array($this->args['connection']) ? array($this->args['connection']) : $this->args['connection']
169
        );
170
    }
171
172
    /**
173
     * @param \Pimple\Container $app
174
     * @param string            $name
175
     *
176
     * @return string|array
177
     */
178
    private function getDefaultArg(Container $app, $name)
179
    {
180
        if (!isset($this->defaultArgs[$name])) {
181
            $this->setDefaultArg($app, $name);
182
        }
183
184
        return $this->defaultArgs[$name];
185
    }
186
187
    private function loadParameters(Container $app)
188
    {
189
        if ($this->isLoaded) {
190
            return;
191
        }
192
193
        $this->isLoaded = true;
194
195
        if (empty($app['mongodb.uri']) || !is_array($app['mongodb.uri'])) {
196
            $this->loadSingletonParameters($app);
197
        } else {
198
            $this->parameters = $app['mongodb.uri'];
199
            $this->defaultConnection = array_keys($this->parameters)[0];
200
        }
201
    }
202
203
    private function loadSingletonParameters(Container $app)
204
    {
205
        $this->parameters[0] = array();
206
207
        if (!empty($app['mongodb.uri'])) {
208
            $this->parameters[0]['uri'] = $app['mongodb.uri'];
209
        } elseif (!empty($app['mongodb.connection'])) {
210
            $this->parameters[0]['connection'] = $app['pdo.connection'];
211
        }
212
213
        if (!empty($app['mongodb.uri_options'])) {
214
            $this->parameters[0]['uri_options'] = $app['mongodb.uri_options'];
215
        }
216
        if (!empty($app['mongodb.driver_options'])) {
217
            $this->parameters[0]['driver_options'] = $app['mongodb.driver_options'];
218
        }
219
    }
220
221
    /**
222
     * @param string $uri
223
     *
224
     * @return string
225
     */
226
    private function sanitizeUri($uri)
227
    {
228
        if ('mongodb:' == substr($uri, 0, 8)) {
229
            $uri = substr($uri, 8);
230
        }
231
232
        return ('//' == substr($uri, 0, 2)) ? substr($uri, 2) : $uri;
233
    }
234
235
    /**
236
     * @param \Pimple\Container $app
237
     * @param string            $name
238
     */
239
    private function setDefaultArg(Container $app, $name)
240
    {
241
        $this->defaultArgs[$name] = empty($app['mongodb.' . $name]) ?
242
            array('uri_options' => array(), 'driver_options' => array())[$name] :
243
            $app['mongodb.' . $name];
244
    }
245
246
    public function register(Container $app)
247
    {
248
        $app[$this->id] = function () use ($app) {
249
            $this->loadParameters($app);
250
251
            return $app[$this->instances][$this->defaultConnection];
252
        };
253
        $app[$this->instances] = function () use ($app) {
254
            $this->loadParameters($app);
255
256
            $instances = new Container();
257
            foreach ($this->parameters as $client => $this->args) {
258
                $instances[$client] = function () use ($app) {
259
                    return $app['mongodb.client'](
260
                        $this->getArgUri($app),
261
                        $this->getArg($app, 'uri_options'),
262
                        $this->getArg($app, 'driver_options')
263
                    );
264
                };
265
            }
266
267
            return $instances;
268
        };
269
270
        $app['mongodb.client'] = $app->protect(
271
            function ($uri = null, array $uriOptions = array(), array $driverOptions = array()) use ($app) {
272
                if (null === $uri) {
273
                    $uri = array();
274
                }
275
276
                return new MongoDB\Client(is_array($uri) ? $this->buildUri($uri) : $uri, $uriOptions, $driverOptions);
277
            }
278
        );
279
    }
280
}
281