Merge branch 'master' into vue-master
This commit is contained in:
@@ -47,6 +47,7 @@ use OCP\IUser;
|
||||
|
||||
class ActivityManager {
|
||||
|
||||
const DECK_NOAUTHOR_COMMENT_SYSTEM_ENFORCED = 'DECK_NOAUTHOR_COMMENT_SYSTEM_ENFORCED';
|
||||
private $manager;
|
||||
private $userId;
|
||||
private $permissionService;
|
||||
@@ -142,7 +143,7 @@ class ActivityManager {
|
||||
$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 {acl}') : $this->l10n->t('{user} has shared the board {board} with {sharee}');
|
||||
$subject = $ownActivity ? $this->l10n->t('You have shared the board {board} with {acl}') : $this->l10n->t('{user} has shared the board {board} with {acl}');
|
||||
break;
|
||||
case self::SUBJECT_BOARD_UNSHARE:
|
||||
$subject = $ownActivity ? $this->l10n->t('You have removed {acl} from the board {board}') : $this->l10n->t('{user} has removed {acl} from the board {board}');
|
||||
@@ -280,7 +281,7 @@ class ActivityManager {
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
$events = [$this->createEvent($objectType, $entity, $subject, $author)];
|
||||
$events = [$this->createEvent($objectType, $entity, $subject)];
|
||||
} catch (\Exception $e) {
|
||||
// Ignore exception for undefined activities on update events
|
||||
}
|
||||
@@ -302,10 +303,10 @@ class ActivityManager {
|
||||
try {
|
||||
$object = $this->findObjectForEntity($objectType, $entity);
|
||||
} catch (DoesNotExistException $e) {
|
||||
\OC::$server->getLogger()->error('Could not create activity entry for ' . $subject . '. Entity not found.', $entity);
|
||||
\OC::$server->getLogger()->error('Could not create activity entry for ' . $subject . '. Entity not found.', (array)$entity);
|
||||
return null;
|
||||
} catch (MultipleObjectsReturnedException $e) {
|
||||
\OC::$server->getLogger()->error('Could not create activity entry for ' . $subject . '. Entity not found.', $entity);
|
||||
\OC::$server->getLogger()->error('Could not create activity entry for ' . $subject . '. Entity not found.', (array)$entity);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -327,6 +328,7 @@ class ActivityManager {
|
||||
// case self::SUBJECT_BOARD_UPDATE_COLOR
|
||||
break;
|
||||
case self::SUBJECT_CARD_COMMENT_CREATE:
|
||||
$eventType = 'deck_comment';
|
||||
$subjectParams = $this->findDetailsForCard($entity->getId());
|
||||
if (array_key_exists('comment', $additionalParams)) {
|
||||
/** @var IComment $entity */
|
||||
@@ -335,7 +337,6 @@ class ActivityManager {
|
||||
unset($additionalParams['comment']);
|
||||
}
|
||||
break;
|
||||
|
||||
case self::SUBJECT_STACK_CREATE:
|
||||
case self::SUBJECT_STACK_UPDATE:
|
||||
case self::SUBJECT_STACK_UPDATE_TITLE:
|
||||
@@ -356,15 +357,13 @@ class ActivityManager {
|
||||
case self::SUBJECT_LABEL_UNASSING:
|
||||
case self::SUBJECT_CARD_USER_ASSIGN:
|
||||
case self::SUBJECT_CARD_USER_UNASSIGN:
|
||||
$subjectParams = $this->findDetailsForCard($entity->getId());
|
||||
$object = $entity;
|
||||
$subjectParams = $this->findDetailsForCard($entity->getId(), $subject);
|
||||
break;
|
||||
case self::SUBJECT_ATTACHMENT_CREATE:
|
||||
case self::SUBJECT_ATTACHMENT_UPDATE:
|
||||
case self::SUBJECT_ATTACHMENT_DELETE:
|
||||
case self::SUBJECT_ATTACHMENT_RESTORE:
|
||||
$subjectParams = $this->findDetailsForAttachment($entity->getId());
|
||||
$object = $subjectParams['card'];
|
||||
break;
|
||||
case self::SUBJECT_BOARD_SHARE:
|
||||
case self::SUBJECT_BOARD_UNSHARE:
|
||||
@@ -402,6 +401,12 @@ class ActivityManager {
|
||||
$event->setMessage($message);
|
||||
}
|
||||
|
||||
// FIXME: We currently require activities for comments even if they are disabled though settings
|
||||
// Get rid of this once the frontend fetches comments/activity individually
|
||||
if ($eventType === 'deck_comment') {
|
||||
$event->setAuthor(self::DECK_NOAUTHOR_COMMENT_SYSTEM_ENFORCED);
|
||||
}
|
||||
|
||||
return $event;
|
||||
}
|
||||
|
||||
@@ -486,10 +491,17 @@ class ActivityManager {
|
||||
];
|
||||
}
|
||||
|
||||
private function findDetailsForCard($cardId) {
|
||||
private function findDetailsForCard($cardId, $subject = null) {
|
||||
$card = $this->cardMapper->find($cardId);
|
||||
$stack = $this->stackMapper->find($card->getStackId());
|
||||
$board = $this->boardMapper->find($stack->getBoardId());
|
||||
if ($subject !== self::SUBJECT_CARD_UPDATE_DESCRIPTION) {
|
||||
$card = [
|
||||
'id' => $card->getId(),
|
||||
'title' => $card->getTitle(),
|
||||
'archived' => $card->getArchived()
|
||||
];
|
||||
}
|
||||
return [
|
||||
'card' => $card,
|
||||
'stack' => $stack,
|
||||
|
||||
@@ -90,7 +90,7 @@ class DeckProvider implements IProvider {
|
||||
|
||||
$author = $event->getAuthor();
|
||||
// get author if
|
||||
if ($author === '' && array_key_exists('author', $subjectParams)) {
|
||||
if (($author === '' || $author === ActivityManager::DECK_NOAUTHOR_COMMENT_SYSTEM_ENFORCED) && array_key_exists('author', $subjectParams)) {
|
||||
$author = $subjectParams['author'];
|
||||
unset($subjectParams['author']);
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ class Filter implements \OCP\Activity\IFilter {
|
||||
* @since 11.0.0
|
||||
*/
|
||||
public function filterTypes(array $types) {
|
||||
return $types;
|
||||
return array_merge($types, ['deck_comment']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
53
lib/Activity/SettingComment.php
Normal file
53
lib/Activity/SettingComment.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2019 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 SettingComment extends Setting {
|
||||
|
||||
/**
|
||||
* @return string Lowercase a-z and underscore only identifier
|
||||
* @since 11.0.0
|
||||
*/
|
||||
public function getIdentifier() {
|
||||
return 'deck_comment';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string A translated string
|
||||
* @since 11.0.0
|
||||
*/
|
||||
public function getName() {
|
||||
return $this->l->t('A <strong>comment</strong> was created on a card');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool True when the option can be changed for the stream
|
||||
* @since 11.0.0
|
||||
*/
|
||||
public function canChangeStream() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,6 +25,7 @@ namespace OCA\Deck\AppInfo;
|
||||
|
||||
use Exception;
|
||||
use OCA\Deck\Activity\CommentEventHandler;
|
||||
use OCA\Deck\Capabilities;
|
||||
use OCA\Deck\Db\Acl;
|
||||
use OCA\Deck\Db\AclMapper;
|
||||
use OCA\Deck\Db\AssignedUsersMapper;
|
||||
@@ -33,7 +34,6 @@ use OCA\Deck\Middleware\ExceptionMiddleware;
|
||||
use OCA\Deck\Notification\Notifier;
|
||||
use OCA\Deck\Service\FullTextSearchService;
|
||||
use OCP\AppFramework\App;
|
||||
use OCA\Deck\Middleware\SharingMiddleware;
|
||||
use OCP\Collaboration\Resources\IManager;
|
||||
use OCP\Comments\CommentsEntityEvent;
|
||||
use OCP\FullTextSearch\IFullTextSearchManager;
|
||||
@@ -117,6 +117,9 @@ class Application extends App {
|
||||
|
||||
$this->registerCollaborationResources();
|
||||
|
||||
$this->getContainer()->registerCapability(Capabilities::class);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -138,12 +141,7 @@ 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'];
|
||||
});
|
||||
$notificationManager->registerNotifierService(Notifier::class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
44
lib/Capabilities.php
Normal file
44
lib/Capabilities.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2019 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;
|
||||
|
||||
|
||||
use OCP\Capabilities\ICapability;
|
||||
|
||||
class Capabilities implements ICapability {
|
||||
|
||||
/**
|
||||
* Function an app uses to return the capabilities
|
||||
*
|
||||
* @return array Array containing the apps capabilities
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function getCapabilities() {
|
||||
return [
|
||||
'deck' => [
|
||||
'version' => \OC::$server->getAppManager()->getAppVersion('deck')
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,8 @@
|
||||
/**
|
||||
* @copyright Copyright (c) 2018 Ryan Fletcher <ryan.fletcher@codepassion.ca>
|
||||
*
|
||||
* @copyright Copyright (c) 2019, Alexandru Puiu (alexpuiu20@yahoo.com)
|
||||
*
|
||||
* @author Ryan Fletcher <ryan.fletcher@codepassion.ca>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
@@ -70,11 +72,12 @@ class CardApiController extends ApiController {
|
||||
* @params $title
|
||||
* @params $type
|
||||
* @params $order
|
||||
* @params $description
|
||||
*
|
||||
* Get a specific card.
|
||||
*/
|
||||
public function create($title, $type = 'plain', $order = 999) {
|
||||
$card = $this->cardService->create($title, $this->request->getParam('stackId'), $type, $order, $this->userId);
|
||||
public function create($title, $type = 'plain', $order = 999, $description = '') {
|
||||
$card = $this->cardService->create($title, $this->request->getParam('stackId'), $type, $order, $this->userId, $description);
|
||||
return new DataResponse($card, HTTP::STATUS_OK);
|
||||
}
|
||||
|
||||
@@ -86,8 +89,8 @@ class CardApiController extends ApiController {
|
||||
*
|
||||
* Update a card
|
||||
*/
|
||||
public function update($title, $type, $order = 0, $description = '', $owner, $duedate = null) {
|
||||
$card = $this->cardService->update($this->request->getParam('cardId'), $title, $this->request->getParam('stackId'), $type, $order, $description, $owner, $duedate, 0);
|
||||
public function update($title, $type, $order = 0, $description = '', $owner, $duedate = null, $archived = null) {
|
||||
$card = $this->cardService->update($this->request->getParam('cardId'), $title, $this->request->getParam('stackId'), $type, $order, $description, $owner, $duedate, 0, $archived);
|
||||
return new DataResponse($card, HTTP::STATUS_OK);
|
||||
}
|
||||
|
||||
|
||||
@@ -103,12 +103,15 @@ class ConfigController extends Controller {
|
||||
$groups = array_map(function($groupId) {
|
||||
/** @var IGroup $groups */
|
||||
$group = $this->groupManager->get($groupId);
|
||||
if ($group === null) {
|
||||
return null;
|
||||
}
|
||||
return [
|
||||
'id' => $group->getGID(),
|
||||
'displayname' => $group->getDisplayName(),
|
||||
];
|
||||
}, $groups);
|
||||
return $groups;
|
||||
return array_filter($groups);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ class Board extends RelationalEntity {
|
||||
*/
|
||||
public function setAcl($acl) {
|
||||
foreach ($acl as $a) {
|
||||
$this->acl[$a->id] = $a;
|
||||
$this->acl[] = $a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace OCA\Deck\Db;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use OCP\AppFramework\QueryException;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\ILogger;
|
||||
use OCP\IUserManager;
|
||||
use OCP\IGroupManager;
|
||||
|
||||
@@ -234,7 +235,7 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
|
||||
\OC::$server->getLogger()->debug('Group ' . $acl->getId() . ' not found when mapping acl ' . $acl->getParticipant());
|
||||
return null;
|
||||
}
|
||||
if ($acl->getType() === Acl::PERMISSION_TYPE_CIRCLE) {
|
||||
if ($acl->getType() === Acl::PERMISSION_TYPE_CIRCLE && $this->circlesEnabled) {
|
||||
try {
|
||||
$circle = \OCA\Circles\Api\v1\Circles::detailsCircle($acl->getParticipant(), true);
|
||||
if ($circle) {
|
||||
@@ -244,7 +245,8 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
throw new \Exception('Unknown permission type for mapping Acl');
|
||||
\OC::$server->getLogger()->log(ILogger::WARN, 'Unknown permission type for mapping acl ' . $acl->getId());
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ class Group extends RelationalObject {
|
||||
public function getObjectSerialization() {
|
||||
return [
|
||||
'uid' => $this->object->getGID(),
|
||||
'displayname' => $this->object->getGID()
|
||||
'displayname' => $this->object->getDisplayName()
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -57,6 +57,26 @@ class Notifier implements INotifier {
|
||||
$this->boardMapper = $boardMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Identifier of the notifier, only use [a-z0-9_]
|
||||
*
|
||||
* @return string
|
||||
* @since 17.0.0
|
||||
*/
|
||||
public function getID(): string {
|
||||
return 'deck';
|
||||
}
|
||||
|
||||
/**
|
||||
* Human readable name describing the notifier
|
||||
*
|
||||
* @return string
|
||||
* @since 17.0.0
|
||||
*/
|
||||
public function getName(): string {
|
||||
return $this->l10nFactory->get('deck')->t('Deck');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param INotification $notification
|
||||
* @param string $languageCode The code of the language that should be used to prepare the notification
|
||||
@@ -64,7 +84,7 @@ class Notifier implements INotifier {
|
||||
* @throws \InvalidArgumentException When the notification was not prepared by a notifier
|
||||
* @since 9.0.0
|
||||
*/
|
||||
public function prepare(INotification $notification, $languageCode) {
|
||||
public function prepare(INotification $notification, string $languageCode): INotification {
|
||||
$l = $this->l10nFactory->get('deck', $languageCode);
|
||||
if ($notification->getApp() !== 'deck') {
|
||||
throw new \InvalidArgumentException();
|
||||
|
||||
@@ -101,7 +101,7 @@ class BoardService {
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function findAll($since = 0, $details = null) {
|
||||
public function findAll($since = -1, $details = null) {
|
||||
$userInfo = $this->getBoardPrerequisites();
|
||||
$userBoards = $this->boardMapper->findAllByUser($userInfo['user'], null, null, $since);
|
||||
$groupBoards = $this->boardMapper->findAllByGroups($userInfo['user'], $userInfo['groups'],null, null, $since);
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
/**
|
||||
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @copyright Copyright (c) 2019, Alexandru Puiu (alexpuiu20@yahoo.com)
|
||||
*
|
||||
* @author Julius Härtl <jus@bitgrid.net>
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
*
|
||||
@@ -147,6 +149,7 @@ class CardService {
|
||||
* @param $stackId
|
||||
* @param $type
|
||||
* @param integer $order
|
||||
* @param $description
|
||||
* @param $owner
|
||||
* @return \OCP\AppFramework\Db\Entity
|
||||
* @throws StatusException
|
||||
@@ -155,8 +158,7 @@ class CardService {
|
||||
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException
|
||||
* @throws BadrequestException
|
||||
*/
|
||||
public function create($title, $stackId, $type, $order, $owner) {
|
||||
|
||||
public function create($title, $stackId, $type, $order, $owner, $description = '') {
|
||||
if ($title === 'false' || $title === null) {
|
||||
throw new BadRequestException('title must be provided');
|
||||
}
|
||||
@@ -187,6 +189,7 @@ class CardService {
|
||||
$card->setType($type);
|
||||
$card->setOrder($order);
|
||||
$card->setOwner($owner);
|
||||
$card->setDescription($description);
|
||||
$card = $this->cardMapper->insert($card);
|
||||
$this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_CARD, $card, ActivityManager::SUBJECT_CARD_CREATE);
|
||||
$this->changeHelper->cardChanged($card->getId(), false);
|
||||
@@ -249,7 +252,7 @@ class CardService {
|
||||
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException
|
||||
* @throws BadRequestException
|
||||
*/
|
||||
public function update($id, $title, $stackId, $type, $order = 0, $description = '', $owner, $duedate = null, $deletedAt) {
|
||||
public function update($id, $title, $stackId, $type, $order = 0, $description = '', $owner, $duedate = null, $deletedAt = null, $archived = null) {
|
||||
|
||||
if (is_numeric($id) === false) {
|
||||
throw new BadRequestException('card id must be a number');
|
||||
@@ -276,7 +279,7 @@ class CardService {
|
||||
throw new StatusException('Operation not allowed. This board is archived.');
|
||||
}
|
||||
$card = $this->cardMapper->find($id);
|
||||
if ($card->getArchived()) {
|
||||
if ($archived !== null && $card->getArchived() && $archived === true) {
|
||||
throw new StatusException('Operation not allowed. This card is archived.');
|
||||
}
|
||||
$changes = new ChangeSet($card);
|
||||
@@ -301,7 +304,13 @@ class CardService {
|
||||
$card->setOrder($order);
|
||||
$card->setOwner($owner);
|
||||
$card->setDuedate($duedate);
|
||||
$card->setDeletedAt($deletedAt);
|
||||
if ($deletedAt) {
|
||||
$card->setDeletedAt($deletedAt);
|
||||
}
|
||||
if ($archived !== null) {
|
||||
$card->setArchived($archived);
|
||||
}
|
||||
|
||||
|
||||
// Trigger update events before setting description as it is handled separately
|
||||
$changes->setAfter($card);
|
||||
|
||||
@@ -178,8 +178,8 @@ class FullTextSearchService {
|
||||
/** @var Card $card */
|
||||
$card = $this->cardMapper->find((int)$document->getId());
|
||||
|
||||
$document->setTitle($card->getTitle());
|
||||
$document->setContent($card->getDescription());
|
||||
$document->setTitle(($card->getTitle() === null) ? '' : $card->getTitle());
|
||||
$document->setContent(($card->getDescription() === null) ? '' : $card->getDescription());
|
||||
$document->setAccess($this->generateDocumentAccessFromCardId((int)$card->getId()));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user