1
0

first commit

This commit is contained in:
Daniel Tartavel
2021-10-14 17:58:21 +02:00
parent e5fe464cbc
commit df07673a67
327 changed files with 44407 additions and 0 deletions

View File

@ -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);
}
}
}

View File

@ -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;
}
}

View 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.
*/
/**
* 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);
}

View File

@ -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;
}
}
}

View File

@ -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');
}
}
}

View 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();
}

View 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());
}
}

View File

@ -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);
}
}

View File

@ -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()
{
}
}

View File

@ -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)
{
}
}

View 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.
*/
/**
* 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();
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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');
}
}
}

View 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);
}

View File

@ -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));
}
}
}

View File

@ -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 = [];
}
}

View File

@ -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();
}
}
}

View 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);
}

View File

@ -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);
}
}

View 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();
}