[Fwd: Some modifications for Mail.php]

"Jason M. Felice" <[email protected]> Fri, 04 Mar 2005 09:42:50 -0500
Newsgroups gmane.comp.horde.whups
Message-ID <[email protected]>
Hi Auke,

I'm forwarding this to the whups e-mail list, which you can subscribe to 
from http://lists.horde.org.  There is also a dev e-mail list, which 
contains more general developer discussions.  Either place is where we 
generally see patches.  Alternately, you can attach them to tickets at 
bugs.horde.org.

I haven't looked at your changes, but it sounds great. :-)

-- 
 Jason M. Felice
 Cronosys, LLC <http://www.cronosys.com/>
 216.221.4600 x302

-- 
Whups mailing list - Join the hunt: http://horde.org/bounties/#whups
Frequently Asked Questions: http://horde.org/faq/
To unsubscribe, mail: [email protected]
Some modifications for Mail.php (message/rfc822, 11.5 KB)
Return-Path: <cyrus@prometheus>
Received: from murder ([unix socket])
	by prometheus (Cyrus v2.2.4-Debian-2.2.4-2) with LMTPA;
	Thu, 03 Mar 2005 17:00:08 -0500
X-Sieve: CMU Sieve 2.2
Received: from localhost (localhost.localdomain [127.0.0.1])
	by prometheus (Postfix) with ESMTP id 72ADF70801B
	for <[email protected]>; Thu,  3 Mar 2005 17:00:08 -0500 (EST)
Received: from prometheus.cronosys.com ([127.0.0.1])
	by localhost (prometheus [127.0.0.1]) (amavisd-new, port 10024)
	with ESMTP id 05712-09 for <[email protected]>;
	Thu, 3 Mar 2005 17:00:07 -0500 (EST)
Received: by prometheus (Postfix, from userid 1002)
	id 8BEC870807A; Thu,  3 Mar 2005 17:00:07 -0500 (EST)
Received: from warserver.warande.net (warserver.warande.net [145.97.193.198])
	by prometheus (Postfix) with ESMTP id 1E08370801B
	for <[email protected]>; Thu,  3 Mar 2005 17:00:06 -0500 (EST)
Received: from localhost (localhost [127.0.0.1])
	by warserver.warande.net (Postfix) with ESMTP id 389B3210150
	for <[email protected]>; Thu,  3 Mar 2005 23:00:01 +0100 (CET)
Received: from warserver.warande.net ([127.0.0.1])
	by localhost (warserver [127.0.0.1]) (amavisd-new, port 10024)
	with ESMTP id 30891-04 for <[email protected]>;
	Thu, 3 Mar 2005 23:00:01 +0100 (CET)
Received: from 73pc222.sshunet.nl (73pc222.sshunet.nl [145.97.222.73])
	by warserver.warande.net (Postfix) with ESMTP id 013B321013C
	for <[email protected]>; Thu,  3 Mar 2005 23:00:01 +0100 (CET)
From: Auke Bruinsma <[email protected]>
To: [email protected]
Subject: Some modifications for Mail.php
Date: Thu, 3 Mar 2005 22:56:17 +0000
User-Agent: KMail/1.7.2
MIME-Version: 1.0
Content-Type: Multipart/Mixed;
  boundary="Boundary-00=_RY5JCTY2MhOuF8N"
Message-Id: <[email protected]>
X-Virus-Scanned: by amavisd-new-20030616-p10 (Debian) at warande.net
X-Spam-Checker-Version: SpamAssassin 3.0.1 (2004-10-22) on 
	prometheus.cronosys.com
X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00 autolearn=ham 
	version=3.0.1
X-Spam-Level: 
X-Virus-Scanned: by amavisd-new-20030616-p7 (Debian) at prometheus.cronosys.com

--Boundary-00=_RY5JCTY2MhOuF8N
Content-Type: text/plain;
  charset="us-ascii"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

Hello,

I made a few modifications to Mail.php, so it can handle, replies and 
attachments. Its works for me.

Hope you find it usefull. I am a very noob to horde, so I do not know where to 
post it.

Greetings,

Auke Bruinsma
ps. I use this in combination with the mail-filter script.. realy a good 
combination.

--Boundary-00=_RY5JCTY2MhOuF8N
Content-Type: application/x-php;
  name="Mail.php"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filename="Mail.php"

<?php
/**
 * Whups mail processing/generation library.
 *
 * $Horde: whups/lib/Mail.php,v 1.11 2005/01/12 17:04:45 chuck Exp $
 *
 * Copyright 2004-2005 Jason M. Felice <[email protected]>
 * Copyright 2005      Auke Bruinsma <[email protected]>
 *
 * See the enclosed file LICENSE for license information (BSD). If you
 * did not receive this file, see http://www.horde.org/licenses/bsdl.php.
 *
 * @author  Jason M. Felice <[email protected]>
 * @package Whups
 */

if (!function_exists ('stripos'))
{
function stripos($haystack,$needle,$offset = 0)
{
   return(strpos(strtolower($haystack),strtolower($needle),$offset));
}
}

class Whups_Mail {

    /**
     * Parse a MIME message and create a new ticket.
     *
     * @param string $text              This is the full text of the MIME
     *                                  message.
     * @param array $info               An array of information for the new
     *                                  ticket.  This should include:
     *                                      'queue' => queue id
     *                                      'type' => type id
     *                                      'state' => state id
     *                                      'priority' => priority id
     * @param optional string $user     This will be the ticket's requestor.
     *                                  If null, we will try to deduce from
     *                                  the message's "From" field--we do
     *                                  NOT default to Auth::getAuth().
     *
     * @returns mixed ? or PEAR_Error:: instance.
     */
    function processMail($text, $info, $user = null)
    {
        global $conf, $whups;

        require_once 'Horde/MIME/Structure.php';
        $message = &MIME_Structure::parseTextMIMEMessage($text);

        if (preg_match("/^(.*?)\r?\n\r?\n/s", $text, $matches)) {
            $hdrText = $matches[1];
        } else {
            $hdrText = $text;
        }
        $headers = MIME_Structure::parseMIMEHeaders($hdrText);

        // Use the message subject as the ticket summary.
        $info['summary'] = Whups_Mail::_findSimpleHeaderValue($headers,
                                                              'Subject');
//        $info['comment'] = Whups_Mail::_buildComment($message, $headers);

        if (is_null($user)) {
            $user = Whups_Mail::_findAuthUser($headers);
        }

        if (!is_null($user)) {
            if ($user != Auth::getAuth()) {
                $params = Horde::getDriverConfig('auth', $conf['auth']['driver']);
                $auth = &Auth::singleton($conf['auth']['driver'], $params);
                $auth->setAuth($user, array());
            }
            // FIXME: Use Identity to set email address.
        } else {
            $from = Whups_Mail::_findSimpleHeaderValue($headers, 'From');
            if (!empty($from)) {
                $info['user_email'] = $from;
            }
        }
	$ticket = Whups_Mail::_getReplyTicket ($info['summary']);
	if ($ticket) {
            $info['comment'] = Whups_Mail::_buildComment($message, $headers, $ticket);
	    $ticket->change ('comment', substr ($info ['comment'],0, stripos ($info ['comment'], 'Received message:', 18)));
            $ticket->commit ("Air2");
	    return $ticket;
        } else {
             $ticket = "";
             $info['comment'] = Whups_Mail::_buildComment($message, $headers, $ticket);
            $ticket = &Whups_Ticket::newTicket($info, $user);
            $info['comment'] = Whups_Mail::_buildComment($message, $headers, $ticket);
            return $ticket; 
        }
         
    }


    function _findSimpleHeaderValue($headers, $name)
    {
        foreach ($headers as $hdrName => $hdrVals) {
            if (strcasecmp($hdrName, $name) == 0) {
                if (is_array($hdrVals)) {
                    return implode(', ', $hdrVals);
                } else {
                    return $hdrVals;
                }
            }
        }

        return null;
    }

    function &_getReplyTicket($subject)
    {
	//FIXME: Should not only check for Re: but also for Aw: (germany) etc.
	if(stripos($subject, 'RE:') !== false) {
            $ticketnum = stripos($subject, 'Tickets #') + 9;
            if($ticketnum === false) return NULL;
            $ticketnumend = stripos($subject, ']', $ticketnum);
            if($ticketnumend === false) return NULL;
            $ticketnum = substr($subject, $ticketnum, $ticketnumend - $ticketnum);
            echo "ticketnummer:\n";
            $ticket = &Whups_Ticket::makeTicket($ticketnum);
            if (is_a($ticket, 'PEAR_Error')) {
            if ($ticket->code === 0) {
                // No permissions to this ticket.
                echo ($ticket->getMessage());
                return NULL;
            } else {
                echo ($ticket->getMessage());
                return NULL;
            }
	    }
            return $ticket;
	}
	else {
             return NULL;	   
	}
    }

    function _buildAttachment (&$ticket, $attachment, $name = "")
    {
         if ($ticket == NULL) return NULL;
         $filename = tempnam ("/tmp", "wupsattach");
         $handle = fopen($filename, "wb");
         if (!$handle) return $ticket;
         fwrite($handle, $attachment);
         fclose($handle); 
         if ($name == "") $name = 'mail attach';
         $ticket->addAttachment ($name, $filename);
         return $ticket;
    }

    function _parseMessageParts(&$part, &$comment, &$ticket)
    {
	if ($part->getType() == 'text/plain') {
            $comment .= $part->getContents();
	    return $comment;
        } elseif ($part->getType() == 'multipart/alternative' ||
                  $part->getType() == 'multipart/mixed' || 
                  $part->getType() == 'text/mixed') {
            foreach ($part->getParts() as $subpart) {
		$tmp = $comment;
		$comment = Whups_Mail::_parseMessageParts ($subpart, $tmp, $ticket);
		return $comment . $subpart->getType ();
            }
       } else {

           if ($ticket != NULL && $ticket != "")
           {
               $ticket = Whups_Mail::_buildAttachment ($ticket, $part->transferDecode (), $part->_contentTypeParameters ['name']);
           }
           return $comment;
      }
    }

    function _buildComment(&$message, $headers, &$ticket)
    {
        // Format the message into a comment.
        $comment = "Received message:\n\n";
        foreach ($headers as $name => $vals) {
            if (!strcasecmp($name, 'Subject') || !strcasecmp($name, 'From') ||
                !strcasecmp($name, 'To') || !strcasecmp($name, 'Cc') ||
                !strcasecmp($name, 'Date')) {
                if (is_array($vals)) {
                    foreach ($vals as $val) {
                        $comment .= $name . ': ' . $val . "\n";
                    }
                } else {
                    $comment .= $name . ': ' . $vals . "\n";
                }
            }
        }

        $comment .= "\n";

        // Look for a text part.
        // FIXME: this is _extremely_ crude.
        if ($message->getType() == 'text/plain') {
            $comment .= $message->getContents();
        } elseif ($message->getType() == 'multipart/alternative' ||
                  $message->getType() == 'multipart/mixed' ||
                  $message->getType() == 'text/mixed') {
            foreach ($message->getParts() as $part) {
                $comment = Whups_Mail::_parseMessageParts ($part, $comment, $ticket);
//                if ($part->getType() == 'text/plain') {
  //                  $comment .= $part->getContents();
    //                break;
//                }
            }
        } else {
            if ($ticket != NULL && $ticket != "")
            {
               $ticket = Whups_Mail::_buildAttachment ($ticket, $message->transferDecode (), $message->getDescription ()); 
            }
            $comment .= "[ Could not render body of message. ]<BR>";
            $comment .= $message->getType();
        }

        $comment .= "\n";
        return $comment;
    }

    /**
     * Search the 'From' header for an email address contained in one
     * of our users' identities.
     *
     * @access private
     */
    function _findAuthUser($headers)
    {
        global $conf;

        require_once 'Horde/Identity.php';
        require_once 'Horde/MIME.php';

        $from = Whups_Mail::_findSimpleHeaderValue($headers, 'From');
        $from = MIME::bareAddress($from);

        $params = Horde::getDriverConfig('auth', $conf['auth']['driver']);
        $auth = &Auth::singleton($conf['auth']['driver'], $params);
        $users = $auth->listUsers();
        foreach ($users as $user) {
            $identity = &Identity::singleton('none', $user);
            $addrs = $identity->getAll('from_addr');
            foreach ($addrs as $addr) {
                if (strcasecmp($from, $addr) == 0) {
                    return $user;
                }
            }
        }

        return null;
    }

}

--Boundary-00=_RY5JCTY2MhOuF8N--