Email Subscribers & Newsletters - Version 5.0.1

Version Description

  • Enhancement: Welcome and Confirmation email are now part of workflows
  • New: Preview email template in popup
  • Fix: Increase character limit in amazon SES
  • Fix: Prevent email sending while campaign is getting queued

=

Download this release

Release Info

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

Code changes from version 5.0.0 to 5.0.1

Files changed (40) hide show
  1. email-subscribers.php +2 -2
  2. lite/admin/class-email-subscribers-admin.php +85 -0
  3. lite/admin/class-ig-es-onboarding.php +38 -25
  4. lite/admin/css/email-subscribers-admin.css +4 -1
  5. lite/admin/images/bfcm2021.png +0 -0
  6. lite/admin/images/bfcm2021_lite.png +0 -0
  7. lite/admin/images/bfcm2021_starter.png +0 -0
  8. lite/admin/images/bfcm_2020.jpg +0 -0
  9. lite/admin/images/halloween2021.png +0 -0
  10. lite/admin/js/email-subscribers-admin.js +45 -0
  11. lite/includes/class-email-subscribers.php +13 -8
  12. lite/includes/class-es-install.php +91 -82
  13. lite/includes/classes/class-es-admin-settings.php +42 -147
  14. lite/includes/classes/class-es-geolocation.php +27 -0
  15. lite/includes/classes/class-es-handle-post-notification.php +1 -1
  16. lite/includes/classes/class-es-handle-subscription.php +4 -6
  17. lite/includes/classes/class-es-mailer.php +1 -1
  18. lite/includes/classes/class-es-newsletters.php +1 -10
  19. lite/includes/classes/class-es-queue.php +2 -121
  20. lite/includes/classes/class-es-templates-table.php +16 -113
  21. lite/includes/db/class-es-db-contacts.php +2 -2
  22. lite/includes/db/class-es-db-mailing-queue.php +35 -23
  23. lite/includes/db/class-es-db-sending-queue.php +25 -11
  24. lite/includes/notices/class-es-admin-notices.php +2 -2
  25. lite/includes/notices/views/ig-es-bfcm-offer.php +9 -2
  26. lite/includes/upgrade/es-update-functions.php +66 -0
  27. lite/includes/workflows/actions/class-es-action-send-email.php +114 -0
  28. lite/includes/workflows/class-es-workflow-actions.php +1 -0
  29. lite/includes/workflows/class-es-workflow-data-types.php +1 -0
  30. lite/includes/workflows/class-es-workflow-triggers.php +6 -5
  31. lite/includes/workflows/class-ig-es-variables-processor.php +3 -0
  32. lite/includes/workflows/data-types/class-es-data-type-campaign.php +93 -0
  33. lite/includes/workflows/data-types/class-es-data-type-subscriber.php +6 -8
  34. lite/includes/workflows/db/class-es-db-workflows.php +108 -1
  35. lite/includes/workflows/triggers/class-es-trigger-campaign-sent.php +79 -0
  36. lite/includes/workflows/triggers/class-es-trigger-user-deleted.php +1 -1
  37. lite/includes/workflows/triggers/class-es-trigger-user-subscribed.php +77 -0
  38. lite/includes/workflows/triggers/class-es-trigger-user-unconfirmed.php +77 -0
  39. lite/public/class-email-subscribers-public.php +2 -5
  40. readme.txt +13 -4
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: 5.0.0
7
  * Author: Icegram
8
  * Author URI: https://www.icegram.com/
9
  * Requires at least: 3.9
@@ -187,7 +187,7 @@ if ( 'premium' === $ig_es_plan ) {
187
  /* ***************************** Initial Compatibility Work (End) ******************* */
188
 
189
  if ( ! defined( 'ES_PLUGIN_VERSION' ) ) {
190
- define( 'ES_PLUGIN_VERSION', '5.0.0' );
191
  }
192
 
193
  // 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: 5.0.1
7
  * Author: Icegram
8
  * Author URI: https://www.icegram.com/
9
  * Requires at least: 3.9
187
  /* ***************************** Initial Compatibility Work (End) ******************* */
188
 
189
  if ( ! defined( 'ES_PLUGIN_VERSION' ) ) {
190
+ define( 'ES_PLUGIN_VERSION', '5.0.1' );
191
  }
192
 
193
  // Plugin Folder Path.
lite/admin/class-email-subscribers-admin.php CHANGED
@@ -100,6 +100,7 @@ class Email_Subscribers_Admin {
100
  // Ajax handler for email preview
101
  add_action( 'wp_ajax_ig_es_preview_email_report', array( $this, 'preview_email_in_report' ) );
102
  add_action( 'wp_ajax_ajax_fetch_report_list', array( $this, 'ajax_fetch_report_list_callback' ) );
 
103
 
104
  if ( class_exists( 'IG_ES_Premium_Services_UI' ) ) {
105
  IG_ES_Premium_Services_UI::instance();
@@ -1472,5 +1473,89 @@ class Email_Subscribers_Admin {
1472
  </div>
1473
  <?php
1474
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1475
  }
1476
 
100
  // Ajax handler for email preview
101
  add_action( 'wp_ajax_ig_es_preview_email_report', array( $this, 'preview_email_in_report' ) );
102
  add_action( 'wp_ajax_ajax_fetch_report_list', array( $this, 'ajax_fetch_report_list_callback' ) );
103
+ add_action( 'wp_ajax_ig_es_preview_template', array( $this, 'preview_email_template_design' ) );
104
 
105
  if ( class_exists( 'IG_ES_Premium_Services_UI' ) ) {
106
  IG_ES_Premium_Services_UI::instance();
1473
  </div>
1474
  <?php
1475
  }
1476
+
1477
+ /**
1478
+ * Method to preview email template on templates screen
1479
+ *
1480
+ * @since 4.9.2
1481
+ */
1482
+ public function preview_email_template_design() {
1483
+
1484
+ check_ajax_referer( 'ig-es-admin-ajax-nonce', 'security' );
1485
+
1486
+ $template_id = ig_es_get_request_data( 'template_id' );
1487
+
1488
+ $template = get_post( $template_id, ARRAY_A );
1489
+ if ( $template ) {
1490
+ $current_user = wp_get_current_user();
1491
+ $username = $current_user->user_login;
1492
+ $useremail = $current_user->user_email;
1493
+ $display_name = $current_user->display_name;
1494
+
1495
+ $contact_id = ES()->contacts_db->get_contact_id_by_email( $useremail );
1496
+ $first_name = '';
1497
+ $last_name = '';
1498
+
1499
+ // Use details from contacts data if present else fetch it from wp profile.
1500
+ if ( ! empty( $contact_id ) ) {
1501
+ $contact_data = ES()->contacts_db->get_by_id( $contact_id );
1502
+ $first_name = $contact_data['first_name'];
1503
+ $last_name = $contact_data['last_name'];
1504
+ } elseif ( ! empty( $display_name ) ) {
1505
+ $contact_details = explode( ' ', $display_name );
1506
+ $first_name = $contact_details[0];
1507
+ // Check if last name is set.
1508
+ if ( ! empty( $contact_details[1] ) ) {
1509
+ $last_name = $contact_details[1];
1510
+ }
1511
+ }
1512
+
1513
+ $es_template_body = $template['post_content'];
1514
+
1515
+ $es_template_type = get_post_meta( $template_id, 'es_template_type', true );
1516
+
1517
+ if ( 'post_notification' === $es_template_type ) {
1518
+ $args = array(
1519
+ 'numberposts' => '1',
1520
+ 'order' => 'DESC',
1521
+ 'post_status' => 'publish',
1522
+ );
1523
+ $recent_posts = wp_get_recent_posts( $args );
1524
+
1525
+ if ( count( $recent_posts ) > 0 ) {
1526
+ $recent_post = array_shift( $recent_posts );
1527
+
1528
+ $post_id = $recent_post['ID'];
1529
+ $es_template_body = ES_Handle_Post_Notification::prepare_body( $es_template_body, $post_id, $template_id );
1530
+ }
1531
+ } else {
1532
+ $es_template_body = ES_Common::es_process_template_body( $es_template_body, $template_id );
1533
+ }
1534
+
1535
+ $es_template_body = str_replace( '{{NAME}}', $username, $es_template_body );
1536
+ $es_template_body = str_replace( '{{EMAIL}}', $useremail, $es_template_body );
1537
+ $es_template_body = str_replace( '{{FIRSTNAME}}', $first_name, $es_template_body );
1538
+ $es_template_body = str_replace( '{{LASTNAME}}', $last_name, $es_template_body );
1539
+ $allowedtags = ig_es_allowed_html_tags_in_esc();
1540
+ add_filter( 'safe_style_css', 'ig_es_allowed_css_style' );
1541
+
1542
+ if ( has_post_thumbnail( $template_id ) ) {
1543
+ $image_array = wp_get_attachment_image_src( get_post_thumbnail_id( $template_id ), 'full' );
1544
+ $image = '<img src="' . $image_array[0] . '" class="img-responsive" alt="Image for Post ' . $template_id . '" />';
1545
+ } else {
1546
+ $image = '';
1547
+ }
1548
+ $response['template_html'] = apply_filters( 'the_content', $es_template_body );
1549
+ } else {
1550
+ $response['template_html'] = __( 'Please publish it or save it as a draft.', 'email-subscribers' );
1551
+ }
1552
+
1553
+ if ( ! empty( $response ) ) {
1554
+ wp_send_json_success( $response );
1555
+ } else {
1556
+ wp_send_json_error();
1557
+ }
1558
+ }
1559
+
1560
  }
1561
 
lite/admin/class-ig-es-onboarding.php CHANGED
@@ -50,7 +50,7 @@ if ( ! class_exists( 'IG_ES_Onboarding' ) ) {
50
  'set_settings',
51
  'create_default_lists',
52
  'create_contacts_and_add_to_list',
53
- 'add_workflow_for_user_registration',
54
  'create_default_newsletter_broadcast',
55
  'create_default_post_notification',
56
  'create_default_subscription_form',
@@ -581,39 +581,52 @@ if ( ! class_exists( 'IG_ES_Onboarding' ) ) {
581
  *
582
  * @since 4.6.0
583
  */
584
- public function add_workflow_for_user_registration() {
 
585
 
586
  $response = array(
587
  'status' => 'error',
588
  );
589
 
590
- $workflow_query_args = array(
591
- 'trigger_name' => 'ig_es_user_registered',
592
- );
593
-
594
- $workflows = ES()->workflows_db->get_workflows( $workflow_query_args );
595
-
596
- // Add workflow only if there is no workflow for user registration already present.
597
- if ( empty( $workflows ) ) {
598
- $main_list = ES()->lists_db->get_list_by_name( IG_MAIN_LIST );
599
 
600
- // Check if Main list exists.
601
- if ( ! empty( $main_list ) ) {
602
- $workflow_title = __( 'User Registered', 'email-subscribers' );
603
- $workflow_name = sanitize_title( $workflow_title );
604
- $trigger_name = 'ig_es_user_registered';
605
- $main_list_id = $main_list['id'];
606
- $workflow_meta = array();
607
- $workflow_meta['when_to_run'] = 'immediately';
608
- $workflow_status = 0;
609
 
610
- $workflow_actions = array(
 
 
 
 
 
 
611
  array(
612
  'action_name' => 'ig_es_add_to_list',
613
  'ig-es-list' => ES_Clean::id( $main_list_id ),
614
- ),
615
- );
 
 
 
616
 
 
 
 
 
 
 
 
 
 
 
 
617
  $workflow_data = array(
618
  'name' => $workflow_name,
619
  'title' => $workflow_title,
@@ -623,14 +636,14 @@ if ( ! class_exists( 'IG_ES_Onboarding' ) ) {
623
  'priority' => 0,
624
  'status' => $workflow_status,
625
  );
626
-
627
  $workflow_id = ES()->workflows_db->insert_workflow( $workflow_data );
628
  if ( $workflow_id ) {
629
  $response['status'] = 'success';
630
  }
631
  }
632
  }
633
-
634
  return $response;
635
  }
636
 
50
  'set_settings',
51
  'create_default_lists',
52
  'create_contacts_and_add_to_list',
53
+ 'add_default_workflows',
54
  'create_default_newsletter_broadcast',
55
  'create_default_post_notification',
56
  'create_default_subscription_form',
581
  *
582
  * @since 4.6.0
583
  */
584
+ public function add_default_workflows() {
585
+
586
 
587
  $response = array(
588
  'status' => 'error',
589
  );
590
 
591
+ $admin_emails = ES()->mailer->get_admin_emails();
592
+ if ( ! empty( $admin_emails ) ) {
593
+ $admin_emails = implode( ',', $admin_emails );
594
+ }
595
+
596
+ $default_workflows = array();
 
 
 
597
 
598
+ $notification_workflows = ES()->workflows_db->get_notification_workflows();
599
+ if ( ! empty( $notification_workflows ) ) {
600
+ $default_workflows = $notification_workflows;
601
+ }
 
 
 
 
 
602
 
603
+ $main_list = ES()->lists_db->get_list_by_name( IG_MAIN_LIST );
604
+ if ( ! empty( $main_list['id'] ) ) {
605
+ $main_list_id = $main_list['id'];
606
+ $default_workflows[] = array(
607
+ 'trigger_name' => 'ig_es_user_registered',
608
+ 'title' => sprintf( __( 'Add to %s list when someone registers', 'email-subscribers' ), IG_MAIN_LIST ),
609
+ 'actions' => array(
610
  array(
611
  'action_name' => 'ig_es_add_to_list',
612
  'ig-es-list' => ES_Clean::id( $main_list_id ),
613
+ )
614
+ ),
615
+ 'status' => 0
616
+ );
617
+ }
618
 
619
+ if ( ! empty( $default_workflows ) ) {
620
+ foreach ( $default_workflows as $workflow ) {
621
+ $workflow_title = $workflow['title'];
622
+ $workflow_name = sanitize_title( $workflow_title );
623
+ $trigger_name = $workflow['trigger_name'];
624
+ $workflow_meta = array();
625
+ $workflow_meta['when_to_run'] = 'immediately';
626
+ $workflow_status = $workflow['status'];
627
+
628
+ $workflow_actions = $workflow['actions'];
629
+
630
  $workflow_data = array(
631
  'name' => $workflow_name,
632
  'title' => $workflow_title,
636
  'priority' => 0,
637
  'status' => $workflow_status,
638
  );
639
+
640
  $workflow_id = ES()->workflows_db->insert_workflow( $workflow_data );
641
  if ( $workflow_id ) {
642
  $response['status'] = 'success';
643
  }
644
  }
645
  }
646
+
647
  return $response;
648
  }
649
 
lite/admin/css/email-subscribers-admin.css CHANGED
@@ -1652,7 +1652,7 @@ input[type="date"]::-webkit-clear-button {
1652
  display: none;
1653
  }
1654
 
1655
- .broadcast_preview_container, .report_preview_container {
1656
  height: 300px;
1657
  overflow: hidden;
1658
  overflow-y: auto;
@@ -1757,8 +1757,11 @@ div.broadcast_side_content{
1757
 
1758
  .post-type-es_template #wp-content-editor-tools{
1759
  padding-top: 18px;
 
1760
  }
1761
 
 
 
1762
  /* Template Page : end */
1763
 
1764
  /* Upselling css: end */
1652
  display: none;
1653
  }
1654
 
1655
+ .broadcast_preview_container, .report_preview_container, .template_preview_container {
1656
  height: 300px;
1657
  overflow: hidden;
1658
  overflow-y: auto;
1757
 
1758
  .post-type-es_template #wp-content-editor-tools{
1759
  padding-top: 18px;
1760
+ z-index: 1;
1761
  }
1762
 
1763
+
1764
+
1765
  /* Template Page : end */
1766
 
1767
  /* Upselling css: end */
lite/admin/images/bfcm2021.png ADDED
Binary file
lite/admin/images/bfcm2021_lite.png ADDED
Binary file
lite/admin/images/bfcm2021_starter.png ADDED
Binary file
lite/admin/images/bfcm_2020.jpg DELETED
Binary file
lite/admin/images/halloween2021.png DELETED
Binary file
lite/admin/js/email-subscribers-admin.js CHANGED
@@ -45,6 +45,44 @@
45
  });
46
  });
47
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  $(document).on('change', '.es_visible', function () {
49
  if ($('.es_visible:checked').length >= 1) {
50
  $('.es_required').prop('disabled', false);
@@ -970,6 +1008,13 @@
970
  $('#report_preview_template').hide();
971
  });
972
 
 
 
 
 
 
 
 
973
 
974
  // Workflow JS
975
  IG_ES_Workflows = {
45
  });
46
  });
47
 
48
+ $('.es_template_preview').click(function(){
49
+ let template_id = $(this).data('post-id');
50
+ let elem = $(this);
51
+
52
+ let preview_data = {
53
+ action : 'ig_es_preview_template',
54
+ security : ig_es_js_data.security,
55
+ template_id : template_id,
56
+ };
57
+
58
+ jQuery.ajax({
59
+ method: 'POST',
60
+ url: ajaxurl,
61
+ data: preview_data,
62
+ dataType: 'json',
63
+ beforeSend: function() {
64
+ $(elem).next('.es-template-preview-loader').show();
65
+ },
66
+ success: function (response) {
67
+ if (response.success) {
68
+ if ( 'undefined' !== typeof response.data ) {
69
+ let response_data = response.data;
70
+ let template_html = response_data.template_html;
71
+ $('.template_preview_container').html(template_html);
72
+ $('#es_preview_template').load().show();
73
+ }
74
+ } else {
75
+ alert( ig_es_js_data.i18n_data.ajax_error_message );
76
+ }
77
+ },
78
+ error: function (err) {
79
+ alert( ig_es_js_data.i18n_data.ajax_error_message );
80
+ }
81
+ }).always(function(){
82
+ $(elem).next('.es-template-preview-loader').hide();
83
+ });
84
+ });
85
+
86
  $(document).on('change', '.es_visible', function () {
87
  if ($('.es_visible:checked').length >= 1) {
88
  $('.es_required').prop('disabled', false);
1008
  $('#report_preview_template').hide();
1009
  });
1010
 
1011
+ jQuery('#es_close_template_preview').on('click', function (event) {
1012
+ event.preventDefault();
1013
+ $('#es_preview_template').hide();
1014
+ });
1015
+
1016
+
1017
+
1018
 
1019
  // Workflow JS
1020
  IG_ES_Workflows = {
lite/includes/class-email-subscribers.php CHANGED
@@ -309,7 +309,7 @@ if ( ! class_exists( 'Email_Subscribers' ) ) {
309
  $show_offer = false;
310
  $current_page = ig_es_get_request_data( 'page' );
311
 
312
- if ( $this->can_upsell_features( array( 'lite', 'trial', 'starter' ) ) && IG_ES_Onboarding::is_onboarding_completed() ) {
313
  if ( 'es_reports' === $current_page ) {
314
  $report_insight = ig_es_get_request_data( 'insight' );
315
  if ( ! $report_insight ) {
@@ -322,10 +322,10 @@ if ( ! class_exists( 'Email_Subscribers' ) ) {
322
 
323
  if ( $show_offer ) {
324
  $args['url'] = 'https://www.icegram.com/';
325
- $args['include'] = ES_PLUGIN_DIR . 'lite/includes/notices/views/ig-es-halloween-offer.php';
326
- ES_Admin_Notices::add_custom_notice( 'halloween_offer_2021', $args );
327
  } else {
328
- ES_Admin_Notices::remove_notice( 'halloween_offer_2021' );
329
  }
330
 
331
  $screen_id = $this->get_current_screen_id();
@@ -819,6 +819,7 @@ if ( ! class_exists( 'Email_Subscribers' ) ) {
819
  'lite/includes/workflows/data-types/abstracts/class-es-data-type-form-data.php',
820
  'lite/includes/workflows/data-types/class-es-data-type-user.php',
821
  'lite/includes/workflows/data-types/class-es-data-type-subscriber.php',
 
822
  'lite/includes/workflows/class-es-workflow-data-types.php',
823
 
824
  'lite/includes/workflows/variables/class-es-workflow-data-types.php',
@@ -846,6 +847,9 @@ if ( ! class_exists( 'Email_Subscribers' ) ) {
846
  'lite/includes/workflows/triggers/class-es-trigger-user-registered.php',
847
  'lite/includes/workflows/triggers/class-es-trigger-user-deleted.php',
848
  'lite/includes/workflows/triggers/class-es-trigger-user-updated.php',
 
 
 
849
  'lite/includes/workflows/class-es-workflow-triggers.php',
850
 
851
  // Abstracts workflow actions
@@ -857,6 +861,7 @@ if ( ! class_exists( 'Email_Subscribers' ) ) {
857
  'lite/includes/workflows/actions/class-es-action-remove-contact.php',
858
  'lite/includes/workflows/actions/class-es-action-delete-contact.php',
859
  'lite/includes/workflows/actions/class-es-action-update-contact.php',
 
860
  'lite/includes/workflows/class-es-workflow-actions.php',
861
 
862
  // Workflow Query
@@ -1992,14 +1997,14 @@ if ( ! class_exists( 'Email_Subscribers' ) ) {
1992
  $current_utc_time = time();
1993
  $current_ist_time = $current_utc_time + ( 5.5 * HOUR_IN_SECONDS ); // Add IST offset to get IST time
1994
 
1995
- if ( 'halloween' === $offer_name ) {
1996
- $offer_start_time = strtotime( '2021-10-27 12:00:00' ); // Offer start time in IST
1997
- $offer_end_time = strtotime( '2021-11-02 12:00:00' ); // Offer end time in IST
1998
  }
1999
 
2000
  $is_offer_period = $current_ist_time >= $offer_start_time && $current_ist_time <= $offer_end_time;
2001
  }
2002
-
2003
  return $is_offer_period;
2004
  }
2005
  }
309
  $show_offer = false;
310
  $current_page = ig_es_get_request_data( 'page' );
311
 
312
+ if ( $this->can_upsell_features( array( 'lite', 'trial', 'starter', 'pro' ) ) && IG_ES_Onboarding::is_onboarding_completed() ) {
313
  if ( 'es_reports' === $current_page ) {
314
  $report_insight = ig_es_get_request_data( 'insight' );
315
  if ( ! $report_insight ) {
322
 
323
  if ( $show_offer ) {
324
  $args['url'] = 'https://www.icegram.com/';
325
+ $args['include'] = ES_PLUGIN_DIR . 'lite/includes/notices/views/ig-es-bfcm-offer.php';
326
+ ES_Admin_Notices::add_custom_notice( 'bfcm_offer_2021', $args );
327
  } else {
328
+ ES_Admin_Notices::remove_notice( 'bfcm_offer_2021' );
329
  }
330
 
331
  $screen_id = $this->get_current_screen_id();
819
  'lite/includes/workflows/data-types/abstracts/class-es-data-type-form-data.php',
820
  'lite/includes/workflows/data-types/class-es-data-type-user.php',
821
  'lite/includes/workflows/data-types/class-es-data-type-subscriber.php',
822
+ 'lite/includes/workflows/data-types/class-es-data-type-campaign.php',
823
  'lite/includes/workflows/class-es-workflow-data-types.php',
824
 
825
  'lite/includes/workflows/variables/class-es-workflow-data-types.php',
847
  'lite/includes/workflows/triggers/class-es-trigger-user-registered.php',
848
  'lite/includes/workflows/triggers/class-es-trigger-user-deleted.php',
849
  'lite/includes/workflows/triggers/class-es-trigger-user-updated.php',
850
+ 'lite/includes/workflows/triggers/class-es-trigger-user-subscribed.php',
851
+ 'lite/includes/workflows/triggers/class-es-trigger-user-unconfirmed.php',
852
+ 'lite/includes/workflows/triggers/class-es-trigger-campaign-sent.php',
853
  'lite/includes/workflows/class-es-workflow-triggers.php',
854
 
855
  // Abstracts workflow actions
861
  'lite/includes/workflows/actions/class-es-action-remove-contact.php',
862
  'lite/includes/workflows/actions/class-es-action-delete-contact.php',
863
  'lite/includes/workflows/actions/class-es-action-update-contact.php',
864
+ 'lite/includes/workflows/actions/class-es-action-send-email.php',
865
  'lite/includes/workflows/class-es-workflow-actions.php',
866
 
867
  // Workflow Query
1997
  $current_utc_time = time();
1998
  $current_ist_time = $current_utc_time + ( 5.5 * HOUR_IN_SECONDS ); // Add IST offset to get IST time
1999
 
2000
+ if ( 'bfcm' === $offer_name ) {
2001
+ $offer_start_time = strtotime( '2021-11-24 12:00:00' ); // Offer start time in IST
2002
+ $offer_end_time = strtotime( '2021-12-01 12:00:00' ); // Offer end time in IST
2003
  }
2004
 
2005
  $is_offer_period = $current_ist_time >= $offer_start_time && $current_ist_time <= $offer_end_time;
2006
  }
2007
+
2008
  return $is_offer_period;
2009
  }
2010
  }
lite/includes/class-es-install.php CHANGED
@@ -34,27 +34,27 @@ if ( ! class_exists( 'ES_Install' ) ) {
34
  */
35
  private static $db_updates = array(
36
 
37
- '3.2.0' => array(
38
  'ig_es_update_320_add_sync_option',
39
  'ig_es_update_320_db_version',
40
  ),
41
 
42
- '3.2.7' => array(
43
  'ig_es_update_327_change_email_type',
44
  'ig_es_update_327_db_version',
45
  ),
46
 
47
- '3.3.0' => array(
48
  'ig_es_update_330_import_options',
49
  'ig_es_update_330_db_version',
50
  ),
51
 
52
- '3.3.6' => array(
53
  'ig_es_update_336_add_template_slug',
54
  'ig_es_update_336_db_version',
55
  ),
56
 
57
- '3.4.0' => array(
58
  'ig_es_update_340_migrate_templates_to_cpt',
59
  'ig_es_update_340_migrate_keywords',
60
  'ig_es_update_340_db_version',
@@ -66,7 +66,7 @@ if ( ! class_exists( 'ES_Install' ) ) {
66
  ),
67
 
68
 
69
- '4.0.0' => array(
70
  /**
71
  * - Create Tables
72
  * - Import Options
@@ -89,23 +89,23 @@ if ( ! class_exists( 'ES_Install' ) ) {
89
  'ig_es_update_400_db_version',
90
  ),
91
 
92
- '4.0.1' => array(
93
  'ig_es_update_401_migrate_newsletters',
94
  'ig_es_update_401_db_version',
95
  ),
96
 
97
- '4.0.2' => array(
98
  'ig_es_update_402_migrate_post_notification_es_template_type',
99
  'ig_es_update_402_db_version',
100
  ),
101
 
102
- '4.0.3' => array(
103
  'ig_es_update_403_alter_campaigns_table',
104
  'ig_es_update_403_alter_mailing_queue_table',
105
  'ig_es_update_403_db_version',
106
  ),
107
 
108
- '4.0.5' => array(
109
  'ig_es_update_405_alter_forms_table',
110
  'ig_es_update_405_alter_lists_table',
111
  'ig_es_update_405_migrate_widgets',
@@ -127,12 +127,12 @@ if ( ! class_exists( 'ES_Install' ) ) {
127
  'ig_es_update_4015_db_version',
128
  ),
129
 
130
- '4.1.1' => array(
131
  'ig_es_update_411_alter_contacts_table',
132
  'ig_es_update_411_db_version',
133
  ),
134
 
135
- '4.1.7' => array(
136
  'ig_es_update_417_alter_campaigns_table',
137
  'ig_es_update_417_alter_mailing_queue_table',
138
  'ig_es_update_417_db_version',
@@ -149,31 +149,31 @@ if ( ! class_exists( 'ES_Install' ) ) {
149
  'ig_es_update_4115_db_version',
150
  ),
151
 
152
- '4.2.0' => array(
153
  'ig_es_update_420_alter_campaigns_table',
154
  'ig_es_update_420_create_tables',
155
  'ig_es_update_420_migrate_mailer_options',
156
  'ig_es_update_420_db_version',
157
  ),
158
 
159
- '4.2.1' => array(
160
  'ig_es_update_421_drop_tables',
161
  'ig_es_update_421_create_tables',
162
  'ig_es_update_421_db_version',
163
  ),
164
 
165
- '4.2.4' => array(
166
  'ig_es_update_424_drop_tables',
167
  'ig_es_update_424_create_tables',
168
  'ig_es_update_424_db_version',
169
  ),
170
 
171
- '4.3.0' => array(
172
  'ig_es_update_430_alter_campaigns_table',
173
  'ig_es_update_430_db_version',
174
  ),
175
 
176
- '4.3.1' => array(
177
  'ig_es_update_431_set_default_permissions',
178
  'ig_es_update_431_permanently_delete_lists',
179
  'ig_es_update_431_permanently_delete_forms',
@@ -181,28 +181,28 @@ if ( ! class_exists( 'ES_Install' ) ) {
181
  'ig_es_update_431_db_version',
182
  ),
183
 
184
- '4.3.2' => array(
185
  'ig_es_update_432_import_bfcm_templates',
186
  'ig_es_update_432_db_version',
187
  ),
188
 
189
- '4.3.4' => array(
190
  'ig_es_update_434_permanently_delete_campaigns',
191
  'ig_es_update_434_db_version',
192
  ),
193
 
194
- '4.4.1' => array(
195
  'ig_es_update_441_create_tables',
196
  'ig_es_update_441_migrate_audience_sync_settings',
197
  'ig_es_update_441_db_version',
198
  ),
199
 
200
- '4.4.2' => array(
201
  'ig_es_update_442_set_workflows_default_permission',
202
  'ig_es_update_442_db_version',
203
  ),
204
 
205
- '4.4.9' => array(
206
  'ig_es_update_449_create_tables',
207
  'ig_es_update_449_db_version',
208
  ),
@@ -212,18 +212,18 @@ if ( ! class_exists( 'ES_Install' ) ) {
212
  'ig_es_update_4410_db_version',
213
  ),
214
 
215
- '4.5.0' => array(
216
  'ig_es_update_450_alter_actions_table',
217
  'ig_es_update_450_db_version',
218
  ),
219
 
220
- '4.5.7' => array(
221
  'ig_es_update_457_alter_list_table',
222
  'ig_es_update_457_add_list_hash',
223
  'ig_es_update_457_db_version',
224
  ),
225
 
226
- '4.6.3' => array(
227
  'ig_es_update_463_alter_contacts_table',
228
  'ig_es_migrate_ip_from_list_contacts_to_contacts_table',
229
  'ig_es_update_463_db_version',
@@ -262,19 +262,26 @@ if ( ! class_exists( 'ES_Install' ) ) {
262
  'ig_es_add_primay_key_to_actions_table',
263
  'ig_es_update_479_db_version',
264
  ),
265
- '4.8.3' => array(
266
  'ig_es_add_engagement_score_to_contacts_table',
267
  'ig_es_calculate_existing_subscribers_engagement_score',
268
  'ig_es_update_483_db_version',
269
  ),
270
- '4.8.4' => array(
271
  'ig_es_update_484_create_custom_field_table',
272
  'ig_es_update_484_db_version',
273
  ),
274
- '4.9.0' => array(
275
  'ig_es_update_490_alter_contacts_table',
276
  'ig_es_update_490_db_version',
277
  ),
 
 
 
 
 
 
 
278
  );
279
 
280
  /**
@@ -765,7 +772,7 @@ if ( ! class_exists( 'ES_Install' ) ) {
765
  $guid = ES_Common::generate_guid( 6 );
766
  $cronurl = $home_url . '?es=cron&guid=' . $guid;
767
 
768
- $report = '';
769
  $report .= "Hi Admin,\n\n";
770
  $report .= "Email has been sent successfully to {{COUNT}} email(s). Please find the details below:\n\n";
771
  $report .= "Unique ID: {{UNIQUE}}\n";
@@ -792,194 +799,195 @@ if ( ! class_exists( 'ES_Install' ) ) {
792
  $unsubscribe_error_message = "Urrgh.. Something's wrong..\r\n\r\nAre you sure that email address is on our file? There was some problem in completing your request.\r\n\r\nPlease try again after some time - or contact us if the problem persists.\r\n\r\n";
793
 
794
  $options = array(
795
- 'ig_es_from_name' => array(
796
  'default' => $sender_details['name'],
797
  'old_option' => 'ig_es_fromname',
798
  ),
799
- 'ig_es_from_email' => array(
800
  'default' => $sender_details['email'],
801
  'old_option' => 'ig_es_fromemail',
802
  ),
803
- 'ig_es_admin_new_contact_email_subject' => array(
804
  'default' => $new_contact_email_subject,
805
  'old_option' => 'ig_es_admin_new_sub_subject',
806
  ),
807
- 'ig_es_admin_new_contact_email_content' => array(
808
  'default' => $new_contact_email_content,
809
  'old_option' => 'ig_es_admin_new_sub_content',
810
  ),
811
- 'ig_es_admin_emails' => array(
812
  'default' => $admin_email,
813
  'old_option' => 'ig_es_adminemail',
814
  ),
815
- 'ig_es_confirmation_mail_subject' => array(
816
  'default' => $confirmation_email_subject,
817
  'old_option' => 'ig_es_confirmsubject',
818
  ),
819
- 'ig_es_confirmation_mail_content' => array(
820
  'default' => $confirmation_email_content,
821
  'old_option' => 'ig_es_confirmcontent',
822
  ),
823
- 'ig_es_enable_welcome_email' => array(
824
  'default' => 'yes',
825
  'old_option' => 'ig_es_welcomeemail',
826
  'action' => 'convert_space_to_underscore',
827
  ),
828
- 'ig_es_welcome_email_subject' => array(
829
  'default' => $welcome_email_subject,
830
  'old_option' => 'ig_es_welcomesubject',
831
  ),
832
- 'ig_es_welcome_email_content' => array(
833
  'default' => $welcome_email_content,
834
  'old_option' => 'ig_es_welcomecontent',
835
  ),
836
- 'ig_es_enable_cron_admin_email' => array(
837
  'default' => 'yes',
838
  'old_option' => 'ig_es_enable_cron_adminmail',
839
  ),
840
- 'ig_es_enable_summary_automation' => array(
841
  'default' => 'yes',
842
  'old_option' => 'ig_es_enable_summary_automation',
843
  ),
844
- 'ig_es_run_cron_on' => array(
845
  'default' => 'monday',
846
  'old_option' => 'ig_es_run_cron_on',
847
  ),
848
- 'ig_es_run_cron_time' => array(
849
  'default' => '4pm',
850
  'old_option' => 'ig_es_run_cron_time',
851
  ),
852
- 'ig_es_cron_admin_email' => array(
853
  'default' => $cron_admin_email,
854
  'old_option' => 'ig_es_cron_adminmail',
855
  ),
856
- 'ig_es_cronurl' => array(
857
  'default' => $cronurl,
858
  'old_option' => 'ig_es_cronurl',
859
  ),
860
- 'ig_es_hourly_email_send_limit' => array(
861
  'default' => 300,
862
  'old_option' => 'ig_es_cron_mailcount',
863
  ),
864
- 'ig_es_sent_report_subject' => array(
865
  'default' => 'Your email has been sent',
866
  'old_option' => 'ig_es_sentreport_subject',
867
  ),
868
- 'ig_es_sent_report_content' => array(
869
  'default' => $report,
870
  'old_option' => 'ig_es_sentreport',
871
  ),
872
- 'ig_es_unsubscribe_link' => array(
873
  'default' => $unsublink,
874
  'old_option' => 'ig_es_unsublink',
875
  ),
876
- 'ig_es_optin_link' => array(
877
  'default' => $optinlink,
878
  'old_option' => 'ig_es_optinlink',
879
  ),
880
- 'ig_es_unsubscribe_link_content' => array(
881
  'default' => $unsubscribe_link_content,
882
  'old_option' => 'ig_es_unsubcontent',
883
  ),
884
- 'ig_es_email_type' => array(
885
  'default' => 'wp_html_mail',
886
  'old_option' => 'ig_es_emailtype',
887
  'action' => 'convert_space_to_underscore',
888
  ),
889
- 'ig_es_notify_admin' => array(
890
  'default' => 'yes',
891
  'old_option' => 'ig_es_notifyadmin',
892
  'action' => 'convert_space_to_underscore',
893
  ),
894
- 'ig_es_optin_type' => array(
895
  'default' => 'double_opt_in',
896
  'old_option' => 'ig_es_optintype',
897
  'action' => 'convert_space_to_underscore',
898
  ),
899
- 'ig_es_subscription_error_messsage' => array(
900
  'default' => $subscription_error_message,
901
  'old_option' => 'ig_es_suberror',
902
  ),
903
- 'ig_es_subscription_success_message' => array(
904
  'default' => 'You have been successfully subscribed.',
905
  'old_option' => 'ig_es_successmsg',
906
  ),
907
- 'ig_es_unsubscribe_error_message' => array(
908
  'default' => $unsubscribe_error_message,
909
  'old_option' => 'ig_es_unsuberror',
910
  ),
911
- 'ig_es_unsubscribe_success_message' => array(
912
  'default' => $unsubscribe_message,
913
  'old_option' => 'ig_es_unsubtext',
914
  ),
915
- 'ig_es_post_image_size' => array(
916
  'default' => 'thumbnail',
917
  'old_option' => 'ig_es_post_image_size',
918
  ),
919
- 'ig_es_db_version' => array(
920
  'default' => $latest_db_version,
921
  'old_option' => 'current_sa_email_subscribers_db_version',
922
  ),
923
- 'ig_es_current_version_date_details' => array(
924
  'default' => '',
925
  'old_option' => '',
926
  ),
927
- 'ig_es_enable_captcha' => array(
928
  'default' => '',
929
  'old_option' => '',
930
  ),
931
- 'ig_es_roles_and_capabilities' => array(
932
  'default' => '',
933
  'old_option' => 'ig_es_rolesandcapabilities',
934
  ),
935
- 'ig_es_sample_data_imported' => array(
936
  'default' => 'no',
937
  'old_option' => '',
938
  ),
939
- 'ig_es_default_subscriber_imported' => array(
940
  'default' => 'no',
941
  'old_option' => '',
942
  ),
943
- 'ig_es_set_widget' => array(
944
  'default' => '',
945
  'old_option' => '',
946
  ),
947
- 'ig_es_sync_wp_users' => array(
948
  'default' => array(),
949
  'old_option' => '',
950
  ),
951
- 'ig_es_blocked_domains' => array( 'default' => 'mail.ru' ),
952
- 'ig_es_disable_wp_cron' => array( 'default' => 'no' ),
953
- 'ig_es_track_email_opens' => array( 'default' => 'yes' ),
954
- 'ig_es_show_opt_in_consent' => array( 'default' => 'yes' ),
955
- 'ig_es_opt_in_consent_text' => array( 'default' => 'Subscribe to our email updates as well.' ),
956
- 'ig_es_installed_on' => array(
 
957
  'default' => ig_get_current_date_time(),
958
  'old_option' => '',
959
  ),
960
- 'ig_es_form_submission_success_message' => array(
961
  'default' => __( 'Your subscription was successful! Kindly check your mailbox and confirm your subscription. If you don\'t see the email within a few minutes, check the spam/junk folder.', 'email-subscribers' ),
962
  'old_option' => '',
963
  ),
964
- 'ig_es_db_update_history' => array( 'default' => $ig_es_db_update_history ),
965
- 'ig_es_email_sent_data' => array( 'default' => array() ),
966
- 'ig_es_mailer_settings' => array(
967
  'default' => array( 'mailer' => 'wpmail' ),
968
  'old_option' => '',
969
  ),
970
- 'ig_es_user_roles' => array(
971
  'default' => self::get_default_permissions(),
972
  'old_option' => '',
973
  ),
974
- 'ig_es_cron_interval' => array(
975
  'default' => IG_ES_CRON_INTERVAL,
976
  'old_option' => '',
977
  ),
978
- 'ig_es_max_email_send_at_once' => array(
979
  'default' => IG_ES_MAX_EMAIL_SEND_AT_ONCE,
980
  'old_option' => '',
981
  ),
982
- 'ig_es_test_mailbox_user' => array(
983
  'default' => ES_Common::generate_test_mailbox_user(),
984
  'old_option' => '',
985
  ),
@@ -1061,6 +1069,7 @@ if ( ! class_exists( 'ES_Install' ) ) {
1061
  `ip_address` varchar(50) DEFAULT NULL,
1062
  `country_code` varchar(50) DEFAULT NULL,
1063
  `bounce_status` enum('0','1','2') NOT NULL DEFAULT '0',
 
1064
  `form_id` int(10) NOT NULL DEFAULT '0',
1065
  `status` varchar(10) DEFAULT NULL,
1066
  `unsubscribed` tinyint(1) NOT NULL DEFAULT '0',
@@ -1492,7 +1501,7 @@ if ( ! class_exists( 'ES_Install' ) ) {
1492
  */
1493
  private static function get_schema( $collate = '' ) {
1494
 
1495
- $tables = self::get_ig_es_400_schema( $collate );
1496
  $tables .= self::get_ig_es_420_schema( $collate );
1497
  $tables .= self::get_ig_es_421_schema( $collate );
1498
  $tables .= self::get_ig_es_424_schema( $collate );
34
  */
35
  private static $db_updates = array(
36
 
37
+ '3.2.0' => array(
38
  'ig_es_update_320_add_sync_option',
39
  'ig_es_update_320_db_version',
40
  ),
41
 
42
+ '3.2.7' => array(
43
  'ig_es_update_327_change_email_type',
44
  'ig_es_update_327_db_version',
45
  ),
46
 
47
+ '3.3.0' => array(
48
  'ig_es_update_330_import_options',
49
  'ig_es_update_330_db_version',
50
  ),
51
 
52
+ '3.3.6' => array(
53
  'ig_es_update_336_add_template_slug',
54
  'ig_es_update_336_db_version',
55
  ),
56
 
57
+ '3.4.0' => array(
58
  'ig_es_update_340_migrate_templates_to_cpt',
59
  'ig_es_update_340_migrate_keywords',
60
  'ig_es_update_340_db_version',
66
  ),
67
 
68
 
69
+ '4.0.0' => array(
70
  /**
71
  * - Create Tables
72
  * - Import Options
89
  'ig_es_update_400_db_version',
90
  ),
91
 
92
+ '4.0.1' => array(
93
  'ig_es_update_401_migrate_newsletters',
94
  'ig_es_update_401_db_version',
95
  ),
96
 
97
+ '4.0.2' => array(
98
  'ig_es_update_402_migrate_post_notification_es_template_type',
99
  'ig_es_update_402_db_version',
100
  ),
101
 
102
+ '4.0.3' => array(
103
  'ig_es_update_403_alter_campaigns_table',
104
  'ig_es_update_403_alter_mailing_queue_table',
105
  'ig_es_update_403_db_version',
106
  ),
107
 
108
+ '4.0.5' => array(
109
  'ig_es_update_405_alter_forms_table',
110
  'ig_es_update_405_alter_lists_table',
111
  'ig_es_update_405_migrate_widgets',
127
  'ig_es_update_4015_db_version',
128
  ),
129
 
130
+ '4.1.1' => array(
131
  'ig_es_update_411_alter_contacts_table',
132
  'ig_es_update_411_db_version',
133
  ),
134
 
135
+ '4.1.7' => array(
136
  'ig_es_update_417_alter_campaigns_table',
137
  'ig_es_update_417_alter_mailing_queue_table',
138
  'ig_es_update_417_db_version',
149
  'ig_es_update_4115_db_version',
150
  ),
151
 
152
+ '4.2.0' => array(
153
  'ig_es_update_420_alter_campaigns_table',
154
  'ig_es_update_420_create_tables',
155
  'ig_es_update_420_migrate_mailer_options',
156
  'ig_es_update_420_db_version',
157
  ),
158
 
159
+ '4.2.1' => array(
160
  'ig_es_update_421_drop_tables',
161
  'ig_es_update_421_create_tables',
162
  'ig_es_update_421_db_version',
163
  ),
164
 
165
+ '4.2.4' => array(
166
  'ig_es_update_424_drop_tables',
167
  'ig_es_update_424_create_tables',
168
  'ig_es_update_424_db_version',
169
  ),
170
 
171
+ '4.3.0' => array(
172
  'ig_es_update_430_alter_campaigns_table',
173
  'ig_es_update_430_db_version',
174
  ),
175
 
176
+ '4.3.1' => array(
177
  'ig_es_update_431_set_default_permissions',
178
  'ig_es_update_431_permanently_delete_lists',
179
  'ig_es_update_431_permanently_delete_forms',
181
  'ig_es_update_431_db_version',
182
  ),
183
 
184
+ '4.3.2' => array(
185
  'ig_es_update_432_import_bfcm_templates',
186
  'ig_es_update_432_db_version',
187
  ),
188
 
189
+ '4.3.4' => array(
190
  'ig_es_update_434_permanently_delete_campaigns',
191
  'ig_es_update_434_db_version',
192
  ),
193
 
194
+ '4.4.1' => array(
195
  'ig_es_update_441_create_tables',
196
  'ig_es_update_441_migrate_audience_sync_settings',
197
  'ig_es_update_441_db_version',
198
  ),
199
 
200
+ '4.4.2' => array(
201
  'ig_es_update_442_set_workflows_default_permission',
202
  'ig_es_update_442_db_version',
203
  ),
204
 
205
+ '4.4.9' => array(
206
  'ig_es_update_449_create_tables',
207
  'ig_es_update_449_db_version',
208
  ),
212
  'ig_es_update_4410_db_version',
213
  ),
214
 
215
+ '4.5.0' => array(
216
  'ig_es_update_450_alter_actions_table',
217
  'ig_es_update_450_db_version',
218
  ),
219
 
220
+ '4.5.7' => array(
221
  'ig_es_update_457_alter_list_table',
222
  'ig_es_update_457_add_list_hash',
223
  'ig_es_update_457_db_version',
224
  ),
225
 
226
+ '4.6.3' => array(
227
  'ig_es_update_463_alter_contacts_table',
228
  'ig_es_migrate_ip_from_list_contacts_to_contacts_table',
229
  'ig_es_update_463_db_version',
262
  'ig_es_add_primay_key_to_actions_table',
263
  'ig_es_update_479_db_version',
264
  ),
265
+ '4.8.3' => array(
266
  'ig_es_add_engagement_score_to_contacts_table',
267
  'ig_es_calculate_existing_subscribers_engagement_score',
268
  'ig_es_update_483_db_version',
269
  ),
270
+ '4.8.4' => array(
271
  'ig_es_update_484_create_custom_field_table',
272
  'ig_es_update_484_db_version',
273
  ),
274
+ '4.9.0' => array(
275
  'ig_es_update_490_alter_contacts_table',
276
  'ig_es_update_490_db_version',
277
  ),
278
+ '5.0.1' => array(
279
+ 'ig_es_update_501_alter_contacts_table',
280
+ 'ig_es_update_501_alter_sending_queue_table',
281
+ 'ig_es_add_timezone_to_contacts_table',
282
+ 'ig_es_update_501_migrate_notifications_into_workflows',
283
+ 'ig_es_update_501_db_version',
284
+ ),
285
  );
286
 
287
  /**
772
  $guid = ES_Common::generate_guid( 6 );
773
  $cronurl = $home_url . '?es=cron&guid=' . $guid;
774
 
775
+ $report = '';
776
  $report .= "Hi Admin,\n\n";
777
  $report .= "Email has been sent successfully to {{COUNT}} email(s). Please find the details below:\n\n";
778
  $report .= "Unique ID: {{UNIQUE}}\n";
799
  $unsubscribe_error_message = "Urrgh.. Something's wrong..\r\n\r\nAre you sure that email address is on our file? There was some problem in completing your request.\r\n\r\nPlease try again after some time - or contact us if the problem persists.\r\n\r\n";
800
 
801
  $options = array(
802
+ 'ig_es_from_name' => array(
803
  'default' => $sender_details['name'],
804
  'old_option' => 'ig_es_fromname',
805
  ),
806
+ 'ig_es_from_email' => array(
807
  'default' => $sender_details['email'],
808
  'old_option' => 'ig_es_fromemail',
809
  ),
810
+ 'ig_es_admin_new_contact_email_subject' => array(
811
  'default' => $new_contact_email_subject,
812
  'old_option' => 'ig_es_admin_new_sub_subject',
813
  ),
814
+ 'ig_es_admin_new_contact_email_content' => array(
815
  'default' => $new_contact_email_content,
816
  'old_option' => 'ig_es_admin_new_sub_content',
817
  ),
818
+ 'ig_es_admin_emails' => array(
819
  'default' => $admin_email,
820
  'old_option' => 'ig_es_adminemail',
821
  ),
822
+ 'ig_es_confirmation_mail_subject' => array(
823
  'default' => $confirmation_email_subject,
824
  'old_option' => 'ig_es_confirmsubject',
825
  ),
826
+ 'ig_es_confirmation_mail_content' => array(
827
  'default' => $confirmation_email_content,
828
  'old_option' => 'ig_es_confirmcontent',
829
  ),
830
+ 'ig_es_enable_welcome_email' => array(
831
  'default' => 'yes',
832
  'old_option' => 'ig_es_welcomeemail',
833
  'action' => 'convert_space_to_underscore',
834
  ),
835
+ 'ig_es_welcome_email_subject' => array(
836
  'default' => $welcome_email_subject,
837
  'old_option' => 'ig_es_welcomesubject',
838
  ),
839
+ 'ig_es_welcome_email_content' => array(
840
  'default' => $welcome_email_content,
841
  'old_option' => 'ig_es_welcomecontent',
842
  ),
843
+ 'ig_es_enable_cron_admin_email' => array(
844
  'default' => 'yes',
845
  'old_option' => 'ig_es_enable_cron_adminmail',
846
  ),
847
+ 'ig_es_enable_summary_automation' => array(
848
  'default' => 'yes',
849
  'old_option' => 'ig_es_enable_summary_automation',
850
  ),
851
+ 'ig_es_run_cron_on' => array(
852
  'default' => 'monday',
853
  'old_option' => 'ig_es_run_cron_on',
854
  ),
855
+ 'ig_es_run_cron_time' => array(
856
  'default' => '4pm',
857
  'old_option' => 'ig_es_run_cron_time',
858
  ),
859
+ 'ig_es_cron_admin_email' => array(
860
  'default' => $cron_admin_email,
861
  'old_option' => 'ig_es_cron_adminmail',
862
  ),
863
+ 'ig_es_cronurl' => array(
864
  'default' => $cronurl,
865
  'old_option' => 'ig_es_cronurl',
866
  ),
867
+ 'ig_es_hourly_email_send_limit' => array(
868
  'default' => 300,
869
  'old_option' => 'ig_es_cron_mailcount',
870
  ),
871
+ 'ig_es_sent_report_subject' => array(
872
  'default' => 'Your email has been sent',
873
  'old_option' => 'ig_es_sentreport_subject',
874
  ),
875
+ 'ig_es_sent_report_content' => array(
876
  'default' => $report,
877
  'old_option' => 'ig_es_sentreport',
878
  ),
879
+ 'ig_es_unsubscribe_link' => array(
880
  'default' => $unsublink,
881
  'old_option' => 'ig_es_unsublink',
882
  ),
883
+ 'ig_es_optin_link' => array(
884
  'default' => $optinlink,
885
  'old_option' => 'ig_es_optinlink',
886
  ),
887
+ 'ig_es_unsubscribe_link_content' => array(
888
  'default' => $unsubscribe_link_content,
889
  'old_option' => 'ig_es_unsubcontent',
890
  ),
891
+ 'ig_es_email_type' => array(
892
  'default' => 'wp_html_mail',
893
  'old_option' => 'ig_es_emailtype',
894
  'action' => 'convert_space_to_underscore',
895
  ),
896
+ 'ig_es_notify_admin' => array(
897
  'default' => 'yes',
898
  'old_option' => 'ig_es_notifyadmin',
899
  'action' => 'convert_space_to_underscore',
900
  ),
901
+ 'ig_es_optin_type' => array(
902
  'default' => 'double_opt_in',
903
  'old_option' => 'ig_es_optintype',
904
  'action' => 'convert_space_to_underscore',
905
  ),
906
+ 'ig_es_subscription_error_messsage' => array(
907
  'default' => $subscription_error_message,
908
  'old_option' => 'ig_es_suberror',
909
  ),
910
+ 'ig_es_subscription_success_message' => array(
911
  'default' => 'You have been successfully subscribed.',
912
  'old_option' => 'ig_es_successmsg',
913
  ),
914
+ 'ig_es_unsubscribe_error_message' => array(
915
  'default' => $unsubscribe_error_message,
916
  'old_option' => 'ig_es_unsuberror',
917
  ),
918
+ 'ig_es_unsubscribe_success_message' => array(
919
  'default' => $unsubscribe_message,
920
  'old_option' => 'ig_es_unsubtext',
921
  ),
922
+ 'ig_es_post_image_size' => array(
923
  'default' => 'thumbnail',
924
  'old_option' => 'ig_es_post_image_size',
925
  ),
926
+ 'ig_es_db_version' => array(
927
  'default' => $latest_db_version,
928
  'old_option' => 'current_sa_email_subscribers_db_version',
929
  ),
930
+ 'ig_es_current_version_date_details' => array(
931
  'default' => '',
932
  'old_option' => '',
933
  ),
934
+ 'ig_es_enable_captcha' => array(
935
  'default' => '',
936
  'old_option' => '',
937
  ),
938
+ 'ig_es_roles_and_capabilities' => array(
939
  'default' => '',
940
  'old_option' => 'ig_es_rolesandcapabilities',
941
  ),
942
+ 'ig_es_sample_data_imported' => array(
943
  'default' => 'no',
944
  'old_option' => '',
945
  ),
946
+ 'ig_es_default_subscriber_imported' => array(
947
  'default' => 'no',
948
  'old_option' => '',
949
  ),
950
+ 'ig_es_set_widget' => array(
951
  'default' => '',
952
  'old_option' => '',
953
  ),
954
+ 'ig_es_sync_wp_users' => array(
955
  'default' => array(),
956
  'old_option' => '',
957
  ),
958
+ 'ig_es_blocked_domains' => array( 'default' => 'mail.ru' ),
959
+ 'ig_es_disable_wp_cron' => array( 'default' => 'no' ),
960
+ 'ig_es_enable_sending_mails_in_customer_timezone' => array( 'default' => 'no' ),
961
+ 'ig_es_track_email_opens' => array( 'default' => 'yes' ),
962
+ 'ig_es_show_opt_in_consent' => array( 'default' => 'yes' ),
963
+ 'ig_es_opt_in_consent_text' => array( 'default' => 'Subscribe to our email updates as well.' ),
964
+ 'ig_es_installed_on' => array(
965
  'default' => ig_get_current_date_time(),
966
  'old_option' => '',
967
  ),
968
+ 'ig_es_form_submission_success_message' => array(
969
  'default' => __( 'Your subscription was successful! Kindly check your mailbox and confirm your subscription. If you don\'t see the email within a few minutes, check the spam/junk folder.', 'email-subscribers' ),
970
  'old_option' => '',
971
  ),
972
+ 'ig_es_db_update_history' => array( 'default' => $ig_es_db_update_history ),
973
+ 'ig_es_email_sent_data' => array( 'default' => array() ),
974
+ 'ig_es_mailer_settings' => array(
975
  'default' => array( 'mailer' => 'wpmail' ),
976
  'old_option' => '',
977
  ),
978
+ 'ig_es_user_roles' => array(
979
  'default' => self::get_default_permissions(),
980
  'old_option' => '',
981
  ),
982
+ 'ig_es_cron_interval' => array(
983
  'default' => IG_ES_CRON_INTERVAL,
984
  'old_option' => '',
985
  ),
986
+ 'ig_es_max_email_send_at_once' => array(
987
  'default' => IG_ES_MAX_EMAIL_SEND_AT_ONCE,
988
  'old_option' => '',
989
  ),
990
+ 'ig_es_test_mailbox_user' => array(
991
  'default' => ES_Common::generate_test_mailbox_user(),
992
  'old_option' => '',
993
  ),
1069
  `ip_address` varchar(50) DEFAULT NULL,
1070
  `country_code` varchar(50) DEFAULT NULL,
1071
  `bounce_status` enum('0','1','2') NOT NULL DEFAULT '0',
1072
+ `timezone` int(11) NULL DEFAULT NULL,
1073
  `form_id` int(10) NOT NULL DEFAULT '0',
1074
  `status` varchar(10) DEFAULT NULL,
1075
  `unsubscribed` tinyint(1) NOT NULL DEFAULT '0',
1501
  */
1502
  private static function get_schema( $collate = '' ) {
1503
 
1504
+ $tables = self::get_ig_es_400_schema( $collate );
1505
  $tables .= self::get_ig_es_420_schema( $collate );
1506
  $tables .= self::get_ig_es_421_schema( $collate );
1507
  $tables .= self::get_ig_es_424_schema( $collate );
lite/includes/classes/class-es-admin-settings.php CHANGED
@@ -45,14 +45,15 @@ class ES_Admin_Settings {
45
 
46
  $options = apply_filters( 'ig_es_before_save_settings', $options );
47
 
48
- $options['ig_es_disable_wp_cron'] = isset( $options['ig_es_disable_wp_cron'] ) ? $options['ig_es_disable_wp_cron'] : 'no';
49
- $options['ig_es_track_email_opens'] = isset( $options['ig_es_track_email_opens'] ) ? $options['ig_es_track_email_opens'] : 'no';
50
- $options['ig_es_enable_welcome_email'] = isset( $options['ig_es_enable_welcome_email'] ) ? $options['ig_es_enable_welcome_email'] : 'no';
51
- $options['ig_es_notify_admin'] = isset( $options['ig_es_notify_admin'] ) ? $options['ig_es_notify_admin'] : 'no';
52
- $options['ig_es_enable_cron_admin_email'] = isset( $options['ig_es_enable_cron_admin_email'] ) ? $options['ig_es_enable_cron_admin_email'] : 'no';
53
- $options['ig_es_delete_plugin_data'] = isset( $options['ig_es_delete_plugin_data'] ) ? $options['ig_es_delete_plugin_data'] : 'no';
54
- $options['ig_es_run_cron_on'] = isset( $options['ig_es_run_cron_on'] ) ? $options['ig_es_run_cron_on'] : 'monday';
55
- $options['ig_es_run_cron_time'] = isset( $options['ig_es_run_cron_time'] ) ? $options['ig_es_run_cron_time'] : '4pm';
 
56
  // Start-IG-Code.
57
  // Show option to enable/disable tracking if user isn't a premium user and trial is not valid i.e. has expired.
58
  if ( ! ES()->is_premium() && ! ES()->is_trial_valid() ) {
@@ -78,6 +79,7 @@ class ES_Admin_Settings {
78
  'ig_es_cronurl',
79
  'ig_es_hourly_email_send_limit',
80
  'ig_es_disable_wp_cron',
 
81
  );
82
 
83
  $textarea_fields_to_sanitize = array(
@@ -366,145 +368,10 @@ class ES_Admin_Settings {
366
 
367
  $signup_confirmation_settings = array(
368
 
369
- 'welcome_emails' => array(
370
- 'id' => 'welcome_emails',
371
- 'name' => __( 'Welcome email', 'email-subscribers' ),
372
- 'info' => __( 'Send this text as a welcome email when new people subscribe.', 'email-subscribers' ),
373
- 'sub_fields' => array(
374
-
375
- 'ig_es_enable_welcome_email' => array(
376
- 'id' => 'ig_es_enable_welcome_email',
377
- 'name' => __( 'Enable?', 'email-subscribers' ),
378
- 'type' => 'checkbox',
379
- 'default' => 'yes',
380
- ),
381
-
382
- 'ig_es_welcome_email_subject' => array(
383
- 'type' => 'text',
384
- 'options' => false,
385
- 'placeholder' => '',
386
- 'supplemental' => '',
387
- 'default' => '',
388
- 'id' => 'ig_es_welcome_email_subject',
389
- 'name' => __( 'Subject', 'email-subscribers' ),
390
- 'desc' => '',
391
- ),
392
- 'ig_es_welcome_email_content' => array(
393
- 'type' => 'textarea',
394
- 'options' => false,
395
- 'placeholder' => '',
396
- 'supplemental' => '',
397
- 'default' => '',
398
- 'id' => 'ig_es_welcome_email_content',
399
- 'name' => __( 'Content', 'email-subscribers' ),
400
- /* translators: %s: List of Keywords */
401
- 'desc' => sprintf( __( 'Available keywords: %s', 'email-subscribers' ), '{{FIRSTNAME}}, {{LASTNAME}}, {{NAME}}, {{EMAIL}}, {{LIST}}, {{UNSUBSCRIBE-LINK}}' ),
402
- ),
403
- ),
404
- ),
405
-
406
- 'confirmation_notifications' => array(
407
- 'id' => 'confirmation_notifications',
408
- 'name' => __( 'Double opt-in confirmation email', 'email-subscribers' ),
409
- 'info' => __( 'Use this text as confirmation email when opt-in type is set to "Double opt-in". Make sure to include {{SUBSCRIBE-LINK}} keyword, otherwise they won\'t be able to confirm their subscription.', 'email-subscribers' ),
410
- 'sub_fields' => array(
411
-
412
- 'ig_es_confirmation_mail_subject' => array(
413
- 'type' => 'text',
414
- 'options' => false,
415
- 'placeholder' => '',
416
- 'supplemental' => '',
417
- 'default' => '',
418
- 'id' => 'ig_es_confirmation_mail_subject',
419
- 'name' => __( 'Subject', 'email-subscribers' ),
420
- 'desc' => '',
421
- ),
422
-
423
- 'ig_es_confirmation_mail_content' => array(
424
- 'type' => 'textarea',
425
- 'options' => false,
426
- 'placeholder' => '',
427
- 'supplemental' => '',
428
- 'default' => '',
429
- 'id' => 'ig_es_confirmation_mail_content',
430
- 'name' => __( 'Content', 'email-subscribers' ),
431
- /* translators: %s: List of Keywords */
432
- 'desc' => sprintf( __( 'Available keywords: %s ', 'email-subscribers' ), '{{FIRSTNAME}}, {{LASTNAME}}, {{NAME}}, {{EMAIL}}, {{SUBSCRIBE-LINK}}' ),
433
- ),
434
- ),
435
- ),
436
-
437
- 'admin_notifications' => array(
438
-
439
- 'id' => 'admin_notifications',
440
- 'name' => __( 'New subscription notification to admin', 'email-subscribers' ),
441
- 'info' => __( 'Notify admin(s) everytime a new contact signups.', 'email-subscribers' ),
442
- 'sub_fields' => array(
443
-
444
- 'notify_admin' => array(
445
- 'id' => 'ig_es_notify_admin',
446
- 'name' => __( 'Notify?', 'email-subscribers' ),
447
- 'type' => 'checkbox',
448
- 'default' => 'yes',
449
- ),
450
-
451
- 'new_contact_email_subject' => array(
452
- 'id' => 'ig_es_admin_new_contact_email_subject',
453
- 'name' => __( 'Subject', 'email-subscribers' ),
454
- 'type' => 'text',
455
- 'desc' => __( 'Subject for the admin email whenever a new contact signs up and is confirmed', 'email-subscribers' ),
456
- 'default' => __( 'New email subscription', 'email-subscribers' ),
457
- ),
458
-
459
- 'new_contact_email_content' => array(
460
- 'id' => 'ig_es_admin_new_contact_email_content',
461
- 'name' => __( 'Content', 'email-subscribers' ),
462
- 'type' => 'textarea',
463
- /* translators: %s: List of Keywords */
464
- 'desc' => sprintf( __( 'Content for the admin email whenever a new subscriber signs up and is confirmed. Available keywords: %s', 'email-subscribers' ), '{{NAME}}, {{EMAIL}}, {{LIST}}' ),
465
- 'default' => '',
466
- ),
467
- ),
468
- ),
469
-
470
- 'ig_es_cron_report' => array(
471
- 'id' => 'ig_es_cron_report',
472
- 'name' => __( 'Campaign sent notification to admin', 'email-subscribers' ),
473
- 'info' => __( 'Notify admin(s) everytime a campaign is sent.', 'email-subscribers' ),
474
- 'sub_fields' => array(
475
-
476
- 'ig_es_enable_cron_admin_email' => array(
477
- 'id' => 'ig_es_enable_cron_admin_email',
478
- 'name' => __( 'Notify?', 'email-subscribers' ),
479
- 'type' => 'checkbox',
480
-
481
- 'default' => 'yes',
482
- ),
483
-
484
- 'ig_es_cron_admin_email_subject' => array(
485
- 'type' => 'text',
486
- 'options' => false,
487
- 'placeholder' => '',
488
- 'supplemental' => '',
489
- 'default' => __( 'Campaign Sent!', 'email-subscribers' ),
490
- 'id' => 'ig_es_cron_admin_email_subject',
491
- 'name' => __( 'Subject', 'email-subscribers' ),
492
- 'desc' => '',
493
- ),
494
-
495
- 'ig_es_cron_admin_email' => array(
496
- 'type' => 'textarea',
497
- 'options' => false,
498
- 'placeholder' => '',
499
- 'supplemental' => '',
500
- 'default' => '',
501
- 'id' => 'ig_es_cron_admin_email',
502
- 'name' => __( 'Content', 'email-subscribers' ),
503
- /* translators: %s: List of Keywords */
504
- 'desc' => sprintf( __( 'Send report to admin(s) whenever campaign is successfully sent to all contacts. Available keywords: %s', 'email-subscribers' ), '{{DATE}}, {{SUBJECT}}, {{COUNT}}' ),
505
- ),
506
-
507
- ),
508
  ),
509
  );
510
 
@@ -1139,4 +1006,32 @@ class ES_Admin_Settings {
1139
 
1140
  return $es_settings;
1141
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1142
  }
45
 
46
  $options = apply_filters( 'ig_es_before_save_settings', $options );
47
 
48
+ $options['ig_es_disable_wp_cron'] = isset( $options['ig_es_disable_wp_cron'] ) ? $options['ig_es_disable_wp_cron'] : 'no';
49
+ $options['ig_es_enable_sending_mails_in_customer_timezone'] = isset( $options['ig_es_enable_sending_mails_in_customer_timezone'] ) ? $options['ig_es_enable_sending_mails_in_customer_timezone'] : 'no';
50
+ $options['ig_es_track_email_opens'] = isset( $options['ig_es_track_email_opens'] ) ? $options['ig_es_track_email_opens'] : 'no';
51
+ $options['ig_es_enable_welcome_email'] = isset( $options['ig_es_enable_welcome_email'] ) ? $options['ig_es_enable_welcome_email'] : 'no';
52
+ $options['ig_es_notify_admin'] = isset( $options['ig_es_notify_admin'] ) ? $options['ig_es_notify_admin'] : 'no';
53
+ $options['ig_es_enable_cron_admin_email'] = isset( $options['ig_es_enable_cron_admin_email'] ) ? $options['ig_es_enable_cron_admin_email'] : 'no';
54
+ $options['ig_es_delete_plugin_data'] = isset( $options['ig_es_delete_plugin_data'] ) ? $options['ig_es_delete_plugin_data'] : 'no';
55
+ $options['ig_es_run_cron_on'] = isset( $options['ig_es_run_cron_on'] ) ? $options['ig_es_run_cron_on'] : 'monday';
56
+ $options['ig_es_run_cron_time'] = isset( $options['ig_es_run_cron_time'] ) ? $options['ig_es_run_cron_time'] : '4pm';
57
  // Start-IG-Code.
58
  // Show option to enable/disable tracking if user isn't a premium user and trial is not valid i.e. has expired.
59
  if ( ! ES()->is_premium() && ! ES()->is_trial_valid() ) {
79
  'ig_es_cronurl',
80
  'ig_es_hourly_email_send_limit',
81
  'ig_es_disable_wp_cron',
82
+ 'ig_es_enable_sending_mails_in_customer_timezone',
83
  );
84
 
85
  $textarea_fields_to_sanitize = array(
368
 
369
  $signup_confirmation_settings = array(
370
 
371
+ 'worflow_migration_notice' => array(
372
+ 'id' => 'worflow_migration_notice',
373
+ 'type' => 'html',
374
+ 'html' => self::get_workflow_migration_notice_html(),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
375
  ),
376
  );
377
 
1006
 
1007
  return $es_settings;
1008
  }
1009
+
1010
+ /**
1011
+ * Render User Permission Settings
1012
+ *
1013
+ * @return false|string
1014
+ *
1015
+ * @since 4.2.0
1016
+ */
1017
+ public static function get_workflow_migration_notice_html() {
1018
+ ob_start();
1019
+ $workflow_url = admin_url( 'admin.php?page=es_workflows' );
1020
+ ?>
1021
+ <style>
1022
+ #tabs-signup_confirmation .es-settings-submit-btn {
1023
+ display: none;
1024
+ }
1025
+ </style>
1026
+ <p class="pb-2 text-sm font-normal text-gray-500">
1027
+ <?php echo esc_html__( 'Now you can control all your notifications through workflows.', 'email-subscribers' ); ?>
1028
+ <?php
1029
+ /* translators: 1. Anchor start tag 2. Anchor end tag */
1030
+ echo sprintf( esc_html__( 'Click %1$shere%2$s to go to workflows.', 'email-subscribers' ), '<a href="' . esc_url( $workflow_url ) . '" class="text-indigo-600" target="_blank">', '</a>' );
1031
+ ?>
1032
+ </p>
1033
+ <?php
1034
+ $html = ob_get_clean();
1035
+ return $html;
1036
+ }
1037
  }
lite/includes/classes/class-es-geolocation.php CHANGED
@@ -73,6 +73,27 @@ class ES_Geolocation {
73
  return $geolocation;
74
  }
75
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  /**
77
  * Use APIs to Geolocate the user.
78
  *
@@ -110,13 +131,16 @@ class ES_Geolocation {
110
  case 'ipinfo.io':
111
  $data = json_decode( $response['body'] );
112
  $country_code = isset( $data->country ) ? $data->country : '';
 
113
  break;
114
  case 'ip-api.com':
115
  $data = json_decode( $response['body'] );
116
  $country_code = isset( $data->countryCode ) ? $data->countryCode : ''; // @codingStandardsIgnoreLine
 
117
  break;
118
  default:
119
  $country_code = apply_filters( 'ig_es_geolocation_geoip_response_' . $service_name, '', $response['body'] );
 
120
  break;
121
  }
122
 
@@ -124,6 +148,7 @@ class ES_Geolocation {
124
 
125
  if ( $country_code ) {
126
  $geo_ip_data['country_code'] = $country_code;
 
127
  break;
128
  }
129
  }
@@ -140,8 +165,10 @@ class ES_Geolocation {
140
  if ( ! is_wp_error( $response ) && $response['body'] ) {
141
  $data = json_decode( $response['body'] );
142
  $country_code = isset( $data->country_code ) ? $data->country_code : '';
 
143
  if ( $country_code ) {
144
  $geo_ip_data['country_code'] = $country_code;
 
145
  }
146
  }
147
  }
73
  return $geolocation;
74
  }
75
 
76
+ /**
77
+ * Convert the String TimeZone to seconds
78
+ *
79
+ * @param $timezone
80
+ *
81
+ * @return int
82
+ */
83
+ public static function convert_timezone_to_seconds( $timezone ) {
84
+ if ( empty( $timezone ) ) {
85
+ return 0;
86
+ }
87
+ try {
88
+ $current = timezone_open( $timezone );
89
+ $utcTime = new DateTime( 'now', new DateTimeZone( 'UTC' ) );
90
+
91
+ return intval( $current->getOffset( $utcTime ) );
92
+ } catch ( Exception $exception ) {
93
+ return 0;
94
+ }
95
+ }
96
+
97
  /**
98
  * Use APIs to Geolocate the user.
99
  *
131
  case 'ipinfo.io':
132
  $data = json_decode( $response['body'] );
133
  $country_code = isset( $data->country ) ? $data->country : '';
134
+ $timezone = isset( $data->timezone ) ? self::convert_timezone_to_seconds( $data->timezone ) : 0;
135
  break;
136
  case 'ip-api.com':
137
  $data = json_decode( $response['body'] );
138
  $country_code = isset( $data->countryCode ) ? $data->countryCode : ''; // @codingStandardsIgnoreLine
139
+ $timezone = isset( $data->timezone ) ? self::convert_timezone_to_seconds( $data->timezone ) : 0;
140
  break;
141
  default:
142
  $country_code = apply_filters( 'ig_es_geolocation_geoip_response_' . $service_name, '', $response['body'] );
143
+ $timezone = apply_filters( 'ig_es_geolocation_geoip_timezone_response_' . $service_name, '', $response['body'] );
144
  break;
145
  }
146
 
148
 
149
  if ( $country_code ) {
150
  $geo_ip_data['country_code'] = $country_code;
151
+ $geo_ip_data['timezone'] = $timezone;
152
  break;
153
  }
154
  }
165
  if ( ! is_wp_error( $response ) && $response['body'] ) {
166
  $data = json_decode( $response['body'] );
167
  $country_code = isset( $data->country_code ) ? $data->country_code : '';
168
+ $timezone = isset( $data->timezone ) ? self::convert_timezone_to_seconds( $data->timezone ) : 0;
169
  if ( $country_code ) {
170
  $geo_ip_data['country_code'] = $country_code;
171
+ $geo_ip_data['timezone'] = $timezone;
172
  }
173
  }
174
  }
lite/includes/classes/class-es-handle-post-notification.php CHANGED
@@ -114,7 +114,7 @@ class ES_Handle_Post_Notification {
114
  'subject' => $post_subject,
115
  'body' => $post_content,
116
  'count' => 0,
117
- 'status' => 'In Queue',
118
  'start_at' => '',
119
  'finish_at' => '',
120
  'created_at' => ig_get_current_date_time(),
114
  'subject' => $post_subject,
115
  'body' => $post_content,
116
  'count' => 0,
117
+ 'status' => '',
118
  'start_at' => '',
119
  'finish_at' => '',
120
  'created_at' => ig_get_current_date_time(),
lite/includes/classes/class-es-handle-subscription.php CHANGED
@@ -361,17 +361,15 @@ if ( ! class_exists( 'ES_Handle_Subscription' ) ) {
361
  );
362
 
363
  if ( $this->is_double_optin ) {
364
- $response = ES()->mailer->send_double_optin_email( $this->email, $merge_tags );
365
  $response['message'] = 'es_optin_success_message';
 
 
366
  } else {
367
 
368
- do_action( 'ig_es_contact_subscribed', $contact_id );
369
-
370
- // Send Welcome Email
371
- ES()->mailer->send_welcome_email( $this->email, $merge_tags );
372
 
373
  // Send Notifications to admins
374
- ES()->mailer->send_add_new_contact_notification_to_admins( $merge_tags );
375
 
376
  $response['message'] = 'es_optin_success_message';
377
  }
361
  );
362
 
363
  if ( $this->is_double_optin ) {
 
364
  $response['message'] = 'es_optin_success_message';
365
+
366
+ do_action( 'ig_es_contact_unconfirmed', $merge_tags );
367
  } else {
368
 
369
+ do_action( 'ig_es_contact_subscribed', $merge_tags );
 
 
 
370
 
371
  // Send Notifications to admins
372
+ //ES()->mailer->send_add_new_contact_notification_to_admins( $merge_tags );
373
 
374
  $response['message'] = 'es_optin_success_message';
375
  }
lite/includes/classes/class-es-mailer.php CHANGED
@@ -748,7 +748,7 @@ if ( ! class_exists( 'ES_Mailer' ) ) {
748
 
749
  $merge_tags['contact_id'] = $contact_id;
750
 
751
- $merge_tags = array_merge( $merge_tags, $this->get_contact_merge_tags( $contact_id ) );
752
 
753
  $this->link_data = array(
754
  'message_id' => $message_id,
748
 
749
  $merge_tags['contact_id'] = $contact_id;
750
 
751
+ $merge_tags = array_merge( $this->get_contact_merge_tags( $contact_id ), $merge_tags );
752
 
753
  $this->link_data = array(
754
  'message_id' => $message_id,
lite/includes/classes/class-es-newsletters.php CHANGED
@@ -537,8 +537,6 @@ class ES_Newsletters {
537
 
538
  $list_id = ! empty( $data['list_ids'] ) ? $data['list_ids'] : '';
539
 
540
- $title = get_the_title( $data['base_template_id'] );
541
-
542
  $data['type'] = 'newsletter';
543
  $data['name'] = $data['subject'];
544
  $data['slug'] = sanitize_title( sanitize_text_field( $data['name'] ) );
@@ -569,7 +567,7 @@ class ES_Newsletters {
569
  'campaign_id' => $campaign_id,
570
  'subject' => $data['subject'],
571
  'body' => $data['body'],
572
- 'status' => 'In Queue',
573
  'start_at' => ! empty( $data['start_at'] ) ? $data['start_at'] : '',
574
  'finish_at' => '',
575
  'created_at' => ig_get_current_date_time(),
@@ -701,13 +699,6 @@ class ES_Newsletters {
701
  $allowedtags = ig_es_allowed_html_tags_in_esc();
702
  add_filter( 'safe_style_css', 'ig_es_allowed_css_style' );
703
 
704
- if ( has_post_thumbnail( $template_id ) ) {
705
- $image_array = wp_get_attachment_image_src( get_post_thumbnail_id( $template_id ), 'full' );
706
- $image = '<img src="' . $image_array[0] . '" class="img-responsive" alt="Image for Post ' . $template_id . '" />';
707
- } else {
708
- $image = '';
709
- }
710
-
711
  $html = '';
712
  $html .= '<style type="text/css">
713
  .es-main-preview-block{
537
 
538
  $list_id = ! empty( $data['list_ids'] ) ? $data['list_ids'] : '';
539
 
 
 
540
  $data['type'] = 'newsletter';
541
  $data['name'] = $data['subject'];
542
  $data['slug'] = sanitize_title( sanitize_text_field( $data['name'] ) );
567
  'campaign_id' => $campaign_id,
568
  'subject' => $data['subject'],
569
  'body' => $data['body'],
570
+ 'status' => '',
571
  'start_at' => ! empty( $data['start_at'] ) ? $data['start_at'] : '',
572
  'finish_at' => '',
573
  'created_at' => ig_get_current_date_time(),
699
  $allowedtags = ig_es_allowed_html_tags_in_esc();
700
  add_filter( 'safe_style_css', 'ig_es_allowed_css_style' );
701
 
 
 
 
 
 
 
 
702
  $html = '';
703
  $html .= '<style type="text/css">
704
  .es-main-preview-block{
lite/includes/classes/class-es-queue.php CHANGED
@@ -44,9 +44,6 @@ if ( ! class_exists( 'ES_Queue' ) ) {
44
  add_action( 'ig_es_contact_unsubscribe', array( &$this, 'delete_contact_queued_emails' ), 10, 4 );
45
  add_action( 'ig_es_admin_contact_unsubscribe', array( &$this, 'delete_contact_queued_emails' ), 10, 4 );
46
 
47
- // Action scheduler action to add subscribers to sending_queue table in background. Called through Action Scheduler library.
48
- add_action( 'ig_es_add_subscribers_to_sending_queue', array( &$this, 'add_subscribers_to_sending_queue' ) );
49
-
50
  // Ajax handler for running action scheduler task.
51
  add_action( 'wp_ajax_ig_es_run_action_scheduler_task', array( 'IG_ES_Background_Process_Helper', 'run_action_scheduler_task' ) );
52
  add_action( 'wp_ajax_nopriv_ig_es_run_action_scheduler_task', array( 'IG_ES_Background_Process_Helper', 'run_action_scheduler_task' ) );
@@ -377,7 +374,7 @@ if ( ! class_exists( 'ES_Queue' ) ) {
377
  'subject' => $subject,
378
  'body' => $content,
379
  'count' => 0,
380
- 'status' => 'In Queue',
381
  'start_at' => ! empty( $campaign['start_at'] ) ? $campaign['start_at'] : '',
382
  'finish_at' => '',
383
  'created_at' => ig_get_current_date_time(),
@@ -771,8 +768,7 @@ if ( ! class_exists( 'ES_Queue' ) ) {
771
  }
772
  }
773
 
774
- // Send Cron Email to admins
775
- ES()->mailer->send_cron_admin_email( $notification_guid );
776
  }
777
 
778
  // TODO: Implement better solution
@@ -963,121 +959,6 @@ if ( ! class_exists( 'ES_Queue' ) ) {
963
  }
964
  }
965
 
966
- /**
967
- * Method to add subscribers to the sending queue in background. Gets called through the Action Scheduler library.
968
- *
969
- * @param array $args action arguements.
970
- *
971
- * @since 4.6.3
972
- */
973
- public function add_subscribers_to_sending_queue( $args = array() ) {
974
-
975
- if ( empty( $args['mailing_queue_id'] ) || ! is_numeric( $args['mailing_queue_id'] ) || empty( $args['list_ids'] ) ) {
976
- return false;
977
- }
978
-
979
- $batch_start_time = time();
980
-
981
- /**
982
- * By subtracting the waiting time from $batch_start_time now,
983
- * We are allowing timeout to happen in the background process loop 3 seconds earlier.
984
- * This earlier timeout will ensure we get engough time to make another asynchrounous request
985
- * since we need to wait for sometime before making the asynchronous request.
986
- */
987
- $batch_start_time = $batch_start_time - IG_ES_Background_Process_Helper::get_wait_seconds();
988
-
989
- $mailing_queue_id = $args['mailing_queue_id'];
990
- $list_ids = $args['list_ids'];
991
-
992
- $mailing_queue = ES_DB_Mailing_Queue::get_mailing_queue_by_id( $mailing_queue_id );
993
-
994
- // Check if mailing queue exists. May have been deleted manually.
995
- if ( empty( $mailing_queue ) ) {
996
- return false;
997
- }
998
-
999
- $mailing_queue_hash = $mailing_queue['hash'];
1000
- $campaign_id = $mailing_queue['campaign_id'];
1001
-
1002
- $active_subscribers = ES()->contacts_db->get_active_contacts_by_list_and_mailing_queue_id( $list_ids, $mailing_queue_id );
1003
-
1004
- if ( ! empty( $active_subscribers ) ) {
1005
- $subscribers_batch_size = 5000;
1006
-
1007
- // Create batches of subscribers each containing maximum subscribers equal to $subscribers_batch_size.
1008
- $subscribers_batches = array_chunk( $active_subscribers, $subscribers_batch_size );
1009
-
1010
- foreach ( $subscribers_batches as $key => $subscribers ) {
1011
-
1012
- $delivery_data = array();
1013
- $delivery_data['hash'] = $mailing_queue_hash;
1014
- $delivery_data['subscribers'] = $subscribers;
1015
- $delivery_data['campaign_id'] = $campaign_id;
1016
- $delivery_data['mailing_queue_id'] = $mailing_queue_id;
1017
-
1018
- ES_DB_Sending_Queue::do_batch_insert( $delivery_data );
1019
-
1020
- // Remove the processed batch.
1021
- unset( $subscribers_batches[ $key ] );
1022
-
1023
- // Check if time limit or memory limit has been reached.
1024
- if ( IG_ES_Background_Process_Helper::time_exceeded( $batch_start_time ) || IG_ES_Background_Process_Helper::memory_exceeded() ) {
1025
- break;
1026
- }
1027
- }
1028
-
1029
- $total_contacts_added = ES_DB_Sending_Queue::get_total_email_count_by_hash( $mailing_queue_hash );
1030
- ES_DB_Mailing_Queue::update_subscribers_count( $mailing_queue_hash, $total_contacts_added );
1031
-
1032
- // Check if there are no batches to process.
1033
- if ( empty( $subscribers_batches ) ) {
1034
-
1035
- $mailing_queue_status = 'In Queue';
1036
- // Update status to 'In Queue' so that cron(ES Cron/WP Cron) can pick it up.
1037
- ES_DB_Mailing_Queue::update_sent_status( $mailing_queue_hash, $mailing_queue_status );
1038
-
1039
- $campaign_type = '';
1040
- if ( ! empty( $campaign_id ) ) {
1041
- $campaign_type = ES()->campaigns_db->get_campaign_type_by_id( $campaign_id );
1042
- }
1043
-
1044
- // If campaign_type is newsletter i.e. broadcast, then trigger email sending if its email sending time has come.
1045
- if ( 'newsletter' === $campaign_type ) {
1046
- $queue_start_at = $mailing_queue['start_at'];
1047
-
1048
- $current_timestamp = time();
1049
- $sending_timestamp = strtotime( $queue_start_at );
1050
-
1051
- // Check if campaign sending time has come.
1052
- if ( $sending_timestamp <= $current_timestamp ) {
1053
- $request_args = array(
1054
- 'action' => 'ig_es_trigger_mailing_queue_sending',
1055
- 'campaign_hash' => $mailing_queue_hash,
1056
- );
1057
- // Send an asynchronous request to trigger sending of campaign emails.
1058
- IG_ES_Background_Process_Helper::send_async_ajax_request( $request_args, true );
1059
- }
1060
- }
1061
- } else {
1062
- /**
1063
- * If all subscribers batches are not processed(i.e. there are still emails to be added in the sending_queue table)
1064
- * Create another action scheduler task to process remaining batches.
1065
- */
1066
- $action_args = array(
1067
- 'mailing_queue_id' => $mailing_queue_id,
1068
- 'list_ids' => $list_ids,
1069
- );
1070
- IG_ES_Background_Process_Helper::add_action_scheduler_task( 'ig_es_add_subscribers_to_sending_queue', $action_args, true, true );
1071
- }
1072
- } else {
1073
- $total_contacts_added = ES_DB_Sending_Queue::get_total_email_count_by_hash( $mailing_queue_hash );
1074
- // Check if there are not any queued email for this mailing queue id. If yes, then delete the mailing queue also since there is no meaning in processing an empty mailing queue.
1075
- if ( empty( $total_contacts_added ) ) {
1076
- ES_DB_Mailing_Queue::delete_notifications( array( $mailing_queue_id ) );
1077
- }
1078
- }
1079
- }
1080
-
1081
  /**
1082
  * Method to trigger email sending through 'ig_es_cron_worker' cron worker.
1083
  *
44
  add_action( 'ig_es_contact_unsubscribe', array( &$this, 'delete_contact_queued_emails' ), 10, 4 );
45
  add_action( 'ig_es_admin_contact_unsubscribe', array( &$this, 'delete_contact_queued_emails' ), 10, 4 );
46
 
 
 
 
47
  // Ajax handler for running action scheduler task.
48
  add_action( 'wp_ajax_ig_es_run_action_scheduler_task', array( 'IG_ES_Background_Process_Helper', 'run_action_scheduler_task' ) );
49
  add_action( 'wp_ajax_nopriv_ig_es_run_action_scheduler_task', array( 'IG_ES_Background_Process_Helper', 'run_action_scheduler_task' ) );
374
  'subject' => $subject,
375
  'body' => $content,
376
  'count' => 0,
377
+ 'status' => '',
378
  'start_at' => ! empty( $campaign['start_at'] ) ? $campaign['start_at'] : '',
379
  'finish_at' => '',
380
  'created_at' => ig_get_current_date_time(),
768
  }
769
  }
770
 
771
+ do_action( 'ig_es_campaign_sent', $notification_guid );
 
772
  }
773
 
774
  // TODO: Implement better solution
959
  }
960
  }
961
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
962
  /**
963
  * Method to trigger email sending through 'ig_es_cron_worker' cron worker.
964
  *
lite/includes/classes/class-es-templates-table.php CHANGED
@@ -20,6 +20,7 @@ class ES_Templates_Table {
20
  // duplicate template
21
  add_filter( 'post_row_actions', array( &$this, 'add_message_action' ), 10, 2 );
22
  add_action( 'admin_init', array( &$this, 'duplicate_message' ), 10, 1 );
 
23
  }
24
 
25
  public function add_template_type() {
@@ -118,7 +119,7 @@ class ES_Templates_Table {
118
 
119
  <div class="misc-pub-section">
120
  <div id="" class="es_preview_button" style="display: block;">
121
- <a style="padding-top: 3px; margin-bottom: 0.2rem;" href="<?php echo esc_url( admin_url() ); ?>admin.php?page=es_template_preview&post=<?php echo esc_attr( $post_id ); ?>&preview=true&preview_id=<?php echo esc_attr( $post_id ); ?>" target="_blank" class="button button-primary es_preview"><?php esc_html_e( 'Preview template', 'email-subscribers' ); ?></a>
122
  <div class="clear"></div>
123
  </div>
124
  </div>
@@ -139,119 +140,21 @@ class ES_Templates_Table {
139
  }
140
 
141
  public function es_template_preview_callback() {
142
-
143
- $template_id = ig_es_get_request_data( 'post' );
144
-
145
- $template = get_post( $template_id, ARRAY_A );
146
-
147
- if ( $template ) {
148
- $current_user = wp_get_current_user();
149
- $username = $current_user->user_login;
150
- $useremail = $current_user->user_email;
151
- $display_name = $current_user->display_name;
152
-
153
- $contact_id = ES()->contacts_db->get_contact_id_by_email( $useremail );
154
- $first_name = '';
155
- $last_name = '';
156
-
157
- // Use details from contacts data if present else fetch it from wp profile.
158
- if ( ! empty( $contact_id ) ) {
159
- $contact_data = ES()->contacts_db->get_by_id( $contact_id );
160
- $first_name = $contact_data['first_name'];
161
- $last_name = $contact_data['last_name'];
162
- } elseif ( ! empty( $display_name ) ) {
163
- $contact_details = explode( ' ', $display_name );
164
- $first_name = $contact_details[0];
165
- // Check if last name is set.
166
- if ( ! empty( $contact_details[1] ) ) {
167
- $last_name = $contact_details[1];
168
- }
169
- }
170
-
171
- $es_template_body = $template['post_content'];
172
-
173
- $es_template_type = get_post_meta( $template_id, 'es_template_type', true );
174
-
175
- if ( 'post_notification' === $es_template_type ) {
176
- $args = array(
177
- 'numberposts' => '1',
178
- 'order' => 'DESC',
179
- 'post_status' => 'publish',
180
- );
181
- $recent_posts = wp_get_recent_posts( $args );
182
-
183
- if ( count( $recent_posts ) > 0 ) {
184
- $recent_post = array_shift( $recent_posts );
185
-
186
- $post_id = $recent_post['ID'];
187
- $es_template_body = ES_Handle_Post_Notification::prepare_body( $es_template_body, $post_id, $template_id );
188
- }
189
- } else {
190
- $es_template_body = ES_Common::es_process_template_body( $es_template_body, $template_id );
191
- }
192
-
193
- $es_template_body = str_replace( '{{NAME}}', $username, $es_template_body );
194
- $es_template_body = str_replace( '{{EMAIL}}', $useremail, $es_template_body );
195
- $es_template_body = str_replace( '{{FIRSTNAME}}', $first_name, $es_template_body );
196
- $es_template_body = str_replace( '{{LASTNAME}}', $last_name, $es_template_body );
197
- $allowedtags = ig_es_allowed_html_tags_in_esc();
198
- add_filter( 'safe_style_css', 'ig_es_allowed_css_style' );
199
-
200
- if ( has_post_thumbnail( $template_id ) ) {
201
- $image_array = wp_get_attachment_image_src( get_post_thumbnail_id( $template_id ), 'full' );
202
- $image = '<img src="' . $image_array[0] . '" class="img-responsive" alt="Image for Post ' . $template_id . '" />';
203
- } else {
204
- $image = '';
205
- }
206
- $html = '';
207
- $html .= '<style type="text/css">
208
- .es-sidebar {
209
- width: 23%;
210
- background-color: rgb(230, 230, 230);
211
- padding:15px;
212
- border-right: 1px solid #bdbdbd;
213
- }
214
- .es-preview {
215
- float: left;
216
- padding:15px;
217
- width: 70%;
218
- background-color:#FFF;
219
- font-size:16px;
220
- }
221
- .es-main-preview-block{
222
- display:flex;
223
- }
224
- .es-clear-preview{
225
- clear: both;
226
- }
227
- .es-preview-margin{
228
- margin-bottom: 1em;
229
- }
230
- </style>
231
- <div class="wrap">
232
- <div class="tool-box">
233
- <div class="es-main-preview-block">
234
- <div class="es-sidebar">
235
- <h2 class="es-preview-margin">
236
- Template Preview <a class="add-new-h2" href="' . admin_url() . 'admin.php?page=es-general-information">Help</a>
237
- </h2>
238
- <p>
239
- <a class="button-primary" href="' . admin_url() . 'post.php?post=' . $template_id . '&action=edit">Edit</a>
240
- </p>
241
- <p>
242
- This is how your email may look.<br><br>Note: Different email services (like gmail, yahoo etc) display email content differently. So there could be a slight variation on how your customer will view the email content. </p>
243
- </div>
244
- <div class="es-preview">' . $es_template_body . '</div>
245
- <div class="es-clear-preview"></div>
246
- </div>
247
- <div class="es-clear-preview"></div>
248
  </div>
249
- </div>';
250
- echo wp_kses( apply_filters( 'the_content', $html ), $allowedtags );
251
- } else {
252
- echo esc_html__( 'Please publish it or save it as a draft.', 'email-subscribers' );
253
- }
254
-
255
  }
256
 
257
  public function add_new_columns( $existing_columns ) {
20
  // duplicate template
21
  add_filter( 'post_row_actions', array( &$this, 'add_message_action' ), 10, 2 );
22
  add_action( 'admin_init', array( &$this, 'duplicate_message' ), 10, 1 );
23
+ add_action( 'admin_footer', array( $this, 'es_template_preview_callback' ), 10 );
24
  }
25
 
26
  public function add_template_type() {
119
 
120
  <div class="misc-pub-section">
121
  <div id="" class="es_preview_button" style="display: block;">
122
+ <a style="padding-top: 3px; margin-bottom: 0.2rem;" href="#" data-post-id="<?php echo esc_attr( $post_id ); ?>" class="button button-primary es_template_preview"><?php esc_html_e( 'Preview template', 'email-subscribers' ); ?></a><img class="es-template-preview-loader inline-flex align-middle pl-2 h-5 w-7" src="<?php echo esc_url( ES_PLUGIN_URL ); ?>lite/admin/images/spinner-2x.gif" style="display:none;"/>
123
  <div class="clear"></div>
124
  </div>
125
  </div>
140
  }
141
 
142
  public function es_template_preview_callback() {
143
+ ?>
144
+ <div class="hidden" id="es_preview_template">
145
+ <div class="fixed top-0 left-0 z-50 flex items-center justify-center w-full h-full" style="background-color: rgba(0,0,0,.5);">
146
+ <div style="height:485px" class="absolute h-auto p-4 ml-16 mr-4 text-left bg-white rounded shadow-xl z-80 md:max-w-5xl md:p-6 lg:p-8 ">
147
+ <h3 class="text-2xl text-center"><?php echo esc_html__( 'Template Preview', 'email-subscribers' ); ?></h3>
148
+ <p class="m-4 text-center"><?php echo esc_html__( 'There could be a slight variation on how your customer will view the email content.', 'email-subscribers' ); ?></p>
149
+ <div class="m-4 list-decimal template_preview_container">
150
+ </div>
151
+ <div class="flex justify-center mt-8">
152
+ <button id="es_close_template_preview" class="px-4 py-2 text-sm font-medium tracking-wide text-gray-700 border rounded select-none no-outline focus:outline-none focus:shadow-outline-red hover:border-red-400 active:shadow-lg "><?php echo esc_html__( 'Close', 'email-subscribers' ); ?></button>
153
+ </div>
154
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
  </div>
156
+ </div>
157
+ <?php
 
 
 
 
158
  }
159
 
160
  public function add_new_columns( $existing_columns ) {
lite/includes/db/class-es-db-contacts.php CHANGED
@@ -77,15 +77,15 @@ class ES_DB_Contacts extends ES_DB {
77
  'is_webmail' => '%d',
78
  'is_deliverable' => '%d',
79
  'is_sendsafely' => '%d',
 
80
  'meta' => '%s',
81
  );
82
 
83
  $custom_field_data = ES()->custom_fields_db->get_custom_fields();
84
  $custom_field_cols = array();
85
  if ( count( $custom_field_data ) > 0 ) {
86
- $type = '%s';
87
-
88
  foreach ($custom_field_data as $key => $data) {
 
89
  if ( isset( $data[ 'type' ] ) && 'number' === $data[ 'type' ] ) {
90
  $type = '%d';
91
  }
77
  'is_webmail' => '%d',
78
  'is_deliverable' => '%d',
79
  'is_sendsafely' => '%d',
80
+ 'timezone' => '%d',
81
  'meta' => '%s',
82
  );
83
 
84
  $custom_field_data = ES()->custom_fields_db->get_custom_fields();
85
  $custom_field_cols = array();
86
  if ( count( $custom_field_data ) > 0 ) {
 
 
87
  foreach ($custom_field_data as $key => $data) {
88
+ $type = '%s';
89
  if ( isset( $data[ 'type' ] ) && 'number' === $data[ 'type' ] ) {
90
  $type = '%d';
91
  }
lite/includes/db/class-es-db-mailing-queue.php CHANGED
@@ -7,21 +7,11 @@ if ( ! defined( 'ABSPATH' ) ) {
7
 
8
  class ES_DB_Mailing_Queue {
9
 
10
- public $table_name;
11
 
12
- public $version;
13
 
14
- public $primary_key;
15
-
16
- public function __construct() {
17
-
18
- global $wpdb;
19
-
20
- $this->table_name = IG_MAILING_QUEUE_TABLE;
21
- $this->primary_key = 'id';
22
- $this->version = '1.0';
23
-
24
- }
25
 
26
  /**
27
  * Get columns and formats
@@ -523,21 +513,43 @@ class ES_DB_Mailing_Queue {
523
  *
524
  * @since 4.6.3
525
  */
526
- public static function update_subscribers_count( $hash = '', $count = 0 ) {
 
 
 
 
527
 
528
  global $wpdb;
529
 
530
- if ( empty( $hash ) ) {
531
- return;
 
 
 
532
  }
533
 
534
- $wpdb->query(
535
- $wpdb->prepare(
536
- "UPDATE {$wpdb->prefix}ig_mailing_queue SET count = %d WHERE hash = %s",
537
- $count,
538
- $hash
539
- )
540
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
541
  }
542
 
543
  /**
7
 
8
  class ES_DB_Mailing_Queue {
9
 
10
+ public static $table_name = IG_MAILING_QUEUE_TABLE;
11
 
12
+ public static $primary_key = 'id';
13
 
14
+ public static $version = '1.0';
 
 
 
 
 
 
 
 
 
 
15
 
16
  /**
17
  * Get columns and formats
513
  *
514
  * @since 4.6.3
515
  */
516
+ public static function update_mailing_queue( $mailing_queue_id = 0, $data = array() ) {
517
+
518
+ if ( empty( $mailing_queue_id ) ) {
519
+ return;
520
+ }
521
 
522
  global $wpdb;
523
 
524
+ // Row ID must be positive integer
525
+ $mailing_queue_id = absint( $mailing_queue_id );
526
+
527
+ if ( empty( $mailing_queue_id ) ) {
528
+ return false;
529
  }
530
 
531
+ if ( empty( $where ) ) {
532
+ $where = self::$primary_key;
533
+ }
534
+
535
+ // Initialise column format array
536
+ $column_formats = self::get_columns();
537
+
538
+ // Force fields to lower case
539
+ $data = array_change_key_case( $data );
540
+
541
+ // White list columns
542
+ $data = array_intersect_key( $data, $column_formats );
543
+
544
+ // Reorder $column_formats to match the order of columns given in $data
545
+ $data_keys = array_keys( $data );
546
+ $column_formats = array_merge( array_flip( $data_keys ), $column_formats );
547
+
548
+ if ( false === $wpdb->update( self::$table_name, $data, array( $where => $mailing_queue_id ), $column_formats ) ) {
549
+ return false;
550
+ }
551
+
552
+ return true;
553
  }
554
 
555
  /**
lite/includes/db/class-es-db-sending-queue.php CHANGED
@@ -52,10 +52,10 @@ class ES_DB_Sending_Queue {
52
 
53
  public static function get_emails_to_be_sent_by_hash( $guid, $limit ) {
54
  global $wpdb;
55
-
56
  $subscribers = $wpdb->get_results(
57
  $wpdb->prepare(
58
- "SELECT * FROM {$wpdb->prefix}ig_sending_queue WHERE status = %s AND mailing_queue_hash = %s ORDER BY id LIMIT 0, %d",
59
  array(
60
  'In Queue',
61
  $guid,
@@ -322,11 +322,15 @@ class ES_DB_Sending_Queue {
322
  'return_sql' => true, // This flag will return the required sql query
323
  'orderby' => array( 'id' ),
324
  );
 
325
  if ( ! empty( $campaign ) && ! empty( $campaign['meta'] ) ) {
326
  $campaign_meta = maybe_unserialize( $campaign['meta'] );
327
  if ( ! empty( $campaign_meta['list_conditions'] ) ) {
328
  $args['conditions'] = $campaign_meta['list_conditions'];
329
  }
 
 
 
330
  }
331
  $query = new IG_ES_Subscribers_Query();
332
  $sql_query = $query->run( $args );
@@ -356,7 +360,8 @@ class ES_DB_Sending_Queue {
356
  `links`,
357
  `opened`,
358
  `sent_at`,
359
- `opened_at`
 
360
  )
361
  SELECT
362
  %d AS `mailing_queue_id`,
@@ -369,7 +374,12 @@ class ES_DB_Sending_Queue {
369
  %s AS `links`,
370
  %d AS `opened`,
371
  %s AS `sent_at`,
372
- %s AS `opened_at`
 
 
 
 
 
373
  FROM `{$wpbd->prefix}ig_contacts` AS `ig_contacts`
374
  WHERE id IN ( " . $sql_query . ')
375
  GROUP BY `ig_contacts`.`email`',
@@ -380,7 +390,6 @@ class ES_DB_Sending_Queue {
380
  // Check if contacts added.
381
  if ( ! empty( $total_contacts_added ) ) {
382
  $is_inserted = true;
383
- ES_DB_Mailing_Queue::update_subscribers_count( $mailing_queue_hash, $total_contacts_added );
384
  } else {
385
 
386
  // If some how above sql query fails then queue emails using old approach.
@@ -391,9 +400,9 @@ class ES_DB_Sending_Queue {
391
  $list_ids = explode( ',', $list_ids );
392
  }
393
 
394
- $subscribers = ES()->contacts_db->get_active_contacts_by_list_id( $list_ids );
395
- $subscribers_count = count( $subscribers );
396
- if ( $subscribers_count > 0 ) {
397
  // Add entry into sending queue table
398
  $delivery_data = array();
399
  $delivery_data['hash'] = $mailing_queue_hash;
@@ -402,12 +411,17 @@ class ES_DB_Sending_Queue {
402
  $delivery_data['campaign_id'] = $campaign_id;
403
  $delivery_data['mailing_queue_id'] = $mailing_queue_id;
404
  $is_inserted = self::do_batch_insert( $delivery_data );
405
- if ( $is_inserted ) {
406
- ES_DB_Mailing_Queue::update_subscribers_count( $mailing_queue_hash, $subscribers_count );
407
- }
408
  }
409
  }
410
 
 
 
 
 
 
 
 
 
411
  return $is_inserted;
412
  }
413
 
52
 
53
  public static function get_emails_to_be_sent_by_hash( $guid, $limit ) {
54
  global $wpdb;
55
+ $where = apply_filters( 'ig_es_get_emails_to_be_sent_by_hash_condition', 'AND 1=1' );
56
  $subscribers = $wpdb->get_results(
57
  $wpdb->prepare(
58
+ "SELECT * FROM {$wpdb->prefix}ig_sending_queue WHERE status = %s AND mailing_queue_hash = %s $where ORDER BY id LIMIT 0, %d",
59
  array(
60
  'In Queue',
61
  $guid,
322
  'return_sql' => true, // This flag will return the required sql query
323
  'orderby' => array( 'id' ),
324
  );
325
+ $schedule_base_time = current_time('mysql', true);
326
  if ( ! empty( $campaign ) && ! empty( $campaign['meta'] ) ) {
327
  $campaign_meta = maybe_unserialize( $campaign['meta'] );
328
  if ( ! empty( $campaign_meta['list_conditions'] ) ) {
329
  $args['conditions'] = $campaign_meta['list_conditions'];
330
  }
331
+ if ( isset( $campaign_meta['scheduling_option'] ) && isset( $campaign_meta['date'] ) && 'schedule_later' == $campaign_meta['scheduling_option'] ) {
332
+ $schedule_base_time = $campaign_meta['date'];
333
+ }
334
  }
335
  $query = new IG_ES_Subscribers_Query();
336
  $sql_query = $query->run( $args );
360
  `links`,
361
  `opened`,
362
  `sent_at`,
363
+ `opened_at`,
364
+ `send_at`
365
  )
366
  SELECT
367
  %d AS `mailing_queue_id`,
374
  %s AS `links`,
375
  %d AS `opened`,
376
  %s AS `sent_at`,
377
+ %s AS `opened_at`,
378
+ CASE
379
+ WHEN `ig_contacts`.`timezone` > 0 THEN DATE_ADD('$schedule_base_time', INTERVAL `ig_contacts`.`timezone` SECOND)
380
+ WHEN `ig_contacts`.`timezone` < 0 THEN DATE_ADD('$schedule_base_time', INTERVAL 86400 - ABS(`ig_contacts`.`timezone`) SECOND)
381
+ ELSE '$schedule_base_time'
382
+ END AS `send_at`
383
  FROM `{$wpbd->prefix}ig_contacts` AS `ig_contacts`
384
  WHERE id IN ( " . $sql_query . ')
385
  GROUP BY `ig_contacts`.`email`',
390
  // Check if contacts added.
391
  if ( ! empty( $total_contacts_added ) ) {
392
  $is_inserted = true;
 
393
  } else {
394
 
395
  // If some how above sql query fails then queue emails using old approach.
400
  $list_ids = explode( ',', $list_ids );
401
  }
402
 
403
+ $subscribers = ES()->contacts_db->get_active_contacts_by_list_id( $list_ids );
404
+ $total_contacts_added = count( $subscribers );
405
+ if ( $total_contacts_added > 0 ) {
406
  // Add entry into sending queue table
407
  $delivery_data = array();
408
  $delivery_data['hash'] = $mailing_queue_hash;
411
  $delivery_data['campaign_id'] = $campaign_id;
412
  $delivery_data['mailing_queue_id'] = $mailing_queue_id;
413
  $is_inserted = self::do_batch_insert( $delivery_data );
 
 
 
414
  }
415
  }
416
 
417
+ if ( $is_inserted ) {
418
+ $data = array(
419
+ 'count' => $total_contacts_added,
420
+ 'status' => IG_ES_MAILING_QUEUE_STATUS_QUEUED
421
+ );
422
+ ES_DB_Mailing_Queue::update_mailing_queue( $mailing_queue_id, $data );
423
+ }
424
+
425
  return $is_inserted;
426
  }
427
 
lite/includes/notices/class-es-admin-notices.php CHANGED
@@ -236,8 +236,8 @@ class ES_Admin_Notices {
236
  }
237
  }
238
 
239
- // Halloween 2021 offer
240
- if ( 'offer_halloween_2021' === $option_name ) {
241
  $url = 'https://www.icegram.com/email-subscribers-pricing/?utm_source=in_app&utm_medium=es_banner&utm_campaign=' . $option_name;
242
  header( "Location: {$url}" );
243
  exit();
236
  }
237
  }
238
 
239
+ // BFCM 2021 offer
240
+ if ( 'offer_bfcm_2021' === $option_name ) {
241
  $url = 'https://www.icegram.com/email-subscribers-pricing/?utm_source=in_app&utm_medium=es_banner&utm_campaign=' . $option_name;
242
  header( "Location: {$url}" );
243
  exit();
lite/includes/notices/views/ig-es-bfcm-offer.php CHANGED
@@ -8,11 +8,18 @@
8
 
9
  </style>
10
  <?php
 
 
 
 
 
 
 
11
 
12
- if ( ( get_option( 'ig_es_offer_bfcm_2020' ) !== 'yes' ) && ( $ig_current_date >= strtotime( '2020-11-24' ) ) && ( $ig_current_date <= strtotime( '2020-12-02' ) ) ) { ?>
13
  <div class="wrap">
14
  <div class="ig_es_offer">
15
- <a target="_blank" href="?es_dismiss_admin_notice=1&option_name=offer_bfcm_2020"><img style="margin:0 auto" src="<?php echo esc_url( ES_PLUGIN_URL ); ?>lite/admin/images/bfcm_2020.jpg"/></a>
16
  </div>
17
  </div>
18
 
8
 
9
  </style>
10
  <?php
11
+ $plan = ES()->get_plan();
12
+ $img_url = esc_url( ES_PLUGIN_URL ) .'lite/admin/images/bfcm2021.png';
13
+ if( 'lite' === $plan || 'trial' === $plan ){
14
+ $img_url = esc_url( ES_PLUGIN_URL ) .'lite/admin/images/bfcm2021_lite.png';
15
+ } elseif ('starter' === $plan ){
16
+ $img_url = esc_url( ES_PLUGIN_URL ) .'lite/admin/images/bfcm2021_starter.png';
17
+ }
18
 
19
+ if ( ( get_option( 'ig_es_offer_bfcm_2021' ) !== 'yes' ) && ES()->is_offer_period( 'bfcm' ) ) { ?>
20
  <div class="wrap">
21
  <div class="ig_es_offer">
22
+ <a target="_blank" href="?es_dismiss_admin_notice=1&option_name=offer_bfcm_2021"><img style="margin:0 auto" src="<?php echo $img_url ?>"/></a>
23
  </div>
24
  </div>
25
 
lite/includes/upgrade/es-update-functions.php CHANGED
@@ -1654,3 +1654,69 @@ function ig_es_update_490_db_version() {
1654
  ES_Install::update_db_version( '4.9.0' );
1655
  }
1656
  /* --------------------- ES 4.9.0(End)--------------------------- */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1654
  ES_Install::update_db_version( '4.9.0' );
1655
  }
1656
  /* --------------------- ES 4.9.0(End)--------------------------- */
1657
+
1658
+
1659
+ /* --------------------- ES 5.0.1(Start)--------------------------- */
1660
+
1661
+ /**
1662
+ * Add send_at column in sending queue table
1663
+ *
1664
+ * @since 5.0.1
1665
+ */
1666
+ function ig_es_update_501_alter_sending_queue_table() {
1667
+ global $wpdb;
1668
+
1669
+ $cols = $wpdb->get_col( "SHOW COLUMNS FROM {$wpdb->prefix}ig_sending_queue" );
1670
+
1671
+ if ( ! in_array( 'send_at', $cols, true ) ) {
1672
+ $wpdb->query(
1673
+ "ALTER TABLE {$wpdb->prefix}ig_sending_queue ADD COLUMN `send_at` DATETIME NULL DEFAULT NULL AFTER `opened`"
1674
+ );
1675
+ }
1676
+ }
1677
+
1678
+ /**
1679
+ * Add timezone column in contacts table
1680
+ *
1681
+ * @since 5.0.1
1682
+ */
1683
+ function ig_es_update_501_alter_contacts_table() {
1684
+ global $wpdb;
1685
+
1686
+ $cols = $wpdb->get_col( "SHOW COLUMNS FROM {$wpdb->prefix}ig_contacts" );
1687
+
1688
+ if ( ! in_array( 'timezone', $cols, true ) ) {
1689
+ $wpdb->query(
1690
+ "ALTER TABLE {$wpdb->prefix}ig_contacts ADD COLUMN `timezone` INT NULL DEFAULT NULL AFTER `bounce_status`"
1691
+ );
1692
+ }
1693
+ }
1694
+
1695
+ /**
1696
+ * Add timezone based on the contacts ip_address
1697
+ *
1698
+ * @since 5.0.1
1699
+ */
1700
+ function ig_es_add_timezone_to_contacts_table() {
1701
+ IG_ES_Background_Process_Helper::add_action_scheduler_task( 'ig_es_add_country_code_to_audience' );
1702
+ }
1703
+
1704
+ /**
1705
+ * Migrate notifications into workflows.
1706
+ *
1707
+ * @since 5.0.1
1708
+ */
1709
+ function ig_es_update_501_migrate_notifications_into_workflows() {
1710
+ ES()->workflows_db->migrate_notifications_to_workflows();
1711
+ }
1712
+
1713
+ /**
1714
+ * Update DB version
1715
+ *
1716
+ * @since 5.0.1
1717
+ */
1718
+ function ig_es_update_501_db_version() {
1719
+ ES_Install::update_db_version( '5.0.1' );
1720
+ }
1721
+
1722
+ /* --------------------- ES 5.0.1(End)--------------------------- */
lite/includes/workflows/actions/class-es-action-send-email.php ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Action to send an email to provided email address.
4
+ *
5
+ * @since 4.5.3
6
+ * @version 1.0
7
+ * @package Email Subscribers
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) {
11
+ exit;
12
+ }
13
+
14
+ /**
15
+ * Class to handle send email action
16
+ *
17
+ * @class ES_Action_Send_Email
18
+ *
19
+ * @since 4.5.3
20
+ */
21
+ class ES_Action_Send_Email extends ES_Action_Send_Email_Abstract {
22
+
23
+ /**
24
+ * Load action admin details.
25
+ *
26
+ * @since 4.5.3
27
+ */
28
+ public function load_admin_details() {
29
+ $this->group = __( 'Email', 'email-subscribers' );
30
+ $this->title = __( 'Send Email', 'email-subscribers' );
31
+ }
32
+
33
+ /**
34
+ * Load action fields
35
+ *
36
+ * @since 4.5.3
37
+ */
38
+ public function load_fields() {
39
+ parent::load_fields();
40
+
41
+ $email_content = new ES_WP_Editor();
42
+ $email_content->set_name( 'ig-es-email-content' );
43
+ $email_content->set_title( __( 'Email Content', 'email-subscribers' ) );
44
+ $email_content->set_required();
45
+
46
+ $this->add_field( $email_content );
47
+ }
48
+
49
+ /**
50
+ * Called when an action should be run
51
+ *
52
+ * @since 4.5.3
53
+ */
54
+ public function run() {
55
+
56
+ $recipients = $this->get_option( 'ig-es-send-to', true );
57
+ $email_content = $this->get_option( 'ig-es-email-content', true, true );
58
+ $subject = $this->get_option( 'ig-es-email-subject', true );
59
+
60
+ $recipients = explode(',', $recipients );
61
+ $recipients = array_map( 'trim', $recipients );
62
+
63
+ // Check if we have all required data to send the email.
64
+ if ( empty( $recipients ) || empty( $email_content ) || empty( $subject ) ) {
65
+ return;
66
+ }
67
+
68
+ // Replace line breaks with paragraphs in email body.
69
+ $email_content = wpautop( $email_content );
70
+
71
+ $raw_data = $this->workflow->data_layer()->get_raw_data();
72
+ if ( ! empty( $raw_data ) ) {
73
+ foreach ( $raw_data as $data_type_id => $data_item ) {
74
+ $data_type = ES_Workflow_Data_Types::get( $data_type_id );
75
+ if ( ! $data_type || ! $data_type->validate( $data_item ) ) {
76
+ continue;
77
+ }
78
+
79
+ $data = array();
80
+ if ( method_exists( $data_type, 'get_data' ) ) {
81
+ $data = $data_type->get_data( $data_item );
82
+ if ( ! empty( $data['email'] ) ) {
83
+ foreach ( $recipients as $index => $recipient_email ) {
84
+ // Replace placeholder tags with the got data from the triggerred event.
85
+ $recipients[$index] = str_replace( '{{EMAIL}}', $data['email'], $recipient_email );
86
+ }
87
+ }
88
+
89
+ if ( 'campaign' === $data_type_id && ! empty( $data['notification_guid'] ) ) {
90
+ $notification = ES_DB_Mailing_Queue::get_notification_by_hash( $data['notification_guid'] );
91
+ $subject = str_replace( '{{SUBJECT}}', $notification['subject'], $subject );
92
+ $email_count = $notification['count'];
93
+ $campaign_subject = $notification['subject'];
94
+ $cron_date = gmdate( 'Y-m-d H:i:s' );
95
+ $cron_local_date = get_date_from_gmt( $cron_date ); // Convert from GMT to local date/time based on WordPress time zone setting.
96
+ $cron_date = ES_Common::convert_date_to_wp_date( $cron_local_date ); // Get formatted date from WordPress date/time settings.
97
+
98
+ $email_content = str_replace( '{{DATE}}', $cron_date, $email_content );
99
+ $email_content = str_replace( '{{COUNT}}', $email_count, $email_content );
100
+ $email_content = str_replace( '{{SUBJECT}}', $campaign_subject, $email_content );
101
+ }
102
+ }
103
+
104
+ }
105
+
106
+ $es_mailer = ES()->mailer;
107
+
108
+ $es_mailer->add_unsubscribe_link = false;
109
+ $es_mailer->add_tracking_pixel = false;
110
+
111
+ $es_mailer->send( $subject, $email_content, $recipients, $data );
112
+ }
113
+ }
114
+ }
lite/includes/workflows/class-es-workflow-actions.php CHANGED
@@ -40,6 +40,7 @@ class ES_Workflow_Actions extends ES_Workflow_Registry {
40
  'ig_es_add_to_list' => 'ES_Action_Add_To_List',
41
  'ig_es_delete_contact' => 'ES_Action_Delete_Contact',
42
  'ig_es_update_contact' => 'ES_Action_Update_Contact',
 
43
  );
44
 
45
  return apply_filters( 'ig_es_workflow_actions', $includes );
40
  'ig_es_add_to_list' => 'ES_Action_Add_To_List',
41
  'ig_es_delete_contact' => 'ES_Action_Delete_Contact',
42
  'ig_es_update_contact' => 'ES_Action_Update_Contact',
43
+ 'ig_es_send_email' => 'ES_Action_Send_Email',
44
  );
45
 
46
  return apply_filters( 'ig_es_workflow_actions', $includes );
lite/includes/workflows/class-es-workflow-data-types.php CHANGED
@@ -40,6 +40,7 @@ class ES_Workflow_Data_Types extends ES_Workflow_Registry {
40
  array(
41
  'user' => 'ES_Data_Type_User',
42
  'subscriber' => 'ES_Data_Type_Subscriber',
 
43
  )
44
  );
45
  }
40
  array(
41
  'user' => 'ES_Data_Type_User',
42
  'subscriber' => 'ES_Data_Type_Subscriber',
43
+ 'campaign' => 'ES_Data_Type_Campaign',
44
  )
45
  );
46
  }
lite/includes/workflows/class-es-workflow-triggers.php CHANGED
@@ -41,12 +41,13 @@ class ES_Workflow_Triggers extends ES_Workflow_Registry {
41
  */
42
  public static function load_includes() {
43
 
44
- global $ig_es_tracker;
45
-
46
  $includes = array(
47
- 'ig_es_user_registered' => 'ES_Trigger_User_Registered',
48
- 'ig_es_user_deleted' => 'ES_Trigger_User_Deleted',
49
- 'ig_es_user_updated' => 'ES_Trigger_User_Updated',
 
 
 
50
  );
51
 
52
  return apply_filters( 'ig_es_workflow_triggers', $includes );
41
  */
42
  public static function load_includes() {
43
 
 
 
44
  $includes = array(
45
+ 'ig_es_user_registered' => 'ES_Trigger_User_Registered',
46
+ 'ig_es_user_deleted' => 'ES_Trigger_User_Deleted',
47
+ 'ig_es_user_updated' => 'ES_Trigger_User_Updated',
48
+ 'ig_es_user_subscribed' => 'ES_Trigger_User_Subscribed',
49
+ 'ig_es_user_unconfirmed' => 'ES_Trigger_User_Unconfirmed',
50
+ 'ig_es_campaign_sent' => 'ES_Trigger_Campaign_Sent',
51
  );
52
 
53
  return apply_filters( 'ig_es_workflow_triggers', $includes );
lite/includes/workflows/class-ig-es-variables-processor.php CHANGED
@@ -182,6 +182,9 @@ class IG_ES_Variables_Processor {
182
  'LIST',
183
  'SITENAME',
184
  'SITEURL',
 
 
 
185
  ));
186
 
187
  return in_array( $variable, $excluded );
182
  'LIST',
183
  'SITENAME',
184
  'SITEURL',
185
+ 'SUBJECT',
186
+ 'COUNT',
187
+ 'DATE',
188
  ));
189
 
190
  return in_array( $variable, $excluded );
lite/includes/workflows/data-types/class-es-data-type-campaign.php ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Workflow data type campaign
4
+ *
5
+ * @since 5.0.1
6
+ * @version 1.0
7
+ * @package Email Subscribers
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) {
11
+ exit;
12
+ }
13
+
14
+ /**
15
+ * Class to handle campaign data item
16
+ *
17
+ * @class ES_Data_Type_Campaign
18
+ *
19
+ * @since 5.0.1
20
+ */
21
+ class ES_Data_Type_Campaign extends ES_Workflow_Data_Type {
22
+
23
+ /**
24
+ * Validate given data item
25
+ *
26
+ * @since 5.0.1
27
+ *
28
+ * @param WP_User $item Data item object.
29
+ *
30
+ * @return bool
31
+ */
32
+ public function validate( $item ) {
33
+
34
+ if ( empty( $item['notification_guid'] ) ) {
35
+ return false;
36
+ }
37
+
38
+ return true;
39
+ }
40
+
41
+
42
+ /**
43
+ * Returns id of given data item object. Only validated $items should be passed to this method
44
+ *
45
+ * @since 5.0.1
46
+ *
47
+ * @param WP_User $item Data item object.
48
+ *
49
+ * @return mixed
50
+ */
51
+ public function compress( $item ) {
52
+ return $item;
53
+ }
54
+
55
+
56
+ /**
57
+ * Return data item object from given id.
58
+ *
59
+ * @since 5.0.1
60
+ *
61
+ * @param string $compressed_item Data item object ID.
62
+ * @param array $compressed_data_layer Data layer.
63
+ *
64
+ * @return mixed
65
+ */
66
+ public function decompress( $compressed_item, $compressed_data_layer ) {
67
+
68
+ if ( ! $compressed_item ) {
69
+ return false;
70
+ }
71
+
72
+ return $compressed_item;
73
+ }
74
+
75
+ /**
76
+ * Abstract required data from data item object
77
+ *
78
+ * @since 5.0.1
79
+ *
80
+ * @param array $item Data item object.
81
+ * @return array
82
+ */
83
+ public function get_data( $item ) {
84
+
85
+ $data = array();
86
+
87
+ if ( ! empty( $item ) ) {
88
+ $data = $item;
89
+ }
90
+
91
+ return $data;
92
+ }
93
+ }
lite/includes/workflows/data-types/class-es-data-type-subscriber.php CHANGED
@@ -31,7 +31,7 @@ class ES_Data_Type_Subscriber extends ES_Workflow_Data_Type {
31
  */
32
  public function validate( $item ) {
33
 
34
- if ( empty( $item['email'] ) || ! is_email( $item['email'] ) ) {
35
  return false;
36
  }
37
 
@@ -49,7 +49,7 @@ class ES_Data_Type_Subscriber extends ES_Workflow_Data_Type {
49
  * @return mixed
50
  */
51
  public function compress( $item ) {
52
- return $item['email'];
53
  }
54
 
55
 
@@ -65,13 +65,11 @@ class ES_Data_Type_Subscriber extends ES_Workflow_Data_Type {
65
  */
66
  public function decompress( $compressed_item, $compressed_data_layer ) {
67
 
68
- $data = array();
69
-
70
- if ( is_email( $compressed_item ) ) {
71
- $data['email'] = $compressed_item;
72
  }
73
 
74
- return $data;
75
  }
76
 
77
  /**
@@ -88,7 +86,7 @@ class ES_Data_Type_Subscriber extends ES_Workflow_Data_Type {
88
 
89
  if ( ! empty( $item['email'] ) ) {
90
  $data = $item;
91
- $data['source'] = 'wp';
92
  }
93
 
94
  return $data;
31
  */
32
  public function validate( $item ) {
33
 
34
+ if ( empty( $item ) || ! is_email( $item['email'] ) ) {
35
  return false;
36
  }
37
 
49
  * @return mixed
50
  */
51
  public function compress( $item ) {
52
+ return $item;
53
  }
54
 
55
 
65
  */
66
  public function decompress( $compressed_item, $compressed_data_layer ) {
67
 
68
+ if ( ! $compressed_item ) {
69
+ return false;
 
 
70
  }
71
 
72
+ return $compressed_item;
73
  }
74
 
75
  /**
86
 
87
  if ( ! empty( $item['email'] ) ) {
88
  $data = $item;
89
+ $data['source'] = 'es';
90
  }
91
 
92
  return $data;
lite/includes/workflows/db/class-es-db-workflows.php CHANGED
@@ -229,7 +229,6 @@ class ES_DB_Workflows extends ES_DB {
229
  * @return array|object|null
230
  */
231
  public function get_workflow( $id = 0, $output = ARRAY_A ) {
232
- global $wpdb;
233
 
234
  if ( empty( $id ) ) {
235
  return array();
@@ -512,6 +511,114 @@ class ES_DB_Workflows extends ES_DB {
512
  return $workflow_data;
513
  }
514
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
515
  /**
516
  * Method to convert audience sync setting to workflow
517
  *
229
  * @return array|object|null
230
  */
231
  public function get_workflow( $id = 0, $output = ARRAY_A ) {
 
232
 
233
  if ( empty( $id ) ) {
234
  return array();
511
  return $workflow_data;
512
  }
513
 
514
+ /**
515
+ * Migrate site notication setting into workflows
516
+ *
517
+ * @since 5.0.1
518
+ */
519
+ public function migrate_notifications_to_workflows() {
520
+
521
+ $notification_workflows = $this->get_notification_workflows();
522
+
523
+ if ( ! empty( $notification_workflows ) ) {
524
+ foreach ( $notification_workflows as $workflow ) {
525
+ $workflow_title = $workflow['title'];
526
+ $workflow_name = sanitize_title( $workflow_title );
527
+ $trigger_name = $workflow['trigger_name'];
528
+ $workflow_meta = array();
529
+ $workflow_meta['when_to_run'] = 'immediately';
530
+ $workflow_status = $workflow['status'];
531
+
532
+ $workflow_actions = $workflow['actions'];
533
+
534
+ $workflow_data = array(
535
+ 'name' => $workflow_name,
536
+ 'title' => $workflow_title,
537
+ 'trigger_name' => $trigger_name,
538
+ 'actions' => maybe_serialize( $workflow_actions ),
539
+ 'meta' => maybe_serialize( $workflow_meta ),
540
+ 'priority' => 0,
541
+ 'status' => $workflow_status,
542
+ );
543
+
544
+ ES()->workflows_db->insert_workflow( $workflow_data );
545
+ }
546
+ }
547
+ }
548
+
549
+ /**
550
+ * Get workflows for site notifications(user subscribed,confirmed,campaign sent)
551
+ *
552
+ *
553
+ * @return array $notification_workflows Workflow data
554
+ *
555
+ * @since 5.0.1
556
+ */
557
+ public function get_notification_workflows() {
558
+
559
+ $admin_emails = ES()->mailer->get_admin_emails();
560
+ if ( ! empty( $admin_emails ) ) {
561
+ $admin_emails = implode( ',', $admin_emails );
562
+ }
563
+
564
+ $notification_workflows = array(
565
+ array(
566
+ 'trigger_name' => 'ig_es_user_subscribed',
567
+ 'title' => __( 'Send welcome email when someone subscribes', 'email-subscribers' ),
568
+ 'actions' => array(
569
+ array(
570
+ 'action_name' => 'ig_es_send_email',
571
+ 'ig-es-send-to' => '{{EMAIL}}',
572
+ 'ig-es-email-subject' => ES()->mailer->get_welcome_email_subject(),
573
+ 'ig-es-email-content' => ES()->mailer->get_welcome_email_content(),
574
+ ),
575
+ ),
576
+ 'status' => ES()->mailer->can_send_welcome_email() ? 1 : 0,
577
+ ),
578
+ array(
579
+ 'trigger_name' => 'ig_es_user_unconfirmed',
580
+ 'title' => __( 'Send confirmation email', 'email-subscribers' ),
581
+ 'actions' => array(
582
+ array(
583
+ 'action_name' => 'ig_es_send_email',
584
+ 'ig-es-send-to' => '{{EMAIL}}',
585
+ 'ig-es-email-subject' => ES()->mailer->get_confirmation_email_subject(),
586
+ 'ig-es-email-content' => ES()->mailer->get_confirmation_email_content(),
587
+ )
588
+ ),
589
+ 'status' => 1,
590
+ ),
591
+ array(
592
+ 'trigger_name' => 'ig_es_user_subscribed',
593
+ 'title' => __( 'Notify admin when someone subscribes', 'email-subscribers' ),
594
+ 'actions' => array(
595
+ array(
596
+ 'action_name' => 'ig_es_send_email',
597
+ 'ig-es-send-to' => $admin_emails,
598
+ 'ig-es-email-subject' => ES()->mailer->get_admin_new_contact_email_subject(),
599
+ 'ig-es-email-content' => ES()->mailer->get_admin_new_contact_email_content(),
600
+ ),
601
+ ),
602
+ 'status' => ES()->mailer->can_send_add_new_contact_notification() ? 1 : 0,
603
+ ),
604
+ array(
605
+ 'trigger_name' => 'ig_es_campaign_sent',
606
+ 'title' => __( 'Notify admin when campaign is sent', 'email-subscribers' ),
607
+ 'actions' => array(
608
+ array(
609
+ 'action_name' => 'ig_es_send_email',
610
+ 'ig-es-send-to' => $admin_emails,
611
+ 'ig-es-email-subject' => ES()->mailer->get_cron_admin_email_subject(),
612
+ 'ig-es-email-content' => ES()->mailer->get_cron_admin_email_content(),
613
+ ),
614
+ ),
615
+ 'status' => ES()->mailer->can_send_cron_admin_email() ? 1 : 0,
616
+ ),
617
+ );
618
+
619
+ return $notification_workflows;
620
+ }
621
+
622
  /**
623
  * Method to convert audience sync setting to workflow
624
  *
lite/includes/workflows/triggers/class-es-trigger-campaign-sent.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Triggers when a user gets subscribed
4
+ *
5
+ * @since 5.0.1
6
+ * @version 1.0
7
+ * @package Email Subscribers
8
+ */
9
+
10
+ defined( 'ABSPATH' ) || exit;
11
+
12
+ /***
13
+ * ES_Trigger_Campaign_Sent class.
14
+ *
15
+ * @since 5.0.1
16
+ */
17
+ class ES_Trigger_Campaign_Sent extends ES_Workflow_Trigger {
18
+
19
+ /**
20
+ * Declares data items available in trigger.
21
+ *
22
+ * @var array
23
+ */
24
+ public $supplied_data_items = array( 'campaign' );
25
+
26
+ /**
27
+ * Load trigger admin props.
28
+ */
29
+ public function load_admin_details() {
30
+ $this->title = __( 'Campaign sent', 'email-subscribers' );
31
+ $this->description = __( 'Fires when a campaign is sent successfully.', 'email-subscribers' );
32
+ $this->group = __( 'Admin', 'email-subscribers' );
33
+ }
34
+
35
+ /**
36
+ * Register trigger hooks.
37
+ */
38
+ public function register_hooks() {
39
+ add_action( 'ig_es_campaign_sent', array( $this, 'handle_campaign_sent' ) );
40
+ }
41
+
42
+
43
+ /**
44
+ * Catch user subscribed hook
45
+ *
46
+ * @param int $notification_guid Notification ID.
47
+ */
48
+ public function handle_campaign_sent( $notification_guid ) {
49
+
50
+ // Prepare data.
51
+ $data = array(
52
+ 'campaign' => array(
53
+ 'notification_guid' => $notification_guid
54
+ )
55
+ );
56
+
57
+ $this->maybe_run( $data );
58
+ }
59
+
60
+
61
+ /**
62
+ * Validate a workflow.
63
+ *
64
+ * @param ES_Workflow $workflow Workflow object.
65
+ *
66
+ * @return bool
67
+ */
68
+ public function validate_workflow( $workflow ) {
69
+
70
+ $campaign = $workflow->data_layer()->get_item( 'campaign' );
71
+
72
+ if ( empty( $campaign ) ) {
73
+ return false;
74
+ }
75
+
76
+ return true;
77
+ }
78
+
79
+ }
lite/includes/workflows/triggers/class-es-trigger-user-deleted.php CHANGED
@@ -58,7 +58,7 @@ class ES_Trigger_User_Deleted extends ES_Workflow_Trigger {
58
  if ( ! empty( $email ) ) {
59
 
60
  $subscriber = array(
61
- 'email' => $email,
62
  );
63
 
64
  // Prepare data.
58
  if ( ! empty( $email ) ) {
59
 
60
  $subscriber = array(
61
+ 'email' => $email,
62
  );
63
 
64
  // Prepare data.
lite/includes/workflows/triggers/class-es-trigger-user-subscribed.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Triggers when a user gets subscribed
4
+ *
5
+ * @since 5.0.1
6
+ * @version 1.0
7
+ * @package Email Subscribers
8
+ */
9
+
10
+ defined( 'ABSPATH' ) || exit;
11
+
12
+ /***
13
+ * ES_Trigger_User_Subscribed class.
14
+ *
15
+ * @since 5.0.1
16
+ */
17
+ class ES_Trigger_User_Subscribed extends ES_Workflow_Trigger {
18
+
19
+ /**
20
+ * Declares data items available in trigger.
21
+ *
22
+ * @var array
23
+ */
24
+ public $supplied_data_items = array( 'subscriber' );
25
+
26
+ /**
27
+ * Load trigger admin props.
28
+ */
29
+ public function load_admin_details() {
30
+ $this->title = __( 'User Subscribed', 'email-subscribers' );
31
+ $this->description = __( 'Fires when someone subscribes.', 'email-subscribers' );
32
+ $this->group = __( 'Subscriber', 'email-subscribers' );
33
+ }
34
+
35
+ /**
36
+ * Register trigger hooks.
37
+ */
38
+ public function register_hooks() {
39
+ add_action( 'ig_es_contact_subscribed', array( $this, 'handle_user_subscribe' ) );
40
+ }
41
+
42
+
43
+ /**
44
+ * Catch user subscribed hook
45
+ *
46
+ * @param int $subscriber_id User ID.
47
+ */
48
+ public function handle_user_subscribe( $subscriber ) {
49
+
50
+ // Prepare data.
51
+ $data = array(
52
+ 'subscriber' => $subscriber
53
+ );
54
+
55
+ $this->maybe_run( $data );
56
+ }
57
+
58
+
59
+ /**
60
+ * Validate a workflow.
61
+ *
62
+ * @param ES_Workflow $workflow Workflow object.
63
+ *
64
+ * @return bool
65
+ */
66
+ public function validate_workflow( $workflow ) {
67
+
68
+ $subscriber = $workflow->data_layer()->get_item( 'subscriber' );
69
+
70
+ if ( empty( $subscriber ) ) {
71
+ return false;
72
+ }
73
+
74
+ return true;
75
+ }
76
+
77
+ }
lite/includes/workflows/triggers/class-es-trigger-user-unconfirmed.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Triggers when a user gets unconfirmed
4
+ *
5
+ * @since 5.0.1
6
+ * @version 1.0
7
+ * @package Email Subscribers
8
+ */
9
+
10
+ defined( 'ABSPATH' ) || exit;
11
+
12
+ /***
13
+ * ES_Trigger_User_Unconfirmed class.
14
+ *
15
+ * @since 5.0.1
16
+ */
17
+ class ES_Trigger_User_Unconfirmed extends ES_Workflow_Trigger {
18
+
19
+ /**
20
+ * Declares data items available in trigger.
21
+ *
22
+ * @var array
23
+ */
24
+ public $supplied_data_items = array( 'subscriber' );
25
+
26
+ /**
27
+ * Load trigger admin props.
28
+ */
29
+ public function load_admin_details() {
30
+ $this->title = __( 'User Unconfirmed', 'email-subscribers' );
31
+ $this->description = __( 'Fires when someone subscribes.', 'email-subscribers' );
32
+ $this->group = __( 'Subscriber', 'email-subscribers' );
33
+ }
34
+
35
+ /**
36
+ * Register trigger hooks.
37
+ */
38
+ public function register_hooks() {
39
+ add_action( 'ig_es_contact_unconfirmed', array( $this, 'handle_user_subscribe' ) );
40
+ }
41
+
42
+
43
+ /**
44
+ * Catch user unconfirmed hook
45
+ *
46
+ * @param int $subscriber_id User ID.
47
+ */
48
+ public function handle_user_subscribe( $subscriber ) {
49
+
50
+ // Prepare data.
51
+ $data = array(
52
+ 'subscriber' => $subscriber
53
+ );
54
+
55
+ $this->maybe_run( $data );
56
+ }
57
+
58
+
59
+ /**
60
+ * Validate a workflow.
61
+ *
62
+ * @param ES_Workflow $workflow Workflow object.
63
+ *
64
+ * @return bool
65
+ */
66
+ public function validate_workflow( $workflow ) {
67
+
68
+ $subscriber = $workflow->data_layer()->get_item( 'subscriber' );
69
+
70
+ if ( empty( $subscriber ) ) {
71
+ return false;
72
+ }
73
+
74
+ return true;
75
+ }
76
+
77
+ }
lite/public/class-email-subscribers-public.php CHANGED
@@ -187,11 +187,8 @@ class Email_Subscribers_Public {
187
 
188
  $data['list_name'] = $list_name;
189
 
190
- do_action( 'ig_es_contact_subscribed', $db_id );
191
-
192
- ES()->mailer->send_welcome_email( $email, $data );
193
-
194
- ES()->mailer->send_add_new_contact_notification_to_admins( $data );
195
  } elseif ( 'unsubscribe' === $option ) {
196
  $unsubscribed = 1;
197
 
187
 
188
  $data['list_name'] = $list_name;
189
 
190
+ do_action( 'ig_es_contact_subscribed', $data );
191
+
 
 
 
192
  } elseif ( 'unsubscribe' === $option ) {
193
  $unsubscribed = 1;
194
 
readme.txt CHANGED
@@ -6,7 +6,7 @@ Tags: email marketing, subscription, autoresponder, post notification, welcome e
6
  Requires at least: 3.9
7
  Tested up to: 5.8.1
8
  Requires PHP: 5.6
9
- Stable tag: 5.0.0
10
  License: GPLv3
11
  License URI: http://www.gnu.org/licenses
12
 
@@ -310,13 +310,22 @@ Refer [here](https://www.icegram.com/documentation/es-faq/).
310
 
311
  == Upgrade Notice ==
312
 
313
- = 5.0.0 =
314
 
315
- * New: Campaign rule to filter on 'bounce status' of recipients while emails **[PRO]**
316
- * New: Campaign rule to filter on 'engagement score' of recipients while emails **[PRO]**
 
 
317
 
318
  == Changelog ==
319
 
 
 
 
 
 
 
 
320
  **5.0.0 (10.11.2021)**
321
 
322
  * New: Campaign rule to filter on 'bounce status' of recipients while emails **[PRO]**
6
  Requires at least: 3.9
7
  Tested up to: 5.8.1
8
  Requires PHP: 5.6
9
+ Stable tag: 5.0.1
10
  License: GPLv3
11
  License URI: http://www.gnu.org/licenses
12
 
310
 
311
  == Upgrade Notice ==
312
 
313
+ = 5.0.1 =
314
 
315
+ * Enhancement: Welcome and Confirmation email are now part of workflows
316
+ * New: Preview email template in popup
317
+ * Fix: Increase character limit in amazon SES
318
+ * Fix: Prevent email sending while campaign is getting queued
319
 
320
  == Changelog ==
321
 
322
+ **5.0.1 (18.11.2021)**
323
+
324
+ * Enhancement: Welcome and Confirmation email are now part of workflows
325
+ * New: Preview email template in popup
326
+ * Fix: Increase character limit in amazon SES
327
+ * Fix: Prevent email sending while campaign is getting queued
328
+
329
  **5.0.0 (10.11.2021)**
330
 
331
  * New: Campaign rule to filter on 'bounce status' of recipients while emails **[PRO]**