]> source.dussan.org Git - nextcloud-server.git/commitdiff
on unshare only unshare childrens if there is no other parent available
authorBjoern Schiessle <schiessle@owncloud.com>
Fri, 26 Sep 2014 14:58:47 +0000 (16:58 +0200)
committerBjoern Schiessle <schiessle@owncloud.com>
Fri, 26 Sep 2014 14:58:47 +0000 (16:58 +0200)
lib/private/share/helper.php
lib/private/share/share.php

index 7e1cbb273b87cf7bc4f2e61de902059525dc3159..90dd12e9842d9c315199c0035e051df242371527 100644 (file)
@@ -85,10 +85,12 @@ class Helper extends \OC\Share\Constants {
         * @param int $parent Id of item to delete
         * @param bool $excludeParent If true, exclude the parent from the delete (optional)
         * @param string $uidOwner The user that the parent was shared with (optional)
+        * @param int $newParent new parent for the childrens
         */
-       public static function delete($parent, $excludeParent = false, $uidOwner = null) {
+       public static function delete($parent, $excludeParent = false, $uidOwner = null, $newParent = null) {
                $ids = array($parent);
                $deletedItems = array();
+               $changeParent = array();
                $parents = array($parent);
                while (!empty($parents)) {
                        $parents = "'".implode("','", $parents)."'";
@@ -106,8 +108,6 @@ class Helper extends \OC\Share\Constants {
                        // Reset parents array, only go through loop again if items are found
                        $parents = array();
                        while ($item = $result->fetchRow()) {
-                               $ids[] = $item['id'];
-                               $parents[] = $item['id'];
                                $tmpItem = array(
                                        'id' => $item['id'],
                                        'shareWith' => $item['share_with'],
@@ -118,12 +118,28 @@ class Helper extends \OC\Share\Constants {
                                if (isset($item['file_target'])) {
                                        $tmpItem['fileTarget'] = $item['file_target'];
                                }
-                               $deletedItems[] = $tmpItem;
+                               // if we have a new parent for the child we remember the child
+                               // to update the parent, if not we add it to the list of items
+                               // which should be deleted
+                               if ($newParent !== null) {
+                                       $changeParent[] = $item['id'];
+                               } else {
+                                       $deletedItems[] = $tmpItem;
+                                       $ids[] = $item['id'];
+                                       $parents[] = $item['id'];
+                               }
                        }
                }
                if ($excludeParent) {
                        unset($ids[0]);
                }
+
+               if (!empty($changeParent)) {
+                       $idList = "'".implode("','", $changeParent)."'";
+                       $query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `parent` = ? WHERE `id` IN ('.$idList.')');
+                       $query->execute(array($newParent));
+               }
+
                if (!empty($ids)) {
                        $idList = "'".implode("','", $ids)."'";
                        $query = \OC_DB::prepare('DELETE FROM `*PREFIX*share` WHERE `id` IN ('.$idList.')');
index 706c51e4bdc42c063d79fc68e6fd4727c0e2afb0..b34b134ee84f77f2285d2def49ea5fe2eb3ca00f 100644 (file)
@@ -294,23 +294,32 @@ class Share extends \OC\Share\Constants {
 
                $shares = array();
 
+               $column = ($itemType === 'file' || $itemType === 'folder') ? 'file_source' : 'item_source';
+               
+               $where = ' `' . $column . '` = ? AND `item_type` = ? ';
+               $arguments = array($itemSource, $itemType);
+               // for link shares $user === null
+               if ($user !== null) {
+                       $where .= ' AND `share_with` = ? ';
+                       $arguments[] = $user;
+               }
+
                // first check if there is a db entry for the specific user
                $query = \OC_DB::prepare(
-                               'SELECT `file_target`, `item_target`, `permissions`, `expiration`
+                               'SELECT *
                                        FROM
                                        `*PREFIX*share`
-                                       WHERE
-                                       `item_source` = ? AND `item_type` = ? AND `share_with` = ?'
+                                       WHERE' . $where
                                );
 
-               $result = \OC_DB::executeAudited($query, array($itemSource, $itemType, $user));
+               $result = \OC_DB::executeAudited($query, $arguments);
 
                while ($row = $result->fetchRow()) {
                        $shares[] = $row;
                }
 
                //if didn't found a result than let's look for a group share.
-               if(empty($shares)) {
+               if(empty($shares) && $user !== null) {
                        $groups = \OC_Group::getUserGroups($user);
 
                        $query = \OC_DB::prepare(
@@ -318,7 +327,7 @@ class Share extends \OC\Share\Constants {
                                                FROM
                                                `*PREFIX*share`
                                                WHERE
-                                               `item_source` = ? AND `item_type` = ? AND `share_with` in (?)'
+                                               `' . $column . '` = ? AND `item_type` = ? AND `share_with` in (?)'
                                        );
 
                        $result = \OC_DB::executeAudited($query, array($itemSource, $itemType, implode(',', $groups)));
@@ -681,9 +690,31 @@ class Share extends \OC\Share\Constants {
         * @return boolean true on success or false on failure
         */
        public static function unshare($itemType, $itemSource, $shareType, $shareWith) {
-               $item = self::getItems($itemType, $itemSource, $shareType, $shareWith, \OC_User::getUser(),self::FORMAT_NONE, null, 1);
-               if (!empty($item)) {
-                       self::unshareItem($item);
+
+               // check if it is a valid itemType
+               self::getBackend($itemType);
+
+               $items = self::getItemSharedWithUser($itemType, $itemSource, $shareWith);
+
+               $toDelete = array();
+               $newParent = null;
+               $currentUser = \OC_User::getUser();
+               foreach ($items as $item) {
+                       // delete the item with the expected share_type and owner
+                       if ((int)$item['share_type'] === (int)$shareType && $item['uid_owner'] === $currentUser) {
+                               $toDelete = $item;
+                       // if there is more then one result we don't have to delete the children
+                       // but update their parent. For group shares the new parent should always be
+                       // the original group share and not the db entry with the unique name
+                       } else if ((int)$item['share_type'] === \OCP\Share::$shareTypeGroupUserUnique) {
+                               $newParent = $item['parent'];
+                       } else {
+                               $newParent = $item['id'];
+                       }
+               }
+
+               if (!empty($toDelete)) {
+                       self::unshareItem($toDelete, $newParent);
                        return true;
                }
                return false;
@@ -1056,9 +1087,10 @@ class Share extends \OC\Share\Constants {
        /**
         * Unshares a share given a share data array
         * @param array $item Share data (usually database row)
+        * @param int new parent ID
         * @return null
         */
-       protected static function unshareItem(array $item) {
+       protected static function unshareItem(array $item, $newParent = null) {
                // Pass all the vars we have for now, they may be useful
                $hookParams = array(
                        'id'            => $item['id'],
@@ -1075,7 +1107,7 @@ class Share extends \OC\Share\Constants {
                }
 
                \OC_Hook::emit('OCP\Share', 'pre_unshare', $hookParams);
-               $deletedShares = Helper::delete($item['id']);
+               $deletedShares = Helper::delete($item['id'], false, null, $newParent);
                $deletedShares[] = $hookParams;
                $hookParams['deletedShares'] = $deletedShares;
                \OC_Hook::emit('OCP\Share', 'post_unshare', $hookParams);