Example #1
0
 /**
  * Main Parse Method
  *
  * @param	string	Raw email contents
  * @param	array	Any headers to override
  * @param	bool	Can pass true to not actually route
  */
 public static function parse($email, $override = array(), $doNotRoute = FALSE)
 {
     $obj = new self();
     $obj->raw = $email;
     //-----------------------------------------
     // Deconstruct it
     //-----------------------------------------
     // It raises strict warnings
     //@error_reporting( E_NONE );
     //@ini_set( 'display_errors', 'off' );
     require_once IPS_KERNEL_PATH . 'PEAR/Mail/mimeDecode.php';
     /*noLibHook*/
     $decoder = new Mail_mimeDecode($email);
     $mail = $decoder->decode(array('include_bodies' => TRUE, 'decode_bodies' => TRUE, 'decode_headers' => TRUE));
     //--------------------------------------
     // Parse Headers
     //--------------------------------------
     /* To */
     if (isset($override['to'])) {
         $obj->to = $override['to'];
     } else {
         if ($mail->headers['delivered-to']) {
             $mail->headers['to'] = $mail->headers['delivered-to'];
         }
         $to = array();
         if (strpos($mail->headers['to'], ',') === FALSE) {
             $mail->headers['to'] = array($mail->headers['to']);
         } else {
             $mail->headers['to'] = explode(',', $mail->headers['to']);
         }
         foreach ($mail->headers['to'] as $_to) {
             if (preg_match("/.+? <(.+?)>/", $_to, $matches)) {
                 $to[] = htmlentities($matches[1]);
             } else {
                 $to[] = htmlentities(trim($_to, '<>'));
             }
         }
         $obj->to = implode(',', $to);
     }
     /* From */
     if (isset($override['from'])) {
         $obj->from = $override['from'];
     } else {
         if (preg_match("/.+? <(.+?)>/", $mail->headers['from'], $matches)) {
             $obj->from = htmlentities($matches[1]);
         } else {
             $obj->from = htmlentities(trim($mail->headers['from'], '<>'));
         }
     }
     /* Subject */
     if (isset($override['subject'])) {
         $obj->subject = $override['subject'];
     } else {
         $obj->subject = (bool) trim($mail->headers['subject']) ? $mail->headers['subject'] : '(No Subject)';
         $obj->subject = htmlentities($obj->subject);
     }
     /* CC */
     $mail->headers['cc'] = preg_replace('/".+?" <(.+?)>/', '$1', $mail->headers['cc']);
     if (strpos($mail->headers['cc'], ',') === FALSE) {
         $mail->headers['cc'] = array($mail->headers['cc']);
     } else {
         $mail->headers['cc'] = explode(',', $mail->headers['cc']);
     }
     foreach ($mail->headers['cc'] as $_cc) {
         if (preg_match("/.+? <(.+?)>/", $_cc, $matches)) {
             $cc[] = $matches[1];
         } else {
             $cc[] = trim($_cc, '<> ');
         }
     }
     $obj->cc = str_replace(array('&gt;', '&lt;'), '', implode(',', $cc));
     //-----------------------------------------
     // Ignore?
     //-----------------------------------------
     if (!$obj->debug_mode and !$doNotRoute) {
         $escapedFrom = $obj->DB->addSlashes($obj->from);
         $log = $obj->DB->buildAndFetch(array('select' => '*', 'from' => 'core_incoming_email_log', 'where' => "log_email='{$escapedFrom}'"));
         if ($log['log_id']) {
             $oneMinuteAgo = time() - 60;
             if ($log['log_time'] > $oneMinuteAgo && $this->settings['sixty_second_rule']) {
                 $ignore = TRUE;
             }
             $obj->DB->update('core_incoming_email_log', array('log_time' => time()), "log_id={$log['log_id']}");
             if ($ignore) {
                 return;
             }
         } else {
             $obj->DB->insert('core_incoming_email_log', array('log_email' => $obj->from, 'log_time' => time()));
         }
     }
     //-----------------------------------------
     // Now destruct the message
     //-----------------------------------------
     $obj->message = '';
     $obj->_parsePart($mail);
     //-----------------------------------------
     // Purify It
     //-----------------------------------------
     // &nbsp; sometimes breaks
     $obj->message = str_replace('&nbsp;', ' ', $obj->message);
     /* Load */
     require_once IPS_KERNEL_PATH . 'HTMLPurifier/HTMLPurifier.auto.php';
     $config = HTMLPurifier_Config::createDefault();
     /* Set Configuration */
     $config->set('AutoFormat.Linkify', TRUE);
     $config->set('Core.Encoding', IPS_DOC_CHAR_SET);
     $config->set('HTML.TargetBlank', TRUE);
     $config->set('URI.Munge', ipsRegistry::getClass('output')->buildUrl('app=nexus&module=support&section=redirect&url=%s&key=%t&resource=%r', 'publicNoSession'));
     $config->set('URI.MungeResources', TRUE);
     $config->set('URI.MungeSecretKey', md5(ipsRegistry::$settings['sql_pass'] . ipsRegistry::$settings['board_url'] . ipsRegistry::$settings['sql_database']));
     /* Retain collapse data attribute */
     $def = $config->getHTMLDefinition(true);
     $def->addAttribute('blockquote', 'data-author', 'CDATA');
     $def->addAttribute('blockquote', 'data-collapsed', 'Number');
     /* Purify */
     $purifier = new HTMLPurifier($config);
     $obj->message = $purifier->purify($obj->message);
     //-----------------------------------------
     // Route
     //-----------------------------------------
     if ($doNotRoute) {
         return $obj;
     }
     $routed = FALSE;
     /* Try our routing criteria */
     $obj->DB->build(array('select' => '*', 'from' => 'core_incoming_emails'));
     $obj->DB->execute();
     while ($row = $obj->DB->fetch()) {
         // What are we looking for?
         switch ($row['rule_criteria_field']) {
             case 'to':
                 $analyse = $obj->to;
                 break;
             case 'from':
                 $analyse = $obj->from;
                 break;
             case 'sbjt':
                 $analyse = $obj->subject;
                 break;
             case 'body':
                 $analyse = $obj->message;
                 break;
         }
         // Does it match?
         $match = false;
         switch ($row['rule_criteria_type']) {
             case 'ctns':
                 $match = (bool) (strpos($analyse, $row['rule_criteria_value']) !== FALSE);
                 break;
             case 'eqls':
                 if (strpos($analyse, ',') !== FALSE) {
                     $match = (bool) in_array($analyse, explode(',', $analyse));
                 } else {
                     $match = (bool) ($analyse == $row['rule_criteria_value']);
                 }
                 break;
             case 'regx':
                 $match = (bool) (preg_match("/{$row['rule_criteria_value']}/", $analyse) == 1);
                 break;
         }
         // If it matches, give to the app
         if ($match) {
             $routed = true;
             if ($row['rule_app'] != '--') {
                 $appdir = IPSLib::getAppDir($row['rule_app']);
                 if (is_file($appdir . '/extensions/incomingEmails.php')) {
                     $class = 'incomingEmails_' . $row['rule_app'];
                     require_once $appdir . '/extensions/incomingEmails.php';
                     /*noLibHook*/
                     $class = new $class();
                     $class->process($obj);
                 }
             }
             break;
         }
     }
     /* Still here? Try all our apps */
     if (!$routed) {
         foreach (ipsRegistry::$applications as $app) {
             $file = IPSLib::getAppDir($app['app_directory']) . '/extensions/incomingEmails.php';
             if (file_exists($file)) {
                 require_once $file;
                 $class = 'incomingEmails_' . $app['app_directory'];
                 $i = new $class();
                 if ($routed = $i->handleUnrouted($obj)) {
                     break;
                 }
             }
         }
     }
     /* STILL Here? Throw the unrouted message */
     if (!$routed) {
         $unroutedMessage = @file_get_contents(DOC_IPS_ROOT_PATH . 'interface/email/unrouted.txt');
         if ($unroutedMessage) {
             IPSText::getTextClass('email')->to = $obj->from;
             IPSText::getTextClass('email')->from = $obj->to;
             IPSText::getTextClass('email')->subject = "Re: {$obj->subject}";
             IPSText::getTextClass('email')->message = nl2br($unroutedMessage);
             IPSText::getTextClass('email')->setHtmlEmail(TRUE);
             IPSText::getTextClass('email')->sendMail();
         }
     }
 }