Passed
Push — php-7.1 ( b6da63...280be0 )
by SignpostMarv
01:58
created

UrlUtils::replaceSuperfluousSlashes()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 9
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 13
ccs 10
cts 10
cp 1
crap 2
rs 9.4285
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
         * parse base URL and convert to local variables:
44
         * $scheme, $host, $path
45
         */
46 9
        $parts = parse_url($base);
47
48 9
        return static::resolveRelativeUrlToAbsoluteUrl(
49 9
            $rel,
50
            (
51 9
                $rel[0] === '/'
52 4
                    ? ''  // destroy path if relative url points to root
53
                    : ( // remove non-directory element from path
54 7
                        isset($parts['path'])
55 7
                            ? preg_replace('#/[^/]*$#', '', $parts["path"])
56 9
                            : ''
57
                    )
58
            ),
59 9
            $parts
60
        );
61
    }
62
63 9
    protected static function resolveRelativeUrlToAbsoluteUrl(
64
        string $rel,
65
        string $path,
66
        array $parts
67
    ) : string {
68
        /* Build absolute URL */
69 9
        $abs = '';
70
71 9
        if (isset($parts["host"])) {
72 5
            $abs .= $parts['host'];
73
        }
74
75 9
        if (isset($parts["port"])) {
76
            $abs .= ":".$parts["port"];
77
        }
78
79 9
        $abs .= $path."/".$rel;
80 9
        $abs = static::replaceSuperfluousSlashes($abs);
81
82 9
        if (isset($parts["scheme"])) {
83 6
            $abs = $parts["scheme"].'://'.$abs;
84
        }
85
86 9
        return $abs;
87
    }
88
89
    /**
90
        * replace superfluous slashes with a single slash.
91
        * covers:
92
        * //
93
        * /./
94
        * /foo/../
95
        *
96
        * @param string $abs
97
        *
98
        * @return string
99
        */
100 9
    protected static function replaceSuperfluousSlashes($abs) {
101 9
        $n = 1;
102
        do {
103 9
            $abs = preg_replace(
104 9
                '#(?:(?:/\.?/)|(?!\.\.)[^/]+/\.\./)#',
105 9
                '/',
106 9
                $abs,
107 9
                -1,
108 9
                $n
109
            );
110 9
        } while ($n > 0);
111
112 9
        return $abs;
113
    }
114
}
115