Happy New Year!
[platal.git] / classes / plmailer.php
index f7a913c..fbcf852 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /***************************************************************************
- *  Copyright (C) 2003-2008 Polytechnique.org                              *
+ *  Copyright (C) 2003-2011 Polytechnique.org                              *
  *  http://opensource.polytechnique.org/                                   *
  *                                                                         *
  *  This program is free software; you can redistribute it and/or modify   *
@@ -47,6 +47,7 @@ class PlMail extends Smarty
         $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);
     }
 
     public static function &get(&$mailer, $tpl)
@@ -162,12 +163,24 @@ class PlMailer extends Mail_Mime {
         }
     }
 
+    static private function formatUser(PlUser $user)
+    {
+        return '"' . $user->fullName() . '" <' . $user->bestEmail() . '>';
+    }
+
     /**
      * converts all : Foo Bar Baz <quux@foobar.org> into "Foo Bar Baz" <quux@foobar.org> which is RFC compliant
      */
     private function correct_emails($email)
     {
-        return preg_replace('!(^|, *)([^<"]+?) *(<[^>]*>)!u', '\1"\2" \3', $email);
+        if ($email instanceof PlUser) {
+            $email = self::formatUser($email);
+        }
+        $email = preg_replace('!(^|, *)([^<"]+?) *(<[^>]*>)!u',
+                              '\1 "\2" \3', $email);
+        return preg_replace('/"([^<]+)"/e',
+                            '"\\"" . PlMailer::encodeStringQP("\1") . "\\""',
+                            $email);
     }
 
     public function addTo($email)
@@ -180,6 +193,12 @@ class PlMailer extends Mail_Mime {
         }
     }
 
+    public function setTo($email)
+    {
+        $email = $this->correct_emails($email);
+        $this->_headers['To'] = $email;
+    }
+
     public function addCc($email)
     {
         return parent::addCc($this->correct_emails($email));
@@ -195,6 +214,26 @@ class PlMailer extends Mail_Mime {
         return parent::setFrom($this->correct_emails($email));
     }
 
+    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) {
@@ -264,7 +303,11 @@ class PlMailer extends Mail_Mime {
     private function processPage($with_html = true)
     {
         if (!is_null($this->page)) {
-            $level = error_reporting(0);
+            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) {
@@ -276,7 +319,9 @@ class PlMailer extends Mail_Mime {
                     }
                 }
             }
-            error_reporting($level);
+            if (!($globals->debug & DEBUG_SMARTY)) {
+                error_reporting($level);
+            }
         }
         if ($this->wiki) {
             $this->setTxtBody(MiniWiki::WikiToText($this->wiki, false, 0, 78));
@@ -286,16 +331,22 @@ class PlMailer extends Mail_Mime {
         }
     }
 
+    public function sendTo(PlUser &$user)
+    {
+        $this->setTo($user);
+        $this->assign_by_ref('user', $user);
+        return $this->send($user->isEmailFormatHtml());
+    }
+
     public function send($with_html = true)
     {
         $this->processPage($with_html);
-        if (S::v('forlife')) {
-            global $globals;
-            $this->addHeader('X-Org-Mail', S::v('forlife') . '@' . $globals->mail->domain);
+        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';
                 $parsed = @Mail_RFC822::parseAddressList($this->_headers[$hdr]);
                 if (is_array($parsed)) {
@@ -303,15 +354,26 @@ class PlMailer extends Mail_Mime {
                 }
             }
         }
-        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',