first commit
This commit is contained in:
@ -0,0 +1,137 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Reduces network flooding when sending large amounts of mail.
|
||||
*
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_Plugins_AntiFloodPlugin implements Swift_Events_SendListener, Swift_Plugins_Sleeper
|
||||
{
|
||||
/**
|
||||
* The number of emails to send before restarting Transport.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $threshold;
|
||||
|
||||
/**
|
||||
* The number of seconds to sleep for during a restart.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $sleep;
|
||||
|
||||
/**
|
||||
* The internal counter.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $counter = 0;
|
||||
|
||||
/**
|
||||
* The Sleeper instance for sleeping.
|
||||
*
|
||||
* @var Swift_Plugins_Sleeper
|
||||
*/
|
||||
private $sleeper;
|
||||
|
||||
/**
|
||||
* Create a new AntiFloodPlugin with $threshold and $sleep time.
|
||||
*
|
||||
* @param int $threshold
|
||||
* @param int $sleep time
|
||||
* @param Swift_Plugins_Sleeper $sleeper (not needed really)
|
||||
*/
|
||||
public function __construct($threshold = 99, $sleep = 0, Swift_Plugins_Sleeper $sleeper = null)
|
||||
{
|
||||
$this->setThreshold($threshold);
|
||||
$this->setSleepTime($sleep);
|
||||
$this->sleeper = $sleeper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the number of emails to send before restarting.
|
||||
*
|
||||
* @param int $threshold
|
||||
*/
|
||||
public function setThreshold($threshold)
|
||||
{
|
||||
$this->threshold = $threshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of emails to send before restarting.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getThreshold()
|
||||
{
|
||||
return $this->threshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the number of seconds to sleep for during a restart.
|
||||
*
|
||||
* @param int $sleep time
|
||||
*/
|
||||
public function setSleepTime($sleep)
|
||||
{
|
||||
$this->sleep = $sleep;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of seconds to sleep for during a restart.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getSleepTime()
|
||||
{
|
||||
return $this->sleep;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked immediately before the Message is sent.
|
||||
*/
|
||||
public function beforeSendPerformed(Swift_Events_SendEvent $evt)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked immediately after the Message is sent.
|
||||
*/
|
||||
public function sendPerformed(Swift_Events_SendEvent $evt)
|
||||
{
|
||||
++$this->counter;
|
||||
if ($this->counter >= $this->threshold) {
|
||||
$transport = $evt->getTransport();
|
||||
$transport->stop();
|
||||
if ($this->sleep) {
|
||||
$this->sleep($this->sleep);
|
||||
}
|
||||
$transport->start();
|
||||
$this->counter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sleep for $seconds.
|
||||
*
|
||||
* @param int $seconds
|
||||
*/
|
||||
public function sleep($seconds)
|
||||
{
|
||||
if (isset($this->sleeper)) {
|
||||
$this->sleeper->sleep($seconds);
|
||||
} else {
|
||||
sleep($seconds);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Reduces network flooding when sending large amounts of mail.
|
||||
*
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_Plugins_BandwidthMonitorPlugin implements Swift_Events_SendListener, Swift_Events_CommandListener, Swift_Events_ResponseListener, Swift_InputByteStream
|
||||
{
|
||||
/**
|
||||
* The outgoing traffic counter.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $out = 0;
|
||||
|
||||
/**
|
||||
* The incoming traffic counter.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $in = 0;
|
||||
|
||||
/** Bound byte streams */
|
||||
private $mirrors = [];
|
||||
|
||||
/**
|
||||
* Not used.
|
||||
*/
|
||||
public function beforeSendPerformed(Swift_Events_SendEvent $evt)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked immediately after the Message is sent.
|
||||
*/
|
||||
public function sendPerformed(Swift_Events_SendEvent $evt)
|
||||
{
|
||||
$message = $evt->getMessage();
|
||||
$message->toByteStream($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked immediately following a command being sent.
|
||||
*/
|
||||
public function commandSent(Swift_Events_CommandEvent $evt)
|
||||
{
|
||||
$command = $evt->getCommand();
|
||||
$this->out += \strlen($command);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked immediately following a response coming back.
|
||||
*/
|
||||
public function responseReceived(Swift_Events_ResponseEvent $evt)
|
||||
{
|
||||
$response = $evt->getResponse();
|
||||
$this->in += \strlen($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a message is sent so that the outgoing counter can be increased.
|
||||
*
|
||||
* @param string $bytes
|
||||
*/
|
||||
public function write($bytes)
|
||||
{
|
||||
$this->out += \strlen($bytes);
|
||||
foreach ($this->mirrors as $stream) {
|
||||
$stream->write($bytes);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Not used.
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach $is to this stream.
|
||||
*
|
||||
* The stream acts as an observer, receiving all data that is written.
|
||||
* All {@link write()} and {@link flushBuffers()} operations will be mirrored.
|
||||
*/
|
||||
public function bind(Swift_InputByteStream $is)
|
||||
{
|
||||
$this->mirrors[] = $is;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an already bound stream.
|
||||
*
|
||||
* If $is is not bound, no errors will be raised.
|
||||
* If the stream currently has any buffered data it will be written to $is
|
||||
* before unbinding occurs.
|
||||
*/
|
||||
public function unbind(Swift_InputByteStream $is)
|
||||
{
|
||||
foreach ($this->mirrors as $k => $stream) {
|
||||
if ($is === $stream) {
|
||||
unset($this->mirrors[$k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Not used.
|
||||
*/
|
||||
public function flushBuffers()
|
||||
{
|
||||
foreach ($this->mirrors as $stream) {
|
||||
$stream->flushBuffers();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the total number of bytes sent to the server.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getBytesOut()
|
||||
{
|
||||
return $this->out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the total number of bytes received from the server.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getBytesIn()
|
||||
{
|
||||
return $this->in;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the internal counters to zero.
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->out = 0;
|
||||
$this->in = 0;
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allows customization of Messages on-the-fly.
|
||||
*
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
interface Swift_Plugins_Decorator_Replacements
|
||||
{
|
||||
/**
|
||||
* Return the array of replacements for $address.
|
||||
*
|
||||
* This method is invoked once for every single recipient of a message.
|
||||
*
|
||||
* If no replacements can be found, an empty value (NULL) should be returned
|
||||
* and no replacements will then be made on the message.
|
||||
*
|
||||
* @param string $address
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getReplacementsFor($address);
|
||||
}
|
@ -0,0 +1,200 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allows customization of Messages on-the-fly.
|
||||
*
|
||||
* @author Chris Corbyn
|
||||
* @author Fabien Potencier
|
||||
*/
|
||||
class Swift_Plugins_DecoratorPlugin implements Swift_Events_SendListener, Swift_Plugins_Decorator_Replacements
|
||||
{
|
||||
/** The replacement map */
|
||||
private $replacements;
|
||||
|
||||
/** The body as it was before replacements */
|
||||
private $originalBody;
|
||||
|
||||
/** The original headers of the message, before replacements */
|
||||
private $originalHeaders = [];
|
||||
|
||||
/** Bodies of children before they are replaced */
|
||||
private $originalChildBodies = [];
|
||||
|
||||
/** The Message that was last replaced */
|
||||
private $lastMessage;
|
||||
|
||||
/**
|
||||
* Create a new DecoratorPlugin with $replacements.
|
||||
*
|
||||
* The $replacements can either be an associative array, or an implementation
|
||||
* of {@link Swift_Plugins_Decorator_Replacements}.
|
||||
*
|
||||
* When using an array, it should be of the form:
|
||||
* <code>
|
||||
* $replacements = array(
|
||||
* "address1@domain.tld" => array("{a}" => "b", "{c}" => "d"),
|
||||
* "address2@domain.tld" => array("{a}" => "x", "{c}" => "y")
|
||||
* )
|
||||
* </code>
|
||||
*
|
||||
* When using an instance of {@link Swift_Plugins_Decorator_Replacements},
|
||||
* the object should return just the array of replacements for the address
|
||||
* given to {@link Swift_Plugins_Decorator_Replacements::getReplacementsFor()}.
|
||||
*
|
||||
* @param mixed $replacements Array or Swift_Plugins_Decorator_Replacements
|
||||
*/
|
||||
public function __construct($replacements)
|
||||
{
|
||||
$this->setReplacements($replacements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets replacements.
|
||||
*
|
||||
* @param mixed $replacements Array or Swift_Plugins_Decorator_Replacements
|
||||
*
|
||||
* @see __construct()
|
||||
*/
|
||||
public function setReplacements($replacements)
|
||||
{
|
||||
if (!($replacements instanceof Swift_Plugins_Decorator_Replacements)) {
|
||||
$this->replacements = (array) $replacements;
|
||||
} else {
|
||||
$this->replacements = $replacements;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked immediately before the Message is sent.
|
||||
*/
|
||||
public function beforeSendPerformed(Swift_Events_SendEvent $evt)
|
||||
{
|
||||
$message = $evt->getMessage();
|
||||
$this->restoreMessage($message);
|
||||
$to = array_keys($message->getTo());
|
||||
$address = array_shift($to);
|
||||
if ($replacements = $this->getReplacementsFor($address)) {
|
||||
$body = $message->getBody();
|
||||
$search = array_keys($replacements);
|
||||
$replace = array_values($replacements);
|
||||
$bodyReplaced = str_replace(
|
||||
$search, $replace, $body
|
||||
);
|
||||
if ($body != $bodyReplaced) {
|
||||
$this->originalBody = $body;
|
||||
$message->setBody($bodyReplaced);
|
||||
}
|
||||
|
||||
foreach ($message->getHeaders()->getAll() as $header) {
|
||||
$body = $header->getFieldBodyModel();
|
||||
$count = 0;
|
||||
if (\is_array($body)) {
|
||||
$bodyReplaced = [];
|
||||
foreach ($body as $key => $value) {
|
||||
$count1 = 0;
|
||||
$count2 = 0;
|
||||
$key = \is_string($key) ? str_replace($search, $replace, $key, $count1) : $key;
|
||||
$value = \is_string($value) ? str_replace($search, $replace, $value, $count2) : $value;
|
||||
$bodyReplaced[$key] = $value;
|
||||
|
||||
if (!$count && ($count1 || $count2)) {
|
||||
$count = 1;
|
||||
}
|
||||
}
|
||||
} elseif (\is_string($body)) {
|
||||
$bodyReplaced = str_replace($search, $replace, $body, $count);
|
||||
}
|
||||
|
||||
if ($count) {
|
||||
$this->originalHeaders[$header->getFieldName()] = $body;
|
||||
$header->setFieldBodyModel($bodyReplaced);
|
||||
}
|
||||
}
|
||||
|
||||
$children = (array) $message->getChildren();
|
||||
foreach ($children as $child) {
|
||||
list($type) = sscanf($child->getContentType(), '%[^/]/%s');
|
||||
if ('text' == $type) {
|
||||
$body = $child->getBody();
|
||||
$bodyReplaced = str_replace(
|
||||
$search, $replace, $body
|
||||
);
|
||||
if ($body != $bodyReplaced) {
|
||||
$child->setBody($bodyReplaced);
|
||||
$this->originalChildBodies[$child->getId()] = $body;
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->lastMessage = $message;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a map of replacements for the address.
|
||||
*
|
||||
* If this plugin was provided with a delegate instance of
|
||||
* {@link Swift_Plugins_Decorator_Replacements} then the call will be
|
||||
* delegated to it. Otherwise, it will attempt to find the replacements
|
||||
* from the array provided in the constructor.
|
||||
*
|
||||
* If no replacements can be found, an empty value (NULL) is returned.
|
||||
*
|
||||
* @param string $address
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getReplacementsFor($address)
|
||||
{
|
||||
if ($this->replacements instanceof Swift_Plugins_Decorator_Replacements) {
|
||||
return $this->replacements->getReplacementsFor($address);
|
||||
}
|
||||
|
||||
return $this->replacements[$address] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked immediately after the Message is sent.
|
||||
*/
|
||||
public function sendPerformed(Swift_Events_SendEvent $evt)
|
||||
{
|
||||
$this->restoreMessage($evt->getMessage());
|
||||
}
|
||||
|
||||
/** Restore a changed message back to its original state */
|
||||
private function restoreMessage(Swift_Mime_SimpleMessage $message)
|
||||
{
|
||||
if ($this->lastMessage === $message) {
|
||||
if (isset($this->originalBody)) {
|
||||
$message->setBody($this->originalBody);
|
||||
$this->originalBody = null;
|
||||
}
|
||||
if (!empty($this->originalHeaders)) {
|
||||
foreach ($message->getHeaders()->getAll() as $header) {
|
||||
if (\array_key_exists($header->getFieldName(), $this->originalHeaders)) {
|
||||
$header->setFieldBodyModel($this->originalHeaders[$header->getFieldName()]);
|
||||
}
|
||||
}
|
||||
$this->originalHeaders = [];
|
||||
}
|
||||
if (!empty($this->originalChildBodies)) {
|
||||
$children = (array) $message->getChildren();
|
||||
foreach ($children as $child) {
|
||||
$id = $child->getId();
|
||||
if (\array_key_exists($id, $this->originalChildBodies)) {
|
||||
$child->setBody($this->originalChildBodies[$id]);
|
||||
}
|
||||
}
|
||||
$this->originalChildBodies = [];
|
||||
}
|
||||
$this->lastMessage = null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2009 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Replaces the sender of a message.
|
||||
*
|
||||
* @author Arjen Brouwer
|
||||
*/
|
||||
class Swift_Plugins_ImpersonatePlugin implements Swift_Events_SendListener
|
||||
{
|
||||
/**
|
||||
* The sender to impersonate.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $sender;
|
||||
|
||||
/**
|
||||
* Create a new ImpersonatePlugin to impersonate $sender.
|
||||
*
|
||||
* @param string $sender address
|
||||
*/
|
||||
public function __construct($sender)
|
||||
{
|
||||
$this->sender = $sender;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked immediately before the Message is sent.
|
||||
*/
|
||||
public function beforeSendPerformed(Swift_Events_SendEvent $evt)
|
||||
{
|
||||
$message = $evt->getMessage();
|
||||
$headers = $message->getHeaders();
|
||||
|
||||
// save current recipients
|
||||
$headers->addPathHeader('X-Swift-Return-Path', $message->getReturnPath());
|
||||
|
||||
// replace them with the one to send to
|
||||
$message->setReturnPath($this->sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked immediately after the Message is sent.
|
||||
*/
|
||||
public function sendPerformed(Swift_Events_SendEvent $evt)
|
||||
{
|
||||
$message = $evt->getMessage();
|
||||
|
||||
// restore original headers
|
||||
$headers = $message->getHeaders();
|
||||
|
||||
if ($headers->has('X-Swift-Return-Path')) {
|
||||
$message->setReturnPath($headers->get('X-Swift-Return-Path')->getAddress());
|
||||
$headers->removeAll('X-Swift-Return-Path');
|
||||
}
|
||||
}
|
||||
}
|
36
include/swiftmailer/lib/classes/Swift/Plugins/Logger.php
Normal file
36
include/swiftmailer/lib/classes/Swift/Plugins/Logger.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Logs events in the Transport system.
|
||||
*
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
interface Swift_Plugins_Logger
|
||||
{
|
||||
/**
|
||||
* Add a log entry.
|
||||
*
|
||||
* @param string $entry
|
||||
*/
|
||||
public function add($entry);
|
||||
|
||||
/**
|
||||
* Clear the log contents.
|
||||
*/
|
||||
public function clear();
|
||||
|
||||
/**
|
||||
* Get this log as a string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function dump();
|
||||
}
|
126
include/swiftmailer/lib/classes/Swift/Plugins/LoggerPlugin.php
Normal file
126
include/swiftmailer/lib/classes/Swift/Plugins/LoggerPlugin.php
Normal file
@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Does real time logging of Transport level information.
|
||||
*
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_Plugins_LoggerPlugin implements Swift_Events_CommandListener, Swift_Events_ResponseListener, Swift_Events_TransportChangeListener, Swift_Events_TransportExceptionListener, Swift_Plugins_Logger
|
||||
{
|
||||
/** The logger which is delegated to */
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
* Create a new LoggerPlugin using $logger.
|
||||
*/
|
||||
public function __construct(Swift_Plugins_Logger $logger)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a log entry.
|
||||
*
|
||||
* @param string $entry
|
||||
*/
|
||||
public function add($entry)
|
||||
{
|
||||
$this->logger->add($entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the log contents.
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->logger->clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get this log as a string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function dump()
|
||||
{
|
||||
return $this->logger->dump();
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked immediately following a command being sent.
|
||||
*/
|
||||
public function commandSent(Swift_Events_CommandEvent $evt)
|
||||
{
|
||||
$command = $evt->getCommand();
|
||||
$this->logger->add(sprintf('>> %s', $command));
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked immediately following a response coming back.
|
||||
*/
|
||||
public function responseReceived(Swift_Events_ResponseEvent $evt)
|
||||
{
|
||||
$response = $evt->getResponse();
|
||||
$this->logger->add(sprintf('<< %s', $response));
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked just before a Transport is started.
|
||||
*/
|
||||
public function beforeTransportStarted(Swift_Events_TransportChangeEvent $evt)
|
||||
{
|
||||
$transportName = \get_class($evt->getSource());
|
||||
$this->logger->add(sprintf('++ Starting %s', $transportName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked immediately after the Transport is started.
|
||||
*/
|
||||
public function transportStarted(Swift_Events_TransportChangeEvent $evt)
|
||||
{
|
||||
$transportName = \get_class($evt->getSource());
|
||||
$this->logger->add(sprintf('++ %s started', $transportName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked just before a Transport is stopped.
|
||||
*/
|
||||
public function beforeTransportStopped(Swift_Events_TransportChangeEvent $evt)
|
||||
{
|
||||
$transportName = \get_class($evt->getSource());
|
||||
$this->logger->add(sprintf('++ Stopping %s', $transportName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked immediately after the Transport is stopped.
|
||||
*/
|
||||
public function transportStopped(Swift_Events_TransportChangeEvent $evt)
|
||||
{
|
||||
$transportName = \get_class($evt->getSource());
|
||||
$this->logger->add(sprintf('++ %s stopped', $transportName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked as a TransportException is thrown in the Transport system.
|
||||
*/
|
||||
public function exceptionThrown(Swift_Events_TransportExceptionEvent $evt)
|
||||
{
|
||||
$e = $evt->getException();
|
||||
$message = $e->getMessage();
|
||||
$code = $e->getCode();
|
||||
$this->logger->add(sprintf('!! %s (code: %s)', $message, $code));
|
||||
$message .= PHP_EOL;
|
||||
$message .= 'Log data:'.PHP_EOL;
|
||||
$message .= $this->logger->dump();
|
||||
$evt->cancelBubble();
|
||||
throw new Swift_TransportException($message, $code, $e->getPrevious());
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Logs to an Array backend.
|
||||
*
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_Plugins_Loggers_ArrayLogger implements Swift_Plugins_Logger
|
||||
{
|
||||
/**
|
||||
* The log contents.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $log = [];
|
||||
|
||||
/**
|
||||
* Max size of the log.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $size = 0;
|
||||
|
||||
/**
|
||||
* Create a new ArrayLogger with a maximum of $size entries.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public function __construct($size = 50)
|
||||
{
|
||||
$this->size = $size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a log entry.
|
||||
*
|
||||
* @param string $entry
|
||||
*/
|
||||
public function add($entry)
|
||||
{
|
||||
$this->log[] = $entry;
|
||||
while (\count($this->log) > $this->size) {
|
||||
array_shift($this->log);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the log contents.
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->log = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get this log as a string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function dump()
|
||||
{
|
||||
return implode(PHP_EOL, $this->log);
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Prints all log messages in real time.
|
||||
*
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_Plugins_Loggers_EchoLogger implements Swift_Plugins_Logger
|
||||
{
|
||||
/** Whether or not HTML should be output */
|
||||
private $isHtml;
|
||||
|
||||
/**
|
||||
* Create a new EchoLogger.
|
||||
*
|
||||
* @param bool $isHtml
|
||||
*/
|
||||
public function __construct($isHtml = true)
|
||||
{
|
||||
$this->isHtml = $isHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a log entry.
|
||||
*
|
||||
* @param string $entry
|
||||
*/
|
||||
public function add($entry)
|
||||
{
|
||||
if ($this->isHtml) {
|
||||
printf('%s%s%s', htmlspecialchars($entry, ENT_QUOTES), '<br />', PHP_EOL);
|
||||
} else {
|
||||
printf('%s%s', $entry, PHP_EOL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Not implemented.
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Not implemented.
|
||||
*/
|
||||
public function dump()
|
||||
{
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2011 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Stores all sent emails for further usage.
|
||||
*
|
||||
* @author Fabien Potencier
|
||||
*/
|
||||
class Swift_Plugins_MessageLogger implements Swift_Events_SendListener
|
||||
{
|
||||
/**
|
||||
* @var Swift_Mime_SimpleMessage[]
|
||||
*/
|
||||
private $messages;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->messages = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message list.
|
||||
*
|
||||
* @return Swift_Mime_SimpleMessage[]
|
||||
*/
|
||||
public function getMessages()
|
||||
{
|
||||
return $this->messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message count.
|
||||
*
|
||||
* @return int count
|
||||
*/
|
||||
public function countMessages()
|
||||
{
|
||||
return \count($this->messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty the message list.
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->messages = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked immediately before the Message is sent.
|
||||
*/
|
||||
public function beforeSendPerformed(Swift_Events_SendEvent $evt)
|
||||
{
|
||||
$this->messages[] = clone $evt->getMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked immediately after the Message is sent.
|
||||
*/
|
||||
public function sendPerformed(Swift_Events_SendEvent $evt)
|
||||
{
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Pop3Connection interface for connecting and disconnecting to a POP3 host.
|
||||
*
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
interface Swift_Plugins_Pop_Pop3Connection
|
||||
{
|
||||
/**
|
||||
* Connect to the POP3 host and throw an Exception if it fails.
|
||||
*
|
||||
* @throws Swift_Plugins_Pop_Pop3Exception
|
||||
*/
|
||||
public function connect();
|
||||
|
||||
/**
|
||||
* Disconnect from the POP3 host and throw an Exception if it fails.
|
||||
*
|
||||
* @throws Swift_Plugins_Pop_Pop3Exception
|
||||
*/
|
||||
public function disconnect();
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Pop3Exception thrown when an error occurs connecting to a POP3 host.
|
||||
*
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_Plugins_Pop_Pop3Exception extends Swift_IoException
|
||||
{
|
||||
/**
|
||||
* Create a new Pop3Exception with $message.
|
||||
*
|
||||
* @param string $message
|
||||
*/
|
||||
public function __construct($message)
|
||||
{
|
||||
parent::__construct($message);
|
||||
}
|
||||
}
|
@ -0,0 +1,242 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Makes sure a connection to a POP3 host has been established prior to connecting to SMTP.
|
||||
*
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_Plugins_PopBeforeSmtpPlugin implements Swift_Events_TransportChangeListener, Swift_Plugins_Pop_Pop3Connection
|
||||
{
|
||||
/** A delegate connection to use (mostly a test hook) */
|
||||
private $connection;
|
||||
|
||||
/** Hostname of the POP3 server */
|
||||
private $host;
|
||||
|
||||
/** Port number to connect on */
|
||||
private $port;
|
||||
|
||||
/** Encryption type to use (if any) */
|
||||
private $crypto;
|
||||
|
||||
/** Username to use (if any) */
|
||||
private $username;
|
||||
|
||||
/** Password to use (if any) */
|
||||
private $password;
|
||||
|
||||
/** Established connection via TCP socket */
|
||||
private $socket;
|
||||
|
||||
/** Connect timeout in seconds */
|
||||
private $timeout = 10;
|
||||
|
||||
/** SMTP Transport to bind to */
|
||||
private $transport;
|
||||
|
||||
/**
|
||||
* Create a new PopBeforeSmtpPlugin for $host and $port.
|
||||
*
|
||||
* @param string $host Hostname or IP. Literal IPv6 addresses should be
|
||||
* wrapped in square brackets.
|
||||
* @param int $port
|
||||
* @param string $crypto as "tls" or "ssl"
|
||||
*/
|
||||
public function __construct($host, $port = 110, $crypto = null)
|
||||
{
|
||||
$this->host = $host;
|
||||
$this->port = $port;
|
||||
$this->crypto = $crypto;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a Pop3Connection to delegate to instead of connecting directly.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setConnection(Swift_Plugins_Pop_Pop3Connection $connection)
|
||||
{
|
||||
$this->connection = $connection;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind this plugin to a specific SMTP transport instance.
|
||||
*/
|
||||
public function bindSmtp(Swift_Transport $smtp)
|
||||
{
|
||||
$this->transport = $smtp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the connection timeout in seconds (default 10).
|
||||
*
|
||||
* @param int $timeout
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setTimeout($timeout)
|
||||
{
|
||||
$this->timeout = (int) $timeout;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the username to use when connecting (if needed).
|
||||
*
|
||||
* @param string $username
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setUsername($username)
|
||||
{
|
||||
$this->username = $username;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the password to use when connecting (if needed).
|
||||
*
|
||||
* @param string $password
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPassword($password)
|
||||
{
|
||||
$this->password = $password;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to the POP3 host and authenticate.
|
||||
*
|
||||
* @throws Swift_Plugins_Pop_Pop3Exception if connection fails
|
||||
*/
|
||||
public function connect()
|
||||
{
|
||||
if (isset($this->connection)) {
|
||||
$this->connection->connect();
|
||||
} else {
|
||||
if (!isset($this->socket)) {
|
||||
if (!$socket = fsockopen(
|
||||
$this->getHostString(), $this->port, $errno, $errstr, $this->timeout)) {
|
||||
throw new Swift_Plugins_Pop_Pop3Exception(sprintf('Failed to connect to POP3 host [%s]: %s', $this->host, $errstr));
|
||||
}
|
||||
$this->socket = $socket;
|
||||
|
||||
if (false === $greeting = fgets($this->socket)) {
|
||||
throw new Swift_Plugins_Pop_Pop3Exception(sprintf('Failed to connect to POP3 host [%s]', trim($greeting)));
|
||||
}
|
||||
|
||||
$this->assertOk($greeting);
|
||||
|
||||
if ($this->username) {
|
||||
$this->command(sprintf("USER %s\r\n", $this->username));
|
||||
$this->command(sprintf("PASS %s\r\n", $this->password));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect from the POP3 host.
|
||||
*/
|
||||
public function disconnect()
|
||||
{
|
||||
if (isset($this->connection)) {
|
||||
$this->connection->disconnect();
|
||||
} else {
|
||||
$this->command("QUIT\r\n");
|
||||
if (!fclose($this->socket)) {
|
||||
throw new Swift_Plugins_Pop_Pop3Exception(sprintf('POP3 host [%s] connection could not be stopped', $this->host));
|
||||
}
|
||||
$this->socket = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked just before a Transport is started.
|
||||
*/
|
||||
public function beforeTransportStarted(Swift_Events_TransportChangeEvent $evt)
|
||||
{
|
||||
if (isset($this->transport)) {
|
||||
if ($this->transport !== $evt->getTransport()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$this->connect();
|
||||
$this->disconnect();
|
||||
}
|
||||
|
||||
/**
|
||||
* Not used.
|
||||
*/
|
||||
public function transportStarted(Swift_Events_TransportChangeEvent $evt)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Not used.
|
||||
*/
|
||||
public function beforeTransportStopped(Swift_Events_TransportChangeEvent $evt)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Not used.
|
||||
*/
|
||||
public function transportStopped(Swift_Events_TransportChangeEvent $evt)
|
||||
{
|
||||
}
|
||||
|
||||
private function command($command)
|
||||
{
|
||||
if (!fwrite($this->socket, $command)) {
|
||||
throw new Swift_Plugins_Pop_Pop3Exception(sprintf('Failed to write command [%s] to POP3 host', trim($command)));
|
||||
}
|
||||
|
||||
if (false === $response = fgets($this->socket)) {
|
||||
throw new Swift_Plugins_Pop_Pop3Exception(sprintf('Failed to read from POP3 host after command [%s]', trim($command)));
|
||||
}
|
||||
|
||||
$this->assertOk($response);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function assertOk($response)
|
||||
{
|
||||
if ('+OK' != substr($response, 0, 3)) {
|
||||
throw new Swift_Plugins_Pop_Pop3Exception(sprintf('POP3 command failed [%s]', trim($response)));
|
||||
}
|
||||
}
|
||||
|
||||
private function getHostString()
|
||||
{
|
||||
$host = $this->host;
|
||||
switch (strtolower($this->crypto)) {
|
||||
case 'ssl':
|
||||
$host = 'ssl://'.$host;
|
||||
break;
|
||||
|
||||
case 'tls':
|
||||
$host = 'tls://'.$host;
|
||||
break;
|
||||
}
|
||||
|
||||
return $host;
|
||||
}
|
||||
}
|
@ -0,0 +1,201 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2009 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Redirects all email to a single recipient.
|
||||
*
|
||||
* @author Fabien Potencier
|
||||
*/
|
||||
class Swift_Plugins_RedirectingPlugin implements Swift_Events_SendListener
|
||||
{
|
||||
/**
|
||||
* The recipient who will receive all messages.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
private $recipient;
|
||||
|
||||
/**
|
||||
* List of regular expression for recipient whitelisting.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $whitelist = [];
|
||||
|
||||
/**
|
||||
* Create a new RedirectingPlugin.
|
||||
*
|
||||
* @param mixed $recipient
|
||||
*/
|
||||
public function __construct($recipient, array $whitelist = [])
|
||||
{
|
||||
$this->recipient = $recipient;
|
||||
$this->whitelist = $whitelist;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the recipient of all messages.
|
||||
*
|
||||
* @param mixed $recipient
|
||||
*/
|
||||
public function setRecipient($recipient)
|
||||
{
|
||||
$this->recipient = $recipient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the recipient of all messages.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getRecipient()
|
||||
{
|
||||
return $this->recipient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a list of regular expressions to whitelist certain recipients.
|
||||
*/
|
||||
public function setWhitelist(array $whitelist)
|
||||
{
|
||||
$this->whitelist = $whitelist;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the whitelist.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getWhitelist()
|
||||
{
|
||||
return $this->whitelist;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked immediately before the Message is sent.
|
||||
*/
|
||||
public function beforeSendPerformed(Swift_Events_SendEvent $evt)
|
||||
{
|
||||
$message = $evt->getMessage();
|
||||
$headers = $message->getHeaders();
|
||||
|
||||
// conditionally save current recipients
|
||||
|
||||
if ($headers->has('to')) {
|
||||
$headers->addMailboxHeader('X-Swift-To', $message->getTo());
|
||||
}
|
||||
|
||||
if ($headers->has('cc')) {
|
||||
$headers->addMailboxHeader('X-Swift-Cc', $message->getCc());
|
||||
}
|
||||
|
||||
if ($headers->has('bcc')) {
|
||||
$headers->addMailboxHeader('X-Swift-Bcc', $message->getBcc());
|
||||
}
|
||||
|
||||
// Filter remaining headers against whitelist
|
||||
$this->filterHeaderSet($headers, 'To');
|
||||
$this->filterHeaderSet($headers, 'Cc');
|
||||
$this->filterHeaderSet($headers, 'Bcc');
|
||||
|
||||
// Add each hard coded recipient
|
||||
$to = $message->getTo();
|
||||
if (null === $to) {
|
||||
$to = [];
|
||||
}
|
||||
|
||||
foreach ((array) $this->recipient as $recipient) {
|
||||
if (!\array_key_exists($recipient, $to)) {
|
||||
$message->addTo($recipient);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter header set against a whitelist of regular expressions.
|
||||
*
|
||||
* @param string $type
|
||||
*/
|
||||
private function filterHeaderSet(Swift_Mime_SimpleHeaderSet $headerSet, $type)
|
||||
{
|
||||
foreach ($headerSet->getAll($type) as $headers) {
|
||||
$headers->setNameAddresses($this->filterNameAddresses($headers->getNameAddresses()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filtered list of addresses => name pairs.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function filterNameAddresses(array $recipients)
|
||||
{
|
||||
$filtered = [];
|
||||
|
||||
foreach ($recipients as $address => $name) {
|
||||
if ($this->isWhitelisted($address)) {
|
||||
$filtered[$address] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
return $filtered;
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches address against whitelist of regular expressions.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isWhitelisted($recipient)
|
||||
{
|
||||
if (\in_array($recipient, (array) $this->recipient)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach ($this->whitelist as $pattern) {
|
||||
if (preg_match($pattern, $recipient)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked immediately after the Message is sent.
|
||||
*/
|
||||
public function sendPerformed(Swift_Events_SendEvent $evt)
|
||||
{
|
||||
$this->restoreMessage($evt->getMessage());
|
||||
}
|
||||
|
||||
private function restoreMessage(Swift_Mime_SimpleMessage $message)
|
||||
{
|
||||
// restore original headers
|
||||
$headers = $message->getHeaders();
|
||||
|
||||
if ($headers->has('X-Swift-To')) {
|
||||
$message->setTo($headers->get('X-Swift-To')->getNameAddresses());
|
||||
$headers->removeAll('X-Swift-To');
|
||||
} else {
|
||||
$message->setTo(null);
|
||||
}
|
||||
|
||||
if ($headers->has('X-Swift-Cc')) {
|
||||
$message->setCc($headers->get('X-Swift-Cc')->getNameAddresses());
|
||||
$headers->removeAll('X-Swift-Cc');
|
||||
}
|
||||
|
||||
if ($headers->has('X-Swift-Bcc')) {
|
||||
$message->setBcc($headers->get('X-Swift-Bcc')->getNameAddresses());
|
||||
$headers->removeAll('X-Swift-Bcc');
|
||||
}
|
||||
}
|
||||
}
|
31
include/swiftmailer/lib/classes/Swift/Plugins/Reporter.php
Normal file
31
include/swiftmailer/lib/classes/Swift/Plugins/Reporter.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Reporter plugin sends pass/fail notification to a Reporter.
|
||||
*
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
interface Swift_Plugins_Reporter
|
||||
{
|
||||
/** The recipient was accepted for delivery */
|
||||
const RESULT_PASS = 0x01;
|
||||
|
||||
/** The recipient could not be accepted */
|
||||
const RESULT_FAIL = 0x10;
|
||||
|
||||
/**
|
||||
* Notifies this ReportNotifier that $address failed or succeeded.
|
||||
*
|
||||
* @param string $address
|
||||
* @param int $result from {@link RESULT_PASS, RESULT_FAIL}
|
||||
*/
|
||||
public function notify(Swift_Mime_SimpleMessage $message, $address, $result);
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Does real time reporting of pass/fail for each recipient.
|
||||
*
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_Plugins_ReporterPlugin implements Swift_Events_SendListener
|
||||
{
|
||||
/**
|
||||
* The reporter backend which takes notifications.
|
||||
*
|
||||
* @var Swift_Plugins_Reporter
|
||||
*/
|
||||
private $reporter;
|
||||
|
||||
/**
|
||||
* Create a new ReporterPlugin using $reporter.
|
||||
*/
|
||||
public function __construct(Swift_Plugins_Reporter $reporter)
|
||||
{
|
||||
$this->reporter = $reporter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not used.
|
||||
*/
|
||||
public function beforeSendPerformed(Swift_Events_SendEvent $evt)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked immediately after the Message is sent.
|
||||
*/
|
||||
public function sendPerformed(Swift_Events_SendEvent $evt)
|
||||
{
|
||||
$message = $evt->getMessage();
|
||||
$failures = array_flip($evt->getFailedRecipients());
|
||||
foreach ((array) $message->getTo() as $address => $null) {
|
||||
$this->reporter->notify($message, $address, (\array_key_exists($address, $failures) ? Swift_Plugins_Reporter::RESULT_FAIL : Swift_Plugins_Reporter::RESULT_PASS));
|
||||
}
|
||||
foreach ((array) $message->getCc() as $address => $null) {
|
||||
$this->reporter->notify($message, $address, (\array_key_exists($address, $failures) ? Swift_Plugins_Reporter::RESULT_FAIL : Swift_Plugins_Reporter::RESULT_PASS));
|
||||
}
|
||||
foreach ((array) $message->getBcc() as $address => $null) {
|
||||
$this->reporter->notify($message, $address, (\array_key_exists($address, $failures) ? Swift_Plugins_Reporter::RESULT_FAIL : Swift_Plugins_Reporter::RESULT_PASS));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A reporter which "collects" failures for the Reporter plugin.
|
||||
*
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_Plugins_Reporters_HitReporter implements Swift_Plugins_Reporter
|
||||
{
|
||||
/**
|
||||
* The list of failures.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $failures = [];
|
||||
|
||||
private $failures_cache = [];
|
||||
|
||||
/**
|
||||
* Notifies this ReportNotifier that $address failed or succeeded.
|
||||
*
|
||||
* @param string $address
|
||||
* @param int $result from {@link RESULT_PASS, RESULT_FAIL}
|
||||
*/
|
||||
public function notify(Swift_Mime_SimpleMessage $message, $address, $result)
|
||||
{
|
||||
if (self::RESULT_FAIL == $result && !isset($this->failures_cache[$address])) {
|
||||
$this->failures[] = $address;
|
||||
$this->failures_cache[$address] = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of addresses for which delivery failed.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFailedRecipients()
|
||||
{
|
||||
return $this->failures;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the buffer (empty the list).
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->failures = $this->failures_cache = [];
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A HTML output reporter for the Reporter plugin.
|
||||
*
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_Plugins_Reporters_HtmlReporter implements Swift_Plugins_Reporter
|
||||
{
|
||||
/**
|
||||
* Notifies this ReportNotifier that $address failed or succeeded.
|
||||
*
|
||||
* @param string $address
|
||||
* @param int $result from {@see RESULT_PASS, RESULT_FAIL}
|
||||
*/
|
||||
public function notify(Swift_Mime_SimpleMessage $message, $address, $result)
|
||||
{
|
||||
if (self::RESULT_PASS == $result) {
|
||||
echo '<div style="color: #fff; background: #006600; padding: 2px; margin: 2px;">'.PHP_EOL;
|
||||
echo 'PASS '.$address.PHP_EOL;
|
||||
echo '</div>'.PHP_EOL;
|
||||
flush();
|
||||
} else {
|
||||
echo '<div style="color: #fff; background: #880000; padding: 2px; margin: 2px;">'.PHP_EOL;
|
||||
echo 'FAIL '.$address.PHP_EOL;
|
||||
echo '</div>'.PHP_EOL;
|
||||
flush();
|
||||
}
|
||||
}
|
||||
}
|
24
include/swiftmailer/lib/classes/Swift/Plugins/Sleeper.php
Normal file
24
include/swiftmailer/lib/classes/Swift/Plugins/Sleeper.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sleeps for a duration of time.
|
||||
*
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
interface Swift_Plugins_Sleeper
|
||||
{
|
||||
/**
|
||||
* Sleep for $seconds.
|
||||
*
|
||||
* @param int $seconds
|
||||
*/
|
||||
public function sleep($seconds);
|
||||
}
|
@ -0,0 +1,196 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Throttles the rate at which emails are sent.
|
||||
*
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_Plugins_ThrottlerPlugin extends Swift_Plugins_BandwidthMonitorPlugin implements Swift_Plugins_Sleeper, Swift_Plugins_Timer
|
||||
{
|
||||
/** Flag for throttling in bytes per minute */
|
||||
const BYTES_PER_MINUTE = 0x01;
|
||||
|
||||
/** Flag for throttling in emails per second (Amazon SES) */
|
||||
const MESSAGES_PER_SECOND = 0x11;
|
||||
|
||||
/** Flag for throttling in emails per minute */
|
||||
const MESSAGES_PER_MINUTE = 0x10;
|
||||
|
||||
/**
|
||||
* The Sleeper instance for sleeping.
|
||||
*
|
||||
* @var Swift_Plugins_Sleeper
|
||||
*/
|
||||
private $sleeper;
|
||||
|
||||
/**
|
||||
* The Timer instance which provides the timestamp.
|
||||
*
|
||||
* @var Swift_Plugins_Timer
|
||||
*/
|
||||
private $timer;
|
||||
|
||||
/**
|
||||
* The time at which the first email was sent.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $start;
|
||||
|
||||
/**
|
||||
* The rate at which messages should be sent.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $rate;
|
||||
|
||||
/**
|
||||
* The mode for throttling.
|
||||
*
|
||||
* This is {@link BYTES_PER_MINUTE} or {@link MESSAGES_PER_MINUTE}
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $mode;
|
||||
|
||||
/**
|
||||
* An internal counter of the number of messages sent.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $messages = 0;
|
||||
|
||||
/**
|
||||
* Create a new ThrottlerPlugin.
|
||||
*
|
||||
* @param int $rate
|
||||
* @param int $mode defaults to {@link BYTES_PER_MINUTE}
|
||||
* @param Swift_Plugins_Sleeper $sleeper (only needed in testing)
|
||||
* @param Swift_Plugins_Timer $timer (only needed in testing)
|
||||
*/
|
||||
public function __construct($rate, $mode = self::BYTES_PER_MINUTE, Swift_Plugins_Sleeper $sleeper = null, Swift_Plugins_Timer $timer = null)
|
||||
{
|
||||
$this->rate = $rate;
|
||||
$this->mode = $mode;
|
||||
$this->sleeper = $sleeper;
|
||||
$this->timer = $timer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked immediately before the Message is sent.
|
||||
*/
|
||||
public function beforeSendPerformed(Swift_Events_SendEvent $evt)
|
||||
{
|
||||
$time = $this->getTimestamp();
|
||||
if (!isset($this->start)) {
|
||||
$this->start = $time;
|
||||
}
|
||||
$duration = $time - $this->start;
|
||||
|
||||
switch ($this->mode) {
|
||||
case self::BYTES_PER_MINUTE:
|
||||
$sleep = $this->throttleBytesPerMinute($duration);
|
||||
break;
|
||||
case self::MESSAGES_PER_SECOND:
|
||||
$sleep = $this->throttleMessagesPerSecond($duration);
|
||||
break;
|
||||
case self::MESSAGES_PER_MINUTE:
|
||||
$sleep = $this->throttleMessagesPerMinute($duration);
|
||||
break;
|
||||
default:
|
||||
$sleep = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if ($sleep > 0) {
|
||||
$this->sleep($sleep);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when a Message is sent.
|
||||
*/
|
||||
public function sendPerformed(Swift_Events_SendEvent $evt)
|
||||
{
|
||||
parent::sendPerformed($evt);
|
||||
++$this->messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sleep for $seconds.
|
||||
*
|
||||
* @param int $seconds
|
||||
*/
|
||||
public function sleep($seconds)
|
||||
{
|
||||
if (isset($this->sleeper)) {
|
||||
$this->sleeper->sleep($seconds);
|
||||
} else {
|
||||
sleep($seconds);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current UNIX timestamp.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getTimestamp()
|
||||
{
|
||||
if (isset($this->timer)) {
|
||||
return $this->timer->getTimestamp();
|
||||
}
|
||||
|
||||
return time();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a number of seconds to sleep for.
|
||||
*
|
||||
* @param int $timePassed
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function throttleBytesPerMinute($timePassed)
|
||||
{
|
||||
$expectedDuration = $this->getBytesOut() / ($this->rate / 60);
|
||||
|
||||
return (int) ceil($expectedDuration - $timePassed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a number of seconds to sleep for.
|
||||
*
|
||||
* @param int $timePassed
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function throttleMessagesPerSecond($timePassed)
|
||||
{
|
||||
$expectedDuration = $this->messages / $this->rate;
|
||||
|
||||
return (int) ceil($expectedDuration - $timePassed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a number of seconds to sleep for.
|
||||
*
|
||||
* @param int $timePassed
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function throttleMessagesPerMinute($timePassed)
|
||||
{
|
||||
$expectedDuration = $this->messages / ($this->rate / 60);
|
||||
|
||||
return (int) ceil($expectedDuration - $timePassed);
|
||||
}
|
||||
}
|
24
include/swiftmailer/lib/classes/Swift/Plugins/Timer.php
Normal file
24
include/swiftmailer/lib/classes/Swift/Plugins/Timer.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides timestamp data.
|
||||
*
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
interface Swift_Plugins_Timer
|
||||
{
|
||||
/**
|
||||
* Get the current UNIX timestamp.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getTimestamp();
|
||||
}
|
Reference in New Issue
Block a user