diff --git a/lib/Service/CardService.php b/lib/Service/CardService.php index 95dbcf59a..869022dcd 100644 --- a/lib/Service/CardService.php +++ b/lib/Service/CardService.php @@ -28,11 +28,13 @@ namespace OCA\Deck\Service; use OCA\Deck\Activity\ActivityManager; use OCA\Deck\Activity\ChangeSet; +use OCA\Deck\Db\Assignment; use OCA\Deck\Db\AssignmentMapper; use OCA\Deck\Db\Card; use OCA\Deck\Db\CardMapper; use OCA\Deck\Db\Acl; use OCA\Deck\Db\ChangeHelper; +use OCA\Deck\Db\Label; use OCA\Deck\Db\StackMapper; use OCA\Deck\Event\CardCreatedEvent; use OCA\Deck\Event\CardDeletedEvent; @@ -114,32 +116,52 @@ class CardService { $this->cardServiceValidator = $cardServiceValidator; } - public function enrich($card) { - $cardId = $card->getId(); - $this->cardMapper->mapOwner($card); - $card->setAssignedUsers($this->assignedUsersMapper->findAll($cardId)); - $card->setLabels($this->labelMapper->findAssignedLabelsForCard($cardId)); - $card->setAttachmentCount($this->attachmentService->count($cardId)); + public function enrichCards($cards) { $user = $this->userManager->get($this->currentUser); - $lastRead = $this->commentsManager->getReadMark('deckCard', (string)$card->getId(), $user); - $countUnreadComments = $this->commentsManager->getNumberOfCommentsForObject('deckCard', (string)$card->getId(), $lastRead); - $countComments = $this->commentsManager->getNumberOfCommentsForObject('deckCard', (string)$card->getId()); - $card->setCommentsUnread($countUnreadComments); - $card->setCommentsCount($countComments); - $stack = $this->stackMapper->find($card->getStackId()); - $board = $this->boardService->find($stack->getBoardId()); - $card->setRelatedStack($stack); - $card->setRelatedBoard($board); + $cardIds = array_map(function (Card $card) { + // Everything done in here might be heavy as it is executed for every card + $cardId = $card->getId(); + $this->cardMapper->mapOwner($card); + + $card->setAttachmentCount($this->attachmentService->count($cardId)); + + // TODO We should find a better way just to get the comment count so we can save 1-3 queries per card here + $countComments = $this->commentsManager->getNumberOfCommentsForObject('deckCard', (string)$card->getId()); + $lastRead = $countComments > 0 ? $this->commentsManager->getReadMark('deckCard', (string)$card->getId(), $user) : null; + $countUnreadComments = $lastRead ? $this->commentsManager->getNumberOfCommentsForObject('deckCard', (string)$card->getId(), $lastRead) : 0; + $card->setCommentsUnread($countUnreadComments); + $card->setCommentsCount($countComments); + + $stack = $this->stackMapper->find($card->getStackId()); + $board = $this->boardService->find($stack->getBoardId(), false); + $card->setRelatedStack($stack); + $card->setRelatedBoard($board); + + return $card->getId(); + }, $cards); + + $assignedLabels = $this->labelMapper->findAssignedLabelsForCards($cardIds); + $assignedUsers = $this->assignedUsersMapper->findIn($cardIds); + + foreach ($cards as $card) { + $cardLabels = array_filter($assignedLabels, function (Label $label) use ($card) { + return $label->getCardId() === $card->getId(); + }); + $cardAssignedUsers = array_filter($assignedUsers, function (Assignment $label) use ($card) { + return $label->getCardId() === $card->getId(); + }); + $card->setLabels($cardLabels); + $card->setAssignedUsers($cardAssignedUsers); + } + + return $cards; } - public function fetchDeleted($boardId) { $this->cardServiceValidator->check(compact('boardId')); $this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_READ); $cards = $this->cardMapper->findDeleted($boardId); - foreach ($cards as $card) { - $this->enrich($card); - } + $this->enrichCards($cards); return $cards; } @@ -162,7 +184,7 @@ class CardService { } $card->setAssignedUsers($assignedUsers); $card->setAttachments($attachments); - $this->enrich($card); + $this->enrichCards([$card]); return $card; } @@ -174,9 +196,7 @@ class CardService { return []; } $cards = $this->cardMapper->findCalendarEntries($boardId); - foreach ($cards as $card) { - $this->enrich($card); - } + $this->enrichCards($cards); return $cards; } diff --git a/lib/Service/OverviewService.php b/lib/Service/OverviewService.php index 8b8b07511..52426c12d 100644 --- a/lib/Service/OverviewService.php +++ b/lib/Service/OverviewService.php @@ -35,8 +35,10 @@ use OCP\Comments\ICommentsManager; use OCA\Deck\Db\BoardMapper; use OCA\Deck\Db\LabelMapper; use OCP\IUserManager; +use OCP\IUserSession; class OverviewService { + private CardService $cardService; private BoardMapper $boardMapper; private LabelMapper $labelMapper; private CardMapper $cardMapper; @@ -46,6 +48,7 @@ class OverviewService { private AttachmentService $attachmentService; public function __construct( + CardService $cardService, BoardMapper $boardMapper, LabelMapper $labelMapper, CardMapper $cardMapper, @@ -54,6 +57,7 @@ class OverviewService { ICommentsManager $commentsManager, AttachmentService $attachmentService ) { + $this->cardService = $cardService; $this->boardMapper = $boardMapper; $this->labelMapper = $labelMapper; $this->cardMapper = $cardMapper; @@ -63,32 +67,15 @@ class OverviewService { $this->attachmentService = $attachmentService; } - public function enrich(Card $card, string $userId): void { - $cardId = $card->getId(); - - $this->cardMapper->mapOwner($card); - $card->setAssignedUsers($this->assignedUsersMapper->findAll($cardId)); - $card->setLabels($this->labelMapper->findAssignedLabelsForCard($cardId)); - $card->setAttachmentCount($this->attachmentService->count($cardId)); - - $user = $this->userManager->get($userId); - if ($user !== null) { - $lastRead = $this->commentsManager->getReadMark('deckCard', (string)$card->getId(), $user); - $count = $this->commentsManager->getNumberOfCommentsForObject('deckCard', (string)$card->getId(), $lastRead); - $card->setCommentsUnread($count); - } - } - public function findAllWithDue(string $userId): array { $userBoards = $this->boardMapper->findAllForUser($userId); $allDueCards = []; foreach ($userBoards as $userBoard) { $allDueCards[] = array_map(function ($card) use ($userBoard, $userId) { - $this->enrich($card, $userId); return (new CardDetails($card, $userBoard))->jsonSerialize(); }, $this->cardMapper->findAllWithDue($userBoard->getId())); } - return array_merge(...$allDueCards); + return $this->cardService->enrichCards(array_merge(...$allDueCards)); } public function findUpcomingCards(string $userId): array { @@ -103,26 +90,29 @@ class OverviewService { $cards = $this->cardMapper->findToMeOrNotAssignedCards($userBoard->getId(), $userId); } - foreach ($cards as $card) { - $this->enrich($card, $userId); - $diffDays = $card->getDaysUntilDue(); + $foundCards[] = $cards; + } - $key = 'later'; - if ($diffDays === null) { - $key = 'nodue'; - } elseif ($diffDays < 0) { - $key = 'overdue'; - } elseif ($diffDays === 0) { - $key = 'today'; - } elseif ($diffDays === 1) { - $key = 'tomorrow'; - } elseif ($diffDays <= 7) { - $key = 'nextSevenDays'; - } + $foundCards = array_merge(...$foundCards); + $this->cardService->enrichCards($foundCards); + foreach ($foundCards as $card) { + $diffDays = $card->getDaysUntilDue(); - $card = (new CardDetails($card, $userBoard)); - $overview[$key][] = $card->jsonSerialize(); + $key = 'later'; + if ($diffDays === null) { + $key = 'nodue'; + } elseif ($diffDays < 0) { + $key = 'overdue'; + } elseif ($diffDays === 0) { + $key = 'today'; + } elseif ($diffDays === 1) { + $key = 'tomorrow'; + } elseif ($diffDays <= 7) { + $key = 'nextSevenDays'; } + + $card = (new CardDetails($card, $userBoard)); + $overview[$key][] = $card->jsonSerialize(); } return $overview; } diff --git a/lib/Service/SearchService.php b/lib/Service/SearchService.php index 11bfedf33..4c9cefa56 100644 --- a/lib/Service/SearchService.php +++ b/lib/Service/SearchService.php @@ -83,10 +83,7 @@ class SearchService { $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); - return $card; - }, $matchedCards); + return $this->cardService->enrichCards($matchedCards); } public function searchBoards(string $term, ?int $limit, ?int $cursor): array { @@ -117,7 +114,8 @@ class SearchService { $comment = $this->commentsManager->get($cardRow['comment_id']); unset($cardRow['comment_id']); $card = Card::fromRow($cardRow); - $self->cardService->enrich($card); + // TODO: Only perform one enrich call here + $self->cardService->enrichCards([$card]); $user = $this->userManager->get($comment->getActorId()); $displayName = $user ? $user->getDisplayName() : ''; return new CommentSearchResultEntry($comment->getId(), $comment->getMessage(), $displayName, $card, $this->urlGenerator, $this->l10n); diff --git a/lib/Service/StackService.php b/lib/Service/StackService.php index d41c00de0..83ca7d23e 100644 --- a/lib/Service/StackService.php +++ b/lib/Service/StackService.php @@ -94,9 +94,9 @@ class StackService { return; } + $this->cardService->enrichCards($cards); $cards = array_map( function (Card $card): CardDetails { - $this->cardService->enrich($card); return new CardDetails($card); }, $cards