Passed
Push — static-analysis ( ae4331...8e814c )
by SignpostMarv
03:31
created

UrlUtils::resolveRelativeUrlAfterEarlyChecks()   B

Complexity

Conditions 3
Paths 1

Size

Total Lines 29
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 3.0015

Importance

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