Product Feed PRO for WooCommerce - Version 7.3.3

Version Description

New feature: you can now decide to only allow products to your feed that have been sold before (and amounts) and indicate a time period that should be taken into account for this. When a shipping method and zone was configured but no shipping cost was set an empty prices shipping node was added to feeds which caused warnings in Google's merchant center. This has been solved now.

Download this release

Release Info

Developer jorisverwater
Plugin Icon 128x128 Product Feed PRO for WooCommerce
Version 7.3.3
Comparing to
See all releases

Code changes from version 7.3.2 to 7.3.3

classes/class-get-products.php CHANGED
@@ -209,6 +209,23 @@ class WooSEA_Get_Products {
209
  return "<![CDATA[ $string ]]>";
210
  }
211
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
  /**
213
  * Get custom attribute names for a product
214
  */
@@ -243,23 +260,53 @@ class WooSEA_Get_Products {
243
  * Get orders for given time period used in filters
244
  */
245
  public function woosea_get_orders( $project_config ){
246
- $query_args = array(
247
- 'post_type' => wc_get_order_types(),
248
- 'post_status' => array_keys( wc_get_order_statuses() ),
249
- 'posts_per_page' => 999999999999,
250
- );
251
- $all_orders = get_posts( $query_args );
252
-
253
- foreach ( $all_orders as $orders ) {
254
- $order = wc_get_order( $orders-> ID);
255
- $order_data = $order->get_data();
256
- $order_date_created = $order_data['date_created']->date('Y-m-d H:i:s');
257
-
258
- foreach ($order->get_items() as $item_key => $item_values){
259
- $product_id = $item_values->get_product_id();
260
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
261
  }
262
- //return $orders_timeframe;
263
  }
264
 
265
  /**
@@ -732,8 +779,8 @@ class WooSEA_Get_Products {
732
  if(isset($v->instance_settings[$class_cost_id])){
733
 
734
  if (is_numeric($v->instance_settings[$class_cost_id])){
735
-
736
  $shipping_cost = $v->instance_settings[$class_cost_id];
 
737
  // Do we need to convert the shipping costswith the Aelia Currency Switcher
738
  if((isset($project_config['AELIA'])) AND (!empty($GLOBALS['woocommerce-aelia-currencyswitcher'])) AND (get_option ('add_aelia_support') == "yes")){
739
  if(!array_key_exists('base_currency', $project_config)){
@@ -760,7 +807,8 @@ class WooSEA_Get_Products {
760
  } else {
761
  $shipping_cost = $v->instance_settings[$class_cost_id];
762
  $shipping_cost = str_replace("[qty]", "1", $shipping_cost);
763
- $mathString = trim($shipping_cost); // trim white spaces
 
764
  if (preg_match("/fee percent/", $mathString)){
765
  $shipcost_piece = explode("+", $mathString);
766
  $mathString = trim($shipcost_piece[0]);
@@ -858,7 +906,13 @@ class WooSEA_Get_Products {
858
  }
859
  }
860
  }
861
- $zone_details['price'] = trim($currency." ".$shipping_cost);
 
 
 
 
 
 
862
  }
863
 
864
  // This shipping zone has postal codes so multiply the zone details
@@ -1743,9 +1797,6 @@ class WooSEA_Get_Products {
1743
  $orderby = "DESC";
1744
  }
1745
 
1746
- // Get Orders
1747
- // $order_timeframe = WooSEA_Get_Products::woosea_get_orders ( $project_config );
1748
-
1749
  // Switch to configured WPML lamguage
1750
  if(isset($project_config['WPML'])){
1751
  if ( function_exists('icl_object_id') ) {
@@ -1755,6 +1806,13 @@ class WooSEA_Get_Products {
1755
  }
1756
  }
1757
 
 
 
 
 
 
 
 
1758
  // Construct WP query
1759
  $wp_query = array(
1760
  'posts_per_page' => $offset_step_size,
@@ -1793,6 +1851,14 @@ class WooSEA_Get_Products {
1793
  if($status != "publish") { continue; }
1794
 
1795
  $product_data['id'] = get_the_ID();
 
 
 
 
 
 
 
 
1796
  $product_data['title'] = $product->get_title();
1797
  $product_data['title'] = $this->woosea_utf8_for_xml( $product_data['title'] );
1798
  $product_data['mother_title'] = $product->get_title();
@@ -2554,7 +2620,8 @@ class WooSEA_Get_Products {
2554
 
2555
  // Get number of orders for this product
2556
  $product_data['total_product_orders'] = 0;
2557
- $product_data['total_product_orders'] = get_post_meta($product_data['item_group_id'], 'total_sales', true);
 
2558
 
2559
  $visibility_list = wp_get_post_terms($product_data['item_group_id'], 'product_visibility', array("fields" => "all"));
2560
  foreach($visibility_list as $visibility_single){
209
  return "<![CDATA[ $string ]]>";
210
  }
211
 
212
+ /**
213
+ * Get number of variation sales for a product variation
214
+ */
215
+ private function woosea_get_nr_orders_variation ( $variation_id ) {
216
+ global $wpdb;
217
+
218
+ // Getting all Order Items with that variation ID
219
+ $nr_sales = $wpdb->get_col( $wpdb->prepare( "
220
+ SELECT count(*) AS nr_sales
221
+ FROM {$wpdb->prefix}woocommerce_order_itemmeta
222
+ WHERE meta_key LIKE '_variation_id'
223
+ AND meta_value = %s
224
+ ", $variation_id ) );
225
+
226
+ return $nr_sales;
227
+ }
228
+
229
  /**
230
  * Get custom attribute names for a product
231
  */
260
  * Get orders for given time period used in filters
261
  */
262
  public function woosea_get_orders( $project_config ){
263
+
264
+ $allowed_products = array();
265
+
266
+ if(isset($project_config['total_product_orders_lookback'])){
267
+
268
+ if($project_config['total_product_orders_lookback'] > 0){
269
+
270
+ $query_args = array(
271
+ 'post_type' => wc_get_order_types(),
272
+ 'post_status' => array_keys( wc_get_order_statuses() ),
273
+ 'posts_per_page' => 999999999999,
274
+ );
275
+ $all_orders = get_posts( $query_args );
276
+
277
+ $today = date("Y-m-d");
278
+ $today_limit = date('Y-m-d', strtotime('-'.$project_config['total_product_orders_lookback'].' days', strtotime($today)));
279
+
280
+ foreach ( $all_orders as $orders ) {
281
+ $order = wc_get_order( $orders-> ID);
282
+ $order_data = $order->get_data();
283
+
284
+ $order_date_created = $order_data['date_created']->date('Y-m-d');
285
+
286
+ if($order_date_created >= $today_limit){
287
+ foreach ($order->get_items() as $item_key => $item_values){
288
+ $order_product_id = $item_values->get_product_id();
289
+ $order_variation_id = $item_values->get_variation_id();
290
+
291
+ // When a variation was sold, add the variation
292
+ if($order_variation_id > 0){
293
+ $order_product_id = $order_variation_id;
294
+ }
295
+
296
+ // Only for existing products
297
+ if($order_product_id > 0){
298
+
299
+ // Only add products that are not in the array yet
300
+ if(!in_array($order_product_id, $allowed_products)){
301
+ $allowed_products[] = $order_product_id;
302
+ }
303
+ }
304
+ }
305
+ }
306
+ }
307
+ }
308
  }
309
+ return $allowed_products;
310
  }
311
 
312
  /**
779
  if(isset($v->instance_settings[$class_cost_id])){
780
 
781
  if (is_numeric($v->instance_settings[$class_cost_id])){
 
782
  $shipping_cost = $v->instance_settings[$class_cost_id];
783
+
784
  // Do we need to convert the shipping costswith the Aelia Currency Switcher
785
  if((isset($project_config['AELIA'])) AND (!empty($GLOBALS['woocommerce-aelia-currencyswitcher'])) AND (get_option ('add_aelia_support') == "yes")){
786
  if(!array_key_exists('base_currency', $project_config)){
807
  } else {
808
  $shipping_cost = $v->instance_settings[$class_cost_id];
809
  $shipping_cost = str_replace("[qty]", "1", $shipping_cost);
810
+
811
+ $mathString = trim($shipping_cost); // trim white spaces
812
  if (preg_match("/fee percent/", $mathString)){
813
  $shipcost_piece = explode("+", $mathString);
814
  $mathString = trim($shipcost_piece[0]);
906
  }
907
  }
908
  }
909
+
910
+ if(strlen($shipping_cost) > 0){
911
+ $zone_details['price'] = trim($currency." ".$shipping_cost);
912
+ } else {
913
+ unset($zone_details);
914
+ unset($shipping_cost);
915
+ }
916
  }
917
 
918
  // This shipping zone has postal codes so multiply the zone details
1797
  $orderby = "DESC";
1798
  }
1799
 
 
 
 
1800
  // Switch to configured WPML lamguage
1801
  if(isset($project_config['WPML'])){
1802
  if ( function_exists('icl_object_id') ) {
1806
  }
1807
  }
1808
 
1809
+ // Get Orders
1810
+ if(isset($project_config['total_product_orders_lookback'])){
1811
+ if($project_config['total_product_orders_lookback'] > 0){
1812
+ $allowed_product_orders = $this->woosea_get_orders ( $project_config );
1813
+ }
1814
+ }
1815
+
1816
  // Construct WP query
1817
  $wp_query = array(
1818
  'posts_per_page' => $offset_step_size,
1851
  if($status != "publish") { continue; }
1852
 
1853
  $product_data['id'] = get_the_ID();
1854
+
1855
+ // Only products that have been sold are allowed to go through
1856
+ if(isset($project_config['total_product_orders_lookback'])){
1857
+ if($project_config['total_product_orders_lookback'] > 0){
1858
+ if(!in_array($product_data['id'], $allowed_product_orders)){ continue; }
1859
+ }
1860
+ }
1861
+
1862
  $product_data['title'] = $product->get_title();
1863
  $product_data['title'] = $this->woosea_utf8_for_xml( $product_data['title'] );
1864
  $product_data['mother_title'] = $product->get_title();
2620
 
2621
  // Get number of orders for this product
2622
  $product_data['total_product_orders'] = 0;
2623
+ $sales_array = $this->woosea_get_nr_orders_variation ( $product_data['id'] );
2624
+ $product_data['total_product_orders'] = $sales_array[0];
2625
 
2626
  $visibility_list = wp_get_post_terms($product_data['item_group_id'], 'product_visibility', array("fields" => "all"));
2627
  foreach($visibility_list as $visibility_single){
js/woosea_key.js CHANGED
@@ -27,7 +27,7 @@ jQuery(document).ready(function($) {
27
  var license_key = $('#license-key').val();
28
 
29
  jQuery.ajax({
30
- url: 'https://www.adtribes.io/check/license.php?key=' + license_key + '&email=' + license_email + '&domain=' + root_domain + '&version=7.3.2',
31
  jsonp: 'callback',
32
  dataType: 'jsonp',
33
  type: 'GET',
27
  var license_key = $('#license-key').val();
28
 
29
  jQuery.ajax({
30
+ url: 'https://www.adtribes.io/check/license.php?key=' + license_key + '&email=' + license_email + '&domain=' + root_domain + '&version=7.3.3',
31
  jsonp: 'callback',
32
  dataType: 'jsonp',
33
  type: 'GET',
pages/admin/woosea-generate-feed-step-5.php CHANGED
@@ -39,12 +39,13 @@ if (array_key_exists('project_hash', $_GET)){
39
  $project['utm_content'] = "";
40
  $project['utm_on'] = "on";
41
  $project['adtribes_conversion'] = "on";
 
42
  }
43
  ?>
44
  <div class="wrap">
45
  <div class="woo-product-feed-pro-form-style-2">
46
  <tbody class="woo-product-feed-pro-body">
47
- <div class="woo-product-feed-pro-form-style-2-heading"><?php _e( 'Google Analytics settings','woo-product-feed-pro' );?></div>
48
 
49
  <div class="<?php _e($notifications_box['message_type']); ?>">
50
  <p><?php _e($notifications_box['message'], 'sample-text-domain' ); ?></p>
@@ -105,6 +106,11 @@ if (array_key_exists('project_hash', $_GET)){
105
  <td><span><?php _e( 'Google Analytics campaign content (utm_content)','woo-product-feed-pro' );?>:</span></td>
106
  <td><input type="text" class="input-field" name="utm_content" value="<?php print "$project[utm_content]";?>" /></td>
107
  </tr>
 
 
 
 
 
108
  <tr>
109
  <td colspan="2">
110
  <?php
39
  $project['utm_content'] = "";
40
  $project['utm_on'] = "on";
41
  $project['adtribes_conversion'] = "on";
42
+ $project['total_product_orders_lookback'] = "";
43
  }
44
  ?>
45
  <div class="wrap">
46
  <div class="woo-product-feed-pro-form-style-2">
47
  <tbody class="woo-product-feed-pro-body">
48
+ <div class="woo-product-feed-pro-form-style-2-heading"><?php _e( 'Conversion & Google Analytics settings','woo-product-feed-pro' );?></div>
49
 
50
  <div class="<?php _e($notifications_box['message_type']); ?>">
51
  <p><?php _e($notifications_box['message'], 'sample-text-domain' ); ?></p>
106
  <td><span><?php _e( 'Google Analytics campaign content (utm_content)','woo-product-feed-pro' );?>:</span></td>
107
  <td><input type="text" class="input-field" name="utm_content" value="<?php print "$project[utm_content]";?>" /></td>
108
  </tr>
109
+ <tr>
110
+ <td><span><?php _e( 'Remove products that did not have sales in the last days','woo-product-feed-pro' );?>: <a href="https://adtribes.io/create-feed-performing-products/" target="_blank">What does this do?</a></span></td>
111
+ <td><input type="text" class="input-field" name="total_product_orders_lookback" value="<?php print "$project[total_product_orders_lookback]";?>" /> days</td>
112
+ </tr>
113
+
114
  <tr>
115
  <td colspan="2">
116
  <?php
pages/admin/woosea-manage-feed.php CHANGED
@@ -232,7 +232,7 @@ if (!wp_next_scheduled( 'woosea_cron_hook' ) ) {
232
  }
233
  ?>
234
  <span class="dashicons dashicons-arrow-right" style="display: inline-block;"></span> <a href="admin.php?page=woo-product-feed-pro%2Fwoocommerce-sea.php&action=edit_project&step=4&project_hash=<?php print "$val[project_hash]";?>&channel_hash=<?php print "$val[channel_hash]";?>"><?php _e( 'Feed filters and rules','woo-product-feed-pro' );?></a><br/>
235
- <span class="dashicons dashicons-arrow-right" style="display: inline-block;"></span> <a href="admin.php?page=woo-product-feed-pro%2Fwoocommerce-sea.php&action=edit_project&step=5&project_hash=<?php print "$val[project_hash]";?>&channel_hash=<?php print "$val[channel_hash]";?>"><?php _e( 'Google Analytics settings' );?></a><br/>
236
  </td>
237
  </tr>
238
  <?php
232
  }
233
  ?>
234
  <span class="dashicons dashicons-arrow-right" style="display: inline-block;"></span> <a href="admin.php?page=woo-product-feed-pro%2Fwoocommerce-sea.php&action=edit_project&step=4&project_hash=<?php print "$val[project_hash]";?>&channel_hash=<?php print "$val[channel_hash]";?>"><?php _e( 'Feed filters and rules','woo-product-feed-pro' );?></a><br/>
235
+ <span class="dashicons dashicons-arrow-right" style="display: inline-block;"></span> <a href="admin.php?page=woo-product-feed-pro%2Fwoocommerce-sea.php&action=edit_project&step=5&project_hash=<?php print "$val[project_hash]";?>&channel_hash=<?php print "$val[channel_hash]";?>"><?php _e( 'Conversion & Google Analytics settings' );?></a><br/>
236
  </td>
237
  </tr>
238
  <?php
readme.txt CHANGED
@@ -5,7 +5,7 @@ License URI: http://www.gnu.org/licenses/gpl.html
5
  Tags: Product Feed, Google Shopping, Google Shopping Feed, WooCommerce Product Feed, WooCommerce Product Feed PRO, Bing Shopping, Bing product feed, Bing remarking, Google Merchant Feed, Google DRM Feed, Google Dynamic Remarketing Feed, Facebook feed, Google feed, Bing feed, Facebook Product Feed, Facebook Dynamic remarketing, Data Feed, WooCommerce Feed, XML product feed, CSV product feed, TSV, TXT product feed, comparison shopping engines, comparison shopping websites, vergelijk.nl, vergelijk.be, vertaa.fi, beslist.nl, kieskeurig.nl, bol.com, raketten, pricerunner, pricegrabber, Buy, leGuide, Kelkoo, Twenga, Yandex, Etsy, Dealtime, Shopzilla, Billiger, Google Product Review feed
6
  Requires at least: 4.5
7
  Tested up to: 5.3
8
- Stable tag: 7.3.2
9
 
10
  == Description ==
11
 
@@ -309,6 +309,10 @@ Questions left or unanswered? Please do not hesitate to contact us at support@ad
309
 
310
  === Changelog ===
311
 
 
 
 
 
312
  = 7.3.2 (2020-01-26) =
313
  * Added a new attribute to the plugin: "Total product orders" which holds the amount of times the specific product is sold. This enables you to create filters and rules on it.
314
 
@@ -2321,6 +2325,10 @@ Questions left or unanswered? Please do not hesitate to contact us at support@ad
2321
 
2322
  == Upgrade Notice ==
2323
 
 
 
 
 
2324
  = 7.3.2 =
2325
  Added a new attribute to the plugin: "Total product orders" which holds the amount of times the specific product is sold. This enables you to create filters and rules on it.
2326
 
5
  Tags: Product Feed, Google Shopping, Google Shopping Feed, WooCommerce Product Feed, WooCommerce Product Feed PRO, Bing Shopping, Bing product feed, Bing remarking, Google Merchant Feed, Google DRM Feed, Google Dynamic Remarketing Feed, Facebook feed, Google feed, Bing feed, Facebook Product Feed, Facebook Dynamic remarketing, Data Feed, WooCommerce Feed, XML product feed, CSV product feed, TSV, TXT product feed, comparison shopping engines, comparison shopping websites, vergelijk.nl, vergelijk.be, vertaa.fi, beslist.nl, kieskeurig.nl, bol.com, raketten, pricerunner, pricegrabber, Buy, leGuide, Kelkoo, Twenga, Yandex, Etsy, Dealtime, Shopzilla, Billiger, Google Product Review feed
6
  Requires at least: 4.5
7
  Tested up to: 5.3
8
+ Stable tag: 7.3.3
9
 
10
  == Description ==
11
 
309
 
310
  === Changelog ===
311
 
312
+ = 7.3.3 (2020-01-28) =
313
+ * New feature: you can now decide to only allow products to your feed that have been sold before (and amounts) and indicate a time period that should be taken into account for this.
314
+ * When a shipping method and zone was configured but no shipping cost was set an empty prices shipping node was added to feeds which caused warnings in Google's merchant center. This has been solved now.
315
+
316
  = 7.3.2 (2020-01-26) =
317
  * Added a new attribute to the plugin: "Total product orders" which holds the amount of times the specific product is sold. This enables you to create filters and rules on it.
318
 
2325
 
2326
  == Upgrade Notice ==
2327
 
2328
+ = 7.3.3 =
2329
+ New feature: you can now decide to only allow products to your feed that have been sold before (and amounts) and indicate a time period that should be taken into account for this.
2330
+ When a shipping method and zone was configured but no shipping cost was set an empty prices shipping node was added to feeds which caused warnings in Google's merchant center. This has been solved now.
2331
+
2332
  = 7.3.2 =
2333
  Added a new attribute to the plugin: "Total product orders" which holds the amount of times the specific product is sold. This enables you to create filters and rules on it.
2334
 
woocommerce-sea.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
  /**
3
  * Plugin Name: Product Feed PRO for WooCommerce
4
- * Version: 7.3.2
5
  * Plugin URI: https://www.adtribes.io/support/?utm_source=wpadmin&utm_medium=plugin&utm_campaign=woosea_product_feed_pro
6
  * Description: Configure and maintain your WooCommerce product feeds for Google Shopping, Facebook, Remarketing, Bing, Yandex, Comparison shopping websites and over a 100 channels more.
7
  * Author: AdTribes.io
@@ -48,7 +48,7 @@ if (!defined('ABSPATH')) {
48
  * Plugin versionnumber, please do not override.
49
  * Define some constants
50
  */
51
- define( 'WOOCOMMERCESEA_PLUGIN_VERSION', '7.3.2' );
52
  define( 'WOOCOMMERCESEA_PLUGIN_NAME', 'woocommerce-product-feed-pro' );
53
  define( 'WOOCOMMERCESEA_PLUGIN_NAME_SHORT', 'woo-product-feed-pro' );
54
 
@@ -91,6 +91,7 @@ function woosea_scripts($hook) {
91
  wp_enqueue_script('jquery');
92
  wp_enqueue_script('jquery-ui-dialog');
93
  wp_enqueue_script('jquery-ui-calender');
 
94
 
95
  // Only register and enqueue JS scripts from within the plugin itself
96
  if (preg_match("/product-feed-pro/i",$hook)){
1
  <?php
2
  /**
3
  * Plugin Name: Product Feed PRO for WooCommerce
4
+ * Version: 7.3.3
5
  * Plugin URI: https://www.adtribes.io/support/?utm_source=wpadmin&utm_medium=plugin&utm_campaign=woosea_product_feed_pro
6
  * Description: Configure and maintain your WooCommerce product feeds for Google Shopping, Facebook, Remarketing, Bing, Yandex, Comparison shopping websites and over a 100 channels more.
7
  * Author: AdTribes.io
48
  * Plugin versionnumber, please do not override.
49
  * Define some constants
50
  */
51
+ define( 'WOOCOMMERCESEA_PLUGIN_VERSION', '7.3.3' );
52
  define( 'WOOCOMMERCESEA_PLUGIN_NAME', 'woocommerce-product-feed-pro' );
53
  define( 'WOOCOMMERCESEA_PLUGIN_NAME_SHORT', 'woo-product-feed-pro' );
54
 
91
  wp_enqueue_script('jquery');
92
  wp_enqueue_script('jquery-ui-dialog');
93
  wp_enqueue_script('jquery-ui-calender');
94
+ wp_enqueue_script('jquery-ui-datepicker');
95
 
96
  // Only register and enqueue JS scripts from within the plugin itself
97
  if (preg_match("/product-feed-pro/i",$hook)){