Example #1
0
function zen_mail($to_name, $to_address, $email_subject, $email_text, $from_email_name, $from_email_address, $block = array(), $module = 'default', $attachments_list = '')
{
    global $db, $messageStack;
    if (SEND_EMAILS != 'true') {
        return false;
    }
    // if sending email is disabled in Admin, just exit
    if (!zen_not_null($email_text) && !zen_not_null($block['EMAIL_MESSAGE_HTML'])) {
        return false;
    }
    // if no text or html-msg supplied, exit
    // Parse "from" addresses for "name" <*****@*****.**> structure, and supply name/address info from it.
    if (eregi(" *([^<]*) *<([^>]*)> *", $from_email_address, $regs)) {
        $from_email_name = trim($regs[1]);
        $from_email_address = $regs[2];
    }
    // if email name is same as email address, use the Store Name as the senders 'Name'
    if ($from_email_name == $from_email_address) {
        $from_email_name = STORE_NAME;
    }
    // loop thru multiple email recipients if more than one listed  --- (esp for the admin's "Extra" emails)...
    foreach (explode(',', $to_address) as $key => $value) {
        if (eregi(" *([^<]*) *<([^>]*)> *", $value, $regs)) {
            $to_name = str_replace('"', '', trim($regs[1]));
            $to_email_address = $regs[2];
        } elseif (eregi(" *([^ ]*) *", $value, $regs)) {
            $to_email_address = trim($regs[1]);
        }
        if (!isset($to_email_address)) {
            $to_email_address = $to_address;
        }
        //if not more than one, just use the main one.
        //define some additional html message blocks available to templates, then build the html portion.
        if ($block['EMAIL_TO_NAME'] == '') {
            $block['EMAIL_TO_NAME'] = $to_name;
        }
        if ($block['EMAIL_TO_ADDRESS'] == '') {
            $block['EMAIL_TO_ADDRESS'] = $to_email_address;
        }
        if ($block['EMAIL_SUBJECT'] == '') {
            $block['EMAIL_SUBJECT'] = $email_subject;
        }
        if ($block['EMAIL_FROM_NAME'] == '') {
            $block['EMAIL_FROM_NAME'] = $from_email_name;
        }
        if ($block['EMAIL_FROM_ADDRESS'] == '') {
            $block['EMAIL_FROM_ADDRESS'] = $from_email_address;
        }
        $email_html = zen_build_html_email_from_template($module, $block);
        //  if ($attachments_list == '') $attachments_list= array();
        // Instantiate a new mail object
        $message = new email(array('X-Mailer: Zen Cart Mailer'));
        // bof: body of the email clean-up
        // clean up &amp; and && from email text
        while (strstr($email_text, '&amp;&amp;')) {
            $email_text = str_replace('&amp;&amp;', '&amp;', $email_text);
        }
        while (strstr($email_text, '&amp;')) {
            $email_text = str_replace('&amp;', '&', $email_text);
        }
        while (strstr($email_text, '&&')) {
            $email_text = str_replace('&&', '&', $email_text);
        }
        // clean up money &euro; to e
        while (strstr($email_text, '&euro;')) {
            $email_text = str_replace('&euro;', 'e', $email_text);
        }
        // fix double quotes
        while (strstr($email_text, '&quot;')) {
            $email_text = str_replace('&quot;', '"', $email_text);
        }
        // fix slashes
        $email_text = stripslashes($email_text);
        $email_html = stripslashes($email_html);
        // eof: body of the email clean-up
        //determine customer's email preference type: HTML or TEXT-ONLY  (HTML assumed if not specified)
        $customers_email_format_read = $db->Execute("select customers_email_format from " . TABLE_CUSTOMERS . " where customers_email_address= '" . $to_email_address . "'");
        $customers_email_format = $customers_email_format_read->fields['customers_email_format'];
        if ($customers_email_format == 'NONE' || $customers_email_format == 'OUT') {
            return;
        }
        //if requested no mail, then don't send.
        if ($customers_email_format == 'HTML') {
            $customers_email_format = 'HTML';
        }
        // if they opted-in to HTML messages, then send HTML format
        //determine what format to send messages in if this is an "extra"/admin-copy email:
        if (ADMIN_EXTRA_EMAIL_FORMAT == 'TEXT' && substr($module, -6) == '_extra') {
            $email_html = '';
            // just blank out the html portion if admin has selected text-only
        }
        // Build the email based on whether customer has selected HTML or TEXT, and whether we have supplied HTML or TEXT-only components
        if (!zen_not_null($email_text)) {
            $text = str_replace('<br[[:space:]]*/?[[:space:]]*>', "@CRLF", $block['EMAIL_MESSAGE_HTML']);
            $text = str_replace('</p>', '</p>@CRLF', $text);
            $text = htmlspecialchars(stripslashes(strip_tags($text)));
        } else {
            $text = strip_tags($email_text);
        }
        if (EMAIL_USE_HTML == 'true' && trim($email_html) != '' && ($customers_email_format == 'HTML' || ADMIN_EXTRA_EMAIL_FORMAT != 'TEXT' && substr($module, -6) == '_extra')) {
            $message->add_html($email_html, $text);
        } else {
            $message->add_text($text);
            $email_html = '';
            // since sending a text-only message, empty the HTML portion so it's not archived either.
        }
        // process attachments
        if (EMAIL_ATTACHMENTS_ENABLED && zen_not_null($attachments_list)) {
            //    while ( list($key, $value) = each($attachments_list)) {
            $fileraw = $message->get_file(DIR_FS_ADMIN . 'attachments/' . $attachments_list['file']);
            $filemime = zen_not_null($attachments_list['file_type']) ? $attachments_list['file_type'] : $message->findMime($attachments_list);
            //findMime determines what type this attachment is (XLS, PDF, etc) and sends proper vendor c_type.
            $message->add_attachment($fileraw, $attachments_list['file'], $filemime);
            //     } //endwhile attach_list
        }
        //endif attachments
        // Prepare message
        $message->build_message();
        // send the actual email
        $result = $message->send($to_name, $to_email_address, $from_email_name, $from_email_address, $email_subject);
        if (!$result) {
            $messageStack->add(sprintf(EMAIL_SEND_FAILED, $to_name, $to_email_address, $email_subject), 'error');
        }
        // Archive this message to storage log
        if (EMAIL_ARCHIVE == 'true' && $module != 'password_forgotten_admin' && $module != 'cc_middle_digs') {
            // don't archive pwd-resets and CC numbers
            zen_mail_archive_write($to_name, $to_email_address, $from_email_name, $from_email_address, $email_subject, $email_html, $text, $module);
        }
        // endif archiving
    }
    // end foreach loop thru possible multiple email addresses
}
Example #2
0
/**
 * Send email (text/html) using MIME. This is the central mail function.
 * If using "PHP" transport method, the SMTP Server or other mail application should be configured correctly in server's php.ini
 *
 * @param string $to_name           The name of the recipient, e.g. "Jim Johanssen"
 * @param string $to_email_address  The email address of the recipient, e.g. john.smith@hzq.com
 * @param string $email_subject     The subject of the eMail
 * @param string $email_text        The text of the email, may contain HTML entities
 * @param string $from_email_name   The name of the sender, e.g. Shop Administration
 * @param string $from_email_adrdess The email address of the sender, e.g. info@myzenshop.com
 * @param array  $block             Array containing values to be inserted into HTML-based email template
 * @param string $module            The module name of the routine calling zen_mail. Used for HTML template selection and email archiving.
 *                                  This is passed to the archive function denoting what module initiated the sending of the email
 * @param array  $attachments_list  Array of attachment names/mime-types to be included  (this portion still in testing, and not fully reliable)
**/
function zen_mail($to_name, $to_address, $email_subject, $email_text, $from_email_name, $from_email_address, $block = array(), $module = 'default', $attachments_list = '')
{
    global $db, $messageStack, $zco_notifier;
    if (!defined('DEVELOPER_OVERRIDE_EMAIL_STATUS') || defined('DEVELOPER_OVERRIDE_EMAIL_STATUS') && DEVELOPER_OVERRIDE_EMAIL_STATUS == 'site') {
        if (SEND_EMAILS != 'true') {
            return false;
        }
    }
    // if sending email is disabled in Admin, just exit
    if (defined('DEVELOPER_OVERRIDE_EMAIL_ADDRESS') && DEVELOPER_OVERRIDE_EMAIL_ADDRESS != '') {
        $to_address = DEVELOPER_OVERRIDE_EMAIL_ADDRESS;
    }
    // ignore sending emails for any of the following pages
    // (The EMAIL_MODULES_TO_SKIP constant can be defined in a new file in the "extra_configures" folder)
    if (defined('EMAIL_MODULES_TO_SKIP') && in_array($module, explode(",", constant('EMAIL_MODULES_TO_SKIP')))) {
        return false;
    }
    // check for injection attempts. If new-line characters found in header fields, simply fail to send the message
    foreach (array($from_email_address, $to_address, $from_email_name, $to_name, $email_subject) as $key => $value) {
        if (eregi("\r", $value) || eregi("\n", $value)) {
            return false;
        }
    }
    // if no text or html-msg supplied, exit
    if (trim($email_text) == '' && (!zen_not_null($block) || isset($block['EMAIL_MESSAGE_HTML']) && $block['EMAIL_MESSAGE_HTML'] == '')) {
        return false;
    }
    // Parse "from" addresses for "name" <*****@*****.**> structure, and supply name/address info from it.
    if (eregi(" *([^<]*) *<([^>]*)> *", $from_email_address, $regs)) {
        $from_email_name = trim($regs[1]);
        $from_email_address = $regs[2];
    }
    // if email name is same as email address, use the Store Name as the senders 'Name'
    if ($from_email_name == $from_email_address) {
        $from_email_name = STORE_NAME;
    }
    // loop thru multiple email recipients if more than one listed  --- (esp for the admin's "Extra" emails)...
    foreach (explode(',', $to_address) as $key => $value) {
        if (eregi(" *([^<]*) *<([^>]*)> *", $value, $regs)) {
            $to_name = str_replace('"', '', trim($regs[1]));
            $to_email_address = $regs[2];
        } elseif (eregi(" *([^ ]*) *", $value, $regs)) {
            $to_email_address = trim($regs[1]);
        }
        if (!isset($to_email_address)) {
            $to_email_address = $to_address;
        }
        //if not more than one, just use the main one.
        //define some additional html message blocks available to templates, then build the html portion.
        if ($block['EMAIL_TO_NAME'] == '') {
            $block['EMAIL_TO_NAME'] = $to_name;
        }
        if ($block['EMAIL_TO_ADDRESS'] == '') {
            $block['EMAIL_TO_ADDRESS'] = $to_email_address;
        }
        if ($block['EMAIL_SUBJECT'] == '') {
            $block['EMAIL_SUBJECT'] = $email_subject;
        }
        if ($block['EMAIL_FROM_NAME'] == '') {
            $block['EMAIL_FROM_NAME'] = $from_email_name;
        }
        if ($block['EMAIL_FROM_ADDRESS'] == '') {
            $block['EMAIL_FROM_ADDRESS'] = $from_email_address;
        }
        $email_html = zen_build_html_email_from_template($module, $block);
        if (!is_array($block) && $block == '' || $block == 'none') {
            $email_html = '';
        }
        // Build the email based on whether customer has selected HTML or TEXT, and whether we have supplied HTML or TEXT-only components
        // special handling for XML content
        if ($email_text == '') {
            $email_text = str_replace(array('<br>', '<br />'), "<br />\n", $block['EMAIL_MESSAGE_HTML']);
            $email_text = str_replace('</p>', "</p>\n", $email_text);
            $email_text = $module != 'xml_record' ? htmlspecialchars(stripslashes(strip_tags($email_text))) : $email_text;
        } else {
            $email_text = $module != 'xml_record' ? strip_tags($email_text) : $email_text;
        }
        if ($module != 'xml_record') {
            if (!strstr($email_text, sprintf(EMAIL_DISCLAIMER, STORE_OWNER_EMAIL_ADDRESS)) && $to_email_address != STORE_OWNER_EMAIL_ADDRESS && !defined('EMAIL_DISCLAIMER_NEW_CUSTOMER')) {
                $email_text .= "\n" . sprintf(EMAIL_DISCLAIMER, STORE_OWNER_EMAIL_ADDRESS);
            }
            if (!strstr($email_text, EMAIL_SPAM_DISCLAIMER) && $to_email_address != STORE_OWNER_EMAIL_ADDRESS) {
                $email_text .= "\n" . EMAIL_SPAM_DISCLAIMER;
            }
        }
        // bof: body of the email clean-up
        // clean up &amp; and && from email text
        while (strstr($email_text, '&amp;&amp;')) {
            $email_text = str_replace('&amp;&amp;', '&amp;', $email_text);
        }
        while (strstr($email_text, '&amp;')) {
            $email_text = str_replace('&amp;', '&', $email_text);
        }
        while (strstr($email_text, '&&')) {
            $email_text = str_replace('&&', '&', $email_text);
        }
        // clean up currencies for text emails
        $zen_fix_currencies = split("[:,]", CURRENCIES_TRANSLATIONS);
        $size = sizeof($zen_fix_currencies);
        for ($i = 0, $n = $size; $i < $n; $i += 2) {
            $zen_fix_current = $zen_fix_currencies[$i];
            $zen_fix_replace = $zen_fix_currencies[$i + 1];
            if (strlen($zen_fix_current) > 0) {
                while (strpos($email_text, $zen_fix_current)) {
                    $email_text = str_replace($zen_fix_current, $zen_fix_replace, $email_text);
                }
            }
        }
        // fix double quotes
        while (strstr($email_text, '&quot;')) {
            $email_text = str_replace('&quot;', '"', $email_text);
        }
        // prevent null characters
        while (strstr($email_text, chr(0))) {
            $email_text = str_replace(chr(0), ' ', $email_text);
        }
        // fix slashes
        $text = stripslashes($email_text);
        $email_html = stripslashes($email_html);
        // eof: body of the email clean-up
        //determine customer's email preference type: HTML or TEXT-ONLY  (HTML assumed if not specified)
        $sql = "select customers_email_format from " . TABLE_CUSTOMERS . " where customers_email_address= :custEmailAddress:";
        $sql = $db->bindVars($sql, ':custEmailAddress:', $to_email_address, 'string');
        $result = $db->Execute($sql);
        $customers_email_format = $result->RecordCount() > 0 ? $result->fields['customers_email_format'] : '';
        if ($customers_email_format == 'NONE' || $customers_email_format == 'OUT') {
            return;
        }
        //if requested no mail, then don't send.
        //      if ($customers_email_format == 'HTML') $customers_email_format = 'HTML'; // if they opted-in to HTML messages, then send HTML format
        // handling admin/"extra"/copy emails:
        if (ADMIN_EXTRA_EMAIL_FORMAT == 'TEXT' && substr($module, -6) == '_extra') {
            $email_html = '';
            // just blank out the html portion if admin has selected text-only
        }
        //determine what format to send messages in if this is an admin email for newsletters:
        if ($customers_email_format == '' && ADMIN_EXTRA_EMAIL_FORMAT == 'HTML' && in_array($module, array('newsletters', 'product_notification')) && isset($_SESSION['admin_id'])) {
            $customers_email_format = 'HTML';
        }
        // special handling for XML content
        if ($module == 'xml_record') {
            $email_html = '';
            $customers_email_format == 'TEXT';
        }
        //notifier intercept option
        $zco_notifier->notify('NOTIFY_EMAIL_AFTER_EMAIL_FORMAT_DETERMINED');
        // now lets build the mail object with the phpmailer class
        $mail =& new PHPMailer();
        $lang_code = strtolower($_SESSION['languages_code'] == '' ? 'en' : $_SESSION['languages_code']);
        $mail->SetLanguage($lang_code, DIR_FS_CATALOG . DIR_WS_CLASSES . 'support/');
        $mail->CharSet = defined('CHARSET') ? CHARSET : "iso-8859-1";
        $mail->Encoding = defined('EMAIL_ENCODING_METHOD') ? EMAIL_ENCODING_METHOD : "7bit";
        if ((int) EMAIL_SYSTEM_DEBUG > 0) {
            $mail->SMTPDebug = (int) EMAIL_SYSTEM_DEBUG;
        }
        $mail->WordWrap = 76;
        // set word wrap to 76 characters
        // set proper line-endings based on switch ... important for windows vs linux hosts:
        $mail->LE = EMAIL_LINEFEED == 'CRLF' ? "\r\n" : "\n";
        switch (EMAIL_TRANSPORT) {
            case 'smtp':
                $mail->IsSMTP();
                $mail->Host = trim(EMAIL_SMTPAUTH_MAIL_SERVER);
                if (EMAIL_SMTPAUTH_MAIL_SERVER_PORT != '25' && EMAIL_SMTPAUTH_MAIL_SERVER_PORT != '') {
                    $mail->Port = trim(EMAIL_SMTPAUTH_MAIL_SERVER_PORT);
                }
                $mail->LE = "\r\n";
                break;
            case 'smtpauth':
                $mail->IsSMTP();
                $mail->SMTPAuth = true;
                $mail->Username = zen_not_null(EMAIL_SMTPAUTH_MAILBOX) ? trim(EMAIL_SMTPAUTH_MAILBOX) : EMAIL_FROM;
                $mail->Password = trim(EMAIL_SMTPAUTH_PASSWORD);
                $mail->Host = trim(EMAIL_SMTPAUTH_MAIL_SERVER);
                if (EMAIL_SMTPAUTH_MAIL_SERVER_PORT != '25' && EMAIL_SMTPAUTH_MAIL_SERVER_PORT != '') {
                    $mail->Port = trim(EMAIL_SMTPAUTH_MAIL_SERVER_PORT);
                }
                $mail->LE = "\r\n";
                //set encryption protocol to allow support for Gmail
                if (EMAIL_SMTPAUTH_MAIL_SERVER_PORT == '465' && EMAIL_SMTPAUTH_MAIL_SERVER == 'smtp.gmail.com') {
                    $mail->Protocol = 'ssl';
                }
                if (defined('SMTPAUTH_EMAIL_PROTOCOL') && SMTPAUTH_EMAIL_PROTOCOL != 'none') {
                    $mail->Protocol = SMTPAUTH_EMAIL_PROTOCOL;
                    if (SMTPAUTH_EMAIL_PROTOCOL == 'starttls') {
                        $mail->Starttls = true;
                        $mail->Context = $Email_Certificate_Context;
                    }
                }
                break;
            case 'PHP':
                $mail->IsMail();
                break;
            case 'Qmail':
                $mail->IsQmail();
                break;
            case 'sendmail':
            case 'sendmail-f':
                $mail->LE = "\n";
            default:
                $mail->IsSendmail();
                if (defined('EMAIL_SENDMAIL_PATH')) {
                    $mail->Sendmail = trim(EMAIL_SENDMAIL_PATH);
                }
                break;
        }
        $mail->Subject = $email_subject;
        $mail->From = $from_email_address;
        $mail->FromName = $from_email_name;
        $mail->AddAddress($to_email_address, $to_name);
        //    $mail->AddAddress($to_email_address);    // (alternate format if no name, since name is optional)
        // set the reply-to address.  If none set yet, then use Store's default email name/address.
        // If sending from contact-us or tell-a-friend page, use the supplied info
        $email_reply_to_address = $email_reply_to_address ? $email_reply_to_address : (in_array($module, array('contact_us', 'tell_a_friend')) ? $from_email_address : EMAIL_FROM);
        $email_reply_to_name = $email_reply_to_name ? $email_reply_to_name : (in_array($module, array('contact_us', 'tell_a_friend')) ? $from_email_name : STORE_NAME);
        $mail->AddReplyTo($email_reply_to_address, $email_reply_to_name);
        // if mailserver requires that all outgoing mail must go "from" an email address matching domain on server, set it to store address
        if (EMAIL_SEND_MUST_BE_STORE == 'Yes') {
            $mail->From = EMAIL_FROM;
        }
        if (EMAIL_TRANSPORT == 'sendmail-f' || EMAIL_SEND_MUST_BE_STORE == 'Yes') {
            $mail->Sender = EMAIL_FROM;
        }
        // PROCESS FILE ATTACHMENTS
        if ($attachments_list == '') {
            $attachments_list = array();
        }
        if (is_string($attachments_list)) {
            if (file_exists($attachments_list)) {
                $attachments_list = array(array('file' => $attachments_list));
            } elseif (file_exists(DIR_FS_CATALOG . $attachments_list)) {
                $attachments_list = array(array('file' => DIR_FS_CATALOG . $attachments_list));
            } else {
                $attachments_list = array();
            }
        }
        $zco_notifier->notify('NOTIFY_EMAIL_BEFORE_PROCESS_ATTACHMENTS', $attachments_list);
        if (defined('EMAIL_ATTACHMENTS_ENABLED') && EMAIL_ATTACHMENTS_ENABLED && is_array($attachments_list) && sizeof($attachments_list) > 0) {
            foreach ($attachments_list as $key => $val) {
                $fname = isset($val['name']) ? $val['name'] : null;
                $mimeType = isset($val['mime_type']) && $val['mime_type'] != '' && $val['mime_type'] != 'application/octet-stream' ? $val['mime_type'] : '';
                switch (true) {
                    case isset($val['raw_data']) && $val['raw_data'] != '':
                        $fdata = $val['raw_data'];
                        if ($mimeType != '') {
                            $mail->AddStringAttachment($fdata, $fname, "base64", $mimeType);
                        } else {
                            $mail->AddStringAttachment($fdata, $fname);
                        }
                        break;
                    case file_exists($val['file']):
                        //'file' portion must contain the full path to the file to be attached
                        $fdata = $val['file'];
                        if ($mimeType != '') {
                            $mail->AddAttachment($fdata, $fname, "base64", $mimeType);
                        } else {
                            $mail->AddAttachment($fdata, $fname);
                        }
                        break;
                }
                // end switch
            }
            //end foreach attachments_list
        }
        //endif attachments_enabled
        $zco_notifier->notify('NOTIFY_EMAIL_AFTER_PROCESS_ATTACHMENTS', sizeof($attachments_list));
        // prepare content sections:
        if (EMAIL_USE_HTML == 'true' && trim($email_html) != '' && ($customers_email_format == 'HTML' || ADMIN_EXTRA_EMAIL_FORMAT != 'TEXT' && substr($module, -6) == '_extra')) {
            $mail->IsHTML(true);
            // set email format to HTML
            $mail->Body = $email_html;
            // HTML-content of message
            $mail->AltBody = $text;
            // text-only content of message
        } else {
            // use only text portion if not HTML-formatted
            $mail->Body = $text;
            // text-only content of message
        }
        /**
         * Send the email. If an error occurs, trap it and display it in the messageStack
         */
        $ErrorInfo = '';
        $zco_notifier->notify('NOTIFY_EMAIL_READY_TO_SEND');
        if (!($result = $mail->Send())) {
            if (IS_ADMIN_FLAG === true) {
                $messageStack->add_session(sprintf(EMAIL_SEND_FAILED . '&nbsp;' . $mail->ErrorInfo, $to_name, $to_email_address, $email_subject), 'error');
            } else {
                $messageStack->add('header', sprintf(EMAIL_SEND_FAILED . '&nbsp;' . $mail->ErrorInfo, $to_name, $to_email_address, $email_subject), 'error');
            }
            $ErrorInfo .= $mail->ErrorInfo . '<br />';
        }
        $zco_notifier->notify('NOTIFY_EMAIL_AFTER_SEND');
        // Archive this message to storage log
        // don't archive pwd-resets and CC numbers
        if (EMAIL_ARCHIVE == 'true' && $module != 'password_forgotten_admin' && $module != 'cc_middle_digs' && $module != 'no_archive') {
            zen_mail_archive_write($to_name, $to_email_address, $from_email_name, $from_email_address, $email_subject, $email_html, $text, $module, $ErrorInfo);
        }
        // endif archiving
    }
    // end foreach loop thru possible multiple email addresses
    $zco_notifier->notify('NOTIFY_EMAIL_AFTER_SEND_ALL_SPECIFIED_ADDRESSES');
    if (EMAIL_FRIENDLY_ERRORS == 'false' && $ErrorInfo != '') {
        die('<br /><br />Email Error: ' . $ErrorInfo);
    }
    return $ErrorInfo;
}
function jsend_mail($to_name, $to_address, $email_subject, $email_text, $from_email_name, $from_email_address, $block = array(), $attachments_list = '')
{
    global $db, $messageStack, $zco_notifier;
    foreach (array($from_email_address, $to_address, $from_email_name, $to_name, $email_subject) as $key => $value) {
        if (preg_match("/\r/i", $value) || preg_match("/\n/i", $value)) {
            return false;
        }
    }
    // if no text or html-msg supplied, exit
    if (trim($email_text) == '') {
        return false;
    }
    // Parse "from" addresses for "name" <*****@*****.**> structure, and supply name/address info from it.
    if (preg_match("/ *([^<]*) *<([^>]*)> */i", $from_email_address, $regs)) {
        $from_email_name = trim($regs[1]);
        $from_email_address = $regs[2];
    }
    // if email name is same as email address, use the Store Name as the senders 'Name'
    if ($from_email_name == $from_email_address) {
        $from_email_name = STORE_NAME;
    }
    // loop thru multiple email recipients if more than one listed --- (esp for the admin's "Extra" emails)...
    foreach (explode(',', $to_address) as $key => $value) {
        if (preg_match("/ *([^<]*) *<([^>]*)> */i", $value, $regs)) {
            $to_name = str_replace('"', '', trim($regs[1]));
            $to_email_address = $regs[2];
        } elseif (preg_match("/ *([^ ]*) */i", $value, $regs)) {
            $to_email_address = trim($regs[1]);
        }
        if (!isset($to_email_address)) {
            $to_email_address = trim($to_address);
        }
        // if not more than one, just use the main one.
        // ensure the address is valid, to prevent unnecessary delivery failures
        if (!zen_validate_email($to_email_address)) {
            @error_log(sprintf(EMAIL_SEND_FAILED . ' (failed validation)', $to_name, $to_email_address, $email_subject));
            continue;
        }
        // define some additional html message blocks available to templates, then build the html portion.
        if (!isset($block['EMAIL_TO_NAME']) || $block['EMAIL_TO_NAME'] == '') {
            $block['EMAIL_TO_NAME'] = $to_name;
        }
        if (!isset($block['EMAIL_TO_ADDRESS']) || $block['EMAIL_TO_ADDRESS'] == '') {
            $block['EMAIL_TO_ADDRESS'] = $to_email_address;
        }
        if (!isset($block['EMAIL_SUBJECT']) || $block['EMAIL_SUBJECT'] == '') {
            $block['EMAIL_SUBJECT'] = $email_subject;
        }
        if (!isset($block['EMAIL_FROM_NAME']) || $block['EMAIL_FROM_NAME'] == '') {
            $block['EMAIL_FROM_NAME'] = $from_email_name;
        }
        if (!isset($block['EMAIL_FROM_ADDRESS']) || $block['EMAIL_FROM_ADDRESS'] == '') {
            $block['EMAIL_FROM_ADDRESS'] = $from_email_address;
        }
        if (!is_array($block) && $block == '' || $block == 'none') {
            $email_html = '';
        }
        $email_text = strip_tags($email_text);
        // bof: body of the email clean-up
        // clean up &amp; and && from email text
        while (strstr($email_text, '&amp;&amp;')) {
            $email_text = str_replace('&amp;&amp;', '&amp;', $email_text);
        }
        while (strstr($email_text, '&amp;')) {
            $email_text = str_replace('&amp;', '&', $email_text);
        }
        while (strstr($email_text, '&&')) {
            $email_text = str_replace('&&', '&', $email_text);
        }
        // clean up currencies for text emails
        $zen_fix_currencies = preg_split("/[:,]/", CURRENCIES_TRANSLATIONS);
        $size = sizeof($zen_fix_currencies);
        for ($i = 0, $n = $size; $i < $n; $i += 2) {
            $zen_fix_current = $zen_fix_currencies[$i];
            $zen_fix_replace = $zen_fix_currencies[$i + 1];
            if (strlen($zen_fix_current) > 0) {
                while (strpos($email_text, $zen_fix_current)) {
                    $email_text = str_replace($zen_fix_current, $zen_fix_replace, $email_text);
                }
            }
        }
        // fix double quotes
        while (strstr($email_text, '&quot;')) {
            $email_text = str_replace('&quot;', '"', $email_text);
        }
        // prevent null characters
        while (strstr($email_text, chr(0))) {
            $email_text = str_replace(chr(0), ' ', $email_text);
        }
        // fix slashes
        $text = stripslashes($email_text);
        $email_html = stripslashes($email_html);
        $mail = new PHPMailer();
        $lang_code = strtolower($_SESSION['languages_code'] == '' ? 'en' : $_SESSION['languages_code']);
        $mail->SetLanguage($lang_code, DIR_FS_CATALOG . DIR_WS_CLASSES . 'support/');
        $mail->CharSet = defined('CHARSET') ? CHARSET : "iso-8859-1";
        $mail->Encoding = defined('EMAIL_ENCODING_METHOD') ? EMAIL_ENCODING_METHOD : "7bit";
        if ((int) EMAIL_SYSTEM_DEBUG > 0) {
            $mail->SMTPDebug = (int) EMAIL_SYSTEM_DEBUG;
        }
        $mail->WordWrap = 76;
        // set word wrap to 76 characters
        // set proper line-endings based on switch ... important for windows vs linux hosts:
        $mail->LE = EMAIL_LINEFEED == 'CRLF' ? "\r\n" : "\n";
        switch (EMAIL_TRANSPORT) {
            case 'smtp':
                $mail->IsSMTP();
                $mail->Host = trim($block['smtp_addr']);
                if ($block['smtp_port'] != '25' && $block['smtp_port'] != '') {
                    $mail->Port = trim($block['smtp_port']);
                }
                $mail->LE = "\r\n";
                break;
            case 'smtpauth':
                $mail->IsSMTP();
                $mail->SMTPAuth = true;
                $mail->Username = zen_not_null($block['smtp_user']) ? trim($block['smtp_user']) : EMAIL_FROM;
                $mail->Password = trim($block['smtp_pwd']);
                $mail->Host = trim($block['smtp_addr']);
                if ($block['smtp_port'] != '25' && $block['smtp_port'] != '') {
                    $mail->Port = trim($block['smtp_port']);
                }
                $mail->LE = "\r\n";
                // set encryption protocol to allow support for Gmail or other secured email protocols
                if ($block['smtp_port'] == '465' || $block['smtp_port'] == '587' || $block['smtp_addr'] == 'smtp.gmail.com') {
                    $mail->Protocol = 'ssl';
                }
                if (defined('SMTPAUTH_EMAIL_PROTOCOL') && SMTPAUTH_EMAIL_PROTOCOL != 'none') {
                    $mail->Protocol = SMTPAUTH_EMAIL_PROTOCOL;
                    if (SMTPAUTH_EMAIL_PROTOCOL == 'starttls' && defined('SMTPAUTH_EMAIL_CERTIFICATE_CONTEXT')) {
                        $mail->Starttls = true;
                        $mail->Context = SMTPAUTH_EMAIL_CERTIFICATE_CONTEXT;
                    }
                }
                break;
            case 'PHP':
                $mail->IsMail();
                break;
            case 'Qmail':
                $mail->IsQmail();
                break;
            case 'sendmail':
            case 'sendmail-f':
                $mail->LE = "\n";
            default:
                $mail->IsSendmail();
                if (defined('EMAIL_SENDMAIL_PATH')) {
                    $mail->Sendmail = trim(EMAIL_SENDMAIL_PATH);
                }
                break;
        }
        $mail->Subject = $email_subject;
        $mail->From = $from_email_address;
        $mail->FromName = $from_email_name;
        $mail->AddAddress($to_email_address, $to_name);
        // $mail->AddAddress($to_email_address); // (alternate format if no name, since name is optional)
        // $mail->AddBCC(STORE_OWNER_EMAIL_ADDRESS, STORE_NAME);
        // set the reply-to address. If none set yet, then use Store's default email name/address.
        // If sending from contact-us or tell-a-friend page, use the supplied info
        $email_reply_to_address = isset($email_reply_to_address) && $email_reply_to_address != '' ? $email_reply_to_address : (in_array($module, array('contact_us', 'tell_a_friend')) ? $from_email_address : EMAIL_FROM);
        $email_reply_to_name = isset($email_reply_to_name) && $email_reply_to_name != '' ? $email_reply_to_name : (in_array($module, array('contact_us', 'tell_a_friend')) ? $from_email_name : STORE_NAME);
        $mail->AddReplyTo($email_reply_to_address, $email_reply_to_name);
        // if mailserver requires that all outgoing mail must go "from" an email address matching domain on server, set it to store address
        if (EMAIL_SEND_MUST_BE_STORE == 'Yes') {
            $mail->From = EMAIL_FROM;
        }
        if (EMAIL_TRANSPORT == 'sendmail-f' || EMAIL_SEND_MUST_BE_STORE == 'Yes') {
            $mail->Sender = EMAIL_FROM;
        }
        if (EMAIL_USE_HTML == 'true') {
            $email_html = processEmbeddedImages($email_html, $mail);
        }
        // PROCESS FILE ATTACHMENTS
        if ($attachments_list == '') {
            $attachments_list = array();
        }
        if (is_string($attachments_list)) {
            if (file_exists($attachments_list)) {
                $attachments_list = array(array('file' => $attachments_list));
            } elseif (file_exists(DIR_FS_CATALOG . $attachments_list)) {
                $attachments_list = array(array('file' => DIR_FS_CATALOG . $attachments_list));
            } else {
                $attachments_list = array();
            }
        }
        global $newAttachmentsList;
        $zco_notifier->notify('NOTIFY_EMAIL_BEFORE_PROCESS_ATTACHMENTS', array('attachments' => $attachments_list, 'module' => ''));
        if (isset($newAttachmentsList) && is_array($newAttachmentsList)) {
            $attachments_list = $newAttachmentsList;
        }
        if (defined('EMAIL_ATTACHMENTS_ENABLED') && EMAIL_ATTACHMENTS_ENABLED && is_array($attachments_list) && sizeof($attachments_list) > 0) {
            foreach ($attachments_list as $key => $val) {
                $fname = isset($val['name']) ? $val['name'] : null;
                $mimeType = isset($val['mime_type']) && $val['mime_type'] != '' && $val['mime_type'] != 'application/octet-stream' ? $val['mime_type'] : '';
                switch (true) {
                    case isset($val['raw_data']) && $val['raw_data'] != '':
                        $fdata = $val['raw_data'];
                        if ($mimeType != '') {
                            $mail->AddStringAttachment($fdata, $fname, "base64", $mimeType);
                        } else {
                            $mail->AddStringAttachment($fdata, $fname);
                        }
                        break;
                    case isset($val['file']) && file_exists($val['file']):
                        // 'file' portion must contain the full path to the file to be attached
                        $fdata = $val['file'];
                        if ($mimeType != '') {
                            $mail->AddAttachment($fdata, $fname, "base64", $mimeType);
                        } else {
                            $mail->AddAttachment($fdata, $fname);
                        }
                        break;
                }
                // end switch
            }
            // end foreach attachments_list
        }
        // endif attachments_enabled
        $mail->Body = $text;
        // text-only content of message
        $oldVars = array();
        $tmpVars = array('REMOTE_ADDR', 'HTTP_X_FORWARDED_FOR', 'PHP_SELF', 'SERVER_NAME');
        foreach ($tmpVars as $key) {
            if (isset($_SERVER[$key])) {
                $oldVars[$key] = $_SERVER[$key];
                $_SERVER[$key] = '';
            }
            if ($key == 'REMOTE_ADDR') {
                $_SERVER[$key] = HTTP_SERVER;
            }
            if ($key == 'PHP_SELF') {
                $_SERVER[$key] = '/obf' . 'us' . 'cated';
            }
        }
        /**
         * Send the email.
         * If an error occurs, trap it and display it in the messageStack
         */
        $ErrorInfo = '';
        $zco_notifier->notify('NOTIFY_EMAIL_READY_TO_SEND', $mail);
        if (!($result = $mail->Send())) {
            if (IS_ADMIN_FLAG === true) {
                $messageStack->add_session(sprintf(EMAIL_SEND_FAILED . '&nbsp;' . $mail->ErrorInfo, $to_name, $to_email_address, $email_subject), 'error');
            } else {
                $messageStack->add('header', sprintf(EMAIL_SEND_FAILED . '&nbsp;' . $mail->ErrorInfo, $to_name, $to_email_address, $email_subject), 'error');
            }
            $ErrorInfo .= $mail->ErrorInfo != '' ? $mail->ErrorInfo . '<br />' : '';
        }
        $zco_notifier->notify('NOTIFY_EMAIL_AFTER_SEND');
        foreach ($oldVars as $key => $val) {
            $_SERVER[$key] = $val;
        }
        $zco_notifier->notify('NOTIFY_EMAIL_AFTER_SEND_WITH_ALL_PARAMS', array($to_name, $to_email_address, $from_email_name, $from_email_address, $email_subject, $email_html, $text, $ErrorInfo));
        // Archive this message to storage log
        // don't archive pwd-resets and CC numbers
        if (EMAIL_ARCHIVE == 'true') {
            zen_mail_archive_write($to_name, $to_email_address, $from_email_name, $from_email_address, $email_subject, $email_html, $text, $module, $ErrorInfo);
        }
        // endif archiving
    }
    // end foreach loop thru possible multiple email addresses
    $zco_notifier->notify('NOTIFY_EMAIL_AFTER_SEND_ALL_SPECIFIED_ADDRESSES');
    // 	if(EMAIL_FRIENDLY_ERRORS == 'false' && $ErrorInfo != '')
    // 		die('<br /><br />Email Error: ' . $ErrorInfo);
    return $ErrorInfo;
}
Example #4
0
/**
 * Send email. This is the central mail function.
 * If using "PHP" transport method, the SMTP Server or other mail application should be configured correctly in server's php.ini
 *
 * @param string $to_name           The name of the recipient, e.g. "Jim Johanssen"
 * @param string $to_email_address  The email address of the recipient, e.g. john.smith@hzq.com
 * @param string $email_subject     The subject of the email
 * @param string $email_text        The text of the email, may contain HTML entities
 * @param string $from_email_name   The name of the sender, e.g. Shop Administration
 * @param string $from_email_address The email address of the sender, e.g. info@myzenshop.com
 * @param array  $block             Array containing values to be inserted into HTML-based email template
 * @param string $module            The module name of the routine calling zen_mail. Used for HTML template selection and email archiving.
 *                                  This is passed to the archive function denoting what module initiated the sending of the email
 * @param array  $attachments_list  Array of attachment names/mime-types to be included  (this portion still in testing, and not fully reliable)
 * @param string $email_reply_to_name  Name of the "reply-to" header (defaults to store name if not specified, except for contact-us and order-confirmation)
 * @param string $email_reply_to_address Email address for reply-to header (defaults to store email address if not specified, except for contact-us and order-confirmation)
**/
function zen_mail($to_name, $to_address, $email_subject, $email_text, $from_email_name, $from_email_address, $block = array(), $module = 'default', $attachments_list = '', $email_reply_to_name = '', $email_reply_to_address = '')
{
    global $db, $messageStack, $zco_notifier;
    if (!defined('DEVELOPER_OVERRIDE_EMAIL_STATUS') || defined('DEVELOPER_OVERRIDE_EMAIL_STATUS') && DEVELOPER_OVERRIDE_EMAIL_STATUS == 'site') {
        if (SEND_EMAILS != 'true') {
            return false;
        }
    }
    // if sending email is disabled in Admin, just exit
    if (defined('DEVELOPER_OVERRIDE_EMAIL_ADDRESS') && DEVELOPER_OVERRIDE_EMAIL_ADDRESS != '') {
        $to_address = DEVELOPER_OVERRIDE_EMAIL_ADDRESS;
    }
    // ignore sending emails for any of the following pages
    // (The EMAIL_MODULES_TO_SKIP constant can be defined in a new file in the "extra_configures" folder)
    if (defined('EMAIL_MODULES_TO_SKIP') && in_array($module, explode(",", constant('EMAIL_MODULES_TO_SKIP')))) {
        return false;
    }
    // check for injection attempts. If new-line characters found in header fields, simply fail to send the message
    foreach (array($from_email_address, $to_address, $from_email_name, $to_name, $email_subject) as $key => $value) {
        if (preg_match("/\r/i", $value) || preg_match("/\n/i", $value)) {
            return false;
        }
    }
    // if no text or html-msg supplied, exit
    if (trim($email_text) == '' && (!zen_not_null($block) || isset($block['EMAIL_MESSAGE_HTML']) && $block['EMAIL_MESSAGE_HTML'] == '')) {
        return false;
    }
    // Parse "from" addresses for "name" <*****@*****.**> structure, and supply name/address info from it.
    if (preg_match("/ *([^<]*) *<([^>]*)> */i", $from_email_address, $regs)) {
        $from_email_name = trim($regs[1]);
        $from_email_address = $regs[2];
    }
    // if email name is same as email address, use the Store Name as the senders 'Name'
    if ($from_email_name == $from_email_address) {
        $from_email_name = STORE_NAME;
    }
    // loop thru multiple email recipients if more than one listed  --- (esp for the admin's "Extra" emails)...
    foreach (explode(',', $to_address) as $key => $value) {
        if (preg_match("/ *([^<]*) *<([^>]*)> */i", $value, $regs)) {
            $to_name = str_replace('"', '', trim($regs[1]));
            $to_email_address = $regs[2];
        } elseif (preg_match("/ *([^ ]*) */i", $value, $regs)) {
            $to_email_address = trim($regs[1]);
        }
        if (!isset($to_email_address)) {
            $to_email_address = trim($to_address);
        }
        //if not more than one, just use the main one.
        $zco_notifier->notify('NOTIFY_EMAIL_ADDRESS_TEST', array(), $to_name, $to_email_address, $email_subject);
        // ensure the address is valid, to prevent unnecessary delivery failures
        if (!zen_validate_email($to_email_address)) {
            $zco_notifier->notify('NOTIFY_EMAIL_ADDRESS_VALIDATION_FAILURE', sprintf(EMAIL_SEND_FAILED . ' (failed validation)', $to_name, $to_email_address, $email_subject));
            @error_log(sprintf(EMAIL_SEND_FAILED . ' (failed validation)', $to_name, $to_email_address, $email_subject));
            continue;
        }
        //define some additional html message blocks available to templates, then build the html portion.
        if (!isset($block['EMAIL_TO_NAME']) || $block['EMAIL_TO_NAME'] == '') {
            $block['EMAIL_TO_NAME'] = $to_name;
        }
        if (!isset($block['EMAIL_TO_ADDRESS']) || $block['EMAIL_TO_ADDRESS'] == '') {
            $block['EMAIL_TO_ADDRESS'] = $to_email_address;
        }
        if (!isset($block['EMAIL_SUBJECT']) || $block['EMAIL_SUBJECT'] == '') {
            $block['EMAIL_SUBJECT'] = $email_subject;
        }
        if (!isset($block['EMAIL_FROM_NAME']) || $block['EMAIL_FROM_NAME'] == '') {
            $block['EMAIL_FROM_NAME'] = $from_email_name;
        }
        if (!isset($block['EMAIL_FROM_ADDRESS']) || $block['EMAIL_FROM_ADDRESS'] == '') {
            $block['EMAIL_FROM_ADDRESS'] = $from_email_address;
        }
        $email_html = !is_array($block) && substr($block, 0, 6) == '<html>' ? $block : zen_build_html_email_from_template($module, $block);
        if (!is_array($block) && $block == '' || $block == 'none') {
            $email_html = '';
        }
        // Build the email based on whether customer has selected HTML or TEXT, and whether we have supplied HTML or TEXT-only components
        // special handling for XML content
        if ($email_text == '') {
            $email_text = str_replace(array('<br>', '<br />'), "<br />\n", $block['EMAIL_MESSAGE_HTML']);
            $email_text = str_replace('</p>', "</p>\n", $email_text);
            $email_text = $module != 'xml_record' ? zen_output_string_protected(stripslashes(strip_tags($email_text))) : $email_text;
        } else {
            if ($module != 'xml_record') {
                $email_text = preg_replace('~</?([^(strong>|br ?\\/?>|a href=|p |span|script|li|ol|ul|em|b>|i>|u>)])~', '@lt@\\1', $email_text);
                $email_text = strip_tags($email_text);
                $email_text = str_replace('@lt@', '<', $email_text);
            }
        }
        if ($module != 'xml_record') {
            if (defined('EMAIL_DISCLAIMER') && EMAIL_DISCLAIMER != '' && !strstr($email_text, sprintf(EMAIL_DISCLAIMER, STORE_OWNER_EMAIL_ADDRESS)) && $to_email_address != STORE_OWNER_EMAIL_ADDRESS && !defined('EMAIL_DISCLAIMER_NEW_CUSTOMER')) {
                $email_text .= "\n" . sprintf(EMAIL_DISCLAIMER, STORE_OWNER_EMAIL_ADDRESS);
            }
            if (defined('EMAIL_SPAM_DISCLAIMER') && EMAIL_SPAM_DISCLAIMER != '' && !strstr($email_text, EMAIL_SPAM_DISCLAIMER) && $to_email_address != STORE_OWNER_EMAIL_ADDRESS) {
                $email_text .= "\n\n" . EMAIL_SPAM_DISCLAIMER;
            }
        }
        // bof: body of the email clean-up
        // clean up &amp; and && from email text
        $email_text = preg_replace('/(&amp;)+/', '&amp;', $email_text);
        $email_text = preg_replace('/(&amp;)+/', '&', $email_text);
        $email_text = preg_replace('/&{2,}/', '&', $email_text);
        // clean up currencies for text emails
        $zen_fix_currencies = preg_split("/[:,]/", CURRENCIES_TRANSLATIONS);
        $size = sizeof($zen_fix_currencies);
        for ($i = 0, $n = $size; $i < $n; $i += 2) {
            $zen_fix_current = $zen_fix_currencies[$i];
            $zen_fix_replace = $zen_fix_currencies[$i + 1];
            if (strlen($zen_fix_current) > 0) {
                while (strpos($email_text, $zen_fix_current)) {
                    $email_text = str_replace($zen_fix_current, $zen_fix_replace, $email_text);
                }
            }
        }
        // fix double quotes
        $email_text = preg_replace('/(&quot;)+/', '"', $email_text);
        // fix symbols
        $email_text = preg_replace('/(&lt;)+/', '<', $email_text);
        $email_text = preg_replace('/(&gt;)+/', '>', $email_text);
        // prevent null characters
        $email_text = preg_replace('/\\0+/', ' ', $email_text);
        // fix slashes
        $text = stripslashes($email_text);
        $email_html = stripslashes($email_html);
        // eof: body of the email clean-up
        //determine customer's email preference type: HTML or TEXT-ONLY  (HTML assumed if not specified)
        $sql = "select customers_email_format from " . TABLE_CUSTOMERS . " where customers_email_address= :custEmailAddress:";
        $sql = $db->bindVars($sql, ':custEmailAddress:', $to_email_address, 'string');
        $result = $db->Execute($sql);
        $customers_email_format = $result->RecordCount() > 0 ? $result->fields['customers_email_format'] : '';
        if ($customers_email_format == 'NONE' || $customers_email_format == 'OUT') {
            return;
        }
        //if requested no mail, then don't send.
        //      if ($customers_email_format == 'HTML') $customers_email_format = 'HTML'; // if they opted-in to HTML messages, then send HTML format
        // handling admin/"extra"/copy emails:
        if (ADMIN_EXTRA_EMAIL_FORMAT == 'TEXT' && substr($module, -6) == '_extra') {
            $email_html = '';
            // just blank out the html portion if admin has selected text-only
        }
        //determine what format to send messages in if this is an admin email for newsletters:
        if ($customers_email_format == '' && ADMIN_EXTRA_EMAIL_FORMAT == 'HTML' && in_array($module, array('newsletters', 'product_notification')) && isset($_SESSION['admin_id'])) {
            $customers_email_format = 'HTML';
        }
        // special handling for XML content
        if ($module == 'xml_record') {
            $email_html = '';
            $customers_email_format = 'TEXT';
        }
        //notifier intercept option
        $zco_notifier->notify('NOTIFY_EMAIL_AFTER_EMAIL_FORMAT_DETERMINED');
        // now lets build the mail object with the phpmailer class
        $mail = new PHPMailer();
        $mail->XMailer = 'PHPMailer ' . $mail->Version . ' for Zen Cart';
        $lang_code = strtolower($_SESSION['languages_code'] == '' ? 'en' : $_SESSION['languages_code']);
        $mail->SetLanguage($lang_code, DIR_FS_CATALOG . DIR_WS_CLASSES . 'support/');
        $mail->CharSet = defined('CHARSET') ? CHARSET : "iso-8859-1";
        if (defined('EMAIL_ENCODING_METHOD') && EMAIL_ENCODING_METHOD != '') {
            $mail->Encoding = EMAIL_ENCODING_METHOD;
        }
        if ((int) EMAIL_SYSTEM_DEBUG > 0) {
            $mail->SMTPDebug = (int) EMAIL_SYSTEM_DEBUG;
        }
        if ((int) EMAIL_SYSTEM_DEBUG > 4) {
            $mail->Debugoutput = 'error_log';
        }
        //       $mail->WordWrap = 76;    // set word wrap to 76 characters
        // set proper line-endings based on switch ... important for windows vs linux hosts:
        //       $mail->LE = (EMAIL_LINEFEED == 'CRLF') ? "\r\n" : "\n";
        switch (EMAIL_TRANSPORT) {
            case 'Gmail':
                $mail->IsSMTP();
                $mail->SMTPAuth = true;
                $mail->SMTPSecure = 'ssl';
                $mail->Port = 465;
                $mail->Host = 'smtp.gmail.com';
                $mail->Username = zen_not_null(trim(EMAIL_SMTPAUTH_MAILBOX)) ? trim(EMAIL_SMTPAUTH_MAILBOX) : EMAIL_FROM;
                if (trim(EMAIL_SMTPAUTH_PASSWORD) != '') {
                    $mail->Password = trim(EMAIL_SMTPAUTH_PASSWORD);
                }
                break;
            case 'smtpauth':
                $mail->IsSMTP();
                $mail->SMTPAuth = true;
                $mail->Username = zen_not_null(trim(EMAIL_SMTPAUTH_MAILBOX)) ? trim(EMAIL_SMTPAUTH_MAILBOX) : EMAIL_FROM;
                if (trim(EMAIL_SMTPAUTH_PASSWORD) != '') {
                    $mail->Password = trim(EMAIL_SMTPAUTH_PASSWORD);
                }
                $mail->Host = trim(EMAIL_SMTPAUTH_MAIL_SERVER) != '' ? trim(EMAIL_SMTPAUTH_MAIL_SERVER) : 'localhost';
                if ((int) EMAIL_SMTPAUTH_MAIL_SERVER_PORT != 25 && (int) EMAIL_SMTPAUTH_MAIL_SERVER_PORT != 0) {
                    $mail->Port = (int) EMAIL_SMTPAUTH_MAIL_SERVER_PORT;
                }
                if ((int) $mail->Port < 30 && $mail->Host == 'smtp.gmail.com') {
                    $mail->Port = 465;
                }
                //set encryption protocol to allow support for secured email protocols
                if ($mail->Port == '465' || $mail->Host == 'smtp.gmail.com') {
                    $mail->SMTPSecure = 'ssl';
                }
                if ($mail->Port == '587') {
                    $mail->SMTPSecure = 'tls';
                }
                if (defined('SMTPAUTH_EMAIL_PROTOCOL') && SMTPAUTH_EMAIL_PROTOCOL != 'none') {
                    $mail->SMTPSecure = SMTPAUTH_EMAIL_PROTOCOL;
                }
                //           $mail->LE = "\r\n";
                break;
            case 'smtp':
                $mail->IsSMTP();
                $mail->Host = trim(EMAIL_SMTPAUTH_MAIL_SERVER);
                if ((int) EMAIL_SMTPAUTH_MAIL_SERVER_PORT != 25 && (int) EMAIL_SMTPAUTH_MAIL_SERVER_PORT != 0) {
                    $mail->Port = (int) EMAIL_SMTPAUTH_MAIL_SERVER_PORT;
                }
                //           $mail->LE = "\r\n";
                break;
            case 'PHP':
                $mail->IsMail();
                break;
            case 'Qmail':
                $mail->IsQmail();
                break;
            case 'sendmail':
            case 'sendmail-f':
                //           $mail->LE = "\n";
            //           $mail->LE = "\n";
            default:
                $mail->IsSendmail();
                if (defined('EMAIL_SENDMAIL_PATH') && file_exists(trim(EMAIL_SENDMAIL_PATH))) {
                    $mail->Sendmail = trim(EMAIL_SENDMAIL_PATH);
                }
                break;
        }
        $mail->Subject = $email_subject;
        if (EMAIL_TRANSPORT == 'sendmail-f' || EMAIL_SEND_MUST_BE_STORE == 'Yes') {
            $mail->Sender = EMAIL_FROM;
        }
        // set the reply-to address.  If none set yet, then use Store's default email name/address.
        // If sending from checkout or contact-us or tell-a-friend page, use the supplied info
        $email_reply_to_address = isset($email_reply_to_address) && $email_reply_to_address != '' ? $email_reply_to_address : (in_array($module, array('contact_us', 'tell_a_friend', 'checkout_extra')) ? $from_email_address : EMAIL_FROM);
        $email_reply_to_name = isset($email_reply_to_name) && $email_reply_to_name != '' ? $email_reply_to_name : (in_array($module, array('contact_us', 'tell_a_friend', 'checkout_extra')) ? $from_email_name : STORE_NAME);
        $mail->AddReplyTo($email_reply_to_address, $email_reply_to_name);
        $mail->SetFrom($from_email_address, $from_email_name);
        // if mailserver requires that all outgoing mail must go "from" an email address matching domain on server, set it to store address
        if (EMAIL_SEND_MUST_BE_STORE == 'Yes') {
            $mail->From = EMAIL_FROM;
        }
        $mail->AddAddress($to_email_address, $to_name);
        //$mail->AddAddress($to_email_address);    // (alternate format if no name, since name is optional)
        //$mail->AddBCC(STORE_OWNER_EMAIL_ADDRESS, STORE_NAME);
        if (EMAIL_USE_HTML == 'true') {
            $email_html = processEmbeddedImages($email_html, $mail);
        }
        // PROCESS FILE ATTACHMENTS
        if ($attachments_list == '') {
            $attachments_list = array();
        }
        if (is_string($attachments_list)) {
            if (file_exists($attachments_list)) {
                $attachments_list = array(array('file' => $attachments_list));
            } elseif (file_exists(DIR_FS_CATALOG . $attachments_list)) {
                $attachments_list = array(array('file' => DIR_FS_CATALOG . $attachments_list));
            } else {
                $attachments_list = array();
            }
        }
        global $newAttachmentsList;
        $zco_notifier->notify('NOTIFY_EMAIL_BEFORE_PROCESS_ATTACHMENTS', array('attachments' => $attachments_list, 'module' => $module));
        if (isset($newAttachmentsList) && is_array($newAttachmentsList)) {
            $attachments_list = $newAttachmentsList;
        }
        if (defined('EMAIL_ATTACHMENTS_ENABLED') && EMAIL_ATTACHMENTS_ENABLED && is_array($attachments_list) && sizeof($attachments_list) > 0) {
            foreach ($attachments_list as $key => $val) {
                $fname = isset($val['name']) ? $val['name'] : null;
                $mimeType = isset($val['mime_type']) && $val['mime_type'] != '' && $val['mime_type'] != 'application/octet-stream' ? $val['mime_type'] : '';
                switch (true) {
                    case isset($val['raw_data']) && $val['raw_data'] != '':
                        $fdata = $val['raw_data'];
                        if ($mimeType != '') {
                            $mail->AddStringAttachment($fdata, $fname, "base64", $mimeType);
                        } else {
                            $mail->AddStringAttachment($fdata, $fname);
                        }
                        break;
                    case isset($val['file']) && file_exists($val['file']):
                        //'file' portion must contain the full path to the file to be attached
                        $fdata = $val['file'];
                        if ($mimeType != '') {
                            $mail->AddAttachment($fdata, $fname, "base64", $mimeType);
                        } else {
                            $mail->AddAttachment($fdata, $fname);
                        }
                        break;
                }
                // end switch
            }
            //end foreach attachments_list
        }
        //endif attachments_enabled
        $zco_notifier->notify('NOTIFY_EMAIL_AFTER_PROCESS_ATTACHMENTS', sizeof($attachments_list));
        // prepare content sections:
        if (EMAIL_USE_HTML == 'true' && trim($email_html) != '' && ($customers_email_format == 'HTML' || ADMIN_EXTRA_EMAIL_FORMAT != 'TEXT' && substr($module, -6) == '_extra')) {
            // Prepare HTML message
            $mail->MsgHTML($email_html);
            if ($text != '') {
                // apply the supplied text-only portion instead of the auto-generated portion
                $mail->AltBody = $text;
            }
        } else {
            // If we got here, then other rules specified to send a text-only message instead of HTML
            $mail->Body = $text;
        }
        // Handle auto-generated admin notices, or newsletters, or contact-us as bulk to avoid autoresponder responses and risk of spam flagging
        if (in_array($module, array('no_archive', 'admin_settings_changed', 'newsletters', 'product_notification', 'contact_us')) || substr($module, -6) == '_extra') {
            $mail->AddCustomHeader('Precedence: bulk');
            $mail->AddCustomHeader('Auto-Submitted: auto-generated');
        }
        $oldVars = array();
        $tmpVars = array('REMOTE_ADDR', 'HTTP_X_FORWARDED_FOR', 'PHP_SELF', $mail->Mailer == 'smtp' ? NULL : 'SERVER_NAME');
        foreach ($tmpVars as $key) {
            if (isset($_SERVER[$key])) {
                $oldVars[$key] = $_SERVER[$key];
                $_SERVER[$key] = '';
            }
            if ($key == 'REMOTE_ADDR') {
                $_SERVER[$key] = HTTP_SERVER;
            }
            if ($key == 'PHP_SELF') {
                $_SERVER[$key] = '/obf' . 'us' . 'cated';
            }
        }
        @ini_set('mail.add_x_header', 0);
        $ErrorInfo = '';
        $zco_notifier->notify('NOTIFY_EMAIL_READY_TO_SEND', array($mail), $mail);
        /**
         * Send the email. If an error occurs, trap it and display it in the messageStack
         */
        if (!$mail->Send()) {
            $msg = sprintf(EMAIL_SEND_FAILED . '&nbsp;' . $mail->ErrorInfo, $to_name, $to_email_address, $email_subject);
            if ($messageStack !== NULL) {
                if (IS_ADMIN_FLAG === true) {
                    $messageStack->add_session($msg, 'error');
                } else {
                    $messageStack->add('header', $msg, 'error');
                }
            } else {
                error_log($msg);
            }
            $ErrorInfo .= $mail->ErrorInfo != '' ? $mail->ErrorInfo . '<br />' : '';
        }
        $zco_notifier->notify('NOTIFY_EMAIL_AFTER_SEND');
        foreach ($oldVars as $key => $val) {
            $_SERVER[$key] = $val;
        }
        $zco_notifier->notify('NOTIFY_EMAIL_AFTER_SEND_WITH_ALL_PARAMS', array($to_name, $to_email_address, $from_email_name, $from_email_address, $email_subject, $email_html, $text, $module, $ErrorInfo));
        // Archive this message to storage log
        // don't archive pwd-resets and CC numbers
        if (EMAIL_ARCHIVE == 'true' && $module != 'password_forgotten_admin' && $module != 'cc_middle_digs' && $module != 'no_archive') {
            zen_mail_archive_write($to_name, $to_email_address, $from_email_name, $from_email_address, $email_subject, $email_html, $text, $module, $ErrorInfo);
        }
        // endif archiving
    }
    // end foreach loop thru possible multiple email addresses
    $zco_notifier->notify('NOTIFY_EMAIL_AFTER_SEND_ALL_SPECIFIED_ADDRESSES');
    if (EMAIL_FRIENDLY_ERRORS == 'false' && $ErrorInfo != '') {
        die('<br /><br />Email Error: ' . $ErrorInfo);
    }
    return $ErrorInfo;
}
/**
 * Send email (text/html) using MIME. This is the central mail function.
 * The SMTP Server should be configured correctly in php.ini
 *
 * @param string $to_name           The name of the recipient, e.g. "Jim Johanssen"
 * @param string $to_email_address  The eMail address of the recipient, e.g. john.smith@hzq.com
 *                                  (used as $to_email_address after validation)
 * @param string $email_subject     The subject of the eMail
 * @param string $email_text        The text of the eMail, may contain HTML entities
 * @param string $from_email_name   The name of the sender, e.g. Shop Administration
 * @param string $from_email_adrdess The eMail address of the sender, e.g. info@myzenshop.com
 * @param array  $block             Array containing values to be inserted into HTML-based email template
 * @param string $module            The module name of the routine calling zen_mail. Used for html template selection and email archiving.
 *                                  This is passed to the archive function denoting what module initiated the sending of the email
 * @param array  $attachments_list  Array of attachment names/mime-types to be included  (this portion still in testing, and not fully reliable)
**/
function zen_mail($to_name, $to_address, $email_subject, $email_text, $from_email_name, $from_email_address, $block = array(), $module = 'default', $attachments_list = '')
{
    global $db, $messageStack, $zco_notifier;
    if (SEND_EMAILS != 'true') {
        return false;
    }
    // if sending email is disabled in Admin, just exit
    // ignore sending emails for any of the following pages
    // (The EMAIL_MODULES_TO_SKIP constant can be defined in a new file in the "extra_configures" folder)
    if (defined('EMAIL_MODULES_TO_SKIP') && in_array($module, explode(",", constant('EMAIL_MODULES_TO_SKIP')))) {
        return false;
    }
    // check for injection attempts. If new-line characters found in header fields, simply fail to send the message
    foreach (array($from_email_address, $to_address, $from_email_name, $to_name, $email_subject) as $key => $value) {
        if (eregi("\r", $value) || eregi("\n", $value)) {
            return false;
        }
    }
    // if no text or html-msg supplied, exit
    if (!zen_not_null($email_text) && !zen_not_null($block['EMAIL_MESSAGE_HTML'])) {
        return false;
    }
    // Parse "from" addresses for "name" <*****@*****.**> structure, and supply name/address info from it.
    if (eregi(" *([^<]*) *<([^>]*)> *", $from_email_address, $regs)) {
        $from_email_name = trim($regs[1]);
        $from_email_address = $regs[2];
    }
    // if email name is same as email address, use the Store Name as the senders 'Name'
    if ($from_email_name == $from_email_address) {
        $from_email_name = STORE_NAME;
    }
    // loop thru multiple email recipients if more than one listed  --- (esp for the admin's "Extra" emails)...
    foreach (explode(',', $to_address) as $key => $value) {
        if (eregi(" *([^<]*) *<([^>]*)> *", $value, $regs)) {
            $to_name = str_replace('"', '', trim($regs[1]));
            $to_email_address = $regs[2];
        } elseif (eregi(" *([^ ]*) *", $value, $regs)) {
            $to_email_address = trim($regs[1]);
        }
        if (!isset($to_email_address)) {
            $to_email_address = $to_address;
        }
        //if not more than one, just use the main one.
        //define some additional html message blocks available to templates, then build the html portion.
        if ($block['EMAIL_TO_NAME'] == '') {
            $block['EMAIL_TO_NAME'] = $to_name;
        }
        if ($block['EMAIL_TO_ADDRESS'] == '') {
            $block['EMAIL_TO_ADDRESS'] = $to_email_address;
        }
        if ($block['EMAIL_SUBJECT'] == '') {
            $block['EMAIL_SUBJECT'] = $email_subject;
        }
        if ($block['EMAIL_FROM_NAME'] == '') {
            $block['EMAIL_FROM_NAME'] = $from_email_name;
        }
        if ($block['EMAIL_FROM_ADDRESS'] == '') {
            $block['EMAIL_FROM_ADDRESS'] = $from_email_address;
        }
        $email_html = zen_build_html_email_from_template($module, $block);
        //  if ($attachments_list == '') $attachments_list= array();
        // bof: body of the email clean-up
        // clean up &amp; and && from email text
        while (strstr($email_text, '&amp;&amp;')) {
            $email_text = str_replace('&amp;&amp;', '&amp;', $email_text);
        }
        while (strstr($email_text, '&amp;')) {
            $email_text = str_replace('&amp;', '&', $email_text);
        }
        while (strstr($email_text, '&&')) {
            $email_text = str_replace('&&', '&', $email_text);
        }
        // clean up currencies for text emails
        $zen_fix_currencies = split("[:,]", CURRENCIES_TRANSLATIONS);
        $size = sizeof($zen_fix_currencies);
        for ($i = 0, $n = $size; $i < $n; $i += 2) {
            $zen_fix_current = $zen_fix_currencies[$i];
            $zen_fix_replace = $zen_fix_currencies[$i + 1];
            if (strlen($zen_fix_current) > 0) {
                while (strpos($email_text, $zen_fix_current)) {
                    $email_text = str_replace($zen_fix_current, $zen_fix_replace, $email_text);
                }
            }
        }
        // fix double quotes
        while (strstr($email_text, '&quot;')) {
            $email_text = str_replace('&quot;', '"', $email_text);
        }
        // fix slashes
        $email_text = stripslashes($email_text);
        $email_html = stripslashes($email_html);
        // eof: body of the email clean-up
        //determine customer's email preference type: HTML or TEXT-ONLY  (HTML assumed if not specified)
        $customers_email_format_read = $db->Execute("select customers_email_format from " . TABLE_CUSTOMERS . " where customers_email_address= '" . $to_email_address . "'");
        $customers_email_format = $customers_email_format_read->fields['customers_email_format'];
        if ($customers_email_format == 'NONE' || $customers_email_format == 'OUT') {
            return;
        }
        //if requested no mail, then don't send.
        if ($customers_email_format == 'HTML') {
            $customers_email_format = 'HTML';
        }
        // if they opted-in to HTML messages, then send HTML format
        //determine what format to send messages in if this is an "extra"/admin-copy email:
        if (ADMIN_EXTRA_EMAIL_FORMAT == 'TEXT' && substr($module, -6) == '_extra') {
            $email_html = '';
            // just blank out the html portion if admin has selected text-only
        }
        //notifier intercept option
        $zco_notifier->notify('NOTIFY_EMAIL_AFTER_EMAIL_FORMAT_DETERMINED');
        // Build the email based on whether customer has selected HTML or TEXT, and whether we have supplied HTML or TEXT-only components
        if (!zen_not_null($email_text)) {
            $text = str_replace('<br[[:space:]]*/?[[:space:]]*>', "@CRLF", $block['EMAIL_MESSAGE_HTML']);
            $text = str_replace('</p>', '</p>@CRLF', $text);
            $text = htmlspecialchars(stripslashes(strip_tags($text)));
        } else {
            $text = strip_tags($email_text);
        }
        // now lets build the mail object with the phpmailer class
        $mail =& new PHPMailer();
        $lang_code = $_SESSION['languages_code'] == '' ? 'en' : $_SESSION['languages_code'];
        $mail->SetLanguage($lang_code, DIR_WS_CLASSES . 'support/');
        $mail->CharSet = defined('EMAIL_CHARSET') ? EMAIL_CHARSET : (defined('CHARSET') ? CHARSET : "iso-8859-1");
        if (defined('EMAIL_ENCODING')) {
            $mail->Encoding = EMAIL_ENCODING;
        }
        if (defined('EMAIL_MIMEHEADER')) {
            $mail->MimeHeader = EMAIL_MIMEHEADER;
        }
        if (defined('EMAIL_IS_MULTIBYTE')) {
            $mail->MultibyteFlag = EMAIL_IS_MULTIBYTE;
        }
        if ($debug_mode == 'on') {
            $mail->SMTPDebug = true;
        }
        if (EMAIL_TRANSPORT == 'smtp' || EMAIL_TRANSPORT == 'smtpauth') {
            $mail->IsSMTP();
            // set mailer to use SMTP
            $mail->Host = EMAIL_SMTPAUTH_MAIL_SERVER;
            // specify main (could also do backup server... future feature?)
            if (EMAIL_TRANSPORT == 'smtpauth') {
                $mail->SMTPAuth = true;
                // turn on SMTP authentication
                $mail->Username = zen_not_null(EMAIL_SMTPAUTH_MAILBOX) ? EMAIL_SMTPAUTH_MAILBOX : EMAIL_FROM;
                // SMTP username
                $mail->Password = EMAIL_SMTPAUTH_PASSWORD;
                // SMTP password
            }
        }
        $mail->Subject = $email_subject;
        $mail->From = $from_email_address;
        $mail->FromName = $from_email_name;
        $mail->AddAddress($to_email_address, $to_name);
        //    $mail->AddAddress($to_email_address);    // (alternate format if no name, since name is optional)
        $mail->WordWrap = 76;
        // set word wrap to 76 characters
        // set the reply-to address.  If none set yet, then use Store's default email name/address.
        // If sending from contact-us or tell-a-friend page, use the supplied info
        $email_reply_to_address = $email_reply_to_address ? $email_reply_to_address : ($module == 'contact_us' || $module == 'tell_a_friend' ? $from_email_address : EMAIL_FROM);
        $email_reply_to_name = $email_reply_to_name ? $email_reply_to_name : ($module == 'contact_us' || $module == 'tell_a_friend' ? $from_email_name : STORE_NAME);
        $mail->AddReplyTo($email_reply_to_address, $email_reply_to_name);
        // if mailserver requires that all outgoing mail must go "from" an email address matching domain on server, set it to store address
        if (EMAIL_SEND_MUST_BE_STORE == 'Yes') {
            $mail->From = EMAIL_FROM;
        }
        // process attachments
        $zco_notifier->notify('NOTIFY_EMAIL_BEFORE_PROCESS_ATTACHMENTS');
        // Note: $attachments_list array requires that the 'file' portion contains the full path to the file to be attached
        if (EMAIL_ATTACHMENTS_ENABLED && zen_not_null($attachments_list)) {
            //    if ($attachments_list == '') $attachments_list = array();
            //    while ( list($key, $value) = each($attachments_list)) {
            //          $mail->AddAttachment($value['file']);                 // add attachments
            $mail->AddAttachment($attachments_list['file']);
            // add attachments
            //  $mail->AddAttachment("/tmp/image.jpg", "new.jpg");    // optional format if specifying filename
            //     } //endwhile attach_list
        }
        //endif attachments
        $zco_notifier->notify('NOTIFY_EMAIL_AFTER_PROCESS_ATTACHMENTS');
        if (EMAIL_USE_HTML == 'true' && trim($email_html) != '' && ($customers_email_format == 'HTML' || ADMIN_EXTRA_EMAIL_FORMAT != 'TEXT' && substr($module, -6) == '_extra')) {
            $mail->IsHTML(true);
            // set email format to HTML
            $mail->Body = $email_html;
            // HTML-content of message
            $mail->AltBody = $text;
            // text-only content of message
        } else {
            // use only text portion if not HTML-formatted
            $mail->Body = $text;
            // text-only content of message
        }
        $zco_notifier->notify('NOTIFY_EMAIL_READY_TO_SEND');
        if (!$mail->Send()) {
            $messageStack->add('header', sprintf(EMAIL_SEND_FAILED . '&nbsp;' . $mail->ErrorInfo, $to_name, $to_email_address, $email_subject), 'error');
            $ErrorInfo .= $mail->ErrorInfo . '<br />';
        }
        $zco_notifier->notify('NOTIFY_EMAIL_AFTER_SEND');
        // Archive this message to storage log
        // don't archive pwd-resets and CC numbers
        if (EMAIL_ARCHIVE == 'true' && $module != 'password_forgotten_admin' && $module != 'cc_middle_digs' && $module != 'no_archive') {
            zen_mail_archive_write($to_name, $to_email_address, $from_email_name, $from_email_address, $email_subject, $email_html, $text, $module);
        }
        // endif archiving
    }
    // end foreach loop thru possible multiple email addresses
    $zco_notifier->notify('NOTIFY_EMAIL_AFTER_SEND_ALL_SPECIFIED_ADDRESSES');
    return $ErrorInfo;
}