Completed
Pull Request — master (#127)
by ignace nyamagana
02:19
created

UriInfo::normalize()   B

Complexity

Conditions 10
Paths 32

Size

Total Lines 34
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 22
CRAP Score 10

Importance

Changes 0
Metric Value
cc 10
eloc 22
nc 32
nop 1
dl 0
loc 34
ccs 22
cts 22
cp 1
crap 10
rs 7.6666
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * League.Uri (https://uri.thephpleague.com)
5
 *
6
 * (c) Ignace Nyamagana Butera <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace League\Uri;
15
16
use League\Uri\Contract\UriInterface;
17
use Psr\Http\Message\UriInterface as Psr7UriInterface;
18
use TypeError;
19
use function explode;
20
use function implode;
21
use function preg_replace_callback;
22
use function rawurldecode;
23
use function sprintf;
24
25
final class UriInfo
26
{
27
    private const REGEXP_ENCODED_CHARS = ',%(2[D|E]|3[0-9]|4[1-9|A-F]|5[0-9|A|F]|6[1-9|A-F]|7[0-9|E]),i';
28
29
    /**
30
     * @codeCoverageIgnore
31
     */
32
    private function __construct()
33
    {
34
    }
35
36
    /**
37
     * Filter the URI object.
38
     *
39
     * To be valid an URI MUST implement at least one of the following interface:
40
     *     - League\Uri\UriInterface
41
     *     - Psr\Http\Message\UriInterface
42
     *
43
     * @param mixed $uri the URI to validate
44
     *
45
     * @throws TypeError if the URI object does not implements the supported interfaces.
46
     *
47
     * @return Psr7UriInterface|UriInterface
48
     */
49 138
    private static function filterUri($uri)
50
    {
51 138
        if ($uri instanceof Psr7UriInterface || $uri instanceof UriInterface) {
52 128
            return $uri;
53
        }
54
55 12
        throw new TypeError(sprintf('The uri must be a valid URI object received `%s`', is_object($uri) ? get_class($uri) : gettype($uri)));
56
    }
57
58
    /**
59
     * Normalize an URI for comparison.
60
     *
61
     * @param Psr7UriInterface|UriInterface $uri
62
     *
63
     * @return Psr7UriInterface|UriInterface
64
     */
65 24
    private static function normalize($uri)
66
    {
67 24
        $uri = self::filterUri($uri);
68 22
        $null = $uri instanceof Psr7UriInterface ? '' : null;
69
70 22
        $path = $uri->getPath();
71 22
        if ('/' === ($path[0] ?? '') || '' !== $uri->getScheme().$uri->getAuthority()) {
72 18
            $path = UriResolver::resolve($uri, $uri->withPath('')->withQuery($null))->getPath();
73
        }
74
75 22
        $query = $uri->getQuery();
76 22
        $fragment = $uri->getFragment();
77 22
        $fragmentOrig = $fragment;
78 22
        $pairs = null === $query ? [] : explode('&', $query);
79 22
        sort($pairs, SORT_REGULAR);
80
81
        $replace = static function (array $matches): string {
82 4
            return rawurldecode($matches[0]);
83 22
        };
84
85 22
        $retval = preg_replace_callback(self::REGEXP_ENCODED_CHARS, $replace, [$path, implode('&', $pairs), $fragment]);
86 22
        if (null !== $retval) {
87 22
            [$path, $query, $fragment] = $retval + ['', $null, $null];
88
        }
89
90 22
        if ($null !== $uri->getAuthority() && '' === $path) {
91 10
            $path = '/';
92
        }
93
94
        return $uri
95 22
            ->withHost(Uri::createFromComponents(['host' => $uri->getHost()])->getHost())
96 22
            ->withPath($path)
97 22
            ->withQuery([] === $pairs ? $null : $query)
98 22
            ->withFragment($null === $fragmentOrig ? $fragmentOrig : $fragment);
99
    }
100
101
    /**
102
     * Tell whether the URI represents an absolute URI.
103
     *
104
     * @param Psr7UriInterface|UriInterface $uri
105
     */
106 10
    public static function isAbsolute($uri): bool
107
    {
108 10
        $null = $uri instanceof Psr7UriInterface ? '' : null;
109
110 10
        return $null !== self::filterUri($uri)->getScheme();
111
    }
112
113
    /**
114
     * Tell whether the URI represents a network path.
115
     *
116
     * @param Psr7UriInterface|UriInterface $uri
117
     */
118 10
    public static function isNetworkPath($uri): bool
119
    {
120 10
        $uri = self::filterUri($uri);
121 8
        $null = $uri instanceof Psr7UriInterface ? '' : null;
122
123 8
        return $null === $uri->getScheme() && $null !== $uri->getAuthority();
124
    }
125
126
    /**
127
     * Tell whether the URI represents an absolute path.
128
     *
129
     * @param Psr7UriInterface|UriInterface $uri
130
     */
131 10
    public static function isAbsolutePath($uri): bool
132
    {
133 10
        $uri = self::filterUri($uri);
134 8
        $null = $uri instanceof Psr7UriInterface ? '' : null;
135
136 8
        return $null === $uri->getScheme()
137 8
            && $null === $uri->getAuthority()
138 8
            && '/' === ($uri->getPath()[0] ?? '');
139
    }
140
141
    /**
142
     * Tell whether the URI represents a relative path.
143
     *
144
     * @param Psr7UriInterface|UriInterface $uri
145
     */
146 110
    public static function isRelativePath($uri): bool
147
    {
148 110
        $uri = self::filterUri($uri);
149 108
        $null = $uri instanceof Psr7UriInterface ? '' : null;
150
151 108
        return $null === $uri->getScheme()
152 108
            && $null === $uri->getAuthority()
153 108
            && '/' !== ($uri->getPath()[0] ?? '');
154
    }
155
156
    /**
157
     * Tell whether both URI refers to the same document.
158
     *
159
     * @param Psr7UriInterface|UriInterface $uri
160
     * @param Psr7UriInterface|UriInterface $base_uri
161
     */
162 24
    public static function isSameDocument($uri, $base_uri): bool
163
    {
164 24
        $uri = self::normalize($uri);
165 22
        $base_uri = self::normalize($base_uri);
166
167 20
        return (string) $uri->withFragment($uri instanceof Psr7UriInterface ? '' : null)
168 20
            === (string) $base_uri->withFragment($base_uri instanceof Psr7UriInterface ? '' : null);
169
    }
170
}
171