From 37e22ef91e269a0f21c072d5c4df152e626efe98 Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Mon, 28 Feb 2011 21:14:54 +0000 Subject: [PATCH] hook for egw_mailer to log or authorize all mail --- phpgwapi/inc/class.egw_mailer.inc.php | 65 ++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/phpgwapi/inc/class.egw_mailer.inc.php b/phpgwapi/inc/class.egw_mailer.inc.php index 919edc2504..112732bbd2 100644 --- a/phpgwapi/inc/class.egw_mailer.inc.php +++ b/phpgwapi/inc/class.egw_mailer.inc.php @@ -15,7 +15,7 @@ require_once(EGW_API_INC.'/class.phpmailer.inc.php'); /** * Log mails to log file specified in $GLOBALS['egw_info']['server']['log_mail'] * or regular error_log for true (can be set either in DB or header.inc.php). - * + * * This class does NOT use anything EGroupware specific, it acts like PHPMail, but logs. */ class egw_mailer extends PHPMailer @@ -26,7 +26,7 @@ class egw_mailer extends PHPMailer function __construct() { parent::__construct(true); // throw exceptions instead of echoing errors - + // setting EGroupware specific path for PHPMailer lang files list($lang,$nation) = explode('-',$GLOBALS['egw_info']['user']['preferences']['common']['lang']); $lang_path = EGW_SERVER_ROOT.'/phpgwapi/lang/'; @@ -43,10 +43,10 @@ class egw_mailer extends PHPMailer /** * Log mails to log file specified in $GLOBALS['egw_info']['server']['log_mail'] * or regular error_log for true (can be set either in DB or header.inc.php). - * + * * We can NOT supply this method as callback to phpMailer, as phpMailer only accepts * functions (not methods) and from a function we can NOT access $this->ErrorInfo. - * + * * @param boolean $isSent * @param string $to * @param string $cc @@ -62,10 +62,12 @@ class egw_mailer extends PHPMailer $msg .= ($isSent ? 'Mail send' : 'Mail NOT send'). ' to '.$to.' with subject: "'.trim($subject).'"'; + $msg .= ' from instance '.$GLOBALS['egw_info']['user']['domain'].' and IP '.egw_session::getuser_ip(); + $msg .= ' from user #'.$GLOBALS['egw_info']['user']['account_id']; + if ($GLOBALS['egw_info']['user']['account_id'] && class_exists('common',false)) { - $msg .= ' from user #'.$GLOBALS['egw_info']['user']['account_id'].' ('. - common::grab_owner_name($GLOBALS['egw_info']['user']['account_id']).')'; + $msg .= ' ('.common::grab_owner_name($GLOBALS['egw_info']['user']['account_id']).')'; } if (!$isSent) { @@ -74,6 +76,7 @@ class egw_mailer extends PHPMailer $msg .= 'ERROR '.str_replace(array('Language string failed to load: smtp_error',"\n","\r"),'', strip_tags($this->ErrorInfo)); } + $msg .= " cc=$cc, bcc=$bcc"; if ($GLOBALS['egw_info']['server']['log_mail'] !== true) $msg .= "\n\n"; error_log($msg,$GLOBALS['egw_info']['server']['log_mail'] === true ? 0 : 3, @@ -82,4 +85,54 @@ class egw_mailer extends PHPMailer // calling the orginal callback of phpMailer parent::doCallback($isSent,$to,$cc,$bcc,$subject,$body); } + + private $addresses = array(); + + /** + * Sends mail via SMTP using PhpSMTP + * + * Overwriting this method from phpmailer, to allow apps to intercept it + * via "send_mail" hook, eg. to log or authorize sending of mail. + * Hooks can throw phpmailerException($message, phpMailer::STOP_CRITICAL), + * to stop sending the mail out like an SMTP error. + * + * @param string $header The message headers + * @param string $body The message body + * @return bool + */ + public function SmtpSend($header, $body) + { + $GLOBALS['egw']->hooks->process(array( + 'location' => 'send_mail', + 'subject' => $this->Subject, + 'from' => $this->Sender ? $this->Sender : $this->From, + 'to' => $this->addresses['To'], + 'cc' => $this->addresses['Cc'], + 'bcc' => $this->addresses['Bcc'], + 'body_sha1' => sha1($body), + 'message_id' => preg_match('/^Message-ID: (.*)$/m', $header,$matches) ? $matches[1] : null, + ), array(), true); // true = call all apps + + $this->addresses = array(); // reset addresses for next mail + + // calling the overwritten method + return parent::SmtpSend($header, $body); + } + + /** + * Creates recipient headers. + * + * Overwritten to get To, Cc and Bcc addresses, which are private in phpMailer + * + * @access public + * @return string + */ + public function AddrAppend($type, $addr) + { + foreach($addr as $data) + { + $this->addresses[$type] .= ($this->addresses[$type] ? ', ' : '').$data[0]; + } + return parent::AddrAppend($type, $addr); + } }