Completed
Push — master ( f525a3...1d202f )
by Jonathan-Paul
02:15
created

MongoDbServiceProvider::getArg()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

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