diff --git a/lib/private/Collaboration/Collaborators/Search.php b/lib/private/Collaboration/Collaborators/Search.php index 78b57b5240062..19fa6dadca821 100644 --- a/lib/private/Collaboration/Collaborators/Search.php +++ b/lib/private/Collaboration/Collaborators/Search.php @@ -87,6 +87,10 @@ public function registerPlugin(array $pluginInfo): void { $this->pluginList[$shareType][] = $pluginInfo['class']; } + /** + * Removes all mail shares where a remote share with the same label exists. + * Remote shares are considered "better" than mail shares, so we hide the "worse" shares in case both are possible. + */ protected function dropMailSharesWhereRemoteShareIsPossible(ISearchResult $searchResult): void { $allResults = $searchResult->asArray(); @@ -98,21 +102,14 @@ protected function dropMailSharesWhereRemoteShareIsPossible(ISearchResult $searc return; } - $mailIdMap = []; + $mails = []; foreach ($allResults[$emailType->getLabel()] as $mailRow) { - // sure, array_reduce looks nicer, but foreach needs less resources and is faster - if (!isset($mailRow['uuid'])) { - continue; - } - $mailIdMap[$mailRow['uuid']] = $mailRow['value']['shareWith']; + $mails[] = $mailRow['value']['shareWith']; } - foreach ($allResults[$remoteType->getLabel()] as $resultRow) { - if (!isset($resultRow['uuid'])) { - continue; - } - if (isset($mailIdMap[$resultRow['uuid']])) { - $searchResult->removeCollaboratorResult($emailType, $mailIdMap[$resultRow['uuid']]); + foreach ($allResults[$remoteType->getLabel()] as $remoteRow) { + if (in_array($remoteRow['value']['shareWith'], $mails, true)) { + $searchResult->removeCollaboratorResult($emailType, $remoteRow['value']['shareWith']); } } } diff --git a/lib/private/Collaboration/Collaborators/SearchResult.php b/lib/private/Collaboration/Collaborators/SearchResult.php index 73c0fed41e03e..99bd307fa4fdc 100644 --- a/lib/private/Collaboration/Collaborators/SearchResult.php +++ b/lib/private/Collaboration/Collaborators/SearchResult.php @@ -78,6 +78,8 @@ public function removeCollaboratorResult(SearchResultType $type, string $collabo foreach ($resultArray as $k => $result) { if ($result['value']['shareWith'] === $collaboratorId) { unset($resultArray[$k]); + // Ensure no gaps after removing the result + $resultArray = array_values($resultArray); $actionDone = true; } } diff --git a/tests/lib/Collaboration/Collaborators/SearchTest.php b/tests/lib/Collaboration/Collaborators/SearchTest.php index 3e43d6331b2b7..e59cd42242f2e 100644 --- a/tests/lib/Collaboration/Collaborators/SearchTest.php +++ b/tests/lib/Collaboration/Collaborators/SearchTest.php @@ -249,6 +249,42 @@ public function dataSearchSharees() { ], false, // expected more results indicator ], + // Remove emails if there is a remote with same label even if non exact match + [ + 'test@example', + [IShare::TYPE_REMOTE, IShare::TYPE_EMAIL], + 1, + 10, + [], + [], + [ + 'results' => [ + ['label' => 'remote', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'test@example.com']], + ['label' => 'remote', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'alice@example.com']], + ], + 'exact' => [], + 'exactIdMatch' => false, + ], + [ + ['label' => 'email', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'test@example.com']], + ['label' => 'email', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'bob@example.com']], + ], + [ + 'exact' => [ + 'remotes' => [], + 'emails' => [], + ], + 'remotes' => [ + ['label' => 'remote', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'test@example.com']], + ['label' => 'remote', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'alice@example.com']], + ], + 'emails' => [ + // test@example.com email is not present + ['label' => 'email', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'bob@example.com']], + ] + ], + false, + ], ]; } }