Completed
Push — master ( ab5847...d4ce93 )
by Maxence
02:13
created

FederatedLinkService   D

Complexity

Total Complexity 58

Size/Duplication

Total Lines 648
Duplicated Lines 4.17 %

Coupling/Cohesion

Components 1
Dependencies 16

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 58
c 2
b 0
f 0
lcom 1
cbo 16
dl 27
loc 648
rs 4.0865

24 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 18 1
A linkCircle() 0 20 4
A linkStatus() 0 20 3
A updateLinkStatus() 0 19 3
A eventOnUpdateLinkStatus() 0 13 3
A requestLinkWithCircle() 0 19 2
A generateNewLinkWithRemoteCircle() 0 16 1
A generateLinkRemoteURL() 0 3 1
A requestLink() 0 20 3
A parseRequestLinkResult() 0 10 2
A eventOnRequestLink() 0 17 3
A parseRequestLinkError() 0 17 2
A updateLinkFromRemote() 0 19 3
A checkUpdateLinkFromRemote() 0 10 3
A checkUpdateLinkFromRemoteLinkUp() 0 15 3
A updateLinkRemote() 0 17 3
A initiateLink() 0 19 3
A checkLinkRequestValidity() 0 17 4
A checkUpdateLinkFromRemoteLinkRemove() 0 19 3
A checkUpdateLinkFromRemoteLinkRequestSent() 9 9 2
A checkUpdateLinkFromRemoteLinkRequested() 9 9 2
A checkUpdateLinkFromRemoteLinkDown() 9 9 2
A generateLinkData() 0 9 1
A generateClientBodyData() 0 7 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like FederatedLinkService often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use FederatedLinkService, and based on these observations, apply Extract Interface, too.

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
30
use Exception;
31
use OCA\Circles\Api\v1\Circles;
32
use OCA\Circles\AppInfo\Application;
33
use OCA\Circles\Db\CirclesRequest;
34
use OCA\Circles\Db\FederatedLinksRequest;
35
use OCA\Circles\Exceptions\CircleTypeNotValidException;
36
use OCA\Circles\Exceptions\FederatedCircleLinkFormatException;
37
use OCA\Circles\Exceptions\FederatedCircleNotAllowedException;
38
use OCA\Circles\Exceptions\FederatedCircleStatusUpdateException;
39
use OCA\Circles\Exceptions\FederatedLinkCreationException;
40
use OCA\Circles\Exceptions\FederatedLinkDoesNotExistException;
41
use OCA\Circles\Exceptions\FederatedLinkUpdateException;
42
use OCA\Circles\Exceptions\FederatedRemoteCircleDoesNotExistException;
43
use OCA\Circles\Exceptions\FederatedRemoteDoesNotAllowException;
44
use OCA\Circles\Exceptions\FederatedRemoteIsDownException;
45
use OCA\Circles\Exceptions\MemberIsNotAdminException;
46
use OCA\Circles\Model\Circle;
47
use OCA\Circles\Model\FederatedLink;
48
use OCP\Http\Client\IClientService;
49
use OCP\Http\Client\IResponse;
50
use OCP\IL10N;
51
52
class FederatedLinkService {
53
54
	/** @var string */
55
	private $userId;
56
57
	/** @var IL10N */
58
	private $l10n;
59
60
	/** @var CirclesRequest */
61
	private $circlesRequest;
62
63
	/** @var ConfigService */
64
	private $configService;
65
66
	/** @var CirclesService */
67
	private $circlesService;
68
69
	/** @var BroadcastService */
70
	private $broadcastService;
71
72
	/** @var FederatedLinksRequest */
73
	private $federatedLinksRequest;
74
75
	/** @var EventsService */
76
	private $eventsService;
77
78
	/** @var IClientService */
79
	private $clientService;
80
81
	/** @var MiscService */
82
	private $miscService;
83
84
85
	/**
86
	 * FederatedLinkService constructor.
87
	 *
88
	 * @param string $UserId
89
	 * @param IL10N $l10n
90
	 * @param CirclesRequest $circlesRequest
91
	 * @param ConfigService $configService
92
	 * @param CirclesService $circlesService
93
	 * @param BroadcastService $broadcastService
94
	 * @param FederatedLinksRequest $federatedLinksRequest
95
	 * @param EventsService $eventsService
96
	 * @param IClientService $clientService
97
	 * @param MiscService $miscService
98
	 */
99
	public function __construct(
0 ignored issues
show
Coding Style Naming introduced by
The parameter $UserId is not named in camelCase.

This check marks parameter names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
100
		$UserId, IL10N $l10n, CirclesRequest $circlesRequest, ConfigService $configService,
101
		CirclesService $circlesService, BroadcastService $broadcastService,
102
		FederatedLinksRequest $federatedLinksRequest, EventsService $eventsService,
103
		IClientService $clientService, MiscService $miscService
104
	) {
105
		$this->userId = $UserId;
106
		$this->l10n = $l10n;
107
		$this->circlesRequest = $circlesRequest;
108
		$this->configService = $configService;
109
		$this->circlesService = $circlesService;
110
		$this->broadcastService = $broadcastService;
111
		$this->federatedLinksRequest = $federatedLinksRequest;
112
		$this->eventsService = $eventsService;
113
114
		$this->clientService = $clientService;
115
		$this->miscService = $miscService;
116
	}
117
118
119
	/**
120
	 * linkCircle();
121
	 *
122
	 * link to a circle.
123
	 * Function will check if settings allow Federated links between circles, and the format of
124
	 * the link ($remote). If no exception, a request to the remote circle will be initiated
125
	 * using requestLinkWithCircle()
126
	 *
127
	 * $remote format: <circle_name>@<remote_host>
128
	 *
129
	 * @param string $circleUniqueId
130
	 * @param string $remote
131
	 *
132
	 * @throws Exception
133
	 * @throws FederatedCircleLinkFormatException
134
	 * @throws CircleTypeNotValidException
135
	 *
136
	 * @return FederatedLink
137
	 */
138
	public function linkCircle($circleUniqueId, $remote) {
139
140
		if (!$this->configService->isFederatedCirclesAllowed()) {
141
			throw new FederatedCircleNotAllowedException(
142
				$this->l10n->t("Federated circles are not allowed on this Nextcloud")
143
			);
144
		}
145
146
		if (strpos($remote, '@') === false) {
147
			throw new FederatedCircleLinkFormatException(
148
				$this->l10n->t("Federated link does not have a valid format")
149
			);
150
		}
151
152
		try {
153
			return $this->requestLinkWithCircle($circleUniqueId, $remote);
154
		} catch (Exception $e) {
155
			throw $e;
156
		}
157
	}
158
159
160
	/**
161
	 * linkStatus()
162
	 *
163
	 * Update the status of a link.
164
	 * Function will check if user can edit the status, will update it and send the update to
165
	 * remote
166
	 *
167
	 * @param string $linkUniqueId
168
	 * @param int $status
169
	 *
170
	 * @throws Exception
171
	 * @throws FederatedCircleLinkFormatException
172
	 * @throws CircleTypeNotValidException
173
	 * @throws MemberIsNotAdminException
174
	 *
175
	 * @return FederatedLink[]
176
	 */
177
	public function linkStatus($linkUniqueId, $status) {
178
179
		try {
180
			$link = $this->federatedLinksRequest->getLinkFromId($linkUniqueId);
181
			$circle = $this->circlesRequest->getCircle($link->getCircleId(), $this->userId);
182
			$circle->hasToBeFederated();
183
			$circle->getHigherViewer()
184
				   ->hasToBeAdmin();
185
			$link->hasToBeValidStatusUpdate($status);
186
187
			if ($link->getStatus() !== $status) {
188
				$this->updateLinkStatus($link, $circle, $status);
189
			}
190
191
			return $this->federatedLinksRequest->getLinksFromCircle($circle->getUniqueId());
192
193
		} catch (Exception $e) {
194
			throw $e;
195
		}
196
	}
197
198
199
	/**
200
	 * @param FederatedLink $link
201
	 * @param Circle $circle
202
	 * @param int $status
203
	 *
204
	 * @return FederatedLink[]
205
	 * @throws Exception
206
	 */
207
	private function updateLinkStatus(FederatedLink $link, Circle $circle, $status) {
208
209
		$this->eventOnUpdateLinkStatus($link, $circle, $status);
210
211
		$link->setStatus($status);
212
		$link->setCircleId($circle->getUniqueId(true));
213
214
		try {
215
			$this->updateLinkRemote($link);
216
		} catch (Exception $e) {
217
			if ($status !== FederatedLink::STATUS_LINK_REMOVE) {
218
				throw $e;
219
			}
220
		}
221
222
		$this->federatedLinksRequest->update($link);
223
224
		return $this->federatedLinksRequest->getLinksFromCircle($circle->getUniqueId());
225
	}
226
227
228
	/**
229
	 * eventOnLinkStatus();
230
	 *
231
	 * Called by linkStatus() to manage events when status is changing.
232
	 * If status does not need update, returns false;
233
	 *
234
	 * @param FederatedLink $link
235
	 * @param Circle $circle
236
	 * @param int $status
237
	 *
238
	 * @return bool
239
	 */
240
	private function eventOnUpdateLinkStatus(FederatedLink $link, Circle $circle, $status) {
241
242
		if ($status === FederatedLink::STATUS_LINK_REMOVE) {
243
			$this->eventsService->onLinkRemove($circle, $link);
244
		}
245
246
		if ($status === FederatedLink::STATUS_LINK_UP) {
247
			$this->eventsService->onLinkRequestAccepting($circle, $link);
248
			$this->eventsService->onLinkUp($circle, $link);
249
		}
250
251
		return true;
252
	}
253
254
255
	/**
256
	 * requestLinkWithCircle()
257
	 *
258
	 * Using CircleId, function will get more infos from the database.
259
	 * Will check if author is at least admin and initiate a FederatedLink, save it
260
	 * in the database and send a request to the remote circle using requestLink()
261
	 * If any issue, entry is removed from the database.
262
	 *
263
	 * @param string $circleUniqueId
264
	 * @param string $remote
265
	 *
266
	 * @return FederatedLink
267
	 * @throws Exception
268
	 */
269
	private function requestLinkWithCircle($circleUniqueId, $remote) {
270
271
		$link = null;
272
		try {
273
			$circle = $this->circlesService->detailsCircle($circleUniqueId);
274
			$circle->getHigherViewer()
275
				   ->hasToBeAdmin();
276
			$circle->hasToBeFederated();
277
			$circle->cantBePersonal();
278
279
			$link = $this->generateNewLinkWithRemoteCircle($circle->getUniqueId(), $remote);
280
			$this->requestLink($circle, $link);
281
		} catch (Exception $e) {
282
			$this->federatedLinksRequest->delete($link);
0 ignored issues
show
Bug introduced by
It seems like $link defined by null on line 271 can be null; however, OCA\Circles\Db\FederatedLinksRequest::delete() does not accept null, maybe add an additional type check?

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

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

function doesNotAcceptNull(stdClass $x) { }

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

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

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
283
			throw $e;
284
		}
285
286
		return $link;
287
	}
288
289
290
	/**
291
	 * @param $circleUniqueId
292
	 * @param $remote
293
	 *
294
	 * @return FederatedLink
295
	 */
296
	private function generateNewLinkWithRemoteCircle($circleUniqueId, $remote) {
297
298
		$link = new FederatedLink();
299
		list($remoteCircle, $remoteAddress) = explode('@', $remote, 2);
300
301
		$link->setCircleId($circleUniqueId)
302
			 ->setLocalAddress($this->configService->getLocalAddress())
303
			 ->setAddress($remoteAddress)
304
			 ->setRemoteCircleName($remoteCircle)
305
			 ->setStatus(FederatedLink::STATUS_LINK_SETUP)
306
			 ->generateToken();
307
308
		$this->federatedLinksRequest->create($link);
309
310
		return $link;
311
	}
312
313
314
	/**
315
	 * @param string $remote
316
	 *
317
	 * @return string
318
	 */
319
	private function generateLinkRemoteURL($remote) {
320
		return $this->configService->generateRemoteHost($remote) . Application::REMOTE_URL_LINK;
321
	}
322
323
324
	/**
325
	 * requestLink()
326
	 *
327
	 *
328
	 * @param Circle $circle
329
	 * @param FederatedLink $link
330
	 *
331
	 * @return boolean
332
	 * @throws Exception
333
	 */
334
	private function requestLink(Circle $circle, FederatedLink &$link) {
335
		$args = array_merge(self::generateLinkData($link), ['sourceName' => $circle->getName()]);
336
337
		try {
338
			$client = $this->clientService->newClient();
339
			$body = self::generateClientBodyData($args);
340
			$response = $client->put($this->generateLinkRemoteURL($link->getAddress()), $body);
341
			$result = $this->parseRequestLinkResult($response);
342
343
			$reason = ((key_exists('reason', $result)) ? $result['reason'] : '');
344
			$this->eventOnRequestLink($circle, $link, $result['status'], $reason);
345
346
			$link->setUniqueId($result['uniqueId']);
347
			$this->federatedLinksRequest->update($link);
348
349
			return true;
350
		} catch (Exception $e) {
351
			throw $e;
352
		}
353
	}
354
355
356
	private function parseRequestLinkResult(IResponse $response) {
357
		$result = json_decode($response->getBody(), true);
358
		if ($result === null) {
359
			throw new FederatedRemoteIsDownException(
360
				$this->l10n->t('The remote host is down or the Circles app is not installed on it')
361
			);
362
		}
363
364
		return $result;
365
	}
366
367
368
	/**
369
	 * eventOnRequestLink();
370
	 *
371
	 * Called by requestLink() will update status and event
372
	 * Will also manage errors returned by the remote link
373
	 *
374
	 * @param Circle $circle
375
	 * @param FederatedLink $link
376
	 * @param int $status
377
	 * @param string $reason
378
	 *
379
	 * @throws Exception
380
	 */
381
	private function eventOnRequestLink(Circle $circle, FederatedLink &$link, $status, $reason) {
382
383
		switch ($status) {
384
			case FederatedLink::STATUS_LINK_UP:
385
				$link->setStatus(FederatedLink::STATUS_LINK_UP);
386
				$this->eventsService->onLinkUp($circle, $link);
387
				break;
388
389
			case  FederatedLink::STATUS_LINK_REQUESTED:
0 ignored issues
show
Coding Style introduced by
As per coding-style, case should be followed by a single space.

As per the PSR-2 coding standard, there must be a space after the case keyword, instead of the test immediately following it.

switch (true) {
    case!isset($a):  //wrong
        doSomething();
        break;
    case !isset($b):  //right
        doSomething();
        break;
}

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

Loading history...
390
				$link->setStatus(FederatedLink::STATUS_REQUEST_SENT);
391
				$this->eventsService->onLinkRequestSent($circle, $link);
392
				break;
393
394
			default:
395
				$this->parseRequestLinkError($reason);
396
		}
397
	}
398
399
400
	/**
401
	 * parseRequestLinkError();
402
	 *
403
	 * Will parse the error reason returned by requestLink() and throw an Exception
404
	 *
405
	 * @param $reason
406
	 *
407
	 * @throws Exception
408
	 * @throws FederatedRemoteCircleDoesNotExistException
409
	 * @throws FederatedRemoteDoesNotAllowException
410
	 */
411
	private function parseRequestLinkError($reason) {
412
413
		$convert = [
414
			'federated_not_allowed' => $this->l10n->t(
415
				'Federated circles are not allowed on the remote Nextcloud'
416
			),
417
			'circle_links_disable'  => $this->l10n->t('Remote circle does not accept federated links'),
418
			'duplicate_unique_id'   => $this->l10n->t('Trying to link a circle to itself'),
419
			'duplicate_link'        => $this->l10n->t('This link exists already'),
420
			'circle_does_not_exist' => $this->l10n->t('The requested remote circle does not exist')
421
		];
422
423
		if (key_exists($reason, $convert)) {
424
			throw new FederatedRemoteDoesNotAllowException($convert[$reason]);
425
		}
426
		throw new Exception($reason);
427
	}
428
429
430
	/**
431
	 * @param string $token
432
	 * @param string $uniqueId
433
	 * @param int $status
434
	 *
435
	 * @return FederatedLink
436
	 * @throws Exception
437
	 */
438
	public function updateLinkFromRemote($token, $uniqueId, $status) {
439
		try {
440
			$link = $this->federatedLinksRequest->getLinkFromToken($token, $uniqueId);
441
			$circle = $this->circlesRequest->forceGetCircle($link->getCircleId());
442
			$circle->hasToBeFederated();
443
444
			$this->checkUpdateLinkFromRemote($status);
445
			$this->checkUpdateLinkFromRemoteLinkUp($circle, $link, $status);
446
			$this->checkUpdateLinkFromRemoteLinkRemove($circle, $link, $status);
447
448
			if ($link->getStatus() !== $status) {
449
				$this->federatedLinksRequest->update($link);
450
			}
451
452
			return $link;
453
		} catch (Exception $e) {
454
			throw $e;
455
		}
456
	}
457
458
	/**
459
	 * checkUpdateLinkFromRemote();
460
	 *
461
	 * will throw exception is the status sent by remote is not correct
462
	 *
463
	 * @param int $status
464
	 *
465
	 * @throws FederatedCircleStatusUpdateException
466
	 */
467
	private function checkUpdateLinkFromRemote($status) {
468
		$status = (int)$status;
469
		if ($status !== FederatedLink::STATUS_LINK_UP
470
			&& $status !== FederatedLink::STATUS_LINK_REMOVE
471
		) {
472
			throw new FederatedCircleStatusUpdateException(
473
				$this->l10n->t('Cannot proceed with this status update')
474
			);
475
		}
476
	}
477
478
479
	/**
480
	 * checkUpdateLinkFromRemoteLinkUp()
481
	 *
482
	 * in case of a request of status update from remote for a link up, we check the current
483
	 * status of the link locally.
484
	 *
485
	 * @param Circle $circle
486
	 * @param FederatedLink $link
487
	 * @param int $status
488
	 *
489
	 * @throws FederatedCircleStatusUpdateException
490
	 */
491
	private function checkUpdateLinkFromRemoteLinkUp(Circle $circle, FederatedLink $link, $status) {
492
		if ((int)$status !== FederatedLink::STATUS_LINK_UP) {
493
			return;
494
		}
495
496
		if ($link->getStatus() !== FederatedLink::STATUS_REQUEST_SENT) {
497
			throw new FederatedCircleStatusUpdateException(
498
				$this->l10n->t('Cannot proceed with this status update')
499
			);
500
		}
501
502
		$this->eventsService->onLinkRequestAccepted($circle, $link);
503
		$this->eventsService->onLinkUp($circle, $link);
504
		$link->setStatus($status);
505
	}
506
507
508
	/**
509
	 * updateLinkRemote()
510
	 *
511
	 * Send a request to the remote of the link to update its status.
512
	 *
513
	 * @param FederatedLink $link
514
	 *
515
	 * @return bool
516
	 * @throws Exception
517
	 */
518
	private function updateLinkRemote(FederatedLink &$link) {
519
520
		try {
521
			$client = $this->clientService->newClient();
522
			$body = self::generateClientBodyData(self::generateLinkData($link));
523
			$response = $client->post($this->generateLinkRemoteURL($link->getAddress()), $body);
524
			$result = $this->parseRequestLinkResult($response);
525
526
			if ($result['status'] === -1) {
527
				throw new FederatedLinkUpdateException($result['reason']);
528
			}
529
530
			return true;
531
		} catch (Exception $e) {
532
			throw $e;
533
		}
534
	}
535
536
537
	/**
538
	 * Create a new link into database and assign the correct status.
539
	 *
540
	 * @param Circle $circle
541
	 * @param FederatedLink $link
542
	 *
543
	 * @throws Exception
544
	 */
545
	public function initiateLink(Circle $circle, FederatedLink &$link) {
546
547
		try {
548
			$this->checkLinkRequestValidity($circle, $link);
549
			$link->setCircleId($circle->getUniqueId());
550
551
			if ($circle->getSetting('allow_links_auto') === 'true') {
552
				$link->setStatus(FederatedLink::STATUS_LINK_UP);
553
				$this->eventsService->onLinkUp($circle, $link);
554
			} else {
555
				$link->setStatus(FederatedLink::STATUS_LINK_REQUESTED);
556
				$this->eventsService->onLinkRequestReceived($circle, $link);
557
			}
558
559
			$this->federatedLinksRequest->create($link);
560
		} catch (Exception $e) {
561
			throw $e;
562
		}
563
	}
564
565
566
	/**
567
	 * @param Circle $circle
568
	 * @param FederatedLink $link
569
	 *
570
	 * @throws FederatedLinkCreationException
571
	 */
572
	private function checkLinkRequestValidity($circle, $link) {
573
		if ($circle->getUniqueId(true) === $link->getUniqueId(true)) {
574
			throw new FederatedLinkCreationException('duplicate_unique_id');
575
		}
576
577
		try {
578
			$this->federatedLinksRequest->getLinkFromCircle(
579
				$circle->getUniqueId(), $link->getUniqueId(true)
580
			);
581
			throw new FederatedLinkCreationException('duplicate_link');
582
		} catch (FederatedLinkDoesNotExistException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
583
		}
584
585
		if ($circle->getSetting('allow_links') !== 'true') {
586
			throw new FederatedLinkCreationException('circle_links_disable');
587
		}
588
	}
589
590
591
	/**
592
	 * checkUpdateLinkFromRemoteLinkRemove();
593
	 *
594
	 * in case of a request of status update from remote for a link down, we check the current
595
	 * status of the link locally
596
	 *
597
	 * @param Circle $circle
598
	 * @param FederatedLink $link
599
	 * @param int $status
600
	 *
601
	 * @throws FederatedCircleStatusUpdateException
602
	 */
603
	private function checkUpdateLinkFromRemoteLinkRemove(Circle $circle, FederatedLink $link, $status) {
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 101 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
604
605
		if ((int)$status !== FederatedLink::STATUS_LINK_REMOVE) {
606
			return;
607
		}
608
609
		$curStatus = $link->getStatus();
610
		$this->checkUpdateLinkFromRemoteLinkRequestSent($circle, $link);
611
		$this->checkUpdateLinkFromRemoteLinkRequested($circle, $link);
612
		$this->checkUpdateLinkFromRemoteLinkDown($circle, $link);
613
614
		if ($curStatus !== $link->getStatus()) {
615
			return;
616
		}
617
618
		throw new FederatedCircleStatusUpdateException(
619
			$this->l10n->t('Cannot proceed with this status update')
620
		);
621
	}
622
623
624
	/**
625
	 * @param Circle $circle
626
	 * @param FederatedLink $link
627
	 */
628 View Code Duplication
	private function checkUpdateLinkFromRemoteLinkRequestSent(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...
629
630
		if ($link->getStatus() !== FederatedLink::STATUS_REQUEST_SENT) {
631
			return;
632
		}
633
634
		$link->setStatus(FederatedLink::STATUS_REQUEST_DECLINED);
635
		$this->eventsService->onLinkRequestRejected($circle, $link);
636
	}
637
638
639
	/**
640
	 * @param Circle $circle
641
	 * @param FederatedLink $link
642
	 */
643 View Code Duplication
	private function checkUpdateLinkFromRemoteLinkRequested(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...
644
645
		if ($link->getStatus() !== FederatedLink::STATUS_LINK_REQUESTED) {
646
			return;
647
		}
648
649
		$link->setStatus(FederatedLink::STATUS_LINK_REMOVE);
650
		$this->eventsService->onLinkRequestCanceled($circle, $link);
651
	}
652
653
654
	/**
655
	 * @param Circle $circle
656
	 * @param FederatedLink $link
657
	 */
658 View Code Duplication
	private function checkUpdateLinkFromRemoteLinkDown(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...
659
660
		if ($link->getStatus() < FederatedLink::STATUS_LINK_DOWN) {
661
			return;
662
		}
663
664
		$link->setStatus(FederatedLink::STATUS_LINK_DOWN);
665
		$this->eventsService->onLinkDown($circle, $link);
666
	}
667
668
669
	/**
670
	 * @param FederatedLink $link
671
	 *
672
	 * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string,integer[]|string|integer>.

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...
673
	 */
674
	private static function generateLinkData(FederatedLink $link) {
675
		return [
676
			'apiVersion' => Circles::version(),
677
			'token'      => $link->getToken(true),
678
			'uniqueId'   => $link->getCircleId(true),
679
			'linkTo'     => $link->getRemoteCircleName(),
680
			'address'    => $link->getLocalAddress()
681
		];
682
	}
683
684
685
	/**
686
	 * @param array $args
687
	 *
688
	 * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string,array|integer>.

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...
689
	 */
690
	private static function generateClientBodyData($args) {
691
		return [
692
			'body'            => $args,
693
			'timeout'         => 5,
694
			'connect_timeout' => 5,
695
		];
696
	}
697
698
699
}