[ Index ]

MailPress 7.2

[ Index ]     [ Classes ]     [ Functions ]     [ Variables ]     [ Constants ]     [ Statistics ]    

title

Body

[close]

/mp-content/add-ons/ -> MailPress_list_unsubscribe.php (source)

   1  <?php
   2  if ( class_exists( 'MailPress' ) && !class_exists( 'MailPress_list_unsubscribe' ) )
   3  {
   4  /*
   5  Plugin Name: MailPress_list_unsubscribe
   6  Plugin URI: http://blog.mailpress.org
   7  Description: Users : Implements List-Unsubscribe headers and other stuff to make it work (the best of <a href="https://tools.ietf.org/html/rfc2369" target="_blank">rfc2369</a> & <a href="https://tools.ietf.org/html/rfc8058" target="_blank">rfc8058</a>) 
   8  Version: 7.2
   9  */
  10  
  11  class MailPress_list_unsubscribe
  12  {
  13      const meta_key         = '_MailPress_list_unsubscribe';
  14      const option_name     = 'MailPress_list_unsubscribe';
  15      const log_name         = 'list_unsubscribe';
  16  
  17      const process_name    = 'mp_process_list_unsubscribe';
  18  
  19      const bt = 132;
  20  
  21  
  22      const key_word        = 'liun';
  23  
  24  
  25      const actions = array (
  26          'a'     => 'delete subscriber',
  27          'b'     => 'unsubscribe from all lists',
  28          'c'     => 'unsubscribe from sending list',
  29      ); 
  30  
  31      const mailto_sc = array(
  32          '%' => '%25',
  33  
  34          ' ' => '%20', '!' => '%21', '"' => '%22', '#' => '%23',    '$' => '%24', '&' => '%26', "'" => '%27', '(' => '%28', ')' => '%29', '*' => '%2A', '+' => '%2B', ',' => '%2C', '-' => '%2D', '/' => '%2F',
  35          ':' => '%3A', ';' => '%3B', '<' => '%3C', '=' => '%3D', '>' => '%3E', '?' => '%3F',
  36          '@' => '%40',
  37          '[' => '%5B', '\\' => '%5C',']' => '%5D', '^' => '%5E', '_' => '%5F', 
  38          '`' => '%60',
  39          '{' => '%7B', '|' => '%7C', '}' => '%7D', '~' => '%7E',
  40      );
  41  
  42  	function __construct()
  43      {
  44  // prepare mail
  45          add_filter( 'MailPress_swift_message_headers',                array( __CLASS__, 'swift_message_headers' ), 10, 2 );
  46  
  47  // for batch mode
  48          add_action( self::process_name,                        array( __CLASS__, 'process' ) );
  49  
  50          $config = get_option( self::option_name );
  51          if ( 'wpcron' == $config['batch_mode'] )
  52          {    
  53              add_action( 'MailPress_schedule_list_unsubscribe',        array( __CLASS__, 'schedule' ) );
  54          }
  55  
  56          if ( is_admin() )
  57          {
  58          // for install
  59              register_activation_hook( plugin_basename( __FILE__ ),        array( __CLASS__, 'install' ) );
  60              register_deactivation_hook( plugin_basename( __FILE__ ),    array( __CLASS__, 'uninstall' ) );
  61          // for link on plugin page
  62              add_filter( 'plugin_action_links',                array( __CLASS__, 'plugin_action_links' ), 10, 2 );
  63  
  64          // for settings
  65              add_filter( 'MailPress_settings_tab',                 array( __CLASS__, 'settings_tab' ), 50, 1 );
  66          // for settings logs
  67              add_action( 'MailPress_settings_logs_form',            array( __CLASS__, 'settings_logs_form' ), 30, 1 );
  68          }
  69  
  70  // for ajax and more
  71          if ( isset( $_POST['List-Unsubscribe'] ) && ( $_POST['List-Unsubscribe'] == 'One-Click' ) )
  72              add_action( 'init',        array( __CLASS__, 'mail_link' ), 200 );
  73          add_action( 'wp_ajax_mp_hlinks',    array( __CLASS__, 'mail_link' ) );
  74          add_action( 'wp_ajax_nopriv_mp_hlinks',    array( __CLASS__, 'mail_link' ) );
  75      }
  76  
  77  // prepare mail
  78  	public static function swift_message_headers( $message, $row )
  79      {
  80          if ( $row->template == 'new_subscriber' ) return $message;
  81  
  82          $config = get_option( self::option_name );
  83  
  84          if ( !$config ) return $message;
  85  
  86          $has_dkim  = ( class_exists( 'Mailpress_signer_dkim' ) );
  87          $has_email = MailPress::is_email( $config['pop3']['username'] );
  88  
  89          $list_unsubscribe = array();
  90  
  91          $confkey   = $row->confkey   ?? '{{_confkey}}';
  92          $list_id   = $row->list_id   ?? '{{_list_id}}';
  93  
  94          if ( $has_dkim )
  95          {
  96              $list_unsubscribe[] = array( 
  97                      'type'  => 'url',
  98                      'url'     => admin_url( 'admin-ajax.php' ),
  99                      'args'     => array(
 100                          'action'     => 'mp_hlinks',
 101                          self::key_word     => $confkey,
 102                          'mid'         => $row->id,
 103                          'id'         => $list_id,
 104                      ),
 105              );
 106          }
 107  
 108          if ( $has_email )
 109          {
 110              $list_unsubscribe[] = array(
 111                      'type'  => 'mailto',
 112                      'mailto'=> $config['pop3']['username'],
 113                      'args'     => array(
 114                          'subject'     => self::key_word . '.' . $row->id . '.' . $confkey . '.' . $list_id,
 115                      ),
 116              );
 117          }
 118  // headers
 119          if ( !empty( $list_unsubscribe ) )
 120          {
 121              $_headers = $message->getHeaders();
 122  
 123              $header = self::get_header( $list_unsubscribe );
 124              $_headers->addTextHeader( 'List-Unsubscribe', $header );
 125  
 126              if ( $has_dkim )
 127              {
 128                  $_headers->addTextHeader( 'List-Unsubscribe-Post', 'List-Unsubscribe=One-Click' );
 129              }
 130          }
 131  
 132          return $message;
 133      }
 134  
 135   	public static function get_header( $list_unsubscribe )
 136       {
 137          $header = '';
 138  
 139          foreach( $list_unsubscribe as $v )
 140          {
 141              if ( !empty( $header ) ) $header .= ',';
 142  
 143              switch( $v['type'] )
 144              {
 145                  case 'url' :
 146                      $header .= '<' . self::get_url( $v ) . '>';
 147                  break;
 148                  case 'mailto' :
 149                      $header .= '<mailto:' . self::get_mailto( $v ) . '>';
 150                  break;
 151              }
 152          }
 153  
 154          return $header;
 155       }
 156  
 157   	public static function get_url( $url )
 158       {
 159          return add_query_arg( $url['args'], $url['url'] );
 160       }
 161  
 162  	public static function get_mailto( $mailto )
 163      {
 164          $args = '';
 165  
 166          foreach( $mailto['args'] as $h => $v )
 167          {
 168              if ( !empty( $args ) ) $args .= '&';
 169              
 170              $args .= $h . '=' . $v;
 171          }
 172          
 173          return self::mailto( $mailto['mailto'] ) . '?' . $args;
 174      }
 175  
 176   	public static function mailto( $email )
 177      {
 178          $parts = explode( '@', $email );
 179  
 180          $domain_part = array_pop( $parts );
 181          $local_part  = implode( '@', $parts );
 182  
 183          /*** Refer to RFC 6068 STD66 ***/
 184          /*** https://tools.ietf.org/html/rfc6068#ref-STD66 ***/
 185  
 186          $local_part = str_replace( array_keys( self::mailto_sc ),  array_values( self::mailto_sc ), $local_part );
 187  
 188          return $local_part . '@' . $domain_part;
 189      }
 190  
 191  // links in mail
 192  	public static function mail_link()
 193      {
 194          $config = get_option( self::option_name );
 195          if ( !$config ) die();
 196  
 197          foreach( array( 'get_' => INPUT_GET, 'pst_' => INPUT_POST, 'srv_' => INPUT_SERVER ) as $k => $v )
 198          {
 199              $$k = filter_input_array( $v );
 200              if ( is_null( $$k ) ) $$k = array();
 201          }
 202  
 203          if ( empty( $pst_ ) ) 
 204          {
 205              $url = ( isset( $get_[self::key_word] ) ) ? MP_User::get_unsubscribe_url( $get_[self::key_word] ) : site_url();
 206              MP_::mp_redirect( $url );
 207              die();
 208          }
 209  
 210          if ( !isset( $pst_['List-Unsubscribe'] ) )         die();
 211          if ( $pst_['List-Unsubscribe'] != 'One-Click' )     die();
 212  
 213          $url_components = parse_url( $srv_['REQUEST_URI'] );
 214          parse_str( $url_components['query'], $args );
 215  
 216          $mail_id = $args['mid']          ?? false;
 217          $confkey = $args[self::key_word] ?? false;
 218          $list_id = $args['id']           ?? false;
 219  
 220          if ( !( $mail_id && $confkey && $list_id ) ) die();
 221  
 222          $mp_user_id = MP_User::get_id( $confkey );
 223          if ( !$mp_user_id ) die();
 224  
 225          $mp_user = MP_User::get( $mp_user_id );
 226          if ( !$mp_user ) die();
 227  
 228          $trace = new MP_Log( 'mp_process_list_unsubscribe_post', array( 'option_name' => 'list_unsubscribe' ) );
 229  
 230          $trace->log( '!' . str_repeat( '-', self::bt ) . '!' );
 231          $bm = sprintf( 'List-Unsubscribe-Post Report ( Processing mode : %1$s )', self::actions[$config['mode']] );
 232          $trace->log( '!' . str_repeat( ' ', 5 ) . $bm . str_repeat( ' ', self::bt - 5 - strlen( $bm ) ) . '!' );
 233  
 234          $trace->log( '!' . str_repeat( '-', self::bt ) . '!' );
 235  
 236          $bm = ' email      ! ' . $mp_user->email . ' ( ' . $mp_user->name . ' ) ';
 237          $trace->log( '!' . $bm . str_repeat( ' ', self::bt - strlen( $bm ) ) . '!' );
 238  
 239          $bm = ' list_id    ! ' . $list_id;
 240          $trace->log( '!' . $bm . str_repeat( ' ', self::bt - strlen( $bm ) ) . '!' );
 241  
 242          $bm = ' mail_id    ! ' . $mail_id;
 243          $trace->log( '!' . $bm . str_repeat( ' ', self::bt - strlen( $bm ) ) . '!' );
 244  
 245          $trace->log( '!' . str_repeat( '-', self::bt ) . '!' );
 246          $trace->end( 1 );
 247  
 248          self::unsubscribe( 'post', $mp_user, $list_id, $mail_id );
 249  
 250          wp_send_json_success();
 251          die();
 252      }
 253  
 254  // unsubscribing at last !
 255  
 256  	public static function unsubscribe( $context, $mp_user, $list_id, $mail_id )
 257      {
 258          $config = get_option( self::option_name );
 259          if ( !$config ) die();
 260  
 261          do_action( 'MailPress_list_unsubscribe_user', $context, $mp_user, $list_id, $mail_id );
 262  
 263          switch( $config['mode'] )
 264          {
 265              case 'a' :
 266                  MP_User::delete( $mp_user->id ) ;
 267              break;
 268              case 'b' :
 269                  MP_User::list_unsubscribed( $mp_user->id );
 270              break;
 271              case 'c' :
 272                  $c = explode( '.', $list_id );
 273                  $class = $c[0];
 274                  $list  = $c[1];
 275                  if ( method_exists( $class, 'list_unsubscribe' ) ) $class::list_unsubscribe( $mp_user->id, $list );
 276              break;
 277          }
 278      }
 279  
 280  // process
 281  	public static function process()
 282      {
 283          MP_::no_abort_limit();
 284  
 285          new MP_List_Unsubscribe();
 286      }
 287  
 288  // schedule
 289  	public static function schedule()
 290      {
 291          $config = get_option( self::option_name );
 292          $now4cron = current_time( 'timestamp', 'gmt' );
 293  
 294          if ( !wp_next_scheduled( self::process_name ) ) 
 295              wp_schedule_single_event( $now4cron + $config['every'], self::process_name );
 296      }
 297  
 298  ////  ADMIN  ////
 299  ////  ADMIN  ////
 300  ////  ADMIN  ////
 301  ////  ADMIN  ////
 302  
 303  // install
 304  	public static function install() 
 305      {
 306          self::uninstall();
 307  
 308          $options = get_option( self::option_name );
 309          if ( !$options )
 310          {
 311              $pop3 = get_option( 'MailPress_connection_pop3' );
 312              if ( $pop3 )
 313              {
 314                  unset( $pop3['username'], $pop3['password'] );
 315                  $options['pop3'] = $pop3;
 316                  update_option( self::option_name, $options );
 317              }
 318          }
 319  
 320          MP_Log::set_option( self::log_name );
 321  
 322          do_action( 'MailPress_schedule_list_unsubscribe' );
 323      }
 324  
 325  	public static function uninstall() 
 326      {
 327          wp_clear_scheduled_hook( self::process_name );
 328      }
 329  
 330  // for link on plugin page
 331  	public static function plugin_action_links( $links, $file )
 332      {
 333          return MailPress::plugin_links( $links, $file, plugin_basename( __FILE__ ), 'list_unsubscribe' );
 334      }
 335  
 336  // for settings
 337  	public static function settings_tab( $tabs )
 338      {
 339          $tabs['list_unsubscribe'] = 'List-Unsubscribe';
 340          return $tabs;
 341      }
 342  
 343  // for settings logs    
 344  	public static function settings_logs_form( $logs )
 345      {
 346          MP_AdminPage::log_form( self::log_name, $logs, __( 'List-Unsubscribe', 'MailPress' ) );
 347      }
 348  }
 349  new MailPress_list_unsubscribe();
 350  }


Generated: Tue May 19 15:55:14 2020 Cross-referenced by PHPXref 0.7.1