summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Müller <thomas.mueller@tmit.eu>2014-04-10 09:26:17 +0200
committerThomas Müller <thomas.mueller@tmit.eu>2014-04-10 09:26:17 +0200
commite20d23e18b5547fffe04745891683b951de8d54f (patch)
treea33063bf93683c08118b90b714e855ace5a86fd9
parent140a65e11b4a6e42e1069c1cc5c32a0a7f6aa61b (diff)
parent61425344cc223a1f4fb6edc36d332d3ded761f2e (diff)
downloadnextcloud-server-e20d23e18b5547fffe04745891683b951de8d54f.tar.gz
nextcloud-server-e20d23e18b5547fffe04745891683b951de8d54f.zip
Merge pull request #8030 from owncloud/getpath-shared-stable5
[stable5] Make getPath work for shared files
-rw-r--r--apps/files_sharing/lib/cache.php44
-rw-r--r--apps/files_sharing/tests/api.php39
-rw-r--r--lib/files/cache/cache.php19
-rw-r--r--lib/files/view.php16
4 files changed, 113 insertions, 5 deletions
diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php
index baa632ec9c1..64ab18348b9 100644
--- a/apps/files_sharing/lib/cache.php
+++ b/apps/files_sharing/lib/cache.php
@@ -336,4 +336,48 @@ class Shared_Cache extends Cache {
return $ids;
}
+ /**
+ * get the path of a file on this storage by it's id
+ *
+ * @param int $id
+ * @param string $pathEnd (optional) used internally for recursive calls
+ * @return string | null
+ **/
+ public function getPathById($id, $pathEnd = '') {
+ // direct shares are easy
+ if ($path = $this->getShareById($id)) {
+ return $path . $pathEnd;
+ } else {
+ // if the item is a direct share we try and get the path of the parent and append the name of the item to it
+ list($parent, $name) = $this->getParentInfo($id);
+ if ($parent > 0) {
+ return $this->getPathById($parent, '/' . $name . $pathEnd);
+ } else {
+ return null;
+ }
+ }
+ }
+
+ private function getShareById($id) {
+ $item = \OCP\Share::getItemSharedWithBySource('file', $id);
+ if ($item) {
+ return trim($item['file_target'], '/');
+ }
+ $item = \OCP\Share::getItemSharedWithBySource('folder', $id);
+ if ($item) {
+ return trim($item['file_target'], '/');
+ }
+ return null;
+ }
+
+ private function getParentInfo($id) {
+ $sql = 'SELECT `parent`, `name` FROM `*PREFIX*filecache` WHERE `fileid` = ?';
+ $query = \OC_DB::prepare($sql);
+ $result = $query->execute(array($id));
+ if ($row = $result->fetchRow()) {
+ return array($row['parent'], $row['name']);
+ } else {
+ return array(-1, '');
+ }
+ }
}
diff --git a/apps/files_sharing/tests/api.php b/apps/files_sharing/tests/api.php
index 7fdbab385dd..c32c425b4aa 100644
--- a/apps/files_sharing/tests/api.php
+++ b/apps/files_sharing/tests/api.php
@@ -981,6 +981,45 @@ class Test_Files_Sharing_Api extends \PHPUnit_Framework_TestCase {
$this->assertSame($expectedResult, $shareApiDummy->correctPathTest($path, $folder));
}
+ public function testGetPathByIdDirectShare() {
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+ \OC\Files\Filesystem::file_put_contents('test.txt', 'foo');
+ $info = \OC\Files\Filesystem::getFileInfo('test.txt');
+ \OCP\Share::shareItem('file', $info['fileid'], \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, \OCP\PERMISSION_ALL);
+ \OC_Util::tearDownFS();
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+ $this->assertTrue(\OC\Files\Filesystem::file_exists('/Shared/test.txt'));
+ list($sharedStorage) = \OC\Files\Filesystem::resolvePath('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/Shared/test.txt');
+ /**
+ * @var \OC\Files\Storage\Shared $sharedStorage
+ */
+
+ $sharedCache = $sharedStorage->getCache();
+ $this->assertEquals('test.txt', $sharedCache->getPathById($info['fileid']));
+ }
+
+ public function testGetPathByIdShareSubFolder() {
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+ \OC\Files\Filesystem::mkdir('foo');
+ \OC\Files\Filesystem::mkdir('foo/bar');
+ \OC\Files\Filesystem::touch('foo/bar/test.txt', 'bar');
+ $folderInfo = \OC\Files\Filesystem::getFileInfo('foo');
+ $fileInfo = \OC\Files\Filesystem::getFileInfo('foo/bar/test.txt');
+ \OCP\Share::shareItem('folder', $folderInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, \OCP\PERMISSION_ALL);
+ \OC_Util::tearDownFS();
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+ $this->assertTrue(\OC\Files\Filesystem::file_exists('/Shared/foo'));
+ list($sharedStorage) = \OC\Files\Filesystem::resolvePath('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/Shared/foo');
+ /**
+ * @var \OC\Files\Storage\Shared $sharedStorage
+ */
+
+ $sharedCache = $sharedStorage->getCache();
+ $this->assertEquals('foo', $sharedCache->getPathById($folderInfo['fileid']));
+ $this->assertEquals('foo/bar/test.txt', $sharedCache->getPathById($fileInfo['fileid']));
+ }
}
/**
diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php
index c8fa27e402b..a30598f5695 100644
--- a/lib/files/cache/cache.php
+++ b/lib/files/cache/cache.php
@@ -660,8 +660,27 @@ class Cache {
}
/**
+ * path of a file on this storage by it's id
+ *
+ * @param int $id
+ * @return string | null
+ */
+ public function getPathById($id) {
+ $sql = 'SELECT `path` FROM `*PREFIX*filecache` WHERE `fileid` = ? AND `storage` = ?';
+ $result = \OC_DB::executeAudited($sql, array($id, $this->getNumericStorageId()));
+ if ($row = $result->fetchRow()) {
+ return $row['path'];
+ } else {
+ return null;
+ }
+ }
+
+ /**
* get the storage id of the storage for a file and the internal path of the file
+ * unlike getPathById this does not limit the search to files on this storage and
+ * instead does a global search in the cache table
*
+ * @param int $id
* @return array, first element holding the storage id, second the path
*/
static public function getById($id) {
diff --git a/lib/files/view.php b/lib/files/view.php
index 19dea87e3bc..3d5d45703e7 100644
--- a/lib/files/view.php
+++ b/lib/files/view.php
@@ -1059,15 +1059,21 @@ class View {
* @return string
*/
public function getPath($id) {
- list($storage, $internalPath) = Cache\Cache::getById($id);
- $mounts = Mount::findByStorageId($storage);
+ $mounts = Mount::findIn($this->fakeRoot);
+ $mounts[] = Mount::find($this->fakeRoot);
+ // reverse the array so we start with the storage this view is in
+ // which is the most likely to contain the file we're looking for
+ $mounts = array_reverse($mounts);
foreach ($mounts as $mount) {
/**
* @var \OC\Files\Mount $mount
*/
- $fullPath = $mount->getMountPoint() . $internalPath;
- if (!is_null($path = $this->getRelativePath($fullPath))) {
- return $path;
+ $cache = $mount->getStorage()->getCache();
+ if ($internalPath = $cache->getPathById($id)) {
+ $fullPath = $mount->getMountPoint() . $internalPath;
+ if (!is_null($path = $this->getRelativePath($fullPath))) {
+ return $path;
+ }
}
}
return null;