Plugin Directory

Changeset 2115371


Ignore:
Timestamp:
07/01/2019 11:23:14 AM (7 years ago)
Author:
ehsantikweb
Message:

Supports yahoo bounce and tagging 1.2.15

Location:
bounce-handler-mailpoet
Files:
4 edited
8 copied

Legend:

Unmodified
Added
Removed
  • bounce-handler-mailpoet/trunk/bounce-handler-mailpoet.php

    r2113611 r2115371  
    66 * Plugin Name:       Bounce Handler Mailpoet
    77 * 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.15
     8 * Version:           1.3.16
    99 * Author:            Tikweb
    1010 * Author URI:        http://www.tikweb.dk/
  • bounce-handler-mailpoet/trunk/changelog.txt

    r2113611 r2115371  
    11== Changelog ==
     2
     3= 1.3.16 - 2019-07-01 =
     4* Supports yahoo bounce
    25
    36= 1.3.15 - 2019-06-27 =
    47* Added: Message expired bounce emails will now consider as mailbox not available
     8* Removed: weird_forward control
    59
    610= 1.3.14 - 2019-06-25 =
  • bounce-handler-mailpoet/trunk/includes/class-mailpoet-bounce-detect.php

    r2113611 r2115371  
    1616    public $detectEmail = '/[a-z0-9!#$%&\'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&\'*+\/=?^_`{|}~-]+)*@([a-z0-9\-]+\.)+[a-z0-9]{2,8}/i';
    1717    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    ];
    2222
    2323    /**
     
    3535     */
    3636    public function decodeHeader($input) {
    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     */
     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    */
    7272    public function connect(){
    73        
     73
    7474        imap_timeout(IMAP_OPENTIMEOUT,120);
    7575        $this->mailbox = imap_open($this->servername, $this->settings->login, mbh_encrypt_decrypt('decrypt',$this->settings->password));
     
    115115            $mail = $this->getBouncedEmail($body,$parsed_header);
    116116            $this->procMail = imap_fetchheader($this->mailbox,$email,0)."\n\n- - -\n\n".$body;
    117            
     117
    118118            // logger
    119119            MBH_Logger::insert(array(
     
    121121                'reason' => @$reason['action'],
    122122                'last_checked' => MBH_Logger::now()
    123                 ));
     123            ));
    124124
    125125            // browser output stream
     
    144144            $resp .= "</body>";
    145145            $resp .= "</html>";
    146            
     146
    147147            // if request from cron than don't need to echo output.
    148148            if ( !$this->croned ){
     
    150150                echo ob_get_clean();
    151151            }
    152            
    153             flush();   
     152
     153            flush();
    154154
    155155        }
     
    181181        $rules = $this->getRules();
    182182        $ret = ['msg'=>null,'action'=>null];
    183        
     183
    184184        foreach ($rules as $key => $value) {
    185185            if ( preg_match('/'.$value['regex'].'/i',$msg,$result)){
     
    190190                    $ret['action'] = $value['key'];
    191191                }
    192                
     192
    193193                return $ret;
    194194            }
    195195        }
    196196
    197        
     197
    198198    }
    199199
     
    201201     * list ignore email like sender , to address
    202202     * @param  object $header imap header object
    203      * @return array         
     203     * @return array
    204204     */
    205205    public function getIgnoreEmail($header){
     
    222222
    223223    /**
    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
    225225     * return `to` email.
    226226     * @param  string $html          mail body
     
    229229     */
    230230    public function getBouncedEmailBySearch($html,$ignore_emails){
    231        
     231
    232232        preg_match_all($this->detectEmail, $html, $result);
    233        
     233
    234234        if ( !isset($result[0]) ){
    235235            return null;
     
    284284
    285285    /**
    286      * Set configuration 
     286     * Set configuration
    287287     */
    288288    public function getEssential(){
    289        
     289
    290290        $this->getSettings();
    291291        if ( empty($this->settings->login) || empty($this->settings->password) ) {
     
    296296        // has port
    297297        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 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 .= '}';
     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 .= '}';
    320320
    321321
     
    333333
    334334        if ( !$subs ){
    335            
     335
    336336            $msgAct .= ' '.__("$email is not subscriber, ", 'bounce-handler-mailpoet').' ';
    337337
    338             if ( 
     338            if (
    339339                isset($this->settings->{$act}->cond) &&
    340340                $this->settings->{$act}->cond == 'mna_addOrRemove' &&
     
    364364                break;
    365365
    366 
    367 
    368366            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;
    378370
    379371            case 'mailbox_full':
     
    388380                $action = $this->settings->{$act};
    389381                break;
    390            
     382
    391383            default:
    392384                $action = "do_nothing";
     
    445437                $msgAct .= " ".__('no action done as per settings!','bounce-handler-mailpoet')." ";
    446438                break;
    447            
     439
    448440            default:
    449                
     441
    450442                if ( is_array($action) && !empty($action) ){
    451                    
     443
    452444                    foreach ($action as $key => $value) {
    453                        
     445
    454446                        if ( $key == 'cond' && $value == 'unsub' ){
    455447                            $subs->status = Subscriber::STATUS_UNSUBSCRIBED;
     
    504496                    }
    505497                }
    506                
     498
    507499                break;
    508500        }
     
    569561     */
    570562    public function unsubscribe($obj){
    571        
     563
    572564        if ( !$obj ){
    573565            return false;
     
    576568        $obj->status = Subscriber::STATUS_UNSUBSCRIBED;
    577569        $obj->save();
    578        
     570
    579571    }
    580572
     
    601593     */
    602594    public function removeSubscriber($obj){
    603        
     595
    604596        if ( !$obj ){
    605597            return false;
    606598        }
    607        
     599
    608600        $obj->status = Subscriber::STATUS_UNSUBSCRIBED;
    609601        SubscriberSegment::unsubscribeFromSegments($obj,[]);
     
    633625            case 'weird_forward':
    634626                $subject = __("[MailPoet] Mail didn't detect as bounced. " ,'bounce-handler-mailpoet');
    635            
     627
    636628            default:
    637629                # code...
     
    641633
    642634        $to = sprintf(
    643                   '%s <%s>',
    644                   $email,
    645                   $email
    646                 );
     635            '%s <%s>',
     636            $email,
     637            $email
     638        );
    647639        $content = array(
    648                   'subject' => $subject,
    649                   'body' => array(
    650                     'html' => $this->procMail,
    651                     'text' => $this->procMail
    652                   )
    653                 );
     640            'subject' => $subject,
     641            'body' => array(
     642                'html' => $this->procMail,
     643                'text' => $this->procMail
     644            )
     645        );
    654646        $mlr = new Mailer();
    655647        $mlr->send($content,$to);
     
    664656    public function getRules(){
    665657        $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;
    711703    }
    712704
  • bounce-handler-mailpoet/trunk/readme.txt

    r2113611 r2115371  
    66Tested up to: 5.2.2
    77Requires PHP: 5.6.0
    8 Stable tag: 1.3.15
     8Stable tag: 1.3.16
    99
    1010Automatic 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.