Completed
Push — activities ( f6cb6d...dc96a4 )
by Maxence
02:54
created

EventsService::onCircleDestruction()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 7

Duplication

Lines 11
Ratio 100 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 11
loc 11
rs 9.4285
cc 2
eloc 7
nc 2
nop 1
1
<?php
2
/**
3
 * Circles - Bring cloud-users closer together.
4
 *
5
 * This file is licensed under the Affero General Public License version 3 or
6
 * later. See the COPYING file.
7
 *
8
 * @author Maxence Lange <[email protected]>
9
 * @copyright 2017
10
 * @license GNU AGPL version 3 or any later version
11
 *
12
 * This program is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU Affero General Public License as
14
 * published by the Free Software Foundation, either version 3 of the
15
 * License, or (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU Affero General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU Affero General Public License
23
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24
 *
25
 */
26
27
namespace OCA\Circles\Service;
28
29
use OCA\Circles\Db\CirclesRequest;
30
use OCA\Circles\Model\Circle;
31
use OCA\Circles\Model\Member;
32
use OCP\Activity\IEvent;
33
use OCP\Activity\IManager;
34
use OCP\IUser;
35
use OCP\IUserManager;
36
37
class EventsService {
38
39
40
	/** @var string */
41
	private $userId;
42
43
	/** @var IManager */
44
	private $activityManager;
45
46
	/** @var IUserManager */
47
	private $userManager;
48
49
	/** @var CirclesRequest */
50
	private $circlesRequest;
51
52
	/** @var MiscService */
53
	private $miscService;
54
55
56
	/**
57
	 * Events constructor.
58
	 *
59
	 * @param string $userId
60
	 * @param IManager $activityManager
61
	 * @param IUserManager $userManager
62
	 * @param CirclesRequest $circlesRequest
63
	 * @param MiscService $miscService
64
	 */
65
	public function __construct(
66
		$userId, IManager $activityManager, IUserManager $userManager,
67
		CirclesRequest $circlesRequest, MiscService $miscService
68
	) {
69
		$this->userId = $userId;
70
		$this->activityManager = $activityManager;
71
		$this->userManager = $userManager;
72
		$this->circlesRequest = $circlesRequest;
73
		$this->miscService = $miscService;
74
	}
75
76
77
	/**
78
	 * onCircleCreation()
79
	 *
80
	 * Called when a circle is created.
81
	 * Broadcast an activity to the cloud
82
	 * We won't do anything if the circle is not PUBLIC or PRIVATE
83
	 *
84
	 * @param Circle $circle
85
	 */
86
	public function onCircleCreation(Circle $circle) {
87
88
		if ($circle->getType() !== Circle::CIRCLES_PUBLIC
89
			&& $circle->getType() !== Circle::CIRCLES_PRIVATE
90
		) {
91
			return;
92
		}
93
94
		$event = $this->generateEvent('circles_as_member');
95
		$event->setSubject('circle_create', ['circle' => json_encode($circle)]);
96
97
		$this->userManager->callForSeenUsers(
98
			function($user) use ($event) {
99
				/** @var IUser $user */
100
				$this->publishEvent($event, [$user]);
101
			}
102
		);
103
	}
104
105
106
	/**
107
	 * onCircleDestruction()
108
	 *
109
	 * Called when a circle is destroyed.
110
	 * Broadcast an activity on its members.
111
	 * We won't do anything if the circle is PERSONAL
112
	 *
113
	 * @param Circle $circle
114
	 */
115 View Code Duplication
	public function onCircleDestruction(Circle $circle) {
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...
116
		if ($circle->getType() === Circle::CIRCLES_PERSONAL) {
117
			return;
118
		}
119
120
		$event = $this->generateEvent('circles_as_member');
121
		$event->setSubject('circle_delete', ['circle' => json_encode($circle)]);
122
		$this->publishEvent(
123
			$event, $this->circlesRequest->getMembers($circle->getId(), Member::LEVEL_MEMBER)
124
		);
125
	}
126
127
128
	/**
129
	 * onMemberNew()
130
	 *
131
	 * Called when a member is added to a circle.
132
	 * Broadcast an activity to the new member and to the moderators of the circle.
133
	 * We won't do anything if the circle is PERSONAL
134
	 * If the level is still 0, we will redirect to onMemberAlmost and manage the
135
	 * invitation/request from there
136
	 * If the level is Owner, we ignore the event.
137
	 *
138
	 * @param Circle $circle
139
	 * @param Member $member
140
	 */
141
	public function onMemberNew(Circle $circle, Member $member) {
142
		if ($member->getLevel() === Member::LEVEL_OWNER
143
			|| $circle->getType() === Circle::CIRCLES_PERSONAL
144
		) {
145
			return;
146
		}
147
148
		if ($member->getLevel() === Member::LEVEL_NONE) {
149
			$this->onMemberAlmost($circle, $member);
150
151
			return;
152
		}
153
154
		$event = $this->generateEvent('circles_as_member');
155
		$event->setSubject(
156
			($this->userId === $member->getUserId()) ? 'member_join' : 'member_add',
157
			['circle' => json_encode($circle), 'member' => json_encode($member)]
158
		);
159
160
		$this->publishEvent(
161
			$event, $this->circlesRequest->getMembers($circle->getId(), Member::LEVEL_MEMBER)
162
		);
163
	}
164
165
166
	/**
167
	 * onMemberAlmost()
168
	 *
169
	 * Called when a member is added to a circle with level=0
170
	 * Trigger onMemberInvitation() or onMemberInvitationRequest() based on Member Status
171
	 *
172
	 * @param Circle $circle
173
	 * @param Member $member
174
	 */
175
	private function onMemberAlmost(Circle $circle, Member $member) {
176
177
		switch ($member->getStatus()) {
178
			case Member::STATUS_INVITED:
179
				$this->onMemberInvitation($circle, $member);
180
181
				return;
182
183
			case Member::STATUS_REQUEST:
184
				$this->onMemberInvitationRequest($circle, $member);
185
186
				return;
187
		}
188
	}
189
190
191
	/**
192
	 * onMemberInvitation()
193
	 *
194
	 * Called when a member is invited to a circle.
195
	 * Broadcast an activity to the invited member and to the moderators of the circle.
196
	 *
197
	 * @param Circle $circle
198
	 * @param Member $member
199
	 */
200 View Code Duplication
	public function onMemberInvitation(Circle $circle, Member $member) {
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...
201
		if ($circle->getType() !== Circle::CIRCLES_PRIVATE) {
202
			return;
203
		}
204
205
		$event = $this->generateEvent('circles_as_moderator');
206
		$event->setSubject(
207
			'member_invited', ['circle' => json_encode($circle), 'member' => json_encode($member)]
208
		);
209
210
		$this->publishEvent(
211
			$event, array_merge(
212
					  [$member],
213
					  $this->circlesRequest->getMembers($circle->getId(), Member::LEVEL_MODERATOR)
214
				  )
215
		);
216
	}
217
218
219
	/**
220
	 * onMemberInvitationRequest()
221
	 *
222
	 * Called when a member request an invitation to a private circle.
223
	 * Broadcast an activity to the requester and to the moderators of the circle.
224
	 *
225
	 * @param Circle $circle
226
	 * @param Member $member
227
	 */
228 View Code Duplication
	public function onMemberInvitationRequest(Circle $circle, Member $member) {
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...
229
		if ($circle->getType() !== Circle::CIRCLES_PRIVATE) {
230
			return;
231
		}
232
233
		$event = $this->generateEvent('circles_as_moderator');
234
		$event->setSubject(
235
			'member_request_invitation',
236
			['circle' => json_encode($circle), 'member' => json_encode($member)]
237
		);
238
239
		$this->publishEvent(
240
			$event, array_merge(
241
					  [$member],
242
					  $this->circlesRequest->getMembers($circle->getId(), Member::LEVEL_MODERATOR)
243
				  )
244
		);
245
246
	}
247
248
249
	/**
250
	 * onCircleMemberLeaving()
251
	 *
252
	 * Called when a member is removed from a circle.
253
	 * Broadcast an activity to the new member and to the moderators of the circle.
254
	 * We won't do anything if the circle is PERSONAL
255
	 *
256
	 * @param Circle $circle
257
	 * @param Member $member
258
	 */
259
	public function onMemberLeaving(Circle $circle, Member $member) {
260
		if ($circle->getType() === Circle::CIRCLES_PERSONAL) {
261
			return;
262
		}
263
264
		$event = $this->generateEvent('circles_as_member');
265
		$event->setSubject(
266
			($this->userId === $member->getUserId()) ? 'member_left' : 'member_remove',
267
			['circle' => json_encode($circle), 'member' => json_encode($member)]
268
		);
269
270
		$this->publishEvent(
271
			$event, array_merge(
272
					  [$member],
273
					  $this->circlesRequest->getMembers($circle->getId(), Member::LEVEL_MEMBER)
274
				  )
275
		);
276
277
	}
278
279
280
	/**
281
	 * onMemberNew()
282
	 *
283
	 * Called when a member have his level changed.
284
	 * Broadcast an activity to all moderator of the circle.
285
	 * We won't do anything if the circle is PERSONAL
286
	 * If the level is Owner, we identify the event as a Coup d'Etat and we broadcast all members.
287
	 *
288
	 * @param Circle $circle
289
	 * @param Member $member
290
	 */
291
	public function onMemberLevel(Circle $circle, Member $member) {
292
		if ($circle->getType() === Circle::CIRCLES_PERSONAL) {
293
			return;
294
		}
295
296
		if ($member->getLevel() === Member::LEVEL_OWNER) {
297
			$this->onMemberOwner($circle, $member);
298
299
			return;
300
		}
301
302
		$event = $this->generateEvent('circles_as_moderator');
303
		$event->setSubject(
304
			'member_level',
305
			['circle' => json_encode($circle), 'member' => json_encode($member)]
306
		);
307
308
		$mods = $this->circlesRequest->getMembers($circle->getId(), Member::LEVEL_MODERATOR);
309
		if ($member->getLevel() < Member::LEVEL_MODERATOR) {
310
			array_push($mods, $member);
311
		}
312
313
		$this->publishEvent($event, $mods);
314
	}
315
316
317 View Code Duplication
	private function onMemberOwner(Circle $circle, Member $member) {
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...
318
		$event = $this->generateEvent('circles_as_moderator');
319
		$event->setSubject(
320
			'member_owner',
321
			['circle' => json_encode($circle), 'member' => json_encode($member)]
322
		);
323
324
		$this->publishEvent(
325
			$event, $this->circlesRequest->getMembers(
326
			$circle->getId(), Member::LEVEL_MEMBER
327
		)
328
		);
329
	}
330
331
	/**
332
	 * generateEvent()
333
	 * Create an Activity Event with the basic settings for the app.
334
	 *
335
	 * @param $type
336
	 *
337
	 * @return \OCP\Activity\IEvent
338
	 */
339
	private function generateEvent($type) {
340
		$event = $this->activityManager->generateEvent();
341
		$event->setApp('circles')
342
			  ->setType($type)
343
			  ->setAuthor($this->userId);
344
345
		return $event;
346
	}
347
348
349
	private function publishEvent(IEvent $event, array $users) {
350
		foreach ($users AS $user) {
351
			if ($user INSTANCEOF IUser) {
1 ignored issue
show
Bug introduced by
The class OCP\IUser does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
352
				$userId = $user->getUID();
353
			} else if ($user INSTANCEOF Member) {
354
				$userId = $user->getUserId();
355
			} else {
356
				continue;
357
			}
358
359
			$event->setAffectedUser($userId);
360
			$this->activityManager->publish($event);
361
		}
362
	}
363
364
365
}