Completed
Pull Request — master (#551)
by Maxence
02:09
created

MemberAdd::manage()   A

Complexity

Conditions 3
Paths 5

Size

Total Lines 46

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 46
rs 9.1781
c 0
b 0
f 0
cc 3
nc 5
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
6
/**
7
 * Circles - Bring cloud-users closer together.
8
 *
9
 * This file is licensed under the Affero General Public License version 3 or
10
 * later. See the COPYING file.
11
 *
12
 * @author Maxence Lange <[email protected]>
13
 * @copyright 2021
14
 * @license GNU AGPL version 3 or any later version
15
 *
16
 * This program is free software: you can redistribute it and/or modify
17
 * it under the terms of the GNU Affero General Public License as
18
 * published by the Free Software Foundation, either version 3 of the
19
 * License, or (at your option) any later version.
20
 *
21
 * This program is distributed in the hope that it will be useful,
22
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24
 * GNU Affero General Public License for more details.
25
 *
26
 * You should have received a copy of the GNU Affero General Public License
27
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
28
 *
29
 */
30
31
32
namespace OCA\Circles\FederatedItems;
33
34
35
use daita\MySmallPhpTools\Exceptions\InvalidItemException;
36
use daita\MySmallPhpTools\Exceptions\RequestNetworkException;
37
use daita\MySmallPhpTools\Exceptions\SignatoryException;
38
use daita\MySmallPhpTools\Traits\Nextcloud\nc21\TNC21Logger;
39
use daita\MySmallPhpTools\Traits\TStringTools;
40
use Exception;
41
use OC\User\NoUserException;
42
use OCA\Circles\Db\MemberRequest;
43
use OCA\Circles\Exceptions\CircleNotFoundException;
44
use OCA\Circles\Exceptions\FederatedUserException;
45
use OCA\Circles\Exceptions\FederatedUserNotFoundException;
46
use OCA\Circles\Exceptions\InvalidIdException;
47
use OCA\Circles\Exceptions\MemberAlreadyExistsException;
48
use OCA\Circles\Exceptions\MemberNotFoundException;
49
use OCA\Circles\Exceptions\MembersLimitException;
50
use OCA\Circles\Exceptions\OwnerNotFoundException;
51
use OCA\Circles\Exceptions\RemoteInstanceException;
52
use OCA\Circles\Exceptions\RemoteNotFoundException;
53
use OCA\Circles\Exceptions\RemoteResourceNotFoundException;
54
use OCA\Circles\Exceptions\TokenDoesNotExistException;
55
use OCA\Circles\Exceptions\UnknownRemoteException;
56
use OCA\Circles\Exceptions\UserTypeNotFoundException;
57
use OCA\Circles\IFederatedItem;
58
use OCA\Circles\IFederatedItemAsyncProcess;
59
use OCA\Circles\IFederatedItemMemberCheckNotRequired;
60
use OCA\Circles\IFederatedItemMemberRequired;
61
use OCA\Circles\IFederatedUser;
62
use OCA\Circles\Model\DeprecatedCircle;
63
use OCA\Circles\Model\DeprecatedMember;
64
use OCA\Circles\Model\Federated\FederatedEvent;
65
use OCA\Circles\Model\FederatedUser;
66
use OCA\Circles\Model\Helpers\MemberHelper;
67
use OCA\Circles\Model\ManagedModel;
68
use OCA\Circles\Model\Member;
69
use OCA\Circles\Model\SharesToken;
70
use OCA\Circles\Service\CircleEventService;
71
use OCA\Circles\Service\CircleService;
72
use OCA\Circles\Service\ConfigService;
73
use OCA\Circles\Service\FederatedUserService;
74
use OCP\IUser;
75
use OCP\IUserManager;
76
use OCP\Mail\IEMailTemplate;
77
use OCP\Util;
78
79
80
/**
81
 * Class MemberAdd
82
 *
83
 * @package OCA\Circles\GlobalScale
84
 */
85
class MemberAdd implements
86
	IFederatedItem,
87
	IFederatedItemAsyncProcess,
88
	IFederatedItemMemberRequired,
89
	IFederatedItemMemberCheckNotRequired {
90
91
92
	use TStringTools;
93
	use TNC21Logger;
94
95
96
	/** @var IUserManager */
97
	private $userManager;
98
99
	/** @var FederatedUserService */
100
	private $federatedUserService;
101
102
	/** @var MemberRequest */
103
	private $memberRequest;
104
105
	/** @var CircleService */
106
	private $circleService;
107
108
	/** @var CircleEventService */
109
	private $circleEventService;
110
111
	/** @var ConfigService */
112
	private $configService;
113
114
115
	/**
116
	 * MemberAdd constructor.
117
	 *
118
	 * @param IUserManager $userManager
119
	 * @param FederatedUserService $federatedUserService
120
	 * @param MemberRequest $memberRequest
121
	 * @param CircleService $circleService
122
	 * @param CircleEventService $circleEventService
123
	 * @param ConfigService $configService
124
	 */
125
	public function __construct(
126
		IUserManager $userManager, FederatedUserService $federatedUserService, MemberRequest $memberRequest,
127
		CircleService $circleService, CircleEventService $circleEventService, ConfigService $configService
128
	) {
129
		$this->userManager = $userManager;
130
		$this->federatedUserService = $federatedUserService;
131
		$this->memberRequest = $memberRequest;
132
		$this->circleService = $circleService;
133
		$this->circleEventService = $circleEventService;
134
		$this->configService = $configService;
135
	}
136
137
138
	/**
139
	 * @param FederatedEvent $event
140
	 *
141
	 * @throws CircleNotFoundException
142
	 * @throws FederatedUserException
143
	 * @throws FederatedUserNotFoundException
144
	 * @throws InvalidItemException
145
	 * @throws MemberAlreadyExistsException
146
	 * @throws MemberNotFoundException
147
	 * @throws MembersLimitException
148
	 * @throws OwnerNotFoundException
149
	 * @throws RemoteInstanceException
150
	 * @throws RemoteNotFoundException
151
	 * @throws RemoteResourceNotFoundException
152
	 * @throws RequestNetworkException
153
	 * @throws SignatoryException
154
	 * @throws UnknownRemoteException
155
	 * @throws UserTypeNotFoundException
156
	 */
157
	public function verify(FederatedEvent $event): void {
158
		$member = $event->getMember();
159
		$circle = $event->getCircle();
160
		$initiator = $circle->getInitiator();
161
162
		$member->setCircleId($circle->getId());
163
164
		$initiatorHelper = new MemberHelper($initiator);
165
		$initiatorHelper->mustBeModerator();
166
167
		$federatedId = $member->getUserId() . '@' . $member->getInstance();
168
169
		try {
170
			$federatedUser =
171
				$this->federatedUserService->getFederatedUser($federatedId, $member->getUserType());
172
		} catch (MemberNotFoundException $e) {
173
			throw new MemberNotFoundException(
174
				ucfirst(Member::$DEF_TYPE[$member->getUserType()]) . ' %s not found',
175
				['member' => $member->getUserId() . '@' . $member->getInstance()]
176
			);
177
		}
178
179
		$member->importFromIFederatedUser($federatedUser);
180
181
		try {
182
			$knownMember = $this->memberRequest->searchMember($member);
0 ignored issues
show
Unused Code introduced by
$knownMember is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
183
			// TODO: maybe member is requesting access
184
			throw new MemberAlreadyExistsException(
185
				ucfirst(Member::$DEF_TYPE[$member->getUserType()]) . ' %s is already a member',
186
				['member' => $member->getUserId() . '@' . $member->getInstance()]
187
			);
188
		} catch (MemberNotFoundException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
189
		}
190
191
		$member->setId($this->uuid(ManagedModel::ID_LENGTH));
192
193
		// TODO: check Config on Circle to know if we set Level to 1 or just send an invitation
194
		$member->setLevel(Member::LEVEL_MEMBER);
195
		$member->setStatus(Member::STATUS_MEMBER);
196
		$event->setDataOutcome(['member' => $member]);
197
198
		// TODO: Managing cached name
199
		//		$member->setCachedName($eventMember->getCachedName());
200
		$this->circleService->confirmCircleNotFull($circle);
201
202
		// TODO: check if it is a member or a mail or a circle and fix the returned message
203
		$event->setReadingOutcome(
204
			ucfirst(Member::$DEF_TYPE[$member->getUserType()]) . ' ' . '\'%s\' have been added to Circle',
205
			['userId' => $member->getUserId()]
206
		);
207
208
		return;
209
210
211
//		$member = $this->membersRequest->getFreshNewMember(
212
//			$circle->getUniqueId(), $ident, $eventMember->getType(), $eventMember->getInstance()
213
//		);
214
//		$member->hasToBeInviteAble()
215
//
216
//		$this->membersService->addMemberBasedOnItsType($circle, $member);
217
//
218
//		$password = '';
219
//		$sendPasswordByMail = false;
220
//		if ($this->configService->enforcePasswordProtection($circle)) {
221
//			if ($circle->getSetting('password_single_enabled') === 'true') {
222
//				$password = $circle->getPasswordSingle();
223
//			} else {
224
//				$sendPasswordByMail = true;
225
//				$password = $this->miscService->token(15);
226
//			}
227
//		}
228
//
229
//		$event->setData(
230
//			new SimpleDataStore(
231
//				[
232
//					'password'       => $password,
233
//					'passwordByMail' => $sendPasswordByMail
234
//				]
235
//			)
236
//		);
237
	}
238
239
240
	/**
241
	 * @param FederatedEvent $event
242
	 *
243
	 * @throws InvalidIdException
244
	 */
245
	public function manage(FederatedEvent $event): void {
246
		$member = $event->getMember();
247
248
		try {
249
			$this->memberRequest->getMember($member->getId());
250
251
			return;
252
		} catch (MemberNotFoundException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
253
		}
254
255
		try {
256
			$federatedUser = new FederatedUser();
257
			$federatedUser->importFromIFederatedUser($member);
258
			$this->federatedUserService->confirmLocalSingleId($federatedUser);
259
		} catch (FederatedUserException $e) {
260
			$this->e($e, ['member' => $member]);
261
262
			return;
263
		}
264
265
		$this->memberRequest->save($member);
266
267
		$this->circleEventService->onMemberAdded($event);
268
269
//
270
//		//
271
//		// TODO: verifiez comment se passe le cached name sur un member_add
272
//		//
273
//		$cachedName = $member->getCachedName();
274
//		$password = $event->getData()
275
//						  ->g('password');
276
//
277
//		$shares = $this->generateUnknownSharesLinks($circle, $member, $password);
278
//		$result = [
279
//			'unknownShares' => $shares,
280
//			'cachedName'    => $cachedName
281
//		];
282
//
283
//		if ($member->getType() === DeprecatedMember::TYPE_CONTACT
284
//			&& $this->configService->isLocalInstance($member->getInstance())) {
285
//			$result['contact'] = $this->miscService->getInfosFromContact($member);
286
//		}
287
//
288
//		$event->setResult(new SimpleDataStore($result));
289
//		$this->eventsService->onMemberNew($circle, $member);
290
	}
291
292
293
	/**
294
	 * @param FederatedEvent[] $events
295
	 *
296
	 * @throws Exception
297
	 */
298
	public function result(array $events): void {
299
//		$password = $cachedName = '';
300
//		$circle = $member = null;
301
//		$links = [];
302
//		$recipients = [];
303
//		foreach ($events as $event) {
304
//			$data = $event->getData();
305
//			if ($data->gBool('passwordByMail') !== false) {
306
//				$password = $data->g('password');
307
//			}
308
//			$circle = $event->getDeprecatedCircle();
309
//			$member = $event->getMember();
310
//			$result = $event->getResult();
311
//			if ($result->g('cachedName') !== '') {
312
//				$cachedName = $result->g('cachedName');
313
//			}
314
//
315
//			$links = array_merge($links, $result->gArray('unknownShares'));
316
//			$contact = $result->gArray('contact');
317
//			if (!empty($contact)) {
318
//				$recipients = $contact['emails'];
319
//			}
320
//		}
321
//
322
//		if (empty($links) || $circle === null || $member === null) {
323
//			return;
324
//		}
325
//
326
//		if ($cachedName !== '') {
327
//			$member->setCachedName($cachedName);
328
//			$this->membersService->updateMember($member);
329
//		}
330
//
331
//		if ($member->getType() === DeprecatedMember::TYPE_MAIL
332
//			|| $member->getType() === DeprecatedMember::TYPE_CONTACT) {
333
//			if ($member->getType() === DeprecatedMember::TYPE_MAIL) {
334
//				$recipients = [$member->getUserId()];
335
//			}
336
//
337
//			foreach ($recipients as $recipient) {
338
//				$this->memberIsMailbox($circle, $recipient, $links, $password);
339
//			}
340
//		}
341
	}
342
343
344
	/**
345
	 * confirm the validity of a UserId, based on UserType.
346
	 *
347
	 * @param IFederatedUser $member
348
	 *
349
	 * @throws FederatedUserException
350
	 * @throws InvalidIdException
351
	 * @throws UserTypeNotFoundException
352
	 * @throws CircleNotFoundException
353
	 * @throws FederatedUserNotFoundException
354
	 * @throws OwnerNotFoundException
355
	 * @throws RemoteInstanceException
356
	 * @throws RemoteNotFoundException
357
	 * @throws RemoteResourceNotFoundException
358
	 * @throws UnknownRemoteException
359
	 * @throws InvalidItemException
360
	 * @throws RequestNetworkException
361
	 * @throws SignatoryException
362
	 */
363
	private function confirmMember(IFederatedUser $member): void {
364
365
		// TODO: confirm SingleId ???
366
//		switch ($member->getUserType()) {
367
//			case Member::TYPE_USER:
368
		$this->federatedUserService->getFederatedUser($member->getUserId(), $member->getUserType());
369
//				break;
370
//
371
//			// TODO: confirm other UserType
372
//			default:
373
//				break;
374
////				throw new UserTypeNotFoundException();
375
//		}
376
	}
377
378
379
	/**
380
	 * @param IFederatedUser $member
381
	 *
382
	 * @throws NoUserException
383
	 */
384
	private function confirmMemberTypeUser(IFederatedUser $member): void {
385
		if ($this->configService->isLocalInstance($member->getInstance())) {
386
			$user = $this->userManager->get($member->getUserId());
387
			if ($user === null) {
388
				throw new NoUserException('user not found');
389
			}
390
391
			$member->setUserId($user->getUID());
392
393
			return;
394
		}
395
396
		// TODO #M002: request the remote instance and check that user exists
397
	}
398
399
//	/**
400
//	 * Verify if a local account is valid.
401
//	 *
402
//	 * @param $ident
403
//	 * @param $type
404
//	 *
405
//	 * @param string $instance
406
//	 *
407
//	 * @throws NoUserException
408
//	 */
409
//	private function verifyIdentLocalMember(&$ident, $type, string $instance = '') {
410
//		if ($type !== DeprecatedMember::TYPE_USER) {
411
//			return;
412
//		}
413
//
414
//		if ($instance === '') {
415
//			try {
416
//				$ident = $this->miscService->getRealUserId($ident);
417
//			} catch (NoUserException $e) {
418
//				throw new NoUserException($this->l10n->t("This user does not exist"));
419
//			}
420
//		}
421
//	}
422
//
423
//
424
//	/**
425
//	 * Verify if a mail have a valid format.
426
//	 *
427
//	 * @param string $ident
428
//	 * @param int $type
429
//	 *
430
//	 * @throws EmailAccountInvalidFormatException
431
//	 */
432
//	private function verifyIdentEmailAddress(string $ident, int $type) {
433
//		if ($type !== DeprecatedMember::TYPE_MAIL) {
434
//			return;
435
//		}
436
//
437
//		if ($this->configService->isAccountOnly()) {
438
//			throw new EmailAccountInvalidFormatException(
439
//				$this->l10n->t('You cannot add a mail address as member of your Circle')
440
//			);
441
//		}
442
//
443
//		if (!filter_var($ident, FILTER_VALIDATE_EMAIL)) {
444
//			throw new EmailAccountInvalidFormatException(
445
//				$this->l10n->t('Email format is not valid')
446
//			);
447
//		}
448
//	}
449
//
450
//
451
//	/**
452
//	 * Verify if a contact exist in current user address books.
453
//	 *
454
//	 * @param $ident
455
//	 * @param $type
456
//	 *
457
//	 * @throws NoUserException
458
//	 * @throws EmailAccountInvalidFormatException
459
//	 */
460
//	private function verifyIdentContact(&$ident, $type) {
461
//		if ($type !== DeprecatedMember::TYPE_CONTACT) {
462
//			return;
463
//		}
464
//
465
//		if ($this->configService->isAccountOnly()) {
466
//			throw new EmailAccountInvalidFormatException(
467
//				$this->l10n->t('You cannot add a contact as member of your Circle')
468
//			);
469
//		}
470
//
471
//		$tmpContact = $this->userId . ':' . $ident;
472
//		$result = MiscService::getContactData($tmpContact);
473
//		if (empty($result)) {
474
//			throw new NoUserException($this->l10n->t("This contact is not available"));
475
//		}
476
//
477
//		$ident = $tmpContact;
478
//	}
479
480
481
	/**
482
	 * @param DeprecatedCircle $circle
483
	 * @param string $recipient
484
	 * @param array $links
485
	 * @param string $password
486
	 */
487 View Code Duplication
	private function memberIsMailbox(
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...
488
		DeprecatedCircle $circle, string $recipient, array $links, string $password
489
	) {
490
		if ($circle->getViewer() === null) {
491
			$author = $circle->getOwner()
492
							 ->getUserId();
493
		} else {
494
			$author = $circle->getViewer()
495
							 ->getUserId();
496
		}
497
498
		try {
499
			$template = $this->generateMailExitingShares($author, $circle->getName());
500
			$this->fillMailExistingShares($template, $links);
501
			$this->sendMailExistingShares($template, $author, $recipient);
502
			$this->sendPasswordExistingShares($author, $recipient, $password);
503
		} catch (Exception $e) {
504
			$this->miscService->log('Failed to send mail about existing share ' . $e->getMessage());
0 ignored issues
show
Bug introduced by
The property miscService does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
505
		}
506
	}
507
508
509
	/**
510
	 * @param DeprecatedCircle $circle
511
	 * @param DeprecatedMember $member
512
	 * @param string $password
513
	 *
514
	 * @return array
515
	 */
516 View Code Duplication
	private function generateUnknownSharesLinks(
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...
517
		DeprecatedCircle $circle, DeprecatedMember $member, string $password
0 ignored issues
show
Unused Code introduced by
The parameter $circle is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
518
	): array {
519
		$unknownShares = $this->getUnknownShares($member);
520
521
		$data = [];
522
		foreach ($unknownShares as $share) {
523
			try {
524
				$data[] = $this->getMailLinkFromShare($share, $member, $password);
525
			} catch (TokenDoesNotExistException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
526
			}
527
		}
528
529
		return $data;
530
	}
531
532
533
	/**
534
	 * @param DeprecatedMember $member
535
	 *
536
	 * @return array
537
	 */
538 View Code Duplication
	private function getUnknownShares(DeprecatedMember $member): array {
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...
539
		$allShares = $this->fileSharesRequest->getSharesForCircle($member->getCircleId());
0 ignored issues
show
Bug introduced by
The property fileSharesRequest does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
540
		$knownShares = array_map(
541
			function(SharesToken $shareToken) {
542
				return $shareToken->getShareId();
543
			},
544
			$this->tokensRequest->getTokensFromMember($member)
0 ignored issues
show
Bug introduced by
The property tokensRequest does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
545
		);
546
547
		$unknownShares = [];
548
		foreach ($allShares as $share) {
549
			if (!in_array($share['id'], $knownShares)) {
550
				$unknownShares[] = $share;
551
			}
552
		}
553
554
		return $unknownShares;
555
	}
556
557
558
	/**
559
	 * @param array $share
560
	 * @param DeprecatedMember $member
561
	 * @param string $password
562
	 *
563
	 * @return array
564
	 * @throws TokenDoesNotExistException
565
	 */
566 View Code Duplication
	private function getMailLinkFromShare(array $share, DeprecatedMember $member, string $password = '') {
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...
567
		$sharesToken = $this->tokensRequest->generateTokenForMember($member, (int)$share['id'], $password);
568
		$link = $this->urlGenerator->linkToRouteAbsolute(
0 ignored issues
show
Bug introduced by
The property urlGenerator does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
569
			'files_sharing.sharecontroller.showShare',
570
			['token' => $sharesToken->getToken()]
571
		);
572
		$author = $share['uid_initiator'];
573
		$filename = basename($share['file_target']);
574
575
		return [
576
			'author'   => $author,
577
			'link'     => $link,
578
			'filename' => $filename
579
		];
580
	}
581
582
583
	/**
584
	 * @param string $author
585
	 * @param string $circleName
586
	 *
587
	 * @return IEMailTemplate
588
	 */
589 View Code Duplication
	private function generateMailExitingShares(string $author, string $circleName): IEMailTemplate {
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...
590
		$emailTemplate = $this->mailer->createEMailTemplate('circles.ExistingShareNotification', []);
0 ignored issues
show
Bug introduced by
The property mailer does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
591
		$emailTemplate->addHeader();
592
593
		$text = $this->l10n->t('%s shared multiple files with \'%s\'.', [$author, $circleName]);
0 ignored issues
show
Bug introduced by
The property l10n does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
594
		$emailTemplate->addBodyText(htmlspecialchars($text), $text);
595
596
		return $emailTemplate;
597
	}
598
599
	/**
600
	 * @param IEMailTemplate $emailTemplate
601
	 * @param array $links
602
	 */
603 View Code Duplication
	private function fillMailExistingShares(IEMailTemplate $emailTemplate, array $links) {
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...
604
		foreach ($links as $item) {
605
			$emailTemplate->addBodyButton(
606
				$this->l10n->t('Open »%s«', [htmlspecialchars($item['filename'])]), $item['link']
607
			);
608
		}
609
	}
610
611
612
	/**
613
	 * @param IEMailTemplate $emailTemplate
614
	 * @param string $author
615
	 * @param string $recipient
616
	 *
617
	 * @throws Exception
618
	 */
619 View Code Duplication
	private function sendMailExistingShares(IEMailTemplate $emailTemplate, string $author, string $recipient
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...
620
	) {
621
		$subject = $this->l10n->t('%s shared multiple files with you.', [$author]);
622
623
		$instanceName = $this->defaults->getName();
0 ignored issues
show
Bug introduced by
The property defaults does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
624
		$senderName = $this->l10n->t('%s on %s', [$author, $instanceName]);
625
626
		$message = $this->mailer->createMessage();
627
628
		$message->setFrom([Util::getDefaultEmailAddress($instanceName) => $senderName]);
629
		$message->setSubject($subject);
630
		$message->setPlainBody($emailTemplate->renderText());
631
		$message->setHtmlBody($emailTemplate->renderHtml());
632
		$message->setTo([$recipient]);
633
634
		$this->mailer->send($message);
635
	}
636
637
638
	/**
639
	 * @param string $author
640
	 * @param string $email
641
	 * @param string $password
642
	 *
643
	 * @throws Exception
644
	 */
645
	protected function sendPasswordExistingShares(string $author, string $email, string $password) {
646
		if ($password === '') {
647
			return;
648
		}
649
650
		$message = $this->mailer->createMessage();
651
652
		$authorUser = $this->userManager->get($author);
653
		$authorName = ($authorUser instanceof IUser) ? $authorUser->getDisplayName() : $author;
0 ignored issues
show
Bug introduced by
The class OCP\IUser does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

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

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

2. Missing use statement

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

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

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

Loading history...
654
		$authorEmail = ($authorUser instanceof IUser) ? $authorUser->getEMailAddress() : null;
0 ignored issues
show
Bug introduced by
The class OCP\IUser does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

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

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

2. Missing use statement

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

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

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

Loading history...
655
656
		$this->miscService->log("Sending password mail about existing files to '" . $email . "'", 0);
657
658
		$plainBodyPart = $this->l10n->t(
659
			"%1\$s shared multiple files with you.\nYou should have already received a separate mail with a link to access them.\n",
660
			[$authorName]
661
		);
662
		$htmlBodyPart = $this->l10n->t(
663
			'%1$s shared multiple files with you. You should have already received a separate mail with a link to access them.',
664
			[$authorName]
665
		);
666
667
		$emailTemplate = $this->mailer->createEMailTemplate(
668
			'sharebymail.RecipientPasswordNotification', [
669
														   'password' => $password,
670
														   'author'   => $author
671
													   ]
672
		);
673
674
		$emailTemplate->setSubject(
675
			$this->l10n->t(
676
				'Password to access files shared to you by %1$s', [$authorName]
677
			)
678
		);
679
		$emailTemplate->addHeader();
680
		$emailTemplate->addHeading($this->l10n->t('Password to access files'), false);
681
		$emailTemplate->addBodyText(htmlspecialchars($htmlBodyPart), $plainBodyPart);
682
		$emailTemplate->addBodyText($this->l10n->t('It is protected with the following password:'));
683
		$emailTemplate->addBodyText($password);
684
685
		// The "From" contains the sharers name
686
		$instanceName = $this->defaults->getName();
687
		$senderName = $this->l10n->t(
688
			'%1$s via %2$s',
689
			[
690
				$authorName,
691
				$instanceName
692
			]
693
		);
694
695
		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
696
		if ($authorEmail !== null) {
697
			$message->setReplyTo([$authorEmail => $authorName]);
698
			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
699
		} else {
700
			$emailTemplate->addFooter();
701
		}
702
703
		$message->setTo([$email]);
704
		$message->useTemplate($emailTemplate);
705
		$this->mailer->send($message);
706
	}
707
708
}
709