diff --git a/lib/Controller/BoardController.php b/lib/Controller/BoardController.php index 9d0b9fcaf4..f33d08e419 100644 --- a/lib/Controller/BoardController.php +++ b/lib/Controller/BoardController.php @@ -73,10 +73,11 @@ public function create($title, $color) { * @param $title * @param $color * @param $archived + * @param $coverImages * @return \OCP\AppFramework\Db\Entity */ - public function update($id, $title, $color, $archived) { - return $this->boardService->update($id, $title, $color, $archived); + public function update($id, $title, $color, $archived, $coverImages) { + return $this->boardService->update($id, $title, $color, $archived, $coverImages); } /** diff --git a/lib/Db/Board.php b/lib/Db/Board.php index 6cf3c32068..0cdecf5533 100644 --- a/lib/Db/Board.php +++ b/lib/Db/Board.php @@ -38,6 +38,7 @@ class Board extends RelationalEntity { protected $stacks = []; protected $deletedAt = 0; protected $lastModified = 0; + protected $coverImages = true; protected $settings = []; @@ -47,6 +48,7 @@ public function __construct() { $this->addType('archived', 'boolean'); $this->addType('deletedAt', 'integer'); $this->addType('lastModified', 'integer'); + $this->addType('coverImages', 'boolean'); $this->addRelation('labels'); $this->addRelation('acl'); $this->addRelation('shared'); diff --git a/lib/Db/BoardMapper.php b/lib/Db/BoardMapper.php index 2a204c50fa..eee0cceb97 100644 --- a/lib/Db/BoardMapper.php +++ b/lib/Db/BoardMapper.php @@ -79,18 +79,10 @@ public function __construct( * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException * @throws DoesNotExistException */ - public function find($id, $withLabels = false, $withAcl = false): Board { - if (!isset($this->boardCache[$id])) { - $qb = $this->db->getQueryBuilder(); - $qb->select('*') - ->from('deck_boards') - ->where($qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT))) - ->orderBy('id'); - $this->boardCache[$id] = $this->findEntity($qb); - } - - // FIXME is this necessary? it was NOT done with the old mapper - // $this->mapOwner($board); + public function find($id, $withLabels = false, $withAcl = false) { + $sql = 'SELECT id, title, owner, color, archived, deleted_at, last_modified, cover_images FROM `*PREFIX*deck_boards` ' . + 'WHERE `id` = ?'; + $board = $this->findEntity($sql, [$id]); // Add labels if ($withLabels && $this->boardCache[$id]->getLabels() === null) { @@ -137,16 +129,9 @@ public function findAllForUser(string $userId, ?int $since = null, bool $include * @param null $offset * @return array */ - public function findAllByUser(string $userId, ?int $limit = null, ?int $offset = null, ?int $since = null, - bool $includeArchived = true, ?int $before = null, ?string $term = null) { - // FIXME this used to be a UNION to get boards owned by $userId and the user shares in one single query - // Is it possible with the query builder? - $qb = $this->db->getQueryBuilder(); - $qb->select('id', 'title', 'owner', 'color', 'archived', 'deleted_at', 'last_modified') - // this does not work in MySQL/PostgreSQL - //->selectAlias('0', 'shared') - ->from('deck_boards', 'b') - ->where($qb->expr()->eq('owner', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR))); + public function findAllByUser($userId, $limit = null, $offset = null, $since = -1, $includeArchived = true) { + // 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, cover_images FROM `*PREFIX*deck_boards` WHERE owner = ? AND last_modified > ?'; if (!$includeArchived) { $qb->andWhere($qb->expr()->eq('archived', $qb->createNamedParameter(false, IQueryBuilder::PARAM_BOOL))) ->andWhere($qb->expr()->eq('deleted_at', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT))); @@ -157,38 +142,9 @@ public function findAllByUser(string $userId, ?int $limit = null, ?int $offset = if ($before !== null) { $qb->andWhere($qb->expr()->lt('last_modified', $qb->createNamedParameter($before, IQueryBuilder::PARAM_INT))); } - if ($term !== null) { - $qb->andWhere( - $qb->expr()->iLike( - 'title', - $qb->createNamedParameter( - '%' . $this->db->escapeLikeParameter($term) . '%', - IQueryBuilder::PARAM_STR - ) - ) - ); - } - $qb->orderBy('b.id'); - if ($limit !== null) { - $qb->setMaxResults($limit); - } - if ($offset !== null) { - $qb->setFirstResult($offset); - } - $entries = $this->findEntities($qb); - foreach ($entries as $entry) { - $entry->setShared(0); - } - - // shared with user - $qb->resetQueryParts(); - $qb->select('b.id', 'title', 'owner', 'color', 'archived', 'deleted_at', 'last_modified') - //->selectAlias('1', 'shared') - ->from('deck_boards', 'b') - ->innerJoin('b', 'deck_board_acl', 'acl', $qb->expr()->eq('b.id', 'acl.board_id')) - ->where($qb->expr()->eq('acl.participant', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR))) - ->andWhere($qb->expr()->eq('acl.type', $qb->createNamedParameter(Acl::PERMISSION_TYPE_USER, IQueryBuilder::PARAM_INT))) - ->andWhere($qb->expr()->neq('b.owner', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR))); + $sql .= ' UNION ' . + 'SELECT boards.id, title, owner, color, archived, deleted_at, 1 as shared, last_modified, cover_images 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 != ? AND last_modified > ?'; if (!$includeArchived) { $qb->andWhere($qb->expr()->eq('archived', $qb->createNamedParameter(false, IQueryBuilder::PARAM_BOOL))) ->andWhere($qb->expr()->eq('deleted_at', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT))); @@ -259,14 +215,8 @@ public function findAllByGroups(string $userId, array $groups, ?int $limit = nul if (count($groups) <= 0) { return []; } - $qb = $this->db->getQueryBuilder(); - $qb->select('b.id', 'title', 'owner', 'color', 'archived', 'deleted_at', 'last_modified') - //->selectAlias('2', 'shared') - ->from('deck_boards', 'b') - ->innerJoin('b', 'deck_board_acl', 'acl', $qb->expr()->eq('b.id', 'acl.board_id')) - ->where($qb->expr()->eq('acl.type', $qb->createNamedParameter(Acl::PERMISSION_TYPE_GROUP, IQueryBuilder::PARAM_INT))) - ->andWhere($qb->expr()->neq('b.owner', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR))); - $or = $qb->expr()->orx(); + $sql = 'SELECT boards.id, title, owner, color, archived, deleted_at, 2 as shared, last_modified, cover_images FROM `*PREFIX*deck_boards` as boards ' . + 'INNER JOIN `*PREFIX*deck_board_acl` as acl ON boards.id=acl.board_id WHERE owner != ? AND type=? AND ('; for ($i = 0, $iMax = count($groups); $i < $iMax; $i++) { $or->add( $qb->expr()->eq('acl.participant', $qb->createNamedParameter($groups[$i], IQueryBuilder::PARAM_STR)) @@ -325,14 +275,8 @@ public function findAllByCircles(string $userId, ?int $limit = null, ?int $offse return []; } - $qb = $this->db->getQueryBuilder(); - $qb->select('b.id', 'title', 'owner', 'color', 'archived', 'deleted_at', 'last_modified') - //->selectAlias('2', 'shared') - ->from('deck_boards', 'b') - ->innerJoin('b', 'deck_board_acl', 'acl', $qb->expr()->eq('b.id', 'acl.board_id')) - ->where($qb->expr()->eq('acl.type', $qb->createNamedParameter(Acl::PERMISSION_TYPE_CIRCLE, IQueryBuilder::PARAM_INT))) - ->andWhere($qb->expr()->neq('b.owner', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR))); - $or = $qb->expr()->orx(); + $sql = 'SELECT boards.id, title, owner, color, archived, deleted_at, 2 as shared, last_modified, cover_images FROM `*PREFIX*deck_boards` as boards ' . + 'INNER JOIN `*PREFIX*deck_board_acl` as acl ON boards.id=acl.board_id WHERE owner != ? AND type=? AND ('; for ($i = 0, $iMax = count($circles); $i < $iMax; $i++) { $or->add( $qb->expr()->eq('acl.participant', $qb->createNamedParameter($circles[$i], IQueryBuilder::PARAM_STR)) @@ -389,12 +333,9 @@ public function findAll(): array { public function findToDelete() { // add buffer of 5 min $timeLimit = time() - (60 * 5); - $qb = $this->db->getQueryBuilder(); - $qb->select('id', 'title', 'owner', 'color', 'archived', 'deleted_at', 'last_modified') - ->from('deck_boards') - ->where($qb->expr()->gt('deleted_at', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT))) - ->andWhere($qb->expr()->lt('deleted_at', $qb->createNamedParameter($timeLimit, IQueryBuilder::PARAM_INT))); - return $this->findEntities($qb); + $sql = 'SELECT id, title, owner, color, archived, deleted_at, last_modified, cover_images FROM `*PREFIX*deck_boards` ' . + 'WHERE `deleted_at` > 0 AND `deleted_at` < ?'; + return $this->findEntities($sql, [$timeLimit]); } public function delete(/** @noinspection PhpUnnecessaryFullyQualifiedNameInspection */ diff --git a/lib/Migration/Version010400Date20210305.php b/lib/Migration/Version010400Date20210305.php new file mode 100644 index 0000000000..9b2e25f9b0 --- /dev/null +++ b/lib/Migration/Version010400Date20210305.php @@ -0,0 +1,28 @@ +getTable('deck_boards'); + if (!$table->hasColumn('cover_images')) { + $table->addColumn('cover_images', 'boolean', [ + 'notnull' => false, + 'default' => true, + ]); + return $schema; + } + return null; + } +} \ No newline at end of file diff --git a/lib/Service/BoardService.php b/lib/Service/BoardService.php index 1ee0a0cf29..2e49c4aa3e 100644 --- a/lib/Service/BoardService.php +++ b/lib/Service/BoardService.php @@ -408,13 +408,14 @@ public function deleteForce($id) { * @param $title * @param $color * @param $archived + * @param $coverImages * @return \OCP\AppFramework\Db\Entity * @throws DoesNotExistException * @throws \OCA\Deck\NoPermissionException * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException * @throws BadRequestException */ - public function update($id, $title, $color, $archived) { + public function update($id, $title, $color, $archived, $coverImages) { if (is_numeric($id) === false) { throw new BadRequestException('board id must be a number'); } @@ -431,12 +432,17 @@ public function update($id, $title, $color, $archived) { throw new BadRequestException('archived must be a boolean'); } + if (is_bool($coverImages) === false) { + throw new BadRequestException('coverImages must be a boolean'); + } + $this->permissionService->checkPermission($this->boardMapper, $id, Acl::PERMISSION_MANAGE); $board = $this->find($id); $changes = new ChangeSet($board); $board->setTitle($title); $board->setColor($color); $board->setArchived($archived); + $board->setCoverImages($coverImages); $changes->setAfter($board); $this->boardMapper->update($board); // operate on clone so we can check for updated fields $this->boardMapper->mapOwner($board); diff --git a/src/components/cards/CardItem.vue b/src/components/cards/CardItem.vue index 3a06757921..f0105b46ba 100644 --- a/src/components/cards/CardItem.vue +++ b/src/components/cards/CardItem.vue @@ -35,7 +35,14 @@ {{ board.title }} ยป {{ stack.title }}