Passed
Push — static-analysis ( ccf5dd...1289d7 )
by SignpostMarv
01:23
created

UrlUtils::resolveRelativeUrl()   B

Complexity

Conditions 6
Paths 4

Size

Total Lines 17
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 6
eloc 7
c 2
b 0
f 0
nc 4
nop 2
dl 0
loc 17
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
    public static function resolveRelativeUrl($base, $rel)
13
    {
14
        if (!$rel) {
15
            return $base;
16
        }
17
18
        /* return if already absolute URL */
19
        if (parse_url($rel, PHP_URL_SCHEME) !== null || substr($rel, 0, 2) === '//') {
20
            return $rel;
21
        }
22
23
        /* queries and anchors */
24
        if ($rel[0] === '#' || $rel[0] === '?') {
25
            return $base.$rel;
26
        }
27
28
        return static::resolveRelativeUrlAfterEarlyChecks($base, $rel);
29
    }
30
31
    /**
32
    * @param string $base
33
    * @param string $rel
34
    *
35
    * @return string
36
    */
37
    protected static function resolveRelativeUrlAfterEarlyChecks($base, $rel)
38
    {
39
        $re = array(
40
            '#(/\.?/)#',
41
            '#/(?!\.\.)[^/]+/\.\./#'
42
        );
43
44
        /* fix url file for Windows */
45
        $base = preg_replace('#^file:\/\/([^/])#', 'file:///\1', $base);
46
47
        /*
48
         * parse base URL and convert to local variables:
49
         * $scheme, $host, $path
50
         */
51
        $parts = parse_url($base);
52
53
        /* remove non-directory element from path */
54
        $path = isset($parts['path']) ? preg_replace('#/[^/]*$#', '', $parts["path"]) : '';
55
56
        /* destroy path if relative url points to root */
57
        if ($rel[0] === '/') {
58
            $path = '';
59
        }
60
61
        /* Build absolute URL */
62
        $abs = '';
63
64
        if (isset($parts["host"])) {
65
            $abs .= $parts['host'];
66
        }
67
68
        if (isset($parts["port"])) {
69
            $abs .= ":".$parts["port"];
70
        }
71
72
        $abs .= $path."/".$rel;
73
74
        /*
75
        * replace superfluous slashes with a single slash.
76
        * covers:
77
        * //
78
        * /./
79
        * /foo/../
80
        */
81
        $n = 1;
82
        do {
83
            $abs = preg_replace($re, '/', $abs, -1, $n);
84
        } while ($n > 0);
85
86
        if (isset($parts["scheme"])) {
87
            $abs = $parts["scheme"].'://'.$abs;
88
        }
89
90
        return $abs;
91
    }
92
93
}
94