Completed
Push — master ( 3bbe82...a6ef08 )
by Maxence
02:32
created

Provider::parseAsModerator()   B

Complexity

Conditions 5
Paths 8

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 20
rs 8.8571
cc 5
eloc 11
nc 8
nop 3
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
		$params = $event->getSubjectParameters();
61
		$circle = Circle::fromJSON($this->l10n, $params['circle']);
62
63
		$event->setIcon(
64
			CirclesService::getCircleIcon(
65
				$circle->getType(),
66
				(method_exists($this->activityManager, 'getRequirePNG')
67
				 && $this->activityManager->getRequirePNG())
68
			)
69
		);
70
71
		$event = $this->parseAsMember($circle, $event, $params);
72
		$event = $this->parseAsModerator($circle, $event, $params);
73
74
		$this->generateParsedSubject($event);
75
76
		return $event;
77
	}
78
79
80
	/**
81
	 * @param Circle $circle
82
	 * @param IEvent $event
83
	 * @param array $params
84
	 *
85
	 * @return IEvent
86
	 */
87
	private function parseAsMember(Circle $circle, IEvent $event, $params) {
88
		if ($event->getType() !== 'circles_as_member') {
89
			return $event;
90
		}
91
92
		switch ($event->getSubject()) {
93
			case 'circle_create':
94
				return $this->parseCircleEvent(
95
					$circle, null, $event,
96
					$this->l10n->t('You created the circle {circle}'),
97
					$this->l10n->t('{author} created the circle {circle}')
98
				);
99
100
			case 'circle_delete':
101
				return $this->parseCircleEvent(
102
					$circle, null, $event,
103
					$this->l10n->t('You deleted {circle}'),
104
					$this->l10n->t('{author} deleted {circle}')
105
				);
106
		}
107
108
		if (key_exists('member', $params)) {
109
			$event = $this->parseMemberAsMember($circle, $event);
110
		}
111
112
		return $event;
113
	}
114
115
116
	/**
117
	 * @param Circle $circle
118
	 * @param IEvent $event
119
	 *
120
	 * @return IEvent
121
	 */
122
	private function parseMemberAsMember(Circle $circle, IEvent $event) {
123
		$params = $event->getSubjectParameters();
124
		$member = Member::fromJSON($this->l10n, $params['member']);
125
126
		switch ($event->getSubject()) {
127 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...
128
				return $this->parseCircleMemberEvent(
129
					$circle, $member, $event,
130
					$this->l10n->t('You joined {circle}'),
131
					$this->l10n->t('{member} joined {circle}')
132
				);
133
134 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...
135
				return $this->parseCircleMemberAdvancedEvent(
136
					$circle, $member, $event,
137
					$this->l10n->t('You added {member} as member to {circle}'),
138
					$this->l10n->t('You were added as member to {circle} by {author}'),
139
					$this->l10n->t('{member} was added as member to {circle} by {author}')
140
				);
141
142 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...
143
				return $this->parseCircleMemberEvent(
144
					$circle, $member, $event,
145
					$this->l10n->t('You left {circle}'),
146
					$this->l10n->t('{member} left {circle}')
147
				);
148
149 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...
150
				return $this->parseCircleMemberAdvancedEvent(
151
					$circle, $member, $event,
152
					$this->l10n->t('You removed {member} from {circle}'),
153
					$this->l10n->t('You were removed from {circle} by {author}'),
154
					$this->l10n->t('{member} was removed from {circle} by {author}')
155
				);
156
		}
157
158
		return $event;
159
	}
160
161
162
	/**
163
	 * @param Circle $circle
164
	 * @param IEvent $event
165
	 * @param array $params
166
	 *
167
	 * @return IEvent
168
	 * @throws Exception
169
	 */
170
	private function parseAsModerator(Circle $circle, IEvent $event, $params) {
171
		if ($event->getType() !== 'circles_as_moderator') {
172
			return $event;
173
		}
174
175
		try {
176
			if (key_exists('member', $params)) {
177
				return $this->parseMemberAsModerator($circle, $event);
178
			}
179
180
			if (key_exists('link', $params)) {
181
				return $this->parseLinkAsModerator($circle, $event);
182
			}
183
184
			throw new InvalidArgumentError();
185
		} catch (Exception $e) {
186
			throw $e;
187
		}
188
189
	}
190
191
192
	/**
193
	 * @param Circle $circle
194
	 * @param IEvent $event
195
	 *
196
	 * @return IEvent
197
	 */
198
	private function parseMemberAsModerator(Circle $circle, IEvent $event) {
199
200
		$params = $event->getSubjectParameters();
201
		$member = Member::fromJSON($this->l10n, $params['member']);
202
203
		switch ($event->getSubject()) {
204 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...
205
				return $this->parseCircleMemberAdvancedEvent(
206
					$circle, $member, $event,
207
					$this->l10n->t('You invited {member} into {circle}'),
208
					$this->l10n->t('You have been invited into {circle} by {author}'),
209
					$this->l10n->t('{member} have been invited into {circle} by {author}')
210
				);
211
212
			case 'member_level':
213
				$level = [$this->l10n->t($member->getLevelString())];
214
215
				return $this->parseCircleMemberAdvancedEvent(
216
					$circle, $member, $event,
217
					$this->l10n->t('You changed {member}\'s level in {circle} to %1$s', $level),
218
					$this->l10n->t('{author} changed your level in {circle} to %1$s', $level),
219
					$this->l10n->t('{author} changed {member}\'s level in {circle} to %1$s', $level)
220
				);
221
222 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...
223
				return $this->parseMemberEvent(
224
					$circle, $member, $event,
225
					$this->l10n->t('You requested an invitation to {circle}'),
226
					$this->l10n->t(
227
						'{member} has requested an invitation into {circle}'
228
					)
229
				);
230
231 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...
232
				return $this->parseMemberEvent(
233
					$circle, $member, $event,
234
					$this->l10n->t('You are the new owner of {circle}'),
235
					$this->l10n->t('{member} is the new owner of {circle}')
236
				);
237
		}
238
239
		throw new InvalidArgumentException();
240
	}
241
242
243
	/**
244
	 * @param Circle $circle
245
	 * @param IEvent $event
246
	 *
247
	 * @return IEvent
248
	 */
249
	private function parseLinkAsModerator(Circle $circle, IEvent $event) {
250
251
		$params = $event->getSubjectParameters();
252
		$link = FederatedLink::fromJSON($params['link']);
253
254
		switch ($event->getSubject()) {
255
			case 'link_request_sent':
256
				return $this->parseCircleEvent(
257
					$circle, $link, $event,
258
					$this->l10n->t('You sent a request to link {circle} with {link}'),
259
					$this->l10n->t('{author} sent a request to link {circle} with {link}')
260
				);
261
262
			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...
263
				return $this->parseLinkEvent(
264
					$circle, $link, $event,
265
					$this->l10n->t('{link} requested a link with {circle}')
266
				);
267
268
			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...
269
				return $this->parseLinkEvent(
270
					$circle, $link, $event, $this->l10n->t(
271
					'The request to link {circle} with {link} has been rejected'
272
				)
273
				);
274
275
			case 'link_request_canceled':
276
				return $this->parseLinkEvent(
277
					$circle, $link, $event,
278
					$this->l10n->t(
279
						'The request to link {link} with {circle} has been canceled remotely'
280
					)
281
				);
282
283
			case 'link_request_accepted':
284
				return $this->parseLinkEvent(
285
					$circle, $link, $event,
286
					$this->l10n->t('The request to link {circle} with {link} has been accepted')
287
				);
288
289
			case 'link_request_removed':
290
				return $this->parseCircleEvent(
291
					$circle, $link, $event,
292
					$this->l10n->t('You dismissed the request to link {link} with {circle}'),
293
					$this->l10n->t('{author} dismissed the request to link {link} with {circle}')
294
				);
295
296
			case 'link_request_canceling':
297
				return $this->parseCircleEvent(
298
					$circle, $link, $event,
299
					$this->l10n->t('You canceled the request to link {circle} with {link}'),
300
					$this->l10n->t('{author} canceled the request to link {circle} with {link}')
301
				);
302
303
			case 'link_request_accepting':
304
				return $this->parseCircleEvent(
305
					$circle, $link, $event,
306
					$this->l10n->t('You accepted the request to link {link} with {circle}'),
307
					$this->l10n->t('{author} accepted the request to link {link} with {circle}')
308
				);
309
310
			case 'link_up':
311
				return $this->parseLinkEvent(
312
					$circle, $link, $event,
313
					$this->l10n->t('A link between {circle} and {link} is now up and running')
314
				);
315
316
			case 'link_down':
317
				return $this->parseLinkEvent(
318
					$circle, $link, $event,
319
					$this->l10n->t(
320
						'The link between {circle} and {link} has been shutdown remotely'
321
					)
322
				);
323
324
			case 'link_remove':
325
				return $this->parseCircleEvent(
326
					$circle, $link, $event,
327
					$this->l10n->t('You closed the link between {circle} and {link}'),
328
					$this->l10n->t('{author} closed the link between {circle} and {link}')
329
				);
330
		}
331
332
		throw new InvalidArgumentException();
333
	}
334
335
336
	/**
337
	 * general function to generate Circle event.
338
	 *
339
	 * @param Circle $circle
340
	 * @param FederatedLink $link
341
	 * @param IEvent $event
342
	 * @param $ownEvent
343
	 * @param $othersEvent
344
	 *
345
	 * @return IEvent
346
	 */
347
	private function parseCircleEvent(Circle $circle, $link, IEvent $event, $ownEvent, $othersEvent
348
	) {
349
		$data = [
350
			'author' => $author = $this->generateUserParameter(
351
				$circle->getUser()
352
					   ->getUserId()
353
			),
354
			'circle' => $this->generateCircleParameter($circle),
355
			'link'   => ($link === null) ? '' : $this->generateLinkParameter($link)
356
		];
357
358
		if ($circle->getUser()
359
				   ->getUserId() === $this->activityManager->getCurrentUserId()
360
		) {
361
			return $event->setRichSubject($ownEvent, $data);
362
		}
363
364
		return $event->setRichSubject($othersEvent, $data);
365
	}
366
367
368
	/**
369
	 * general function to generate Member event.
370
	 *
371
	 * @param Circle $circle
372
	 * @param $member
373
	 * @param IEvent $event
374
	 * @param $ownEvent
375
	 * @param $othersEvent
376
	 *
377
	 * @return IEvent
378
	 */
379 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...
380
		Circle $circle, Member $member, IEvent $event, $ownEvent, $othersEvent
381
	) {
382
		$data = [
383
			'circle' => $this->generateCircleParameter($circle),
384
			'member' => $this->generateMemberParameter($member)
385
		];
386
387
		if ($member->getUserId() === $this->activityManager->getCurrentUserId()
388
		) {
389
			return $event->setRichSubject($ownEvent, $data);
390
		}
391
392
		return $event->setRichSubject($othersEvent, $data);
393
	}
394
395
396
	/**
397
	 * general function to generate Link event.
398
	 *
399
	 * @param Circle $circle
400
	 * @param FederatedLink $link
401
	 * @param IEvent $event
402
	 * @param $line
403
	 *
404
	 * @return IEvent
405
	 */
406
	private function parseLinkEvent(Circle $circle, FederatedLink $link, IEvent $event, $line) {
407
		$data = [
408
			'circle' => $this->generateCircleParameter($circle),
409
			'link'   => $this->generateLinkParameter($link)
410
		];
411
412
		return $event->setRichSubject($line, $data);
413
	}
414
415
416
	/**
417
	 * general function to generate Circle+Member event.
418
	 *
419
	 * @param Circle $circle
420
	 * @param Member $member
421
	 * @param IEvent $event
422
	 * @param $ownEvent
423
	 * @param $othersEvent
424
	 *
425
	 * @return IEvent
426
	 */
427 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...
428
		Circle $circle, Member $member, IEvent $event, $ownEvent, $othersEvent
429
	) {
430
		$data = [
431
			'circle' => $this->generateCircleParameter($circle),
432
			'member' => $this->generateMemberParameter($member)
433
		];
434
435
		if ($circle->getUser()
436
				   ->getUserId() === $this->activityManager->getCurrentUserId()
437
		) {
438
			return $event->setRichSubject($ownEvent, $data);
439
		}
440
441
		return $event->setRichSubject($othersEvent, $data);
442
	}
443
444
445
	/**
446
	 * general function to generate Circle+Member advanced event.
447
	 *
448
	 * @param Circle $circle
449
	 * @param Member $member
450
	 * @param IEvent $event
451
	 *\
452
	 * @param $ownEvent
453
	 * @param $targetEvent
454
	 * @param $othersEvent
455
	 *
456
	 * @return IEvent
457
	 */
458
	private function parseCircleMemberAdvancedEvent(
459
		Circle $circle, Member $member, IEvent $event, $ownEvent, $targetEvent, $othersEvent
460
	) {
461
462
		$data = [
463
			'author' => $this->generateUserParameter(
464
				$circle->getUser()
465
					   ->getUserId()
466
			),
467
			'circle' => $this->generateCircleParameter($circle),
468
			'member' => $this->generateMemberParameter($member)
469
		];
470
471
		if ($circle->getUser()
472
				   ->getUserId() === $this->activityManager->getCurrentUserId()
473
		) {
474
			return $event->setRichSubject($ownEvent, $data);
475
		}
476
477
		if ($member->getUserId() === $this->activityManager->getCurrentUserId()) {
478
			return $event->setRichSubject($targetEvent, $data);
479
		}
480
481
		return $event->setRichSubject($othersEvent, $data);
482
	}
483
484
485
	/**
486
	 * @param IEvent $event
487
	 */
488
	private function generateParsedSubject(IEvent $event) {
489
		$subject = $event->getRichSubject();
490
		$params = $event->getRichSubjectParameters();
491
		$ak = array_keys($params);
492
		foreach ($ak as $k) {
493
			if (is_array($params[$k])) {
494
				$subject = str_replace('{' . $k . '}', $params[$k]['parsed'], $subject);
495
			}
496
		}
497
498
		$event->setParsedSubject($subject);
499
	}
500
501
	/**
502
	 * @param Member $member
503
	 *
504
	 * @return array<string,string|integer>
505
	 */
506
	private function generateMemberParameter(Member $member) {
507
		return $this->generateUserParameter($member->getUserId());
508
	}
509
510
511
	/**
512
	 * @param Circle $circle
513
	 *
514
	 * @return array<string,string|integer>
515
	 */
516
	private function generateCircleParameter(Circle $circle) {
517
		return [
518
			'type'   => 'circle',
519
			'id'     => $circle->getId(),
520
			'name'   => $circle->getName(),
521
			'parsed' => $circle->getName(),
522
			'link'   => Circles::generateLink($circle->getId())
523
		];
524
	}
525
526
527
	/**
528
	 * @param FederatedLink $link
529
	 *
530
	 * @return array<string,string|integer>
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string,string>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
531
	 */
532
	private function generateLinkParameter(FederatedLink $link) {
533
		return [
534
			'type'   => 'circle',
535
			'id'     => $link->getUniqueId(),
536
			'name'   => $link->getToken() . '@' . $link->getAddress(),
537
			'parsed' => $link->getToken() . '@' . $link->getAddress()
538
		];
539
//			'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...
540
	}
541
542
543
	/**
544
	 * @param $userId
545
	 *
546
	 * @return array<string,string|integer>
547
	 */
548
	private function generateUserParameter($userId) {
549
		return [
550
			'type'   => 'user',
551
			'id'     => $userId,
552
			'name'   => \OC::$server->getUserManager()
553
									->get($userId)
554
									->getDisplayName(),
555
			'parsed' => \OC::$server->getUserManager()
556
									->get($userId)
557
									->getDisplayName()
558
		];
559
	}
560
}
561