[ Index ]

MailPress 544

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

title

Body

[close]

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

   1  <?php
   2  if (class_exists('MailPress') && !class_exists('MailPress_tracking'))
   3  {
   4  /*
   5  Plugin Name: MailPress_tracking
   6  Plugin URI: http://blog.mailpress.org/tutorials/add-ons/tracking/
   7  Description: Tracking : mails &amp; users activity
   8  Version: 5.4.4
   9  */
  10  
  11  /** for admin plugin pages */
  12  define ('MailPress_page_tracking_m', MailPress_page_mails . '&file=tracking');
  13  define ('MailPress_page_tracking_u', MailPress_page_users . '&file=tracking');
  14  
  15  /** for admin plugin urls */
  16  $mp_file = 'admin.php';
  17  define ('MailPress_tracking_m',     $mp_file . '?page='     . MailPress_page_tracking_m);
  18  define ('MailPress_tracking_u',     $mp_file . '?page='     . MailPress_page_tracking_u);
  19  
  20  /** for mysql */ 
  21  global $wpdb;
  22  $wpdb->mp_tracks = $wpdb->prefix . 'mailpress_tracks';
  23  
  24  define ('MailPress_tracking_openedmail',     '_MailPress_mail_opened');
  25  
  26  class MailPress_tracking
  27  {
  28      const option_name = 'MailPress_tracking';
  29  
  30  	function __construct()
  31      {
  32  // for wordpress hooks
  33          add_action('init',                      array(__CLASS__, 'init'), 100);
  34  // for mails list
  35          add_filter('MailPress_mails_actions',         array(__CLASS__, 'mails_actions'),  8, 3);
  36  // for users list
  37          add_filter('MailPress_users_actions',         array(__CLASS__, 'users_actions'),  8, 3);
  38          add_filter('MailPress_bulk_actions_mailpress_users',    array(__CLASS__, 'bulk_actions_mailpress_users'), 8, 1);
  39          add_action('MailPress_do_bulk_action_mailpress_users',array(__CLASS__, 'do_bulk_action_mailpress_users'), 8, 2);
  40  // for referential integrity
  41          add_action('MailPress_delete_mail',          array(__CLASS__, 'delete_mail'), 1, 1);
  42          add_action('MailPress_delete_user',          array(__CLASS__, 'delete_user'), 1, 1);
  43          add_action('MailPress_unsubscribe_user',        array(__CLASS__, 'unsubscribe_user'), 1, 1);
  44  // prepare mail
  45          add_filter('MailPress_is_tracking',          array(__CLASS__, 'is_tracking'), 1, 1);
  46          add_filter('MailPress_header_url',            array(__CLASS__, 'header_url'), 8, 2);
  47          add_filter('MailPress_mail',                array(__CLASS__, 'mail'), 8, 2);
  48  // process link
  49          add_action('mp_action_tracking',             array(__CLASS__, 'tracking'), 8, 1);
  50  
  51          if (is_admin())
  52          {
  53          // install
  54              register_activation_hook(plugin_basename(__FILE__),     array(__CLASS__, 'install'));
  55          // for link on plugin page
  56              add_filter('plugin_action_links',         array(__CLASS__, 'plugin_action_links'), 10, 2 );
  57          // for role & capabilities
  58              add_filter('MailPress_capabilities',      array(__CLASS__, 'capabilities'), 1, 1);
  59          // for load admin page
  60              add_filter('MailPress_load_admin_page',     array(__CLASS__, 'load_admin_page'), 10, 1);
  61          // for settings
  62              add_filter('MailPress_settings_tab',     array(__CLASS__, 'settings_tab'), 40, 1);
  63          // for autorefresh
  64              add_filter('MailPress_autorefresh_js',    array(__CLASS__, 'autorefresh_js'), 8, 1);
  65          }
  66      }
  67  
  68  	public static function init()
  69      {
  70      // for mails list
  71          if ( current_user_can('MailPress_tracking_mails') )
  72          {
  73              add_filter('MailPress_mails_columns',         array(__CLASS__, 'mails_columns'), 8, 1);
  74              add_action('MailPress_mails_get_row',          array(__CLASS__, 'mails_get_row'), 1, 3);
  75          }
  76      }
  77  
  78  // for mails list
  79  	public static function mails_actions($actions, $mail, $url_parms)
  80      {
  81          if (!current_user_can('MailPress_tracking_mails'))    return $actions;
  82          if ('draft' == $mail->status)                    return $actions;
  83  
  84      // url
  85          $args = array();
  86          $args['id']     = $mail->id;
  87  
  88          $tracking_url     = esc_url(MP_::url( MailPress_tracking_m, array_merge($args, $url_parms)));
  89  
  90      // actions
  91          $actions['tracking'] = "<a href='$tracking_url' title='" . __('See tracking results', MP_TXTDOM ) . "'>" . __('Tracking', MP_TXTDOM) . '</a>';
  92  
  93          return $actions;
  94      }
  95  
  96  // for users list
  97  	public static function users_actions($actions, $user, $url_parms)
  98      {
  99          if (!current_user_can('MailPress_tracking_users'))    return $actions;
 100  
 101      // url
 102          $args = array();
 103          $args['id']     = $user->id;
 104  
 105          $tracking_url     = esc_url(MP_::url( MailPress_tracking_u, array_merge($args, $url_parms)));
 106  
 107      // actions
 108          $actions['tracking'] = "<a href='$tracking_url' title='" . __('See tracking results', MP_TXTDOM ) . "'>" . __('Tracking', MP_TXTDOM) . '</a>';
 109  
 110          return $actions;
 111      }
 112  
 113  	public static function bulk_actions_mailpress_users($bulk_actions)
 114      {
 115          $bulk_actions['geolocate'] = __('re-Geolocate', MP_TXTDOM);
 116          return $bulk_actions;
 117      }
 118  
 119  	public static function do_bulk_action_mailpress_users($action, $checked)
 120      {
 121          if ('bulk-geolocate' != $action) return false;
 122          $count = 0;
 123          foreach($checked as $id) if (self::set_ip($id)) $count++;
 124          return $count;
 125      }
 126  
 127  	public static function set_ip($id)
 128      {
 129          global $wpdb;
 130  
 131          $ip = $wpdb->get_var( $wpdb->prepare( "SELECT ip FROM $wpdb->mp_tracks WHERE user_id = %d AND ip <> '' ORDER BY tmstp DESC LIMIT 1;", $id) );
 132          if (!$ip) return false;
 133  
 134          return MP_User::set_ip($id, $ip);
 135      }
 136  
 137  // for referential integrity
 138  	public static function delete_mail($mail_id)
 139      {
 140          global $wpdb;
 141          $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->mp_tracks   WHERE mail_id = %d ; ", $mail_id ) );
 142          $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->mp_usermeta WHERE meta_key = '_MailPress_mail_sent' AND meta_value = %d ; ", $mail_id ) );
 143      }
 144  
 145  	public static function delete_user($mp_user_id)
 146      {
 147          global $wpdb;
 148          $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->mp_tracks WHERE user_id = %d ; ", $mp_user_id ) );
 149      }
 150  
 151  	public static function unsubscribe_user($mp_user_id)
 152      {
 153          if (!$mp_user_id) return;
 154  
 155          $data = $format         = array();
 156  
 157          $data['user_id']         = $mp_user_id;                                            $format[] = '%d';
 158          $data['mail_id']         = 0;                                                    $format[] = '%d';
 159          $data['mmeta_id']     = 0;                                                    $format[] = '%d';
 160          $data['track']         = '!!unsubscribed!!';                                        $format[] = '%s';
 161          $data['context']         = '?';                                                $format[] = '%s';
 162          $data['ip']         = trim($_SERVER['REMOTE_ADDR']);                                $format[] = '%s';
 163          $data['agent']         = trim($_SERVER['HTTP_USER_AGENT']);                            $format[] = '%s';
 164          $data['referrer']        = (isset($_SERVER['HTTP_REFERER'])) ? trim($_SERVER['HTTP_REFERER']) : '';    $format[] = '%s';
 165          $data['tmstp']        = current_time( 'mysql' );                                    $format[] = '%s';
 166  
 167          global $wpdb;
 168          $wpdb->insert( $wpdb->mp_tracks, $data, $format );
 169      }
 170  
 171  // prepare mail
 172  	public static function is_tracking($x)
 173      {
 174          return true;
 175      }
 176  
 177  	public static function header_url($url, $mail)
 178      {
 179          $MP_Tracking_url = MP_Action_url;
 180          $MP_Tracking_url_args = '?tg=%1$s&mm=%2$s&co=%3$s&us={{_confkey}}';
 181  
 182          $meta_id = self::get_mmid($mail->id, '_MailPress_mail_link', str_replace('&amp;', '&', $url));
 183          $t_url = $MP_Tracking_url . sprintf($MP_Tracking_url_args, 'l', $meta_id, 'h');
 184          $t_url = apply_filters('MailPress_tracking_url', $t_url, $mail);
 185          return $t_url;
 186      }
 187  
 188  	public static function mail($mail)
 189      {
 190          $MP_Tracking_url = MP_Action_url;
 191          $MP_Tracking_url_args = '?tg=%1$s&mm=%2$s&co=%3$s&us={{_confkey}}';
 192  
 193          foreach($mail->recipients as $k => $v)
 194          {
 195              $toemail = (is_email($k)) ? $k : $v;
 196              if (isset($mail->replacements[$toemail]['{{_confkey}}']))
 197              {
 198                  MP_User_meta::add(MP_User::get_id_by_email($toemail), '_MailPress_mail_sent', $mail->id);
 199              }
 200          }
 201  
 202          $output = preg_match_all('/<a [^>]*href=[\'"]([^\'"]+)[\'"][^>]*>(.*?)<\/a>/is', $mail->html, $matches, PREG_SET_ORDER);
 203  
 204          $hrefs_txt = array();
 205          if ($matches)
 206          {
 207              foreach ($matches as $match)
 208              {
 209                  if (strpos($match[1], 'mailto:') !== false) continue;
 210                  if ('#' == $match[1][1]) continue;
 211                  if (strpos($match[1], '#') !== false) continue;
 212  
 213                  $meta_id = self::get_mmid($mail->id, '_MailPress_mail_link', str_replace('&amp;', '&', $match[1]));
 214  
 215                  $t_url = $MP_Tracking_url . sprintf($MP_Tracking_url_args, 'l', $meta_id, 'h');
 216                  $t_url = apply_filters('MailPress_tracking_url', $t_url, $mail);
 217  
 218                  $link = self::str_replace_count($match[1], $t_url, $match[0], 1);
 219                  $mail->html = str_replace($match[0], $link, $mail->html);
 220  
 221                  $t_url = 'ttrraacck_uurrll' . sprintf($MP_Tracking_url_args, 'l', $meta_id, 'p');
 222                  $t_url = apply_filters('MailPress_tracking_url', $t_url, $mail);
 223                  $hrefs_txt[$match[1]] = $t_url;
 224              }
 225          }
 226          $meta_id = self::get_mmid($mail->id, MailPress_tracking_openedmail, MailPress_tracking_openedmail);
 227          $t_url = $MP_Tracking_url . sprintf($MP_Tracking_url_args, 'o', $meta_id, 'h');
 228          $t_url = apply_filters('MailPress_tracking_url', $t_url, $mail);
 229          $mail->html = str_ireplace('</body>', "\n<img src='" . $t_url . "' alt='' style='margin:0;padding:0;border:none;' /></body>", $mail->html);
 230  
 231          if (!empty($hrefs_txt))
 232          {
 233              uksort($hrefs_txt, create_function('$a, $b', 'return strcmp(strlen($a), strlen($b));'));
 234              $hrefs_txt = array_reverse($hrefs_txt);
 235              $t_url = apply_filters('MailPress_tracking_url', $MP_Tracking_url, $mail);
 236              $hrefs_txt['ttrraacck_uurrll'] = $t_url;
 237              $mail->plaintext = str_replace(array_keys($hrefs_txt), $hrefs_txt, $mail->plaintext);
 238          }
 239          return $mail;
 240      }
 241  
 242  	public static function str_replace_count($search, $replace, $subject, $times=1) 
 243      {
 244          $subject_original=$subject;
 245  
 246          $len=strlen($search);
 247          $pos=0;
 248          for ($i=1;$i<=$times;$i++) 
 249          {
 250              $pos=strpos($subject, $search, $pos);
 251              if($pos!==false) 
 252              {
 253                  $subject=substr($subject_original, 0, $pos);
 254                  $subject.=$replace;
 255                  $subject.=substr($subject_original, $pos+$len);
 256                  $subject_original=$subject;
 257              }
 258              else
 259              {
 260                  break;
 261              }
 262          }
 263          return($subject);
 264      }
 265  
 266  	public static function get_mmid($mail_id, $meta_key, $meta_value)
 267      {
 268          global $wpdb;
 269          $meta_id = $wpdb->get_var( $wpdb->prepare( "SELECT meta_id FROM $wpdb->mp_mailmeta WHERE mp_mail_id = %d AND meta_key = %s AND meta_value = %s ;", $mail_id, $meta_key, $meta_value ) );
 270          if ($meta_id) return $meta_id;
 271          return MP_Mail_meta::add( $mail_id, $meta_key, $meta_value);
 272      }
 273  
 274  // process link
 275  	public static function tracking($meta)
 276      {
 277          switch ($_GET['tg'])
 278          {
 279              case ('l') :
 280                  self::save($meta);
 281              break;
 282              case ('o') :
 283                  self::save($meta);
 284              break;
 285              default :
 286                  $meta->meta_value = '404';
 287                  self::save($meta);
 288              break;
 289          }
 290      }
 291  
 292  	public static function save($meta)
 293      {
 294          global $wpdb;
 295  
 296          $mp_user_id = MP_User::get_id($_GET['us']);
 297  
 298          if (!$mp_user_id) return;
 299          if (0 == $mp_user_id) return;
 300  
 301          $open_meta_id     = (MailPress_tracking_openedmail == $meta->meta_value) ? $meta->meta_id : self::get_mmid($meta->mp_mail_id, MailPress_tracking_openedmail, MailPress_tracking_openedmail);
 302          $opened_mail    = $wpdb->get_var( $wpdb->prepare( "SELECT count(*) FROM $wpdb->mp_tracks WHERE user_id = %d AND mail_id = %d AND mmeta_id = %d ;", $mp_user_id, $meta->mp_mail_id, $open_meta_id ) );
 303          if ((MailPress_tracking_openedmail == $meta->meta_value) && ($opened_mail)) return;
 304  
 305          $data = $format         = array();
 306  
 307          $data['user_id']         = $mp_user_id;                                                            $format[] = '%d';
 308          $data['mail_id']         = $meta->mp_mail_id;                                                        $format[] = '%d';
 309          $data['mmeta_id']     = $meta->meta_id;                                                            $format[] = '%d';
 310          $data['track']         = mysql_real_escape_string($meta->meta_value);                                        $format[] = '%s';
 311          $data['context']         = ('h' == $_GET['co']) ? 'html' : 'plaintext';                                        $format[] = '%s';
 312          $data['ip']         = mysql_real_escape_string(trim($_SERVER['REMOTE_ADDR']));                                $format[] = '%s';
 313          $data['agent']         = mysql_real_escape_string(trim($_SERVER['HTTP_USER_AGENT']));                            $format[] = '%s';
 314          $data['referrer']        = (isset($_SERVER['HTTP_REFERER'])) ? mysql_real_escape_string(trim($_SERVER['HTTP_REFERER'])) : '';    $format[] = '%s';
 315          $data['tmstp']        = current_time( 'mysql' );                                                    $format[] = '%s';
 316  
 317          $wpdb->insert( $wpdb->mp_tracks, $data, $format );
 318  
 319          if (MailPress_tracking_openedmail == $meta->meta_value) $opened_mail = true;
 320          if ($opened_mail) return;
 321  
 322          $data['mmeta_id']     = $open_meta_id;
 323          $data['track']         = MailPress_tracking_openedmail;
 324  
 325          $wpdb->insert( $wpdb->mp_tracks, $data, $format );
 326      }
 327  
 328  ////  ADMIN  ////
 329  ////  ADMIN  ////
 330  ////  ADMIN  ////
 331  ////  ADMIN  ////
 332  
 333  // install
 334  	public static function install() 
 335      {
 336          include  (MP_ABSPATH . 'mp-admin/includes/install/tracking.php');
 337      }
 338      
 339  // for link on plugin page
 340  	public static function plugin_action_links($links, $file)
 341      {
 342          return MailPress::plugin_links($links, $file, plugin_basename(__FILE__), 'tracking');
 343      }
 344  
 345  // for role & capabilities
 346  	public static function capabilities($capabilities) 
 347      {
 348          $capabilities['MailPress_tracking_mails'] = array(    'name'      => __('View tracking', MP_TXTDOM), 
 349                                                  'group'     => 'mails'
 350                                              );
 351          $capabilities['MailPress_tracking_users'] = array(    'name'      => __('View tracking', MP_TXTDOM), 
 352                                                  'group'     => 'users'
 353                                              );
 354          return $capabilities;
 355      }
 356  
 357  // for load admin page //
 358  	public static function load_admin_page($hub)
 359      {
 360          $hub[MailPress_page_tracking_m] = 'tracking_m';
 361          $hub[MailPress_page_tracking_u] = 'tracking_u';
 362          return $hub;
 363      }
 364  
 365  // for settings
 366  	public static function settings_tab($tabs)
 367      {
 368          $tabs['tracking'] = __('Tracking', MP_TXTDOM);
 369          return $tabs;
 370      }
 371  
 372  // for autorefresh
 373  	public static function autorefresh_js($scripts)
 374      {
 375          return MP_AutoRefresh_js::register_scripts($scripts);
 376      }
 377  
 378  // for mails list
 379  	public static function mails_columns($x)
 380      {
 381          $date = array_pop($x);
 382          $x['tracking_openrate']    =  __('Open rate', MP_TXTDOM);
 383          $x['tracking_clicks']    =  __('Clicks', MP_TXTDOM);
 384          $x['tracking_unsubscribe']    =  __('Unsubscribed', MP_TXTDOM);
 385          $x['date']        = $date;
 386          return $x;
 387      }
 388  
 389  	public static function mails_get_row($column_name, $mail, $url_parms)
 390      {
 391          global $wpdb;
 392          switch ($column_name)
 393          {
 394              case 'tracking_openrate' :
 395                  if (is_email($mail->toemail)) $total = 1;
 396                  elseif (is_serialized($mail->toemail)) $total = count(unserialize($mail->toemail));
 397                  else return;
 398  
 399                  $result = $wpdb->get_results( $wpdb->prepare( "SELECT DISTINCT user_id FROM $wpdb->mp_tracks WHERE mail_id = %d AND track = %s ;", $mail->id, MailPress_tracking_openedmail) );
 400                  if ($result) if ($total > 0) printf("%01.2f %%", 100 * count($result)/$total );
 401              break;
 402              case 'tracking_clicks' :
 403                  $exclude = array(MailPress_tracking_openedmail, '!!unsubscribed!!', '{{unsubscribe}}');
 404  
 405                  $result = $wpdb->get_var( $wpdb->prepare( "SELECT count(*) FROM $wpdb->mp_tracks WHERE mail_id = %d AND track NOT IN ( '" . join("','", $exclude) . "' ) ;", $mail->id) );
 406                  if ($result) echo "<div class='num post-com-count-wrapper'><a class='post-com-count'><span class='comment-count'>$result</span></a></div>";
 407              break;
 408              case 'tracking_unsubscribe' :
 409                  $exclude = array('{{unsubscribe}}');
 410  
 411                  $r  = $wpdb->get_results( $wpdb->prepare( "SELECT SQL_CALC_FOUND_ROWS DISTINCT user_id FROM $wpdb->mp_tracks WHERE mail_id = %d AND track = %s ;", $mail->id, '!!unsubscribed!!') );
 412                  $ud = $wpdb->get_var( "SELECT FOUND_ROWS()" );
 413  
 414                  $u  = $wpdb->get_var( $wpdb->prepare( "SELECT count(*) FROM $wpdb->mp_tracks WHERE mail_id = %d AND track IN ('" . join("','", $exclude) .  "') ;", $mail->id) );
 415                  $title = (!$u) ? '' : esc_attr(sprintf(_n(__('%d click on unsubscribe link',  MP_TXTDOM), __('%d clicks on unsubscribe link',  MP_TXTDOM), $u), $u));
 416  
 417                  $r = $ud;
 418                  if (!$r) return;
 419                  echo "<a class='post-com-count'><span class='comment-count'><abbr title='{$title}'>{$r}</abbr></span></a>";
 420              break;
 421          }
 422      }
 423  
 424  // for reports
 425  
 426  	public static function translate_track($track, $mail_id, $strlen = 20)
 427      {
 428          switch ($track)
 429          {
 430              case '{{subscribe}}' :
 431                  return __('subscribe', MP_TXTDOM);
 432              break;
 433              case '{{unsubscribe}}' :
 434                  return __('unsubscribe', MP_TXTDOM);
 435              break;
 436              case '{{viewhtml}}' :
 437                  return __('view html', MP_TXTDOM);
 438              break;
 439              case MailPress_tracking_openedmail :
 440                  return __('mail opened', MP_TXTDOM);
 441              break;
 442              case '!!unsubscribed!!' :
 443                  return __('<b>unsubscribed</b>', MP_TXTDOM);
 444              break;
 445              default :
 446                  $confkey = '#$&$#';
 447                  $url = MP_User::get_subscribe_url($confkey);
 448                  $url = str_replace($confkey, '', $url);
 449                  if (stripos($track, $url) !== false) {return __('subscribe', MP_TXTDOM);}
 450                  $url = MP_User::get_unsubscribe_url($confkey);
 451                  $url = str_replace($confkey, '', $url);
 452                  if (stripos($track, $url) !== false) {return __('unsubscribe', MP_TXTDOM);}
 453                  $url = MP_User::get_view_url($confkey, $mail_id);
 454                  $url = str_replace($confkey . '&id=' . $mail_id, '', $url);
 455                  if (stripos($track, $url) !== false) {return __('view html', MP_TXTDOM);}
 456              break;
 457          }
 458          global $wpdb;
 459          $title = $wpdb->get_var("SELECT post_title FROM $wpdb->posts WHERE guid = '$track';");
 460          $title = $display_title = ($title) ? $title : $track;
 461          $display_title = (substr($display_title, 0, 7) == 'http://') ? substr($display_title, 7) : $display_title;
 462          $display_title = (substr($display_title, 0, 8) == 'https://') ? substr($display_title, 8) : $display_title;
 463          $display_title = (strlen($display_title) > $strlen) ? substr($display_title, 0, $strlen - 2) . '...' : $display_title;
 464          return "<a href='$track' title=\"" . esc_attr($title) . "\">$display_title</a>";
 465      }
 466  }
 467  new MailPress_tracking();
 468  }


Generated: Thu Apr 28 18:38:52 2016 Cross-referenced by PHPXref 0.7.1