Completed
Push — master ( 537a78...b29bba )
by Maxence
03:35
created

Provider::parseCircleEvent()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 19
rs 9.4285
cc 3
eloc 11
nc 4
nop 5
1
<?php
2
3
4
namespace OCA\Circles\Activity;
5
6
7
use Exception;
8
use InvalidArgumentException;
9
use OCA\Circles\Api\v1\Circles;
10
use OCA\Circles\Model\Circle;
11
use OCA\Circles\Model\FederatedLink;
12
use OCA\Circles\Model\Member;
13
use OCA\Circles\Service\CirclesService;
14
use OCA\Circles\Service\MiscService;
15
use OCP\Activity\IEvent;
16
use OCP\Activity\IManager;
17
use OCP\Activity\IProvider;
18
use OCP\IL10N;
19
use OCP\IURLGenerator;
20
use OpenCloud\Common\Exceptions\InvalidArgumentError;
21
22
23
class Provider implements IProvider {
24
25
	/** @var MiscService */
26
	protected $miscService;
27
28
	/** @var IL10N */
29
	protected $l10n;
30
31
	/** @var IURLGenerator */
32
	protected $url;
33
34
	/** @var IManager */
35
	protected $activityManager;
36
37
	public function __construct(
38
		IURLGenerator $url, IManager $activityManager, IL10N $l10n, MiscService $miscService
39
	) {
40
		$this->url = $url;
41
		$this->activityManager = $activityManager;
42
		$this->l10n = $l10n;
43
		$this->miscService = $miscService;
44
	}
45
46
47
	/**
48
	 * @param string $lang
49
	 * @param IEvent $event
50
	 * @param IEvent|null $previousEvent
51
	 *
52
	 * @return IEvent
53
	 */
54
	public function parse($lang, IEvent $event, IEvent $previousEvent = null) {
55
56
		if ($event->getApp() !== 'circles') {
57
			throw new \InvalidArgumentException();
58
		}
59
60
		$event = $this->parseAsMember($event);
61
		$event = $this->parseAsModerator($event);
62
63
		return $event;
64
	}
65
66
67
	/**
68
	 * @param IEvent $event
69
	 *
70
	 * @return IEvent
71
	 * @throws Exception
72
	 */
73
	private function parseAsMember(IEvent $event) {
74
		if ($event->getType() !== 'circles_as_member') {
75
			return $event;
76
		}
77
78
		$params = $event->getSubjectParameters();
79
		$circle = Circle::fromJSON($this->l10n, $params['circle']);
80
		$event->setIcon(CirclesService::getCircleIcon($circle->getType()));
81
82
		switch ($event->getSubject()) {
83
			case 'circle_create':
84
				return $this->parseCircleEvent(
85
					$circle, null, $event,
86
					$this->l10n->t('You created the circle {circle}'),
87
					$this->l10n->t('{author} created the circle {circle}')
88
				);
89
90
			case 'circle_delete':
91
				return $this->parseCircleEvent(
92
					$circle, null, $event,
93
					$this->l10n->t('You deleted {circle}'),
94
					$this->l10n->t('{author} deleted {circle}')
95
				);
96
		}
97
98
		if (key_exists('member', $params)) {
99
			$event = $this->parseMemberAsMember($circle, $event);
100
		}
101
102
		return $event;
103
	}
104
105
106
	/**
107
	 * @param Circle $circle
108
	 * @param IEvent $event
109
	 *
110
	 * @return IEvent
111
	 */
112
	private function parseMemberAsMember(Circle $circle, IEvent $event) {
113
		$params = $event->getSubjectParameters();
114
		$member = Member::fromJSON($this->l10n, $params['member']);
115
116
		switch ($event->getSubject()) {
117 View Code Duplication
			case 'member_join':
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...
118
				return $this->parseCircleMemberEvent(
119
					$circle, $member, $event,
120
					$this->l10n->t('You joined {circle}'),
121
					$this->l10n->t('{member} joined {circle}')
122
				);
123
124 View Code Duplication
			case 'member_add':
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...
125
				return $this->parseCircleMemberAdvancedEvent(
126
					$circle, $member, $event,
127
					$this->l10n->t('You added {member} as member to {circle}'),
128
					$this->l10n->t('You were added as member to {circle} by {author}'),
129
					$this->l10n->t('{member} was added as member to {circle} by {author}')
130
				);
131
132 View Code Duplication
			case 'member_left':
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
				return $this->parseCircleMemberEvent(
134
					$circle, $member, $event,
135
					$this->l10n->t('You left {circle}'),
136
					$this->l10n->t('{member} left {circle}')
137
				);
138
139 View Code Duplication
			case 'member_remove':
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...
140
				return $this->parseCircleMemberAdvancedEvent(
141
					$circle, $member, $event,
142
					$this->l10n->t('You removed {member} from {circle}'),
143
					$this->l10n->t('You were removed from {circle} by {author}'),
144
					$this->l10n->t('{member} was removed from {circle} by {author}')
145
				);
146
		}
147
148
		return $event;
149
	}
150
151
152
	/**
153
	 * @param IEvent $event
154
	 *
155
	 * @return IEvent
156
	 * @throws Exception
157
	 */
158
	private function parseAsModerator(IEvent $event) {
159
		if ($event->getType() !== 'circles_as_moderator') {
160
			return $event;
161
		}
162
163
		try {
164
			$params = $event->getSubjectParameters();
165
			$circle = Circle::fromJSON($this->l10n, $params['circle']);
166
			$event->setIcon(CirclesService::getCircleIcon($circle->getType()));
167
168
			if (key_exists('member', $params)) {
169
				return $this->parseMemberAsModerator($circle, $event);
170
			}
171
172
			if (key_exists('link', $params)) {
173
				return $this->parseLinkAsModerator($circle, $event);
174
			}
175
176
			throw new InvalidArgumentError();
177
		} catch (Exception $e) {
178
			throw $e;
179
		}
180
181
	}
182
183
184
	/**
185
	 * @param Circle $circle
186
	 * @param IEvent $event
187
	 *
188
	 * @return IEvent
189
	 */
190
	private function parseMemberAsModerator(Circle $circle, IEvent $event) {
191
192
		$params = $event->getSubjectParameters();
193
		$member = Member::fromJSON($this->l10n, $params['member']);
194
195
		switch ($event->getSubject()) {
196 View Code Duplication
			case 'member_invited':
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...
197
				return $this->parseCircleMemberAdvancedEvent(
198
					$circle, $member, $event,
199
					$this->l10n->t('You invited {member} into {circle}'),
200
					$this->l10n->t('You have been invited into {circle} by {author}'),
201
					$this->l10n->t('{member} have been invited into {circle} by {author}')
202
				);
203
204
			case 'member_level':
205
				$level = [$this->l10n->t($member->getLevelString())];
206
207
				return $this->parseCircleMemberAdvancedEvent(
208
					$circle, $member, $event,
209
					$this->l10n->t('You changed {member}\'s level in {circle} to %1$s', $level),
210
					$this->l10n->t('{author} changed your level in {circle} to %1$s', $level),
211
					$this->l10n->t('{author} changed {member}\'s level in {circle} to %1$s', $level)
212
				);
213
214 View Code Duplication
			case 'member_request_invitation':
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...
215
				return $this->parseMemberEvent(
216
					$circle, $member, $event,
217
					$this->l10n->t('You requested an invitation to {circle}'),
218
					$this->l10n->t(
219
						'{member} has requested an invitation into {circle}'
220
					)
221
				);
222
223 View Code Duplication
			case 'member_owner':
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...
224
				return $this->parseMemberEvent(
225
					$circle, $member, $event,
226
					$this->l10n->t('You are the new owner of {circle}'),
227
					$this->l10n->t('{member} is the new owner of {circle}')
228
				);
229
		}
230
231
		throw new InvalidArgumentException();
232
	}
233
234
235
	/**
236
	 * @param Circle $circle
237
	 * @param IEvent $event
238
	 *
239
	 * @return IEvent
240
	 */
241
	private function parseLinkAsModerator(Circle $circle, IEvent $event) {
242
243
		$params = $event->getSubjectParameters();
244
		$link = FederatedLink::fromJSON($params['link']);
245
246
		switch ($event->getSubject()) {
247
			case 'link_request_sent':
248
				return $this->parseCircleEvent(
249
					$circle, $link, $event,
250
					$this->l10n->t('You sent a request to link {circle} with {link}'),
251
					$this->l10n->t('{author} sent a request to link {circle} with {link}')
252
				);
253
254
			case 'link_request_received';
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
255
				return $this->parseLinkEvent(
256
					$circle, $link, $event,
257
					$this->l10n->t('{link} requested a link with {circle}')
258
				);
259
260
			case 'link_request_rejected';
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
261
				return $this->parseLinkEvent(
262
					$circle, $link, $event, $this->l10n->t(
263
					'The request to link {circle} with {link} has been rejected'
264
				)
265
				);
266
267
			case 'link_request_canceled':
268
				return $this->parseLinkEvent(
269
					$circle, $link, $event,
270
					$this->l10n->t(
271
						'The request to link {link} with {circle} has been canceled remotely'
272
					)
273
				);
274
275
			case 'link_request_accepted':
276
				return $this->parseLinkEvent(
277
					$circle, $link, $event,
278
					$this->l10n->t('The request to link {circle} with {link} has been accepted')
279
				);
280
281
			case 'link_request_removed':
282
				return $this->parseCircleEvent(
283
					$circle, $link, $event,
284
					$this->l10n->t('You dismissed the request to link {link} with {circle}'),
285
					$this->l10n->t('{author} dismissed the request to link {link} with {circle}')
286
				);
287
288
			case 'link_request_canceling':
289
				return $this->parseCircleEvent(
290
					$circle, $link, $event,
291
					$this->l10n->t('You canceled the request to link {circle} with {link}'),
292
					$this->l10n->t('{author} canceled the request to link {circle} with {link}')
293
				);
294
295
			case 'link_request_accepting':
296
				return $this->parseCircleEvent(
297
					$circle, $link, $event,
298
					$this->l10n->t('You accepted the request to link {link} with {circle}'),
299
					$this->l10n->t('{author} accepted the request to link {link} with {circle}')
300
				);
301
302
			case 'link_up':
303
				return $this->parseLinkEvent(
304
					$circle, $link, $event,
305
					$this->l10n->t('A link between {circle} and {link} is now up and running')
306
				);
307
308
			case 'link_down':
309
				return $this->parseLinkEvent(
310
					$circle, $link, $event,
311
					$this->l10n->t(
312
						'The link between {circle} and {link} has been shutdown remotely'
313
					)
314
				);
315
316
			case 'link_remove':
317
				return $this->parseCircleEvent(
318
					$circle, $link, $event,
319
					$this->l10n->t('You closed the link between {circle} and {link}'),
320
					$this->l10n->t('{author} closed the link between {circle} and {link}')
321
				);
322
		}
323
324
		throw new InvalidArgumentException();
325
	}
326
327
328
	/**
329
	 * general function to generate Circle event.
330
	 *
331
	 * @param Circle $circle
332
	 * @param FederatedLink $link
333
	 * @param IEvent $event
334
	 * @param $ownEvent
335
	 * @param $othersEvent
336
	 *
337
	 * @return IEvent
338
	 */
339
	private function parseCircleEvent(Circle $circle, $link, IEvent $event, $ownEvent, $othersEvent
340
	) {
341
		$data = [
342
			'author' => $author = $this->generateUserParameter(
343
				$circle->getUser()
344
					   ->getUserId()
345
			),
346
			'circle' => $this->generateCircleParameter($circle),
347
			'link'   => ($link === null) ? '' : $this->generateLinkParameter($link)
348
		];
349
350
		if ($circle->getUser()
351
				   ->getUserId() === $this->activityManager->getCurrentUserId()
352
		) {
353
			return $event->setRichSubject($ownEvent, $data);
354
		}
355
356
		return $event->setRichSubject($othersEvent, $data);
357
	}
358
359
360
	/**
361
	 * general function to generate Member event.
362
	 *
363
	 * @param Circle $circle
364
	 * @param $member
365
	 * @param IEvent $event
366
	 * @param $ownEvent
367
	 * @param $othersEvent
368
	 *
369
	 * @return IEvent
370
	 */
371 View Code Duplication
	private function parseMemberEvent(
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...
372
		Circle $circle, Member $member, IEvent $event, $ownEvent, $othersEvent
373
	) {
374
		$data = [
375
			'circle' => $this->generateCircleParameter($circle),
376
			'member' => $this->generateMemberParameter($member)
377
		];
378
379
		if ($member->getUserId() === $this->activityManager->getCurrentUserId()
380
		) {
381
			return $event->setRichSubject($ownEvent, $data);
382
		}
383
384
		return $event->setRichSubject($othersEvent, $data);
385
	}
386
387
388
	/**
389
	 * general function to generate Link event.
390
	 *
391
	 * @param Circle $circle
392
	 * @param FederatedLink $link
393
	 * @param IEvent $event
394
	 * @param $line
395
	 *
396
	 * @return IEvent
397
	 */
398
	private function parseLinkEvent(Circle $circle, FederatedLink $link, IEvent $event, $line) {
399
		$data = [
400
			'circle' => $this->generateCircleParameter($circle),
401
			'link'   => $this->generateLinkParameter($link)
402
		];
403
404
		return $event->setRichSubject($line, $data);
405
	}
406
407
408
	/**
409
	 * general function to generate Circle+Member event.
410
	 *
411
	 * @param Circle $circle
412
	 * @param Member $member
413
	 * @param IEvent $event
414
	 * @param $ownEvent
415
	 * @param $othersEvent
416
	 *
417
	 * @return IEvent
418
	 */
419 View Code Duplication
	private function parseCircleMemberEvent(
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
		Circle $circle, Member $member, IEvent $event, $ownEvent, $othersEvent
421
	) {
422
		$data = [
423
			'circle' => $this->generateCircleParameter($circle),
424
			'member' => $this->generateMemberParameter($member)
425
		];
426
427
		if ($circle->getUser()
428
				   ->getUserId() === $this->activityManager->getCurrentUserId()
429
		) {
430
			return $event->setRichSubject($ownEvent, $data);
431
		}
432
433
		return $event->setRichSubject($othersEvent, $data);
434
	}
435
436
437
	/**
438
	 * general function to generate Circle+Member advanced event.
439
	 *
440
	 * @param Circle $circle
441
	 * @param Member $member
442
	 * @param IEvent $event
443
	 *\
444
	 * @param $ownEvent
445
	 * @param $targetEvent
446
	 * @param $othersEvent
447
	 *
448
	 * @return IEvent
449
	 */
450
	private function parseCircleMemberAdvancedEvent(
451
		Circle $circle, Member $member, IEvent $event, $ownEvent, $targetEvent, $othersEvent
452
	) {
453
454
		$data = [
455
			'author' => $this->generateUserParameter(
456
				$circle->getUser()
457
					   ->getUserId()
458
			),
459
			'circle' => $this->generateCircleParameter($circle),
460
			'member' => $this->generateMemberParameter($member)
461
		];
462
463
		if ($circle->getUser()
464
				   ->getUserId() === $this->activityManager->getCurrentUserId()
465
		) {
466
			return $event->setRichSubject($ownEvent, $data);
467
		}
468
469
		if ($member->getUserId() === $this->activityManager->getCurrentUserId()) {
470
			return $event->setRichSubject($targetEvent, $data);
471
		}
472
473
		return $event->setRichSubject($othersEvent, $data);
474
	}
475
476
477
	private function generateMemberParameter(Member $member) {
478
		return $this->generateUserParameter($member->getUserId());
479
	}
480
481
482
	private function generateCircleParameter(Circle $circle) {
483
		return [
484
			'type' => 'circle',
485
			'id'   => $circle->getId(),
486
			'name' => $circle->getName(),
487
			'link' => Circles::generateLink($circle->getId())
488
		];
489
	}
490
491
492
	private function generateLinkParameter(FederatedLink $link) {
493
		return [
494
			'type' => 'circle',
495
			'id'   => $link->getUniqueId(),
496
			'name' => $link->getToken() . '@' . $link->getAddress()
497
		];
498
//			'link' => Circles::generateRemoteLink($link)
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
499
	}
500
501
502
	/**
503
	 * @param $userId
504
	 *
505
	 * @return array
506
	 */
507
	private function generateUserParameter(
508
		$userId
509
	) {
510
		return [
511
			'type' => 'user',
512
			'id'   => $userId,
513
			'name' => $userId
514
		];
515
	}
516
}
517