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
|
9 |
|
public function __construct($id = null, $instances = null) |
61
|
|
|
{ |
62
|
9 |
|
if (strlen($id)) { |
63
|
1 |
|
$this->id = $id; |
64
|
1 |
|
} |
65
|
9 |
|
if (strlen($instances)) { |
66
|
1 |
|
$this->instances = $instances; |
67
|
1 |
|
} |
68
|
9 |
|
} |
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
|
5 |
|
private function buildUri($connection) |
93
|
|
|
{ |
94
|
5 |
|
return 'mongodb://' . $this->buildConnectionString($connection); |
|
|
|
|
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
/** |
98
|
|
|
* @param \Pimple\Container $app |
99
|
|
|
* @param string $name |
100
|
|
|
* |
101
|
|
|
* @return string |
102
|
|
|
*/ |
103
|
9 |
|
private function getArg(Container $app, $name) |
104
|
|
|
{ |
105
|
9 |
|
return isset($this->args[$name]) ? $this->args[$name] : $this->getDefaultArg($app, $name); |
106
|
|
|
} |
107
|
|
|
|
108
|
5 |
|
private function getArgConnectionAuthority(array $connection) |
109
|
|
|
{ |
110
|
5 |
|
if (empty($connection['user'])) { |
111
|
2 |
|
return $this->getArgConnectionHost($connection); |
112
|
|
|
} |
113
|
|
|
|
114
|
3 |
|
return $connection['user'] . ':' . rawurlencode($connection['pwd']) . '@' . |
115
|
3 |
|
$this->getArgConnectionHost($connection); |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
/** |
119
|
|
|
* @return string |
120
|
|
|
*/ |
121
|
5 |
|
private function getArgConnectionHost(array $connection = array()) |
122
|
|
|
{ |
123
|
5 |
|
if (!empty($connection['hosts'])) { |
124
|
1 |
|
return $this->getArgConnectionHosts($connection); |
125
|
|
|
} |
126
|
|
|
|
127
|
5 |
|
if (empty($connection['host'])) { |
128
|
4 |
|
$connection['host'] = '127.0.0.1'; |
129
|
4 |
|
} |
130
|
|
|
|
131
|
5 |
|
return empty($connection['port']) ? $connection['host'] : $connection['host'] . ':' . $connection['port']; |
132
|
|
|
} |
133
|
|
|
|
134
|
1 |
|
private function getArgConnectionHosts(array $connection) |
135
|
|
|
{ |
136
|
|
|
return implode(',', array_map(function ($hosts) { |
137
|
1 |
|
return $this->getArgConnectionHost(is_array($hosts) ? $hosts : array('host' => $hosts)); |
138
|
1 |
|
}, $connection['hosts'])); |
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
/** |
142
|
|
|
* @return string |
143
|
|
|
*/ |
144
|
9 |
|
private function getArgUri() |
145
|
|
|
{ |
146
|
9 |
|
if (!empty($this->args['uri'])) { |
147
|
2 |
|
return $this->args['uri']; |
148
|
|
|
} |
149
|
7 |
|
if (!empty($this->args['connection'])) { |
150
|
5 |
|
return $this->args['connection']; |
151
|
|
|
} |
152
|
2 |
|
} |
153
|
|
|
|
154
|
|
|
/** |
155
|
|
|
* @param \Pimple\Container $app |
156
|
|
|
* @param string $name |
157
|
|
|
* |
158
|
|
|
* @return string|array |
159
|
|
|
*/ |
160
|
8 |
|
private function getDefaultArg(Container $app, $name) |
161
|
|
|
{ |
162
|
8 |
|
if (!isset($this->defaultArgs[$name])) { |
163
|
8 |
|
$this->defaultArgs[$name] = empty($app['mongodb.' . $name]) ? |
164
|
8 |
|
array('uri_options' => array(), 'driver_options' => array())[$name] : |
165
|
1 |
|
$app['mongodb.' . $name]; |
166
|
8 |
|
} |
167
|
|
|
|
168
|
8 |
|
return $this->defaultArgs[$name]; |
169
|
|
|
} |
170
|
|
|
|
171
|
9 |
|
private function loadParameters(Container $app) |
172
|
|
|
{ |
173
|
9 |
|
if ($this->isLoaded) { |
174
|
9 |
|
return; |
175
|
|
|
} |
176
|
|
|
|
177
|
9 |
|
$this->isLoaded = true; |
178
|
|
|
|
179
|
9 |
|
if (empty($app['mongodb.uri']) || !is_array($app['mongodb.uri'])) { |
180
|
8 |
|
$this->loadSingletonParameters($app); |
181
|
8 |
|
} else { |
182
|
1 |
|
$this->parameters = $app['mongodb.uri']; |
183
|
1 |
|
$this->defaultConnection = array_keys($this->parameters)[0]; |
184
|
|
|
} |
185
|
9 |
|
} |
186
|
|
|
|
187
|
8 |
|
private function loadSingletonParameters(Container $app) |
188
|
|
|
{ |
189
|
8 |
|
$this->parameters[0] = array(); |
190
|
|
|
|
191
|
8 |
|
if (!empty($app['mongodb.uri'])) { |
192
|
2 |
|
$this->parameters[0]['uri'] = $app['mongodb.uri']; |
193
|
8 |
|
} elseif (!empty($app['mongodb.connection'])) { |
194
|
4 |
|
$this->parameters[0]['connection'] = $app['mongodb.connection']; |
195
|
4 |
|
} |
196
|
|
|
|
197
|
8 |
|
if (!empty($app['mongodb.uri_options'])) { |
198
|
1 |
|
$this->parameters[0]['uri_options'] = $app['mongodb.uri_options']; |
199
|
1 |
|
} |
200
|
8 |
|
if (!empty($app['mongodb.driver_options'])) { |
201
|
1 |
|
$this->parameters[0]['driver_options'] = $app['mongodb.driver_options']; |
202
|
1 |
|
} |
203
|
8 |
|
} |
204
|
|
|
|
205
|
9 |
|
public function register(Container $app) |
206
|
|
|
{ |
207
|
|
|
$app[$this->id] = function () use ($app) { |
208
|
9 |
|
$this->loadParameters($app); |
209
|
|
|
|
210
|
9 |
|
return $app[$this->instances][$this->defaultConnection]; |
211
|
|
|
}; |
212
|
|
|
$app[$this->instances] = function () use ($app) { |
213
|
9 |
|
$this->loadParameters($app); |
214
|
|
|
|
215
|
9 |
|
$instances = new Container(); |
216
|
9 |
|
foreach ($this->parameters as $client => $this->args) { |
217
|
|
|
$instances[$client] = function () use ($app) { |
218
|
9 |
|
return $app['mongodb.client']( |
219
|
9 |
|
$this->getArgUri(), |
220
|
9 |
|
$this->getArg($app, 'uri_options'), |
221
|
9 |
|
$this->getArg($app, 'driver_options') |
222
|
9 |
|
); |
223
|
|
|
}; |
224
|
9 |
|
} |
225
|
|
|
|
226
|
9 |
|
return $instances; |
227
|
|
|
}; |
228
|
|
|
|
229
|
9 |
|
$app['mongodb.client'] = $app->protect( |
230
|
9 |
|
function ($uri = null, array $uriOptions = array(), array $driverOptions = array()) { |
231
|
9 |
|
return new MongoDB\Client(is_array($uri) ? $this->buildUri($uri) : $uri, $uriOptions, $driverOptions); |
232
|
|
|
} |
233
|
9 |
|
); |
234
|
9 |
|
} |
235
|
|
|
} |
236
|
|
|
|
This check looks at variables that have been passed in as parameters and are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.