Completed
Push — master ( d5d16c...173441 )
by Maxence
03:33 queued 01:39
created

EventsService::onMemberNew()   A

Complexity

Conditions 5
Paths 3

Size

Total Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 31
rs 9.1128
c 0
b 0
f 0
cc 5
nc 3
nop 2
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
 * @author: Vinicius Cubas Brand <[email protected]>
10
 * @copyright 2017
11
 * @license GNU AGPL version 3 or any later version
12
 *
13
 * This program is free software: you can redistribute it and/or modify
14
 * it under the terms of the GNU Affero General Public License as
15
 * published by the Free Software Foundation, either version 3 of the
16
 * License, or (at your option) any later version.
17
 *
18
 * This program is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 * GNU Affero General Public License for more details.
22
 *
23
 * You should have received a copy of the GNU Affero General Public License
24
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
25
 *
26
 */
27
28
namespace OCA\Circles\Service;
29
30
use OCA\Circles\AppInfo\Application;
31
use OCA\Circles\Db\CirclesRequest;
32
use OCA\Circles\Db\MembersRequest;
33
use OCA\Circles\Model\Circle;
34
use OCA\Circles\Model\FederatedLink;
35
use OCA\Circles\Model\Member;
36
use OCP\Activity\IEvent;
37
use OCP\Activity\IManager as IActivityManager;
38
use OCP\AppFramework\Utility\ITimeFactory;
39
use OCP\IURLGenerator;
40
use OCP\IUser;
41
use OCP\IUserManager;
42
use OCP\Notification\IManager as INotificationManager;
43
use OCP\Notification\INotification;
44
use Symfony\Component\EventDispatcher\EventDispatcher;
45
use Symfony\Component\EventDispatcher\GenericEvent;
46
47
class EventsService {
48
49
50
	/** @var string */
51
	private $userId;
52
53
	/** @var ITimeFactory */
54
	private $time;
55
56
	/** @var IActivityManager */
57
	private $activityManager;
58
59
	/** @var INotificationManager */
60
	private $notificationManager;
61
62
	/** @var IUserManager */
63
	private $userManager;
64
65
	/** @var IURLGenerator */
66
	private $urlGenerator;
67
68
	/** @var EventDispatcher */
69
	private $eventDispatcher;
70
71
	/** @var CirclesRequest */
72
	private $circlesRequest;
73
74
	/** @var MembersRequest */
75
	private $membersRequest;
76
77
	/** @var ConfigService */
78
	private $configService;
79
80
	/** @var MiscService */
81
	private $miscService;
82
83
84
	/**
85
	 * Events constructor.
86
	 *
87
	 * @param string $userId
88
	 * @param ITimeFactory $time
89
	 * @param IActivityManager $activityManager
90
	 * @param INotificationManager $notificationManager
91
	 * @param IUserManager $userManager
92
	 * @param IURLGenerator $urlGenerator
93
	 * @param EventDispatcher $eventDispatcher
94
	 * @param CirclesRequest $circlesRequest
95
	 * @param MembersRequest $membersRequest
96
	 * @param ConfigService $configService
97
	 * @param MiscService $miscService
98
	 */
99 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...
100
		$userId, ITimeFactory $time, IActivityManager $activityManager,
101
		INotificationManager $notificationManager, IUserManager $userManager, IURLGenerator $urlGenerator,
102
		EventDispatcher $eventDispatcher, CirclesRequest $circlesRequest, MembersRequest $membersRequest,
103
		ConfigService $configService, MiscService $miscService
104
	) {
105
		$this->userId = $userId;
106
		$this->time = $time;
107
		$this->activityManager = $activityManager;
108
		$this->notificationManager = $notificationManager;
109
		$this->userManager = $userManager;
110
		$this->urlGenerator = $urlGenerator;
111
		$this->eventDispatcher = $eventDispatcher;
112
		$this->circlesRequest = $circlesRequest;
113
		$this->membersRequest = $membersRequest;
114
		$this->configService = $configService;
115
		$this->miscService = $miscService;
116
	}
117
118
119
	/**
120
	 * onCircleCreation()
121
	 *
122
	 * Called when a circle is created.
123
	 * Broadcast an activity to the cloud
124
	 * We won't do anything if the circle is not PUBLIC or CLOSED
125
	 *
126
	 * @param Circle $circle
127
	 */
128
	public function onCircleCreation(Circle $circle) {
129
		if ($this->configService->getAppValue(ConfigService::CIRCLES_ACTIVITY_ON_CREATION) !== '1'
130
			|| ($circle->getType() !== Circle::CIRCLES_PUBLIC
131
				&& $circle->getType() !== Circle::CIRCLES_CLOSED)) {
132
			return;
133
		}
134
135
		$event = $this->generateEvent('circles_as_member');
136
		$event->setSubject('circle_create', ['circle' => json_encode($circle)]);
137
138
		$this->userManager->callForSeenUsers(
139
			function($user) use ($event) {
140
				/** @var IUser $user */
141
				$this->publishEvent($event, [$user]);
142
			}
143
		);
144
145
		$this->dispatch('\OCA\Circles::onCircleCreation', ['circle' => $circle]);
146
	}
147
148
149
	/**
150
	 * onCircleDestruction()
151
	 *
152
	 * Called when a circle is destroyed.
153
	 * Broadcast an activity on its members.
154
	 * We won't do anything if the circle is PERSONAL
155
	 *
156
	 * @param Circle $circle
157
	 */
158
	public function onCircleDestruction(Circle $circle) {
159
		if ($circle->getType() === Circle::CIRCLES_PERSONAL) {
160
			return;
161
		}
162
163
		$event = $this->generateEvent('circles_as_member');
164
		$event->setSubject('circle_delete', ['circle' => json_encode($circle)]);
165
		$this->publishEvent(
166
			$event,
167
			$this->membersRequest->forceGetMembers(
168
				$circle->getUniqueId(), Member::LEVEL_MEMBER, true
169
			)
170
		);
171
172
		$this->dispatch('\OCA\Circles::onCircleDestruction', ['circle' => $circle]);
173
	}
174
175
176
	/**
177
	 * onMemberNew()
178
	 *
179
	 * Called when a member is added to a circle.
180
	 * Broadcast an activity to the new member and to the moderators of the circle.
181
	 * We won't do anything if the circle is PERSONAL
182
	 * If the level is still 0, we will redirect to onMemberAlmost and manage the
183
	 * invitation/request from there
184
	 * If the level is Owner, we ignore the event.
185
	 *
186
	 * @param Circle $circle
187
	 * @param Member $member
188
	 */
189
	public function onMemberNew(Circle $circle, Member $member) {
190
		if ($member->getLevel() === Member::LEVEL_OWNER
191
			|| $circle->getType() === Circle::CIRCLES_PERSONAL
192
		) {
193
			return;
194
		}
195
196
		if ($member->getLevel() === Member::LEVEL_NONE) {
197
			$this->onMemberAlmost($circle, $member);
198
199
			return;
200
		}
201
202
		$event = $this->generateEvent('circles_as_member');
203
		$event->setSubject(
204
			($this->userId === $member->getUserId()) ? 'member_join' : 'member_add',
205
			['circle' => json_encode($circle), 'member' => json_encode($member)]
206
		);
207
208
		$this->publishEvent(
209
			$event, array_merge(
210
					  [$member],
211
					  $this->membersRequest->forceGetMembers(
212
						  $circle->getUniqueId(), Member::LEVEL_MODERATOR, true
213
					  )
214
				  )
215
		);
216
		$this->dispatch('\OCA\Circles::onMemberNew', ['circle' => $circle, 'member' => $member]);
217
218
		$this->notificationOnMemberNew($circle, $member);
219
	}
220
221
222
	/**
223
	 * onMemberAlmost()
224
	 *
225
	 * Called when a member is added to a circle with level=0
226
	 * Trigger onMemberInvitation() or onMemberInvitationRequest() based on Member Status
227
	 *
228
	 * @param Circle $circle
229
	 * @param Member $member
230
	 */
231
	private function onMemberAlmost(Circle $circle, Member $member) {
232
233
		switch ($member->getStatus()) {
234
			case Member::STATUS_INVITED:
235
				$this->onMemberInvited($circle, $member);
236
237
				return;
238
239
			case Member::STATUS_REQUEST:
240
				$this->onMemberRequesting($circle, $member);
241
242
				return;
243
		}
244
	}
245
246
247
	/**
248
	 * onMemberInvited()
249
	 *
250
	 * Called when a member is invited to a circle.
251
	 * Broadcast an activity to the invited member and to the moderators of the circle.
252
	 *
253
	 * @param Circle $circle
254
	 * @param Member $member
255
	 */
256 View Code Duplication
	private function onMemberInvited(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...
257
		if ($circle->getType() !== Circle::CIRCLES_CLOSED) {
258
			return;
259
		}
260
261
		$event = $this->generateEvent('circles_as_moderator');
262
		$event->setSubject(
263
			'member_invited', ['circle' => json_encode($circle), 'member' => json_encode($member)]
264
		);
265
266
		$this->publishEvent(
267
			$event, array_merge(
268
					  [$member],
269
					  $this->membersRequest->forceGetMembers(
270
						  $circle->getUniqueId(), Member::LEVEL_MODERATOR, true
271
					  )
272
				  )
273
		);
274
		$this->dispatch('\OCA\Circles::onMemberInvited', ['circle' => $circle, 'member' => $member]);
275
276
		$this->notificationOnInvitation($circle, $member);
277
	}
278
279
280
	/**
281
	 * onMemberRequesting()
282
	 *
283
	 * Called when a member request an invitation to a private circle.
284
	 * Broadcast an activity to the requester and to the moderators of the circle.
285
	 *
286
	 * @param Circle $circle
287
	 * @param Member $member
288
	 */
289 View Code Duplication
	private function onMemberRequesting(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...
290
		if ($circle->getType() !== Circle::CIRCLES_CLOSED) {
291
			return;
292
		}
293
294
		$event = $this->generateEvent('circles_as_moderator');
295
		$event->setSubject(
296
			'member_request_invitation',
297
			['circle' => json_encode($circle), 'member' => json_encode($member)]
298
		);
299
300
		$this->publishEvent(
301
			$event, array_merge(
302
					  [$member],
303
					  $this->membersRequest->forceGetMembers(
304
						  $circle->getUniqueId(), Member::LEVEL_MODERATOR, true
305
					  )
306
				  )
307
		);
308
		$this->dispatch('\OCA\Circles::onMemberRequesting', ['circle' => $circle, 'member' => $member]);
309
310
		$this->notificationOnRequest($circle, $member);
311
	}
312
313
314
	/**
315
	 * onMemberLeaving()
316
	 *
317
	 * Called when a member is removed from a circle.
318
	 * Broadcast an activity to the leaving member and to the moderators of the circle.
319
	 * We won't do anything if the circle is PERSONAL
320
	 *
321
	 * @param Circle $circle
322
	 * @param Member $member
323
	 */
324
	public function onMemberLeaving(Circle $circle, Member $member) {
325
		if ($circle->getType() === Circle::CIRCLES_PERSONAL) {
326
			return;
327
		}
328
329
		$event = $this->generateEvent('circles_as_member');
330
		$event->setSubject(
331
			($this->userId === $member->getUserId()) ? 'member_left' : 'member_remove',
332
			['circle' => json_encode($circle), 'member' => json_encode($member)]
333
		);
334
335
		$this->publishEvent(
336
			$event, array_merge(
337
					  [$member],
338
					  $this->membersRequest->forceGetMembers(
339
						  $circle->getUniqueId(), Member::LEVEL_MODERATOR, true
340
					  )
341
				  )
342
		);
343
		$this->dispatch('\OCA\Circles::onMemberLeaving', ['circle' => $circle, 'member' => $member]);
344
345
		$this->deleteNotification('membership', $member->getMemberId());
346
		$this->deleteNotification('membership_request', $member->getMemberId());
347
	}
348
349
350
	/**
351
	 * onMemberLevel()
352
	 *
353
	 * Called when a member have his level changed.
354
	 * Broadcast an activity to all moderator of the circle, and the member if he is demoted.
355
	 * If the level is Owner, we identify the event as a Coup d'Etat and we broadcast all members.
356
	 *
357
	 * @param Circle $circle
358
	 * @param Member $member
359
	 */
360 View Code Duplication
	public function onMemberLevel(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...
361
		if ($member->getLevel() === Member::LEVEL_OWNER) {
362
			$this->onMemberOwner($circle, $member);
363
364
			return;
365
		}
366
367
		$event = $this->generateEvent('circles_as_moderator');
368
		$event->setSubject(
369
			'member_level',
370
			['circle' => json_encode($circle), 'member' => json_encode($member)]
371
		);
372
373
		$mods = $this->membersRequest->forceGetMembers(
374
			$circle->getUniqueId(), Member::LEVEL_MODERATOR, true
375
		);
376
		$this->membersRequest->avoidDuplicateMembers($mods, [$member]);
377
378
		$this->publishEvent($event, $mods);
379
		$this->dispatch('\OCA\Circles::onMemberLevel', ['circle' => $circle, 'member' => $member]);
380
	}
381
382
383
	/**
384
	 * onMemberOwner()
385
	 *
386
	 * Called when the owner rights of a circle have be given to another member.
387
	 *
388
	 * @param Circle $circle
389
	 * @param Member $member
390
	 */
391
	public function onMemberOwner(Circle $circle, Member $member) {
392
		$event = $this->generateEvent('circles_as_moderator');
393
		$event->setSubject(
394
			'member_owner',
395
			['circle' => json_encode($circle), 'member' => json_encode($member)]
396
		);
397
398
		$this->publishEvent(
399
			$event,
400
			$this->membersRequest->forceGetMembers(
401
				$circle->getUniqueId(), Member::LEVEL_MEMBER, true
402
			)
403
		);
404
405
		$this->dispatch('\OCA\Circles::onMemberOwner', ['circle' => $circle, 'member' => $member]);
406
	}
407
408
409
	/**
410
	 * onGroupLink()
411
	 *
412
	 * Called when a group is linked to a circle.
413
	 * Broadcast an activity to the member of the linked group and to the moderators of the circle.
414
	 * We won't do anything if the circle is PERSONAL
415
	 *
416
	 * @param Circle $circle
417
	 * @param Member $group
418
	 */
419 View Code Duplication
	public function onGroupLink(Circle $circle, Member $group) {
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...
420
		if ($circle->getType() === Circle::CIRCLES_PERSONAL) {
421
			return;
422
		}
423
424
		$event = $this->generateEvent('circles_as_moderator');
425
		$event->setSubject(
426
			'group_link',
427
			['circle' => json_encode($circle), 'group' => json_encode($group)]
428
		);
429
430
		$mods = $this->membersRequest->forceGetMembers(
431
			$circle->getUniqueId(), Member::LEVEL_MODERATOR, true
432
		);
433
		$this->membersRequest->avoidDuplicateMembers(
434
			$mods, $this->membersRequest->getGroupMemberMembers($group)
435
		);
436
437
		$this->publishEvent($event, $mods);
438
		$this->dispatch('\OCA\Circles::onGroupLink', ['circle' => $circle, 'group' => $group]);
439
	}
440
441
442
	/**
443
	 * onGroupUnlink()
444
	 *
445
	 * Called when a group is unlinked from a circle.
446
	 * Broadcast an activity to the member of the unlinked group and to the moderators of the
447
	 * circle. We won't do anything if the circle is PERSONAL
448
	 *
449
	 * @param Circle $circle
450
	 * @param Member $group
451
	 */
452 View Code Duplication
	public function onGroupUnlink(Circle $circle, Member $group) {
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...
453
		if ($circle->getType() === Circle::CIRCLES_PERSONAL) {
454
			return;
455
		}
456
457
		$event = $this->generateEvent('circles_as_moderator');
458
		$event->setSubject(
459
			'group_unlink',
460
			['circle' => json_encode($circle), 'group' => json_encode($group)]
461
		);
462
463
		$mods = $this->membersRequest->forceGetMembers(
464
			$circle->getUniqueId(), Member::LEVEL_MODERATOR, true
465
		);
466
		$this->membersRequest->avoidDuplicateMembers(
467
			$mods, $this->membersRequest->getGroupMemberMembers($group)
468
		);
469
470
		$this->publishEvent($event, $mods);
471
		$this->dispatch('\OCA\Circles::onGroupUnlink', ['circle' => $circle, 'group' => $group]);
472
	}
473
474
475
	/**
476
	 * onGroupLevel()
477
	 *
478
	 * Called when a linked group have his level changed.
479
	 * Broadcast an activity to all moderator of the circle, and the group members in case of
480
	 * demotion.
481
	 *
482
	 * @param Circle $circle
483
	 * @param Member $group
484
	 */
485 View Code Duplication
	public function onGroupLevel(Circle $circle, Member $group) {
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...
486
		if ($circle->getType() === Circle::CIRCLES_PERSONAL) {
487
			return;
488
		}
489
490
		$event = $this->generateEvent('circles_as_moderator');
491
		$event->setSubject(
492
			'group_level',
493
			['circle' => json_encode($circle), 'group' => json_encode($group)]
494
		);
495
496
		$mods = $this->membersRequest->forceGetMembers(
497
			$circle->getUniqueId(), Member::LEVEL_MODERATOR, true
498
		);
499
		$this->membersRequest->avoidDuplicateMembers(
500
			$mods, $this->membersRequest->getGroupMemberMembers($group)
501
		);
502
503
		$this->publishEvent($event, $mods);
504
		$this->dispatch('\OCA\Circles::onGroupLevel', ['circle' => $circle, 'group' => $group]);
505
	}
506
507
508
	/**
509
	 * onLinkRequestSent()
510
	 *
511
	 * Called when a request to generate a link with a remote circle is sent.
512
	 * Broadcast an activity to the moderators of the circle.
513
	 *
514
	 * @param Circle $circle
515
	 * @param FederatedLink $link
516
	 */
517 View Code Duplication
	public function onLinkRequestSent(Circle $circle, FederatedLink $link) {
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...
518
		$event = $this->generateEvent('circles_as_moderator');
519
		$event->setSubject(
520
			'link_request_sent',
521
			['circle' => $circle->getJson(false, true), 'link' => $link->getJson()]
522
		);
523
524
		$this->publishEvent(
525
			$event, $this->membersRequest->forceGetMembers(
526
			$link->getCircleId(), Member::LEVEL_MODERATOR, true
527
		)
528
		);
529
		$this->dispatch('\OCA\Circles::onLinkRequestSent', ['circle' => $circle, 'link' => $link]);
530
	}
531
532
533
	/**
534
	 * onLinkRequestReceived()
535
	 *
536
	 * Called when a request to generate a link from a remote host is received.
537
	 * Broadcast an activity to the moderators of the circle.
538
	 *
539
	 * @param Circle $circle
540
	 * @param FederatedLink $link
541
	 */
542 View Code Duplication
	public function onLinkRequestReceived(Circle $circle, FederatedLink $link) {
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...
543
		$event = $this->generateEvent('circles_as_moderator');
544
		$event->setSubject(
545
			'link_request_received',
546
			['circle' => $circle->getJson(false, true), 'link' => $link->getJson()]
547
		);
548
549
		$this->publishEvent(
550
			$event, $this->membersRequest->forceGetMembers(
551
			$link->getCircleId(), Member::LEVEL_MODERATOR, true
552
		)
553
		);
554
		$this->dispatch('\OCA\Circles::onLinkRequestReceived', ['circle' => $circle, 'link' => $link]);
555
	}
556
557
558
	/**
559
	 * onLinkRequestRejected()
560
	 *
561
	 * Called when a request to generate a link from a remote host is dismissed.
562
	 * Broadcast an activity to the moderators of the circle.
563
	 *
564
	 * @param Circle $circle
565
	 * @param FederatedLink $link
566
	 */
567 View Code Duplication
	public function onLinkRequestRejected(Circle $circle, FederatedLink $link) {
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...
568
		$event = $this->generateEvent('circles_as_moderator');
569
		$event->setSubject(
570
			'link_request_rejected',
571
			['circle' => $circle->getJson(false, true), 'link' => $link->getJson()]
572
		);
573
574
		$this->publishEvent(
575
			$event, $this->membersRequest->forceGetMembers(
576
			$link->getCircleId(), Member::LEVEL_MODERATOR, true
577
		)
578
		);
579
		$this->dispatch('\OCA\Circles::onLinkRequestRejected', ['circle' => $circle, 'link' => $link]);
580
	}
581
582
583
	/**
584
	 * onLinkRequestCanceled()
585
	 *
586
	 * Called when a request to generate a link from a remote host is dismissed.
587
	 * Broadcast an activity to the moderators of the circle.
588
	 *
589
	 * @param Circle $circle
590
	 * @param FederatedLink $link
591
	 */
592 View Code Duplication
	public function onLinkRequestCanceled(Circle $circle, FederatedLink $link) {
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...
593
		$event = $this->generateEvent('circles_as_moderator');
594
		$event->setSubject(
595
			'link_request_canceled',
596
			['circle' => $circle->getJson(false, true), 'link' => $link->getJson()]
597
		);
598
599
		$this->publishEvent(
600
			$event, $this->membersRequest->forceGetMembers(
601
			$link->getCircleId(), Member::LEVEL_MODERATOR, true
602
		)
603
		);
604
		$this->dispatch('\OCA\Circles::onLinkRequestCanceled', ['circle' => $circle, 'link' => $link]);
605
	}
606
607
608
	/**
609
	 * onLinkRequestAccepted()
610
	 *
611
	 * Called when a request to generate a link from a remote host is accepted.
612
	 * Broadcast an activity to the moderators of the circle.
613
	 *
614
	 * @param Circle $circle
615
	 * @param FederatedLink $link
616
	 */
617 View Code Duplication
	public function onLinkRequestAccepted(Circle $circle, FederatedLink $link) {
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...
618
		$event = $this->generateEvent('circles_as_moderator');
619
		$event->setSubject(
620
			'link_request_accepted',
621
			['circle' => $circle->getJson(false, true), 'link' => $link->getJson()]
622
		);
623
624
		$this->publishEvent(
625
			$event, $this->membersRequest->forceGetMembers(
626
			$link->getCircleId(), Member::LEVEL_MODERATOR, true
627
		)
628
		);
629
		$this->dispatch('\OCA\Circles::onLinkRequestAccepted', ['circle' => $circle, 'link' => $link]);
630
	}
631
632
633
	/**
634
	 * onLinkRequestAccepting()
635
	 *
636
	 * Called when a link is Up and Running.
637
	 * Broadcast an activity to the moderators of the circle.
638
	 *
639
	 * @param Circle $circle
640
	 * @param FederatedLink $link
641
	 */
642 View Code Duplication
	public function onLinkRequestAccepting(Circle $circle, FederatedLink $link) {
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...
643
		$event = $this->generateEvent('circles_as_moderator');
644
		$event->setSubject(
645
			'link_request_accepting',
646
			['circle' => $circle->getJson(false, true), 'link' => $link->getJson()]
647
		);
648
649
		$this->publishEvent(
650
			$event, $this->membersRequest->forceGetMembers(
651
			$link->getCircleId(), Member::LEVEL_MODERATOR, true
652
		)
653
		);
654
		$this->dispatch('\OCA\Circles::onLinkRequestAccepting', ['circle' => $circle, 'link' => $link]);
655
	}
656
657
658
	/**
659
	 * onLinkUp()
660
	 *
661
	 * Called when a link is Up and Running.
662
	 * Broadcast an activity to the moderators of the circle.
663
	 *
664
	 * @param Circle $circle
665
	 * @param FederatedLink $link
666
	 */
667 View Code Duplication
	public function onLinkUp(Circle $circle, FederatedLink $link) {
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...
668
		$event = $this->generateEvent('circles_as_moderator');
669
		$event->setSubject(
670
			'link_up',
671
			['circle' => $circle->getJson(false, true), 'link' => $link->getJson()]
672
		);
673
674
		$this->publishEvent(
675
			$event, $this->membersRequest->forceGetMembers(
676
			$link->getCircleId(), Member::LEVEL_MODERATOR, true
677
		)
678
		);
679
		$this->dispatch('\OCA\Circles::onLinkUp', ['circle' => $circle, 'link' => $link]);
680
	}
681
682
683
	/**
684
	 * onLinkDown()
685
	 *
686
	 * Called when a link is closed (usually by remote).
687
	 * Broadcast an activity to the moderators of the circle.
688
	 *
689
	 * @param Circle $circle
690
	 * @param FederatedLink $link
691
	 */
692 View Code Duplication
	public function onLinkDown(Circle $circle, FederatedLink $link) {
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...
693
		$event = $this->generateEvent('circles_as_moderator');
694
		$event->setSubject(
695
			'link_down',
696
			['circle' => $circle->getJson(false, true), 'link' => $link->getJson()]
697
		);
698
699
		$this->publishEvent(
700
			$event, $this->membersRequest->forceGetMembers(
701
			$link->getCircleId(), Member::LEVEL_MODERATOR, true
702
		)
703
		);
704
		$this->dispatch('\OCA\Circles::onLinkDown', ['circle' => $circle, 'link' => $link]);
705
	}
706
707
708
	/**
709
	 * onLinkRemove()
710
	 *
711
	 * Called when a link is removed.
712
	 * Subject is based on the current status of the Link.
713
	 * Broadcast an activity to the moderators of the circle.
714
	 *
715
	 * @param Circle $circle
716
	 * @param FederatedLink $link
717
	 */
718
	public function onLinkRemove(Circle $circle, FederatedLink $link) {
719
		$event = $this->generateEvent('circles_as_moderator');
720
721
		if ($link->getStatus() === FederatedLink::STATUS_LINK_DOWN) {
722
			return;
723
		}
724
725
		$subject = 'link_remove';
726
		if ($link->getStatus() === FederatedLink::STATUS_LINK_REQUESTED) {
727
			$subject = 'link_request_removed';
728
		} elseif ($link->getStatus() === FederatedLink::STATUS_REQUEST_SENT) {
729
			$subject = 'link_request_canceling';
730
		}
731
732
		$event->setSubject(
733
			$subject, ['circle' => $circle->getJson(false, true), 'link' => $link->getJson()]
734
		);
735
736
		$this->publishEvent(
737
			$event, $this->membersRequest->forceGetMembers(
738
			$link->getCircleId(), Member::LEVEL_MODERATOR, true
739
		)
740
		);
741
		$this->dispatch('\OCA\Circles::onLinkRemove', ['circle' => $circle, 'link' => $link]);
742
	}
743
744
	/**
745
	 * onSettingsChange()
746
	 *
747
	 * Called when the circle's settings are changed
748
	 *
749
	 * @param Circle $circle
750
	 */
751
	public function onSettingsChange(Circle $circle) {
752
		$this->dispatch('\OCA\Circles::onSettingsChange', ['circle' => $circle]);
753
	}
754
755
756
	/**
757
	 * generateEvent()
758
	 * Create an Activity Event with the basic settings for the app.
759
	 *
760
	 * @param $type
761
	 *
762
	 * @return \OCP\Activity\IEvent
763
	 */
764
	private function generateEvent($type) {
765
		$event = $this->activityManager->generateEvent();
766
		$event->setApp(Application::APP_NAME)
767
			  ->setType($type);
768
769
		//	if ($this->userId === null) {
770
		//	$event->setAuthor($this->userId);
771
		//	}
772
773
		return $event;
774
	}
775
776
777
	/**
778
	 * Publish the event to the users.
779
	 *
780
	 * @param IEvent $event
781
	 * @param array $users
782
	 */
783
	private function publishEvent(IEvent $event, array $users) {
784
		foreach ($users AS $user) {
785
			if ($user instanceof IUser) {
786
				$userId = $user->getUID();
787
			} else if ($user instanceof Member) {
788
				$userId = $user->getUserId();
789
			} else {
790
				continue;
791
			}
792
793
			$event->setAffectedUser($userId);
794
			$this->activityManager->publish($event);
795
		}
796
	}
797
798
799
	/**
800
	 * @param Circle $circle
801
	 * @param Member $member
802
	 */
803
	private function notificationOnInvitation(Circle $circle, Member $member) {
804
		$this->deleteNotification('membership_request', $member->getMemberId());
805
806
		$notification =
807
			$this->createNotification(
808
				$circle, $circle->getViewer(), $member->getUserId(), 'invitation', 'membership',
809
				$member->getMemberId()
810
			);
811
812
		$declineAction = $notification->createAction();
813
		$declineAction->setLabel('refuse')
814
					  ->setLink(
815
						  $this->urlGenerator->linkToRoute(
816
							  'circles.Circles.leave', ['uniqueId' => $circle->getUniqueId()]
817
						  ), 'GET'
818
					  );
819
		$notification->addAction($declineAction);
820
821
		$acceptAction = $notification->createAction();
822
		$acceptAction->setLabel('accept')
823
					 ->setLink(
824
						 $this->urlGenerator->linkToRoute(
825
							 'circles.Circles.join', ['uniqueId' => $circle->getUniqueId()]
826
						 ), 'GET'
827
					 );
828
		$notification->addAction($acceptAction);
829
830
		$this->notificationManager->notify($notification);
831
	}
832
833
	/**
834
	 * @param Circle $circle
835
	 * @param Member $author
836
	 */
837
	private function notificationOnRequest(Circle $circle, Member $author) {
838
		$members = $this->membersRequest->forceGetMembers($circle->getUniqueId(), Member::LEVEL_MODERATOR);
839
		foreach ($members as $member) {
840
			$notification = $this->createNotification(
841
				$circle, $author, $member->getUserId(), 'request_new', 'membership_request',
842
				$author->getMemberId()
843
			);
844
845
			$declineAction = $notification->createAction();
846
			$declineAction->setLabel('refuse')
847
						  ->setLink(
848
							  $this->urlGenerator->linkToRoute(
849
								  'circles.Members.removeMemberById', ['memberId' => $author->getMemberId()]
850
							  ), 'DELETE'
851
						  );
852
			$notification->addAction($declineAction);
853
854
			$acceptAction = $notification->createAction();
855
			$acceptAction->setLabel('accept')
856
						 ->setLink(
857
							 $this->urlGenerator->linkToRoute(
858
								 'circles.Members.addMemberById', ['memberId' => $author->getMemberId()]
859
							 ), 'PUT'
860
						 );
861
			$notification->addAction($acceptAction);
862
863
			$this->notificationManager->notify($notification);
864
		}
865
	}
866
867
868
	/**
869
	 * @param Circle $circle
870
	 * @param Member $member
871
	 */
872
	private function notificationOnMemberNew(Circle $circle, Member $member) {
873
		$this->deleteNotification('membership_request', $member->getMemberId());
874
		$this->deleteNotification('membership', $member->getMemberId());
875
		if ($this->userId === $member->getUserId()) {
876
			return;
877
		}
878
879
		$notification =
880
			$this->createNotification(
881
				$circle, $circle->getViewer(), $member->getUserId(), 'member_new', 'membership',
882
				$member->getMemberId()
883
			);
884
885
886
		$leave = $notification->createAction();
887
		$leave->setLabel('leave')
888
			  ->setLink(
889
				  $this->urlGenerator->linkToRoute(
890
					  'circles.Circles.leave', ['uniqueId' => $circle->getUniqueId()]
891
				  ), 'GET'
892
			  );
893
		$notification->addAction($leave);
894
895
		$this->notificationManager->notify($notification);
896
	}
897
898
899
	/**
900
	 * @param string $object
901
	 * @param string $objectId
902
	 */
903
	public function deleteNotification(string $object, string $objectId) {
904
		if ($objectId === '') {
905
			return;
906
		}
907
908
		$notification = $this->notificationManager->createNotification();
909
		$notification->setApp('circles')
910
					 ->setObject($object, $objectId);
911
912
		$this->notificationManager->markProcessed($notification);
913
	}
914
915
916
	/**
917
	 * @param Circle $circle
918
	 * @param Member $author
919
	 * @param string $userId
920
	 * @param string $subject
921
	 * @param string $object
922
	 * @param string $objectId
923
	 *
924
	 * @return INotification
925
	 */
926
	private function createNotification(
927
		Circle $circle, Member $author, string $userId, string $subject, string $object, string $objectId
928
	) {
929
		$now = $this->time->getDateTime();
930
		$notification = $this->notificationManager->createNotification();
931
		$notification->setApp('circles')
932
					 ->setDateTime($now)
933
					 ->setUser($userId)
934
					 ->setObject($object, $objectId)
935
					 ->setSubject(
936
						 $subject, [$author->getUserId(), $circle->getName(), json_encode($circle)]
937
					 );
938
939
		return $notification;
940
	}
941
942
943
	/**
944
	 * @param string $context
945
	 * @param array $arguments
946
	 */
947
	private function dispatch($context, $arguments) {
948
		$this->eventDispatcher->dispatch($context, new GenericEvent(null, $arguments));
949
	}
950
951
}
952