Page MenuHomePhabricator

D13424.id32507.diff
No OneTemporary

D13424.id32507.diff

diff --git a/src/filesystem/Filesystem.php b/src/filesystem/Filesystem.php
--- a/src/filesystem/Filesystem.php
+++ b/src/filesystem/Filesystem.php
@@ -853,6 +853,48 @@
}
/**
+ * Retrieve the relative location of the specified path.
+ *
+ * This function returns the relative path from the current path to a given
+ * absolute path.
+ *
+ * @param string An absolute path.
+ * @return string The relative path between the current path and the
+ * specified path.
+ */
+ public static function relativePath($path, $root) {
+ // Some compatibility fixes for Windows paths
+ $from = is_dir($root) ? rtrim($root, '\/').'/' : $root;
+ $to = is_dir($path) ? rtrim($path, '\/').'/' : $path;
+ $from = str_replace('\\', '/', $from);
+ $to = str_replace('\\', '/', $to);
+
+ $from = explode('/', $from);
+ $to = explode('/', $to);
+
+ $rel_path = $to;
+
+ foreach ($from as $depth => $dir) {
+ // Find first non-matching directory.
+ if ($dir === $to[$depth]) {
+ // Ignore this directory.
+ array_shift($rel_path);
+ } else {
+ // Get number of remaining directories to $from.
+ $remaining = count($from) - $depth;
+ if ($remaining > 1) {
+ // Add traversals up to first matching directory.
+ $pad_length = (count($rel_path) + $remaining - 1) * -1;
+ $rel_path = array_pad($rel_path, $pad_length, '..');
+ break;
+ }
+ }
+ }
+
+ return implode('/', $rel_path);
+ }
+
+ /**
* Test whether a path is descendant from some root path after resolving all
* symlinks and removing artifacts. Both paths must exists for the relation
* to obtain. A path is always a descendant of itself as long as it exists.
diff --git a/src/filesystem/__tests__/FilesystemTestCase.php b/src/filesystem/__tests__/FilesystemTestCase.php
--- a/src/filesystem/__tests__/FilesystemTestCase.php
+++ b/src/filesystem/__tests__/FilesystemTestCase.php
@@ -163,4 +163,32 @@
}
}
+ public function testRelativePath() {
+ $test_cases = array(
+ array(
+ '/foo/bar/baz',
+ '/',
+ 'foo/bar/baz',
+ ),
+ array(
+ '/foo/bar/baz',
+ '/foo',
+ 'bar/baz',
+ ),
+ array(
+ '/foo/foobar',
+ '/foo/bar/baz',
+ '../foobar',
+ ),
+ );
+
+ foreach ($test_cases as $test_case) {
+ list($path, $root, $expected) = $test_case;
+
+ $this->assertEqual(
+ $expected,
+ Filesystem::relativePath($path, $root));
+ }
+ }
+
}

File Metadata

Mime Type
text/plain
Expires
Sat, Jan 25, 6:45 AM (5 h, 29 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7047907
Default Alt Text
D13424.id32507.diff (2 KB)

Event Timeline