MongoDbServiceProvider::__construct()   A
last analyzed

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