Completed
Push — master ( d62417...7b2aa5 )
by René
10:14 queued 11s
created

MailService::sendInvitationMail()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 47
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 3
eloc 32
nc 3
nop 1
dl 0
loc 47
ccs 0
cts 38
cp 0
crap 12
rs 9.408
c 2
b 0
f 0
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 OCP\IUser;
27
use OCP\IUserManager;
28
use OCP\IGroupManager;
29
use OCP\IConfig;
30
use OCP\IURLGenerator;
31
use OCP\IL10N;
32
use OCP\L10N\IFactory;
33
use OCP\Mail\IMailer;
34
use OCP\ILogger;
35
36
use OCA\Polls\Db\SubscriptionMapper;
37
use OCA\Polls\Db\Subscription;
38
use OCA\Polls\Db\EventMapper;
39
use OCA\Polls\Db\Event;
40
use OCA\Polls\Db\ShareMapper;
41
use OCA\Polls\Db\Share;
42
use OCA\Polls\Db\LogMapper;
43
44
class MailService  {
45
46
	private $userManager;
47
	private $groupManager;
48
	private $config;
49
	private $urlGenerator;
50
	private $trans;
51
	private $transFactory;
52
	private $mailer;
53
	private $logger;
54
55
	private $shareMapper;
56
	private $subscriptionMapper;
57
	private $eventMapper;
58
	private $logMapper;
59
60
	/**
61
	 * MailService constructor.
62
	 * @param IUserManager $userManager
63
	 * @param IGroupManager $groupManager
64
	 * @param IConfig $config
65
	 * @param IURLGenerator $urlGenerator
66
	 * @param IL10N $trans
67
	 * @param IFactory $transFactory
68
	 * @param IMailer $mailer
69
	 * @param ILogger $logger
70
	 * @param SubscriptionMapper $subscriptionMapper
71
	 * @param ShareMapper $shareMapper
72
	 * @param EventMapper $eventMapper
73
	 * @param LogMapper $logMapper
74
	 */
75
76
	public function __construct(
77
		IUserManager $userManager,
78
		IGroupManager $groupManager,
79
		IConfig $config,
80
		IURLGenerator $urlGenerator,
81
		IL10N $trans,
82
		IFactory $transFactory,
83
		IMailer $mailer,
84
		ILogger $logger,
85
		ShareMapper $shareMapper,
86
		SubscriptionMapper $subscriptionMapper,
87
		EventMapper $eventMapper,
88
		LogMapper $logMapper
89
	) {
90
		$this->config = $config;
91
		$this->userManager = $userManager;
92
		$this->groupManager = $groupManager;
93
		$this->urlGenerator = $urlGenerator;
94
		$this->trans = $trans;
95
		$this->transFactory = $transFactory;
96
		$this->mailer = $mailer;
97
		$this->logger = $logger;
98
		$this->shareMapper = $shareMapper;
99
		$this->subscriptionMapper = $subscriptionMapper;
100
		$this->eventMapper = $eventMapper;
101
		$this->logMapper = $logMapper;
102
	}
103
104
105
	/**
106
	 * sendMail - Send eMail and evaluate recipient's mail address
107
	 * and displayname if $toUserId is a site user
108
	 * @param IEmailTemplate $emailTemplate
0 ignored issues
show
Bug introduced by
The type OCA\Polls\Service\IEmailTemplate was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
109
	 * @param String $toUserId
110
	 * @param String $toEmail
111
	 * @param String $toDisplayName
112
	 * @return Bool
113
	 */
114
115
	private function sendMail($emailTemplate, $toUserId = '', $toEmail = '', $toDisplayName = '') {
116
117
		if ($this->userManager->get($toUserId) instanceof IUser && !$toEmail) {
118
			$toEmail = \OC::$server->getConfig()->getUserValue($toUserId, 'settings', 'email');
119
			$toDisplayName = $this->userManager->get($toUserId)->getDisplayName();
120
		}
121
122
		if (!$toEmail || !filter_var($toEmail, FILTER_VALIDATE_EMAIL)) {
123
       		throw new Exception( 'Invalid email address (' . $toEmail .')' );
0 ignored issues
show
Bug introduced by
The type OCA\Polls\Service\Exception was not found. Did you mean Exception? If so, make sure to prefix the type with \.
Loading history...
124
		}
125
126
		try {
127
			$message = $this->mailer->createMessage();
128
			$message->setTo([$toEmail => $toDisplayName]);
129
			$message->useTemplate($emailTemplate);
130
			$this->mailer->send($message);
131
		} catch (\Exception $e) {
132
			$this->logger->logException($e, ['app' => 'polls']);
133
			throw $e;
134
		}
135
136
	}
137
138
	/**
139
	 * @param Share $share
140
	 * @param String $defaultLang
141
	 * @param String $skipUser
142
	 * @return Array $recipients
143
	 */
144
	private function getRecipientsByShare($share, $defaultLang = 'en', $skipUser = null) {
145
		$recipients = [];
146
		$contactsManager = \OC::$server->getContactsManager();
147
148
		if ($share->getType() === 'user') {
149
150
			$recipients[] = array(
151
				'userId' => $share->getUserId(),
152
				'email' => null,
153
				'displayName' => null,
154
				'language' => $this->config->getUserValue($share->getUserId(), 'core', 'lang'),
155
				'link' => $this->urlGenerator->getAbsoluteURL(
156
					$this->urlGenerator->linkToRoute(
157
						'polls.page.polls', array('pollId' => $share->getPollId())
158
					)
159
				)
160
			);
161
162
		} elseif ($share->getType() === 'contact') {
163
			$contacts = $contactsManager->search($share->getUserId(), array('UID'));
164
			if (is_array($contacts)) {
165
				$contact = $contacts[0];
166
167
				$recipients[] = array(
168
					'userId' => $share->getUserId(),
169
					'email' => $contact['EMAIL'][0],
170
					'displayName' => $contact['FN'],
171
					'language' => $defaultLang,
172
					'link' => $this->urlGenerator->getAbsoluteURL(
173
						$this->urlGenerator->linkToRoute(
174
							'polls.page.polls', array('pollId' => $share->getPollId())
175
						)
176
					)
177
				);
178
			} else {
179
				return;
180
			}
181
182
		} elseif ($share->getType() === 'external' || $share->getType() === 'mail') {
183
184
			$recipients[] = array(
185
				'userId' => $share->getUserId(),
186
				'email' => $share->getUserEmail(),
187
				'displayName' => $share->getUserId(),
188
				'language' => $defaultLang,
189
				'link' => $this->urlGenerator->getAbsoluteURL(
190
					$this->urlGenerator->linkToRoute(
191
						'polls.page.vote_public', array('token' => $share->getToken())
192
					)
193
				)
194
			);
195
196
		} elseif ($share->getType() === 'group') {
197
198
			$groupMembers = array_keys($this->groupManager->displayNamesInGroup($share->getUserId()));
199
200
			foreach ($groupMembers as $member) {
201
				if ($skipUser === $member) {
202
					continue;
203
				}
204
205
				$recipients[] = array(
206
					'userId' => $member,
207
					'email' => null,
208
					'displayName' => null,
209
					'language' => $this->config->getUserValue($share->getUserId(), 'core', 'lang'),
210
					'link' => $this->urlGenerator->getAbsoluteURL(
211
						$this->urlGenerator->linkToRoute(
212
							'polls.page.polls', array('pollId' => $share->getPollId())
213
						)
214
					)
215
				);
216
217
			}
218
		}
219
220
		return $recipients;
221
	}
222
223
	/**
224
	 * @param string $token
225
	 */
226
	public function sendInvitationMail($token) {
227
		$share = $this->shareMapper->findByToken($token);
228
		$event = $this->eventMapper->find($share->getPollId());
229
		$owner = $this->userManager->get($event->getOwner());
230
231
		$recipients = $this->getRecipientsByShare(
232
			$this->shareMapper->findByToken($token),
233
			$this->config->getUserValue($event->getOwner(), 'core', 'lang'),
234
			$event->getOwner()
235
		);
236
		$this->logger->debug(json_encode($recipients));
237
238
		foreach ($recipients as $recipient) {
239
240
			$trans = $this->transFactory->get('polls', $recipient['language']);
241
242
			$emailTemplate = $this->mailer->createEMailTemplate('polls.Invitation', [
243
				'owner' => $owner->getDisplayName(),
244
				'title' => $event->getTitle(),
245
				'link' => $recipient['link']
246
			]);
247
248
			$emailTemplate->setSubject($trans->t('Poll invitation "%s"', $event->getTitle()));
249
			$emailTemplate->addHeader();
250
			$emailTemplate->addHeading($trans->t('Poll invitation "%s"', $event->getTitle()), false);
251
252
			$emailTemplate->addBodyText(str_replace(
253
				['{owner}', '{title}'],
254
				[$owner->getDisplayName(), $event->getTitle()],
255
				$trans->t('{owner} invited you to take part in the poll "{title}"' )
256
			));
257
258
			$emailTemplate->addBodyButton(
259
				htmlspecialchars($trans->t('Go to poll')),
260
				$recipient['link']
261
			);
262
263
			$emailTemplate->addFooter($trans->t('This email is sent to you, because you are invited to vote in this poll by the poll owner.' ));
264
265
			try {
266
				$this->sendMail(
267
					$emailTemplate,
268
					$recipient['userId'],
269
					$recipient['email'],
270
					$recipient['displayName']
271
				);
272
			} catch (Exeption $e) {
0 ignored issues
show
Bug introduced by
The type OCA\Polls\Service\Exeption was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
273
				// todo alert Owner
274
				// Invitation to $recipient['userId'] could not be sent
275
			}
276
277
		}
278
	}
279
280
	/**
281
	 * @param int $pollId
282
	 * @param string $from
283
	 */
284
	public function sendNotice() {
285
		$this->logger->debug('sendNotice test');
286
	}
287
288
	public function sendNotifications() {
289
		$subscriptions = [];
290
		$log = $this->logMapper->findUnprocessedPolls();
291
292
		foreach ($log as $logItem) {
293
			$subscriptions = array_merge($subscriptions, $this->subscriptionMapper->findAllByPoll($logItem->getPollId()));
294
		}
295
296
		$log = $this->logMapper->findUnprocessed();
297
298
		foreach ($subscriptions as $subscription) {
299
300
			if ($this->userManager->get($subscription->getUserId()) instanceof IUser) {
301
				$lang = $this->config->getUserValue($subscription->getUserId(), 'core', 'lang');
302
			} else {
303
				continue;
304
			}
305
306
			$event = $this->eventMapper->find($subscription->getPollId());
307
			$trans = $this->transFactory->get('polls', $lang);
308
309
			$url = $this->urlGenerator->getAbsoluteURL(
310
				$this->urlGenerator->linkToRoute(
311
					'polls.page.polls',
312
					array('pollId' => $subscription->getPollId())
313
				)
314
			);
315
316
			$emailTemplate = $this->mailer->createEMailTemplate('polls.Invitation', [
317
				'title' => $event->getTitle(),
318
				'link' => $url
319
			]);
320
			$emailTemplate->setSubject($trans->t('Polls App - New Activity'));
321
			$emailTemplate->addHeader();
322
			$emailTemplate->addHeading($trans->t('Polls App - New Activity'), false);
323
			$emailTemplate->addBodyText(str_replace(
324
				['{title}'],
325
				[$event->getTitle()],
326
				$trans->t('"{title}" had recent activity: ')
327
			));
328
329
			foreach ($log as $logItem) {
330
				if ($logItem->getPollId() === $subscription->getPollId()) {
331
					if ($logItem->getMessage()) {
332
						$emailTemplate->addBodyText($logItem->getMessage());
333
					} elseif ($logItem->getMessageId() === 'setVote') {
334
						$emailTemplate->addBodyText($trans->t(
335
							'- %s voted.',
336
							array( $this->userManager->get($logItem->getUserId())->getDisplayName()))
337
					);
338
					} elseif ($logItem->getMessageId() === 'updatePoll') {
339
						$emailTemplate->addBodyText($trans->t(
340
							'- %s updated the poll configuration. Please check your votes.',
341
							array( $this->userManager->get($logItem->getUserId())->getDisplayName()))
342
						);
343
					} elseif ($logItem->getMessageId() === 'deletePoll') {
344
						$emailTemplate->addBodyText($trans->t(
345
							'- %s deleted the poll.',
346
							array( $this->userManager->get($logItem->getUserId())->getDisplayName()))
347
						);
348
					} elseif ($logItem->getMessageId() === 'restorePoll') {
349
						$emailTemplate->addBodyText($trans->t(
350
							'- %s restored the poll.',
351
							array( $this->userManager->get($logItem->getUserId())->getDisplayName()))
352
						);
353
					} elseif ($logItem->getMessageId() === 'expirePoll') {
354
						$emailTemplate->addBodyText($trans->t(
355
							'- The poll expired.',
356
							array( $this->userManager->get($logItem->getUserId())->getDisplayName()))
357
						);
358
					}
359
360
				}
361
362
				$logItem->setProcessed(time());
363
				$this->logMapper->update($logItem);
364
			}
365
366
			$emailTemplate->addBodyButton(
367
				htmlspecialchars($trans->t('Go to poll')),
368
				$url,
369
				/** @scrutinizer ignore-type */ false
370
			);
371
			$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.' ));
372
373
			try {
374
				$this->sendMail( $emailTemplate, $subscription->getUserId());
375
			} catch (Exeption $e) {
376
				// todo alert Owner
377
				// Notification to $subscription->getUserId() could not be sent
378
			}
379
		}
380
	}
381
}
382