1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* This file is part of phpDocumentor. |
4
|
|
|
* |
5
|
|
|
* For the full copyright and license information, please view the LICENSE |
6
|
|
|
* file that was distributed with this source code. |
7
|
|
|
* |
8
|
|
|
* @copyright 2010-2015 Mike van Riel<[email protected]> |
9
|
|
|
* @license http://www.opensource.org/licenses/mit-license.php MIT |
10
|
|
|
* @link http://phpdoc.org |
11
|
|
|
*/ |
12
|
|
|
|
13
|
|
|
namespace phpDocumentor\DomainModel; |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* Value Object for DSN. |
17
|
|
|
*/ |
18
|
|
|
final class Dsn |
19
|
|
|
{ |
20
|
|
|
/** @var string */ |
21
|
|
|
private $dsn; |
22
|
|
|
|
23
|
|
|
/** @var string */ |
24
|
|
|
private $scheme; |
25
|
|
|
|
26
|
|
|
/** @var string */ |
27
|
|
|
private $host; |
28
|
|
|
|
29
|
|
|
/** @var int */ |
30
|
|
|
private $port; |
31
|
|
|
|
32
|
|
|
/** @var string */ |
33
|
|
|
private $user; |
34
|
|
|
|
35
|
|
|
/** @var string */ |
36
|
|
|
private $password; |
37
|
|
|
|
38
|
|
|
/** @var string */ |
39
|
|
|
private $path; |
40
|
|
|
|
41
|
|
|
/** @var string[] */ |
42
|
|
|
private $query = []; |
43
|
|
|
|
44
|
|
|
/** @var string[] */ |
45
|
|
|
private $parameters = []; |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* Initializes the Dsn |
49
|
|
|
* |
50
|
|
|
* @param string $dsn |
51
|
|
|
*/ |
52
|
|
|
public function __construct($dsn) |
53
|
|
|
{ |
54
|
|
|
$this->parse($dsn); |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
/** |
58
|
|
|
* Returns a string representation of the DSN. |
59
|
|
|
* |
60
|
|
|
* @return string |
61
|
|
|
*/ |
62
|
|
|
public function __toString() |
63
|
|
|
{ |
64
|
|
|
return $this->dsn; |
65
|
|
|
} |
66
|
|
|
|
67
|
|
|
/** |
68
|
|
|
* Returns the scheme part of the DSN |
69
|
|
|
* |
70
|
|
|
* @return string |
71
|
|
|
*/ |
72
|
|
|
public function getScheme() |
73
|
|
|
{ |
74
|
|
|
return $this->scheme; |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* Returns the host part of the DSN |
79
|
|
|
* |
80
|
|
|
* @return string |
81
|
|
|
*/ |
82
|
|
|
public function getHost() |
83
|
|
|
{ |
84
|
|
|
return $this->host; |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
/** |
88
|
|
|
* Returns the port part of the DSN |
89
|
|
|
* |
90
|
|
|
* @return int |
91
|
|
|
*/ |
92
|
|
|
public function getPort() |
93
|
|
|
{ |
94
|
|
|
return $this->port; |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
/** |
98
|
|
|
* Returns the username part of the DSN |
99
|
|
|
* |
100
|
|
|
* @return string |
101
|
|
|
*/ |
102
|
|
|
public function getUsername() |
103
|
|
|
{ |
104
|
|
|
return $this->user; |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
/** |
108
|
|
|
* Returns the password part of the DSN |
109
|
|
|
* |
110
|
|
|
* @return string |
111
|
|
|
*/ |
112
|
|
|
public function getPassword() |
113
|
|
|
{ |
114
|
|
|
return $this->password; |
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
/** |
118
|
|
|
* Returns the path part of the DSN |
119
|
|
|
* |
120
|
|
|
* @return string |
121
|
|
|
*/ |
122
|
|
|
public function getPath() |
123
|
|
|
{ |
124
|
|
|
return new Path($this->path); |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
/** |
128
|
|
|
* Returns the query part of the DSN |
129
|
|
|
* |
130
|
|
|
* @return string[] |
131
|
|
|
*/ |
132
|
|
|
public function getQuery() |
133
|
|
|
{ |
134
|
|
|
return $this->query; |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
/** |
138
|
|
|
* Returns the parameters part of the DSN |
139
|
|
|
* |
140
|
|
|
* @return string[] |
141
|
|
|
*/ |
142
|
|
|
public function getParameters() |
143
|
|
|
{ |
144
|
|
|
return $this->parameters; |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
/** |
148
|
|
|
* Parses the given DSN |
149
|
|
|
* |
150
|
|
|
* @param string $dsn |
151
|
|
|
* @return void |
152
|
|
|
*/ |
153
|
|
|
private function parse($dsn) |
|
|
|
|
154
|
|
|
{ |
155
|
|
|
if (! is_string($dsn)) { |
156
|
|
|
throw new \InvalidArgumentException( |
157
|
|
|
sprintf('"%s" is not a valid DSN.', var_export($dsn, true)) |
158
|
|
|
); |
159
|
|
|
} |
160
|
|
|
|
161
|
|
|
$dsnParts = explode(';', $dsn); |
162
|
|
|
$location = $dsnParts[0]; |
163
|
|
|
unset($dsnParts[0]); |
164
|
|
|
$locationParts = parse_url($location); |
165
|
|
|
|
166
|
|
|
if (! isset($locationParts['scheme'])) { |
167
|
|
|
$locationParts['scheme'] = 'file'; |
168
|
|
|
$location = 'file://' . $location; |
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
if (! filter_var($location, FILTER_VALIDATE_URL)) { |
172
|
|
|
throw new \InvalidArgumentException( |
173
|
|
|
sprintf('"%s" is not a valid DSN.', $dsn) |
174
|
|
|
); |
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
$this->parseDsn($location, $dsnParts); |
178
|
|
|
|
179
|
|
|
$this->parseScheme($locationParts); |
|
|
|
|
180
|
|
|
|
181
|
|
|
$this->parseHostAndPath($locationParts); |
|
|
|
|
182
|
|
|
|
183
|
|
|
$this->parsePort($locationParts); |
|
|
|
|
184
|
|
|
|
185
|
|
|
$this->user = isset($locationParts['user']) ? $locationParts['user'] : ""; |
186
|
|
|
|
187
|
|
|
$this->password = isset($locationParts['pass']) ? $locationParts['pass'] : ""; |
188
|
|
|
|
189
|
|
|
$this->parseQuery($locationParts); |
|
|
|
|
190
|
|
|
|
191
|
|
|
$this->parseParameters($dsnParts); |
192
|
|
|
} |
193
|
|
|
|
194
|
|
|
/** |
195
|
|
|
* Reconstructs the original DSN but |
196
|
|
|
* when scheme was omitted in the original DSN, it will now be file:// |
197
|
|
|
* |
198
|
|
|
* @param string $location |
199
|
|
|
* @param string[] $dsnParts |
200
|
|
|
* @return void |
201
|
|
|
*/ |
202
|
|
|
private function parseDsn($location, array $dsnParts) |
203
|
|
|
{ |
204
|
|
|
array_splice($dsnParts, 0, 0, $location); |
205
|
|
|
$this->dsn = implode(";", $dsnParts); |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
/** |
209
|
|
|
* validates and sets the scheme property |
210
|
|
|
* |
211
|
|
|
* @param string[] $locationParts |
212
|
|
|
* @return void |
213
|
|
|
*/ |
214
|
|
|
private function parseScheme(array $locationParts) |
215
|
|
|
{ |
216
|
|
|
$validSchemes = ['file', 'git+http', 'git+https']; |
217
|
|
|
if (! in_array(strtolower($locationParts['scheme']), $validSchemes)) { |
218
|
|
|
throw new \InvalidArgumentException( |
219
|
|
|
sprintf('"%s" is not a valid scheme.', $locationParts['scheme']) |
220
|
|
|
); |
221
|
|
|
} |
222
|
|
|
$this->scheme = strtolower($locationParts['scheme']); |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
/** |
226
|
|
|
* Validates and sets the host and path properties |
227
|
|
|
* |
228
|
|
|
* @param string[] $locationParts |
229
|
|
|
* @return void |
230
|
|
|
*/ |
231
|
|
|
private function parseHostAndPath(array $locationParts) |
232
|
|
|
{ |
233
|
|
|
$path = isset($locationParts['path']) ? $locationParts['path'] : ""; |
234
|
|
|
$host = isset($locationParts['host']) ? $locationParts['host'] : ""; |
235
|
|
|
|
236
|
|
|
if ($this->getScheme() === 'file') { |
237
|
|
|
$this->path = $host . $path; |
238
|
|
|
} else { |
239
|
|
|
$this->host = $host; |
240
|
|
|
$this->path = $path; |
241
|
|
|
} |
242
|
|
|
} |
243
|
|
|
|
244
|
|
|
/** |
245
|
|
|
* Validates and sets the port property |
246
|
|
|
* |
247
|
|
|
* @param string[] $locationParts |
248
|
|
|
* @return void |
249
|
|
|
*/ |
250
|
|
|
private function parsePort(array $locationParts) |
251
|
|
|
{ |
252
|
|
|
if (! isset($locationParts['port'])) { |
253
|
|
|
if ($this->getScheme() === 'git+http') { |
254
|
|
|
$this->port = 80; |
255
|
|
|
} elseif ($this->getScheme() === 'git+https') { |
256
|
|
|
$this->port = 443; |
257
|
|
|
} else { |
258
|
|
|
$this->port = 0; |
259
|
|
|
} |
260
|
|
|
} else { |
261
|
|
|
$this->port = $locationParts['port']; |
|
|
|
|
262
|
|
|
} |
263
|
|
|
} |
264
|
|
|
|
265
|
|
|
/** |
266
|
|
|
* validates and sets the query property |
267
|
|
|
* |
268
|
|
|
* @param string[] $locationParts |
269
|
|
|
* @return void |
270
|
|
|
*/ |
271
|
|
|
private function parseQuery(array $locationParts) |
272
|
|
|
{ |
273
|
|
|
if (isset($locationParts['query'])) { |
274
|
|
|
$queryParts = explode('&', $locationParts['query']); |
275
|
|
|
foreach ($queryParts as $part) { |
276
|
|
|
$option = $this->splitKeyValuePair($part); |
277
|
|
|
|
278
|
|
|
$this->query[$option[0]] = $option[1]; |
279
|
|
|
} |
280
|
|
|
} |
281
|
|
|
} |
282
|
|
|
|
283
|
|
|
/** |
284
|
|
|
* validates and sets the parameters property |
285
|
|
|
* |
286
|
|
|
* @param string[] $dsnParts |
287
|
|
|
* @return void |
288
|
|
|
*/ |
289
|
|
|
private function parseParameters(array $dsnParts) |
290
|
|
|
{ |
291
|
|
|
foreach ($dsnParts as $part) { |
292
|
|
|
$option = $this->splitKeyValuePair($part); |
293
|
|
|
|
294
|
|
|
$this->parameters[$option[0]] = $option[1]; |
295
|
|
|
} |
296
|
|
|
} |
297
|
|
|
|
298
|
|
|
/** |
299
|
|
|
* Splits a key-value pair |
300
|
|
|
* |
301
|
|
|
* @param string $pair |
302
|
|
|
* @return string[] $option |
303
|
|
|
*/ |
304
|
|
|
private function splitKeyValuePair($pair) |
305
|
|
|
{ |
306
|
|
|
$option = explode('=', $pair); |
307
|
|
|
if (count($option) !== 2) { |
308
|
|
|
throw new \InvalidArgumentException( |
309
|
|
|
sprintf('"%s" is not a valid query or parameter.', $pair) |
310
|
|
|
); |
311
|
|
|
} |
312
|
|
|
|
313
|
|
|
return $option; |
314
|
|
|
} |
315
|
|
|
} |
316
|
|
|
|
A high number of execution paths generally suggests many nested conditional statements and make the code less readible. This can usually be fixed by splitting the method into several smaller methods.
You can also find more information in the “Code” section of your repository.