Skip to content

Instantly share code, notes, and snippets.

@pateketrueke
Created March 20, 2013 20:51
Show Gist options
  • Save pateketrueke/5208307 to your computer and use it in GitHub Desktop.
Save pateketrueke/5208307 to your computer and use it in GitHub Desktop.
Mailer class for built-in PHP mail()
<?php
class Mailer
{
protected $to = array();
protected $cc = array();
protected $bcc = array();
protected $reply = array();
protected $files = array();
protected $headers = array();
protected $content = array();
protected $main_boundary = '';
protected $extra_boundary = '';
protected $subject= '';
protected $from = '';
private function __construct(){}
public static function factory()
{
$out = new static;
$out->main_boundary = md5(uniqid('--main-boundary'));
$out->extra_boundary = md5(uniqid('--extra-boundary'));
return $out;
}
public function add_to($test)
{
$this->to []= $test;
return $this;
}
public function add_reply($test)
{
$this->reply []= $test;
return $this;
}
public function add_bcc($test)
{
$this->bcc []= $test;
return $this;
}
public function add_cc($test)
{
$this->cc []= $test;
return $this;
}
public function add_file($file, $mime = '')
{
if (is_file($file)) {
$mime = strpos($mime, '/') !== FALSE ? $mime : 'application/octet-stream';
$this->files []= array($mime => $file);
}
return $this;
}
public function add_header($key, $val = '')
{
if (is_array($key)) {
foreach ($key as $sub => $val) {
$this->headers []= "$sub: $val";
}
} elseif ( ! is_numeric($key) && $val) {
$this->headers []= "$key: $val";
}
return $this;
}
public function set_from($test, $name = '')
{
$this->from = $name ? "$name <{$test}>" : $test;
return $this;
}
public function set_subject($text)
{
$this->subject = $text;
return $this;
}
public function set_content($text)
{
$this->content = preg_split('/[\r\n]+/', $text);
return $this;
}
public function add_content($text)
{
$this->content []= $text;
return $this;
}
public function send()
{
$to = join(', ', $this->to);
$html = join("\n", $this->content);
if (($content = $this->build_mail($html)) === FALSE) {
return FALSE;
}
return @mail($to, $this->subject, $content, $this->get_headers());
}
public function reset()
{
$this->to = array();
$this->cc = array();
$this->bcc = array();
$this->reply = array();
$this->files = array();
$this->headers = array();
$this->content = array();
$this->subject = '';
$this->from = '';
}
private function get_attachments()
{
$out = '';
foreach ($this->files as $one) {
$mime = key($one);
$file = $one[$mime];
$name = basename($file);
if ($tmp = chunk_split(base64_encode(read($file)))) {
$out .= "--$this->main_boundary\nContent-Type: $mime; name=\"$name\"\n"
. "Content-Transfer-Encoding: base64\n"
. "Content-Disposition: attachment; filename=\"$name\"\n\n"
. "$tmp\n";
}
}
return $out;
}
private function get_headers()
{
$out = "From: $this->from\nMIME-Version: 1.0\n"
. 'Content-Type: ' . sprintf("multipart/%s; boundary=\"%s\"\n", $this->files ? 'mixed' : 'alternative', $this->main_boundary);
$this->reply && $out .= sprintf("Reply-To: %s\n", join(', ', $this->reply));
return $out;
}
private function build_mail($test)
{
// TODO: =HEX values?
$plain = preg_replace('/\r?\n/', '<br />', str_replace("\t", ' ', $test));
$plain = strip_tags(preg_replace('/<br\s*\/?' . '>/', "\n", $plain));
$charset = 'UTF-8';
$out = "MIME-Version: 1.0\n"
. "Content-Type: multipart/alternative; boundary=\"$this->main_boundary\"\n\n"
. "This is a multi-part message in MIME format.\n\n"
. "--$this->main_boundary\nContent-Type: text/plain; charset=\"$charset\"\n"
. "Content-Transfer-Encoding: quoted-printable\n\n"
. "$plain\n--$this->main_boundary\n"
. "Content-Type: text/html; charset=\"$charset\"\n"
. "Content-Transfer-Encoding: quoted-printable\n\n"
. "$test\n\n--$this->main_boundary--";
if ( ! empty($this->files)) {
$files = $this->get_attachments();
$out = "This is a multi-part message in MIME format.\n\n"
. "--$this->main_boundary\nContent-Type: multipart/alternative; boundary=\"$this->extra_boundary\"\n\n"
. "--$this->extra_boundary\nContent-Type: text/plain; charset=\"$charset\"\n"
. "Content-Transfer-Encoding: quoted-printable\n\n$plain\n"
. "--$this->extra_boundary\nContent-Type: text/html; charset=\"$charset\"\n"
. "Content-Transfer-Encoding: quoted-printable\n\n"
. "$test\n\n--$this->extra_boundary--\n\n"
. "$files\n--$this->main_boundary--";
}
return $out;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment