Email Subscribers & Newsletters - Version 4.3.5

Version Description

Download this release

Release Info

Developer Icegram
Plugin Icon 128x128 Email Subscribers & Newsletters
Version 4.3.5
Comparing to
See all releases

Code changes from version 4.3.4.1 to 4.3.5

email-subscribers.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Email Subscribers & Newsletters
4
  * Plugin URI: https://www.icegram.com/
5
  * Description: Add subscription forms on website, send HTML newsletters & automatically notify subscribers about new blog posts once it is published.
6
- * Version: 4.3.4.1
7
  * Author: Icegram
8
  * Author URI: https://www.icegram.com/
9
  * Requires at least: 3.9
@@ -111,7 +111,7 @@ if ( $is_premium ) {
111
  /* ***************************** Initial Compatibility Work (End) ******************* */
112
 
113
  if ( ! defined( 'ES_PLUGIN_VERSION' ) ) {
114
- define( 'ES_PLUGIN_VERSION', '4.3.4.1' );
115
  }
116
 
117
  // Plugin Folder Path.
3
  * Plugin Name: Email Subscribers & Newsletters
4
  * Plugin URI: https://www.icegram.com/
5
  * Description: Add subscription forms on website, send HTML newsletters & automatically notify subscribers about new blog posts once it is published.
6
+ * Version: 4.3.5
7
  * Author: Icegram
8
  * Author URI: https://www.icegram.com/
9
  * Requires at least: 3.9
111
  /* ***************************** Initial Compatibility Work (End) ******************* */
112
 
113
  if ( ! defined( 'ES_PLUGIN_VERSION' ) ) {
114
+ define( 'ES_PLUGIN_VERSION', '4.3.5' );
115
  }
116
 
117
  // Plugin Folder Path.
lite/admin/class-email-subscribers-admin.php CHANGED
@@ -435,8 +435,21 @@ class Email_Subscribers_Admin {
435
  $total_contacts = ES()->contacts_db->count_active_contacts_by_list_id();
436
  $total_email_sent = ES_DB_Mailing_Queue::get_notifications_count();
437
 
 
 
 
 
 
438
  if ( ( $total_contacts >= 10 || $total_email_sent > 2 ) && 'yes' !== $star_rating_dismiss && 'yes' !== $star_rating_done ) {
439
- echo '<div class="notice notice-warning" style="background-color: #FFF;"><p style="letter-spacing: 0.6px;">If you like <strong>Email Subscribers</strong>, please consider leaving us a <a target="_blank" href="?es_dismiss_admin_notice=1&option_name=star_notice_done"><span>&#9733;</span><span>&#9733;</span><span>&#9733;</span><span>&#9733;</span><span>&#9733;</span></a> rating. A huge thank you from Icegram in advance! <a style="float:right" class="es-admin-btn es-admin-btn-secondary" href="?es_dismiss_admin_notice=1&option_name=dismiss_star_notice">No, I don\'t like it</a></p></div>';
 
 
 
 
 
 
 
 
440
  }
441
  }
442
 
@@ -466,7 +479,6 @@ class Email_Subscribers_Admin {
466
  $contact_id = ES()->contacts_db->insert( $data );
467
  if ( $contact_id ) {
468
  $data = array(
469
- 'list_id' => array( $list_id ),
470
  'contact_id' => $contact_id,
471
  'status' => 'subscribed',
472
  'optin_type' => IG_SINGLE_OPTIN,
@@ -474,7 +486,7 @@ class Email_Subscribers_Admin {
474
  'subscribed_ip' => null
475
  );
476
 
477
- ES_DB_Lists_Contacts::add_lists_contacts( $data );
478
  }
479
  }
480
  $res = ES_Install::create_and_send_default_broadcast();
@@ -490,7 +502,7 @@ class Email_Subscribers_Admin {
490
 
491
  update_option( 'ig_es_onboarding_complete', 'yes' );
492
 
493
- $response = array();
494
  $response['dashboard_url'] = admin_url( 'admin.php?page=es_dashboard' );
495
  $response['status'] = 'SUCCESS';
496
  echo json_encode( $res );
@@ -531,7 +543,7 @@ class Email_Subscribers_Admin {
531
  return 0;
532
  }
533
 
534
- $total_count = ES_DB_Lists_Contacts::get_total_count_by_list( $list_id, $status );
535
 
536
  die( json_encode( array( 'total' => $total_count ) ) );
537
  }
435
  $total_contacts = ES()->contacts_db->count_active_contacts_by_list_id();
436
  $total_email_sent = ES_DB_Mailing_Queue::get_notifications_count();
437
 
438
+ $icon_url = plugin_dir_url( __FILE__ ) . 'images/icon-64.png';
439
+
440
+ $reviewurl = '?es_dismiss_admin_notice=1&option_name=star_notice_done';
441
+ $nobugurl = '?es_dismiss_admin_notice=1&option_name=dismiss_star_notice';
442
+
443
  if ( ( $total_contacts >= 10 || $total_email_sent > 2 ) && 'yes' !== $star_rating_dismiss && 'yes' !== $star_rating_done ) {
444
+
445
+ echo '<div class="notice notice-warning">';
446
+ echo '<span style="float: left;"><img style="height=90px; width=90px;" src="' . $icon_url . '" /></span>';
447
+ echo __( "<span><p>We hope you're enjoying <b>Email Subscribers</b> plugin! Could you please do us a BIG favor and give us a 5-star rating on WordPress to help us spread the word and boost our motivation?</p>", "temporary-login-without-password" );
448
+ echo "<ul class='tlwp-notice-links'>";
449
+ echo sprintf( '<li><a href="%s" class="tlwp-rating-link-header" target="_blank" data-rated="' . esc_attr__( "Thank You :) ",
450
+ 'temporary-login-without-password' ) . '"><span class="dashicons dashicons-external"></span>&nbsp;&nbsp;Ok, you deserve it!</a></li> <li><a href="%s"><span class="dashicons dashicons-calendar-alt"></span>&nbsp;&nbsp;Maybe later</a></li>', esc_url( $reviewurl ), esc_url( $nobugurl ) );
451
+ echo "</ul></span>";
452
+ echo '</div>';
453
  }
454
  }
455
 
479
  $contact_id = ES()->contacts_db->insert( $data );
480
  if ( $contact_id ) {
481
  $data = array(
 
482
  'contact_id' => $contact_id,
483
  'status' => 'subscribed',
484
  'optin_type' => IG_SINGLE_OPTIN,
486
  'subscribed_ip' => null
487
  );
488
 
489
+ ES()->lists_contacts_db->add_contact_to_lists( $data, $list_id );
490
  }
491
  }
492
  $res = ES_Install::create_and_send_default_broadcast();
502
 
503
  update_option( 'ig_es_onboarding_complete', 'yes' );
504
 
505
+ $response = array();
506
  $response['dashboard_url'] = admin_url( 'admin.php?page=es_dashboard' );
507
  $response['status'] = 'SUCCESS';
508
  echo json_encode( $res );
543
  return 0;
544
  }
545
 
546
+ $total_count = ES()->lists_contacts_db->get_total_count_by_list( $list_id, $status );
547
 
548
  die( json_encode( array( 'total' => $total_count ) ) );
549
  }
lite/admin/images/icon-64.png ADDED
Binary file
lite/includes/class-email-subscribers.php CHANGED
@@ -182,6 +182,13 @@ if ( ! class_exists( 'Email_Subscribers' ) ) {
182
  */
183
  public $links_db;
184
 
 
 
 
 
 
 
 
185
  /**
186
  *
187
  * @since 4.2.1
@@ -257,12 +264,12 @@ if ( ! class_exists( 'Email_Subscribers' ) ) {
257
 
258
  $active_plugins = $ig_es_tracker::get_active_plugins();
259
 
260
- $args['url'] = 'https://www.icegram.com/';
261
- $args['include'] = ES_PLUGIN_DIR . 'lite/includes/notices/views/ig-es-offer.php';
262
- ES_Admin_Notices::add_custom_notice('bfcm_2019', $args );
263
 
264
- $screen = get_current_screen();
265
- $screen_id = $screen ? $screen->id : '';
266
  // Don't show admin notices on Dashboard if onboarding is not yet completed.
267
  $is_onboarding_complete = get_option( 'ig_es_onboarding_complete', false );
268
 
@@ -284,10 +291,10 @@ if ( ! class_exists( 'Email_Subscribers' ) ) {
284
  $disable_wp_cron_notice = sprintf( __( 'WordPress Cron is disable on your site. Email notifications from Email Subscribers plugin will not be sent automatically. <a href="%s" target="_blank" >Here\'s how you can enable it.</a>', 'email-subscribers' ), $es_cron_url );
285
  $disable_wp_cron_notice .= '<br/>' . sprintf( __( 'Or schedule Cron in <a href="%s" target="_blank">cPanel</a>', 'email-subscribers' ), $cpanel_url );
286
  $disable_wp_cron_notice .= '<br/>' . sprintf( __( 'Or use <strong><a href="%s" target="_blank">Email Subscribers Pro</a></strong> for automatic Cron support', 'email-subscribers' ), $es_pro_url );
287
- $html = '<div class="notice notice-warning" style="background-color: #FFF;"><p style="letter-spacing: 0.6px;">' . $disable_wp_cron_notice . '<a style="float:right" class="es-admin-btn es-admin-btn-secondary " href="' . admin_url() . '?es_dismiss_admin_notice=1&option_name=wp_cron_notice">' . __( 'OK, I Got it!',
288
  'email-subscribers' ) . '</a></p></div>';
289
- $args['html'] = $html;
290
- ES_Admin_Notices::add_custom_notice('show_wp_cron', $args );
291
  }
292
 
293
  }
@@ -498,6 +505,9 @@ if ( ! class_exists( 'Email_Subscribers' ) ) {
498
  if ( ! defined( 'IG_ES_CRON_INTERVAL' ) ) {
499
  define( 'IG_ES_CRON_INTERVAL', 15 * MINUTE_IN_SECONDS );
500
  }
 
 
 
501
  }
502
 
503
  /**
@@ -770,25 +780,25 @@ if ( ! class_exists( 'Email_Subscribers' ) ) {
770
  }
771
 
772
  /**
773
- * Log Fatal Errors on Shutdown
774
- *
775
  * @since 4.3.1
776
  */
777
- public function log_errors() {
778
- $error = error_get_last();
779
- if ( in_array( $error['type'], array( E_ERROR, E_PARSE, E_COMPILE_ERROR, E_USER_ERROR, E_RECOVERABLE_ERROR ), true ) ) {
780
  $logger = get_ig_logger();
781
 
782
- $logger->critical(
783
- sprintf( __( '%1$s in %2$s on line %3$s', 'email-subscribers' ), $error['message'], $error['file'], $error['line'] ) . PHP_EOL,
784
- array(
785
- 'source' => 'fatal-errors',
786
- )
787
- );
788
 
789
- do_action( 'ig_es_shutdown_error', $error );
790
- }
791
- }
792
 
793
  /**
794
  * Return a true instance of a class
@@ -829,6 +839,7 @@ if ( ! class_exists( 'Email_Subscribers' ) ) {
829
  self::$instance->lists_db = new ES_DB_Lists();
830
  self::$instance->forms_db = new ES_DB_Forms();
831
  self::$instance->contacts_db = new ES_DB_Contacts();
 
832
  self::$instance->blocked_emails_db = new ES_DB_Blocked_Emails();
833
  self::$instance->links_db = new ES_DB_Links();
834
  self::$instance->queue = new ES_Queue();
182
  */
183
  public $links_db;
184
 
185
+ /**
186
+ * @since 4.3.5
187
+ *
188
+ * @var object|ES_DB_Lists_Contacts
189
+ */
190
+ public $lists_contacts_db;
191
+
192
  /**
193
  *
194
  * @since 4.2.1
264
 
265
  $active_plugins = $ig_es_tracker::get_active_plugins();
266
 
267
+ $args['url'] = 'https://www.icegram.com/';
268
+ $args['include'] = ES_PLUGIN_DIR . 'lite/includes/notices/views/ig-es-offer.php';
269
+ ES_Admin_Notices::add_custom_notice( 'bfcm_2019', $args );
270
 
271
+ $screen = get_current_screen();
272
+ $screen_id = $screen ? $screen->id : '';
273
  // Don't show admin notices on Dashboard if onboarding is not yet completed.
274
  $is_onboarding_complete = get_option( 'ig_es_onboarding_complete', false );
275
 
291
  $disable_wp_cron_notice = sprintf( __( 'WordPress Cron is disable on your site. Email notifications from Email Subscribers plugin will not be sent automatically. <a href="%s" target="_blank" >Here\'s how you can enable it.</a>', 'email-subscribers' ), $es_cron_url );
292
  $disable_wp_cron_notice .= '<br/>' . sprintf( __( 'Or schedule Cron in <a href="%s" target="_blank">cPanel</a>', 'email-subscribers' ), $cpanel_url );
293
  $disable_wp_cron_notice .= '<br/>' . sprintf( __( 'Or use <strong><a href="%s" target="_blank">Email Subscribers Pro</a></strong> for automatic Cron support', 'email-subscribers' ), $es_pro_url );
294
+ $html = '<div class="notice notice-warning" style="background-color: #FFF;"><p style="letter-spacing: 0.6px;">' . $disable_wp_cron_notice . '<a style="float:right" class="es-admin-btn es-admin-btn-secondary " href="' . admin_url() . '?es_dismiss_admin_notice=1&option_name=wp_cron_notice">' . __( 'OK, I Got it!',
295
  'email-subscribers' ) . '</a></p></div>';
296
+ $args['html'] = $html;
297
+ ES_Admin_Notices::add_custom_notice( 'show_wp_cron', $args );
298
  }
299
 
300
  }
505
  if ( ! defined( 'IG_ES_CRON_INTERVAL' ) ) {
506
  define( 'IG_ES_CRON_INTERVAL', 15 * MINUTE_IN_SECONDS );
507
  }
508
+ if ( ! defined( 'IG_ES_MAX_EMAIL_SEND_AT_ONCE' ) ) {
509
+ define( 'IG_ES_MAX_EMAIL_SEND_AT_ONCE', 30 );
510
+ }
511
  }
512
 
513
  /**
780
  }
781
 
782
  /**
783
+ * Log Fatal Errors on Shutdown
784
+ *
785
  * @since 4.3.1
786
  */
787
+ public function log_errors() {
788
+ $error = error_get_last();
789
+ if ( in_array( $error['type'], array( E_ERROR, E_PARSE, E_COMPILE_ERROR, E_USER_ERROR, E_RECOVERABLE_ERROR ), true ) ) {
790
  $logger = get_ig_logger();
791
 
792
+ $logger->critical(
793
+ sprintf( __( '%1$s in %2$s on line %3$s', 'email-subscribers' ), $error['message'], $error['file'], $error['line'] ) . PHP_EOL,
794
+ array(
795
+ 'source' => 'fatal-errors',
796
+ )
797
+ );
798
 
799
+ do_action( 'ig_es_shutdown_error', $error );
800
+ }
801
+ }
802
 
803
  /**
804
  * Return a true instance of a class
839
  self::$instance->lists_db = new ES_DB_Lists();
840
  self::$instance->forms_db = new ES_DB_Forms();
841
  self::$instance->contacts_db = new ES_DB_Contacts();
842
+ self::$instance->lists_contacts_db = new ES_DB_Lists_Contacts();
843
  self::$instance->blocked_emails_db = new ES_DB_Blocked_Emails();
844
  self::$instance->links_db = new ES_DB_Links();
845
  self::$instance->queue = new ES_Queue();
lite/includes/class-es-common.php CHANGED
@@ -63,13 +63,13 @@ Class ES_Common {
63
  $site_url = home_url( '/' );
64
  $content = str_replace( "{{SITEURL}}", $site_url, $content );
65
 
66
- /*TODO: Enable it once Pre header issue fix
67
  $meta = ES()->campaigns_db->get_campaign_meta_by_id( $campaign_id );
68
  $meta['pre_header'] = !empty($meta['pre_header']) ? $meta['pre_header'] : '';
69
  if( !empty( $meta['pre_header'] )){
70
  $content = '<span class="es_preheader" style="display: none !important; visibility: hidden; opacity: 0; color: transparent; height: 0; width: 0;">'.$meta['pre_header'].'</span>'.$content;
71
  }
72
- */
73
 
74
  return $content;
75
  }
@@ -1139,43 +1139,6 @@ Class ES_Common {
1139
  return $screens;
1140
  }
1141
 
1142
- /**
1143
- * Get total emails can send in this hour.
1144
- *
1145
- * @since 4.1.15
1146
- */
1147
- public static function total_emails_to_be_sent( $max_send = 100000 ) {
1148
-
1149
- $current_date = ig_es_get_current_date();
1150
- $current_hour = ig_es_get_current_hour();
1151
-
1152
- //Get total emails sent in this hour
1153
- $email_sent_data = ES_Common::get_ig_option( 'email_sent_data', array() );
1154
-
1155
- $total_emails_sent = 0;
1156
- if ( is_array( $email_sent_data ) && ! empty( $email_sent_data[ $current_date ] ) && ! empty( $email_sent_data[ $current_date ][ $current_hour ] ) ) {
1157
- $total_emails_sent = $email_sent_data[ $current_date ][ $current_hour ];
1158
- }
1159
-
1160
- // Get hourly limit
1161
- $can_total_emails_send_in_hour = ES_Common::get_ig_option( 'hourly_email_send_limit', 300 );
1162
-
1163
- // Is limit exceed?
1164
- if ( $total_emails_sent >= $can_total_emails_send_in_hour ) {
1165
- return 0;
1166
- }
1167
-
1168
- // Still, you can send these many emails.
1169
- $total_emails_can_send_now = $can_total_emails_send_in_hour - $total_emails_sent;
1170
-
1171
- // We can send more emails but if we get the count, send only those
1172
- if ( ( $max_send > 0 ) && ( $max_send < $total_emails_can_send_now ) ) {
1173
- $total_emails_can_send_now = $max_send;
1174
- }
1175
-
1176
- return $total_emails_can_send_now;
1177
- }
1178
-
1179
  /**
1180
  * Update Total Email Sent count
1181
  *
63
  $site_url = home_url( '/' );
64
  $content = str_replace( "{{SITEURL}}", $site_url, $content );
65
 
66
+ /*TODO: Enable it once Pre header issue fix
67
  $meta = ES()->campaigns_db->get_campaign_meta_by_id( $campaign_id );
68
  $meta['pre_header'] = !empty($meta['pre_header']) ? $meta['pre_header'] : '';
69
  if( !empty( $meta['pre_header'] )){
70
  $content = '<span class="es_preheader" style="display: none !important; visibility: hidden; opacity: 0; color: transparent; height: 0; width: 0;">'.$meta['pre_header'].'</span>'.$content;
71
  }
72
+ */
73
 
74
  return $content;
75
  }
1139
  return $screens;
1140
  }
1141
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1142
  /**
1143
  * Update Total Email Sent count
1144
  *
lite/includes/class-es-install.php CHANGED
@@ -722,7 +722,7 @@ if ( ! class_exists( 'ES_Install' ) ) {
722
  'ig_es_sample_data_imported' => array( 'default' => 'no', 'old_option' => '' ),
723
  'ig_es_default_subscriber_imported' => array( 'default' => 'no', 'old_option' => '' ),
724
  'ig_es_set_widget' => array( 'default' => '', 'old_option' => '' ),
725
- 'ig_es_sync_wp_users' => array( 'default' => '', 'old_option' => '' ),
726
  'ig_es_blocked_domains' => array( 'default' => 'mail.ru' ),
727
  'ig_es_disable_wp_cron' => array( 'default' => 'no' ),
728
  'ig_es_track_email_opens' => array( 'default' => 'yes' ),
@@ -732,6 +732,8 @@ if ( ! class_exists( 'ES_Install' ) ) {
732
  'ig_es_email_sent_data' => array( 'default' => array() ),
733
  'ig_es_mailer_settings' => array( 'default' => array( 'mailer' => 'wpmail' ), 'old_option' => '' ),
734
  'ig_es_user_roles' => array( 'default' => ES_Install::get_default_permissions(), 'old_option' => '' ),
 
 
735
  );
736
 
737
  return $options;
@@ -1099,7 +1101,6 @@ if ( ! class_exists( 'ES_Install' ) ) {
1099
 
1100
  if ( $contact_id ) {
1101
  $data = array(
1102
- 'list_id' => array( $list_id ),
1103
  'contact_id' => $contact_id,
1104
  'status' => 'subscribed',
1105
  'optin_type' => IG_SINGLE_OPTIN,
@@ -1107,7 +1108,7 @@ if ( ! class_exists( 'ES_Install' ) ) {
1107
  'subscribed_ip' => null
1108
  );
1109
 
1110
- ES_DB_Lists_Contacts::add_lists_contacts( $data );
1111
  }
1112
 
1113
  }
@@ -1125,10 +1126,8 @@ if ( ! class_exists( 'ES_Install' ) ) {
1125
  'subscribed_ip' => null
1126
  );
1127
 
1128
- ES_DB_Lists_Contacts::add_lists_contacts( $data );
1129
  }
1130
-
1131
-
1132
  }
1133
 
1134
  /**
722
  'ig_es_sample_data_imported' => array( 'default' => 'no', 'old_option' => '' ),
723
  'ig_es_default_subscriber_imported' => array( 'default' => 'no', 'old_option' => '' ),
724
  'ig_es_set_widget' => array( 'default' => '', 'old_option' => '' ),
725
+ 'ig_es_sync_wp_users' => array( 'default' => array(), 'old_option' => '' ),
726
  'ig_es_blocked_domains' => array( 'default' => 'mail.ru' ),
727
  'ig_es_disable_wp_cron' => array( 'default' => 'no' ),
728
  'ig_es_track_email_opens' => array( 'default' => 'yes' ),
732
  'ig_es_email_sent_data' => array( 'default' => array() ),
733
  'ig_es_mailer_settings' => array( 'default' => array( 'mailer' => 'wpmail' ), 'old_option' => '' ),
734
  'ig_es_user_roles' => array( 'default' => ES_Install::get_default_permissions(), 'old_option' => '' ),
735
+ 'ig_es_cron_interval' => array( 'default' => IG_ES_CRON_INTERVAL, 'old_option' => '' ),
736
+ 'ig_es_max_email_send_at_once' => array( 'default' => IG_ES_MAX_EMAIL_SEND_AT_ONCE, 'old_option' => '' ),
737
  );
738
 
739
  return $options;
1101
 
1102
  if ( $contact_id ) {
1103
  $data = array(
 
1104
  'contact_id' => $contact_id,
1105
  'status' => 'subscribed',
1106
  'optin_type' => IG_SINGLE_OPTIN,
1108
  'subscribed_ip' => null
1109
  );
1110
 
1111
+ ES()->lists_contacts_db->add_contact_to_lists( $data, $list_id );
1112
  }
1113
 
1114
  }
1126
  'subscribed_ip' => null
1127
  );
1128
 
1129
+ ES()->lists_contacts_db->add_contact_to_lists( $data, $main_list_id );
1130
  }
 
 
1131
  }
1132
 
1133
  /**
lite/includes/classes/class-es-admin-settings.php CHANGED
@@ -490,6 +490,15 @@ class ES_Admin_Settings {
490
  'desc' => __( 'Check this if you do not want Email Subscribers to use WP cron for sending emails', 'email-subscribers' )
491
  ),
492
 
 
 
 
 
 
 
 
 
 
493
  'ig_es_hourly_email_send_limit' => array(
494
  'type' => 'number',
495
  'placeholder' => '',
@@ -500,6 +509,16 @@ class ES_Admin_Settings {
500
  'desc' => __( 'Total emails your host can send in an hour.', 'email-subscribers' )
501
  ),
502
 
 
 
 
 
 
 
 
 
 
 
503
  'ig_es_test_send_email' => array(
504
  'type' => 'html',
505
  'html' => '<input id="es-test-email" type="email"/><input type="submit" name="submit" id="es-send-test" class="button button-primary" value="Send Email"><span class="es_spinner_image_admin" id="spinner-image" style="display:none"><img src="' . ES_PLUGIN_URL . 'lite/public/images/spinner.gif' . '"/></span>',
490
  'desc' => __( 'Check this if you do not want Email Subscribers to use WP cron for sending emails', 'email-subscribers' )
491
  ),
492
 
493
+ 'ig_es_cron_interval' => array(
494
+ 'id' => 'ig_es_cron_interval',
495
+ 'name' => __( 'Send Emails At Most Every', 'email-subscribers' ),
496
+ 'type' => 'select',
497
+ 'options' => ES()->cron->cron_intervals(),
498
+ 'desc' => __( '<p>Optional if a real cron service is used</p>', 'email-subscribers' ),
499
+ 'default' => IG_ES_CRON_INTERVAL
500
+ ),
501
+
502
  'ig_es_hourly_email_send_limit' => array(
503
  'type' => 'number',
504
  'placeholder' => '',
509
  'desc' => __( 'Total emails your host can send in an hour.', 'email-subscribers' )
510
  ),
511
 
512
+ 'ig_es_max_email_send_at_once' => array(
513
+ 'type' => 'number',
514
+ 'placeholder' => '',
515
+ 'supplemental' => '',
516
+ 'default' => IG_ES_MAX_EMAIL_SEND_AT_ONCE,
517
+ 'id' => 'ig_es_max_email_send_at_once',
518
+ 'name' => __( 'Maximum Emails To Send At once', 'email-subscribers' ),
519
+ 'desc' => __( 'Maximum emails you want to send on every cron request.', 'email-subscribers' )
520
+ ),
521
+
522
  'ig_es_test_send_email' => array(
523
  'type' => 'html',
524
  'html' => '<input id="es-test-email" type="email"/><input type="submit" name="submit" id="es-send-test" class="button button-primary" value="Send Email"><span class="es_spinner_image_admin" id="spinner-image" style="display:none"><img src="' . ES_PLUGIN_URL . 'lite/public/images/spinner.gif' . '"/></span>',
lite/includes/classes/class-es-contacts-table.php CHANGED
@@ -217,8 +217,8 @@ class ES_Contacts_Table extends WP_List_Table {
217
  }
218
 
219
  /**
220
- * Get Contacts Reports
221
- *
222
  * @since 4.3.1
223
  */
224
  public function get_contacts_reports() {
@@ -276,7 +276,7 @@ class ES_Contacts_Table extends WP_List_Table {
276
  $first_name = ! empty( $contact['first_name'] ) ? $contact['first_name'] : '';
277
  $last_name = ! empty( $contact['last_name'] ) ? $contact['last_name'] : '';
278
  $email = ! empty( $contact['email'] ) ? $contact['email'] : '';
279
- $list_ids = ES_DB_Lists_Contacts::get_list_ids_by_contact( $id );
280
  $guid = $contact['hash'];
281
  $nonce = esc_attr( ig_es_get_request_data( '_wpnonce' ) );
282
  }
@@ -332,7 +332,7 @@ class ES_Contacts_Table extends WP_List_Table {
332
 
333
  $list_ids = ! empty( $list_ids ) ? $list_ids : array( 1 );
334
 
335
- ES_DB_Lists_Contacts::update_list_contacts( $id, $list_ids );
336
 
337
  if ( $id ) {
338
 
@@ -529,7 +529,7 @@ class ES_Contacts_Table extends WP_List_Table {
529
 
530
  $title = $notificationid[0]->first_name . ' ' . $notificationid[0]->last_name;
531
  $email = $notificationid[0]->email;
532
- $contact_lists = ES_DB_Lists_Contacts::get_list_ids_by_contact( $notificationid[0]->id );
533
 
534
  $status = ig_es_get_request_data( 'status' );
535
  if ( 'updated' === $status ) {
@@ -852,7 +852,7 @@ class ES_Contacts_Table extends WP_List_Table {
852
  <?php }
853
 
854
 
855
- public function get_contact_id($contact) {
856
  return $contact['id'];
857
  }
858
 
@@ -887,14 +887,11 @@ class ES_Contacts_Table extends WP_List_Table {
887
 
888
  $contact_ids = array_map( array( $this, 'get_contact_id' ), $contacts );
889
 
890
- $contact_lists_statuses = ES_DB_Lists_Contacts::get_list_status_by_contact_ids( $contact_ids );
891
 
892
  $this->contact_lists_statuses = $contact_lists_statuses;
893
 
894
- $lists_id_name_map = ES()->lists_db->get_list_id_name_map();
895
-
896
- $this->lists_id_name_map = $lists_id_name_map;
897
-
898
  }
899
  }
900
 
@@ -1021,7 +1018,7 @@ class ES_Contacts_Table extends WP_List_Table {
1021
  }
1022
 
1023
  // loop over the array of record IDs and delete them
1024
- $edited = ES_DB_Lists_Contacts::edit_subscriber_status( $subscriber_ids, $status );
1025
 
1026
  if ( $edited ) {
1027
  $message = __( 'Status has been changed successfully!', 'email-subscribers' );
@@ -1041,7 +1038,7 @@ class ES_Contacts_Table extends WP_List_Table {
1041
  return;
1042
  }
1043
 
1044
- $edited = ES()->contacts_db->update_contacts_list( $subscriber_ids, $list_id );
1045
 
1046
  if ( $edited ) {
1047
  $message = __( 'Contact(s) have been moved to list successfully!', 'email-subscribers' );
@@ -1062,7 +1059,7 @@ class ES_Contacts_Table extends WP_List_Table {
1062
  return;
1063
  }
1064
 
1065
- $edited = ES()->contacts_db->add_contacts_to_list( $subscriber_ids, $list_id );
1066
 
1067
  if ( $edited ) {
1068
  $message = __( 'Contact(s) have been added to list successfully!', 'email-subscribers' );
@@ -1077,18 +1074,18 @@ class ES_Contacts_Table extends WP_List_Table {
1077
  /**
1078
  * Remove contacts from list when list is deleted
1079
  *
1080
- * @param $list_ids
1081
  *
1082
  * @since 4.3.1
 
1083
  */
1084
- public function delete_contacts_from_list( $list_id ) {
1085
- global $wpdb;
1086
-
1087
- $ig_lists_contacts_table = IG_LISTS_CONTACTS_TABLE;
1088
 
1089
- $query = "DELETE FROM {$ig_lists_contacts_table} WHERE list_id = %d";
 
 
1090
 
1091
- $wpdb->query( $wpdb->prepare( $query, $list_id ) );
1092
  }
1093
 
1094
  /**
217
  }
218
 
219
  /**
220
+ * Get Contacts Reports
221
+ *
222
  * @since 4.3.1
223
  */
224
  public function get_contacts_reports() {
276
  $first_name = ! empty( $contact['first_name'] ) ? $contact['first_name'] : '';
277
  $last_name = ! empty( $contact['last_name'] ) ? $contact['last_name'] : '';
278
  $email = ! empty( $contact['email'] ) ? $contact['email'] : '';
279
+ $list_ids = ES()->lists_contacts_db->get_list_ids_by_contact( $id );
280
  $guid = $contact['hash'];
281
  $nonce = esc_attr( ig_es_get_request_data( '_wpnonce' ) );
282
  }
332
 
333
  $list_ids = ! empty( $list_ids ) ? $list_ids : array( 1 );
334
 
335
+ ES()->lists_contacts_db->update_contact_lists( $id, $list_ids );
336
 
337
  if ( $id ) {
338
 
529
 
530
  $title = $notificationid[0]->first_name . ' ' . $notificationid[0]->last_name;
531
  $email = $notificationid[0]->email;
532
+ $contact_lists = ES()->lists_contacts_db->get_list_ids_by_contact( $notificationid[0]->id );
533
 
534
  $status = ig_es_get_request_data( 'status' );
535
  if ( 'updated' === $status ) {
852
  <?php }
853
 
854
 
855
+ public function get_contact_id( $contact ) {
856
  return $contact['id'];
857
  }
858
 
887
 
888
  $contact_ids = array_map( array( $this, 'get_contact_id' ), $contacts );
889
 
890
+ $contact_lists_statuses = ES()->lists_contacts_db->get_list_status_by_contact_ids( $contact_ids );
891
 
892
  $this->contact_lists_statuses = $contact_lists_statuses;
893
 
894
+ $this->lists_id_name_map = ES()->lists_db->get_list_id_name_map();
 
 
 
895
  }
896
  }
897
 
1018
  }
1019
 
1020
  // loop over the array of record IDs and delete them
1021
+ $edited = ES()->lists_contacts_db->edit_subscriber_status( $subscriber_ids, $status );
1022
 
1023
  if ( $edited ) {
1024
  $message = __( 'Status has been changed successfully!', 'email-subscribers' );
1038
  return;
1039
  }
1040
 
1041
+ $edited = ES()->lists_contacts_db->move_contacts_to_list( $subscriber_ids, $list_id );
1042
 
1043
  if ( $edited ) {
1044
  $message = __( 'Contact(s) have been moved to list successfully!', 'email-subscribers' );
1059
  return;
1060
  }
1061
 
1062
+ $edited = ES()->lists_contacts_db->add_contacts_to_list( $subscriber_ids, $list_id );
1063
 
1064
  if ( $edited ) {
1065
  $message = __( 'Contact(s) have been added to list successfully!', 'email-subscribers' );
1074
  /**
1075
  * Remove contacts from list when list is deleted
1076
  *
1077
+ * @param $list_id
1078
  *
1079
  * @since 4.3.1
1080
+ * @since 4.3.5 Used remove_contacts_from_list method
1081
  */
1082
+ public function delete_contacts_from_list( $list_id = 0 ) {
 
 
 
1083
 
1084
+ if ( empty( $list_id ) ) {
1085
+ return;
1086
+ }
1087
 
1088
+ return ES()->lists_contacts_db->remove_all_contacts_from_list( $list_id );
1089
  }
1090
 
1091
  /**
lite/includes/classes/class-es-cron.php CHANGED
@@ -10,10 +10,12 @@ class ES_Cron {
10
  * ES_Cron constructor.
11
  *
12
  * @since 4.0.0
 
13
  */
14
  public function __construct() {
15
  add_action( 'wp_loaded', array( &$this, 'init' ), 1 );
16
  add_action( 'ig_es_plugin_deactivate', array( &$this, 'clear' ) );
 
17
  }
18
 
19
  /**
@@ -55,10 +57,8 @@ class ES_Cron {
55
  return false;
56
  }
57
 
58
- $ig_es_disable_wp_cron = get_option( 'ig_es_disable_wp_cron', 'no' );
59
-
60
  // Don't want to use WP_CRON?
61
- if ( 'yes' === $ig_es_disable_wp_cron ) {
62
  $this->clear();
63
 
64
  return true;
@@ -69,6 +69,38 @@ class ES_Cron {
69
  return false;
70
  }
71
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  /**
73
  * Update Crons every hour
74
  *
@@ -203,13 +235,49 @@ class ES_Cron {
203
  public function cron_schedules( $schedules = array() ) {
204
 
205
  $schedules['ig_es_cron_interval'] = array(
206
- 'interval' => IG_ES_CRON_INTERVAL,
207
  'display' => esc_html__( 'Email Subscribers Cronjob Interval' ),
208
  );
209
 
210
  return $schedules;
211
  }
212
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213
  /**
214
  * Get Cron URL
215
  *
@@ -491,5 +559,4 @@ class ES_Cron {
491
 
492
  return $message_text;
493
  }
494
-
495
  }
10
  * ES_Cron constructor.
11
  *
12
  * @since 4.0.0
13
+ * @since 4.3.5 Added ig_es_after_settings_save action
14
  */
15
  public function __construct() {
16
  add_action( 'wp_loaded', array( &$this, 'init' ), 1 );
17
  add_action( 'ig_es_plugin_deactivate', array( &$this, 'clear' ) );
18
+ add_action( 'ig_es_after_settings_save', array( &$this, 'reschedule' ) );
19
  }
20
 
21
  /**
57
  return false;
58
  }
59
 
 
 
60
  // Don't want to use WP_CRON?
61
+ if ( ! $this->is_wp_cron_enable() ) {
62
  $this->clear();
63
 
64
  return true;
69
  return false;
70
  }
71
 
72
+ /**
73
+ * Is WP Cron enable?
74
+ *
75
+ * @return bool
76
+ *
77
+ * @since 4.3.5
78
+ */
79
+ public function is_wp_cron_enable() {
80
+ $ig_es_disable_wp_cron = get_option( 'ig_es_disable_wp_cron', 'no' );
81
+
82
+ // Don't want to use WP_CRON?
83
+ if ( 'yes' === $ig_es_disable_wp_cron ) {
84
+ return false;
85
+ }
86
+
87
+ return true;
88
+ }
89
+
90
+ /**
91
+ * Reschedule Crons
92
+ *
93
+ * @since 4.3.5
94
+ */
95
+ public function reschedule() {
96
+
97
+ $this->clear();
98
+
99
+ if ( $this->is_wp_cron_enable() ) {
100
+ $this->schedule();
101
+ }
102
+ }
103
+
104
  /**
105
  * Update Crons every hour
106
  *
235
  public function cron_schedules( $schedules = array() ) {
236
 
237
  $schedules['ig_es_cron_interval'] = array(
238
+ 'interval' => $this->get_cron_interval(),
239
  'display' => esc_html__( 'Email Subscribers Cronjob Interval' ),
240
  );
241
 
242
  return $schedules;
243
  }
244
 
245
+ /**
246
+ * Get Cron Interval
247
+ *
248
+ * @return int
249
+ *
250
+ * @since 4.3.5
251
+ */
252
+ public function get_cron_interval() {
253
+ $cron_interval = (int) get_option( 'ig_es_cron_interval', IG_ES_CRON_INTERVAL );
254
+
255
+ if ( $cron_interval <= 0 ) {
256
+ $cron_interval = IG_ES_CRON_INTERVAL;
257
+ }
258
+
259
+ return $cron_interval;
260
+ }
261
+
262
+ /**
263
+ * Get available cron intervals
264
+ *
265
+ * @return array
266
+ *
267
+ * @since 4.3.5
268
+ */
269
+ public function cron_intervals() {
270
+
271
+ return array(
272
+ 600 => __( '10 minutes', 'email-subscribers' ),
273
+ 900 => __( '15 minutes', 'email-subscribers' ),
274
+ 1200 => __( '20 minutes', 'email-subscribers' ),
275
+ 1500 => __( '25 minutes', 'email-subscribers' ),
276
+ 1800 => __( '30 minutes', 'email-subscribers' )
277
+ );
278
+
279
+ }
280
+
281
  /**
282
  * Get Cron URL
283
  *
559
 
560
  return $message_text;
561
  }
 
562
  }
lite/includes/classes/class-es-handle-post-notification.php CHANGED
@@ -203,6 +203,7 @@ class ES_Handle_Post_Notification {
203
  if ( $post_thumbnail != "" ) {
204
  $post_thumbnail_link = "<a href='" . $post_link . "' target='_blank'>" . $post_thumbnail . "</a>";
205
  }
 
206
  $es_templ_body = str_replace( '{{POSTIMAGE}}', $post_thumbnail_link, $es_templ_body );
207
 
208
  // Get post description
203
  if ( $post_thumbnail != "" ) {
204
  $post_thumbnail_link = "<a href='" . $post_link . "' target='_blank'>" . $post_thumbnail . "</a>";
205
  }
206
+
207
  $es_templ_body = str_replace( '{{POSTIMAGE}}', $post_thumbnail_link, $es_templ_body );
208
 
209
  // Get post description
lite/includes/classes/class-es-handle-subscription.php CHANGED
@@ -202,7 +202,7 @@ if ( ! class_exists( 'ES_Handle_Subscription' ) ) {
202
  }
203
 
204
  if ( count( $this->list_ids ) > 0 ) {
205
- $contact_lists = ES_DB_Lists_Contacts::get_list_ids_by_contact( $contact_id, 'subscribed' );
206
  if ( $contact_lists == $this->list_ids ) {
207
  $response['message'] = 'es_email_exists_notice';
208
  $this->do_response( $response );
@@ -210,15 +210,14 @@ if ( ! class_exists( 'ES_Handle_Subscription' ) ) {
210
  }
211
  $optin_type = $this->is_double_optin ? IG_DOUBLE_OPTIN : IG_SINGLE_OPTIN;
212
  $list_contact_data = array(
213
- 'list_id' => $this->list_ids,
214
  'contact_id' => $contact_id,
215
  'status' => $this->status,
216
  'subscribed_at' => ( $this->status === 'subscribed' ) ? ig_get_current_date_time() : '',
217
  'optin_type' => $optin_type,
218
  'subscribed_ip' => ig_es_get_ip()
219
  );
220
- ES_DB_Lists_Contacts::delete_list_contacts( $contact_id, $this->list_ids );
221
- ES_DB_Lists_Contacts::add_lists_contacts( $list_contact_data );
222
 
223
  if ( $contact_id ) {
224
 
202
  }
203
 
204
  if ( count( $this->list_ids ) > 0 ) {
205
+ $contact_lists = ES()->lists_contacts_db->get_list_ids_by_contact( $contact_id, 'subscribed' );
206
  if ( $contact_lists == $this->list_ids ) {
207
  $response['message'] = 'es_email_exists_notice';
208
  $this->do_response( $response );
210
  }
211
  $optin_type = $this->is_double_optin ? IG_DOUBLE_OPTIN : IG_SINGLE_OPTIN;
212
  $list_contact_data = array(
 
213
  'contact_id' => $contact_id,
214
  'status' => $this->status,
215
  'subscribed_at' => ( $this->status === 'subscribed' ) ? ig_get_current_date_time() : '',
216
  'optin_type' => $optin_type,
217
  'subscribed_ip' => ig_es_get_ip()
218
  );
219
+
220
+ ES()->lists_contacts_db->add_contact_to_lists( $list_contact_data, $this->list_ids );
221
 
222
  if ( $contact_id ) {
223
 
lite/includes/classes/class-es-handle-sync-wp-user.php CHANGED
@@ -8,7 +8,7 @@ class ES_Handle_Sync_Wp_User {
8
  // Sync upcoming WordPress users
9
  add_action( 'user_register', array( $this, 'sync_registered_wp_user' ) );
10
  add_action( 'ig_es_sync_users_tabs_wordpress', array( $this, 'sync_wordpress_users_settings' ) );
11
- add_action('edit_user_profile_update', array( $this, 'update_es_contact') );
12
  }
13
 
14
  public function sync_wordpress_users_settings( $wordpress_tab ) {
@@ -92,28 +92,35 @@ class ES_Handle_Sync_Wp_User {
92
  <?php
93
  }
94
 
 
95
  public function sync_registered_wp_user( $user_id ) {
96
- //get option
97
- $ig_es_sync_wp_users = get_option( 'ig_es_sync_wp_users', 'norecord' );
98
- $ig_es_sync_unserialized_data = maybe_unserialize( $ig_es_sync_wp_users );
99
- $ig_es_registered = ( $ig_es_sync_unserialized_data != 'norecord' ) ? $ig_es_sync_unserialized_data['es_registered'] : 'NO';
100
- if ( $ig_es_sync_wp_users != 'norecord' && 'YES' === $ig_es_registered ) {
101
- $list_id = $ig_es_sync_unserialized_data['es_registered_group'];
 
 
 
 
 
 
102
  //get user info
103
  $user_info = get_userdata( $user_id );
104
  if ( ! ( $user_info instanceof WP_User ) ) {
105
  return false;
106
  }
107
- $user_firstname = $user_info->display_name;
108
 
 
109
 
110
  $email = $user_info->user_email;
111
- if ( empty( $user_firstname ) ) {
112
- $user_firstname = ES_Common::get_name_from_email( $email );
113
  }
114
  //prepare data
115
  $data = array(
116
- 'first_name' => $user_firstname,
117
  'email' => $email,
118
  'source' => 'wp',
119
  'status' => 'verified',
@@ -126,23 +133,29 @@ class ES_Handle_Sync_Wp_User {
126
  }
127
 
128
  return true;
129
-
130
  }
131
 
132
- public function update_es_contact( $user_id ){
 
 
 
 
 
 
 
 
 
 
 
133
 
134
- $ig_es_sync_wp_users = get_option( 'ig_es_sync_wp_users', 'norecord' );
135
- $ig_es_sync_unserialized_data = maybe_unserialize( $ig_es_sync_wp_users );
136
- $ig_es_registered = ( $ig_es_sync_unserialized_data != 'norecord' ) ? $ig_es_sync_unserialized_data['es_registered'] : 'NO';
137
- if ( $ig_es_sync_wp_users != 'norecord' && 'YES' === $ig_es_registered ) {
138
  $user_info = get_userdata( $user_id );
139
  if ( ! ( $user_info instanceof WP_User ) ) {
140
  return;
141
  }
142
  //check if user exist with this email
143
  $es_contact_id = ES()->contacts_db->get_contact_id_by_email( $user_info->user_email );
144
- if( $es_contact_id ){
145
- $contact['email'] = $_POST['email'];
146
  $contact['first_name'] = $_POST['display_name'];
147
  ES()->contacts_db->update_contact( $es_contact_id, $contact );
148
  }
8
  // Sync upcoming WordPress users
9
  add_action( 'user_register', array( $this, 'sync_registered_wp_user' ) );
10
  add_action( 'ig_es_sync_users_tabs_wordpress', array( $this, 'sync_wordpress_users_settings' ) );
11
+ add_action( 'edit_user_profile_update', array( $this, 'update_es_contact' ) );
12
  }
13
 
14
  public function sync_wordpress_users_settings( $wordpress_tab ) {
92
  <?php
93
  }
94
 
95
+
96
  public function sync_registered_wp_user( $user_id ) {
97
+ $ig_es_sync_wp_users = get_option( 'ig_es_sync_wp_users', array() );
98
+
99
+ if ( empty( $ig_es_sync_wp_users ) ) {
100
+ $ig_es_sync_wp_users = array();
101
+ }
102
+
103
+ $ig_es_sync_wp_users = maybe_unserialize( $ig_es_sync_wp_users );
104
+
105
+ $ig_es_registered = ( ! empty( $ig_es_sync_wp_users['es_registered'] ) ) ? $ig_es_sync_wp_users['es_registered'] : 'NO';
106
+
107
+ if ( 'YES' === $ig_es_registered ) {
108
+ $list_id = $ig_es_sync_wp_users['es_registered_group'];
109
  //get user info
110
  $user_info = get_userdata( $user_id );
111
  if ( ! ( $user_info instanceof WP_User ) ) {
112
  return false;
113
  }
 
114
 
115
+ $user_first_name = $user_info->display_name;
116
 
117
  $email = $user_info->user_email;
118
+ if ( empty( $user_first_name ) ) {
119
+ $user_first_name = ES_Common::get_name_from_email( $email );
120
  }
121
  //prepare data
122
  $data = array(
123
+ 'first_name' => $user_first_name,
124
  'email' => $email,
125
  'source' => 'wp',
126
  'status' => 'verified',
133
  }
134
 
135
  return true;
 
136
  }
137
 
138
+ public function update_es_contact( $user_id ) {
139
+ $ig_es_sync_wp_users = get_option( 'ig_es_sync_wp_users', array() );
140
+
141
+ if ( empty( $ig_es_sync_wp_users ) ) {
142
+ $ig_es_sync_wp_users = array();
143
+ }
144
+
145
+ $ig_es_sync_wp_users = maybe_unserialize( $ig_es_sync_wp_users );
146
+
147
+ $ig_es_registered = ( ! empty( $ig_es_sync_wp_users['es_registered'] ) ) ? $ig_es_sync_wp_users['es_registered'] : 'NO';
148
+
149
+ if ( 'YES' === $ig_es_registered ) {
150
 
 
 
 
 
151
  $user_info = get_userdata( $user_id );
152
  if ( ! ( $user_info instanceof WP_User ) ) {
153
  return;
154
  }
155
  //check if user exist with this email
156
  $es_contact_id = ES()->contacts_db->get_contact_id_by_email( $user_info->user_email );
157
+ if ( $es_contact_id ) {
158
+ $contact['email'] = $_POST['email'];
159
  $contact['first_name'] = $_POST['display_name'];
160
  ES()->contacts_db->update_contact( $es_contact_id, $contact );
161
  }
lite/includes/classes/class-es-import-subscribers.php CHANGED
@@ -146,8 +146,8 @@ class ES_Import_Subscribers {
146
 
147
  $contact_ids = ES()->contacts_db->get_contact_ids_by_emails( $emails );
148
  if ( count( $contact_ids ) > 0 ) {
149
- ES_DB_Lists_Contacts::delete_contacts_from_list( $list_id, $contact_ids );
150
- ES_DB_Lists_Contacts::do_import_contacts_into_list( $list_id, $contact_ids, $status, 1, $current_date_time );
151
  }
152
 
153
  $message = sprintf( __( 'Total %d contacts have been imported successfully!', 'email-subscribers' ), $imported_subscribers_count );
146
 
147
  $contact_ids = ES()->contacts_db->get_contact_ids_by_emails( $emails );
148
  if ( count( $contact_ids ) > 0 ) {
149
+ ES()->lists_contacts_db->remove_contacts_from_lists( $contact_ids, $list_id );
150
+ ES()->lists_contacts_db->do_import_contacts_into_list( $list_id, $contact_ids, $status, 1, $current_date_time );
151
  }
152
 
153
  $message = sprintf( __( 'Total %d contacts have been imported successfully!', 'email-subscribers' ), $imported_subscribers_count );
lite/includes/classes/class-es-lists-table.php CHANGED
@@ -417,7 +417,7 @@ class ES_Lists_Table extends WP_List_Table {
417
 
418
  switch ( $column_name ) {
419
  case 'active_contacts':
420
- $count = ES_DB_Lists_Contacts::get_total_count_by_list( $item['id'], 'subscribed' );
421
  if ( $count > 0 ) {
422
  $url = admin_url( 'admin.php?page=es_subscribers&filter_by_status=subscribed&filter_by_list_id=' . $item['id'] );
423
  $count = sprintf( __( '<a href="%s" target="_blank">%d</a>', 'email-subscribers' ), $url, $count );
@@ -426,7 +426,7 @@ class ES_Lists_Table extends WP_List_Table {
426
  return $count;
427
  break;
428
  case 'all_contacts':
429
- $count = ES_DB_Lists_Contacts::get_total_count_by_list( $item['id'], 'all' );
430
  if ( $count > 0 ) {
431
  $url = admin_url( 'admin.php?page=es_subscribers&filter_by_list_id=' . $item['id'] );
432
  $count = sprintf( __( '<a href="%s" target="_blank">%d</a>', 'email-subscribers' ), $url, $count );
417
 
418
  switch ( $column_name ) {
419
  case 'active_contacts':
420
+ $count = ES()->lists_contacts_db->get_total_count_by_list( $item['id'], 'subscribed' );
421
  if ( $count > 0 ) {
422
  $url = admin_url( 'admin.php?page=es_subscribers&filter_by_status=subscribed&filter_by_list_id=' . $item['id'] );
423
  $count = sprintf( __( '<a href="%s" target="_blank">%d</a>', 'email-subscribers' ), $url, $count );
426
  return $count;
427
  break;
428
  case 'all_contacts':
429
+ $count = ES()->lists_contacts_db->get_total_count_by_list( $item['id'], 'all' );
430
  if ( $count > 0 ) {
431
  $url = admin_url( 'admin.php?page=es_subscribers&filter_by_list_id=' . $item['id'] );
432
  $count = sprintf( __( '<a href="%s" target="_blank">%d</a>', 'email-subscribers' ), $url, $count );
lite/includes/classes/class-es-mailer.php CHANGED
@@ -141,7 +141,7 @@ if ( ! class_exists( 'ES_Mailer' ) ) {
141
 
142
  $this->time_limit = $this->time_start + $max_time;
143
 
144
- $this->email_limit = ES_Common::total_emails_to_be_sent();
145
 
146
  // We are doing heavy lifting..allocate more memory
147
  if ( function_exists( 'memory_get_usage' ) && ( (int) @ini_get( 'memory_limit' ) < 128 ) ) {
@@ -1162,5 +1162,66 @@ if ( ! class_exists( 'ES_Mailer' ) ) {
1162
 
1163
  return $this->prepare_link( $link_data );
1164
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1165
  }
1166
  }
141
 
142
  $this->time_limit = $this->time_start + $max_time;
143
 
144
+ $this->email_limit = $this->get_total_emails_send_now();
145
 
146
  // We are doing heavy lifting..allocate more memory
147
  if ( function_exists( 'memory_get_usage' ) && ( (int) @ini_get( 'memory_limit' ) < 128 ) ) {
1162
 
1163
  return $this->prepare_link( $link_data );
1164
  }
1165
+
1166
+ /**
1167
+ * How many emails we can send now?
1168
+ *
1169
+ * @since 4.3.5
1170
+ */
1171
+ public function get_total_emails_send_now( $max_send = 100000 ) {
1172
+
1173
+ $current_date = ig_es_get_current_date();
1174
+ $current_hour = ig_es_get_current_hour();
1175
+
1176
+ //Get total emails sent in this hour
1177
+ $email_sent_data = ES_Common::get_ig_option( 'email_sent_data', array() );
1178
+
1179
+ $total_emails_sent = 0;
1180
+ if ( is_array( $email_sent_data ) && ! empty( $email_sent_data[ $current_date ] ) && ! empty( $email_sent_data[ $current_date ][ $current_hour ] ) ) {
1181
+ $total_emails_sent = $email_sent_data[ $current_date ][ $current_hour ];
1182
+ }
1183
+
1184
+ // Get hourly limit
1185
+ $can_total_emails_send_in_hour = ES_Common::get_ig_option( 'hourly_email_send_limit', 300 );
1186
+
1187
+ // Is limit exceed?
1188
+ if ( $total_emails_sent >= $can_total_emails_send_in_hour ) {
1189
+ return 0;
1190
+ }
1191
+
1192
+ // Still, you can send these many emails.
1193
+ $total_emails_can_send_now = $can_total_emails_send_in_hour - $total_emails_sent;
1194
+
1195
+ // We can send more emails but if we get the count, send only those
1196
+ if ( ( $max_send > 0 ) && ( $max_send < $total_emails_can_send_now ) ) {
1197
+ $total_emails_can_send_now = $max_send;
1198
+ }
1199
+
1200
+ // Do we have max email sending limit at once set?
1201
+ $can_total_emails_send_at_once = $this->get_max_email_send_at_once_count();
1202
+
1203
+ if ( $can_total_emails_send_at_once < $total_emails_can_send_now ) {
1204
+ $total_emails_can_send_now = $can_total_emails_send_at_once;
1205
+ }
1206
+
1207
+ return $total_emails_can_send_now;
1208
+ }
1209
+
1210
+ /**
1211
+ * Get max email send at once count
1212
+ *
1213
+ * @return int
1214
+ *
1215
+ * @since 4.3.5
1216
+ */
1217
+ public function get_max_email_send_at_once_count() {
1218
+ $max_count = (int) ES_Common::get_ig_option( 'max_email_send_at_once', IG_ES_MAX_EMAIL_SEND_AT_ONCE );
1219
+
1220
+ if ( $max_count <= 0 ) {
1221
+ $max_count = IG_ES_MAX_EMAIL_SEND_AT_ONCE;
1222
+ }
1223
+
1224
+ return $max_count;
1225
+ }
1226
  }
1227
  }
lite/includes/classes/class-es-queue.php CHANGED
@@ -609,7 +609,7 @@ if ( ! class_exists( 'ES_Queue' ) ) {
609
  * - Update status in ig_es_mailing_queue table
610
  * - Update status in ig_es_sending_queue table
611
  */
612
- $es_c_croncount = ES_Common::total_emails_to_be_sent();
613
 
614
  if ( $es_c_croncount > 0 ) {
615
 
609
  * - Update status in ig_es_mailing_queue table
610
  * - Update status in ig_es_sending_queue table
611
  */
612
+ $es_c_croncount = ES()->mailer->get_total_emails_send_now();
613
 
614
  if ( $es_c_croncount > 0 ) {
615
 
lite/includes/classes/class-es-reports-data.php CHANGED
@@ -29,9 +29,13 @@ if ( ! class_exists( 'ES_Reports_Data' ) ) {
29
  * @param int $days
30
  *
31
  * @return int
 
 
 
 
32
  */
33
  public static function get_total_subscribed_contacts( $days = 0 ) {
34
- return ES_DB_Lists_Contacts::get_total_subscribed_contacts( $days );
35
  }
36
 
37
  /**
@@ -40,9 +44,13 @@ if ( ! class_exists( 'ES_Reports_Data' ) ) {
40
  * @param int $days
41
  *
42
  * @return int
 
 
 
 
43
  */
44
  public static function get_total_unsubscribed_contacts( $days = 0 ) {
45
- return ES_DB_Lists_Contacts::get_total_unsubscribed_contacts( $days );
46
  }
47
 
48
  /**
@@ -62,6 +70,8 @@ if ( ! class_exists( 'ES_Reports_Data' ) ) {
62
  * @param int $days
63
  *
64
  * @return int
 
 
65
  */
66
  public static function get_total_contacts_clicks_links( $days = 60 ) {
67
  return ES()->actions_db->get_total_contacts_clicks_links( $days );
29
  * @param int $days
30
  *
31
  * @return int
32
+ *
33
+ * @since 4.3.2
34
+ * @since 4.3.5 Modified ES_DB_Lists_Contacts::get_total_subscribed_contacts to
35
+ * ES()->lists_contacts_db->get_total_subscribed_contacts
36
  */
37
  public static function get_total_subscribed_contacts( $days = 0 ) {
38
+ return ES()->lists_contacts_db->get_total_subscribed_contacts( $days );
39
  }
40
 
41
  /**
44
  * @param int $days
45
  *
46
  * @return int
47
+ *
48
+ * @since 4.3.2
49
+ * @since 4.3.5 Modified ES_DB_Lists_Contacts::get_total_unsubscribed_contacts to
50
+ * ES()->lists_contacts_db->get_total_unsubscribed_contacts
51
  */
52
  public static function get_total_unsubscribed_contacts( $days = 0 ) {
53
+ return ES()->lists_contacts_db->get_total_unsubscribed_contacts( $days );
54
  }
55
 
56
  /**
70
  * @param int $days
71
  *
72
  * @return int
73
+ *
74
+ * @since 4.3.2
75
  */
76
  public static function get_total_contacts_clicks_links( $days = 60 ) {
77
  return ES()->actions_db->get_total_contacts_clicks_links( $days );
lite/includes/db/class-es-db-contacts.php CHANGED
@@ -342,94 +342,6 @@ class ES_DB_Contacts extends ES_DB {
342
  return $wpdb->query( $query );
343
  }
344
 
345
- /**
346
- * Update Contact Lists
347
- *
348
- * @param $ids
349
- * @param $list_id
350
- *
351
- * @return bool
352
- *
353
- * @since 4.0.0
354
- */
355
- public function update_contacts_list( $ids, $list_id ) {
356
- global $wpdb;
357
-
358
- $ids_str = $this->prepare_for_in_query( $ids );
359
-
360
- $ig_lists_contacts_table = IG_LISTS_CONTACTS_TABLE;
361
-
362
- //delete all list contact entry
363
- $query = "DELETE FROM $ig_lists_contacts_table WHERE contact_id IN ($ids_str) ";
364
-
365
- $wpdb->query( $query );
366
-
367
- $values = $place_holders = array();
368
- $optin_type_option = get_option( 'ig_es_optin_type', true );
369
- $optin_type = 1;
370
- if ( in_array( $optin_type_option, array( 'double_opt_in', 'double_optin' ) ) ) {
371
- $optin_type = 2;
372
- }
373
- $subscribed_at = ig_get_current_date_time();
374
- $subscribed_ip = '';
375
- foreach ( $ids as $contact_id ) {
376
- array_push( $values, $list_id, $contact_id, 'subscribed', $optin_type, $subscribed_at, $subscribed_ip );
377
- $place_holders[] = "( %d, %d, %s, %s, %s, %s )"; /* In my case, i know they will always be integers */
378
- }
379
-
380
- $query = "INSERT INTO $ig_lists_contacts_table (`list_id`, `contact_id`, `status`, `optin_type`, `subscribed_at`, `subscribed_ip` ) VALUES ";
381
- $query .= implode( ', ', $place_holders );
382
- $sql = $wpdb->prepare( "$query ", $values );
383
- if ( $wpdb->query( $sql ) ) {
384
- return true;
385
- } else {
386
- return false;
387
- }
388
- }
389
-
390
- /**
391
- * Add contacts to list
392
- *
393
- * @param $ids
394
- * @param $list_id
395
- *
396
- * @return bool
397
- *
398
- * @since 4.0.0
399
- */
400
- public function add_contacts_to_list( $ids, $list_id ) {
401
- global $wpdb;
402
-
403
- $ids_str = $this->prepare_for_in_query( $ids );
404
-
405
- $ig_lists_contacts_table = IG_LISTS_CONTACTS_TABLE;
406
-
407
- $delete_list_contact = "DELETE FROM $ig_lists_contacts_table WHERE contact_id IN ($ids_str) AND list_id = %s";
408
- $del_query = $wpdb->prepare( $delete_list_contact, array( $list_id ) );
409
- $wpdb->query( $del_query );
410
-
411
- $values = $place_holders = array();
412
- $optin_type_option = get_option( 'ig_es_optin_type', true );
413
- $optin_type = 1;
414
- if ( in_array( $optin_type_option, array( 'double_opt_in', 'double_optin' ) ) ) {
415
- $optin_type = 2;
416
- }
417
- $subscribed_at = ig_get_current_date_time();
418
- $subscribed_ip = '';
419
- foreach ( $ids as $contact_id ) {
420
- array_push( $values, $list_id, $contact_id, 'subscribed', $optin_type, $subscribed_at, $subscribed_ip );
421
- $place_holders[] = "( %d, %d, %s, %s, %s, %s )"; /* In my case, i know they will always be integers */
422
- }
423
- $query = "INSERT INTO " . IG_LISTS_CONTACTS_TABLE . " (`list_id`, `contact_id`, `status`, `optin_type`, `subscribed_at`, `subscribed_ip` ) VALUES ";
424
- $query .= implode( ', ', $place_holders );
425
- $sql = $wpdb->prepare( "$query ", $values );
426
- if ( $wpdb->query( $sql ) ) {
427
- return true;
428
- } else {
429
- return false;
430
- }
431
- }
432
-
433
  /**
434
  * Edit global status of contact
435
  *
@@ -748,7 +660,7 @@ class ES_DB_Contacts extends ES_DB {
748
  $list_name_id_map = ES()->lists_db->get_list_id_name_map( '', true );
749
  foreach ( $lists_contacts as $list_name => $contacts ) {
750
  if ( ! empty( $list_name_id_map[ $list_name ] ) ) {
751
- ES_DB_Lists_Contacts::import_contacts_into_lists( $list_name_id_map[ $list_name ], $contacts );
752
  }
753
  }
754
  }
342
  return $wpdb->query( $query );
343
  }
344
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
345
  /**
346
  * Edit global status of contact
347
  *
660
  $list_name_id_map = ES()->lists_db->get_list_id_name_map( '', true );
661
  foreach ( $lists_contacts as $list_name => $contacts ) {
662
  if ( ! empty( $list_name_id_map[ $list_name ] ) ) {
663
+ ES()->lists_contacts_db->import_contacts_into_lists( $list_name_id_map[ $list_name ], $contacts );
664
  }
665
  }
666
  }
lite/includes/db/class-es-db-lists-contacts.php CHANGED
@@ -1,114 +1,392 @@
1
  <?php
 
 
 
 
2
 
3
- class ES_DB_Lists_Contacts {
 
 
 
 
 
 
 
 
 
 
 
 
 
4
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  public function __construct() {
 
6
 
 
 
 
 
 
 
 
7
  }
8
 
9
- public static function add_lists_contacts( $data ) {
10
- global $wpdb;
11
- $values = array();
12
- foreach ( $data['list_id'] as $list_id ) {
13
- array_push( $values, $list_id, $data['contact_id'], $data['status'], $data['optin_type'], $data['subscribed_at'], $data['subscribed_ip'] );
14
- $place_holders[] = "( %d, %d, %s, %s, %s, %s )"; /* In my case, i know they will always be integers */
15
- }
16
- $query = "INSERT INTO " . IG_LISTS_CONTACTS_TABLE . " (`list_id`, `contact_id`, `status`, `optin_type`, `subscribed_at`, `subscribed_ip` ) VALUES ";
17
- $query .= implode( ', ', $place_holders );
18
- $sql = $wpdb->prepare( "$query ", $values );
19
- if ( $wpdb->query( $sql ) ) {
20
- return true;
21
- } else {
22
- return false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  }
 
 
24
  }
25
 
26
- public static function get_list_ids_by_contact( $id, $status = '' ) {
27
- global $wpdb;
28
- $query = "SELECT list_id FROM " . IG_LISTS_CONTACTS_TABLE . " WHERE contact_id = $id";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
- if ( ! empty( $status ) ) {
31
- $query .= " AND status = %s";
32
- $query = $wpdb->prepare( $query, $status );
33
  }
34
- $res = $wpdb->get_col( $query );
35
 
36
- return $res;
37
  }
38
 
39
- public static function get_list_details_by_contact( $id ) {
40
- global $wpdb;
41
- $query = "SELECT * FROM " . IG_LISTS_CONTACTS_TABLE . " WHERE contact_id = $id";
42
- $res = $wpdb->get_results( $query, ARRAY_A );
 
 
 
 
 
 
 
 
 
 
 
43
 
44
- return $res;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  }
46
 
47
- public static function get_list_contact_status_map( $id ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  global $wpdb;
49
 
50
- $query = "SELECT list_id, status FROM " . IG_LISTS_CONTACTS_TABLE . " WHERE contact_id = {$id}";
 
 
51
 
52
- $res = $wpdb->get_results( $query, ARRAY_A );
 
53
 
54
- $lists_contact_status_map = array();
55
- if ( count( $res ) > 0 ) {
56
- foreach ( $res as $list ) {
57
- $lists_contact_status_map[ $list['list_id'] ] = $list['status'];
58
- }
59
  }
60
 
61
- return $lists_contact_status_map;
 
 
62
  }
63
 
64
- public static function update_list_contacts( $contact_id, $list_ids ) {
 
 
 
 
 
 
 
 
 
65
  global $wpdb;
66
- $query = "DELETE FROM " . IG_LISTS_CONTACTS_TABLE . " WHERE contact_id = $contact_id";
67
- $res = $wpdb->query( $query );
68
 
69
- $result = false;
70
- $optin_type_option = get_option( 'ig_es_optin_type', true );
 
 
 
 
71
 
72
- $optin_type = 1;
73
- if ( in_array( $optin_type_option, array( 'double_opt_in', 'double_optin' ) ) ) {
74
- $optin_type = 2;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  }
76
 
 
 
 
 
 
77
  if ( ! empty( $list_ids ) ) {
78
- $data['list_id'] = $list_ids;
 
 
 
 
 
 
79
  $data['contact_id'] = $contact_id;
80
  $data['status'] = 'subscribed';
81
  $data['optin_type'] = $optin_type;
82
  $data['subscribed_at'] = ig_get_current_date_time();
83
- $data['subscribed_ip'] = '';
84
 
85
- $result = ES_DB_Lists_Contacts::add_lists_contacts( $data );
86
  }
87
 
88
- return $result;
 
89
  }
90
 
91
- public static function delete_list_contacts( $contact_id, $list_ids ) {
92
- global $wpdb;
93
- $list_ids = implode( ',', $list_ids );
94
- $query = "DELETE FROM " . IG_LISTS_CONTACTS_TABLE . " WHERE contact_id = $contact_id AND list_id IN ($list_ids)";
95
- $res = $wpdb->get_results( $query );
 
 
 
 
 
 
96
 
97
- return $res;
98
- }
 
99
 
100
- public static function delete_contacts_from_list( $list_id, $contact_ids ) {
101
- global $wpdb;
102
- $contact_ids = implode( ',', $contact_ids );
103
- $query = "DELETE FROM " . IG_LISTS_CONTACTS_TABLE . " WHERE list_id = $list_id AND contact_id IN ($contact_ids)";
104
- $res = $wpdb->get_results( $query );
 
 
 
 
 
 
 
 
105
 
106
- return $res;
 
 
 
 
 
 
 
 
 
107
  }
108
 
109
- public static function import_contacts_into_lists( $list_id, $contacts ) {
110
- global $wpdb;
 
 
 
 
 
 
 
 
 
 
 
111
 
 
 
 
 
 
 
 
 
 
 
 
 
112
 
113
  if ( count( $contacts ) > 0 ) {
114
 
@@ -117,16 +395,13 @@ class ES_DB_Lists_Contacts {
117
  $emails[] = $contact['email'];
118
  }
119
 
120
- $contacts_str = "'" . implode( "', '", $emails ) . "'";
121
- $query = "SELECT id, email FROM " . IG_CONTACTS_TABLE . " WHERE email IN ( {$contacts_str} )";
122
- $results = $wpdb->get_results( $query, ARRAY_A );
123
- $email_id_map = array();
124
- foreach ( $results as $result ) {
125
- $email_id_map[ $result['email'] ] = $result['id'];
126
- }
127
 
128
- $values = array();
129
- foreach ( $contacts as $contact ) {
 
 
 
130
  $status = 'subscribed';
131
  $optin_type = IG_SINGLE_OPTIN;
132
  if ( $contact['status'] === 'Single Opt In' ) {
@@ -141,86 +416,139 @@ class ES_DB_Lists_Contacts {
141
  $status = 'unsubscribed';
142
  }
143
 
144
- array_push( $values, $list_id, $email_id_map[ $contact['email'] ], $status, $optin_type, $contact['subscribed_at'] );
145
- $place_holders[] = "( %d, %d, %s, %s, %s )"; /* In my case, i know they will always be integers */
146
- }
147
-
148
- $query = "INSERT INTO " . IG_LISTS_CONTACTS_TABLE . " (`list_id`, `contact_id`, `status`, `optin_type`, `subscribed_at` ) VALUES ";
149
- $query .= implode( ', ', $place_holders );
150
- $sql = $wpdb->prepare( $query, $values );
151
-
152
- if ( $wpdb->query( $sql ) ) {
153
- return true;
154
- } else {
155
- return false;
156
  }
157
 
 
158
  }
159
 
160
  return true;
161
  }
162
 
163
- public static function do_import_contacts_into_list( $list_id, $contacts, $status = 'subscribed', $optin_type = 1, $subscribed_at = null, $subscribed_ip = null, $unsubscribed_at = null, $unsubscribed_ip = null ) {
164
-
165
- global $wpdb;
166
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
167
  if ( count( $contacts ) > 0 ) {
168
-
169
  $values = array();
170
- foreach ( $contacts as $contact_id ) {
171
 
172
- array_push( $values, $list_id, $contact_id, $status, $optin_type, $subscribed_at, $subscribed_ip, $unsubscribed_at, $unsubscribed_ip );
173
- $place_holders[] = "( %d, %d, %s, %d, %s, %s, %s, %s )"; /* In my case, i know they will always be integers */
174
- }
175
 
176
- $query = "INSERT INTO " . IG_LISTS_CONTACTS_TABLE . " (`list_id`, `contact_id`, `status`, `optin_type`, `subscribed_at`, `subscribed_ip`, `unsubscribed_at`, `unsubscribed_ip` ) VALUES ";
177
- $query .= implode( ', ', $place_holders );
178
- $sql = $wpdb->prepare( $query, $values );
 
 
 
 
 
179
 
180
- if ( $wpdb->query( $sql ) ) {
181
- return true;
182
- } else {
183
- return false;
184
  }
185
 
 
186
  }
187
 
188
- return true;
189
-
190
  }
191
 
192
- public static function get_total_count_by_list( $list_id, $status = 'subscribed' ) {
 
 
 
 
 
 
 
 
 
 
 
193
  global $wpdb;
194
 
195
- if ( 'subscribed' === $status ) {
196
- $sql = "SELECT count(DISTINCT(contact_id)) FROM " . IG_LISTS_CONTACTS_TABLE . " WHERE list_id = %d AND status = 'subscribed'";
197
- } elseif ( 'unsubscribed' === $status ) {
198
- $sql = "SELECT count(DISTINCT(contact_id)) FROM " . IG_LISTS_CONTACTS_TABLE . " WHERE list_id = %d AND status = 'unsubscribed'";
199
- } elseif ( 'confirmed' === $status ) {
200
- $sql = "SELECT count(DISTINCT(contact_id)) FROM " . IG_LISTS_CONTACTS_TABLE . " WHERE list_id = %d AND status = 'subscribed' AND optin_type = 2 ";
201
- } elseif ( 'unconfirmed' === $status ) {
202
- $sql = "SELECT count(DISTINCT(contact_id)) FROM " . IG_LISTS_CONTACTS_TABLE . " WHERE list_id = %d AND status = 'unconfirmed'";
203
- } else {
204
- $sql = "SELECT count(DISTINCT(contact_id)) FROM " . IG_LISTS_CONTACTS_TABLE . " WHERE list_id = %d";
205
- }
206
 
207
- $total_count = $wpdb->get_var( $wpdb->prepare( $sql, $list_id ) );
 
 
 
 
 
 
208
 
209
- return $total_count;
210
 
 
211
  }
212
 
213
- public static function get_list_status_by_contact_ids( $contact_ids ) {
 
 
 
 
 
 
 
 
 
214
  global $wpdb;
215
 
216
- $lists_contacts_table = IG_LISTS_CONTACTS_TABLE;
217
 
218
- if ( is_array( $contact_ids ) ) {
219
- $contact_ids_str = "'" . implode( "', '", $contact_ids ) . "'";
220
- $query = "SELECT contact_id, list_id, status FROM {$lists_contacts_table} WHERE contact_id IN ($contact_ids_str)";
221
  }
222
 
223
- $results = $wpdb->get_results( $query, ARRAY_A );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224
 
225
  $map = array();
226
  if ( count( $results ) > 0 ) {
@@ -242,35 +570,39 @@ class ES_DB_Lists_Contacts {
242
  * @return bool|int
243
  *
244
  * @since 4.1.14
 
245
  */
246
- public static function edit_subscriber_status( $ids, $status ) {
247
  global $wpdb;
248
 
249
  if ( is_string( $ids ) ) {
250
  $ids = array( $ids );
251
  }
252
 
253
- $ids = esc_sql( $ids );
254
  $status = esc_sql( $status );
255
 
256
- $ids = implode( ', ', array_map( 'absint', $ids ) );
257
 
258
  $current_date = ig_get_current_date_time();
259
 
260
- $ig_lists_contact_table = IG_LISTS_CONTACTS_TABLE;
261
-
262
  if ( 'subscribed' === $status ) {
263
- $sql = "UPDATE {$ig_lists_contact_table} SET status = %s, subscribed_at = %s WHERE contact_id IN ($ids)";
264
  $query = $wpdb->prepare( $sql, array( $status, $current_date ) );
265
  } elseif ( 'unsubscribed' === $status ) {
266
- $sql = "UPDATE {$ig_lists_contact_table} SET status = %s, unsubscribed_at = %s WHERE contact_id IN ($ids)";
267
  $query = $wpdb->prepare( $sql, array( $status, $current_date ) );
268
  } elseif ( 'unconfirmed' === $status ) {
269
- $sql = "UPDATE {$ig_lists_contact_table} SET status = %s, optin_type = %d, subscribed_at = NULL, unsubscribed_at = NULL WHERE contact_id IN ($ids)";
270
  $query = $wpdb->prepare( $sql, array( $status, IG_DOUBLE_OPTIN ) );
271
  }
272
 
273
- return $wpdb->query( $query );
 
 
 
 
274
 
275
  }
276
 
@@ -283,32 +615,26 @@ class ES_DB_Lists_Contacts {
283
  * @return bool
284
  *
285
  * @since 4.1.14
 
286
  */
287
- public static function is_status_update_required( $ids = array(), $status = '' ) {
288
  global $wpdb;
289
 
290
- $response = false;
291
-
292
  if ( is_string( $ids ) ) {
293
  $ids = array( $ids );
294
  }
295
 
296
- $ids = esc_sql( $ids );
297
-
298
- $ig_lists_contact_table = IG_LISTS_CONTACTS_TABLE;
299
 
300
- $ids = implode( ', ', array_map( 'absint', $ids ) );
301
 
302
- $sql = "SELECT count(*) as total FROM {$ig_lists_contact_table} WHERE contact_id IN ($ids) && status != %s";
303
- $query = $wpdb->prepare( $sql, array( $status ) );
304
 
305
- $total = $wpdb->get_var( $query );
306
-
307
- if ( $total > 0 ) {
308
- $response = true;
309
  }
310
 
311
- return $response;
312
  }
313
 
314
  /**
@@ -319,25 +645,22 @@ class ES_DB_Lists_Contacts {
319
  * @return string|null
320
  *
321
  * @since 4.3.2
 
322
  */
323
- public static function get_total_subscribed_contacts( $days = 0 ) {
324
 
325
  global $wpdb;
326
 
327
- $ig_lists_contacts_table = IG_LISTS_CONTACTS_TABLE;
328
 
329
- $query = "SELECT COUNT(DISTINCT(`contact_id`)) FROM $ig_lists_contacts_table WHERE `status` = %s ";
330
 
331
- $args[] = 'subscribed';
332
-
333
- if ( 0 != $days ) {
334
- $days = esc_sql( $days );
335
- $where = " AND subscribed_at >= DATE_SUB(NOW(), INTERVAL %d DAY)";
336
- $query .= $where;
337
- $args[] = $days;
338
  }
339
 
340
- return $wpdb->get_var( $wpdb->prepare( $query, $args ) );
341
  }
342
 
343
  /**
@@ -348,25 +671,21 @@ class ES_DB_Lists_Contacts {
348
  * @return string|null
349
  *
350
  * @since 4.3.2
 
351
  */
352
- public static function get_total_unsubscribed_contacts( $days = 0 ) {
353
 
354
  global $wpdb;
355
 
356
- $ig_lists_contacts_table = IG_LISTS_CONTACTS_TABLE;
357
-
358
- $query = "SELECT COUNT(DISTINCT(`contact_id`)) FROM $ig_lists_contacts_table WHERE `status` = %s ";
359
 
360
- $args[] = 'unsubscribed';
361
 
362
- if ( 0 != $days ) {
363
- $days = esc_sql( $days );
364
- $where = " AND unsubscribed_at >= DATE_SUB(NOW(), INTERVAL %d DAY)";
365
- $query .= $where;
366
- $args[] = $days;
367
  }
368
 
369
- return $wpdb->get_var( $wpdb->prepare( $query, $args ) );
370
  }
371
-
372
  }
1
  <?php
2
+ // Exit if accessed directly
3
+ if ( ! defined( 'ABSPATH' ) ) {
4
+ exit;
5
+ }
6
 
7
+ class ES_DB_Lists_Contacts extends ES_DB {
8
+ /**
9
+ * @since 4.3.5
10
+ *
11
+ * @var $table_name
12
+ */
13
+ public $table_name;
14
+
15
+ /**
16
+ * @since 4.3.5
17
+ *
18
+ * @var $version
19
+ */
20
+ public $version;
21
 
22
+ /**
23
+ * @since 4.3.5
24
+ *
25
+ * @var $primary_key
26
+ */
27
+ public $primary_key;
28
+
29
+ /**
30
+ * ES_DB_Lists_Contacts constructor.
31
+ *
32
+ * @since 4.0.0
33
+ */
34
  public function __construct() {
35
+ global $wpdb;
36
 
37
+ parent::__construct();
38
+
39
+ $this->table_name = $wpdb->prefix . 'ig_lists_contacts';
40
+
41
+ $this->primary_key = 'id';
42
+
43
+ $this->version = '1.0';
44
  }
45
 
46
+ /**
47
+ * Get columns
48
+ *
49
+ * @return array
50
+ *
51
+ * @since 4.3.5
52
+ */
53
+ public function get_columns() {
54
+ return array(
55
+ 'id' => '%d',
56
+ 'list_id' => '%d',
57
+ 'contact_id' => '%d',
58
+ 'status' => '%s',
59
+ 'optin_type' => '%d',
60
+ 'subscribed_at' => '%s',
61
+ 'subscribed_ip' => '%s',
62
+ 'unsubscribed_at' => '%s',
63
+ 'unsubscribed_ip' => '%s',
64
+ );
65
+ }
66
+
67
+ /**
68
+ * Get default column values
69
+ *
70
+ * @since 4.3.5
71
+ */
72
+ public function get_column_defaults() {
73
+ return array(
74
+ 'list_id' => 0,
75
+ 'contact_id' => 0,
76
+ 'status' => 0,
77
+ 'optin_type' => 1,
78
+ 'subscribed_at' => null,
79
+ 'subscribed_ip' => null,
80
+ 'unsubscribed_at' => null,
81
+ 'unsubscribed_ip' => null,
82
+ );
83
+ }
84
+
85
+ /**
86
+ * Add single contacts to multiple lists
87
+ *
88
+ * @param array $contact_data
89
+ * @param array $list_ids
90
+ *
91
+ * @return bool
92
+ *
93
+ * @since 4.3.5
94
+ */
95
+ public function add_contact_to_lists( $contact_data = array(), $list_ids = array() ) {
96
+
97
+ if ( is_string( $list_ids ) ) {
98
+ $list_ids = array( $list_ids );
99
+ }
100
+
101
+ if ( is_array( $list_ids ) && count( $list_ids ) > 0 ) {
102
+
103
+ // Remove entry if it's already there in a list
104
+ $contact_id = ! empty( $contact_data['contact_id'] ) ? $contact_data['contact_id'] : 0;
105
+ $this->remove_contacts_from_lists( $contact_id, $list_ids );
106
+
107
+ foreach ( $list_ids as $list_id ) {
108
+ $contact_data['list_id'] = $list_id;
109
+ if ( ! $this->insert( $contact_data, 'list_contact' ) ) {
110
+ return false;
111
+ }
112
+ }
113
  }
114
+
115
+ return true;
116
  }
117
 
118
+ /**
119
+ * Prepare contact_data
120
+ *
121
+ * @param array $contact_ids
122
+ * @param $list_id
123
+ *
124
+ * @return array|bool
125
+ *
126
+ * @since 4.3.5
127
+ */
128
+ public function prepare_contact_data( $contact_ids = array(), $list_id ) {
129
+
130
+ if ( empty( $contact_ids ) || empty( $list_id ) ) {
131
+ return array();
132
+ }
133
+
134
+ $list_id = esc_sql( absint( $list_id ) );
135
+
136
+ $contact_data = array();
137
+ if ( 0 != $list_id ) {
138
+
139
+ $optin_type_option = get_option( 'ig_es_optin_type', true );
140
+
141
+ $optin_type = 1;
142
+ if ( in_array( $optin_type_option, array( 'double_opt_in', 'double_optin' ) ) ) {
143
+ $optin_type = 2;
144
+ }
145
+
146
+ $data = array(
147
+ 'list_id' => $list_id,
148
+ 'status' => 'subscribed',
149
+ 'optin_type' => $optin_type,
150
+ 'subscribed_at' => ig_get_current_date_time()
151
+ );
152
+
153
+ foreach ( $contact_ids as $contact_id ) {
154
+ $data['contact_id'] = $contact_id;
155
+ $contact_data[] = $data;
156
+ }
157
 
 
 
 
158
  }
 
159
 
160
+ return $contact_data;
161
  }
162
 
163
+ /**
164
+ * Add contacts to list
165
+ *
166
+ * @param array $contact_ids
167
+ * @param int $list_id
168
+ *
169
+ * @return bool
170
+ *
171
+ * @since 4.3.5
172
+ */
173
+ public function add_contacts_to_list( $contact_ids = array(), $list_id = 0 ) {
174
+
175
+ if ( empty( $list_id ) ) {
176
+ return false;
177
+ }
178
 
179
+ if ( is_string( $contact_ids ) ) {
180
+ $contact_ids = array( absint( $contact_ids ) );
181
+ }
182
+
183
+ $list_id = esc_sql( absint( $list_id ) );
184
+
185
+ if ( 0 != $list_id ) {
186
+ $this->remove_contacts_from_lists( $contact_ids, $list_id );
187
+
188
+ $contact_data = $this->prepare_contact_data( $contact_ids, $list_id );
189
+
190
+ return $this->bulk_insert( $contact_data );
191
+ }
192
+
193
+ return false;
194
  }
195
 
196
+ /**
197
+ * Move multiple contacts to specific list
198
+ *
199
+ * @param array $contact_ids
200
+ * @param int $list_id
201
+ *
202
+ * @return bool
203
+ *
204
+ * @since 4.3.5
205
+ */
206
+ public function move_contacts_to_list( $contact_ids = array(), $list_id = 0 ) {
207
+
208
+ if ( empty( $contact_ids ) ) {
209
+ return false;
210
+ }
211
+
212
+ $list_id = esc_sql( absint( $list_id ) );
213
+
214
+ if ( is_array( $contact_ids ) && count( $contact_ids ) > 0 ) {
215
+
216
+ $this->remove_contacts_from_lists( $contact_ids );
217
+
218
+ $contact_data = $this->prepare_contact_data( $contact_ids, $list_id );
219
+
220
+ return $this->bulk_insert( $contact_data );
221
+ }
222
+
223
+ return false;
224
+ }
225
+
226
+ /**
227
+ * @param $id
228
+ * @param string $status
229
+ *
230
+ * @return array
231
+ *
232
+ * @since 4.0.0
233
+ * @since 4.3.5 Removed Static Method
234
+ */
235
+ public function get_list_ids_by_contact( $contact_id = 0, $status = '' ) {
236
  global $wpdb;
237
 
238
+ if ( empty( $contact_id ) ) {
239
+ return array();
240
+ }
241
 
242
+ $where = "contact_id = %d";
243
+ $args[] = esc_sql( $contact_id );
244
 
245
+ if ( ! empty( $status ) ) {
246
+ $where .= " AND status = %s";
247
+ $args[] = esc_sql( $status );
 
 
248
  }
249
 
250
+ $where = $wpdb->prepare( $where, $args );
251
+
252
+ return $this->get_column_by_condition( 'list_id', $where );
253
  }
254
 
255
+ /**
256
+ * @param int $contact_id
257
+ *
258
+ * @return array
259
+ *
260
+ * @since 4.0.0
261
+ * @since 4.3.5 Removed Static method. Call get_columns_map method
262
+ */
263
+ public function get_list_contact_status_map( $contact_id = 0 ) {
264
+
265
  global $wpdb;
 
 
266
 
267
+ if ( 0 == $contact_id ) {
268
+ return array();
269
+ }
270
+
271
+ $where = "contact_id = %d";
272
+ $where = $wpdb->prepare( $where, $contact_id );
273
 
274
+ return $this->get_columns_map( 'list_id', 'status', $where );
275
+ }
276
+
277
+ /**
278
+ * Update lists of contact
279
+ *
280
+ * @param int $contact_id
281
+ * @param array $list_ids
282
+ *
283
+ * @return bool
284
+ *
285
+ * @since 4.3.5
286
+ */
287
+ public function update_contact_lists( $contact_id = 0, $list_ids = array() ) {
288
+
289
+ if ( empty( $contact_id ) || empty( $list_ids ) ) {
290
+ return false;
291
+ }
292
+
293
+ if ( is_string( $list_ids ) ) {
294
+ $list_ids = array( absint( $list_ids ) );
295
  }
296
 
297
+ $contact_id = esc_sql( $contact_id );
298
+ $list_ids = esc_sql( $list_ids );
299
+
300
+ $this->remove_contacts_from_lists( $contact_id );
301
+
302
  if ( ! empty( $list_ids ) ) {
303
+ $optin_type_option = get_option( 'ig_es_optin_type', true );
304
+
305
+ $optin_type = 1;
306
+ if ( in_array( $optin_type_option, array( 'double_opt_in', 'double_optin' ) ) ) {
307
+ $optin_type = 2;
308
+ }
309
+
310
  $data['contact_id'] = $contact_id;
311
  $data['status'] = 'subscribed';
312
  $data['optin_type'] = $optin_type;
313
  $data['subscribed_at'] = ig_get_current_date_time();
 
314
 
315
+ return ES()->lists_contacts_db->add_contact_to_lists( $data, $list_ids );
316
  }
317
 
318
+ return false;
319
+
320
  }
321
 
322
+ /**
323
+ * Remove Contacts from lists
324
+ *
325
+ * @param array $contact_id
326
+ * @param array $list_ids
327
+ *
328
+ * @return bool
329
+ *
330
+ * @since 4.3.5
331
+ */
332
+ public function remove_contacts_from_lists( $contact_ids = array(), $list_ids = array() ) {
333
 
334
+ if ( is_string( $contact_ids ) ) {
335
+ $contact_ids = array( absint( $contact_ids ) );
336
+ }
337
 
338
+ if ( is_string( $list_ids ) ) {
339
+ $list_ids = array( absint( $list_ids ) );
340
+ }
341
+
342
+ $where = '';
343
+ if ( is_array( $contact_ids ) && count( $contact_ids ) > 0 ) {
344
+
345
+ $contact_ids_str = $this->prepare_for_in_query( $contact_ids );
346
+
347
+ $where = "contact_id IN ($contact_ids_str)";
348
+ }
349
+
350
+ if ( is_array( $list_ids ) && count( $list_ids ) > 0 ) {
351
 
352
+ $list_ids_str = $this->prepare_for_in_query( $list_ids );
353
+
354
+ if ( ! empty( $where ) ) {
355
+ $where .= " AND ";
356
+ }
357
+
358
+ $where .= "list_id IN ($list_ids_str)";
359
+ }
360
+
361
+ return $this->delete_by_condition( $where );
362
  }
363
 
364
+ /**
365
+ * Remove all contacts from specific list
366
+ *
367
+ * @param int $list_id
368
+ * @param array $contact_ids
369
+ *
370
+ * @return bool
371
+ *
372
+ * @since 4.3.5
373
+ */
374
+ public function remove_all_contacts_from_list( $list_id = 0 ) {
375
+ return $this->remove_contacts_from_lists( array(), $list_id );
376
+ }
377
 
378
+ /**
379
+ * Import contacts into lists
380
+ *
381
+ * @param int $list_id
382
+ * @param array $contacts
383
+ *
384
+ * @return bool
385
+ *
386
+ * @since 4.0.0
387
+ * @since 4.3.5
388
+ */
389
+ public function import_contacts_into_lists( $list_id = 0, $contacts = array() ) {
390
 
391
  if ( count( $contacts ) > 0 ) {
392
 
395
  $emails[] = $contact['email'];
396
  }
397
 
398
+ $contacts_str = $this->prepare_for_in_query( $emails );
 
 
 
 
 
 
399
 
400
+ $where = "email IN ($contacts_str)";
401
+
402
+ $email_id_map = $this->get_columns_map( 'email', 'id', $where );
403
+
404
+ foreach ( $contacts as $key => $contact ) {
405
  $status = 'subscribed';
406
  $optin_type = IG_SINGLE_OPTIN;
407
  if ( $contact['status'] === 'Single Opt In' ) {
416
  $status = 'unsubscribed';
417
  }
418
 
419
+ $contact[ $key ]['list_id'] = $list_id;
420
+ $contact[ $key ]['contact_id'] = $email_id_map[ $contact['email'] ];
421
+ $contact[ $key ]['status'] = $status;
422
+ $contact[ $key ]['optin_type'] = $optin_type;
423
+ $contact[ $key ]['subscribed_at'] = $contact['subscribed_at'];
 
 
 
 
 
 
 
424
  }
425
 
426
+ return $this->bulk_insert( $contacts );
427
  }
428
 
429
  return true;
430
  }
431
 
432
+ /**
433
+ * Add contacts into lists_contacts table
434
+ *
435
+ * @param int $list_id
436
+ * @param array $contacts
437
+ * @param string $status
438
+ * @param int $optin_type
439
+ * @param null $subscribed_at
440
+ * @param null $subscribed_ip
441
+ * @param null $unsubscribed_at
442
+ * @param null $unsubscribed_ip
443
+ *
444
+ * @return bool
445
+ *
446
+ * @since 4.0.0
447
+ * @since 4.3.5 Used bulk_insert method
448
+ */
449
+ public function do_import_contacts_into_list( $list_id = 0, $contacts = array(), $status = 'subscribed', $optin_type = 1, $subscribed_at = null, $subscribed_ip = null, $unsubscribed_at = null, $unsubscribed_ip = null ) {
450
  if ( count( $contacts ) > 0 ) {
 
451
  $values = array();
 
452
 
453
+ $key = 0;
454
+ foreach ( $contacts as $contact_id ) {
 
455
 
456
+ $values[ $key ]['contact_id'] = $contact_id;
457
+ $values[ $key ]['list_id'] = $list_id;
458
+ $values[ $key ]['status'] = $status;
459
+ $values[ $key ]['optin_type'] = $optin_type;
460
+ $values[ $key ]['subscribed_at'] = $subscribed_at;
461
+ $values[ $key ]['subscribed_ip'] = $subscribed_ip;
462
+ $values[ $key ]['unsubscribed_at'] = $unsubscribed_at;
463
+ $values[ $key ]['unsubscribed_ip'] = $unsubscribed_ip;
464
 
465
+ $key ++;
 
 
 
466
  }
467
 
468
+ return $this->bulk_insert( $values );
469
  }
470
 
471
+ return false;
 
472
  }
473
 
474
+ /**
475
+ * Get total contacts based on list & status
476
+ *
477
+ * @param int $list_id
478
+ * @param string $status
479
+ *
480
+ * @return string|null
481
+ *
482
+ * @since 4.0.0
483
+ * @since 4.3.5 Removed static call
484
+ */
485
+ public function get_total_count_by_list( $list_id = 0, $status = 'subscribed' ) {
486
  global $wpdb;
487
 
488
+ $list_id = esc_sql( $list_id );
489
+ $status = esc_sql( $status );
 
 
 
 
 
 
 
 
 
490
 
491
+ $where = "list_id = %d";
492
+ if ( ! empty( $status ) ) {
493
+ $where .= " AND status = %s";
494
+ if ( 'confirmed' === $status ) {
495
+ $where .= " AND optin_type = 2";
496
+ }
497
+ }
498
 
499
+ $where = $wpdb->prepare( $where, $list_id, $status );
500
 
501
+ return $this->get_total_contacts( $where );
502
  }
503
 
504
+ /**
505
+ * Get total distinct contacts by condition
506
+ *
507
+ * @param string $where
508
+ *
509
+ * @return string|null
510
+ *
511
+ * @since 4.3.5
512
+ */
513
+ public function get_total_contacts( $where = '' ) {
514
  global $wpdb;
515
 
516
+ $query = "SELECT count(DISTINCT(contact_id)) FROM $this->table_name";
517
 
518
+ if ( ! empty( $where ) ) {
519
+ $query .= " WHERE $where";
 
520
  }
521
 
522
+ return $wpdb->get_var( $query );
523
+ }
524
+
525
+ /**
526
+ * Get List => Status map by contact_ids
527
+ *
528
+ * @param array $contact_ids
529
+ *
530
+ * @return array
531
+ *
532
+ * @since 4.0.0
533
+ * @since 4.3.5 Used prepare_for_in_query & get_columns_by_condition method
534
+ */
535
+ public function get_list_status_by_contact_ids( $contact_ids = array() ) {
536
+
537
+ if ( empty( $contact_ids ) ) {
538
+ return array();
539
+ }
540
+
541
+ if ( is_string( $contact_ids ) ) {
542
+ $contact_ids = array( $contact_ids );
543
+ }
544
+
545
+ $contact_ids_str = $this->prepare_for_in_query( $contact_ids );
546
+
547
+ $where = "contact_id IN ($contact_ids_str)";
548
+
549
+ $columns = array( 'contact_id', 'list_id', 'status' );
550
+
551
+ $results = $this->get_columns_by_condition( $columns, $where );
552
 
553
  $map = array();
554
  if ( count( $results ) > 0 ) {
570
  * @return bool|int
571
  *
572
  * @since 4.1.14
573
+ * @since 4.3.5 Removed static call
574
  */
575
+ public function edit_subscriber_status( $ids = array(), $status = '' ) {
576
  global $wpdb;
577
 
578
  if ( is_string( $ids ) ) {
579
  $ids = array( $ids );
580
  }
581
 
582
+ $ids = array_map( 'absint', $ids );
583
  $status = esc_sql( $status );
584
 
585
+ $ids = $this->prepare_for_in_query( $ids );
586
 
587
  $current_date = ig_get_current_date_time();
588
 
589
+ $query = '';
 
590
  if ( 'subscribed' === $status ) {
591
+ $sql = "UPDATE $this->table_name SET status = %s, subscribed_at = %s WHERE contact_id IN ($ids)";
592
  $query = $wpdb->prepare( $sql, array( $status, $current_date ) );
593
  } elseif ( 'unsubscribed' === $status ) {
594
+ $sql = "UPDATE $this->table_name SET status = %s, unsubscribed_at = %s WHERE contact_id IN ($ids)";
595
  $query = $wpdb->prepare( $sql, array( $status, $current_date ) );
596
  } elseif ( 'unconfirmed' === $status ) {
597
+ $sql = "UPDATE $this->table_name SET status = %s, optin_type = %d, subscribed_at = NULL, unsubscribed_at = NULL WHERE contact_id IN ($ids)";
598
  $query = $wpdb->prepare( $sql, array( $status, IG_DOUBLE_OPTIN ) );
599
  }
600
 
601
+ if ( $query ) {
602
+ return $wpdb->query( $query );
603
+ }
604
+
605
+ return false;
606
 
607
  }
608
 
615
  * @return bool
616
  *
617
  * @since 4.1.14
618
+ * @since 4.3.5 Removed static call
619
  */
620
+ public function is_status_update_required( $ids = array(), $status = '' ) {
621
  global $wpdb;
622
 
 
 
623
  if ( is_string( $ids ) ) {
624
  $ids = array( $ids );
625
  }
626
 
627
+ $ids = array_map( 'absint', $ids );
 
 
628
 
629
+ $ids = $this->prepare_for_in_query( $ids );
630
 
631
+ $where = $wpdb->prepare( "contact_id IN ($ids) && status != %s", $status );
 
632
 
633
+ if ( $this->count( $where ) ) {
634
+ return true;
 
 
635
  }
636
 
637
+ return false;
638
  }
639
 
640
  /**
645
  * @return string|null
646
  *
647
  * @since 4.3.2
648
+ * @since 4.3.5 Removed static call
649
  */
650
+ public function get_total_subscribed_contacts( $days = 0 ) {
651
 
652
  global $wpdb;
653
 
654
+ $where = $wpdb->prepare( "status = %s", 'subscribed' );
655
 
656
+ $days = absint( $days );
657
 
658
+ if ( $days > 0 ) {
659
+ $days = esc_sql( $days );
660
+ $where .= $wpdb->prepare( " AND subscribed_at >= DATE_SUB(NOW(), INTERVAL %d DAY)", $days );
 
 
 
 
661
  }
662
 
663
+ return $this->get_total_contacts( $where );
664
  }
665
 
666
  /**
671
  * @return string|null
672
  *
673
  * @since 4.3.2
674
+ * @since 4.3.5 Removed static call
675
  */
676
+ public function get_total_unsubscribed_contacts( $days = 0 ) {
677
 
678
  global $wpdb;
679
 
680
+ $where = $wpdb->prepare( "status = %s", 'unsubscribed' );
 
 
681
 
682
+ $days = absint( $days );
683
 
684
+ if ( $days > 0 ) {
685
+ $days = esc_sql( $days );
686
+ $where .= $wpdb->prepare( " AND unsubscribed_at >= DATE_SUB(NOW(), INTERVAL %d DAY)", $days );
 
 
687
  }
688
 
689
+ return $this->get_total_contacts( $where );
690
  }
 
691
  }
lite/includes/db/class-es-db.php CHANGED
@@ -169,6 +169,56 @@ abstract class ES_DB {
169
  }
170
  }
171
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172
  /**
173
  * Insert a new row
174
  *
@@ -300,7 +350,7 @@ abstract class ES_DB {
300
 
301
  $row_ids_str = $this->prepare_for_in_query( $row_ids );
302
 
303
- $where = "$this->primary_key IN ($row_ids_str)";
304
 
305
  if ( false === $this->delete_by_condition( $where ) ) {
306
  return false;
@@ -387,12 +437,13 @@ abstract class ES_DB {
387
  * @param string $type
388
  *
389
  * @since 4.2.1
 
390
  */
391
- public function bulk_insert( $values, $length = 100, $type = '' ) {
392
  global $wpdb;
393
 
394
  if ( ! is_array( $values ) ) {
395
- return;
396
  }
397
 
398
  // Get the first value from an array to check data structure
@@ -417,7 +468,8 @@ abstract class ES_DB {
417
  $data = wp_parse_args( $data, $this->get_column_defaults() );
418
 
419
  $data_keys = array_keys( $data );
420
- $fields = array_merge( array_flip( $data_keys ), $column_formats );
 
421
 
422
  // Convert Batches into smaller chunk
423
  $batches = array_chunk( $values, $length );
@@ -430,19 +482,24 @@ abstract class ES_DB {
430
 
431
  $formats = array();
432
  foreach ( $column_formats as $column => $format ) {
433
- $final_values[] = $value[ $column ];
434
  $formats[] = $format;
435
  }
436
 
437
  $place_holders[] = "( " . implode( ', ', $formats ) . " )";
438
  $fields_str = "`" . implode( "`, `", $fields ) . "`";
439
- $query = "INSERT INTO $this->table_name({$fields_str}) VALUES ";
440
- $query .= implode( ', ', $place_holders );
441
- $sql = $wpdb->prepare( $query, $final_values );
442
 
443
- $wpdb->query( $sql );
 
 
 
 
 
444
  }
445
  }
 
 
446
  }
447
 
448
  /**
@@ -479,26 +536,42 @@ abstract class ES_DB {
479
  * @return array
480
  *
481
  * @since 4.2.2
 
482
  */
483
  public function get_id_name_map( $where = '' ) {
484
- global $wpdb;
485
-
486
- $query = "SELECT $this->primary_key, name FROM $this->table_name";
487
 
488
- if ( ! empty( $where ) ) {
489
- $query .= " WHERE $where";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
490
  }
491
 
492
- $results = $wpdb->get_results( $query, ARRAY_A );
 
 
493
 
494
- $id_name_map = array();
495
  if ( count( $results ) > 0 ) {
496
  foreach ( $results as $result ) {
497
- $id_name_map[ $result['id'] ] = $result['name'];
498
  }
499
  }
500
 
501
- return $id_name_map;
502
  }
503
 
504
  public static function prepare_data( $data, $column_formats, $column_defaults, $insert = true ) {
169
  }
170
  }
171
 
172
+ /**
173
+ * Get column based on where condition
174
+ *
175
+ * @param $column
176
+ * @param string $where
177
+ *
178
+ * @return array
179
+ *
180
+ * @since 4.3.5
181
+ */
182
+ public function get_column_by_condition( $column, $where = '' ) {
183
+ global $wpdb;
184
+
185
+ $column = esc_sql( $column );
186
+
187
+ if ( ! empty( $where ) ) {
188
+ return $wpdb->get_col( "SELECT $column FROM $this->table_name WHERE $where" );
189
+ } else {
190
+ return $wpdb->get_col( "SELECT $column FROM $this->table_name" );
191
+ }
192
+ }
193
+
194
+ /**
195
+ * Select few columns based on condition
196
+ *
197
+ * @param array $columns
198
+ * @param string $where
199
+ *
200
+ * @return array|object|null
201
+ *
202
+ * @since 4.3.5
203
+ */
204
+ public function get_columns_by_condition( $columns = array(), $where = '', $output = ARRAY_A ) {
205
+ global $wpdb;
206
+
207
+ if ( ! is_array( $columns ) ) {
208
+ return array();
209
+ }
210
+
211
+ $columns = esc_sql( $columns );
212
+
213
+ $columns = implode( ', ', $columns );
214
+
215
+ if ( ! empty( $where ) ) {
216
+ return $wpdb->get_results( "SELECT $columns FROM $this->table_name WHERE $where", $output );
217
+ } else {
218
+ return $wpdb->get_results( "SELECT $columns FROM $this->table_name", $output );
219
+ }
220
+ }
221
+
222
  /**
223
  * Insert a new row
224
  *
350
 
351
  $row_ids_str = $this->prepare_for_in_query( $row_ids );
352
 
353
+ $where = "$this->primary_key IN( $row_ids_str )";
354
 
355
  if ( false === $this->delete_by_condition( $where ) ) {
356
  return false;
437
  * @param string $type
438
  *
439
  * @since 4.2.1
440
+ * @since 4.3.5 Fixed issues and started using it.
441
  */
442
+ public function bulk_insert( $values, $length = 100 ) {
443
  global $wpdb;
444
 
445
  if ( ! is_array( $values ) ) {
446
+ return false;
447
  }
448
 
449
  // Get the first value from an array to check data structure
468
  $data = wp_parse_args( $data, $this->get_column_defaults() );
469
 
470
  $data_keys = array_keys( $data );
471
+
472
+ $fields = array_keys( array_merge( array_flip( $data_keys ), $column_formats ) );
473
 
474
  // Convert Batches into smaller chunk
475
  $batches = array_chunk( $values, $length );
482
 
483
  $formats = array();
484
  foreach ( $column_formats as $column => $format ) {
485
+ $final_values[] = isset( $value[ $column ] ) ? $value[ $column ] : $data[ $column ]; // set default if we don't have
486
  $formats[] = $format;
487
  }
488
 
489
  $place_holders[] = "( " . implode( ', ', $formats ) . " )";
490
  $fields_str = "`" . implode( "`, `", $fields ) . "`";
491
+ }
 
 
492
 
493
+ $query = "INSERT INTO $this->table_name ({$fields_str}) VALUES ";
494
+ $query .= implode( ', ', $place_holders );
495
+ $sql = $wpdb->prepare( $query, $final_values );
496
+
497
+ if ( ! $wpdb->query( $sql ) ) {
498
+ return false;
499
  }
500
  }
501
+
502
+ return true;
503
  }
504
 
505
  /**
536
  * @return array
537
  *
538
  * @since 4.2.2
539
+ * @since 4.3.5 Used get_columns_map method
540
  */
541
  public function get_id_name_map( $where = '' ) {
542
+ return $this->get_columns_map( $this->primary_key, 'name', $where );
543
+ }
 
544
 
545
+ /**
546
+ * Get map of two columns
547
+ *
548
+ * e.g array($column_1 => $column_2)
549
+ *
550
+ * @param string $column_1
551
+ * @param string $column_2
552
+ * @param string $where
553
+ *
554
+ * @return array
555
+ *
556
+ * @since 4.3.5
557
+ */
558
+ public function get_columns_map( $column_1 = '', $column_2 = '', $where = '' ) {
559
+ if ( empty( $column_1 ) || empty( $column_2 ) ) {
560
+ return array();
561
  }
562
 
563
+ $columns = array( $column_1, $column_2 );
564
+
565
+ $results = $this->get_columns_by_condition( $columns, $where );
566
 
567
+ $map = array();
568
  if ( count( $results ) > 0 ) {
569
  foreach ( $results as $result ) {
570
+ $map[ $result[ $column_1 ] ] = $result[ $column_2 ];
571
  }
572
  }
573
 
574
+ return $map;
575
  }
576
 
577
  public static function prepare_data( $data, $column_formats, $column_defaults, $insert = true ) {
lite/includes/es-backward.php CHANGED
@@ -65,7 +65,6 @@ class es_cls_dbquery {
65
  $list_id = ! empty( $list_data['id'] ) ? $list_data['id'] : 1;
66
  $list_ids = array( $list_id );
67
  $list_contact_data = array(
68
- 'list_id' => $list_ids,
69
  'contact_id' => $contact_id,
70
  'status' => $status,
71
  'optin_type' => $optin_type,
@@ -73,8 +72,7 @@ class es_cls_dbquery {
73
  'subscribed_ip' => ig_es_get_ip()
74
  );
75
 
76
- ES_DB_Lists_Contacts::delete_list_contacts( $contact_id, $list_ids );
77
- ES_DB_Lists_Contacts::add_lists_contacts( $list_contact_data );
78
 
79
  $list_name = ES_Common::prepare_list_name_by_ids( $list_ids );
80
 
65
  $list_id = ! empty( $list_data['id'] ) ? $list_data['id'] : 1;
66
  $list_ids = array( $list_id );
67
  $list_contact_data = array(
 
68
  'contact_id' => $contact_id,
69
  'status' => $status,
70
  'optin_type' => $optin_type,
72
  'subscribed_ip' => ig_es_get_ip()
73
  );
74
 
75
+ ES()->lists_contacts_db->add_contact_to_lists( $list_contact_data, $list_id );
 
76
 
77
  $list_name = ES_Common::prepare_list_name_by_ids( $list_ids );
78
 
lite/includes/feedback/class-ig-feedback.php CHANGED
@@ -12,11 +12,11 @@ if ( ! class_exists( 'IG_Feedback_V_1_0_11' ) ) {
12
  * There are different types of feedabck widget like Stars, Emoji, Thubms Up/ Down, Number etc.
13
  *
14
  * @class IG_Feedback_V_1_0_11
15
- * @package feedback
16
  * @copyright Copyright (c) 2019, Icegram
17
  * @license https://opensource.org/licenses/gpl-license GNU Public License
18
  * @author Icegram
19
- * @since 1.0.0
20
  */
21
  class IG_Feedback_V_1_0_11 {
22
 
12
  * There are different types of feedabck widget like Stars, Emoji, Thubms Up/ Down, Number etc.
13
  *
14
  * @class IG_Feedback_V_1_0_11
15
+ * @since 1.0.0
16
  * @copyright Copyright (c) 2019, Icegram
17
  * @license https://opensource.org/licenses/gpl-license GNU Public License
18
  * @author Icegram
19
+ * @package feedback
20
  */
21
  class IG_Feedback_V_1_0_11 {
22
 
lite/public/class-email-subscribers-public.php CHANGED
@@ -138,7 +138,7 @@ class Email_Subscribers_Public {
138
 
139
  if ( ! empty( $hash ) ) {
140
 
141
- $data = ig_es_decode_request_data( $hash );
142
  $db_id = ! empty( $data['contact_id'] ) ? (int) $data['contact_id'] : 0;
143
  $email = ! empty( $data['email'] ) ? $data['email'] : '';
144
  $guid = ! empty( $data['guid'] ) ? $data['guid'] : '';
@@ -164,12 +164,12 @@ class Email_Subscribers_Public {
164
  $status = $subject = $content = '';
165
  $unsubscribed = 0;
166
  $status = ( $option === 'optin' ) ? 'subscribed' : 'unsubscribed';
167
- $is_status_update_required = ES_DB_Lists_Contacts::is_status_update_required( $ids, $status );
168
  if ( $is_status_update_required ) {
169
  if ( $option === 'optin' ) {
170
  $message = get_option( 'ig_es_subscription_success_message' );
171
  ES()->contacts_db->edit_contact_global_status( $ids, $unsubscribed );
172
- ES_DB_Lists_Contacts::edit_subscriber_status( $ids, $status );
173
  //send welcome email
174
  $contact = ES()->contacts_db->get_contacts_email_name_map( array( $email ) );
175
  $data = array(
@@ -213,13 +213,13 @@ class Email_Subscribers_Public {
213
  do_action( 'ig_es_confirm_unsubscription' );
214
  }
215
 
216
- $unsubscribe_lists = ES_DB_Lists_Contacts::get_list_ids_by_contact( $db_id, 'subscribed' );
217
  }
218
 
219
  //update list status
220
  ES()->contacts_db->edit_list_contact_status( array( $db_id ), $unsubscribe_lists, 'unsubscribed' );
221
  //check if all list have same status
222
- $list_ids = ES_DB_Lists_Contacts::get_list_ids_by_contact( $db_id, 'subscribed' );
223
  if ( count( $list_ids ) == 0 ) {
224
  //update global
225
  ES()->contacts_db->edit_contact_global_status( array( $db_id ), 1 );
@@ -307,7 +307,6 @@ class Email_Subscribers_Public {
307
  $optin_type = ( $optin_type === 'double_opt_in' ) ? 2 : 1;
308
  $list_id = ! empty( $list_id ) ? $list_id : 1;
309
  $list_contact_data = array(
310
- 'list_id' => array( $list_id ),
311
  'contact_id' => $contact_id,
312
  'status' => 'subscribed',
313
  'subscribed_at' => ig_get_current_date_time(),
@@ -315,9 +314,9 @@ class Email_Subscribers_Public {
315
  'subscribed_ip' => null
316
  );
317
 
318
- ES_DB_Lists_Contacts::delete_list_contacts( $contact_id, array( $list_id ) );
319
 
320
- $result = ES_DB_Lists_Contacts::add_lists_contacts( $list_contact_data );
321
  }
322
 
323
  }
138
 
139
  if ( ! empty( $hash ) ) {
140
 
141
+ $data = ig_es_decode_request_data( $hash );
142
  $db_id = ! empty( $data['contact_id'] ) ? (int) $data['contact_id'] : 0;
143
  $email = ! empty( $data['email'] ) ? $data['email'] : '';
144
  $guid = ! empty( $data['guid'] ) ? $data['guid'] : '';
164
  $status = $subject = $content = '';
165
  $unsubscribed = 0;
166
  $status = ( $option === 'optin' ) ? 'subscribed' : 'unsubscribed';
167
+ $is_status_update_required = ES()->lists_contacts_db->is_status_update_required( $ids, $status );
168
  if ( $is_status_update_required ) {
169
  if ( $option === 'optin' ) {
170
  $message = get_option( 'ig_es_subscription_success_message' );
171
  ES()->contacts_db->edit_contact_global_status( $ids, $unsubscribed );
172
+ ES()->lists_contacts_db->edit_subscriber_status( $ids, $status );
173
  //send welcome email
174
  $contact = ES()->contacts_db->get_contacts_email_name_map( array( $email ) );
175
  $data = array(
213
  do_action( 'ig_es_confirm_unsubscription' );
214
  }
215
 
216
+ $unsubscribe_lists = ES()->lists_contacts_db->get_list_ids_by_contact( $db_id, 'subscribed' );
217
  }
218
 
219
  //update list status
220
  ES()->contacts_db->edit_list_contact_status( array( $db_id ), $unsubscribe_lists, 'unsubscribed' );
221
  //check if all list have same status
222
+ $list_ids = ES()->lists_contacts_db->get_list_ids_by_contact( $db_id, 'subscribed' );
223
  if ( count( $list_ids ) == 0 ) {
224
  //update global
225
  ES()->contacts_db->edit_contact_global_status( array( $db_id ), 1 );
307
  $optin_type = ( $optin_type === 'double_opt_in' ) ? 2 : 1;
308
  $list_id = ! empty( $list_id ) ? $list_id : 1;
309
  $list_contact_data = array(
 
310
  'contact_id' => $contact_id,
311
  'status' => 'subscribed',
312
  'subscribed_at' => ig_get_current_date_time(),
314
  'subscribed_ip' => null
315
  );
316
 
317
+ ES()->lists_contacts_db->remove_contacts_from_lists( $contact_id, $list_id );
318
 
319
+ ES()->lists_contacts_db->add_contact_to_lists( $list_contact_data, $list_id );
320
  }
321
 
322
  }
lite/public/partials/class-es-shortcode.php CHANGED
@@ -246,7 +246,7 @@ class ES_Shortcode {
246
  $i = 0;
247
 
248
  if ( ! empty( $contact_id ) ) {
249
- $list_contact_status_map = ES_DB_Lists_Contacts::get_list_contact_status_map( $contact_id );
250
  }
251
 
252
  foreach ( $lists as $list_id => $list_name ) {
246
  $i = 0;
247
 
248
  if ( ! empty( $contact_id ) ) {
249
+ $list_contact_status_map = ES()->lists_contacts_db->get_list_contact_status_map( $contact_id );
250
  }
251
 
252
  foreach ( $lists as $list_id => $list_name ) {
readme.txt CHANGED
@@ -5,7 +5,7 @@ Author URI: https://www.icegram.com/
5
  Tags: subscription, newsletter, email marketing, post notification, email newsletter form, email signup, email widget, newsletter signup, subscribe, subscription form, bulk emails, signup form, list builder, lead generation, welcome email, contacts
6
  Requires at least: 3.9
7
  Tested up to: 5.3
8
- Stable tag: 4.3.4.1
9
  License: GPLv3
10
  License URI: http://www.gnu.org/licenses
11
 
@@ -300,6 +300,11 @@ Refer [here](https://www.icegram.com/documentation/es-faq/).
300
 
301
  == Changelog ==
302
 
 
 
 
 
 
303
  **4.3.4.1 (29.11.2019)**
304
  * Fix: Delete Campaigns Permanently issue
305
  * Fix: Security issues
5
  Tags: subscription, newsletter, email marketing, post notification, email newsletter form, email signup, email widget, newsletter signup, subscribe, subscription form, bulk emails, signup form, list builder, lead generation, welcome email, contacts
6
  Requires at least: 3.9
7
  Tested up to: 5.3
8
+ Stable tag: 4.3.5
9
  License: GPLv3
10
  License URI: http://www.gnu.org/licenses
11
 
300
 
301
  == Changelog ==
302
 
303
+ **4.3.5 (04.12.2019)**
304
+ * New: Added setting to set cron interval
305
+ * New: Added setting to set maximum emails to send on every cron request
306
+ * Fix: Illegal string offset ‘es_registered’ warning
307
+
308
  **4.3.4.1 (29.11.2019)**
309
  * Fix: Delete Campaigns Permanently issue
310
  * Fix: Security issues