Url::makeRelative()   B
last analyzed

Complexity

Conditions 5
Paths 6

Size

Total Lines 29
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 5

Importance

Changes 7
Bugs 1 Features 1
Metric Value
c 7
b 1
f 1
dl 0
loc 29
ccs 15
cts 15
cp 1
rs 8.439
cc 5
eloc 19
nc 6
nop 2
crap 5
1
<?php
2
3
/*
4
 * This file is part of the webmozart/path-util package.
5
 *
6
 * (c) Bernhard Schussek <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Webmozart\PathUtil;
13
14
use InvalidArgumentException;
15
use Webmozart\Assert\Assert;
16
17
/**
18
 * Contains utility methods for handling URL strings.
19
 *
20
 * The methods in this class are able to deal with URLs.
21
 *
22
 * @since  2.3
23
 *
24
 * @author Bernhard Schussek <[email protected]>
25
 * @author Claudio Zizza <[email protected]>
26
 */
27
final class Url
28
{
29
    /**
30
     * Turns a URL into a relative path.
31
     *
32
     * The result is a canonical path. This class is using functionality of Path class.
33
     *
34
     * @see Path
35
     *
36
     * @param string $url     A URL to make relative.
37
     * @param string $baseUrl A base URL.
38
     *
39
     * @return string
40
     *
41
     * @throws InvalidArgumentException If the URL and base URL does
42
     *                                  not match.
43
     */
44 61
    public static function makeRelative($url, $baseUrl)
45
    {
46 61
        Assert::string($url, 'The URL must be a string. Got: %s');
47 60
        Assert::string($baseUrl, 'The base URL must be a string. Got: %s');
48 58
        Assert::contains($baseUrl, '://', '%s is not an absolute Url.');
49
50 56
        list($baseHost, $basePath) = self::split($baseUrl);
51
52 56
        if (false === strpos($url, '://')) {
53 34
            if (0 === strpos($url, '/')) {
54 20
                $host = $baseHost;
55
            } else {
56 14
                $host = '';
57
            }
58 34
            $path = $url;
59
        } else {
60 43
            list($host, $path) = self::split($url);
61
        }
62
63 56
        if ('' !== $host && $host !== $baseHost) {
64 1
            throw new InvalidArgumentException(sprintf(
65 1
                'The URL "%s" cannot be made relative to "%s" since their host names are different.',
66
                $host,
67
                $baseHost
68
            ));
69
        }
70
71 55
        return Path::makeRelative($path, $basePath);
72
    }
73
74
    /**
75
     * Splits a URL into its host and the path.
76
     *
77
     * ```php
78
     * list ($root, $path) = Path::split("http://example.com/webmozart")
79
     * // => array("http://example.com", "/webmozart")
80
     *
81
     * list ($root, $path) = Path::split("http://example.com")
82
     * // => array("http://example.com", "")
83
     * ```
84
     *
85
     * @param string $url The URL to split.
86
     *
87
     * @return string[] An array with the host and the path of the URL.
88
     *
89
     * @throws InvalidArgumentException If $url is not a URL.
90
     */
91 56
    private static function split($url)
92
    {
93 56
        $pos = strpos($url, '://');
94 56
        $scheme = substr($url, 0, $pos + 3);
95 56
        $url = substr($url, $pos + 3);
96
97 56
        if (false !== ($pos = strpos($url, '/'))) {
98 45
            $host = substr($url, 0, $pos);
99 45
            $url = substr($url, $pos);
100
        } else {
101
            // No path, only host
102 11
            $host = $url;
103 11
            $url = '/';
104
        }
105
106
        // At this point, we have $scheme, $host and $path
107 56
        $root = $scheme.$host;
108
109 56
        return array($root, $url);
110
    }
111
}
112