Completed
Push — master ( 31e04a...fdefa9 )
by Jonathan-Paul
10:23
created

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