From 723ce6c8936c61431a36adb4ac0c597f9bbc15af Mon Sep 17 00:00:00 2001 From: Raul Date: Mon, 2 May 2022 16:58:43 +0200 Subject: [PATCH 1/6] Add CardDetails model Signed-off-by: Raul --- lib/Model/CardDetails.php | 83 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 lib/Model/CardDetails.php diff --git a/lib/Model/CardDetails.php b/lib/Model/CardDetails.php new file mode 100644 index 000000000..4703b29fb --- /dev/null +++ b/lib/Model/CardDetails.php @@ -0,0 +1,83 @@ + + * + * @author Raul Ferreira Fuentes + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ +namespace OCA\Deck\Model; + +use DateTime; +use OCA\Deck\Db\Board; +use OCA\Deck\Db\Card; + +class CardDetails extends Card +{ + private Card $card; + private ?Board $board; + + public function __construct( + Card $card, + Board $board = null + ) { + parent::__construct(); + $this->card = $card; + $this->board = $board; + } + + protected function getter($name) { + return $this->card->getter($name); + } + + public function jsonSerialize(): array { + $array = parent::jsonSerialize(); + $array['boardId'] = $this->board->id ?? null; + $array['overdue'] = $this->getDueStatus(); + $array['foo'] = 'bar'; + + unset($array['notified']); + unset($array['descriptionPrev']); + unset($array['relatedStack']); + unset($array['relatedBoard']); + + return $array; + } + + private function getDueStatus(): int { + $today = new DateTime(); + $today->setTime(0, 0); + + $match_date = new DateTime($this->duedate); + $match_date->setTime(0, 0); + + $diff = $today->diff($match_date); + $diffDays = (integer) $diff->format('%R%a'); // Extract days count in interval + + if ($diffDays === 1) { + return self::DUEDATE_NEXT; + } + if ($diffDays === 0) { + return self::DUEDATE_NOW; + } + if ($diffDays < 0) { + return self::DUEDATE_OVERDUE; + } + + return self::DUEDATE_FUTURE; + } +} From 7b7af7580231c44464be7559ec2aa0ad423758d0 Mon Sep 17 00:00:00 2001 From: Raul Date: Tue, 3 May 2022 12:59:58 +0200 Subject: [PATCH 2/6] Update Card serialization (`jsonSerialize` usages) to use CardDetails model Signed-off-by: Raul --- lib/Command/UserExport.php | 5 +++- lib/Controller/SearchController.php | 8 ++++-- lib/Db/CardMapper.php | 15 +++++++++++ lib/Service/OverviewService.php | 41 ++++++++++++----------------- lib/Service/StackService.php | 30 ++++++++++++++------- 5 files changed, 63 insertions(+), 36 deletions(-) diff --git a/lib/Command/UserExport.php b/lib/Command/UserExport.php index 1d73e8dcf..090e2f072 100644 --- a/lib/Command/UserExport.php +++ b/lib/Command/UserExport.php @@ -27,6 +27,7 @@ use OCA\Deck\Db\AssignmentMapper; use OCA\Deck\Db\BoardMapper; use OCA\Deck\Db\CardMapper; use OCA\Deck\Db\StackMapper; +use OCA\Deck\Model\CardDetails; use OCA\Deck\Service\BoardService; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Db\MultipleObjectsReturnedException; @@ -101,7 +102,9 @@ class UserExport extends Command { $fullCard = $this->cardMapper->find($card->getId()); $assignedUsers = $this->assignedUsersMapper->findAll($card->getId()); $fullCard->setAssignedUsers($assignedUsers); - $data[$board->getId()]['stacks'][$stack->getId()]['cards'][] = (array)$fullCard->jsonSerialize(); + + $cardDetails = new CardDetails($fullCard, $fullBoard); + $data[$board->getId()]['stacks'][$stack->getId()]['cards'][] = $cardDetails->jsonSerialize(); } } } diff --git a/lib/Controller/SearchController.php b/lib/Controller/SearchController.php index 154158454..04bd2644e 100644 --- a/lib/Controller/SearchController.php +++ b/lib/Controller/SearchController.php @@ -27,6 +27,7 @@ declare(strict_types=1); namespace OCA\Deck\Controller; use OCA\Deck\Db\Card; +use OCA\Deck\Model\CardDetails; use OCA\Deck\Service\SearchService; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\OCSController; @@ -50,9 +51,12 @@ class SearchController extends OCSController { public function search(string $term, ?int $limit = null, ?int $cursor = null): DataResponse { $cards = $this->searchService->searchCards($term, $limit, $cursor); return new DataResponse(array_map(function (Card $card) { - $json = $card->jsonSerialize(); + $board = $card->getRelatedBoard(); + $json = (new CardDetails($card, $board))->jsonSerialize(); + + $json['relatedBoard'] = $board; $json['relatedStack'] = $card->getRelatedStack(); - $json['relatedBoard'] = $card->getRelatedBoard(); + return $json; }, $cards)); } diff --git a/lib/Db/CardMapper.php b/lib/Db/CardMapper.php index 219588f81..4f62dfa67 100644 --- a/lib/Db/CardMapper.php +++ b/lib/Db/CardMapper.php @@ -226,6 +226,21 @@ class CardMapper extends QBMapper implements IPermissionMapper { return $this->findEntities($qb); } + public function findAllByBoardId(int $boardId, ?int $limit = null, ?int $offset = null): array { + $qb = $this->db->getQueryBuilder(); + $qb->select('c.*') + ->from('deck_cards', 'c') + ->innerJoin('c', 'deck_stacks', 's', 's.id = c.stack_id') + ->innerJoin('s', 'deck_boards', 'b', 'b.id = s.board_id') + ->where($qb->expr()->eq('board_id', $qb->createNamedParameter($boardId, IQueryBuilder::PARAM_INT))) + ->andWhere($qb->expr()->eq('archived', $qb->createNamedParameter(false, IQueryBuilder::PARAM_BOOL))) + ->setMaxResults($limit) + ->setFirstResult($offset) + ->orderBy('c.lastmodified') + ->addOrderBy('c.id'); + return $this->findEntities($qb); + } + public function findAllWithDue($boardId) { $qb = $this->db->getQueryBuilder(); $qb->select('c.*') diff --git a/lib/Service/OverviewService.php b/lib/Service/OverviewService.php index a8bb3990f..3d2152bc3 100644 --- a/lib/Service/OverviewService.php +++ b/lib/Service/OverviewService.php @@ -30,9 +30,9 @@ namespace OCA\Deck\Service; use OCA\Deck\Db\AssignmentMapper; use OCA\Deck\Db\Card; use OCA\Deck\Db\CardMapper; +use OCA\Deck\Model\CardDetails; use OCP\Comments\ICommentsManager; use OCP\IGroupManager; -use OCA\Deck\Db\Board; use OCA\Deck\Db\BoardMapper; use OCA\Deck\Db\LabelMapper; use OCP\IUserManager; @@ -96,42 +96,35 @@ class OverviewService { $userBoards = $this->findAllBoardsFromUser($userId); $allDueCards = []; foreach ($userBoards as $userBoard) { - $service = $this; - $allDueCards[] = array_map(static function ($card) use ($service, $userBoard, $userId) { - $service->enrich($card, $userId); - $cardData = $card->jsonSerialize(); - $cardData['boardId'] = $userBoard->getId(); - return $cardData; + $allDueCards[] = array_map(function ($card) use ($userBoard, $userId) { + $this->enrich($card, $userId); + return (new CardDetails($card, $userBoard))->jsonSerialize(); }, $this->cardMapper->findAllWithDue($userBoard->getId())); } - return $allDueCards; + return array_merge(...$allDueCards); } public function findUpcomingCards(string $userId): array { $userBoards = $this->findAllBoardsFromUser($userId); - $findCards = []; + $foundCards = []; foreach ($userBoards as $userBoard) { - $service = $this; - if (count($userBoard->getAcl()) === 0) { // private board: get cards with due date - $findCards[] = array_map(static function ($card) use ($service, $userBoard, $userId) { - $service->enrich($card, $userId); - $cardData = $card->jsonSerialize(); - $cardData['boardId'] = $userBoard->getId(); - return $cardData; - }, $this->cardMapper->findAllWithDue($userBoard->getId())); + $cards = $this->cardMapper->findAllWithDue($userBoard->getId()); } else { // shared board: get all my assigned or unassigned cards - $findCards[] = array_map(static function ($card) use ($service, $userBoard, $userId) { - $service->enrich($card, $userId); - $cardData = $card->jsonSerialize(); - $cardData['boardId'] = $userBoard->getId(); - return $cardData; - }, $this->cardMapper->findToMeOrNotAssignedCards($userBoard->getId(), $userId)); + $cards = $this->cardMapper->findToMeOrNotAssignedCards($userBoard->getId(), $userId); } + + $foundCards[] = array_map( + function (Card $card) use ($userBoard, $userId) { + $this->enrich($card, $userId); + return new CardDetails($card, $userBoard); + }, + $cards + ); } - return $findCards; + return array_merge(...$foundCards); } // FIXME: This is duplicate code with the board service diff --git a/lib/Service/StackService.php b/lib/Service/StackService.php index 79f659eba..a5fba8c9e 100644 --- a/lib/Service/StackService.php +++ b/lib/Service/StackService.php @@ -30,11 +30,13 @@ use OCA\Deck\BadRequestException; use OCA\Deck\Db\Acl; use OCA\Deck\Db\AssignmentMapper; use OCA\Deck\Db\BoardMapper; +use OCA\Deck\Db\Card; use OCA\Deck\Db\CardMapper; use OCA\Deck\Db\ChangeHelper; use OCA\Deck\Db\LabelMapper; use OCA\Deck\Db\Stack; use OCA\Deck\Db\StackMapper; +use OCA\Deck\Model\CardDetails; use OCA\Deck\NoPermissionException; use OCA\Deck\StatusException; @@ -84,9 +86,13 @@ class StackService { return; } - foreach ($cards as $card) { - $this->cardService->enrich($card); - } + $cards = array_map( + function (Card $card): CardDetails { + $this->cardService->enrich($card); + return new CardDetails($card); + }, + $cards + ); $stack->setCards($cards); } @@ -112,12 +118,18 @@ class StackService { $this->permissionService->checkPermission($this->stackMapper, $stackId, Acl::PERMISSION_READ); $stack = $this->stackMapper->find($stackId); - $cards = $this->cardMapper->findAll($stackId); - foreach ($cards as $cardIndex => $card) { - $assignedUsers = $this->assignedUsersMapper->findAll($card->getId()); - $card->setAssignedUsers($assignedUsers); - $card->setAttachmentCount($this->attachmentService->count($card->getId())); - } + + $cards = array_map( + function (Card $card): CardDetails { + $assignedUsers = $this->assignedUsersMapper->findAll($card->getId()); + $card->setAssignedUsers($assignedUsers); + $card->setAttachmentCount($this->attachmentService->count($card->getId())); + + return new CardDetails($card); + }, + $this->cardMapper->findAll($stackId) + ); + $stack->setCards($cards); return $stack; From 6bf9ba397e73f892f221c1d68c9bbab03ade0d4d Mon Sep 17 00:00:00 2001 From: Raul Date: Tue, 3 May 2022 13:00:51 +0200 Subject: [PATCH 3/6] Add phpDoc typehints for magic methods Signed-off-by: Raul --- lib/Db/Card.php | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/lib/Db/Card.php b/lib/Db/Card.php index 91bc6ab08..9b19c2a84 100644 --- a/lib/Db/Card.php +++ b/lib/Db/Card.php @@ -27,6 +27,43 @@ use DateTime; use DateTimeZone; use Sabre\VObject\Component\VCalendar; +/** + * @method string getTitle() + * @method string getDescription() + * @method string getDescriptionPrev() + * @method int getStackId() + * @method int getLastModified() + * @method int getCreatedAt() + * @method bool getArchived() + * @method bool getNotified() + * + * @method void setLabels(Label[] $labels) + * @method null|Label[] getLabels() + * + * @method void setAssignedUsers(User[] $users) + * @method null|User[] getAssignedUsers() + * + * @method void setAttachments(Attachment[] $attachments) + * @method null|Attachment[] getAttachments() + * + * @method void setAttachmentCount(int $count) + * @method null|int getAttachmentCount() + * + * @method void setCommentsUnread(int $count) + * @method null|int getCommentsUnread() + * + * @method void setCommentsCount(int $count) + * @method null|int getCommentsCount() + * + * @method void setOwner(User $user) + * @method null|User getOwner() + * + * @method void setRelatedStack(Stack $stack) + * @method null|Stack getRelatedStack() + * + * @method void setRelatedBoard(Board $board) + * @method null|Board getRelatedBoard() + */ class Card extends RelationalEntity { public const TITLE_MAX_LENGTH = 255; From ebbafbe55d7b7fa4e456f4474e4031f65ad493ae Mon Sep 17 00:00:00 2001 From: Raul Date: Tue, 3 May 2022 13:01:09 +0200 Subject: [PATCH 4/6] Add board summary model Signed-off-by: Raul --- lib/Db/Card.php | 42 ++++-------------------------- lib/Model/BoardSummary.php | 46 +++++++++++++++++++++++++++++++++ lib/Model/CardDetails.php | 38 +++++++++++++++++---------- lib/Service/OverviewService.php | 2 +- 4 files changed, 76 insertions(+), 52 deletions(-) create mode 100644 lib/Model/BoardSummary.php diff --git a/lib/Db/Card.php b/lib/Db/Card.php index 9b19c2a84..e6823b37b 100644 --- a/lib/Db/Card.php +++ b/lib/Db/Card.php @@ -32,6 +32,7 @@ use Sabre\VObject\Component\VCalendar; * @method string getDescription() * @method string getDescriptionPrev() * @method int getStackId() + * @method int getOrder() * @method int getLastModified() * @method int getCreatedAt() * @method bool getArchived() @@ -40,7 +41,7 @@ use Sabre\VObject\Component\VCalendar; * @method void setLabels(Label[] $labels) * @method null|Label[] getLabels() * - * @method void setAssignedUsers(User[] $users) + * @method void setAssignedUsers(Assignment[] $users) * @method null|User[] getAssignedUsers() * * @method void setAttachments(Attachment[] $attachments) @@ -55,8 +56,8 @@ use Sabre\VObject\Component\VCalendar; * @method void setCommentsCount(int $count) * @method null|int getCommentsCount() * - * @method void setOwner(User $user) - * @method null|User getOwner() + * @method void setOwner(string $user) + * @method null|string getOwner() * * @method void setRelatedStack(Stack $stack) * @method null|Stack getRelatedStack() @@ -91,7 +92,7 @@ class Card extends RelationalEntity { protected $relatedStack = null; protected $relatedBoard = null; - private $databaseType = 'sqlite'; + protected $databaseType = 'sqlite'; public const DUEDATE_FUTURE = 0; public const DUEDATE_NEXT = 1; @@ -135,39 +136,6 @@ class Card extends RelationalEntity { return $dt->format('c'); } - public function jsonSerialize(): array { - $json = parent::jsonSerialize(); - $json['overdue'] = self::DUEDATE_FUTURE; - $due = $this->duedate ? strtotime($this->duedate) : false; - if ($due !== false) { - $today = new DateTime(); - $today->setTime(0, 0); - - $match_date = new DateTime($this->duedate); - - $match_date->setTime(0, 0); - - $diff = $today->diff($match_date); - $diffDays = (integer) $diff->format('%R%a'); // Extract days count in interval - - if ($diffDays === 1) { - $json['overdue'] = self::DUEDATE_NEXT; - } - if ($diffDays === 0) { - $json['overdue'] = self::DUEDATE_NOW; - } - if ($diffDays < 0) { - $json['overdue'] = self::DUEDATE_OVERDUE; - } - } - $json['duedate'] = $this->getDuedate(true); - unset($json['notified']); - unset($json['descriptionPrev']); - unset($json['relatedStack']); - unset($json['relatedBoard']); - return $json; - } - public function getCalendarObject(): VCalendar { $calendar = new VCalendar(); $event = $calendar->createComponent('VTODO'); diff --git a/lib/Model/BoardSummary.php b/lib/Model/BoardSummary.php new file mode 100644 index 000000000..ad5519781 --- /dev/null +++ b/lib/Model/BoardSummary.php @@ -0,0 +1,46 @@ + + * + * @author Raul Ferreira Fuentes + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ +namespace OCA\Deck\Model; + +use OCA\Deck\Db\Board; + +class BoardSummary extends Board +{ + private Board $board; + + public function __construct(Board $board = null) { + parent::__construct(); + $this->board = $board; + } + + public function jsonSerialize(): array { + return [ + 'id' => $this->getId(), + 'title' => $this->getTitle() + ]; + } + + protected function getter($name) { + return $this->board->getter($name); + } +} diff --git a/lib/Model/CardDetails.php b/lib/Model/CardDetails.php index 4703b29fb..08da0ff67 100644 --- a/lib/Model/CardDetails.php +++ b/lib/Model/CardDetails.php @@ -31,30 +31,27 @@ class CardDetails extends Card private Card $card; private ?Board $board; - public function __construct( - Card $card, - Board $board = null - ) { + public function __construct(Card $card, ?Board $board = null) { parent::__construct(); $this->card = $card; $this->board = $board; } - protected function getter($name) { - return $this->card->getter($name); + public function setBoard(?Board $board): void { + $this->board = $board; } - public function jsonSerialize(): array { + public function jsonSerialize(array $extras = []): array { $array = parent::jsonSerialize(); - $array['boardId'] = $this->board->id ?? null; $array['overdue'] = $this->getDueStatus(); - $array['foo'] = 'bar'; unset($array['notified']); unset($array['descriptionPrev']); unset($array['relatedStack']); unset($array['relatedBoard']); + $this->appendBoardDetails($array); + return $array; } @@ -62,22 +59,35 @@ class CardDetails extends Card $today = new DateTime(); $today->setTime(0, 0); - $match_date = new DateTime($this->duedate); + $match_date = new DateTime($this->getDuedate()); $match_date->setTime(0, 0); $diff = $today->diff($match_date); $diffDays = (integer) $diff->format('%R%a'); // Extract days count in interval if ($diffDays === 1) { - return self::DUEDATE_NEXT; + return static::DUEDATE_NEXT; } if ($diffDays === 0) { - return self::DUEDATE_NOW; + return static::DUEDATE_NOW; } if ($diffDays < 0) { - return self::DUEDATE_OVERDUE; + return static::DUEDATE_OVERDUE; } - return self::DUEDATE_FUTURE; + return static::DUEDATE_FUTURE; + } + + private function appendBoardDetails(&$array): void { + if (!$this->board) { + return; + } + + $array['boardId'] = $this->board->id; + $array['board'] = (new BoardSummary($this->board))->jsonSerialize(); + } + + protected function getter($name) { + return $this->card->getter($name); } } diff --git a/lib/Service/OverviewService.php b/lib/Service/OverviewService.php index 3d2152bc3..1a3ab3d45 100644 --- a/lib/Service/OverviewService.php +++ b/lib/Service/OverviewService.php @@ -119,7 +119,7 @@ class OverviewService { $foundCards[] = array_map( function (Card $card) use ($userBoard, $userId) { $this->enrich($card, $userId); - return new CardDetails($card, $userBoard); + return (new CardDetails($card, $userBoard))->jsonSerialize(); }, $cards ); From 9369a697e3152d6e071e90ec63496f9aeaf5ce7d Mon Sep 17 00:00:00 2001 From: Raul Date: Wed, 4 May 2022 17:44:25 +0200 Subject: [PATCH 5/6] Add `getDueDateTime` function to expose the duedate in datetime format. Signed-off-by: Raul --- lib/Db/Card.php | 17 ++++++++++------- lib/Model/CardDetails.php | 2 +- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/lib/Db/Card.php b/lib/Db/Card.php index e6823b37b..5599aef76 100644 --- a/lib/Db/Card.php +++ b/lib/Db/Card.php @@ -125,15 +125,18 @@ class Card extends RelationalEntity { $this->databaseType = $type; } - public function getDuedate($isoFormat = false) { - if ($this->duedate === null) { - return null; - } - $dt = new DateTime($this->duedate); + public function getDueDateTime(): ?DateTime { + return $this->duedate ? new DateTime($this->duedate) : null; + } + + public function getDuedate($isoFormat = false): ?string { + $dt = $this->getDueDateTime(); + $format = 'c'; if (!$isoFormat && $this->databaseType === 'mysql') { - return $dt->format('Y-m-d H:i:s'); + $format = 'Y-m-d H:i:s'; } - return $dt->format('c'); + + return $dt ? $dt->format($format) : null; } public function getCalendarObject(): VCalendar { diff --git a/lib/Model/CardDetails.php b/lib/Model/CardDetails.php index 08da0ff67..57e246450 100644 --- a/lib/Model/CardDetails.php +++ b/lib/Model/CardDetails.php @@ -59,7 +59,7 @@ class CardDetails extends Card $today = new DateTime(); $today->setTime(0, 0); - $match_date = new DateTime($this->getDuedate()); + $match_date = $this->getDueDateTime() ?? new DateTime(); $match_date->setTime(0, 0); $diff = $today->diff($match_date); From 9fca104059e35b4afd881f7f9cb74003c6cebe19 Mon Sep 17 00:00:00 2001 From: Raul Date: Thu, 5 May 2022 13:50:16 +0200 Subject: [PATCH 6/6] Pipeline and codestyle fixes Signed-off-by: Raul --- lib/Db/Board.php | 8 ++++++++ lib/Db/Card.php | 3 ++- lib/Model/BoardSummary.php | 9 ++++----- lib/Model/CardDetails.php | 33 ++++++++++++++++----------------- tests/unit/Db/CardTest.php | 9 +++++---- 5 files changed, 35 insertions(+), 27 deletions(-) diff --git a/lib/Db/Board.php b/lib/Db/Board.php index 3b5bea9fe..8cc845c35 100644 --- a/lib/Db/Board.php +++ b/lib/Db/Board.php @@ -23,6 +23,14 @@ namespace OCA\Deck\Db; +/** + * @method int getId() + * @method string getTitle() + * @method int getShared() + * @method bool getArchived() + * @method int getDeletedAt() + * @method int getLastModified() + */ class Board extends RelationalEntity { protected $title; protected $owner; diff --git a/lib/Db/Card.php b/lib/Db/Card.php index 5599aef76..674ee8f8a 100644 --- a/lib/Db/Card.php +++ b/lib/Db/Card.php @@ -92,7 +92,7 @@ class Card extends RelationalEntity { protected $relatedStack = null; protected $relatedBoard = null; - protected $databaseType = 'sqlite'; + private $databaseType = 'sqlite'; public const DUEDATE_FUTURE = 0; public const DUEDATE_NEXT = 1; @@ -108,6 +108,7 @@ class Card extends RelationalEntity { $this->addType('archived', 'boolean'); $this->addType('notified', 'boolean'); $this->addType('deletedAt', 'integer'); + $this->addType('duedate', 'string'); $this->addRelation('labels'); $this->addRelation('assignedUsers'); $this->addRelation('attachments'); diff --git a/lib/Model/BoardSummary.php b/lib/Model/BoardSummary.php index ad5519781..4c363ff3e 100644 --- a/lib/Model/BoardSummary.php +++ b/lib/Model/BoardSummary.php @@ -24,11 +24,10 @@ namespace OCA\Deck\Model; use OCA\Deck\Db\Board; -class BoardSummary extends Board -{ +class BoardSummary extends Board { private Board $board; - public function __construct(Board $board = null) { + public function __construct(Board $board) { parent::__construct(); $this->board = $board; } @@ -40,7 +39,7 @@ class BoardSummary extends Board ]; } - protected function getter($name) { - return $this->board->getter($name); + public function __call($name, $arguments) { + return $this->board->__call($name, $arguments); } } diff --git a/lib/Model/CardDetails.php b/lib/Model/CardDetails.php index 57e246450..6c51ef841 100644 --- a/lib/Model/CardDetails.php +++ b/lib/Model/CardDetails.php @@ -26,8 +26,7 @@ use DateTime; use OCA\Deck\Db\Board; use OCA\Deck\Db\Card; -class CardDetails extends Card -{ +class CardDetails extends Card { private Card $card; private ?Board $board; @@ -42,14 +41,10 @@ class CardDetails extends Card } public function jsonSerialize(array $extras = []): array { - $array = parent::jsonSerialize(); + $array = $this->card->jsonSerialize(); + unset($array['notified'], $array['descriptionPrev'], $array['relatedStack'], $array['relatedBoard']); + $array['overdue'] = $this->getDueStatus(); - - unset($array['notified']); - unset($array['descriptionPrev']); - unset($array['relatedStack']); - unset($array['relatedBoard']); - $this->appendBoardDetails($array); return $array; @@ -59,23 +54,27 @@ class CardDetails extends Card $today = new DateTime(); $today->setTime(0, 0); - $match_date = $this->getDueDateTime() ?? new DateTime(); + $match_date = $this->card->getDueDateTime(); + if (!$match_date) { + return Card::DUEDATE_FUTURE; + } $match_date->setTime(0, 0); $diff = $today->diff($match_date); - $diffDays = (integer) $diff->format('%R%a'); // Extract days count in interval + $diffDays = (int) $diff->format('%R%a'); // Extract days count in interval + if ($diffDays === 1) { - return static::DUEDATE_NEXT; + return Card::DUEDATE_NEXT; } if ($diffDays === 0) { - return static::DUEDATE_NOW; + return Card::DUEDATE_NOW; } if ($diffDays < 0) { - return static::DUEDATE_OVERDUE; + return Card::DUEDATE_OVERDUE; } - return static::DUEDATE_FUTURE; + return Card::DUEDATE_FUTURE; } private function appendBoardDetails(&$array): void { @@ -87,7 +86,7 @@ class CardDetails extends Card $array['board'] = (new BoardSummary($this->board))->jsonSerialize(); } - protected function getter($name) { - return $this->card->getter($name); + public function __call($name, $arguments) { + return $this->card->__call($name, $arguments); } } diff --git a/tests/unit/Db/CardTest.php b/tests/unit/Db/CardTest.php index 9465a53e4..15c5c9f50 100644 --- a/tests/unit/Db/CardTest.php +++ b/tests/unit/Db/CardTest.php @@ -25,6 +25,7 @@ namespace OCA\Deck\Db; use DateInterval; use DateTime; +use OCA\Deck\Model\CardDetails; use Test\TestCase; class CardTest extends TestCase { @@ -59,7 +60,7 @@ class CardTest extends TestCase { public function testDuedate(DateTime $duedate, $state) { $card = $this->createCard(); $card->setDuedate($duedate->format('Y-m-d H:i:s')); - $this->assertEquals($state, $card->jsonSerialize()['overdue']); + $this->assertEquals($state, (new CardDetails($card))->jsonSerialize()['overdue']); } public function testJsonSerialize() { @@ -86,7 +87,7 @@ class CardTest extends TestCase { 'commentsCount' => 0, 'lastEditor' => null, 'ETag' => $card->getETag(), - ], $card->jsonSerialize()); + ], (new CardDetails($card))->jsonSerialize()); } public function testJsonSerializeLabels() { $card = $this->createCard(); @@ -113,7 +114,7 @@ class CardTest extends TestCase { 'commentsCount' => 0, 'lastEditor' => null, 'ETag' => $card->getETag(), - ], $card->jsonSerialize()); + ], (new CardDetails($card))->jsonSerialize()); } public function testMysqlDateFallback() { @@ -150,6 +151,6 @@ class CardTest extends TestCase { 'commentsCount' => 0, 'lastEditor' => null, 'ETag' => $card->getETag(), - ], $card->jsonSerialize()); + ], (new CardDetails($card))->jsonSerialize()); } }