Passed
Push — static-analysis ( 935891...314368 )
by SignpostMarv
02:22
created

UrlUtils::replaceSuperfluousSlashes()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 9
nc 1
nop 1
dl 0
loc 14
ccs 10
cts 10
cp 1
crap 2
rs 9.4285
c 0
b 0
f 0
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 54
    public static function resolveRelativeUrl($base, $rel)
14
    {
15 54
        if (!$rel) {
16 2
            return $base;
17
        } elseif (
18
        /* return if already absolute URL */
19 53
            parse_url($rel, PHP_URL_SCHEME) !== null ||
20 9
            substr($rel, 0, 2) === '//'
21 53
        ) {
22 45
            return $rel;
23
        } elseif (
24
        /* queries and anchors */
25 9
            in_array(
26 9
                $rel[0],
27
                [
28 9
                    '#',
29 9
                    '?',
30
                ]
31 9
            )
32 9
        ) {
33 2
            return $base.$rel;
34
        }
35
36 9
        return static::resolveRelativeUrlAfterEarlyChecks($base, $rel);
37
    }
38
39
    /**
40
     * @param string $base
41
     * @param string $rel
42
     *
43
     * @return string
44
     */
45 9
    protected static function resolveRelativeUrlAfterEarlyChecks($base, $rel)
46
    {
47
        /* fix url file for Windows */
48 9
        $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 9
        $parts = parse_url($base);
57
58 9
        return static::resolveRelativeUrlToAbsoluteUrl(
59 9
            $rel,
60
            (
61 9
                $rel[0] === '/'
62 9
                    ? ''  // destroy path if relative url points to root
63 4
                    : ( // remove non-directory element from path
64 7
                        isset($parts['path'])
65 7
                            ? preg_replace(
66 7
                                '#/[^/]*$#',
67 7
                                '',
68 7
                                (string) $parts['path']
69 7
                            )
70 7
                            : ''
71
                    )
72 9
            ),
73
            $parts
74 9
        );
75
    }
76
77
    /**
78
     * @param string $rel
79
     * @param string $path
80
     *
81
     * @return string
82
     */
83 9
    protected static function resolveRelativeUrlToAbsoluteUrl(
84
        $rel,
85
        $path,
86
        array $parts
87
    ) {
88
        /* Build absolute URL */
89 9
        $abs = '';
90
91 9
        if (isset($parts['host'])) {
92 5
            $abs .= (string) $parts['host'];
93 5
        }
94
95 9
        if (isset($parts['port'])) {
96
            $abs .= ':'.(string) $parts['port'];
97
        }
98
99 9
        $abs .= $path.'/'.$rel;
100 9
        $abs = static::replaceSuperfluousSlashes($abs);
101
102 9
        if (isset($parts['scheme'])) {
103 6
            $abs = (string) $parts['scheme'].'://'.$abs;
104 6
        }
105
106 9
        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 9
    protected static function replaceSuperfluousSlashes($abs)
121
    {
122 9
        $n = 1;
123
        do {
124 9
            $abs = preg_replace(
125 9
                '#(?:(?:/\.?/)|(?!\.\.)[^/]+/\.\./)#',
126 9
                '/',
127 9
                $abs,
128 9
                -1,
129
                $n
130 9
            );
131 9
        } while ($n > 0);
132
133 9
        return $abs;
134
    }
135
}
136