freenetis-github/system/vendor/swift/Swift/BatchMailer.php @ 45d52e19
8baed187 | Michal Kliment | <?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;
|
|||
}
|
|||
}
|