diff --git a/appinfo/info.xml b/appinfo/info.xml index 8da927459..5ed1ec72d 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -14,7 +14,7 @@ - 🚀 Get your project organized - 0.5.0-dev2 + 0.5.0-dev3 agpl Julius Härtl Deck @@ -40,4 +40,15 @@ OCA\Deck\Command\UserExport + + + OCA\Deck\Activity\DeckProvider + + + OCA\Deck\Activity\Setting + + + OCA\Deck\Activity\Filter + + diff --git a/lib/Activity/ActivityManager.php b/lib/Activity/ActivityManager.php new file mode 100644 index 000000000..2930dc588 --- /dev/null +++ b/lib/Activity/ActivityManager.php @@ -0,0 +1,392 @@ + + * + * @author Julius Härtl + * + * @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\Activity; + +use OCA\Deck\Db\AssignedUsers; +use OCA\Deck\Db\Attachment; +use OCA\Deck\Db\AttachmentMapper; +use OCA\Deck\Db\Board; +use OCA\Deck\Db\BoardMapper; +use OCA\Deck\Db\Card; +use OCA\Deck\Db\CardMapper; +use OCA\Deck\Db\IPermissionMapper; +use OCA\Deck\Db\Label; +use OCA\Deck\Db\Stack; +use OCA\Deck\Db\StackMapper; +use OCA\Deck\Service\PermissionService; +use OCP\Activity\IEvent; +use OCP\Activity\IManager; +use OCP\AppFramework\Db\DoesNotExistException; +use OCP\AppFramework\Db\MultipleObjectsReturnedException; +use OCP\IL10N; +use OCP\IUser; + +class ActivityManager { + + private $manager; + private $userId; + private $permissionService; + private $boardMapper; + private $cardMapper; + private $attachmentMapper; + private $stackMapper; + private $l10n; + + const DECK_OBJECT_BOARD = 'deck_board'; + const DECK_OBJECT_CARD = 'deck_card'; + + const SUBJECT_BOARD_CREATE = 'board_create'; + const SUBJECT_BOARD_UPDATE = 'board_update'; + const SUBJECT_BOARD_UPDATE_TITLE = 'board_update_title'; + const SUBJECT_BOARD_UPDATE_ARCHIVED = 'board_update_archived'; + const SUBJECT_BOARD_DELETE = 'board_delete'; + const SUBJECT_BOARD_RESTORE = 'board_restore'; + const SUBJECT_BOARD_SHARE = 'board_share'; + const SUBJECT_BOARD_ARCHIVE = 'board_archive'; + const SUBJECT_BOARD_UNARCHIVE = 'board_unarchive'; + + const SUBJECT_STACK_CREATE = 'stack_create'; + const SUBJECT_STACK_UPDATE = 'stack_update'; + const SUBJECT_STACK_UPDATE_TITLE = 'stack_update_title'; + const SUBJECT_STACK_UPDATE_ORDER = 'stack_update_order'; + const SUBJECT_STACK_DELETE = 'stack_delete'; + + const SUBJECT_CARD_CREATE = 'card_create'; + const SUBJECT_CARD_DELETE = 'card_delete'; + const SUBJECT_CARD_RESTORE = 'card_restore'; + const SUBJECT_CARD_UPDATE = 'card_update'; + const SUBJECT_CARD_UPDATE_TITLE = 'card_update_title'; + const SUBJECT_CARD_UPDATE_DESCRIPTION = 'card_update_description'; + const SUBJECT_CARD_UPDATE_ARCHIVE = 'card_update_archive'; + const SUBJECT_CARD_UPDATE_UNARCHIVE = 'card_update_unarchive'; + + const SUBJECT_ATTACHMENT_CREATE = 'attachment_create'; + const SUBJECT_ATTACHMENT_UPDATE = 'attachment_update'; + const SUBJECT_ATTACHMENT_DELETE = 'attachment_delete'; + + const SUBJECT_LABEL_CREATE = 'label_create'; + const SUBJECT_LABEL_UPDATE = 'label_update'; + const SUBJECT_LABEL_DELETE = 'label_delete'; + const SUBJECT_LABEL_ASSIGN = 'label_assign'; + const SUBJECT_LABEL_UNASSING = 'label_unassign'; + + public function __construct( + IManager $manager, + PermissionService $permissionsService, + BoardMapper $boardMapper, + CardMapper $cardMapper, + StackMapper $stackMapper, + AttachmentMapper $attachmentMapper, + IL10N $l10n, + $userId + ) { + $this->manager = $manager; + $this->permissionService = $permissionsService; + $this->boardMapper = $boardMapper; + $this->cardMapper = $cardMapper; + $this->stackMapper = $stackMapper; + $this->attachmentMapper = $attachmentMapper; + $this->l10n = $l10n; + $this->userId = $userId; + } + + /** + * @param $objectType + * @param $entity + * @return null|\OCA\Deck\Db\RelationalEntity|\OCP\AppFramework\Db\Entity + * @throws \OCP\AppFramework\Db\DoesNotExistException + * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException + */ + protected function findObjectForEntity($objectType, $entity) { + $className = \get_class($entity); + $objectId = null; + switch ($className) { + case Board::class: + case Card::class: + $objectId = $entity->getId(); + break; + case Attachment::class: + case Label::class: + case AssignedUsers::class: + $objectId = $entity->getCardId(); + break; + case Stack::class: + $objectId = $entity->getBoardId(); + } + + if ($objectType === self::DECK_OBJECT_CARD) { + return $this->cardMapper->find($objectId); + } + if ($objectType === self::DECK_OBJECT_BOARD) { + return $this->boardMapper->find($objectId); + } + + return null; + } + + /** + * @param $subjectIdentifier + * @param bool $ownActivity + * @return string + * @throws \Exception + */ + public function getActivityFormat($subjectIdentifier, $ownActivity = false) { + $subject = ''; + switch ($subjectIdentifier) { + case self::SUBJECT_BOARD_CREATE: + $subject = $this->l10n->t('You have created a new board {board}'); + break; + case self::SUBJECT_BOARD_DELETE: + $subject = $ownActivity ? $this->l10n->t('You have deleted the board {board}') : $this->l10n->t('{user} has deleted the board {board}'); + break; + case self::SUBJECT_BOARD_RESTORE: + $subject = $ownActivity ? $this->l10n->t('You have restored the board {board}') : $this->l10n->t('{user} has restored the board {board}'); + break; + case self::SUBJECT_BOARD_SHARE: + $subject = $ownActivity ? $this->l10n->t('You have shared the board {board} with {sharee}') : $this->l10n->t('{user} has shared the board {board} with {sharee}'); + break; + case self::SUBJECT_BOARD_ARCHIVE: + $subject = $ownActivity ? $this->l10n->t('You have archived the board {board}') : $this->l10n->t('{user} has archived the board {board}'); + break; + case self::SUBJECT_BOARD_UNARCHIVE: + $subject = $ownActivity ? $this->l10n->t('You have unarchived the board {board}') : $this->l10n->t('{user} has unarchived the board {board}'); + break; + + case self::SUBJECT_BOARD_UPDATE_TITLE: + $subject = $ownActivity ? $this->l10n->t('You have renamed the board {before} to {board}') : $this->l10n->t('{user} has has renamed the board {before} to {board}'); + break; + case self::SUBJECT_BOARD_UPDATE_ARCHIVED: + $subject = $ownActivity ? $this->l10n->t('You have renamed the board {before} to {board}') : $this->l10n->t('{user} has has renamed the board {before} to {board}'); + break; + + case self::SUBJECT_STACK_CREATE: + $subject = $ownActivity ? $this->l10n->t('You have created a new stack {stack} on {board}') : $this->l10n->t('{user} has created a new stack {stack} on {board}'); + break; + case self::SUBJECT_STACK_UPDATE: + $subject = $ownActivity ? $this->l10n->t('You have created a new stack {stack} on {board}') : $this->l10n->t('{user} has created a new stack {stack} on {board}'); + break; + case self::SUBJECT_STACK_UPDATE_TITLE: + $subject = $ownActivity ? $this->l10n->t('You have renamed a new stack {before} to {stack} on {board}') : $this->l10n->t('{user} has renamed a new stack {before} to {stack} on {board}'); + break; + case self::SUBJECT_STACK_DELETE: + $subject = $ownActivity ? $this->l10n->t('You have deleted {stack} on {board}') : $this->l10n->t('{user} has deleted {stack} on {board}'); + break; + case self::SUBJECT_CARD_CREATE: + $subject = $ownActivity ? $this->l10n->t('You have created {card} in {stack} on {board}') : $this->l10n->t('{user} has created {card} in {stack} on {board}'); + break; + case self::SUBJECT_CARD_DELETE: + $subject = $ownActivity ? $this->l10n->t('You have deleted {card} in {stack} on {board}') : $this->l10n->t('{user} has deleted {card} in {stack} on {board}'); + break; + case self::SUBJECT_CARD_UPDATE_DESCRIPTION: + $subject = $ownActivity ? $this->l10n->t('You have updated the description of {card} in {stack} on {board}') : $this->l10n->t('{user} has updated the description {card} in {stack} on {board}'); + break; + case self::SUBJECT_CARD_UPDATE_ARCHIVE: + $subject = $ownActivity ? $this->l10n->t('You have archived {card} in {stack} on {board}') : $this->l10n->t('{user} has archived {card} in {stack} on {board}'); + break; + case self::SUBJECT_CARD_UPDATE_UNARCHIVE: + $subject = $ownActivity ? $this->l10n->t('You have unarchived {card} in {stack} on {board}') : $this->l10n->t('{user} has unarchived {card} in {stack} on {board}'); + break; + default: + break; + } + return $subject; + } + + public function triggerEvent($objectType, $entity, $subject) { + try { + $event = $this->createEvent($objectType, $entity, $subject); + $this->sendToUsers($event); + } catch (\Exception $e) { + // Ignore exception for undefined activities on update events + } + } + + /** + * + * @param $objectType + * @param ChangeSet $changeSet + * @param $subject + * @throws \Exception + */ + public function triggerUpdateEvents($objectType, ChangeSet $changeSet, $subject) { + $previousEntity = $changeSet->getBefore(); + $entity = $changeSet->getAfter(); + $events = []; + if ($previousEntity !== null) { + foreach ($entity->getUpdatedFields() as $field => $value) { + $getter = 'get' . ucfirst($field); + $subject = $subject . '_' . $field; + $changes = [ + 'before' => $previousEntity->$getter(), + 'after' => $entity->$getter() + ]; + if ($changes['before'] !== $changes['after']) { + try { + $event = $this->createEvent($objectType, $entity, $subject, $changes); + $events[] = $event; + } catch (\Exception $e) { + // Ignore exception for undefined activities on update events + } + } + } + + } else { + $events = [$this->createEvent($objectType, $entity, $subject)]; + } + foreach ($events as $event) { + $this->sendToUsers($event); + } + } + + /** + * @param $objectType + * @param $entity + * @param $subject + * @param array $additionalParams + * @return IEvent + * @throws \Exception + */ + public function createEvent($objectType, $entity, $subject, $additionalParams = []) { + try { + $object = $this->findObjectForEntity($objectType, $entity); + } catch (DoesNotExistException $e) { + } catch (MultipleObjectsReturnedException $e) { + \OC::$server->getLogger()->error('Could not create activity entry for ' . $subject . '. Entity not found.', $entity); + return null; + } + + /** + * Automatically fetch related details for subject parameters + * depending on the subject + */ + $subjectParams = []; + $message = null; + switch ($subject) { + // No need to enhance parameters since entity already contains the required data + case self::SUBJECT_BOARD_CREATE: + case self::SUBJECT_BOARD_UPDATE_TITLE: + case self::SUBJECT_BOARD_UPDATE_ARCHIVED: + // Not defined as there is no activity for + // case self::SUBJECT_BOARD_UPDATE_COLOR + break; + + case self::SUBJECT_STACK_CREATE: + case self::SUBJECT_STACK_UPDATE: + case self::SUBJECT_STACK_UPDATE_TITLE: + case self::SUBJECT_STACK_UPDATE_ORDER: + case self::SUBJECT_STACK_DELETE: + $subjectParams = $this->findDetailsForStack($entity->getId()); + break; + + case self::SUBJECT_CARD_CREATE: + case self::SUBJECT_CARD_DELETE: + case self::SUBJECT_CARD_UPDATE_ARCHIVE: + case self::SUBJECT_CARD_UPDATE_UNARCHIVE: + case self::SUBJECT_CARD_UPDATE_TITLE: + case self::SUBJECT_CARD_UPDATE_DESCRIPTION: + $subjectParams = $this->findDetailsForCard($entity->getId()); + $object = $entity; + $message = $additionalParams['after']; + break; + + default: + throw new \Exception('Unknown subject for activity.'); + break; + } + + $event = $this->manager->generateEvent(); + $event->setApp('deck') + ->setType('deck') + ->setAuthor($this->userId) + ->setObject($objectType, (int)$object->getId(), $object->getTitle()) + ->setSubject($subject, array_merge($subjectParams, $additionalParams)) + ->setTimestamp(time()); + + if ($message !== null) { + $event->setMessage($message); + } + + return $event; + } + + /** + * Publish activity to all users that are part of the board of a given object + * + * @param IEvent $event + * @param IPermissionMapper $mapper + */ + public function sendToUsers(IEvent $event) { + switch ($event->getObjectType()) { + case self::DECK_OBJECT_BOARD: + $mapper = $this->boardMapper; + break; + case self::DECK_OBJECT_CARD: + $mapper = $this->cardMapper; + break; + } + $boardId = $mapper->findBoardId($event->getObjectId()); + /** @var IUser $user */ + foreach ($this->permissionService->findUsers($boardId) as $user) { + $event->setAffectedUser($user->getUID()); + /** @noinspection DisconnectedForeachInstructionInspection */ + $this->manager->publish($event); + } + } + + public function findDetailsForStack($stackId) { + $stack = $this->stackMapper->find($stackId); + $board = $this->boardMapper->find($stack->getBoardId()); + return [ + 'stack' => $stack, + 'board' => $board + ]; + } + + public function findDetailsForCard($cardId) { + $card = $this->cardMapper->find($cardId); + $stack = $this->stackMapper->find($card->getStackId()); + $board = $this->boardMapper->find($stack->getBoardId()); + return [ + 'card' => $card, + 'stack' => $stack, + 'board' => $board + ]; + } + + public function findDetailsForAttachment($attachmentId) { + $attachment = $this->attachmentMapper->find($attachmentId); + $data = $this->findDetailsForCard($attachmentId->getCardId()); + return array_merge($data, [$attachment]); + } + + public function findDetailsForLabel($labelId) { + // LabelMapper + } + + public function findDetailsForLabelAssignment($labelId, $cardId) { + $card = $this->cardMapper->find($cardId); + + } + +} diff --git a/lib/Activity/ChangeSet.php b/lib/Activity/ChangeSet.php new file mode 100644 index 000000000..3d483733b --- /dev/null +++ b/lib/Activity/ChangeSet.php @@ -0,0 +1,56 @@ + + * + * @author Julius Härtl + * + * @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\Activity; + + +class ChangeSet { + + private $before; + private $after; + + public function __construct($before = null, $after = null) { + if ($before !== null) { + $this->setBefore($before); + } + if ($after !== null) { + $this->setAfter($after); + } + } + + public function setBefore($before) { + $this->before = clone $before; + } + + public function setAfter($after) { + $this->after = clone $after; + } + + public function getBefore() { + return $this->before; + } + + public function getAfter() { + return $this->after; + } +} diff --git a/lib/Activity/DeckProvider.php b/lib/Activity/DeckProvider.php new file mode 100644 index 000000000..081919022 --- /dev/null +++ b/lib/Activity/DeckProvider.php @@ -0,0 +1,147 @@ + + * + * @author Julius Härtl + * + * @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\Activity; + + +use OCP\Activity\IEvent; +use OCP\Activity\IProvider; +use OCP\IL10N; +use OCP\IURLGenerator; + +class DeckProvider implements IProvider { + + /** @var string */ + private $userId; + /** @var IURLGenerator */ + private $urlGenerator; + /** @var ActivityManager */ + private $activityManager; + + public function __construct(IURLGenerator $urlGenerator, ActivityManager $activityManager, $userId) { + $this->userId = $userId; + $this->urlGenerator = $urlGenerator; + $this->activityManager = $activityManager; + } + + + /** + * @param string $language The language which should be used for translating, e.g. "en" + * @param IEvent $event The current event which should be parsed + * @param IEvent|null $previousEvent A potential previous event which you can combine with the current one. + * To do so, simply use setChildEvent($previousEvent) after setting the + * combined subject on the current event. + * @return IEvent + * @throws \InvalidArgumentException Should be thrown if your provider does not know this event + * @since 11.0.0 + */ + public function parse($language, IEvent $event, IEvent $previousEvent = null) { + if ($event->getApp() !== 'deck') { + throw new \InvalidArgumentException(); + } + + $event->setIcon(\OC::$server->getURLGenerator()->imagePath('deck', 'deck-dark.svg')); + + $subjectIdentifier = $event->getSubject(); + $subjectParams = $event->getSubjectParameters(); + + $ownActivity = ($event->getAuthor() === $this->userId); + + if ($event->getObjectType() === ActivityManager::DECK_OBJECT_BOARD) { + $board = [ + 'type' => 'highlight', + 'id' => $event->getObjectId(), + 'name' => $event->getObjectName(), + 'link' => $this->deckUrl('/board/' . $event->getObjectId()), + ]; + } + + if ($event->getObjectType() === ActivityManager::DECK_OBJECT_CARD) { + $card = [ + 'type' => 'highlight', + 'id' => $event->getObjectId(), + 'name' => $event->getObjectName(), + ]; + + if ($subjectParams['board']) { + // TODO: check if archvied? + $card['link'] = $this->deckUrl('/board/' . $subjectParams['board']['id'] . '//card/' . $event->getObjectId()); + } + } + + $userManager = \OC::$server->getUserManager(); + $author = $event->getAuthor(); + $user = $userManager->get($author); + $params = [ + 'board' => $board, + 'card' => $card, + 'user' => [ + 'type' => 'user', + 'id' => $author, + 'name' => $user !== null ? $user->getDisplayName() : $author + ] + ]; + + if (array_key_exists('stack', $subjectParams)) { + $params['stack'] = [ + 'type' => 'highlight', + 'id' => $subjectParams['stack']['id'], + 'name' => $subjectParams['stack']['title'], + 'link' => $this->deckUrl('/board/' . $subjectParams['stack']['boardId'] . '/'), + ]; + } + + if (array_key_exists('board', $subjectParams)) { + $params['board'] = [ + 'type' => 'highlight', + 'id' => $subjectParams['board']['id'], + 'name' => $subjectParams['board']['title'], + 'link' => $this->deckUrl('/board/' . $subjectParams['board']['id'] . '/'), + ]; + } + + if (array_key_exists('before', $subjectParams)) { + $params['before'] = [ + 'type' => 'highlight', + 'id' => $subjectParams['before'], + 'name' => $subjectParams['before'] + ]; + } + + $subject = $this->activityManager->getActivityFormat($subjectIdentifier, $ownActivity); + $event->setParsedSubject($subject); + $event->setRichSubject( + $subject, + $params + ); + if ($event->getMessage() !== '') { + $event->setParsedMessage('
' . $event->getMessage() . '
'); + } + + return $event; + } + + public function deckUrl($endpoint) { + return $this->urlGenerator->linkToRoute('deck.page.index') . '#!' . $endpoint; + } +} diff --git a/lib/Activity/Filter.php b/lib/Activity/Filter.php new file mode 100644 index 000000000..4dcbd5260 --- /dev/null +++ b/lib/Activity/Filter.php @@ -0,0 +1,89 @@ + + * + * @author Julius Härtl + * + * @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\Activity; + +use OCP\IL10N; + +class Filter implements \OCP\Activity\IFilter { + + private $l10n; + + public function __construct( + IL10N $l10n + ) { + $this->l10n = $l10n; + } + + /** + * @return string Lowercase a-z and underscore only identifier + * @since 11.0.0 + */ + public function getIdentifier() { + return 'deck'; + } + + /** + * @return string A translated string + * @since 11.0.0 + */ + public function getName() { + return $this->l10n->t('Deck'); + } + + /** + * @return int whether the filter should be rather on the top or bottom of + * the admin section. The filters are arranged in ascending order of the + * priority values. It is required to return a value between 0 and 100. + * @since 11.0.0 + */ + public function getPriority() { + return 90; + } + + /** + * @return string Full URL to an icon, empty string when none is given + * @since 11.0.0 + */ + public function getIcon() { + //TODO: inject + return \OC::$server->getURLGenerator()->imagePath('deck', 'deck-dark.svg'); + } + + /** + * @param string[] $types + * @return string[] An array of allowed apps from which activities should be displayed + * @since 11.0.0 + */ + public function filterTypes(array $types) { + return $types; + } + + /** + * @return string[] An array of allowed apps from which activities should be displayed + * @since 11.0.0 + */ + public function allowedApps() { + return ['deck']; + } +} \ No newline at end of file diff --git a/lib/Activity/Setting.php b/lib/Activity/Setting.php new file mode 100644 index 000000000..12080f263 --- /dev/null +++ b/lib/Activity/Setting.php @@ -0,0 +1,86 @@ + + * + * @author Julius Härtl + * + * @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\Activity; + + +class Setting implements \OCP\Activity\ISetting { + + /** + * @return string Lowercase a-z and underscore only identifier + * @since 11.0.0 + */ + public function getIdentifier() { + return 'deck'; + } + + /** + * @return string A translated string + * @since 11.0.0 + */ + public function getName() { + return 'Deck'; + } + + /** + * @return int whether the filter should be rather on the top or bottom of + * the admin section. The filters are arranged in ascending order of the + * priority values. It is required to return a value between 0 and 100. + * @since 11.0.0 + */ + public function getPriority() { + return 90; + } + + /** + * @return bool True when the option can be changed for the stream + * @since 11.0.0 + */ + public function canChangeStream() { + return true; + } + + /** + * @return bool True when the option can be changed for the stream + * @since 11.0.0 + */ + public function isDefaultEnabledStream() { + return true; + } + + /** + * @return bool True when the option can be changed for the mail + * @since 11.0.0 + */ + public function canChangeMail() { + return true; + } + + /** + * @return bool True when the option can be changed for the stream + * @since 11.0.0 + */ + public function isDefaultEnabledMail() { + return false; + } +} diff --git a/lib/Service/StackService.php b/lib/Service/StackService.php index f2bdbaff8..4f8e4be24 100644 --- a/lib/Service/StackService.php +++ b/lib/Service/StackService.php @@ -32,6 +32,7 @@ use OCA\Deck\Db\Stack; use OCA\Deck\Db\StackMapper; use OCA\Deck\StatusException; use OCA\Deck\BadRequestException; +use OCP\Activity\IManager; class StackService { @@ -45,6 +46,7 @@ class StackService { private $cardService; private $assignedUsersMapper; private $attachmentService; + private $activityManager; public function __construct( StackMapper $stackMapper, @@ -55,7 +57,8 @@ class StackService { BoardService $boardService, CardService $cardService, AssignedUsersMapper $assignedUsersMapper, - AttachmentService $attachmentService + AttachmentService $attachmentService, + IManager $activityManager ) { $this->stackMapper = $stackMapper; $this->boardMapper = $boardMapper; @@ -66,6 +69,7 @@ class StackService { $this->cardService = $cardService; $this->assignedUsersMapper = $assignedUsersMapper; $this->attachmentService = $attachmentService; + $this->activityManager = $activityManager; } private function enrichStackWithCards($stack) { @@ -195,8 +199,33 @@ class StackService { $stack->setTitle($title); $stack->setBoardId($boardId); $stack->setOrder($order); - return $this->stackMapper->insert($stack); + $result = $this->stackMapper->insert($stack); + $board = $this->boardMapper->find($boardId); + $event = $this->activityManager->generateEvent(); + $event->setApp('deck') + ->setType('deck_own_boards') + ->setAffectedUser($board->getOwner()) + ->setAuthor($board->getOwner()) + ->setObject('stack', $result->getId()) + ->setSubject('foo') + ->setTimestamp(time()); + /*->setSubject('{actor} created a new stack {stack} on {board}', + [ + 'actor' => $event->getAuthor(), + 'stack' => [ + 'id' => (int) $result->getId(), + //'uri' => $calendarData['uri'], + 'name' => $stack->getTitle(), + ], + 'board' => [ + 'id' => (int) $boardId, + 'name' => $board->getTitle(), + ], + ]);*/ + + $this->activityManager->publish($event); + return $result; } /**