/** * Send a Notification to a user by email * * @param $user User to notify. * @param $event EchoEvent to notify about. * @return bool */ public static function notifyWithEmail($user, $event) { // No valid email address or email notification if (!$user->isEmailConfirmed() || $user->getOption('echo-email-frequency') < 0) { return false; } // Final check on whether to send email for this user & event if (!wfRunHooks('EchoAbortEmailNotification', array($user, $event))) { return false; } // See if the user wants to receive emails for this category or the user is eligible to receive this email if (in_array($event->getType(), EchoNotificationController::getUserEnabledEvents($user, 'email'))) { global $wgEchoEnableEmailBatch, $wgEchoNotifications, $wgNotificationSender, $wgNotificationSenderName, $wgNotificationReplyName, $wgEchoBundleEmailInterval; $priority = EchoNotificationController::getNotificationPriority($event->getType()); $bundleString = $bundleHash = ''; // We should have bundling for email digest as long as either web or email bundling is on, for example, talk page // email bundling is off, but if a user decides to receive email digest, we should bundle those messages if (!empty($wgEchoNotifications[$event->getType()]['bundle']['web']) || !empty($wgEchoNotifications[$event->getType()]['bundle']['email'])) { wfRunHooks('EchoGetBundleRules', array($event, &$bundleString)); } if ($bundleString) { $bundleHash = md5($bundleString); } MWEchoEventLogging::logSchemaEcho($user, $event, 'email'); // email digest notification ( weekly or daily ) if ($wgEchoEnableEmailBatch && $user->getOption('echo-email-frequency') > 0) { // always create a unique event hash for those events don't support bundling // this is mainly for group by if (!$bundleHash) { $bundleHash = md5($event->getType() . '-' . $event->getId()); } MWEchoEmailBatch::addToQueue($user->getId(), $event->getId(), $priority, $bundleHash); return true; } $addedToQueue = false; // only send bundle email if email bundling is on if ($wgEchoBundleEmailInterval && $bundleHash && !empty($wgEchoNotifications[$event->getType()]['bundle']['email'])) { $bundler = MWEchoEmailBundler::newFromUserHash($user, $bundleHash); if ($bundler) { $addedToQueue = $bundler->addToEmailBatch($event->getId(), $priority); } } // send single notification if the email wasn't added to queue for bundling if (!$addedToQueue) { // instant email notification $toAddress = new MailAddress($user); $fromAddress = new MailAddress($wgNotificationSender, $wgNotificationSenderName); $replyAddress = new MailAddress($wgNotificationSender, $wgNotificationReplyName); // Since we are sending a single email, should set the bundle hash to null // if it is set with a value from somewhere else $event->setBundleHash(null); $email = EchoNotificationController::formatNotification($event, $user, 'email', 'email'); $subject = $email['subject']; $body = $email['body']; UserMailer::send($toAddress, $fromAddress, $subject, $body, $replyAddress); MWEchoEventLogging::logSchemaEchoMail($user, 'single'); } } return true; }
public function execute() { global $wgEchoCluster; $this->output("Started processing... \n"); $startUserId = 0; $count = $this->batchSize; while ($count === $this->batchSize) { $count = 0; $res = MWEchoEmailBatch::getUsersToNotify($startUserId, $this->batchSize); $updated = false; foreach ($res as $row) { $userId = intval($row->eeb_user_id); if ($userId && $userId > $startUserId) { $emailBatch = MWEchoEmailBatch::newFromUserId($userId); if ($emailBatch) { $this->output("processing user_Id " . $userId . " \n"); $emailBatch->process(); } $startUserId = $userId; $updated = true; } $count++; } wfWaitForSlaves(false, false, $wgEchoCluster); // This is required since we are updating user properties in main wikidb wfWaitForSlaves(); // double check to make sure that the id is updated if (!$updated) { break; } } $this->output("Completed \n"); }
/** * Check if a new notification should be added to the batch queue * true - added to the queue for bundling email * false - not added, the client should send single email * @return bool */ public function addToEmailBatch($eventId, $eventPriority) { $this->retrieveLastEmailTimestamp(); $this->retrieveBaseEvent(); // send instant single notification email if there is no base event in the batch queue // and the email is ready to send, otherwiase, add the email to batch and schedule // a delayed job if (!$this->baseEvent && $this->shouldSendEmailNow()) { $this->timestamp = wfTimestampNow(); $this->updateEmailMetadata(); return false; } else { // add to email batch queue MWEchoEmailBatch::addToQueue($this->mUser->getId(), $eventId, $eventPriority, $this->bundleHash); // always push the job to job queue in case the previous job // was lost, job queue will ignore duplicate $this->pushToJobQueue($this->getDelayTime()); return true; } }