Completed
Pull Request — master (#83)
by Ruud
04:59
created

AbstractUri::toString()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * League.Uri (http://uri.thephpleague.com)
4
 *
5
 * @package   League.uri
6
 * @author    Ignace Nyamagana Butera <[email protected]>
7
 * @copyright 2013-2015 Ignace Nyamagana Butera
8
 * @license   https://github.com/thephpleague/uri/blob/master/LICENSE (MIT License)
9
 * @version   4.2.0
10
 * @link      https://github.com/thephpleague/uri/
11
 */
12
namespace League\Uri\Schemes\Generic;
13
14
use InvalidArgumentException;
15
use League\Uri\Interfaces\Fragment;
16
use League\Uri\Interfaces\Host;
17
use League\Uri\Interfaces\Path;
18
use League\Uri\Interfaces\Port;
19
use League\Uri\Interfaces\Query;
20
use League\Uri\Interfaces\Scheme;
21
use League\Uri\Interfaces\UserInfo;
22
use League\Uri\Types\ImmutablePropertyTrait;
23
24
/**
25
 * common URI Object properties and methods
26
 *
27
 * @package League.uri
28
 * @author  Ignace Nyamagana Butera <[email protected]>
29
 * @since   4.0.0
30
 */
31
abstract class AbstractUri
32
{
33
    use ImmutablePropertyTrait;
34
35
    use UriBuilderTrait;
36
37
    /**
38
     * Scheme Component
39
     *
40
     * @var Scheme
41
     */
42
    protected $scheme;
43
44
    /**
45
     * User Information Part
46
     *
47
     * @var UserInfo
48
     */
49
    protected $userInfo;
50
51
    /**
52
     * Host Component
53
     *
54
     * @var Host
55
     */
56
    protected $host;
57
58
    /**
59
     * Port Component
60
     *
61
     * @var Port
62
     */
63
    protected $port;
64
65
    /**
66
     * Path Component
67
     *
68
     * @var Path
69
     */
70
    protected $path;
71
72
    /**
73
     * Query Component
74
     *
75
     * @var Query
76
     */
77
    protected $query;
78
79
    /**
80
     * Fragment Component
81
     *
82
     * @var Fragment
83
     */
84
    protected $fragment;
85
86
    /**
87
     * Supported Schemes
88
     *
89
     * @var array
90
     */
91
    protected static $supportedSchemes = [];
92
93
    /**
94
     * @inheritdoc
95
     */
96 779
    public function getScheme()
97
    {
98 779
        return $this->scheme->__toString();
99
    }
100
101
    /**
102
     * @inheritdoc
103
     */
104 180
    public function getUserInfo()
105
    {
106 180
        return $this->userInfo->__toString();
107
    }
108
109
    /**
110
     * @inheritdoc
111
     */
112 731
    public function getHost()
113
    {
114 731
        return $this->host->__toString();
115
    }
116
117
    /**
118
     * @inheritdoc
119
     */
120 189
    public function getPort()
121
    {
122 189
        return $this->hasStandardPort() ? null : $this->port->getContent();
123
    }
124
125
    /**
126
     * Returns whether the standard port for the given scheme is used, when
127
     * the scheme is unknown or unsupported will the method return false
128
     *
129
     * @return bool
130
     */
131 794
    protected function hasStandardPort()
132
    {
133 794
        $port = $this->port->getContent();
134 794
        if (null === $port) {
135 660
            return true;
136
        }
137
138 170
        $scheme = $this->scheme->__toString();
139 170
        if ('' === $scheme) {
140 15
            return false;
141
        }
142
143 161
        return isset(static::$supportedSchemes[$scheme])
144 161
            && static::$supportedSchemes[$scheme] === $port;
145
    }
146
147
    /**
148
     * @inheritdoc
149
     */
150 402
    public function getPath()
151
    {
152 402
        return $this->path->__toString();
153
    }
154
155
    /**
156
     * @inheritdoc
157
     */
158 270
    public function getQuery()
159
    {
160 270
        return $this->query->__toString();
161
    }
162
163
    /**
164
     * @inheritdoc
165
     */
166 66
    public function getFragment()
167
    {
168 66
        return $this->fragment->__toString();
169
    }
170
171
    /**
172
     * @inheritdoc
173
     */
174 255
    public function withScheme($scheme)
175
    {
176 255
        return $this->withProperty('scheme', $this->filterPropertyValue($scheme));
177
    }
178
179
    /**
180
     * @inheritdoc
181
     */
182 243
    public function withUserInfo($user, $password = null)
183
    {
184 243
        if (null === $password) {
185 237
            $password = '';
186 158
        }
187
188 243
        $userInfo = $this->userInfo
189 243
            ->withUser($this->filterPropertyValue($user))
190 243
            ->withPass($password);
191
192 243
        if ($this->userInfo->getUser() === $userInfo->getUser()
193 243
            && $this->userInfo->getPass() === $userInfo->getPass()
194 162
        ) {
195 234
            return $this;
196
        }
197
198 9
        $clone = clone $this;
199 9
        $clone->userInfo = $userInfo;
200
201 9
        return $clone;
202
    }
203
204
    /**
205
     * @inheritdoc
206
     */
207 363
    public function withHost($host)
208
    {
209 363
        return $this->withProperty('host', $this->filterPropertyValue($host));
210
    }
211
212
    /**
213
     * @inheritdoc
214
     */
215 243
    public function withPort($port)
216
    {
217 243
        return $this->withProperty('port', $port);
218
    }
219
220
    /**
221
     * @inheritdoc
222
     */
223 372
    public function withPath($path)
224
    {
225 372
        return $this->withProperty('path', $path);
226
    }
227
228
    /**
229
     * @inheritdoc
230
     */
231 243
    public function withQuery($query)
232
    {
233 243
        return $this->withProperty('query', $this->filterPropertyValue($query));
234
    }
235
236
    /**
237
     * @inheritdoc
238
     */
239 48
    public function withFragment($fragment)
240
    {
241 48
        return $this->withProperty('fragment', $this->filterPropertyValue($fragment));
242
    }
243
244
    /**
245
     * @inheritdoc
246
     */
247 2
    public function __debugInfo()
248
    {
249 2
        return ['uri' => $this->__toString()];
250
    }
251
252
    /**
253
     * @inheritdoc
254
     */
255 488
    public function __toString()
256
    {
257 488
        return $this->scheme->getUriComponent().$this->getSchemeSpecificPart();
258
    }
259
260
    /**
261
     * @inheritdoc
262
     */
263
    public function toString()
264
    {
265
        return $this->__toString();
266
    }
267
268
    /**
269
     * Retrieve the scheme specific part of the URI.
270
     *
271
     * If no specific part information is present, this method MUST return an empty
272
     * string.
273
     *
274
     * @return string
275
     */
276 770
    protected function getSchemeSpecificPart()
277
    {
278 770
        $authority = $this->getAuthority();
279
280 770
        $res = array_filter([
281 770
            $this->userInfo->getContent(),
282 770
            $this->host->getContent(),
283 770
            $this->port->getContent(),
284 770
        ], function ($value) {
285 770
            return null !== $value;
286 770
        });
287
288 770
        if (!empty($res)) {
289 647
            $authority = '//'.$authority;
290 431
        }
291
292
        return $authority
293 770
            .$this->path->getUriComponent()
294 770
            .$this->query->getUriComponent()
295 770
            .$this->fragment->getUriComponent();
296
    }
297
298
    /**
299
     * @inheritdoc
300
     */
301 794
    public function getAuthority()
302
    {
303 794
        $port = '';
304 794
        if (!$this->hasStandardPort()) {
305 158
            $port = $this->port->getUriComponent();
306 105
        }
307
308 794
        return $this->userInfo->getUriComponent()
309 794
            .$this->host->getUriComponent()
310 794
            .$port;
311
    }
312
313
    /**
314
     * Assert if the current URI object is valid
315
     *
316
     * @throws InvalidArgumentException for transformations that would result in an object in invalid state.
317
     */
318 779
    protected function assertValidObject()
319
    {
320 779
        if (!$this->isValid()) {
321 24
            throw new InvalidArgumentException(sprintf(
322 24
                'The URI components will produce a `%s` instance in invalid state',
323 16
                get_class($this)
324 16
            ));
325
        }
326 740
    }
327
328
    /**
329
     * Tell whether the current URI is valid.
330
     *
331
     * The URI object validity depends on the scheme. This method
332
     * MUST be implemented on every URI object
333
     *
334
     * @return bool
335
     */
336
    abstract protected function isValid();
337
338
    /**
339
     *  Tell whether any generic URI is valid
340
     *
341
     * @return bool
342
     */
343 770
    protected function isValidGenericUri()
344
    {
345 770
        $path = $this->path->getUriComponent();
346 770
        if ('' !== $this->getAuthority()) {
347 635
            return '' === $path || strpos($path, '/') === 0;
348
        }
349
350 381
        if (0 === strpos($path, '//')) {
351 3
            return false;
352
        }
353
354 381
        if ('' !== $this->scheme->getUriComponent() || false === ($pos = strpos($path, ':'))) {
355 372
            return true;
356
        }
357
358 12
        return false !== strpos(substr($path, 0, $pos), '/');
359
    }
360
361
    /**
362
     * Assert whether the current scheme is supported by the URI object
363
     *
364
     * @throws InvalidArgumentException If the Scheme is not supported
365
     */
366 638
    protected function assertSupportedScheme()
367
    {
368 638
        if (!array_key_exists($this->scheme->__toString(), static::$supportedSchemes)) {
369 21
            throw new InvalidArgumentException(sprintf(
370 21
                'The submitted scheme is unsupported by `%s`',
371 14
                get_class($this)
372 14
            ));
373
        }
374 620
    }
375
}
376