Completed
Push — master ( 0ee0a5...f5691e )
by Julius
23s queued 10s
created

ActivityManager::findObjectForEntity()   B

Complexity

Conditions 11
Paths 11

Size

Total Lines 35

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 35
rs 7.3166
c 0
b 0
f 0
cc 11
nc 11
nop 2

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * @copyright Copyright (c) 2018 Julius Härtl <[email protected]>
4
 *
5
 * @author Julius Härtl <[email protected]>
6
 *
7
 * @license GNU AGPL version 3 or any later version
8
 *
9
 * This program is free software: you can redistribute it and/or modify
10
 * it under the terms of the GNU Affero General Public License as
11
 * published by the Free Software Foundation, either version 3 of the
12
 * License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU Affero General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Affero General Public License
20
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21
 *
22
 */
23
24
namespace OCA\Deck\Activity;
25
26
use InvalidArgumentException;
27
use OCA\Deck\Db\Acl;
28
use OCA\Deck\Db\AclMapper;
29
use OCA\Deck\Db\AssignedUsers;
30
use OCA\Deck\Db\Attachment;
31
use OCA\Deck\Db\AttachmentMapper;
32
use OCA\Deck\Db\Board;
33
use OCA\Deck\Db\BoardMapper;
34
use OCA\Deck\Db\Card;
35
use OCA\Deck\Db\CardMapper;
36
use OCA\Deck\Db\Label;
37
use OCA\Deck\Db\Stack;
38
use OCA\Deck\Db\StackMapper;
39
use OCA\Deck\Service\PermissionService;
40
use OCP\Activity\IEvent;
41
use OCP\Activity\IManager;
42
use OCP\AppFramework\Db\DoesNotExistException;
43
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
44
use OCP\IL10N;
45
use OCP\IUser;
46
47
class ActivityManager {
48
49
	private $manager;
50
	private $userId;
51
	private $permissionService;
52
	private $boardMapper;
53
	private $cardMapper;
54
	private $attachmentMapper;
55
	private $aclMapper;
56
	private $stackMapper;
57
	private $l10n;
58
59
	const DECK_OBJECT_BOARD = 'deck_board';
60
	const DECK_OBJECT_CARD = 'deck_card';
61
62
	const SUBJECT_BOARD_CREATE = 'board_create';
63
	const SUBJECT_BOARD_UPDATE = 'board_update';
64
	const SUBJECT_BOARD_UPDATE_TITLE = 'board_update_title';
65
	const SUBJECT_BOARD_UPDATE_ARCHIVED = 'board_update_archived';
66
	const SUBJECT_BOARD_DELETE = 'board_delete';
67
	const SUBJECT_BOARD_RESTORE = 'board_restore';
68
	const SUBJECT_BOARD_SHARE = 'board_share';
69
	const SUBJECT_BOARD_UNSHARE = 'board_unshare';
70
71
	const SUBJECT_STACK_CREATE = 'stack_create';
72
	const SUBJECT_STACK_UPDATE = 'stack_update';
73
	const SUBJECT_STACK_UPDATE_TITLE = 'stack_update_title';
74
	const SUBJECT_STACK_UPDATE_ORDER = 'stack_update_order';
75
	const SUBJECT_STACK_DELETE = 'stack_delete';
76
77
	const SUBJECT_CARD_CREATE = 'card_create';
78
	const SUBJECT_CARD_DELETE = 'card_delete';
79
	const SUBJECT_CARD_RESTORE = 'card_restore';
80
	const SUBJECT_CARD_UPDATE = 'card_update';
81
	const SUBJECT_CARD_UPDATE_TITLE = 'card_update_title';
82
	const SUBJECT_CARD_UPDATE_DESCRIPTION = 'card_update_description';
83
	const SUBJECT_CARD_UPDATE_DUEDATE = 'card_update_duedate';
84
	const SUBJECT_CARD_UPDATE_ARCHIVE = 'card_update_archive';
85
	const SUBJECT_CARD_UPDATE_UNARCHIVE = 'card_update_unarchive';
86
	const SUBJECT_CARD_UPDATE_STACKID = 'card_update_stackId';
87
	const SUBJECT_CARD_USER_ASSIGN = 'card_user_assign';
88
	const SUBJECT_CARD_USER_UNASSIGN = 'card_user_unassign';
89
90
	const SUBJECT_ATTACHMENT_CREATE = 'attachment_create';
91
	const SUBJECT_ATTACHMENT_UPDATE = 'attachment_update';
92
	const SUBJECT_ATTACHMENT_DELETE = 'attachment_delete';
93
	const SUBJECT_ATTACHMENT_RESTORE = 'attachment_restore';
94
95
	const SUBJECT_LABEL_CREATE = 'label_create';
96
	const SUBJECT_LABEL_UPDATE = 'label_update';
97
	const SUBJECT_LABEL_DELETE = 'label_delete';
98
	const SUBJECT_LABEL_ASSIGN = 'label_assign';
99
	const SUBJECT_LABEL_UNASSING = 'label_unassign';
100
101 View Code Duplication
	public function __construct(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
102
		IManager $manager,
103
		PermissionService $permissionsService,
104
		BoardMapper $boardMapper,
105
		CardMapper $cardMapper,
106
		StackMapper $stackMapper,
107
		AttachmentMapper $attachmentMapper,
108
		AclMapper $aclMapper,
109
		IL10N $l10n,
110
		$userId
111
	) {
112
		$this->manager = $manager;
113
		$this->permissionService = $permissionsService;
114
		$this->boardMapper = $boardMapper;
115
		$this->cardMapper = $cardMapper;
116
		$this->stackMapper = $stackMapper;
117
		$this->attachmentMapper = $attachmentMapper;
118
		$this->aclMapper = $aclMapper;
119
		$this->l10n = $l10n;
120
		$this->userId = $userId;
121
	}
122
123
	/**
124
	 * @param $subjectIdentifier
125
	 * @param array $subjectParams
126
	 * @param bool $ownActivity
127
	 * @return string
128
	 */
129
	public function getActivityFormat($subjectIdentifier, $subjectParams = [], $ownActivity = false) {
130
		$subject = '';
131
		switch ($subjectIdentifier) {
132 View Code Duplication
			case self::SUBJECT_BOARD_CREATE:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
133
				$subject = $ownActivity ? $this->l10n->t('You have created a new board {board}'): $this->l10n->t('{user} has created a new board {board}');
134
				break;
135 View Code Duplication
			case self::SUBJECT_BOARD_DELETE:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
136
				$subject = $ownActivity ? $this->l10n->t('You have deleted the board {board}') : $this->l10n->t('{user} has deleted the board {board}');
137
				break;
138 View Code Duplication
			case self::SUBJECT_BOARD_RESTORE:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
139
				$subject = $ownActivity ? $this->l10n->t('You have restored the board {board}') : $this->l10n->t('{user} has restored the board {board}');
140
				break;
141 View Code Duplication
			case self::SUBJECT_BOARD_SHARE:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
142
				$subject = $ownActivity ? $this->l10n->t('You have shared the board {board} with {acl}') : $this->l10n->t('{user} has shared the board {board} with {sharee}');
143
				break;
144 View Code Duplication
			case self::SUBJECT_BOARD_UNSHARE:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
145
				$subject = $ownActivity ? $this->l10n->t('You have removed {acl} from the board {board}') : $this->l10n->t('{user} has removed {acl} from the board {board}');
146
				break;
147
148 View Code Duplication
			case self::SUBJECT_BOARD_UPDATE_TITLE:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
149
				$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}');
150
				break;
151 View Code Duplication
			case self::SUBJECT_BOARD_UPDATE_ARCHIVED:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
152
				if (isset($subjectParams['after']) && $subjectParams['after']) {
153
					$subject = $ownActivity ? $this->l10n->t('You have archived the board {board}') : $this->l10n->t('{user} has archived the board {before}');
154
				} else {
155
					$subject = $ownActivity ? $this->l10n->t('You have unarchived the board {board}') : $this->l10n->t('{user} has unarchived the board {before}');
156
				}
157
				break;
158
159 View Code Duplication
			case self::SUBJECT_STACK_CREATE:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
160
				$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}');
161
				break;
162 View Code Duplication
			case self::SUBJECT_STACK_UPDATE:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
163
				$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}');
164
				break;
165 View Code Duplication
			case self::SUBJECT_STACK_UPDATE_TITLE:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
166
				$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}');
167
				break;
168 View Code Duplication
			case self::SUBJECT_STACK_DELETE:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
169
				$subject = $ownActivity ? $this->l10n->t('You have deleted {stack} on {board}') : $this->l10n->t('{user} has deleted {stack} on {board}');
170
				break;
171 View Code Duplication
			case self::SUBJECT_CARD_CREATE:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
172
				$subject = $ownActivity ? $this->l10n->t('You have created {card} in {stack} on {board}') : $this->l10n->t('{user} has created {card} in {stack} on {board}');
173
				break;
174 View Code Duplication
			case self::SUBJECT_CARD_DELETE:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
175
				$subject = $ownActivity ? $this->l10n->t('You have deleted {card} in {stack} on {board}') : $this->l10n->t('{user} has deleted {card} in {stack} on {board}');
176
				break;
177 View Code Duplication
			case self::SUBJECT_CARD_UPDATE_TITLE:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
178
				$subject = $ownActivity ? $this->l10n->t('You have renamed the card {before} to {card}') : $this->l10n->t('{user} has renamed the card {before} to {card}');
179
				break;
180 View Code Duplication
			case self::SUBJECT_CARD_UPDATE_DESCRIPTION:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
181
				if (!isset($subjectParams['before'])) {
182
					$subject = $ownActivity ? $this->l10n->t('You have added a description to {card} in {stack} on {board}') : $this->l10n->t('{user} has added a description to {card} in {stack} on {board}');
183
				} else {
184
					$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}');
185
				}
186
				break;
187 View Code Duplication
			case self::SUBJECT_CARD_UPDATE_ARCHIVE:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
188
				$subject = $ownActivity ? $this->l10n->t('You have archived {card} in {stack} on {board}') : $this->l10n->t('{user} has archived {card} in {stack} on {board}');
189
				break;
190 View Code Duplication
			case self::SUBJECT_CARD_UPDATE_UNARCHIVE:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
191
				$subject = $ownActivity ? $this->l10n->t('You have unarchived {card} in {stack} on {board}') : $this->l10n->t('{user} has unarchived {card} in {stack} on {board}');
192
				break;
193
			case self::SUBJECT_CARD_UPDATE_DUEDATE:
194
				if (!isset($subjectParams['after'])) {
195
					$subject = $ownActivity ? $this->l10n->t('You have removed the due date of {card}') : $this->l10n->t('{user} has removed the due date of {card}');
196
				} else if (isset($subjectParams['before']) && !isset($subjectParams['after'])) {
197
					$subject = $ownActivity ? $this->l10n->t('You have set the due date of {card} to {after}') : $this->l10n->t('{user} has set the due date of {card} to {after}');
198
				} else {
199
					$subject = $ownActivity ? $this->l10n->t('You have updated the due date of {card} to {after}') : $this->l10n->t('{user} has updated the due date of {card} to {after}');
200
				}
201
202
				break;
203 View Code Duplication
			case self::SUBJECT_LABEL_ASSIGN:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
204
				$subject = $ownActivity ? $this->l10n->t('You have added the label {label} to {card} in {stack} on {board}') : $this->l10n->t('{user} has added the label {label} to {card} in {stack} on {board}');
205
				break;
206 View Code Duplication
			case self::SUBJECT_LABEL_UNASSING:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
207
				$subject = $ownActivity ? $this->l10n->t('You have removed the label {label} from {card} in {stack} on {board}') : $this->l10n->t('{user} has removed the label {label} from {card} in {stack} on {board}');
208
				break;
209 View Code Duplication
			case self::SUBJECT_CARD_USER_ASSIGN:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
210
				$subject = $ownActivity ? $this->l10n->t('You have assigned {assigneduser} to {card} on {board}') : $this->l10n->t('{user} has assigned {assigneduser} to {card} on {board}');
211
				break;
212 View Code Duplication
			case self::SUBJECT_CARD_USER_UNASSIGN:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
213
				$subject = $ownActivity ? $this->l10n->t('You have unassigned {assigneduser} from {card} on {board}') : $this->l10n->t('{user} has unassigned {assigneduser} from {card} on {board}');
214
				break;
215 View Code Duplication
			case self::SUBJECT_CARD_UPDATE_STACKID:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
216
				$subject = $ownActivity ? $this->l10n->t('You have moved the card {card} from {stackBefore} to {stack}') : $this->l10n->t('{user} has moved the card {card} from {stackBefore} to {stack}');
217
				break;
218 View Code Duplication
			case self::SUBJECT_ATTACHMENT_CREATE:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
219
				$subject = $ownActivity ? $this->l10n->t('You have added the attachment {attachment} to {card}') : $this->l10n->t('{user} has added the attachment {attachment} to {card}');
220
				break;
221 View Code Duplication
			case self::SUBJECT_ATTACHMENT_UPDATE:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
222
				$subject = $ownActivity ? $this->l10n->t('You have updated the attachment {attachment} on {card}') : $this->l10n->t('{user} has updated the attachment {attachment} to {card}');
223
				break;
224 View Code Duplication
			case self::SUBJECT_ATTACHMENT_DELETE:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
225
				$subject = $ownActivity ? $this->l10n->t('You have deleted the attachment {attachment} from {card}') : $this->l10n->t('{user} has deleted the attachment {attachment} to {card}');
226
				break;
227 View Code Duplication
			case self::SUBJECT_ATTACHMENT_RESTORE:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
228
				$subject = $ownActivity ? $this->l10n->t('You have restored the attachment {attachment} to {card}') : $this->l10n->t('{user} has restored the attachment {attachment} to {card}');
229
				break;
230
			default:
231
				break;
232
		}
233
		return $subject;
234
	}
235
236
	public function triggerEvent($objectType, $entity, $subject, $additionalParams = []) {
237
		try {
238
			$event = $this->createEvent($objectType, $entity, $subject, $additionalParams);
239
			$this->sendToUsers($event);
0 ignored issues
show
Bug introduced by
It seems like $event defined by $this->createEvent($obje...ect, $additionalParams) on line 238 can be null; however, OCA\Deck\Activity\ActivityManager::sendToUsers() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
240
		} catch (\Exception $e) {
241
			// Ignore exception for undefined activities on update events
242
		}
243
	}
244
245
	/**
246
	 *
247
	 * @param $objectType
248
	 * @param ChangeSet $changeSet
249
	 * @param $subject
250
	 * @throws \Exception
251
	 */
252
	public function triggerUpdateEvents($objectType, ChangeSet $changeSet, $subject) {
253
		$previousEntity = $changeSet->getBefore();
254
		$entity = $changeSet->getAfter();
255
		$events = [];
256
		if ($previousEntity !== null) {
257
			foreach ($entity->getUpdatedFields() as $field => $value) {
258
				$getter = 'get' . ucfirst($field);
259
				$subject = $subject . '_' . $field;
260
				$changes = [
261
					'before' => $previousEntity->$getter(),
262
					'after' => $entity->$getter()
263
				];
264
				if ($changes['before'] !== $changes['after']) {
265
					try {
266
						$event = $this->createEvent($objectType, $entity, $subject, $changes);
267
						$events[] = $event;
268
					} catch (\Exception $e) {
269
						// Ignore exception for undefined activities on update events
270
					}
271
				}
272
			}
273
		} else {
274
			try {
275
				$events = [$this->createEvent($objectType, $entity, $subject)];
276
			} catch (\Exception $e) {
277
				// Ignore exception for undefined activities on update events
278
			}
279
		}
280
		foreach ($events as $event) {
281
			$this->sendToUsers($event);
282
		}
283
	}
284
285
	/**
286
	 * @param $objectType
287
	 * @param $entity
288
	 * @param $subject
289
	 * @param array $additionalParams
290
	 * @return IEvent
291
	 * @throws \Exception
292
	 */
293
	private function createEvent($objectType, $entity, $subject, $additionalParams = []) {
294
		try {
295
			$object = $this->findObjectForEntity($objectType, $entity);
296
		} catch (DoesNotExistException $e) {
297
		} catch (MultipleObjectsReturnedException $e) {
298
			\OC::$server->getLogger()->error('Could not create activity entry for ' . $subject . '. Entity not found.', $entity);
299
			return null;
300
		}
301
302
		/**
303
		 * Automatically fetch related details for subject parameters
304
		 * depending on the subject
305
		 */
306
		$subjectParams = [];
307
		$message = null;
308
		switch ($subject) {
309
			// No need to enhance parameters since entity already contains the required data
310
			case self::SUBJECT_BOARD_CREATE:
311
			case self::SUBJECT_BOARD_UPDATE_TITLE:
312
			case self::SUBJECT_BOARD_UPDATE_ARCHIVED:
313
			case self::SUBJECT_BOARD_DELETE:
314
			case self::SUBJECT_BOARD_RESTORE:
315
			// Not defined as there is no activity for
316
			// case self::SUBJECT_BOARD_UPDATE_COLOR
317
				break;
318
319
			case self::SUBJECT_STACK_CREATE:
320
			case self::SUBJECT_STACK_UPDATE:
321
			case self::SUBJECT_STACK_UPDATE_TITLE:
322
			case self::SUBJECT_STACK_UPDATE_ORDER:
323
			case self::SUBJECT_STACK_DELETE:
324
				$subjectParams = $this->findDetailsForStack($entity->getId());
325
				break;
326
327
			case self::SUBJECT_CARD_CREATE:
328
			case self::SUBJECT_CARD_DELETE:
329
			case self::SUBJECT_CARD_UPDATE_ARCHIVE:
330
			case self::SUBJECT_CARD_UPDATE_UNARCHIVE:
331
			case self::SUBJECT_CARD_UPDATE_TITLE:
332
			case self::SUBJECT_CARD_UPDATE_DESCRIPTION:
333
			case self::SUBJECT_CARD_UPDATE_DUEDATE:
334
			case self::SUBJECT_CARD_UPDATE_STACKID:
335
			case self::SUBJECT_LABEL_ASSIGN:
336
			case self::SUBJECT_LABEL_UNASSING:
337
			case self::SUBJECT_CARD_USER_ASSIGN:
338
			case self::SUBJECT_CARD_USER_UNASSIGN:
339
				$subjectParams = $this->findDetailsForCard($entity->getId());
340
				$object = $entity;
341
				break;
342
			case self::SUBJECT_ATTACHMENT_CREATE:
343
			case self::SUBJECT_ATTACHMENT_UPDATE:
344
			case self::SUBJECT_ATTACHMENT_DELETE:
345
			case self::SUBJECT_ATTACHMENT_RESTORE:
346
				$subjectParams = $this->findDetailsForAttachment($entity->getId());
347
				$object = $subjectParams['card'];
348
				break;
349
			case self::SUBJECT_BOARD_SHARE:
350
			case self::SUBJECT_BOARD_UNSHARE:
351
				$subjectParams = $this->findDetailsForAcl($entity->getId());
352
				break;
353
			default:
354
				throw new \Exception('Unknown subject for activity.');
355
				break;
0 ignored issues
show
Unused Code introduced by
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
356
		}
357
358
		if ($subject === self::SUBJECT_CARD_UPDATE_DESCRIPTION){
359
			$subjectParams['diff'] = true;
360
		}
361
		if ($subject === self::SUBJECT_CARD_UPDATE_STACKID) {
362
			$subjectParams['stackBefore'] = $this->stackMapper->find($additionalParams['before']);
363
		}
364
365
		$event = $this->manager->generateEvent();
366
		$event->setApp('deck')
367
			->setType('deck')
368
			->setAuthor($this->userId)
369
			->setObject($objectType, (int)$object->getId(), $object->getTitle())
370
			->setSubject($subject, array_merge($subjectParams, $additionalParams))
371
			->setTimestamp(time());
372
373
		if ($message !== null) {
374
			$event->setMessage($message);
375
		}
376
377
		return $event;
378
	}
379
380
	/**
381
	 * Publish activity to all users that are part of the board of a given object
382
	 *
383
	 * @param IEvent $event
384
	 */
385
	private function sendToUsers(IEvent $event) {
386
		switch ($event->getObjectType()) {
387
			case self::DECK_OBJECT_BOARD:
388
				$mapper = $this->boardMapper;
389
				break;
390
			case self::DECK_OBJECT_CARD:
391
				$mapper = $this->cardMapper;
392
				break;
393
		}
394
		$boardId = $mapper->findBoardId($event->getObjectId());
0 ignored issues
show
Bug introduced by
The variable $mapper does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
395
		/** @var IUser $user */
396
		foreach ($this->permissionService->findUsers($boardId) as $user) {
397
			$event->setAffectedUser($user->getUID());
398
			/** @noinspection DisconnectedForeachInstructionInspection */
399
			$this->manager->publish($event);
400
		}
401
	}
402
403
	/**
404
	 * @param $objectType
405
	 * @param $entity
406
	 * @return null|\OCA\Deck\Db\RelationalEntity|\OCP\AppFramework\Db\Entity
407
	 * @throws \OCP\AppFramework\Db\DoesNotExistException
408
	 * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException
409
	 */
410
	private function findObjectForEntity($objectType, $entity) {
411
		$className = \get_class($entity);
412
		$objectId = null;
0 ignored issues
show
Unused Code introduced by
$objectId is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
413
		if ($objectType === self::DECK_OBJECT_CARD) {
414
			switch ($className) {
415
				case Card::class:
416
					$objectId = $entity->getId();
417
					break;
418
				case Attachment::class:
419
				case Label::class:
420
				case AssignedUsers::class:
421
					$objectId = $entity->getCardId();
422
					break;
423
				default:
424
					throw new InvalidArgumentException('No entity relation present for '. $className . ' to ' . $objectType);
425
			}
426
			return $this->cardMapper->find($objectId);
427
		}
428
		if ($objectType === self::DECK_OBJECT_BOARD) {
429
			switch ($className) {
430
				case Board::class:
431
					$objectId = $entity->getId();
432
					break;
433
				case Label::class:
434
				case Stack::class:
435
				case Acl::class:
436
					$objectId = $entity->getBoardId();
437
					break;
438
				default:
439
					throw new InvalidArgumentException('No entity relation present for '. $className . ' to ' . $objectType);
440
			}
441
			return $this->boardMapper->find($objectId);
442
		}
443
		throw new InvalidArgumentException('No entity relation present for '. $className . ' to ' . $objectType);
444
	}
445
446 View Code Duplication
	private function findDetailsForStack($stackId) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
447
		$stack = $this->stackMapper->find($stackId);
448
		$board = $this->boardMapper->find($stack->getBoardId());
449
		return [
450
			'stack' => $stack,
451
			'board' => $board
452
		];
453
	}
454
455
	private function findDetailsForCard($cardId) {
456
		$card = $this->cardMapper->find($cardId);
457
		$stack = $this->stackMapper->find($card->getStackId());
458
		$board = $this->boardMapper->find($stack->getBoardId());
459
		return [
460
			'card' => $card,
461
			'stack' => $stack,
462
			'board' => $board
463
		];
464
	}
465
466
	private function findDetailsForAttachment($attachmentId) {
467
		$attachment = $this->attachmentMapper->find($attachmentId);
468
		$data = $this->findDetailsForCard($attachment->getCardId());
469
		return array_merge($data, ['attachment' => $attachment]);
470
	}
471
472 View Code Duplication
	private function findDetailsForAcl($aclId) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
473
		$acl = $this->aclMapper->find($aclId);
474
		$board = $this->boardMapper->find($acl->getBoardId());
475
		return [
476
			'acl' => $acl,
477
			'board' => $board
478
		];
479
	}
480
481
}
482