Email Subscribers & Newsletters - Version 4.1.7

Version Description

(15.07.2019) = * Update: Now, able to sort reports by Subject, Status, Start Date, End Date & Total Contacts * Update: Now, able to sort forms by Name & Created date * Update: Now, email template will pick up the latest content while email sending * Fix: Importing issue * Fix: Migration issue * Fix: Fixed Vulnerability

Download this release

Release Info

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

Code changes from version 4.1.6 to 4.1.7

admin/images/email-subscribers-pricing-back.png ADDED
Binary file
admin/images/email-subscribers-pricing.png CHANGED
Binary file
admin/partials/pricing.php CHANGED
@@ -38,17 +38,37 @@ if ( ! defined( 'ABSPATH' ) ) {
38
  .button.green-light{
39
  background: #4fad43;
40
  }
 
 
 
 
 
 
 
 
 
41
  @media only screen and (max-width: 1362px) {
42
  .es-starter-gopro img{
43
  width: 90%;
44
  }
 
 
 
45
  }
46
  </style>
47
  <div class="es-starter-gopro">
48
- <img class="ig-es-pricing-img" src="<?php echo EMAIL_SUBSCRIBERS_URL.'/admin/images/email-subscribers-pricing.png' ?>"/><br/>
49
- <a class="button large green-light" href="https://www.icegram.com/?buy-now=409349&qty=1&page=6&with-cart=0&utm_source=in_app&utm_medium=go_pro_monthly&utm_campaign=es_upsale" target="_blank"> <?php _e('Get Started @ $9/month', 'email-subscribers') ?></a>
50
- <div class="mid-or">OR</div>
51
- <a class="button large green" href="https://www.icegram.com/?buy-now=407190&qty=1&page=6&with-cart=0&utm_source=in_app&utm_medium=go_pro_yearly&utm_campaign=es_upsale" target="_blank"> <?php _e('Get Started @ $49/year', 'email-subscribers') ?></a>
 
 
 
 
 
 
 
 
52
  </div>
53
 
54
 
38
  .button.green-light{
39
  background: #4fad43;
40
  }
41
+ .es-btn-wrapper{
42
+ display: inline-block;
43
+ }
44
+ .es-monthly{
45
+ font-size: 1.2em; margin-top: 1.2em;
46
+ }
47
+ .es-monthly-wrapper{
48
+ width: 80%; padding-top: 0.7em;
49
+ }
50
  @media only screen and (max-width: 1362px) {
51
  .es-starter-gopro img{
52
  width: 90%;
53
  }
54
+ .es-monthly-wrapper{
55
+ width: 65%;
56
+ }
57
  }
58
  </style>
59
  <div class="es-starter-gopro">
60
+ <img class="ig-es-pricing-img" src="<?php echo EMAIL_SUBSCRIBERS_URL.'/admin/images/email-subscribers-pricing.png' ?>"/><br/>
61
+ <h1><?php _e('Ready to Grow Your Audience?', 'email-subscribers'); ?></h1>
62
+ <div class="es-btn-wrapper">
63
+ <a class="button large green-light" href="https://www.icegram.com/?buy-now=407190&qty=1&page=6&with-cart=0&utm_source=in_app&utm_medium=go_starter_yearly&utm_campaign=es_upsale" target="_blank"> <?php _e('Get Starter @ $49/year', 'email-subscribers') ?></a>
64
+ </div>
65
+ <div class="mid-or"></div>
66
+ <div class="es-btn-wrapper">
67
+ <a class="button large green" href="https://www.icegram.com/?buy-now=39944&qty=1&page=6&with-cart=0&utm_source=in_app&utm_medium=go_pro_yearly&utm_campaign=es_upsale" target="_blank"> <?php _e('Get Pro @ $129/year', 'email-subscribers') ?></a>
68
+ </div>
69
+ <div class="es-monthly-wrapper">
70
+ <a class="es-monthly" href="https://www.icegram.com/?buy-now=409349&qty=1&page=6&with-cart=0&utm_source=in_app&utm_medium=go_starter_monthly&utm_campaign=es_upsale" target="_blank"> <?php _e('OR @ $9/month', 'email-subscribers') ?></a>
71
+ </div>
72
  </div>
73
 
74
 
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.1.6
7
  * Author: Icegram
8
  * Author URI: https://www.icegram.com/
9
  * Requires at least: 3.9
@@ -24,7 +24,7 @@ if ( ! defined( 'WPINC' ) ) {
24
  * Define constants
25
  */
26
  define( 'ES_PLUGIN_DIR', dirname( __FILE__ ) );
27
- define( 'ES_PLUGIN_VERSION', '4.1.6' );
28
  define( 'ES_PLUGIN_BASE_NAME', plugin_basename( __FILE__ ) );
29
 
30
  if ( ! defined( 'ES_PLUGIN_FILE' ) ) {
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.1.7
7
  * Author: Icegram
8
  * Author URI: https://www.icegram.com/
9
  * Requires at least: 3.9
24
  * Define constants
25
  */
26
  define( 'ES_PLUGIN_DIR', dirname( __FILE__ ) );
27
+ define( 'ES_PLUGIN_VERSION', '4.1.7' );
28
  define( 'ES_PLUGIN_BASE_NAME', plugin_basename( __FILE__ ) );
29
 
30
  if ( ! defined( 'ES_PLUGIN_FILE' ) ) {
includes/admin/class-es-campaigns-table.php CHANGED
@@ -121,16 +121,23 @@ class ES_Campaigns_Table extends WP_List_Table {
121
 
122
  if ( ! $do_count_only ) {
123
 
124
- // Prepare Order by clause
125
- $order_by_clause = '';
126
- $order = ! empty( $order ) ? ' ' . esc_sql( $order ) : ' DESC';
127
- $order_by_clause = ' ORDER BY ' . esc_sql( 'created_at' ) . ' ' . $order;
128
- $order_by_clause = ! empty( $order_by ) ? $order_by_clause . ' , ' . esc_sql( $order_by ) . ' ' . $order : $order_by_clause;
 
 
 
 
 
 
129
 
130
  $sql .= $order_by_clause;
131
  $sql .= " LIMIT $per_page";
132
  $sql .= ' OFFSET ' . ( $page_number - 1 ) * $per_page;
133
 
 
134
  $result = $wpdb->get_results( $sql, 'ARRAY_A' );
135
  } else {
136
  $result = $wpdb->get_var( $sql );
@@ -205,7 +212,6 @@ class ES_Campaigns_Table extends WP_List_Table {
205
  );
206
  }
207
 
208
-
209
  /**
210
  * Method for name column
211
  *
@@ -230,10 +236,10 @@ class ES_Campaigns_Table extends WP_List_Table {
230
  }
231
 
232
  if ( ! empty( $item['type'] ) && $item['type'] == 'post_notification' ) {
233
- $actions ['edit'] = sprintf( __('<a href="?page=%s&action=%s&list=%s&_wpnonce=%s">Edit</a>', 'email-subscribers' ), esc_attr( 'es_notifications' ), 'edit', absint( $item['id'] ), $nonce );
234
  }
235
 
236
- $actions['delete'] = sprintf( __('<a href="?page=%s&action=%s&list=%s&_wpnonce=%s" onclick="return checkDelete()">Delete</a>', 'email-subscribers'), esc_attr( 'es_campaigns' ), 'delete', absint( $item['id'] ), $nonce );
237
  $title = $title . $this->row_actions( $actions );
238
  } else {
239
  $title = $item['name'];
@@ -268,9 +274,10 @@ class ES_Campaigns_Table extends WP_List_Table {
268
  */
269
  public function get_sortable_columns() {
270
  $sortable_columns = array(
271
- 'base_template_id' => array( 'base_template_id', true ),
272
- 'list_ids' => array( 'list_ids', true ),
273
- 'status' => array( 'status', true )
 
274
  );
275
 
276
  return $sortable_columns;
@@ -293,7 +300,7 @@ class ES_Campaigns_Table extends WP_List_Table {
293
  <p class="search-box">
294
  <label class="screen-reader-text" for="<?php echo $input_id ?>"><?php echo $text; ?>:</label>
295
  <input type="search" id="<?php echo $input_id ?>" name="s" value="<?php _admin_search_query(); ?>"/>
296
- <?php submit_button( __('Search Campaigns', 'email-subscribers'), 'button', false, false, array( 'id' => 'search-submit' ) ); ?>
297
  </p>
298
  <?php }
299
 
@@ -348,19 +355,19 @@ class ES_Campaigns_Table extends WP_List_Table {
348
 
349
  $ids = esc_sql( Email_Subscribers::get_request( 'campaigns' ) );
350
 
351
- if(is_array($ids) && count($ids) > 0) {
352
 
353
- $deleted = $this->delete_list( $ids );
 
 
 
 
 
 
354
 
355
- if ( $deleted ) {
356
- $message = __( 'Campaign(s) have been deleted successfully!', 'email-subscribers' );
357
- ES_Common::show_message( $message );
358
- }
359
- } else {
360
-
361
  $message = __( 'Please check campaign(s) to delete.', 'email-subscribers' );
362
  ES_Common::show_message( $message, 'error' );
363
- }
364
 
365
 
366
  }
121
 
122
  if ( ! $do_count_only ) {
123
 
124
+ $order = ! empty( $order ) ? ' ' . esc_sql( $order ) : ' DESC';
125
+
126
+ $default_order_by = esc_sql( 'created_at' );
127
+
128
+ $expected_order_by_values = array( 'base_template_id', 'type' );
129
+ if ( ! in_array( $order_by, $expected_order_by_values ) ) {
130
+ $order_by_clause = " ORDER BY {$default_order_by} DESC";
131
+ } else {
132
+ $order_by = esc_sql( $order_by );
133
+ $order_by_clause = " ORDER BY {$order_by} {$order}, {$default_order_by} DESC";
134
+ }
135
 
136
  $sql .= $order_by_clause;
137
  $sql .= " LIMIT $per_page";
138
  $sql .= ' OFFSET ' . ( $page_number - 1 ) * $per_page;
139
 
140
+
141
  $result = $wpdb->get_results( $sql, 'ARRAY_A' );
142
  } else {
143
  $result = $wpdb->get_var( $sql );
212
  );
213
  }
214
 
 
215
  /**
216
  * Method for name column
217
  *
236
  }
237
 
238
  if ( ! empty( $item['type'] ) && $item['type'] == 'post_notification' ) {
239
+ $actions ['edit'] = sprintf( __( '<a href="?page=%s&action=%s&list=%s&_wpnonce=%s">Edit</a>', 'email-subscribers' ), esc_attr( 'es_notifications' ), 'edit', absint( $item['id'] ), $nonce );
240
  }
241
 
242
+ $actions['delete'] = sprintf( __( '<a href="?page=%s&action=%s&list=%s&_wpnonce=%s" onclick="return checkDelete()">Delete</a>', 'email-subscribers' ), esc_attr( 'es_campaigns' ), 'delete', absint( $item['id'] ), $nonce );
243
  $title = $title . $this->row_actions( $actions );
244
  } else {
245
  $title = $item['name'];
274
  */
275
  public function get_sortable_columns() {
276
  $sortable_columns = array(
277
+ //'base_template_id' => array( 'base_template_id', true ),
278
+ //'list_ids' => array( 'list_ids', true ),
279
+ //'status' => array( 'status', true )
280
+ 'type' => array( 'type', true )
281
  );
282
 
283
  return $sortable_columns;
300
  <p class="search-box">
301
  <label class="screen-reader-text" for="<?php echo $input_id ?>"><?php echo $text; ?>:</label>
302
  <input type="search" id="<?php echo $input_id ?>" name="s" value="<?php _admin_search_query(); ?>"/>
303
+ <?php submit_button( __( 'Search Campaigns', 'email-subscribers' ), 'button', false, false, array( 'id' => 'search-submit' ) ); ?>
304
  </p>
305
  <?php }
306
 
355
 
356
  $ids = esc_sql( Email_Subscribers::get_request( 'campaigns' ) );
357
 
358
+ if ( is_array( $ids ) && count( $ids ) > 0 ) {
359
 
360
+ $deleted = $this->delete_list( $ids );
361
+
362
+ if ( $deleted ) {
363
+ $message = __( 'Campaign(s) have been deleted successfully!', 'email-subscribers' );
364
+ ES_Common::show_message( $message );
365
+ }
366
+ } else {
367
 
 
 
 
 
 
 
368
  $message = __( 'Please check campaign(s) to delete.', 'email-subscribers' );
369
  ES_Common::show_message( $message, 'error' );
370
+ }
371
 
372
 
373
  }
includes/admin/class-es-cron.php CHANGED
@@ -19,6 +19,7 @@ class ES_Cron {
19
  }
20
 
21
  public function handle_cron_request( $es = '', $guid = '' ) {
 
22
  $is_wp_cron = false;
23
  if ( ! empty( $es ) ) {
24
  $es_request = $es;
@@ -27,13 +28,20 @@ class ES_Cron {
27
  $es_request = Email_Subscribers::get_request( 'es' );
28
  }
29
 
 
 
 
 
 
30
  $ig_es_disable_wp_cron = get_option( 'ig_es_disable_wp_cron', 'no');
31
- if( $is_wp_cron && 'yes' === $ig_es_disable_wp_cron ) return;
 
 
 
32
 
33
  $self = ! empty( $_REQUEST['self'] ) ? $_REQUEST['self'] : 0;
34
 
35
  if ( 'cron' === $es_request ) {
36
-
37
  /*
38
  $ig_es_last_cron_run = get_option( 'ig_es_last_cron_run', true );
39
  $time_diff = ( time() - $ig_es_last_cron_run );
@@ -86,13 +94,13 @@ class ES_Cron {
86
  */
87
 
88
  // Get GUID from sentdetails report which are in queue
89
- $campign_hash = Email_Subscribers::get_request( 'campaign_hash' );
90
 
91
  if ( $self ) {
92
  $es_c_croncount = ceil( $es_c_croncount / 4 ); // Send 1/4 of total limit
93
  }
94
 
95
- $notification = ES_DB_Mailing_Queue::get_notification_to_be_sent( $campign_hash );
96
  $notification_guid = isset( $notification['hash'] ) ? $notification['hash'] : null;
97
 
98
  if ( ! is_null( $notification_guid ) ) {
19
  }
20
 
21
  public function handle_cron_request( $es = '', $guid = '' ) {
22
+
23
  $is_wp_cron = false;
24
  if ( ! empty( $es ) ) {
25
  $es_request = $es;
28
  $es_request = Email_Subscribers::get_request( 'es' );
29
  }
30
 
31
+ // It's not a cron request. Say Goodbye!
32
+ if('cron' !== $es_request) {
33
+ return;
34
+ }
35
+
36
  $ig_es_disable_wp_cron = get_option( 'ig_es_disable_wp_cron', 'no');
37
+
38
+ if( $is_wp_cron && 'yes' === $ig_es_disable_wp_cron ) {
39
+ return;
40
+ }
41
 
42
  $self = ! empty( $_REQUEST['self'] ) ? $_REQUEST['self'] : 0;
43
 
44
  if ( 'cron' === $es_request ) {
 
45
  /*
46
  $ig_es_last_cron_run = get_option( 'ig_es_last_cron_run', true );
47
  $time_diff = ( time() - $ig_es_last_cron_run );
94
  */
95
 
96
  // Get GUID from sentdetails report which are in queue
97
+ $campaign_hash = Email_Subscribers::get_request( 'campaign_hash' );
98
 
99
  if ( $self ) {
100
  $es_c_croncount = ceil( $es_c_croncount / 4 ); // Send 1/4 of total limit
101
  }
102
 
103
+ $notification = ES_DB_Mailing_Queue::get_notification_to_be_sent( $campaign_hash );
104
  $notification_guid = isset( $notification['hash'] ) ? $notification['hash'] : null;
105
 
106
  if ( ! is_null( $notification_guid ) ) {
includes/admin/class-es-forms-table.php CHANGED
@@ -286,7 +286,9 @@ class ES_Forms_Table extends WP_List_Table {
286
  <td><input type="checkbox" class="es_required" name="form_data[name_required]" value="yes" <?php if ( $form_data['name_required'] === 'yes' ) {
287
  echo 'checked=checked';
288
  } ?>></td>
289
- <!-- <td> <input type="text" class="es_name_label" name="form_data[name_label]" value="<?php echo $form_data['name_label']; ?>" <?php if ( $form_data['name_required'] === 'yes' ) { echo 'disabled=disabled'; } ?> ></td>-->
 
 
290
  </tr>
291
  <tr class="form-field">
292
  <td><?php _e( 'Button', 'email-subscribers' ); ?></td>
@@ -371,7 +373,10 @@ class ES_Forms_Table extends WP_List_Table {
371
 
372
  if ( ! empty( $id ) ) {
373
  $form_data['updated_at'] = ig_get_current_date_time();
374
- $return = $wpdb->update( IG_FORMS_TABLE, $form_data, array( 'id' => $id ) );
 
 
 
375
  } else {
376
  $return = $wpdb->insert( IG_FORMS_TABLE, $form_data );
377
  }
@@ -481,16 +486,16 @@ class ES_Forms_Table extends WP_List_Table {
481
  if ( $d['id'] === 'name' ) {
482
  $form_data['name_visible'] = ( $d['params']['show'] === true ) ? 'yes' : '';
483
  $form_data['name_required'] = ( $d['params']['required'] === true ) ? 'yes' : '';
484
- $form_data['name_label'] = !empty($d['params']['label']) ? $d['params']['label'] : '';
485
  } elseif ( $d['id'] === 'lists' ) {
486
  $form_data['list_visible'] = ( $d['params']['show'] === true ) ? 'yes' : '';
487
  $form_data['list_required'] = ( $d['params']['required'] === true ) ? 'yes' : '';
488
  $form_data['lists'] = ! empty( $d['params']['values'] ) ? $d['params']['values'] : array();
489
- } elseif ($d['id'] === 'email') {
490
- $form_data['email_label'] = !empty($d['params']['label']) ? $d['params']['label'] : '';
491
- } elseif($d['id'] === 'submit') {
492
- $form_data['button_label'] = !empty($d['params']['label']) ? $d['params']['label'] : '';
493
- }
494
  }
495
 
496
  return $form_data;
@@ -541,11 +546,17 @@ class ES_Forms_Table extends WP_List_Table {
541
 
542
  if ( ! $do_count_only ) {
543
 
544
- // Prepare Order by clause
545
- $order_by_clause = '';
546
- if ( ! empty( $order_by ) ) {
547
- $order_by_clause = ' ORDER BY ' . esc_sql( $order_by );
548
- $order_by_clause .= ! empty( $order ) ? ' ' . esc_sql( $order ) : ' ASC';
 
 
 
 
 
 
549
  }
550
 
551
  $sql .= $order_by_clause;
@@ -672,7 +683,8 @@ class ES_Forms_Table extends WP_List_Table {
672
  */
673
  public function get_sortable_columns() {
674
  $sortable_columns = array(
675
- 'name' => array( 'name', true ),
 
676
  );
677
 
678
  return $sortable_columns;
286
  <td><input type="checkbox" class="es_required" name="form_data[name_required]" value="yes" <?php if ( $form_data['name_required'] === 'yes' ) {
287
  echo 'checked=checked';
288
  } ?>></td>
289
+ <!-- <td> <input type="text" class="es_name_label" name="form_data[name_label]" value="<?php echo $form_data['name_label']; ?>" <?php if ( $form_data['name_required'] === 'yes' ) {
290
+ echo 'disabled=disabled';
291
+ } ?> ></td>-->
292
  </tr>
293
  <tr class="form-field">
294
  <td><?php _e( 'Button', 'email-subscribers' ); ?></td>
373
 
374
  if ( ! empty( $id ) ) {
375
  $form_data['updated_at'] = ig_get_current_date_time();
376
+
377
+ // We don't want to change the created_at date for update
378
+ unset( $form_data['created_at'] );
379
+ $return = $wpdb->update( IG_FORMS_TABLE, $form_data, array( 'id' => $id ) );
380
  } else {
381
  $return = $wpdb->insert( IG_FORMS_TABLE, $form_data );
382
  }
486
  if ( $d['id'] === 'name' ) {
487
  $form_data['name_visible'] = ( $d['params']['show'] === true ) ? 'yes' : '';
488
  $form_data['name_required'] = ( $d['params']['required'] === true ) ? 'yes' : '';
489
+ $form_data['name_label'] = ! empty( $d['params']['label'] ) ? $d['params']['label'] : '';
490
  } elseif ( $d['id'] === 'lists' ) {
491
  $form_data['list_visible'] = ( $d['params']['show'] === true ) ? 'yes' : '';
492
  $form_data['list_required'] = ( $d['params']['required'] === true ) ? 'yes' : '';
493
  $form_data['lists'] = ! empty( $d['params']['values'] ) ? $d['params']['values'] : array();
494
+ } elseif ( $d['id'] === 'email' ) {
495
+ $form_data['email_label'] = ! empty( $d['params']['label'] ) ? $d['params']['label'] : '';
496
+ } elseif ( $d['id'] === 'submit' ) {
497
+ $form_data['button_label'] = ! empty( $d['params']['label'] ) ? $d['params']['label'] : '';
498
+ }
499
  }
500
 
501
  return $form_data;
546
 
547
  if ( ! $do_count_only ) {
548
 
549
+ $order = ! empty( $order ) ? ' ' . esc_sql( $order ) : ' DESC';
550
+
551
+ $default_order_by = esc_sql( 'created_at' );
552
+
553
+ $expected_order_by_values = array( 'name', 'created_at' );
554
+
555
+ if ( ! in_array( $order_by, $expected_order_by_values ) ) {
556
+ $order_by_clause = " ORDER BY {$default_order_by} DESC";
557
+ } else {
558
+ $order_by = esc_sql( $order_by );
559
+ $order_by_clause = " ORDER BY {$order_by} {$order}, {$default_order_by} DESC";
560
  }
561
 
562
  $sql .= $order_by_clause;
683
  */
684
  public function get_sortable_columns() {
685
  $sortable_columns = array(
686
+ 'name' => array( 'name', true ),
687
+ 'created_at' => array( 'created_at', true ),
688
  );
689
 
690
  return $sortable_columns;
includes/admin/class-es-handle-post-notification.php CHANGED
@@ -126,7 +126,8 @@ class ES_Handle_Post_Notification {
126
  'start_at' => '',
127
  'finish_at' => '',
128
  'created_at' => ig_get_current_date_time(),
129
- 'updated_at' => ig_get_current_date_time()
 
130
  );
131
 
132
  // Add entry into mailing queue table
@@ -241,5 +242,16 @@ class ES_Handle_Post_Notification {
241
  return $content;
242
  }
243
 
 
 
 
 
 
 
 
 
 
 
 
244
  }
245
 
126
  'start_at' => '',
127
  'finish_at' => '',
128
  'created_at' => ig_get_current_date_time(),
129
+ 'updated_at' => ig_get_current_date_time(),
130
+ 'meta' => maybe_serialize(array( 'post_id'=> $post_id, 'type' => 'post_notification' ))
131
  );
132
 
133
  // Add entry into mailing queue table
242
  return $content;
243
  }
244
 
245
+ public static function refresh_post_content( $post_id, $campaign_id ){
246
+ $post = get_post( $post_id );
247
+ $template_id = ES_DB_Campaigns::get_templateid_by_campaign( $campaign_id );
248
+ $template = get_post( $template_id );
249
+ $template_content = $template->post_content;
250
+ $content['subject'] = self::prepare_subject( $post, $template );
251
+ $content['body'] = self::prepare_body( $template_content, $post_id, $template_id );
252
+ return $content;
253
+
254
+ }
255
+
256
  }
257
 
includes/admin/class-es-handle-subscription.php CHANGED
@@ -304,6 +304,7 @@ class ES_Handle_Subscription {
304
  $hp_key = "esfpx_es_hp_" . wp_create_nonce( 'es_hp' );
305
  if ( ! isset( $data[ $hp_key ] ) || ! empty( $data[ $hp_key ] ) ) {
306
  $es_response['message'] = 'es_unexpected_error_notice';
 
307
  return $es_response;
308
  }
309
  }
@@ -358,9 +359,23 @@ class ES_Handle_Subscription {
358
  return $es_response;
359
  }
360
 
 
 
 
 
 
361
  public function is_domain_blocked( $email ) {
362
 
363
- $domains = get_option( 'ig_es_blocked_domains' );
 
 
 
 
 
 
 
 
 
364
 
365
  $domains = explode( PHP_EOL, $domains );
366
 
304
  $hp_key = "esfpx_es_hp_" . wp_create_nonce( 'es_hp' );
305
  if ( ! isset( $data[ $hp_key ] ) || ! empty( $data[ $hp_key ] ) ) {
306
  $es_response['message'] = 'es_unexpected_error_notice';
307
+
308
  return $es_response;
309
  }
310
  }
359
  return $es_response;
360
  }
361
 
362
+ /**
363
+ * @param $email
364
+ *
365
+ * @return bool
366
+ */
367
  public function is_domain_blocked( $email ) {
368
 
369
+ if ( empty( $email ) ) {
370
+ return true;
371
+ }
372
+
373
+ $domains = trim(get_option( 'ig_es_blocked_domains', '' ));
374
+
375
+ // No domains to block? Return
376
+ if ( empty( $domains ) ) {
377
+ return false;
378
+ }
379
 
380
  $domains = explode( PHP_EOL, $domains );
381
 
includes/admin/class-es-import-subscribers.php CHANGED
@@ -64,14 +64,13 @@ class ES_Import_Subscribers {
64
 
65
  $data = array_combine( $headers, $data );
66
  $name = isset( $data['Name'] ) ? trim( $data['Name'] ) : '';
67
- $email = isset( $data['Email'] ) ? trim( $data['Email'] ) : '';
68
 
69
  if ( empty( $email ) ) {
70
  $invalid_emails_count ++;
71
  continue;
72
  }
73
 
74
-
75
  if ( empty( $name ) ) {
76
  $name = ES_Common::get_name_from_email( $email );
77
  }
@@ -79,8 +78,8 @@ class ES_Import_Subscribers {
79
  if ( !in_array( $email, $existing_contacts ) ) {
80
 
81
  $names = ES_Common::prepare_first_name_last_name( $name );
82
- $first_name = $names['first_name'];
83
- $last_name = $names['last_name'];
84
 
85
  $guid = ES_Common::generate_guid();
86
 
64
 
65
  $data = array_combine( $headers, $data );
66
  $name = isset( $data['Name'] ) ? trim( $data['Name'] ) : '';
67
+ $email = isset( $data['Email'] ) ? sanitize_email(trim( $data['Email'] )) : '';
68
 
69
  if ( empty( $email ) ) {
70
  $invalid_emails_count ++;
71
  continue;
72
  }
73
 
 
74
  if ( empty( $name ) ) {
75
  $name = ES_Common::get_name_from_email( $email );
76
  }
78
  if ( !in_array( $email, $existing_contacts ) ) {
79
 
80
  $names = ES_Common::prepare_first_name_last_name( $name );
81
+ $first_name = sanitize_text_field($names['first_name']);
82
+ $last_name = sanitize_text_field($names['last_name']);
83
 
84
  $guid = ES_Common::generate_guid();
85
 
includes/admin/class-es-lists-table.php CHANGED
@@ -301,10 +301,18 @@ class ES_Lists_Table extends WP_List_Table {
301
  if ( ! $do_count_only ) {
302
 
303
  // Prepare Order by clause
304
- $order_by_clause = '';
305
- $order = ! empty( $order ) ? ' ' . esc_sql( $order ) : ' DESC';
306
- $order_by_clause = ' ORDER BY ' . esc_sql( 'created_at' ) . ' ' . $order;
307
- $order_by_clause = ! empty( $order_by ) ? $order_by_clause . ' , ' . esc_sql( $order_by ) . ' ' . $order : $order_by_clause;
 
 
 
 
 
 
 
 
308
 
309
  $sql .= $order_by_clause;
310
  $sql .= " LIMIT $per_page";
@@ -453,7 +461,8 @@ class ES_Lists_Table extends WP_List_Table {
453
  */
454
  public function get_sortable_columns() {
455
  $sortable_columns = array(
456
- 'name' => array( 'name', true ),
 
457
  );
458
 
459
  return $sortable_columns;
@@ -487,7 +496,6 @@ class ES_Lists_Table extends WP_List_Table {
487
 
488
  $this->_column_headers = $this->get_column_info();
489
 
490
-
491
  /** Process bulk action */
492
  $this->process_bulk_action();
493
  $this->search_box( Email_Subscribers::get_request( 's' ), 'list-search-input' );
301
  if ( ! $do_count_only ) {
302
 
303
  // Prepare Order by clause
304
+ $order = ! empty( $order ) ? ' ' . esc_sql( $order ) : ' DESC';
305
+
306
+ $default_order_by = esc_sql( 'created_at' );
307
+
308
+ $expected_order_by_values = array( 'name', 'created_at' );
309
+
310
+ if ( ! in_array( $order_by, $expected_order_by_values ) ) {
311
+ $order_by_clause = " ORDER BY {$default_order_by} DESC";
312
+ } else {
313
+ $order_by = esc_sql( $order_by );
314
+ $order_by_clause = " ORDER BY {$order_by} {$order}, {$default_order_by} DESC";
315
+ }
316
 
317
  $sql .= $order_by_clause;
318
  $sql .= " LIMIT $per_page";
461
  */
462
  public function get_sortable_columns() {
463
  $sortable_columns = array(
464
+ 'name' => array( 'name', true ),
465
+ 'created_at' => array( 'created_at', true ),
466
  );
467
 
468
  return $sortable_columns;
496
 
497
  $this->_column_headers = $this->get_column_info();
498
 
 
499
  /** Process bulk action */
500
  $this->process_bulk_action();
501
  $this->search_box( Email_Subscribers::get_request( 's' ), 'list-search-input' );
includes/admin/class-es-newsletters.php CHANGED
@@ -50,9 +50,9 @@ class ES_Newsletters {
50
  } else {
51
 
52
  $data = array(
53
- 'ig_es_broadcast_base_template_id' => $template_id,
54
- 'ig_es_broadcast_list_ids' => $list_id,
55
- 'status' => 1
56
  );
57
 
58
  self::es_send_email_callback( $data );
@@ -227,8 +227,8 @@ class ES_Newsletters {
227
 
228
  public static function es_send_email_callback( $data ) {
229
 
230
- $template_id = ! empty( $data['ig_es_broadcast_base_template_id'] ) ? $data['ig_es_broadcast_base_template_id'] : '';
231
- $list_id = ! empty( $data['ig_es_broadcast_list_ids'] ) ? $data['ig_es_broadcast_list_ids'] : '';
232
 
233
  $data['type'] = 'newsletter';
234
  $data['name'] = get_the_title( $template_id );
@@ -236,6 +236,9 @@ class ES_Newsletters {
236
  $data['list_ids'] = $list_id;
237
  $data['base_template_id'] = $template_id;
238
 
 
 
 
239
  if ( ! empty( $template_id ) ) {
240
 
241
  $campaign_id = ES_DB_Campaigns::save_campaign( $data );
@@ -258,10 +261,11 @@ class ES_Newsletters {
258
  'body' => $post_template_content,
259
  'count' => count( $subscribers ),
260
  'status' => 'In Queue',
261
- 'start_at' => '',
262
  'finish_at' => '',
263
  'created_at' => ig_get_current_date_time(),
264
- 'updated_at' => ig_get_current_date_time()
 
265
  );
266
 
267
  $last_report_id = ES_DB_Mailing_Queue::add_notification( $data );
@@ -280,6 +284,15 @@ class ES_Newsletters {
280
 
281
  }
282
 
 
 
 
 
 
 
 
 
 
283
  public static function get_instance() {
284
  if ( ! isset( self::$instance ) ) {
285
  self::$instance = new self();
50
  } else {
51
 
52
  $data = array(
53
+ 'base_template_id' => $template_id,
54
+ 'list_ids' => $list_id,
55
+ 'status' => 1
56
  );
57
 
58
  self::es_send_email_callback( $data );
227
 
228
  public static function es_send_email_callback( $data ) {
229
 
230
+ $template_id = ! empty( $data['base_template_id'] ) ? $data['base_template_id'] : '';
231
+ $list_id = ! empty( $data['list_ids'] ) ? $data['list_ids'] : '';
232
 
233
  $data['type'] = 'newsletter';
234
  $data['name'] = get_the_title( $template_id );
236
  $data['list_ids'] = $list_id;
237
  $data['base_template_id'] = $template_id;
238
 
239
+ $data = apply_filters( 'ig_es_broadcast_data', $data );
240
+
241
+
242
  if ( ! empty( $template_id ) ) {
243
 
244
  $campaign_id = ES_DB_Campaigns::save_campaign( $data );
261
  'body' => $post_template_content,
262
  'count' => count( $subscribers ),
263
  'status' => 'In Queue',
264
+ 'start_at' => !empty($data['start_at']) ? $data['start_at'] : '',
265
  'finish_at' => '',
266
  'created_at' => ig_get_current_date_time(),
267
+ 'updated_at' => ig_get_current_date_time(),
268
+ 'meta' => maybe_serialize(array( 'type' => 'newsletter' ))
269
  );
270
 
271
  $last_report_id = ES_DB_Mailing_Queue::add_notification( $data );
284
 
285
  }
286
 
287
+ public static function refresh_newsletter_content( $campaign_id ){
288
+ $template_id = ES_DB_Campaigns::get_templateid_by_campaign( $campaign_id );
289
+ $template = get_post( $template_id );
290
+ $content['subject'] = ! empty( $template->post_title ) ? $template->post_title : '';
291
+ $content['body'] = ! empty( $template->post_content ) ? $template->post_content : '';
292
+ $content['body'] = ES_Common::es_process_template_body( $content['body'], $template_id );
293
+ return $content;
294
+ }
295
+
296
  public static function get_instance() {
297
  if ( ! isset( self::$instance ) ) {
298
  self::$instance = new self();
includes/admin/class-es-reports-table.php CHANGED
@@ -151,7 +151,7 @@ class ES_Reports_Table extends WP_List_Table {
151
  <td><?php echo $email['email']; ?></td>
152
  <td><span style="color:#03a025;font-weight:bold;"><?php echo $email['status']; ?></span></td>
153
  <td><?php echo ig_es_format_date_time( $email['sent_at'] ); ?></td>
154
- <td><span><?php echo ( ! empty( $email['opened'] ) && $email['opened'] == 1 ) ? _e('Viewed', 'email-subscribers') : '<i title="'.__('Not yet viewed', 'email-subscribers').'" class="dashicons dashicons-es dashicons-minus">' ?></span></td>
155
  <td><?php echo ig_es_format_date_time( $email['opened_at'] ); ?></td>
156
  </tr>
157
 
@@ -184,7 +184,7 @@ class ES_Reports_Table extends WP_List_Table {
184
  return ig_es_format_date_time( $item[ $column_name ] );
185
  case 'type':
186
  if ( empty( $item['campaign_id'] ) ) {
187
- $type = __('Post Notification', 'email-subscribers');
188
  } else {
189
  $type = ES_DB_Campaigns::get_campaign_type_by_id( $item['campaign_id'] );
190
  $type = strtolower( $type );
@@ -245,7 +245,7 @@ class ES_Reports_Table extends WP_List_Table {
245
  $title = '<strong>' . $item['subject'] . '</strong>';
246
 
247
  $actions = array(
248
- 'view' => sprintf( '<a href="?page=%s&action=%s&list=%s&_wpnonce=%s">%s</a>', esc_attr( Email_Subscribers::get_request( 'page' ) ), 'view', $item['hash'], $es_nonce, __( 'View', 'email-subscribers' ) ),
249
  'delete' => sprintf( '<a href="?page=%s&action=%s&list=%s&_wpnonce=%s">%s</a>', esc_attr( Email_Subscribers::get_request( 'page' ) ), 'delete', absint( $item['id'] ), $es_nonce, __( 'Delete', 'email-subscribers' ) ),
250
  'preview_email' => sprintf( '<a target="_blank" href="?page=%s&action=%s&list=%s&_wpnonce=%s">%s</a>', esc_attr( Email_Subscribers::get_request( 'page' ) ), 'preview', absint( $item['id'] ), $es_nonce, __( 'Preview', 'email-subscribers' ) )
251
  );
@@ -312,9 +312,11 @@ class ES_Reports_Table extends WP_List_Table {
312
  */
313
  public function get_sortable_columns() {
314
  $sortable_columns = array(
315
- 'status' => array( 'sentstatus', true ),
316
- 'date' => array( 'sentdate', true ),
317
- 'emailid' => array( 'emailid', true )
 
 
318
  );
319
 
320
  return $sortable_columns;
@@ -327,7 +329,7 @@ class ES_Reports_Table extends WP_List_Table {
327
  */
328
  public function get_bulk_actions() {
329
  $actions = array(
330
- 'bulk_delete' => __('Delete', 'email-subscribers')
331
  );
332
 
333
  return $actions;
@@ -346,14 +348,56 @@ class ES_Reports_Table extends WP_List_Table {
346
 
347
  $per_page = $this->get_items_per_page( 'reports_per_page', 20 );
348
  $current_page = $this->get_pagenum();
349
- $total_items = ES_DB_Mailing_Queue::get_notifications_count();
350
 
351
  $this->set_pagination_args( array(
352
  'total_items' => $total_items, //WE have to calculate the total number of items
353
  'per_page' => $per_page //WE have to determine how many items to show on a page
354
  ) );
355
 
356
- $this->items = ES_DB_Mailing_Queue::get_notifications( $per_page, $current_page );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
357
  }
358
 
359
  public function process_bulk_action() {
151
  <td><?php echo $email['email']; ?></td>
152
  <td><span style="color:#03a025;font-weight:bold;"><?php echo $email['status']; ?></span></td>
153
  <td><?php echo ig_es_format_date_time( $email['sent_at'] ); ?></td>
154
+ <td><span><?php echo ( ! empty( $email['opened'] ) && $email['opened'] == 1 ) ? _e( 'Viewed', 'email-subscribers' ) : '<i title="' . __( 'Not yet viewed', 'email-subscribers' ) . '" class="dashicons dashicons-es dashicons-minus">' ?></span></td>
155
  <td><?php echo ig_es_format_date_time( $email['opened_at'] ); ?></td>
156
  </tr>
157
 
184
  return ig_es_format_date_time( $item[ $column_name ] );
185
  case 'type':
186
  if ( empty( $item['campaign_id'] ) ) {
187
+ $type = __( 'Post Notification', 'email-subscribers' );
188
  } else {
189
  $type = ES_DB_Campaigns::get_campaign_type_by_id( $item['campaign_id'] );
190
  $type = strtolower( $type );
245
  $title = '<strong>' . $item['subject'] . '</strong>';
246
 
247
  $actions = array(
248
+ 'view' => sprintf( '<a href="?page=%s&action=%s&list=%s&_wpnonce=%s">%s</a>', esc_attr( Email_Subscribers::get_request( 'page' ) ), 'view', $item['hash'], $es_nonce, __( 'View', 'email-subscribers' ) ),
249
  'delete' => sprintf( '<a href="?page=%s&action=%s&list=%s&_wpnonce=%s">%s</a>', esc_attr( Email_Subscribers::get_request( 'page' ) ), 'delete', absint( $item['id'] ), $es_nonce, __( 'Delete', 'email-subscribers' ) ),
250
  'preview_email' => sprintf( '<a target="_blank" href="?page=%s&action=%s&list=%s&_wpnonce=%s">%s</a>', esc_attr( Email_Subscribers::get_request( 'page' ) ), 'preview', absint( $item['id'] ), $es_nonce, __( 'Preview', 'email-subscribers' ) )
251
  );
312
  */
313
  public function get_sortable_columns() {
314
  $sortable_columns = array(
315
+ 'subject' => array( 'subject', true ),
316
+ 'status' => array( 'status', true ),
317
+ 'start_at' => array( 'start_at', true ),
318
+ 'finish_at' => array( 'finish_at', true ),
319
+ 'count' => array( 'count', true )
320
  );
321
 
322
  return $sortable_columns;
329
  */
330
  public function get_bulk_actions() {
331
  $actions = array(
332
+ 'bulk_delete' => __( 'Delete', 'email-subscribers' )
333
  );
334
 
335
  return $actions;
348
 
349
  $per_page = $this->get_items_per_page( 'reports_per_page', 20 );
350
  $current_page = $this->get_pagenum();
351
+ $total_items = $this->get_notifications( 0, 0, true );
352
 
353
  $this->set_pagination_args( array(
354
  'total_items' => $total_items, //WE have to calculate the total number of items
355
  'per_page' => $per_page //WE have to determine how many items to show on a page
356
  ) );
357
 
358
+ $this->items = $this->get_notifications( $per_page, $current_page, false );
359
+ }
360
+
361
+ public function get_notifications( $per_page = 5, $page_number = 1, $do_count_only = false ) {
362
+ global $wpdb;
363
+
364
+ $order_by = Email_Subscribers::get_request( 'orderby' );
365
+ $order = Email_Subscribers::get_request( 'order' );
366
+
367
+ $ig_mailing_queue_table = IG_MAILING_QUEUE_TABLE;
368
+
369
+ if ( $do_count_only ) {
370
+ $sql = "SELECT count(*) as total FROM {$ig_mailing_queue_table}";
371
+ } else {
372
+ $sql = "SELECT * FROM {$ig_mailing_queue_table}";
373
+ }
374
+
375
+ if ( ! $do_count_only ) {
376
+
377
+ // Prepare Order by clause
378
+ $order = ! empty( $order ) ? ' ' . esc_sql( $order ) : ' DESC';
379
+
380
+ $default_order_by = esc_sql( 'created_at' );
381
+
382
+ $expected_order_by_values = array( 'subject', 'type', 'status', 'start_at', 'count', 'created_at' );
383
+
384
+ if ( ! in_array( $order_by, $expected_order_by_values ) ) {
385
+ $order_by_clause = " ORDER BY {$default_order_by} DESC";
386
+ } else {
387
+ $order_by = esc_sql( $order_by );
388
+ $order_by_clause = " ORDER BY {$order_by} {$order}, {$default_order_by} DESC";
389
+ }
390
+
391
+ $sql .= $order_by_clause;
392
+ $sql .= " LIMIT $per_page";
393
+ $sql .= ' OFFSET ' . ( $page_number - 1 ) * $per_page;
394
+ $result = $wpdb->get_results( $sql, 'ARRAY_A' );
395
+
396
+ } else {
397
+ $result = $wpdb->get_var( $sql );
398
+ }
399
+
400
+ return $result;
401
  }
402
 
403
  public function process_bulk_action() {
includes/admin/class-es-subscribers-table.php CHANGED
@@ -13,8 +13,13 @@ class ES_Subscribers_Table extends WP_List_Table {
13
 
14
  static $instance;
15
 
16
- public function __construct() {
 
 
 
 
17
 
 
18
 
19
  //set_error_handler(array( 'Email_General' , 'es_handle_error'));
20
  parent::__construct( array(
@@ -203,7 +208,6 @@ class ES_Subscribers_Table extends WP_List_Table {
203
 
204
  if ( Email_Subscribers::get_request( 'email' ) ) {
205
 
206
-
207
  $list_id = Email_Subscribers::get_request( 'lists' );
208
 
209
  if ( empty( $list_id ) ) {
@@ -277,36 +281,57 @@ class ES_Subscribers_Table extends WP_List_Table {
277
  $filter_by_list_id = Email_Subscribers::get_request( 'filter_by_list_id' );
278
  $filter_by_status = Email_Subscribers::get_request( 'filter_by_status' );
279
 
 
 
 
 
280
  $add_where_clause = false;
281
 
 
 
 
282
  if ( $do_count_only ) {
283
- $sql = "SELECT count(*) as total FROM " . IG_CONTACTS_TABLE;
284
  } else {
285
- $sql = "SELECT * FROM " . IG_CONTACTS_TABLE;
286
  }
287
 
288
- $args = array();
289
- $query = array();
290
-
291
  // Prepare filter by list query
292
  if ( ! empty( $filter_by_list_id ) || ! empty( $filter_by_status ) ) {
293
  $add_where_clause = true;
294
- $list_sql = "SELECT contact_id FROM " . IG_LISTS_CONTACTS_TABLE;
295
- $filter_sql = ! empty( $filter_by_list_id ) ? " list_id = $filter_by_list_id " : ' ';
296
- $filter_sql .= ! empty( $filter_by_status ) ? ( ( ! empty( $filter_by_list_id ) ) ? "AND status = '$filter_by_status' " : " status = '$filter_by_status' " ) : ' ';
297
- $list_sql = ! empty( $filter_sql ) ? $list_sql . " WHERE " . $filter_sql : $list_sql;
298
- $query[] = "id IN ( $list_sql )";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
299
  }
300
 
301
  // Prepare search query
302
  if ( ! empty( $search ) ) {
303
- $add_where_clause = true;
304
- $query[] = " ( first_name LIKE %s OR email LIKE %s ) ";
305
- $args[] = "%" . $wpdb->esc_like( $search ) . "%";
306
- $args[] = "%" . $wpdb->esc_like( $search ) . "%";
307
  }
308
 
309
- if ( $add_where_clause ) {
310
  $sql .= " WHERE ";
311
 
312
  if ( count( $query ) > 0 ) {
@@ -321,13 +346,20 @@ class ES_Subscribers_Table extends WP_List_Table {
321
  if ( ! $do_count_only ) {
322
 
323
  // Prepare Order by clause
324
- $order_by_clause = '';
325
- $order = ! empty( $order ) ? ' ' . esc_sql( $order ) : ' DESC';
326
- $order_by_clause = ' ORDER BY ';
327
- $order_by_clause = ! empty( $order_by ) ? $order_by_clause . ' ' . esc_sql( $order_by ) . ' ' . $order : $order_by_clause . esc_sql( 'created_at' ) . ' ' . $order;
 
 
 
 
 
 
 
 
328
  $sql .= $order_by_clause;
329
- $sql .= " LIMIT $per_page";
330
- $sql .= ' OFFSET ' . ( $page_number - 1 ) * $per_page;
331
 
332
  $result = $wpdb->get_results( $sql, 'ARRAY_A' );
333
  } else {
@@ -505,7 +537,6 @@ class ES_Subscribers_Table extends WP_List_Table {
505
  switch ( $column_name ) {
506
  case 'lists':
507
  return $this->get_lists_to_show( $item['id'] );
508
- //implode( ", ", ES_DB_Lists::get_all_lists_name_by_contact( $item['id'] ) );
509
  case 'created_at':
510
  return ig_es_format_date_time( $item[ $column_name ] );
511
  case 'first_name':
@@ -516,15 +547,20 @@ class ES_Subscribers_Table extends WP_List_Table {
516
  }
517
 
518
  public function get_lists_to_show( $contact_id ) {
519
- $contact_lists = ES_DB_Lists_Contacts::get_list_details_by_contact( $contact_id );
520
- $list_str = '';
521
- if ( count( $contact_lists ) > 0 ) {
522
- $contact_lists_to_display = array_slice( $contact_lists, 0, 4 );
523
- $list_id_name_map = ES_DB_Lists::get_list_id_name_map();
524
-
525
- foreach ( $contact_lists_to_display as $contact_list ) {
526
- if ( ! empty( $list_id_name_map[ $contact_list['list_id'] ] ) ) {
527
- $list_str .= '<span class="es_list_contact_status ' . strtolower( $contact_list['status'] ) . '" title="' . ucwords( $contact_list['status'] ) . '">' . $list_id_name_map[ $contact_list['list_id'] ] . '</span> ';
 
 
 
 
 
528
  }
529
  }
530
  }
@@ -573,7 +609,7 @@ class ES_Subscribers_Table extends WP_List_Table {
573
  * @return string
574
  */
575
  function column_name( $item ) {
576
- $delete_nonce = wp_create_nonce( 'sp_delete_subscriber' );
577
 
578
  $name = ES_Common::prepare_name_from_first_name_last_name( $item['first_name'], $item['last_name'] );
579
  $title = '<strong>' . $name . '</strong>';
@@ -619,7 +655,7 @@ class ES_Subscribers_Table extends WP_List_Table {
619
  */
620
  public function get_sortable_columns() {
621
  $sortable_columns = array(
622
- 'name' => array( 'first_name', true ),
623
  'email' => array( 'email', false ),
624
  // 'status' => array( 'status', false ),
625
  'created_at' => array( 'created_at', false )
@@ -689,8 +725,28 @@ class ES_Subscribers_Table extends WP_List_Table {
689
  'per_page' => $per_page //WE have to determine how many items to show on a page
690
  ) );
691
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
692
 
693
- $this->items = $this->get_subscribers( $per_page, $current_page );
 
694
  }
695
 
696
  public function edit_group() {
@@ -718,7 +774,7 @@ class ES_Subscribers_Table extends WP_List_Table {
718
  // In our file that handles the request, verify the nonce.
719
  $nonce = esc_attr( Email_Subscribers::get_request( '_wpnonce' ) );
720
 
721
- if ( ! wp_verify_nonce( $nonce, 'sp_delete_subscriber' ) ) {
722
  die( 'You do not have a permission to delete subscriber' );
723
  } else {
724
  $this->edit_list( absint( Email_Subscribers::get_request( 'subscriber' ) ) );
@@ -734,7 +790,7 @@ class ES_Subscribers_Table extends WP_List_Table {
734
  // In our file that handles the request, verify the nonce.
735
  $nonce = esc_attr( Email_Subscribers::get_request( '_wpnonce' ) );
736
 
737
- if ( ! wp_verify_nonce( $nonce, 'sp_delete_subscriber' ) ) {
738
  die( 'You do not have a permission to delete contact(s)' );
739
  } else {
740
  $deleted = ES_DB_Contacts::delete_subscribers( array( absint( Email_Subscribers::get_request( 'subscriber' ) ) ) );
@@ -752,7 +808,7 @@ class ES_Subscribers_Table extends WP_List_Table {
752
  // In our file that handles the request, verify the nonce.
753
  $nonce = esc_attr( Email_Subscribers::get_request( '_wpnonce' ) );
754
 
755
- if ( ! wp_verify_nonce( $nonce, 'sp_delete_subscriber' ) ) {
756
  die( 'You do not have a permission to resend email confirmation' );
757
  } else {
758
  $id = absint( Email_Subscribers::get_request( 'subscriber' ) );
13
 
14
  static $instance;
15
 
16
+ public $contact_lists_statuses = array();
17
+
18
+ public $list_ids = array();
19
+
20
+ public $lists_id_name_map = array();
21
 
22
+ public function __construct() {
23
 
24
  //set_error_handler(array( 'Email_General' , 'es_handle_error'));
25
  parent::__construct( array(
208
 
209
  if ( Email_Subscribers::get_request( 'email' ) ) {
210
 
 
211
  $list_id = Email_Subscribers::get_request( 'lists' );
212
 
213
  if ( empty( $list_id ) ) {
281
  $filter_by_list_id = Email_Subscribers::get_request( 'filter_by_list_id' );
282
  $filter_by_status = Email_Subscribers::get_request( 'filter_by_status' );
283
 
284
+
285
+ $contacts_table = IG_CONTACTS_TABLE;
286
+ $lists_contacts_table = IG_LISTS_CONTACTS_TABLE;
287
+
288
  $add_where_clause = false;
289
 
290
+ $args = array();
291
+ $query = array();
292
+
293
  if ( $do_count_only ) {
294
+ $sql = "SELECT count(*) FROM {$contacts_table}";
295
  } else {
296
+ $sql = "SELECT * FROM {$contacts_table}";
297
  }
298
 
 
 
 
299
  // Prepare filter by list query
300
  if ( ! empty( $filter_by_list_id ) || ! empty( $filter_by_status ) ) {
301
  $add_where_clause = true;
302
+
303
+ $filter_sql = "SELECT contact_id FROM {$lists_contacts_table}";
304
+
305
+ $list_filter_sql = '';
306
+ $where_clause_added = false;
307
+
308
+ if ( ! empty( $filter_by_list_id ) ) {
309
+ $list_filter_sql = $wpdb->prepare( " WHERE list_id = %d", $filter_by_list_id );
310
+ $where_clause_added = true;
311
+ }
312
+
313
+ if ( ! empty( $filter_by_status ) ) {
314
+ if ( $where_clause_added ) {
315
+ $list_filter_sql .= $wpdb->prepare( " AND status = %s", $filter_by_status );
316
+ } else {
317
+ $list_filter_sql .= $wpdb->prepare( " WHERE status = %s", $filter_by_status );
318
+ }
319
+
320
+ }
321
+
322
+ $filter_sql .= $list_filter_sql;
323
+ $query[] = "id IN ( $filter_sql )";
324
  }
325
 
326
  // Prepare search query
327
  if ( ! empty( $search ) ) {
328
+ $query[] = " ( first_name LIKE %s OR last_name LIKE %s OR email LIKE %s ) ";
329
+ $args[] = "%" . $wpdb->esc_like( $search ) . "%";
330
+ $args[] = "%" . $wpdb->esc_like( $search ) . "%";
331
+ $args[] = "%" . $wpdb->esc_like( $search ) . "%";
332
  }
333
 
334
+ if ( $add_where_clause || count( $query ) > 0 ) {
335
  $sql .= " WHERE ";
336
 
337
  if ( count( $query ) > 0 ) {
346
  if ( ! $do_count_only ) {
347
 
348
  // Prepare Order by clause
349
+ $order = ! empty( $order ) ? esc_sql( $order ) : 'DESC';
350
+ $offset = ( $page_number - 1 ) * $per_page;
351
+
352
+ $expected_order_by_values = array( 'name', 'email', 'created_at' );
353
+ if ( ! in_array( $order_by, $expected_order_by_values ) ) {
354
+ $order_by = 'created_at';
355
+ }
356
+
357
+ $order_by = esc_sql( $order_by );
358
+
359
+ $order_by_clause = " ORDER BY {$order_by} {$order}";
360
+
361
  $sql .= $order_by_clause;
362
+ $sql .= " LIMIT {$offset}, {$per_page}";
 
363
 
364
  $result = $wpdb->get_results( $sql, 'ARRAY_A' );
365
  } else {
537
  switch ( $column_name ) {
538
  case 'lists':
539
  return $this->get_lists_to_show( $item['id'] );
 
540
  case 'created_at':
541
  return ig_es_format_date_time( $item[ $column_name ] );
542
  case 'first_name':
547
  }
548
 
549
  public function get_lists_to_show( $contact_id ) {
550
+
551
+ $list_str = '';
552
+
553
+ if ( isset( $this->contact_lists_statuses[ $contact_id ] ) ) {
554
+
555
+ $lists = $this->contact_lists_statuses[ $contact_id ];
556
+
557
+ if ( count( $lists ) > 0 ) {
558
+ // Show only 4 lists
559
+ //$contact_lists_to_display = array_slice( $lists, 0, 4 );
560
+ foreach ( $lists as $list_id => $status ) {
561
+ if ( ! empty( $this->lists_id_name_map[ $list_id ] ) ) {
562
+ $list_str .= '<span class="es_list_contact_status ' . strtolower( $status ) . '" title="' . ucwords( $status ) . '">' . $this->lists_id_name_map[ $list_id ] . '</span> ';
563
+ }
564
  }
565
  }
566
  }
609
  * @return string
610
  */
611
  function column_name( $item ) {
612
+ $delete_nonce = wp_create_nonce( 'ig_es_delete_subscriber' );
613
 
614
  $name = ES_Common::prepare_name_from_first_name_last_name( $item['first_name'], $item['last_name'] );
615
  $title = '<strong>' . $name . '</strong>';
655
  */
656
  public function get_sortable_columns() {
657
  $sortable_columns = array(
658
+ 'name' => array( 'first_name', true ),
659
  'email' => array( 'email', false ),
660
  // 'status' => array( 'status', false ),
661
  'created_at' => array( 'created_at', false )
725
  'per_page' => $per_page //WE have to determine how many items to show on a page
726
  ) );
727
 
728
+ $contacts = $this->get_subscribers( $per_page, $current_page );
729
+
730
+
731
+ $this->items = $contacts;
732
+
733
+ if ( count( $contacts ) > 0 ) {
734
+
735
+ $contact_ids = array_map( array( $this, 'get_contact_id' ), $contacts );
736
+
737
+ $contact_lists_statuses = ES_DB_Lists_Contacts::get_list_status_by_contact_ids( $contact_ids );
738
+
739
+ $this->contact_lists_statuses = $contact_lists_statuses;
740
+
741
+ $lists_id_name_map = ES_DB_Lists::get_list_id_name_map();
742
+
743
+ $this->lists_id_name_map = $lists_id_name_map;
744
+
745
+ }
746
+ }
747
 
748
+ public function get_contact_id( $contact ) {
749
+ return $contact['id'];
750
  }
751
 
752
  public function edit_group() {
774
  // In our file that handles the request, verify the nonce.
775
  $nonce = esc_attr( Email_Subscribers::get_request( '_wpnonce' ) );
776
 
777
+ if ( ! wp_verify_nonce( $nonce, 'ig_es_delete_subscriber' ) ) {
778
  die( 'You do not have a permission to delete subscriber' );
779
  } else {
780
  $this->edit_list( absint( Email_Subscribers::get_request( 'subscriber' ) ) );
790
  // In our file that handles the request, verify the nonce.
791
  $nonce = esc_attr( Email_Subscribers::get_request( '_wpnonce' ) );
792
 
793
+ if ( ! wp_verify_nonce( $nonce, 'ig_es_delete_subscriber' ) ) {
794
  die( 'You do not have a permission to delete contact(s)' );
795
  } else {
796
  $deleted = ES_DB_Contacts::delete_subscribers( array( absint( Email_Subscribers::get_request( 'subscriber' ) ) ) );
808
  // In our file that handles the request, verify the nonce.
809
  $nonce = esc_attr( Email_Subscribers::get_request( '_wpnonce' ) );
810
 
811
+ if ( ! wp_verify_nonce( $nonce, 'ig_es_delete_subscriber' ) ) {
812
  die( 'You do not have a permission to resend email confirmation' );
813
  } else {
814
  $id = absint( Email_Subscribers::get_request( 'subscriber' ) );
includes/class-email-subscribers.php CHANGED
@@ -93,10 +93,10 @@ class Email_Subscribers {
93
  $this->define_admin_hooks();
94
  $this->define_public_hooks();
95
 
96
- $ig_es_tracker = 'IG_Tracker_V_' . str_replace('.', '_', $feedback_version);
97
  if ( is_admin() ) {
98
- $ig_es_feedback_class = 'IG_Feedback_V_' . str_replace('.', '_', $feedback_version);
99
- $ig_es_feedback = new $ig_es_feedback_class( 'Email Subscribers', 'email-subscribers', 'ig_es', 'esfree.', false );
100
  $ig_es_feedback->render_deactivate_feedback();
101
  }
102
 
@@ -105,7 +105,7 @@ class Email_Subscribers {
105
  }
106
 
107
  public function add_admin_notice() {
108
- global $ig_es_tracker;
109
 
110
  $screen = get_current_screen();
111
  $screen_id = $screen ? $screen->id : '';
@@ -149,8 +149,8 @@ class Email_Subscribers {
149
  $es_premium = 'email-subscribers-premium/email-subscribers-premium.php';
150
  $all_plugins = $ig_es_tracker::get_plugins();
151
  //get pro button
152
- if ( ! in_array( $es_premium, $all_plugins ) && is_admin() && ! in_array( $screen_id, array('toplevel_page_es_dashboard'), true ) ) {
153
- echo "<div class='notice es-floting-button'><i class='dashicons dashicons-es dashicons-awards'></i> <a href='https://www.icegram.com/email-subscribers-pricing/?utm_source=in_app&utm_medium=get_starter_floating_button&utm_campaign=es_upsale' target='_blank'>" .__('Get Starter Now!', 'email-subscribers') ."</a></div>";
154
  }
155
  //cron notice
156
  $notice_option = get_option( 'ig_es_wp_cron_notice' );
@@ -273,7 +273,7 @@ class Email_Subscribers {
273
  */
274
  private function load_dependencies( $feedback_version ) {
275
 
276
- $feedback_version_for_file = str_replace('.', '-', $feedback_version);
277
  /**
278
  * The class responsible for orchestrating the actions and filters of the
279
  * core plugin.
@@ -515,4 +515,4 @@ class Email_Subscribers {
515
  return $schedules;
516
  }
517
 
518
- }
93
  $this->define_admin_hooks();
94
  $this->define_public_hooks();
95
 
96
+ $ig_es_tracker = 'IG_Tracker_V_' . str_replace( '.', '_', $feedback_version );
97
  if ( is_admin() ) {
98
+ $ig_es_feedback_class = 'IG_Feedback_V_' . str_replace( '.', '_', $feedback_version );
99
+ $ig_es_feedback = new $ig_es_feedback_class( 'Email Subscribers', 'email-subscribers', 'ig_es', 'esfree.', false );
100
  $ig_es_feedback->render_deactivate_feedback();
101
  }
102
 
105
  }
106
 
107
  public function add_admin_notice() {
108
+ global $ig_es_tracker;
109
 
110
  $screen = get_current_screen();
111
  $screen_id = $screen ? $screen->id : '';
149
  $es_premium = 'email-subscribers-premium/email-subscribers-premium.php';
150
  $all_plugins = $ig_es_tracker::get_plugins();
151
  //get pro button
152
+ if ( ! in_array( $es_premium, $all_plugins ) && is_admin() && ! in_array( $screen_id, array( 'toplevel_page_es_dashboard' ), true ) ) {
153
+ echo "<div class='notice es-floting-button'><i class='dashicons dashicons-es dashicons-awards'></i> <a href='https://www.icegram.com/email-subscribers-pricing/?utm_source=in_app&utm_medium=get_starter_floating_button&utm_campaign=es_upsale' target='_blank'>" . __( 'Get Starter Now!', 'email-subscribers' ) . "</a></div>";
154
  }
155
  //cron notice
156
  $notice_option = get_option( 'ig_es_wp_cron_notice' );
273
  */
274
  private function load_dependencies( $feedback_version ) {
275
 
276
+ $feedback_version_for_file = str_replace( '.', '-', $feedback_version );
277
  /**
278
  * The class responsible for orchestrating the actions and filters of the
279
  * core plugin.
515
  return $schedules;
516
  }
517
 
518
+ }
includes/class-es-install.php CHANGED
@@ -111,6 +111,12 @@ class ES_Install {
111
  '4.1.1' => array(
112
  'ig_es_update_411_alter_contacts_table',
113
  'ig_es_update_411_db_version'
 
 
 
 
 
 
114
  )
115
  );
116
 
@@ -222,6 +228,8 @@ class ES_Install {
222
  public static function delete_update_transient() {
223
  global $wpdb;
224
 
 
 
225
  $transient_like = $wpdb->esc_like( '_transient_ig_es_update_' ) . '%';
226
  $updating_like = $wpdb->esc_like( '_transient_ig_es_updating' ) . '%';
227
  $last_sent_queue_like = '%' . $wpdb->esc_like( '_last_sending_queue_batch_run' ) . '%';
@@ -230,6 +238,7 @@ class ES_Install {
230
  $query = "DELETE FROM {$wpdb->prefix}options WHERE option_name LIKE '{$transient_like}' OR option_name LIKE '{$updating_like}' OR option_name LIKE '{$last_sent_queue_like}' OR option_name LIKE '{$running_migration_queue_like}' ";
231
 
232
  $wpdb->query( $query );
 
233
  }
234
 
235
  public static function is_new_install() {
@@ -274,7 +283,6 @@ class ES_Install {
274
  // Check if we are not already running this routine.
275
  if ( 'yes' === get_transient( 'ig_es_updating' ) ) {
276
  self::$logger->info( '********* Update is already running..... ****** ' );
277
-
278
  return;
279
  }
280
 
@@ -436,6 +444,7 @@ class ES_Install {
436
  `list_ids` text NOT NULL,
437
  `base_template_id` int(10) NOT NULL,
438
  `status` tinyint(4) NOT NULL,
 
439
  `created_at` datetime DEFAULT NULL,
440
  `updated_at` datetime DEFAULT NULL,
441
  `deleted_at` datetime DEFAULT NULL,
@@ -528,6 +537,7 @@ class ES_Install {
528
  `status` varchar(10) NOT NULL,
529
  `start_at` datetime DEFAULT NULL,
530
  `finish_at` datetime DEFAULT NULL,
 
531
  `created_at` datetime DEFAULT NULL,
532
  `updated_at` datetime DEFAULT NULL,
533
  PRIMARY KEY (id)
111
  '4.1.1' => array(
112
  'ig_es_update_411_alter_contacts_table',
113
  'ig_es_update_411_db_version'
114
+ ),
115
+
116
+ '4.1.7' => array(
117
+ 'ig_es_update_417_alter_campaigns_table',
118
+ 'ig_es_update_417_alter_mailing_queue_table',
119
+ 'ig_es_update_417_db_version'
120
  )
121
  );
122
 
228
  public static function delete_update_transient() {
229
  global $wpdb;
230
 
231
+ delete_option('ig_es_processed_update_tasks');
232
+
233
  $transient_like = $wpdb->esc_like( '_transient_ig_es_update_' ) . '%';
234
  $updating_like = $wpdb->esc_like( '_transient_ig_es_updating' ) . '%';
235
  $last_sent_queue_like = '%' . $wpdb->esc_like( '_last_sending_queue_batch_run' ) . '%';
238
  $query = "DELETE FROM {$wpdb->prefix}options WHERE option_name LIKE '{$transient_like}' OR option_name LIKE '{$updating_like}' OR option_name LIKE '{$last_sent_queue_like}' OR option_name LIKE '{$running_migration_queue_like}' ";
239
 
240
  $wpdb->query( $query );
241
+
242
  }
243
 
244
  public static function is_new_install() {
283
  // Check if we are not already running this routine.
284
  if ( 'yes' === get_transient( 'ig_es_updating' ) ) {
285
  self::$logger->info( '********* Update is already running..... ****** ' );
 
286
  return;
287
  }
288
 
444
  `list_ids` text NOT NULL,
445
  `base_template_id` int(10) NOT NULL,
446
  `status` tinyint(4) NOT NULL,
447
+ `meta` longtext DEFAULT NULL,
448
  `created_at` datetime DEFAULT NULL,
449
  `updated_at` datetime DEFAULT NULL,
450
  `deleted_at` datetime DEFAULT NULL,
537
  `status` varchar(10) NOT NULL,
538
  `start_at` datetime DEFAULT NULL,
539
  `finish_at` datetime DEFAULT NULL,
540
+ `meta` longtext DEFAULT NULL,
541
  `created_at` datetime DEFAULT NULL,
542
  `updated_at` datetime DEFAULT NULL,
543
  PRIMARY KEY (id)
includes/db/class-es-db-campaigns.php CHANGED
@@ -41,6 +41,7 @@ class ES_DB_Campaigns {
41
  'created_at' => '%s',
42
  'updated_at' => '%s',
43
  'deleted_at' => '%s',
 
44
  );
45
  }
46
 
@@ -65,7 +66,8 @@ class ES_DB_Campaigns {
65
  'status' => 0,
66
  'created_at' => ig_get_current_date_time(),
67
  'updated_at' => null,
68
- 'deleted_at' => null
 
69
  );
70
  }
71
 
@@ -74,7 +76,7 @@ class ES_DB_Campaigns {
74
 
75
 
76
  $campiagns_table = IG_CAMPAIGNS_TABLE;
77
- $query = "INSERT INTO {$campiagns_table} (`slug`, `name`, `type`, `from_name`, `from_email`, `reply_to_name`, `reply_to_email`, `sequence_ids`, `categories`, `list_ids`, `base_template_id`, `status`, `created_at`, `updated_at`, `deleted_at`) VALUES ";
78
  $query .= implode( ', ', $place_holders );
79
  $sql = $wpdb->prepare( "$query ", $values );
80
 
@@ -107,7 +109,6 @@ class ES_DB_Campaigns {
107
 
108
  $campaigns_data = $prepared_data['data'];
109
  $column_formats = $prepared_data['column_formats'];
110
-
111
  if ( $insert ) {
112
  $result = $wpdb->insert( IG_CAMPAIGNS_TABLE, $campaigns_data, $column_formats );
113
  if ( $result ) {
41
  'created_at' => '%s',
42
  'updated_at' => '%s',
43
  'deleted_at' => '%s',
44
+ 'meta' => '%s'
45
  );
46
  }
47
 
66
  'status' => 0,
67
  'created_at' => ig_get_current_date_time(),
68
  'updated_at' => null,
69
+ 'deleted_at' => null,
70
+ 'meta' => null
71
  );
72
  }
73
 
76
 
77
 
78
  $campiagns_table = IG_CAMPAIGNS_TABLE;
79
+ $query = "INSERT INTO {$campiagns_table} (`slug`, `name`, `type`, `from_name`, `from_email`, `reply_to_name`, `reply_to_email`, `sequence_ids`, `categories`, `list_ids`, `base_template_id`, `status`, `created_at`, `updated_at`, `deleted_at`, `meta`) VALUES ";
80
  $query .= implode( ', ', $place_holders );
81
  $sql = $wpdb->prepare( "$query ", $values );
82
 
109
 
110
  $campaigns_data = $prepared_data['data'];
111
  $column_formats = $prepared_data['column_formats'];
 
112
  if ( $insert ) {
113
  $result = $wpdb->insert( IG_CAMPAIGNS_TABLE, $campaigns_data, $column_formats );
114
  if ( $result ) {
includes/db/class-es-db-lists-contacts.php CHANGED
@@ -47,10 +47,16 @@ class ES_DB_Lists_Contacts {
47
 
48
  public static function get_list_contact_status_map( $id ) {
49
  global $wpdb;
50
- $query = "SELECT list_id, status FROM " . IG_LISTS_CONTACTS_TABLE . " WHERE contact_id = $id";
51
- $res = $wpdb->get_results( $query, ARRAY_A );
52
- foreach ( $res as $list ) {
53
- $lists_contact_status_map[ $list['list_id'] ] = $list['status'];
 
 
 
 
 
 
54
  }
55
 
56
  return $lists_contact_status_map;
@@ -202,5 +208,28 @@ class ES_DB_Lists_Contacts {
202
 
203
  }
204
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
205
 
206
  }
47
 
48
  public static function get_list_contact_status_map( $id ) {
49
  global $wpdb;
50
+
51
+ $query = "SELECT list_id, status FROM " . IG_LISTS_CONTACTS_TABLE . " WHERE contact_id = {$id}";
52
+
53
+ $res = $wpdb->get_results( $query, ARRAY_A );
54
+
55
+ $lists_contact_status_map = array();
56
+ if ( count( $res ) > 0 ) {
57
+ foreach ( $res as $list ) {
58
+ $lists_contact_status_map[ $list['list_id'] ] = $list['status'];
59
+ }
60
  }
61
 
62
  return $lists_contact_status_map;
208
 
209
  }
210
 
211
+ public static function get_list_status_by_contact_ids( $contact_ids ) {
212
+ global $wpdb;
213
+
214
+ $lists_contacts_table = IG_LISTS_CONTACTS_TABLE;
215
+
216
+ if ( is_array( $contact_ids ) ) {
217
+ $contact_ids_str = "'" . implode( "', '", $contact_ids ) . "'";
218
+ $query = "SELECT contact_id, list_id, status FROM {$lists_contacts_table} WHERE contact_id IN ($contact_ids_str)";
219
+ }
220
+
221
+ $results = $wpdb->get_results( $query, ARRAY_A );
222
+
223
+ $map = array();
224
+ if ( count( $results ) > 0 ) {
225
+
226
+ foreach ( $results as $result ) {
227
+ $map[ $result['contact_id'] ][ $result['list_id'] ] = $result['status'];
228
+ }
229
+ }
230
+
231
+ return $map;
232
+ }
233
+
234
 
235
  }
includes/db/class-es-db-mailing-queue.php CHANGED
@@ -7,7 +7,6 @@ if ( ! defined( 'ABSPATH' ) ) {
7
 
8
  class ES_DB_Mailing_Queue {
9
 
10
-
11
  public $table_name;
12
 
13
  public $version;
@@ -41,7 +40,8 @@ class ES_DB_Mailing_Queue {
41
  'start_at' => '%s',
42
  'finish_at' => '%s',
43
  'created_at' => '%s',
44
- 'updated_at' => '%s'
 
45
  );
46
  }
47
 
@@ -56,7 +56,8 @@ class ES_DB_Mailing_Queue {
56
  'start_at' => null,
57
  'finish_at' => null,
58
  'created_at' => ig_get_current_date_time(),
59
- 'updated_at' => null
 
60
  );
61
  }
62
 
@@ -78,21 +79,42 @@ class ES_DB_Mailing_Queue {
78
 
79
  $notification = array();
80
 
 
 
81
  if ( ! empty( $campaign_hash ) ) {
82
- $query = "SELECT * FROM " . IG_MAILING_QUEUE_TABLE . " WHERE hash = %s";
83
  $query = $wpdb->prepare( $query, array( $campaign_hash ) );
84
  } else {
85
- $query = "SELECT * FROM " . IG_MAILING_QUEUE_TABLE . " WHERE status IN ('Sending', 'In Queue') ORDER BY id LIMIT 0, 1";
 
 
86
  }
87
 
88
  $results = $wpdb->get_results( $query, ARRAY_A );
89
 
90
  if ( count( $results ) > 0 ) {
91
  $notification = array_shift( $results );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  //update sent date
93
  $currentdate = ig_get_current_date_time();
94
- $query = $wpdb->prepare( "UPDATE " . IG_MAILING_QUEUE_TABLE . "
95
- SET start_at = %s WHERE hash = %s AND start_at = %s", array( $currentdate, $notification['hash'], '0000-00-00 00:00:00' ) );
 
 
96
  $return_id = $wpdb->query( $query );
97
  }
98
 
7
 
8
  class ES_DB_Mailing_Queue {
9
 
 
10
  public $table_name;
11
 
12
  public $version;
40
  'start_at' => '%s',
41
  'finish_at' => '%s',
42
  'created_at' => '%s',
43
+ 'updated_at' => '%s',
44
+ 'meta' => '%s'
45
  );
46
  }
47
 
56
  'start_at' => null,
57
  'finish_at' => null,
58
  'created_at' => ig_get_current_date_time(),
59
+ 'updated_at' => null,
60
+ 'meta' => null
61
  );
62
  }
63
 
79
 
80
  $notification = array();
81
 
82
+ $ig_mailing_queue_table = IG_MAILING_QUEUE_TABLE;
83
+
84
  if ( ! empty( $campaign_hash ) ) {
85
+ $query = "SELECT * FROM {$ig_mailing_queue_table} WHERE hash = %s";
86
  $query = $wpdb->prepare( $query, array( $campaign_hash ) );
87
  } else {
88
+ $current_time = ig_get_current_date_time();
89
+
90
+ $query = "SELECT * FROM {$ig_mailing_queue_table} WHERE status IN ('Sending', 'In Queue') AND start_at <= '{$current_time}' ORDER BY start_at, id LIMIT 0, 1";
91
  }
92
 
93
  $results = $wpdb->get_results( $query, ARRAY_A );
94
 
95
  if ( count( $results ) > 0 ) {
96
  $notification = array_shift( $results );
97
+ // refresh content
98
+ $meta = maybe_unserialize( $notification['meta'] );
99
+ if ( ! empty( $meta ) ) {
100
+ if ( 'post_notification' === $meta['type'] ) {
101
+ $content = ES_Handle_Post_Notification::refresh_post_content( $meta['post_id'], $notification['campaign_id'] );
102
+ } elseif ( 'newsletter' === $meta['type'] ) {
103
+ $content = ES_Newsletters::refresh_newsletter_content( $notification['campaign_id'] );
104
+ }
105
+
106
+ if ( ! empty( $content ) ) {
107
+ $notification['subject'] = ! empty( $content['subject'] ) ? $content['subject'] : $notification['subject'];
108
+ $notification['body'] = ! empty( $content['body'] ) ? $content['body'] : $notification['body'];
109
+ $query_sub_str = " , subject = '" . esc_sql($notification['subject']) . "', body = '" . esc_sql($notification['body']) . "' ";
110
+ }
111
+ }
112
  //update sent date
113
  $currentdate = ig_get_current_date_time();
114
+ $query_str = "UPDATE {$ig_mailing_queue_table} SET start_at = %s ";
115
+ $where = " WHERE hash = %s AND start_at = %s";
116
+ $query_str = ! empty( $query_sub_str ) ? $query_str . $query_sub_str . $where : $query_str . $where;
117
+ $query = $wpdb->prepare( $query_str, array( $currentdate, $notification['hash'], '0000-00-00 00:00:00' ) );
118
  $return_id = $wpdb->query( $query );
119
  }
120
 
includes/db/class-es-db.php CHANGED
@@ -148,7 +148,7 @@ abstract class ES_DB {
148
 
149
  $query = "INSERT INTO {$table_name} ({$fields_str}) VALUES ";
150
  $query .= implode( ', ', $place_holders );
151
- $sql = $wpdb->prepare( "$query ", $values );
152
 
153
  if ( $wpdb->query( $sql ) ) {
154
  return true;
148
 
149
  $query = "INSERT INTO {$table_name} ({$fields_str}) VALUES ";
150
  $query .= implode( ', ', $place_holders );
151
+ $sql = $wpdb->prepare( $query, $values );
152
 
153
  if ( $wpdb->query( $sql ) ) {
154
  return true;
includes/feedback/class-ig-feedback-v-1-0-5.php CHANGED
@@ -956,8 +956,15 @@ if ( ! class_exists( 'IG_Feedback_V_1_0_5' ) ) {
956
  if ( false === strpos( $url, 'http://' ) && false === strpos( $url, 'https://' ) ) {
957
  $url = 'http://' . $url;
958
  }
 
959
  $url_parts = parse_url( $url );
960
  $host = ! empty( $url_parts['host'] ) ? $url_parts['host'] : false;
 
 
 
 
 
 
961
  if ( ! empty( $url ) && ! empty( $host ) ) {
962
  if ( false !== ip2long( $host ) ) {
963
  if ( ! filter_var( $host, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) ) {
956
  if ( false === strpos( $url, 'http://' ) && false === strpos( $url, 'https://' ) ) {
957
  $url = 'http://' . $url;
958
  }
959
+
960
  $url_parts = parse_url( $url );
961
  $host = ! empty( $url_parts['host'] ) ? $url_parts['host'] : false;
962
+
963
+ // Discard our development environment
964
+ if('192.168.0.112' === $host) {
965
+ return false;
966
+ }
967
+
968
  if ( ! empty( $url ) && ! empty( $host ) ) {
969
  if ( false !== ip2long( $host ) ) {
970
  if ( ! filter_var( $host, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) ) {
includes/upgrade/class-es-background-process.php CHANGED
@@ -100,13 +100,16 @@ abstract class ES_Background_Process extends WP_Background_Process {
100
 
101
  $logger->info( '--------------------- Started To Run Task Again---------------------', array( 'source' => 'es_update' ) );
102
  foreach ( $batch->data as $key => $value ) {
103
- $task_transient = $value . '_processed';
104
-
105
- $task = false; // By default it's set to false
 
106
  $logger->info( '-------- Checking Transient For: ' . $value, array( 'source' => 'es_update' ) );
107
- if ( false === get_transient( $task_transient ) ) {
 
 
108
  $logger->info( '------- Running Task: >>>>> ' . $value, array( 'source' => 'es_update' ) );
109
- $task = $this->task( $value );
110
  $logger->info( '------ Task Completed: >>>>> ' . $value . ' data ' . print_r( $task, true ), array( 'source' => 'es_update' ) );
111
  }
112
 
@@ -114,7 +117,12 @@ abstract class ES_Background_Process extends WP_Background_Process {
114
  $batch->data[ $key ] = $task;
115
  } else {
116
  $logger->info( '---- Setting Transient For: ' . $value, array( 'source' => 'es_update' ) );
117
- set_transient( $task_transient, true, MINUTE_IN_SECONDS * 100 );
 
 
 
 
 
118
  unset( $batch->data[ $key ] );
119
  }
120
 
100
 
101
  $logger->info( '--------------------- Started To Run Task Again---------------------', array( 'source' => 'es_update' ) );
102
  foreach ( $batch->data as $key => $value ) {
103
+ $is_value_exists = true;
104
+ //$task_transient = $value . '_processed';
105
+ $ig_es_update_processed_tasks = get_option( 'ig_es_processed_update_tasks', array() );
106
+ $task = false; // By default it's set to false
107
  $logger->info( '-------- Checking Transient For: ' . $value, array( 'source' => 'es_update' ) );
108
+ //if ( false === get_transient( $task_transient ) ) {
109
+ if ( ! in_array( $value, $ig_es_update_processed_tasks ) ) {
110
+ $is_value_exists = false;
111
  $logger->info( '------- Running Task: >>>>> ' . $value, array( 'source' => 'es_update' ) );
112
+ $task = (bool) $this->task( $value );
113
  $logger->info( '------ Task Completed: >>>>> ' . $value . ' data ' . print_r( $task, true ), array( 'source' => 'es_update' ) );
114
  }
115
 
117
  $batch->data[ $key ] = $task;
118
  } else {
119
  $logger->info( '---- Setting Transient For: ' . $value, array( 'source' => 'es_update' ) );
120
+
121
+ if ( ! $is_value_exists ) {
122
+ $ig_es_update_processed_tasks[] = $value;
123
+ update_option( 'ig_es_update_processed_tasks', $ig_es_update_processed_tasks );
124
+ }
125
+ //set_transient( $task_transient, true, MINUTE_IN_SECONDS * 100 );
126
  unset( $batch->data[ $key ] );
127
  }
128
 
includes/upgrade/es-update-functions.php CHANGED
@@ -435,9 +435,9 @@ function ig_es_update_400_delete_tables() {
435
  $wpdb->prefix . 'ig_sending_queue'
436
  );
437
 
438
- foreach ($tables_to_delete as $table) {
439
  $query = "DROP TABLE IF EXISTS {$table}";
440
- $wpdb->query($query);
441
  }
442
  }
443
 
@@ -506,7 +506,7 @@ function ig_es_update_400_migrate_notifications() {
506
 
507
  function ig_es_update_400_migrate_reports_data() {
508
 
509
- @ini_set('max_execution_time', 0);
510
  /**
511
  * - Migrate individual notification data from es_deliverreport to ig_es_sending_queue table
512
  * es_deliverreport => ig_es_sending_queue
@@ -625,6 +625,7 @@ function ig_es_update_4010_db_version() {
625
  $db_update_option = '4010_db_updated_at';
626
  ES_Common::set_ig_option( $db_update_option, ig_get_current_date_time() );
627
  }
 
628
  /* --------------------- ES 4.0.10(End)--------------------------- */
629
 
630
  function ig_es_update_4011_migrate_newsletter_es_template_type() {
@@ -640,6 +641,7 @@ function ig_es_update_4011_db_version() {
640
  $db_update_option = '4011_db_updated_at';
641
  ES_Common::set_ig_option( $db_update_option, ig_get_current_date_time() );
642
  }
 
643
  /* --------------------- ES 4.0.11(End)--------------------------- */
644
 
645
  function ig_es_update_4015_alter_blocked_emails_table() {
@@ -654,6 +656,7 @@ function ig_es_update_4015_db_version() {
654
  $db_update_option = '4015_db_updated_at';
655
  ES_Common::set_ig_option( $db_update_option, ig_get_current_date_time() );
656
  }
 
657
  /* --------------------- ES 4.0.15(End)--------------------------- */
658
  function ig_es_update_411_alter_contacts_table() {
659
  global $wpdb;
@@ -667,4 +670,35 @@ function ig_es_update_411_db_version() {
667
  $db_update_option = '411_db_updated_at';
668
  ES_Common::set_ig_option( $db_update_option, ig_get_current_date_time() );
669
  }
670
- /* --------------------- ES 4.1.1(End)--------------------------- */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
435
  $wpdb->prefix . 'ig_sending_queue'
436
  );
437
 
438
+ foreach ( $tables_to_delete as $table ) {
439
  $query = "DROP TABLE IF EXISTS {$table}";
440
+ $wpdb->query( $query );
441
  }
442
  }
443
 
506
 
507
  function ig_es_update_400_migrate_reports_data() {
508
 
509
+ @ini_set( 'max_execution_time', 0 );
510
  /**
511
  * - Migrate individual notification data from es_deliverreport to ig_es_sending_queue table
512
  * es_deliverreport => ig_es_sending_queue
625
  $db_update_option = '4010_db_updated_at';
626
  ES_Common::set_ig_option( $db_update_option, ig_get_current_date_time() );
627
  }
628
+
629
  /* --------------------- ES 4.0.10(End)--------------------------- */
630
 
631
  function ig_es_update_4011_migrate_newsletter_es_template_type() {
641
  $db_update_option = '4011_db_updated_at';
642
  ES_Common::set_ig_option( $db_update_option, ig_get_current_date_time() );
643
  }
644
+
645
  /* --------------------- ES 4.0.11(End)--------------------------- */
646
 
647
  function ig_es_update_4015_alter_blocked_emails_table() {
656
  $db_update_option = '4015_db_updated_at';
657
  ES_Common::set_ig_option( $db_update_option, ig_get_current_date_time() );
658
  }
659
+
660
  /* --------------------- ES 4.0.15(End)--------------------------- */
661
  function ig_es_update_411_alter_contacts_table() {
662
  global $wpdb;
670
  $db_update_option = '411_db_updated_at';
671
  ES_Common::set_ig_option( $db_update_option, ig_get_current_date_time() );
672
  }
673
+
674
+ /* --------------------- ES 4.1.1(End)--------------------------- */
675
+ function ig_es_update_417_alter_campaigns_table() {
676
+ global $wpdb;
677
+
678
+ $campaigns_table = IG_CAMPAIGNS_TABLE;
679
+
680
+ $cols = $wpdb->get_col( "SHOW COLUMNS FROM {$campaigns_table}" );
681
+ if ( ! in_array( 'meta', $cols ) ) {
682
+ $query = "ALTER TABLE {$campaigns_table} ADD COLUMN meta longtext NULL AFTER `status`";
683
+ $wpdb->query( $query );
684
+ }
685
+ }
686
+
687
+ function ig_es_update_417_alter_mailing_queue_table() {
688
+ global $wpdb;
689
+
690
+ $mailing_queue_table = IG_MAILING_QUEUE_TABLE;
691
+
692
+ $cols = $wpdb->get_col( "SHOW COLUMNS FROM {$mailing_queue_table}" );
693
+ if ( ! in_array( 'meta', $cols ) ) {
694
+ $query = "ALTER TABLE {$mailing_queue_table} ADD COLUMN meta longtext NULL AFTER `finish_at`";
695
+ $wpdb->query( $query );
696
+ }
697
+ }
698
+
699
+ function ig_es_update_417_db_version() {
700
+ ES_Install::update_db_version( '4.1.7' );
701
+ $db_update_option = '417_db_updated_at';
702
+ ES_Common::set_ig_option( $db_update_option, ig_get_current_date_time() );
703
+ }
704
+ /* --------------------- ES 4.1.7(End)--------------------------- */
public/partials/class-es-shortcode.php CHANGED
@@ -210,6 +210,11 @@ class ES_Shortcode {
210
  public static function prepare_lists_checkboxes( $lists, $list_ids = array(), $columns = 3, $selected_lists = array(), $contact_id = 0 ) {
211
  $lists_html = '<div><p><b>' . __('Select List(s)', 'email-subscribers') .'*</b></p><table class="ig-es-form-list-selection"><tr>';
212
  $i = 0;
 
 
 
 
 
213
  foreach ( $lists as $list_id => $list_name ) {
214
  if ( $i != 0 && ( $i % $columns ) === 0 ) {
215
  $lists_html .= "</tr><tr>";
@@ -218,7 +223,6 @@ class ES_Shortcode {
218
  if ( in_array( $list_id, $list_ids ) ) {
219
  if ( in_array( $list_id, $selected_lists ) ) {
220
  if ( ! empty( $contact_id ) ) {
221
- $list_contact_status_map = ES_DB_Lists_Contacts::get_list_contact_status_map( $contact_id );
222
  $status_span = '<span class="es_list_contact_status ' . $list_contact_status_map[ $list_id ] . '" title="' . ucwords( $list_contact_status_map[ $list_id ] ) . '">';
223
  }
224
  $lists_html .= '<td>' . $status_span . '<label><input type="checkbox" name="lists[]" checked="checked" value="' . $list_id . '" />' . $list_name . '</label></td>';
210
  public static function prepare_lists_checkboxes( $lists, $list_ids = array(), $columns = 3, $selected_lists = array(), $contact_id = 0 ) {
211
  $lists_html = '<div><p><b>' . __('Select List(s)', 'email-subscribers') .'*</b></p><table class="ig-es-form-list-selection"><tr>';
212
  $i = 0;
213
+
214
+ if(!empty($contact_id)) {
215
+ $list_contact_status_map = ES_DB_Lists_Contacts::get_list_contact_status_map( $contact_id );
216
+ }
217
+
218
  foreach ( $lists as $list_id => $list_name ) {
219
  if ( $i != 0 && ( $i % $columns ) === 0 ) {
220
  $lists_html .= "</tr><tr>";
223
  if ( in_array( $list_id, $list_ids ) ) {
224
  if ( in_array( $list_id, $selected_lists ) ) {
225
  if ( ! empty( $contact_id ) ) {
 
226
  $status_span = '<span class="es_list_contact_status ' . $list_contact_status_map[ $list_id ] . '" title="' . ucwords( $list_contact_status_map[ $list_id ] ) . '">';
227
  }
228
  $lists_html .= '<td>' . $status_span . '<label><input type="checkbox" name="lists[]" checked="checked" value="' . $list_id . '" />' . $list_name . '</label></td>';
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.2.2
8
- Stable tag: 4.1.6
9
  License: GPLv3
10
  License URI: http://www.gnu.org/licenses
11
 
@@ -304,6 +304,15 @@ Use our free plugin [Email Subscribers - Group Selector](https://wordpress.org/p
304
  9. Admin page - Settings Tab 4 - Security Settings
305
 
306
  == Changelog ==
 
 
 
 
 
 
 
 
 
307
  = 4.1.6 (01.07.2019) =
308
  * Update: Added sorting for name field in Audience tab
309
  * Fix: Warning: Illegal string offset 'es_registered'
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.2.2
8
+ Stable tag: 4.1.7
9
  License: GPLv3
10
  License URI: http://www.gnu.org/licenses
11
 
304
  9. Admin page - Settings Tab 4 - Security Settings
305
 
306
  == Changelog ==
307
+
308
+ = 4.1.7 (15.07.2019) =
309
+ * Update: Now, able to sort reports by Subject, Status, Start Date, End Date & Total Contacts
310
+ * Update: Now, able to sort forms by Name & Created date
311
+ * Update: Now, email template will pick up the latest content while email sending
312
+ * Fix: Importing issue
313
+ * Fix: Migration issue
314
+ * Fix: Fixed Vulnerability
315
+
316
  = 4.1.6 (01.07.2019) =
317
  * Update: Added sorting for name field in Audience tab
318
  * Fix: Warning: Illegal string offset 'es_registered'