From 4719305e3b99d53c72a341c5b6cbfee6bf984fb7 Mon Sep 17 00:00:00 2001
From: Bjoern Schiessle <schiessle@owncloud.com>
Date: Mon, 17 Aug 2015 12:53:24 +0200
Subject: [PATCH] cache result from parent folders

---
 lib/private/encryption/file.php | 27 ++++++++++++++++++++++++---
 lib/private/share/share.php     |  5 +++--
 lib/public/share.php            |  9 +++++----
 3 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/lib/private/encryption/file.php b/lib/private/encryption/file.php
index 5a7357b9e2..6d261f46d0 100644
--- a/lib/private/encryption/file.php
+++ b/lib/private/encryption/file.php
@@ -27,6 +27,13 @@ class File implements \OCP\Encryption\IFile {
 	/** @var Util */
 	protected $util;
 
+	/**
+	 * cache results of already checked folders
+	 *
+	 * @var array
+	 */
+	protected $cache;
+
 	public function __construct(Util $util) {
 		$this->util = $util;
 	}
@@ -53,10 +60,24 @@ class File implements \OCP\Encryption\IFile {
 		$ownerPath = substr($ownerPath, strlen('/files'));
 		$ownerPath = $this->util->stripPartialFileExtension($ownerPath);
 
+
+		// first get the shares for the parent and cache the result so that we don't
+		// need to check all parents for every file
+		$parent = dirname($ownerPath);
+		if (isset($this->cache[$parent])) {
+			$resultForParents = $this->cache[$parent];
+		} else {
+			$resultForParents = \OCP\Share::getUsersSharingFile($parent, $owner);
+			$this->cache[$parent] = $resultForParents;
+		}
+		$userIds = \array_merge($userIds, $resultForParents['users']);
+		$public = $resultForParents['public'] || $resultForParents['remote'];
+
+
 		// Find out who, if anyone, is sharing the file
-		$result = \OCP\Share::getUsersSharingFile($ownerPath, $owner);
-		$userIds = \array_merge($userIds, $result['users']);
-		$public = $result['public'] || $result['remote'];
+		$resultForFile = \OCP\Share::getUsersSharingFile($ownerPath, $owner, false, false, false);
+		$userIds = \array_merge($userIds, $resultForFile['users']);
+		$public = $resultForFile['public'] || $resultForFile['remote'] || $public;
 
 		// check if it is a group mount
 		if (\OCP\App::isEnabled("files_external")) {
diff --git a/lib/private/share/share.php b/lib/private/share/share.php
index e79b2204a6..0693a9c08f 100644
--- a/lib/private/share/share.php
+++ b/lib/private/share/share.php
@@ -122,11 +122,12 @@ class Share extends Constants {
 	 * @param string $ownerUser owner of the file
 	 * @param boolean $includeOwner include owner to the list of users with access to the file
 	 * @param boolean $returnUserPaths Return an array with the user => path map
+	 * @param boolean $recursive take all parent folders into account (default true)
 	 * @return array
 	 * @note $path needs to be relative to user data dir, e.g. 'file.txt'
 	 *       not '/admin/data/file.txt'
 	 */
-	public static function getUsersSharingFile($path, $ownerUser, $includeOwner = false, $returnUserPaths = false) {
+	public static function getUsersSharingFile($path, $ownerUser, $includeOwner = false, $returnUserPaths = false, $recursive = true) {
 
 		Filesystem::initMountPoints($ownerUser);
 		$shares = $sharePaths = $fileTargets = array();
@@ -252,7 +253,7 @@ class Share extends Constants {
 
 			// let's get the parent for the next round
 			$meta = $cache->get((int)$source);
-			if($meta !== false) {
+			if ($recursive === true && $meta !== false) {
 				$source = (int)$meta['parent'];
 			} else {
 				$source = -1;
diff --git a/lib/public/share.php b/lib/public/share.php
index 68f278005e..4e7323c40f 100644
--- a/lib/public/share.php
+++ b/lib/public/share.php
@@ -80,13 +80,14 @@ class Share extends \OC\Share\Constants {
 	 * @param string $ownerUser owner of the file
 	 * @param bool $includeOwner include owner to the list of users with access to the file
 	 * @param bool $returnUserPaths Return an array with the user => path map
+	 * @param bool $recursive take parent folders into account
 	 * @return array
 	 * @note $path needs to be relative to user data dir, e.g. 'file.txt'
-	 *       not '/admin/data/file.txt'
-	 * @since 5.0.0
+	 *       not '/admin/files/file.txt'
+	 * @since 5.0.0 - $recursive was added in 8.2.0
 	 */
-	public static function getUsersSharingFile($path, $ownerUser, $includeOwner = false, $returnUserPaths = false) {
-		return \OC\Share\Share::getUsersSharingFile($path, $ownerUser, $includeOwner, $returnUserPaths);
+	public static function getUsersSharingFile($path, $ownerUser, $includeOwner = false, $returnUserPaths = false, $recursive = true) {
+		return \OC\Share\Share::getUsersSharingFile($path, $ownerUser, $includeOwner, $returnUserPaths, $recursive);
 	}
 
 	/**
-- 
GitLab