Completed
Push — master ( b3027b...6d4b98 )
by Jonathan-Paul
02:20
created

MongoDbServiceProvider::__construct()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 8
cts 8
cp 1
rs 9.6666
c 0
b 0
f 0
cc 3
eloc 5
nc 4
nop 2
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['hosts'])) {
134
            return implode(',', array_map(function ($hosts) {
135 1
                return $this->getArgConnectionHost(is_array($hosts) ? $hosts : array('host' => $hosts));
136 1
            }, $connection['hosts']));
137
        }
138
139 5
        if (empty($connection['host'])) {
140 4
            $connection['host'] = '127.0.0.1';
141 4
        }
142
143 5
        return empty($connection['port']) ? $connection['host'] : $connection['host'] . ':' . $connection['port'];
144
    }
145
146
    /**
147
     * @return string
148
     */
149 11
    private function getArgUri()
150
    {
151 11
        if (!empty($this->args['uri'])) {
152 5
            return $this->args['uri'];
153 6
        } elseif (!empty($this->args['connection'])) {
154 5
            return $this->args['connection'];
155
        }
156 1
    }
157
158
    /**
159
     * @param \Pimple\Container $app
160
     * @param string            $name
161
     *
162
     * @return string|array
163
     */
164 11
    private function getDefaultArg(Container $app, $name)
165
    {
166 11
        if (!isset($this->defaultArgs[$name])) {
167
            $this->setDefaultArg($app, $name);
168
        }
169
170 11
        return $this->defaultArgs[$name];
171
    }
172
173 11
    private function loadParameters(Container $app)
174
    {
175 11
        if ($this->isLoaded) {
176 11
            return;
177
        }
178
179 11
        $this->isLoaded = true;
180
181 11
        if (empty($app['mongodb.uri']) || !is_array($app['mongodb.uri'])) {
182 10
            $this->loadSingletonParameters($app);
183 10
        } else {
184 1
            $this->parameters = $app['mongodb.uri'];
185 1
            $this->defaultConnection = array_keys($this->parameters)[0];
186
        }
187 11
    }
188
189 10
    private function loadSingletonParameters(Container $app)
190
    {
191 10
        $this->parameters[0] = array();
192
193 10
        if (!empty($app['mongodb.uri'])) {
194 5
            $this->parameters[0]['uri'] = $app['mongodb.uri'];
195 10
        } elseif (!empty($app['mongodb.connection'])) {
196 4
            $this->parameters[0]['connection'] = $app['mongodb.connection'];
197 4
        }
198
199 10
        if (!empty($app['mongodb.uri_options'])) {
200
            $this->parameters[0]['uri_options'] = $app['mongodb.uri_options'];
201
        }
202 10
        if (!empty($app['mongodb.driver_options'])) {
203
            $this->parameters[0]['driver_options'] = $app['mongodb.driver_options'];
204
        }
205 10
    }
206
207
    /**
208
     * @param string $uri
209
     *
210
     * @return string
211
     */
212 5
    private function sanitizeUri($uri)
213
    {
214 5
        if ('mongodb:' == substr($uri, 0, 8)) {
215 2
            $uri = substr($uri, 8);
216 2
        }
217
218 5
        return ('//' == substr($uri, 0, 2)) ? substr($uri, 2) : $uri;
219
    }
220
221
    /**
222
     * @param \Pimple\Container $app
223
     * @param string            $name
224
     */
225
    private function setDefaultArg(Container $app, $name)
226
    {
227
        $this->defaultArgs[$name] = empty($app['mongodb.' . $name]) ?
228
            array('uri_options' => array(), 'driver_options' => array())[$name] :
229
            $app['mongodb.' . $name];
230
    }
231
232 11
    public function register(Container $app)
233
    {
234
        $app[$this->id] = function () use ($app) {
235 11
            $this->loadParameters($app);
236
237 11
            return $app[$this->instances][$this->defaultConnection];
238
        };
239
        $app[$this->instances] = function () use ($app) {
240 11
            $this->loadParameters($app);
241
242 11
            $instances = new Container();
243 11
            foreach ($this->parameters as $client => $this->args) {
244
                $instances[$client] = function () use ($app) {
245 11
                    return $app['mongodb.client'](
246 11
                        $this->getArgUri(),
247 11
                        $this->getArg($app, 'uri_options'),
248 11
                        $this->getArg($app, 'driver_options')
249 11
                    );
250
                };
251 11
            }
252
253 11
            return $instances;
254
        };
255
256 11
        $app['mongodb.client'] = $app->protect(
257 11
            function ($uri = null, array $uriOptions = array(), array $driverOptions = array()) {
258 11
                return new MongoDB\Client($this->buildUri($uri), $uriOptions, $driverOptions);
259
            }
260 11
        );
261 11
    }
262
}
263