WIP: Activity integration
Signed-off-by: Julius Härtl <jus@bitgrid.net>
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
- 🚀 Get your project organized
|
||||
|
||||
</description>
|
||||
<version>0.5.0-dev2</version>
|
||||
<version>0.5.0-dev3</version>
|
||||
<licence>agpl</licence>
|
||||
<author>Julius Härtl</author>
|
||||
<namespace>Deck</namespace>
|
||||
@@ -40,4 +40,15 @@
|
||||
<commands>
|
||||
<command>OCA\Deck\Command\UserExport</command>
|
||||
</commands>
|
||||
<activity>
|
||||
<providers>
|
||||
<provider>OCA\Deck\Activity\DeckProvider</provider>
|
||||
</providers>
|
||||
<settings>
|
||||
<setting>OCA\Deck\Activity\Setting</setting>
|
||||
</settings>
|
||||
<filters>
|
||||
<filter>OCA\Deck\Activity\Filter</filter>
|
||||
</filters>
|
||||
</activity>
|
||||
</info>
|
||||
|
||||
392
lib/Activity/ActivityManager.php
Normal file
392
lib/Activity/ActivityManager.php
Normal file
@@ -0,0 +1,392 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2018 Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @author Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
56
lib/Activity/ChangeSet.php
Normal file
56
lib/Activity/ChangeSet.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2018 Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @author Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
147
lib/Activity/DeckProvider.php
Normal file
147
lib/Activity/DeckProvider.php
Normal file
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2018 Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @author Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
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('<pre>' . $event->getMessage() . '</pre>');
|
||||
}
|
||||
|
||||
return $event;
|
||||
}
|
||||
|
||||
public function deckUrl($endpoint) {
|
||||
return $this->urlGenerator->linkToRoute('deck.page.index') . '#!' . $endpoint;
|
||||
}
|
||||
}
|
||||
89
lib/Activity/Filter.php
Normal file
89
lib/Activity/Filter.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2018 Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @author Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
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'];
|
||||
}
|
||||
}
|
||||
86
lib/Activity/Setting.php
Normal file
86
lib/Activity/Setting.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2018 Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @author Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user