Test Failed
Pull Request — master (#18)
by SignpostMarv
03:33
created

UrlUtils::resolveRelativeUrl()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 24
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 5

Importance

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