X-Git-Url: http://git.polytechnique.org/?a=blobdiff_plain;f=classes%2Fplmailer.php;h=24479f6550af7c947b72cb88c9fc2fc6a135e46c;hb=4c603b95edc398a28dd8ea01d756ca14f01f95e5;hp=f418b3c21b00b0f492c8c06d28062a339468d59d;hpb=b98794ca72217aac4d5d395d7955ee67ca6e9dea;p=platal.git diff --git a/classes/plmailer.php b/classes/plmailer.php index f418b3c..24479f6 100644 --- a/classes/plmailer.php +++ b/classes/plmailer.php @@ -1,6 +1,6 @@ tpl = $tpl; - $this->mailer = $mailer; $this->caching = false; $this->compile_check = true; $this->template_dir = $globals->spoolroot . "/templates/"; - $this->compile_dir = $globals->spoolroot . "/spool/templates_c/"; + $this->compile_dir = $globals->spoolroot . "/spool/mails_c/"; $this->config_dir = $globals->spoolroot . "/configs/"; + array_unshift($this->plugins_dir, $globals->spoolroot."/plugins/"); $this->register_outputfilter(Array($this, 'mail_format')); $this->register_function('from', Array($this, 'setFrom')); @@ -50,30 +46,37 @@ class PlMail extends Smarty $this->register_function('cc', Array($this, 'addCc')); $this->register_function('bcc', Array($this, 'addBcc')); $this->register_function('subject', Array($this, 'setSubject')); + $this->register_function('add_header', Array($this, 'addHeader')); + $this->assign_by_ref('globals', $globals); } - // }}} - // {{{ function run() - - function run($html) + public static function &get(&$mailer, $tpl) { - $this->assign('html_version', $html); - return $this->fetch($this->tpl); + static $plmail; + if (!isset($plmail) || $plmail->tpl != $tpl) { + $plmail = new PlMail($tpl); + } + $plmail->mailer =& $mailer; + return $plmail; } - // }}} - // {{{ function mail_format() + public function run($version) + { + $this->assign('mail_part', $version); + $text = $this->fetch($this->tpl); + if ($version == 'text') { + return wordwrap($text, 78); + } + return $text; + } /** used to remove the empty lines due to {from ...}, {to ...} ... functions */ - static function mail_format($output, &$smarty) + static public function mail_format($output, &$smarty) { - return wordwrap("\n".trim($output)."\n",75); + return "\n".trim($output)."\n"; } - // }}} - // {{{ function format_addr() - - static function format_addr(&$params) + static protected function format_addr(&$params) { if (isset($params['full'])) { return $params['full']; @@ -84,109 +87,103 @@ class PlMail extends Smarty } } - // }}} - // {{{ function setFrom() - /** template function : from. * {from full=...} for an already formatted address * {from addr=... [text=...]} else */ - function setFrom($params, &$smarty) + public function setFrom($params, &$smarty) { - $smarty->mailer->setFrom($this->format_addr($params)); + $smarty->mailer->setFrom(PlMail::format_addr($params)); } - // }}} - // {{{ function setTo() - /** template function : to. * {to full=...} for an already formatted address * {to addr=... [text=...]} else */ - function addTo($params, &$smarty) + public function addTo($params, &$smarty) { - $smarty->mailer->addTo($this->format_addr($params)); + $smarty->mailer->addTo(PlMail::format_addr($params)); } - // }}} - // {{{ function setCc() - /** template function : cc. * {cc full=...} for an already formatted address * {cc addr=... [text=...]} else */ - function addCc($params, &$smarty) + public function addCc($params, &$smarty) { - $smarty->mailer->addCc($this->format_addr($params)); + $smarty->mailer->addCc(PlMail::format_addr($params)); } - // }}} - // {{{ function setBcc() - /** template function : bcc. * {bcc full=...} for an already formatted address * {bcc addr=... [text=...]} else */ - function addBcc($params, &$smarty) + public function addBcc($params, &$smarty) { - $smarty->mailer->addBcc($this->format_addr($params)); + $smarty->mailer->addBcc(PlMail::format_addr($params)); } - // }}} - // {{{ function setSubject() - /** template function : subject. - * {subject text=...} + * {subject text=...} */ - function setSubject($params, &$smarty) + public function setSubject($params, &$smarty) { $smarty->mailer->setSubject($params['text']); } - // }}} + /** template function : add_header. + * {add_header name=... value=...} + */ + public function addHeader($params, &$smarty) + { + $smarty->mailer->addHeader($params['name'], $params['value']); + } } -// }}} - require_once('Mail.php'); require_once('Mail/mime.php'); -// {{{ class PlMailer /** Class for sending inline or multipart-emails. + * Based on Diogenes' HermesMailer */ class PlMailer extends Mail_Mime { private $mail; private $page = null; private $charset; - // {{{ constructor + private $wiki = null; - function PlMailer($tpl = null, $charset = "ISO-8859-15") + function __construct($tpl = null, $charset = "UTF-8") { $this->charset = $charset; $this->Mail_Mime("\n"); - $this->mail =& Mail::factory('sendmail', Array('sendmail_args' => '-oi')); + $this->mail = Mail::factory('sendmail', Array('sendmail_args' => '-oi')); if (!is_null($tpl)) { - $this->page = new PlMail($this, $tpl); + $this->page =& PlMail::get($this, $tpl); } } - // }}} - // {{{ function correct_emails() + static private function formatUser(PlUser $user) + { + return '"' . $user->fullName() . '" <' . $user->bestEmail() . '>'; + } /** * converts all : Foo Bar Baz into "Foo Bar Baz" which is RFC compliant */ - private function correct_emails($email) { - return preg_replace('!(^|, *)([^<"][^<"]*[^< "]) *(<[^>]*>)!', '\1"\2" \3', $email); + if ($email instanceof PlUser) { + $email = self::formatUser($email); + } + $email = preg_replace('!(^|, *)([^<"]+?) *(<[^>]*>)!ue', + '\1 "\2" \3', $email); + return preg_replace('/"([^<]+)"/e', + '"\\"" . PlMailer::encodeStringQP("\1") . "\\""', + $email); } - // }}} - // {{{ function addTo() - - function addTo($email) + public function addTo($email) { $email = $this->correct_emails($email); if (isset($this->_headers['To'])) { @@ -196,34 +193,48 @@ class PlMailer extends Mail_Mime { } } - // }}} - // {{{ function addCc() + public function setTo($email) + { + $email = $this->correct_emails($email); + $this->_headers['To'] = $email; + } - function addCc($email) + public function addCc($email) { return parent::addCc($this->correct_emails($email)); } - // }}} - // {{{ function addBcc() - - function addBcc($email) + public function addBcc($email) { return parent::addBcc($this->correct_emails($email)); } - // }}} - // {{{ function setFrom() - - function setFrom($email) + public function setFrom($email) { return parent::setFrom($this->correct_emails($email)); } - // }}} - // {{{ function addHeader() - - function addHeader($hdr,$val) + static function encodeStringQP($string) + { + if (!preg_match('/^[\x20-\x7e]*$/', $string)) { + $string = '=?UTF-8?Q?' . preg_replace('/[^\x21-\x3C\x3e\x40-\x7e]/e', 'PlMailer::encodeQP("\0")', $string) + . '?='; + } + return $string; + } + + + static function encodeQP($char) + { + return sprintf('=%02X', ord($char)); + } + + public function setSubject($subject) + { + return parent::setSubject(self::encodeStringQP($subject)); + } + + public function addHeader($hdr,$val) { switch($hdr) { case 'From': @@ -250,66 +261,132 @@ class PlMailer extends Mail_Mime { } } - // }}} - // {{{ function assign() + public function addUploadAttachment(PlUpload &$upload, $name) + { + $encoding = $upload->isType('text') ? 'quoted-printable' : 'base64'; + $this->addAttachment($upload->getContents(), $upload->contentType(), $name, false, $encoding); + } - function assign($var, $value) + public function assign($var, $value) { if (!is_null($this->page)) { $this->page->assign($var, $value); } } - - // }}} - // {{{ function processPage() - private function processPage() + public function assign_by_ref($var, &$value) + { + if (!is_null($this->page)) { + $this->page->assign_by_ref($var, $value); + } + } + + public function register_modifier($var, $callback) + { + if (!is_null($this->page)) { + $this->page->register_modifier($var, $callback); + } + } + + public function register_function($var, $callback) + { + if (!is_null($this->page)) { + $this->page->register_function($var, $callback); + } + } + + public function setWikiBody($wiki) + { + $this->wiki = $wiki; + } + + private function processPage($with_html = true) { if (!is_null($this->page)) { - $this->setTxtBody($this->page->run(false)); - $html = trim($this->page->run(true)); - if (!empty($html)) { - $this->setHtmlBody($html); + global $globals; + if (!($globals->debug & DEBUG_SMARTY)) { + $level = error_reporting(0); + } + $this->page->assign_by_ref('globals', $globals); + $this->page->run('head'); // process page headers + $this->wiki = trim($this->page->run('wiki')); // get wiki + if (!$this->wiki) { + $this->setTxtBody($this->page->run('text')); + if ($with_html) { + $html = trim($this->page->run('html')); + if (!empty($html)) { + $this->setHtmlBody($html); + } + } + } + if (!($globals->debug & DEBUG_SMARTY)) { + error_reporting($level); + } + } + if ($this->wiki) { + $this->setTxtBody(MiniWiki::WikiToText($this->wiki, false, 0, 78)); + if ($with_html) { + $this->setHtmlBody('' . MiniWiki::WikiToHtml($this->wiki, true) . ''); } } } - // }}} - // {{{ function send() + public function sendTo(PlUser &$user) + { + $this->setTo($user); + $this->assign_by_ref('user', $user); + return $this->send($user->isEmailFormatHtml()); + } - function send() + public function send($with_html = true) { - $this->processPage(); - if (S::v('forlife')) { - $this->addHeader('X-Org-Mail', S::v('forlife') . '@polytechnique.org'); + $this->processPage($with_html); + if (S::user()) { + $this->addHeader('X-Org-Mail', S::user()->forlifeEmail()); } $addrs = Array(); - foreach(Array('To', 'Cc', 'Bcc') as $hdr) { - if(isset($this->_headers[$hdr])) { + foreach (Array('To', 'Cc', 'Bcc') as $hdr) { + if (isset($this->_headers[$hdr])) { require_once 'Mail/RFC822.php'; - $addrs = array_merge($addrs, Mail_RFC822::parseAddressList($this->_headers[$hdr])); + $parsed = @Mail_RFC822::parseAddressList($this->_headers[$hdr]); + if (is_array($parsed)) { + $addrs = array_merge($addrs, $parsed); + } } } - if(empty($addrs)) { + if (empty($addrs)) { return false; } - + $dests = Array(); - foreach($addrs as $a) { + foreach ($addrs as $a) { $dests[] = "{$a->mailbox}@{$a->host}"; } - + + // Support for a "catch-all" email address, to be used by developers. + // This mode can only be activated when the working copy is in restricted + // mode, to ensure that production plat/al copies are never affected. + global $globals; + if ($globals->email_catchall && $globals->core->restricted_platal) { + require_once 'Mail/RFC822.php'; + if (@Mail_RFC822::isValidInetAddress($globals->email_catchall)) { + $dests = array($globals->email_catchall); + } + } + // very important to do it in THIS order very precisely. $body = $this->get(array('text_charset' => $this->charset, + 'text_encoding' => '8bit', 'html_charset' => $this->charset, 'head_charset' => $this->charset)); $hdrs = $this->headers(); + if (empty($hdrs['From'])) { + trigger_error('Empty "From", mail not sent', E_USER_WARNING); + return false; + } return $this->mail->send($dests, $hdrs, $body); } - - // }}} } -// }}} - +// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8: ?>