Passed
Push — php-7.1 ( ed6d10...451fb2 )
by SignpostMarv
02:49
created

UrlUtils   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 114
Duplicated Lines 0 %

Test Coverage

Coverage 97.83%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 114
ccs 45
cts 46
cp 0.9783
rs 10
wmc 14

4 Methods

Rating   Name   Duplication   Size   Complexity  
B resolveRelativeUrl() 0 26 5
A replaceSuperfluousSlashes() 0 13 2
B resolveRelativeUrlToAbsoluteUrl() 0 24 4
B resolveRelativeUrlAfterEarlyChecks() 0 31 3
1
<?php
2
declare(strict_types = 1);
3
namespace GoetasWebservices\XML\XSDReader\Utils;
4
5
class UrlUtils
6
{
7 54
    public static function resolveRelativeUrl(
8
        string $base,
9
        string $rel
10
    ) : string {
11 54
        if (!$rel) {
12 2
            return $base;
13
        } elseif (
14
        /* return if already absolute URL */
15 53
            parse_url($rel, PHP_URL_SCHEME) !== null ||
16 9
            substr($rel, 0, 2) === '//'
17
        ) {
18 45
            return $rel;
19
        } elseif (
20
        /* queries and anchors */
21 9
            in_array(
22 9
                $rel[0],
23
                [
24 9
                    '#',
25
                    '?'
26
                ]
27
            )
28
        ) {
29 2
            return $base.$rel;
30
        }
31
32 9
        return static::resolveRelativeUrlAfterEarlyChecks($base, $rel);
33
    }
34
35 9
    protected static function resolveRelativeUrlAfterEarlyChecks(
36
        string $base,
37
        string $rel
38
    ) : string {
39
        /* fix url file for Windows */
40 9
        $base = preg_replace('#^file:\/\/([^/])#', 'file:///\1', $base);
41
42
        /**
43
         * @var mixed[] $parts
44
         *
45
         * parse base URL and convert to local variables:
46
         * $scheme, $host, $path
47
         */
48 9
        $parts = parse_url($base);
49
50 9
        return static::resolveRelativeUrlToAbsoluteUrl(
51 9
            $rel,
52
            (
53 9
                $rel[0] === '/'
54 4
                    ? ''  // destroy path if relative url points to root
55
                    : ( // remove non-directory element from path
56 7
                        isset($parts['path'])
57 7
                            ? preg_replace(
58 7
                                '#/[^/]*$#',
59 7
                                '',
60 7
                                (string) $parts["path"]
61
                            )
62 9
                            : ''
63
                    )
64
            ),
65 9
            $parts
66
        );
67
    }
68
69 9
    protected static function resolveRelativeUrlToAbsoluteUrl(
70
        string $rel,
71
        string $path,
72
        array $parts
73
    ) : string {
74
        /* Build absolute URL */
75 9
        $abs = '';
76
77 9
        if (isset($parts["host"])) {
78 5
            $abs .= (string) $parts['host'];
79
        }
80
81 9
        if (isset($parts["port"])) {
82
            $abs .= ":" . (string) $parts["port"];
83
        }
84
85 9
        $abs .= $path."/".$rel;
86 9
        $abs = static::replaceSuperfluousSlashes($abs);
87
88 9
        if (isset($parts["scheme"])) {
89 6
            $abs = (string) $parts["scheme"] . '://' . $abs;
90
        }
91
92 9
        return $abs;
93
    }
94
95
    /**
96
        * replace superfluous slashes with a single slash.
97
        * covers:
98
        * //
99
        * /./
100
        * /foo/../
101
        *
102
        * @param string $abs
103
        *
104
        * @return string
105
        */
106 9
    protected static function replaceSuperfluousSlashes($abs) {
107 9
        $n = 1;
108
        do {
109 9
            $abs = preg_replace(
110 9
                '#(?:(?:/\.?/)|(?!\.\.)[^/]+/\.\./)#',
111 9
                '/',
112 9
                $abs,
113 9
                -1,
114 9
                $n
115
            );
116 9
        } while ($n > 0);
117
118 9
        return $abs;
119
    }
120
}
121