Added method to encode email addresses
[squirrelmail.git] / class / mime / Rfc822Header.class.php
index e168a35..ddaca41 100644 (file)
@@ -3,7 +3,7 @@
 /**
  * Rfc822Header.class.php
  *
- * Copyright (c) 2002 The SquirrelMail Project Team
+ * Copyright (c) 2003 The SquirrelMail Project Team
  * Licensed under the GNU GPL. For full terms see the file COPYING.
  *
  * This contains functions needed to handle mime messages.
@@ -53,10 +53,6 @@ class Rfc822Header {
                 $field = substr($line, 0, $pos);
                if (!strstr($field,' ')) { /* valid field */
                    $value = trim(substr($line, $pos+1));
-                   if(!preg_match('/^X.*/i', $field) &&
-                       !preg_match('/^Subject/i', $field)) {
-                       $value = $this->stripComments($value);
-                    }
                    $this->parseField($field, $value);
                }
             }
@@ -68,7 +64,6 @@ class Rfc822Header {
 
     function stripComments($value) {
         $result = '';
-
         $cnt = strlen($value);
         for ($i = 0; $i < $cnt; ++$i) {
             switch ($value{$i}) {
@@ -113,6 +108,7 @@ class Rfc822Header {
         $field = strtolower($field);
         switch($field) {
             case 'date':
+               $value = $this->stripComments($value);
                 $d = strtr($value, array('  ' => ' '));
                 $d = explode(' ', $d);
                 $this->date = getTimeStamp($d);
@@ -142,66 +138,98 @@ class Rfc822Header {
                 $this->in_reply_to = $value;
                 break;
             case 'message-id':
+               $value = $this->stripComments($value);
                 $this->message_id = $value;
                 break;
            case 'references':
+               $value = $this->stripComments($value);
                $this->references = $value;
                break;
+           case 'x-confirm-reading-to':
+           case 'return-receipt-to':
             case 'disposition-notification-to':
+               $value = $this->stripComments($value);
                 $this->dnt = $this->parseAddress($value);
                 break;
             case 'mime-version':
+               $value = $this->stripComments($value);
                 $value = str_replace(' ', '', $value);
                 $this->mime = ($value == '1.0' ? true : $this->mime);
                 break;
             case 'content-type':
+               $value = $this->stripComments($value);
                 $this->parseContentType($value);
                 break;
             case 'content-disposition':
+               $value = $this->stripComments($value);
                 $this->parseDisposition($value);
                 break;
             case 'user-agent':
             case 'x-mailer':
-                $this->xmailer = $value;
+               $this->xmailer = $value;
                 break;
             case 'x-priority':
                 $this->priority = $value;
                 break;
             case 'list-post':
+               $value = $this->stripComments($value);
                 $this->mlist('post', $value);
                 break;
             case 'list-reply':
+               $value = $this->stripComments($value);      
                 $this->mlist('reply', $value);
                 break;
             case 'list-subscribe':
+               $value = $this->stripComments($value);      
                 $this->mlist('subscribe', $value);
                 break;
             case 'list-unsubscribe':
+               $value = $this->stripComments($value);
                 $this->mlist('unsubscribe', $value);
                 break;
             case 'list-archive':
+               $value = $this->stripComments($value);
                 $this->mlist('archive', $value);
                 break;
             case 'list-owner':
+               $value = $this->stripComments($value);
                 $this->mlist('owner', $value);
                 break;
             case 'list-help':
+               $value = $this->stripComments($value);
                 $this->mlist('help', $value);
                 break;
             case 'list-id':
+               $value = $this->stripComments($value);
                 $this->mlist('id', $value);
                 break;
             default:
                 break;
         }
     }
-
+    /*
+     * parseAddress: recursive function for parsing address strings and store 
+     *               them in an address stucture object.
+     *               input: $address = string
+     *                      $ar      = boolean (return array instead of only the
+     *                                 first element)
+     *                      $addr_ar = array with parsed addresses
+     *                      $group   = string
+     *                      $host    = string (default domainname in case of 
+     *                                 addresses without a domainname)
+     *                      $lookup  = callback function (for lookup address
+     *                                 strings which are probably nicks
+     *                                 (without @ ) ) 
+     *               output: array with addressstructure objects or only one
+     *                       address_structure object.
+     */
     function parseAddress
-    ($address, $ar=false, $addr_ar = array(), $group = '', $host='') {
+    ($address, $ar=false, $addr_ar = array(), $group = '', $host='',$lookup=false) {
         $pos = 0;
         $j = strlen($address);
         $name = '';
         $addr = '';
+       $comment = '';
         while ($pos < $j) {
             switch ($address{$pos}) {
                 case '"': /* get the personal name */
@@ -227,17 +255,17 @@ class Rfc822Header {
                     break;
                 case '(':  /* rip off comments */
                     $addr_start = $pos;
-                    for (++$pos; ($pos < $j) && ($address{$pos} != ')'); ++$pos) {
-                        $addr .= $address{$pos};
-                    }
-                    $address_start = substr($address, 0, $addr_start);
-                    $address_end   = substr($address, $pos + 1);
-                    $address       = $address_start . $address_end;
+                   $pos = strpos($address,')');
+                   if ($pos !== false) {
+                       $comment = substr($address, $addr_start+1,($pos-$addr_start-1));
+                       $address_start = substr($address, 0, $addr_start);
+                       $address_end   = substr($address, $pos + 1);
+                       $address       = $address_start . $address_end;
+                   }
                     $j = strlen($address);
                     $pos = $addr_start + 1;
                     break;
                 case ',':  /* we reached a delimiter */
-//case ';':
                     if ($addr == '') {
                         $addr = substr($address, 0, $pos);
                     } else if ($name == '') {
@@ -246,15 +274,30 @@ class Rfc822Header {
 
                     $at = strpos($addr, '@');
                     $addr_structure = new AddressStructure();
+                   if (!$name && $comment) $name = $comment;
                     $addr_structure->personal = $name;
                     $addr_structure->group = $group;
                     if ($at) {
                         $addr_structure->mailbox = substr($addr, 0, $at);
                         $addr_structure->host = substr($addr, $at+1);
                     } else {
-                        $addr_structure->mailbox = $addr;
-                       if ($host) {
-                          $addr_structure->host = $host;
+                       /* if lookup function */
+                       if ($lookup) {
+                           $aAddr = call_user_func_array($lookup,array($addr));
+                           if (isset($aAddr['email'])) {
+                               $at = strpos($aAddr['email'], '@');
+                               $addr_structure->mailbox = substr($aAddr['email'], 0, $at);
+                               $addr_structure->host = substr($aAddr['email'], $at+1);
+                               if (isset($aAddr['name'])) {
+                                   $addr_structure->personal = $aAddr['name'];
+                               }
+                           }
+                       }
+                       if (!$addr_structure->mailbox) {
+                           $addr_structure->mailbox = trim($addr);
+                           if ($host) {
+                               $addr_structure->host = $host;
+                           }
                        }
                     }
                     $address = trim(substr($address, $pos+1));
@@ -291,6 +334,7 @@ class Rfc822Header {
         } else if ($name == '') {
             $name = trim(substr($address, 0, $addr_start));
         }
+        if (!$name && $comment) $name = $comment;
         $at = strpos($addr, '@');
         $addr_structure = new AddressStructure();
         $addr_structure->group = $group;
@@ -298,9 +342,23 @@ class Rfc822Header {
             $addr_structure->mailbox = trim(substr($addr, 0, $at));
             $addr_structure->host = trim(substr($addr, $at+1));
         } else {
-            $addr_structure->mailbox = trim($addr);
-            if ($host) {
-              $addr_structure->host = $host;
+           /* if lookup function */
+           if ($lookup) {
+               $aAddr = call_user_func_array($lookup,array($addr));
+               if (isset($aAddr['email'])) {
+                   $at = strpos($aAddr['email'], '@');
+                    $addr_structure->mailbox = substr($aAddr['email'], 0, $at);
+                    $addr_structure->host = substr($aAddr['email'], $at+1);
+                   if (isset($aAddr['name'])) {
+                       $addr_structure->personal = $aAddr['name'];
+                   }
+               }
+           }
+           if (!$addr_structure->mailbox) {
+                $addr_structure->mailbox = trim($addr);
+               if ($host) {
+                   $addr_structure->host = $host;
+               }
            }
         }
         if ($group && $addr == '') { /* no addresses found in group */
@@ -400,28 +458,37 @@ class Rfc822Header {
      * example1: header->getAddr_s('to').
      * example2: header->getAddr_s(array('to', 'cc', 'bcc'))
      */
-    function getAddr_s($arr, $separator = ',') {
+    function getAddr_s($arr, $separator = ',',$encoded=false) {
         $s = '';
 
         if (is_array($arr)) {
             foreach($arr as $arg) {
-                if ($this->getAddr_s($arg)) {
+                if ($this->getAddr_s($arg, $separator, $encoded)) {
                     $s .= $separator . $result;
                 }
             }
             $s = ($s ? substr($s, 2) : $s);
         } else {
-            eval('$addr = $this->' . $arr . ';') ;
+            $addr = $this->{$arr};
+            //eval('$addr = $this->' . $arr . ';') ;
             if (is_array($addr)) {
                 foreach ($addr as $addr_o) {
                     if (is_object($addr_o)) {
-                        $s .= $addr_o->getAddress() . $separator;
+                        if ($encoded) {
+                            $s .= $addr_o->getEncodedAddress() . $separator;
+                        } else {
+                            $s .= $addr_o->getAddress() . $separator;
+                        }
                     }
                 }
                 $s = substr($s, 0, -strlen($separator));
             } else {
                 if (is_object($addr)) {
-                    $s .= $addr->getAddress();
+                    if ($encoded) {
+                        $s .= $addr->getEncodedAddress();
+                    } else {
+                        $s .= $addr->getAddress();
+                    }
                 }
             }
         }
@@ -434,7 +501,7 @@ class Rfc822Header {
                 $arr = $this->getAddr_a($argument, $excl_arr, $arr);
             }
         } else {
-            eval('$addr = $this->' . $arg . ';') ;
+           $addr = $this->{$arg};
             if (is_array($addr)) {
                 foreach ($addr as $next_addr) {
                     if (is_object($next_addr)) {
@@ -480,6 +547,7 @@ class Rfc822Header {
                ++$i;   
             }
        } else {
+           if (!is_array($this->cc)) $this->cc = array();
            $srch_addr = $this->parseAddress($address);
            $results = array();
            foreach ($this->to as $to) {
@@ -518,6 +586,7 @@ class Rfc822Header {
                return false;
            }   
        }
+        //exit;
        return $result;
     }