1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* @copyright Copyright (c) 2018 Julius Härtl <[email protected]> |
4
|
|
|
* |
5
|
|
|
* @copyright Copyright (c) 2019 Alexandru Puiu <[email protected]> |
6
|
|
|
* |
7
|
|
|
* @author Julius Härtl <[email protected]> |
8
|
|
|
* |
9
|
|
|
* @license GNU AGPL version 3 or any later version |
10
|
|
|
* |
11
|
|
|
* This program is free software: you can redistribute it and/or modify |
12
|
|
|
* it under the terms of the GNU Affero General Public License as |
13
|
|
|
* published by the Free Software Foundation, either version 3 of the |
14
|
|
|
* License, or (at your option) any later version. |
15
|
|
|
* |
16
|
|
|
* This program is distributed in the hope that it will be useful, |
17
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
18
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
19
|
|
|
* GNU Affero General Public License for more details. |
20
|
|
|
* |
21
|
|
|
* You should have received a copy of the GNU Affero General Public License |
22
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
23
|
|
|
* |
24
|
|
|
*/ |
25
|
|
|
|
26
|
|
|
namespace OCA\Deck\Activity; |
27
|
|
|
|
28
|
|
|
use InvalidArgumentException; |
29
|
|
|
use OCA\Deck\Db\Acl; |
30
|
|
|
use OCA\Deck\Db\AclMapper; |
31
|
|
|
use OCA\Deck\Db\AssignedUsers; |
32
|
|
|
use OCA\Deck\Db\Attachment; |
33
|
|
|
use OCA\Deck\Db\AttachmentMapper; |
34
|
|
|
use OCA\Deck\Db\Board; |
35
|
|
|
use OCA\Deck\Db\BoardMapper; |
36
|
|
|
use OCA\Deck\Db\Card; |
37
|
|
|
use OCA\Deck\Db\CardMapper; |
38
|
|
|
use OCA\Deck\Db\Label; |
39
|
|
|
use OCA\Deck\Db\Stack; |
40
|
|
|
use OCA\Deck\Db\StackMapper; |
41
|
|
|
use OCA\Deck\Service\PermissionService; |
42
|
|
|
use OCP\Activity\IEvent; |
43
|
|
|
use OCP\Activity\IManager; |
44
|
|
|
use OCP\AppFramework\Db\DoesNotExistException; |
45
|
|
|
use OCP\AppFramework\Db\MultipleObjectsReturnedException; |
46
|
|
|
use OCP\Comments\IComment; |
47
|
|
|
use OCP\IL10N; |
48
|
|
|
use OCP\IUser; |
49
|
|
|
|
50
|
|
|
class ActivityManager { |
51
|
|
|
|
52
|
|
|
const DECK_NOAUTHOR_COMMENT_SYSTEM_ENFORCED = 'DECK_NOAUTHOR_COMMENT_SYSTEM_ENFORCED'; |
53
|
|
|
private $manager; |
54
|
|
|
private $userId; |
55
|
|
|
private $permissionService; |
56
|
|
|
private $boardMapper; |
57
|
|
|
private $cardMapper; |
58
|
|
|
private $attachmentMapper; |
59
|
|
|
private $aclMapper; |
60
|
|
|
private $stackMapper; |
61
|
|
|
private $l10n; |
62
|
|
|
|
63
|
|
|
const DECK_OBJECT_BOARD = 'deck_board'; |
64
|
|
|
const DECK_OBJECT_CARD = 'deck_card'; |
65
|
|
|
|
66
|
|
|
const SUBJECT_BOARD_CREATE = 'board_create'; |
67
|
|
|
const SUBJECT_BOARD_UPDATE = 'board_update'; |
68
|
|
|
const SUBJECT_BOARD_UPDATE_TITLE = 'board_update_title'; |
69
|
|
|
const SUBJECT_BOARD_UPDATE_ARCHIVED = 'board_update_archived'; |
70
|
|
|
const SUBJECT_BOARD_DELETE = 'board_delete'; |
71
|
|
|
const SUBJECT_BOARD_RESTORE = 'board_restore'; |
72
|
|
|
const SUBJECT_BOARD_SHARE = 'board_share'; |
73
|
|
|
const SUBJECT_BOARD_UNSHARE = 'board_unshare'; |
74
|
|
|
|
75
|
|
|
const SUBJECT_STACK_CREATE = 'stack_create'; |
76
|
|
|
const SUBJECT_STACK_UPDATE = 'stack_update'; |
77
|
|
|
const SUBJECT_STACK_UPDATE_TITLE = 'stack_update_title'; |
78
|
|
|
const SUBJECT_STACK_UPDATE_ORDER = 'stack_update_order'; |
79
|
|
|
const SUBJECT_STACK_DELETE = 'stack_delete'; |
80
|
|
|
|
81
|
|
|
const SUBJECT_CARD_CREATE = 'card_create'; |
82
|
|
|
const SUBJECT_CARD_DELETE = 'card_delete'; |
83
|
|
|
const SUBJECT_CARD_RESTORE = 'card_restore'; |
84
|
|
|
const SUBJECT_CARD_UPDATE = 'card_update'; |
85
|
|
|
const SUBJECT_CARD_UPDATE_TITLE = 'card_update_title'; |
86
|
|
|
const SUBJECT_CARD_UPDATE_DESCRIPTION = 'card_update_description'; |
87
|
|
|
const SUBJECT_CARD_UPDATE_DUEDATE = 'card_update_duedate'; |
88
|
|
|
const SUBJECT_CARD_UPDATE_ARCHIVE = 'card_update_archive'; |
89
|
|
|
const SUBJECT_CARD_UPDATE_UNARCHIVE = 'card_update_unarchive'; |
90
|
|
|
const SUBJECT_CARD_UPDATE_STACKID = 'card_update_stackId'; |
91
|
|
|
const SUBJECT_CARD_USER_ASSIGN = 'card_user_assign'; |
92
|
|
|
const SUBJECT_CARD_USER_UNASSIGN = 'card_user_unassign'; |
93
|
|
|
|
94
|
|
|
const SUBJECT_ATTACHMENT_CREATE = 'attachment_create'; |
95
|
|
|
const SUBJECT_ATTACHMENT_UPDATE = 'attachment_update'; |
96
|
|
|
const SUBJECT_ATTACHMENT_DELETE = 'attachment_delete'; |
97
|
|
|
const SUBJECT_ATTACHMENT_RESTORE = 'attachment_restore'; |
98
|
|
|
|
99
|
|
|
const SUBJECT_LABEL_CREATE = 'label_create'; |
100
|
|
|
const SUBJECT_LABEL_UPDATE = 'label_update'; |
101
|
|
|
const SUBJECT_LABEL_DELETE = 'label_delete'; |
102
|
|
|
const SUBJECT_LABEL_ASSIGN = 'label_assign'; |
103
|
|
|
const SUBJECT_LABEL_UNASSING = 'label_unassign'; |
104
|
|
|
|
105
|
|
|
const SUBJECT_CARD_COMMENT_CREATE = 'card_comment_create'; |
106
|
|
|
|
107
|
|
|
public function __construct( |
108
|
|
|
IManager $manager, |
109
|
|
|
PermissionService $permissionsService, |
110
|
|
|
BoardMapper $boardMapper, |
111
|
|
|
CardMapper $cardMapper, |
112
|
|
|
StackMapper $stackMapper, |
113
|
|
|
AttachmentMapper $attachmentMapper, |
114
|
|
|
AclMapper $aclMapper, |
115
|
|
|
IL10N $l10n, |
116
|
|
|
$userId |
117
|
|
|
) { |
118
|
|
|
$this->manager = $manager; |
119
|
|
|
$this->permissionService = $permissionsService; |
120
|
|
|
$this->boardMapper = $boardMapper; |
121
|
|
|
$this->cardMapper = $cardMapper; |
122
|
|
|
$this->stackMapper = $stackMapper; |
123
|
|
|
$this->attachmentMapper = $attachmentMapper; |
124
|
|
|
$this->aclMapper = $aclMapper; |
125
|
|
|
$this->l10n = $l10n; |
126
|
|
|
$this->userId = $userId; |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
/** |
130
|
|
|
* @param $subjectIdentifier |
131
|
|
|
* @param array $subjectParams |
132
|
|
|
* @param bool $ownActivity |
133
|
|
|
* @return string |
134
|
|
|
*/ |
135
|
|
|
public function getActivityFormat($subjectIdentifier, $subjectParams = [], $ownActivity = false) { |
136
|
|
|
$subject = ''; |
137
|
|
|
switch ($subjectIdentifier) { |
138
|
|
View Code Duplication |
case self::SUBJECT_BOARD_CREATE: |
|
|
|
|
139
|
|
|
$subject = $ownActivity ? $this->l10n->t('You have created a new board {board}'): $this->l10n->t('{user} has created a new board {board}'); |
140
|
|
|
break; |
141
|
|
View Code Duplication |
case self::SUBJECT_BOARD_DELETE: |
|
|
|
|
142
|
|
|
$subject = $ownActivity ? $this->l10n->t('You have deleted the board {board}') : $this->l10n->t('{user} has deleted the board {board}'); |
143
|
|
|
break; |
144
|
|
View Code Duplication |
case self::SUBJECT_BOARD_RESTORE: |
|
|
|
|
145
|
|
|
$subject = $ownActivity ? $this->l10n->t('You have restored the board {board}') : $this->l10n->t('{user} has restored the board {board}'); |
146
|
|
|
break; |
147
|
|
View Code Duplication |
case self::SUBJECT_BOARD_SHARE: |
|
|
|
|
148
|
|
|
$subject = $ownActivity ? $this->l10n->t('You have shared the board {board} with {acl}') : $this->l10n->t('{user} has shared the board {board} with {acl}'); |
149
|
|
|
break; |
150
|
|
View Code Duplication |
case self::SUBJECT_BOARD_UNSHARE: |
|
|
|
|
151
|
|
|
$subject = $ownActivity ? $this->l10n->t('You have removed {acl} from the board {board}') : $this->l10n->t('{user} has removed {acl} from the board {board}'); |
152
|
|
|
break; |
153
|
|
View Code Duplication |
case self::SUBJECT_BOARD_UPDATE_TITLE: |
|
|
|
|
154
|
|
|
$subject = $ownActivity ? $this->l10n->t('You have renamed the board {before} to {board}') : $this->l10n->t('{user} has renamed the board {before} to {board}'); |
155
|
|
|
break; |
156
|
|
View Code Duplication |
case self::SUBJECT_BOARD_UPDATE_ARCHIVED: |
|
|
|
|
157
|
|
|
if (isset($subjectParams['after']) && $subjectParams['after']) { |
158
|
|
|
$subject = $ownActivity ? $this->l10n->t('You have archived the board {board}') : $this->l10n->t('{user} has archived the board {before}'); |
159
|
|
|
} else { |
160
|
|
|
$subject = $ownActivity ? $this->l10n->t('You have unarchived the board {board}') : $this->l10n->t('{user} has unarchived the board {before}'); |
161
|
|
|
} |
162
|
|
|
break; |
163
|
|
View Code Duplication |
case self::SUBJECT_STACK_CREATE: |
|
|
|
|
164
|
|
|
$subject = $ownActivity ? $this->l10n->t('You have created a new stack {stack} on board {board}') : $this->l10n->t('{user} has created a new stack {stack} on board {board}'); |
165
|
|
|
break; |
166
|
|
View Code Duplication |
case self::SUBJECT_STACK_UPDATE: |
|
|
|
|
167
|
|
|
$subject = $ownActivity ? $this->l10n->t('You have created a new stack {stack} on board {board}') : $this->l10n->t('{user} has created a new stack {stack} on board {board}'); |
168
|
|
|
break; |
169
|
|
View Code Duplication |
case self::SUBJECT_STACK_UPDATE_TITLE: |
|
|
|
|
170
|
|
|
$subject = $ownActivity ? $this->l10n->t('You have renamed stack {before} to {stack} on board {board}') : $this->l10n->t('{user} has renamed stack {before} to {stack} on board {board}'); |
171
|
|
|
break; |
172
|
|
View Code Duplication |
case self::SUBJECT_STACK_DELETE: |
|
|
|
|
173
|
|
|
$subject = $ownActivity ? $this->l10n->t('You have deleted stack {stack} on board {board}') : $this->l10n->t('{user} has deleted stack {stack} on board {board}'); |
174
|
|
|
break; |
175
|
|
View Code Duplication |
case self::SUBJECT_CARD_CREATE: |
|
|
|
|
176
|
|
|
$subject = $ownActivity ? $this->l10n->t('You have created card {card} in stack {stack} on board {board}') : $this->l10n->t('{user} has created card {card} in stack {stack} on board {board}'); |
177
|
|
|
break; |
178
|
|
View Code Duplication |
case self::SUBJECT_CARD_DELETE: |
|
|
|
|
179
|
|
|
$subject = $ownActivity ? $this->l10n->t('You have deleted card {card} in stack {stack} on board {board}') : $this->l10n->t('{user} has deleted card {card} in stack {stack} on board {board}'); |
180
|
|
|
break; |
181
|
|
View Code Duplication |
case self::SUBJECT_CARD_UPDATE_TITLE: |
|
|
|
|
182
|
|
|
$subject = $ownActivity ? $this->l10n->t('You have renamed the card {before} to {card}') : $this->l10n->t('{user} has renamed the card {before} to {card}'); |
183
|
|
|
break; |
184
|
|
View Code Duplication |
case self::SUBJECT_CARD_UPDATE_DESCRIPTION: |
|
|
|
|
185
|
|
|
if (!isset($subjectParams['before'])) { |
186
|
|
|
$subject = $ownActivity ? $this->l10n->t('You have added a description to card {card} in stack {stack} on board {board}') : $this->l10n->t('{user} has added a description to card {card} in stack {stack} on board {board}'); |
187
|
|
|
} else { |
188
|
|
|
$subject = $ownActivity ? $this->l10n->t('You have updated the description of card {card} in stack {stack} on board {board}') : $this->l10n->t('{user} has updated the description of the card {card} in stack {stack} on board {board}'); |
189
|
|
|
} |
190
|
|
|
break; |
191
|
|
View Code Duplication |
case self::SUBJECT_CARD_UPDATE_ARCHIVE: |
|
|
|
|
192
|
|
|
$subject = $ownActivity ? $this->l10n->t('You have archived card {card} in stack {stack} on board {board}') : $this->l10n->t('{user} has archived card {card} in stack {stack} on board {board}'); |
193
|
|
|
break; |
194
|
|
View Code Duplication |
case self::SUBJECT_CARD_UPDATE_UNARCHIVE: |
|
|
|
|
195
|
|
|
$subject = $ownActivity ? $this->l10n->t('You have unarchived card {card} in stack {stack} on board {board}') : $this->l10n->t('{user} has unarchived card {card} in stack {stack} on board {board}'); |
196
|
|
|
break; |
197
|
|
|
case self::SUBJECT_CARD_UPDATE_DUEDATE: |
198
|
|
|
if (!isset($subjectParams['after'])) { |
199
|
|
|
$subject = $ownActivity ? $this->l10n->t('You have removed the due date of card {card}') : $this->l10n->t('{user} has removed the due date of card {card}'); |
200
|
|
|
} else if (!isset($subjectParams['before']) && isset($subjectParams['after'])) { |
201
|
|
|
$subject = $ownActivity ? $this->l10n->t('You have set the due date of card {card} to {after}') : $this->l10n->t('{user} has set the due date of card {card} to {after}'); |
202
|
|
|
} else { |
203
|
|
|
$subject = $ownActivity ? $this->l10n->t('You have updated the due date of card {card} to {after}') : $this->l10n->t('{user} has updated the due date of card {card} to {after}'); |
204
|
|
|
} |
205
|
|
|
|
206
|
|
|
break; |
207
|
|
View Code Duplication |
case self::SUBJECT_LABEL_ASSIGN: |
|
|
|
|
208
|
|
|
$subject = $ownActivity ? $this->l10n->t('You have added the tag {label} to card {card} in stack {stack} on board {board}') : $this->l10n->t('{user} has added the tag {label} to card {card} in stack {stack} on board {board}'); |
209
|
|
|
break; |
210
|
|
View Code Duplication |
case self::SUBJECT_LABEL_UNASSING: |
|
|
|
|
211
|
|
|
$subject = $ownActivity ? $this->l10n->t('You have removed the tag {label} from card {card} in stack {stack} on board {board}') : $this->l10n->t('{user} has removed the tag {label} from card {card} in stack {stack} on board {board}'); |
212
|
|
|
break; |
213
|
|
View Code Duplication |
case self::SUBJECT_CARD_USER_ASSIGN: |
|
|
|
|
214
|
|
|
$subject = $ownActivity ? $this->l10n->t('You have assigned {assigneduser} to card {card} on board {board}') : $this->l10n->t('{user} has assigned {assigneduser} to card {card} on board {board}'); |
215
|
|
|
break; |
216
|
|
View Code Duplication |
case self::SUBJECT_CARD_USER_UNASSIGN: |
|
|
|
|
217
|
|
|
$subject = $ownActivity ? $this->l10n->t('You have unassigned {assigneduser} from card {card} on board {board}') : $this->l10n->t('{user} has unassigned {assigneduser} from card {card} on board {board}'); |
218
|
|
|
break; |
219
|
|
View Code Duplication |
case self::SUBJECT_CARD_UPDATE_STACKID: |
|
|
|
|
220
|
|
|
$subject = $ownActivity ? $this->l10n->t('You have moved the card {card} from stack {stackBefore} to {stack}') : $this->l10n->t('{user} has moved the card {card} from stack {stackBefore} to {stack}'); |
221
|
|
|
break; |
222
|
|
View Code Duplication |
case self::SUBJECT_ATTACHMENT_CREATE: |
|
|
|
|
223
|
|
|
$subject = $ownActivity ? $this->l10n->t('You have added the attachment {attachment} to card {card}') : $this->l10n->t('{user} has added the attachment {attachment} to card {card}'); |
224
|
|
|
break; |
225
|
|
View Code Duplication |
case self::SUBJECT_ATTACHMENT_UPDATE: |
|
|
|
|
226
|
|
|
$subject = $ownActivity ? $this->l10n->t('You have updated the attachment {attachment} on card {card}') : $this->l10n->t('{user} has updated the attachment {attachment} on card {card}'); |
227
|
|
|
break; |
228
|
|
View Code Duplication |
case self::SUBJECT_ATTACHMENT_DELETE: |
|
|
|
|
229
|
|
|
$subject = $ownActivity ? $this->l10n->t('You have deleted the attachment {attachment} from card {card}') : $this->l10n->t('{user} has deleted the attachment {attachment} from card {card}'); |
230
|
|
|
break; |
231
|
|
View Code Duplication |
case self::SUBJECT_ATTACHMENT_RESTORE: |
|
|
|
|
232
|
|
|
$subject = $ownActivity ? $this->l10n->t('You have restored the attachment {attachment} to card {card}') : $this->l10n->t('{user} has restored the attachment {attachment} to card {card}'); |
233
|
|
|
break; |
234
|
|
View Code Duplication |
case self::SUBJECT_CARD_COMMENT_CREATE: |
|
|
|
|
235
|
|
|
$subject = $ownActivity ? $this->l10n->t('You have commented on card {card}') : $this->l10n->t('{user} has commented on card {card}'); |
236
|
|
|
break; |
237
|
|
|
default: |
238
|
|
|
break; |
239
|
|
|
} |
240
|
|
|
return $subject; |
241
|
|
|
} |
242
|
|
|
|
243
|
|
|
public function triggerEvent($objectType, $entity, $subject, $additionalParams = [], $author = null) { |
244
|
|
|
try { |
245
|
|
|
$event = $this->createEvent($objectType, $entity, $subject, $additionalParams, $author); |
246
|
|
|
if ($event !== null) { |
247
|
|
|
$this->sendToUsers($event); |
248
|
|
|
} |
249
|
|
|
} catch (\Exception $e) { |
250
|
|
|
// Ignore exception for undefined activities on update events |
251
|
|
|
} |
252
|
|
|
} |
253
|
|
|
|
254
|
|
|
/** |
255
|
|
|
* |
256
|
|
|
* @param $objectType |
257
|
|
|
* @param ChangeSet $changeSet |
258
|
|
|
* @param $subject |
259
|
|
|
* @throws \Exception |
260
|
|
|
*/ |
261
|
|
|
public function triggerUpdateEvents($objectType, ChangeSet $changeSet, $subject) { |
262
|
|
|
$previousEntity = $changeSet->getBefore(); |
263
|
|
|
$entity = $changeSet->getAfter(); |
264
|
|
|
$events = []; |
265
|
|
|
if ($previousEntity !== null) { |
266
|
|
|
foreach ($entity->getUpdatedFields() as $field => $value) { |
267
|
|
|
$getter = 'get' . ucfirst($field); |
268
|
|
|
$subjectComplete = $subject . '_' . $field; |
269
|
|
|
$changes = [ |
270
|
|
|
'before' => $previousEntity->$getter(), |
271
|
|
|
'after' => $entity->$getter() |
272
|
|
|
]; |
273
|
|
|
if ($changes['before'] !== $changes['after']) { |
274
|
|
|
try { |
275
|
|
|
$event = $this->createEvent($objectType, $entity, $subjectComplete, $changes); |
276
|
|
|
if ($event !== null) { |
277
|
|
|
$events[] = $event; |
278
|
|
|
} |
279
|
|
|
} catch (\Exception $e) { |
280
|
|
|
// Ignore exception for undefined activities on update events |
281
|
|
|
} |
282
|
|
|
} |
283
|
|
|
} |
284
|
|
|
} else { |
285
|
|
|
try { |
286
|
|
|
$events = [$this->createEvent($objectType, $entity, $subject)]; |
287
|
|
|
} catch (\Exception $e) { |
288
|
|
|
// Ignore exception for undefined activities on update events |
289
|
|
|
} |
290
|
|
|
} |
291
|
|
|
foreach ($events as $event) { |
292
|
|
|
$this->sendToUsers($event); |
293
|
|
|
} |
294
|
|
|
} |
295
|
|
|
|
296
|
|
|
/** |
297
|
|
|
* @param $objectType |
298
|
|
|
* @param $entity |
299
|
|
|
* @param $subject |
300
|
|
|
* @param array $additionalParams |
301
|
|
|
* @return IEvent|null |
302
|
|
|
* @throws \Exception |
303
|
|
|
*/ |
304
|
|
|
private function createEvent($objectType, $entity, $subject, $additionalParams = [], $author = null) { |
305
|
|
|
try { |
306
|
|
|
$object = $this->findObjectForEntity($objectType, $entity); |
307
|
|
|
} catch (DoesNotExistException $e) { |
308
|
|
|
\OC::$server->getLogger()->error('Could not create activity entry for ' . $subject . '. Entity not found.', (array)$entity); |
309
|
|
|
return null; |
310
|
|
|
} catch (MultipleObjectsReturnedException $e) { |
311
|
|
|
\OC::$server->getLogger()->error('Could not create activity entry for ' . $subject . '. Entity not found.', (array)$entity); |
312
|
|
|
return null; |
313
|
|
|
} |
314
|
|
|
|
315
|
|
|
/** |
316
|
|
|
* Automatically fetch related details for subject parameters |
317
|
|
|
* depending on the subject |
318
|
|
|
*/ |
319
|
|
|
$eventType = 'deck'; |
320
|
|
|
$subjectParams = []; |
321
|
|
|
$message = null; |
322
|
|
|
switch ($subject) { |
323
|
|
|
// No need to enhance parameters since entity already contains the required data |
324
|
|
|
case self::SUBJECT_BOARD_CREATE: |
325
|
|
|
case self::SUBJECT_BOARD_UPDATE_TITLE: |
326
|
|
|
case self::SUBJECT_BOARD_UPDATE_ARCHIVED: |
327
|
|
|
case self::SUBJECT_BOARD_DELETE: |
328
|
|
|
case self::SUBJECT_BOARD_RESTORE: |
329
|
|
|
// Not defined as there is no activity for |
330
|
|
|
// case self::SUBJECT_BOARD_UPDATE_COLOR |
|
|
|
|
331
|
|
|
break; |
332
|
|
|
case self::SUBJECT_CARD_COMMENT_CREATE: |
333
|
|
|
$eventType = 'deck_comment'; |
334
|
|
|
$subjectParams = $this->findDetailsForCard($entity->getId()); |
335
|
|
|
if (array_key_exists('comment', $additionalParams)) { |
336
|
|
|
/** @var IComment $entity */ |
337
|
|
|
$comment = $additionalParams['comment']; |
338
|
|
|
$subjectParams['comment'] = $comment->getId(); |
339
|
|
|
unset($additionalParams['comment']); |
340
|
|
|
} |
341
|
|
|
break; |
342
|
|
|
case self::SUBJECT_STACK_CREATE: |
343
|
|
|
case self::SUBJECT_STACK_UPDATE: |
344
|
|
|
case self::SUBJECT_STACK_UPDATE_TITLE: |
345
|
|
|
case self::SUBJECT_STACK_UPDATE_ORDER: |
346
|
|
|
case self::SUBJECT_STACK_DELETE: |
347
|
|
|
$subjectParams = $this->findDetailsForStack($entity->getId()); |
348
|
|
|
break; |
349
|
|
|
|
350
|
|
|
case self::SUBJECT_CARD_CREATE: |
351
|
|
|
case self::SUBJECT_CARD_DELETE: |
352
|
|
|
case self::SUBJECT_CARD_UPDATE_ARCHIVE: |
353
|
|
|
case self::SUBJECT_CARD_UPDATE_UNARCHIVE: |
354
|
|
|
case self::SUBJECT_CARD_UPDATE_TITLE: |
355
|
|
|
case self::SUBJECT_CARD_UPDATE_DESCRIPTION: |
356
|
|
|
case self::SUBJECT_CARD_UPDATE_DUEDATE: |
357
|
|
|
case self::SUBJECT_CARD_UPDATE_STACKID: |
358
|
|
|
case self::SUBJECT_LABEL_ASSIGN: |
359
|
|
|
case self::SUBJECT_LABEL_UNASSING: |
360
|
|
|
case self::SUBJECT_CARD_USER_ASSIGN: |
361
|
|
|
case self::SUBJECT_CARD_USER_UNASSIGN: |
362
|
|
|
$subjectParams = $this->findDetailsForCard($entity->getId(), $subject); |
363
|
|
|
break; |
364
|
|
|
case self::SUBJECT_ATTACHMENT_CREATE: |
365
|
|
|
case self::SUBJECT_ATTACHMENT_UPDATE: |
366
|
|
|
case self::SUBJECT_ATTACHMENT_DELETE: |
367
|
|
|
case self::SUBJECT_ATTACHMENT_RESTORE: |
368
|
|
|
$subjectParams = $this->findDetailsForAttachment($entity->getId()); |
369
|
|
|
break; |
370
|
|
|
case self::SUBJECT_BOARD_SHARE: |
371
|
|
|
case self::SUBJECT_BOARD_UNSHARE: |
372
|
|
|
$subjectParams = $this->findDetailsForAcl($entity->getId()); |
373
|
|
|
break; |
374
|
|
|
default: |
375
|
|
|
throw new \Exception('Unknown subject for activity.'); |
376
|
|
|
break; |
|
|
|
|
377
|
|
|
} |
378
|
|
|
|
379
|
|
|
if ($subject === self::SUBJECT_CARD_UPDATE_DESCRIPTION){ |
380
|
|
|
$card = $subjectParams['card']; |
381
|
|
|
if ($card->getLastEditor() === $this->userId) { |
382
|
|
|
return null; |
383
|
|
|
} |
384
|
|
|
$subjectParams['diff'] = true; |
385
|
|
|
$eventType = 'deck_card_description'; |
386
|
|
|
} |
387
|
|
|
if ($subject === self::SUBJECT_CARD_UPDATE_STACKID) { |
388
|
|
|
$subjectParams['stackBefore'] = $this->stackMapper->find($additionalParams['before']); |
389
|
|
|
$subjectParams['stack'] = $this->stackMapper->find($additionalParams['after']); |
390
|
|
|
} |
391
|
|
|
|
392
|
|
|
$subjectParams['author'] = $this->userId; |
393
|
|
|
|
394
|
|
|
|
395
|
|
|
$event = $this->manager->generateEvent(); |
396
|
|
|
$event->setApp('deck') |
397
|
|
|
->setType($eventType) |
398
|
|
|
->setAuthor($author === null ? $this->userId : $author) |
399
|
|
|
->setObject($objectType, (int)$object->getId(), $object->getTitle()) |
400
|
|
|
->setSubject($subject, array_merge($subjectParams, $additionalParams)) |
401
|
|
|
->setTimestamp(time()); |
402
|
|
|
|
403
|
|
|
if ($message !== null) { |
404
|
|
|
$event->setMessage($message); |
405
|
|
|
} |
406
|
|
|
|
407
|
|
|
// FIXME: We currently require activities for comments even if they are disabled though settings |
408
|
|
|
// Get rid of this once the frontend fetches comments/activity individually |
409
|
|
|
if ($eventType === 'deck_comment') { |
410
|
|
|
$event->setAuthor(self::DECK_NOAUTHOR_COMMENT_SYSTEM_ENFORCED); |
411
|
|
|
} |
412
|
|
|
|
413
|
|
|
return $event; |
414
|
|
|
} |
415
|
|
|
|
416
|
|
|
/** |
417
|
|
|
* Publish activity to all users that are part of the board of a given object |
418
|
|
|
* |
419
|
|
|
* @param IEvent $event |
420
|
|
|
*/ |
421
|
|
|
private function sendToUsers(IEvent $event) { |
422
|
|
|
switch ($event->getObjectType()) { |
423
|
|
|
case self::DECK_OBJECT_BOARD: |
424
|
|
|
$mapper = $this->boardMapper; |
425
|
|
|
break; |
426
|
|
|
case self::DECK_OBJECT_CARD: |
427
|
|
|
$mapper = $this->cardMapper; |
428
|
|
|
break; |
429
|
|
|
} |
430
|
|
|
$boardId = $mapper->findBoardId($event->getObjectId()); |
|
|
|
|
431
|
|
|
/** @var IUser $user */ |
432
|
|
|
foreach ($this->permissionService->findUsers($boardId) as $user) { |
433
|
|
|
$event->setAffectedUser($user->getUID()); |
434
|
|
|
/** @noinspection DisconnectedForeachInstructionInspection */ |
435
|
|
|
$this->manager->publish($event); |
436
|
|
|
} |
437
|
|
|
} |
438
|
|
|
|
439
|
|
|
/** |
440
|
|
|
* @param $objectType |
441
|
|
|
* @param $entity |
442
|
|
|
* @return null|\OCA\Deck\Db\RelationalEntity|\OCP\AppFramework\Db\Entity |
443
|
|
|
* @throws \OCP\AppFramework\Db\DoesNotExistException |
444
|
|
|
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException |
445
|
|
|
*/ |
446
|
|
|
private function findObjectForEntity($objectType, $entity) { |
447
|
|
|
$className = \get_class($entity); |
448
|
|
|
if ($entity instanceof IComment) { |
449
|
|
|
$className = IComment::class; |
450
|
|
|
} |
451
|
|
|
$objectId = null; |
|
|
|
|
452
|
|
|
if ($objectType === self::DECK_OBJECT_CARD) { |
453
|
|
|
switch ($className) { |
454
|
|
|
case Card::class: |
455
|
|
|
$objectId = $entity->getId(); |
456
|
|
|
break; |
457
|
|
|
case Attachment::class: |
458
|
|
|
case Label::class: |
459
|
|
|
case AssignedUsers::class: |
460
|
|
|
$objectId = $entity->getCardId(); |
461
|
|
|
break; |
462
|
|
|
case IComment::class: |
463
|
|
|
$objectId = $entity->getObjectId(); |
464
|
|
|
break; |
465
|
|
|
default: |
466
|
|
|
throw new InvalidArgumentException('No entity relation present for '. $className . ' to ' . $objectType); |
467
|
|
|
} |
468
|
|
|
return $this->cardMapper->find($objectId); |
469
|
|
|
} |
470
|
|
|
if ($objectType === self::DECK_OBJECT_BOARD) { |
471
|
|
|
switch ($className) { |
472
|
|
|
case Board::class: |
473
|
|
|
$objectId = $entity->getId(); |
474
|
|
|
break; |
475
|
|
|
case Label::class: |
476
|
|
|
case Stack::class: |
477
|
|
|
case Acl::class: |
478
|
|
|
$objectId = $entity->getBoardId(); |
479
|
|
|
break; |
480
|
|
|
default: |
481
|
|
|
throw new InvalidArgumentException('No entity relation present for '. $className . ' to ' . $objectType); |
482
|
|
|
} |
483
|
|
|
return $this->boardMapper->find($objectId); |
484
|
|
|
} |
485
|
|
|
throw new InvalidArgumentException('No entity relation present for '. $className . ' to ' . $objectType); |
486
|
|
|
} |
487
|
|
|
|
488
|
|
View Code Duplication |
private function findDetailsForStack($stackId) { |
|
|
|
|
489
|
|
|
$stack = $this->stackMapper->find($stackId); |
490
|
|
|
$board = $this->boardMapper->find($stack->getBoardId()); |
491
|
|
|
return [ |
492
|
|
|
'stack' => $stack, |
493
|
|
|
'board' => $board |
494
|
|
|
]; |
495
|
|
|
} |
496
|
|
|
|
497
|
|
|
private function findDetailsForCard($cardId, $subject = null) { |
498
|
|
|
$card = $this->cardMapper->find($cardId); |
499
|
|
|
$stack = $this->stackMapper->find($card->getStackId()); |
500
|
|
|
$board = $this->boardMapper->find($stack->getBoardId()); |
501
|
|
|
if ($subject !== self::SUBJECT_CARD_UPDATE_DESCRIPTION) { |
502
|
|
|
$card = [ |
503
|
|
|
'id' => $card->getId(), |
504
|
|
|
'title' => $card->getTitle(), |
505
|
|
|
'archived' => $card->getArchived() |
506
|
|
|
]; |
507
|
|
|
} |
508
|
|
|
return [ |
509
|
|
|
'card' => $card, |
510
|
|
|
'stack' => $stack, |
511
|
|
|
'board' => $board |
512
|
|
|
]; |
513
|
|
|
} |
514
|
|
|
|
515
|
|
|
private function findDetailsForAttachment($attachmentId) { |
516
|
|
|
$attachment = $this->attachmentMapper->find($attachmentId); |
517
|
|
|
$data = $this->findDetailsForCard($attachment->getCardId()); |
518
|
|
|
return array_merge($data, ['attachment' => $attachment]); |
519
|
|
|
} |
520
|
|
|
|
521
|
|
View Code Duplication |
private function findDetailsForAcl($aclId) { |
|
|
|
|
522
|
|
|
$acl = $this->aclMapper->find($aclId); |
523
|
|
|
$board = $this->boardMapper->find($acl->getBoardId()); |
524
|
|
|
return [ |
525
|
|
|
'acl' => $acl, |
526
|
|
|
'board' => $board |
527
|
|
|
]; |
528
|
|
|
} |
529
|
|
|
|
530
|
|
|
} |
531
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.