Passed
Pull Request — master (#875)
by René
03:44
created

MailService::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 26
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 12
nc 1
nop 12
dl 0
loc 26
ccs 0
cts 26
cp 0
crap 2
rs 9.8666
c 2
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/**
3
 * @copyright Copyright (c) 2017 Vinzenz Rosenkranz <[email protected]>
4
 *
5
 * @author René Gieling <[email protected]>
6
 *
7
 * @license GNU AGPL version 3 or any later version
8
 *
9
 *  This program is free software: you can redistribute it and/or modify
10
 *  it under the terms of the GNU Affero General Public License as
11
 *  published by the Free Software Foundation, either version 3 of the
12
 *  License, or (at your option) any later version.
13
 *
14
 *  This program is distributed in the hope that it will be useful,
15
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 *  GNU Affero General Public License for more details.
18
 *
19
 *  You should have received a copy of the GNU Affero General Public License
20
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
 *
22
 */
23
24
namespace OCA\Polls\Service;
25
26
use Exception;
27
28
use OCP\IUser;
29
use OCP\IUserManager;
30
use OCP\IGroupManager;
31
use OCP\IConfig;
32
use OCP\IURLGenerator;
33
use OCP\IL10N;
34
use OCP\L10N\IFactory;
35
use OCP\Mail\IMailer;
36
use OCP\Mail\IEMailTemplate;
37
use OCP\ILogger;
38
39
use OCA\Polls\Db\SubscriptionMapper;
40
use OCA\Polls\Db\Subscription;
41
use OCA\Polls\Db\PollMapper;
42
use OCA\Polls\Db\Poll;
43
use OCA\Polls\Db\ShareMapper;
44
use OCA\Polls\Db\Share;
45
use OCA\Polls\Db\LogMapper;
46
47
class MailService {
48
49
	private $userManager;
50
	private $groupManager;
51
	private $config;
52
	private $urlGenerator;
53
	private $trans;
54
	private $transFactory;
55
	private $mailer;
56
	private $logger;
57
58
	private $shareMapper;
59
	private $subscriptionMapper;
60
	private $pollMapper;
61
	private $logMapper;
62
63
	/**
64
	 * MailService constructor.
65
	 * @param IUserManager $userManager
66
	 * @param IGroupManager $groupManager
67
	 * @param IConfig $config
68
	 * @param IURLGenerator $urlGenerator
69
	 * @param IL10N $trans
70
	 * @param IFactory $transFactory
71
	 * @param IMailer $mailer
72
	 * @param ILogger $logger
73
	 * @param SubscriptionMapper $subscriptionMapper
74
	 * @param ShareMapper $shareMapper
75
	 * @param PollMapper $pollMapper
76
	 * @param LogMapper $logMapper
77
	 */
78
79
	public function __construct(
80
		IUserManager $userManager,
81
		IGroupManager $groupManager,
82
		IConfig $config,
83
		IURLGenerator $urlGenerator,
84
		IL10N $trans,
85
		IFactory $transFactory,
86
		IMailer $mailer,
87
		ILogger $logger,
88
		ShareMapper $shareMapper,
89
		SubscriptionMapper $subscriptionMapper,
90
		PollMapper $pollMapper,
91
		LogMapper $logMapper
92
	) {
93
		$this->config = $config;
94
		$this->userManager = $userManager;
95
		$this->groupManager = $groupManager;
96
		$this->urlGenerator = $urlGenerator;
97
		$this->trans = $trans;
98
		$this->transFactory = $transFactory;
99
		$this->mailer = $mailer;
100
		$this->logger = $logger;
101
		$this->shareMapper = $shareMapper;
102
		$this->subscriptionMapper = $subscriptionMapper;
103
		$this->pollMapper = $pollMapper;
104
		$this->logMapper = $logMapper;
105
	}
106
107
108
	/**
109
	 * sendMail - Send eMail and evaluate recipient's mail address
110
	 * and displayname if $toUserId is a site user
111
	 * @param IEmailTemplate $emailTemplate
112
	 * @param String $toUserId
113
	 * @param String $toEmail
114
	 * @param String $toDisplayName
115
	 * @return String
116
	 */
117
118
	private function sendMail($emailTemplate, $toUserId = '', $toEmail = '', $toDisplayName = '') {
119
120
		if ($this->userManager->get($toUserId) instanceof IUser && !$toEmail) {
121
			$toEmail = \OC::$server->getConfig()->getUserValue($toUserId, 'settings', 'email');
122
			$toDisplayName = $this->userManager->get($toUserId)->getDisplayName();
123
		}
124
125
		if (!$toEmail || !filter_var($toEmail, FILTER_VALIDATE_EMAIL)) {
126
	   		throw new Exception('Invalid email address (' . $toEmail . ')');
127
		}
128
129
		try {
130
			$message = $this->mailer->createMessage();
131
			$message->setTo([$toEmail => $toDisplayName]);
132
			$message->useTemplate($emailTemplate);
133
			$this->mailer->send($message);
134
135
			return null;
136
137
		} catch (\Exception $e) {
138
			$this->logger->logException($e, ['app' => 'polls']);
139
			throw $e;
140
		}
141
142
	}
143
144
	/**
145
	 * @param Share $share
146
	 * @param String $defaultLang
147
	 * @param String $skipUser
148
	 * @return Array $recipients
149
	 */
150
	private function getRecipientsByShare($share, $defaultLang = 'en', $skipUser = null) {
151
		$recipients = [];
152
		$contactsManager = \OC::$server->getContactsManager();
153
154
		if ($share->getType() === 'user') {
155
			// $this->logger->debug('User share ' . json_encode($share));
156
157
			$recipients[] = array(
158
				'userId' => $share->getUserId(),
159
				'eMailAddress' => null,
160
				'displayName' => null,
161
				'language' => $this->config->getUserValue(
162
					$share->getUserId(),
163
					'core', 'lang'
164
				),
165
				'link' => $this->urlGenerator->getAbsoluteURL(
166
					$this->urlGenerator->linkToRoute(
167
						'polls.page.indexvote',
168
						array('id' => $share->getPollId())
169
					)
170
				)
171
			);
172
173
		} elseif ($share->getType() === 'email') {
174
			// $this->logger->debug('User share ' . json_encode($share));
175
176
			$recipients[] = array(
177
				'userId' => $share->getUserEmail(),
178
				'eMailAddress' => $share->getUserEmail(),
179
				'displayName' => $share->getUserEmail(),
180
				'language' => $defaultLang,
181
				'link' => $this->urlGenerator->getAbsoluteURL(
182
					$this->urlGenerator->linkToRoute(
183
						'polls.page.vote_publicpublic',
184
						array('token' => $share->getToken())
185
					)
186
				)
187
			);
188
189
		} elseif ($share->getType() === 'contact') {
190
			// $this->logger->debug('Contact share ' . json_encode($share));
191
			$contacts = $contactsManager->search($share->getUserId(), array('FN'));
192
			if (is_array($contacts)) {
193
				$contact = $contacts[0];
194
195
				$recipients[] = array(
196
					'userId' => $share->getUserId(),
197
					'eMailAddress' => $contact['EMAIL'][0],
198
					'displayName' => $contact['FN'],
199
					'language' => $defaultLang,
200
					'link' => $this->urlGenerator->getAbsoluteURL(
201
						$this->urlGenerator->linkToRoute(
202
							'polls.page.vote_publicpublic',
203
							array('token' => $share->getToken())
204
						)
205
					)
206
				);
207
			} else {
208
				return;
209
			}
210
211
		} elseif ($share->getType() === 'external' || $share->getType() === 'email') {
212
			// $this->logger->debug('External share ' . json_encode($share));
213
214
			$recipients[] = array(
215
				'userId' => $share->getUserId(),
216
				'eMailAddress' => $share->getUserEmail(),
217
				'displayName' => $share->getUserId(),
218
				'language' => $defaultLang,
219
				'link' => $this->urlGenerator->getAbsoluteURL(
220
					$this->urlGenerator->linkToRoute(
221
						'polls.page.vote_publicpublic',
222
						array('token' => $share->getToken())
223
					)
224
				)
225
			);
226
227
		} elseif ($share->getType() === 'group') {
228
			// $this->logger->debug('Group share ' . json_encode($share));
229
230
			$groupMembers = array_keys($this->groupManager->displayNamesInGroup($share->getUserId()));
231
			// $this->logger->debug('Members are ' . json_encode($groupMembers));
232
233
			foreach ($groupMembers as $member) {
234
				if ($skipUser === $member) {
235
					// $this->logger->debug('skip ' . $skipUser);
236
					continue;
237
				}
238
				// $this->logger->debug('add ' . $member);
239
240
				$recipients[] = array(
241
					'userId' => $member,
242
					'eMailAddress' => null,
243
					'displayName' => null,
244
					'language' => $this->config->getUserValue($share->getUserId(), 'core', 'lang'),
245
					'link' => $this->urlGenerator->getAbsoluteURL(
246
						$this->urlGenerator->linkToRoute(
247
							'polls.page.indexvote', ['id' => $share->getPollId()]
248
						)
249
					)
250
				);
251
252
			}
253
		}
254
		// $this->logger->debug('Recipients: ' . json_encode($recipients));
255
256
		return $recipients;
257
	}
258
259
	/**
260
	 * @param string $token
261
	 */
262
	public function sendInvitationMail($token) {
263
264
		$share = $this->shareMapper->findByToken($token);
265
		$poll = $this->pollMapper->find($share->getPollId());
266
		$owner = $this->userManager->get($poll->getOwner());
267
		$sentMails = [];
268
		$abortedMails = [];
269
		// $this->logger->debug('Search users for token ' . $token);
270
		$recipients = $this->getRecipientsByShare(
271
			$this->shareMapper->findByToken($token),
272
			$this->config->getUserValue($poll->getOwner(), 'core', 'lang'),
273
			$poll->getOwner()
274
		);
275
276
		// $this->logger->debug('Found these recipients: ' . json_encode($recipients));
277
		foreach ($recipients as $recipient) {
278
			$trans = $this->transFactory->get('polls', $recipient['language']);
279
280
			// $this->logger->debug('Build eMailTemplate for  ' . $recipient['userId']);
281
282
			$emailTemplate = $this->mailer->createEMailTemplate('polls.Invitation', [
283
				'owner' => $owner->getDisplayName(),
284
				'title' => $poll->getTitle(),
285
				'link' => $recipient['link']
286
			]);
287
288
			$emailTemplate->setSubject($trans->t('Poll invitation "%s"', $poll->getTitle()));
289
			$emailTemplate->addHeader();
290
			$emailTemplate->addHeading($trans->t('Poll invitation "%s"', $poll->getTitle()), false);
291
292
			$emailTemplate->addBodyText(str_replace(
293
				['{owner}', '{title}'],
294
				[$owner->getDisplayName(), $poll->getTitle()],
295
				$trans->t('{owner} invited you to take part in the poll "{title}"')
296
			));
297
298
			$emailTemplate->addBodyButton(
299
				htmlspecialchars($trans->t('Go to poll')),
300
				$recipient['link']
301
			);
302
303
			$emailTemplate->addFooter($trans->t('This email is sent to you, because you are invited to vote in this poll by the poll owner.'));
304
305
			try {
306
				// $this->logger->debug('Send Mail to ' . $recipient);
307
308
				$this->sendMail(
309
					$emailTemplate,
310
					$recipient['userId'],
311
					$recipient['eMailAddress'],
312
					$recipient['displayName']
313
				);
314
				$sentMails[] = $recipient;
315
			} catch (Exception $e) {
316
				$abortedMails[] = $recipient;
317
				$this->logger->alert('Error sending Mail to ' . json_encode($recipient));
318
			}
319
		}
320
		return ['sentMails' => $sentMails, 'abortedMails' => $abortedMails];
321
	}
322
323
	public function sendNotifications() {
324
		$subscriptions = [];
325
		$log = $this->logMapper->findUnprocessedPolls();
326
327
		foreach ($log as $logItem) {
328
			$subscriptions = array_merge($subscriptions, $this->subscriptionMapper->findAllByPoll($logItem->getPollId()));
329
		}
330
331
		$log = $this->logMapper->findUnprocessed();
332
333
		foreach ($subscriptions as $subscription) {
334
335
			if ($this->userManager->get($subscription->getUserId()) instanceof IUser) {
336
				$lang = $this->config->getUserValue($subscription->getUserId(), 'core', 'lang');
337
			} else {
338
				continue;
339
			}
340
341
			$poll = $this->pollMapper->find($subscription->getPollId());
342
			$trans = $this->transFactory->get('polls', $lang);
343
344
			$url = $this->urlGenerator->getAbsoluteURL(
345
				$this->urlGenerator->linkToRoute(
346
					'polls.page.indexvote',
347
					array('id' => $subscription->getPollId())
348
				)
349
			);
350
351
			$emailTemplate = $this->mailer->createEMailTemplate('polls.Invitation', [
352
				'title' => $poll->getTitle(),
353
				'link' => $url
354
			]);
355
			$emailTemplate->setSubject($trans->t('Polls App - New Activity'));
356
			$emailTemplate->addHeader();
357
			$emailTemplate->addHeading($trans->t('Polls App - New Activity'), false);
358
			$emailTemplate->addBodyText(str_replace(
359
				['{title}'],
360
				[$poll->getTitle()],
361
				$trans->t('"{title}" had recent activity: ')
362
			));
363
364
			foreach ($log as $logItem) {
365
				if ($logItem->getPollId() === $subscription->getPollId()) {
366
367
					if ($this->userManager->get($logItem->getUserId()) instanceof IUser) {
368
						$displayUser = $this->userManager->get($logItem->getUserId())->getDisplayName();
369
					} else {
370
						$displayUser = $logItem->getUserId();
371
					}
372
373
					if ($logItem->getMessage()) {
374
						$emailTemplate->addBodyText($logItem->getMessage());
375
376
					} elseif ($logItem->getMessageId() === 'setVote') {
377
						$emailTemplate->addBodyText($trans->t(
378
							'- %s voted.',
379
							array($displayUser)
380
						));
381
382
					} elseif ($logItem->getMessageId() === 'updatePoll') {
383
						$emailTemplate->addBodyText($trans->t(
384
							'- %s updated the poll configuration. Please check your votes.',
385
							array($displayUser)
386
						));
387
388
					} elseif ($logItem->getMessageId() === 'deletePoll') {
389
						$emailTemplate->addBodyText($trans->t(
390
							'- %s deleted the poll.',
391
							array($displayUser)
392
						));
393
394
					} elseif ($logItem->getMessageId() === 'restorePoll') {
395
						$emailTemplate->addBodyText($trans->t(
396
							'- %s restored the poll.',
397
							array($displayUser)
398
						));
399
400
					} elseif ($logItem->getMessageId() === 'expirePoll') {
401
						$emailTemplate->addBodyText($trans->t(
402
							'- The poll expired.',
403
							array($displayUser)
404
						));
405
406
					} elseif ($logItem->getMessageId() === 'addOption') {
407
						$emailTemplate->addBodyText($trans->t(
408
							'- %s added a vote option.',
409
							array($displayUser)
410
						));
411
412
					} elseif ($logItem->getMessageId() === 'deleteOption') {
413
						$emailTemplate->addBodyText($trans->t(
414
							'- %s removed a vote option.',
415
							array($displayUser)
416
						));
417
418
					} else {
419
						$emailTemplate->addBodyText(
420
							$logItem->getMessageId() . " (" . $displayUser . ")"
421
						);
422
					}
423
				}
424
425
				$logItem->setProcessed(time());
426
				$this->logMapper->update($logItem);
427
			}
428
429
			$emailTemplate->addBodyButton(
430
				htmlspecialchars($trans->t('Go to poll')),
431
				$url,
432
				/** @scrutinizer ignore-type */ false
433
			);
434
			$emailTemplate->addFooter($trans->t('This email is sent to you, because you subscribed to notifications of this poll. To opt out, visit the poll and remove your subscription.'));
435
436
			try {
437
				$this->sendMail($emailTemplate, $subscription->getUserId());
438
			} catch (Exception $e) {
439
				$this->logger->alert('Error sending Mail to ' . $subscription->getUserId());
440
				// TODO: alert Owner
441
			}
442
		}
443
	}
444
}
445