/applicationv2/libraries/v2/phpmailer/class.phpmailer.php
PHP | 3391 lines | 2092 code | 216 blank | 1083 comment | 316 complexity | 65776ff39c853ac7bc0e80eb02cc0abf MD5 | raw file
Possible License(s): LGPL-2.1
Large files files are truncated, but you can click here to view the full file
- <?php
- /**
- * PHPMailer - PHP email creation and transport class.
- * PHP Version 5.0.0
- * Version 5.2.7
- * @package PHPMailer
- * @link https://github.com/PHPMailer/PHPMailer/
- * @author Marcus Bointon (coolbru) <phpmailer@synchromedia.co.uk>
- * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
- * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
- * @author Brent R. Matzelle (original founder)
- * @copyright 2013 Marcus Bointon
- * @copyright 2010 - 2012 Jim Jagielski
- * @copyright 2004 - 2009 Andy Prevost
- * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
- * @note 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.
- */
- if (version_compare(PHP_VERSION, '5.0.0', '<')) {
- exit("Sorry, PHPMailer will only run on PHP version 5 or greater!\n");
- }
- /**
- * PHPMailer - PHP email creation and transport class.
- * PHP Version 5.0.0
- * @package PHPMailer
- * @author Marcus Bointon (coolbru) <phpmailer@synchromedia.co.uk>
- * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
- * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
- * @author Brent R. Matzelle (original founder)
- * @copyright 2013 Marcus Bointon
- * @copyright 2010 - 2012 Jim Jagielski
- * @copyright 2004 - 2009 Andy Prevost
- */
- class PHPMailer
- {
- /**
- * The PHPMailer Version number.
- * @type string
- */
- public $Version = '5.2.7';
- /**
- * Email priority.
- * Options: 1 = High, 3 = Normal, 5 = low.
- * @type int
- */
- public $Priority = 3;
- /**
- * The character set of the message.
- * @type string
- */
- public $CharSet = 'utf-8';
- /**
- * The MIME Content-type of the message.
- * @type string
- */
- public $ContentType = 'text/plain';
- /**
- * The message encoding.
- * Options: "8bit", "7bit", "binary", "base64", and "quoted-printable".
- * @type string
- */
- public $Encoding = '8bit';
- /**
- * Holds the most recent mailer error message.
- * @type string
- */
- public $ErrorInfo = '';
- /**
- * The From email address for the message.
- * @type string
- */
- public $From = 'root@localhost';
- /**
- * The From name of the message.
- * @type string
- */
- public $FromName = 'Root User';
- /**
- * 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.
- * @type string
- */
- public $Sender = '';
- /**
- * The Return-Path of the message.
- * If empty, it will be set to either From or Sender.
- * @type string
- */
- public $ReturnPath = '';
- /**
- * The Subject of the message.
- * @type string
- */
- public $Subject = '';
- /**
- * An HTML or plain text message body.
- * If HTML then call isHTML(true).
- * @type string
- */
- public $Body = '';
- /**
- * The plain-text message body.
- * This body can be read by mail clients that do not have HTML email
- * capability such as mutt & Eudora.
- * Clients that can read HTML will view the normal Body.
- * @type string
- */
- public $AltBody = '';
- /**
- * An iCal message part body.
- * Only supported in simple alt or alt_inline message types
- * To generate iCal events, use the bundled extras/EasyPeasyICS.php class or iCalcreator
- * @link http://sprain.ch/blog/downloads/php-class-easypeasyics-create-ical-files-with-php/
- * @link http://kigkonsult.se/iCalcreator/
- * @type string
- */
- public $Ical = '';
- /**
- * The complete compiled MIME message body.
- * @access protected
- * @type string
- */
- protected $MIMEBody = '';
- /**
- * The complete compiled MIME message headers.
- * @type string
- * @access protected
- */
- protected $MIMEHeader = '';
- /**
- * Extra headers that createHeader() doesn't fold in.
- * @type string
- * @access protected
- */
- protected $mailHeader = '';
- /**
- * Word-wrap the message body to this number of chars.
- * @type int
- */
- public $WordWrap = 0;
- /**
- * Which method to use to send mail.
- * Options: "mail", "sendmail", or "smtp".
- * @type string
- */
- public $Mailer = 'mail';
- /**
- * The path to the sendmail program.
- * @type string
- */
- public $Sendmail = '/usr/sbin/sendmail';
- /**
- * Whether mail() uses a fully sendmail-compatible MTA.
- * One which supports sendmail's "-oi -f" options.
- * @type bool
- */
- public $UseSendmailOptions = true;
- /**
- * Path to PHPMailer plugins.
- * Useful if the SMTP class is not in the PHP include path.
- * @type string
- * @deprecated Should not be needed now there is an autoloader.
- */
- public $PluginDir = '';
- /**
- * The email address that a reading confirmation should be sent to.
- * @type string
- */
- public $ConfirmReadingTo = '';
- /**
- * 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'.
- * @type string
- */
- public $Hostname = '';
- /**
- * An ID to be used in the Message-Id header.
- * If empty, a unique id will be generated.
- * @type string
- */
- public $MessageID = '';
- /**
- * The message Date to be used in the Date header.
- * If empty, the current date will be added.
- * @type string
- */
- public $MessageDate = '';
- /**
- * SMTP hosts.
- * Either a single hostname or multiple semicolon-delimited hostnames.
- * 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.
- * @type string
- */
- public $Host = 'localhost';
- /**
- * The default SMTP server port.
- * @type int
- * @Todo Why is this needed when the SMTP class takes care of it?
- */
- public $Port = 25;
- /**
- * The SMTP HELO of the message.
- * Default is $Hostname.
- * @type string
- * @see PHPMailer::$Hostname
- */
- public $Helo = '';
- /**
- * The secure connection prefix.
- * Options: "", "ssl" or "tls"
- * @type string
- */
- public $SMTPSecure = '';
- /**
- * Whether to use SMTP authentication.
- * Uses the Username and Password properties.
- * @type bool
- * @see PHPMailer::$Username
- * @see PHPMailer::$Password
- */
- public $SMTPAuth = false;
- /**
- * SMTP username.
- * @type string
- */
- public $Username = '';
- /**
- * SMTP password.
- * @type string
- */
- public $Password = '';
- /**
- * SMTP auth type.
- * Options are LOGIN (default), PLAIN, NTLM, CRAM-MD5
- * @type string
- */
- public $AuthType = '';
- /**
- * SMTP realm.
- * Used for NTLM auth
- * @type string
- */
- public $Realm = '';
- /**
- * SMTP workstation.
- * Used for NTLM auth
- * @type string
- */
- public $Workstation = '';
- /**
- * The SMTP server timeout in seconds.
- * @type int
- */
- public $Timeout = 10;
- /**
- * SMTP class debug output mode.
- * Options: 0 = off, 1 = commands, 2 = commands and data
- * @type int
- * @see SMTP::$do_debug
- */
- public $SMTPDebug = 0;
- /**
- * The function/method to use for debugging output.
- * Options: "echo" or "error_log"
- * @type string
- * @see SMTP::$Debugoutput
- */
- public $Debugoutput = "echo";
- /**
- * Whether to keep SMTP connection open after each message.
- * If this is set to true then to close the connection
- * requires an explicit call to smtpClose().
- * @type bool
- */
- public $SMTPKeepAlive = false;
- /**
- * Whether to split multiple to addresses into multiple messages
- * or send them all in one message.
- * @type bool
- */
- public $SingleTo = false;
- /**
- * Storage for addresses when SingleTo is enabled.
- * @type array
- * @todo This should really not be public
- */
- public $SingleToArray = array();
- /**
- * Whether to generate VERP addresses on send.
- * Only applicable when sending via SMTP.
- * @link http://en.wikipedia.org/wiki/Variable_envelope_return_path
- * @type bool
- */
- public $do_verp = false;
- /**
- * Whether to allow sending messages with an empty body.
- * @type bool
- */
- public $AllowEmpty = false;
- /**
- * The default line ending.
- * @note The default remains "\n". We force CRLF where we know
- * it must be used via self::CRLF.
- * @type string
- */
- public $LE = "\n";
- /**
- * DKIM selector.
- * @type string
- */
- public $DKIM_selector = '';
- /**
- * DKIM Identity.
- * Usually the email address used as the source of the email
- * @type string
- */
- public $DKIM_identity = '';
- /**
- * DKIM passphrase.
- * Used if your key is encrypted.
- * @type string
- */
- public $DKIM_passphrase = '';
- /**
- * DKIM signing domain name.
- * @example 'example.com'
- * @type string
- */
- public $DKIM_domain = '';
- /**
- * DKIM private key file path.
- * @type string
- */
- public $DKIM_private = '';
- /**
- * Callback Action function name.
- *
- * The function that handles the result of the send email action.
- * It is called out by send() for each email sent.
- *
- * Value can be any php callable: http://www.php.net/is_callable
- *
- * Parameters:
- * bool $result result of the send action
- * string $to email address of the recipient
- * string $cc cc email addresses
- * string $bcc bcc email addresses
- * string $subject the subject
- * string $body the email body
- * string $from email address of sender
- * @type string
- */
- public $action_function = '';
- /**
- * What to use in the X-Mailer header.
- * Options: null for default, whitespace for none, or a string to use
- * @type string
- */
- public $XMailer = '';
- /**
- * An instance of the SMTP sender class.
- * @type SMTP
- * @access protected
- */
- protected $smtp = null;
- /**
- * The array of 'to' addresses.
- * @type array
- * @access protected
- */
- protected $to = array();
- /**
- * The array of 'cc' addresses.
- * @type array
- * @access protected
- */
- protected $cc = array();
- /**
- * The array of 'bcc' addresses.
- * @type array
- * @access protected
- */
- protected $bcc = array();
- /**
- * The array of reply-to names and addresses.
- * @type array
- * @access protected
- */
- protected $ReplyTo = array();
- /**
- * An array of all kinds of addresses.
- * Includes all of $to, $cc, $bcc, $replyto
- * @type array
- * @access protected
- */
- protected $all_recipients = array();
- /**
- * The array of attachments.
- * @type array
- * @access protected
- */
- protected $attachment = array();
- /**
- * The array of custom headers.
- * @type array
- * @access protected
- */
- protected $CustomHeader = array();
- /**
- * The most recent Message-ID (including angular brackets).
- * @type string
- * @access protected
- */
- protected $lastMessageID = '';
- /**
- * The message's MIME type.
- * @type string
- * @access protected
- */
- protected $message_type = '';
- /**
- * The array of MIME boundary strings.
- * @type array
- * @access protected
- */
- protected $boundary = array();
- /**
- * The array of available languages.
- * @type array
- * @access protected
- */
- protected $language = array();
- /**
- * The number of errors encountered.
- * @type integer
- * @access protected
- */
- protected $error_count = 0;
- /**
- * The S/MIME certificate file path.
- * @type string
- * @access protected
- */
- protected $sign_cert_file = '';
- /**
- * The S/MIME key file path.
- * @type string
- * @access protected
- */
- protected $sign_key_file = '';
- /**
- * The S/MIME password for the key.
- * Used only if the key is encrypted.
- * @type string
- * @access protected
- */
- protected $sign_key_pass = '';
- /**
- * Whether to throw exceptions for errors.
- * @type bool
- * @access protected
- */
- protected $exceptions = false;
- /**
- * Error severity: message only, continue processing
- */
- const STOP_MESSAGE = 0;
- /**
- * Error severity: message, likely ok to continue processing
- */
- const STOP_CONTINUE = 1;
- /**
- * Error severity: message, plus full stop, critical error reached
- */
- const STOP_CRITICAL = 2;
- /**
- * SMTP RFC standard line ending
- */
- const CRLF = "\r\n";
- /**
- * Constructor
- * @param bool $exceptions Should we throw external exceptions?
- */
- public function __construct($exceptions = false)
- {
- $this->exceptions = ($exceptions == true);
- //Make sure our autoloader is loaded
- if (version_compare(PHP_VERSION, '5.1.2', '>=')) {
- $al = spl_autoload_functions();
- if ($al === false or !in_array('PHPMailerAutoload', $al)) {
- require 'PHPMailerAutoload.php';
- }
- }
- }
- /**
- * Destructor.
- */
- public function __destruct()
- {
- if ($this->Mailer == 'smtp') { //close any open SMTP connection nicely
- $this->smtpClose();
- }
- }
- /**
- * Call mail() in a safe_mode-aware fashion.
- * Also, unless sendmail_path points to sendmail (or something that
- * claims to be sendmail), don't pass params (not a perfect fix,
- * but it will do)
- * @param string $to To
- * @param string $subject Subject
- * @param string $body Message Body
- * @param string $header Additional Header(s)
- * @param string $params Params
- * @access private
- * @return bool
- */
- private function mailPassthru($to, $subject, $body, $header, $params)
- {
- //Check overloading of mail function to avoid double-encoding
- if (ini_get('mbstring.func_overload') & 1) {
- $subject = $this->secureHeader($subject);
- } else {
- $subject = $this->encodeHeader($this->secureHeader($subject));
- }
- if (ini_get('safe_mode') || !($this->UseSendmailOptions)) {
- $rt = @mail($to, $subject, $body, $header);
- } else {
- $rt = @mail($to, $subject, $body, $header, $params);
- }
- return $rt;
- }
- /**
- * Output debugging info via user-defined method.
- * Only if debug output is enabled.
- * @see PHPMailer::$Debugoutput
- * @see PHPMailer::$SMTPDebug
- * @param string $str
- */
- protected function edebug($str)
- {
- if (!$this->SMTPDebug) {
- return;
- }
- switch ($this->Debugoutput) {
- case 'error_log':
- error_log($str);
- break;
- case 'html':
- //Cleans up output a bit for a better looking display that's HTML-safe
- echo htmlentities(preg_replace('/[\r\n]+/', '', $str), ENT_QUOTES, $this->CharSet) . "<br>\n";
- break;
- case 'echo':
- default:
- echo $str."\n";
- }
- }
- /**
- * Sets message type to HTML or plain.
- * @param bool $ishtml True for HTML mode.
- * @return void
- */
- public function isHTML($ishtml = true)
- {
- if ($ishtml) {
- $this->ContentType = 'text/html';
- } else {
- $this->ContentType = 'text/plain';
- }
- }
- /**
- * Send messages using SMTP.
- * @return void
- */
- public function isSMTP()
- {
- $this->Mailer = 'smtp';
- }
- /**
- * Send messages using PHP's mail() function.
- * @return void
- */
- public function isMail()
- {
- $this->Mailer = 'mail';
- }
- /**
- * Send messages using $Sendmail.
- * @return void
- */
- public function isSendmail()
- {
- if (!stristr(ini_get('sendmail_path'), 'sendmail')) {
- $this->Sendmail = '/usr/sbin/sendmail';
- }
- $this->Mailer = 'sendmail';
- }
- /**
- * Send messages using qmail.
- * @return void
- */
- public function isQmail()
- {
- if (!stristr(ini_get('sendmail_path'), 'qmail')) {
- $this->Sendmail = '/var/qmail/bin/qmail-inject';
- }
- $this->Mailer = 'qmail';
- }
- /**
- * Add a "To" address.
- * @param string $address
- * @param string $name
- * @return bool true on success, false if address already used
- */
- public function addAddress($address, $name = '')
- {
- return $this->addAnAddress('to', $address, $name);
- }
- /**
- * Add 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 bool true on success, false if address already used
- */
- public function addCC($address, $name = '')
- {
- return $this->addAnAddress('cc', $address, $name);
- }
- /**
- * Add 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 bool true on success, false if address already used
- */
- public function addBCC($address, $name = '')
- {
- return $this->addAnAddress('bcc', $address, $name);
- }
- /**
- * Add a "Reply-to" address.
- * @param string $address
- * @param string $name
- * @return bool
- */
- public function addReplyTo($address, $name = '')
- {
- return $this->addAnAddress('Reply-To', $address, $name);
- }
- /**
- * Add an address to one of the recipient arrays.
- * Addresses that have been added already return false, but do not throw exceptions
- * @param string $kind One of 'to', 'cc', 'bcc', 'ReplyTo'
- * @param string $address The email address to send to
- * @param string $name
- * @throws phpmailerException
- * @return bool true on success, false if address already used or invalid in some way
- * @access protected
- */
- protected function addAnAddress($kind, $address, $name = '')
- {
- if (!preg_match('/^(to|cc|bcc|Reply-To)$/', $kind)) {
- $this->setError($this->lang('Invalid recipient array') . ': ' . $kind);
- $this->edebug($this->lang('Invalid recipient array') . ': ' . $kind);
- if ($this->exceptions) {
- throw new phpmailerException('Invalid recipient array: ' . $kind);
- }
- return false;
- }
- $address = trim($address);
- $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
- if (!$this->validateAddress($address)) {
- $this->setError($this->lang('invalid_address') . ': ' . $address);
- $this->edebug($this->lang('invalid_address') . ': ' . $address);
- if ($this->exceptions) {
- throw new phpmailerException($this->lang('invalid_address') . ': ' . $address);
- }
- return false;
- }
- if ($kind != 'Reply-To') {
- if (!isset($this->all_recipients[strtolower($address)])) {
- array_push($this->$kind, array($address, $name));
- $this->all_recipients[strtolower($address)] = true;
- return true;
- }
- } else {
- if (!array_key_exists(strtolower($address), $this->ReplyTo)) {
- $this->ReplyTo[strtolower($address)] = array($address, $name);
- return true;
- }
- }
- return false;
- }
- /**
- * Set the From and FromName properties.
- * @param string $address
- * @param string $name
- * @param bool $auto Whether to also set the Sender address, defaults to true
- * @throws phpmailerException
- * @return bool
- */
- public function setFrom($address, $name = '', $auto = true)
- {
- $address = trim($address);
- $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
- if (!$this->validateAddress($address)) {
- $this->setError($this->lang('invalid_address') . ': ' . $address);
- $this->edebug($this->lang('invalid_address') . ': ' . $address);
- if ($this->exceptions) {
- throw new phpmailerException($this->lang('invalid_address') . ': ' . $address);
- }
- return false;
- }
- $this->From = $address;
- $this->FromName = $name;
- if ($auto) {
- if (empty($this->Sender)) {
- $this->Sender = $address;
- }
- }
- return true;
- }
- /**
- * Return the Message-ID header of the last email.
- * Technically this is the value from the last time the headers were created,
- * but it's also the message ID of the last sent message except in
- * pathological cases.
- * @return string
- */
- public function getLastMessageID()
- {
- return $this->lastMessageID;
- }
- /**
- * Check that a string looks like an email address.
- * @param string $address The email address to check
- * @param string $patternselect A selector for the validation pattern to use :
- * 'auto' - pick best one automatically;
- * 'pcre8' - use the squiloople.com pattern, requires PCRE > 8.0, PHP >= 5.3.2, 5.2.14;
- * 'pcre' - use old PCRE implementation;
- * 'php' - use PHP built-in FILTER_VALIDATE_EMAIL; faster, less thorough;
- * 'noregex' - super fast, really dumb.
- * @return bool
- * @static
- * @access public
- */
- public static function validateAddress($address, $patternselect = 'auto')
- {
- if ($patternselect == 'auto') {
- if (defined(
- 'PCRE_VERSION'
- )
- ) { //Check this instead of extension_loaded so it works when that function is disabled
- if (version_compare(PCRE_VERSION, '8.0') >= 0) {
- $patternselect = 'pcre8';
- } else {
- $patternselect = 'pcre';
- }
- } else {
- //Filter_var appeared in PHP 5.2.0 and does not require the PCRE extension
- if (version_compare(PHP_VERSION, '5.2.0') >= 0) {
- $patternselect = 'php';
- } else {
- $patternselect = 'noregex';
- }
- }
- }
- switch ($patternselect) {
- case 'pcre8':
- /**
- * Conforms to RFC5322: Uses *correct* regex on which FILTER_VALIDATE_EMAIL is
- * based; So why not use FILTER_VALIDATE_EMAIL? Because it was broken to
- * not allow a@b type valid addresses :(
- * @link http://squiloople.com/2009/12/20/email-address-validation/
- * @copyright 2009-2010 Michael Rushton
- * Feel free to use and redistribute this code. But please keep this copyright notice.
- */
- return (bool)preg_match(
- '/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)' .
- '((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)' .
- '(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)' .
- '([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*' .
- '(?2)")(?>(?1)\.(?1)(?4))*(?1)@(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)' .
- '(?>(?1)\.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}' .
- '|(?!(?:.*[a-f0-9][:\]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:' .
- '|(?!(?:.*[a-f0-9]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}' .
- '|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD',
- $address
- );
- break;
- case 'pcre':
- //An older regex that doesn't need a recent PCRE
- return (bool)preg_match(
- '/^(?!(?>"?(?>\\\[ -~]|[^"])"?){255,})(?!(?>"?(?>\\\[ -~]|[^"])"?){65,}@)(?>' .
- '[!#-\'*+\/-9=?^-~-]+|"(?>(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\xFF]))*")' .
- '(?>\.(?>[!#-\'*+\/-9=?^-~-]+|"(?>(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\xFF]))*"))*' .
- '@(?>(?![a-z0-9-]{64,})(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>\.(?![a-z0-9-]{64,})' .
- '(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?)){0,126}|\[(?:(?>IPv6:(?>(?>[a-f0-9]{1,4})(?>:' .
- '[a-f0-9]{1,4}){7}|(?!(?:.*[a-f0-9][:\]]){8,})(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,6})?' .
- '::(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,6})?))|(?>(?>IPv6:(?>[a-f0-9]{1,4}(?>:' .
- '[a-f0-9]{1,4}){5}:|(?!(?:.*[a-f0-9]:){6,})(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,4})?' .
- '::(?>(?:[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,4}):)?))?(?>25[0-5]|2[0-4][0-9]|1[0-9]{2}' .
- '|[1-9]?[0-9])(?>\.(?>25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}))\])$/isD',
- $address
- );
- break;
- case 'php':
- default:
- return (bool)filter_var($address, FILTER_VALIDATE_EMAIL);
- break;
- case 'noregex':
- //No PCRE! Do something _very_ approximate!
- //Check the address is 3 chars or longer and contains an @ that's not the first or last char
- return (strlen($address) >= 3
- and strpos($address, '@') >= 1
- and strpos($address, '@') != strlen($address) - 1);
- break;
- }
- }
- /**
- * Create a message and send it.
- * Uses the sending method specified by $Mailer.
- * @throws phpmailerException
- * @return bool false on error - See the ErrorInfo property for details of the error.
- */
- public function send()
- {
- try {
- if (!$this->preSend()) {
- return false;
- }
- return $this->postSend();
- } catch (phpmailerException $e) {
- $this->mailHeader = '';
- $this->setError($e->getMessage());
- if ($this->exceptions) {
- throw $e;
- }
- return false;
- }
- }
- /**
- * Prepare a message for sending.
- * @throws phpmailerException
- * @return bool
- */
- public function preSend()
- {
- try {
- $this->mailHeader = "";
- if ((count($this->to) + count($this->cc) + count($this->bcc)) < 1) {
- throw new phpmailerException($this->lang('provide_address'), self::STOP_CRITICAL);
- }
- // Set whether the message is multipart/alternative
- if (!empty($this->AltBody)) {
- $this->ContentType = 'multipart/alternative';
- }
- $this->error_count = 0; // reset errors
- $this->setMessageType();
- // Refuse to send an empty message unless we are specifically allowing it
- if (!$this->AllowEmpty and empty($this->Body)) {
- throw new phpmailerException($this->lang('empty_message'), self::STOP_CRITICAL);
- }
- $this->MIMEHeader = $this->createHeader();
- $this->MIMEBody = $this->createBody();
- // To capture the complete message when using mail(), create
- // an extra header list which createHeader() doesn't fold in
- if ($this->Mailer == 'mail') {
- if (count($this->to) > 0) {
- $this->mailHeader .= $this->addrAppend("To", $this->to);
- } else {
- $this->mailHeader .= $this->headerLine("To", "undisclosed-recipients:;");
- }
- $this->mailHeader .= $this->headerLine(
- 'Subject',
- $this->encodeHeader($this->secureHeader(trim($this->Subject)))
- );
- }
- // Sign with DKIM if enabled
- if (!empty($this->DKIM_domain)
- && !empty($this->DKIM_private)
- && !empty($this->DKIM_selector)
- && !empty($this->DKIM_domain)
- && file_exists($this->DKIM_private)) {
- $header_dkim = $this->DKIM_Add(
- $this->MIMEHeader . $this->mailHeader,
- $this->encodeHeader($this->secureHeader($this->Subject)),
- $this->MIMEBody
- );
- $this->MIMEHeader = rtrim($this->MIMEHeader, "\r\n ") . self::CRLF .
- str_replace("\r\n", "\n", $header_dkim) . self::CRLF;
- }
- return true;
- } catch (phpmailerException $e) {
- $this->setError($e->getMessage());
- if ($this->exceptions) {
- throw $e;
- }
- return false;
- }
- }
- /**
- * Actually send a message.
- * Send the email via the selected mechanism
- * @throws phpmailerException
- * @return bool
- */
- public function postSend()
- {
- try {
- // Choose the mailer and send through it
- switch ($this->Mailer) {
- case 'sendmail':
- case 'qmail':
- return $this->sendmailSend($this->MIMEHeader, $this->MIMEBody);
- case 'smtp':
- return $this->smtpSend($this->MIMEHeader, $this->MIMEBody);
- case 'mail':
- return $this->mailSend($this->MIMEHeader, $this->MIMEBody);
- default:
- if (method_exists($this, $this->Mailer.'Send')) {
- $sendMethod = $this->Mailer.'Send';
- return $this->$sendMethod($this->MIMEHeader, $this->MIMEBody);
- } else {
- return $this->mailSend($this->MIMEHeader, $this->MIMEBody);
- }
- }
- } catch (phpmailerException $e) {
- $this->setError($e->getMessage());
- $this->edebug($e->getMessage());
- if ($this->exceptions) {
- throw $e;
- }
- }
- return false;
- }
- /**
- * Send mail using the $Sendmail program.
- * @param string $header The message headers
- * @param string $body The message body
- * @see PHPMailer::$Sendmail
- * @throws phpmailerException
- * @access protected
- * @return bool
- */
- protected function sendmailSend($header, $body)
- {
- if ($this->Sender != '') {
- if ($this->Mailer == 'qmail') {
- $sendmail = sprintf("%s -f%s", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));
- } else {
- $sendmail = sprintf("%s -oi -f%s -t", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));
- }
- } else {
- if ($this->Mailer == 'qmail') {
- $sendmail = sprintf("%s", escapeshellcmd($this->Sendmail));
- } else {
- $sendmail = sprintf("%s -oi -t", escapeshellcmd($this->Sendmail));
- }
- }
- if ($this->SingleTo === true) {
- foreach ($this->SingleToArray as $val) {
- if (!@$mail = popen($sendmail, 'w')) {
- throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
- }
- fputs($mail, "To: " . $val . "\n");
- fputs($mail, $header);
- fputs($mail, $body);
- $result = pclose($mail);
- // implement call back function if it exists
- $isSent = ($result == 0) ? 1 : 0;
- $this->doCallback($isSent, $val, $this->cc, $this->bcc, $this->Subject, $body, $this->From);
- if ($result != 0) {
- throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
- }
- }
- } else {
- if (!@$mail = popen($sendmail, 'w')) {
- throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
- }
- fputs($mail, $header);
- fputs($mail, $body);
- $result = pclose($mail);
- // implement call back function if it exists
- $isSent = ($result == 0) ? 1 : 0;
- $this->doCallback($isSent, $this->to, $this->cc, $this->bcc, $this->Subject, $body, $this->From);
- if ($result != 0) {
- throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
- }
- }
- return true;
- }
- /**
- * Send mail using the PHP mail() function.
- * @param string $header The message headers
- * @param string $body The message body
- * @link http://www.php.net/manual/en/book.mail.php
- * @throws phpmailerException
- * @access protected
- * @return bool
- */
- protected function mailSend($header, $body)
- {
- $toArr = array();
- foreach ($this->to as $t) {
- $toArr[] = $this->addrFormat($t);
- }
- $to = implode(', ', $toArr);
- if (empty($this->Sender)) {
- $params = " ";
- } else {
- $params = sprintf("-f%s", $this->Sender);
- }
- if ($this->Sender != '' and !ini_get('safe_mode')) {
- $old_from = ini_get('sendmail_from');
- ini_set('sendmail_from', $this->Sender);
- }
- $rt = false;
- if ($this->SingleTo === true && count($toArr) > 1) {
- foreach ($toArr as $val) {
- $rt = $this->mailPassthru($val, $this->Subject, $body, $header, $params);
- // implement call back function if it exists
- $isSent = ($rt == 1) ? 1 : 0;
- $this->doCallback($isSent, $val, $this->cc, $this->bcc, $this->Subject, $body, $this->From);
- }
- } else {
- $rt = $this->mailPassthru($to, $this->Subject, $body, $header, $params);
- // implement call back function if it exists
- $isSent = ($rt == 1) ? 1 : 0;
- $this->doCallback($isSent, $to, $this->cc, $this->bcc, $this->Subject, $body, $this->From);
- }
- if (isset($old_from)) {
- ini_set('sendmail_from', $old_from);
- }
- if (!$rt) {
- throw new phpmailerException($this->lang('instantiate'), self::STOP_CRITICAL);
- }
- return true;
- }
- /**
- * Get an instance to use for SMTP operations.
- * Override this function to load your own SMTP implementation
- * @return SMTP
- */
- public function getSMTPInstance()
- {
- if (!is_object($this->smtp)) {
- $this->smtp = new SMTP;
- }
- return $this->smtp;
- }
- /**
- * Send mail via SMTP.
- * Returns false if there is a bad MAIL FROM, RCPT, or DATA input.
- * Uses the PHPMailerSMTP class by default.
- * @see PHPMailer::getSMTPInstance() to use a different class.
- * @param string $header The message headers
- * @param string $body The message body
- * @throws phpmailerException
- * @uses SMTP
- * @access protected
- * @return bool
- */
- protected function smtpSend($header, $body)
- {
- $bad_rcpt = array();
- if (!$this->smtpConnect()) {
- throw new phpmailerException($this->lang('smtp_connect_failed'), self::STOP_CRITICAL);
- }
- $smtp_from = ($this->Sender == '') ? $this->From : $this->Sender;
- if (!$this->smtp->mail($smtp_from)) {
- $this->setError($this->lang('from_failed') . $smtp_from . ' : ' . implode(',', $this->smtp->getError()));
- throw new phpmailerException($this->ErrorInfo, self::STOP_CRITICAL);
- }
- // Attempt to send to all recipients
- foreach ($this->to as $to) {
- if (!$this->smtp->recipient($to[0])) {
- $bad_rcpt[] = $to[0];
- $isSent = 0;
- } else {
- $isSent = 1;
- }
- $this->doCallback($isSent, $to[0], '', '', $this->Subject, $body, $this->From);
- }
- foreach ($this->cc as $cc) {
- if (!$this->smtp->recipient($cc[0])) {
- $bad_rcpt[] = $cc[0];
- $isSent = 0;
- } else {
- $isSent = 1;
- }
- $this->doCallback($isSent, '', $cc[0], '', $this->Subject, $body, $this->From);
- }
- foreach ($this->bcc as $bcc) {
- if (!$this->smtp->recipient($bcc[0])) {
- $bad_rcpt[] = $bcc[0];
- $isSent = 0;
- } else {
- $isSent = 1;
- }
- $this->doCallback($isSent, '', '', $bcc[0], $this->Subject, $body, $this->From);
- }
- //Only send the DATA command if we have viable recipients
- if ((count($this->all_recipients) > count($bad_rcpt)) and !$this->smtp->data($header . $body)) {
- throw new phpmailerException($this->lang('data_not_accepted'), self::STOP_CRITICAL);
- }
- if ($this->SMTPKeepAlive == true) {
- $this->smtp->reset();
- } else {
- $this->smtp->quit();
- $this->smtp->close();
- }
- if (count($bad_rcpt) > 0) { //Create error message for any bad addresses
- throw new phpmailerException(
- $this->lang('recipients_failed') . implode(', ', $bad_rcpt),
- self::STOP_CONTINUE
- );
- }
- return true;
- }
- /**
- * Initiate a connection to an SMTP server.
- * Returns false if the operation failed.
- * @param array $options An array of options compatible with stream_context_create()
- * @uses SMTP
- * @access public
- * @throws phpmailerException
- * @return bool
- */
- public function smtpConnect($options = array())
- {
- if (is_null($this->smtp)) {
- $this->smtp = $this->getSMTPInstance();
- }
- //Already connected?
- if ($this->smtp->connected()) {
- return true;
- }
- $this->smtp->setTimeout($this->Timeout);
- $this->smtp->setDebugLevel($this->SMTPDebug);
- $this->smtp->setDebugOutput($this->Debugoutput);
- $this->smtp->setVerp($this->do_verp);
- $hosts = explode(';', $this->Host);
- $lastexception = null;
- foreach ($hosts as $hostentry) {
- $hostinfo = array();
- if (!preg_match('/^((ssl|tls):\/\/)*([a-zA-Z0-9\.-]*):?([0-9]*)$/', trim($hostentry), $hostinfo)) {
- //Not a valid host entry
- continue;
- }
- //$hostinfo[2]: optional ssl or tls prefix
- //$hostinfo[3]: the hostname
- //$hostinfo[4]: optional port number
- //The host string prefix can temporarily override the current setting for SMTPSecure
- //If it's not specified, the default value is used
- $prefix = '';
- $tls = ($this->SMTPSecure == 'tls');
- if ($hostinfo[2] == 'ssl' or ($hostinfo[2] == '' and $this->SMTPSecure == 'ssl')) {
- $prefix = 'ssl://';
- $tls = false; //Can't have SSL and TLS at once
- } elseif ($hostinfo[2] == 'tls') {
- $tls = true;
- //tls doesn't use a prefix
- }
- $host = $hostinfo[3];
- $port = $this->Port;
- $tport = (integer)$hostinfo[4];
- if ($tport > 0 and $tport < 65536) {
- $port = $tport;
- }
- if ($this->smtp->connect($prefix . $host, $port, $this->Timeout, $options)) {
- try {
- if ($this->Helo) {
- $hello = $this->Helo;
- } else {
- $hello = $this->serverHostname();
- }
- $this->smtp->hello($hello);
- if ($tls) {
- if (!$this->smtp->startTLS()) {
- throw new phpmailerException($this->lang('connect_host'));
- }
- //We must resend HELO after tls negotiation
- $this->smtp->hello($hello);
- }
- if ($this->SMTPAuth) {
- if (!$this->smtp->authenticate(
- $this->Username,
- $this->Password,
- $this->AuthType,
- $this->Realm,
- $this->Workstation
- )
- ) {
- throw new phpmailerException($this->lang('authenticate'));
- }
- }
- return true;
- } catch (phpmailerException $e) {
- $lastexception = $e;
- //We must have connected, but then failed TLS or Auth, so close connection nicely
- $this->smtp->quit();
- }
- }
- }
- //If we get here, all connection attempts have failed, so close connection hard
- $this->smtp->close();
- //As we've caught all exceptions, just report whatever the last one was
- if ($this->exceptions and !is_null($lastexception)) {
- throw $lastexception;
- }
- return false;
- }
- /**
- * Close 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();
- }
- }
- }
- /**
- * Set the language for error messages.
- * Returns false if it cannot load the language file.
- * The default language is English.
- * @param string $langcode ISO 639-1 2-character language code (e.g. French is "fr")
- * @param string $lang_path Path to the language file directory, with trailing separator (slash)
- * @return bool
- * @access public
- */
- public function setLanguage($langcode = 'en', $lang_path = 'language/')
- {
- //Define full set of translatable strings
- $PHPMAILER_LANG = array(
- 'authenticate' => 'SMTP Error: Could not authenticate.',
- 'connect_host' => 'SMTP Error: Could not connect to SMTP host.',
- 'data_not_accepted' => 'SMTP Error: data not accepted.',
- 'empty_message' => 'Message body empty',
- 'encoding' => 'Unknown encoding: ',
- 'execute' => 'Could not execute: ',
- 'file_access' => 'Could not access file: ',
- 'file_open' => 'File Error: Could not open file: ',
- 'from_failed' => 'The following From address failed: ',
- 'instantiate' => 'Could not instantiate mail function.',
- 'invalid_address' => 'Invalid address',
- 'mailer_not_supported' => ' mailer is not supported.',
- 'provide_address' => 'You must provide at least one recipient email address.',
- 'recipients_failed' => 'SMTP Error: The following recipients failed: ',
- 'signing' => 'Signing Error: ',
- 'smtp_connect_failed' => 'SMTP connect() failed.',
- 'smtp_error' => 'SMTP server error: ',
- 'variable_set' => 'Cannot set or reset variable: '
- );
- //Overwrite language-specific strings.
- //This way we'll never have missing translations - no more "language string failed to load"!
- $l = true;
- $lang_file = $lang_path . 'phpmailer.lang-' . $langcode . '.php';
- if ($langcode != 'en') { //There is no English translation file
- //Make sure language file path is readable
- if (!is_readable($lang_file)) {
- $l = false;
- } else {
- $l = include $lang_file;
- }
- }
- $this->language = $PHPMAILER_LANG;
- return ($l == true); //Returns false if language not found
- }
- /**
- * Get the array of strings for the current language.
- * @return array
- */
- public function getTranslations()
- {
- return $this->language;
- }
- /**
- * Create recipient headers.
- * @access public
- * @param string $type
- * @param array $addr An array of recipient,
- * where each recipient is a 2-element indexed array with element 0 containing an address
- * and element 1 containing a name, like:
- * array(array('joe@example.com', 'Joe User'), array('zoe@example.com', 'Zoe User'))
- * @return string
- */
- public function addrAppend($type, $addr)
- {
- $addresses = array();
- foreach ($addr as $a) {
- $addresses[] = $this->addrFormat($a);
- }
- return $type . ': ' . implode(', ', $addresses) . $this->LE;
- }
- /**
- * Format an address for use in a message header.
- * @access public
- * @param array $addr A 2-element indexed array, element 0 containing an address, element 1 containing a name
- * like array('joe@example.com', 'Joe User')
- * @return string
- */
- public function addrFormat($addr)
- {
- if (empty($addr[1])) { // No name provided
- return $this->secureHeader($addr[0]);
- } else {
- return $this->encodeHeader($this->secureHeader($addr[1]), 'phrase') . " <" . $this->secureHeader(
- $addr[0]
- ) . ">";
- }
- }
- /**
- * Word-wrap message.
- * For use with mailers that do not automatically perform wrapping
- * and for quoted-printable encoded messages.
- * Original written by philippe.
- * @param string $message The message to wrap
- * @param integer $length The line length to wrap to
- * @param bool $qp_mode Whether to run in Quoted-Printable mode
- * @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");
- $lelen = strlen($this->LE);
- $crlflen = strlen(self::CRLF);
- $message = $this->fixEOL($message);
- if (substr($message, -$lelen) == $this->LE) {
- $message = substr($message, 0, -$lelen);
- }
- $line = explode($this->LE, $message); // Magic. We know fixEOL uses $LE
- $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) - $crlflen;
- 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", self::CRLF);
- } else {
- $message .= $buf . $soft_break;
- }
- $buf = '';
- }
- while (strlen($word) > 0) {
- if ($length <= 0) {
- break;
- }
- $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", self::CRLF);
- } 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;
- }
- …
Large files files are truncated, but you can click here to view the full file