PHP Developers Network

A community of PHP developers offering assistance, advice, discussion, and friendship.
 
Loading
It is currently Tue Nov 13, 2018 2:15 am

All times are UTC - 5 hours




Post new topic Reply to topic  [ 53 posts ]  Go to page 1, 2, 3, 4  Next
Author Message
PostPosted: Fri May 05, 2006 6:29 am 
Offline
Breakbeat Nuttzer
User avatar

Joined: Wed Mar 24, 2004 8:57 am
Posts: 13098
Location: Melbourne, Australia
If you have a support request can you please post it in the "PHP Code" forum rather than in this thread since the thread was getting too long. Your request will be handled just the same. Thanks :)

Image

Official website:
http://www.swiftmailer.org/

Online Documentation:
http://www.swiftmailer.org/documentation/

Bugs/Tracking:
http://sourceforge.net/tracker/?group_id=170045

Donations:
http://sourceforge.net/donate/index.php?group_id=170045
The SourceForge link to PayPal sometimes doesn't work so the PayPal address is chris@w3style.co.uk ;)
(Donations are currently being used so I can get a new Mac. Total so far is £305 (17th Nov 2006) of £400 needed).

You are advised to download one of the archives from the website (or preferably sourceforge) rather than directly copying and pasting the code.

PHP5: [GZIP] Swift-2.1.17.tar.gz
PHP5: [ZIP] Swift-2.1.17.zip
PHP4: [GZIP] Swift-2.1.17-php4.tar.gz
PHP4: [ZIP] Swift-2.1.17-php4.zip
SourceForge Releases: http://sourceforge.net/project/showfile ... _id=170045

-----------------------------------------------------------------

This is a mailer class that uses sockets and avoids the torturous use of the mail() function.

Features:
  • Connect to an SMTP Server or use a binary on the local machine
  • Send Batch emails over a single connection (tested on my own low-spec PC, low-bandwidth connection to remote SMTP to send over 500 emails per minute)
  • Create multipart emails with MIME 1.0 support
  • Add attachments (even dynamically generated ones)
  • Use SMTP authentication (pluggable -- LOGIN, PLAIN, CRAM-MD5, POP3 Before SMTP)
  • Add custom headers
  • Multiple redundant connections and/or connection rotation
  • Fast Cc and Bcc handling
  • Unicode UTF-8 support, with auto detection
  • Batch emailing with multiple To's or without
  • Continues sending to batch when any recipients fail (other mailer classes stop when an address fails)
  • Send to thousands of recipients without cron
  • Request Read Receipts
  • Set Message Priority
  • Send inline images or other file types
  • TLS (STARTTLS) Encryption (used by Gmail servers)
  • Keep logs of all commands and responses with the server
  • Use SSL to connect securely (OpenSSH needs to be compiled with PHP)
  • Encode emails in different formats
  • Write your own connection handlers
  • Write plugins with incredible control over the behaviour of the class


Here's the basic components.

Swift.php
Syntax: [ Download ] [ Hide ]
<?php



/**

 * Swift Mailer: A Flexible PHP Mailer Class.

 *

 * Current functionality:

 *  

 *  * Send uses one single connection to the SMTP server

 *  * Doesn't rely on mail()

 *  * Custom Headers

 *  * Unlimited redundant connections (can be mixed type)

 *  * Connection cycling & load balancing

 *  * Sends Multipart messages, handles encoding

 *  * Sends Plain-text single-part emails

 *  * Fast Cc and Bcc handling

 *  * Immune to rejected recipients (sends to subsequent recipients w/out error)

 *  * Set Priority Level

 *  * Request Read Receipts

 *  * Unicode UTF-8 support with auto-detection

 *  * Auto-detection of SMTP/Sendmail details based on PHP & server configuration

 *  * Batch emailing with multiple To's or without

 *  * Support for multiple attachments

 *  * Sendmail (or other binary) support

 *  * Pluggable SMTP Authentication (LOGIN, PLAIN, MD5-CRAM, POP Before SMTP)

 *  * Secure Socket Layer connections (SSL)

 *  * Transport Layer security (TLS) - Gmail account holders!

 *  * Send mail with inline embedded images easily (or embed other file types)!

 *  * Loadable plugin support with event handling features

 *

 * @package     Swift

 * @version     2.1.16

 * @author      Chris Corbyn

 * @date        9th September 2006

 * @license http://www.gnu.org/licenses/lgpl.txt Lesser GNU Public License

 *

 * @copyright Copyright &copy; 2006 Chris Corbyn - All Rights Reserved.

 * @filesource

 *

 * -----------------------------------------------------------------------

 *

 *   This library is free software; you can redistribute it and/or

 *   modify it under the terms of the GNU Lesser General Public

 *   License as published by the Free Software Foundation; either

 *   version 2.1 of the License, or any later version.

 *

 *   This library is distributed in the hope that it will be useful,

 *   but WITHOUT ANY WARRANTY; without even the implied warranty of

 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU

 *   Lesser General Public License for more details.

 *

 *   You should have received a copy of the GNU Lesser General Public

 *   License along with this library; if not, write to

 *

 *   The Free Software Foundation, Inc.,

 *   51 Franklin Street,

 *   Fifth Floor,

 *   Boston,

 *   MA  02110-1301  USA

 *

 *    "Chris Corbyn" <chris@w3style.co.uk>

 *

 */




if (!defined('SWIFT_VERSION')) define('SWIFT_VERSION', '2.1.16');



/**

 * Swift Plugin Interface. Describes the methods which plugins should implement

 * @package Swift

 */


interface Swift_IPlugin

{

        /**

         * Required Properties

         *

         * private SwiftInstance;

         * public pluginName;

         */


       

        /**

         * Loads an instance of Swift to the Plugin

         * @param  object  SwiftInstance

         * @return  void

         */


        public function loadBaseObject(&$object);

       

        /**

         * Optional Methods to implement

         *

         * public function onLoad();

         * public function onClose();

         * public function onFail();

         * public function onError();

         * public function onBeforeSend();

         * public function onSend();

         * public function onBeforeCommand();

         * public function onCommand();

         * public function onLog();

         * public function onAuthenticate();

         * public function onFlush();

         * public function onResponse();

         */


}



/**

 * Swift Authenticator Interface. Describes the methods which authenticators should implement

 * @package     Swift

 */


interface Swift_IAuthenticator

{

        /**

         * Required Properties

         * private SwiftInstance;

         * public serverString;

         */


       

        /**

         * Loads an instance of Swift to the Plugin

         * @param  object  SwiftInstance

         * @return  void

         */


        public function loadBaseObject(&$object);

        /**

         * Executes the logic in the authentication mechanism

         * @param  string  username

         * @param  string  password

         * @return  bool  successful

         */


        public function run($username, $password);

       

}



/**

 * Swift Connection Handler Interface.

 * Describes the methods which connection handlers should implement

 * @package     Swift

 */


interface Swift_IConnection

{

        /**

         * Required properties

         *

         * public readHook;

         * public writeHook;

         * public error

         */


       

        /**

         * Establishes a connection with the MTA

         * @return  bool  connected

         */


        public function start();

        /**

         * Closes the connection with the MTA

         * @return  void

         */


        public function stop();

        /**

         * Returns a boolean value TRUE if the connection is active.

         * @return bool connected

         */


        public function isConnected();

}



/**

 * Swift Mailer Class.

 * Accepts connections to an MTA and deals with the sending and processing of

 * commands and responses.

 * @package     Swift

 */


class Swift

{

        /**

         * Plugins container

         * @var  array  plugins

         * @private

         */


        private $plugins = array();

        private $esmtp = false;

        private $_8bitmime = false;

        private $autoCompliance = false;

        /**

         * Whether or not Swift should send unique emails to all "To"

         * recipients or just bulk them together in the To header.

         * @var bool use_exact

         */


        private $useExactCopy = false;

        private $domain = 'SwiftUser';

        private $mimeBoundary;

        private $mimeWarning;

        /**

         * MIME Parts container

         * @var  array  parts

         * @private

         */


        private $parts = array();

        /**

         * Attachment data container

         * @var  array  attachments

         * @private

         */


        private $attachments = array();

        /**

         * Inline image container

         * @var  array  image parts

         * @private

         */


        private $images = array();

        /**

         * Response codes expected for commands

         * $command => $code

         * @var  array  codes

         * @private

         */


        private $expectedCodes = array(

                'ehlo' => 250,

                'helo' => 250,

                'mail' => 250,

                'rcpt' => 250,

                'data' => 354

        );

        /**

         * Blind-carbon-copy address container

         * @var array addresses

         */


        private $Bcc = array();

        /**

         * Carbon-copy address container

         * @var array addresses

         */


        private $Cc = array();

        /**

         * The address any replies will go to

         * @var string address

         */


        private $replyTo;

        /**

         * The addresses we're sending to

         * @var string address

         */


        private $to = array();

        /**

         * The sender of the email

         * @var string sender

         */


        private $from;

        /**

         * Priority value 1 (high) to 5 (low)

         * @var int priority (1-5)

         */


        private $priority = 3;

        /**

         * Whether a read-receipt is required

         * @var bool read receipt

         */


        private $readReceipt = false;

        /**

         * The max number of entires that can exist in the log

         * (saves memory)

         * @var int log size

         */


        private $maxLogSize = 30;

        /**

         * The address to which bounces are sent

         * @var string Return-Path:

         */


        private $returnPath;

       

        /**

         * Connection object (container holding a socket)

         * @var  object  connection

         */


        public $connection;

        /**

         * Authenticators container

         * @var  array  authenticators

         */


        public $authenticators = array();

        public $authTypes = array();

        /**

         * Holds the username used in authentication (if any)

         * @var string username

         */


        public $username;

        /**

         * Holds the password used in authentication (if any)

         * @var string password

         */


        public $password;

       

        public $charset = "ISO-8859-1";

        private $userCharset = false;

        /**

         * Boolean value representing if Swift has failed or not

         * @var  bool  failed

         */


        public $failed = false;

        /**

         * If Swift should clear headers etc automatically

         * @var bool autoFlush

         */


        public $autoFlush = true;

        /**

         * Numeric code from the last MTA response

         * @var  int  code

         */


        public $responseCode;

        /**

         * Keyword of the command being sent

         * @var string keyword

         */


        public $commandKeyword;

        /**

         * Last email sent or email about to be sent (dependant on location)

         * @var  array  commands

         */


        public $currentMail = array();

        /**

         * Email headers

         * @var  string  headers

         */


        public $headers;

        public $currentCommand = '';

        /**

         * Errors container

         * @var  array  errors

         */


        public $errors = array();

        /**

         * Log container

         * @var  array  transactions

         */


        public $transactions = array();

       

        public $lastTransaction;

        public $lastError;

        /**

         * The very most recent response received from the MTA

         * @var  string  response

         */


        public $lastResponse;

        /**

         * The total number of failed recipients

         * @var int failed

         */


        private $failCount = 0;

        /**

         * Number of failed recipients for this email

         * @var int failed

         */


        private $subFailCount = 0;

        /**

         * Number of addresses expected to pass this email

         * @var int recipients

         */


        private $numAddresses;

        /**

         * Container for any recipients rejected

         * @var array failed addresses

         */


        private $failedAddresses = array();

        /**

         * Number of commands which will be skipped

         */


        public $ignoreCommands = 0;

        /**

         * Number of commands skipped thus far

         */


        private $skippedCommands = 0;

       

        /**

         * Swift Constructor

         * @param  object  Swift_IConnection

         * @param  string  user_domain, optional

         */


        public function __construct(Swift_IConnection &$object, $domain=false)

        {

                if (!$domain) $domain = !empty($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : 'SwiftUser';

               

                $this->domain = $domain;

                $this->connection =& $object;



                $this->connect();

                // * Hey this library is FREE so it's not much to ask   But if you really do want to

                // remove this header then go ahead of course... what's GPL for?

                $this->headers = "X-Mailer: Swift ".SWIFT_VERSION." by Chris Corbyn\r\n";

                $this->mimeWarning = "This part of the E-mail should never be seen. If\r\n".

                "you are reading this, consider upgrading your e-mail\r\n".

                "client to a MIME-compatible client.";

        }

        /**

         * Connect to the server

         * @return bool connected

         */


        public function connect()

        {

                if (!$this->connection->start())

                {

                        $this->fail();

                        $error = 'Connection to the given MTA failed.';

                        if (!empty($this->connection->error)) $error .= ' The Connection Interface said: '.$this->connection->error;

                        $this->logError($error, 0);

                        return false;

                }

                else

                {

                        $this->handshake();

                        return true;

                }

        }

        /**

         * Returns TRUE if the connection is active.

         */


        public function isConnected()

        {

                return $this->connection->isConnected();

        }

        /**

         * Sends the standard polite greetings to the MTA and then

         * identifies the MTA's capabilities

         */


        public function handshake()

        {

                $this->commandKeyword = "";

                //What did the server greet us with on connect?

                $this->logTransaction();

                if ($this->supportsESMTP($this->lastResponse))

                {

                        //Just being polite

                        $list = $this->command("EHLO {$this->domain}\r\n");

                        $this->check8BitMime($this->lastResponse);

                       

                        $this->getAuthenticationMethods($list);

                       

                        $this->esmtp = true;

                }

                else $this->command("HELO {$this->domain}\r\n");

        }

        /**

         * Check if the server allows 8bit emails to be sent without quoted-printable encoding

         * @param string EHLO response

         */


        private function check8BitMime($string)

        {

                if (strpos($string, '8BITMIME')) $this->_8bitmime = true;

        }

        /**

         * Checks for Extended SMTP support

         * @param  string  MTA greeting

         * @return  bool  ESMTP

         * @private

         */


        private function supportsESMTP($greeting)

        {

                //Not mentiioned in RFC 2821 but this how it's done

                if (strpos($greeting, 'ESMTP')) return true;

                else return false;

        }

        /**

         * Set the maximum num ber of entries in the log

         * @param int size

         */


        public function setMaxLogSize($size)

        {

                $this->maxLogSize = (int) $size;

        }

        /**

         * Sets the priority level of the email

         * This must be 1 to 5 where 1 is highest

         * @param int priority

         */


        public function setPriority($level)

        {

                $level = (int) $level;

                if ($level < 1) $level = 1;

                if ($level > 5) $level = 5;

                switch ($level)

                {

                        case 1: case 2:

                        $this->addHeaders("X-Priority: $level\r\nX-MSMail-Priority: High");

                        break;

                        case 4: case 5:

                        $this->addHeaders("X-Priority: $level\r\nX-MSMail-Priority: Low");

                        break;

                        case 3: default:

                        $this->addHeaders("X-Priority: $level\r\nX-MSMail-Priority: Normal");

                }

        }

        /**

         * Set the return path address (Bounce detection)

         * @param string address

         */


        public function setReturnPath($address)

        {

                $this->returnPath = $this->getAddress($address);

        }

        /**

         * Request a read receipt from all recipients

         * @param bool request receipt

         */


        public function requestReadReceipt($request=true)

        {

                $this->readReceipt = (bool) $request;

        }

        /**

         * Set the character encoding were using

         * @param string charset

         */


        public function setCharset($string)

        {

                $this->charset = $string;

                $this->userCharset = $string;

        }

        /**

         * Whether or not Swift should send unique emails to all To recipients

         * @param bool unique

         */


        public function useExactCopy($use=true)

        {

                $this->useExactCopy = (bool) $use;

        }

        /**

         * Get the return path recipient

         */


        public function getReturnPath()

        {

                return $this->returnPath;

        }

        /**

         * Get the sender

         */


        public function getFromAddress()

        {

                return $this->from;

        }

        /**

         * Get Cc recipients

         */


        public function getCcAddresses()

        {

                return $this->Cc;

        }

        /**

         * Get Bcc addresses

         */


        public function getBccAddresses()

        {

                return $this->Bcc;

        }

        /**

         * Get To addresses

         */


        public function getToAddresses()

        {

                return $this->to;

        }

        /**

         * Get the list of failed recipients

         * @return array recipients

         */


        public function getFailedRecipients()

        {

                return $this->failedAddresses;

        }

        /**

         * Return the array of errors (if any)

         * @return array errors

         */


        public function getErrors()

        {

                return $this->errors;

        }

        /**

         * Return the conversation up to maxLogSize between the SMTP server and swift

         * @return array transactions

         */


        public function getTransactions()

        {

                return $this->transactions;

        }

        /**

         * Sets the Reply-To address used for sending mail

         * @param string address

         */


        public function setReplyTo($string)

        {

                $this->replyTo = $this->getAddress($string);

        }

        /**

         * Add one or more Blind-carbon-copy recipients to the mail

         * @param mixed addresses

         */


        public function addBcc($addresses)

        {

                $this->Bcc = array_merge($this->Bcc, $this->parseAddressList((array) $addresses));

        }

        /**

         * Add one or more Carbon-copy recipients to the mail

         * @param mixed addresses

         */


        public function addCc($addresses)

        {

                $this->Cc = array_merge($this->Cc, $this->parseAddressList((array) $addresses));

        }

        /**

         * Force swift to break lines longer than 76 characters long

         * @param  bool  resize

         */


        public function useAutoLineResizing($use=true)

        {

                $this->autoCompliance = (bool) $use;

        }

        /**

         * Associate a code with a command. Swift will fail quietly if the code

         * returned does not match.

         * @param  string  command

         * @param  int  code

         */


        public function addExpectedCode($command, $code)

        {

                $this->expectedCodes[$command] = (int) $code;

        }

        /**

         * Reads the EHLO return string to see what AUTH methods are supported

         * @param  string  EHLO response

         * @return  void

         * @private

         */


        private function getAuthenticationMethods($list)

        {

                preg_match("/^250[\-\ ]AUTH\ (.*)\r\n/m", $list, $matches);

                if (!empty($matches[1]))

                {

                        $types = explode(' ', $matches[1]);

                        $this->authTypes = $types;

                }

        }

        /**

         * Load a plugin object into Swift

         * @param  object  Swift_IPlugin

         * @param string plugin name

         * @return  void

         */


        public function loadPlugin(Swift_IPlugin &$object, $id=false)

        {

                if ($id) $object->pluginName = $id;

                $this->plugins[$object->pluginName] =& $object;

                $this->plugins[$object->pluginName]->loadBaseObject($this);



                if (method_exists($this->plugins[$object->pluginName], 'onLoad'))

                {

                        $this->plugins[$object->pluginName]->onLoad();

                }

        }

        /**

         * Fetch a reference to a plugin in Swift

         * @param  string  plugin name

         * @return  object  Swift_IPlugin

         */


        public function &getPlugin($name)

        {

                if (isset($this->plugins[$name]))

                {

                        return $this->plugins[$name];

                }

        }

        /**

         * Un-plug a loaded plugin. Returns false on failure.

         * @param string plugin_name

         * @return bool success

         */


        public function removePlugin($name)

        {

                if (!isset($this->plugins[$name])) return false;

               

                if (method_exists($this->plugins[$name], 'onUnload'))

                {

                        $this->plugins[$name]->onUnload();

                }

                unset($this->plugins[$name]);

                return true;

        }

        /**

         * Return the number of plugins loaded

         * @return int plugins

         */


        public function numPlugins()

        {

                return count($this->plugins);

        }

        /**

         * Trigger event handlers

         * @param  string  event handler

         * @return  void

         * @private

         */


        private function triggerEventHandler($func)

        {

                foreach ($this->plugins as $name => $object)

                {

                        if (method_exists($this->plugins[$name], $func))

                        {

                                $this->plugins[$name]->$func();

                        }

                }

        }

        /**

         * Attempt to load any authenticators from the Swift/ directory

         * @see  RFC 2554

         * @return  void

         * @private

         */


        private function loadDefaultAuthenticators()

        {

                $dir = dirname(__FILE__).'/Swift/Authenticator';

                if (file_exists($dir) && is_dir($dir))

                {

                        $handle = opendir($dir);

                        while ($file = readdir($handle))

                        {

                                if (preg_match('@^([a-zA-Z\d]*)\.php$@', $file, $matches))

                                {

                                        require_once($dir.'/'.$file);

                                        $class = 'Swift_Authenticator_'.$matches[1];

                                        $this->loadAuthenticator(new $class);

                                }

                        }

                        closedir($handle);

                }

        }

        /**

         * Use SMTP authentication

         * @param  string  username

         * @param  string  password

         * @return  bool  successful

         */


        public function authenticate($username, $password)

        {

                $this->username = $username;

                $this->password = $password;

       

                if (empty($this->authenticators)) $this->loadDefaultAuthenticators();

               

                if (!$this->esmtp || empty($this->authTypes))

                {

                        $this->logError('The MTA doesn\'t support any of Swift\'s loaded authentication mechanisms', 0);

                        return false;

                }

                foreach ($this->authenticators as $name => $object)

                {

                        //An asterisk means that the auth type is not advertised by ESMTP

                        if (in_array($name, $this->authTypes) || substr($name, 0, 1) == '*')

                        {

                                if ($this->authenticators[$name]->run($username, $password))

                                {

                                        $this->triggerEventHandler('onAuthenticate');

                                        return true;

                                }

                                else return false;

                        }

                }

                //If we get this far, no authenticators were used

                $this->logError('The MTA doesn\'t support any of Swift\'s loaded authentication mechanisms', 0);

                $this->fail();

                return false;

        }

        /**

         * Load an authentication mechanism object into Swift

         * @param  object  Swift_IAuthenticator

         * @return  void

         */


        public function loadAuthenticator(Swift_IAuthenticator &$object)

        {

                $this->authenticators[$object->serverString] =& $object;

                $this->authenticators[$object->serverString]->loadBaseObject($this);

        }

        /**

         * Get a unique multipart MIME boundary

         * @param  string  mail data, optional

         * @return  string  boundary

         * @private

         */


        private function getMimeBoundary($string=false)

        {

                $force = true;

                if (!$string)

                {

                        $force = false;

                        $string = implode('', $this->parts);

                        $string .= implode('', $this->attachments);

                }

                if ($this->mimeBoundary && !$force) return $this->mimeBoundary;

                else

                { //Make sure we don't (as if it would ever happen!) -

                  // produce a boundary that's actually in the email already

                        do

                        {

                                $this->mimeBoundary = '_=_swift-'.uniqid(rand(), true);

                        } while(strpos($string, $this->mimeBoundary));

                }

                return $this->mimeBoundary;

        }

        /**

         * Append a string to the message header

         * @param  string  headers

         * @return  void

         */


        public function addHeaders($string)

        {

                $this->headers .= preg_replace("/(?:\r|\n|^)[^:]*?:\ *(.*?)(?:\r|\n|$)/me", 'str_replace("$1", $this->safeEncodeHeader("$1"), "$0")', $string);

                if (substr($this->headers, -2) != "\r\n")

                        $this->headers .= "\r\n";

        }

        /**

         * Set the multipart MIME boundary (only works for first part)

         * @param  string  boundary

         * @return  void

         */


        public function setMimeBoundary($string)

        {

                $this->mimeBoundary = $string;

        }

        /**

         * Set the text that displays in non-MIME clients

         * @param  string  warning

         * @return  void

         */


        public function setMimeWarning($warning)

        {

                $this->mimeWarning = $warning;

        }

        /**

         * Tells Swift to clear out attachment, parts, headers etc

         * automatically upon sending - this is the default.

         * @param bool flush

         */


        public function autoFlush($flush=true)

        {

                $this->autoFlush = (bool) $flush;

        }

        /**

         * Empty out the MIME parts and attachments

         * @param  bool  reset headers

         * @return  void

         */


        public function flush($clear_headers=false)

        {

                $this->parts = array();

                $this->attachments = array();

                $this->images = array();

                $this->mimeBoundary = null;

                $this->Bcc = array();

                $this->to = array();

                $this->Cc = array();

                $this->replyTo = null;

                //See comment above the headers property above the constructor before editing this line! *

                if ($clear_headers) $this->headers = "X-Mailer: Swift ".SWIFT_VERSION." by Chris Corbyn\r\n";

                $this->triggerEventHandler('onFlush');

        }

        /**

         * Reset to

         */


        public function flushTo()

        {

                $this->to = array();

        }

        /**

         * Reset Cc

         */


        public function flushCc()

        {

                $this->Cc = array();

        }

        /**

         * Reset Bcc

         */


        public function flushBcc()

        {

                $this->Bcc = array();

        }

        /**

         * Reset parts

         */


        public function flushParts()

        {

                $this->parts = array();

                $this->images = array();

        }

        /**

         * Reset attachments

         */


        public function flushAttachments()

        {

                $this->attachments = array();

        }

        /**

         * Reset headers

         */


        public function flushHeaders()

        {

                $this->headers = "X-Mailer: Swift ".SWIFT_VERSION." by Chris Corbyn\r\n";

        }

        /**

         * Log an error in Swift::errors

         * @param  string  error string

         * @param  int  error number

         * @return  void

         */


        public function logError($errstr, $errno=0)

        {

                $this->errors[] = array(

                        'num' => $errno,

                        'time' => microtime(),

                        'message' => $errstr

                );

                $this->lastError = $errstr;

               

                $this->triggerEventHandler('onError');

        }

        /**

         * Log a transaction in Swift::transactions

         * @param  string  command

         * @return  void

         */


        public function logTransaction($command='')

        {

                $this->lastTransaction = array(

                        'command' => $command,

                        'time' => microtime(),

                        'response' => $this->getResponse()

                );

                $this->triggerEventHandler('onLog');

                if ($this->maxLogSize)

                {

                        $this->transactions = array_slice(array_merge($this->transactions, array($this->lastTransaction)), -$this->maxLogSize);

                }

                else $this->transactions[] = $this->lastTransaction;

        }

        /**

         * Read the data from the socket

         * @return  string  response

         * @private

         */


        private function getResponse()

        {

                if (!$this->connection->readHook || !$this->isConnected()) return false;

                $ret = "";

                while (true)

                {

                        $tmp = @fgets($this->connection->readHook);

                        $ret .= $tmp;

                        //The last line of SMTP replies have a space after the status number

                        // They do NOT have an EOF so while(!feof($socket)) will hang!

                        if (substr($tmp, 3, 1) == ' ' || $tmp == false) break;

                }

                $this->responseCode = $this->getResponseCode($ret);

                $this->lastResponse = $ret;

                $this->triggerEventHandler('onResponse');

                return $this->lastResponse;

        }

        /**

         * Get the number of the last server response

         * @param  string  response string

         * @return  int  response code

         * @private

         */


        private function getResponseCode($string)

        {

                return (int) sprintf("%d", $string);

        }

        /**

         * Get the first word of the command

         * @param  string  command

         * @return  string  keyword

         * @private

         */


        private function getCommandKeyword($comm)

        {

                if (false !== $pos = strpos($comm, ' '))

                {

                        return $this->commandKeyword = strtolower(substr($comm, 0, $pos));

                }

                else return $this->commandKeyword = strtolower(trim($comm));

        }

        /**

         * Send a reset command in the event of a problem

         */


        public function reset()

        {

                $this->command("RSET\r\n");

        }

        /**

         * Issue a command to the socket

         * @param  string  command

         * @return  string  response

         */


        public function command($comm)

        {

                //We'll usually ignore a certain sequence of commands if something screwed up

                if ($this->ignoreCommands)

                {

                        $this->skippedCommands++;

                        if ($this->skippedCommands >= $this->ignoreCommands)

                        {

                                $this->responseCode = -2; //Done (internal to swift)

                                $this->ignoreCommands = 0;

                                $this->skippedCommands = 0;

                        }

                        return true;

                }

               

                $this->currentCommand = ltrim($comm);

               

                $this->triggerEventHandler('onBeforeCommand');

               

                if (!$this->connection->writeHook || !$this->isConnected() || $this->failed)

                {

                        $this->logError('Error running command: '.trim($comm).'.  No connection available', 0);

                        return false;

                }



                $command_keyword = $this->getCommandKeyword($this->currentCommand);

               

                //We successfully got as far as asking to send the email so we can forget any failed addresses for now

                if ($command_keyword != 'rcpt' && $command_keyword != 'rset') $this->subFailCount = 0;

               

                //SMTP commands must end with CRLF

                if (substr($this->currentCommand, -2) != "\r\n") $this->currentCommand .= "\r\n";

               

                if (@fwrite($this->connection->writeHook, $this->currentCommand))

                {

                        $this->logTransaction($this->currentCommand);

                        if (array_key_exists($command_keyword, $this->expectedCodes))

                        {

                                if ($this->expectedCodes[$command_keyword] != $this->responseCode)

                                {

                                        //If a recipient was rejected

                                        if ($command_keyword == 'rcpt')

                                        {

                                                $this->failCount++;

                                                $this->failedAddresses[] = $this->getAddress($comm);

                                                //Some addresses may still work...

                                                if (++$this->subFailCount >= $this->numAddresses)

                                                {

                                                        //Sending failed, just RSET and don't send data to this recipient

                                                        $this->reset();

                                                        //So we can still cache the mail body in send()

                                                        $this->responseCode = -1; //Pending (internal to swift)

                                                        //Skip the next two commands (DATA and <mail>)

                                                        $this->ignoreCommands = 2;

                                                        $this->logError('Send Error: Sending to '.$this->subFailCount.' recipients rejected (bad response code).', $this->responseCode);

                                                        //But don't fail here.... these are usually not fatal

                                                }

                                        }

                                        else

                                        {

                                                $this->fail();

                                                $this->logError('MTA Error (Swift was expecting response code '.$this->expectedCodes[$command_keyword].' but got '.$this->responseCode.'): '.$this->lastResponse, $this->responseCode);

                                                return $this->hasFailed();

                                        }

                                }

                        }

                        $this->triggerEventHandler('onCommand');

                        return $this->lastResponse;

                }

                else return false;

        }

        /**

         * Splits lines longer than 76 characters to multiple lines

         * @param  string  text

         * @return  string chunked output

         */


        public function chunkSplitLines($string)

        {

                return wordwrap($string, 74, "\r\n");

        }

        /**

         * Add a part to a multipart message

         * @param  string  body

         * @param  string  content-type, optional

         * @param  string  content-transfer-encoding, optional

         * @return  void

         */


        public function addPart($string, $type='text/plain', $encoding=false)

        {

                if (!$this->userCharset && (strtoupper($this->charset) != 'UTF-8') && $this->detectUTF8($string)) $this->charset = 'UTF-8';

               

                if (!$encoding && $this->_8bitmime) $encoding = '8bit';

                elseif (!$encoding) $encoding = 'quoted-printable';

               

                $body_string = $this->encode($string, $encoding);

                if ($this->autoCompliance && $encoding != 'binary') $body_string = $this->chunkSplitLines($body_string);

                $ret = "Content-Type: $type; charset=\"{$this->charset}\"; format=flowed\r\n".

                                "Content-Transfer-Encoding: $encoding\r\n\r\n".

                                $body_string;

               

                if (strtolower($type) == 'text/html') $this->parts[] = $this->makeSafe($ret);

                else $this->parts = array_merge((array) $this->makeSafe($ret), $this->parts);

        }

        /**

         * Get the current number of parts in the email

         * @return int num parts

         */


        public function numParts()

        {

                return count($this->parts);

        }

        /**

         * Add an attachment to a multipart message.

         * Attachments are added as base64 encoded data.

         * @param  string  data

         * @param  string  filename

         * @param  string  content-type

         * @return  void

         */


        public function addAttachment($data, $filename, $type='application/octet-stream')

        {

                $this->attachments[] = "Content-Type: $type; ".

                                "name=\"$filename\";\r\n".

                                "Content-Transfer-Encoding: base64\r\n".

                                "Content-Description: $filename\r\n".

                                "Content-Disposition: attachment; ".

                                "filename=\"$filename\"\r\n\r\n".

                                chunk_split($this->encode($data, 'base64'));

        }

        /**

         * Get the current number of attachments in the mail

         * @return int num attachments

         */


        public function numAttachments()

        {

                return count($this->attachments);

        }

        /**

         * Insert an inline image and return it's name

         * These work like attachments but have a content-id

         * and are inline/related.

         * @param string path

         * @return string name

         */


        public function addImage($path)

        {

                if (!file_exists($path)) return false;

               

                $gpc = ini_get('magic_quotes_gpc');

                ini_set('magic_quotes_gpc', 0);

                $gpc_run = ini_get('magic_quotes_runtime');

                ini_set('magic_quotes_runtime', 0);

               

                $img_data = @getimagesize($path);

                if (!$img_data) return false;

               

                $type = image_type_to_mime_type($img_data[2]);

                $filename = basename($path);

                $data = file_get_contents($path);

                $cid = 'SWM'.md5(uniqid(rand(), true));

               

                $this->images[] = "Content-Type: $type\r\n".

                                "Content-Transfer-Encoding: base64\r\n".

                                "Content-Disposition: inline; ".

                                "filename=\"$filename\"\r\n".

                                "Content-ID: <$cid>\r\n\r\n".

                                chunk_split($this->encode($data, 'base64'));

               

                ini_set('magic_quotes_gpc', $gpc);

                ini_set('magic_quotes_runtime', $gpc_run);

               

                return 'cid:'.$cid;

        }

        /**

         * Insert an inline file and return it's name

         * These work like attachments but have a content-id

         * and are inline/related.

         * The data is the file contents itself (binary safe)

         * @param string file contents

         * @param string content-type

         * @param string filename

         * @param string content-id

         * @return string name

         */


        public function embedFile($data, $type='application/octet-stream', $filename=false, $cid=false)

        {

                if (!$cid) $cid = 'SWM'.md5(uniqid(rand(), true));

               

                if (!$filename) $filename = $cid;

               

                $this->images[] = "Content-Type: $type\r\n".

                                "Content-Transfer-Encoding: base64\r\n".

                                "Content-Disposition: inline; ".

                                "filename=\"$filename\"\r\n".

                                "Content-ID: <$cid>\r\n\r\n".

                                chunk_split($this->encode($data, 'base64'));

               

                return 'cid:'.$cid;

        }

        /**

         * Close the connection in the connecion object

         * @return  void

         */


        public function close()

        {

                if ($this->connection->writeHook && $this->isConnected())

                {

                        $this->command("QUIT\r\n");

                        $this->connection->stop();

                }

                $this->triggerEventHandler('onClose');

        }

        /**

         * Check if Swift has failed and stopped processing

         * @return  bool  failed

         */


        public function hasFailed()

        {

                return $this->failed;

        }

        /**

         * Force Swift to fail and stop processing

         * @return  void

         */


        public function fail()

        {

                $this->failed = true;

                $this->triggerEventHandler('onFail');

        }

        /**

         * Detect if a string contains multi-byte non-ascii chars that fall in the UTF-8 tanges

         * @param mixed input

         * @return bool

         */


        public function detectUTF8($string_in)

        {

                foreach ((array)$string_in as $string)

                {

                        if (preg_match('%(?:

                        [\xC2-\xDF][\x80-\xBF]                          # non-overlong 2-byte

                        |\xE0[\xA0-\xBF][\x80-\xBF]                     # excluding overlongs

                        |[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}      # straight 3-byte

                        |\xED[\x80-\x9F][\x80-\xBF]                     # excluding surrogates

                        |\xF0[\x90-\xBF][\x80-\xBF]{2}          # planes 1-3

                        |[\xF1-\xF3][\x80-\xBF]{3}                      # planes 4-15

                        |\xF4[\x80-\x8F][\x80-\xBF]{2}          # plane 16

                        )+%xs'
, $string)) return true;

                }

                return false;

        }

        /**

         * This function checks for 7bit *printable* characters

         * which excludes \r \n \t etc and so, is safe for use in mail headers

         * Actual permitted chars [\ !"#\$%&'\(\)\*\+,-\.\/0123456789:;<=>\?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\[\\\]\^_`abcdefghijklmnopqrstuvwxyz{\|}~]

         * Ranges \x00-\x1F are printer control sequences

         * \x7F is the ascii delete character

         * @param string input

         * @return bool

         */


        public function is7bitPrintable($string)

        {

                if (preg_match('/^[\x20-\x7E]*$/D', $string)) return true;

                else return false;

        }

        /**

         * This is harsh! It makes things safe for sending as command sequences in SMTP

         * Specifically the enveloping.  We could be extremely strict and implement what I planned on doing

         * here: http://www.swiftmailer.org/contrib/prop ... s-test.txt

         * @param string input

         * @return safe output

         */


        public function make7bitPrintable($string)

        {

                return preg_replace('/[^\x20-\x7E]/', '', $string);

        }

        /**

         * Encode a string (mail) in a given format

         * Currently supports:

         *  - BASE64

         *  - Quoted-Printable

         *  - Ascii 7-bit

         *  - Ascii 8bit

         *  - Binary (not encoded)

         *

         * @param  string  input

         * @param  string  encoding

         * @return  string  encoded output

         */


        public function encode($string, $type, $maxlen=false)

        {

                $type = strtolower($type);

               

                switch ($type)

                {

                        case 'base64':

                        return base64_encode($string);

                        break;

                        //

                        case 'quoted-printable':

                        return $this->quotedPrintableEncode($string, $maxlen);

                        //

                        case '7bit':

                        case '8bit':

                        break;

                        case 'binary':

                        default:

                        break;

                }

               

                return $string;

        }

        /**

         * Headers cannot have non-ascii or high ascii chars in them

         * @param mixed input

         * @return string encoded output (with encoding type)

         */


        public function safeEncodeHeader($string)

        {

                if (!is_array($string))

                {

                        if ($this->is7bitPrintable($string)) return $string;

                        else

                        {

                                //Check if the string contains address notation

                                $address_start = strrpos($string, '<');

                                $address_end = strrpos($string, '>');

                                $address = '';

                                //If the < and > are in the correct places

                                if (($address_start !== false) && $address_start < $address_end)

                                {

                                        //Then store the email address

                                        $address = substr($string, $address_start, ($address_end-$address_start+1));

                                        if (!$this->is7bitPrintable($address)) $address = $this->make7bitPrintable($address);

                                        //... and remove it from the string

                                        $string = substr($string, 0, $address_start);

                                }

                                $encoded = trim(chunk_split($this->encode($string, 'base64')));

                                $lines = explode("\r\n", $encoded);

                                return  '=?'.$this->charset.'?B?'.implode("?=\r\n =?{$this->charset}?B?", $lines).'?= '.$address;

                        }

                }

                else

                {

                        $ret = array();

                        foreach ($string as $line)

                        {

                                $ret[] = $this->safeEncodeHeader($line); //Recurse

                        }

                        return $ret;

                }

        }

        /**

         * Handles quoted-printable encoding

         * From php.net by user bendi at interia dot pl

         * @param  string  input

         * @param int maxlength

         * @return  string  encoded output

         * @private

         */


        private function quotedPrintableEncode($string, $maxlen=false)

        {

                if (!$maxlen) $maxlen = 73;

                $string = preg_replace('/[^\x21-\x3C\x3E-\x7E\x09\x20]/e', 'sprintf( "=%02x", ord ( "$0" ) ) ;', $string);

                preg_match_all('/.{1,'.$maxlen.'}([^=]{0,3})?/', $string, $matches);

                $sep = "=\r\n";

                return implode($sep, $matches[0]);

        }

        /**

         * Converts lone LF characters to CRLF

         * @param  string  input

         * @return  string  converted output

         */


        public function LFtoCRLF($string)

        {

                return preg_replace("@(?:(?<!\r)\n)|(?:\r(?!\n))@", "\r\n", $string);

        }

        /**

         * Prevents premature <CRLF>.<CRLF> strings

         * Converts any lone LF characters to CRLF

         * @param  string  input

         * @return  string  escaped output

         */


        public function makeSafe($string)

        {

                return str_replace("\r\n.", "\r\n..", $this->LFtoCRLF($string));

        }

        /**

         * Pulls an email address from a "Name" <add@ress> string

         * @param string input

         * @return string address

         */


        public function getAddress($string)

        {

                if (!$string) return null;

               

                if (preg_match('/^.*?<([^>]+)>\s*$/s', $string, $matches))

                {

                        return '<'.$this->make7bitPrintable($matches[1]).'>';

                }

                elseif (!preg_match('/<|>/', $string)) return '<'.$this->make7bitPrintable($string).'>';

                else return $this->make7bitPrintable($string);

        }

        /**

         * Builds the headers needed to reflect who the mail is sent to

         * Presently this is just the "To: " header

         * @param  string  address

         * @return  string  headers

         * @private

         */


        private function makeRecipientHeaders($address=false)

        {

                if ($address) return "To: ".$this->safeEncodeHeader($address)."\r\n";

                else

                {

                        $ret = "To: ".implode(",\r\n\t", $this->safeEncodeHeader($this->to))."\r\n";

                        if (!empty($this->Cc)) $ret .= "Cc: ".implode(",\r\n\t", $this->safeEncodeHeader($this->Cc))."\r\n";

                        return $ret;

                }

        }

        /**

         * Structure a given array of addresses into the 1-dim we want

         * @param array unstructured

         * @return array structured

         * @private

         */


        private function parseAddressList($u_array)

        {

                $ret = array();

                foreach ($u_array as $val)

                {

                        if (is_array($val)) $ret[] = '"'.$val[0].'" <'.$val[1].'>';

                        else $ret[] = $val;

                }

                return $ret;

        }

        /**

         * Send an email using Swift (send commands)

         * @param  string  to_address

         * @param  string  from_address

         * @param  string  subject

         * @param  string  body, optional

         * @param  string  content-type,optional

         * @param  string  content-transfer-encoding,optional

         * @return  bool  successful

         */


        public function send($to, $from, $subject, $body=false, $type='text/plain', $encoding=false)

        {

                if ((strtoupper($this->charset) != 'UTF-8') && $body && $this->detectUTF8($body) && !$this->userCharset) $this->charset = 'UTF-8';

                if ((strtoupper($this->charset) != 'UTF-8') && $this->detectUTF8($subject) && !$this->userCharset) $this->charset = 'UTF-8';

                if ((strtoupper($this->charset) != 'UTF-8') && $this->detectUTF8($to) && !$this->userCharset) $this->charset = 'UTF-8';

                if ((strtoupper($this->charset) != 'UTF-8') && $this->detectUTF8($from) && !$this->userCharset) $this->charset = 'UTF-8';

               

                if (!$encoding && $this->_8bitmime) $encoding = '8bit';

                elseif (!$encoding) $encoding = 'quoted-printable';

               

                $to = (array) $to;

                $this->to = $this->parseAddressList($to);

                //In these cases we just send the one email

                if ($this->useExactCopy || !empty($this->Cc) || !empty($this->Bcc))

                {

                        $this->currentMail = $this->buildMail(false, $from, $subject, $body, $type, $encoding, 1);

                        $this->triggerEventHandler('onBeforeSend');

                        foreach ($this->currentMail as $command)

                        {

                                //Number of successful addresses expected

                                $this->numAddresses = 1;

                               

                                if (is_array($command))

                                { //Commands can be returned as 1-dimensional arrays

                                        $this->numAddresses = count($command);

                                        foreach ($command as $c)

                                        {

                                                if (!$this->command($c))

                                                {

                                                        $this->logError('Sending failed on command: '.$c, 0);

                                                        return false;

                                                }

                                        }

                                }

                                else if (!$this->command($command))

                                {

                                        $this->logError('Sending failed on command: '.$command, 0);

                                        return false;

                                }

                        }

                        $this->triggerEventHandler('onSend');

                }

                else

                {

                        $get_body = true;

                        $cached_body = '';

                        foreach ($this->to as $address)

                        {

                                $this->currentMail = $this->buildMail($address, $from, $subject, $body, $type, $encoding, $get_body);

                                //If we have a cached version

                                if (!$get_body) $this->currentMail[] = $this->makeRecipientHeaders($address).$cached_body;

                                $this->triggerEventHandler('onBeforeSend');

                                foreach ($this->currentMail as $command)

                                {

                                        //This means we're about to send the DATA part

                                        if ($get_body && ($this->responseCode == 354 || $this->responseCode == -1))

                                        {

                                                $cached_body = $command;

                                                $command = $this->makeRecipientHeaders($address).$command;

                                        }

                                        if (is_array($command))

                                        {

                                                foreach ($command as $c)

                                                {

                                                        if (!$this->command($c))

                                                        {

                                                                $this->logError('Sending failed on command: '.$c, 0);

                                                                return false;

                                                        }

                                                }

                                        }

                                        else if (!$this->command($command))

                                        {

                                                $this->logError('Sending failed on command: '.$command, 0);

                                                return false;

                                        }

                                }

                                $this->triggerEventHandler('onSend');

                                $get_body = false;

                        }

                }

                if ($this->autoFlush) $this->flush(true); //Tidy up a bit

                return true;

        }

        /**

         * Builds the list of commands to send the email

         * The last command in the output is the email itself (DATA)

         * The commands are as follows:

         *  - MAIL FROM: <address> (0)

         *  - RCPT TO: <address> (1)

         *  - DATA (2)

         *  - <email> (3)

         *

         * @param  string  to_address

         * @param  string  from_address

         * @param  string  subject

         * @param  string  body, optional

         * @param  string  content-type, optional

         * @param  string  encoding, optional

         * @return  array  commands

         * @private

         */


        private function buildMail($to, $from, $subject, $body, $type='text/plain', $encoding='8bit', $return_data_part=true)

        {

                $date = date('r'); //RFC 2822 date

                $return_path = $this->returnPath ? $this->returnPath : $this->getAddress($from);

                $ret = array("MAIL FROM: ".$return_path."\r\n"); //Always

                //If the user specifies a different reply-to

                $reply_to = !empty($this->replyTo) ? $this->getAddress($this->replyTo) : $this->getAddress($from);

                //Standard headers

                $this->from = $from;

                $data = "From: ".$this->safeEncodeHeader($from)."\r\n".

                        "Reply-To: ".$this->safeEncodeHeader($reply_to)."\r\n".

                        "Subject: ".$this->safeEncodeHeader($subject)."\r\n".

                        "Date: $date\r\n";

                if ($this->readReceipt) $data .= "Disposition-Notification-To: ".$this->safeEncodeHeader($from)."\r\n";

               

                if (!$to) //Only need one mail if no address was given

                { //We'll collate the addresses from the class properties

                        $data .= $this->getMimeBody($body, $type, $encoding)."\r\n.\r\n";

                        $headers = $this->makeRecipientHeaders();

                        //Rcpt can be run several times

                        $rcpt = array();

                        foreach ($this->to as $address) $rcpt[] = "RCPT TO: ".$this->getAddress($address)."\r\n";

                        foreach ($this->Cc as $address) $rcpt[] = "RCPT TO: ".$this->getAddress($address)."\r\n";

                        $ret[] = $rcpt;

                        $ret[] = "DATA\r\n";

                        $ret[] = $headers.$this->headers.$data;

                        //Bcc recipients get to see their own Bcc header but nobody else's

                        foreach ($this->Bcc as $address)

                        {

                                $ret[] = "MAIL FROM: ".$this->getAddress($from)."\r\n";

                                $ret[] = "RCPT TO: ".$this->getAddress($address)."\r\n";

                                $ret[] = "DATA\r\n";

                                $ret[] = $headers."Bcc: ".$this->safeEncodeHeader($address)."\r\n".$this->headers.$data;

                        }

                }

                else //Just make this individual email

                {

                        if ($return_data_part) $mail_body = $this->getMimeBody($body, $type, $encoding);

                        $ret[] = "RCPT TO: ".$this->getAddress($to)."\r\n";

                        $ret[] = "DATA\r\n";

                        if ($return_data_part) $ret[] = $data.$this->headers.$mail_body."\r\n.\r\n";

                }

                return $ret;

        }

        /**

         * Returns the MIME-specific headers followed by the email

         * content as a string.

         * @param string body

         * @param string content-type

         * @param string encoding

         * @return string mime data

         * @private

         */


        private function getMimeBody($string, $type, $encoding)

        {

                if ($string) //Not using MIME parts

                {

                        $body = $this->encode($string, $encoding);

                        if ($this->autoCompliance) $body = $this->chunkSplitLines($body);

                        $data = "Content-Type: $type; charset=\"{$this->charset}\"; format=flowed\r\n".

                                "Content-Transfer-Encoding: $encoding\r\n\r\n".

                                $this->makeSafe($body);

                }

                else

                { //Build a full email from the parts we have

                        $boundary = $this->getMimeBoundary();

                        $encoding = '8bit';

                        $mixalt = 'alternative';

                        $alternative_boundary = $this->getMimeBoundary(implode($this->parts));



                        if (!empty($this->images))

                        {

                                $mixalt = 'mixed';

                                $related_boundary = $this->getMimeBoundary(implode($this->parts).implode($this->images));

                               

                                $message_body = "Content-Type: multipart/related; ".

                                        "boundary=\"{$related_boundary}\"\r\n\r\n".

                                        "--{$related_boundary}\r\n";

                               

                                $parts_body = "Content-Type: multipart/alternative; ".

                                        "boundary=\"{$alternative_boundary}\"\r\n\r\n".

                                        "--{$alternative_boundary}\r\n".

                                        implode("\r\n\r\n--$alternative_boundary\r\n", $this->parts).

                                        "\r\n--$alternative_boundary--\r\n";

                               

                                $message_body .= $parts_body.

                                        "--$related_boundary\r\n";

                               

                                $images_body = implode("\r\n\r\n--$related_boundary\r\n", $this->images);

                               

                                $message_body .= $images_body.

                                        "\r\n--$related_boundary--\r\n";

                               

                        }

                        else

                        {

                                if (!empty($this->attachments))

                                {

                                        $message_body = "Content-Type: multipart/alternative; ".

                                        "boundary=\"{$alternative_boundary}\"\r\n\r\n".

                                        "--{$alternative_boundary}\r\n".

                                        implode("\r\n\r\n--$alternative_boundary\r\n", $this->parts).

                                        "\r\n--$alternative_boundary--\r\n";

                                }

                                else $message_body = implode("\r\n\r\n--$boundary\r\n", $this->parts);

                        }

       

                        if (!empty($this->attachments)) //Make a sub-message that contains attachment data

                        {

                                $mixalt = 'mixed';

                                $message_body .= "\r\n\r\n--$boundary\r\n".

                                        implode("\r\n--$boundary\r\n", $this->attachments);

                        }

                       

                        $data = "MIME-Version: 1.0\r\n".

                                "Content-Type: multipart/{$mixalt};\r\n".

                                "       boundary=\"{$boundary}\"\r\n".

                                "Content-Transfer-Encoding: {$encoding}\r\n\r\n".

                                "{$this->mimeWarning}\r\n".

                                "--$boundary\r\n".

                                "$message_body\r\n".

                                "--$boundary--";

                }

                return $data;

        }

}



?>


Swift/Connection/SMTP.php
Syntax: [ Download ] [ Hide ]
<?php



/**

 * This is the SMTP handler for Swift Mailer, a PHP Mailer class.

 *

 * @package     Swift

 * @version     >= 2.0.0

 * @author      Chris Corbyn

 * @date        30th July 2006

 * @license     http://www.gnu.org/licenses/lgpl.txt Lesser GNU Public License

 *

 * @copyright Copyright &copy; 2006 Chris Corbyn - All Rights Reserved.

 * @filesource

 *

 *   This library is free software; you can redistribute it and/or

 *   modify it under the terms of the GNU Lesser General Public

 *   License as published by the Free Software Foundation; either

 *   version 2.1 of the License, or (at your option) any later version.

 *

 *   This library is distributed in the hope that it will be useful,

 *   but WITHOUT ANY WARRANTY; without even the implied warranty of

 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU

 *   Lesser General Public License for more details.

 *

 *   You should have received a copy of the GNU Lesser General Public

 *   License along with this library; if not, write to

 *

 *   The Free Software Foundation, Inc.,

 *   51 Franklin Street,

 *   Fifth Floor,

 *   Boston,

 *   MA  02110-1301  USA

 *

 *    "Chris Corbyn" <chris@w3style.co.uk>

 *

 */




if (!defined('SWIFT_OPEN')) define('SWIFT_OPEN', 0);

if (!defined('SWIFT_SSL')) define('SWIFT_SSL', 1);

if (!defined('SWIFT_TLS')) define('SWIFT_TLS', 2);

if (!defined('SWIFT_DEFAULT_PORT')) define('SWIFT_DEFAULT_PORT', 25);

if (!defined('SWIFT_SECURE_PORT')) define('SWIFT_SECURE_PORT', 465);

if (!defined('SWIFT_AUTO_DETECT')) define('SWIFT_AUTO_DETECT', -2);



/**

 * SMTP Connection Class.

 * Connects to a remote MTA and stores the connections internally

 * @package Swift

 */


class Swift_Connection_SMTP implements Swift_IConnection

{

        /**

         * Any errors we see

         * @var string error

         */


        public $error;

        /**

         * Just a boolean value for when we're connected

         * @var bool connected

         */


        public $connected = false;

        /**

         * SMTP Connection socket

         * @var resource        socket

         */


        public $socket;

        /**

         * SMTP Read part of I/O for Swift

         * @var resource        socket (reference)

         */


        public $readHook;

        /**

         * SMTP Write part of I/O for Swift

         * @var resource        socket (reference)

         */


        public $writeHook;

        /**

         * Number of seconds to try to connect for (non-settable)

         * @var int             seconds timeout

         */


        public $connectTimeout = 30;

        /**

         * SMTP server

         * @var resource        socket

         */


        public $server;

        /**

         * SMTP Port (default 25)

         * @var int             port number

         */


        public $port = SWIFT_DEFAULT_PORT;

        /**

         * Use SSL Encryption

         * @var bool    SSL

         */


        public $ssl;



        /**

         * Constructor

         * @param       string  SMTP server

         * @param       int             SMTP Port, optional

         * @param       bool    SSL

         */


        public function __construct($server, $port=false, $transport=SWIFT_OPEN)

        {

                if ($server == SWIFT_AUTO_DETECT) $server = @ini_get('SMTP');

                if ($port == SWIFT_AUTO_DETECT) $port = @ini_get('smtp_port');

               

                $this->server = $server;

                if ($port) $this->port = $port;

                $this->ssl = $transport;

                if ($transport && !$port)

                {

                        $this->port = SWIFT_SECURE_PORT;

                }

        }

        /**

         * Establishes a connection with the MTA

         * The SwiftInstance Object calls this

         *

         * @return      bool    connected

         */


        public function start()

        {

                return $this->connect();

        }

        /**

         * Establishes a connection with the MTA

         *

         * @return      bool    connected

         * @private

         */


        protected function connect()

        {

                $server = $this->server;

               

                switch ($this->ssl)

                {

                        case SWIFT_SSL: $protocol = 'ssl://';

                        break;

                        case SWIFT_TLS: $protocol = 'tls://';

                        break;

                        case SWIFT_OPEN:

                        default: $protocol = '';

                }

               

                $server = $protocol.$server;

               

                $this->socket = @fsockopen($server, $this->port, $errno, $errstr, $this->connectTimeout);

               

                $this->readHook =& $this->socket;

                $this->writeHook =& $this->socket;



                if (!$this->socket)

                {

                        $this->error = $errstr;

                        return $this->connected = false;

                }

                else return $this->connected = true;

        }

        /**

         * Closes the connection with the MTA

         * Called by the SwiftInstance object

         *

         * @return      void

         */


        public function stop()

        {

                $this->disconnect();

        }

        /**

         * Closes the connection with the MTA

         * @return      void

         */


        protected function disconnect()

        {

                if ($this->connected && $this->socket)

                {

                        fclose($this->socket);

                        $this->readHook = false;

                        $this->writeHook = false;

                        $this->socket = false;

                       

                        $this->connected = false;

                }

        }

        /**

         * Returns TRUE if the socket is connected

         * @return bool connected

         */


        public function isConnected()

        {

                return $this->connected;

        }

        /**

         * Change the default timeout from 30 seconds

         * @param int timeout secs

         * @return void

         */


        public function setConnectTimeout($seconds)

        {

                $this->connectTimeout = (int) $seconds;

        }

        /**

         * Destructor.  Closes any open connections

         */


        public function __destruct()

        {

                $this->disconnect();

        }

}



?>


I'd love feedback on this by the way.

Cheers,

d11


Last edited by Chris Corbyn on Thu Nov 30, 2006 2:25 pm, edited 69 times in total.

Top
 Profile  
 
 Post subject:
PostPosted: Fri May 05, 2006 6:32 am 
Offline
Admin
User avatar

Joined: Wed Aug 13, 2003 7:02 am
Posts: 4522
Location: York, UK
I think you should have a thanks section in the comments and put me in it ;)

Only kidding...

Looks great...definately got a use for this very soon. i can give more feedback then


Top
 Profile  
 
 Post subject:
PostPosted: Fri May 05, 2006 6:34 am 
Offline
Breakbeat Nuttzer
User avatar

Joined: Wed Mar 24, 2004 8:57 am
Posts: 13098
Location: Melbourne, Australia
Here's a handful examples - You'll need the download in order to see a more complete set.

Basic SMTP mailing
Syntax: [ Download ] [ Hide ]
<?php



require('../../Swift.php');

require('../../Swift/Connection/SMTP.php');



//The mailer will now establish a connection with the server

$mailer = new Swift(new Swift_Connection_SMTP('smtp.somedomain.com'));



//If anything goes wrong you can see what happened in the logs

if ($mailer->isConnected()) //Optional

{

        //Sends a simple email

        $mailer->send(

                '"Joe Bloggs" <joe@bloggs.com>',

                '"Your name" <you@yourdomain.com>',

                'Some Subject',

                "Hello Joe it's only me!"

        );

        //Closes cleanly... works without this but it's not as polite.

        $mailer->close();

}

else echo "The mailer failed to connect. Errors: ".print_r($mailer->errors, 1).". Log: ".print_r($mailer->transactions, 1);



?>


Basic sendmail mailing
Syntax: [ Download ] [ Hide ]
<?php



require('../../Swift.php');

require('../../Swift/Connection/Sendmail.php');



$mailer = new Swift(new Swift_Connection_Sendmail);



//If anything goes wrong you can see what happened in the logs

if ($mailer->isConnected())

{

        //Sends a simple email

        $mailer->send(

                '"Joe Bloggs" <joe@bloggs.com>',

                '"Your name" <you@yourdomain.com>',

                'Some Subject',

                "Hello Joe it's only me!"

        );

        //Closes cleanly... works without this but it's not as polite.

        $mailer->close();

}

else echo "The mailer failed to connect. Errors: ".print_r($mailer->errors, 1).". Log: ".print_r($mailer->transactions, 1);



?>


Batch mailing in MIME
Syntax: [ Download ] [ Hide ]
<?php



require('../../Swift.php');

require('../../Swift/Connection/SMTP.php');



//The mailer will now establish a connection with the server

$mailer = new Swift(Swift_Connection_SMTP('smtp.somedomain.com'));



$recipients = array(

        'joe@bloggs.com',

        'fred@perry.com',

        'japser@conran.com',

        'john@smith.com'

);



//If anything goes wrong you can see what happened in the logs

if ($mailer->isConnected())

{

        //Add as many parts as you need here

        $mailer->addPart('Some plain text part');

        $mailer->addPart('Some HTML <strong>part with bold</strong> text', 'text/html');

       

        //Leaving the body out of send() makes the mailer send a multipart message

        $mailer->send(

                $recipients,

                '"Your name" <you@yourdomain.com>',

                'Some Subject'

        );

       

        $mailer->close();

}

else echo "The mailer failed to connect. Errors: ".print_r($mailer->errors, 1).". Log: ".print_r($mailer->transactions, 1);



?>


Sending a multipart mail with attachments
Syntax: [ Download ] [ Hide ]
<?php



require('../../Swift.php');

require('../../Swift/Connection/SMTP.php');



//The mailer will now establish a connection with the server

$mailer = new Swift(Swift_Connection_SMTP('smtp.somedomain.com'));



$file = '../../files/durham.jpg';



//If anything goes wrong you can see what happened in the logs

if ($mailer->isConnected())

{

        //Add as many parts as you need here

        $mailer->addPart('Have a look at durhaml!!');

        $mailer->addPart('Have a look at durham <strong>NOW</strong>!!', 'text/html');



        //Add attachments as raw strings

        $mailer->addAttachment(file_get_contents($file), 'dur.jpg', 'image/jpeg');

       

        //Leaving the body out of send() makes the mailer send a multipart message

        $mailer->send(

                'joe@bloggs.com',

                '"Your name" <you@yourdomain.com>',

                'Some Subject'

        );

       

        $mailer->close();

}

else echo "The mailer failed to connect. Errors: ".print_r($mailer->errors, 1).". Log: ".print_r($mailer->transactions, 1);



?>


Authentication
Syntax: [ Download ] [ Hide ]
<?php



require('../../Swift.php');

require('../../Swift/Connection/SMTP.php');

require('../../Swift/Authenticator/LOGIN.php');



//The mailer will now establish a connection with the server

$mailer = new Swift(new Swift_Connection_SMTP('smtp.somedomain.com'));



//Load in an authenticator to use (this will hopefully be done automagically in future)

$mailer->loadAuthenticator(new Swift_Authenticator_LOGIN);



//If anything goes wrong you can see what happened in the logs

if ($mailer->isConnected()) //Optional

{

        //You can call authenticate() anywhere before calling send()

        if ($mailer->authenticate('username', 'password'))

        {

                //Sends a simple email

                $mailer->send(

                        '"Joe Bloggs" <joe@bloggs.com>',

                        '"Your name" <you@yourdomain.com>',

                        'Some Subject',

                        "Hello Joe it's only me!"

                );

        }

        else echo "Didn't authenticate to server";

       

        //Closes cleanly... works without this but it's not as polite.

        $mailer->close();

}

else echo "The mailer failed to connect. Errors: ".print_r($mailer->errors, 1).". Log: ".print_r($mailer->transactions, 1);



?>


An example plugin:
Syntax: [ Download ] [ Hide ]
<?php



/*

 An example of how to write a plugin for Swift.

 

 You should read Plugin_API in docs fully before writing

  your own plugins

 */




class Swift_Plugin_Example implements Swift_IPlugin

{

        // ** Required ** - Identifies this plugin

        public $pluginName = "Example";

       

        private $SwiftInstance;

       

        //Optional - run when the user instantiates the plguin

        public function __construct()

        {

                //

        }

       

        // ** Required ** - Swift loads passes itself here

        public function loadBaseObject(&$object)

        {

                $this->SwiftInstance =& $object;

               

                echo "SwiftInstance loaded into plugin...<br />";

        }



        public function onLoad()

        {

                echo "Plugin loaded fully...<br />";

        }



        public function onError()

        {

                echo "An error has occured.  See this error log:<br />";

                print_r($this->SwiftInstance->errors);

        }



        public function onBeforeSend()

        {

                echo "A message is about to be sent...<br />";

                $commands = $this->SwiftInstance->currentMail;

               

                echo "Here's the message data...<br />".

                $commands[3];

               

                $commands[3] = preg_replace('/\d+/', '{NUMBER}', $commands[3]);

               

                $this->SwiftInstance->currentMail = $commands;

               

                echo "But here's what Swift is about to send now...<br />".

                $commands[3];

        }



        public function onSend()

        {

                echo "A message was sent...<br />";

        }



        public function onClose()

        {

                echo "Swift has closed the connection...<br />";

        }



        public function onFail()

        {

                echo "Swift has failed, nothing else will execute, let's override it!<br />";

                $this->SwiftInstance->failed = false;

        }

}



?>


Last edited by Chris Corbyn on Mon Jul 31, 2006 10:08 am, edited 5 times in total.

Top
 Profile  
 
 Post subject:
PostPosted: Fri May 05, 2006 6:36 am 
Offline
Breakbeat Nuttzer
User avatar

Joined: Wed Mar 24, 2004 8:57 am
Posts: 13098
Location: Melbourne, Australia
Pimptastic wrote:
I think you should have a thanks section in the comments and put me in it ;)

Only kidding...

Looks great...definately got a use for this very soon. i can give more feedback then


Actually you are right Mark :D

(Pimp's referring to the fact he lent me a connection to his SMTP server for testing some authentication mechanisms).


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 09, 2006 11:31 am 
Offline
Forum Contributor
User avatar

Joined: Fri Jul 01, 2005 5:33 pm
Posts: 137
Location: Atlanta, GA
So is this Mail class finish yet so I can try it out? :D


Top
 Profile  
 
PostPosted: Tue May 09, 2006 11:58 am 
Offline
Tutorials Group

Joined: Sun Jan 04, 2004 11:30 pm
Posts: 2692
d11wtq wrote:
It offers pretty much all the things phpMailer offers but the complexity of the way you interface with it is impressively simpler.

Could you give examples for usage of phpmailer and your class, so I can compare and understand what you mean by this comment?

I'm a huge fan of phpmailer, but I'm always willing to look at better solutions. I'm just not seeing much advantage here over phpmailer that would make me want to switch (yet). Mind selling me a little bit on the idea? :)


Top
 Profile  
 
PostPosted: Tue May 09, 2006 5:29 pm 
Offline
Breakbeat Nuttzer
User avatar

Joined: Wed Mar 24, 2004 8:57 am
Posts: 13098
Location: Melbourne, Australia
Roja wrote:
d11wtq wrote:
It offers pretty much all the things phpMailer offers but the complexity of the way you interface with it is impressively simpler.

Could you give examples for usage of phpmailer and your class, so I can compare and understand what you mean by this comment?

I'm a huge fan of phpmailer, but I'm always willing to look at better solutions. I'm just not seeing much advantage here over phpmailer that would make me want to switch (yet). Mind selling me a little bit on the idea? :)


I've actually been developing this further and have made some more improvements flexibility-wise... I'll hopefully post the newer code tomorrow but essentially the changes I've made mean that you can write plugins for the class. The authentication stuff has gone that direction too, with the ones that were hard-coded into the core in this version now being auto-loaded if they can be found (i.e. the end-user shouldn't be affected but people can write addtional mechanisms if needs be).

I'll post some comparisons of this vs phpMailer too (I haven't benchmarked the two against each other yet but I don't see there being a huge difference there since most of the time taken will be due to the comunications with the server).

quadoc wrote:
So is this Mail class finish yet so I can try it out? :D


This is pretty fresh, and although working with PHP5 it'll no doubt be ongoing in development for a good while yet. Making it work with PHP4 should be pretty simple, in fact I did a quick conversion a few days ago but never had a chance to test it. Was it a PHP4 version you're looking for?


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 10, 2006 6:16 pm 
Offline
Breakbeat Nuttzer
User avatar

Joined: Wed Mar 24, 2004 8:57 am
Posts: 13098
Location: Melbourne, Australia
I've posted the latest code, now with plugin support.

NOTE: The version number has remained at 0.0.1 - I went back to scratch, and consider this the first official release.

~Roja: I've been writing documentation for a good part of the night, I'll put some side-by-side comparisons with phpMailer up here in a tick.

NOTE: I'm not attempting to out-do phpMailer; this started as a bit of fun but it's certainly another alternative to using phpMailer.

PHP4 version should be linked in with the downloads in the first post with 48 hours - there aren't any issues with the conversion, it just needs testing.


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 11, 2006 11:21 am 
Offline
Breakbeat Nuttzer
User avatar

Joined: Wed Mar 24, 2004 8:57 am
Posts: 13098
Location: Melbourne, Australia
PHP4 version added for download - see first post.


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 17, 2006 4:55 pm 
Offline
Forum Contributor
User avatar

Joined: Wed Aug 31, 2005 5:58 pm
Posts: 396
Location: Arkansas, USA
I just took a second to look over the examples... very nice work d11. Slick and easy to understand... I'll be using this sometime :)


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 18, 2006 1:07 am 
Offline
DevNet Master

Joined: Thu Oct 06, 2005 3:57 pm
Posts: 3360
Looks very cool indeed. Going to try it. Good work Chris!


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 16, 2006 5:12 am 
Offline
Breakbeat Nuttzer
User avatar

Joined: Wed Mar 24, 2004 8:57 am
Posts: 13098
Location: Melbourne, Australia
Copied from the Split thread...

Since it's been requested, here's a few side-by-side's against PHPMailer.

Some of these examples are only available in 1.1 due for release in a couple of days.

It's the first time I've done this actually so pretty interesting :) I'm aware of the fact that the Swift code looks tighter - I've just laid it out the way I code, copy and past and muck around if you want.

---------------------
Sending a plain email over SMTP:

In PHPMailer
Syntax: [ Download ] [ Hide ]
<?php



require('class.phpmailer.php');



$mail = new PHPMailer;



$mail->From = 'someone@tld';

$mail->FromName = 'Someone';



$mail->Host = 'smtp.host.tld';

$mail->Mailer = 'smtp';



$mail-Subject = 'Some subject';

$mail->Body = 'The email body';



$mail->AddAddress('recipient@tld', 'Recipient Name');



if (!$mail->Send()) echo 'Not sent!';



$mail->ClearAddresses();



?>


In Swift
Syntax: [ Download ] [ Hide ]
<?php



require('Swift.php');

require('Swift/Swift_SMTP_Connection.php');



$mail = new Swift(new Swift_SMTP_Connection('smtp.host.com'));



if (!$mail->send(

        '"Recipient Name" <recipient@tld>',

        '"Someone" <someone@tld>',

        'Some subject',

        'This is the body')) echo 'Not sent!';



?>


-------------------------------

Sending a mail with a HTML part and a plain text part

PHPMailer
Syntax: [ Download ] [ Hide ]
<?php



require('class.phpmailer.php');



$mail = new PHPMailer;



$mail->From = 'someone@tld';

$mail->FromName = 'Someone';



$mail->Host = 'smtp.host.tld';

$mail->Mailer = 'smtp';



$mail->IsHTML();

$mail-Subject = 'Some subject';

$mail->Body = '<em>HTML</em> part';

$mail->AltBody = 'Plain part';



$mail->AddAddress('recipient@tld', 'Recipient Name');



if (!$mail->Send()) echo 'Not sent!';



$mail->ClearAddresses();



?>


Swift
Syntax: [ Download ] [ Hide ]
<?php



require('Swift.php');

require('Swift/Swift_SMTP_Connection.php');



$mail = new Swift(new Swift_SMTP_Connection('smtp.host.com'));



$mail->addPart('Plain part');

$mail->addPart('<em>HTML</em> part', 'text/html');



if (!$mail->send(

        '"Recipient Name" <recipient@tld>',

        '"Someone" <someone@tld>',

        'Some subject')) echo 'Not sent!';



?>


----------------------------------------

Sending an email to 4 people independently:

In PHPMailer
Syntax: [ Download ] [ Hide ]
<?php



require('class.phpmailer.php');



$mail = new PHPMailer;



$recipients = array('one@tld', 'two@tld', 'three@tld', 'four@tld');



$mail->From = 'someone@tld';

$mail->FromName = 'Someone';



$mail->Host = 'smtp.host.tld';

$mail->Mailer = 'smtp';



$mail-Subject = 'Some subject';

$mail->Body = 'Body';



foreach ($recipients as $address)

{

        $mail->AddAddress($address);

       

        if (!$mail->Send()) echo 'Not sent!';

       

        $mail->ClearAddresses();

}



?>


Swift
Syntax: [ Download ] [ Hide ]
<?php



require('Swift.php');

require('Swift/Swift_SMTP_Connection.php');



$mail = new Swift(new Swift_SMTP_Connection('smtp.host.com'));



$recipients = array('one@tld', 'two@tld', 'three@tld', 'four@tld');



if (!$mail->send(

        $recipients,

        '"Someone" <someone@tld>',

        'Some subject',

        'Body')) echo 'Not sent!';



?>


--------------------------------

Sending an attachment:

PHPMailer
Syntax: [ Download ] [ Hide ]
<?php



require('class.phpmailer.php');



$mail = new PHPMailer;



$file = '../files/myimage.jpg';

$filename = 'My Image.jpg';



$mail->From = 'someone@tld';

$mail->FromName = 'Someone';



$mail->Host = 'smtp.host.tld';

$mail->Mailer = 'smtp';



$mail-Subject = 'Some subject';

$mail->Body = 'Body';



$mail->AddAddress('recipient@tld', 'Recipient Name');



$mail->AddAttachment($file, $filename);



if (!$mail->Send()) echo 'Not sent!';



$mail->ClearAddresses();

$mail->ClearAttachments();



?>


Swift
Syntax: [ Download ] [ Hide ]
<?php



require('Swift.php');

require('Swift/Swift_SMTP_Connection.php');



$mail = new Swift(new Swift_SMTP_Connection('smtp.host.com'));



$file = '../files/myimage.jpg';

$filename = 'My Image.jpg';



$mail->addPart('Body');



$mail->addAttachment(file_get_contents($file), $filename);



if (!$mail->send(

        '"Recipient Name" <recipient@tld>',

        '"Someone" <someone@tld>',

        'Some subject')) echo 'Not sent!';



?>


---------------------------------------------

Sending mail with an inline image:

PHPMailer
Syntax: [ Download ] [ Hide ]
<?php



require('class.phpmailer.php');



$mail = new PHPMailer;



$cid = 'abcdefg123456';

$image = '../files/myimage.jpg';



$mail->IsHTML();



$mail->From = 'someone@tld';

$mail->FromName = 'Someone';



$mail->Host = 'smtp.host.tld';

$mail->Mailer = 'smtp';



$mail-Subject = 'Some subject';

$mail->Body = '<strong>So here is where we went!</strong><br />

<img src="cid:'
.$cid.'" alt="Somewhere" /><br />

Pretty nice eh?'
;



$mail->AddEmmbeddedImage($file, $cid);



$mail->AddAddress('recipient@tld', 'Recipient Name');



if (!$mail->Send()) echo 'Not sent!';



$mail->ClearAddresses();

$mail->ClearAttachments();



?>


Swift
Syntax: [ Download ] [ Hide ]
<?php



require('Swift.php');

require('Swift/Swift_SMTP_Connection.php');



$mail = new Swift(new Swift_SMTP_Connection('smtp.host.com'));



$image = '../files/myimage.jpg';



$mail->addPart('<strong>So here is where we went!</strong><br />

<img src="'
.$mail->addImage($image).'" alt="Somewhere" /><br />

Pretty nice eh?'
, 'text/html');



if (!$mail->send(

        '"Recipient Name" <recipient@tld>',

        '"Someone" <someone@tld>',

        'Some subject')) echo 'Not sent!';



?>


-----------------------------------------

Relaying mail via Gmail servers (TLS encryption)

PHPMailer
Syntax: [ Download ] [ Hide ]
<?php



/** Forget it - TLS is not supported **/



?>


Swift
Syntax: [ Download ] [ Hide ]
<?php



require('Swift.php');

require('Swift/Swift_SMTP_Connection.php');



//I had this automated but it was flaky - I'll try to remove the need to do this again

$mail = new Swift(new Swift_SMTP_Connection('smtp.gmail.com', false, SWIFT_TLS));



$mail->authenticate('user@gmail.com', 'pass');



if (!$mail->send(

        '"Recipient Name" <recipient@tld>',

        '"Someone" <someone@tld>',

        'Some subject',

        'The body')) echo 'Not sent!';



?>


Haven't had time to benchmark yet... was this what you were looking for though?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 16, 2006 5:14 am 
Offline
Breakbeat Nuttzer
User avatar

Joined: Wed Mar 24, 2004 8:57 am
Posts: 13098
Location: Melbourne, Australia
Copied from Split thread....

First official plugin now bundled with 1.1.2 :)

It's an anti-flood plugin. On some shared hosts and some SMTP servers there is a limit of, for example 10 emails sent per connetion. This automatically politely closes the connection at the limit you set, and then opens a fresh one. This happens in the middle of Swift sending a batch email but without actually interfering with anything that would cause things to stop working.

Syntax: [ Download ] [ Hide ]
<?php



/**

 * Anti-Flood plugin for Swift Mailer, a PHP Mailer class.

 *

 * @package     Swift

 * @version     >= 1.1.2

 * @author      Chris Corbyn

 * @date        4th June 2006

 * @license     http://www.gnu.org/licenses/lgpl.txt Lesser GNU Public License

 *

 * @copyright Copyright &copy; 2006 Chris Corbyn - All Rights Reserved.

 * @filesource

 *

 *   This library is free software; you can redistribute it and/or

 *   modify it under the terms of the GNU Lesser General Public

 *   License as published by the Free Software Foundation; either

 *   version 2.1 of the License, or (at your option) any later version.

 *

 *   This library is distributed in the hope that it will be useful,

 *   but WITHOUT ANY WARRANTY; without even the implied warranty of

 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU

 *   Lesser General Public License for more details.

 *

 *   You should have received a copy of the GNU Lesser General Public

 *   License along with this library; if not, write to

 *

 *   The Free Software Foundation, Inc.,

 *   51 Franklin Street,

 *   Fifth Floor,

 *   Boston,

 *   MA  02110-1301  USA

 *

 *    "Chris Corbyn" <chris@w3style.co.uk>

 *

 */




class Swift_Anti_Flood_Plugin implements Swift_IPlugin

{

        /**

         * Name of the plugin (identifier)

         * @var string plugin id

         */


        public $pluginName = 'Anti_Flood';

        /**

         * The maximum number of messages to send

         * over a single connection

         * @var int max messages

         */


        public $maxMessages;

        /**

         * The time to wait for before reconnecting

         * @var int sleep seconds

         */


        public $sleep;

        /**

         * Current messages sent since last reconnect

         * or plugin loading.

         * @var int current messages

         */


        private $currMessages = 0;

        /**

         * Contains a reference to the main swift object.

         * @var object swiftInstance

         */


        private $swiftInstance;

       

        /**

         * Constructor.

         * @param int max messages, optional

         * @return void

         */


        public function __construct($max=10, $sleep=0)

        {

                $this->maxMessages = (int) $max;

                $this->sleep = (int) $sleep;

        }

        /**

         * Load in Swift

         * @param object SwiftInstance

         */


        public function loadBaseObject(&$object)

        {

                $this->swiftInstance =& $object;

        }

        /**

         * Event handler for onSend.

         */


        public function onSend()

        {

                $this->currMessages++;

                if ($this->currMessages >= $this->maxMessages)

                {

                        $this->reconnect();

                        $this->currMessages = 0;

                }

        }

        /**

         * Reconnect to the server

         */


        private function reconnect()

        {

                $this->swiftInstance->close();

               

                //Wait for N seconds if needed to give the server a rest

                if ($this->sleep) sleep($this->sleep);

               

                $this->swiftInstance->connect();

                //Re-authenticate if needs be

                if (!empty($this->swiftInstance->username))

                {

                        $this->swiftInstance->authenticate(

                                $this->swiftInstance->username,

                                $this->swiftInstance->password

                        );

                }

        }

}



?>


Usage:

Syntax: [ Download ] [ Hide ]
$swift = new Swift($connectionObject);



$swift->loadPlugin(new Swift_Anti_Flood_Plugin(10)); //The 10 is default in any case



/* Go ahead and send out batch mail as usual */


Last edited by Chris Corbyn on Sat Jun 17, 2006 3:18 am, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 16, 2006 5:15 am 
Offline
Breakbeat Nuttzer
User avatar

Joined: Wed Mar 24, 2004 8:57 am
Posts: 13098
Location: Melbourne, Australia
Copied from Split thread...

Another plugin.

It's for verbose errors. This was pretty much needed since some people don't like having to do a check themselves if swift has failed.

With this plugin you'll get errors to the effect of:

Quote:
Error running command: MAIL FROM: . No connection available near Swift::send in /home/d11wtq/public_html/Swift-1.1.4/test.php on line 22

Sending failed on command: MAIL FROM: near Swift::send in /home/d11wtq/public_html/Swift-1.1.4/test.php on line 22



Syntax: [ Download ] [ Hide ]
<?php



/**

 * Error handling plugin for Swift Mailer, a PHP Mailer class.

 *

 * @package     Swift

 * @version     >= 0.0.4

 * @author      Chris Corbyn

 * @date        8th June 2006

 * @license     http://www.gnu.org/licenses/lgpl.txt Lesser GNU Public License

 *

 * @copyright Copyright &copy; 2006 Chris Corbyn - All Rights Reserved.

 * @filesource

 *

 *   This library is free software; you can redistribute it and/or

 *   modify it under the terms of the GNU Lesser General Public

 *   License as published by the Free Software Foundation; either

 *   version 2.1 of the License, or (at your option) any later version.

 *

 *   This library is distributed in the hope that it will be useful,

 *   but WITHOUT ANY WARRANTY; without even the implied warranty of

 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU

 *   Lesser General Public License for more details.

 *

 *   You should have received a copy of the GNU Lesser General Public

 *   License along with this library; if not, write to

 *

 *   The Free Software Foundation, Inc.,

 *   51 Franklin Street,

 *   Fifth Floor,

 *   Boston,

 *   MA  02110-1301  USA

 *

 *    "Chris Corbyn" <chris@w3style.co.uk>

 *

 */




class Swift_Errors_Plugin implements Swift_IPlugin

{

        /**

         * Name of the plugin (identifier)

         * @var string plugin id

         */


        public $pluginName = 'Errors';

        /**

         * Contains a reference to the main swift object.

         * @var object swiftInstance

         */


        private $swiftInstance;

        /**

         * The norm is the echo and continue.

         * Settting this to TRUE makes it echo the die()

         * @var bool halt

         */


        private $halt;

       

        /**

         * Constructor.

         * @param bool halt (if the script should die() on error)

         */


        public function __construct($halt=false)

        {

                $this->halt = (bool) $halt;

        }

        /**

         * Load in Swift

         * @param object SwiftInstance

         */


        public function loadBaseObject(&$object)

        {

                $this->swiftInstance =& $object;

        }

        /**

         * Event handler for onError

         */


        public function onError()

        {

                $this_error = $this->swiftInstance->lastError;

               

                $error_info = $this->getErrorStartPoint();

               

                if (!empty($error_info['class'])) $class = $error_info['class'].'::';

                else $class = '';

               

                $file_info = ' near '.$class.$error_info['function'].

                        ' in <strong>'.$error_info['file'].'</strong> on line <strong>'.

                        $error_info['line'].'</strong><br />';

               

                $output = '<br />'.$this_error.$file_info;

                echo $output;

                if ($this->halt) exit();

        }

        /**

         * Get the command that caused the error

         */


        private function getErrorStartPoint()

        {

                $trace = debug_backtrace();

                $start = array_pop($trace);

                return array(

                        'file' => $start['file'],

                        'line' => $start['line'],

                        'class' => $start['class'],

                        'function' => $start['function']

                );

        }

}



?>


Now I have a question. I'm just echoing these errors. The problem being now that you can't use "@" to surpress the error. It shouldn't really matter because you wouldn't load the plugin if you were gonna surpress errors but still I'd like to tweak it if I can (at least in the PHP5 version). I tried using trigger_error() but there was one major flaw. It spits out the file info for the plugin trigger_error() is called from when I want to generate my own user level warning without that info in it.

Anybody know a workaround? :)


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 16, 2006 5:22 am 
Offline
Breakbeat Nuttzer
User avatar

Joined: Wed Mar 24, 2004 8:57 am
Posts: 13098
Location: Melbourne, Australia
NOTE: This thread has been split off to here: http://forums.devnetwork.net/viewtopic.php?p=265101

The number of support requests in this single thread was getting too long so the thread has now been split. If you have a support request please open a new thread in the "PHP Code" forum and I will deal with it in exactly the same way and in just the same amount of time.

Feature Requests/Bugs and general critique/comments are still welcome here however.

Thanks,

d11


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 53 posts ]  Go to page 1, 2, 3, 4  Next

All times are UTC - 5 hours


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
Powered by phpBB® Forum Software © phpBB Group