diff --git a/appinfo/app.php b/appinfo/app.php index 3dc7fc82d..e7b8bf9b3 100644 --- a/appinfo/app.php +++ b/appinfo/app.php @@ -23,3 +23,4 @@ $app = new \OCA\Deck\AppInfo\Application(); $app->registerNavigationEntry(); +$app->registerNotifications(); \ No newline at end of file diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 02921ad38..efcf3bbb6 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -25,6 +25,7 @@ namespace OCA\Deck\AppInfo; use OCA\Deck\Db\Acl; use OCA\Deck\Db\AclMapper; +use OCA\Deck\Notification\Notifier; use OCP\AppFramework\App; use OCA\Deck\Middleware\SharingMiddleware; use OCP\IGroup; @@ -93,4 +94,15 @@ class Application extends App { ]; }); } + + public function registerNotifications() { + $notificationManager = \OC::$server->getNotificationManager(); + $self = &$this; + $notificationManager->registerNotifier(function() use (&$self) { + return $self->getContainer()->query(Notifier::class); + }, function () { + return ['id' => 'deck', 'name' => 'Deck']; + }); + + } } diff --git a/lib/Notification/Notifier.php b/lib/Notification/Notifier.php new file mode 100644 index 000000000..d1aa3c271 --- /dev/null +++ b/lib/Notification/Notifier.php @@ -0,0 +1,120 @@ + + * + * @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\Notification; + +use OCA\Deck\Db\BoardMapper; +use OCA\Deck\Db\CardMapper; +use OCP\IURLGenerator; +use OCP\IUserManager; +use OCP\L10N\IFactory; +use OCP\Notification\INotification; +use OCP\Notification\INotifier; +use OCP\RichObjectStrings\Definitions; + +class Notifier implements INotifier { + /** @var IFactory */ + protected $l10nFactory; + /** @var IURLGenerator */ + protected $url; + /** @var IUserManager */ + protected $userManager; + /** @var CardMapper */ + protected $cardMapper; + /** @var BoardMapper */ + protected $boardMapper; + + public function __construct( + IFactory $l10nFactory, + IURLGenerator $url, + IUserManager $userManager, + CardMapper $cardMapper, + BoardMapper $boardMapper, + Definitions $definitions + ) { + $this->l10nFactory = $l10nFactory; + $this->url = $url; + $this->userManager = $userManager; + $this->cardMapper = $cardMapper; + $this->boardMapper = $boardMapper; + $definitions->addDefinition('highlight', [ + 'author' => 'Deck', + 'app' => 'deck', + 'since' => '12.0.0', + 'parameters' => [ + 'name' => [ + 'since' => '12.0.0', + 'required' => true, + 'description' => 'The text that should be highlighted.', + 'example' => 'Foobar', + ] + ], + ]); + } + + /** + * @param INotification $notification + * @param string $languageCode The code of the language that should be used to prepare the notification + * @return INotification + * @throws \InvalidArgumentException When the notification was not prepared by a notifier + * @since 9.0.0 + */ + public function prepare(INotification $notification, $languageCode) { + if($notification->getApp() !== 'deck') { + throw new \InvalidArgumentException(); + } + $l = $this->l10nFactory->get('deck', $languageCode); + $notification->setIcon($this->url->getAbsoluteURL($this->url->imagePath('deck', 'deck-dark.svg'))); + + switch($notification->getSubject()) { + case 'board-shared': + $boardId = $notification->getObjectId(); + $params = $notification->getSubjectParameters(); + $initiator = \OC::$server->getUserManager()->get($params[1]); + if($initiator !== null) { + $dn = $initiator->getDisplayName(); + } else { + $dn = $params[1]; + } + $notification->setParsedSubject( + (string) $l->t('The board "%s" has been shared with you by %s.', [$params[0], $dn]) + )->setRichSubject( + (string) $l->t('{user} has shared the board {board} with you.'), + [ + 'user' => [ + 'type' => 'user', + 'id' => $params[1], + 'name' => $dn, + ], + 'board' => [ + 'type' => 'highlight', + 'name' => $params[0], + ], + ] + ); + $notification->setLink($this->url->linkToRouteAbsolute('deck.page.index') . '#!/board/'.$boardId.'/'); + break; + } + return $notification; + } +} \ No newline at end of file diff --git a/lib/Service/BoardService.php b/lib/Service/BoardService.php index 9e3f9948f..8d5efdbf4 100644 --- a/lib/Service/BoardService.php +++ b/lib/Service/BoardService.php @@ -23,6 +23,7 @@ namespace OCA\Deck\Service; +use DateTime; use OCA\Deck\ArchivedItemException; use OCA\Deck\Db\Acl; use OCA\Deck\Db\AclMapper; @@ -42,13 +43,15 @@ class BoardService { private $aclMapper; private $l10n; private $permissionService; + private $userId; - public function __construct(BoardMapper $boardMapper, IL10N $l10n, LabelMapper $labelMapper, AclMapper $aclMapper, PermissionService $permissionService) { + public function __construct(BoardMapper $boardMapper, IL10N $l10n, LabelMapper $labelMapper, AclMapper $aclMapper, PermissionService $permissionService, $userId) { $this->boardMapper = $boardMapper; $this->labelMapper = $labelMapper; $this->aclMapper = $aclMapper; $this->l10n = $l10n; $this->permissionService = $permissionService; + $this->userId = $userId; } public function findAll($userInfo) { @@ -209,6 +212,20 @@ class BoardService { $acl->setPermissionEdit($edit); $acl->setPermissionShare($share); $acl->setPermissionManage($manage); + /* Notify users about the shared board */ + if($acl->getType() === Acl::PERMISSION_TYPE_USER) { + $board = $this->boardMapper->find($boardId); + $initiator = \OC::$server->getUserManager()->get($this->userId); + $manager = \OC::$server->getNotificationManager(); + $notification = $manager->createNotification(); + $notification + ->setApp('deck') + ->setUser($participant['uid']) + ->setDateTime(new DateTime()) + ->setObject('board', $boardId)// $type and $id + ->setSubject('board-shared', [$board->getTitle(), $initiator->getUID()]); + $manager->notify($notification); + } $newAcl = $this->aclMapper->insert($acl); $this->boardMapper->mapAcl($newAcl); return $newAcl;