Changeset 2115371
- Timestamp:
- 07/01/2019 11:23:14 AM (7 years ago)
- Location:
- bounce-handler-mailpoet
- Files:
-
- 4 edited
- 8 copied
-
tags/1.3.15 (copied) (copied from bounce-handler-mailpoet/trunk)
-
tags/1.3.15/bounce-handler-mailpoet.php (copied) (copied from bounce-handler-mailpoet/trunk/bounce-handler-mailpoet.php)
-
tags/1.3.15/changelog.txt (copied) (copied from bounce-handler-mailpoet/trunk/changelog.txt)
-
tags/1.3.15/includes/class-mailpoet-bounce-detect.php (copied) (copied from bounce-handler-mailpoet/trunk/includes/class-mailpoet-bounce-detect.php)
-
tags/1.3.15/includes/class-mailpoet-bounce-handler.php (copied) (copied from bounce-handler-mailpoet/trunk/includes/class-mailpoet-bounce-handler.php)
-
tags/1.3.15/languages/bounce-handler-mailpoet-da_DK.mo (copied) (copied from bounce-handler-mailpoet/trunk/languages/bounce-handler-mailpoet-da_DK.mo)
-
tags/1.3.15/languages/bounce-handler-mailpoet-da_DK.po (copied) (copied from bounce-handler-mailpoet/trunk/languages/bounce-handler-mailpoet-da_DK.po)
-
tags/1.3.15/readme.txt (copied) (copied from bounce-handler-mailpoet/trunk/readme.txt)
-
trunk/bounce-handler-mailpoet.php (modified) (1 diff)
-
trunk/changelog.txt (modified) (1 diff)
-
trunk/includes/class-mailpoet-bounce-detect.php (modified) (24 diffs)
-
trunk/readme.txt (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
bounce-handler-mailpoet/trunk/bounce-handler-mailpoet.php
r2113611 r2115371 6 6 * Plugin Name: Bounce Handler Mailpoet 7 7 * Description: Bounce Handler Mailpoet is an add-on for MailPoet 3 to handle bounce emails easily, when using your own SMTP server. 8 * Version: 1.3.1 58 * Version: 1.3.16 9 9 * Author: Tikweb 10 10 * Author URI: http://www.tikweb.dk/ -
bounce-handler-mailpoet/trunk/changelog.txt
r2113611 r2115371 1 1 == Changelog == 2 3 = 1.3.16 - 2019-07-01 = 4 * Supports yahoo bounce 2 5 3 6 = 1.3.15 - 2019-06-27 = 4 7 * Added: Message expired bounce emails will now consider as mailbox not available 8 * Removed: weird_forward control 5 9 6 10 = 1.3.14 - 2019-06-25 = -
bounce-handler-mailpoet/trunk/includes/class-mailpoet-bounce-detect.php
r2113611 r2115371 16 16 public $detectEmail = '/[a-z0-9!#$%&\'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&\'*+\/=?^_`{|}~-]+)*@([a-z0-9\-]+\.)+[a-z0-9]{2,8}/i'; 17 17 public $rules = [ 18 'status' => 'Status:(\s?\d\.\d\.\d)',19 'action' => 'Action:\s*?(.+)$',20 'rcpt' => '\w*-Recipient:\s*?rfc\d*\;\s*?(.+)$'21 ];18 'status' => 'Status:(\s?\d\.\d\.\d)', 19 'action' => 'Action:\s*?(.+)$', 20 'rcpt' => '\w*-Recipient:\s*?rfc\d*\;\s*?(.+)$' 21 ]; 22 22 23 23 /** … … 35 35 */ 36 36 public function decodeHeader($input) { 37 // Remove white space between encoded-words38 $input = preg_replace('/(=\?[^?]+\?(q|b)\?[^?]*\?=)(\s)+=\?/i', '\1=?', $input);39 $this->charset = false;40 41 // For each encoded-word...42 while (preg_match('/(=\?([^?]+)\?(q|b)\?([^?]*)\?=)/i', $input, $matches)) {43 44 $encoded = $matches[1];45 $charset = $matches[2];46 $encoding = $matches[3];47 $text = $matches[4];48 49 switch (strtolower($encoding)) {50 case 'b':51 $text = base64_decode($text);52 break;53 54 case 'q':55 $text = str_replace('_', ' ', $text);56 preg_match_all('/=([a-f0-9]{2})/i', $text, $matches);57 foreach ($matches[1] as $value)58 $text = str_replace('=' . $value, chr(hexdec($value)), $text);59 break;60 }61 $this->charset = $charset;62 $input = str_replace($encoded, $text, $input);63 }64 65 return $input;66 }67 68 /**69 * imap connect, if error than return false and exit.70 * @return void 71 */37 // Remove white space between encoded-words 38 $input = preg_replace('/(=\?[^?]+\?(q|b)\?[^?]*\?=)(\s)+=\?/i', '\1=?', $input); 39 $this->charset = false; 40 41 // For each encoded-word... 42 while (preg_match('/(=\?([^?]+)\?(q|b)\?([^?]*)\?=)/i', $input, $matches)) { 43 44 $encoded = $matches[1]; 45 $charset = $matches[2]; 46 $encoding = $matches[3]; 47 $text = $matches[4]; 48 49 switch (strtolower($encoding)) { 50 case 'b': 51 $text = base64_decode($text); 52 break; 53 54 case 'q': 55 $text = str_replace('_', ' ', $text); 56 preg_match_all('/=([a-f0-9]{2})/i', $text, $matches); 57 foreach ($matches[1] as $value) 58 $text = str_replace('=' . $value, chr(hexdec($value)), $text); 59 break; 60 } 61 $this->charset = $charset; 62 $input = str_replace($encoded, $text, $input); 63 } 64 65 return $input; 66 } 67 68 /** 69 * imap connect, if error than return false and exit. 70 * @return void 71 */ 72 72 public function connect(){ 73 73 74 74 imap_timeout(IMAP_OPENTIMEOUT,120); 75 75 $this->mailbox = imap_open($this->servername, $this->settings->login, mbh_encrypt_decrypt('decrypt',$this->settings->password)); … … 115 115 $mail = $this->getBouncedEmail($body,$parsed_header); 116 116 $this->procMail = imap_fetchheader($this->mailbox,$email,0)."\n\n- - -\n\n".$body; 117 117 118 118 // logger 119 119 MBH_Logger::insert(array( … … 121 121 'reason' => @$reason['action'], 122 122 'last_checked' => MBH_Logger::now() 123 ));123 )); 124 124 125 125 // browser output stream … … 144 144 $resp .= "</body>"; 145 145 $resp .= "</html>"; 146 146 147 147 // if request from cron than don't need to echo output. 148 148 if ( !$this->croned ){ … … 150 150 echo ob_get_clean(); 151 151 } 152 153 flush(); 152 153 flush(); 154 154 155 155 } … … 181 181 $rules = $this->getRules(); 182 182 $ret = ['msg'=>null,'action'=>null]; 183 183 184 184 foreach ($rules as $key => $value) { 185 185 if ( preg_match('/'.$value['regex'].'/i',$msg,$result)){ … … 190 190 $ret['action'] = $value['key']; 191 191 } 192 192 193 193 return $ret; 194 194 } 195 195 } 196 196 197 197 198 198 } 199 199 … … 201 201 * list ignore email like sender , to address 202 202 * @param object $header imap header object 203 * @return array 203 * @return array 204 204 */ 205 205 public function getIgnoreEmail($header){ … … 222 222 223 223 /** 224 * Get Bounced email by listing all emails, if no emails found than 224 * Get Bounced email by listing all emails, if no emails found than 225 225 * return `to` email. 226 226 * @param string $html mail body … … 229 229 */ 230 230 public function getBouncedEmailBySearch($html,$ignore_emails){ 231 231 232 232 preg_match_all($this->detectEmail, $html, $result); 233 233 234 234 if ( !isset($result[0]) ){ 235 235 return null; … … 284 284 285 285 /** 286 * Set configuration 286 * Set configuration 287 287 */ 288 288 public function getEssential(){ 289 289 290 290 $this->getSettings(); 291 291 if ( empty($this->settings->login) || empty($this->settings->password) ) { … … 296 296 // has port 297 297 if( empty($this->settings->port) ){ 298 if ($this->settings->secure_connection && $this->settings->connection_method == 'imap')299 $this->settings->port = '993';300 elseif ($this->settings->connection_method == 'imap')301 $this->settings->port = '143';302 elseif ($this->settings->connection_method == 'pop3')303 $this->settings->port = '110';304 }305 306 // make server name307 308 $this->servername = '{'.$this->settings->hostname;309 $this->servername .= ':'.$this->settings->port;310 $this->servername .= '/'.$this->settings->connection_method;311 if ( $this->settings->secure_connection ){312 $this->servername .= '/ssl';313 }314 315 if ( $this->settings->self_signed_certificates == '0' ) {316 $this->servername .= '/novalidate-cert';317 }318 319 $this->servername .= '}';298 if ($this->settings->secure_connection && $this->settings->connection_method == 'imap') 299 $this->settings->port = '993'; 300 elseif ($this->settings->connection_method == 'imap') 301 $this->settings->port = '143'; 302 elseif ($this->settings->connection_method == 'pop3') 303 $this->settings->port = '110'; 304 } 305 306 // make server name 307 308 $this->servername = '{'.$this->settings->hostname; 309 $this->servername .= ':'.$this->settings->port; 310 $this->servername .= '/'.$this->settings->connection_method; 311 if ( $this->settings->secure_connection ){ 312 $this->servername .= '/ssl'; 313 } 314 315 if ( $this->settings->self_signed_certificates == '0' ) { 316 $this->servername .= '/novalidate-cert'; 317 } 318 319 $this->servername .= '}'; 320 320 321 321 … … 333 333 334 334 if ( !$subs ){ 335 335 336 336 $msgAct .= ' '.__("$email is not subscriber, ", 'bounce-handler-mailpoet').' '; 337 337 338 if ( 338 if ( 339 339 isset($this->settings->{$act}->cond) && 340 340 $this->settings->{$act}->cond == 'mna_addOrRemove' && … … 364 364 break; 365 365 366 367 368 366 case 'weird_forward': 369 $setting = get_option('mbh_bounce_config'); 370 if ('forward_email' === $setting['wfa_cond']) { 371 $action = 'weird_forward'; 372 $forward_mail = $this->settings->{$act}; 373 } else { 374 $action = $this->settings->{$act}; 375 } 376 break; 377 367 $action = 'weird_forward'; 368 $forward_mail = $this->settings->{$act}; 369 break; 378 370 379 371 case 'mailbox_full': … … 388 380 $action = $this->settings->{$act}; 389 381 break; 390 382 391 383 default: 392 384 $action = "do_nothing"; … … 445 437 $msgAct .= " ".__('no action done as per settings!','bounce-handler-mailpoet')." "; 446 438 break; 447 439 448 440 default: 449 441 450 442 if ( is_array($action) && !empty($action) ){ 451 443 452 444 foreach ($action as $key => $value) { 453 445 454 446 if ( $key == 'cond' && $value == 'unsub' ){ 455 447 $subs->status = Subscriber::STATUS_UNSUBSCRIBED; … … 504 496 } 505 497 } 506 498 507 499 break; 508 500 } … … 569 561 */ 570 562 public function unsubscribe($obj){ 571 563 572 564 if ( !$obj ){ 573 565 return false; … … 576 568 $obj->status = Subscriber::STATUS_UNSUBSCRIBED; 577 569 $obj->save(); 578 570 579 571 } 580 572 … … 601 593 */ 602 594 public function removeSubscriber($obj){ 603 595 604 596 if ( !$obj ){ 605 597 return false; 606 598 } 607 599 608 600 $obj->status = Subscriber::STATUS_UNSUBSCRIBED; 609 601 SubscriberSegment::unsubscribeFromSegments($obj,[]); … … 633 625 case 'weird_forward': 634 626 $subject = __("[MailPoet] Mail didn't detect as bounced. " ,'bounce-handler-mailpoet'); 635 627 636 628 default: 637 629 # code... … … 641 633 642 634 $to = sprintf( 643 '%s <%s>',644 $email,645 646 );635 '%s <%s>', 636 $email, 637 $email 638 ); 647 639 $content = array( 648 'subject' => $subject,649 'body' => array(650 'html' => $this->procMail,651 'text' => $this->procMail652 )653 );640 'subject' => $subject, 641 'body' => array( 642 'html' => $this->procMail, 643 'text' => $this->procMail 644 ) 645 ); 654 646 $mlr = new Mailer(); 655 647 $mlr->send($content,$to); … … 664 656 public function getRules(){ 665 657 $arr = [ 666 [667 "key" => "mailbox_full",668 "name" => __('Mailbox Full', 'bounce-handler-mailpoet'),669 "title" => __('When mailbox is full', 'bounce-handler-mailpoet'),670 "regex" => '((mailbox|mailfolder|storage|quota|space) *(is)? *(over)? *(exceeded|size|storage|allocation|full|quota|maxi))|((over|exceeded|full) *(mail|storage|quota))'671 ],672 [673 "key" => "mailbox_not_available",674 "name" => __('Mailbox not available', 'bounce-handler-mailpoet'),675 "title" => __('When mailbox is not available', 'bounce-handler-mailpoet'),676 "regex" => 'expired|(Invalid|no such|unknown|bad|des?activated|undelivered|inactive|unrouteable|delivery|mail ID|failed to|may not|no known user|email account) *(mail|destination|recipient|user|address|person|failure|has failed|does not exist|deliver to|exist|with this email|is closed)|RecipNotFound|status(-code)? *(:|=)? *5\.(1\.[1-6]|0\.0|4\.[0123467])|(user|mailbox|address|recipients?|host|account|domain) *(is|has been)? *(error|disabled|failed|unknown|unavailable|not *(found|available)|.{1,30}inactiv)|recipient *address *rejected|does *not *like *recipient|no *mailbox *here|user does.?n.t have.{0,20}account'677 ],678 [679 "key" => "message_delayed",680 "name" => __('Message delayed', 'bounce-handler-mailpoet'),681 "title" => __('When message is delayed', 'bounce-handler-mailpoet'),682 "regex" => 'possible *mail *loop|too *many *hops|Action: *delayed|has.*been.*delayed|delayed *mail|temporary *failure'683 ],684 [685 "key" => "failed_permanent",686 "name" => __('Failed Permanently', 'bounce-handler-mailpoet'),687 "title" => __('When failed permanently', 'bounce-handler-mailpoet'),688 "regex" => 'failed *permanently|permanent *(fatal)? *(failure|error)|Unrouteable *address|not *accepting *(any)? *mail'689 ],690 [691 "key" => "action_required",692 "name" => __('Action Required', 'bounce-handler-mailpoet'),693 "title" => __('When you need to confirm you\'re a human being, forward to:', 'bounce-handler-mailpoet') ,694 "regex" => 'action *required|verif'695 ],696 [697 "key" => "blocked_ip",698 "name" => __('Blocked IP', 'bounce-handler-mailpoet'),699 "title" => __('When you are flagged as a spammer forward the bounced message to', 'bounce-handler-mailpoet'),700 "regex" => 'is *(currently)? *blocked *by|block *list|spam *detected|(unacceptable|banned|offensive|filtered|blocked) *(content|message|e-?mail)|administratively *denied'701 ],702 [703 "key" => "nohandle",704 "name" => __('Final Rule', 'bounce-handler-mailpoet'),705 "title" => __('When the bounce is weird and we\'re not sure what to do, forward to:','bounce-handler-mailpoet'),706 "regex" => '.'707 ]708 ];709 710 return $arr;658 [ 659 "key" => "mailbox_full", 660 "name" => __('Mailbox Full', 'bounce-handler-mailpoet'), 661 "title" => __('When mailbox is full', 'bounce-handler-mailpoet'), 662 "regex" => '((mailbox|mailfolder|storage|quota|space) *(is)? *(over)? *(exceeded|size|storage|allocation|full|quota|maxi))|((over|exceeded|full) *(mail|storage|quota))' 663 ], 664 [ 665 "key" => "mailbox_not_available", 666 "name" => __('Mailbox not available', 'bounce-handler-mailpoet'), 667 "title" => __('When mailbox is not available', 'bounce-handler-mailpoet'), 668 "regex" => 'dd Requested|expired|(Invalid|no such|unknown|bad|des?activated|undelivered|inactive|unrouteable|delivery|mail ID|failed to|may not|no known user|email account) *(mail|destination|recipient|user|address|person|failure|has failed|does not exist|deliver to|exist|with this email|is closed)|RecipNotFound|status(-code)? *(:|=)? *5\.(1\.[1-6]|0\.0|4\.[0123467])|(user|mailbox|address|recipients?|host|account|domain) *(is|has been)? *(error|disabled|failed|unknown|unavailable|not *(found|available)|.{1,30}inactiv)|recipient *address *rejected|does *not *like *recipient|no *mailbox *here|user does.?n.t have.{0,20}account' 669 ], 670 [ 671 "key" => "message_delayed", 672 "name" => __('Message delayed', 'bounce-handler-mailpoet'), 673 "title" => __('When message is delayed', 'bounce-handler-mailpoet'), 674 "regex" => 'possible *mail *loop|too *many *hops|Action: *delayed|has.*been.*delayed|delayed *mail|temporary *failure' 675 ], 676 [ 677 "key" => "failed_permanent", 678 "name" => __('Failed Permanently', 'bounce-handler-mailpoet'), 679 "title" => __('When failed permanently', 'bounce-handler-mailpoet'), 680 "regex" => 'failed *permanently|permanent *(fatal)? *(failure|error)|Unrouteable *address|not *accepting *(any)? *mail' 681 ], 682 [ 683 "key" => "action_required", 684 "name" => __('Action Required', 'bounce-handler-mailpoet'), 685 "title" => __('When you need to confirm you\'re a human being, forward to:', 'bounce-handler-mailpoet') , 686 "regex" => 'action *required|verif' 687 ], 688 [ 689 "key" => "blocked_ip", 690 "name" => __('Blocked IP', 'bounce-handler-mailpoet'), 691 "title" => __('When you are flagged as a spammer forward the bounced message to', 'bounce-handler-mailpoet'), 692 "regex" => 'is *(currently)? *blocked *by|block *list|spam *detected|(unacceptable|banned|offensive|filtered|blocked) *(content|message|e-?mail)|administratively *denied' 693 ], 694 [ 695 "key" => "nohandle", 696 "name" => __('Final Rule', 'bounce-handler-mailpoet'), 697 "title" => __('When the bounce is weird and we\'re not sure what to do, forward to:','bounce-handler-mailpoet'), 698 "regex" => '.' 699 ] 700 ]; 701 702 return $arr; 711 703 } 712 704 -
bounce-handler-mailpoet/trunk/readme.txt
r2113611 r2115371 6 6 Tested up to: 5.2.2 7 7 Requires PHP: 5.6.0 8 Stable tag: 1.3.1 58 Stable tag: 1.3.16 9 9 10 10 Automatic mail bounce handling for MailPoet 3 to handle bounce emails easily when using your own SMTP server.
Note: See TracChangeset
for help on using the changeset viewer.