/** * Hook to handle emails send by elgg_send_email * * @param string $hook * @param string $type * @param bool $return * @param array $params * to => who to send the email to * from => who is the sender * subject => subject of the message * body => message * params => optional params */ function html_email_handler_email_hook($hook, $type, $return, $params) { // generate HTML mail body $html_message = html_email_handler_make_html_body($params["subject"], $params["body"]); // set options for sending $options = array("to" => $params["to"], "from" => $params["from"], "subject" => $params["subject"], "html_message" => $html_message, "plaintext_message" => $params["body"]); return html_email_handler_send_email($options); }
function html_email_handler_notification_handler(ElggEntity $from, ElggUser $to, $subject, $message, array $params = NULL) { if (!$from) { $msg = elgg_echo("NotificationException:MissingParameter", array("from")); throw new NotificationException($msg); } if (!$to) { $msg = elgg_echo("NotificationException:MissingParameter", array("to")); throw new NotificationException($msg); } if ($to->email == "") { $msg = elgg_echo("NotificationException:NoEmailAddress", array($to->guid)); throw new NotificationException($msg); } // To $to = html_email_handler_make_rfc822_address($to); // From $site = elgg_get_site_entity(); // If there's an email address, use it - but only if its not from a user. if (!$from instanceof ElggUser && !empty($from->email)) { $from = html_email_handler_make_rfc822_address($from); } elseif (!empty($site->email)) { // Use email address of current site if we cannot use sender's email $from = html_email_handler_make_rfc822_address($site); } else { // If all else fails, use the domain of the site. if (!empty($site->name)) { $name = $site->name; if (strstr($name, ',')) { $name = '"' . $name . '"'; // Protect the name with quotations if it contains a comma } $name = '=?UTF-8?B?' . base64_encode($name) . '?='; // Encode the name. If may content nos ASCII chars. $from = $name . " <noreply@" . get_site_domain($site->getGUID()) . ">"; } else { $from = "noreply@" . get_site_domain($site->getGUID()); } } // generate HTML mail body $html_message = html_email_handler_make_html_body($subject, $message); // set options for sending $options = array("to" => $to, "from" => $from, "subject" => '=?UTF-8?B?' . base64_encode($subject) . '?=', "html_message" => $html_message, "plaintext_message" => $message); if (!empty($params) && is_array($params)) { $options = array_merge($options, $params); } return html_email_handler_send_email($options); }
/** * 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); }