CTX Feed – WooCommerce Product Feed Manager Plugin - Version 3.2.2

Version Description

(2019-12-15) = * Product query type settings added for compatibility. * Request sanitization. * Necessary SQL escaped.

Download this release

Release Info

Developer wahid0003
Plugin Icon 128x128 CTX Feed – WooCommerce Product Feed Manager Plugin
Version 3.2.2
Comparing to
See all releases

Code changes from version 3.2.1 to 3.2.2

README.txt CHANGED
@@ -5,7 +5,7 @@ Tags:woocommerce,google product feed,facebook product feed,woocommerce product f
5
  Requires at least: 3.6
6
  Tested Up To: 5.4-alpha-46743
7
  Requires PHP: 5.6
8
- Stable tag: 3.2.1
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -305,6 +305,11 @@ Using pro version:
305
 
306
  == Changelog ==
307
 
 
 
 
 
 
308
  = 3.2.1 (2019-12-12) =
309
  * XML element space replace with underscore issue fixed
310
  * Fix: Undefined index.
5
  Requires at least: 3.6
6
  Tested Up To: 5.4-alpha-46743
7
  Requires PHP: 5.6
8
+ Stable tag: 3.2.2
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
305
 
306
  == Changelog ==
307
 
308
+ = 3.2.2 (2019-12-15) =
309
+ * Product query type settings added for compatibility.
310
+ * Request sanitization.
311
+ * Necessary SQL escaped.
312
+
313
  = 3.2.1 (2019-12-12) =
314
  * XML element space replace with underscore issue fixed
315
  * Fix: Undefined index.
admin/class-woo-feed-manage-list.php CHANGED
@@ -155,8 +155,7 @@ class Woo_Feed_Manage_list extends Woo_Feed_List_Table
155
  public static function get_feeds($search = "")
156
  {
157
  global $wpdb;
158
- $var = "wf_feed_";
159
- $query = $wpdb->prepare("SELECT * FROM $wpdb->options WHERE option_name LIKE %s ORDER BY option_id DESC;", $var . "%");
160
  $result = $wpdb->get_results($query, 'ARRAY_A');
161
 
162
  return $result;
@@ -186,7 +185,7 @@ class Woo_Feed_Manage_list extends Woo_Feed_List_Table
186
  public static function delete_feed_file($id)
187
  {
188
  global $wpdb;
189
- $mylink = $wpdb->get_row("SELECT * FROM {$wpdb->prefix}options WHERE option_id = $id");
190
  $option_name = $mylink->option_name;
191
  $feedInfo = unserialize(get_option($option_name));
192
 
@@ -205,7 +204,7 @@ class Woo_Feed_Manage_list extends Woo_Feed_List_Table
205
  public static function record_count()
206
  {
207
  global $wpdb;
208
- $sql = "SELECT * FROM {$wpdb->prefix}options WHERE option_name like 'wf_feed_%'";
209
  return $wpdb->get_var($sql);
210
  }
211
 
@@ -450,7 +449,7 @@ class Woo_Feed_Manage_list extends Woo_Feed_List_Table
450
  * be able to use your precisely-queried data immediately.
451
  */
452
  if (isset($_POST['s'])) {
453
- $data = $this->get_feeds($_POST['s']);
454
  } else {
455
  $data = $this->get_feeds();
456
  }
@@ -466,8 +465,8 @@ class Woo_Feed_Manage_list extends Woo_Feed_List_Table
466
  */
467
  function usort_reorder($a, $b)
468
  {
469
- $orderby = (!empty($_REQUEST['orderby'])) ? $_REQUEST['orderby'] : 'option_name'; //If no sort, default to title
470
- $order = (!empty($_REQUEST['order'])) ? $_REQUEST['order'] : 'asc'; //If no order, default to asc
471
  $result = strcmp($a[$orderby], $b[$orderby]); //Determine sort order
472
  return ($order === 'asc') ? $result : -$result; //Send final sort direction to usort
473
  }
155
  public static function get_feeds($search = "")
156
  {
157
  global $wpdb;
158
+ $query = $wpdb->prepare("SELECT * FROM $wpdb->options WHERE option_name LIKE %s ORDER BY option_id DESC;", "wf_feed_%");
 
159
  $result = $wpdb->get_results($query, 'ARRAY_A');
160
 
161
  return $result;
185
  public static function delete_feed_file($id)
186
  {
187
  global $wpdb;
188
+ $mylink = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->options WHERE option_id = %d", $id ) );
189
  $option_name = $mylink->option_name;
190
  $feedInfo = unserialize(get_option($option_name));
191
 
204
  public static function record_count()
205
  {
206
  global $wpdb;
207
+ $sql = "SELECT * FROM $wpdb->options WHERE option_name like 'wf_feed_%'";
208
  return $wpdb->get_var($sql);
209
  }
210
 
449
  * be able to use your precisely-queried data immediately.
450
  */
451
  if (isset($_POST['s'])) {
452
+ $data = $this->get_feeds( sanitize_text_field( $_POST['s'] ) );
453
  } else {
454
  $data = $this->get_feeds();
455
  }
465
  */
466
  function usort_reorder($a, $b)
467
  {
468
+ $orderby = (!empty($_REQUEST['orderby'])) ? sanitize_text_field( $_REQUEST['orderby'] ) : 'option_name'; //If no sort, default to title
469
+ $order = (!empty($_REQUEST['order'])) ? sanitize_text_field( $_REQUEST['order'] ) : 'asc'; //If no order, default to asc
470
  $result = strcmp($a[$orderby], $b[$orderby]); //Determine sort order
471
  return ($order === 'asc') ? $result : -$result; //Send final sort direction to usort
472
  }
admin/css/woo-feed-admin.css CHANGED
@@ -622,6 +622,9 @@ input[class=woo_feed_status_input]:checked + label:before{
622
  border-left-color: rgba(255,255,255,.8)
623
  }
624
 
 
 
 
625
  /** Admin Page Wrapper **/
626
  .wapk-admin, .wapk-admin * {
627
  -webkit-box-sizing: border-box;
622
  border-left-color: rgba(255,255,255,.8)
623
  }
624
 
625
+ ul.tracker_collection_list { list-style: initial; padding: initial; margin: -10px 0 0 30px; font-size: 11px !important; }
626
+ ul.tracker_collection_list li { margin: 0; }
627
+
628
  /** Admin Page Wrapper **/
629
  .wapk-admin, .wapk-admin * {
630
  -webkit-box-sizing: border-box;
admin/js/woo-feed-admin.js CHANGED
@@ -56,7 +56,10 @@
56
  event.preventDefault();
57
  $(this).closest('.postbox').toggleClass('closed');
58
  } );
59
-
 
 
 
60
  if( ! ClipboardJS.isSupported() || /iPhone|iPad/i.test(navigator.userAgent) ) {
61
  $copyBtn.find('img').hide(0);
62
  } else {
56
  event.preventDefault();
57
  $(this).closest('.postbox').toggleClass('closed');
58
  } );
59
+ $('[data-toggle_slide]').on('click', function(e) {
60
+ e.preventDefault();
61
+ $($(this).data('toggle_slide')).slideToggle('fast');
62
+ });
63
  if( ! ClipboardJS.isSupported() || /iPhone|iPad/i.test(navigator.userAgent) ) {
64
  $copyBtn.find('img').hide(0);
65
  } else {
admin/partials/woo-feed-config.php CHANGED
@@ -4,42 +4,112 @@
4
  *
5
  * @link https://webappick.com/
6
  * @since 1.0.0
 
7
  *
8
  * @package Woo_Feed
9
  * @subpackage Woo_Feed/admin/partial
10
  * @author Ohidul Islam <wahid@webappick.com>
11
  */
 
 
 
 
 
 
 
 
12
  ?>
13
  <div class="wrap">
14
- <h2><?php _e('Settings', 'woo-feed'); ?></h2>
15
- <?php echo WPFFWMessage()->infoMessage1(); ?>
16
- <form action="" method="post">
17
- <table class="widefat fixed" >
18
- <thead>
19
- <tr>
20
- <th colspan="2"><b><?php _e('Common Settings', 'woo-feed'); ?></b></th>
21
- </tr>
22
- </thead>
23
- <tbody>
24
- <tr>
25
- <td>Product per batch</td>
26
- <td>
27
- <input type="text" name="limit" value="<?php echo (get_option('woo_feed_per_batch')?get_option('woo_feed_per_batch'):"200"); ?>">
28
- <br><span><i>Don't change the value if you are not sure about this. Plugin may fail to make feed. </i></span>
29
- </td>
30
- </tr>
31
- <tr>
32
- <td>Enable Error Debugging?</td>
33
- <td>
34
- <input type="checkbox" name="enable_error_debugging" value="on" <?php
35
- echo (get_option('woo_feed_enable_error_debugging') == 'on' ? "checked" :""); ?> >
36
- </td>
37
- </tr>
38
- <tr>
39
- <td></td>
40
- <td ><input type="submit" class="button button-primary" name="wa_woo_feed_config" value="Save"></td>
41
- </tr>
42
- </tbody>
43
- </table>
44
- </form>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  </div>
 
4
  *
5
  * @link https://webappick.com/
6
  * @since 1.0.0
7
+ * @version 1.0.1
8
  *
9
  * @package Woo_Feed
10
  * @subpackage Woo_Feed/admin/partial
11
  * @author Ohidul Islam <wahid@webappick.com>
12
  */
13
+ $batch_limit = (int) get_option( 'woo_feed_per_batch', 200 );
14
+ $queryType = get_option('woo_feed_product_query_type' );
15
+ if( ! $queryType || ! in_array( $queryType, [ 'wc', 'wp', 'both' ] ) ) {
16
+ $queryType = 'wc';
17
+ }
18
+ if ( ! $batch_limit || $batch_limit <= 0 ) {
19
+ $batch_limit = 200;
20
+ }
21
  ?>
22
  <div class="wrap">
23
+ <h2><?php _e( 'Settings', 'woo-feed' ); ?></h2>
24
+ <?php echo WPFFWMessage()->infoMessage1(); ?>
25
+ <form action="" method="post" autocomplete="off">
26
+ <?php wp_nonce_field(); ?>
27
+ <table class="widefat fixed" role="presentation">
28
+ <thead>
29
+ <tr>
30
+ <th colspan="2"><b><?php _e( 'Common Settings', 'woo-feed' ); ?></b></th>
31
+ </tr>
32
+ </thead>
33
+ <tbody>
34
+ <?php do_action( 'woo_feed_before_settings_page_fields' ); ?>
35
+ <tr>
36
+ <th scope="row"><label for="batch_limit"><?php _e( 'Product per batch', 'woo-feed' ); ?></label></th>
37
+ <td>
38
+ <input class="regular-text" type="number" min="1" name="batch_limit" id="batch_limit" value="<?php echo esc_attr( $batch_limit ); ?>">
39
+ <p class="description"><?php _e( 'Don\'t change the value if you are not sure about this. Plugin may fail to make feed.', 'woo-feed' ); ?></p>
40
+ </td>
41
+ </tr>
42
+ <tr>
43
+ <th scope="row"><label for="woo_feed_product_query_type"><?php _e( 'Product Query Type', 'woo-feed'); ?></label></th>
44
+ <td>
45
+ <select name="woo_feed_product_query_type" id="woo_feed_product_query_type">
46
+ <option value="wc" <?php selected( $queryType, 'wc' ); ?> ><?php esc_html_e( 'WC_Product_Query', 'woo-feed' ); ?></option>
47
+ <option value="wp" <?php selected( $queryType, 'wp' ); ?> ><?php esc_html_e( 'WP_Query', 'woo-feed' ); ?></option>
48
+ <option value="both" <?php selected( $queryType, 'both' ); ?>><?php esc_html_e( 'Both', 'woo-feed' ); ?></option>
49
+ </select>
50
+ <p class="description"><?php _e( 'Don\'t change the value if you are not sure about this. Plugin may fail to make feed.', 'woo-feed' ); ?></p>
51
+ </td>
52
+ </tr>
53
+ <?php
54
+ /*
55
+ <tr>
56
+ <th scope="row"><label for="enable_error_debugging"><?php _e( 'Debug Mode', 'woo-feed' ); ?></label>
57
+ </th>
58
+ <td>
59
+ <label for="enable_error_debugging">
60
+ <input type="checkbox" name="enable_error_debugging" id="enable_error_debugging" value="on" <?php checked( woo_feed_is_debugging_enabled(), true ); ?> >
61
+ <?php _e( 'Enable Logging', 'woo-feed' ); ?>
62
+ </label>
63
+ <p class="description"
64
+ style="font-size: smaller;color: #ea3d3d;font-weight: bold;"><?php _e( 'Enabling Logging will decrease performance of feed generation.', 'woo-feed' ); ?></p>
65
+ </td>
66
+ </tr>
67
+ <tr>
68
+ <th scope="row"><label for="clear_all_logs"><?php _e( 'Clear Logs', 'woo-feed' ); ?></label></th>
69
+ <td>
70
+ <label for="clear_all_logs">
71
+ <input type="checkbox" name="clear_all_logs" id="clear_all_logs" value="on">
72
+ <?php _e( 'Clear All Log Data', 'woo-feed' ); ?>
73
+ </label>
74
+ <p class="description"
75
+ style="font-size: smaller;color: #ea3d3d;font-weight: bold;"><?php _e( 'This will clear all log files generated by this plugin.', 'woo-feed' ); ?></p>
76
+ </td>
77
+ </tr>
78
+ */
79
+ ?>
80
+ <tr>
81
+ <td><label for="opt_in"><?php _e( 'Send Debug Info', 'woo-feed' ); ?></label></td>
82
+ <td>
83
+ <label for="opt_in">
84
+ <input type="checkbox" name="opt_in" id="opt_in"
85
+ value="on" <?php checked( WooFeedTracker::getInstance()->is_tracking_allowed(),
86
+ true ); ?>>
87
+ <?php _e( 'Allow WooFeed To Collect Debug Info.', 'woo-feed' ); ?>
88
+ </label>
89
+ <p class="description"><?php
90
+ _e( 'To opt out, leave this box unchecked. Your Feed Data remains un-tracked, and no data will be collected. No sensitive data is tracked.',
91
+ 'woo-feed' );
92
+ ?> <a href="#"
93
+ data-toggle_slide=".tracker_collection_list"><?php esc_html_e( 'See What We Collect',
94
+ 'webappick' ); ?></a>
95
+ </p>
96
+ <ul class="tracker_collection_list" style="display: none;">
97
+ <li><?php echo implode( '</li><li>',
98
+ WooFeedTracker::getInstance()->get_data_collection_description() ); ?></li>
99
+ </ul>
100
+ </td>
101
+ </tr>
102
+ <?php do_action( 'woo_feed_after_settings_page_fields' ); ?>
103
+ <tr>
104
+ <td colspan="2">
105
+ <p class="submit" style="text-align: center">
106
+ <input type="submit" class="button button-primary" name="wa_woo_feed_config"
107
+ value="<?php esc_attr_e( 'Save Changes', 'woo-feed' ); ?>">
108
+ </p>
109
+ </td>
110
+ </tr>
111
+ </tbody>
112
+ </table>
113
+ </form>
114
  </div>
115
+
admin/partials/woo-feed-manage-list.php CHANGED
@@ -98,7 +98,7 @@ if (woo_feed_wc_version_check(3.2)) {
98
  </table>
99
  <form id="contact-filter" method="post">
100
  <!-- For plugins, we also need to ensure that the form posts back to our current page -->
101
- <input type="hidden" name="page" value="<?php echo $_REQUEST['page'] ?>"/>
102
  <?php //$myListTable->search_box('search', 'search_id'); ?>
103
  <!-- Now we can render the completed list table -->
104
  <?php $myListTable->display() ?>
98
  </table>
99
  <form id="contact-filter" method="post">
100
  <!-- For plugins, we also need to ensure that the form posts back to our current page -->
101
+ <input type="hidden" name="page" value="<?php echo esc_attr( $_REQUEST['page'] ); ?>"/>
102
  <?php //$myListTable->search_box('search', 'search_id'); ?>
103
  <!-- Now we can render the completed list table -->
104
  <?php $myListTable->display() ?>
admin/partials/woo-feed-search-category.php CHANGED
@@ -7,8 +7,8 @@
7
  * @author Ohidul Islam <wahid@webappick.com>
8
  */
9
  if (isset($_POST['q'])) {
10
- $searchfor = $_POST['q'];
11
- $provider = $_POST['provider'];
12
  if ($provider != 'custom') {
13
  $file = "$provider/categories.txt";
14
  $matches = array();
7
  * @author Ohidul Islam <wahid@webappick.com>
8
  */
9
  if (isset($_POST['q'])) {
10
+ $searchfor = sanitize_text_field( $_POST['q'] );
11
+ $provider = sanitize_text_field( $_POST['provider'] );
12
  if ($provider != 'custom') {
13
  $file = "$provider/categories.txt";
14
  $matches = array();
includes/classes/class-woo-feed-auto-update.php CHANGED
@@ -33,8 +33,7 @@ class WOO_FEED_AUTO_UPDATE{
33
  public function get_feed_names()
34
  {
35
  global $wpdb;
36
- $var = "wf_feed_";
37
- $query = $wpdb->prepare("SELECT * FROM $wpdb->options WHERE option_name LIKE %s;", $var . "%");
38
  $result = $wpdb->get_results($query, 'ARRAY_A');
39
  $feeds=array();
40
  $i=1;
33
  public function get_feed_names()
34
  {
35
  global $wpdb;
36
+ $query = $wpdb->prepare("SELECT * FROM $wpdb->options WHERE option_name LIKE %s;", "wf_feed_%");
 
37
  $result = $wpdb->get_results($query, 'ARRAY_A');
38
  $feeds=array();
39
  $i=1;
includes/classes/class-woo-feed-list-table.php CHANGED
@@ -556,7 +556,7 @@ class Woo_Feed_List_Table {
556
  if ( ! isset( $_GET['post_status'] ) || 'trash' !== $_GET['post_status'] ) {
557
  $extra_checks .= " AND post_status != 'trash'";
558
  } elseif ( isset( $_GET['post_status'] ) ) {
559
- $extra_checks = $wpdb->prepare( ' AND post_status = %s', $_GET['post_status'] );
560
  }
561
 
562
  $months = $wpdb->get_results( $wpdb->prepare( "
@@ -1053,7 +1053,7 @@ class Woo_Feed_List_Table {
1053
  $current_url = remove_query_arg( 'paged', $current_url );
1054
 
1055
  if ( isset( $_GET['orderby'] ) ) {
1056
- $current_orderby = $_GET['orderby'];
1057
  } else {
1058
  $current_orderby = '';
1059
  }
556
  if ( ! isset( $_GET['post_status'] ) || 'trash' !== $_GET['post_status'] ) {
557
  $extra_checks .= " AND post_status != 'trash'";
558
  } elseif ( isset( $_GET['post_status'] ) ) {
559
+ $extra_checks = $wpdb->prepare( ' AND post_status = %s', sanitize_text_field( $_GET['post_status'] ) );
560
  }
561
 
562
  $months = $wpdb->get_results( $wpdb->prepare( "
1053
  $current_url = remove_query_arg( 'paged', $current_url );
1054
 
1055
  if ( isset( $_GET['orderby'] ) ) {
1056
+ $current_orderby = sanitize_text_field( $_GET['orderby'] );
1057
  } else {
1058
  $current_orderby = '';
1059
  }
includes/classes/class-woo-feed-products-v3.php CHANGED
@@ -55,6 +55,10 @@ class Woo_Feed_Products_v3 {
55
 
56
  public function __construct( $config ) {
57
  $this->config = $config;
 
 
 
 
58
  }
59
 
60
  /**
@@ -64,36 +68,15 @@ class Woo_Feed_Products_v3 {
64
  */
65
  public function get_wc_query_products() {
66
 
67
- $this->queryType = 'wc';
68
-
69
- # Set Vendors && Categories
70
- $this->vendors = isset( $this->config['vendors'] ) ? $this->config['vendors'] : "";
71
- $this->categories = isset( $this->config['categories'] ) ? $this->config['categories'] : "";
72
-
73
- # Set Limit & Offset
74
- $limit = ( isset( $this->config['Limit'] ) && ! empty( $this->config['Limit'] ) ) ? absint( esc_html( $this->config['Limit'] ) ) : - 1;
75
- $offset = ( isset( $this->config['Offset'] ) && ! empty( $this->config['Offset'] ) ) ? absint( esc_html( $this->config['Offset'] ) ) : 0;
76
-
77
  # Query Arguments
78
  $arg = array(
79
- 'limit' => $limit,
80
- 'offset' => $offset,
81
  'status' => 'publish',
82
  'orderby' => 'date',
83
  'order' => 'DESC',
84
  'return' => 'ids',
85
  );
86
 
87
- # Remove Out Of Stock Products
88
- if ( isset( $this->config['is_outOfStock'] ) && $this->config['is_outOfStock'] == "y" ) {
89
- $arg['stock_status'] = "instock";
90
- }
91
-
92
-
93
- # Get Products for Specific Categories
94
- if ( is_array( $this->categories ) && ! empty( $this->categories[0] ) ) {
95
- $arg['category'] = $this->categories;
96
- }
97
 
98
  $types = array(
99
  'simple',
@@ -139,36 +122,15 @@ class Woo_Feed_Products_v3 {
139
  * @return array|object
140
  */
141
  public function query_products() {
142
- return $this->get_wp_query_products();
143
- }
144
-
145
- /**
146
- * Organize Feed Attribute config
147
- * @return array|bool
148
- */
149
- public function get_attribute_config() {
150
- if ( empty( $this->config ) ) {
151
- return false;
152
- }
153
-
154
- $attributeConfig = array();
155
- $merchantAttributes = $this->config['mattributes'];
156
- if ( ! empty( $merchantAttributes ) ) {
157
- $i = 0;
158
- foreach ( $merchantAttributes as $key => $value ) {
159
- $attributeConfig[ $i ]['mattributes'] = $value;
160
- $attributeConfig[ $i ]['prefix'] = $this->config['prefix'][ $key ];
161
- $attributeConfig[ $i ]['type'] = $this->config['type'][ $key ];
162
- $attributeConfig[ $i ]['attributes'] = $this->config['attributes'][ $key ];
163
- $attributeConfig[ $i ]['default'] = $this->config['default'][ $key ];
164
- $attributeConfig[ $i ]['suffix'] = $this->config['suffix'][ $key ];
165
- $attributeConfig[ $i ]['output_type'] = $this->config['output_type'][ $key ];
166
- $attributeConfig[ $i ]['limit'] = $this->config['limit'][ $key ];
167
- $i ++;
168
- }
169
- }
170
-
171
- return $attributeConfig;
172
  }
173
 
174
  /**
@@ -185,11 +147,6 @@ class Woo_Feed_Products_v3 {
185
  if ( empty( $ids ) ) {
186
  return false;
187
  }
188
-
189
- $attributeConfig = $this->get_attribute_config();
190
- if (empty($attributeConfig)) {
191
- return false;
192
- }
193
 
194
  foreach ( $ids as $key => $pid ) {
195
 
@@ -469,15 +426,25 @@ class Woo_Feed_Products_v3 {
469
 
470
  $output = $prefix . $output . $suffix;
471
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
472
 
473
  if ($value == "shipping_country") {
474
- if ($s == 0) {
475
- $shipping .= "<g:shipping>";
476
- $s = 1;
477
- } else {
478
- $shipping .= "</g:shipping>" . "\n";
479
- $shipping .= "<g:shipping>";
480
- }
481
  $shipping .= "<g:country>" . $output . "</g:country>" . "\n";
482
  } else if ($value == "shipping_region") {
483
  $shipping .= "<g:region>" . $output . "</g:region>" . "\n";
55
 
56
  public function __construct( $config ) {
57
  $this->config = $config;
58
+ $this->queryType=get_option('woo_feed_product_query_type');
59
+ if(empty($this->queryType)){
60
+ $this->queryType='wc';
61
+ }
62
  }
63
 
64
  /**
68
  */
69
  public function get_wc_query_products() {
70
 
 
 
 
 
 
 
 
 
 
 
71
  # Query Arguments
72
  $arg = array(
73
+ 'limit' => 2e3,
 
74
  'status' => 'publish',
75
  'orderby' => 'date',
76
  'order' => 'DESC',
77
  'return' => 'ids',
78
  );
79
 
 
 
 
 
 
 
 
 
 
 
80
 
81
  $types = array(
82
  'simple',
122
  * @return array|object
123
  */
124
  public function query_products() {
125
+ if($this->queryType=='wc'){
126
+ return $this->get_wc_query_products();
127
+ }elseif ($this->queryType=='wp'){
128
+ return $this->get_wp_query_products();
129
+ }elseif ($this->queryType=='both'){
130
+ $wc=$this->get_wc_query_products();
131
+ $wp=$this->get_wp_query_products();
132
+ return array_unique(array_merge($wc,$wp));
133
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
  }
135
 
136
  /**
147
  if ( empty( $ids ) ) {
148
  return false;
149
  }
 
 
 
 
 
150
 
151
  foreach ( $ids as $key => $pid ) {
152
 
426
 
427
  $output = $prefix . $output . $suffix;
428
 
429
+ if ( $value == "shipping_country") {
430
+ if ( $s == 0 ) {
431
+ $shipping .= "<g:shipping>";
432
+ $s = 1;
433
+ } else {
434
+ $shipping .= "</g:shipping>" . "\n";
435
+ $shipping .= "<g:shipping>";
436
+ }
437
+ }elseif (!in_array("shipping_country",$merchantAttributes) && $value == "shipping_price"){
438
+ if ( $s == 0 ) {
439
+ $shipping .= "<g:shipping>";
440
+ $s = 1;
441
+ } else {
442
+ $shipping .= "</g:shipping>" . "\n";
443
+ $shipping .= "<g:shipping>";
444
+ }
445
+ }
446
 
447
  if ($value == "shipping_country") {
 
 
 
 
 
 
 
448
  $shipping .= "<g:country>" . $output . "</g:country>" . "\n";
449
  } else if ($value == "shipping_region") {
450
  $shipping .= "<g:region>" . $output . "</g:region>" . "\n";
includes/classes/class-woo-feed-products.php CHANGED
@@ -77,24 +77,24 @@ class Woo_Feed_Products {
77
  $limit="";
78
  $offset="";
79
  if($arg['limit']!="" && $arg['limit']!="-1" && $arg['limit']>0){
80
- $limit=$arg['limit'];
81
  $limit="LIMIT $limit";
82
 
83
 
84
  if($arg['offset']!="" && $arg['offset']!="-1"){
85
- $offset=$arg['offset'];
86
  $offset="OFFSET $offset";
87
  }
88
  }
89
 
90
 
91
 
92
- $query = "SELECT DISTINCT {$wpdb->prefix}posts.ID
93
- FROM {$wpdb->prefix}posts
94
- LEFT JOIN {$wpdb->prefix}term_relationships ON ({$wpdb->prefix}posts.ID = {$wpdb->prefix}term_relationships.object_id)
95
- LEFT JOIN {$wpdb->prefix}term_taxonomy ON ({$wpdb->prefix}term_relationships.term_taxonomy_id = {$wpdb->prefix}term_taxonomy.term_taxonomy_id)
96
- LEFT JOIN {$wpdb->prefix}postmeta ON ({$wpdb->prefix}posts.ID = {$wpdb->prefix}postmeta.post_id)
97
- WHERE {$wpdb->prefix}posts.post_status = 'publish' AND {$wpdb->prefix}posts.post_type IN ('product','product_variation')
98
  ORDER BY ID DESC $limit $offset";
99
  $products = $wpdb->get_results($query, ARRAY_A );
100
  return $products;
@@ -1756,8 +1756,7 @@ class Woo_Feed_Products {
1756
  global $wpdb;
1757
 
1758
  //Load Custom Category Mapped Attributes
1759
- $var = "wf_cmapping_";
1760
- $sql = $wpdb->prepare("SELECT * FROM $wpdb->options WHERE option_name LIKE %s;", $var . "%");
1761
  $data = $wpdb->get_results($sql);
1762
  if (count($data)) {
1763
  foreach ($data as $key => $value) {
77
  $limit="";
78
  $offset="";
79
  if($arg['limit']!="" && $arg['limit']!="-1" && $arg['limit']>0){
80
+ $limit= absint( $arg['limit'] );
81
  $limit="LIMIT $limit";
82
 
83
 
84
  if($arg['offset']!="" && $arg['offset']!="-1"){
85
+ $offset= absint( $arg['offset'] );
86
  $offset="OFFSET $offset";
87
  }
88
  }
89
 
90
 
91
 
92
+ $query = "SELECT DISTINCT $wpdb->posts.ID
93
+ FROM $wpdb->posts
94
+ LEFT JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id)
95
+ LEFT JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
96
+ LEFT JOIN $wpdb->postmeta ON ($wpdb->posts.ID = $wpdb->postmeta.post_id)
97
+ WHERE $wpdb->posts.post_status = 'publish' AND $wpdb->posts.post_type IN ('product','product_variation')
98
  ORDER BY ID DESC $limit $offset";
99
  $products = $wpdb->get_results($query, ARRAY_A );
100
  return $products;
1756
  global $wpdb;
1757
 
1758
  //Load Custom Category Mapped Attributes
1759
+ $sql = $wpdb->prepare("SELECT * FROM $wpdb->options WHERE option_name LIKE %s;", "wf_cmapping_%");
 
1760
  $data = $wpdb->get_results($sql);
1761
  if (count($data)) {
1762
  foreach ($data as $key => $value) {
includes/classes/class-woo-feed-tracker.php CHANGED
@@ -3,72 +3,153 @@
3
  * WooCommerce Product Feed Plugin Uses Tracker
4
  * Uses Webappick Insights for tracking
5
  * @since 3.1.41
6
- * @version 1.0.0
7
  */
8
  if( ! defined( 'ABSPATH' ) ) die();
9
- /**
10
- * Class WooFeedTracker
11
- */
12
- final class WooFeedTracker {
13
-
14
- /**
15
- * Insight class instance
16
- * @var \WebAppick\AppServices\Insights
17
- */
18
- public $insights;
19
  /**
20
- * Promotions Class Instance
21
- * @var \WebAppick\AppServices\Promotions
22
  */
23
- public $promotion;
24
-
25
- /**
26
- * Class constructor
27
- *
28
- * @return void
29
- * @since 1.0.0
30
- *
31
- */
32
- public function __construct() {
33
- if ( ! class_exists( 'WebAppick\AppServices\Client' ) ) {
34
- /** @noinspection PhpIncludeInspection */
35
- require_once WOO_FEED_LIBS_PATH . 'WebAppick/AppServices/Client.php';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  }
37
 
38
- $client = new WebAppick\AppServices\Client( '4e68acba-cbdc-476b-b4bf-eab176ac6a16', 'WooCommerce Product Feed', WOO_FEED_FREE_FILE );
39
- $this->insights = $client->insights();
40
- // Hide tracker notice until tracking server gets ready...
41
- // Tracker will not send data until user click Allow (optIn)
42
- $this->insights->hide_notice();
43
  /**
44
- * @TODO count products by type
45
- * @see wc_get_product_types();
46
  */
47
- $this->insights->add_extra( [
48
- 'products' => $this->insights->get_post_count( 'product' ),
49
- 'batch_limit' => get_option( 'woo_feed_per_batch', '' ),
50
- 'using_currency_conversion' => ( ! empty( get_option( 'woo_feed_currency_api_code', '' ) ) ),
51
- 'product_cat_num' => wp_count_terms( 'product_cat', ['hide_empty'=> false, 'parent' => 0] ),
52
- ] );
53
- $this->insights->init_plugin();
54
- // Promo offers
55
- $this->promotion = $client->promotions();
56
- $this->promotion->set_source( 'https://api.bitbucket.org/2.0/snippets/woofeed/RLbyop/files/woo-feed-notice.json' )->init();
57
 
58
- add_filter( $client->getSlug() . '_WebAppick_API_URL', array( $this, 'uninstallStatEndPoint' ), 10, 3 );
59
- }
60
-
61
- /**
62
- * Tracker API EndPoint
63
- * @param string $URL
64
- * @param string $apiEndPoint
65
- * @param string $route
66
- * @return string
67
- */
68
- public function uninstallStatEndPoint( $URL, $apiEndPoint, $route = '' ) {
69
- if( $route === 'reason' ) return 'https://track.webappick.com/api/receive-uninstall-tracking';
70
- return $URL;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  }
73
  }
74
- // End of file class-woo-feed-tracker.php
3
  * WooCommerce Product Feed Plugin Uses Tracker
4
  * Uses Webappick Insights for tracking
5
  * @since 3.1.41
6
+ * @version 1.0.2
7
  */
8
  if( ! defined( 'ABSPATH' ) ) die();
9
+
10
+ if( ! class_exists( 'WooFeedTracker' ) ) {
 
 
 
 
 
 
 
 
11
  /**
12
+ * Class WooFeedTracker
 
13
  */
14
+ final class WooFeedTracker {
15
+
16
+ /**
17
+ * Singleton instance
18
+ * @var WooFeedTracker
19
+ */
20
+ protected static $instance;
21
+
22
+ /**
23
+ * @var WebAppick\AppServices\Insights
24
+ */
25
+ protected $insights = null;
26
+
27
+ /**
28
+ * Promotions Class Instance
29
+ * @var \WebAppick\AppServices\Promotions
30
+ */
31
+ public $promotion;
32
+
33
+ /**
34
+ * @var WebAppick\AppServices\Updater
35
+ */
36
+ protected $updater = null;
37
+
38
+ /**
39
+ * @var WebAppick\AppServices\License
40
+ */
41
+ protected $license = null;
42
+
43
+ /**
44
+ * Initialize
45
+ * @return WooFeedTracker
46
+ */
47
+ public static function getInstance() {
48
+ if( is_null( self::$instance ) ) self::$instance = new self();
49
+ return self::$instance;
50
+ }
51
+
52
+ /**
53
+ * Class constructor
54
+ *
55
+ * @return void
56
+ * @since 1.0.0
57
+ *
58
+ */
59
+ private function __construct() {
60
+ add_action( 'init', [ $this, '__init' ] );
61
  }
62
 
 
 
 
 
 
63
  /**
64
+ * Cloning is forbidden.
65
+ * @since 1.0.2
66
  */
67
+ public function __clone() {
68
+ _doing_it_wrong( __FUNCTION__, __( 'Cloning is forbidden.', 'woo-feed' ), '1.0.2' );
69
+ }
 
 
 
 
 
 
 
70
 
71
+ public function __init() {
72
+ if ( ! class_exists( 'WebAppick\AppServices\Client' ) ) {
73
+ /** @noinspection PhpIncludeInspection */
74
+ require_once WOO_FEED_LIBS_PATH . 'WebAppick/AppServices/Client.php';
75
+ }
76
+
77
+ $client = new WebAppick\AppServices\Client( '4e68acba-cbdc-476b-b4bf-eab176ac6a16', 'WooCommerce Product Feed', WOO_FEED_FREE_FILE );
78
+ $this->insights = $client->insights();
79
+
80
+ // $this->license = $client->license();
81
+ // $this->updater = $client->updater();
82
+ // $this->license->add_settings_page( [ 'type' => 'submenu', 'parent_slug' => 'webappick-manage-feeds', ] );
83
+
84
+ $catCount = wp_count_terms( 'product_cat', ['hide_empty'=> false, 'parent' => 0] );
85
+ if( is_wp_error( $catCount ) ) $catCount = 0;
86
+ /**
87
+ * @TODO count products by type
88
+ * @see wc_get_product_types();
89
+ */
90
+ $this->insights->add_extra( [
91
+ 'products' => $this->insights->get_post_count( 'product' ),
92
+ 'batch_limit' => get_option( 'woo_feed_per_batch' ),
93
+ 'using_currency_conversion' => ( ! empty( get_option( 'woo_feed_currency_api_code', '' ) ) ),
94
+ 'product_cat_num' => $catCount,
95
+ ] );
96
+ // Promo offers
97
+ $this->promotion = $client->promotions();
98
+ $this->promotion->set_source( 'https://api.bitbucket.org/2.0/snippets/woofeed/RLbyop/files/woo-feed-notice.json' )->init();
99
+
100
+ add_filter( $client->getSlug() . '_what_tracked', [ $this, 'data_we_collect' ], 10, 1 );
101
+
102
+ $this->insights->init_plugin();
103
+ }
104
+
105
+ /**
106
+ * Set Data Collection description for the tracker
107
+ * @param $data
108
+ *
109
+ * @return array
110
+ */
111
+ public function data_we_collect( $data ) {
112
+ $data = array_merge( $data, [
113
+ esc_html__( 'Number of products in your site', 'woo-feed' ),
114
+ esc_html__( 'Number of product categories in your site', 'woo-feed' ),
115
+ esc_html__( 'Site language', 'woo-feed' ),
116
+ esc_html__( 'Number of active and inactive plugins', 'woo-feed' ),
117
+ esc_html__( 'Site name and url', 'woo-feed' ),
118
+ esc_html__( 'Your name and email address', 'woo-feed' )
119
+ ] );
120
+ return $data;
121
+ }
122
 
123
+ public function get_data_collection_description() {
124
+ return $this->insights->get_data_collection_description();
125
+ }
126
+
127
+ /**
128
+ * Update Tracker OptIn
129
+ *
130
+ * @param bool $override optional. ignore last send datetime settings if true.
131
+ * @see Insights::send_tracking_data()
132
+ * @return void
133
+ */
134
+ public function trackerOptIn( $override = false ) {
135
+ $this->insights->optIn( true );
136
+ }
137
+
138
+ /**
139
+ * Update Tracker OptOut
140
+ * @return void
141
+ */
142
+ public function trackerOptOut() {
143
+ $this->insights->optOut();
144
+ }
145
+
146
+ /**
147
+ * Check if tracking is enable
148
+ * @return bool
149
+ */
150
+ public function is_tracking_allowed() {
151
+ return $this->insights->is_tracking_allowed();
152
+ }
153
  }
154
  }
155
+ // End of file class-woo-feed-tracker.php
libs/WebAppick/AppServices/Insights.php CHANGED
@@ -167,7 +167,7 @@ class Insights {
167
  public function send_tracking_data( $override = false ) {
168
  // skip on AJAX Requests
169
  if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) return;
170
- if ( ! $this->__tracking_allowed() && ! $override ) return;
171
  // Send a maximum of once per week
172
  $last_send = $this->__get_last_send();
173
  /**
@@ -177,15 +177,15 @@ class Insights {
177
  * @link https://www.php.net/manual/en/function.strtotime.php
178
  */
179
  $trackingInterval = apply_filters( $this->client->getSlug() . '_tracking_interval', '-1 week' );
180
- $intervalCheck = false;
181
  try {
182
  $intervalCheck = strtotime( $trackingInterval );
183
- } catch( Exception $e ) {}
184
- // fallback to default 1 week if filter returned unusable data
185
- if( ! $intervalCheck ) $intervalCheck = strtotime( '-1 week' );
 
186
  if ( $last_send && $last_send > $intervalCheck && ! $override ) return;
187
  $this->client->send_request( $this->get_tracking_data(), 'track' );
188
- update_option( $this->client->getSlug() . '_tracking_last_send', time() );
189
  }
190
 
191
  /**
@@ -196,18 +196,21 @@ class Insights {
196
  protected function get_tracking_data() {
197
  $all_plugins = $this->__get_all_plugins();
198
  $admin_user = $this->__get_admin();
 
 
 
199
  $data = array(
200
  'version' => $this->client->getProjectVersion(),
201
  'url' => esc_url( home_url() ),
202
  'site' => $this->__get_site_name(),
203
- 'admin_email' => get_option( 'admin_email' ) . ',' . $admin_user->user_email,
204
  'first_name' => $admin_user->first_name ? $admin_user->first_name : $admin_user->display_name,
205
  'last_name' => $admin_user->last_name,
206
  'plugin' => $this->client->getName(),
207
  'hash' => $this->client->getHash(),
208
  'server' => $this->__get_server_info(),
209
  'wp' => $this->__get_wp_info(),
210
- 'users' => $this->__get_user_counts(),
211
  'active_plugins' => $all_plugins['active_plugins'],
212
  'inactive_plugins' => $all_plugins['inactive_plugins'],
213
  'ip_address' => $this->__get_user_ip_address(),
@@ -235,18 +238,17 @@ class Insights {
235
  * @return array
236
  */
237
  protected function data_we_collect() {
238
- $data = array(
239
  esc_html__( 'Server environment details (php, mysql, server, WordPress versions)', 'webappick' ),
240
- esc_html__( 'Number of users in your site', 'webappick' ),
241
- esc_html__( 'Number of products in your site', 'webappick' ),
242
- esc_html__( 'Site language', 'webappick' ),
243
- esc_html__( 'Number of active and inactive plugins', 'webappick' ),
244
- esc_html__( 'Site name and url', 'webappick' ),
245
- esc_html__( 'Your name and email address', 'webappick' ),
246
- );
247
  return $data;
248
  }
249
 
 
 
 
 
250
  /**
251
  * Get Site SuperAdmin
252
  * Returns Empty WP_User instance if fails
@@ -268,7 +270,7 @@ class Insights {
268
  *
269
  * @return bool
270
  */
271
- private function __tracking_allowed() {
272
  return 'yes' == get_option( $this->client->getSlug() . '_allow_tracking', 'no' );
273
  }
274
 
@@ -330,13 +332,11 @@ class Insights {
330
  public function admin_notice() {
331
  if ( $this->__notice_dismissed() ) return;
332
 
333
- if ( $this->__tracking_allowed() ) return;
334
  if ( ! current_user_can( 'manage_options' ) ) return;
335
 
336
  // don't show tracking if a local server
337
  if ( ! $this->__is_local_server() ) {
338
- $optOutUrl = add_query_arg( $this->client->getSlug() . '_tracker_optOut', 'true' );
339
- $optInUrl = add_query_arg( $this->client->getSlug() . '_tracker_optIn', 'true' );
340
 
341
  if ( empty( $this->notice ) ) {
342
  $notice = sprintf( esc_html__( 'Want to help make %1$s even more awesome? Allow %1$s to collect non-sensitive diagnostic data and usage information.', 'webappick' ), '<strong>'.$this->client->getName().'</strong>' );
@@ -349,8 +349,8 @@ class Insights {
349
  echo '<div class="updated"><p>';
350
  echo $notice;
351
  echo '</p><p class="submit">';
352
- echo '&nbsp;<a href="' . esc_url( $optOutUrl ) . '" class="button button-secondary">' . esc_html__( 'No thanks', 'webappick' ) . '</a>';
353
- echo '&nbsp;<a href="' . esc_url( $optInUrl ) . '" class="button button-primary">' . esc_html__( 'Allow', 'webappick' ) . '</a>';
354
  echo '</p></div>';
355
  echo "<script type='text/javascript'>jQuery('." . $this->client->getSlug() . "-insights-data-we-collect').on('click', function(e) {
356
  e.preventDefault();
@@ -359,6 +359,22 @@ class Insights {
359
  }
360
  }
361
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
362
  /**
363
  * handle the optIn/optOut
364
  *
@@ -390,14 +406,16 @@ class Insights {
390
  /**
391
  * Tracking optIn
392
  *
 
 
393
  * @return void
394
  */
395
- public function optIn() {
396
- update_option( $this->client->getSlug() . '_allow_tracking', 'yes' );
397
- update_option( $this->client->getSlug() . '_tracking_notice', 'hide' );
398
  $this->__clear_schedule_event();
399
  $this->__schedule_event();
400
- $this->send_tracking_data();
401
  }
402
 
403
  /**
@@ -406,8 +424,8 @@ class Insights {
406
  * @return void
407
  */
408
  public function optOut() {
409
- update_option( $this->client->getSlug() . '_allow_tracking', 'no' );
410
- update_option( $this->client->getSlug() . '_tracking_notice', 'hide' );
411
  $this->__clear_schedule_event();
412
  }
413
 
@@ -420,7 +438,7 @@ class Insights {
420
  */
421
  public function get_post_count( $post_type ) {
422
  global $wpdb;
423
- return (int) $wpdb->get_var( "SELECT count(ID) FROM $wpdb->posts WHERE post_type = '$post_type' and post_status = 'publish'");
424
  }
425
 
426
  /**
@@ -639,8 +657,8 @@ class Insights {
639
  $data = array(
640
  'hash' => $this->client->getHash(),
641
  'reason_id' => isset( $_REQUEST['reason_id'] ) && ! empty( $_REQUEST['reason_id'] ) ? sanitize_text_field( $_REQUEST['reason_id'] ) : '', // WPCS: CSRF ok, Input var ok.
642
- 'reason_info' => isset( $_REQUEST['reason_info'] ) ? trim( sanitize_textarea_field( $_REQUEST['reason_info'] ) ) : '',
643
- 'plugin' => $this->client->getName(), // deprecated
644
  'site' => $this->__get_site_name(),
645
  'url' => esc_url( home_url() ),
646
  'admin_email' => get_option( 'admin_email' ),
167
  public function send_tracking_data( $override = false ) {
168
  // skip on AJAX Requests
169
  if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) return;
170
+ if ( ! $this->is_tracking_allowed() && ! $override ) return;
171
  // Send a maximum of once per week
172
  $last_send = $this->__get_last_send();
173
  /**
177
  * @link https://www.php.net/manual/en/function.strtotime.php
178
  */
179
  $trackingInterval = apply_filters( $this->client->getSlug() . '_tracking_interval', '-1 week' );
 
180
  try {
181
  $intervalCheck = strtotime( $trackingInterval );
182
+ } catch( Exception $e ) {
183
+ // fallback to default 1 week if filter returned unusable data
184
+ $intervalCheck = strtotime( '-1 week' );
185
+ }
186
  if ( $last_send && $last_send > $intervalCheck && ! $override ) return;
187
  $this->client->send_request( $this->get_tracking_data(), 'track' );
188
+ update_option( $this->client->getSlug() . '_tracking_last_send', time(), false );
189
  }
190
 
191
  /**
196
  protected function get_tracking_data() {
197
  $all_plugins = $this->__get_all_plugins();
198
  $admin_user = $this->__get_admin();
199
+ $admin_emails = [ get_option( 'admin_email' ), $admin_user->user_email ];
200
+ $admin_emails = array_filter( $admin_emails );
201
+ $admin_emails = array_unique( $admin_emails );
202
  $data = array(
203
  'version' => $this->client->getProjectVersion(),
204
  'url' => esc_url( home_url() ),
205
  'site' => $this->__get_site_name(),
206
+ 'admin_email' => $admin_emails,
207
  'first_name' => $admin_user->first_name ? $admin_user->first_name : $admin_user->display_name,
208
  'last_name' => $admin_user->last_name,
209
  'plugin' => $this->client->getName(),
210
  'hash' => $this->client->getHash(),
211
  'server' => $this->__get_server_info(),
212
  'wp' => $this->__get_wp_info(),
213
+ //'users' => $this->__get_user_counts(),
214
  'active_plugins' => $all_plugins['active_plugins'],
215
  'inactive_plugins' => $all_plugins['inactive_plugins'],
216
  'ip_address' => $this->__get_user_ip_address(),
238
  * @return array
239
  */
240
  protected function data_we_collect() {
241
+ $data = [
242
  esc_html__( 'Server environment details (php, mysql, server, WordPress versions)', 'webappick' ),
243
+ ];
244
+ $data = apply_filters( $this->client->getSlug() . '_what_tracked', $data );
 
 
 
 
 
245
  return $data;
246
  }
247
 
248
+ public function get_data_collection_description() {
249
+ return $this->data_we_collect();
250
+ }
251
+
252
  /**
253
  * Get Site SuperAdmin
254
  * Returns Empty WP_User instance if fails
270
  *
271
  * @return bool
272
  */
273
+ public function is_tracking_allowed() {
274
  return 'yes' == get_option( $this->client->getSlug() . '_allow_tracking', 'no' );
275
  }
276
 
332
  public function admin_notice() {
333
  if ( $this->__notice_dismissed() ) return;
334
 
335
+ if ( $this->is_tracking_allowed() ) return;
336
  if ( ! current_user_can( 'manage_options' ) ) return;
337
 
338
  // don't show tracking if a local server
339
  if ( ! $this->__is_local_server() ) {
 
 
340
 
341
  if ( empty( $this->notice ) ) {
342
  $notice = sprintf( esc_html__( 'Want to help make %1$s even more awesome? Allow %1$s to collect non-sensitive diagnostic data and usage information.', 'webappick' ), '<strong>'.$this->client->getName().'</strong>' );
349
  echo '<div class="updated"><p>';
350
  echo $notice;
351
  echo '</p><p class="submit">';
352
+ echo '&nbsp;<a href="' . esc_url( $this->get_opt_out_url() ) . '" class="button button-secondary">' . esc_html__( 'No thanks', 'webappick' ) . '</a>';
353
+ echo '&nbsp;<a href="' . esc_url( $this->get_opt_in_url() ) . '" class="button button-primary">' . esc_html__( 'Allow', 'webappick' ) . '</a>';
354
  echo '</p></div>';
355
  echo "<script type='text/javascript'>jQuery('." . $this->client->getSlug() . "-insights-data-we-collect').on('click', function(e) {
356
  e.preventDefault();
359
  }
360
  }
361
 
362
+ /**
363
+ * Tracking Opt In URL
364
+ * @return string
365
+ */
366
+ public function get_opt_in_url() {
367
+ return add_query_arg( $this->client->getSlug() . '_tracker_optOut', 'true' );
368
+ }
369
+
370
+ /**
371
+ * Tracking Opt Out URL
372
+ * @return string
373
+ */
374
+ public function get_opt_out_url() {
375
+ return add_query_arg( $this->client->getSlug() . '_tracker_optIn', 'true' );
376
+ }
377
+
378
  /**
379
  * handle the optIn/optOut
380
  *
406
  /**
407
  * Tracking optIn
408
  *
409
+ * @param bool $override optional. set send tracking data override setting, ignore last send datetime setting if true.
410
+ * @see Insights::send_tracking_data()
411
  * @return void
412
  */
413
+ public function optIn( $override = false ) {
414
+ update_option( $this->client->getSlug() . '_allow_tracking', 'yes', false );
415
+ update_option( $this->client->getSlug() . '_tracking_notice', 'hide', false );
416
  $this->__clear_schedule_event();
417
  $this->__schedule_event();
418
+ $this->send_tracking_data( $override );
419
  }
420
 
421
  /**
424
  * @return void
425
  */
426
  public function optOut() {
427
+ update_option( $this->client->getSlug() . '_allow_tracking', 'no', false );
428
+ update_option( $this->client->getSlug() . '_tracking_notice', 'hide', false );
429
  $this->__clear_schedule_event();
430
  }
431
 
438
  */
439
  public function get_post_count( $post_type ) {
440
  global $wpdb;
441
+ return (int) $wpdb->get_var( $wpdb->prepare( "SELECT count(ID) FROM $wpdb->posts WHERE post_type = %s and post_status = 'publish'", $post_type ) );
442
  }
443
 
444
  /**
657
  $data = array(
658
  'hash' => $this->client->getHash(),
659
  'reason_id' => isset( $_REQUEST['reason_id'] ) && ! empty( $_REQUEST['reason_id'] ) ? sanitize_text_field( $_REQUEST['reason_id'] ) : '', // WPCS: CSRF ok, Input var ok.
660
+ 'reason_info' => isset( $_REQUEST['reason_info'] ) ? trim( sanitize_textarea_field( $_REQUEST['reason_info'] ) ) : '', // WPCS: CSRF ok, Input var ok.
661
+ 'plugin' => $this->client->getName(),
662
  'site' => $this->__get_site_name(),
663
  'url' => esc_url( home_url() ),
664
  'admin_email' => get_option( 'admin_email' ),
libs/WebAppick/AppServices/License.php CHANGED
@@ -598,7 +598,7 @@ class License {
598
  */
599
  private function formActionUrl() {
600
  echo add_query_arg(
601
- array( 'page' => $_GET['page'] ),
602
  admin_url( basename( $_SERVER['SCRIPT_NAME'] ) )
603
  );
604
  }
598
  */
599
  private function formActionUrl() {
600
  echo add_query_arg(
601
+ array( 'page' => sanitize_text_field( $_GET['page'] ) ),
602
  admin_url( basename( $_SERVER['SCRIPT_NAME'] ) )
603
  );
604
  }
libs/WebAppick/AppServices/Promotions.php CHANGED
@@ -318,7 +318,7 @@ class Promotions {
318
  ! empty( $_REQUEST['hash'] ) &&
319
  wp_verify_nonce( $_REQUEST['_wpnonce'], 'wapk-dismiss-promo' )
320
  ) {
321
- $this->hiddenPromotions = array_merge( $this->hiddenPromotions, [ $_REQUEST['hash'] ] );
322
  update_user_option( $this->currentUser, $this->client->getSlug() . '_hidden_promos', $this->hiddenPromotions );
323
  wp_send_json_success( __( 'Promo hidden', 'webappick' ) );
324
  }
318
  ! empty( $_REQUEST['hash'] ) &&
319
  wp_verify_nonce( $_REQUEST['_wpnonce'], 'wapk-dismiss-promo' )
320
  ) {
321
+ $this->hiddenPromotions = array_merge( $this->hiddenPromotions, [ sanitize_text_field( $_REQUEST['hash'] ) ] );
322
  update_user_option( $this->currentUser, $this->client->getSlug() . '_hidden_promos', $this->hiddenPromotions );
323
  wp_send_json_success( __( 'Promo hidden', 'webappick' ) );
324
  }
woo-feed.php CHANGED
@@ -15,7 +15,7 @@
15
  * Plugin Name: WooCommerce Product Feed
16
  * Plugin URI: https://webappick.com/
17
  * Description: This plugin generate WooCommerce product feed for Shopping Engines like Google Shopping,Facebook Product Feed,eBay,Amazon,Idealo and many more..
18
- * Version: 3.2.1
19
  * Author: WebAppick
20
  * Author URI: https://webappick.com/
21
  * License: GPL v2
@@ -41,7 +41,7 @@ if( ! defined( 'WOO_FEED_VERSION' ) ) {
41
  * Plugin Version
42
  * @var string
43
  */
44
- define( 'WOO_FEED_VERSION', '3.2.1' );
45
  }
46
  if( ! defined( 'WOO_FEED_FREE_FILE') ) {
47
  /**
@@ -106,6 +106,17 @@ if( ! defined( 'WOO_FEED_PLUGIN_BASE_NAME' ) ) {
106
  define( 'WOO_FEED_PLUGIN_BASE_NAME', plugin_basename(__FILE__) );
107
  }
108
 
 
 
 
 
 
 
 
 
 
 
 
109
  /**
110
  * Load Helper functions
111
  */
@@ -171,10 +182,11 @@ if( ! function_exists( 'run_woo_feed' ) ) {
171
  /**
172
  * Ensure Feed Plugin runs only if WooCommerce loaded (installed and activated)
173
  * @since 3.1.41
 
174
  */
175
- add_action( 'woocommerce_loaded', array( $plugin, 'run' ) );
176
  add_action( 'admin_notices', 'wooFeed_Admin_Notices' );
177
- new WooFeedTracker();
178
  }
179
  run_woo_feed();
180
  }
@@ -383,7 +395,7 @@ if( ! function_exists( 'woo_feed_get_product_information' ) ) {
383
  if(woo_feed_wc_version_check(3.2)){
384
 
385
  $feed = sanitize_text_field( $_REQUEST['feed'] );
386
- $limit = sanitize_text_field( $_REQUEST['limit'] );
387
 
388
  $getConfig=maybe_unserialize(get_option($feed));
389
 
@@ -584,7 +596,7 @@ if( ! function_exists( 'woo_feed_make_batch_feed' ) ) {
584
  $feedInfo=$getFeedConfig['feedrules'];
585
  }
586
 
587
- $products = $_REQUEST['products'];
588
  $offset = absint( $_REQUEST['loop'] );
589
  $feedInfo['productIds'] = $products;
590
 
@@ -638,10 +650,10 @@ if( ! function_exists( 'woo_feed_save_feed_file' ) ) {
638
  function woo_feed_save_feed_file(){
639
 
640
  check_ajax_referer('wpf_feed_nonce');
641
- $feed = str_replace("wf_feed_", "",$_REQUEST['feed']);
642
  $info = get_option($feed);
643
  if(!$info){
644
- $getInfo = unserialize(get_option($_REQUEST['feed']));
645
  $info = $getInfo['feedrules'];
646
  }
647
 
@@ -816,7 +828,7 @@ if( ! function_exists( 'woo_feed_sanitize_form_fields' ) ) {
816
  if( true === apply_filters( 'woo_feed_sanitize_form_fields', true, $k, $v, $data ) ) {
817
  if( is_array( $v ) ) {
818
  $v = woo_feed_sanitize_form_fields( $v );
819
- }else{
820
  //$v = sanitize_text_field( $v ); #TODO should not trim Prefix and Suffix field
821
  }
822
  }
@@ -876,25 +888,25 @@ if( ! function_exists( 'woo_feed_generate_feed' ) ) {
876
  wp_die( 'Invalid Feed Type!' );
877
  }
878
  // Sanitize Fields
879
- $_POST = woo_feed_sanitize_form_fields( $_POST );
880
  //@TODO simplefy feed db, combine wf_config & wf_feed_ prefix...
881
- $feedDir = woo_feed_get_file_dir( $_POST['provider'], $_POST['feedType'] );
882
- $_POST['filename'] = sanitize_title( $_POST['filename'], '', 'save' );
883
  // check option name uniqueness ...
884
- $_POST['filename'] = woo_feed_unique_feed_slug( $_POST['filename'], null );
885
- $_POST['filename'] = sanitize_file_name( $_POST['filename'] . '.' . $_POST['feedType'] );
886
- $_POST['filename'] = wp_unique_filename( $feedDir, $_POST['filename'] );
887
- $_POST['filename'] = str_replace( '.' . $_POST['feedType'] , '', $_POST['filename'] );
888
  # Option Name
889
- $fileName = "wf_config" . $_POST['filename'];
890
  # Store Config
891
- update_option( $fileName, $_POST );
892
 
893
  # Schedule Cron
894
- $arg = array( sanitize_text_field( $_POST['filename'] ) );
895
- wp_schedule_event(time(), 'woo_feed_corn', 'woo_feed_update_single_feed',$arg);
896
-
897
-
898
  require WOO_FEED_ADMIN_PATH . "partials/woo-feed-manage-list.php";
899
  } else {
900
  echo "<div class='notice notice-warning is-dismissible'><p>" . __("You are awesome for using <b>WooCommerce Product Feed</b>. Free version works great for up to <b>2000 products including variations.</b>", 'woo-feed') . "</p></div>";
@@ -919,19 +931,11 @@ if( ! function_exists( 'woo_feed_manage_feed' ) ) {
919
  wp_die( 'Invalid Feed Type!' );
920
  }
921
  // Sanitize Fields
922
- $_POST = woo_feed_sanitize_form_fields( $_POST );
923
- //@TODO simplefy feed db, combine wf_config & wf_feed_ prefix...
924
- // $feedDir = woo_feed_get_file_dir( $_POST['provider'], $_POST['feedType'] );
925
- // $_POST['filename'] = sanitize_title( $_POST['filename'], '', 'save' );
926
- // check option name uniqueness ...
927
- // $_POST['filename'] = woo_feed_unique_feed_slug( $_POST['filename'], $_POST['feed_id'] );
928
- // $_POST['filename'] = sanitize_file_name( $_POST['filename'] . '.' . $_POST['feedType'] );
929
- // $_POST['filename'] = wp_unique_filename( $feedDir, $_POST['filename'] );
930
- // $_POST['filename'] = str_replace( '.' . $_POST['feedType'] , '', $_POST['filename'] );
931
- # Option Name
932
- $fileName = "wf_config" . $_POST['filename'];
933
  # Store Config
934
- update_option( $fileName, $_POST );
935
 
936
  require WOO_FEED_ADMIN_PATH . "partials/woo-feed-manage-list.php";
937
  wp_die();
@@ -1042,14 +1046,24 @@ if( ! function_exists( 'woo_feed_config_feed' ) ) {
1042
  * Feed config
1043
  */
1044
  function woo_feed_config_feed(){
1045
- if(isset($_POST['wa_woo_feed_config'])) {
1046
- update_option("woo_feed_per_batch",sanitize_text_field($_POST['limit']));
1047
- if(isset($_POST['enable_error_debugging'])) {
1048
- update_option("woo_feed_enable_error_debugging", sanitize_text_field($_POST['enable_error_debugging']));
 
 
 
 
 
 
 
 
 
1049
  } else {
1050
- update_option("woo_feed_enable_error_debugging", "off");
1051
  }
1052
  }
 
1053
  require WOO_FEED_ADMIN_PATH . "partials/woo-feed-config.php";
1054
  }
1055
  }
@@ -1061,8 +1075,7 @@ if( ! function_exists( 'woo_feed_getFeedInfoForCronUpdate' ) ) {
1061
 
1062
  check_ajax_referer('wpf_feed_nonce');
1063
  global $wpdb;
1064
- $var = "wf_feed_";
1065
- $query = $wpdb->prepare("SELECT * FROM $wpdb->options WHERE option_name LIKE %s;", $var . "%");
1066
  $result = $wpdb->get_results($query, 'ARRAY_A');
1067
  $feeds=array();
1068
  foreach ($result as $key => $value) {
@@ -1085,10 +1098,10 @@ if( ! function_exists( 'woo_feed_update_feed_status' ) ) {
1085
  */
1086
  function woo_feed_update_feed_status(){
1087
  if(!empty($_POST['feedName'])){
1088
- $feedInfo = unserialize(get_option($_POST['feedName']));
1089
- $feedInfo['status'] = $_POST['status'];
1090
  $data = array('status' => true);
1091
- update_option($_POST['feedName'],serialize($feedInfo));
1092
  wp_send_json_success($data);
1093
  }else{
1094
  $data = array('status' => false);
@@ -1104,8 +1117,7 @@ if( ! function_exists( 'woo_feed_cron_update_feed' ) ) {
1104
  */
1105
  function woo_feed_cron_update_feed() {
1106
  global $wpdb;
1107
- $var = "wf_feed_";
1108
- $query = $wpdb->prepare("SELECT * FROM $wpdb->options WHERE option_name LIKE %s;", $var . "%");
1109
  $result = $wpdb->get_results($query, 'ARRAY_A');
1110
  foreach ($result as $key => $value) {
1111
  $feedInfo = unserialize(get_option($value['option_name']));
@@ -1128,12 +1140,7 @@ if( ! function_exists( 'woo_feed_cron_update_single_feed' ) ) {
1128
 
1129
 
1130
  $result = $wpdb->get_results(
1131
- $wpdb->prepare( "
1132
- SELECT * FROM $wpdb->options
1133
- WHERE option_name = %s",
1134
- $feedname
1135
- )
1136
- ,'ARRAY_A');
1137
 
1138
 
1139
  if(!empty($result)){
15
  * Plugin Name: WooCommerce Product Feed
16
  * Plugin URI: https://webappick.com/
17
  * Description: This plugin generate WooCommerce product feed for Shopping Engines like Google Shopping,Facebook Product Feed,eBay,Amazon,Idealo and many more..
18
+ * Version: 3.2.2
19
  * Author: WebAppick
20
  * Author URI: https://webappick.com/
21
  * License: GPL v2
41
  * Plugin Version
42
  * @var string
43
  */
44
+ define( 'WOO_FEED_VERSION', '3.2.2' );
45
  }
46
  if( ! defined( 'WOO_FEED_FREE_FILE') ) {
47
  /**
106
  define( 'WOO_FEED_PLUGIN_BASE_NAME', plugin_basename(__FILE__) );
107
  }
108
 
109
+ if( ! defined( 'WOO_FEED_LOG_DIR' ) ) {
110
+ $upload_dir = wp_upload_dir();
111
+ /**
112
+ * Log Directory
113
+ * @var string
114
+ * @since 3.2.1
115
+ */
116
+ /** @define "WOO_FEED_LOG_DIR" "./../../uploads/woo-feed/logs" */
117
+ define( 'WOO_FEED_LOG_DIR', $upload_dir['basedir'] . '/woo-feed/logs/' );
118
+ }
119
+
120
  /**
121
  * Load Helper functions
122
  */
182
  /**
183
  * Ensure Feed Plugin runs only if WooCommerce loaded (installed and activated)
184
  * @since 3.1.41
185
+ * @since 3.2.2 using plugins_loaded action
186
  */
187
+ add_action( 'plugins_loaded', array( $plugin, 'run' ), PHP_INT_MAX );
188
  add_action( 'admin_notices', 'wooFeed_Admin_Notices' );
189
+ WooFeedTracker::getInstance();
190
  }
191
  run_woo_feed();
192
  }
395
  if(woo_feed_wc_version_check(3.2)){
396
 
397
  $feed = sanitize_text_field( $_REQUEST['feed'] );
398
+ $limit = absint( $_REQUEST['limit'] );
399
 
400
  $getConfig=maybe_unserialize(get_option($feed));
401
 
596
  $feedInfo=$getFeedConfig['feedrules'];
597
  }
598
 
599
+ $products = array_map( 'absint', $_REQUEST['products'] );
600
  $offset = absint( $_REQUEST['loop'] );
601
  $feedInfo['productIds'] = $products;
602
 
650
  function woo_feed_save_feed_file(){
651
 
652
  check_ajax_referer('wpf_feed_nonce');
653
+ $feed = str_replace("wf_feed_", "", sanitize_text_field( $_REQUEST['feed'] ) );
654
  $info = get_option($feed);
655
  if(!$info){
656
+ $getInfo = unserialize(get_option( sanitize_text_field( $_REQUEST['feed'] ) ));
657
  $info = $getInfo['feedrules'];
658
  }
659
 
828
  if( true === apply_filters( 'woo_feed_sanitize_form_fields', true, $k, $v, $data ) ) {
829
  if( is_array( $v ) ) {
830
  $v = woo_feed_sanitize_form_fields( $v );
831
+ } else {
832
  //$v = sanitize_text_field( $v ); #TODO should not trim Prefix and Suffix field
833
  }
834
  }
888
  wp_die( 'Invalid Feed Type!' );
889
  }
890
  // Sanitize Fields
891
+ $_data = woo_feed_sanitize_form_fields( $_POST );
892
  //@TODO simplefy feed db, combine wf_config & wf_feed_ prefix...
893
+ $feedDir = woo_feed_get_file_dir( $_data['provider'], $_data['feedType'] );
894
+ $_data['filename'] = sanitize_title( $_data['filename'], '', 'save' );
895
  // check option name uniqueness ...
896
+ $_data['filename'] = woo_feed_unique_feed_slug( $_data['filename'], null );
897
+ $_data['filename'] = sanitize_file_name( $_data['filename'] . '.' . $_data['feedType'] );
898
+ $_data['filename'] = wp_unique_filename( $feedDir, $_data['filename'] );
899
+ $_data['filename'] = str_replace( '.' . $_data['feedType'] , '', $_data['filename'] );
900
  # Option Name
901
+ $fileName = "wf_config" . $_data['filename'];
902
  # Store Config
903
+ update_option( $fileName, $_data );
904
 
905
  # Schedule Cron
906
+ $arg = array( sanitize_text_field( $_data['filename'] ) );
907
+
908
+ wp_schedule_event(time(), 'woo_feed_corn', 'woo_feed_update_single_feed', $arg );
909
+
910
  require WOO_FEED_ADMIN_PATH . "partials/woo-feed-manage-list.php";
911
  } else {
912
  echo "<div class='notice notice-warning is-dismissible'><p>" . __("You are awesome for using <b>WooCommerce Product Feed</b>. Free version works great for up to <b>2000 products including variations.</b>", 'woo-feed') . "</p></div>";
931
  wp_die( 'Invalid Feed Type!' );
932
  }
933
  // Sanitize Fields
934
+ $_data = woo_feed_sanitize_form_fields( $_POST );
935
+ # Option Name
936
+ $fileName = "wf_config" . $_data['filename'];
 
 
 
 
 
 
 
 
937
  # Store Config
938
+ update_option( $fileName, $_data );
939
 
940
  require WOO_FEED_ADMIN_PATH . "partials/woo-feed-manage-list.php";
941
  wp_die();
1046
  * Feed config
1047
  */
1048
  function woo_feed_config_feed(){
1049
+ if( isset( $_POST['wa_woo_feed_config'], $_POST['_wpnonce'] ) ) {
1050
+ check_admin_referer();
1051
+ $batch_limit = absint( $_POST['batch_limit'] );
1052
+ if( $batch_limit <= 0 ) $batch_limit = 200;
1053
+ update_option( "woo_feed_per_batch", $batch_limit, false );
1054
+ $queryType = strtolower( sanitize_text_field( $_POST['woo_feed_product_query_type'] ) );
1055
+ if( ! $queryType || ! in_array( $queryType, [ 'wc', 'wp', 'both' ] ) ) {
1056
+ $queryType = 'wc';
1057
+ }
1058
+ update_option( "woo_feed_product_query_type", $queryType,false );
1059
+ update_option( "woo_feed_enable_error_debugging", sanitize_text_field( $_POST['enable_error_debugging'] ), false );
1060
+ if( isset( $_POST['opt_in'] ) ) {
1061
+ WooFeedTracker::getInstance()->trackerOptIn();
1062
  } else {
1063
+ WooFeedTracker::getInstance()->trackerOptOut();
1064
  }
1065
  }
1066
+
1067
  require WOO_FEED_ADMIN_PATH . "partials/woo-feed-config.php";
1068
  }
1069
  }
1075
 
1076
  check_ajax_referer('wpf_feed_nonce');
1077
  global $wpdb;
1078
+ $query = $wpdb->prepare("SELECT * FROM $wpdb->options WHERE option_name LIKE %s;", "wf_feed_%");
 
1079
  $result = $wpdb->get_results($query, 'ARRAY_A');
1080
  $feeds=array();
1081
  foreach ($result as $key => $value) {
1098
  */
1099
  function woo_feed_update_feed_status(){
1100
  if(!empty($_POST['feedName'])){
1101
+ $feedInfo = unserialize(get_option( sanitize_text_field( $_POST['feedName'] ) ));
1102
+ $feedInfo['status'] = sanitize_text_field( $_POST['status'] );
1103
  $data = array('status' => true);
1104
+ update_option( sanitize_text_field( $_POST['feedName'] ),serialize($feedInfo));
1105
  wp_send_json_success($data);
1106
  }else{
1107
  $data = array('status' => false);
1117
  */
1118
  function woo_feed_cron_update_feed() {
1119
  global $wpdb;
1120
+ $query = $wpdb->prepare("SELECT * FROM $wpdb->options WHERE option_name LIKE %s;", "wf_feed_%");
 
1121
  $result = $wpdb->get_results($query, 'ARRAY_A');
1122
  foreach ($result as $key => $value) {
1123
  $feedInfo = unserialize(get_option($value['option_name']));
1140
 
1141
 
1142
  $result = $wpdb->get_results(
1143
+ $wpdb->prepare( "SELECT * FROM $wpdb->options WHERE option_name = %s", $feedname ),'ARRAY_A');
 
 
 
 
 
1144
 
1145
 
1146
  if(!empty($result)){