[Filesystem] Fixed makePathRelative
This commit is contained in:
parent
2adfb375c6
commit
2bc11505f4
|
@ -358,25 +358,28 @@ class Filesystem
|
||||||
$startPath = str_replace('\\', '/', $startPath);
|
$startPath = str_replace('\\', '/', $startPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$stripDriveLetter = function ($path) {
|
||||||
|
if (strlen($path) > 2 && ':' === $path[1] && '/' === $path[2] && ctype_alpha($path[0])) {
|
||||||
|
return substr($path, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $path;
|
||||||
|
};
|
||||||
|
|
||||||
|
$endPath = $stripDriveLetter($endPath);
|
||||||
|
$startPath = $stripDriveLetter($startPath);
|
||||||
|
|
||||||
// Split the paths into arrays
|
// Split the paths into arrays
|
||||||
$startPathArr = explode('/', trim($startPath, '/'));
|
$startPathArr = explode('/', trim($startPath, '/'));
|
||||||
$endPathArr = explode('/', trim($endPath, '/'));
|
$endPathArr = explode('/', trim($endPath, '/'));
|
||||||
|
|
||||||
if ('/' !== $startPath[0]) {
|
$normalizePathArray = function ($pathSegments, $absolute) {
|
||||||
array_shift($startPathArr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('/' !== $endPath[0]) {
|
|
||||||
array_shift($endPathArr);
|
|
||||||
}
|
|
||||||
|
|
||||||
$normalizePathArray = function ($pathSegments) {
|
|
||||||
$result = array();
|
$result = array();
|
||||||
|
|
||||||
foreach ($pathSegments as $segment) {
|
foreach ($pathSegments as $segment) {
|
||||||
if ('..' === $segment) {
|
if ('..' === $segment && ($absolute || count($result))) {
|
||||||
array_pop($result);
|
array_pop($result);
|
||||||
} else {
|
} elseif ('.' !== $segment) {
|
||||||
$result[] = $segment;
|
$result[] = $segment;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -384,8 +387,8 @@ class Filesystem
|
||||||
return $result;
|
return $result;
|
||||||
};
|
};
|
||||||
|
|
||||||
$startPathArr = $normalizePathArray($startPathArr);
|
$startPathArr = $normalizePathArray($startPathArr, static::isAbsolutePath($startPath));
|
||||||
$endPathArr = $normalizePathArray($endPathArr);
|
$endPathArr = $normalizePathArray($endPathArr, static::isAbsolutePath($endPath));
|
||||||
|
|
||||||
// Find for which directory the common path stops
|
// Find for which directory the common path stops
|
||||||
$index = 0;
|
$index = 0;
|
||||||
|
@ -394,19 +397,14 @@ class Filesystem
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine how deep the start path is relative to the common path (ie, "web/bundles" = 2 levels)
|
// Determine how deep the start path is relative to the common path (ie, "web/bundles" = 2 levels)
|
||||||
if (count($startPathArr) === 1 && $startPathArr[0] === '') {
|
if (1 === count($startPathArr) && '' === $startPathArr[0]) {
|
||||||
$depth = 0;
|
$depth = 0;
|
||||||
} else {
|
} else {
|
||||||
$depth = count($startPathArr) - $index;
|
$depth = count($startPathArr) - $index;
|
||||||
}
|
}
|
||||||
|
|
||||||
// When we need to traverse from the start, and we are starting from a root path, don't add '../'
|
// Repeated "../" for each level need to reach the common path
|
||||||
if ('/' === $startPath[0] && 0 === $index && 0 === $depth) {
|
$traverser = str_repeat('../', $depth);
|
||||||
$traverser = '';
|
|
||||||
} else {
|
|
||||||
// Repeated "../" for each level need to reach the common path
|
|
||||||
$traverser = str_repeat('../', $depth);
|
|
||||||
}
|
|
||||||
|
|
||||||
$endPathRemainder = implode('/', array_slice($endPathArr, $index));
|
$endPathRemainder = implode('/', array_slice($endPathArr, $index));
|
||||||
|
|
||||||
|
@ -500,7 +498,7 @@ class Filesystem
|
||||||
{
|
{
|
||||||
return strspn($file, '/\\', 0, 1)
|
return strspn($file, '/\\', 0, 1)
|
||||||
|| (strlen($file) > 3 && ctype_alpha($file[0])
|
|| (strlen($file) > 3 && ctype_alpha($file[0])
|
||||||
&& substr($file, 1, 1) === ':'
|
&& ':' === substr($file, 1, 1)
|
||||||
&& strspn($file, '/\\', 2, 1)
|
&& strspn($file, '/\\', 2, 1)
|
||||||
)
|
)
|
||||||
|| null !== parse_url($file, PHP_URL_SCHEME)
|
|| null !== parse_url($file, PHP_URL_SCHEME)
|
||||||
|
|
|
@ -847,6 +847,7 @@ class FilesystemTest extends FilesystemTestCase
|
||||||
array('/var/lib/symfony/src/Symfony', '/var/lib/symfony/src/Symfony/Component/', '../'),
|
array('/var/lib/symfony/src/Symfony', '/var/lib/symfony/src/Symfony/Component/', '../'),
|
||||||
array('var/lib/symfony/', 'var/lib/symfony/src/Symfony/Component', '../../../'),
|
array('var/lib/symfony/', 'var/lib/symfony/src/Symfony/Component', '../../../'),
|
||||||
array('/usr/lib/symfony/', '/var/lib/symfony/src/Symfony/Component', '../../../../../../usr/lib/symfony/'),
|
array('/usr/lib/symfony/', '/var/lib/symfony/src/Symfony/Component', '../../../../../../usr/lib/symfony/'),
|
||||||
|
array('usr/lib/symfony/', 'var/lib/symfony/src/Symfony/Component', '../../../../../../usr/lib/symfony/'),
|
||||||
array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/', 'src/Symfony/'),
|
array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/', 'src/Symfony/'),
|
||||||
array('/aa/bb', '/aa/bb', './'),
|
array('/aa/bb', '/aa/bb', './'),
|
||||||
array('/aa/bb', '/aa/bb/', './'),
|
array('/aa/bb', '/aa/bb/', './'),
|
||||||
|
@ -878,6 +879,17 @@ class FilesystemTest extends FilesystemTestCase
|
||||||
array('C:/aa/bb/../../cc', 'C:/aa/../dd/..', 'cc/'),
|
array('C:/aa/bb/../../cc', 'C:/aa/../dd/..', 'cc/'),
|
||||||
array('C:/../aa/bb/cc', 'C:/aa/dd/..', 'bb/cc/'),
|
array('C:/../aa/bb/cc', 'C:/aa/dd/..', 'bb/cc/'),
|
||||||
array('C:/../../aa/../bb/cc', 'C:/aa/dd/..', '../bb/cc/'),
|
array('C:/../../aa/../bb/cc', 'C:/aa/dd/..', '../bb/cc/'),
|
||||||
|
array('aa/bb', 'aa/cc', '../bb/'),
|
||||||
|
array('aa/cc', 'bb/cc', '../../aa/cc/'),
|
||||||
|
array('aa/bb', 'aa/./cc', '../bb/'),
|
||||||
|
array('aa/./bb', 'aa/cc', '../bb/'),
|
||||||
|
array('aa/./bb', 'aa/./cc', '../bb/'),
|
||||||
|
array('../../', '../../', './'),
|
||||||
|
array('../aa/bb/', 'aa/bb/', '../../../aa/bb/'),
|
||||||
|
array('../../../', '../../', '../'),
|
||||||
|
array('', '', './'),
|
||||||
|
array('', 'aa/', '../'),
|
||||||
|
array('aa/', '', 'aa/'),
|
||||||
);
|
);
|
||||||
|
|
||||||
if ('\\' === DIRECTORY_SEPARATOR) {
|
if ('\\' === DIRECTORY_SEPARATOR) {
|
||||||
|
|
Reference in New Issue