1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
namespace Eclipxe\XmlResourceRetriever; |
6
|
|
|
|
7
|
|
|
class Utils |
8
|
|
|
{ |
9
|
|
|
/** |
10
|
|
|
* Return the relative path from one location to other |
11
|
|
|
* |
12
|
|
|
* @param string $sourceFile |
13
|
|
|
* @param string $destinationFile |
14
|
|
|
* @return string |
15
|
|
|
*/ |
16
|
11 |
|
public static function relativePath(string $sourceFile, string $destinationFile): string |
17
|
|
|
{ |
18
|
11 |
|
$source = static::simplifyPath($sourceFile); |
19
|
11 |
|
$destination = static::simplifyPath($destinationFile); |
20
|
11 |
|
if ('' !== $source[0] && '' === $destination[0]) { |
21
|
1 |
|
return implode('/', $destination); |
22
|
|
|
} |
23
|
|
|
// remove the common path |
24
|
10 |
|
foreach ($source as $depth => $dir) { |
25
|
10 |
|
if (isset($destination[$depth])) { |
26
|
10 |
|
if ($dir === $destination[$depth]) { |
27
|
7 |
|
unset($destination[$depth]); |
28
|
7 |
|
unset($source[$depth]); |
29
|
|
|
} else { |
30
|
10 |
|
break; |
31
|
|
|
} |
32
|
|
|
} |
33
|
|
|
} |
34
|
|
|
// add '..' to the beginning of the source as required by the count of from |
35
|
10 |
|
$fromCount = count($source); |
36
|
10 |
|
for ($i = 0; $i < $fromCount - 1; $i++) { |
37
|
8 |
|
array_unshift($destination, '..'); |
38
|
|
|
} |
39
|
10 |
|
return implode('/', $destination); |
40
|
|
|
} |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* Simplify a path and return its parts as an array |
44
|
|
|
* |
45
|
|
|
* @param string $path |
46
|
|
|
* @return string[] |
47
|
|
|
*/ |
48
|
27 |
|
public static function simplifyPath(string $path): array |
49
|
|
|
{ |
50
|
27 |
|
$parts = explode('/', str_replace('//', '/./', $path)); |
51
|
27 |
|
$count = count($parts); |
52
|
27 |
|
for ($i = 0; $i < $count; $i = $i + 1) { |
53
|
|
|
// is .. and previous is not .. |
54
|
27 |
|
if ($i > 0 && '..' === $parts[$i] && '..' !== $parts[$i - 1]) { |
55
|
6 |
|
unset($parts[$i - 1]); |
56
|
6 |
|
unset($parts[$i]); |
57
|
6 |
|
return static::simplifyPath(implode('/', $parts)); |
58
|
|
|
} |
59
|
|
|
// is inner '.' |
60
|
27 |
|
if ('.' == $parts[$i]) { |
61
|
9 |
|
unset($parts[$i]); |
62
|
9 |
|
return static::simplifyPath(implode('/', $parts)); |
63
|
|
|
} |
64
|
|
|
} |
65
|
27 |
|
return $parts; |
66
|
|
|
} |
67
|
|
|
} |
68
|
|
|
|