Test Failed
Push — master ( e7146b...0b973c )
by Jonathan-Paul
05:32
created

MongoDbServiceProvider::getArgUri()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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