Map stacks to VTODO and link them as parent entries

Signed-off-by: Julius Härtl <jus@bitgrid.net>
This commit is contained in:
Julius Härtl
2020-03-07 11:48:35 +01:00
parent fc58439d2e
commit 08097ea65f
7 changed files with 67 additions and 20 deletions

View File

@@ -27,7 +27,9 @@ use OCA\DAV\CalDAV\Plugin;
use OCA\DAV\DAV\Sharing\IShareable; use OCA\DAV\DAV\Sharing\IShareable;
use OCA\Deck\Db\Board; use OCA\Deck\Db\Board;
use OCA\Deck\Db\Card; use OCA\Deck\Db\Card;
use OCA\Deck\Db\Stack;
use OCA\Deck\Service\CardService; use OCA\Deck\Service\CardService;
use OCA\Deck\Service\StackService;
use Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet; use Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet;
use Sabre\DAV\PropPatch; use Sabre\DAV\PropPatch;
@@ -62,9 +64,14 @@ class Calendar extends ExternalCalendar implements IShareable {
if ($board) { if ($board) {
/** @var CardService cardService */ /** @var CardService $cardService */
$cardService = \OC::$server->query(CardService::class); $cardService = \OC::$server->query(CardService::class);
$this->children = $cardService->findCalendarEntries($board->getId()); /** @var StackService $stackService */
$stackService = \OC::$server->query(StackService::class);
$this->children = array_merge(
$cardService->findCalendarEntries($board->getId()),
$stackService->findCalendarEntries($board->getId())
);
} else { } else {
$this->children = []; $this->children = [];
} }
@@ -120,8 +127,8 @@ class Calendar extends ExternalCalendar implements IShareable {
*/ */
function calendarQuery(array $filters) { function calendarQuery(array $filters) {
// In a real implementation this should actually filter // In a real implementation this should actually filter
return array_map(function (Card $card) { return array_map(function ($card) {
return $card->getId() . '.ics'; return $card->getCalendarPrefix() . '-' . $card->getId() . '.ics';
}, $this->children); }, $this->children);
} }
@@ -140,7 +147,7 @@ class Calendar extends ExternalCalendar implements IShareable {
$card = array_values(array_filter( $card = array_values(array_filter(
$this->children, $this->children,
function ($card) use (&$name) { function ($card) use (&$name) {
return $card->getId() . '.ics' === $name; return $card->getCalendarPrefix() . '-' . $card->getId() . '.ics' === $name;
} }
)); ));
if (count($card) > 0) { if (count($card) > 0) {
@@ -153,8 +160,8 @@ class Calendar extends ExternalCalendar implements IShareable {
* @inheritDoc * @inheritDoc
*/ */
function getChildren() { function getChildren() {
$childNames = array_map(function (Card $card) { $childNames = array_map(function ($card) {
return $card->getId() . '.ics'; return $card->getCalendarPrefix() . '-' . $card->getId() . '.ics';
}, $this->children); }, $this->children);
$children = []; $children = [];
@@ -173,7 +180,7 @@ class Calendar extends ExternalCalendar implements IShareable {
return count(array_filter( return count(array_filter(
$this->children, $this->children,
function ($card) use (&$name) { function ($card) use (&$name) {
return $card->getId() . '.ics' === $name; return $card->getCalendarPrefix() . '-' . $card->getId() . '.ics' === $name;
} }
)) > 0; )) > 0;
} }

View File

@@ -36,7 +36,7 @@ class CalendarObject implements \Sabre\CalDAV\ICalendarObject, \Sabre\DAVACL\IAC
/** /**
* @var Card * @var Card
*/ */
private $card; private $sourceItem;
/** /**
* CalendarObject constructor. * CalendarObject constructor.
@@ -44,10 +44,10 @@ class CalendarObject implements \Sabre\CalDAV\ICalendarObject, \Sabre\DAVACL\IAC
* @param Calendar $calendar * @param Calendar $calendar
* @param string $name * @param string $name
*/ */
public function __construct(Calendar $calendar, string $name, Card $card = null) { public function __construct(Calendar $calendar, string $name, $sourceItem = null) {
$this->calendar = $calendar; $this->calendar = $calendar;
$this->name = $name; $this->name = $name;
$this->card = $card; $this->sourceItem = $sourceItem;
} }
/** /**
@@ -96,8 +96,8 @@ class CalendarObject implements \Sabre\CalDAV\ICalendarObject, \Sabre\DAVACL\IAC
* @inheritDoc * @inheritDoc
*/ */
function get() { function get() {
if ($this->card) { if ($this->sourceItem) {
return $this->card->getCalendarObject()->serialize(); return $this->sourceItem->getCalendarObject()->serialize();
} }
} }
@@ -147,6 +147,6 @@ class CalendarObject implements \Sabre\CalDAV\ICalendarObject, \Sabre\DAVACL\IAC
* @inheritDoc * @inheritDoc
*/ */
function getLastModified() { function getLastModified() {
return $this->card->getLastModified(); return $this->sourceItem->getLastModified();
} }
} }

View File

@@ -121,14 +121,32 @@ class Card extends RelationalEntity {
public function getCalendarObject(): VCalendar { public function getCalendarObject(): VCalendar {
$calendar = new VCalendar(); $calendar = new VCalendar();
$event = $calendar->createComponent('VEVENT'); $event = $calendar->createComponent('VTODO');
$event->UID = 'deck-cardevent' . $this->getId() . '@example.com'; $event->UID = 'deck-card-' . $this->getId();
$event->DTSTAMP = new \DateTime($this->getDuedate()); $event->DTSTAMP = new \DateTime($this->getDuedate());
$event->DTSTART = new \DateTime($this->getDuedate()); $event->DTSTART = new \DateTime($this->getDuedate());
$event->DTEND = new \DateTime($this->getDuedate()); $event->DTEND = new \DateTime($this->getDuedate());
$event->add('RELATED-TO', 'deck-stack-' . $this->getStackId());
// For write support: CANCELLED / IN-PROCESS handling
$event->STATUS = $this->getArchived() ? "COMPLETED" : "NEEDS-ACTION";
if ($this->getArchived()) {
$date = new DateTime();
$date->setTimestamp($this->getLastModified());
$event->COMPLETED = $date;
}
if (count($this->getLabels()) > 0) {
$event->CATEGORIES = array_map(function ($label) {
return $label->getTitle();
}, $this->getLabels());
}
$event->SUMMARY = $this->getTitle(); $event->SUMMARY = $this->getTitle();
$calendar->add($event); $calendar->add($event);
return $calendar; return $calendar;
} }
public function getCalendarPrefix(): string {
return 'card';
}
} }

View File

@@ -175,9 +175,7 @@ class CardMapper extends QBMapper implements IPermissionMapper {
->from('deck_cards', 'c') ->from('deck_cards', 'c')
->join('c', 'deck_stacks', 's', 's.id = c.stack_id') ->join('c', 'deck_stacks', 's', 's.id = c.stack_id')
->where($qb->expr()->eq('s.board_id', $qb->createNamedParameter($boardId))) ->where($qb->expr()->eq('s.board_id', $qb->createNamedParameter($boardId)))
->andWhere($qb->expr()->neq('c.archived', $qb->createNamedParameter(true)))
->andWhere($qb->expr()->eq('c.deleted_at', $qb->createNamedParameter('0'))) ->andWhere($qb->expr()->eq('c.deleted_at', $qb->createNamedParameter('0')))
->andWhere($qb->expr()->isNotNull('c.duedate'))
->orderBy('c.duedate') ->orderBy('c.duedate')
->setMaxResults($limit) ->setMaxResults($limit)
->setFirstResult($offset); ->setFirstResult($offset);

View File

@@ -23,6 +23,8 @@
namespace OCA\Deck\Db; namespace OCA\Deck\Db;
use Sabre\VObject\Component\VCalendar;
class Stack extends RelationalEntity { class Stack extends RelationalEntity {
protected $title; protected $title;
protected $boardId; protected $boardId;
@@ -50,4 +52,18 @@ class Stack extends RelationalEntity {
} }
return $json; return $json;
} }
public function getCalendarObject(): VCalendar {
$calendar = new VCalendar();
$event = $calendar->createComponent('VTODO');
$event->UID = 'deck-stack-' . $this->getId();
$event->SUMMARY = '[Stack]: ' . $this->getTitle();
$calendar->add($event);
return $calendar;
}
public function getCalendarPrefix(): string {
return 'stack';
}
} }

View File

@@ -146,8 +146,11 @@ class CardService {
public function findCalendarEntries($boardId) { public function findCalendarEntries($boardId) {
$this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_READ); $this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_READ);
$cards = $this->cardMapper->findCalendarEntries($boardId);
return $this->cardMapper->findCalendarEntries($boardId); foreach ($cards as $card) {
$this->enrich($card);
}
return $cards;
} }
/** /**

View File

@@ -146,6 +146,11 @@ class StackService {
return $stacks; return $stacks;
} }
public function findCalendarEntries($boardId) {
$this->permissionService->checkPermission(null, $boardId, Acl::PERMISSION_READ);
return $this->stackMapper->findAll($boardId);
}
public function fetchDeleted($boardId) { public function fetchDeleted($boardId) {
$this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_READ); $this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_READ);
$stacks = $this->stackMapper->findDeleted($boardId); $stacks = $this->stackMapper->findDeleted($boardId);