Skip to content

Commit

Permalink
Merge pull request #891 from nextcloud/us_25810
Browse files Browse the repository at this point in the history
[OC] Fix unmerged shares repair targetdecision
  • Loading branch information
MorrisJobke authored Aug 30, 2016
2 parents 7278bd2 + df9b509 commit 4afe4bd
Show file tree
Hide file tree
Showing 2 changed files with 216 additions and 45 deletions.
50 changes: 48 additions & 2 deletions lib/private/Repair/RepairUnmergedShares.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ private function buildPreparedQueries() {
*/
$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')))
Expand Down Expand Up @@ -148,6 +148,52 @@ private function getSharesWithUser($shareType, $shareWiths) {
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
Expand All @@ -171,7 +217,7 @@ private function fixThisShare($groupShares, $subShares) {
return false;
}

$targetPath = $groupShares[0]['file_target'];
$targetPath = $this->findBestTargetName($groupShares, $subShares);

// check whether the user opted out completely of all subshares
$optedOut = true;
Expand Down
Loading

0 comments on commit 4afe4bd

Please sign in to comment.