WooCommerce Cart Abandonment Recovery - Version 1.2.11

Version Description

Download this release

Release Info

Developer cartflowswp
Plugin Icon 128x128 WooCommerce Cart Abandonment Recovery
Version 1.2.11
Comparing to
See all releases

Code changes from version 1.2.10 to 1.2.11

admin/assets/js/admin-email-templates.js CHANGED
@@ -20,7 +20,7 @@
20
  }
21
  }).attr('readonly','readonly').css('background', 'white');
22
 
23
- $("#wcf_ca_custom_filter").click(function () {
24
  var from = $("#wcf_ca_custom_filter_from").val().trim();
25
  var to = $("#wcf_ca_custom_filter_to").val().trim();
26
  var url = window.location.search;
@@ -29,7 +29,7 @@
29
 
30
  });
31
 
32
- $("#wcf_search_id_submit").click( function () {
33
  var search = $("#wcf_search_id_search_input").val().trim();
34
  window.location.href = window.location.search + "&search_term=" + search;
35
  } );
@@ -50,7 +50,7 @@
50
  $("#wcf_ca_discount_type, #wcf_ca_coupon_amount, #wcf_ca_coupon_expiry").closest('tr').show();
51
  }
52
 
53
- $("#wcf_ca_coupon_code_status").click(
54
  function () {
55
  if (!$("#wcf_ca_coupon_code_status:checked").length) {
56
  $("#wcf_ca_discount_type, #wcf_ca_coupon_amount, #wcf_ca_coupon_expiry").closest('tr').fadeOut();
@@ -60,7 +60,7 @@
60
  }
61
  );
62
 
63
- $("#wcf_ca_gdpr_status").click(
64
  function () {
65
  if (!$("#wcf_ca_gdpr_status:checked").length) {
66
  $("#wcf_ca_gdpr_message").closest('tr').fadeOut();
@@ -70,7 +70,7 @@
70
  }
71
  );
72
 
73
- $("#wcf_ca_zapier_tracking_status").click(
74
  function () {
75
  if (!$("#wcf_ca_zapier_tracking_status:checked").length) {
76
  $("#wcf_ca_zapier_cart_abandoned_webhook, #wcf_ca_coupon_code_status").closest('tr').fadeOut();
@@ -228,7 +228,7 @@
228
  ZapierSettings = {
229
  init: function () {
230
 
231
- $(document).delegate("#wcf_ca_trigger_web_hook_abandoned_btn", "click",
232
  { 'order_status': 'abandoned' },
233
  ZapierSettings.zapier_trigger_sample);
234
  },
@@ -283,15 +283,14 @@
283
  ToolTipHover = {
284
  init: function () {
285
 
286
- $(".wcf-ca-report-table-row .wcf-ca-icon-row").hover(function(){
287
  $(this).find('.wcf-ca-tooltip-text').toggleClass("display_tool_tip");
288
  });
289
  },
290
  }
291
 
292
 
293
- $(document).ready(
294
- function () {
295
  EmailTemplatesAdmin.init();
296
  CartAbandonmentSettings.init();
297
  ZapierSettings.init();
20
  }
21
  }).attr('readonly','readonly').css('background', 'white');
22
 
23
+ $("#wcf_ca_custom_filter").on('click',function () {
24
  var from = $("#wcf_ca_custom_filter_from").val().trim();
25
  var to = $("#wcf_ca_custom_filter_to").val().trim();
26
  var url = window.location.search;
29
 
30
  });
31
 
32
+ $("#wcf_search_id_submit").on('click', function () {
33
  var search = $("#wcf_search_id_search_input").val().trim();
34
  window.location.href = window.location.search + "&search_term=" + search;
35
  } );
50
  $("#wcf_ca_discount_type, #wcf_ca_coupon_amount, #wcf_ca_coupon_expiry").closest('tr').show();
51
  }
52
 
53
+ $("#wcf_ca_coupon_code_status").on( 'click',
54
  function () {
55
  if (!$("#wcf_ca_coupon_code_status:checked").length) {
56
  $("#wcf_ca_discount_type, #wcf_ca_coupon_amount, #wcf_ca_coupon_expiry").closest('tr').fadeOut();
60
  }
61
  );
62
 
63
+ $("#wcf_ca_gdpr_status").on( 'click',
64
  function () {
65
  if (!$("#wcf_ca_gdpr_status:checked").length) {
66
  $("#wcf_ca_gdpr_message").closest('tr').fadeOut();
70
  }
71
  );
72
 
73
+ $("#wcf_ca_zapier_tracking_status").on('click',
74
  function () {
75
  if (!$("#wcf_ca_zapier_tracking_status:checked").length) {
76
  $("#wcf_ca_zapier_cart_abandoned_webhook, #wcf_ca_coupon_code_status").closest('tr').fadeOut();
228
  ZapierSettings = {
229
  init: function () {
230
 
231
+ $(document).on( "click", "#wcf_ca_trigger_web_hook_abandoned_btn",
232
  { 'order_status': 'abandoned' },
233
  ZapierSettings.zapier_trigger_sample);
234
  },
283
  ToolTipHover = {
284
  init: function () {
285
 
286
+ $(".wcf-ca-report-table-row .wcf-ca-icon-row").on('hover',function(){
287
  $(this).find('.wcf-ca-tooltip-text').toggleClass("display_tool_tip");
288
  });
289
  },
290
  }
291
 
292
 
293
+ $(function () {
 
294
  EmailTemplatesAdmin.init();
295
  CartAbandonmentSettings.init();
296
  ZapierSettings.init();
admin/bsf-analytics/assets/css/minified/style-rtl.min.css DELETED
@@ -1 +0,0 @@
1
- [ID*="-optin-notice"]{padding:1px 12px;border-right-color:#007cba}[ID*="-optin-notice"] .notice-container{padding-top:10px;padding-bottom:12px}[ID*="-optin-notice"] .notice-content{margin:0}[ID*="-optin-notice"] .notice-heading{padding:0 0 12px 20px}[ID*="-optin-notice"] .button-primary{margin-left:5px}
 
admin/bsf-analytics/assets/css/minified/style.min.css DELETED
@@ -1 +0,0 @@
1
- [ID*="-optin-notice"]{padding:1px 12px;border-left-color:#007cba}[ID*="-optin-notice"] .notice-container{padding-top:10px;padding-bottom:12px}[ID*="-optin-notice"] .notice-content{margin:0}[ID*="-optin-notice"] .notice-heading{padding:0 20px 12px 0}[ID*="-optin-notice"] .button-primary{margin-right:5px}
 
admin/bsf-analytics/assets/css/unminified/style-rtl.css DELETED
@@ -1,21 +0,0 @@
1
- [ID*="-optin-notice"] {
2
- padding: 1px 12px;
3
- border-right-color: #007cba;
4
- }
5
-
6
- [ID*="-optin-notice"] .notice-container {
7
- padding-top: 10px;
8
- padding-bottom: 12px;
9
- }
10
-
11
- [ID*="-optin-notice"] .notice-content {
12
- margin: 0;
13
- }
14
-
15
- [ID*="-optin-notice"] .notice-heading {
16
- padding: 0 0 12px 20px;
17
- }
18
-
19
- [ID*="-optin-notice"] .button-primary {
20
- margin-left: 5px;
21
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/bsf-analytics/assets/css/unminified/style.css DELETED
@@ -1,21 +0,0 @@
1
- [ID*="-optin-notice"] {
2
- padding: 1px 12px;
3
- border-left-color: #007cba;
4
- }
5
-
6
- [ID*="-optin-notice"] .notice-container {
7
- padding-top: 10px;
8
- padding-bottom: 12px;
9
- }
10
-
11
- [ID*="-optin-notice"] .notice-content {
12
- margin: 0;
13
- }
14
-
15
- [ID*="-optin-notice"] .notice-heading {
16
- padding: 0 20px 12px 0;
17
- }
18
-
19
- [ID*="-optin-notice"] .button-primary {
20
- margin-right: 5px;
21
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/bsf-analytics/class-bsf-analytics-loader.php DELETED
@@ -1,118 +0,0 @@
1
- <?php
2
- /**
3
- * BSF analytics loader file.
4
- *
5
- * @version 1.0.0
6
- *
7
- * @package bsf-analytics
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) {
11
- exit();
12
- }
13
-
14
- /**
15
- * Class BSF_Analytics_Loader.
16
- */
17
- class BSF_Analytics_Loader {
18
-
19
- /**
20
- * Analytics Entities.
21
- *
22
- * @access private
23
- * @var array Entities array.
24
- */
25
- private $entities = array();
26
-
27
- /**
28
- * Analytics Version.
29
- *
30
- * @access private
31
- * @var float analytics version.
32
- */
33
- private $analytics_version = '';
34
-
35
- /**
36
- * Analytics path.
37
- *
38
- * @access private
39
- * @var string path array.
40
- */
41
- private $analytics_path = '';
42
-
43
- /**
44
- * Instance
45
- *
46
- * @access private
47
- * @var object Class object.
48
- */
49
- private static $instance = null;
50
-
51
- /**
52
- * Get instace of class.
53
- *
54
- * @return object
55
- */
56
- public static function get_instance() {
57
- if ( null === self::$instance ) {
58
- self::$instance = new self();
59
- }
60
-
61
- return self::$instance;
62
- }
63
-
64
- /**
65
- * Constructor
66
- */
67
- public function __construct() {
68
- add_action( 'init', array( $this, 'load_analytics' ) );
69
- }
70
-
71
- /**
72
- * Set entity for analytics.
73
- *
74
- * @param string $data Entity attributes data.
75
- * @return void
76
- */
77
- public function set_entity( $data ) {
78
- array_push( $this->entities, $data );
79
- }
80
-
81
- /**
82
- * Load Analytics library.
83
- *
84
- * @return void
85
- */
86
- public function load_analytics() {
87
- $unique_entities = array();
88
-
89
- if ( ! empty( $this->entities ) ) {
90
- foreach ( $this->entities as $entity ) {
91
- foreach ( $entity as $key => $data ) {
92
-
93
- if ( isset( $data['path'] ) ) {
94
- if ( file_exists( $data['path'] . '/version.json' ) ) {
95
- $file_contents = file_get_contents( $data['path'] . '/version.json' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
96
- $analytics_version = json_decode( $file_contents, 1 );
97
- $analytics_version = $analytics_version['bsf-analytics-ver'];
98
-
99
- if ( version_compare( $analytics_version, $this->analytics_version, '>' ) ) {
100
- $this->analytics_version = $analytics_version;
101
- $this->analytics_path = $data['path'];
102
- }
103
- }
104
- }
105
-
106
- if ( ! isset( $unique_entities[ $key ] ) ) {
107
- $unique_entities[ $key ] = $data;
108
- }
109
- }
110
- }
111
-
112
- if ( file_exists( $this->analytics_path ) && ! class_exists( 'BSF_Analytics' ) ) {
113
- require_once $this->analytics_path . '/class-bsf-analytics.php';
114
- new BSF_Analytics( $unique_entities, $this->analytics_path, $this->analytics_version );
115
- }
116
- }
117
- }
118
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/bsf-analytics/class-bsf-analytics-stats.php DELETED
@@ -1,256 +0,0 @@
1
- <?php
2
- /**
3
- * BSF analytics stat class file.
4
- *
5
- * @package bsf-analytics
6
- */
7
-
8
- if ( ! defined( 'ABSPATH' ) ) {
9
- exit; // Exit if accessed directly.
10
- }
11
-
12
- if ( ! class_exists( 'BSF_Analytics_Stats' ) ) {
13
- /**
14
- * BSF analytics stat class.
15
- */
16
- class BSF_Analytics_Stats {
17
-
18
- /**
19
- * Active plugins.
20
- *
21
- * Holds the sites active plugins list.
22
- *
23
- * @var array
24
- */
25
- private $plugins;
26
-
27
- /**
28
- * Instance of BSF_Analytics_Stats.
29
- *
30
- * Holds only the first object of class.
31
- *
32
- * @var object
33
- */
34
- private static $instance = null;
35
-
36
- /**
37
- * Create only once instance of a class.
38
- *
39
- * @return object
40
- * @since 1.0.0
41
- */
42
- public static function instance() {
43
- if ( null === self::$instance ) {
44
- self::$instance = new self();
45
- }
46
-
47
- return self::$instance;
48
- }
49
-
50
- /**
51
- * Get stats.
52
- *
53
- * @return array stats data.
54
- * @since 1.0.0
55
- */
56
- public function get_stats() {
57
- return apply_filters( 'bsf_core_stats', $this->get_default_stats() );
58
- }
59
-
60
- /**
61
- * Retrieve stats for site.
62
- *
63
- * @return array stats data.
64
- * @since 1.0.0
65
- */
66
- private function get_default_stats() {
67
- return array(
68
- 'graupi_version' => defined( 'BSF_UPDATER_VERSION' ) ? BSF_UPDATER_VERSION : false,
69
- 'domain_name' => get_site_url(),
70
- 'php_os' => PHP_OS,
71
- 'server_software' => isset( $_SERVER['SERVER_SOFTWARE'] ) ? filter_var( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ), FILTER_SANITIZE_STRING ) : '',
72
- 'mysql_version' => $this->get_mysql_version(),
73
- 'php_version' => $this->get_php_version(),
74
- 'php_max_input_vars' => ini_get( 'max_input_vars' ), // phpcs:ignore:PHPCompatibility.IniDirectives.NewIniDirectives.max_input_varsFound
75
- 'php_post_max_size' => ini_get( 'post_max_size' ),
76
- 'php_max_execution_time' => ini_get( 'max_execution_time' ),
77
- 'php_memory_limit' => ini_get( 'memory_limit' ),
78
- 'zip_installed' => extension_loaded( 'zip' ),
79
- 'imagick_availabile' => extension_loaded( 'imagick' ),
80
- 'xmlreader_exists' => class_exists( 'XMLReader' ),
81
- 'gd_available' => extension_loaded( 'gd' ),
82
- 'curl_version' => $this->get_curl_version(),
83
- 'curl_ssl_version' => $this->get_curl_ssl_version(),
84
- 'is_writable' => $this->is_content_writable(),
85
-
86
- 'wp_version' => get_bloginfo( 'version' ),
87
- 'user_count' => $this->get_user_count(),
88
- 'site_language' => get_locale(),
89
- 'timezone' => wp_timezone_string(),
90
- 'is_ssl' => is_ssl(),
91
- 'is_multisite' => is_multisite(),
92
- 'network_url' => network_site_url(),
93
- 'external_object_cache' => (bool) wp_using_ext_object_cache(),
94
- 'wp_debug' => WP_DEBUG,
95
- 'wp_debug_display' => WP_DEBUG_DISPLAY,
96
- 'script_debug' => SCRIPT_DEBUG,
97
-
98
- 'active_plugins' => $this->get_active_plugins(),
99
-
100
- 'active_theme' => get_template(),
101
- 'active_stylesheet' => get_stylesheet(),
102
- );
103
- }
104
-
105
- /**
106
- * Get installed PHP version.
107
- *
108
- * @return float PHP version.
109
- * @since 1.0.0
110
- */
111
- private function get_php_version() {
112
- if ( defined( 'PHP_MAJOR_VERSION' ) && defined( 'PHP_MINOR_VERSION' ) && defined( 'PHP_RELEASE_VERSION' ) ) { // phpcs:ignore
113
- return PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION . '.' . PHP_RELEASE_VERSION;
114
- }
115
-
116
- return phpversion();
117
- }
118
-
119
- /**
120
- * User count on site.
121
- *
122
- * @return int User count.
123
- * @since 1.0.0
124
- */
125
- private function get_user_count() {
126
- if ( is_multisite() ) {
127
- $user_count = get_user_count();
128
- } else {
129
- $count = count_users();
130
- $user_count = $count['total_users'];
131
- }
132
-
133
- return $user_count;
134
- }
135
-
136
- /**
137
- * Get active plugin's data.
138
- *
139
- * @return array active plugin's list.
140
- * @since 1.0.0
141
- */
142
- private function get_active_plugins() {
143
- if ( ! $this->plugins ) {
144
- // Ensure get_plugin_data function is loaded.
145
- if ( ! function_exists( 'get_plugin_data' ) ) {
146
- require_once ABSPATH . 'wp-admin/includes/plugin.php';
147
- }
148
-
149
- $plugins = wp_get_active_and_valid_plugins();
150
- $plugins = array_map( 'get_plugin_data', $plugins );
151
- $this->plugins = array_map( array( $this, 'format_plugin' ), $plugins );
152
- }
153
-
154
- return $this->plugins;
155
- }
156
-
157
- /**
158
- * Format plugin data.
159
- *
160
- * @param string $plugin plugin.
161
- * @return array formatted plugin data.
162
- * @since 1.0.0
163
- */
164
- public function format_plugin( $plugin ) {
165
- return array(
166
- 'name' => html_entity_decode( $plugin['Name'], ENT_COMPAT, 'UTF-8' ),
167
- 'url' => $plugin['PluginURI'],
168
- 'version' => $plugin['Version'],
169
- 'slug' => $plugin['TextDomain'],
170
- 'author_name' => html_entity_decode( wp_strip_all_tags( $plugin['Author'] ), ENT_COMPAT, 'UTF-8' ),
171
- 'author_url' => $plugin['AuthorURI'],
172
- );
173
- }
174
-
175
- /**
176
- * Curl SSL version.
177
- *
178
- * @return float SSL version.
179
- * @since 1.0.0
180
- */
181
- private function get_curl_ssl_version() {
182
- $curl = array();
183
- if ( function_exists( 'curl_version' ) ) {
184
- $curl = curl_version(); // phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_version
185
- }
186
-
187
- return isset( $curl['ssl_version'] ) ? $curl['ssl_version'] : false;
188
- }
189
-
190
- /**
191
- * Get cURL version.
192
- *
193
- * @return float cURL version.
194
- * @since 1.0.0
195
- */
196
- private function get_curl_version() {
197
- if ( function_exists( 'curl_version' ) ) {
198
- $curl = curl_version(); // phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_version
199
- }
200
-
201
- return isset( $curl['version'] ) ? $curl['version'] : false;
202
- }
203
-
204
- /**
205
- * Get MySQL version.
206
- *
207
- * @return float MySQL version.
208
- * @since 1.0.0
209
- */
210
- private function get_mysql_version() {
211
- global $wpdb;
212
- return $wpdb->db_version();
213
- }
214
-
215
- /**
216
- * Check if content directory is writable.
217
- *
218
- * @return bool
219
- * @since 1.0.0
220
- */
221
- private function is_content_writable() {
222
- $upload_dir = wp_upload_dir();
223
- return wp_is_writable( $upload_dir['basedir'] );
224
- }
225
- }
226
- }
227
-
228
- /**
229
- * Polyfill for sites using WP version less than 5.3
230
- */
231
- if ( ! function_exists( 'wp_timezone_string' ) ) {
232
- /**
233
- * Get timezone string.
234
- *
235
- * @return string timezone string.
236
- * @since 1.0.0
237
- */
238
- function wp_timezone_string() {
239
- $timezone_string = get_option( 'timezone_string' );
240
-
241
- if ( $timezone_string ) {
242
- return $timezone_string;
243
- }
244
-
245
- $offset = (float) get_option( 'gmt_offset' );
246
- $hours = (int) $offset;
247
- $minutes = ( $offset - $hours );
248
-
249
- $sign = ( $offset < 0 ) ? '-' : '+';
250
- $abs_hour = abs( $hours );
251
- $abs_mins = abs( $minutes * 60 );
252
- $tz_offset = sprintf( '%s%02d:%02d', $sign, $abs_hour, $abs_mins );
253
-
254
- return $tz_offset;
255
- }
256
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/bsf-analytics/class-bsf-analytics.php DELETED
@@ -1,508 +0,0 @@
1
- <?php
2
- /**
3
- * BSF analytics class file.
4
- *
5
- * @version 1.0.0
6
- *
7
- * @package bsf-analytics
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) {
11
- exit; // Exit if accessed directly.
12
- }
13
-
14
- if ( ! class_exists( 'BSF_Analytics' ) ) {
15
-
16
- /**
17
- * BSF analytics
18
- */
19
- class BSF_Analytics {
20
-
21
- /**
22
- * Member Variable
23
- *
24
- * @var array Entities data.
25
- */
26
- private $entities;
27
-
28
- /**
29
- * Member Variable
30
- *
31
- * @var string Usage tracking document URL
32
- */
33
- public $usage_doc_link = 'https://store.brainstormforce.com/usage-tracking/?utm_source=wp_dashboard&utm_medium=general_settings&utm_campaign=usage_tracking';
34
-
35
- /**
36
- * Setup actions, load files.
37
- *
38
- * @param array $args entity data for analytics.
39
- * @param string $analytics_path directory path to analytics library.
40
- * @param float $analytics_version analytics library version.
41
- * @since 1.0.0
42
- */
43
- public function __construct( $args, $analytics_path, $analytics_version ) {
44
-
45
- // Bail when no analytics entities are registered.
46
- if ( empty( $args ) ) {
47
- return;
48
- }
49
-
50
- $this->entities = $args;
51
-
52
- define( 'BSF_ANALYTICS_VERSION', $analytics_version );
53
- define( 'BSF_ANALYTICS_URI', $this->get_analytics_url( $analytics_path ) );
54
-
55
- add_action( 'admin_init', array( $this, 'handle_optin_optout' ) );
56
- add_action( 'admin_notices', array( $this, 'option_notice' ) );
57
- add_action( 'init', array( $this, 'maybe_track_analytics' ), 99 );
58
-
59
- $this->set_actions();
60
-
61
- add_action( 'admin_init', array( $this, 'register_usage_tracking_setting' ) );
62
-
63
- $this->includes();
64
- }
65
-
66
- /**
67
- * Setup actions for admin notice style and analytics cron event.
68
- *
69
- * @since 1.0.4
70
- */
71
- public function set_actions() {
72
-
73
- foreach ( $this->entities as $key => $data ) {
74
- add_action( 'astra_notice_before_markup_' . $key . '-optin-notice', array( $this, 'enqueue_assets' ) );
75
- add_action( 'update_option_' . $key . '_analytics_optin', array( $this, 'update_analytics_option_callback' ), 10, 3 );
76
- add_action( 'add_option_' . $key . '_analytics_optin', array( $this, 'add_analytics_option_callback' ), 10, 2 );
77
- }
78
- }
79
-
80
- /**
81
- * BSF Analytics URL
82
- *
83
- * @param string $analytics_path directory path to analytics library.
84
- * @return String URL of bsf-analytics directory.
85
- * @since 1.0.0
86
- */
87
- public function get_analytics_url( $analytics_path ) {
88
-
89
- $content_dir_path = wp_normalize_path( WP_CONTENT_DIR );
90
-
91
- $analytics_path = wp_normalize_path( $analytics_path );
92
-
93
- return str_replace( $content_dir_path, content_url(), $analytics_path );
94
- }
95
-
96
- /**
97
- * Get API URL for sending analytics.
98
- *
99
- * @return string API URL.
100
- * @since 1.0.0
101
- */
102
- private function get_api_url() {
103
- return defined( 'BSF_API_URL' ) ? BSF_API_URL : 'https://support.brainstormforce.com/';
104
- }
105
-
106
- /**
107
- * Enqueue Scripts.
108
- *
109
- * @since 1.0.0
110
- * @return void
111
- */
112
- public function enqueue_assets() {
113
-
114
- /**
115
- * Load unminified if SCRIPT_DEBUG is true.
116
- *
117
- * Directory and Extensions.
118
- */
119
- $dir_name = ( SCRIPT_DEBUG ) ? 'unminified' : 'minified';
120
- $file_rtl = ( is_rtl() ) ? '-rtl' : '';
121
- $css_ext = ( SCRIPT_DEBUG ) ? '.css' : '.min.css';
122
-
123
- $css_uri = BSF_ANALYTICS_URI . '/assets/css/' . $dir_name . '/style' . $file_rtl . $css_ext;
124
-
125
- wp_enqueue_style( 'bsf-analytics-admin-style', $css_uri, false, BSF_ANALYTICS_VERSION, 'all' );
126
- }
127
-
128
- /**
129
- * Send analytics API call.
130
- *
131
- * @since 1.0.0
132
- */
133
- public function send() {
134
- wp_remote_post(
135
- $this->get_api_url() . 'wp-json/bsf-core/v1/analytics/',
136
- array(
137
- 'body' => BSF_Analytics_Stats::instance()->get_stats(),
138
- 'timeout' => 5,
139
- 'blocking' => false,
140
- )
141
- );
142
- }
143
-
144
- /**
145
- * Check if usage tracking is enabled.
146
- *
147
- * @return bool
148
- * @since 1.0.0
149
- */
150
- public function is_tracking_enabled() {
151
-
152
- foreach ( $this->entities as $key => $data ) {
153
-
154
- $is_enabled = get_site_option( $key . '_analytics_optin' ) === 'yes' ? true : false;
155
- $is_enabled = $this->is_white_label_enabled( $key ) ? false : $is_enabled;
156
-
157
- if ( apply_filters( $key . '_tracking_enabled', $is_enabled ) ) {
158
- return true;
159
- }
160
- }
161
-
162
- return false;
163
- }
164
-
165
- /**
166
- * Check if WHITE label is enabled for BSF products.
167
- *
168
- * @param string $source source of analytics.
169
- * @return bool
170
- * @since 1.0.0
171
- */
172
- public function is_white_label_enabled( $source ) {
173
-
174
- $options = apply_filters( $source . '_white_label_options', array() );
175
- $is_enabled = false;
176
-
177
- if ( is_array( $options ) ) {
178
- foreach ( $options as $option ) {
179
- if ( true === $option ) {
180
- $is_enabled = true;
181
- break;
182
- }
183
- }
184
- }
185
-
186
- return $is_enabled;
187
- }
188
-
189
- /**
190
- * Display admin notice for usage tracking.
191
- *
192
- * @since 1.0.0
193
- */
194
- public function option_notice() {
195
-
196
- if ( ! current_user_can( 'manage_options' ) ) {
197
- return;
198
- }
199
-
200
- foreach ( $this->entities as $key => $data ) {
201
-
202
- $time_to_display = isset( $data['time_to_display'] ) ? $data['time_to_display'] : '+24 hours';
203
- $usage_doc_link = isset( $data['usage_doc_link'] ) ? $data['usage_doc_link'] : $this->usage_doc_link;
204
-
205
- // Don't display the notice if tracking is disabled or White Label is enabled for any of our plugins.
206
- if ( false !== get_site_option( $key . '_analytics_optin', false ) || $this->is_white_label_enabled( $key ) ) {
207
- continue;
208
- }
209
-
210
- // Show tracker consent notice after 24 hours from installed time.
211
- if ( strtotime( $time_to_display, $this->get_analytics_install_time( $key ) ) > time() ) {
212
- continue;
213
- }
214
-
215
- /* translators: %s product name */
216
- $notice_string = __( 'Want to help make <strong>%1s</strong> even more awesome? Allow us to collect non-sensitive diagnostic data and usage information. ', 'woo-cart-abandonment-recovery' );
217
-
218
- if ( is_multisite() ) {
219
- $notice_string .= __( 'This will be applicable for all sites from the network.', 'woo-cart-abandonment-recovery' );
220
- }
221
-
222
- $language_dir = is_rtl() ? 'rtl' : 'ltr';
223
-
224
- Astra_Notices::add_notice(
225
- array(
226
- 'id' => $key . '-optin-notice',
227
- 'type' => '',
228
- 'message' => sprintf(
229
- '<div class="notice-content">
230
- <div class="notice-heading">
231
- %1$s
232
- </div>
233
- <div class="astra-notices-container">
234
- <a href="%2$s" class="astra-notices button-primary">
235
- %3$s
236
- </a>
237
- <a href="%4$s" data-repeat-notice-after="%5$s" class="astra-notices button-secondary">
238
- %6$s
239
- </a>
240
- </div>
241
- </div>',
242
- /* translators: %s usage doc link */
243
- sprintf( $notice_string . '<span dir="%2s"><a href="%3s" target="_blank" rel="noreferrer noopener">%4s</a><span>', esc_html( $data['product_name'] ), $language_dir, esc_url( $usage_doc_link ), __( ' Know More.', 'woo-cart-abandonment-recovery' ) ),
244
- add_query_arg(
245
- array(
246
- $key . '_analytics_optin' => 'yes',
247
- $key . '_analytics_nonce' => wp_create_nonce( $key . '_analytics_optin' ),
248
- 'bsf_analytics_source' => $key,
249
- )
250
- ),
251
- __( 'Yes! Allow it', 'woo-cart-abandonment-recovery' ),
252
- add_query_arg(
253
- array(
254
- $key . '_analytics_optin' => 'no',
255
- $key . '_analytics_nonce' => wp_create_nonce( $key . '_analytics_optin' ),
256
- 'bsf_analytics_source' => $key,
257
- )
258
- ),
259
- MONTH_IN_SECONDS,
260
- __( 'No Thanks', 'woo-cart-abandonment-recovery' )
261
- ),
262
- 'show_if' => true,
263
- 'repeat-notice-after' => false,
264
- 'priority' => 18,
265
- 'display-with-other-notices' => true,
266
- )
267
- );
268
- }
269
- }
270
-
271
- /**
272
- * Process usage tracking opt out.
273
- *
274
- * @since 1.0.0
275
- */
276
- public function handle_optin_optout() {
277
-
278
- if ( ! current_user_can( 'manage_options' ) ) {
279
- return;
280
- }
281
-
282
- $source = isset( $_GET['bsf_analytics_source'] ) ? sanitize_text_field( wp_unslash( $_GET['bsf_analytics_source'] ) ) : '';
283
-
284
- if ( ! isset( $_GET[ $source . '_analytics_nonce' ] ) ) {
285
- return;
286
- }
287
-
288
- if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET[ $source . '_analytics_nonce' ] ) ), $source . '_analytics_optin' ) ) {
289
- return;
290
- }
291
-
292
- $optin_status = isset( $_GET[ $source . '_analytics_optin' ] ) ? sanitize_text_field( wp_unslash( $_GET[ $source . '_analytics_optin' ] ) ) : '';
293
-
294
- if ( 'yes' === $optin_status ) {
295
- $this->optin( $source );
296
- } elseif ( 'no' === $optin_status ) {
297
- $this->optout( $source );
298
- }
299
-
300
- wp_safe_redirect(
301
- remove_query_arg(
302
- array(
303
- $source . '_analytics_optin',
304
- $source . '_analytics_nonce',
305
- 'bsf_analytics_source',
306
- )
307
- )
308
- );
309
- }
310
-
311
- /**
312
- * Opt in to usage tracking.
313
- *
314
- * @param string $source source of analytics.
315
- * @since 1.0.0
316
- */
317
- private function optin( $source ) {
318
- update_site_option( $source . '_analytics_optin', 'yes' );
319
- }
320
-
321
- /**
322
- * Opt out to usage tracking.
323
- *
324
- * @param string $source source of analytics.
325
- * @since 1.0.0
326
- */
327
- private function optout( $source ) {
328
- update_site_option( $source . '_analytics_optin', 'no' );
329
- }
330
-
331
- /**
332
- * Load analytics stat class.
333
- *
334
- * @since 1.0.0
335
- */
336
- private function includes() {
337
- require_once __DIR__ . '/class-bsf-analytics-stats.php';
338
- }
339
-
340
- /**
341
- * Register usage tracking option in General settings page.
342
- *
343
- * @since 1.0.0
344
- */
345
- public function register_usage_tracking_setting() {
346
-
347
- foreach ( $this->entities as $key => $data ) {
348
-
349
- if ( ! apply_filters( $key . '_tracking_enabled', true ) || $this->is_white_label_enabled( $key ) ) {
350
- return;
351
- }
352
-
353
- $usage_doc_link = isset( $data['usage_doc_link'] ) ? $data['usage_doc_link'] : $this->usage_doc_link;
354
- $author = isset( $data['author'] ) ? $data['author'] : 'Brainstorm Force';
355
-
356
- register_setting(
357
- 'general', // Options group.
358
- $key . '_analytics_optin', // Option name/database.
359
- array( 'sanitize_callback' => array( $this, 'sanitize_option' ) ) // sanitize callback function.
360
- );
361
-
362
- add_settings_field(
363
- $key . '-analytics-optin', // Field ID.
364
- __( 'Usage Tracking', 'woo-cart-abandonment-recovery' ), // Field title.
365
- array( $this, 'render_settings_field_html' ), // Field callback function.
366
- 'general',
367
- 'default', // Settings page slug.
368
- array(
369
- 'type' => 'checkbox',
370
- 'title' => $author,
371
- 'name' => $key . '_analytics_optin',
372
- 'label_for' => $key . '-analytics-optin',
373
- 'id' => $key . '-analytics-optin',
374
- 'usage_doc_link' => $usage_doc_link,
375
- )
376
- );
377
- }
378
- }
379
-
380
- /**
381
- * Sanitize Callback Function
382
- *
383
- * @param bool $input Option value.
384
- * @since 1.0.0
385
- */
386
- public function sanitize_option( $input ) {
387
-
388
- if ( ! $input || 'no' === $input ) {
389
- return 'no';
390
- }
391
-
392
- return 'yes';
393
- }
394
-
395
- /**
396
- * Print settings field HTML.
397
- *
398
- * @param array $args arguments to field.
399
- * @since 1.0.0
400
- */
401
- public function render_settings_field_html( $args ) {
402
- ?>
403
- <fieldset>
404
- <label for="<?php echo esc_attr( $args['label_for'] ); ?>">
405
- <input id="<?php echo esc_attr( $args['id'] ); ?>" type="checkbox" value="1" name="<?php echo esc_attr( $args['name'] ); ?>" <?php checked( get_site_option( $args['name'], 'no' ), 'yes' ); ?>>
406
- <?php
407
- /* translators: %s Product title */
408
- echo esc_html( sprintf( __( 'Allow %s products to track non-sensitive usage tracking data.', 'woo-cart-abandonment-recovery' ), $args['title'] ) );// phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralText
409
-
410
- if ( is_multisite() ) {
411
- esc_html_e( ' This will be applicable for all sites from the network.', 'woo-cart-abandonment-recovery' );
412
- }
413
- ?>
414
- </label>
415
- <?php
416
- echo wp_kses_post( sprintf( '<a href="%1s" target="_blank" rel="noreferrer noopener">%2s</a>', esc_url( $args['usage_doc_link'] ), __( 'Learn More.', 'woo-cart-abandonment-recovery' ) ) );
417
- ?>
418
- </fieldset>
419
- <?php
420
- }
421
-
422
- /**
423
- * Set analytics installed time in option.
424
- *
425
- * @param string $source source of analytics.
426
- * @return string $time analytics installed time.
427
- * @since 1.0.0
428
- */
429
- private function get_analytics_install_time( $source ) {
430
-
431
- $time = get_site_option( $source . '_analytics_installed_time' );
432
-
433
- if ( ! $time ) {
434
- $time = time();
435
- update_site_option( $source . '_analytics_installed_time', time() );
436
- }
437
-
438
- return $time;
439
- }
440
-
441
- /**
442
- * Schedule/unschedule cron event on updation of option.
443
- *
444
- * @param string $old_value old value of option.
445
- * @param string $value value of option.
446
- * @param string $option Option name.
447
- * @since 1.0.0
448
- */
449
- public function update_analytics_option_callback( $old_value, $value, $option ) {
450
- if ( is_multisite() ) {
451
- $this->add_option_to_network( $option, $value );
452
- }
453
- }
454
-
455
- /**
456
- * Analytics option add callback.
457
- *
458
- * @param string $option Option name.
459
- * @param string $value value of option.
460
- * @since 1.0.0
461
- */
462
- public function add_analytics_option_callback( $option, $value ) {
463
- if ( is_multisite() ) {
464
- $this->add_option_to_network( $option, $value );
465
- }
466
- }
467
-
468
- /**
469
- * Send analaytics track event if tracking is enabled.
470
- *
471
- * @since 1.0.0
472
- */
473
- public function maybe_track_analytics() {
474
-
475
- if ( ! $this->is_tracking_enabled() ) {
476
- return;
477
- }
478
-
479
- $analytics_track = get_site_transient( 'bsf_analytics_track' );
480
-
481
- // If the last data sent is 2 days old i.e. transient is expired.
482
- if ( ! $analytics_track ) {
483
- $this->send();
484
- set_site_transient( 'bsf_analytics_track', true, 2 * DAY_IN_SECONDS );
485
- }
486
- }
487
-
488
- /**
489
- * Save analytics option to network.
490
- *
491
- * @param string $option name of option.
492
- * @param string $value value of option.
493
- * @since 1.0.0
494
- */
495
- public function add_option_to_network( $option, $value ) {
496
-
497
- // If action coming from general settings page.
498
- if ( isset( $_POST['option_page'] ) && 'general' === $_POST['option_page'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
499
-
500
- if ( get_site_option( $option ) ) {
501
- update_site_option( $option, $value );
502
- } else {
503
- add_site_option( $option, $value );
504
- }
505
- }
506
- }
507
- }
508
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/bsf-analytics/version.json DELETED
@@ -1,4 +0,0 @@
1
- {
2
- "bsf-analytics-ver": "1.1.1"
3
- }
4
-
 
 
 
 
changelog.txt CHANGED
@@ -1,3 +1,7 @@
 
 
 
 
1
  Version 1.2.10 - Tuesday, 16th February 2021
2
  - New: Added the option to delete the plugin data on plugin deletion.
3
  - New: Added the filter before triggering the webhook.
1
+ Version 1.2.11 - Monday, 08th March 2021
2
+ - Improvement: WordPress 5.7 compatibility.
3
+ - Improvement: Removed jQuery3 deprecated function notices.
4
+
5
  Version 1.2.10 - Tuesday, 16th February 2021
6
  - New: Added the option to delete the plugin data on plugin deletion.
7
  - New: Added the filter before triggering the webhook.
classes/class-cartflows-ca-loader.php CHANGED
@@ -82,7 +82,7 @@ if ( ! class_exists( 'CARTFLOWS_CA_Loader' ) ) {
82
  define( 'CARTFLOWS_CA_BASE', plugin_basename( CARTFLOWS_CA_FILE ) );
83
  define( 'CARTFLOWS_CA_DIR', plugin_dir_path( CARTFLOWS_CA_FILE ) );
84
  define( 'CARTFLOWS_CA_URL', plugins_url( '/', CARTFLOWS_CA_FILE ) );
85
- define( 'CARTFLOWS_CA_VER', '1.2.10' );
86
  define( 'CARTFLOWS_CA_SLUG', 'cartflows_ca' );
87
 
88
  define( 'CARTFLOWS_CA_CART_ABANDONMENT_TABLE', 'cartflows_ca_cart_abandonment' );
@@ -218,26 +218,6 @@ if ( ! class_exists( 'CARTFLOWS_CA_Loader' ) ) {
218
 
219
  include_once CARTFLOWS_CA_DIR . 'classes/class-cartflows-ca-settings.php';
220
 
221
- if ( is_admin() ) {
222
- require_once CARTFLOWS_CA_DIR . 'lib/notices/class-astra-notices.php';
223
- }
224
-
225
- if ( ! class_exists( 'BSF_Analytics_Loader' ) ) {
226
- require_once CARTFLOWS_CA_DIR . '/admin/bsf-analytics/class-bsf-analytics-loader.php';
227
- }
228
-
229
- $bsf_analytics = BSF_Analytics_Loader::get_instance();
230
-
231
- $bsf_analytics->set_entity(
232
- array(
233
- 'cf' => array(
234
- 'product_name' => 'Woocommerce Cart Abandonment Recovery',
235
- 'usage_doc_link' => 'https://my.cartflows.com/usage-tracking/',
236
- 'path' => CARTFLOWS_CA_DIR . 'admin/bsf-analytics',
237
- 'author' => 'CartFlows Inc',
238
- ),
239
- )
240
- );
241
  }
242
 
243
  /**
82
  define( 'CARTFLOWS_CA_BASE', plugin_basename( CARTFLOWS_CA_FILE ) );
83
  define( 'CARTFLOWS_CA_DIR', plugin_dir_path( CARTFLOWS_CA_FILE ) );
84
  define( 'CARTFLOWS_CA_URL', plugins_url( '/', CARTFLOWS_CA_FILE ) );
85
+ define( 'CARTFLOWS_CA_VER', '1.2.11' );
86
  define( 'CARTFLOWS_CA_SLUG', 'cartflows_ca' );
87
 
88
  define( 'CARTFLOWS_CA_CART_ABANDONMENT_TABLE', 'cartflows_ca_cart_abandonment' );
218
 
219
  include_once CARTFLOWS_CA_DIR . 'classes/class-cartflows-ca-settings.php';
220
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
221
  }
222
 
223
  /**
languages/woo-cart-abandonment-recovery.pot CHANGED
@@ -2,10 +2,10 @@
2
  # This file is distributed under the same license as the WooCommerce Cart Abandonment Recovery package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: WooCommerce Cart Abandonment Recovery 1.2.10\n"
6
  "Report-Msgid-Bugs-To: "
7
  "https://wordpress.org/support/plugin/woo-cart-abandonment-recovery\n"
8
- "POT-Creation-Date: 2021-02-15 12:16:02+00:00\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=utf-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
@@ -25,48 +25,6 @@ msgstr ""
25
  "X-Textdomain-Support: yes\n"
26
  "X-Generator: grunt-wp-i18n 1.0.3\n"
27
 
28
- #: admin/bsf-analytics/class-bsf-analytics.php:216
29
- #. translators: %s product name
30
- msgid ""
31
- "Want to help make <strong>%1s</strong> even more awesome? Allow us to "
32
- "collect non-sensitive diagnostic data and usage information. "
33
- msgstr ""
34
-
35
- #: admin/bsf-analytics/class-bsf-analytics.php:219
36
- msgid "This will be applicable for all sites from the network."
37
- msgstr ""
38
-
39
- #: admin/bsf-analytics/class-bsf-analytics.php:243
40
- #. translators: %s usage doc link
41
- msgid " Know More."
42
- msgstr ""
43
-
44
- #: admin/bsf-analytics/class-bsf-analytics.php:251
45
- msgid "Yes! Allow it"
46
- msgstr ""
47
-
48
- #: admin/bsf-analytics/class-bsf-analytics.php:260
49
- #: modules/cart-abandonment/class-cartflows-ca-cart-abandonment.php:543
50
- msgid "No Thanks"
51
- msgstr ""
52
-
53
- #: admin/bsf-analytics/class-bsf-analytics.php:364
54
- msgid "Usage Tracking"
55
- msgstr ""
56
-
57
- #: admin/bsf-analytics/class-bsf-analytics.php:408
58
- #. translators: %s Product title
59
- msgid "Allow %s products to track non-sensitive usage tracking data."
60
- msgstr ""
61
-
62
- #: admin/bsf-analytics/class-bsf-analytics.php:411
63
- msgid " This will be applicable for all sites from the network."
64
- msgstr ""
65
-
66
- #: admin/bsf-analytics/class-bsf-analytics.php:416
67
- msgid "Learn More."
68
- msgstr ""
69
-
70
  #: classes/class-cartflows-ca-loader.php:142
71
  #. translators: %s: html tags
72
  msgid ""
@@ -295,10 +253,6 @@ msgstr ""
295
  msgid "Invalid email \"Reply\" address field"
296
  msgstr ""
297
 
298
- #: lib/notices/class-astra-notices.php:120
299
- msgid "WordPress Nonce not validated."
300
- msgstr ""
301
-
302
  #: modules/cart-abandonment/class-cartflows-ca-cart-abandonment-table.php:85
303
  msgid "View"
304
  msgstr ""
@@ -365,6 +319,10 @@ msgid ""
365
  "plugin from test mail."
366
  msgstr ""
367
 
 
 
 
 
368
  #: modules/cart-abandonment/class-cartflows-ca-cart-abandonment.php:544
369
  msgid "You won't receive further emails from us, thank you!"
370
  msgstr ""
2
  # This file is distributed under the same license as the WooCommerce Cart Abandonment Recovery package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: WooCommerce Cart Abandonment Recovery 1.2.11\n"
6
  "Report-Msgid-Bugs-To: "
7
  "https://wordpress.org/support/plugin/woo-cart-abandonment-recovery\n"
8
+ "POT-Creation-Date: 2021-03-05 05:29:49+00:00\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=utf-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
25
  "X-Textdomain-Support: yes\n"
26
  "X-Generator: grunt-wp-i18n 1.0.3\n"
27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  #: classes/class-cartflows-ca-loader.php:142
29
  #. translators: %s: html tags
30
  msgid ""
253
  msgid "Invalid email \"Reply\" address field"
254
  msgstr ""
255
 
 
 
 
 
256
  #: modules/cart-abandonment/class-cartflows-ca-cart-abandonment-table.php:85
257
  msgid "View"
258
  msgstr ""
319
  "plugin from test mail."
320
  msgstr ""
321
 
322
+ #: modules/cart-abandonment/class-cartflows-ca-cart-abandonment.php:543
323
+ msgid "No Thanks"
324
+ msgstr ""
325
+
326
  #: modules/cart-abandonment/class-cartflows-ca-cart-abandonment.php:544
327
  msgid "You won't receive further emails from us, thank you!"
328
  msgstr ""
lib/notices/class-astra-notices.php DELETED
@@ -1,360 +0,0 @@
1
- <?php
2
- /**
3
- * Astra Sites Notices
4
- *
5
- * Closing notice on click on `astra-notice-close` class.
6
- *
7
- * If notice has the data attribute `data-repeat-notice-after="%2$s"` then notice close for that SPECIFIC TIME.
8
- * If notice has NO data attribute `data-repeat-notice-after="%2$s"` then notice close for the CURRENT USER FOREVER.
9
- *
10
- * > Create custom close notice link in the notice markup. E.g.
11
- * `<a href="#" data-repeat-notice-after="<?php echo MONTH_IN_SECONDS; ?>" class="astra-notice-close">`
12
- * It close the notice for 30 days.
13
- *
14
- * @package Astra Sites
15
- * @since 1.4.0
16
- */
17
-
18
- if ( ! defined( 'ABSPATH' ) ) {
19
- exit; // Exit if accessed directly.
20
- }
21
-
22
- if ( ! class_exists( 'Astra_Notices' ) ) :
23
-
24
- /**
25
- * Astra_Notices
26
- *
27
- * @since 1.4.0
28
- */
29
- class Astra_Notices {
30
-
31
- /**
32
- * Notices
33
- *
34
- * @access private
35
- * @var array Notices.
36
- * @since 1.4.0
37
- */
38
- private static $version = '1.1.5';
39
-
40
- /**
41
- * Notices
42
- *
43
- * @access private
44
- * @var array Notices.
45
- * @since 1.4.0
46
- */
47
- private static $notices = array();
48
-
49
- /**
50
- * Instance
51
- *
52
- * @access private
53
- * @var object Class object.
54
- * @since 1.4.0
55
- */
56
- private static $instance;
57
-
58
- /**
59
- * Initiator
60
- *
61
- * @since 1.4.0
62
- * @return object initialized object of class.
63
- */
64
- public static function get_instance() {
65
- if ( ! isset( self::$instance ) ) {
66
- self::$instance = new self();
67
- }
68
- return self::$instance;
69
- }
70
-
71
- /**
72
- * Constructor
73
- *
74
- * @since 1.4.0
75
- */
76
- public function __construct() {
77
- add_action( 'admin_notices', array( $this, 'show_notices' ), 30 );
78
- add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
79
- add_action( 'wp_ajax_astra-notice-dismiss', array( $this, 'dismiss_notice' ) );
80
- add_filter( 'wp_kses_allowed_html', array( $this, 'add_data_attributes' ), 10, 2 );
81
- }
82
-
83
- /**
84
- * Filters and Returns a list of allowed tags and attributes for a given context.
85
- *
86
- * @param Array $allowedposttags Array of allowed tags.
87
- * @param String $context Context type (explicit).
88
- * @since 1.4.0
89
- * @return Array
90
- */
91
- public function add_data_attributes( $allowedposttags, $context ) {
92
- $allowedposttags['a']['data-repeat-notice-after'] = true;
93
-
94
- return $allowedposttags;
95
- }
96
-
97
- /**
98
- * Add Notice.
99
- *
100
- * @since 1.4.0
101
- * @param array $args Notice arguments.
102
- * @return void
103
- */
104
- public static function add_notice( $args = array() ) {
105
- self::$notices[] = $args;
106
- }
107
-
108
- /**
109
- * Dismiss Notice.
110
- *
111
- * @since 1.4.0
112
- * @return void
113
- */
114
- public function dismiss_notice() {
115
- $notice_id = ( isset( $_POST['notice_id'] ) ) ? sanitize_key( $_POST['notice_id'] ) : '';
116
- $repeat_notice_after = ( isset( $_POST['repeat_notice_after'] ) ) ? absint( $_POST['repeat_notice_after'] ) : '';
117
- $nonce = ( isset( $_POST['nonce'] ) ) ? sanitize_key( $_POST['nonce'] ) : '';
118
-
119
- if ( false === wp_verify_nonce( $nonce, 'astra-notices' ) ) {
120
- wp_send_json_error( esc_html_e( 'WordPress Nonce not validated.', 'woo-cart-abandonment-recovery' ) );
121
- }
122
-
123
- // Valid inputs?
124
- if ( ! empty( $notice_id ) ) {
125
-
126
- if ( ! empty( $repeat_notice_after ) ) {
127
- set_transient( $notice_id, true, $repeat_notice_after );
128
- } else {
129
- update_user_meta( get_current_user_id(), $notice_id, 'notice-dismissed' );
130
- }
131
-
132
- wp_send_json_success();
133
- }
134
-
135
- wp_send_json_error();
136
- }
137
-
138
- /**
139
- * Enqueue Scripts.
140
- *
141
- * @since 1.4.0
142
- * @return void
143
- */
144
- public function enqueue_scripts() {
145
- wp_register_script( 'astra-notices', self::_get_uri() . 'notices.js', array( 'jquery' ), self::$version, true );
146
- wp_localize_script(
147
- 'astra-notices',
148
- 'astraNotices',
149
- array(
150
- '_notice_nonce' => wp_create_nonce( 'astra-notices' ),
151
- )
152
- );
153
- }
154
-
155
- /**
156
- * Rating priority sort
157
- *
158
- * @since 1.5.2
159
- * @param array $array1 array one.
160
- * @param array $array2 array two.
161
- * @return array
162
- */
163
- public function sort_notices( $array1, $array2 ) {
164
- if ( ! isset( $array1['priority'] ) ) {
165
- $array1['priority'] = 10;
166
- }
167
- if ( ! isset( $array2['priority'] ) ) {
168
- $array2['priority'] = 10;
169
- }
170
-
171
- return $array1['priority'] - $array2['priority'];
172
- }
173
-
174
- /**
175
- * Notice Types
176
- *
177
- * @since 1.4.0
178
- * @return void
179
- */
180
- public function show_notices() {
181
-
182
- $defaults = array(
183
- 'id' => '', // Optional, Notice ID. If empty it set `astra-notices-id-<$array-index>`.
184
- 'type' => 'info', // Optional, Notice type. Default `info`. Expected [info, warning, notice, error].
185
- 'message' => '', // Optional, Message.
186
- 'show_if' => true, // Optional, Show notice on custom condition. E.g. 'show_if' => if( is_admin() ) ? true, false, .
187
- 'repeat-notice-after' => '', // Optional, Dismiss-able notice time. It'll auto show after given time.
188
- 'display-notice-after' => false, // Optional, Dismiss-able notice time. It'll auto show after given time.
189
- 'class' => '', // Optional, Additional notice wrapper class.
190
- 'priority' => 10, // Priority of the notice.
191
- 'display-with-other-notices' => true, // Should the notice be displayed if other notices are being displayed from Astra_Notices.
192
- 'is_dismissible' => true,
193
- );
194
-
195
- // Count for the notices that are rendered.
196
- $notices_displayed = 0;
197
-
198
- // sort the array with priority.
199
- usort( self::$notices, array( $this, 'sort_notices' ) );
200
-
201
- foreach ( self::$notices as $key => $notice ) {
202
-
203
- $notice = wp_parse_args( $notice, $defaults );
204
-
205
- $notice['id'] = self::get_notice_id( $notice, $key );
206
-
207
- $notice['classes'] = self::get_wrap_classes( $notice );
208
-
209
- // Notices visible after transient expire.
210
- if ( isset( $notice['show_if'] ) && true === $notice['show_if'] ) {
211
-
212
- // don't display the notice if it is not supposed to be displayed with other notices.
213
- if ( 0 !== $notices_displayed && false === $notice['display-with-other-notices'] ) {
214
- continue;
215
- }
216
-
217
- if ( self::is_expired( $notice ) ) {
218
-
219
- self::markup( $notice );
220
- ++$notices_displayed;
221
- }
222
- }
223
- }
224
-
225
- }
226
-
227
- /**
228
- * Markup Notice.
229
- *
230
- * @since 1.4.0
231
- * @param array $notice Notice markup.
232
- * @return void
233
- */
234
- public static function markup( $notice = array() ) {
235
-
236
- wp_enqueue_script( 'astra-notices' );
237
-
238
- do_action( 'astra_notice_before_markup' );
239
-
240
- do_action( "astra_notice_before_markup_{$notice['id']}" );
241
-
242
- ?>
243
- <div id="<?php echo esc_attr( $notice['id'] ); ?>" class="<?php echo esc_attr( $notice['classes'] ); ?>" data-repeat-notice-after="<?php echo esc_attr( $notice['repeat-notice-after'] ); ?>">
244
- <div class="notice-container">
245
- <?php do_action( "astra_notice_inside_markup_{$notice['id']}" ); ?>
246
- <?php echo wp_kses_post( $notice['message'] ); ?>
247
- </div>
248
- </div>
249
- <?php
250
-
251
- do_action( "astra_notice_after_markup_{$notice['id']}" );
252
-
253
- do_action( 'astra_notice_after_markup' );
254
-
255
- }
256
-
257
- /**
258
- * Notice classes.
259
- *
260
- * @since 1.4.0
261
- *
262
- * @param array $notice Notice arguments.
263
- * @return array Notice wrapper classes.
264
- */
265
- private static function get_wrap_classes( $notice ) {
266
- $classes = array( 'astra-notice', 'notice' );
267
-
268
- if ( $notice['is_dismissible'] ) {
269
- $classes[] = 'is-dismissible';
270
- }
271
-
272
- $classes[] = $notice['class'];
273
- if ( isset( $notice['type'] ) && '' !== $notice['type'] ) {
274
- $classes[] = 'notice-' . $notice['type'];
275
- }
276
-
277
- return esc_attr( implode( ' ', $classes ) );
278
- }
279
-
280
- /**
281
- * Get Notice ID.
282
- *
283
- * @since 1.4.0
284
- *
285
- * @param array $notice Notice arguments.
286
- * @param int $key Notice array index.
287
- * @return string Notice id.
288
- */
289
- private static function get_notice_id( $notice, $key ) {
290
- if ( isset( $notice['id'] ) && ! empty( $notice['id'] ) ) {
291
- return $notice['id'];
292
- }
293
-
294
- return 'astra-notices-id-' . $key;
295
- }
296
-
297
- /**
298
- * Is notice expired?
299
- *
300
- * @since 1.4.0
301
- *
302
- * @param array $notice Notice arguments.
303
- * @return boolean
304
- */
305
- private static function is_expired( $notice ) {
306
- $transient_status = get_transient( $notice['id'] );
307
-
308
- if ( false === $transient_status ) {
309
-
310
- if ( isset( $notice['display-notice-after'] ) && false !== $notice['display-notice-after'] ) {
311
-
312
- if ( 'delayed-notice' !== get_user_meta( get_current_user_id(), $notice['id'], true ) &&
313
- 'notice-dismissed' !== get_user_meta( get_current_user_id(), $notice['id'], true ) ) {
314
- set_transient( $notice['id'], 'delayed-notice', $notice['display-notice-after'] );
315
- update_user_meta( get_current_user_id(), $notice['id'], 'delayed-notice' );
316
-
317
- return false;
318
- }
319
- }
320
-
321
- // Check the user meta status if current notice is dismissed or delay completed.
322
- $meta_status = get_user_meta( get_current_user_id(), $notice['id'], true );
323
-
324
- if ( empty( $meta_status ) || 'delayed-notice' === $meta_status ) {
325
- return true;
326
- }
327
- }
328
-
329
- return false;
330
- }
331
-
332
- /**
333
- * Get URI
334
- *
335
- * @return mixed URL.
336
- */
337
- public static function _get_uri() { // phpcs:ignore PSR2.Methods.MethodDeclaration.Underscore
338
- $path = wp_normalize_path( dirname( __FILE__ ) );
339
- $theme_dir = wp_normalize_path( get_template_directory() );
340
- $plugin_dir = wp_normalize_path( WP_PLUGIN_DIR );
341
-
342
- if ( strpos( $path, $theme_dir ) !== false ) {
343
- return trailingslashit( get_template_directory_uri() . str_replace( $theme_dir, '', $path ) );
344
- } elseif ( strpos( $path, $plugin_dir ) !== false ) {
345
- return plugin_dir_url( __FILE__ );
346
- } elseif ( strpos( $path, dirname( plugin_basename( __FILE__ ) ) ) !== false ) {
347
- return plugin_dir_url( __FILE__ );
348
- }
349
-
350
- return; // phpcs:ignore Squiz.PHP.NonExecutableCode.ReturnNotRequired
351
- }
352
-
353
- }
354
-
355
- /**
356
- * Kicking this off by calling 'get_instance()' method
357
- */
358
- Astra_Notices::get_instance();
359
-
360
- endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/notices/notices.js DELETED
@@ -1,95 +0,0 @@
1
- /**
2
- * Customizer controls toggles
3
- *
4
- * @package Astra
5
- */
6
-
7
- ( function( $ ) {
8
-
9
- /**
10
- * Helper class for the main Customizer interface.
11
- *
12
- * @since 1.0.0
13
- * @class ASTCustomizer
14
- */
15
- AstraNotices = {
16
-
17
- /**
18
- * Initializes our custom logic for the Customizer.
19
- *
20
- * @since 1.0.0
21
- * @method init
22
- */
23
- init: function()
24
- {
25
- this._bind();
26
- },
27
-
28
- /**
29
- * Binds events for the Astra Portfolio.
30
- *
31
- * @since 1.0.0
32
- * @access private
33
- * @method _bind
34
- */
35
- _bind: function()
36
- {
37
- $( document ).on('click', '.astra-notice-close', AstraNotices._dismissNoticeNew );
38
- $( document ).on('click', '.astra-notice .notice-dismiss', AstraNotices._dismissNotice );
39
- },
40
-
41
- _dismissNotice: function( event ) {
42
- event.preventDefault();
43
-
44
- var repeat_notice_after = $( this ).parents('.astra-notice').data( 'repeat-notice-after' ) || '';
45
- var notice_id = $( this ).parents('.astra-notice').attr( 'id' ) || '';
46
-
47
- AstraNotices._ajax( notice_id, repeat_notice_after );
48
- },
49
-
50
- _dismissNoticeNew: function( event ) {
51
- event.preventDefault();
52
-
53
- var repeat_notice_after = $( this ).attr( 'data-repeat-notice-after' ) || '';
54
- var notice_id = $( this ).parents('.astra-notice').attr( 'id' ) || '';
55
-
56
- var $el = $( this ).parents('.astra-notice');
57
- $el.fadeTo( 100, 0, function() {
58
- $el.slideUp( 100, function() {
59
- $el.remove();
60
- });
61
- });
62
-
63
- AstraNotices._ajax( notice_id, repeat_notice_after );
64
-
65
- var link = $( this ).attr( 'href' ) || '';
66
- var target = $( this ).attr( 'target' ) || '';
67
- if( '' !== link && '_blank' === target ) {
68
- window.open(link , '_blank');
69
- }
70
- },
71
-
72
- _ajax: function( notice_id, repeat_notice_after ) {
73
-
74
- if( '' === notice_id ) {
75
- return;
76
- }
77
-
78
- $.ajax({
79
- url: ajaxurl,
80
- type: 'POST',
81
- data: {
82
- action : 'astra-notice-dismiss',
83
- nonce : astraNotices._notice_nonce,
84
- notice_id : notice_id,
85
- repeat_notice_after : parseInt( repeat_notice_after ),
86
- },
87
- });
88
-
89
- }
90
- };
91
-
92
- $( function() {
93
- AstraNotices.init();
94
- } );
95
- } )( jQuery );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
modules/cart-abandonment/assets/js/cart-abandonment-tracking.js CHANGED
@@ -15,7 +15,7 @@
15
  this._getCheckoutData
16
  );
17
 
18
- $("#wcf_ca_gdpr_no_thanks").click( function () {
19
  wcf_cart_abandonment._set_cookie();
20
  } );
21
 
@@ -23,7 +23,7 @@
23
  wcf_cart_abandonment._getCheckoutData();
24
  });
25
 
26
- $(document).on('ready', function(e) {
27
  setTimeout(function() {
28
  wcf_cart_abandonment._getCheckoutData();
29
  }, 800);
15
  this._getCheckoutData
16
  );
17
 
18
+ $("#wcf_ca_gdpr_no_thanks").on( 'click', function () {
19
  wcf_cart_abandonment._set_cookie();
20
  } );
21
 
23
  wcf_cart_abandonment._getCheckoutData();
24
  });
25
 
26
+ $( function(e) {
27
  setTimeout(function() {
28
  wcf_cart_abandonment._getCheckoutData();
29
  }, 800);
readme.txt CHANGED
@@ -1,10 +1,9 @@
1
  === WooCommerce Cart Abandonment Recovery ===
2
- Contributors: brainstormforce, wpcrafter
3
- Donate link: https://www.paypal.me/BrainstormForce
4
  Tags: woocommerce, cart abandonment, cart recovery
5
- Requires at least: 4.4
6
- Tested up to: 5.6
7
- Stable tag: 1.2.10
8
  Requires PHP: 5.6
9
  License: GPLv2 or later
10
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
@@ -129,6 +128,10 @@ Here are few thoughts behind making it available for free:
129
 
130
  == Changelog ==
131
 
 
 
 
 
132
  = Version 1.2.10 - Tuesday, 16th February 2021 =
133
  * New: Added the option to delete the plugin data on plugin deletion.
134
  * New: Added the filter before triggering the webhook.
1
  === WooCommerce Cart Abandonment Recovery ===
2
+ Contributors: sujaypawar, wpcrafter
 
3
  Tags: woocommerce, cart abandonment, cart recovery
4
+ Requires at least: 5.4
5
+ Tested up to: 5.7
6
+ Stable tag: 1.2.11
7
  Requires PHP: 5.6
8
  License: GPLv2 or later
9
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
128
 
129
  == Changelog ==
130
 
131
+ = Version 1.2.11 - Monday, 08th March 2021 =
132
+ * Improvement: WordPress 5.7 compatibility.
133
+ * Improvement: Removed jQuery3 deprecated function notices.
134
+
135
  = Version 1.2.10 - Tuesday, 16th February 2021 =
136
  * New: Added the option to delete the plugin data on plugin deletion.
137
  * New: Added the filter before triggering the webhook.
woo-cart-abandonment-recovery.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: WooCommerce Cart Abandonment Recovery
4
  * Plugin URI: https://cartflows.com/
5
  * Description: Recover your lost revenue. Capture email address of users on the checkout page and send follow up emails if they don't complete the purchase.
6
- * Version: 1.2.10
7
  * Author: CartFlows Inc
8
  * Author URI: https://cartflows.com/
9
  * Text Domain: woo-cart-abandonment-recovery
3
  * Plugin Name: WooCommerce Cart Abandonment Recovery
4
  * Plugin URI: https://cartflows.com/
5
  * Description: Recover your lost revenue. Capture email address of users on the checkout page and send follow up emails if they don't complete the purchase.
6
+ * Version: 1.2.11
7
  * Author: CartFlows Inc
8
  * Author URI: https://cartflows.com/
9
  * Text Domain: woo-cart-abandonment-recovery