Skip to content

Commit

Permalink
Merge pull request #3344 from nextcloud/enh/paginated-search-for-boar…
Browse files Browse the repository at this point in the history
…ds-and-cards
  • Loading branch information
juliusknorr authored Oct 4, 2021
2 parents ede6a05 + b533d11 commit c706fb7
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 19 deletions.
78 changes: 62 additions & 16 deletions lib/Search/DeckProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,29 +63,52 @@ public function getName(): string {
}

public function search(IUser $user, ISearchQuery $query): SearchResult {
$cursor = $query->getCursor() !== null ? (int)$query->getCursor() : null;
$boardResults = $this->searchService->searchBoards($query->getTerm(), $query->getLimit(), $cursor);
$cardResults = $this->searchService->searchCards($query->getTerm(), $query->getLimit(), $cursor);
$results = array_merge(
array_map(function (Board $board) {
return new BoardSearchResultEntry($board, $this->urlGenerator);
}, $boardResults),
array_map(function (Card $card) {
return new CardSearchResultEntry($card->getRelatedBoard(), $card->getRelatedStack(), $card, $this->urlGenerator);
}, $cardResults)
);
$cursor = $query->getCursor();
[$boardCursor, $cardCursor] = $this->parseCursor($cursor);

$boardObjects = $this->searchService->searchBoards($query->getTerm(), $query->getLimit(), $boardCursor);
$boardResults = array_map(function (Board $board) {
return [
'object' => $board,
'entry' => new BoardSearchResultEntry($board, $this->urlGenerator)
];
}, $boardObjects);

$cardObjects = $this->searchService->searchCards($query->getTerm(), $query->getLimit(), $cardCursor);
$cardResults = array_map(function (Card $card) {
return [
'object' => $card,
'entry' => new CardSearchResultEntry($card->getRelatedBoard(), $card->getRelatedStack(), $card, $this->urlGenerator)
];
}, $cardObjects);

$results = array_merge($boardResults, $cardResults);

usort($results, function ($a, $b) {
$ta = $a['object']->getLastModified();
$tb = $b['object']->getLastModified();
return $ta === $tb
? 0
: ($ta > $tb ? -1 : 1);
});

$resultEntries = array_map(function (array $result) {
return $result['entry'];
}, $results);

if (count($cardResults) < $query->getLimit()) {
// if both cards and boards results are less then the limit, we know we won't get more
if (count($resultEntries) < $query->getLimit()) {
return SearchResult::complete(
'Deck',
$results
$resultEntries
);
}


$newCursor = $this->getNewCursor($boardObjects, $cardObjects);
return SearchResult::paginated(
'Deck',
$results,
$cardResults[count($results) - 1]->getLastModified()
$resultEntries,
$newCursor
);
}

Expand All @@ -95,4 +118,27 @@ public function getOrder(string $route, array $routeParameters): int {
}
return 10;
}

private function parseCursor(?string $cursor): array {
$boardCursor = null;
$cardCursor = null;
if ($cursor !== null) {
$splitCursor = explode('|', $cursor);
if (count($splitCursor) >= 2) {
$boardCursor = (int)$splitCursor[0] ?: null;
$cardCursor = (int)$splitCursor[1] ?: null;
}
}
return [$boardCursor, $cardCursor];
}

private function getNewCursor(array $boards, array $cards): string {
$boardTimestamps = array_map(function (Board $board) {
return $board->getLastModified();
}, $boards);
$cardTimestamps = array_map(function (Card $card) {
return $card->getLastModified();
}, $cards);
return (min($boardTimestamps) ?: '') . '|' . (min($cardTimestamps) ?: '');
}
}
21 changes: 18 additions & 3 deletions lib/Service/SearchService.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public function searchCards(string $term, int $limit = null, ?int $cursor = null
return $board->getId();
}, $boards);
$matchedCards = $this->cardMapper->search($boardIds, $this->filterStringParser->parse($term), $limit, $cursor);

$self = $this;
return array_map(function (Card $card) use ($self) {
$self->cardService->enrich($card);
Expand All @@ -91,9 +91,24 @@ public function searchCards(string $term, int $limit = null, ?int $cursor = null

public function searchBoards(string $term, ?int $limit, ?int $cursor): array {
$boards = $this->boardService->getUserBoards();
return array_filter($boards, static function (Board $board) use ($term) {
return mb_stripos(mb_strtolower($board->getTitle()), mb_strtolower($term)) > -1;
// get boards that have a lastmodified date which is lower than the cursor
// and which match the search term
$filteredBoards = array_filter($boards, static function (Board $board) use ($term, $cursor) {
return (
($cursor === null || $board->getLastModified() < $cursor)
&& mb_stripos(mb_strtolower($board->getTitle()), mb_strtolower($term)) > -1
);
});
// sort the boards, recently modified first
usort($filteredBoards, function ($boardA, $boardB) {
$ta = $boardA->getLastModified();
$tb = $boardB->getLastModified();
return $ta === $tb
? 0
: ($ta > $tb ? -1 : 1);
});
// limit the number of results
return array_slice($filteredBoards, 0, $limit);
}

public function searchComments(string $term, ?int $limit = null, ?int $cursor = null): array {
Expand Down

0 comments on commit c706fb7

Please sign in to comment.