/**
  * Function to process each individual message
  *
  * @param int    $pos          message number
  * @param string $type         DNS or BODY type
  * @param string $totalFetched total number of messages in mailbox
  *
  * @return boolean
  */
 public function processBounce($pos, $type, $totalFetched)
 {
     $header = imap_header($this->mailboxLink, $pos);
     $subject = strip_tags($header->subject);
     $body = '';
     if ($type == 'DSN') {
         // first part of DSN (Delivery Status Notification), human-readable explanation
         $dsnMsg = imap_fetchbody($this->mailboxLink, $pos, "1");
         $dsnMsgStructure = imap_bodystruct($this->mailboxLink, $pos, "1");
         if ($dsnMsgStructure->encoding == 4) {
             $dsnMsg = quoted_printable_decode($dsnMsg);
         } elseif ($dsnMsgStructure->encoding == 3) {
             $dsnMsg = base64_decode($dsnMsg);
         }
         // second part of DSN (Delivery Status Notification), delivery-status
         $dsnReport = imap_fetchbody($this->mailboxLink, $pos, "2");
         // process bounces by rules
         $result = bmhDSNRules($dsnMsg, $dsnReport, $this->debugDsnRule);
     } elseif ($type == 'BODY') {
         $structure = imap_fetchstructure($this->mailboxLink, $pos);
         switch ($structure->type) {
             case 0:
                 // Content-type = text
                 $body = imap_fetchbody($this->mailboxLink, $pos, "1");
                 $result = bmhBodyRules($body, $structure, $this->debugBodyRule);
                 break;
             case 1:
                 // Content-type = multipart
                 $body = imap_fetchbody($this->mailboxLink, $pos, "1");
                 // Detect encoding and decode - only base64
                 if ($structure->parts[0]->encoding == 4) {
                     $body = quoted_printable_decode($body);
                 } elseif ($structure->parts[0]->encoding == 3) {
                     $body = base64_decode($body);
                 }
                 $result = bmhBodyRules($body, $structure, $this->debugBodyRule);
                 break;
             case 2:
                 // Content-type = message
                 $body = imap_body($this->mailboxLink, $pos);
                 if ($structure->encoding == 4) {
                     $body = quoted_printable_decode($body);
                 } elseif ($structure->encoding == 3) {
                     $body = base64_decode($body);
                 }
                 $body = substr($body, 0, 1000);
                 $result = bmhBodyRules($body, $structure, $this->debugBodyRule);
                 break;
             default:
                 // unsupport Content-type
                 $this->output('Msg #' . $pos . ' is unsupported Content-Type:' . $structure->type, self::VERBOSE_REPORT);
                 return false;
         }
     } else {
         // internal error
         $this->errorMessage = 'Internal Error: unknown type';
         return false;
     }
     $email = $result['email'];
     $bounceType = $result['bounce_type'];
     if ($this->moveHard && $result['remove'] == 1) {
         $remove = 'moved (hard)';
     } elseif ($this->moveSoft && $result['remove'] == 1) {
         $remove = 'moved (soft)';
     } elseif ($this->disableDelete) {
         $remove = 0;
     } else {
         $remove = $result['remove'];
     }
     $ruleNumber = $result['rule_no'];
     $ruleCategory = $result['rule_cat'];
     $xheader = false;
     if ($ruleNumber === '0000') {
         // unrecognized
         if (trim($email) == '') {
             $email = $header->fromaddress;
         }
         if ($this->testMode) {
             $this->output('Match: ' . $ruleNumber . ':' . $ruleCategory . '; ' . $bounceType . '; ' . $email);
         } else {
             // code below will use the Callback function, but return no value
             $params = array($pos, $bounceType, $email, $subject, $header, $remove, $ruleNumber, $ruleCategory, $totalFetched, $body);
             call_user_func_array($this->actionFunction, $params);
         }
     } else {
         // match rule, do bounce action
         if ($this->testMode) {
             $this->output('Match: ' . $ruleNumber . ':' . $ruleCategory . '; ' . $bounceType . '; ' . $email);
             return true;
         } else {
             $params = array($pos, $bounceType, $email, $subject, $xheader, $remove, $ruleNumber, $ruleCategory, $totalFetched, $body);
             return call_user_func_array($this->actionFunction, $params);
         }
     }
 }
Example #2
0
 /**
  * Function to process each individual message.
  *
  * @param int    $pos          message number
  * @param string $type         DNS or BODY type
  * @param string $totalFetched total number of messages in mailbox
  *
  * @return boolean
  */
 public function processBounce($pos, $type, $totalFetched)
 {
     $header = imap_header($this->mailboxLink, $pos);
     $subject = isset($header->subject) ? strip_tags($header->subject) : '[NO SUBJECT]';
     $body = '';
     $headerFull = imap_fetchheader($this->mailboxLink, $pos);
     $bodyFull = imap_body($this->mailboxLink, $pos);
     if ($type == 'DSN') {
         // first part of DSN (Delivery Status Notification), human-readable explanation
         $dsnMsg = imap_fetchbody($this->mailboxLink, $pos, '1');
         $dsnMsgStructure = imap_bodystruct($this->mailboxLink, $pos, '1');
         if ($dsnMsgStructure->encoding == 4) {
             $dsnMsg = quoted_printable_decode($dsnMsg);
         } elseif ($dsnMsgStructure->encoding == 3) {
             $dsnMsg = base64_decode($dsnMsg);
         }
         // second part of DSN (Delivery Status Notification), delivery-status
         $dsnReport = imap_fetchbody($this->mailboxLink, $pos, '2');
         // process bounces by rules
         $result = bmhDSNRules($dsnMsg, $dsnReport, $this->debugDsnRule);
         $result = is_callable($this->customDSNRulesCallback) ? call_user_func($this->customDSNRulesCallback, $result, $dsnMsg, $dsnReport, $this->debugDsnRule) : $result;
     } elseif ($type == 'BODY') {
         /** @noinspection PhpUsageOfSilenceOperatorInspection */
         $structure = @imap_fetchstructure($this->mailboxLink, $pos);
         if (!is_object($structure)) {
             return false;
         }
         switch ($structure->type) {
             case 0:
                 // Content-type = text
                 $body = imap_fetchbody($this->mailboxLink, $pos, '1');
                 $result = bmhBodyRules($body, $structure, $this->debugBodyRule);
                 $result = is_callable($this->customBodyRulesCallback) ? call_user_func($this->customBodyRulesCallback, $result, $body, $structure, $this->debugBodyRule) : $result;
                 break;
             case 1:
                 // Content-type = multipart
                 $body = imap_fetchbody($this->mailboxLink, $pos, '1');
                 // Detect encoding and decode - only base64
                 if ($structure->parts[0]->encoding == 4) {
                     $body = quoted_printable_decode($body);
                 } elseif ($structure->parts[0]->encoding == 3) {
                     $body = base64_decode($body);
                 }
                 $result = bmhBodyRules($body, $structure, $this->debugBodyRule);
                 $result = is_callable($this->customBodyRulesCallback) ? call_user_func($this->customBodyRulesCallback, $result, $body, $structure, $this->debugBodyRule) : $result;
                 break;
             case 2:
                 // Content-type = message
                 $body = imap_body($this->mailboxLink, $pos);
                 if ($structure->encoding == 4) {
                     $body = quoted_printable_decode($body);
                 } elseif ($structure->encoding == 3) {
                     $body = base64_decode($body);
                 }
                 $body = substr($body, 0, 1000);
                 $result = bmhBodyRules($body, $structure, $this->debugBodyRule);
                 $result = is_callable($this->customBodyRulesCallback) ? call_user_func($this->customBodyRulesCallback, $result, $body, $structure, $this->debugBodyRule) : $result;
                 break;
             default:
                 // unsupport Content-type
                 $this->output('Msg #' . $pos . ' is unsupported Content-Type:' . $structure->type, self::VERBOSE_REPORT);
                 return false;
         }
     } else {
         // internal error
         $this->errorMessage = 'Internal Error: unknown type';
         return false;
     }
     $email = $result['email'];
     $bounceType = $result['bounce_type'];
     // workaround: I think there is a error in one of the reg-ex in "phpmailer-bmh_rules.php".
     if ($email && strpos($email, 'TO:<')) {
         $email = str_replace('TO:<', '', $email);
     }
     if ($this->moveHard && $result['remove'] == 1) {
         $remove = 'moved (hard)';
     } elseif ($this->moveSoft && $result['remove'] == 1) {
         $remove = 'moved (soft)';
     } elseif ($this->disableDelete) {
         $remove = 0;
     } else {
         $remove = $result['remove'];
     }
     $ruleNumber = $result['rule_no'];
     $ruleCategory = $result['rule_cat'];
     $status_code = $result['status_code'];
     $action = $result['action'];
     $diagnostic_code = $result['diagnostic_code'];
     $xheader = false;
     if ($ruleNumber === '0000') {
         // unrecognized
         if (trim($email) == '' && property_exists($header, 'fromaddress') === true) {
             $email = $header->fromaddress;
         }
         if ($this->testMode) {
             $this->output('Match: ' . $ruleNumber . ':' . $ruleCategory . '; ' . $bounceType . '; ' . $email);
         } else {
             // code below will use the Callback function, but return no value
             $params = array($pos, $bounceType, $email, $subject, $header, $remove, $ruleNumber, $ruleCategory, $totalFetched, $body, $headerFull, $bodyFull, $status_code, $action, $diagnostic_code);
             call_user_func_array($this->actionFunction, $params);
         }
     } else {
         // match rule, do bounce action
         if ($this->testMode) {
             $this->output('Match: ' . $ruleNumber . ':' . $ruleCategory . '; ' . $bounceType . '; ' . $email);
             return true;
         } else {
             $params = array($pos, $bounceType, $email, $subject, $xheader, $remove, $ruleNumber, $ruleCategory, $totalFetched, $body, $headerFull, $bodyFull, $status_code, $action, $diagnostic_code);
             return call_user_func_array($this->actionFunction, $params);
         }
     }
     return false;
 }
Example #3
0
 /**
  * Function to process each individual message
  * @param int    $pos            (message UID)
  * @param string $type           (DNS or BODY type)
  * @param string $totalFetched   (total number of messages in mailbox)
  * @return boolean
  */
 function processBounce($pos, $type, $totalFetched)
 {
     $time = mktime();
     //var_dump('process bounce ' . $pos .'-'.  $type .'-'.  $totalFetched);
     $header = $this->protocol->getMessageHeaders($pos, FT_UID);
     //imap_header
     //var_dump('headers ' . (mktime() - $time));
     if (!empty($header->subject)) {
         $subject = strip_tags($header->subject);
     } else {
         $subject = '';
     }
     $met = ini_get('max_execution_time');
     if ($met < 6000 && $met != 0) {
         set_time_limit(6000);
     }
     $this->protocol->setTimeout(6000);
     //var_dump($header, $subject);
     if ($type == 'DSN') {
         // first part of DSN (Delivery Status Notification), human-readable explanation
         //var_dump('getMessageBody ' . (mktime() - $time));
         $dsn_msg = $this->protocol->getMessageBody($pos, "1", FT_UID);
         //var_dump('getMessageBody(end) ' . (mktime() - $time));
         $dsn_msg_structure = $this->protocol->getMessageBodyStruct($pos, "1", FT_UID);
         //var_dump('getMessageBodyStruct(end) ' . (mktime() - $time));
         if ($dsn_msg_structure->encoding == 4) {
             $dsn_msg = quoted_printable_decode($dsn_msg);
         } elseif ($dsn_msg_structure->encoding == 3) {
             $dsn_msg = base64_decode($dsn_msg);
         }
         // second part of DSN (Delivery Status Notification), delivery-status
         $dsn_report = $this->protocol->getMessageBody($pos, "2", FT_UID);
         //imap_fetchbody($this->_mailbox_link, $pos, "2");
         //var_dump('getMessageBody(pos2)-end ' . (mktime() - $time));
         // process bounces by rules
         $result = bmhDSNRules($dsn_msg, $dsn_report, $this->debug_dsn_rule);
     } elseif ($type == 'BODY') {
         //var_dump('getMessageBodyStructure ' . (mktime() - $time));
         $structure = $this->protocol->getMessageBodyStructure($pos, FT_UID);
         // imap_fetchstructure($this->_mailbox_link, $pos);
         //var_dump('getMessageBodyStructure-end ' . (mktime() - $time));
         switch ($structure->type) {
             case 0:
                 // Content-type = text
             // Content-type = text
             case 1:
                 // Content-type = multipart
                 //var_dump('getMessageBody2 ' . (mktime() - $time));
                 $body = $this->protocol->getMessageFetchedBody($pos, "1", FT_UID);
                 //imap_fetchbody($this->_mailbox_link, $pos, "1");
                 //var_dump('getMessageBody2-end ' . (mktime() - $time));
                 // Detect encoding and decode - only base64
                 if (!empty($structure->parts[0]->encoding) && $structure->parts[0]->encoding == 4) {
                     $body = quoted_printable_decode($body);
                 } elseif (!empty($structure->parts[0]->encoding) && $structure->parts[0]->encoding == 3) {
                     $body = base64_decode($body);
                 }
                 //var_dump('bmhBodyRules ' . (mktime() - $time) . ' body length ' . strlen($body));
                 $result = bmhBodyRules($body, $structure);
                 //var_dump('bmhBodyRules-end ' . (mktime() - $time));
                 break;
             case 2:
                 // Content-type = message
                 //var_dump('getMessageBody3 ' . (mktime() - $time));
                 $body = $this->protocol->getMessageBody($pos, FT_UID);
                 //imap_body($this->_mailbox_link, $pos);
                 //var_dump('getMessageBody3-end ' . (mktime() - $time));
                 if ($structure->encoding == 4) {
                     $body = quoted_printable_decode($body);
                 } elseif ($structure->encoding == 3) {
                     $body = base64_decode($body);
                 }
                 $body = substr($body, 0, 1000);
                 //var_dump('bmhBodyRules ' . (mktime() - $time));
                 $result = bmhBodyRules($body, $structure);
                 //var_dump('bmhBodyRules-end ' . (mktime() - $time));
                 break;
             default:
                 // unsupport Content-type
                 $this->output('Msg #' . $pos . ' is unsupported Content-Type:' . $structure->type, VERBOSE_REPORT);
                 return false;
         }
     } else {
         // internal error
         $this->error_msg = 'Internal Error: unknown type';
         return false;
     }
     $email = $result['email'];
     $bounce_type = $result['bounce_type'];
     if ($this->moveHard && $result['remove'] == 1) {
         $remove = 'moved (hard)';
     } elseif ($this->disableDelete) {
         $remove = 0;
     } else {
         $remove = $result['remove'];
     }
     $rule_no = $result['rule_no'];
     $rule_cat = $result['rule_cat'];
     $xheader = false;
     if ($rule_no == '0000') {
         // internal error      return false;
         // code below will use the Callback function, but return no value
         if (trim($email) == '') {
             if (!empty($header->fromaddress)) {
                 $email = $header->fromaddress;
             }
         }
         $params = array($pos, $body, $bounce_type, $email, $subject, $xheader, $remove, $rule_no, $rule_cat, $totalFetched);
         call_user_func_array(array($this, 'callbackAction'), $params);
     } else {
         // match rule, do bounce action
         $params = array($pos, $body, $bounce_type, $email, $subject, $xheader, $remove, $rule_no, $rule_cat, $totalFetched);
         return call_user_func_array(array($this, 'callbackAction'), $params);
     }
     //var_dump('process bounce-end ' . (mktime() - $time));
     return true;
 }
Example #4
0
 /**
  * Function to process each individual message
  * @param int    $pos            (message number)
  * @param string $type           (DNS or BODY type)
  * @param string $totalFetched   (total number of messages in mailbox)
  * @return boolean
  */
 function processBounce($pos, $type, $totalFetched)
 {
     $header = imap_header($this->_mailbox_link, $pos);
     $subject = strip_tags($header->subject);
     $met = ini_get('max_execution_time');
     if ($met < 6000 && $met != 0) {
         set_time_limit(6000);
     }
     imap_timeout(IMAP_READTIMEOUT, 6000);
     imap_timeout(IMAP_WRITETIMEOUT, 6000);
     if ($type == 'DSN') {
         // first part of DSN (Delivery Status Notification), human-readable explanation
         $dsn_msg = imap_fetchbody($this->_mailbox_link, $pos, "1");
         $dsn_msg_structure = imap_bodystruct($this->_mailbox_link, $pos, "1");
         if ($dsn_msg_structure->encoding == 4) {
             $dsn_msg = quoted_printable_decode($dsn_msg);
         } elseif ($dsn_msg_structure->encoding == 3) {
             $dsn_msg = base64_decode($dsn_msg);
         }
         // second part of DSN (Delivery Status Notification), delivery-status
         $dsn_report = imap_fetchbody($this->_mailbox_link, $pos, "2");
         // process bounces by rules
         $result = bmhDSNRules($dsn_msg, $dsn_report, $this->debug_dsn_rule);
     } elseif ($type == 'BODY') {
         $structure = imap_fetchstructure($this->_mailbox_link, $pos);
         switch ($structure->type) {
             case 0:
                 // Content-type = text
             // Content-type = text
             case 1:
                 // Content-type = multipart
                 $body = imap_fetchbody($this->_mailbox_link, $pos, "1");
                 // Detect encoding and decode - only base64
                 if (!empty($structure->parts[0]->encoding) && $structure->parts[0]->encoding == 4) {
                     $body = quoted_printable_decode($body);
                 } elseif (!empty($structure->parts[0]->encoding) && $structure->parts[0]->encoding == 3) {
                     $body = base64_decode($body);
                 }
                 $result = bmhBodyRules($body, $structure, $this->debug_body_rule);
                 break;
             case 2:
                 // Content-type = message
                 $body = imap_body($this->_mailbox_link, $pos);
                 if ($structure->encoding == 4) {
                     $body = quoted_printable_decode($body);
                 } elseif ($structure->encoding == 3) {
                     $body = base64_decode($body);
                 }
                 $body = substr($body, 0, 1000);
                 $result = bmhBodyRules($body, $structure, $this->debug_body_rule);
                 break;
             default:
                 // unsupport Content-type
                 $this->output('Msg #' . $pos . ' is unsupported Content-Type:' . $structure->type, VERBOSE_REPORT);
                 return false;
         }
     } else {
         // internal error
         $this->error_msg = 'Internal Error: unknown type';
         return false;
     }
     $email = $result['email'];
     $bounce_type = $result['bounce_type'];
     if ($this->moveHard && $result['remove'] == 1) {
         $remove = 'moved (hard)';
     } elseif ($this->moveSoft && $result['remove'] == 1) {
         $remove = 'moved (soft)';
     } elseif ($this->disable_delete) {
         $remove = 0;
     } else {
         $remove = $result['remove'];
     }
     $rule_no = $result['rule_no'];
     $rule_cat = $result['rule_cat'];
     $xheader = false;
     if ($rule_no == '0000') {
         // internal error      return false;
         // code below will use the Callback function, but return no value
         if (trim($email) == '') {
             $email = $header->fromaddress;
         }
         $params = array($pos, $body, $bounce_type, $email, $subject, $xheader, $remove, $rule_no, $rule_cat, $totalFetched);
         call_user_func_array($this->action_function, $params);
     } else {
         // match rule, do bounce action
         if ($this->testmode) {
             $this->output('Match: ' . $rule_no . ':' . $rule_cat . '; ' . $bounce_type . '; ' . $email);
             return true;
         } else {
             $params = array($pos, $body, $bounce_type, $email, $subject, $xheader, $remove, $rule_no, $rule_cat, $totalFetched);
             return call_user_func_array($this->action_function, $params);
         }
     }
 }
Example #5
0
 function processBounce($pos, $type, $header = null)
 {
     if (!empty($header)) {
         $md5header = md5($header);
     } else {
         $md5header = null;
     }
     if ($type == 'DSN') {
         // first part of DSN (Delivery Status Notification), human-readable explanation
         $dsn_msg = imap_fetchbody($this->_mailbox_link, $pos, "1");
         $dsn_msg_structure = imap_bodystruct($this->_mailbox_link, $pos, "1");
         if ($dsn_msg_structure->encoding == 3) {
             $dsn_msg = base64_decode($dsn_msg);
         }
         // second part of DSN (Delivery Status Notification), delivery-status
         $dsn_report = imap_fetchbody($this->_mailbox_link, $pos, "2");
         // process bounces by rules
         $result = bmhDSNRules($dsn_msg, $dsn_report, $this->debug_dsn_rule);
     } elseif ($type == 'BODY') {
         $structure = imap_fetchstructure($this->_mailbox_link, $pos);
         switch ($structure->type) {
             case 0:
                 // Content-type = text
             // Content-type = text
             case 2:
                 // Content-type = message
                 $body = imap_body($this->_mailbox_link, $pos);
                 if ($structure->encoding == 3) {
                     $body = base64_decode($body);
                 }
                 $body = substr($body, 0, 1000);
                 $result = bmhBodyRules($body, $structure, $this->debug_body_rule);
                 break;
             case 1:
                 // Content-type = multipart
                 $body = imap_fetchbody($this->_mailbox_link, $pos, "1");
                 // TRICKY : detect encoding and decode
                 // only handle base64 right now
                 if ($structure->parts[0]->encoding == 3) {
                     $body = base64_decode($body);
                 }
                 $body = substr($body, 0, 1000);
                 $result = bmhBodyRules($body, $structure, $this->debug_body_rule);
                 break;
             default:
                 // unsupport Content-type
                 $this->output("The No. {$pos} is unsupport Content-Type:{$structure->type}", VERBOSE_REPORT);
                 return false;
         }
     } else {
         // internal error
         $this->error_msg = 'Internal Error: unknown type';
         return false;
     }
     $result['rule_type'] = $type;
     if (!empty($header)) {
         if (preg_match("/Subject:((?:[^\n]|\n[\t ])+)(?:\n[^\t ]|\$)/is", $header, $match)) {
             $result['subject'] = trim($match[1]);
         }
         if (preg_match("/Date:[\t ]*(.*)/i", $header, $match)) {
             $result['date'] = trim($match[1]);
         }
         if (preg_match("/From:((?:[^\n]|\n[\t ])+)(?:\n[^\t ]|\$)/is", $header, $match)) {
             $addresses = imap_rfc822_parse_adrlist($match[1], '???');
             if (!empty($addresses) && is_array($addresses)) {
                 $result['from'] = $addresses[0]->mailbox . '@' . $addresses[0]->host;
             }
         }
     }
     // last chance for unmatched rules
     if ($result['rule_no'] == '0000') {
         $result = bmhOtherRules($result);
     }
     $result['md5header'] = $md5header;
     // log the result if wanted
     if (!empty($this->log_function) && function_exists($this->log_function)) {
         call_user_func($this->log_function, $result);
         $this->c_log++;
     }
     // call user function for unmatched rules
     if ($result['rule_no'] == '0000') {
         if (!empty($this->unmatched_function) && function_exists($this->unmatched_function)) {
             return call_user_func($this->unmatched_function, $result);
         }
         return false;
     }
     if ($this->testmode) {
         $this->output(print_r($result, true));
         return false;
     }
     // match a rule, take bounce action
     if (!empty($this->action_function) && function_exists($this->action_function)) {
         return call_user_func($this->action_function, $result);
     }
     return true;
 }