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, '\\', '/');
|
$startPath = strtr($startPath, '\\', '/');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find for which character the the common path stops
|
// Split the paths into arrays
|
||||||
$offset = 0;
|
$startPathArr = explode('/', trim($startPath, '/'));
|
||||||
while (isset($startPath[$offset]) && isset($endPath[$offset]) && $startPath[$offset] === $endPath[$offset]) {
|
$endPathArr = explode('/', trim($endPath, '/'));
|
||||||
$offset++;
|
|
||||||
|
// 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)
|
// Determine how deep the start path is relative to the common path (ie, "web/bundles" = 2 levels)
|
||||||
$diffPath = trim(substr($startPath, $offset), '/');
|
$depth = count($startPathArr) - $index;
|
||||||
$depth = strlen($diffPath) > 0 ? substr_count($diffPath, '/') + 1 : 0;
|
|
||||||
|
|
||||||
// Repeated "../" for each level need to reach the common path
|
// Repeated "../" for each level need to reach the common path
|
||||||
$traverser = str_repeat('../', $depth);
|
$traverser = str_repeat('../', $depth);
|
||||||
|
|
||||||
|
$endPathRemainder = implode('/', array_slice($endPathArr, $index));
|
||||||
|
|
||||||
// Construct $endPath from traversing to the common path, then to the remaining $endPath
|
// 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('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('/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/', './'),
|
||||||
|
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')) {
|
if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
|
||||||
|
Reference in New Issue
Block a user