3 namespace wcf\system\worker
;
5 use wcf\data\user\User
;
6 use wcf\system\background\BackgroundQueueHandler
;
7 use wcf\system\clipboard\ClipboardHandler
;
8 use wcf\system\database\util\PreparedStatementConditionBuilder
;
9 use wcf\system\email\Email
;
10 use wcf\system\email\Mailbox
;
11 use wcf\system\email\mime\MimePartFacade
;
12 use wcf\system\email\mime\RecipientAwareTextMimePart
;
13 use wcf\system\email\UserMailbox
;
14 use wcf\system\exception\SystemException
;
15 use wcf\system\request\LinkHandler
;
19 * Worker implementation for sending mails.
21 * @author Alexander Ebert
22 * @copyright 2001-2019 WoltLab GmbH
23 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
25 class MailWorker
extends AbstractWorker
28 * condition builder object
29 * @var PreparedStatementConditionBuilder
31 protected $conditions;
36 protected $limit = 50;
47 public function validate()
49 WCF
::getSession()->checkPermissions(['admin.user.canMailUser']);
51 if (!isset($this->parameters
['mailID'])) {
52 throw new SystemException("mailID missing");
55 $userMailData = WCF
::getSession()->getVar('userMailData');
56 if (!isset($userMailData[$this->parameters
['mailID']])) {
57 throw new SystemException("mailID '" . $this->parameters
['mailID'] . "' is invalid");
60 $this->mailData
= $userMailData[$this->parameters
['mailID']];
61 if (!isset($this->mailData
['message-id'])) {
62 $this->mailData
['message-id'] = \
sprintf(
63 'com.woltlab.wcf.mailWorker/%d/%s',
65 \bin
2hex
(\random_bytes
(8))
67 $userMailData[$this->parameters
['mailID']] = $this->mailData
;
68 WCF
::getSession()->register('userMailData', $userMailData);
75 public function countObjects()
77 $this->conditions
= new PreparedStatementConditionBuilder();
78 if ($this->mailData
['action'] == '') {
79 $this->conditions
->add("user.userID IN (?)", [$this->mailData
['userIDs']]);
81 $this->conditions
->add("user.emailConfirmed IS NULL");
82 $this->conditions
->add("user.banned = ?", [0]);
84 if ($this->mailData
['action'] == 'group') {
85 $this->conditions
->add(
88 FROM wcf" . WCF_N
. "_user_to_group
91 [$this->mailData
['groupIDs']]
96 $sql = "SELECT COUNT(*)
97 FROM wcf" . WCF_N
. "_user user
98 " . $this->conditions
;
99 $statement = WCF
::getDB()->prepareStatement($sql);
100 $statement->execute($this->conditions
->getParameters());
102 $this->count
= $statement->fetchSingleColumn();
108 public function getProgress()
110 $progress = parent
::getProgress();
112 if ($progress == 100) {
114 $typeID = ClipboardHandler
::getInstance()->getObjectTypeID('com.woltlab.wcf.user');
115 ClipboardHandler
::getInstance()->removeItems($typeID);
118 $userMailData = WCF
::getSession()->getVar('userMailData');
119 unset($userMailData[$this->parameters
['mailID']]);
120 WCF
::getSession()->register('userMailData', $userMailData);
129 public function execute()
131 $email = new Email();
132 $email->setMessageID($this->mailData
['message-id']);
133 $email->setSubject($this->mailData
['subject']);
135 $this->mailData
['from'],
136 (!empty($this->mailData
['fromName']) ?
$this->mailData
['fromName'] : null)
138 $email->setSender($from);
139 $email->setReplyTo($from);
141 'text' => $this->mailData
['text'],
142 'enableHTML' => $this->mailData
['enableHTML'] ?
true : false,
144 if ($this->mailData
['enableHTML']) {
145 $email->setBody(new RecipientAwareTextMimePart('text/html', 'email_mailWorker', 'wcf', $variables));
147 $email->setBody(new MimePartFacade([
148 new RecipientAwareTextMimePart('text/html', 'email_mailWorker', 'wcf', $variables),
149 new RecipientAwareTextMimePart('text/plain', 'email_mailWorker', 'wcf', $variables),
154 $sql = "SELECT user_option.*, user.*
155 FROM wcf" . WCF_N
. "_user user
156 LEFT JOIN wcf" . WCF_N
. "_user_option_value user_option
157 ON user_option.userID = user.userID
158 " . $this->conditions
. "
159 ORDER BY user.userID";
160 $statement = WCF
::getDB()->prepareStatement($sql, $this->limit
, $this->limit
* $this->loopCount
);
161 $statement->execute($this->conditions
->getParameters());
162 while ($row = $statement->fetchArray()) {
163 $user = new User(null, $row);
164 $adminCanMail = $user->adminCanMail
;
165 if ($adminCanMail === null ||
$adminCanMail) {
166 $this->sendMail($email, $user);
172 * Sends the given blueprint (Email without recipients) to the given user.
174 * @param Email $blueprint
177 protected function sendMail(Email
$blueprint, User
$user)
179 $email = clone $blueprint;
180 $email->addRecipient(new UserMailbox($user));
181 $jobs = $email->getJobs();
182 foreach ($jobs as $job) {
183 BackgroundQueueHandler
::getInstance()->performJob($job);
190 public function getProceedURL()
192 return LinkHandler
::getInstance()->getLink('UserList');