/system/vendor/swift/Swift/BatchMailer.php
PHP | 229 lines | 123 code | 4 blank | 102 comment | 7 complexity | 22cd85e332e1775130c1106b05c2bf4d MD5 | raw file
Possible License(s): LGPL-2.1
- <?php
- /**
- * Handles batch mailing with Swift Mailer with fail-safe support.
- * Restarts the connection if it dies and then continues where it left off.
- * Please read the LICENSE file
- * @copyright Chris Corbyn <chris@w3style.co.uk>
- * @author Chris Corbyn <chris@w3style.co.uk>
- * @package Swift
- * @license GNU Lesser General Public License
- */
- class Swift_BatchMailer
- {
- /**
- * The current instance of Swift.
- * @var Swift
- */
- protected $swift;
- /**
- * The maximum number of times a single recipient can be attempted before giving up.
- * @var int
- */
- protected $maxTries = 2;
- /**
- * The number of seconds to sleep for if an error occurs.
- * @var int
- */
- protected $sleepTime = 0;
- /**
- * Failed recipients (undeliverable)
- * @var array
- */
- protected $failed = array();
- /**
- * The maximum number of successive failures before giving up.
- * @var int
- */
- protected $maxFails = 0;
- /**
- * A temporary copy of some message headers.
- * @var array
- */
- protected $headers = array();
-
- /**
- * Constructor.
- * @param Swift The current instance of Swift
- */
- public function __construct(Swift $swift)
- {
- $this->setSwift($swift);
- }
- /**
- * Set the current Swift instance.
- * @param Swift The instance
- */
- public function setSwift(Swift $swift)
- {
- $this->swift = $swift;
- }
- /**
- * Get the Swift instance which is running.
- * @return Swift
- */
- public function getSwift()
- {
- return $this->swift;
- }
- /**
- * Set the maximum number of times a single address is allowed to be retried.
- * @param int The maximum number of tries.
- */
- public function setMaxTries($max)
- {
- $this->maxTries = abs($max);
- }
- /**
- * Get the number of times a single address will be attempted in a batch.
- * @return int
- */
- public function getMaxTries()
- {
- return $this->maxTries;
- }
- /**
- * Set the amount of time to sleep for if an error occurs.
- * @param int Number of seconds
- */
- public function setSleepTime($secs)
- {
- $this->sleepTime = abs($secs);
- }
- /**
- * Get the amount of time to sleep for on errors.
- * @return int
- */
- public function getSleepTime()
- {
- return $this->sleepTime;
- }
- /**
- * Log a failed recipient.
- * @param string The email address.
- */
- public function addFailedRecipient($address)
- {
- $this->failed[] = $address;
- $this->failed = array_unique($this->failed);
- }
- /**
- * Get all recipients which failed in this batch.
- * @return array
- */
- public function getFailedRecipients()
- {
- return $this->failed;
- }
- /**
- * Clear out the list of failed recipients.
- */
- public function flushFailedRecipients()
- {
- $this->failed = null;
- $this->failed = array();
- }
- /**
- * Set the maximum number of times an error can be thrown in succession and still be hidden.
- * @param int
- */
- public function setMaxSuccessiveFailures($fails)
- {
- $this->maxFails = abs($fails);
- }
- /**
- * Get the maximum number of times an error can be thrown and still be hidden.
- * @return int
- */
- public function getMaxSuccessiveFailures()
- {
- return $this->maxFails;
- }
- /**
- * Restarts Swift forcibly.
- */
- protected function forceRestartSwift()
- {
- //Pre-empting problems trying to issue "QUIT" to a dead connection
- $this->swift->connection->stop();
- $this->swift->connection->start();
- $this->swift->disconnect();
- //Restart swift
- $this->swift->connect();
- }
- /**
- * Takes a temporary copy of original message headers in case an error occurs and they need restoring.
- * @param Swift_Message The message object
- */
- protected function copyMessageHeaders(&$message)
- {
- $this->headers["To"] = $message->headers->has("To") ?
- $message->headers->get("To") : null;
- $this->headers["Reply-To"] = $message->headers->has("Reply-To") ?
- $message->headers->get("Reply-To") : null;
- $this->headers["Return-Path"] = $message->headers->has("Return-Path") ?
- $message->headers->get("Return-Path") : null;
- $this->headers["From"] = $message->headers->has("From") ?
- $message->headers->get("From") : null;
- }
- /**
- * Restore message headers to original values in the event of a failure.
- * @param Swift_Message The message
- */
- protected function restoreMessageHeaders(&$message)
- {
- foreach ($this->headers as $name => $value)
- {
- $message->headers->set($name, $value);
- }
- }
- /**
- * Run a batch send in a fail-safe manner.
- * This operates as Swift::batchSend() except it deals with errors itself.
- * @param Swift_Message To send
- * @param Swift_RecipientList Recipients (To: only)
- * @param Swift_Address The sender's address
- * @return int The number sent to
- */
- public function send(Swift_Message $message, Swift_RecipientList $recipients, $sender)
- {
- $sent = 0;
- $successive_fails = 0;
-
- $it = $recipients->getIterator("to");
- while ($it->hasNext())
- {
- $it->next();
- $recipient = $it->getValue();
- $tried = 0;
- $loop = true;
- while ($loop && $tried < $this->getMaxTries())
- {
- try {
- $tried++;
- $loop = false;
- $this->copyMessageHeaders($message);
- $sent += ($n = $this->swift->send($message, $recipient, $sender));
- if (!$n) $this->addFailedRecipient($recipient->getAddress());
- $successive_fails = 0;
- } catch (Exception $e) {
- $successive_fails++;
- $this->restoreMessageHeaders($message);
- if (($max = $this->getMaxSuccessiveFailures())
- && $successive_fails > $max)
- {
- throw new Exception(
- "Too many successive failures. BatchMailer is configured to allow no more than " . $max .
- " successive failures.");
- }
- //If an exception was thrown, give it one more go
- if ($t = $this->getSleepTime()) sleep($t);
- $this->forceRestartSwift();
- $loop = true;
- }
- }
- }
-
- return $sent;
- }
- }