<?php

require_once 'Horde/Identity.php';
require_once IMP_BASE . '/lib/Compose.php';

/**
 * The IMP_Spam:: class contains functions related to reporting spam
 * messages in IMP.
 *
 * $Horde: imp/lib/Spam.php,v 1.3.4.1 2005/01/03 12:25:33 jan Exp $
 *
 * Copyright 2004-2005 Michael Slusarz <slusarz@curecanti.org>
 *
 * See the enclosed file COPYING for license information (GPL). If you
 * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
 *
 * @author  Michael Slusarz <slusarz@curecanti.org>
 * @version $Revision: 1.3.4.1 $
 * @since   IMP 4.0
 * @package IMP
 */
class IMP_Spam {

    /**
     * The IMP_Compose:: object used by the class.
     *
     * @var object IMP_Compose $_imp_compose
     */
    var $_imp_compose;

    /**
     * The IMP_Identity:: object used by the class.
     *
     * @var object IMP_Identity $_identity
     */
    var $_identity;

    /**
     * Constructor.
     *
     * @access public
     */
    function IMP_Spam()
    {
        $this->_imp_compose = &new IMP_Compose();
        $this->_identity = &Identity::singleton(array('imp', 'imp'));
    }

    /**
     * Report a list of messages as spam, based on the local configuration
     * parameters.
     *
     * @access public
     *
     * @param array $indices  A list of indices to report as spam.
     * @param string $action  Either 'spam' or 'notspam'.
     */
    function reportSpam($indices, $action)
    {
        require_once IMP_BASE . '/lib/MIME/Contents.php';

        /* Abort immediately if spam reporting has not been enabled. */
        if (empty($GLOBALS['conf'][$action]['reporting'])) {
            return;
        }

        /* We can report 'program' and 'bounce' messages as the same since
         * they are both meant to indicate that the message has been reported
         * to some program for analysis. */
        $email_msg_count = $report_msg_count = 0;

        foreach ($indices as $msgnum) {
            /* Fetch the raw message contents (headers and complete 
             * body). */
            $imp_contents = &IMP_Contents::singleton($msgnum);

            $to = null;
            $report_flag = false;

            /* If a (not)spam reporting program has been provided, use it. */
            if (!empty($GLOBALS['conf'][$action]['program'])) {
                $raw_msg = $imp_contents->fullMessageText();
                /* Use a pipe to write the message contents. This should
                 * be secure. */
                $pipe = popen($GLOBALS['conf'][$action]['program'], 'w');
                fwrite($pipe, $raw_msg);
                pclose($pipe);
                $report_msg_count++;
                $report_flag = true;
            }

            /* If a (not)spam reporting email address has been provided,
             * use it. */
            if (!empty($GLOBALS['conf'][$action]['email'])) {
                if (!isset($raw_msg)) {
                    $raw_msg = $imp_contents->fullMessageText();
                }
                $this->_sendSpamReportMessage($action, $raw_msg);
                $email_msg_count++;
            }

            /* If a (not)spam bounce email address has been provided, use
             * it. */
            if (!empty($GLOBALS['conf'][$action]['bounce'])) {
                $to = $GLOBALS['conf'][$action]['bounce'];
            } elseif (!empty($GLOBALS['conf']['hooks']['spam_bounce'])) {
                /* Call the bounce email generation hook, if requested. */
                require_once HORDE_BASE . '/config/hooks.php';
                if (function_exists('_imp_hook_spam_bounce')) {
                    $to = call_user_func('_imp_hook_spam_bounce', $action);
                }
            }

            if ($to) {
                require_once IMP_BASE . '/lib/MIME/Headers.php';
                $imp_headers = &new IMP_Headers($msgnum);
                $imp_headers->buildHeaders();

                $from_addr = $this->_identity->getFromAddress();
                $imp_headers->addResentHeaders($from_addr, $to);

                /* We need to set the Return-Path header to the current user -
                 * see RFC 2821 [4.4]. */
                $imp_headers->removeHeader('return-path');
                $imp_headers->addHeader('Return-Path', $from_addr);

                $bodytext = $imp_contents->getBody();

                $this->_imp_compose->sendMessage($to, $imp_headers, $bodytext, NLS::getCharset());
                if (!$report_flag) {
                    $report_msg_count++;
                }
            }
        }

        /* Report what we've done. */
        if ($report_msg_count) {
            switch ($action) {
            case 'spam':
                if ($report_msg_count > 1) {
                    $GLOBALS['notification']->push(sprintf(_("%d messages have been reported as spam."), $report_msg_count), 'horde.message');
                } else {
                    $GLOBALS['notification']->push(_("1 message has been reported as spam."), 'horde.message');
                }
                break;

            case 'notspam':
                if ($report_msg_count > 1) {
                    $GLOBALS['notification']->push(sprintf(_("%d messages have been reported as not spam."), $report_msg_count), 'horde.message');
                } else {
                    $GLOBALS['notification']->push(_("1 message has been reported as not spam."), 'horde.message');
                }
                break;
            }
        }

        if ($email_msg_count) {
            switch ($action) {
            case 'spam':
                if ($email_msg_count > 1) {
                    $GLOBALS['notification']->push(sprintf(_("%d messages have been reported as spam to your system administrator."), $email_msg_count), 'horde.message');
                } else {
                    $GLOBALS['notification']->push(_("1 message has been reported as spam to your system administrator."), 'horde.message');
                }
                break;

            case 'notspam':
                if ($email_msg_count > 1) {
                    $GLOBALS['notification']->push(sprintf(_("%d messages have been reported as not spam to your system administrator."), $email_msg_count), 'horde.message');
                } else {
                    $GLOBALS['notification']->push(_("1 message has been reported as not spam to your system administrator."), 'horde.message');
                }
                break;
            }
        }
    }

    /**
     * Send a (not)spam message to the sysadmin.
     *
     * @access private
     *
     * @param string $action  The message data.
     * @param string $data    The message data.
     */
    function _sendSpamReportMessage($action, $data)
    {
        require_once 'Horde/MIME/Message.php';

        /* Build the MIME structure. */
        $mime = &new MIME_Message();
        $mime->setType('multipart/digest');
        $mime->addPart(new MIME_Part('message/rfc822', $data));

        $spam_headers = &new IMP_Headers();
        $spam_headers->addMessageIdHeader();
        $spam_headers->addHeader('Date', date('r'));
        $spam_headers->addHeader('To', $GLOBALS['conf'][$action]['email']);
        $spam_headers->addHeader('From', $this->_identity->getFromLine());
        $spam_headers->addHeader('Subject', _("$action Report from") . ' ' . $GLOBALS['imp']['user']);
        $spam_headers->addMIMEHeaders($mime);

        /* Send the message. */
        $this->_imp_compose->sendMessage($GLOBALS['conf'][$action]['email'], $spam_headers, $mime, NLS::getCharset());
    }

}
