Completed
Pull Request — master (#129)
by Jan-Christoph
52:33 queued 50:39
created

EmailNotification   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 100
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 94.74%

Importance

Changes 0
Metric Value
wmc 11
lcom 1
cbo 1
dl 0
loc 100
ccs 36
cts 38
cp 0.9474
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 12 1
A run() 0 17 3
C runStep() 0 39 7
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Joas Schilling <[email protected]>
6
 * @author Morris Jobke <[email protected]>
7
 *
8
 * @license AGPL-3.0
9
 *
10
 * This code is free software: you can redistribute it and/or modify
11
 * it under the terms of the GNU Affero General Public License, version 3,
12
 * as published by the Free Software Foundation.
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, version 3,
20
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
21
 *
22
 */
23
24
namespace OCA\Activity\BackgroundJob;
25
26
use OC\BackgroundJob\TimedJob;
27
use OCA\Activity\MailQueueHandler;
28
use OCP\IConfig;
29
use OCP\ILogger;
30
31
/**
32
 * Class EmailNotification
33
 *
34
 * @package OCA\Activity\BackgroundJob
35
 */
36
class EmailNotification extends TimedJob {
37
	const CLI_EMAIL_BATCH_SIZE = 500;
38
	const WEB_EMAIL_BATCH_SIZE = 25;
39
40
	/** @var MailQueueHandler */
41
	protected $mqHandler;
42
43
	/** @var IConfig */
44
	protected $config;
45
46
	/** @var ILogger */
47
	protected $logger;
48
49
	/** @var bool */
50
	protected $isCLI;
51
52
	/**
53
	 * @param MailQueueHandler $mailQueueHandler
54
	 * @param IConfig $config
55
	 * @param ILogger $logger
56
	 * @param bool $isCLI
57
	 */
58 5
	public function __construct(MailQueueHandler $mailQueueHandler,
59
								IConfig $config,
60
								ILogger $logger,
61
								$isCLI) {
62
		// Run all 15 Minutes
63 5
		$this->setInterval(15 * 60);
64
65 5
		$this->mqHandler = $mailQueueHandler;
66 5
		$this->config = $config;
67 5
		$this->logger = $logger;
68 5
		$this->isCLI = $isCLI;
69 5
	}
70
71 2
	protected function run($argument) {
72
		// We don't use time() but "time() - 1" here, so we don't run into
73
		// runtime issues later and delete emails, which were created in the
74
		// same second, but were not collected for the emails.
75 2
		$sendTime = time() - 1;
76
77 2
		if ($this->isCLI) {
78
			do {
79
				// If we are in CLI mode, we keep sending emails
80
				// until we are done.
81 1
				$emails_sent = $this->runStep(self::CLI_EMAIL_BATCH_SIZE, $sendTime);
82 1
			} while ($emails_sent === self::CLI_EMAIL_BATCH_SIZE);
83 1
		} else {
84
			// Only send 25 Emails in one go for web cron
85 1
			$this->runStep(self::WEB_EMAIL_BATCH_SIZE, $sendTime);
86
		}
87 2
	}
88
89
	/**
90
	 * Send an email to {$limit} users
91
	 *
92
	 * @param int $limit Number of users we want to send an email to
93
	 * @param int $sendTime The latest send time
94
	 * @return int Number of users we sent an email to
95
	 */
96 3
	protected function runStep($limit, $sendTime) {
97
		// Get all users which should receive an email
98 3
		$affectedUsers = $this->mqHandler->getAffectedUsers($limit, $sendTime);
99 3
		if (empty($affectedUsers)) {
100
			// No users found to notify, mission abort
101 2
			return 0;
102
		}
103
104 1
		$userLanguages = $this->config->getUserValueForUsers('core', 'lang', $affectedUsers);
105 1
		$userTimezones = $this->config->getUserValueForUsers('core', 'timezone', $affectedUsers);
106 1
		$userEmails = $this->config->getUserValueForUsers('settings', 'email', $affectedUsers);
107
108
		// Send Email
109 1
		$default_lang = $this->config->getSystemValue('default_language', 'en');
110 1
		$defaultTimeZone = date_default_timezone_get();
111
112 1
		$deleteItemsForUsers = [];
113 1
		foreach ($affectedUsers as $user) {
114 1
			if (empty($userEmails[$user])) {
115
				// The user did not setup an email address
116
				// So we will not send an email :(
117 1
				$this->logger->debug("Couldn't send notification email to user '" . $user . "' (email address isn't set for that user)", ['app' => 'activity']);
118 1
				continue;
119
			}
120
121 1
			$language = (!empty($userLanguages[$user])) ? $userLanguages[$user] : $default_lang;
122 1
			$timezone = (!empty($userTimezones[$user])) ? $userTimezones[$user] : $defaultTimeZone;
123 1
			if ($this->mqHandler->sendEmailToUser($user, $userEmails[$user], $language, $timezone, $sendTime)) {
124
				$deleteItemsForUsers[] = $user;
125
			} else {
126 1
				$this->logger->debug("Failed sending activity mail to user '" . $user . "'.", ['app' => 'activity']);
127
			}
128 1
		}
129
130
		// Delete all entries we dealt with
131 1
		$this->mqHandler->deleteSentItems($deleteItemsForUsers, $sendTime);
132
133 1
		return sizeof($affectedUsers);
134
	}
135
}
136