diff --git a/lib/Db/BoardMapper.php b/lib/Db/BoardMapper.php index fb05034a9..d585b3ba1 100644 --- a/lib/Db/BoardMapper.php +++ b/lib/Db/BoardMapper.php @@ -94,15 +94,16 @@ class BoardMapper extends DeckMapper implements IPermissionMapper { return $board; } - public function findAllForUser(string $userId, ?int $since = null, bool $includeArchived = true, ?int $before = null): array { - $useCache = ($since === -1 && $includeArchived === true && $before === null); + public function findAllForUser(string $userId, ?int $since = null, bool $includeArchived = true, ?int $before = null, + ?string $term = null): array { + $useCache = ($since === -1 && $includeArchived === true && $before === null && $term === null); if (!isset($this->userBoardCache[$userId]) || !$useCache) { $groups = $this->groupManager->getUserGroupIds( $this->userManager->get($userId) ); - $userBoards = $this->findAllByUser($userId, null, null, $since, $includeArchived, $before); - $groupBoards = $this->findAllByGroups($userId, $groups, null, null, $since, $includeArchived, $before); - $circleBoards = $this->findAllByCircles($userId, null, null, $since, $includeArchived, $before); + $userBoards = $this->findAllByUser($userId, null, null, $since, $includeArchived, $before, $term); + $groupBoards = $this->findAllByGroups($userId, $groups, null, null, $since, $includeArchived, $before, $term); + $circleBoards = $this->findAllByCircles($userId, null, null, $since, $includeArchived, $before, $term); $allBoards = array_unique(array_merge($userBoards, $groupBoards, $circleBoards)); if ($useCache) { $this->userBoardCache[$userId] = $allBoards; @@ -121,7 +122,7 @@ class BoardMapper extends DeckMapper implements IPermissionMapper { * @return array */ public function findAllByUser(string $userId, ?int $limit = null, ?int $offset = null, ?int $since = null, - bool $includeArchived = true, ?int $before = null) { + bool $includeArchived = true, ?int $before = null, ?string $term = null) { // FIXME: One moving to QBMapper we should allow filtering the boards probably by method chaining for additional where clauses $sql = 'SELECT id, title, owner, color, archived, deleted_at, 0 as shared, last_modified FROM `*PREFIX*deck_boards` WHERE owner = ?'; $params = [$userId]; @@ -136,6 +137,10 @@ class BoardMapper extends DeckMapper implements IPermissionMapper { $sql .= ' AND last_modified < ?'; $params[] = $before; } + if ($term !== null) { + $sql .= ' AND lower(title) LIKE ?'; + $params[] = '%' . $term . '%'; + } $sql .= ' UNION ' . 'SELECT boards.id, title, owner, color, archived, deleted_at, 1 as shared, last_modified FROM `*PREFIX*deck_boards` as boards ' . 'JOIN `*PREFIX*deck_board_acl` as acl ON boards.id=acl.board_id WHERE acl.participant=? AND acl.type=? AND boards.owner != ?'; @@ -151,6 +156,10 @@ class BoardMapper extends DeckMapper implements IPermissionMapper { $sql .= ' AND last_modified < ?'; $params[] = $before; } + if ($term !== null) { + $sql .= ' AND lower(title) LIKE ?'; + $params[] = '%' . $term . '%'; + } $entries = $this->findEntities($sql, $params, $limit, $offset); /* @var Board $entry */ foreach ($entries as $entry) { @@ -175,7 +184,7 @@ class BoardMapper extends DeckMapper implements IPermissionMapper { * @return array */ public function findAllByGroups(string $userId, array $groups, ?int $limit = null, ?int $offset = null, ?int $since = null, - bool $includeArchived = true, ?int $before = null) { + bool $includeArchived = true, ?int $before = null, ?string $term = null) { if (count($groups) <= 0) { return []; } @@ -201,6 +210,10 @@ class BoardMapper extends DeckMapper implements IPermissionMapper { $sql .= ' AND last_modified < ?'; $params[] = $before; } + if ($term !== null) { + $sql .= ' AND lower(title) LIKE ?'; + $params[] = '%' . $term . '%'; + } $entries = $this->findEntities($sql, $params, $limit, $offset); /* @var Board $entry */ foreach ($entries as $entry) { @@ -211,7 +224,7 @@ class BoardMapper extends DeckMapper implements IPermissionMapper { } public function findAllByCircles(string $userId, ?int $limit = null, ?int $offset = null, ?int $since = null, - bool $includeArchived = true, ?int $before = null) { + bool $includeArchived = true, ?int $before = null, ?string $term = null) { if (!$this->circlesEnabled) { return []; } @@ -244,6 +257,10 @@ class BoardMapper extends DeckMapper implements IPermissionMapper { $sql .= ' AND last_modified < ?'; $params[] = $before; } + if ($term !== null) { + $sql .= ' AND lower(title) LIKE ?'; + $params[] = '%' . $term . '%'; + } $entries = $this->findEntities($sql, $params, $limit, $offset); /* @var Board $entry */ foreach ($entries as $entry) { diff --git a/lib/Service/BoardService.php b/lib/Service/BoardService.php index f6f55ece4..71cf6172a 100644 --- a/lib/Service/BoardService.php +++ b/lib/Service/BoardService.php @@ -118,8 +118,9 @@ class BoardService { /** * Get all boards that are shared with a user, their groups or circles */ - public function getUserBoards(?int $since = null, bool $includeArchived = true, ?int $before = null): array { - return $this->boardMapper->findAllForUser($this->userId, $since, $includeArchived, $before); + public function getUserBoards(?int $since = null, bool $includeArchived = true, ?int $before = null, + ?string $term = null): array { + return $this->boardMapper->findAllForUser($this->userId, $since, $includeArchived, $before, $term); } /** diff --git a/lib/Service/SearchService.php b/lib/Service/SearchService.php index c38147fd5..11bfedf33 100644 --- a/lib/Service/SearchService.php +++ b/lib/Service/SearchService.php @@ -90,22 +90,19 @@ class SearchService { } public function searchBoards(string $term, ?int $limit, ?int $cursor): array { - $boards = $this->boardService->getUserBoards(null, true, $cursor); - // 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 mb_stripos(mb_strtolower($board->getTitle()), mb_strtolower($term)) > -1; - }); + $boards = $this->boardService->getUserBoards(null, true, $cursor, mb_strtolower($term)); + // sort the boards, recently modified first - usort($filteredBoards, function ($boardA, $boardB) { + usort($boards, 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); + return array_slice($boards, 0, $limit); } public function searchComments(string $term, ?int $limit = null, ?int $cursor = null): array {