forked from goetas-webservices/xsd-reader
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathUrlUtils.php
More file actions
108 lines (89 loc) · 2.65 KB
/
UrlUtils.php
File metadata and controls
108 lines (89 loc) · 2.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<?php
declare(strict_types=1);
namespace GoetasWebservices\XML\XSDReader\Utils;
class UrlUtils
{
public static function resolveRelativeUrl(string $base, string $rel): string
{
if ('' === trim($rel)) {
return $base;
}
if (null !== parse_url($rel, PHP_URL_SCHEME) || str_starts_with($rel, '//')) {
return $rel;
}
if (in_array($rel[0], ['#', '?'], true)) {
return $base . $rel;
}
return static::resolveRelativeUrlAfterEarlyChecks($base, $rel);
}
protected static function resolveRelativeUrlAfterEarlyChecks(string $base, string $rel): string
{
/* fix url file for Windows */
$base = preg_replace('#^file:\/\/([^/])#', 'file:///\1', $base);
/**
* @var mixed[]
*
* parse base URL and convert to local variables:
* $scheme, $host, $path
*/
$parts = parse_url($base);
$path = '/' === $rel[0]
? '' // destroy path if relative url points to root
: ( // remove non-directory element from path
isset($parts['path'])
? preg_replace(
'#/[^/]*$#',
'',
(string) $parts['path']
)
: ''
);
return static::resolveRelativeUrlToAbsoluteUrl($rel, $path, $parts);
}
/**
* @param array<string, string> $parts
*/
protected static function resolveRelativeUrlToAbsoluteUrl(string $rel, string $path, array $parts): string
{
/* Build absolute URL */
$abs = '';
if (isset($parts['host'])) {
$abs .= $parts['host'];
}
if (isset($parts['port'])) {
$abs .= ':' . $parts['port'];
}
$abs .= $path . '/' . $rel;
$abs = static::replaceSuperfluousSlashes($abs);
if (isset($parts['scheme'])) {
$abs = $parts['scheme'] . '://' . $abs;
}
return $abs;
}
/**
* replace superfluous slashes with a single slash.
* covers:.
* //
* /./
* /foo/../.
*/
protected static function replaceSuperfluousSlashes(string $abs): string
{
/* Use realpath to deal with multiple levels if the path exists */
$rp = realpath($abs);
if ($rp) {
return $rp;
}
$n = 1;
do {
$abs = preg_replace(
'#(?:(?:/\.?/)|(?!\.\.)[^/]+/\.\./)#',
'/',
$abs,
-1,
$n
);
} while (0 < $n);
return $abs;
}
}