PHP Mailer 1.8 v1.8

Release Notes

Tested on elgg 1.8b2

  • can u make this pluggin cron triggered..?

  • @Thuvalpakshi what do you mean with cron triggered? perhaps the function phpmailer() instead of send the message immediately, will push a message in the tail and cron send the messages? or i don't understand.

  • There are *two "cron" situations :-

    1. Linux/OS CRON
    2. Elgg's psuedo CRON thingy (which I believe did not quite work as intended according one of the Elgg Team's recent posts)

    However -- why on earth do you want this PlugIn to be "cron-trigerred" ? What is your intent ? whatcha wanna accomplish ?

  • @ Angel Gabriel instead of sending immediately it should push the message in tail and cron send the message. this will reduce the server load.

    @ DhrupDeScoop Also if the site has more than 2000 members in a group and all members have chosen notify by email, then posting a comment for a discussion will appear only after sending 2000 mail notification.

    if server limit for sending emails is 1000 /hr then rest 1000 will be returned.

    Thats y I asked is it possible to make it cron triggered.

    Thank you

  • @Thuvalpakshi:
    But wouldn't the server load be the same regardless if the messages are sent immediately or collected via cron. If the sending is delayed via cron you might even make matters worse because if your server is not capable to send the amount of messages at once it surely will get complete overloaded if the message sending of ALL messages is triggered at once.

    Also, the restriction of number of messages could result in an ever-increasing number of un-sent messages. Let's take your example with a 1000 messages/hour restriction: 2000 messages need to be sent. 1000 are sent at the next cron job execution and 1000 are hold back. What happens if yet another posting is made in the meantime and yet another 2000 messages need to be sent? Now already 3000 messages would be in queue. Then the next posting...

  •  

    Which CRON ?

    1. Linux/OS CRON
    2. Elgg psuedo CRON

    Other Factors -- Hosting Type :- Shared, VPS, Dedicated ?

    One cannot discuss very much - without the prerequisite choice - those technologies are a couple of galaxies apart ;) 

    Did you ever look at Kevin Jardine's  ? := 

    Message Queue
    by Kevin Jardine
    First uploaded 18 June 2010 @ 8:03am
    email, cron

    Uses cron to send background mail jobs
    This plugin requires a properly set up Elgg cron system. It does nothing by itself. It provides a mechanism which allows other plugins to schedule background mail jobs.

    If you did not.. you missed the boat (queue? lolz) because Kevin removed that PlugIn due to an utterly pathetic and dismal lack of interest shown by the general Elgg community in returning any feedback what-so-ever !!!

     

  • Also "..if the site has more than 2000 members.." ?

    Does your site currently have > 2000 members in Groups ??

  • hi Angel, i tried this php mailer a few months ago and i couldn't get it working, because i'm a noob about this stuff, i'll now try again, i hope you are available for a bit of advice.

    thanks

    wayne

  • How do I get the the plugin in Portuguese? I'm willing to do the translation, if it does not exist yet

  • I installed PHP Mailer 1.8 and I have no problem ... or maybe the
    problem is that I see no difference!
    I appropriately configured the plugin, but the messages are sent as
    previously. Everything is working
    as previously. I can't understand the functional advantanges of this plugin.
    
    Thanks.
  • Im rather confused... if this plugin allows you to send html emails where do you write them? and would it allow you to mass email your users i.e. a newsletter?

  • I've released a 1.8 version of my plugin. It includes the updated PHPMailer lib. http://community.elgg.org/pg/plugins/project/384769/developer/costelloc/phpmailer



  • Welcome.. Was the same problem with work on it.. After hour i find right way. It work on it - http://community.elgg.org/plugins/384769/1.0/phpmailer so can work hire.

     

    1st - http://sadeczanie.com.pl/images/plugins.jpg - u must have all options like that !!

    2nd - go to file - mod/phpmailer/vendors/class.phpmailer.php - open in editor

    3rd - use sample from hire using your smtp details - http://sadeczanie.com.pl/images/class_phpmailer.rar

    Have good day ;) !!

  • hello to all friends,this is a great plugin with a small issue.The issue is in special characters  like greek or russian or any other special character except latins in SMTP. for many days i try to find a solutions and here is the solution for special characters. in file class.phpmailer remove the code and add that one

     

    <?php
    /*~ class.phpmailer.php
    .---------------------------------------------------------------------------.
    |  Software: PHPMailer - PHP email class                                    |
    |   Version: 2.3                                                            |
    |   Contact: via sourceforge.net support pages (also www.codeworxtech.com)  |
    |      Info: http://phpmailer.sourceforge.net                               |
    |   Support: http://sourceforge.net/projects/phpmailer/                     |
    | ------------------------------------------------------------------------- |
    |    Author: Andy Prevost (project admininistrator)                         |
    |    Author: Brent R. Matzelle (original founder)                           |
    | Copyright (c) 2004-2007, Andy Prevost. All Rights Reserved.               |
    | Copyright (c) 2001-2003, Brent R. Matzelle                                |
    | ------------------------------------------------------------------------- |
    |   License: Distributed under the Lesser General Public License (LGPL)     |
    |            http://www.gnu.org/copyleft/lesser.html                        |
    | This program is distributed in the hope that it will be useful - WITHOUT  |
    | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or     |
    | FITNESS FOR A PARTICULAR PURPOSE.                                         |
    | ------------------------------------------------------------------------- |
    | We offer a number of paid services (www.codeworxtech.com):                |
    | - Web Hosting on highly optimized fast and secure servers                 |
    | - Technology Consulting                                                   |
    | - Oursourcing (highly qualified programmers and graphic designers)        |
    '---------------------------------------------------------------------------'

    /**
     * PHPMailer - PHP email transport class
     * NOTE: Designed for use with PHP version 5 and up
     * @package PHPMailer
     * @author Andy Prevost
     * @copyright 2004 - 2008 Andy Prevost
     */

    class PHPMailer {

      /////////////////////////////////////////////////
      // PROPERTIES, PUBLIC
      /////////////////////////////////////////////////

      /**
       * Email priority (1 = High, 3 = Normal, 5 = low).
       * @var int
       */
      public $Priority          = 3;

      /**
       * Sets the CharSet of the message.
       * @var string
       */
      public $CharSet           = 'utf-8';

      /**
       * Sets the Content-type of the message.
       * @var string
       */
      public $ContentType       = 'text/plain';

      /**
       * Sets the Encoding of the message. Options for this are "8bit",
       * "7bit", "binary", "base64", and "quoted-printable".
       * @var string
       */
      public $Encoding          = '8bit';

      /**
       * Holds the most recent mailer error message.
       * @var string
       */
      public $ErrorInfo         = '';

      /**
       * Sets the From email address for the message.
       * @var string
       */
      public $From              = 'root@localhost';

      /**
       * Sets the From name of the message.
       * @var string
       */
      public $FromName          = 'Root User';

      /**
       * Sets the Sender email (Return-Path) of the message.  If not empty,
       * will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode.
       * @var string
       */
      public $Sender            = '';

      /**
       * Sets the Subject of the message.
       * @var string
       */
      public $Subject           = '';

      /**
       * Sets the Body of the message.  This can be either an HTML or text body.
       * If HTML then run IsHTML(true).
       * @var string
       */
      public $Body              = '';

      /**
       * Sets the text-only body of the message.  This automatically sets the
       * email to multipart/alternative.  This body can be read by mail
       * clients that do not have HTML email capability such as mutt. Clients
       * that can read HTML will view the normal Body.
       * @var string
       */
      public $AltBody           = '';

      /**
       * Sets word wrapping on the body of the message to a given number of
       * characters.
       * @var int
       */
      public $WordWrap          = 0;

      /**
       * Method to send mail: ("mail", "sendmail", or "smtp").
       * @var string
       */
      public $Mailer            = 'mail';

      /**
       * Sets the path of the sendmail program.
       * @var string
       */
      public $Sendmail          = '/usr/sbin/sendmail';

      /**
       * Path to PHPMailer plugins.  This is now only useful if the SMTP class
       * is in a different directory than the PHP include path.
       * @var string
       */
      public $PluginDir         = '';

      /**
       * Holds PHPMailer version.
       * @var string
       */
      public $Version           = "2.3";

      /**
       * Sets the email address that a reading confirmation will be sent.
       * @var string
       */
      public $ConfirmReadingTo  = '';

      /**
       * Sets the hostname to use in Message-Id and Received headers
       * and as default HELO string. If empty, the value returned
       * by SERVER_NAME is used or 'localhost.localdomain'.
       * @var string
       */
      public $Hostname          = '';

      /**
       * Sets the message ID to be used in the Message-Id header.
       * If empty, a unique id will be generated.
       * @var string
       */
      public $MessageID      = '';

      /////////////////////////////////////////////////
      // PROPERTIES FOR SMTP
      /////////////////////////////////////////////////

      /**
       * Sets the SMTP hosts.  All hosts must be separated by a
       * semicolon.  You can also specify a different port
       * for each host by using this format: [hostname:port]
       * (e.g. "smtp1.example.com:25;smtp2.example.com").
       * Hosts will be tried in order.
       * @var string
       */
      public $Host        = 'localhost';

      /**
       * Sets the default SMTP server port.
       * @var int
       */
      public $Port        = 25;

      /**
       * Sets the SMTP HELO of the message (Default is $Hostname).
       * @var string
       */
      public $Helo        = '';

      /**
       * Sets connection prefix.
       * Options are "", "ssl" or "tls"
       * @var string
       */
      public $SMTPSecure = "";

      /**
       * Sets SMTP authentication. Utilizes the Username and Password variables.
       * @var bool
       */
      public $SMTPAuth     = false;

      /**
       * Sets SMTP username.
       * @var string
       */
      public $Username     = '';

      /**
       * Sets SMTP password.
       * @var string
       */
      public $Password     = '';

      /**
       * Sets the SMTP server timeout in seconds. This function will not
       * work with the win32 version.
       * @var int
       */
      public $Timeout      = 10;

      /**
       * Sets SMTP class debugging on or off.
       * @var bool
       */
      public $SMTPDebug    = false;

      /**
       * Prevents the SMTP connection from being closed after each mail
       * sending.  If this is set to true then to close the connection
       * requires an explicit call to SmtpClose().
       * @var bool
       */
      public $SMTPKeepAlive = false;

      /**
       * Provides the ability to have the TO field process individual
       * emails, instead of sending to entire TO addresses
       * @var bool
       */
      public $SingleTo = false;

      /**
       * Provides the ability to change the line ending
       * @var string
       */
      public $LE              = "\r\n";

      /////////////////////////////////////////////////
      // PROPERTIES, PRIVATE
      /////////////////////////////////////////////////

      private $smtp            = NULL;
      private $to              = array();
      private $cc              = array();
      private $bcc             = array();
      private $ReplyTo         = array();
      private $attachment      = array();
      private $CustomHeader    = array();
      private $message_type    = '';
      private $boundary        = array();
      private $language        = array();
      private $error_count     = 0;
      private $sign_cert_file  = "";
      private $sign_key_file   = "";
      private $sign_key_pass   = "";

      /////////////////////////////////////////////////
      // METHODS, VARIABLES
      /////////////////////////////////////////////////

      /**
       * Sets message type to HTML.
       * @param bool $bool
       * @return void
       */
      public function IsHTML($bool) {
        if($bool == true) {
          $this->ContentType = 'text/html';
        } else {
          $this->ContentType = 'text/plain';
        }
      }

      /**
       * Sets Mailer to send message using SMTP.
       * @return void
       */
      public function IsSMTP() {
        $this->Mailer = 'smtp';
      }

      /**
       * Sets Mailer to send message using PHP mail() function.
       * @return void
       */
      public function IsMail() {
        $this->Mailer = 'mail';
      }

      /**
       * Sets Mailer to send message using the $Sendmail program.
       * @return void
       */
      public function IsSendmail() {
        $this->Mailer = 'sendmail';
      }

      /**
       * Sets Mailer to send message using the qmail MTA.
       * @return void
       */
      public function IsQmail() {
        $this->Sendmail = '/var/qmail/bin/sendmail';
        $this->Mailer   = 'sendmail';
      }

      /////////////////////////////////////////////////
      // METHODS, RECIPIENTS
      /////////////////////////////////////////////////

      /**
       * Adds a "To" address.
       * @param string $address
       * @param string $name
       * @return void
       */
      public function AddAddress($address, $name = '') {
        $cur = count($this->to);
        $this->to[$cur][0] = trim($address);
        $this->to[$cur][1] = $name;
      }

      /**
       * Adds a "Cc" address. Note: this function works
       * with the SMTP mailer on win32, not with the "mail"
       * mailer.
       * @param string $address
       * @param string $name
       * @return void
       */
      public function AddCC($address, $name = '') {
        $cur = count($this->cc);
        $this->cc[$cur][0] = trim($address);
        $this->cc[$cur][1] = $name;
      }

      /**
       * Adds a "Bcc" address. Note: this function works
       * with the SMTP mailer on win32, not with the "mail"
       * mailer.
       * @param string $address
       * @param string $name
       * @return void
       */
      public function AddBCC($address, $name = '') {
        $cur = count($this->bcc);
        $this->bcc[$cur][0] = trim($address);
        $this->bcc[$cur][1] = $name;
      }

      /**
       * Adds a "Reply-to" address.
       * @param string $address
       * @param string $name
       * @return void
       */
      public function AddReplyTo($address, $name = '') {
        $cur = count($this->ReplyTo);
        $this->ReplyTo[$cur][0] = trim($address);
        $this->ReplyTo[$cur][1] = $name;
      }

      /////////////////////////////////////////////////
      // METHODS, MAIL SENDING
      /////////////////////////////////////////////////

      /**
       * Creates message and assigns Mailer. If the message is
       * not sent successfully then it returns false.  Use the ErrorInfo
       * variable to view description of the error.
       * @return bool
       */
      public function Send() {
        $header = '';
        $body = '';
        $result = true;

        if((count($this->to) + count($this->cc) + count($this->bcc)) < 1) {
          $this->SetError($this->Lang('provide_address'));
          return false;
        }

        /* Set whether the message is multipart/alternative */
        if(!empty($this->AltBody)) {
          $this->ContentType = 'multipart/alternative';
        }

        $this->error_count = 0; // reset errors
        $this->SetMessageType();
        $header .= $this->CreateHeader();
        $body = $this->CreateBody();

        if($body == '') {
          return false;
        }

        /* Choose the mailer */
        switch($this->Mailer) {
          case 'sendmail':
            $result = $this->SendmailSend($header, $body);
            break;
          case 'smtp':
            $result = $this->SmtpSend($header, $body);
            break;
          case 'mail':
            $result = $this->MailSend($header, $body);
            break;
          default:
            $result = $this->MailSend($header, $body);
            break;
            //$this->SetError($this->Mailer . $this->Lang('mailer_not_supported'));
            //$result = false;
            //break;
        }

        return $result;
      }

      /**
       * Sends mail using the $Sendmail program.
       * @access public
       * @return bool
       */
      public function SendmailSend($header, $body) {
        if ($this->Sender != '') {
          $sendmail = sprintf("%s -oi -f %s -t", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));
        } else {
          $sendmail = sprintf("%s -oi -t", escapeshellcmd($this->Sendmail));
        }

        if(!@$mail = popen($sendmail, 'w')) {
          $this->SetError($this->Lang('execute') . $this->Sendmail);
          return false;
        }

        fputs($mail, $header);
        fputs($mail, $body);

        $result = pclose($mail);
        if (version_compare(phpversion(), '4.2.3') == -1) {
          $result = $result >> 8 & 0xFF;
        }
        if($result != 0) {
          $this->SetError($this->Lang('execute') . $this->Sendmail);
          return false;
        }

        return true;
      }

      /**
       * Sends mail using the PHP mail() function.
       * @access public
       * @return bool
       */
      public function MailSend($header, $body) {

        $to = '';
        for($i = 0; $i < count($this->to); $i++) {
          if($i != 0) { $to .= ', '; }
          $to .= $this->AddrFormat($this->to[$i]);
        }

        $toArr = split(',', $to);

        $params = sprintf("-oi -f %s", $this->Sender);
        if ($this->Sender != '' && strlen(ini_get('safe_mode'))< 1) {
          $old_from = ini_get('sendmail_from');
          ini_set('sendmail_from', $this->Sender);
          if ($this->SingleTo === true && count($toArr) > 1) {
            foreach ($toArr as $key => $val) {
              $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);
            }
          } else {
            $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);
          }
        } else {
          if ($this->SingleTo === true && count($toArr) > 1) {
            foreach ($toArr as $key => $val) {
              $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);
            }
          } else {
            $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header);
          }
        }

        if (isset($old_from)) {
          ini_set('sendmail_from', $old_from);
        }

        if(!$rt) {
          $this->SetError($this->Lang('instantiate'));
          return false;
        }

        return true;
      }

      /**
       * Sends mail via SMTP using PhpSMTP (Author:
       * Chris Ryan).  Returns bool.  Returns false if there is a
       * bad MAIL FROM, RCPT, or DATA input.
       * @access public
       * @return bool
       */
      public function SmtpSend($header, $body) {
        include_once($this->PluginDir . 'class.smtp.php');
        $error = '';
        $bad_rcpt = array();

        if(!$this->SmtpConnect()) {
          return false;
        }

        $smtp_from = ($this->Sender == '') ? $this->From : $this->Sender;
        if(!$this->smtp->Mail($smtp_from)) {
          $error = $this->Lang('from_failed') . $smtp_from;
          $this->SetError($error);
          $this->smtp->Reset();
          return false;
        }

        /* Attempt to send attach all recipients */
        for($i = 0; $i < count($this->to); $i++) {
          if(!$this->smtp->Recipient($this->to[$i][0])) {
            $bad_rcpt[] = $this->to[$i][0];
          }
        }
        for($i = 0; $i < count($this->cc); $i++) {
          if(!$this->smtp->Recipient($this->cc[$i][0])) {
            $bad_rcpt[] = $this->cc[$i][0];
          }
        }
        for($i = 0; $i < count($this->bcc); $i++) {
          if(!$this->smtp->Recipient($this->bcc[$i][0])) {
            $bad_rcpt[] = $this->bcc[$i][0];
          }
        }

        if(count($bad_rcpt) > 0) { // Create error message
          for($i = 0; $i < count($bad_rcpt); $i++) {
            if($i != 0) {
              $error .= ', ';
            }
            $error .= $bad_rcpt[$i];
          }
          $error = $this->Lang('recipients_failed') . $error;
          $this->SetError($error);
          $this->smtp->Reset();
          return false;
        }

        if(!$this->smtp->Data($header . $body)) {
          $this->SetError($this->Lang('data_not_accepted'));
          $this->smtp->Reset();
          return false;
        }
        if($this->SMTPKeepAlive == true) {
          $this->smtp->Reset();
        } else {
          $this->SmtpClose();
        }

        return true;
      }

      /**
       * Initiates a connection to an SMTP server.  Returns false if the
       * operation failed.
       * @access public
       * @return bool
       */
      public function SmtpConnect() {
        if($this->smtp == NULL) {
          $this->smtp = new SMTP();
        }

        $this->smtp->do_debug = $this->SMTPDebug;
        $hosts = explode(';', $this->Host);
        $index = 0;
        $connection = ($this->smtp->Connected());

        /* Retry while there is no connection */
        while($index < count($hosts) && $connection == false) {
          $hostinfo = array();
          if(eregi('^(.+):([0-9]+)$', $hosts[$index], $hostinfo)) {
            $host = $hostinfo[1];
            $port = $hostinfo[2];
          } else {
            $host = $hosts[$index];
            $port = $this->Port;
          }

          $tls = ($this->SMTPSecure == 'tls');
          $ssl = ($this->SMTPSecure == 'ssl');

          if($this->smtp->Connect(($ssl ? 'ssl://':'').$host, $port, $this->Timeout)) {

            $hello = ($this->Helo != '' ? $this->Helo : $this->ServerHostname());
            $this->smtp->Hello($hello);

            if($tls) {
              if(!$this->smtp->StartTLS()) {
                $this->SetError($this->Lang("tls"));
                $this->smtp->Reset();
                $connection = false;
              }

              //We must resend HELLO after tls negociation
              $this->smtp->Hello($hello);
            }

            $connection = true;
            if($this->SMTPAuth) {
              if(!$this->smtp->Authenticate($this->Username, $this->Password)) {
                $this->SetError($this->Lang('authenticate'));
                $this->smtp->Reset();
                $connection = false;
              }
            }
          }
          $index++;
        }
        if(!$connection) {
          $this->SetError($this->Lang('connect_host'));
        }

        return $connection;
      }

      /**
       * Closes the active SMTP session if one exists.
       * @return void
       */
      public function SmtpClose() {
        if($this->smtp != NULL) {
          if($this->smtp->Connected()) {
            $this->smtp->Quit();
            $this->smtp->Close();
          }
        }
      }

      /**
       * Sets the language for all class error messages.  Returns false
       * if it cannot load the language file.  The default language type
       * is English.
       * @param string $lang_type Type of language (e.g. Portuguese: "br")
       * @param string $lang_path Path to the language file directory
       * @access public
       * @return bool
       */
      function SetLanguage($lang_type = 'en', $lang_path = 'language/') {
        if( !(@include $lang_path.'phpmailer.lang-'.$lang_type.'.php') ) {
          $PHPMAILER_LANG = array();
          $PHPMAILER_LANG["provide_address"]      = 'You must provide at least one ' .
          $PHPMAILER_LANG["mailer_not_supported"] = ' mailer is not supported.';
          $PHPMAILER_LANG["execute"]              = 'Could not execute: ';
          $PHPMAILER_LANG["instantiate"]          = 'Could not instantiate mail function.';
          $PHPMAILER_LANG["authenticate"]         = 'SMTP Error: Could not authenticate.';
          $PHPMAILER_LANG["from_failed"]          = 'The following From address failed: ';
          $PHPMAILER_LANG["recipients_failed"]    = 'SMTP Error: The following ' .
          $PHPMAILER_LANG["data_not_accepted"]    = 'SMTP Error: Data not accepted.';
          $PHPMAILER_LANG["connect_host"]         = 'SMTP Error: Could not connect to SMTP host.';
          $PHPMAILER_LANG["file_access"]          = 'Could not access file: ';
          $PHPMAILER_LANG["file_open"]            = 'File Error: Could not open file: ';
          $PHPMAILER_LANG["encoding"]             = 'Unknown encoding: ';
          $PHPMAILER_LANG["signing"]              = 'Signing Error: ';
        }
        $this->language = $PHPMAILER_LANG;
        return true;
      }

      /////////////////////////////////////////////////
      // METHODS, MESSAGE CREATION
      /////////////////////////////////////////////////

      /**
       * Creates recipient headers.
       * @access public
       * @return string
       */
      public function AddrAppend($type, $addr) {
        $addr_str = $type . ': ';
        $addr_str .= $this->AddrFormat($addr[0]);
        if(count($addr) > 1) {
          for($i = 1; $i < count($addr); $i++) {
            $addr_str .= ', ' . $this->AddrFormat($addr[$i]);
          }
        }
        $addr_str .= $this->LE;

        return $addr_str;
      }

      /**
       * Formats an address correctly.
       * @access public
       * @return string
       */
      public function AddrFormat($addr) {
        if(empty($addr[1])) {
          $formatted = $this->SecureHeader($addr[0]);
        } else {
          $formatted = $this->EncodeHeader($this->SecureHeader($addr[1]), 'phrase') . " <" . $this->SecureHeader($addr[0]) . ">";
        }

        return $formatted;
      }

      /**
       * Wraps message for use with mailers that do not
       * automatically perform wrapping and for quoted-printable.
       * Original written by philippe.
       * @access public
       * @return string
       */
      public function WrapText($message, $length, $qp_mode = false) {
        $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE;
        // If utf-8 encoding is used, we will need to make sure we don't
        // split multibyte characters when we wrap
        $is_utf8 = (strtolower($this->CharSet) == "utf-8");

        $message = $this->FixEOL($message);
        if (substr($message, -1) == $this->LE) {
          $message = substr($message, 0, -1);
        }

        $line = explode($this->LE, $message);
        $message = '';
        for ($i=0 ;$i < count($line); $i++) {
          $line_part = explode(' ', $line[$i]);
          $buf = '';
          for ($e = 0; $e<count($line_part); $e++) {
            $word = $line_part[$e];
            if ($qp_mode and (strlen($word) > $length)) {
              $space_left = $length - strlen($buf) - 1;
              if ($e != 0) {
                if ($space_left > 20) {
                  $len = $space_left;
                  if ($is_utf8) {
                    $len = $this->UTF8CharBoundary($word, $len);
                  } elseif (substr($word, $len - 1, 1) == "=") {
                    $len--;
                  } elseif (substr($word, $len - 2, 1) == "=") {
                    $len -= 2;
                  }
                  $part = substr($word, 0, $len);
                  $word = substr($word, $len);
                  $buf .= ' ' . $part;
                  $message .= $buf . sprintf("=%s", $this->LE);
                } else {
                  $message .= $buf . $soft_break;
                }
                $buf = '';
              }
              while (strlen($word) > 0) {
                $len = $length;
                if ($is_utf8) {
                  $len = $this->UTF8CharBoundary($word, $len);
                } elseif (substr($word, $len - 1, 1) == "=") {
                  $len--;
                } elseif (substr($word, $len - 2, 1) == "=") {
                  $len -= 2;
                }
                $part = substr($word, 0, $len);
                $word = substr($word, $len);

                if (strlen($word) > 0) {
                  $message .= $part . sprintf("=%s", $this->LE);
                } else {
                  $buf = $part;
                }
              }
            } else {
              $buf_o = $buf;
              $buf .= ($e == 0) ? $word : (' ' . $word);

              if (strlen($buf) > $length and $buf_o != '') {
                $message .= $buf_o . $soft_break;
                $buf = $word;
              }
            }
          }
          $message .= $buf . $this->LE;
        }

        return $message;
      }

      /**
       * Finds last character boundary prior to maxLength in a utf-8
       * quoted (printable) encoded string.
       * Original written by Colin Brown.
       * @access public
       * @param string $encodedText utf-8 QP text
       * @param int    $maxLength   find last character boundary prior to this length
       * @return int
       */
      public function UTF8CharBoundary($encodedText, $maxLength) {
        $foundSplitPos = false;
        $lookBack = 3;
        while (!$foundSplitPos) {
          $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack);
          $encodedCharPos = strpos($lastChunk, "=");
          if ($encodedCharPos !== false) {
            // Found start of encoded character byte within $lookBack block.
            // Check the encoded byte value (the 2 chars after the '=')
            $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2);
            $dec = hexdec($hex);
            if ($dec < 128) { // Single byte character.
              // If the encoded char was found at pos 0, it will fit
              // otherwise reduce maxLength to start of the encoded char
              $maxLength = ($encodedCharPos == 0) ? $maxLength :
              $maxLength - ($lookBack - $encodedCharPos);
              $foundSplitPos = true;
            } elseif ($dec >= 192) { // First byte of a multi byte character
              // Reduce maxLength to split at start of character
              $maxLength = $maxLength - ($lookBack - $encodedCharPos);
              $foundSplitPos = true;
            } elseif ($dec < 192) { // Middle byte of a multi byte character, look further back
              $lookBack += 3;
            }
          } else {
            // No encoded character found
            $foundSplitPos = true;
          }
        }
        return $maxLength;
      }


      /**
       * Set the body wrapping.
       * @access public
       * @return void
       */
      public function SetWordWrap() {
        if($this->WordWrap < 1) {
          return;
        }

        switch($this->message_type) {
          case 'alt':
            /* fall through */
          case 'alt_attachments':
            $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap);
            break;
          default:
            $this->Body = $this->WrapText($this->Body, $this->WordWrap);
            break;
        }
      }

      /**
       * Assembles message header.
       * @access public
       * @return string
       */
      public function CreateHeader() {
        $result = '';

        /* Set the boundaries */
        $uniq_id = md5(uniqid(time()));
        $this->boundary[1] = 'b1_' . $uniq_id;
        $this->boundary[2] = 'b2_' . $uniq_id;

        $result .= $this->HeaderLine('Date', $this->RFCDate());
        if($this->Sender == '') {
          $result .= $this->HeaderLine('Return-Path', trim($this->From));
        } else {
          $result .= $this->HeaderLine('Return-Path', trim($this->Sender));
        }

        /* To be created automatically by mail() */
        if($this->Mailer != 'mail') {
          if(count($this->to) > 0) {
            $result .= $this->AddrAppend('To', $this->to);
          } elseif (count($this->cc) == 0) {
            $result .= $this->HeaderLine('To', 'undisclosed-recipients:;');
          }
        }

        $from = array();
        $from[0][0] = trim($this->From);
        $from[0][1] = $this->FromName;
        $result .= $this->AddrAppend('From', $from);

        /* sendmail and mail() extract Cc from the header before sending */
        if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->cc) > 0)) {
          $result .= $this->AddrAppend('Cc', $this->cc);
        }

        /* sendmail and mail() extract Bcc from the header before sending */
        if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->bcc) > 0)) {
          $result .= $this->AddrAppend('Bcc', $this->bcc);
        }

        if(count($this->ReplyTo) > 0) {
          $result .= $this->AddrAppend('Reply-to', $this->ReplyTo);
        }

        /* mail() sets the subject itself */
        if($this->Mailer != 'mail') {
          $result .= $this->HeaderLine('Subject', $this->EncodeHeader($this->SecureHeader($this->Subject)));
        }

        if($this->MessageID != '') {
          $result .= $this->HeaderLine('Message-ID',$this->MessageID);
        } else {
          $result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE);
        }
        $result .= $this->HeaderLine('X-Priority', $this->Priority);
        $result .= $this->HeaderLine('X-Mailer', 'PHPMailer (phpmailer.codeworxtech.com) [version ' . $this->Version . ']');

        if($this->ConfirmReadingTo != '') {
          $result .= $this->HeaderLine('Disposition-Notification-To', '<' . trim($this->ConfirmReadingTo) . '>');
        }

        // Add custom headers
        for($index = 0; $index < count($this->CustomHeader); $index++) {
          $result .= $this->HeaderLine(trim($this->CustomHeader[$index][0]), $this->EncodeHeader(trim($this->CustomHeader[$index][1])));
        }
        if (!$this->sign_key_file) {
          $result .= $this->HeaderLine('MIME-Version', '1.0');
          $result .= $this->GetMailMIME();
        }

        return $result;
      }

      /**
       * Returns the message MIME.
       * @access public
       * @return string
       */
      public function GetMailMIME() {
        $result = '';
        switch($this->message_type) {
          case 'plain':
            $result .= $this->HeaderLine('Content-Transfer-Encoding', $this->Encoding);
            $result .= sprintf("Content-Type: %s; charset=\"%s\"", $this->ContentType, $this->CharSet);
            break;
          case 'attachments':
            /* fall through */
          case 'alt_attachments':
            if($this->InlineImageExists()){
              $result .= sprintf("Content-Type: %s;%s\ttype=\"text/html\";%s\tboundary=\"%s\"%s", 'multipart/related', $this->LE, $this->LE, $this->boundary[1], $this->LE);
            } else {
              $result .= $this->HeaderLine('Content-Type', 'multipart/mixed;');
              $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');
            }
            break;
          case 'alt':
            $result .= $this->HeaderLine('Content-Type', 'multipart/alternative;');
            $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');
            break;
        }

        if($this->Mailer != 'mail') {
          $result .= $this->LE.$this->LE;
        }

        return $result;
      }

      /**
       * Assembles the message body.  Returns an empty string on failure.
       * @access public
       * @return string
       */
      public function CreateBody() {
        $result = '';

        if ($this->sign_key_file) {
          $result .= $this->GetMailMIME();
        }

        $this->SetWordWrap();

        switch($this->message_type) {
          case 'alt':
            $result .= $this->GetBoundary($this->boundary[1], '', 'text/plain', '');
            $result .= $this->EncodeString($this->AltBody, $this->Encoding);
            $result .= $this->LE.$this->LE;
            $result .= $this->GetBoundary($this->boundary[1], '', 'text/html', '');
            $result .= $this->EncodeString($this->Body, $this->Encoding);
            $result .= $this->LE.$this->LE;
            $result .= $this->EndBoundary($this->boundary[1]);
            break;
          case 'plain':
            $result .= $this->EncodeString($this->Body, $this->Encoding);
            break;
          case 'attachments':
            $result .= $this->GetBoundary($this->boundary[1], '', '', '');
            $result .= $this->EncodeString($this->Body, $this->Encoding);
            $result .= $this->LE;
            $result .= $this->AttachAll();
            break;
          case 'alt_attachments':
            $result .= sprintf("--%s%s", $this->boundary[1], $this->LE);
            $result .= sprintf("Content-Type: %s;%s" . "\tboundary=\"%s\"%s", 'multipart/alternative', $this->LE, $this->boundary[2], $this->LE.$this->LE);
            $result .= $this->GetBoundary($this->boundary[2], '', 'text/plain', '') . $this->LE; // Create text body
            $result .= $this->EncodeString($this->AltBody, $this->Encoding);
            $result .= $this->LE.$this->LE;
            $result .= $this->GetBoundary($this->boundary[2], '', 'text/html', '') . $this->LE; // Create the HTML body
            $result .= $this->EncodeString($this->Body, $this->Encoding);
            $result .= $this->LE.$this->LE;
            $result .= $this->EndBoundary($this->boundary[2]);
            $result .= $this->AttachAll();
            break;
        }

        if($this->IsError()) {
          $result = '';
        } else if ($this->sign_key_file) {
          $file = tempnam("", "mail");
          $fp = fopen($file, "w");
          fwrite($fp, $result);
          fclose($fp);
          $signed = tempnam("", "signed");

          if (@openssl_pkcs7_sign($file, $signed, "file://".$this->sign_cert_file, array("file://".$this->sign_key_file, $this->sign_key_pass), null)) {
            $fp = fopen($signed, "r");
            $result = '';
            while(!feof($fp)){
              $result = $result . fread($fp, 1024);
            }
            fclose($fp);
          } else {
            $this->SetError($this->Lang("signing").openssl_error_string());
            $result = '';
          }

          unlink($file);
          unlink($signed);
        }

        return $result;
      }

      /**
       * Returns the start of a message boundary.
       * @access public
       */
      public function GetBoundary($boundary, $charSet, $contentType, $encoding) {
        $result = '';
        if($charSet == '') {
          $charSet = $this->CharSet;
        }
        if($contentType == '') {
          $contentType = $this->ContentType;
        }
        if($encoding == '') {
          $encoding = $this->Encoding;
        }
        $result .= $this->TextLine('--' . $boundary);
        $result .= sprintf("Content-Type: %s; charset = \"%s\"", $contentType, $charSet);
        $result .= $this->LE;
        $result .= $this->HeaderLine('Content-Transfer-Encoding', $encoding);
        $result .= $this->LE;

        return $result;
      }

      /**
       * Returns the end of a message boundary.
       * @access public
       */
      public function EndBoundary($boundary) {
        return $this->LE . '--' . $boundary . '--' . $this->LE;
      }

      /**
       * Sets the message type.
       * @access public
       * @return void
       */
      public function SetMessageType() {
        if(count($this->attachment) < 1 && strlen($this->AltBody) < 1) {
          $this->message_type = 'plain';
        } else {
          if(count($this->attachment) > 0) {
            $this->message_type = 'attachments';
          }
          if(strlen($this->AltBody) > 0 && count($this->attachment) < 1) {
            $this->message_type = 'alt';
          }
          if(strlen($this->AltBody) > 0 && count($this->attachment) > 0) {
            $this->message_type = 'alt_attachments';
          }
        }
      }

      /* Returns a formatted header line.
       * @access public
       * @return string
       */
      public function HeaderLine($name, $value) {
        return $name . ': ' . $value . $this->LE;
      }

      /**
       * Returns a formatted mail line.
       * @access public
       * @return string
       */
      public function TextLine($value) {
        return $value . $this->LE;
      }

      /////////////////////////////////////////////////
      // CLASS METHODS, ATTACHMENTS
      /////////////////////////////////////////////////

      /**
       * Adds an attachment from a path on the filesystem.
       * Returns false if the file could not be found
       * or accessed.
       * @param string $path Path to the attachment.
       * @param string $name Overrides the attachment name.
       * @param string $encoding File encoding (see $Encoding).
       * @param string $type File extension (MIME) type.
       * @return bool
       */
      public function AddAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
        if(!@is_file($path)) {
          $this->SetError($this->Lang('file_access') . $path);
          return false;
        }

        $filename = basename($path);
        if($name == '') {
          $name = $filename;
        }

        $cur = count($this->attachment);
        $this->attachment[$cur][0] = $path;
        $this->attachment[$cur][1] = $filename;
        $this->attachment[$cur][2] = $name;
        $this->attachment[$cur][3] = $encoding;
        $this->attachment[$cur][4] = $type;
        $this->attachment[$cur][5] = false; // isStringAttachment
        $this->attachment[$cur][6] = 'attachment';
        $this->attachment[$cur][7] = 0;

        return true;
      }

      /**
       * Attaches all fs, string, and binary attachments to the message.
       * Returns an empty string on failure.
       * @access public
       * @return string
       */
      public function AttachAll() {
        /* Return text of body */
        $mime = array();

        /* Add all attachments */
        for($i = 0; $i < count($this->attachment); $i++) {
          /* Check for string attachment */
          $bString = $this->attachment[$i][5];
          if ($bString) {
            $string = $this->attachment[$i][0];
          } else {
            $path = $this->attachment[$i][0];
          }

          $filename    = $this->attachment[$i][1];
          $name        = $this->attachment[$i][2];
          $encoding    = $this->attachment[$i][3];
          $type        = $this->attachment[$i][4];
          $disposition = $this->attachment[$i][6];
          $cid         = $this->attachment[$i][7];

          $mime[] = sprintf("--%s%s", $this->boundary[1], $this->LE);
          //$mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $name, $this->LE);
          $mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $this->EncodeHeader($this->SecureHeader($name)), $this->LE);
          $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE);

          if($disposition == 'inline') {
            $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE);
          }

          //$mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", $disposition, $name, $this->LE.$this->LE);
          $mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", $disposition, $this->EncodeHeader($this->SecureHeader($name)), $this->LE.$this->LE);

          /* Encode as string attachment */
          if($bString) {
            $mime[] = $this->EncodeString($string, $encoding);
            if($this->IsError()) {
              return '';
            }
            $mime[] = $this->LE.$this->LE;
          } else {
            $mime[] = $this->EncodeFile($path, $encoding);
            if($this->IsError()) {
              return '';
            }
            $mime[] = $this->LE.$this->LE;
          }
        }

        $mime[] = sprintf("--%s--%s", $this->boundary[1], $this->LE);

        return join('', $mime);
      }

      /**
       * Encodes attachment in requested format.  Returns an
       * empty string on failure.
       * @access public
       * @return string
       */
      public function EncodeFile ($path, $encoding = 'base64') {
        if(!@$fd = fopen($path, 'rb')) {
          $this->SetError($this->Lang('file_open') . $path);
          return '';
        }
        if (function_exists('get_magic_quotes')) {
            function get_magic_quotes() {
                return false;
            }
    }
        if (PHP_VERSION < 6) {
          $magic_quotes = get_magic_quotes_runtime();
          set_magic_quotes_runtime(0);
        }
        $file_buffer  = file_get_contents($path);
        $file_buffer  = $this->EncodeString($file_buffer, $encoding);
        fclose($fd);
        if (PHP_VERSION < 6) { set_magic_quotes_runtime($magic_quotes); }
        return $file_buffer;
      }

      /**
       * Encodes string to requested format. Returns an
       * empty string on failure.
       * @access public
       * @return string
       */
      public function EncodeString ($str, $encoding = 'base64') {
        $encoded = '';
        switch(strtolower($encoding)) {
          case 'base64':
            $encoded = chunk_split(base64_encode($str), 76, $this->LE);
            break;
          case '7bit':
          case '8bit':
            $encoded = $this->FixEOL($str);
            if (substr($encoded, -(strlen($this->LE))) != $this->LE)
              $encoded .= $this->LE;
            break;
          case 'binary':
            $encoded = $str;
            break;
          case 'quoted-printable':
            $encoded = $this->EncodeQP($str);
            break;
          default:
            $this->SetError($this->Lang('encoding') . $encoding);
            break;
        }
        return $encoded;
      }

      /**
       * Encode a header string to best of Q, B, quoted or none.
       * @access public
       * @return string
       */
      public function EncodeHeader ($str, $position = 'text') {
        $x = 0;

        switch (strtolower($position)) {
          case 'phrase':
            if (!preg_match('/[\200-\377]/', $str)) {
              /* Can't use addslashes as we don't know what value has magic_quote

Stats

  • Category: Communication
  • License: GNU General Public License (GPL) version 2
  • Updated: 2014-11-17
  • Downloads: 3189
  • Recommendations: 6

Other Projects

View Gabriel Vargas's plugins