Completed
Push — master ( cf8c5e...b3027b )
by Jonathan-Paul
03:55
created

MongoDbServiceProvider::getArgConnectionHost()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

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