Example #1
0
/**
 * Sends out a full HTML mail
 *
 * @param array $options In the format:
 *     to => STR|ARR of recipients in RFC-2822 format (http://www.faqs.org/rfcs/rfc2822.html)
 *     from => STR of senden in RFC-2822 format (http://www.faqs.org/rfcs/rfc2822.html)
 *     subject => STR with the subject of the message
 *     body => STR with the message body
 *     plaintext_message STR with the plaintext version of the message
 *     html_message => STR with the HTML version of the message
 *     cc => NULL|STR|ARR of CC recipients in RFC-2822 format (http://www.faqs.org/rfcs/rfc2822.html)
 *     bcc => NULL|STR|ARR of BCC recipients in RFC-2822 format (http://www.faqs.org/rfcs/rfc2822.html)
 *     date => NULL|UNIX timestamp with the date the message was created
 *     attachments => NULL|ARR of array(array('mimetype', 'filename', 'content'))
 *
 * @return bool
 */
function html_email_handler_send_email(array $options = null)
{
    static $limit_subject;
    $site = elgg_get_site_entity();
    // make site email
    $site_from = html_email_handler_make_rfc822_address($site);
    // get sendmail options
    $sendmail_options = html_email_handler_get_sendmail_options();
    if (!isset($limit_subject)) {
        $limit_subject = false;
        if (elgg_get_plugin_setting("limit_subject", "html_email_handler") == "yes") {
            $limit_subject = true;
        }
    }
    // set default options
    $default_options = array("to" => array(), "from" => $site_from, "subject" => "", "html_message" => "", "plaintext_message" => "", "cc" => array(), "bcc" => array(), "date" => null);
    // merge options
    $options = array_merge($default_options, $options);
    // redo to/from for notifications
    $notification = elgg_extract('notification', $options);
    if (!empty($notification) && $notification instanceof \Elgg\Notifications\Notification) {
        $recipient = $notification->getRecipient();
        $sender = $notification->getSender();
        $options['to'] = html_email_handler_make_rfc822_address($recipient);
        if (!isset($options['recipient'])) {
            $options['recipient'] = $recipient;
        }
        if (!$sender instanceof \ElggUser && $sender->email) {
            $options['from'] = html_email_handler_make_rfc822_address($sender);
        } else {
            $options['from'] = $site_from;
        }
    }
    // check options
    if (!empty($options["to"]) && !is_array($options["to"])) {
        $options["to"] = array($options["to"]);
    }
    if (!empty($options["cc"]) && !is_array($options["cc"])) {
        $options["cc"] = array($options["cc"]);
    }
    if (!empty($options["bcc"]) && !is_array($options["bcc"])) {
        $options["bcc"] = array($options["bcc"]);
    }
    if (empty($options['html_message']) && empty($options['plaintext_message'])) {
        $options['html_message'] = html_email_handler_make_html_body($options);
        $options['plaintext_message'] = $options['body'];
    }
    // can we send a message
    if (empty($options["to"]) || empty($options["html_message"]) && empty($options["plaintext_message"])) {
        return false;
    }
    // start preparing
    // Facyla : better without spaces and special chars
    //$boundary = uniqid($site->name);
    $boundary = uniqid(elgg_get_friendly_title($site->name));
    $headers = $options['headers'];
    // start building headers
    if (!empty($options["from"])) {
        $headers['From'] = $options['from'];
    } else {
        $headers['From'] = $site_from;
    }
    // check CC mail
    if (!empty($options["cc"])) {
        $headers['Cc'] = implode(', ', $options['cc']);
    }
    // check BCC mail
    if (!empty($options["bcc"])) {
        $headers['Bcc'] = implode(', ', $options['bcc']);
    }
    // add a date header
    if (!empty($options["date"])) {
        $headers['Date'] = date('r', $options['date']);
    }
    $headers['X-Mailer'] = ' PHP/' . phpversion();
    $headers['MIME-Version'] = '1.0';
    // Facyla : try to add attchments if set
    $attachments = "";
    // Allow to add single or multiple attachments
    if (!empty($options["attachments"])) {
        $attachment_counter = 0;
        foreach ($options["attachments"] as $attachment) {
            // Alternatively fetch content based on an absolute path to a file on server:
            if (empty($attachment["content"]) && !empty($attachment["filepath"])) {
                $attachment["content"] = chunk_split(base64_encode(file_get_contents($attachment["filepath"])));
            }
            // Cannot attach an empty file in any case..
            if (empty($attachment["content"])) {
                continue;
            }
            // Count valid attachments
            $attachment_counter++;
            // Use defaults for other less critical settings
            if (empty($attachment["mimetype"])) {
                $attachment["mimetype"] = "application/octet-stream";
            }
            if (empty($attachment["filename"])) {
                $attachment["filename"] = "file_" . $attachment_counter;
            }
            $attachments .= "Content-Type: {" . $attachment["mimetype"] . "};" . PHP_EOL . " name=\"" . $attachment["filename"] . "\"" . PHP_EOL;
            $attachments .= "Content-Disposition: attachment;" . PHP_EOL . " filename=\"" . $attachment["filename"] . "\"" . PHP_EOL;
            $attachments .= "Content-Transfer-Encoding: base64" . PHP_EOL . PHP_EOL;
            $attachments .= $attachment["content"] . PHP_EOL . PHP_EOL;
            $attachments .= "--mixed--" . $boundary . PHP_EOL;
        }
    }
    // Use attachments headers for real only if they are valid
    if (!empty($attachments)) {
        $headers['Content-Type'] = "multipart/mixed; boundary=\"mixed--{$boundary}\"";
    } else {
        $headers['Content-Type'] = "multipart/alternative; boundary=\"{$boundary}\"";
    }
    $header_eol = "\r\n";
    if (elgg_get_config('broken_mta')) {
        // Allow non-RFC 2822 mail headers to support some broken MTAs
        $header_eol = "\n";
    }
    // stringify headers
    $headers_string = '';
    foreach ($headers as $key => $value) {
        $headers_string .= "{$key}: {$value}{$header_eol}";
    }
    // start building the message
    $message = "";
    // TEXT part of message
    $plaintext_message = elgg_extract("plaintext_message", $options);
    if (!empty($plaintext_message)) {
        // normalize URL's in the text
        $plaintext_message = html_email_handler_normalize_urls($plaintext_message);
        // add boundry / content type
        $message .= "--" . $boundary . PHP_EOL;
        $message .= "Content-Type: text/plain; charset=\"utf-8\"" . PHP_EOL;
        $message .= "Content-Transfer-Encoding: base64" . PHP_EOL . PHP_EOL;
        // add content
        $message .= chunk_split(base64_encode($plaintext_message)) . PHP_EOL . PHP_EOL;
    }
    // HTML part of message
    $html_message = elgg_extract("html_message", $options);
    if (!empty($html_message)) {
        $html_boundary = $boundary;
        // normalize URL's in the text
        $html_message = html_email_handler_normalize_urls($html_message);
        $html_message = html_email_handler_base64_encode_images($html_message);
        $image_attachments = html_email_handler_attach_images($html_message);
        if (is_array($image_attachments)) {
            $html_boundary .= "-alt";
            $html_message = elgg_extract("text", $image_attachments);
            $message .= "--" . $boundary . PHP_EOL;
            $message .= "Content-Type: multipart/related; boundary=\"{$html_boundary}\"" . PHP_EOL . PHP_EOL;
        }
        // add boundry / content type
        $message .= "--" . $html_boundary . PHP_EOL;
        $message .= "Content-Type: text/html; charset=\"utf-8\"" . PHP_EOL;
        $message .= "Content-Transfer-Encoding: base64" . PHP_EOL . PHP_EOL;
        // add content
        $message .= chunk_split(base64_encode($html_message)) . PHP_EOL;
        if (is_array($image_attachments)) {
            $images = elgg_extract("images", $image_attachments);
            foreach ($images as $image_info) {
                $message .= "--" . $html_boundary . PHP_EOL;
                $message .= "Content-Type: " . elgg_extract("content_type", $image_info) . "; charset=\"utf-8\"" . PHP_EOL;
                $message .= "Content-Disposition: inline; filename=\"" . elgg_extract("name", $image_info) . "\"" . PHP_EOL;
                $message .= "Content-ID: <" . elgg_extract("uid", $image_info) . ">" . PHP_EOL;
                $message .= "Content-Transfer-Encoding: base64" . PHP_EOL . PHP_EOL;
                // add content
                $message .= chunk_split(elgg_extract("data", $image_info)) . PHP_EOL;
            }
            $message .= "--" . $html_boundary . "--" . PHP_EOL;
        }
    }
    // Final boundry
    $message .= "--" . $boundary . "--" . PHP_EOL;
    // Facyla : FILE part of message
    if (!empty($attachments)) {
        // Build strings that will be added before TEXT/HTML message
        $before_message = "--mixed--" . $boundary . PHP_EOL;
        $before_message .= "Content-Type: multipart/alternative; boundary=\"" . $boundary . "\"" . PHP_EOL . PHP_EOL;
        // Build strings that will be added after TEXT/HTML message
        $after_message = PHP_EOL;
        $after_message .= "--mixed--" . $boundary . PHP_EOL;
        $after_message .= $attachments;
        // Wrap TEXT/HTML message into mixed message content
        $message = $before_message . PHP_EOL . $message . PHP_EOL . $after_message;
    }
    // convert to to correct format
    $to = implode(", ", $options["to"]);
    // encode subject to handle special chars
    $subject = $options["subject"];
    $subject = html_entity_decode($subject, ENT_QUOTES, 'UTF-8');
    // Decode any html entities
    if ($limit_subject) {
        $subject = elgg_get_excerpt($subject, 175);
    }
    $subject = "=?UTF-8?B?" . base64_encode($subject) . "?=";
    return mail($to, $subject, $message, $headers_string, $sendmail_options);
}
Example #2
0
<?php

/**
 * A test page for theme developer to view the layout of an email notification
 */
elgg_admin_gatekeeper();
$user = elgg_get_logged_in_user_entity();
$site = elgg_get_site_entity();
$subject = elgg_echo("useradd:subject");
$plain_message = elgg_echo("useradd:body", array($user->name, $site->name, $site->url, $user->username, 'test123'));
$html_message = elgg_view("html_email_handler/notification/body", array("subject" => $subject, "body" => $plain_message, "recipient" => $user));
$html_message = html_email_handler_css_inliner($html_message);
$html_message_ext = html_email_handler_normalize_urls($html_message);
$html_message_ext = html_email_handler_base64_encode_images($html_message_ext);
echo $html_message_ext;
if (get_input("mail")) {
    // Test sending a basic HTML mail
    $options = array('to' => $user->email, 'subject' => $subject, 'body' => $plain_message, 'recipient' => $user, 'attachments' => array(array('filepath' => dirname(__DIR__) . '/manifest.xml')));
    html_email_handler_send_email($options);
    // Test sending attachments through notify_user()
    $to = $user->guid;
    $from = $site->guid;
    $subject = 'Notification test';
    $message = 'This notification has been sent using notify_user() and it should have an attachment.';
    $params = array('recipient' => $user, 'attachments' => array(array('filepath' => dirname(__DIR__) . '/manifest.xml')));
    notify_user($to, $from, $subject, $message, $params, array('email'));
}