Passed
Pull Request — master (#18)
by SignpostMarv
03:22
created

UrlUtils   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 129
Duplicated Lines 0 %

Test Coverage

Coverage 94.92%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 129
ccs 56
cts 59
cp 0.9492
rs 10
wmc 14

4 Methods

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