[Filesystem] Handle paths on different drives
This commit is contained in:
parent
08ded7fed6
commit
00e727ae4e
@ -455,28 +455,19 @@ class Filesystem
|
|||||||
$startPath = str_replace('\\', '/', $startPath);
|
$startPath = str_replace('\\', '/', $startPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
$stripDriveLetter = function ($path) {
|
$splitDriveLetter = function ($path) {
|
||||||
if (\strlen($path) > 2 && ':' === $path[1] && '/' === $path[2] && ctype_alpha($path[0])) {
|
return (\strlen($path) > 2 && ':' === $path[1] && '/' === $path[2] && ctype_alpha($path[0]))
|
||||||
return substr($path, 2);
|
? [substr($path, 2), strtoupper($path[0])]
|
||||||
}
|
: [$path, null];
|
||||||
|
|
||||||
return $path;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$endPath = $stripDriveLetter($endPath);
|
$splitPath = function ($path, $absolute) {
|
||||||
$startPath = $stripDriveLetter($startPath);
|
|
||||||
|
|
||||||
// Split the paths into arrays
|
|
||||||
$startPathArr = explode('/', trim($startPath, '/'));
|
|
||||||
$endPathArr = explode('/', trim($endPath, '/'));
|
|
||||||
|
|
||||||
$normalizePathArray = function ($pathSegments, $absolute) {
|
|
||||||
$result = [];
|
$result = [];
|
||||||
|
|
||||||
foreach ($pathSegments as $segment) {
|
foreach (explode('/', trim($path, '/')) as $segment) {
|
||||||
if ('..' === $segment && ($absolute || \count($result))) {
|
if ('..' === $segment && ($absolute || \count($result))) {
|
||||||
array_pop($result);
|
array_pop($result);
|
||||||
} elseif ('.' !== $segment) {
|
} elseif ('.' !== $segment && '' !== $segment) {
|
||||||
$result[] = $segment;
|
$result[] = $segment;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -484,8 +475,16 @@ class Filesystem
|
|||||||
return $result;
|
return $result;
|
||||||
};
|
};
|
||||||
|
|
||||||
$startPathArr = $normalizePathArray($startPathArr, static::isAbsolutePath($startPath));
|
list($endPath, $endDriveLetter) = $splitDriveLetter($endPath);
|
||||||
$endPathArr = $normalizePathArray($endPathArr, static::isAbsolutePath($endPath));
|
list($startPath, $startDriveLetter) = $splitDriveLetter($startPath);
|
||||||
|
|
||||||
|
$startPathArr = $splitPath($startPath, static::isAbsolutePath($startPath));
|
||||||
|
$endPathArr = $splitPath($endPath, static::isAbsolutePath($endPath));
|
||||||
|
|
||||||
|
if ($endDriveLetter && $startDriveLetter && $endDriveLetter != $startDriveLetter) {
|
||||||
|
// End path is on another drive, so no relative path exists
|
||||||
|
return $endDriveLetter.':/'.($endPathArr ? implode('/', $endPathArr).'/' : '');
|
||||||
|
}
|
||||||
|
|
||||||
// Find for which directory the common path stops
|
// Find for which directory the common path stops
|
||||||
$index = 0;
|
$index = 0;
|
||||||
|
@ -1111,10 +1111,14 @@ class FilesystemTest extends FilesystemTestCase
|
|||||||
['/../aa/bb/cc', '/aa/dd/..', 'bb/cc/'],
|
['/../aa/bb/cc', '/aa/dd/..', 'bb/cc/'],
|
||||||
['/../../aa/../bb/cc', '/aa/dd/..', '../bb/cc/'],
|
['/../../aa/../bb/cc', '/aa/dd/..', '../bb/cc/'],
|
||||||
['C:/aa/bb/cc', 'C:/aa/dd/..', 'bb/cc/'],
|
['C:/aa/bb/cc', 'C:/aa/dd/..', 'bb/cc/'],
|
||||||
|
['C:/aa/bb/cc', 'c:/aa/dd/..', 'bb/cc/'],
|
||||||
['c:/aa/../bb/cc', 'c:/aa/dd/..', '../bb/cc/'],
|
['c:/aa/../bb/cc', 'c:/aa/dd/..', '../bb/cc/'],
|
||||||
['C:/aa/bb/../../cc', 'C:/aa/../dd/..', 'cc/'],
|
['C:/aa/bb/../../cc', 'C:/aa/../dd/..', 'cc/'],
|
||||||
['C:/../aa/bb/cc', 'C:/aa/dd/..', 'bb/cc/'],
|
['C:/../aa/bb/cc', 'C:/aa/dd/..', 'bb/cc/'],
|
||||||
['C:/../../aa/../bb/cc', 'C:/aa/dd/..', '../bb/cc/'],
|
['C:/../../aa/../bb/cc', 'C:/aa/dd/..', '../bb/cc/'],
|
||||||
|
['D:/', 'C:/aa/../bb/cc', 'D:/'],
|
||||||
|
['D:/aa/bb', 'C:/aa', 'D:/aa/bb/'],
|
||||||
|
['D:/../../aa/../bb/cc', 'C:/aa/dd/..', 'D:/bb/cc/'],
|
||||||
];
|
];
|
||||||
|
|
||||||
if ('\\' === \DIRECTORY_SEPARATOR) {
|
if ('\\' === \DIRECTORY_SEPARATOR) {
|
||||||
|
Reference in New Issue
Block a user