Passed
Push — master ( c4035d...4d6446 )
by Gabriel
07:43
created

Url   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 118
Duplicated Lines 0 %

Test Coverage

Coverage 15.38%

Importance

Changes 1
Bugs 0 Features 1
Metric Value
wmc 19
eloc 43
c 1
b 0
f 1
dl 0
loc 118
ccs 4
cts 26
cp 0.1538
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A buildQuery() 0 20 5
F build() 0 13 12
A isValid() 0 24 2
1
<?php
2
3
/**
4
 * @inspiration
5
 * https://github.com/drupal/drupal/blob/8.8.x/core/lib/Drupal/Component/Utility/UrlHelper.php
6
 */
7
8
namespace Nip\Utility;
9
10
/**
11
 * Class Url
12
 * @package Nip\Utility
13
 */
14
class Url
15
{
16
    /**
17
     * The list of allowed protocols.
18
     *
19
     * @var array
20
     */
21
    protected static $allowedProtocols = ['http', 'https'];
22
23
    /**
24
     * Parses an array into a valid, rawurlencoded query string.
25
     *
26
     *
27
     * rawurlencode() is RFC3986 compliant, and as a consequence RFC3987
28
     * compliant. The latter defines the required format of "URLs" in HTML5.
29
     * urlencode() is almost the same as rawurlencode(), except that it encodes
30
     * spaces as "+" instead of "%20". This makes its result non compliant to
31
     * RFC3986 and as a consequence non compliant to RFC3987 and as a consequence
32
     * not valid as a "URL" in HTML5.
33
     *
34
     * @param array $query
35
     *   The query parameter array to be processed,
36
     *   e.g. \Drupal::request()->query->all().
37
     * @param string $parent
38
     *   Internal use only. Used to build the $query array key for nested items.
39
     *
40
     * @return string
41
     *   A rawurlencoded string which can be used as or appended to the URL query
42
     *   string.
43
     *
44
     * @ingroup php_wrappers
45
     * @todo Remove this function once PHP 5.4 is required as we can use just
46
     *   http_build_query() directly.
47
     *
48
     */
49
    public static function buildQuery(array $query, $parent = '')
50
    {
51
        $params = [];
52
53
        foreach ($query as $key => $value) {
54
            $key = ($parent ? $parent . '[' . rawurlencode($key) . ']' : rawurlencode($key));
55
56
            // Recurse into children.
57
            if (is_array($value)) {
58
                $params[] = static::buildQuery($value, $key);
59
            } // If a query parameter value is NULL, only append its key.
60
            elseif (!isset($value)) {
61
                $params[] = $key;
62
            } else {
63
                // For better readability of paths in query strings, we decode slashes.
64
                $params[] = $key . '=' . str_replace('%2F', '/', rawurlencode($value));
65
            }
66
        }
67
68
        return implode('&', $params);
69
    }
70
71
    /**
72
     * Reverse of the PHP built-in function parse_url
73
     *
74
     * @see http://php.net/parse_url
75
     * @param $url
76
     * @return string
77
     */
78
    public static function build($url)
79
    {
80
        $scheme = isset($url['scheme']) ? $url['scheme'] . '://' : '';
81
        $host = isset($url['host']) ? $url['host'] : '';
82
        $port = isset($url['port']) ? ':' . $url['port'] : '';
83
        $user = isset($url['user']) ? $url['user'] : '';
84
        $pass = isset($url['pass']) ? ':' . $url['pass'] : '';
85
        $pass = ($user || $pass) ? "$pass@" : '';
86
        $path = isset($url['path']) ? $url['path'] : '';
87
        $query = isset($url['query']) && $url['query'] ? '?' . $url['query'] : '';
88
        $fragment = isset($url['fragment']) ? '#' . $url['fragment'] : '';
89
90
        return $scheme . $user . $pass . $host . $port . $path . $query . $fragment;
91
    }
92
93
    /**
94
     * Verifies the syntax of the given URL.
95
     *
96
     * This function should only be used on actual URLs. It should not be used for
97
     * Drupal menu paths, which can contain arbitrary characters.
98
     * Valid values per RFC 3986.
99
     *
100
     * @param string $url
101
     *   The URL to verify.
102
     * @param bool $absolute
103
     *   Whether the URL is absolute (beginning with a scheme such as "http:").
104
     *
105
     * @return bool
106
     *   TRUE if the URL is in a valid format, FALSE otherwise.
107
     */
108 3
    public static function isValid($url, $absolute = true)
109
    {
110 3
        if ($absolute) {
111 3
            return (bool)preg_match(
112 3
                "
113
        /^                                                      # Start at the beginning of the text
114
        (?:ftp|https?|feed):\/\/                                # Look for ftp, http, https or feed schemes
115
        (?:                                                     # Userinfo (optional) which is typically
116
          (?:(?:[\w\.\-\+!$&'\(\)*\+,;=]|%[0-9a-f]{2})+:)*      # a username or a username and password
117
          (?:[\w\.\-\+%!$&'\(\)*\+,;=]|%[0-9a-f]{2})+@          # combination
118
        )?
119
        (?:
120
          (?:[a-z0-9\-\.]|%[0-9a-f]{2})+                        # A domain name or a IPv4 address
121
          |(?:\[(?:[0-9a-f]{0,4}:)*(?:[0-9a-f]{0,4})\])         # or a well formed IPv6 address
122
        )
123
        (?::[0-9]+)?                                            # Server port number (optional)
124
        (?:[\/|\?]
125
          (?:[\w#!:\.\?\+=&@$'~*,;\/\(\)\[\]\-]|%[0-9a-f]{2})   # The path and query (optional)
126
        *)?
127
      $/xi",
128
                $url
129
            );
130
        } else {
131
            return (bool)preg_match("/^(?:[\w#!:\.\?\+=&@$'~*,;\/\(\)\[\]\-]|%[0-9a-f]{2})+$/i", $url);
132
        }
133
    }
134
}
135