Completed
Pull Request — master (#551)
by Maxence
01:59
created

MemberAdd::sendPasswordExistingShares()   B

Complexity

Conditions 5
Paths 9

Size

Total Lines 62

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 62
rs 8.5178
c 0
b 0
f 0
cc 5
nc 9
nop 3

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\MemberTypeNotFoundException;
51
use OCA\Circles\Exceptions\OwnerNotFoundException;
52
use OCA\Circles\Exceptions\RemoteInstanceException;
53
use OCA\Circles\Exceptions\RemoteNotFoundException;
54
use OCA\Circles\Exceptions\RemoteResourceNotFoundException;
55
use OCA\Circles\Exceptions\TokenDoesNotExistException;
56
use OCA\Circles\Exceptions\UnknownRemoteException;
57
use OCA\Circles\Exceptions\UserTypeNotFoundException;
58
use OCA\Circles\IFederatedItem;
59
use OCA\Circles\IFederatedItemAsync;
60
use OCA\Circles\IFederatedItemMemberCheckNotRequired;
61
use OCA\Circles\IFederatedItemMemberRequired;
62
use OCA\Circles\IFederatedUser;
63
use OCA\Circles\Model\DeprecatedCircle;
64
use OCA\Circles\Model\DeprecatedMember;
65
use OCA\Circles\Model\Federated\FederatedEvent;
66
use OCA\Circles\Model\FederatedUser;
67
use OCA\Circles\Model\Helpers\MemberHelper;
68
use OCA\Circles\Model\ManagedModel;
69
use OCA\Circles\Model\Member;
70
use OCA\Circles\Model\SharesToken;
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
	IFederatedItemAsync,
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 ConfigService */
109
	private $configService;
110
111
112
	/**
113
	 * MemberAdd constructor.
114
	 *
115
	 * @param IUserManager $userManager
116
	 * @param FederatedUserService $federatedUserService
117
	 * @param MemberRequest $memberRequest
118
	 * @param CircleService $circleService
119
	 * @param ConfigService $configService
120
	 */
121 View Code Duplication
	public function __construct(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
122
		IUserManager $userManager, FederatedUserService $federatedUserService, MemberRequest $memberRequest,
123
		CircleService $circleService, ConfigService $configService
124
	) {
125
		$this->userManager = $userManager;
126
		$this->federatedUserService = $federatedUserService;
127
		$this->memberRequest = $memberRequest;
128
		$this->circleService = $circleService;
129
		$this->configService = $configService;
130
	}
131
132
133
	/**
134
	 * @param FederatedEvent $event
135
	 *
136
	 * @throws CircleNotFoundException
137
	 * @throws FederatedUserException
138
	 * @throws FederatedUserNotFoundException
139
	 * @throws InvalidIdException
140
	 * @throws InvalidItemException
141
	 * @throws MemberAlreadyExistsException
142
	 * @throws MembersLimitException
143
	 * @throws OwnerNotFoundException
144
	 * @throws RemoteInstanceException
145
	 * @throws RemoteNotFoundException
146
	 * @throws RemoteResourceNotFoundException
147
	 * @throws RequestNetworkException
148
	 * @throws SignatoryException
149
	 * @throws UnknownRemoteException
150
	 * @throws UserTypeNotFoundException
151
	 * @throws MemberNotFoundException
152
	 */
153
	public function verify(FederatedEvent $event): void {
154
		$member = $event->getMember();
155
		$circle = $event->getCircle();
156
		$initiator = $circle->getInitiator();
157
158
		$member->setCircleId($circle->getId());
159
160
		$initiatorHelper = new MemberHelper($initiator);
161
		$initiatorHelper->mustBeModerator();
162
163
		$federatedId = $member->getUserId() . '@' . $member->getInstance();
164
165
		try {
166
			$federatedUser =
167
				$this->federatedUserService->getFederatedUser($federatedId, $member->getUserType());
168
		} catch (MemberNotFoundException $e) {
169
			throw new MemberNotFoundException(
170
				ucfirst(Member::$DEF_TYPE[$member->getUserType()]) . ' %s not found',
171
				['member' => $member->getUserId() . '@' . $member->getInstance()]
172
			);
173
		}
174
		$member->importFromIFederatedUser($federatedUser);
175
176
		try {
177
			$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...
178
			// TODO: maybe member is requesting access
179
			throw new MemberAlreadyExistsException(
180
				ucfirst(Member::$DEF_TYPE[$member->getUserType()]) . ' %s is already a member',
181
				['member' => $member->getUserId() . '@' . $member->getInstance()]
182
			);
183
		} catch (MemberNotFoundException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
184
		}
185
186
		$member->setId($this->uuid(ManagedModel::ID_LENGTH));
187
188
		// TODO: check Config on Circle to know if we set Level to 1 or just send an invitation
189
		$member->setLevel(Member::LEVEL_MEMBER);
190
		$member->setStatus(Member::STATUS_MEMBER);
191
		$event->setDataOutcome(['member' => $member]);
192
193
		// TODO: Managing cached name
194
		//		$member->setCachedName($eventMember->getCachedName());
195
		$this->circleService->confirmCircleNotFull($circle);
196
197
		// TODO: check if it is a member or a mail or a circle and fix the returned message
198
		$event->setReadingOutcome(
199
			ucfirst(Member::$DEF_TYPE[$member->getUserType()]) . ' ' . '\'%s\' have been added to Circle',
200
			['userId' => $member->getUserId()]
201
		);
202
203
		return;
204
205
206
//		$member = $this->membersRequest->getFreshNewMember(
207
//			$circle->getUniqueId(), $ident, $eventMember->getType(), $eventMember->getInstance()
208
//		);
209
//		$member->hasToBeInviteAble()
210
//
211
//		$this->membersService->addMemberBasedOnItsType($circle, $member);
212
//
213
//		$password = '';
214
//		$sendPasswordByMail = false;
215
//		if ($this->configService->enforcePasswordProtection($circle)) {
216
//			if ($circle->getSetting('password_single_enabled') === 'true') {
217
//				$password = $circle->getPasswordSingle();
218
//			} else {
219
//				$sendPasswordByMail = true;
220
//				$password = $this->miscService->token(15);
221
//			}
222
//		}
223
//
224
//		$event->setData(
225
//			new SimpleDataStore(
226
//				[
227
//					'password'       => $password,
228
//					'passwordByMail' => $sendPasswordByMail
229
//				]
230
//			)
231
//		);
232
	}
233
234
235
	/**
236
	 * @param FederatedEvent $event
237
	 *
238
	 * @throws InvalidIdException
239
	 */
240
	public function manage(FederatedEvent $event): void {
241
		$member = $event->getMember();
242
243
		try {
244
			$this->memberRequest->getMember($member->getId());
245
246
			return;
247
		} catch (MemberNotFoundException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
248
		}
249
250
		try {
251
			$federatedUser = new FederatedUser();
252
			$federatedUser->importFromIFederatedUser($member);
253
			$this->federatedUserService->confirmLocalSingleId($federatedUser);
254
		} catch (FederatedUserException $e) {
255
			$this->e($e, ['member' => $member]);
256
257
			return;
258
		}
259
260
		$this->memberRequest->save($member);
261
262
//
263
//		//
264
//		// TODO: verifiez comment se passe le cached name sur un member_add
265
//		//
266
//		$cachedName = $member->getCachedName();
267
//		$password = $event->getData()
268
//						  ->g('password');
269
//
270
//		$shares = $this->generateUnknownSharesLinks($circle, $member, $password);
271
//		$result = [
272
//			'unknownShares' => $shares,
273
//			'cachedName'    => $cachedName
274
//		];
275
//
276
//		if ($member->getType() === DeprecatedMember::TYPE_CONTACT
277
//			&& $this->configService->isLocalInstance($member->getInstance())) {
278
//			$result['contact'] = $this->miscService->getInfosFromContact($member);
279
//		}
280
//
281
//		$event->setResult(new SimpleDataStore($result));
282
//		$this->eventsService->onMemberNew($circle, $member);
283
	}
284
285
286
	/**
287
	 * @param FederatedEvent[] $events
288
	 *
289
	 * @throws Exception
290
	 */
291
	public function result(array $events): void {
292
//		$password = $cachedName = '';
293
//		$circle = $member = null;
294
//		$links = [];
295
//		$recipients = [];
296
//		foreach ($events as $event) {
297
//			$data = $event->getData();
298
//			if ($data->gBool('passwordByMail') !== false) {
299
//				$password = $data->g('password');
300
//			}
301
//			$circle = $event->getDeprecatedCircle();
302
//			$member = $event->getMember();
303
//			$result = $event->getResult();
304
//			if ($result->g('cachedName') !== '') {
305
//				$cachedName = $result->g('cachedName');
306
//			}
307
//
308
//			$links = array_merge($links, $result->gArray('unknownShares'));
309
//			$contact = $result->gArray('contact');
310
//			if (!empty($contact)) {
311
//				$recipients = $contact['emails'];
312
//			}
313
//		}
314
//
315
//		if (empty($links) || $circle === null || $member === null) {
316
//			return;
317
//		}
318
//
319
//		if ($cachedName !== '') {
320
//			$member->setCachedName($cachedName);
321
//			$this->membersService->updateMember($member);
322
//		}
323
//
324
//		if ($member->getType() === DeprecatedMember::TYPE_MAIL
325
//			|| $member->getType() === DeprecatedMember::TYPE_CONTACT) {
326
//			if ($member->getType() === DeprecatedMember::TYPE_MAIL) {
327
//				$recipients = [$member->getUserId()];
328
//			}
329
//
330
//			foreach ($recipients as $recipient) {
331
//				$this->memberIsMailbox($circle, $recipient, $links, $password);
332
//			}
333
//		}
334
	}
335
336
337
	/**
338
	 * confirm the validity of a UserId, based on UserType.
339
	 *
340
	 * @param IFederatedUser $member
341
	 *
342
	 * @throws FederatedUserException
343
	 * @throws InvalidIdException
344
	 * @throws UserTypeNotFoundException
345
	 * @throws CircleNotFoundException
346
	 * @throws FederatedUserNotFoundException
347
	 * @throws OwnerNotFoundException
348
	 * @throws RemoteInstanceException
349
	 * @throws RemoteNotFoundException
350
	 * @throws RemoteResourceNotFoundException
351
	 * @throws UnknownRemoteException
352
	 * @throws InvalidItemException
353
	 * @throws RequestNetworkException
354
	 * @throws SignatoryException
355
	 */
356
	private function confirmMember(IFederatedUser $member): void {
357
358
		// TODO: confirm SingleId ???
359
//		switch ($member->getUserType()) {
360
//			case Member::TYPE_USER:
361
		$this->federatedUserService->getFederatedUser($member->getUserId(), $member->getUserType());
362
//				break;
363
//
364
//			// TODO: confirm other UserType
365
//			default:
366
//				break;
367
////				throw new UserTypeNotFoundException();
368
//		}
369
	}
370
371
372
	/**
373
	 * @param IFederatedUser $member
374
	 *
375
	 * @throws NoUserException
376
	 */
377
	private function confirmMemberTypeUser(IFederatedUser $member): void {
378
		if ($this->configService->isLocalInstance($member->getInstance())) {
379
			$user = $this->userManager->get($member->getUserId());
380
			if ($user === null) {
381
				throw new NoUserException('user not found');
382
			}
383
384
			$member->setUserId($user->getUID());
385
386
			return;
387
		}
388
389
		// TODO #M002: request the remote instance and check that user exists
390
	}
391
392
//	/**
393
//	 * Verify if a local account is valid.
394
//	 *
395
//	 * @param $ident
396
//	 * @param $type
397
//	 *
398
//	 * @param string $instance
399
//	 *
400
//	 * @throws NoUserException
401
//	 */
402
//	private function verifyIdentLocalMember(&$ident, $type, string $instance = '') {
403
//		if ($type !== DeprecatedMember::TYPE_USER) {
404
//			return;
405
//		}
406
//
407
//		if ($instance === '') {
408
//			try {
409
//				$ident = $this->miscService->getRealUserId($ident);
410
//			} catch (NoUserException $e) {
411
//				throw new NoUserException($this->l10n->t("This user does not exist"));
412
//			}
413
//		}
414
//	}
415
//
416
//
417
//	/**
418
//	 * Verify if a mail have a valid format.
419
//	 *
420
//	 * @param string $ident
421
//	 * @param int $type
422
//	 *
423
//	 * @throws EmailAccountInvalidFormatException
424
//	 */
425
//	private function verifyIdentEmailAddress(string $ident, int $type) {
426
//		if ($type !== DeprecatedMember::TYPE_MAIL) {
427
//			return;
428
//		}
429
//
430
//		if ($this->configService->isAccountOnly()) {
431
//			throw new EmailAccountInvalidFormatException(
432
//				$this->l10n->t('You cannot add a mail address as member of your Circle')
433
//			);
434
//		}
435
//
436
//		if (!filter_var($ident, FILTER_VALIDATE_EMAIL)) {
437
//			throw new EmailAccountInvalidFormatException(
438
//				$this->l10n->t('Email format is not valid')
439
//			);
440
//		}
441
//	}
442
//
443
//
444
//	/**
445
//	 * Verify if a contact exist in current user address books.
446
//	 *
447
//	 * @param $ident
448
//	 * @param $type
449
//	 *
450
//	 * @throws NoUserException
451
//	 * @throws EmailAccountInvalidFormatException
452
//	 */
453
//	private function verifyIdentContact(&$ident, $type) {
454
//		if ($type !== DeprecatedMember::TYPE_CONTACT) {
455
//			return;
456
//		}
457
//
458
//		if ($this->configService->isAccountOnly()) {
459
//			throw new EmailAccountInvalidFormatException(
460
//				$this->l10n->t('You cannot add a contact as member of your Circle')
461
//			);
462
//		}
463
//
464
//		$tmpContact = $this->userId . ':' . $ident;
465
//		$result = MiscService::getContactData($tmpContact);
466
//		if (empty($result)) {
467
//			throw new NoUserException($this->l10n->t("This contact is not available"));
468
//		}
469
//
470
//		$ident = $tmpContact;
471
//	}
472
473
474
	/**
475
	 * @param DeprecatedCircle $circle
476
	 * @param string $recipient
477
	 * @param array $links
478
	 * @param string $password
479
	 */
480 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...
481
		DeprecatedCircle $circle, string $recipient, array $links, string $password
482
	) {
483
		if ($circle->getViewer() === null) {
484
			$author = $circle->getOwner()
485
							 ->getUserId();
486
		} else {
487
			$author = $circle->getViewer()
488
							 ->getUserId();
489
		}
490
491
		try {
492
			$template = $this->generateMailExitingShares($author, $circle->getName());
493
			$this->fillMailExistingShares($template, $links);
494
			$this->sendMailExistingShares($template, $author, $recipient);
495
			$this->sendPasswordExistingShares($author, $recipient, $password);
496
		} catch (Exception $e) {
497
			$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...
498
		}
499
	}
500
501
502
	/**
503
	 * @param DeprecatedCircle $circle
504
	 * @param DeprecatedMember $member
505
	 * @param string $password
506
	 *
507
	 * @return array
508
	 */
509 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...
510
		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...
511
	): array {
512
		$unknownShares = $this->getUnknownShares($member);
513
514
		$data = [];
515
		foreach ($unknownShares as $share) {
516
			try {
517
				$data[] = $this->getMailLinkFromShare($share, $member, $password);
518
			} catch (TokenDoesNotExistException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
519
			}
520
		}
521
522
		return $data;
523
	}
524
525
526
	/**
527
	 * @param DeprecatedMember $member
528
	 *
529
	 * @return array
530
	 */
531 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...
532
		$allShares = $this->sharesRequest->getSharesForCircle($member->getCircleId());
0 ignored issues
show
Bug introduced by
The property sharesRequest 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...
533
		$knownShares = array_map(
534
			function(SharesToken $shareToken) {
535
				return $shareToken->getShareId();
536
			},
537
			$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...
538
		);
539
540
		$unknownShares = [];
541
		foreach ($allShares as $share) {
542
			if (!in_array($share['id'], $knownShares)) {
543
				$unknownShares[] = $share;
544
			}
545
		}
546
547
		return $unknownShares;
548
	}
549
550
551
	/**
552
	 * @param array $share
553
	 * @param DeprecatedMember $member
554
	 * @param string $password
555
	 *
556
	 * @return array
557
	 * @throws TokenDoesNotExistException
558
	 */
559 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...
560
		$sharesToken = $this->tokensRequest->generateTokenForMember($member, (int)$share['id'], $password);
561
		$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...
562
			'files_sharing.sharecontroller.showShare',
563
			['token' => $sharesToken->getToken()]
564
		);
565
		$author = $share['uid_initiator'];
566
		$filename = basename($share['file_target']);
567
568
		return [
569
			'author'   => $author,
570
			'link'     => $link,
571
			'filename' => $filename
572
		];
573
	}
574
575
576
	/**
577
	 * @param string $author
578
	 * @param string $circleName
579
	 *
580
	 * @return IEMailTemplate
581
	 */
582 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...
583
		$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...
584
		$emailTemplate->addHeader();
585
586
		$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...
587
		$emailTemplate->addBodyText(htmlspecialchars($text), $text);
588
589
		return $emailTemplate;
590
	}
591
592
	/**
593
	 * @param IEMailTemplate $emailTemplate
594
	 * @param array $links
595
	 */
596 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...
597
		foreach ($links as $item) {
598
			$emailTemplate->addBodyButton(
599
				$this->l10n->t('Open »%s«', [htmlspecialchars($item['filename'])]), $item['link']
600
			);
601
		}
602
	}
603
604
605
	/**
606
	 * @param IEMailTemplate $emailTemplate
607
	 * @param string $author
608
	 * @param string $recipient
609
	 *
610
	 * @throws Exception
611
	 */
612 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...
613
	) {
614
		$subject = $this->l10n->t('%s shared multiple files with you.', [$author]);
615
616
		$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...
617
		$senderName = $this->l10n->t('%s on %s', [$author, $instanceName]);
618
619
		$message = $this->mailer->createMessage();
620
621
		$message->setFrom([Util::getDefaultEmailAddress($instanceName) => $senderName]);
622
		$message->setSubject($subject);
623
		$message->setPlainBody($emailTemplate->renderText());
624
		$message->setHtmlBody($emailTemplate->renderHtml());
625
		$message->setTo([$recipient]);
626
627
		$this->mailer->send($message);
628
	}
629
630
631
	/**
632
	 * @param string $author
633
	 * @param string $email
634
	 * @param string $password
635
	 *
636
	 * @throws Exception
637
	 */
638
	protected function sendPasswordExistingShares(string $author, string $email, string $password) {
639
		if ($password === '') {
640
			return;
641
		}
642
643
		$message = $this->mailer->createMessage();
644
645
		$authorUser = $this->userManager->get($author);
646
		$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...
647
		$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...
648
649
		$this->miscService->log("Sending password mail about existing files to '" . $email . "'", 0);
650
651
		$plainBodyPart = $this->l10n->t(
652
			"%1\$s shared multiple files with you.\nYou should have already received a separate mail with a link to access them.\n",
653
			[$authorName]
654
		);
655
		$htmlBodyPart = $this->l10n->t(
656
			'%1$s shared multiple files with you. You should have already received a separate mail with a link to access them.',
657
			[$authorName]
658
		);
659
660
		$emailTemplate = $this->mailer->createEMailTemplate(
661
			'sharebymail.RecipientPasswordNotification', [
662
														   'password' => $password,
663
														   'author'   => $author
664
													   ]
665
		);
666
667
		$emailTemplate->setSubject(
668
			$this->l10n->t(
669
				'Password to access files shared to you by %1$s', [$authorName]
670
			)
671
		);
672
		$emailTemplate->addHeader();
673
		$emailTemplate->addHeading($this->l10n->t('Password to access files'), false);
674
		$emailTemplate->addBodyText(htmlspecialchars($htmlBodyPart), $plainBodyPart);
675
		$emailTemplate->addBodyText($this->l10n->t('It is protected with the following password:'));
676
		$emailTemplate->addBodyText($password);
677
678
		// The "From" contains the sharers name
679
		$instanceName = $this->defaults->getName();
680
		$senderName = $this->l10n->t(
681
			'%1$s via %2$s',
682
			[
683
				$authorName,
684
				$instanceName
685
			]
686
		);
687
688
		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
689
		if ($authorEmail !== null) {
690
			$message->setReplyTo([$authorEmail => $authorName]);
691
			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
692
		} else {
693
			$emailTemplate->addFooter();
694
		}
695
696
		$message->setTo([$email]);
697
		$message->useTemplate($emailTemplate);
698
		$this->mailer->send($message);
699
	}
700
701
}
702