Refactored Filesystem::makePathRelative function to correctly handle more use-cases
This commit is contained in:
parent
064ad6255c
commit
6def8d1dd1
@ -302,21 +302,28 @@ class Filesystem
|
||||
$startPath = strtr($startPath, '\\', '/');
|
||||
}
|
||||
|
||||
// Find for which character the the common path stops
|
||||
$offset = 0;
|
||||
while (isset($startPath[$offset]) && isset($endPath[$offset]) && $startPath[$offset] === $endPath[$offset]) {
|
||||
$offset++;
|
||||
// Split the paths into arrays
|
||||
$startPathArr = explode('/', trim($startPath, '/'));
|
||||
$endPathArr = explode('/', trim($endPath, '/'));
|
||||
|
||||
// Find for which directory the common path stops
|
||||
$index = 0;
|
||||
while (isset($startPathArr[$index]) && isset($endPathArr[$index]) && $startPathArr[$index] === $endPathArr[$index]) {
|
||||
$index++;
|
||||
}
|
||||
|
||||
// Determine how deep the start path is relative to the common path (ie, "web/bundles" = 2 levels)
|
||||
$diffPath = trim(substr($startPath, $offset), '/');
|
||||
$depth = strlen($diffPath) > 0 ? substr_count($diffPath, '/') + 1 : 0;
|
||||
$depth = count($startPathArr) - $index;
|
||||
|
||||
// Repeated "../" for each level need to reach the common path
|
||||
$traverser = str_repeat('../', $depth);
|
||||
|
||||
$endPathRemainder = implode('/', array_slice($endPathArr, $index));
|
||||
|
||||
// Construct $endPath from traversing to the common path, then to the remaining $endPath
|
||||
return $traverser.substr($endPath, $offset);
|
||||
$relativePath = $traverser . (strlen($endPathRemainder) > 0 ? $endPathRemainder . '/' : '');
|
||||
|
||||
return (strlen($relativePath) === 0) ? './' : $relativePath;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -733,6 +733,22 @@ class FilesystemTest extends \PHPUnit_Framework_TestCase
|
||||
array('var/lib/symfony/', 'var/lib/symfony/src/Symfony/Component', '../../../'),
|
||||
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('/aa/bb', '/aa/bb', './'),
|
||||
array('/aa/bb', '/aa/bb/', './'),
|
||||
array('/aa/bb/', '/aa/bb', './'),
|
||||
array('/aa/bb/', '/aa/bb/', './'),
|
||||
array('/aa/bb/cc', '/aa/bb/cc/dd', '../'),
|
||||
array('/aa/bb/cc', '/aa/bb/cc/dd/', '../'),
|
||||
array('/aa/bb/cc/', '/aa/bb/cc/dd', '../'),
|
||||
array('/aa/bb/cc/', '/aa/bb/cc/dd/', '../'),
|
||||
array('/aa/bb/cc', '/aa', 'bb/cc/'),
|
||||
array('/aa/bb/cc', '/aa/', 'bb/cc/'),
|
||||
array('/aa/bb/cc/', '/aa', 'bb/cc/'),
|
||||
array('/aa/bb/cc/', '/aa/', 'bb/cc/'),
|
||||
array('/a/aab/bb', '/a/aa', '../aab/bb/'),
|
||||
array('/a/aab/bb', '/a/aa/', '../aab/bb/'),
|
||||
array('/a/aab/bb/', '/a/aa', '../aab/bb/'),
|
||||
array('/a/aab/bb/', '/a/aa/', '../aab/bb/'),
|
||||
);
|
||||
|
||||
if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
|
||||
|
Reference in New Issue
Block a user