[Pkg-owncloud-commits] [owncloud] 157/258: generateTarget() will always find a unique target

David Prévot taffit at moszumanska.debian.org
Sat Oct 11 17:22:31 UTC 2014


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch master
in repository owncloud.

commit 97dba2e022aa1d2431b97efa01ec158bf3979040
Author: Bjoern Schiessle <schiessle at owncloud.com>
Date:   Fri Aug 22 15:59:44 2014 +0200

    generateTarget() will always find a unique target
---
 lib/private/share/helper.php | 117 +++++++++++++++----------------------------
 lib/private/share/share.php  |  59 +++++++++++++++-------
 2 files changed, 80 insertions(+), 96 deletions(-)

diff --git a/lib/private/share/helper.php b/lib/private/share/helper.php
index 46e3c28..0c679b2 100644
--- a/lib/private/share/helper.php
+++ b/lib/private/share/helper.php
@@ -35,8 +35,7 @@ class Helper extends \OC\Share\Constants {
 	 * @throws \Exception
 	 * @return string Item target
 	 */
-	public static function generateTarget($itemType, $itemSource, $shareType, $shareWith, $uidOwner,
-		$suggestedTarget = null, $groupParent = null) {
+	public static function generateTarget($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $suggestedTarget = null, $groupParent = null) {
 		$backend = \OC\Share\Share::getBackend($itemType);
 		if ($shareType == self::SHARE_TYPE_LINK) {
 			if (isset($suggestedTarget)) {
@@ -58,87 +57,51 @@ class Helper extends \OC\Share\Constants {
 			} else {
 				$userAndGroups = false;
 			}
-			$exclude = null;
-			// Backend has 3 opportunities to generate a unique target
-			for ($i = 0; $i < 2; $i++) {
-				// Check if suggested target exists first
-				if ($i == 0 && isset($suggestedTarget)) {
-					$target = $suggestedTarget;
+			$exclude = array();
+			// Find similar targets to improve backend's chances to generate a unqiue target
+			if ($userAndGroups) {
+				if ($column == 'file_target') {
+					$checkTargets = \OC_DB::prepare('SELECT `' . $column . '` FROM `*PREFIX*share`'
+									. ' WHERE `item_type` IN (\'file\', \'folder\')'
+									. ' AND `share_type` IN (?,?,?)'
+									. ' AND `share_with` IN (\'' . implode('\',\'', $userAndGroups) . '\')');
+					$result = $checkTargets->execute(array(self::SHARE_TYPE_USER, self::SHARE_TYPE_GROUP,
+						self::$shareTypeGroupUserUnique));
 				} else {
-					if ($shareType == self::SHARE_TYPE_GROUP) {
-						$target = $backend->generateTarget($itemSource, false, $exclude);
-					} else {
-						$target = $backend->generateTarget($itemSource, $shareWith, $exclude);
-					}
-					if (is_array($exclude) && in_array($target, $exclude)) {
-						break;
-					}
+					$checkTargets = \OC_DB::prepare('SELECT `' . $column . '` FROM `*PREFIX*share`'
+									. ' WHERE `item_type` = ? AND `share_type` IN (?,?,?)'
+									. ' AND `share_with` IN (\'' . implode('\',\'', $userAndGroups) . '\')');
+					$result = $checkTargets->execute(array($itemType, self::SHARE_TYPE_USER,
+						self::SHARE_TYPE_GROUP, self::$shareTypeGroupUserUnique));
 				}
-				// Check if target already exists
-				$checkTarget = \OC\Share\Share::getItems($itemType, $target, $shareType, $shareWith);
-				if (!empty($checkTarget)) {
-					foreach ($checkTarget as $item) {
-						// Skip item if it is the group parent row
-						if (isset($groupParent) && $item['id'] == $groupParent) {
-							if (count($checkTarget) == 1) {
-								return $target;
-							} else {
-								continue;
-							}
-						}
-						if ($item['uid_owner'] == $uidOwner) {
-							if ($itemType == 'file' || $itemType == 'folder') {
-								$meta = \OC\Files\Filesystem::getFileInfo($itemSource);
-								if ($item['file_source'] == $meta['fileid']) {
-									return $target;
-								}
-							} else if ($item['item_source'] == $itemSource) {
-								return $target;
-							}
-						}
-					}
-					if (!isset($exclude)) {
-						$exclude = array();
-					}
-					// Find similar targets to improve backend's chances to generate a unqiue target
-					if ($userAndGroups) {
-						if ($column == 'file_target') {
-							$checkTargets = \OC_DB::prepare('SELECT `'.$column.'` FROM `*PREFIX*share`'
-								.' WHERE `item_type` IN (\'file\', \'folder\')'
-								.' AND `share_type` IN (?,?,?)'
-								.' AND `share_with` IN (\''.implode('\',\'', $userAndGroups).'\')');
-							$result = $checkTargets->execute(array(self::SHARE_TYPE_USER, self::SHARE_TYPE_GROUP,
-								self::$shareTypeGroupUserUnique));
-						} else {
-							$checkTargets = \OC_DB::prepare('SELECT `'.$column.'` FROM `*PREFIX*share`'
-								.' WHERE `item_type` = ? AND `share_type` IN (?,?,?)'
-								.' AND `share_with` IN (\''.implode('\',\'', $userAndGroups).'\')');
-							$result = $checkTargets->execute(array($itemType, self::SHARE_TYPE_USER,
-								self::SHARE_TYPE_GROUP, self::$shareTypeGroupUserUnique));
-						}
-					} else {
-						if ($column == 'file_target') {
-							$checkTargets = \OC_DB::prepare('SELECT `'.$column.'` FROM `*PREFIX*share`'
-								.' WHERE `item_type` IN (\'file\', \'folder\')'
-								.' AND `share_type` = ? AND `share_with` = ?');
-							$result = $checkTargets->execute(array(self::SHARE_TYPE_GROUP, $shareWith));
-						} else {
-							$checkTargets = \OC_DB::prepare('SELECT `'.$column.'` FROM `*PREFIX*share`'
-								.' WHERE `item_type` = ? AND `share_type` = ? AND `share_with` = ?');
-							$result = $checkTargets->execute(array($itemType, self::SHARE_TYPE_GROUP, $shareWith));
-						}
-					}
-					while ($row = $result->fetchRow()) {
-						$exclude[] = $row[$column];
-					}
+			} else {
+				if ($column == 'file_target') {
+					$checkTargets = \OC_DB::prepare('SELECT `' . $column . '` FROM `*PREFIX*share`'
+									. ' WHERE `item_type` IN (\'file\', \'folder\')'
+									. ' AND `share_type` = ? AND `share_with` = ?');
+					$result = $checkTargets->execute(array(self::SHARE_TYPE_GROUP, $shareWith));
 				} else {
-					return $target;
+					$checkTargets = \OC_DB::prepare('SELECT `' . $column . '` FROM `*PREFIX*share`'
+									. ' WHERE `item_type` = ? AND `share_type` = ? AND `share_with` = ?');
+					$result = $checkTargets->execute(array($itemType, self::SHARE_TYPE_GROUP, $shareWith));
 				}
 			}
+			while ($row = $result->fetchRow()) {
+				$exclude[] = $row[$column];
+			}
+
+			// Check if suggested target exists first
+			if (!isset($suggestedTarget)) {
+				$suggestedTarget = $itemSource;
+			}
+			if ($shareType == self::SHARE_TYPE_GROUP) {
+				$target = $backend->generateTarget($suggestedTarget, false, $exclude);
+			} else {
+				$target = $backend->generateTarget($suggestedTarget, $shareWith, $exclude);
+			}
+
+			return $target;
 		}
-		$message = 'Sharing backend registered for '.$itemType.' did not generate a unique target for '.$itemSource;
-		\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
-		throw new \Exception($message);
 	}
 
 	/**
diff --git a/lib/private/share/share.php b/lib/private/share/share.php
index 4405140..c16ef5a 100644
--- a/lib/private/share/share.php
+++ b/lib/private/share/share.php
@@ -296,7 +296,7 @@ class Share extends \OC\Share\Constants {
 
 		// first check if there is a db entry for the specific user
 		$query = \OC_DB::prepare(
-				'SELECT `file_target`, `permissions`, `expiration`
+				'SELECT `file_target`, `item_target`, `permissions`, `expiration`
 					FROM
 					`*PREFIX*share`
 					WHERE
@@ -1290,13 +1290,17 @@ class Share extends \OC\Share\Constants {
 				$queryArgs = array_merge($queryArgs, $collectionTypes);
 			}
 		}
+
+		if ($shareType == self::$shareTypeUserAndGroups) {
+			// Make sure the unique user target is returned if it exists,
+			// unique targets should follow the group share in the database
+			// If the limit is not 1, the filtering can be done later
+			$where .= ' ORDER BY `*PREFIX*share`.`id` DESC';
+		} else {
+			$where .= ' ORDER BY `*PREFIX*share`.`id` ASC';
+		}
+
 		if ($limit != -1 && !$includeCollections) {
-			if ($shareType == self::$shareTypeUserAndGroups) {
-				// Make sure the unique user target is returned if it exists,
-				// unique targets should follow the group share in the database
-				// If the limit is not 1, the filtering can be done later
-				$where .= ' ORDER BY `*PREFIX*share`.`id` ASC';
-			}
 			// The limit must be at least 3, because filtering needs to be done
 			if ($limit < 3) {
 				$queryLimit = 3;
@@ -1305,7 +1309,6 @@ class Share extends \OC\Share\Constants {
 			}
 		} else {
 			$queryLimit = null;
-			$where .= ' ORDER BY `*PREFIX*share`.`id` ASC';
 		}
 		$select = self::createSelectStatement($format, $fileDependent, $uidOwner);
 		$root = strlen($root);
@@ -1334,10 +1337,10 @@ class Share extends \OC\Share\Constants {
 				}
 			} else if (!isset($uidOwner)) {
 				// Check if the same target already exists
-				if (isset($targets[$row[$column]])) {
+				if (isset($targets[$row['id']])) {
 					// Check if the same owner shared with the user twice
 					// through a group and user share - this is allowed
-					$id = $targets[$row[$column]];
+					$id = $targets[$row['id']];
 					if (isset($items[$id]) && $items[$id]['uid_owner'] == $row['uid_owner']) {
 						// Switch to group share type to ensure resharing conditions aren't bypassed
 						if ($items[$id]['share_type'] != self::SHARE_TYPE_GROUP) {
@@ -1353,12 +1356,12 @@ class Share extends \OC\Share\Constants {
 							unset($items[$id]);
 							$id = $row['id'];
 						}
-						// Combine the permissions for the item
 						$items[$id]['permissions'] |= (int)$row['permissions'];
-						continue;
+
 					}
-				} else {
-					$targets[$row[$column]] = $row['id'];
+					continue;
+				} elseif (!empty($row['parent'])) {
+					$targets[$row['parent']] = $row['id'];
 				}
 			}
 			// Remove root from file source paths if retrieving own shared items
@@ -1413,10 +1416,13 @@ class Share extends \OC\Share\Constants {
 				$row['displayname_owner'] = \OCP\User::getDisplayName($row['uid_owner']);
 			}
 
-			$items[$row['id']] = $row;
+			if ($row['permissions'] > 0) {
+				$items[$row['id']] = $row;
+			}
 
 		}
 
+		// group items if we are looking for items shared with the current user
 		if (isset($shareWith) && $shareWith === \OCP\User::getUser()) {
 			$items = self::groupItems($items, $itemType);
 		}
@@ -1642,7 +1648,8 @@ class Share extends \OC\Share\Constants {
 		}
 
 		foreach ($users as $user) {
-			$sourceExists = self::getItemSharedWithBySource($itemType, $itemSource, self::FORMAT_NONE, null, true, $user);
+			$sourceId = ($itemType === 'file' || $itemType === 'folder') ? $fileSource : $itemSource;
+			$sourceExists = self::getItemSharedWithBySource($itemType, $sourceId, self::FORMAT_NONE, null, true, $user);
 
 			$shareType = ($isGroupShare) ? self::$shareTypeGroupUserUnique : $shareType;
 
@@ -1675,9 +1682,23 @@ class Share extends \OC\Share\Constants {
 				}
 
 			} else {
-                // move to the next user if it is neither a unique group share
-				// nor a single share without adding it to the share table
-				continue;
+
+				// group share which doesn't exists until now, check if we need a unique target for this user
+
+				$itemTarget = Helper::generateTarget($itemType, $itemSource, self::SHARE_TYPE_USER, $user,
+					$uidOwner, $suggestedItemTarget, $parent);
+
+				// do we also need a file target
+				if (isset($fileSource)) {
+					$fileTarget = Helper::generateTarget('file', $filePath, self::SHARE_TYPE_USER, $user,
+							$uidOwner, $suggestedFileTarget, $parent);
+				} else {
+					$fileTarget = null;
+				}
+
+				if ($itemTarget === $groupItemTarget) {
+					continue;
+				}
 			}
 
 			$queriesToExecute[] = array(

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/owncloud.git



More information about the Pkg-owncloud-commits mailing list