From ad54dda17a98ec3154233da052c7fd4e9ac09ec2 Mon Sep 17 00:00:00 2001
From: Peter Rotich <peter@enhancesoft.com>
Date: Mon, 11 Nov 2013 20:39:03 +0000
Subject: [PATCH] Parse collaborators from email header.

---
 include/api.tickets.php     |  5 +++-
 include/class.mailfetch.php | 46 +++++++++++++++++++++++--------------
 include/class.mailparse.php | 44 ++++++++++++++++++++++++++---------
 3 files changed, 66 insertions(+), 29 deletions(-)

diff --git a/include/api.tickets.php b/include/api.tickets.php
index f0758d5d2..e0a761e27 100644
--- a/include/api.tickets.php
+++ b/include/api.tickets.php
@@ -39,7 +39,10 @@ class TicketApiController extends ApiController {
         if(!strcasecmp($format, 'email')) {
             $supported = array_merge($supported, array('header', 'mid',
                 'emailId', 'ticketId', 'reply-to', 'reply-to-name',
-                'in-reply-to', 'references'));
+                'in-reply-to', 'references',
+                'collaborators' => array("*" => array("name", "email"))
+                ));
+
             $supported['attachments']['*'][] = 'cid';
         }
 
diff --git a/include/class.mailfetch.php b/include/class.mailfetch.php
index 3c4306d1e..97805cd52 100644
--- a/include/class.mailfetch.php
+++ b/include/class.mailfetch.php
@@ -269,9 +269,9 @@ class MailFetcher {
 
         $sender=$headerinfo->from[0];
         //Just what we need...
-        $header=array('name'  =>@$sender->personal,
+        $header=array('name'  => $this->mime_decode(@$sender->personal),
                       'email'  => trim(strtolower($sender->mailbox).'@'.$sender->host),
-                      'subject'=>@$headerinfo->subject,
+                      'subject'=> $this->mime_decode(@$headerinfo->subject),
                       'mid'    => trim(@$headerinfo->message_id),
                       'header' => $this->getHeader($mid),
                       'in-reply-to' => $headerinfo->in_reply_to,
@@ -283,22 +283,33 @@ class MailFetcher {
             $header['reply-to-name'] = $replyto[0]->personal;
         }
 
-        //Try to determine target email - useful when fetched inbox has
-        // aliases that are independent emails within osTicket.
-        $emailId = 0;
+        // Put together a list of recipients
         $tolist = array();
         if($headerinfo->to)
             $tolist = array_merge($tolist, $headerinfo->to);
         if($headerinfo->cc)
             $tolist = array_merge($tolist, $headerinfo->cc);
-        if($headerinfo->bcc)
-            $tolist = array_merge($tolist, $headerinfo->bcc);
 
-        foreach($tolist as $addr)
-            if(($emailId=Email::getIdByEmail(strtolower($addr->mailbox).'@'.$addr->host)))
-                break;
+        $header['collaborators'] = array();
+        foreach($tolist as $addr) {
+            if(!($emailId=Email::getIdByEmail(strtolower($addr->mailbox).'@'.$addr->host))) {
+                $header['collaborators'][] = array(
+                        'name' => $this->mime_decode(@$addr->personal),
+                        'email' => strtolower($addr->mailbox).'@'.$addr->host);
+            } elseif(!$header['emailId']) {
+                $header['emailId'] = $emailId;
+            }
+        }
 
-        $header['emailId'] = $emailId;
+        //BCCed?
+        if(!$header['emailId']) {
+            unset($header['collaborators']); //Nuke the recipients - we were bcced
+            if($headerinfo->bcc)
+                foreach($headerinfo->bcc as $addr)
+                    if(!$header['emailId']
+                            && ($emailId=Email::getIdByEmail(strtolower($addr->mailbox).'@'.$addr->host)))
+                        $header['emailId'] = $emailId;
+        }
 
         // Ensure we have a message-id. If unable to read it out of the
         // email, use the hash of the entire email headers
@@ -485,18 +496,18 @@ class MailFetcher {
         }
 
         $vars = $mailinfo;
-        $vars['name']=$this->mime_decode($mailinfo['name']);
-        $vars['subject']=$mailinfo['subject']?$this->mime_decode($mailinfo['subject']):'[No Subject]';
-        $vars['message']=Format::stripEmptyLines($this->getBody($mid));
-        $vars['emailId']=$mailinfo['emailId']?$mailinfo['emailId']:$this->getEmailId();
+        $vars['name'] = $mailinfo['name'];
+        $vars['subject'] = $mailinfo['subject'] ? $mailinfo['subject'] : '[No Subject]';
+        $vars['message'] = Format::stripEmptyLines($this->getBody($mid));
+        $vars['emailId'] = $mailinfo['emailId'] ? $mailinfo['emailId'] : $this->getEmailId();
 
         //Missing FROM name  - use email address.
         if(!$vars['name'])
-            $vars['name'] = $vars['email'];
+            list($vars['name']) = explode('@', $vars['email']);
 
         //An email with just attachments can have empty body.
         if(!$vars['message'])
-            $vars['message'] = '-';
+            $vars['message'] = '--';
 
         if($ost->getConfig()->useEmailPriority())
             $vars['priorityId']=$this->getPriority($mid);
@@ -565,6 +576,7 @@ class MailFetcher {
             return null;
         }
 
+
         return $ticket;
     }
 
diff --git a/include/class.mailparse.php b/include/class.mailparse.php
index 32b0083a6..c1f4700c4 100644
--- a/include/class.mailparse.php
+++ b/include/class.mailparse.php
@@ -154,6 +154,13 @@ class Mail_Parse {
         return Mail_Parse::parseAddressList($header);
     }
 
+    function getBccAddressList(){
+        if (!($header = $this->struct->headers['bcc']))
+            return null;
+
+        return Mail_Parse::parseAddressList($header);
+    }
+
     function getMessageId(){
         return $this->struct->headers['message-id'];
     }
@@ -378,19 +385,35 @@ class EmailDataParser {
         }
 
         //TO Address:Try to figure out the email address... associated with the incoming email.
-        $emailId = 0;
-        if(($tolist = $parser->getToAddressList())) {
-            foreach ($tolist as $toaddr) {
-                if(($emailId=Email::getIdByEmail($toaddr->mailbox.'@'.$toaddr->host)))
-                    break;
+        $data['emailId'] = 0;
+        $data['collaborators'] = array();
+        $tolist = array();
+        if(($to = $parser->getToAddressList()))
+            $tolist = array_merge($tolist, $to);
+
+        if(($cc = $parser->getCcAddressList()))
+            $tolist = array_merge($tolist, $cc);
+
+        foreach ($tolist as $addr) {
+            if(!($emailId=Email::getIdByEmail(strtolower($addr->mailbox).'@'.$addr->host))) {
+                $data['collaborators'][] = array(
+                          'name' => trim(@$addr->personal, '"'),
+                          'email' => strtolower($addr->mailbox).'@'.$addr->host);
+            } elseif(!$data['emailId']) {
+                $data['emailId'] = $emailId;
             }
         }
-        //maybe we got CC'ed??
-        if(!$emailId && ($cclist=$parser->getCcAddressList())) {
-            foreach ($cclist as $ccaddr) {
-                if(($emailId=Email::getIdByEmail($ccaddr->mailbox.'@'.$ccaddr->host)))
-                    break;
+
+        //maybe we got BCC'ed??
+        if(!$data['emailId']) {
+            unset($data['collaborators']);
+            $emailId =  0;
+            if($bcc = $parser->getBccAddressList())
+                foreach ($bcc as $addr) {
+                    if(($emailId=Email::getIdByEmail($addr->mailbox.'@'.$addr->host)))
+                        break;
             }
+            $data['emailId'] = $emailId;
         }
 
         $data['subject'] = $parser->getSubject();
@@ -398,7 +421,6 @@ class EmailDataParser {
         $data['header'] = $parser->getHeader();
         $data['mid'] = $parser->getMessageId();
         $data['priorityId'] = $parser->getPriority();
-        $data['emailId'] = $emailId;
 
         $data['in-reply-to'] = $parser->struct->headers['in-reply-to'];
         $data['references'] = $parser->struct->headers['references'];
-- 
GitLab