mirror of
https://github.com/torrentpier/torrentpier-lts.git
synced 2025-03-01 15:21:02 +03:00
345 lines
8.6 KiB
PHP
345 lines
8.6 KiB
PHP
|
<?php
|
||
|
/**
|
||
|
* Zend Framework (http://framework.zend.com/)
|
||
|
*
|
||
|
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||
|
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||
|
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||
|
*/
|
||
|
|
||
|
namespace Zend\Mail\Transport;
|
||
|
|
||
|
use Zend\Mail\Address;
|
||
|
use Zend\Mail\Headers;
|
||
|
use Zend\Mail\Message;
|
||
|
use Zend\Mail\Protocol;
|
||
|
use Zend\Mail\Protocol\Exception as ProtocolException;
|
||
|
|
||
|
/**
|
||
|
* SMTP connection object
|
||
|
*
|
||
|
* Loads an instance of Zend\Mail\Protocol\Smtp and forwards smtp transactions
|
||
|
*/
|
||
|
class Smtp implements TransportInterface
|
||
|
{
|
||
|
/**
|
||
|
* @var SmtpOptions
|
||
|
*/
|
||
|
protected $options;
|
||
|
|
||
|
/**
|
||
|
* @var Protocol\Smtp
|
||
|
*/
|
||
|
protected $connection;
|
||
|
|
||
|
/**
|
||
|
* @var bool
|
||
|
*/
|
||
|
protected $autoDisconnect = true;
|
||
|
|
||
|
/**
|
||
|
* @var Protocol\SmtpPluginManager
|
||
|
*/
|
||
|
protected $plugins;
|
||
|
|
||
|
/**
|
||
|
* Constructor.
|
||
|
*
|
||
|
* @param SmtpOptions $options Optional
|
||
|
*/
|
||
|
public function __construct(SmtpOptions $options = null)
|
||
|
{
|
||
|
if (!$options instanceof SmtpOptions) {
|
||
|
$options = new SmtpOptions();
|
||
|
}
|
||
|
$this->setOptions($options);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Set options
|
||
|
*
|
||
|
* @param SmtpOptions $options
|
||
|
* @return Smtp
|
||
|
*/
|
||
|
public function setOptions(SmtpOptions $options)
|
||
|
{
|
||
|
$this->options = $options;
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get options
|
||
|
*
|
||
|
* @return SmtpOptions
|
||
|
*/
|
||
|
public function getOptions()
|
||
|
{
|
||
|
return $this->options;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Set plugin manager for obtaining SMTP protocol connection
|
||
|
*
|
||
|
* @param Protocol\SmtpPluginManager $plugins
|
||
|
* @throws Exception\InvalidArgumentException
|
||
|
* @return Smtp
|
||
|
*/
|
||
|
public function setPluginManager(Protocol\SmtpPluginManager $plugins)
|
||
|
{
|
||
|
$this->plugins = $plugins;
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get plugin manager for loading SMTP protocol connection
|
||
|
*
|
||
|
* @return Protocol\SmtpPluginManager
|
||
|
*/
|
||
|
public function getPluginManager()
|
||
|
{
|
||
|
if (null === $this->plugins) {
|
||
|
$this->setPluginManager(new Protocol\SmtpPluginManager());
|
||
|
}
|
||
|
return $this->plugins;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Set the automatic disconnection when destruct
|
||
|
*
|
||
|
* @param bool $flag
|
||
|
* @return Smtp
|
||
|
*/
|
||
|
public function setAutoDisconnect($flag)
|
||
|
{
|
||
|
$this->autoDisconnect = (bool) $flag;
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the automatic disconnection value
|
||
|
*
|
||
|
* @return bool
|
||
|
*/
|
||
|
public function getAutoDisconnect()
|
||
|
{
|
||
|
return $this->autoDisconnect;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Return an SMTP connection
|
||
|
*
|
||
|
* @param string $name
|
||
|
* @param array|null $options
|
||
|
* @return Protocol\Smtp
|
||
|
*/
|
||
|
public function plugin($name, array $options = null)
|
||
|
{
|
||
|
return $this->getPluginManager()->get($name, $options);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Class destructor to ensure all open connections are closed
|
||
|
*/
|
||
|
public function __destruct()
|
||
|
{
|
||
|
if ($this->connection instanceof Protocol\Smtp) {
|
||
|
try {
|
||
|
$this->connection->quit();
|
||
|
} catch (ProtocolException\ExceptionInterface $e) {
|
||
|
// ignore
|
||
|
}
|
||
|
if ($this->autoDisconnect) {
|
||
|
$this->connection->disconnect();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets the connection protocol instance
|
||
|
*
|
||
|
* @param Protocol\AbstractProtocol $connection
|
||
|
*/
|
||
|
public function setConnection(Protocol\AbstractProtocol $connection)
|
||
|
{
|
||
|
$this->connection = $connection;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Gets the connection protocol instance
|
||
|
*
|
||
|
* @return Protocol\Smtp
|
||
|
*/
|
||
|
public function getConnection()
|
||
|
{
|
||
|
return $this->connection;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Disconnect the connection protocol instance
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
public function disconnect()
|
||
|
{
|
||
|
if (!empty($this->connection) && ($this->connection instanceof Protocol\Smtp)) {
|
||
|
$this->connection->disconnect();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Send an email via the SMTP connection protocol
|
||
|
*
|
||
|
* The connection via the protocol adapter is made just-in-time to allow a
|
||
|
* developer to add a custom adapter if required before mail is sent.
|
||
|
*
|
||
|
* @param Message $message
|
||
|
* @throws Exception\RuntimeException
|
||
|
*/
|
||
|
public function send(Message $message)
|
||
|
{
|
||
|
// If sending multiple messages per session use existing adapter
|
||
|
$connection = $this->getConnection();
|
||
|
|
||
|
if (!($connection instanceof Protocol\Smtp) || !$connection->hasSession()) {
|
||
|
$connection = $this->connect();
|
||
|
} else {
|
||
|
// Reset connection to ensure reliable transaction
|
||
|
$connection->rset();
|
||
|
}
|
||
|
|
||
|
// Prepare message
|
||
|
$from = $this->prepareFromAddress($message);
|
||
|
$recipients = $this->prepareRecipients($message);
|
||
|
$headers = $this->prepareHeaders($message);
|
||
|
$body = $this->prepareBody($message);
|
||
|
|
||
|
if ((count($recipients) == 0) && (!empty($headers) || !empty($body))) {
|
||
|
throw new Exception\RuntimeException( // Per RFC 2821 3.3 (page 18)
|
||
|
sprintf(
|
||
|
'%s transport expects at least one recipient if the message has at least one header or body',
|
||
|
__CLASS__
|
||
|
));
|
||
|
}
|
||
|
|
||
|
// Set sender email address
|
||
|
$connection->mail($from);
|
||
|
|
||
|
// Set recipient forward paths
|
||
|
foreach ($recipients as $recipient) {
|
||
|
$connection->rcpt($recipient);
|
||
|
}
|
||
|
|
||
|
// Issue DATA command to client
|
||
|
$connection->data($headers . Headers::EOL . $body);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Retrieve email address for envelope FROM
|
||
|
*
|
||
|
* @param Message $message
|
||
|
* @throws Exception\RuntimeException
|
||
|
* @return string
|
||
|
*/
|
||
|
protected function prepareFromAddress(Message $message)
|
||
|
{
|
||
|
$sender = $message->getSender();
|
||
|
if ($sender instanceof Address\AddressInterface) {
|
||
|
return $sender->getEmail();
|
||
|
}
|
||
|
|
||
|
$from = $message->getFrom();
|
||
|
if (!count($from)) { // Per RFC 2822 3.6
|
||
|
throw new Exception\RuntimeException(sprintf(
|
||
|
'%s transport expects either a Sender or at least one From address in the Message; none provided',
|
||
|
__CLASS__
|
||
|
));
|
||
|
}
|
||
|
|
||
|
$from->rewind();
|
||
|
$sender = $from->current();
|
||
|
return $sender->getEmail();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Prepare array of email address recipients
|
||
|
*
|
||
|
* @param Message $message
|
||
|
* @return array
|
||
|
*/
|
||
|
protected function prepareRecipients(Message $message)
|
||
|
{
|
||
|
$recipients = array();
|
||
|
foreach ($message->getTo() as $address) {
|
||
|
$recipients[] = $address->getEmail();
|
||
|
}
|
||
|
foreach ($message->getCc() as $address) {
|
||
|
$recipients[] = $address->getEmail();
|
||
|
}
|
||
|
foreach ($message->getBcc() as $address) {
|
||
|
$recipients[] = $address->getEmail();
|
||
|
}
|
||
|
$recipients = array_unique($recipients);
|
||
|
return $recipients;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Prepare header string from message
|
||
|
*
|
||
|
* @param Message $message
|
||
|
* @return string
|
||
|
*/
|
||
|
protected function prepareHeaders(Message $message)
|
||
|
{
|
||
|
$headers = clone $message->getHeaders();
|
||
|
$headers->removeHeader('Bcc');
|
||
|
return $headers->toString();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Prepare body string from message
|
||
|
*
|
||
|
* @param Message $message
|
||
|
* @return string
|
||
|
*/
|
||
|
protected function prepareBody(Message $message)
|
||
|
{
|
||
|
return $message->getBodyText();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Lazy load the connection
|
||
|
*
|
||
|
* @return Protocol\Smtp
|
||
|
*/
|
||
|
protected function lazyLoadConnection()
|
||
|
{
|
||
|
// Check if authentication is required and determine required class
|
||
|
$options = $this->getOptions();
|
||
|
$config = $options->getConnectionConfig();
|
||
|
$config['host'] = $options->getHost();
|
||
|
$config['port'] = $options->getPort();
|
||
|
$connection = $this->plugin($options->getConnectionClass(), $config);
|
||
|
$this->connection = $connection;
|
||
|
|
||
|
return $this->connect();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Connect the connection, and pass it helo
|
||
|
*
|
||
|
* @return Protocol\Smtp
|
||
|
*/
|
||
|
protected function connect()
|
||
|
{
|
||
|
if (!$this->connection instanceof Protocol\Smtp) {
|
||
|
return $this->lazyLoadConnection();
|
||
|
}
|
||
|
|
||
|
$this->connection->connect();
|
||
|
$this->connection->helo($this->getOptions()->getName());
|
||
|
|
||
|
return $this->connection;
|
||
|
}
|
||
|
}
|