diff options
author | Morris Jobke <hey@morrisjobke.de> | 2016-08-30 08:22:34 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-08-30 08:22:34 +0200 |
commit | 4afe4bda2686ebb770b7574e87573a2cf708cd4c (patch) | |
tree | 9d7fa5cb77e2e36982b87fddad54a7a3d39ac1bc /lib | |
parent | 7278bd29872aa27ecfbb1974d373b1a3e29244df (diff) | |
parent | df9b509ed33ef6e3041b76b4b7ce1b22c7d81fcc (diff) | |
download | nextcloud-server-4afe4bda2686ebb770b7574e87573a2cf708cd4c.tar.gz nextcloud-server-4afe4bda2686ebb770b7574e87573a2cf708cd4c.zip |
Merge pull request #891 from nextcloud/us_25810
[OC] Fix unmerged shares repair targetdecision
Diffstat (limited to 'lib')
-rw-r--r-- | lib/private/Repair/RepairUnmergedShares.php | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/lib/private/Repair/RepairUnmergedShares.php b/lib/private/Repair/RepairUnmergedShares.php index 353877bb873..d57bc3779f8 100644 --- a/lib/private/Repair/RepairUnmergedShares.php +++ b/lib/private/Repair/RepairUnmergedShares.php @@ -93,7 +93,7 @@ class RepairUnmergedShares implements IRepairStep { */ $query = $this->connection->getQueryBuilder(); $query - ->select('item_source', 'id', 'file_target', 'permissions', 'parent', 'share_type') + ->select('item_source', 'id', 'file_target', 'permissions', 'parent', 'share_type', 'stime') ->from('share') ->where($query->expr()->eq('share_type', $query->createParameter('shareType'))) ->andWhere($query->expr()->in('share_with', $query->createParameter('shareWiths'))) @@ -148,6 +148,52 @@ class RepairUnmergedShares implements IRepairStep { return $groupedShares; } + private function isPotentialDuplicateName($name) { + return (preg_match('/\(\d+\)(\.[^\.]+)?$/', $name) === 1); + } + + /** + * Decide on the best target name based on all group shares and subshares, + * goal is to increase the likeliness that the chosen name matches what + * the user is expecting. + * + * For this, we discard the entries with parenthesis "(2)". + * In case the user also renamed the duplicates to a legitimate name, this logic + * will still pick the most recent one as it's the one the user is most likely to + * remember renaming. + * + * If no suitable subshare is found, use the least recent group share instead. + * + * @param array $groupShares group share entries + * @param array $subShares sub share entries + * + * @return string chosen target name + */ + private function findBestTargetName($groupShares, $subShares) { + $pickedShare = null; + // sort by stime, this also properly sorts the direct user share if any + @usort($subShares, function($a, $b) { + return ((int)$a['stime'] - (int)$b['stime']); + }); + + foreach ($subShares as $subShare) { + // skip entries that have parenthesis with numbers + if ($this->isPotentialDuplicateName($subShare['file_target'])) { + continue; + } + // pick any share found that would match, the last being the most recent + $pickedShare = $subShare; + } + + // no suitable subshare found + if ($pickedShare === null) { + // use least recent group share target instead + $pickedShare = $groupShares[0]; + } + + return $pickedShare['file_target']; + } + /** * Fix the given received share represented by the set of group shares * and matching sub shares @@ -171,7 +217,7 @@ class RepairUnmergedShares implements IRepairStep { return false; } - $targetPath = $groupShares[0]['file_target']; + $targetPath = $this->findBestTargetName($groupShares, $subShares); // check whether the user opted out completely of all subshares $optedOut = true; |