|
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
|
3 |
|
$url |
|
129
|
|
|
); |
|
130
|
|
|
} else { |
|
131
|
|
|
return (bool)preg_match("/^(?:[\w#!:\.\?\+=&@$'~*,;\/\(\)\[\]\-]|%[0-9a-f]{2})+$/i", $url); |
|
132
|
|
|
} |
|
133
|
|
|
} |
|
134
|
|
|
} |