CTX Feed – WooCommerce Product Feed Manager Plugin - Version 4.4.64

Version Description

(2022-05-30) = * Added: Securing, Fixing Some input-output P2

Download this release

Release Info

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

Code changes from version 4.4.63 to 4.4.64

README.txt CHANGED
@@ -5,7 +5,7 @@ Tags: WooCommerce Product Feed, WooCommerce, Google Shopping, Google Merchant, F
5
  Requires at least: 4.4
6
  Tested Up To: 5.9
7
  Requires PHP: 5.6
8
- Stable tag: 4.4.63
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -590,7 +590,10 @@ Using pro version:
590
 
591
  == Changelog ==
592
 
593
- = 4.4.62 (2022-05-26) =
 
 
 
594
  * Added: added filter to secure input-output P1
595
 
596
  = 4.4.62 (2022-05-25) =
5
  Requires at least: 4.4
6
  Tested Up To: 5.9
7
  Requires PHP: 5.6
8
+ Stable tag: 4.4.64
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
590
 
591
  == Changelog ==
592
 
593
+ = 4.4.64 (2022-05-30) =
594
+ * Added: Securing, Fixing Some input-output P2
595
+
596
+ = 4.4.63 (2022-05-26) =
597
  * Added: added filter to secure input-output P1
598
 
599
  = 4.4.62 (2022-05-25) =
admin/class-woo-feed-admin.php CHANGED
@@ -106,10 +106,12 @@ class Woo_Feed_Admin {
106
 
107
  //dequeue unnecessary scripts from loading
108
  $js_dequeue_handles = woo_feed_get_js_dequeue_handles_list();
109
- if ( isset($_GET['page']) ) {
 
 
110
  $woo_feed_plugin_pages = woo_feed_get_plugin_pages_slugs();
111
 
112
- if ( in_array($_GET['page'], $woo_feed_plugin_pages) ) {
113
  if ( isset($js_dequeue_handles) && ! empty($js_dequeue_handles) ) {
114
  foreach ( $js_dequeue_handles as $script_handle ) {
115
  wp_dequeue_script($script_handle);
@@ -151,14 +153,18 @@ class Woo_Feed_Admin {
151
 
152
  //get feed options with which feed is previously generated
153
  $feed_rules = "";
154
- if ( isset($_GET['feed']) ) {
155
- $filename = str_replace('wf_feed_', '', wp_unslash($_GET['feed']));
 
 
156
  $feed_options = maybe_unserialize(get_option('wf_feed_' . $filename));
157
  if ( isset($feed_options['feedrules']) ) {
158
  $feed_rules = $feed_options['feedrules'];
159
  }
160
  }
161
 
 
 
162
  $js_opts = array(
163
  'wpf_ajax_url' => admin_url( 'admin-ajax.php' ),
164
  'wpf_debug' => woo_feed_is_debugging_enabled(),
@@ -169,8 +175,8 @@ class Woo_Feed_Admin {
169
  ],
170
  ],
171
  'nonce' => wp_create_nonce( 'wpf_feed_nonce' ),
172
- 'is_feed_edit' => isset( $_GET['page'], $_GET['action'] ) && 'webappick-manage-feeds' === $_GET['page'] && 'edit-feed' === $_GET['action'], // phpcs:ignore WordPress.Security.NonceVerification.Recommended
173
- 'is_feed_add' => isset( $_GET['page'] ) && 'webappick-new-feed' === $_GET['page'], // phpcs:ignore WordPress.Security.NonceVerification.Recommended
174
  'na' => esc_html__( 'N/A', 'woo-feed' ),
175
  'regenerate' => esc_html__( 'Generating...', 'woo-feed' ),
176
  'learn_more' => esc_html__( 'Learn More..', 'woo-feed' ),
@@ -204,10 +210,17 @@ class Woo_Feed_Admin {
204
  'dimension' => get_option('woocommerce_dimension_unit'),
205
  ],
206
  );
 
 
 
 
 
 
 
207
  // phpcs:ignore WordPress.Security.NonceVerification.Recommended
208
- if ( ( isset( $_GET['feed_created'] ) || isset( $_GET['feed_updated'] ) || isset( $_GET['feed_imported'] ) ) && isset( $_GET['feed_regenerate'] ) && 1 === (int) $_GET['feed_regenerate'] ) {
209
  // phpcs:ignore WordPress.Security.NonceVerification.Recommended
210
- $fileName = isset( $_GET['feed_name'] ) && ! empty( $_GET['feed_name'] ) ? sanitize_text_field( wp_unslash($_GET['feed_name']) ) : ''; // trigger feed regenerate...
211
  if ( ! empty( $fileName ) ) {
212
  // filename must be wf_config+XXX format for js to work.
213
  $js_opts['generator']['feed'] = 'wf_config' . woo_feed_extract_feed_option_name( $fileName );
106
 
107
  //dequeue unnecessary scripts from loading
108
  $js_dequeue_handles = woo_feed_get_js_dequeue_handles_list();
109
+
110
+ $page = apply_filters('CTXFEED_filter_securing_input', "GET", @$_GET['page'], "text");
111
+ if ( $page ) {
112
  $woo_feed_plugin_pages = woo_feed_get_plugin_pages_slugs();
113
 
114
+ if ( in_array($page, $woo_feed_plugin_pages) ) {
115
  if ( isset($js_dequeue_handles) && ! empty($js_dequeue_handles) ) {
116
  foreach ( $js_dequeue_handles as $script_handle ) {
117
  wp_dequeue_script($script_handle);
153
 
154
  //get feed options with which feed is previously generated
155
  $feed_rules = "";
156
+
157
+ $feed = apply_filters('CTXFEED_filter_securing_input', "GET", @$_GET['feed'], "text");
158
+ if ( $feed ) {
159
+ $filename = str_replace('wf_feed_', '', wp_unslash($feed));
160
  $feed_options = maybe_unserialize(get_option('wf_feed_' . $filename));
161
  if ( isset($feed_options['feedrules']) ) {
162
  $feed_rules = $feed_options['feedrules'];
163
  }
164
  }
165
 
166
+ $page = apply_filters('CTXFEED_filter_securing_input', "GET", @$_GET['page'], "text");
167
+ $action = apply_filters('CTXFEED_filter_securing_input', "GET", @$_GET['action'], "text");
168
  $js_opts = array(
169
  'wpf_ajax_url' => admin_url( 'admin-ajax.php' ),
170
  'wpf_debug' => woo_feed_is_debugging_enabled(),
175
  ],
176
  ],
177
  'nonce' => wp_create_nonce( 'wpf_feed_nonce' ),
178
+ 'is_feed_edit' => $page && $action && 'webappick-manage-feeds' === $page && 'edit-feed' === $page, // phpcs:ignore WordPress.Security.NonceVerification.Recommended
179
+ 'is_feed_add' => $page && 'webappick-new-feed' === $page, // phpcs:ignore WordPress.Security.NonceVerification.Recommended
180
  'na' => esc_html__( 'N/A', 'woo-feed' ),
181
  'regenerate' => esc_html__( 'Generating...', 'woo-feed' ),
182
  'learn_more' => esc_html__( 'Learn More..', 'woo-feed' ),
210
  'dimension' => get_option('woocommerce_dimension_unit'),
211
  ],
212
  );
213
+
214
+ $feed_created = apply_filters('CTXFEED_filter_securing_input', "GET", @$_GET['feed_created'], "text");
215
+ $feed_updated = apply_filters('CTXFEED_filter_securing_input', "GET", @$_GET['feed_updated'], "text");
216
+ $feed_imported = apply_filters('CTXFEED_filter_securing_input', "GET", @$_GET['feed_imported'], "text");
217
+ $feed_regenerate = apply_filters('CTXFEED_filter_securing_input', "GET", @$_GET['feed_regenerate'], "text");
218
+ $feed_name = apply_filters('CTXFEED_filter_securing_input', "GET", @$_GET['feed_name'], "file_name");
219
+
220
  // phpcs:ignore WordPress.Security.NonceVerification.Recommended
221
+ if ( ( $feed_created || $feed_updated || $feed_imported ) && $feed_regenerate && 1 === (int) $feed_regenerate ) {
222
  // phpcs:ignore WordPress.Security.NonceVerification.Recommended
223
+ $fileName = ! empty( $feed_name ) ? wp_unslash($feed_name) : ''; // trigger feed regenerate...
224
  if ( ! empty( $fileName ) ) {
225
  // filename must be wf_config+XXX format for js to work.
226
  $js_opts['generator']['feed'] = 'wf_config' . woo_feed_extract_feed_option_name( $fileName );
admin/class-woo-feed-category-list.php CHANGED
@@ -317,7 +317,8 @@ class Woo_Feed_Category_list extends Woo_Feed_List_Table {
317
  wp_safe_redirect( admin_url( 'admin.php?page=webappick-feed-category-mapping&wpf_message=error' ) );
318
  die();
319
  } else {
320
- if ( isset( $_GET['cmapping'] ) && self::delete_mapping( absint( $_GET['cmapping'] ) ) ) {
 
321
  update_option( 'wpf_message', esc_html__( 'Mapping Deleted Successfully', 'woo-feed' ), false );
322
  wp_safe_redirect( admin_url( 'admin.php?page=webappick-feed-category-mapping&wpf_message=success' ) );
323
  die();
@@ -335,12 +336,15 @@ class Woo_Feed_Category_list extends Woo_Feed_List_Table {
335
  wp_die( esc_html__( 'You do not have sufficient permission to delete!', 'woo-feed' ), 403 );
336
  }
337
  }
338
- $mapping = array_map( 'sanitize_text_field', isset( $_POST['mapping'] ) && is_array($_POST['mapping']) ? $_POST['mapping'] : [] );
339
- $action = sanitize_text_field( isset( $_POST['action'] ) ? $_POST['action'] : '' ) ;
340
- $action2 = sanitize_text_field( isset( $_POST['action2'] ) ? $_POST['action2'] : '' );
 
 
341
 
342
  // If the delete bulk action is triggered
343
- if ( ! empty($mapping) && ( 'bulk-delete' === $action || 'bulk-delete' === $action2 )) {
 
344
  if ( 'bulk-delete' === $this->current_action() ) {
345
  if ( ! wp_verify_nonce( $nonce, 'bulk-' . $this->_args['plural'] ) ) {
346
  update_option( 'wpf_message', esc_html__( 'Failed To Delete Mapping. You do not have sufficient permission to delete.', 'woo-feed' ), false );
317
  wp_safe_redirect( admin_url( 'admin.php?page=webappick-feed-category-mapping&wpf_message=error' ) );
318
  die();
319
  } else {
320
+ $cmapping = apply_filters('CTXFEED_filter_securing_input', "GET", @$_GET['cmapping'], "text");
321
+ if ( $cmapping && self::delete_mapping( absint( $cmapping) ) ) {
322
  update_option( 'wpf_message', esc_html__( 'Mapping Deleted Successfully', 'woo-feed' ), false );
323
  wp_safe_redirect( admin_url( 'admin.php?page=webappick-feed-category-mapping&wpf_message=success' ) );
324
  die();
336
  wp_die( esc_html__( 'You do not have sufficient permission to delete!', 'woo-feed' ), 403 );
337
  }
338
  }
339
+ $mapping = array_map( function ($input) {
340
+ return apply_filters('CTXFEED_filter_securing_input', "POST", $input, "text");
341
+ }, is_array(@$_POST['mapping']) ? $_POST['mapping'] : [] );
342
+ $action = apply_filters('CTXFEED_filter_securing_input', "POST", @$_POST['action'], "text");
343
+ $action2 = apply_filters('CTXFEED_filter_securing_input', "POST", @$_POST['action2'], "text");
344
 
345
  // If the delete bulk action is triggered
346
+ if ( ! empty($mapping)
347
+ && ( 'bulk-delete' === $action || 'bulk-delete' === $action2 )) {
348
  if ( 'bulk-delete' === $this->current_action() ) {
349
  if ( ! wp_verify_nonce( $nonce, 'bulk-' . $this->_args['plural'] ) ) {
350
  update_option( 'wpf_message', esc_html__( 'Failed To Delete Mapping. You do not have sufficient permission to delete.', 'woo-feed' ), false );
admin/class-woo-feed-manage-list.php CHANGED
@@ -384,7 +384,9 @@ class Woo_Feed_Manage_list extends Woo_Feed_List_Table {
384
  wp_safe_redirect( admin_url( 'admin.php?page=webappick-manage-feeds&wpf_message=error' ) );
385
  die();
386
  } else {
387
- if ( isset( $_GET['feed'] ) && self::delete_feed( absint( $_GET['feed'] ) ) ) {
 
 
388
  update_option( 'wpf_message', esc_html__( 'Feed Deleted Successfully', 'woo-feed' ), false );
389
  wp_safe_redirect( admin_url( 'admin.php?page=webappick-manage-feeds&wpf_message=success' ) );
390
  die();
@@ -425,9 +427,11 @@ class Woo_Feed_Manage_list extends Woo_Feed_List_Table {
425
  }
426
  }
427
 
428
- $feed = array_map( 'sanitize_text_field', isset( $_POST['feed'] ) && is_array($_POST['feed']) ? $_POST['feed'] : [] );
429
- $action = sanitize_text_field( isset( $_POST['action'] ) ? $_POST['action'] : '' ) ;
430
- $action2 = sanitize_text_field( isset( $_POST['action2'] ) ? $_POST['action2'] : '' );
 
 
431
 
432
  // If the delete bulk action is triggered
433
  if ( ! empty($feed) && ( 'bulk-delete' === $action || 'bulk-delete' === $action2) ) {
384
  wp_safe_redirect( admin_url( 'admin.php?page=webappick-manage-feeds&wpf_message=error' ) );
385
  die();
386
  } else {
387
+ $feed = apply_filters('CTXFEED_filter_securing_input', "GET", @$_GET['feed'], "text");
388
+
389
+ if ( $feed && self::delete_feed( absint( $feed ) ) ) {
390
  update_option( 'wpf_message', esc_html__( 'Feed Deleted Successfully', 'woo-feed' ), false );
391
  wp_safe_redirect( admin_url( 'admin.php?page=webappick-manage-feeds&wpf_message=success' ) );
392
  die();
427
  }
428
  }
429
 
430
+ $feed = array_map( function ($input) {
431
+ return apply_filters('CTXFEED_filter_securing_input', "POST", $input, "text");
432
+ }, is_array(@$_POST['feed']) ? $_POST['feed'] : [] );
433
+ $action = apply_filters('CTXFEED_filter_securing_input', "POST", @$_POST['action'], "text");
434
+ $action2 = apply_filters('CTXFEED_filter_securing_input', "POST", @$_POST['action2'], "text");
435
 
436
  // If the delete bulk action is triggered
437
  if ( ! empty($feed) && ( 'bulk-delete' === $action || 'bulk-delete' === $action2) ) {
admin/class-woo-feed-option-list.php CHANGED
@@ -317,7 +317,8 @@ class Woo_Feed_Option_list extends Woo_Feed_List_Table {
317
  wp_safe_redirect( admin_url( 'admin.php?page=webappick-wp-options&wpf_message=error' ) );
318
  die();
319
  } else {
320
- if ( isset( $_GET['option'] ) && self::delete_option( $_GET['option'] ) ) {
 
321
  update_option( 'wpf_message', esc_html__( 'Option Deleted Successfully.', 'woo-feed' ), false );
322
  wp_safe_redirect( admin_url( 'admin.php?page=webappick-wp-options&wpf_message=success' ) );
323
  die();
@@ -337,9 +338,12 @@ class Woo_Feed_Option_list extends Woo_Feed_List_Table {
337
  }
338
  }
339
 
340
- $option = array_map( 'sanitize_text_field', isset( $_POST['option'] ) && is_array($_POST['option']) ? $_POST['option'] : [] );
341
- $action = sanitize_text_field( isset( $_POST['action'] ) ? $_POST['action'] : '' ) ;
342
- $action2 = sanitize_text_field( isset( $_POST['action2'] ) ? $_POST['action2'] : '' );
 
 
 
343
  // If the delete bulk action is triggered
344
  if (
345
  ! empty( $option )
317
  wp_safe_redirect( admin_url( 'admin.php?page=webappick-wp-options&wpf_message=error' ) );
318
  die();
319
  } else {
320
+ $option = apply_filters('CTXFEED_filter_securing_input', "GET", @$_GET['option'], "text");
321
+ if ( $option && self::delete_option( $option ) ) {
322
  update_option( 'wpf_message', esc_html__( 'Option Deleted Successfully.', 'woo-feed' ), false );
323
  wp_safe_redirect( admin_url( 'admin.php?page=webappick-wp-options&wpf_message=success' ) );
324
  die();
338
  }
339
  }
340
 
341
+ $option = array_map( function ($input) {
342
+ return apply_filters('CTXFEED_filter_securing_input', "POST", $input, "text");
343
+ }, is_array(@$_POST['option']) ? $_POST['option'] : [] );
344
+
345
+ $action = apply_filters('CTXFEED_filter_securing_input', "POST", @$_POST['action'], "text");
346
+ $action2 = apply_filters('CTXFEED_filter_securing_input', "POST", @$_POST['action2'], "text");
347
  // If the delete bulk action is triggered
348
  if (
349
  ! empty( $option )
admin/js/woo-feed-admin.js CHANGED
@@ -1258,7 +1258,7 @@
1258
  if (type === 'csv' || type === 'txt' || type === 'tsv') {
1259
  wf_csv_txt.show();
1260
  itemWrapper.hide();
1261
-
1262
  if( 'tsv' === type ) {
1263
  $('#delimiter option:last').prop("selected", "selected");
1264
  } else if( 'csv' === type ) {
@@ -1340,18 +1340,17 @@
1340
  if( googleMap.indexOf(provider) !== -1 ) {
1341
  $('input[id*="cat_mapping_"]').css('display', 'none');
1342
  $('.wf_default.wf_attributes').css('display', 'block').css('width', '100%');
1343
-
1344
- var cat_init = new WooFeedMapCategories();
1345
- if( "facebook" === provider ) {
1346
- cat_init.wooFeed_get_facebook_categories();
1347
- } else {
1348
- cat_init.wooFeed_get_google_categories();
1349
- }
1350
-
1351
- } else {
1352
- $('input[id*="cat_mapping_"]').css('display', 'block');
1353
- $('.wf_default.wf_attributes').css('display', 'none').css('width', '100%');
1354
- }
1355
  })
1356
 
1357
  // Copy parent category ids to child categories.
@@ -1379,11 +1378,10 @@
1379
  });
1380
 
1381
  $(document).ready(function () {
1382
- var provider = $("#providers").val();
1383
- var cat_init = new WooFeedMapCategories();
1384
-
1385
- var url = new URL(window.location.href);
1386
- var cat_mapping_action = url.searchParams.get("action");
1387
 
1388
  if( "edit-mapping" === cat_mapping_action ) {
1389
  $('.woo-feed-category-mapping-config-table').prepend('<div class="woo-feed-cat-map-spinner"><h3><span style="float:none;margin: -3px 0 0;" class="spinner is-active"></span> Loading Mapping...</h3></div>');
@@ -1393,8 +1391,8 @@
1393
  } else {
1394
  cat_init.wooFeed_get_google_categories();
1395
  }
1396
- }
1397
 
 
1398
  });
1399
 
1400
  /*
@@ -1429,23 +1427,17 @@
1429
 
1430
  function update_postfix(){
1431
  var attribute_list = {
1432
-
1433
  'price': wpf_ajax_obj.woocommerce.currency,
1434
  'current_price': wpf_ajax_obj.woocommerce.currency,
1435
  'sale_price': wpf_ajax_obj.woocommerce.currency,
1436
  'price_with_tax': wpf_ajax_obj.woocommerce.currency,
1437
  'current_price_with_tax': wpf_ajax_obj.woocommerce.currency,
1438
  'sale_price_with_tax': wpf_ajax_obj.woocommerce.currency,
1439
-
1440
-
1441
  'weight': wpf_ajax_obj.woocommerce.weight,
1442
  'weight_unit': wpf_ajax_obj.woocommerce.weight,
1443
-
1444
-
1445
  'height': wpf_ajax_obj.woocommerce.dimension,
1446
  'length': wpf_ajax_obj.woocommerce.dimension,
1447
  'width': wpf_ajax_obj.woocommerce.dimension
1448
-
1449
  };
1450
 
1451
  if (typeof wpf_ajax_obj.feed_rules !== 'undefined' && wpf_ajax_obj.feed_rules !== null) {
@@ -1458,10 +1450,10 @@
1458
  var urlParams = new URLSearchParams(queryString);
1459
  var action = urlParams.get('action');
1460
 
1461
- $( '.wf_attr.wf_attributes' ).each( function( key, value){
1462
 
1463
  var attribute_value = $(value).val();
1464
- var current_Value = $( 'input[name^="suffix"]' ).eq( parseInt( key ) ).val();
1465
 
1466
  if( -1 !== $.inArray( current_Value, [
1467
  ' ' + wpf_ajax_obj.woocommerce.currency,
1258
  if (type === 'csv' || type === 'txt' || type === 'tsv') {
1259
  wf_csv_txt.show();
1260
  itemWrapper.hide();
1261
+
1262
  if( 'tsv' === type ) {
1263
  $('#delimiter option:last').prop("selected", "selected");
1264
  } else if( 'csv' === type ) {
1340
  if( googleMap.indexOf(provider) !== -1 ) {
1341
  $('input[id*="cat_mapping_"]').css('display', 'none');
1342
  $('.wf_default.wf_attributes').css('display', 'block').css('width', '100%');
1343
+ var cat_init = new WooFeedMapCategories();
1344
+ if( "facebook" === provider ) {
1345
+ cat_init.wooFeed_get_facebook_categories();
1346
+ } else {
1347
+ cat_init.wooFeed_get_google_categories();
1348
+ }
1349
+ } else {
1350
+ $('input[id*="cat_mapping_"]').css('display', 'block');
1351
+ $('.wf_default.wf_attributes').css('display', 'none').css('width', '100%');
1352
+ $('.woo-feed-category-mapping-config-table .woo-feed-cat-map-spinner').css('display', 'none');
1353
+ }
 
1354
  })
1355
 
1356
  // Copy parent category ids to child categories.
1378
  });
1379
 
1380
  $(document).ready(function () {
1381
+ var provider = $("#providers").val(),
1382
+ cat_init = new WooFeedMapCategories(),
1383
+ url = new URL(window.location.href),
1384
+ cat_mapping_action = url.searchParams.get("action");
 
1385
 
1386
  if( "edit-mapping" === cat_mapping_action ) {
1387
  $('.woo-feed-category-mapping-config-table').prepend('<div class="woo-feed-cat-map-spinner"><h3><span style="float:none;margin: -3px 0 0;" class="spinner is-active"></span> Loading Mapping...</h3></div>');
1391
  } else {
1392
  cat_init.wooFeed_get_google_categories();
1393
  }
 
1394
 
1395
+ }
1396
  });
1397
 
1398
  /*
1427
 
1428
  function update_postfix(){
1429
  var attribute_list = {
 
1430
  'price': wpf_ajax_obj.woocommerce.currency,
1431
  'current_price': wpf_ajax_obj.woocommerce.currency,
1432
  'sale_price': wpf_ajax_obj.woocommerce.currency,
1433
  'price_with_tax': wpf_ajax_obj.woocommerce.currency,
1434
  'current_price_with_tax': wpf_ajax_obj.woocommerce.currency,
1435
  'sale_price_with_tax': wpf_ajax_obj.woocommerce.currency,
 
 
1436
  'weight': wpf_ajax_obj.woocommerce.weight,
1437
  'weight_unit': wpf_ajax_obj.woocommerce.weight,
 
 
1438
  'height': wpf_ajax_obj.woocommerce.dimension,
1439
  'length': wpf_ajax_obj.woocommerce.dimension,
1440
  'width': wpf_ajax_obj.woocommerce.dimension
 
1441
  };
1442
 
1443
  if (typeof wpf_ajax_obj.feed_rules !== 'undefined' && wpf_ajax_obj.feed_rules !== null) {
1450
  var urlParams = new URLSearchParams(queryString);
1451
  var action = urlParams.get('action');
1452
 
1453
+ $('.wf_attr.wf_attributes').each( function( key, value){
1454
 
1455
  var attribute_value = $(value).val();
1456
+ var current_Value = $('input[name^="suffix"]').eq( parseInt( key ) ).val();
1457
 
1458
  if( -1 !== $.inArray( current_Value, [
1459
  ' ' + wpf_ajax_obj.woocommerce.currency,
admin/js/woo-feed-admin.min.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _defineProperties(e,t){for(var o=0;o<t.length;o++){var a=t[o];a.enumerable=a.enumerable||!1,a.configurable=!0,"value"in a&&(a.writable=!0),Object.defineProperty(e,a.key,a)}}function _createClass(e,t,o){return t&&_defineProperties(e.prototype,t),o&&_defineProperties(e,o),e}!function(s,a,c,l,d){s.fn.disabled=function(o){return s(this).each(function(){var e=s(this),t="disabled";void 0!==e.prop(t)?e.prop(t,void 0===o||!0===o):!0===o?e.addClass(t):e.removeClass(t)}),self},s.fn.isDisabled=function(){var e=s(this),t="disabled";return void 0!==e.prop(t)?e.prop(t):e.hasClass(t)};function e(e){s(e.currentTarget).removeClass(function(e,t){return(t.match(/\btooltipped-\S+/g)||[]).join(" ")}).removeClass("tooltipped").removeAttr("aria-label")}function o(e,t){s(e).addClass("tooltipped tooltipped-s").attr("aria-label",t)}function n(e,t){return s.extend(!0,{},e,t)}function t(){i=s(".toClipboard"),!ClipboardJS.isSupported()||/iPhone|iPad/i.test(navigator.userAgent)?i.find("img").hide(0):(i.each(function(){s(this).on("mouseleave",e).on("blur",e)}),new ClipboardJS(".toClipboard").on("error",function(e){var t;o(e.trigger,(t=e.action,e="cut"===t?"X":"C",t=/iPhone|iPad/i.test(navigator.userAgent)?"No support :(":/Mac/i.test(navigator.userAgent)?"Press ⌘-"+e+" to "+t:"Press Ctrl-"+e+" to "+t))}).on("success",function(e){o(e.trigger,"Copied")}))}var i,r,f,_=function(){function a(e,t,o){_classCallCheck(this,a),this.productCustomFields(e,t,o)}return _createClass(a,[{key:"cacheClear",value:function(){var e={action:"woo_feed_product_attribute_cache_remove",nonce:wpf_ajax_obj.ajax.nonce};s.ajax({method:"POST",url:wpf_ajax_obj.wpf_ajax_url,data:e})}},{key:"productCustomFields",value:function(t){var o=this,e={action:"woo_feed_custom_fields_status_change",nonce:wpf_ajax_obj.ajax.nonce,field:t,status:1<arguments.length&&void 0!==arguments[1]&&arguments[1],isTaxonomy:2<arguments.length?arguments[2]:void 0};s.ajax({method:"POST",url:wpf_ajax_obj.wpf_ajax_url,data:e,success:function(e){e.success?o.cacheClear():console.log(e),s("#"+t+"-switcher").closest("td").find(".switch-loader").hide()}})}}]),a}(),p=function(){function e(){_classCallCheck(this,e)}return _createClass(e,[{key:"wooFeed_get_google_categories",value:function(){l.send("get_google_categories",{type:"GET",data:{_ajax_nonce:d.nonce,action:"get_google_categories"}}).then(function(e){s(".selectize-google-category").selectize({valueField:"value",labelField:"text",placeholder:"Select a category",searchField:["value","text"],options:e,render:{option:function(e,t){return'<div class="item wapk-selectize-item">'.concat(t(e.value+" - "+e.text),"</div>")},item:function(e,t){return'<div class="item wapk-selectize-item">'.concat(t(e.value+" - "+e.text),"</div>")}}}),s(".woo-feed-cat-map-spinner").remove()}).fail(u.ajax_fail)}},{key:"wooFeed_get_facebook_categories",value:function(){l.send("get_facebook_categories",{type:"GET",data:{_ajax_nonce:d.nonce,action:"get_facebook_categories"}}).then(function(e){s(".selectize-google-category").selectize({valueField:"value",labelField:"text",placeholder:"Select a Facebook category",searchField:["value","text"],options:e,render:{option:function(e,t){return'<div class="item wapk-selectize-item">'.concat(t(e.value+" - "+e.text),"</div>")},item:function(e,t){return'<div class="item wapk-selectize-item">'.concat(t(e.value+" - "+e.text),"</div>")}}}),s(".woo-feed-cat-map-spinner").remove()}).fail(u.ajax_fail)}}]),e}(),u={in_array:function(e,t){try{return-1!==t.indexOf(e)}catch(e){return!1}},selectize_render_item:function(e,t){return'<div class="item wapk-selectize-item">'.concat(t(e.text),"</div>")},ajax_fail:function(e){console.warn(e),alert(e.hasOwnProperty("statusText")&&e.hasOwnProperty("status")?d.ajax.error+"\n"+e.statusText+" ("+e.status+")":e)},sortable:function(e,o,a,i){return(e||s(".sorted_table")).each(function(){var e=s(this),t=e.find("tbody > tr:eq(0) > td").length||a||9;e.wf_sortable(n({containerSelector:"table",itemPath:"> tbody",itemSelector:"tr",handle:"i.wf_sortedtable",placeholder:'<tr class="placeholder"><td colspan="'.concat(t,'"></td></tr>'),onDrop:function(e,t,o,a){e.removeClass(t.group.options.draggedClass).removeAttr("style"),s("body").removeClass(t.group.options.bodyClass);var n=e.find(".wf_mattributes").attr("name").replace(/\D/g,"");e.find("input.wf_attributes").attr("name","default["+n+"]"),i&&"function"==typeof i&&i(e,t,o,a)}},o))})},selectize:function(e,t){return(e||s("select.selectize")).not(".selectized").not(".selectize-google-category").each(function(){var e=s(this);e.selectize(n({create:e.data("create")||!1,plugins:e.data("plugins")?e.data("plugins").split(",").map(function(e){return e.trim()}):[],render:{item:u.selectize_render_item}},t))})},fancySelect:function(e,t){return(e||s("select.fancySelect")).not(".FancySelectInit").each(function(){s(this).fancySelect(n({maxItemShow:3},t))})},reindex_config_table:function(){s("#table-1").find("tbody tr").each(function(o,e){s(e).find("[name]").each(function(e,t){s(t).attr("name",s(t).attr("name").replace(/(\[\d\])/g,"[".concat(o,"]")))})})},common:function(){u.sortable(s(".sorted_table"),{},9,u.reindex_config_table),u.selectize(),u.fancySelect(s(".outputType"))}},h={form:null,init:function(){this.form=s(".generateFeed"),this.form.length&&(u.common(),s(c).trigger("feed_editor_init"),s(c).trigger(new jQuery.Event("feedEditor.init",{target:this.form})))},renderMerchantInfo:function(o,a,n){for(var e in n)!function(e){var t;n.hasOwnProperty(e)&&(o.find(".merchant-info-section."+e+" .data").html(n[e]),"feed_file_type"===e&&((t=n[e].split(",").map(function(e){return e.trim().toLowerCase()}).filter(function(e){return""!==e&&e!==d.na.toLowerCase()})).length?(a.find("option").removeAttr("selected").each(function(){var e=s(this);e.val()&&!u.in_array(e.val(),t)?e.disabled(!0):e.disabled(!1)}),1===t.length&&a.find('option[value="'+t[0]+'"]').attr("selected","selected")):a.find("option").disabled(!1)))}(e);o.find(".spinner").removeClass("is-active"),a.disabled(!1),a.trigger("change"),s(c).trigger("woo_feed_config_loaded"),a.parent().find(".spinner").removeClass("is-active")},renderMerchantTemplate:function(o,a){for(var e in a)!function(t){var e;a.hasOwnProperty(t)&&("tabs"===t?o.html(a[t]):(e=s('[name="'+t+'"]')).length&&e.each(function(){var e=s(this);e.is("select")?e.find('[value="'+a[t]+'"]').prop("selected",!0):(e.is("[type=checkbox]")||e.is("[type=radio]"))&&e.val()===a[t]?e.prop("checked",!0):e.val(a[t])}).trigger("change"))}(e);h.init()}},g=[],v=[],m=function(){function e(){_classCallCheck(this,e),this._feed=d.generator.feed,this._limit=d.generator.limit,this._progress=0,this._timer=null,this._color=!1,this._total_batch=0,this._current_batch=0,this._product_ids=[],this._progress_per_batch=0,this._refresh=!0,this._regenerate=d.generator.regenerate,a.isRegenerating=!1,this._all_btn=s(".wpf_regenerate"),this._current_btn=s("#".concat(this._feed.replace("wf_config","wf_feed_"))),this._current_btn_label=""}return _createClass(e,[{key:"init",value:function(){var t=this;""!==this._feed&&this._regenerate&&!1===a.isRegenerating&&this.generate();var e=a.location.search;return"webappick-manage-feeds"===new URLSearchParams(e).get("page")&&s("body").addClass("woo-import-popup-body"),s(c).on("click",".woo-feed-campaign-close-button",function(e){e.preventDefault(),s(this).parent(".woo-feed-promotion").hide();e=s(this).data("condition");1===e&&l.post("woo_feed_hide_promotion",{_ajax_nonce:d.nonce,condition:e}).then(function(e){t._log(e)}).fail(function(e){t._log(e),t._updateProgressStatus(e.message),t._color="red"})}),s(c).on("click",".wpf_regenerate",function(e){e.preventDefault(),t._current_btn=s(this),t._current_btn.hasClass("disabled")||!0===a.isRegenerating||(t._feed=t._current_btn.attr("id").replace("wf_feed_","wf_config"),""!==t._feed&&t.generate())}),this}},{key:"_block_button",value:function(){this._all_btn.length&&this._all_btn.addClass("disabled"),this._current_btn.length&&(this._current_btn.find("span").addClass("wpf_spin reverse_spin"),this._current_btn_label=this._current_btn.attr("title"),this._current_btn.attr("aria-label",d.regenerate).attr("title",d.regenerate))}},{key:"_unblock_button",value:function(){this._all_btn.length&&this._all_btn.removeClass("disabled"),this._current_btn.length&&(this._current_btn.find("span").removeClass("wpf_spin"),this._current_btn.find("span").removeClass("reverse_spin"),this._current_btn.attr("aria-label",this._current_btn_label).attr("title",this._current_btn_label))}},{key:"generate",value:function(){var t=this,o=this;a.isRegenerating=!0,this._block_button(),this._resetProgressBar(),this._progressBarActive(),this._log("Counting Total Products"),this._updateProgressStatus("Fetching products."),this._get_product_ids().then(function(e){t._progress=10,o._log({response:e}),e.success?(o._log("Total ".concat(e.total," Products found.")),o._product_ids=e.product,o._total_batch=t._product_ids.length,o._current_batch=0,o._progress_per_batch=(90-t._progress)/t._total_batch,o._process_batch(),o._updateProgressStatus("Processing Products...")):o._updateProgressStatus(e.data.message)}).fail(function(e){o._log(e),o._updateProgressStatus(e.message),o._color="red",setTimeout(function(){o._stopProgressBar(),o._unblock_button()},1500)})}},{key:"_get_product_ids",value:function(){return this._progress=5,l.post("get_product_information",{_ajax_nonce:d.nonce,feed:this._feed,limit:this._limit})}},{key:"_process_batch",value:function(){var t=this,e="Processing Batch ".concat(this._current_batch+1," of ").concat(this._total_batch);this._updateProgressStatus(e),this._log(e),l.post("make_batch_feed",{_ajax_nonce:d.nonce,feed:this._feed,products:this._product_ids[this._current_batch],loop:this._current_batch}).then(function(e){t._current_batch++,t._log("Batch ".concat(t._current_batch," Completed")),t._log(e),t._current_batch<t._total_batch&&(t._process_batch(),t._progress+=t._progress_per_batch),t._current_batch===t._total_batch&&t._save_feed_file()}).fail(function(e){t._log(e),t._updateProgressStatus(e.message),t._color="red",setTimeout(function(){t._stopProgressBar(),t._unblock_button()},1500)})}},{key:"_save_feed_file",value:function(){var t=this;this._log("Saving feed file"),this._updateProgressStatus("Saving feed file"),l.post("save_feed_file",{_ajax_nonce:d.nonce,feed:this._feed}).then(function(e){t._log(e),t._progress=100,t._refresh&&(a.location.href="".concat(d.pages.list.feed,"&link=").concat(e.url,"&cat=").concat(e.cat)),setTimeout(function(){t._stopProgressBar(),setTimeout(function(){t._resetProgressBar(!0),t._unblock_button()},3e3)},2500)}).fail(function(e){t._log(e),t._updateProgressStatus(e.message),t._color="red",setTimeout(function(){t._stopProgressBar(),t._unblock_button()},1500)})}},{key:"_log",value:function(e){return d.wpf_debug&&console.log(e),this}},{key:"_progressBarActive",value:function(){var e=0<arguments.length&&void 0!==arguments[0]?arguments[0]:0,t=this;return this._toggleProgressBar(!0),this._timer=setInterval(function(){t._updateProgressBar()},e||1e3),this}},{key:"_stopProgressBar",value:function(){return clearInterval(this._timer),this}},{key:"_resetProgressBar",value:function(e){return this._toggleProgressBar(!1),this._updateProgressStatus(""),clearInterval(this._timer),this._color=!1,this._timer=null,this._progress=0,e&&this._updateProgressBar(),this}},{key:"_toggleProgressBar",value:function(e){var t=s("#feed_progress_table");return e?t.show():t.hide(),this}},{key:"_updateProgressStatus",value:function(e){return s(".feed-progress-status").html(e),this}},{key:"_getErrorMessageByCode",value:function(e){s(".feed-progress-status").css({color:this._color}),s(".feed-progress-percentage").css({color:this._color}),s(".wpf_spin").css({color:this._color});var t=e.status+" : "+e.statusText+". ";500===e.status&&(t+="Please increase your PHP max_execution_time. Please <a target='_blank' href='https://webappick.com/docs/woo-feed/faq-for-woocommerce-product-feed/how-to-solve-processing-10-feed-generation-stuck-error/'>read this doc</a>."),this._updateProgressStatus(t)}},{key:"_updateProgressBar",value:function(){var e=s(".feed-progress-percentage"),t=s(".feed-progress-bar-fill"),o="".concat(Math.round(this._progress),"%");t.css({width:o}),e.text(o)}}]),e}();a.wf={helper:u,feedEditor:h,generator:m},s(a).on("load",function(){null!==s(location).attr("href").match(/webappick.*feed/g)&&s("#wpbody-content").addClass("woofeed-body-content"),t(),postboxes.add_postbox_toggles(pagenow),(new m).init(),""!==d.generator.feed&&d.generator.regenerate,h.init(),u.common(),s(".wfmasterTooltip").hover(function(){var e=s(this),t=e.attr("wftitle");e.data("tipText",t).removeAttr("wftitle"),s('<p class="wftooltip"></p>').text(t).appendTo("body").fadeIn("slow")},function(){var e=s(this);e.attr("wftitle",e.data("tipText")),s(".wftooltip").remove()}).mousemove(function(e){s(".wftooltip").css({top:e.pageY+10,left:e.pageX+20})}),s(".generateFeed").validate(),s(c).on("blur",'input[name="wfDAttributeName"]',function(e){e.preventDefault();e=s(this).val();e=(e=e.toLowerCase()).split(" ").join("_"),s("#wfDAttributeCode").val(e)}).on("click","[data-toggle_slide]",function(e){e.preventDefault(),s(s(this).data("toggle_slide")).slideToggle("fast")}).on("click","#wf_newRow",function(){var e=s("#table-1 tbody"),t=s("#feed_config_template").text().trim().replace(/__idx__/g,e.find("tr").length);e.append(t),u.fancySelect(s(".outputType"))}).on("click",".single-feed-delete",function(e){e.preventDefault(),confirm(d.form.del_confirm)&&(a.location.href=s(this).attr("val"))}).on("click",".wf_clean_cache_wrapper",function(e){e.preventDefault();var e=s(".woo-feed-clean-cache-nonce").val(),t=s(".woo-feed-cache-loader");t.show(),l.post("clear_cache_data",{_ajax_clean_nonce:e}).then(function(e){e.success&&(t.hide(),location.reload())}).fail(function(){console.log("something wrong")})}).on("click","#woo-feed-copy-status-btn",function(e){e.preventDefault();var t=s("#woo-feed-copy-status-btn"),e=s("#woo-feed-status-area");t.val("Copied"),e.css("visibility","visible"),e.select(),c.execCommand("copy")}).on("change",".wf_attr.wf_attributes",function(e){e.preventDefault(),s(".fancy-picker-picked").trigger("click");var t,o=s(this).val(),a=s(this).parents("tr").find(".outputType"),e=s(this).parents("tr").find(".fancy-picker-content .fancy-picker-option"),n=s(this).parents("tr").find(".fancy-picker-data span"),i=["price","current_price","sale_price","price_with_tax","current_price_with_tax","sale_price_with_tax","shipping_cost"].includes(o)?(t="for_price","Price"):""!==o&&-1!==o.indexOf("wf_taxo")?(t="for_custom_taxo","parent_if_empty"):(t="for_all","Default");e.removeClass("selected"),"for_custom_taxo"===t||"for_price"===t?(e.each(function(){i===s(this).text()&&(s(this).addClass("selected"),n.text(i),a.find("option").text(i),a.find("option").val(s(this).data("value")))}),"for_price"===t&&(t=null!=(t=s("#feedCurrency").val())?t:wpf_ajax_obj.woocommerce.currency,s(this).closest("tr").find("td:eq(5) input").val(" "+t))):(e.each(function(){i===s(this).text()&&(s(this).addClass("selected"),n.text(i),a.find("option").text(i),a.find("option").val(s(this).data("value")))}),s(this).closest("tr").find("td:eq(5) input").val(""))}).on("click","#doaction, #doaction2",function(){return confirm(d.form.del_confirm_multi)}).on("change",".dType",function(){var e=s(this),t=e.val(),e=e.closest("tr");"pattern"===t?(e.find(".value_attribute").hide(),e.find(".value_pattern").show()):"attribute"===t?(e.find(".value_attribute").show(),e.find(".value_pattern").hide()):"remove"===t&&(e.find(".value_attribute").hide(),e.find(".value_pattern").hide())}).on("click",".delRow",function(e){e.preventDefault(),s(this).closest("tr").remove(),u.reindex_config_table()}).on("submit","#generateFeed",function(){s(this).validate(),s(this).valid()&&s(".makeFeedResponse").show().html('<b style="color: darkblue;"><i class="dashicons dashicons-sos wpf_spin"></i> '.concat(d.form.generate,"</b>"))}).on("submit","#updatefeed",function(e,t){s(this).validate(),s(this).valid()&&s(".makeFeedResponse").show().html('<b style="color: darkblue;"><i class="dashicons dashicons-sos wpf_spin"></i> '.concat(t&&t.save?d.form.save:d.form.generate,"</b>"))}).on("ready woo_feed_config_loaded",function(){"0"===s("#ftpenabled").val()?(s(".google-merchant-message").hide("slow"),s(".woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) input, .woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) select").attr("disabled","disabled")):("google"===s("#provider").val()?s(".google-merchant-message").show("slow"):s(".google-merchant-message").hide("slow"),s(".woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) input, .woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) select").removeAttr("disabled")),s("#ftpenabled").on("change",function(){"0"===s("#ftpenabled").val()?(s(".google-merchant-message").hide("slow"),s(".woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) input, .woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) select").attr("disabled","disabled")):(s(".woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) input, .woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) select").removeAttr("disabled"),"google"===s("#provider").val()?s(".google-merchant-message").show("slow"):s(".google-merchant-message").hide("slow"))})}).on("change",".ftporsftp",function(){var e=s(this).val(),t=s(".ssh2_status");"sftp"===e?(t.show().css("color","dodgerblue").text(d.form.sftp_checking),l.post("get_ssh2_status",{_ajax_nonce:d.nonce,server:e}).then(function(e){"exists"===e?(t.css("color","#2CC185").text(d.form.sftp_available),setTimeout(function(){t.hide()},1500)):t.show().css("color","red").text(d.form.sftp_warning)}).fail(function(e){t.hide(),u.ajax_fail(e)})):t.hide()}).on("click",'[name="save_feed_config"]',function(e){e.preventDefault(),s("#updatefeed").trigger("submit",{save:!0})}).on("change","#provider",function(e){e.preventDefault();var t=s(this).val(),o=s(this).find(":selected").text(),a=s("#filename").val(),n=s("#feedType"),i=s("#providerPage"),r=s("#feed_merchant_info");i.html('<h3><span style="float:none;margin: -3px 0 0;" class="spinner is-active"></span> '+d.form.loading_tmpl+"</h3>"),r.find(".spinner").addClass("is-active"),n.disabled(!0),n.parent().find(".spinner").addClass("is-active"),r.find(".merchant-info-section .data").html(""),g.hasOwnProperty(t)?(h.renderMerchantInfo(r,n,g[t]),s(c).trigger("woo_feed_config_loaded")):l.send("woo_feed_get_merchant_info",{type:"GET",data:{nonce:d.nonce,provider:t,templateName:o}}).then(function(e){g[t]=e,h.renderMerchantInfo(r,n,e)}).then(function(){s(c).trigger("woo_feed_config_loaded")}).fail(u.ajax_fail),v.hasOwnProperty(t)?(h.renderMerchantTemplate(i,v[t]),s(c).trigger("woo_feed_config_loaded")):l.post("get_feed_merchant",{_ajax_nonce:d.nonce,merchant:t}).then(function(e){v[t]=e,h.renderMerchantTemplate(i,e),s("#utm_source").val(o),s("#utm_campaign").val(a),"bing"===t&&(s("#delimiter option").removeAttr("selected"),s('#delimiter option[value="tab"]').attr("selected","selected"),s("#enclosure option").removeAttr("selected"),s('#enclosure option[value=" "]').attr("selected","selected")),"google_product_review"!==t&&s('.wf_attributes option[value="reviewer_name"]').hide()}).then(function(){s(c).trigger("woo_feed_config_loaded")}).fail(u.ajax_fail)}).on("change",".woo_feed_status_input",function(){var e=s(this);l.post("update_feed_status",{_ajax_nonce:d.nonce,feedName:e.val(),status:e[0].checked?1:0})}),s(c).on("change",'[name="is_outOfStock"], [name="product_visibility"]',function(){var e=s(".out-of-stock-visibility");"n"===s('[name="is_outOfStock"]:checked').val()&&"1"===s('[name="product_visibility"]:checked').val()?e.show():e.hide()}).on("change",".attr_type",function(){var e=s(this),t=e.val(),e=e.closest("tr");"pattern"===t?(e.find(".wf_attr").hide(),e.find(".wf_attr").val(""),e.find(".wf_default").show()):(e.find(".wf_attr").show(),e.find(".wf_default").hide(),e.find(".wf_default").val(""))}).on("change",".wf_mattributes, .attr_type",function(){var e=s(this).closest("tr"),o=e.find(".wf_mattributes"),t=e.find(".attr_type"),a=e.find("td:eq(4)"),n=s("#provider").val();d.form.google_category.hasOwnProperty(o.val())&&"pattern"===t.val()&&u.in_array(n,d.form.google_category[o.val()])?0===a.find("select.selectize").length&&(a.find("input.wf_default").remove(),a.append('<span class="wf_default wf_attributes"><select name="default[]" class="selectize"></select></span>'),a.append('<span style="font-size:x-small;"><a style="color: red" href="https://webappick.com/docs/woo-feed/feed-configuration/how-to-map-store-category-with-merchant-category/" target="_blank">'.concat(d.learn_more,"</a></span>")),r&&f||a.append('<span class="spinner is-active" style="margin: 0;"></span>'),e=a.find(".wf_attributes select"),u.selectize(e,{preload:!0,placeholder:d.form.select_category,load:function(e,t){r?t(r):l.send("get_google_categories",{type:"GET",data:{_ajax_nonce:d.nonce,action:"get_google_categories",provider:n}}).then(function(e){t(r=e),a.find(".spinner").remove()}).fail(u.ajax_fail),f||"facebook"!==n||"fb_product_category"!==o.val()?t(f):l.send("get_facebook_categories",{type:"GET",data:{_ajax_nonce:d.nonce,action:"get_facebook_categories",provider:n}}).then(function(e){t(f=e),a.find(".spinner").remove()}).fail(u.ajax_fail)}})):"current_category"!==o.val()&&0===a.find("input.wf_default").length&&(a.find("span").remove(),a.append('<input autocomplete="off" class="wf_default wf_attributes" type="text" name="default[]" value="">'),"pattern"!==t.val()&&a.find("input.wf_default").hide())}).on("change","#feedType,#provider",function(e){var t=s("#feedType").val(),o=s("#provider").val(),a=s(".itemWrapper"),n=s(".wf_csvtxt");""!==t&&u.in_array(o,d.form.item_wrapper_hidden)&&a.hide(),"feedType"===e.target.id&&("csv"===t||"txt"===t||"tsv"===t?(n.show(),a.hide(),"tsv"===t?s("#delimiter option:last").prop("selected","selected"):"csv"===t&&s("#delimiter option:first").prop("selected","selected")):"xml"===t&&"custom"===o?(a.show(),n.hide()):"json"===t&&n.hide()),"custom"!==o&&a.hide()}).trigger("change"),s(c).on("click",'.woofeed-custom-fields [id*="-switcher"]',function(){s(this).closest("td").find(".switch-loader").show();var e=s(this).attr("id").split("-")[0],t=s(this).data("taxonomy"),o=s(this).prop("checked");new _(e,o,t)}).ready(function(){var e=s(".wapk-feed-buy-now-container");s(a).scroll(function(){s(a).scrollTop()<=5e3?e.addClass("fixed"):e.removeClass("fixed")})})}),s(c).on("click","#woo-feed-debug-log-download",function(e){e.preventDefault(),s("<a />",{download:new Date+".log",href:URL.createObjectURL(new Blob([s("#woo-feed-debug-log").val()],{type:"text/plain"}))}).appendTo("body")[0].click()}).on("keyup","#filename",function(){var e=s("#filename").val();s("#utm_campaign").val(e)}).on("click",".wf-tab-name",function(e){s(".wf-tab-name.activate").removeClass("activate"),s(this).addClass("activate");var t=s(this).attr("for");s(".wf_tabs li.active").removeClass("active"),s(".wf_tabs .wf-tab-content#"+t).parent().addClass("active")}).on("change","#category-mapping-form #providers",function(){var e,t=s(this).find(":selected").val();s(".woo-feed-category-mapping-config-table").prepend('<div class="woo-feed-cat-map-spinner"><h3><span style="float:none;margin: -3px 0 0;" class="spinner is-active"></span> Loading Mapping...</h3></div>'),-1!==["google","facebook","pinterest","bing","bing_local_inventory","snapchat"].indexOf(t)?(s('input[id*="cat_mapping_"]').css("display","none"),s(".wf_default.wf_attributes").css("display","block").css("width","100%"),e=new p,"facebook"===t?e.wooFeed_get_facebook_categories():e.wooFeed_get_google_categories()):(s('input[id*="cat_mapping_"]').css("display","block"),s(".wf_default.wf_attributes").css("display","none").css("width","100%"))}).on("click",'span[id*="cat-map-"]',function(e){e.preventDefault();var o,t=s("#category-mapping-form #providers").val(),a=s(this).attr("id").replace(/[^\d.]/g,""),e="group-child-"+a;-1!==["google","facebook","pinterest","bing","bing_local_inventory","snapchat"].indexOf(t)?(o=s(this).parents("tr").find(".selectized").val())&&s("."+e).parents("tr").find("select").each(function(e,t){s(t).data("selectize").setValue(o)}):(a=s("#cat_mapping_"+a).val(),s("."+e).parents("tr").find("input").val(a))}),s(c).ready(function(){var e=s("#providers").val(),t=new p;"edit-mapping"===new URL(a.location.href).searchParams.get("action")&&(s(".woo-feed-category-mapping-config-table").prepend('<div class="woo-feed-cat-map-spinner"><h3><span style="float:none;margin: -3px 0 0;" class="spinner is-active"></span> Loading Mapping...</h3></div>'),"facebook"===e?t.wooFeed_get_facebook_categories():t.wooFeed_get_google_categories())}),s(c).on("feed_editor_init",function(){var t=s(".merchant-info-section.feed_file_type .data").html().split(",").map(function(e){return e.trim().toLowerCase()}),e=s("#feedType");t.length?(e.find("option").each(function(){var e=s(this);e.val()&&!u.in_array(e.val(),t)?e.disabled(!0):e.disabled(!1)}),1===t.length&&e.find('option[value="'+t[0]+'"]').attr("selected","selected")):e.find("option").disabled(!1)}),s(c).on("ready",function(){s(c).on("feedEditor.init",function(){!function(){var i,t={price:wpf_ajax_obj.woocommerce.currency,current_price:wpf_ajax_obj.woocommerce.currency,sale_price:wpf_ajax_obj.woocommerce.currency,price_with_tax:wpf_ajax_obj.woocommerce.currency,current_price_with_tax:wpf_ajax_obj.woocommerce.currency,sale_price_with_tax:wpf_ajax_obj.woocommerce.currency,weight:wpf_ajax_obj.woocommerce.weight,weight_unit:wpf_ajax_obj.woocommerce.weight,height:wpf_ajax_obj.woocommerce.dimension,length:wpf_ajax_obj.woocommerce.dimension,width:wpf_ajax_obj.woocommerce.dimension};void 0!==wpf_ajax_obj.feed_rules&&null!==wpf_ajax_obj.feed_rules&&(i=wpf_ajax_obj.feed_rules.feedCurrency);var e=a.location.search,r=new URLSearchParams(e).get("action");s(".wf_attr.wf_attributes").each(function(o,e){var a=s(e).val(),n=s('input[name^="suffix"]').eq(parseInt(o)).val();-1!==s.inArray(n,[" "+wpf_ajax_obj.woocommerce.currency," "+wpf_ajax_obj.woocommerce.weight," "+wpf_ajax_obj.woocommerce.dimension])&&s('input[name^="suffix"]').eq(parseInt(o)).val(""),s.each(t,function(e,t){a===e&&(t=null!=i?i:t,"undefined"!==r&&"edit-feed"!==r?s('input[name^="suffix"]').eq(parseInt(o)).val(" "+t):s('input[name^="suffix"]').eq(parseInt(o)).val(n))})}),s(c).trigger("feedEditor.after.free.postfix.update")}()})})}(jQuery,window,document,wp.ajax,wpf_ajax_obj);
2
  //# sourceMappingURL=woo-feed-admin.min.js.map
1
+ "use strict";function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _defineProperties(e,t){for(var o=0;o<t.length;o++){var a=t[o];a.enumerable=a.enumerable||!1,a.configurable=!0,"value"in a&&(a.writable=!0),Object.defineProperty(e,a.key,a)}}function _createClass(e,t,o){return t&&_defineProperties(e.prototype,t),o&&_defineProperties(e,o),e}!function(s,a,c,l,d){s.fn.disabled=function(o){return s(this).each(function(){var e=s(this),t="disabled";void 0!==e.prop(t)?e.prop(t,void 0===o||!0===o):!0===o?e.addClass(t):e.removeClass(t)}),self},s.fn.isDisabled=function(){var e=s(this),t="disabled";return void 0!==e.prop(t)?e.prop(t):e.hasClass(t)};function e(e){s(e.currentTarget).removeClass(function(e,t){return(t.match(/\btooltipped-\S+/g)||[]).join(" ")}).removeClass("tooltipped").removeAttr("aria-label")}function o(e,t){s(e).addClass("tooltipped tooltipped-s").attr("aria-label",t)}function n(e,t){return s.extend(!0,{},e,t)}function t(){i=s(".toClipboard"),!ClipboardJS.isSupported()||/iPhone|iPad/i.test(navigator.userAgent)?i.find("img").hide(0):(i.each(function(){s(this).on("mouseleave",e).on("blur",e)}),new ClipboardJS(".toClipboard").on("error",function(e){var t;o(e.trigger,(t=e.action,e="cut"===t?"X":"C",t=/iPhone|iPad/i.test(navigator.userAgent)?"No support :(":/Mac/i.test(navigator.userAgent)?"Press ⌘-"+e+" to "+t:"Press Ctrl-"+e+" to "+t))}).on("success",function(e){o(e.trigger,"Copied")}))}var i,r,f,_=function(){function a(e,t,o){_classCallCheck(this,a),this.productCustomFields(e,t,o)}return _createClass(a,[{key:"cacheClear",value:function(){var e={action:"woo_feed_product_attribute_cache_remove",nonce:wpf_ajax_obj.ajax.nonce};s.ajax({method:"POST",url:wpf_ajax_obj.wpf_ajax_url,data:e})}},{key:"productCustomFields",value:function(t){var o=this,e={action:"woo_feed_custom_fields_status_change",nonce:wpf_ajax_obj.ajax.nonce,field:t,status:1<arguments.length&&void 0!==arguments[1]&&arguments[1],isTaxonomy:2<arguments.length?arguments[2]:void 0};s.ajax({method:"POST",url:wpf_ajax_obj.wpf_ajax_url,data:e,success:function(e){e.success?o.cacheClear():console.log(e),s("#"+t+"-switcher").closest("td").find(".switch-loader").hide()}})}}]),a}(),p=function(){function e(){_classCallCheck(this,e)}return _createClass(e,[{key:"wooFeed_get_google_categories",value:function(){l.send("get_google_categories",{type:"GET",data:{_ajax_nonce:d.nonce,action:"get_google_categories"}}).then(function(e){s(".selectize-google-category").selectize({valueField:"value",labelField:"text",placeholder:"Select a category",searchField:["value","text"],options:e,render:{option:function(e,t){return'<div class="item wapk-selectize-item">'.concat(t(e.value+" - "+e.text),"</div>")},item:function(e,t){return'<div class="item wapk-selectize-item">'.concat(t(e.value+" - "+e.text),"</div>")}}}),s(".woo-feed-cat-map-spinner").remove()}).fail(u.ajax_fail)}},{key:"wooFeed_get_facebook_categories",value:function(){l.send("get_facebook_categories",{type:"GET",data:{_ajax_nonce:d.nonce,action:"get_facebook_categories"}}).then(function(e){s(".selectize-google-category").selectize({valueField:"value",labelField:"text",placeholder:"Select a Facebook category",searchField:["value","text"],options:e,render:{option:function(e,t){return'<div class="item wapk-selectize-item">'.concat(t(e.value+" - "+e.text),"</div>")},item:function(e,t){return'<div class="item wapk-selectize-item">'.concat(t(e.value+" - "+e.text),"</div>")}}}),s(".woo-feed-cat-map-spinner").remove()}).fail(u.ajax_fail)}}]),e}(),u={in_array:function(e,t){try{return-1!==t.indexOf(e)}catch(e){return!1}},selectize_render_item:function(e,t){return'<div class="item wapk-selectize-item">'.concat(t(e.text),"</div>")},ajax_fail:function(e){console.warn(e),alert(e.hasOwnProperty("statusText")&&e.hasOwnProperty("status")?d.ajax.error+"\n"+e.statusText+" ("+e.status+")":e)},sortable:function(e,o,a,i){return(e||s(".sorted_table")).each(function(){var e=s(this),t=e.find("tbody > tr:eq(0) > td").length||a||9;e.wf_sortable(n({containerSelector:"table",itemPath:"> tbody",itemSelector:"tr",handle:"i.wf_sortedtable",placeholder:'<tr class="placeholder"><td colspan="'.concat(t,'"></td></tr>'),onDrop:function(e,t,o,a){e.removeClass(t.group.options.draggedClass).removeAttr("style"),s("body").removeClass(t.group.options.bodyClass);var n=e.find(".wf_mattributes").attr("name").replace(/\D/g,"");e.find("input.wf_attributes").attr("name","default["+n+"]"),i&&"function"==typeof i&&i(e,t,o,a)}},o))})},selectize:function(e,t){return(e||s("select.selectize")).not(".selectized").not(".selectize-google-category").each(function(){var e=s(this);e.selectize(n({create:e.data("create")||!1,plugins:e.data("plugins")?e.data("plugins").split(",").map(function(e){return e.trim()}):[],render:{item:u.selectize_render_item}},t))})},fancySelect:function(e,t){return(e||s("select.fancySelect")).not(".FancySelectInit").each(function(){s(this).fancySelect(n({maxItemShow:3},t))})},reindex_config_table:function(){s("#table-1").find("tbody tr").each(function(o,e){s(e).find("[name]").each(function(e,t){s(t).attr("name",s(t).attr("name").replace(/(\[\d\])/g,"[".concat(o,"]")))})})},common:function(){u.sortable(s(".sorted_table"),{},9,u.reindex_config_table),u.selectize(),u.fancySelect(s(".outputType"))}},h={form:null,init:function(){this.form=s(".generateFeed"),this.form.length&&(u.common(),s(c).trigger("feed_editor_init"),s(c).trigger(new jQuery.Event("feedEditor.init",{target:this.form})))},renderMerchantInfo:function(o,a,n){for(var e in n)!function(e){var t;n.hasOwnProperty(e)&&(o.find(".merchant-info-section."+e+" .data").html(n[e]),"feed_file_type"===e&&((t=n[e].split(",").map(function(e){return e.trim().toLowerCase()}).filter(function(e){return""!==e&&e!==d.na.toLowerCase()})).length?(a.find("option").removeAttr("selected").each(function(){var e=s(this);e.val()&&!u.in_array(e.val(),t)?e.disabled(!0):e.disabled(!1)}),1===t.length&&a.find('option[value="'+t[0]+'"]').attr("selected","selected")):a.find("option").disabled(!1)))}(e);o.find(".spinner").removeClass("is-active"),a.disabled(!1),a.trigger("change"),s(c).trigger("woo_feed_config_loaded"),a.parent().find(".spinner").removeClass("is-active")},renderMerchantTemplate:function(o,a){for(var e in a)!function(t){var e;a.hasOwnProperty(t)&&("tabs"===t?o.html(a[t]):(e=s('[name="'+t+'"]')).length&&e.each(function(){var e=s(this);e.is("select")?e.find('[value="'+a[t]+'"]').prop("selected",!0):(e.is("[type=checkbox]")||e.is("[type=radio]"))&&e.val()===a[t]?e.prop("checked",!0):e.val(a[t])}).trigger("change"))}(e);h.init()}},g=[],v=[],m=function(){function e(){_classCallCheck(this,e),this._feed=d.generator.feed,this._limit=d.generator.limit,this._progress=0,this._timer=null,this._color=!1,this._total_batch=0,this._current_batch=0,this._product_ids=[],this._progress_per_batch=0,this._refresh=!0,this._regenerate=d.generator.regenerate,a.isRegenerating=!1,this._all_btn=s(".wpf_regenerate"),this._current_btn=s("#".concat(this._feed.replace("wf_config","wf_feed_"))),this._current_btn_label=""}return _createClass(e,[{key:"init",value:function(){var t=this;""!==this._feed&&this._regenerate&&!1===a.isRegenerating&&this.generate();var e=a.location.search;return"webappick-manage-feeds"===new URLSearchParams(e).get("page")&&s("body").addClass("woo-import-popup-body"),s(c).on("click",".woo-feed-campaign-close-button",function(e){e.preventDefault(),s(this).parent(".woo-feed-promotion").hide();e=s(this).data("condition");1===e&&l.post("woo_feed_hide_promotion",{_ajax_nonce:d.nonce,condition:e}).then(function(e){t._log(e)}).fail(function(e){t._log(e),t._updateProgressStatus(e.message),t._color="red"})}),s(c).on("click",".wpf_regenerate",function(e){e.preventDefault(),t._current_btn=s(this),t._current_btn.hasClass("disabled")||!0===a.isRegenerating||(t._feed=t._current_btn.attr("id").replace("wf_feed_","wf_config"),""!==t._feed&&t.generate())}),this}},{key:"_block_button",value:function(){this._all_btn.length&&this._all_btn.addClass("disabled"),this._current_btn.length&&(this._current_btn.find("span").addClass("wpf_spin reverse_spin"),this._current_btn_label=this._current_btn.attr("title"),this._current_btn.attr("aria-label",d.regenerate).attr("title",d.regenerate))}},{key:"_unblock_button",value:function(){this._all_btn.length&&this._all_btn.removeClass("disabled"),this._current_btn.length&&(this._current_btn.find("span").removeClass("wpf_spin"),this._current_btn.find("span").removeClass("reverse_spin"),this._current_btn.attr("aria-label",this._current_btn_label).attr("title",this._current_btn_label))}},{key:"generate",value:function(){var t=this,o=this;a.isRegenerating=!0,this._block_button(),this._resetProgressBar(),this._progressBarActive(),this._log("Counting Total Products"),this._updateProgressStatus("Fetching products."),this._get_product_ids().then(function(e){t._progress=10,o._log({response:e}),e.success?(o._log("Total ".concat(e.total," Products found.")),o._product_ids=e.product,o._total_batch=t._product_ids.length,o._current_batch=0,o._progress_per_batch=(90-t._progress)/t._total_batch,o._process_batch(),o._updateProgressStatus("Processing Products...")):o._updateProgressStatus(e.data.message)}).fail(function(e){o._log(e),o._updateProgressStatus(e.message),o._color="red",setTimeout(function(){o._stopProgressBar(),o._unblock_button()},1500)})}},{key:"_get_product_ids",value:function(){return this._progress=5,l.post("get_product_information",{_ajax_nonce:d.nonce,feed:this._feed,limit:this._limit})}},{key:"_process_batch",value:function(){var t=this,e="Processing Batch ".concat(this._current_batch+1," of ").concat(this._total_batch);this._updateProgressStatus(e),this._log(e),l.post("make_batch_feed",{_ajax_nonce:d.nonce,feed:this._feed,products:this._product_ids[this._current_batch],loop:this._current_batch}).then(function(e){t._current_batch++,t._log("Batch ".concat(t._current_batch," Completed")),t._log(e),t._current_batch<t._total_batch&&(t._process_batch(),t._progress+=t._progress_per_batch),t._current_batch===t._total_batch&&t._save_feed_file()}).fail(function(e){t._log(e),t._updateProgressStatus(e.message),t._color="red",setTimeout(function(){t._stopProgressBar(),t._unblock_button()},1500)})}},{key:"_save_feed_file",value:function(){var t=this;this._log("Saving feed file"),this._updateProgressStatus("Saving feed file"),l.post("save_feed_file",{_ajax_nonce:d.nonce,feed:this._feed}).then(function(e){t._log(e),t._progress=100,t._refresh&&(a.location.href="".concat(d.pages.list.feed,"&link=").concat(e.url,"&cat=").concat(e.cat)),setTimeout(function(){t._stopProgressBar(),setTimeout(function(){t._resetProgressBar(!0),t._unblock_button()},3e3)},2500)}).fail(function(e){t._log(e),t._updateProgressStatus(e.message),t._color="red",setTimeout(function(){t._stopProgressBar(),t._unblock_button()},1500)})}},{key:"_log",value:function(e){return d.wpf_debug&&console.log(e),this}},{key:"_progressBarActive",value:function(){var e=0<arguments.length&&void 0!==arguments[0]?arguments[0]:0,t=this;return this._toggleProgressBar(!0),this._timer=setInterval(function(){t._updateProgressBar()},e||1e3),this}},{key:"_stopProgressBar",value:function(){return clearInterval(this._timer),this}},{key:"_resetProgressBar",value:function(e){return this._toggleProgressBar(!1),this._updateProgressStatus(""),clearInterval(this._timer),this._color=!1,this._timer=null,this._progress=0,e&&this._updateProgressBar(),this}},{key:"_toggleProgressBar",value:function(e){var t=s("#feed_progress_table");return e?t.show():t.hide(),this}},{key:"_updateProgressStatus",value:function(e){return s(".feed-progress-status").html(e),this}},{key:"_getErrorMessageByCode",value:function(e){s(".feed-progress-status").css({color:this._color}),s(".feed-progress-percentage").css({color:this._color}),s(".wpf_spin").css({color:this._color});var t=e.status+" : "+e.statusText+". ";500===e.status&&(t+="Please increase your PHP max_execution_time. Please <a target='_blank' href='https://webappick.com/docs/woo-feed/faq-for-woocommerce-product-feed/how-to-solve-processing-10-feed-generation-stuck-error/'>read this doc</a>."),this._updateProgressStatus(t)}},{key:"_updateProgressBar",value:function(){var e=s(".feed-progress-percentage"),t=s(".feed-progress-bar-fill"),o="".concat(Math.round(this._progress),"%");t.css({width:o}),e.text(o)}}]),e}();a.wf={helper:u,feedEditor:h,generator:m},s(a).on("load",function(){null!==s(location).attr("href").match(/webappick.*feed/g)&&s("#wpbody-content").addClass("woofeed-body-content"),t(),postboxes.add_postbox_toggles(pagenow),(new m).init(),""!==d.generator.feed&&d.generator.regenerate,h.init(),u.common(),s(".wfmasterTooltip").hover(function(){var e=s(this),t=e.attr("wftitle");e.data("tipText",t).removeAttr("wftitle"),s('<p class="wftooltip"></p>').text(t).appendTo("body").fadeIn("slow")},function(){var e=s(this);e.attr("wftitle",e.data("tipText")),s(".wftooltip").remove()}).mousemove(function(e){s(".wftooltip").css({top:e.pageY+10,left:e.pageX+20})}),s(".generateFeed").validate(),s(c).on("blur",'input[name="wfDAttributeName"]',function(e){e.preventDefault();e=s(this).val();e=(e=e.toLowerCase()).split(" ").join("_"),s("#wfDAttributeCode").val(e)}).on("click","[data-toggle_slide]",function(e){e.preventDefault(),s(s(this).data("toggle_slide")).slideToggle("fast")}).on("click","#wf_newRow",function(){var e=s("#table-1 tbody"),t=s("#feed_config_template").text().trim().replace(/__idx__/g,e.find("tr").length);e.append(t),u.fancySelect(s(".outputType"))}).on("click",".single-feed-delete",function(e){e.preventDefault(),confirm(d.form.del_confirm)&&(a.location.href=s(this).attr("val"))}).on("click",".wf_clean_cache_wrapper",function(e){e.preventDefault();var e=s(".woo-feed-clean-cache-nonce").val(),t=s(".woo-feed-cache-loader");t.show(),l.post("clear_cache_data",{_ajax_clean_nonce:e}).then(function(e){e.success&&(t.hide(),location.reload())}).fail(function(){console.log("something wrong")})}).on("click","#woo-feed-copy-status-btn",function(e){e.preventDefault();var t=s("#woo-feed-copy-status-btn"),e=s("#woo-feed-status-area");t.val("Copied"),e.css("visibility","visible"),e.select(),c.execCommand("copy")}).on("change",".wf_attr.wf_attributes",function(e){e.preventDefault(),s(".fancy-picker-picked").trigger("click");var t,o=s(this).val(),a=s(this).parents("tr").find(".outputType"),e=s(this).parents("tr").find(".fancy-picker-content .fancy-picker-option"),n=s(this).parents("tr").find(".fancy-picker-data span"),i=["price","current_price","sale_price","price_with_tax","current_price_with_tax","sale_price_with_tax","shipping_cost"].includes(o)?(t="for_price","Price"):""!==o&&-1!==o.indexOf("wf_taxo")?(t="for_custom_taxo","parent_if_empty"):(t="for_all","Default");e.removeClass("selected"),"for_custom_taxo"===t||"for_price"===t?(e.each(function(){i===s(this).text()&&(s(this).addClass("selected"),n.text(i),a.find("option").text(i),a.find("option").val(s(this).data("value")))}),"for_price"===t&&(t=null!=(t=s("#feedCurrency").val())?t:wpf_ajax_obj.woocommerce.currency,s(this).closest("tr").find("td:eq(5) input").val(" "+t))):(e.each(function(){i===s(this).text()&&(s(this).addClass("selected"),n.text(i),a.find("option").text(i),a.find("option").val(s(this).data("value")))}),s(this).closest("tr").find("td:eq(5) input").val(""))}).on("click","#doaction, #doaction2",function(){return confirm(d.form.del_confirm_multi)}).on("change",".dType",function(){var e=s(this),t=e.val(),e=e.closest("tr");"pattern"===t?(e.find(".value_attribute").hide(),e.find(".value_pattern").show()):"attribute"===t?(e.find(".value_attribute").show(),e.find(".value_pattern").hide()):"remove"===t&&(e.find(".value_attribute").hide(),e.find(".value_pattern").hide())}).on("click",".delRow",function(e){e.preventDefault(),s(this).closest("tr").remove(),u.reindex_config_table()}).on("submit","#generateFeed",function(){s(this).validate(),s(this).valid()&&s(".makeFeedResponse").show().html('<b style="color: darkblue;"><i class="dashicons dashicons-sos wpf_spin"></i> '.concat(d.form.generate,"</b>"))}).on("submit","#updatefeed",function(e,t){s(this).validate(),s(this).valid()&&s(".makeFeedResponse").show().html('<b style="color: darkblue;"><i class="dashicons dashicons-sos wpf_spin"></i> '.concat(t&&t.save?d.form.save:d.form.generate,"</b>"))}).on("ready woo_feed_config_loaded",function(){"0"===s("#ftpenabled").val()?(s(".google-merchant-message").hide("slow"),s(".woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) input, .woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) select").attr("disabled","disabled")):("google"===s("#provider").val()?s(".google-merchant-message").show("slow"):s(".google-merchant-message").hide("slow"),s(".woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) input, .woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) select").removeAttr("disabled")),s("#ftpenabled").on("change",function(){"0"===s("#ftpenabled").val()?(s(".google-merchant-message").hide("slow"),s(".woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) input, .woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) select").attr("disabled","disabled")):(s(".woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) input, .woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) select").removeAttr("disabled"),"google"===s("#provider").val()?s(".google-merchant-message").show("slow"):s(".google-merchant-message").hide("slow"))})}).on("change",".ftporsftp",function(){var e=s(this).val(),t=s(".ssh2_status");"sftp"===e?(t.show().css("color","dodgerblue").text(d.form.sftp_checking),l.post("get_ssh2_status",{_ajax_nonce:d.nonce,server:e}).then(function(e){"exists"===e?(t.css("color","#2CC185").text(d.form.sftp_available),setTimeout(function(){t.hide()},1500)):t.show().css("color","red").text(d.form.sftp_warning)}).fail(function(e){t.hide(),u.ajax_fail(e)})):t.hide()}).on("click",'[name="save_feed_config"]',function(e){e.preventDefault(),s("#updatefeed").trigger("submit",{save:!0})}).on("change","#provider",function(e){e.preventDefault();var t=s(this).val(),o=s(this).find(":selected").text(),a=s("#filename").val(),n=s("#feedType"),i=s("#providerPage"),r=s("#feed_merchant_info");i.html('<h3><span style="float:none;margin: -3px 0 0;" class="spinner is-active"></span> '+d.form.loading_tmpl+"</h3>"),r.find(".spinner").addClass("is-active"),n.disabled(!0),n.parent().find(".spinner").addClass("is-active"),r.find(".merchant-info-section .data").html(""),g.hasOwnProperty(t)?(h.renderMerchantInfo(r,n,g[t]),s(c).trigger("woo_feed_config_loaded")):l.send("woo_feed_get_merchant_info",{type:"GET",data:{nonce:d.nonce,provider:t,templateName:o}}).then(function(e){g[t]=e,h.renderMerchantInfo(r,n,e)}).then(function(){s(c).trigger("woo_feed_config_loaded")}).fail(u.ajax_fail),v.hasOwnProperty(t)?(h.renderMerchantTemplate(i,v[t]),s(c).trigger("woo_feed_config_loaded")):l.post("get_feed_merchant",{_ajax_nonce:d.nonce,merchant:t}).then(function(e){v[t]=e,h.renderMerchantTemplate(i,e),s("#utm_source").val(o),s("#utm_campaign").val(a),"bing"===t&&(s("#delimiter option").removeAttr("selected"),s('#delimiter option[value="tab"]').attr("selected","selected"),s("#enclosure option").removeAttr("selected"),s('#enclosure option[value=" "]').attr("selected","selected")),"google_product_review"!==t&&s('.wf_attributes option[value="reviewer_name"]').hide()}).then(function(){s(c).trigger("woo_feed_config_loaded")}).fail(u.ajax_fail)}).on("change",".woo_feed_status_input",function(){var e=s(this);l.post("update_feed_status",{_ajax_nonce:d.nonce,feedName:e.val(),status:e[0].checked?1:0})}),s(c).on("change",'[name="is_outOfStock"], [name="product_visibility"]',function(){var e=s(".out-of-stock-visibility");"n"===s('[name="is_outOfStock"]:checked').val()&&"1"===s('[name="product_visibility"]:checked').val()?e.show():e.hide()}).on("change",".attr_type",function(){var e=s(this),t=e.val(),e=e.closest("tr");"pattern"===t?(e.find(".wf_attr").hide(),e.find(".wf_attr").val(""),e.find(".wf_default").show()):(e.find(".wf_attr").show(),e.find(".wf_default").hide(),e.find(".wf_default").val(""))}).on("change",".wf_mattributes, .attr_type",function(){var e=s(this).closest("tr"),o=e.find(".wf_mattributes"),t=e.find(".attr_type"),a=e.find("td:eq(4)"),n=s("#provider").val();d.form.google_category.hasOwnProperty(o.val())&&"pattern"===t.val()&&u.in_array(n,d.form.google_category[o.val()])?0===a.find("select.selectize").length&&(a.find("input.wf_default").remove(),a.append('<span class="wf_default wf_attributes"><select name="default[]" class="selectize"></select></span>'),a.append('<span style="font-size:x-small;"><a style="color: red" href="https://webappick.com/docs/woo-feed/feed-configuration/how-to-map-store-category-with-merchant-category/" target="_blank">'.concat(d.learn_more,"</a></span>")),r&&f||a.append('<span class="spinner is-active" style="margin: 0;"></span>'),e=a.find(".wf_attributes select"),u.selectize(e,{preload:!0,placeholder:d.form.select_category,load:function(e,t){r?t(r):l.send("get_google_categories",{type:"GET",data:{_ajax_nonce:d.nonce,action:"get_google_categories",provider:n}}).then(function(e){t(r=e),a.find(".spinner").remove()}).fail(u.ajax_fail),f||"facebook"!==n||"fb_product_category"!==o.val()?t(f):l.send("get_facebook_categories",{type:"GET",data:{_ajax_nonce:d.nonce,action:"get_facebook_categories",provider:n}}).then(function(e){t(f=e),a.find(".spinner").remove()}).fail(u.ajax_fail)}})):"current_category"!==o.val()&&0===a.find("input.wf_default").length&&(a.find("span").remove(),a.append('<input autocomplete="off" class="wf_default wf_attributes" type="text" name="default[]" value="">'),"pattern"!==t.val()&&a.find("input.wf_default").hide())}).on("change","#feedType,#provider",function(e){var t=s("#feedType").val(),o=s("#provider").val(),a=s(".itemWrapper"),n=s(".wf_csvtxt");""!==t&&u.in_array(o,d.form.item_wrapper_hidden)&&a.hide(),"feedType"===e.target.id&&("csv"===t||"txt"===t||"tsv"===t?(n.show(),a.hide(),"tsv"===t?s("#delimiter option:last").prop("selected","selected"):"csv"===t&&s("#delimiter option:first").prop("selected","selected")):"xml"===t&&"custom"===o?(a.show(),n.hide()):"json"===t&&n.hide()),"custom"!==o&&a.hide()}).trigger("change"),s(c).on("click",'.woofeed-custom-fields [id*="-switcher"]',function(){s(this).closest("td").find(".switch-loader").show();var e=s(this).attr("id").split("-")[0],t=s(this).data("taxonomy"),o=s(this).prop("checked");new _(e,o,t)}).ready(function(){var e=s(".wapk-feed-buy-now-container");s(a).scroll(function(){s(a).scrollTop()<=5e3?e.addClass("fixed"):e.removeClass("fixed")})})}),s(c).on("click","#woo-feed-debug-log-download",function(e){e.preventDefault(),s("<a />",{download:new Date+".log",href:URL.createObjectURL(new Blob([s("#woo-feed-debug-log").val()],{type:"text/plain"}))}).appendTo("body")[0].click()}).on("keyup","#filename",function(){var e=s("#filename").val();s("#utm_campaign").val(e)}).on("click",".wf-tab-name",function(e){s(".wf-tab-name.activate").removeClass("activate"),s(this).addClass("activate");var t=s(this).attr("for");s(".wf_tabs li.active").removeClass("active"),s(".wf_tabs .wf-tab-content#"+t).parent().addClass("active")}).on("change","#category-mapping-form #providers",function(){var e,t=s(this).find(":selected").val();s(".woo-feed-category-mapping-config-table").prepend('<div class="woo-feed-cat-map-spinner"><h3><span style="float:none;margin: -3px 0 0;" class="spinner is-active"></span> Loading Mapping...</h3></div>'),-1!==["google","facebook","pinterest","bing","bing_local_inventory","snapchat","tiktok"].indexOf(t)?(s('input[id*="cat_mapping_"]').css("display","none"),s(".wf_default.wf_attributes").css("display","block").css("width","100%"),e=new p,"facebook"===t?e.wooFeed_get_facebook_categories():e.wooFeed_get_google_categories()):(s('input[id*="cat_mapping_"]').css("display","block"),s(".wf_default.wf_attributes").css("display","none").css("width","100%"))}).on("click",'span[id*="cat-map-"]',function(e){e.preventDefault();var o,t=s("#category-mapping-form #providers").val(),a=s(this).attr("id").replace(/[^\d.]/g,""),e="group-child-"+a;-1!==["google","facebook","pinterest","bing","bing_local_inventory","snapchat","tiktok"].indexOf(t)?(o=s(this).parents("tr").find(".selectized").val())&&s("."+e).parents("tr").find("select").each(function(e,t){s(t).data("selectize").setValue(o)}):(a=s("#cat_mapping_"+a).val(),s("."+e).parents("tr").find("input").val(a))}),s(c).ready(function(){var e=s("#providers").val(),t=new p;"edit-mapping"===new URL(a.location.href).searchParams.get("action")&&(s(".woo-feed-category-mapping-config-table").prepend('<div class="woo-feed-cat-map-spinner"><h3><span style="float:none;margin: -3px 0 0;" class="spinner is-active"></span> Loading Mapping...</h3></div>'),"facebook"===e?t.wooFeed_get_facebook_categories():t.wooFeed_get_google_categories())}),s(c).on("feed_editor_init",function(){var t=s(".merchant-info-section.feed_file_type .data").html().split(",").map(function(e){return e.trim().toLowerCase()}),e=s("#feedType");t.length?(e.find("option").each(function(){var e=s(this);e.val()&&!u.in_array(e.val(),t)?e.disabled(!0):e.disabled(!1)}),1===t.length&&e.find('option[value="'+t[0]+'"]').attr("selected","selected")):e.find("option").disabled(!1)}),s(c).on("ready",function(){s(c).on("feedEditor.init",function(){var e=s(this).find(":selected").val();-1!==["google","facebook","pinterest","bing","bing_local_inventory","snapchat","tiktok"].indexOf(e)&&function(){var i,t={price:wpf_ajax_obj.woocommerce.currency,current_price:wpf_ajax_obj.woocommerce.currency,sale_price:wpf_ajax_obj.woocommerce.currency,price_with_tax:wpf_ajax_obj.woocommerce.currency,current_price_with_tax:wpf_ajax_obj.woocommerce.currency,sale_price_with_tax:wpf_ajax_obj.woocommerce.currency,weight:wpf_ajax_obj.woocommerce.weight,weight_unit:wpf_ajax_obj.woocommerce.weight,height:wpf_ajax_obj.woocommerce.dimension,length:wpf_ajax_obj.woocommerce.dimension,width:wpf_ajax_obj.woocommerce.dimension};void 0!==wpf_ajax_obj.feed_rules&&null!==wpf_ajax_obj.feed_rules&&(i=wpf_ajax_obj.feed_rules.feedCurrency);var e=a.location.search,r=new URLSearchParams(e).get("action");s(".wf_attr.wf_attributes").each(function(o,e){var a=s(e).val(),n=s('input[name^="suffix"]').eq(parseInt(o)).val();-1!==s.inArray(n,[" "+wpf_ajax_obj.woocommerce.currency," "+wpf_ajax_obj.woocommerce.weight," "+wpf_ajax_obj.woocommerce.dimension])&&s('input[name^="suffix"]').eq(parseInt(o)).val(""),s.each(t,function(e,t){a===e&&(t=null!=i?i:t,"undefined"!==r&&"edit-feed"!==r?s('input[name^="suffix"]').eq(parseInt(o)).val(" "+t):s('input[name^="suffix"]').eq(parseInt(o)).val(n))})}),s(c).trigger("feedEditor.after.free.postfix.update")}()})})}(jQuery,window,document,wp.ajax,wpf_ajax_obj);
2
  //# sourceMappingURL=woo-feed-admin.min.js.map
admin/js/woo-feed-admin.min.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["woo-feed-admin.js"],"names":["_defineProperties","target","props","descriptor","i","enumerable","configurable","writable","Object","defineProperty","key","_createClass","Constructor","protoProps","staticProps","prototype","window","wpAjax","$","document","opts","self","prop","status","addClass","removeClass","hasClass","currentTarget","clearTooltip","userAgent","actionMsg","match","actionKey","index","join","removeAttr","elem","attr","msg","extend","_default","_args","option","ClipboardJS","isSupported","test","navigator","$copyBtn","feedGenerator","this","on","event","action","_loop","ajax_fail","alert","url","data","_classCallCheck","WooFeedCustomFields","productCustomFields","field","isTaxonomy","value","ajax","nonce","method","response","wpf_ajax_obj","wpf_ajax_url","success","_this","cacheClear","closest","find","hide","selectize","WooFeedMapCategories","options","render","send","type","item","_ajax_nonce","valueField","helper","labelField","placeholder","searchField","escape","concat","text","remove","googleCategories","fail","onDrop","column_count","containerSelector","e","hasOwnProperty","error","statusText","sortable","column","each","_super","length","wf_sortable","itemPath","handle","el","$item","container","create","group","draggedClass","plugins","bodyClass","numb","needle","replace","_onDrop","selectize_render_item","config","not","fancySelect","split","map","s","trim","reindex_config_table","itemSelector","common","init","renderMerchantInfo","form","k","opt","merchantInfo","feedType","r","types","html","t","toLowerCase","na","disabled","trigger","val","in_array","_loop2","contentSettings","feedForm","feedEditor","is","merchantInfoCache","tooltip","css","top","merchantTemplateCache","title","_feed","_current_btn","feed","_limit","generator","limit","_color","_product_ids","_progress_per_batch","_refresh","isRegenerating","_all_btn","generate","clip","clipboard","showTooltip","condition","then","URLSearchParams","preventDefault","parent","_progress","_log","_total_batch","_regenerate","regenerate","page_name","_block_button","_current_btn_label","post","_updateProgressStatus","message","product","_this2","_process_batch","setTimeout","_stopProgressBar","_current_batch","_save_feed_file","loop","_unblock_button","_resetProgressBar","console","refreshInterval","arguments","undefined","products","clearInterval","_timer","setInterval","_toggleProgressBar","table","show","color","width","wf","pagenow","attr_name","hover","appendTo","left","pageX","confirm","href","slideToggle","loader","_updateProgressBar","location","reload","button","status_area","select","execCommand","current_attribute_value","fancyOption","fancyDataPicker","selectIf","currency","price_attributes","selectKey","parents","includes","indexOf","outputSelect","feedCurrency","woocommerce","del_confirm_multi","row","validate","template","_ajax_clean_nonce","valid","save","server","sftp_checking","sftp_available","merchant","sftp_warning","name","templateName","loading_tmpl","provider","renderMerchantTemplate","checked","valueColumn","attribute","preload","google_category","query","learn_more","append","cb","facebookCategories","outOfStockVisibilityRow","wf_csv_txt","itemWrapper","item_wrapper_hidden","id","ready","windowpos","load","download","URL","scrollTop","googleMap","Date","click","cat_init","wooFeed_get_facebook_categories","wooFeed_get_google_categories","for_attr","prepend","setValue","catField","catId","groupId","searchParams","v","get","attribute_list","current_feed_currency","price_with_tax","current_price_with_tax","queryString","sale_price_with_tax","urlParams","weight","weight_unit","attribute_value","current_Value","dimension","search","eq","parseInt","inArray","_key","_value"],"mappings":"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","file":"woo-feed-admin.min.js","sourcesContent":["// noinspection JSUnresolvedletiable\n/**!\n * WooFeed Scripts\n * @version 3.3.6\n * @package WooFeed\n * @copyright 2020 WebAppick\n *\n */\n/* global ajaxurl, wpAjax, postboxes, pagenow, alert, deleteUserSetting, typenow, adminpage, thousandsSeparator, decimalPoint, isRtl */\n// noinspection JSUnresolvedVariable\n(function($, window, document, wpAjax, opts) {\n \"use strict\";\n /**\n * All of the code for your admin-facing JavaScript source\n * should reside in this file.\n *\n * Note: It has been assumed you will write jQuery code here, so the\n * $ function reference has been prepared for usage within the scope\n * of this function.\n *\n * This enables you to define handlers, for when the DOM is ready:\n */\n\n /**\n * disable element utility\n *\n * @since 3.1.9\n *\n * @param {*} status\n * @returns {$|HTMLElement}\n */\n $.fn.disabled = function(status) {\n $(this).each(function() {\n let self = $(this),\n prop = 'disabled';\n\n if (typeof self.prop(prop) !== 'undefined') {\n self.prop(prop, status === void 0 || status === true);\n } else {\n !0 === status ? self.addClass(prop) : self.removeClass(prop);\n }\n });\n return self; // method chaining\n };\n\n /**\n * Check if a HTMLElement or jQuery is disabled\n */\n $.fn.isDisabled = function() {\n let self = $(this),\n prop = 'disabled';\n return typeof self.prop(prop) !== 'undefined' ? self.prop(prop) : self.hasClass(prop);\n };\n\n /**\n * Clear Tooltip for clip board js\n * @param {Object} event\n */\n const clearTooltip = (event) => {\n $(event.currentTarget).removeClass( (index, className) => (className.match(/\\btooltipped-\\S+/g) || []).join(' ') ).removeClass('tooltipped').removeAttr('aria-label');\n };\n\n const showTooltip = (elem, msg) => {\n $(elem).addClass('tooltipped tooltipped-s').attr('aria-label', msg);\n };\n\n const fallbackMessage = (action) =>{\n let actionMsg,\n actionKey = action === 'cut' ? 'X' : 'C';\n\n if (/iPhone|iPad/i.test(navigator.userAgent)) {\n actionMsg = 'No support :(';\n } else if (/Mac/i.test(navigator.userAgent)) {\n actionMsg = 'Press ⌘-' + actionKey + ' to ' + action;\n } else {\n actionMsg = 'Press Ctrl-' + actionKey + ' to ' + action;\n }\n\n return actionMsg;\n };\n\n /**\n * Alias of jQuery.extend()\n * @param {Object} _default\n * @param {Object} _args\n */\n const extend = (_default, _args) => $.extend(true, {}, _default, _args);\n\n\t/*\n\t* Handles product attributes\n\t*\n\t* @since 4.4.18\n\t* */\n\tclass WooFeedCustomFields {\n\n\t\tconstructor( field, status, isTaxonomy ) {\n\t\t\tthis.productCustomFields( field, status, isTaxonomy );\n\t\t}\n\n\t\tcacheClear() {\n\t\t\tlet data = {\n\t\t\t\taction: 'woo_feed_product_attribute_cache_remove',\n\t\t\t\tnonce: wpf_ajax_obj.ajax.nonce,\n\t\t\t};\n\t\t\t$.ajax({\n\t\t\t\tmethod: 'POST',\n\t\t\t\turl: wpf_ajax_obj.wpf_ajax_url,\n\t\t\t\tdata\n\t\t\t});\n\t\t}\n\n\t\tproductCustomFields( field, status = false, isTaxonomy ) {\n\t\t\tlet data = {\n\t\t\t\taction: 'woo_feed_custom_fields_status_change',\n\t\t\t\tnonce: wpf_ajax_obj.ajax.nonce,\n\t\t\t\tfield,\n\t\t\t\tstatus,\n\t\t\t\tisTaxonomy\n\t\t\t};\n\t\t\t$.ajax({\n\t\t\t\tmethod: 'POST',\n\t\t\t\turl: wpf_ajax_obj.wpf_ajax_url,\n\t\t\t\tdata,\n\t\t\t\tsuccess: ( response ) => {\n\t\t\t\t\tif( response.success ) {\n\t\t\t\t\t\tthis.cacheClear();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.log( response );\n\t\t\t\t\t}\n $('#'+field+'-switcher').closest('td').find('.switch-loader').hide();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n /*\n * Handles product categories\n *\n * @since 4.4.39\n * */\n class WooFeedMapCategories {\n wooFeed_get_google_categories () {\n wpAjax.send('get_google_categories', {\n type: 'GET',\n data: {\n _ajax_nonce: opts.nonce,\n action: \"get_google_categories\",\n // provider: provider\n }\n }).then(function (response) {\n $('.selectize-google-category').selectize({\n valueField: 'value',\n labelField: 'text',\n placeholder: 'Select a category',\n searchField: ['value', 'text'],\n options: response,\n render: {\n option: (data, escape) => `<div class=\"item wapk-selectize-item\">${escape(data.value + ' - ' + data.text)}</div>`,\n item: (data, escape) => `<div class=\"item wapk-selectize-item\">${escape(data.value + ' - ' + data.text)}</div>`\n }\n });\n\n //remove spinner element\n $('.woo-feed-cat-map-spinner').remove();\n }).fail(helper.ajax_fail);\n }\n\n wooFeed_get_facebook_categories() {\n // get facebook categories\n wpAjax.send('get_facebook_categories', {\n type: 'GET',\n data: {\n _ajax_nonce: opts.nonce,\n action: \"get_facebook_categories\",\n // provider: provider\n }\n }).then(function (response) {\n $('.selectize-google-category').selectize({\n valueField: 'value',\n labelField: 'text',\n placeholder: 'Select a Facebook category',\n searchField: ['value', 'text'],\n options: response,\n render: {\n option: (data, escape) => `<div class=\"item wapk-selectize-item\">${escape(data.value + ' - ' + data.text)}</div>`,\n item: (data, escape) => `<div class=\"item wapk-selectize-item\">${escape(data.value + ' - ' + data.text)}</div>`\n }\n });\n\n //remove spinner element\n $('.woo-feed-cat-map-spinner').remove();\n }).fail(helper.ajax_fail);\n }\n }\n\n let $copyBtn,\n clipboard,\n googleCategories,\n facebookCategories,\n helper = {\n in_array: (needle, haystack) => {\n try {\n return haystack.indexOf(needle) !== -1;\n } catch (e) {\n return false;\n }\n },\n selectize_render_item: (data, escape) => `<div class=\"item wapk-selectize-item\">${escape(data.text)}</div>`, // phpcs:ignore WordPressVIPMinimum.JS.StringConcat.Found,\n ajax_fail: e => {\n console.warn(e);\n alert(e.hasOwnProperty('statusText') && e.hasOwnProperty('status') ? opts.ajax.error + '\\n' + e.statusText + ' (' + e.status + ')' : e);\n },\n /**\n * Initialize Sortable\n * @param {$|HTMLElement} el\n * @param {object} config\n * @param {int|boolean} column\n * @param {function} onDrop\n * @return {$|HTMLElement}\n */\n sortable: (el, config, column, onDrop) => {\n return (el || $('.sorted_table')).each(function() {\n let self = $(this),\n column_count = self.find('tbody > tr:eq(0) > td').length || column || 9;\n self.wf_sortable(extend({\n containerSelector: 'table',\n itemPath: '> tbody',\n itemSelector: 'tr',\n handle: 'i.wf_sortedtable',\n placeholder: `<tr class=\"placeholder\"><td colspan=\"${column_count}\"></td></tr>`,\n onDrop: ($item, container, _super, event) => {\n $item.removeClass(container.group.options.draggedClass).removeAttr('style');\n $(\"body\").removeClass(container.group.options.bodyClass);\n var numb = $item.find(\".wf_mattributes\").attr(\"name\").replace(/\\D/g, \"\");\n $item.find(\"input.wf_attributes\").attr(\"name\", \"default[\"+ numb +\"]\");\n if ( onDrop && 'function' === typeof( onDrop ) ) {\n onDrop( $item, container, _super, event );\n }\n },\n }, config));\n });\n },\n selectize: (el, config) => {\n return (el || $('select.selectize')).not('.selectized').not('.selectize-google-category').each(function() {\n let self = $(this);\n self.selectize(extend({\n create: self.data('create') || false,\n plugins: self.data('plugins') ? self.data('plugins').split(',').map(function(s) {\n return s.trim();\n }) : [],\n //['remove_button'],\n render: {\n item: helper.selectize_render_item\n }\n }, config));\n });\n },\n fancySelect: (el, config) => {\n return (el || $('select.fancySelect')).not('.FancySelectInit').each(function() {\n let self = $(this);\n self.fancySelect(extend({\n maxItemShow: 3\n }, config));\n });\n },\n reindex_config_table: () => {\n $('#table-1').find('tbody tr').each( ( x, el ) => {\n $(el).find('[name]').each( ( x1, el ) => {\n $(el).attr('name', $(el).attr('name').replace(/(\\[\\d\\])/g, `[${x}]`));\n } );\n } );\n },\n common: () => {\n helper.sortable( $('.sorted_table'), {}, 9, helper.reindex_config_table );\n helper.selectize();\n helper.fancySelect($('.outputType'));\n }\n },\n // helper functions\n feedEditor = {\n /**\n * The Editor Form Elem.\n * @type {$|HTMLElement}\n */\n form: null,\n\n /**\n * Initialize The Feed Editor {Tabs...}\n * @returns {void}\n */\n init: function () {\n let self = this;\n self.form = $('.generateFeed');\n if (!self.form.length) return;\n helper.common();\n // noinspection JSUnresolvedVariable\n $(document).trigger('feed_editor_init');\n $(document).trigger(new jQuery.Event('feedEditor.init', {\n target: this.form\n }));\n },\n\n /**\n * Render Merchant info ajax response and handle allowed feed type for selected merchant\n * @param {$|HTMLElement} merchantInfo jQuery dom object\n * @param {$|HTMLElement} feedType jQuery dom object\n * @param {Object} r ajax response object\n */\n renderMerchantInfo: function (merchantInfo, feedType, r) {\n for (let k in r) {\n if (r.hasOwnProperty(k)) {\n merchantInfo.find('.merchant-info-section.' + k + ' .data').html(r[k]); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html\n\n if ('feed_file_type' === k) {\n (function() {\n let types = r[k].split(\",\").map(function(t) {\n return t.trim().toLowerCase();\n }).filter(function(t) {\n // noinspection JSUnresolvedVariable\n return t !== '' && t !== opts.na.toLowerCase();\n });\n\n if (types.length) {\n feedType.find('option').removeAttr('selected').each(function() {\n let opt = $(this);\n opt.val() && !helper.in_array(opt.val(), types) ? opt.disabled(!0) : opt.disabled(!1);\n });\n if (types.length === 1) feedType.find('option[value=\"' + types[0] + '\"]').attr('selected', 'selected');\n } else feedType.find('option').disabled(!1);\n })();\n }\n }\n }\n\n merchantInfo.find('.spinner').removeClass('is-active');\n feedType.disabled(!1);\n feedType.trigger('change');\n\n /**\n * Triggers after merchant configuration is fetched & loaded\n * */\n $(document).trigger('woo_feed_config_loaded');\n\n feedType.parent().find('.spinner').removeClass('is-active');\n },\n\n /**\n * Render Feed Template Tabs and settings while creating new feed.\n * @param {$|HTMLElement} feedForm feed from query dom object\n * @param {object} r merchant template ajax response object\n */\n renderMerchantTemplate: function (feedForm, r) {\n let _loop = function _loop(k) {\n if (r.hasOwnProperty(k)) {\n if ('tabs' === k) {\n // noinspection JSUnresolvedFunction\n feedForm.html(r[k]); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html\n } else {\n let contentSettings = $('[name=\"' + k + '\"]');\n\n if (contentSettings.length) {\n contentSettings.each(function() {\n let elem = $(this);\n\n if (elem.is('select')) {\n elem.find('[value=\"' + r[k] + '\"]').prop('selected', true);\n } else if ((elem.is('[type=checkbox]') || elem.is('[type=radio]')) && elem.val() === r[k]) {\n elem.prop('checked', true);\n } else {\n elem.val(r[k]); // type=text\n }\n }).trigger('change');\n }\n }\n }\n };\n\n for (let k in r) {\n _loop(k);\n }\n\n feedEditor.init();\n }\n },\n // Feed Editor Table\n merchantInfoCache = [],\n merchantTemplateCache = [],\n tooltip = () => {\n // Tooltip only Text\n $('.wfmasterTooltip')\n .hover(function () {\n // Hover over code\n let self = $(this), title = self.attr('wftitle');\n self.data('tipText', title).removeAttr('wftitle');\n $('<p class=\"wftooltip\"></p>').text(title).appendTo('body').fadeIn('slow');\n }, function () {\n // Hover out code\n let self = $(this);\n self.attr('wftitle', self.data('tipText'));\n $('.wftooltip').remove();\n })\n .mousemove(function (e) {\n $('.wftooltip').css({\n top: e.pageY + 10,\n left: e.pageX + 20\n });\n });\n },\n clip = () => {\n $copyBtn = $('.toClipboard');\n if (!ClipboardJS.isSupported() || /iPhone|iPad/i.test(navigator.userAgent)) {\n $copyBtn.find('img').hide(0);\n } else {\n $copyBtn.each(function() {\n $(this).on('mouseleave', clearTooltip).on('blur', clearTooltip);\n });\n clipboard = new ClipboardJS('.toClipboard');\n clipboard.on('error', function(event) {\n showTooltip(event.trigger, fallbackMessage(event.action));\n }).on('success', function(event) {\n showTooltip(event.trigger, 'Copied');\n });\n }\n };\n\n /**\n * Feed Generator Module\n */\n class feedGenerator {\n\n /**\n * Constructor\n * @constructor\n */\n constructor() {\n this._feed = opts.generator.feed; // wf_config+xxxx\n this._limit = opts.generator.limit;\n this._progress = 0;\n this._timer = null;\n this._color = false;\n // batch info\n this._total_batch = 0;\n this._current_batch = 0;\n this._product_ids = [];\n this._progress_per_batch = 0;\n this._refresh = true;\n // noinspection JSUnresolvedVariable\n this._regenerate = opts.generator.regenerate;\n window.isRegenerating = false;\n this._all_btn = $('.wpf_regenerate');\n this._current_btn = $(`#${this._feed.replace( 'wf_config', 'wf_feed_' )}`);\n this._current_btn_label = '';\n }\n\n /**\n * Init Hooks (Event)\n * @return {feedGenerator}\n */\n init() {\n let self = this;\n if ( '' !== this._feed && this._regenerate && false === window.isRegenerating ) {\n this.generate();\n }\n\n //thickbox body add feed plugin class to make it unique and custom style\n let current_page_query = window.location.search;\n let params = new URLSearchParams(current_page_query);\n let page_name = params.get(\"page\");\n if( \"webappick-manage-feeds\" === page_name ) {\n $('body').addClass('woo-import-popup-body');\n }\n\n $(document).on('click', '.woo-feed-campaign-close-button', function(event) {\n event.preventDefault();\n\n $(this).parent('.woo-feed-promotion').hide();\n let condition = $(this).data('condition');\n if(1 === condition) {\n wpAjax.post( 'woo_feed_hide_promotion', {\n _ajax_nonce: opts.nonce,\n condition: condition,\n } ).then( response => {\n self._log( response );\n } ).fail( error => {\n self._log( error );\n self._updateProgressStatus( error.message );\n self._color = 'red';\n } );\n }\n });\n\n $(document).on('click', '.wpf_regenerate', function(event) {\n event.preventDefault();\n self._current_btn = $( this );\n if( self._current_btn.hasClass('disabled') || window.isRegenerating === true ) return;\n self._feed = self._current_btn.attr('id').replace( 'wf_feed_', 'wf_config' );\n if( '' !== self._feed ) {\n self.generate();\n }\n });\n return this;\n }\n\n _block_button() {\n if ( this._all_btn.length ) {\n this._all_btn.addClass('disabled');\n }\n if ( this._current_btn.length ) {\n this._current_btn.find('span').addClass('wpf_spin reverse_spin');\n this._current_btn_label = this._current_btn.attr('title');\n // noinspection JSUnresolvedVariable\n this._current_btn.attr( 'aria-label', opts.regenerate ).attr( 'title', opts.regenerate );\n }\n }\n\n _unblock_button() {\n if ( this._all_btn.length ) {\n this._all_btn.removeClass('disabled');\n }\n if ( this._current_btn.length ) {\n this._current_btn.find('span').removeClass('wpf_spin');\n this._current_btn.find('span').removeClass('reverse_spin');\n this._current_btn.attr( 'aria-label', this._current_btn_label ).attr( 'title', this._current_btn_label );\n }\n }\n\n /**\n * Generate Feed\n * @return void\n */\n generate() {\n let self = this;\n window.isRegenerating = true;\n this._block_button();\n this._resetProgressBar();\n this._progressBarActive();\n this._log( 'Counting Total Products' );\n this._updateProgressStatus( 'Fetching products.' );\n this._get_product_ids().then( response => {\n this._progress = 10;\n self._log( {response} );\n if(response.success) {\n self._log( `Total ${response.total} Products found.` );\n self._product_ids = response.product;\n self._total_batch = this._product_ids.length;\n self._current_batch = 0;\n self._progress_per_batch = ( 90 - this._progress ) / this._total_batch;\n self._process_batch();\n self._updateProgressStatus( 'Processing Products...' );\n } else {\n self._updateProgressStatus( response.data.message );\n }\n }).fail( error => {\n self._log( error );\n self._updateProgressStatus( error.message );\n self._color = 'red';\n setTimeout( function(){\n self._stopProgressBar();\n self._unblock_button();\n }, 1500 );\n } );\n }\n\n /**\n * Get Product Ids\n * @returns {$.promise}\n * @private\n */\n _get_product_ids() {\n this._progress = 5;\n return wpAjax.post( 'get_product_information', {\n _ajax_nonce: opts.nonce,\n feed: this._feed,\n limit: this._limit,\n } );\n }\n\n /**\n * Run the Batch\n * @private\n */\n _process_batch() {\n let self = this;\n let status = `Processing Batch ${this._current_batch+1} of ${this._total_batch}`;\n this._updateProgressStatus( status );\n this._log( status );\n wpAjax.post( 'make_batch_feed', {\n _ajax_nonce: opts.nonce,\n feed: this._feed,\n products: this._product_ids[this._current_batch],\n loop: this._current_batch,\n } ).then( response => {\n self._current_batch++;\n self._log( `Batch ${self._current_batch} Completed` );\n self._log( response );\n if ( self._current_batch < self._total_batch ) {\n self._process_batch();\n self._progress += self._progress_per_batch;\n }\n if ( self._current_batch === self._total_batch ) {\n self._save_feed_file();\n }\n } ).fail( error => {\n self._log( error );\n self._updateProgressStatus( error.message );\n self._color = 'red';\n setTimeout( function(){\n self._stopProgressBar();\n self._unblock_button();\n }, 1500 );\n } );\n }\n\n /**\n * Save Feed Data from temp to feed file\n * @private\n */\n _save_feed_file() {\n let self = this;\n this._log( 'Saving feed file' );\n this._updateProgressStatus( 'Saving feed file' );\n wpAjax.post( 'save_feed_file', {\n _ajax_nonce: opts.nonce,\n feed: this._feed,\n } ).then( response => {\n self._log( response );\n self._progress = 100;\n if ( self._refresh ) {\n window.location.href = `${opts.pages.list.feed}&link=${response.url}&cat=${response.cat}`;\n }\n setTimeout( function(){\n self._stopProgressBar();\n setTimeout( function(){\n self._resetProgressBar( true );\n self._unblock_button();\n }, 3000 );\n }, 2500 );\n } ).fail( error => {\n self._log( error );\n self._updateProgressStatus( error.message );\n self._color = 'red';\n setTimeout( function(){\n self._stopProgressBar();\n self._unblock_button();\n }, 1500 );\n } );\n }\n\n /**\n * Console log wrapper with debug settings.\n * @param data\n * @returns {feedGenerator}\n * @private\n */\n _log( data ) {\n // noinspection JSUnresolvedVariable\n if ( opts.wpf_debug ) {\n console.log( data );\n }\n return this;\n }\n\n /**\n * Run the progressbar refresh interval\n * @param {int} refreshInterval\n * @returns {feedGenerator}\n * @private\n */\n _progressBarActive( refreshInterval = 0 ) {\n let self = this;\n this._toggleProgressBar( true );\n this._timer = setInterval( function(){\n self._updateProgressBar();\n }, refreshInterval || 1000 );\n return this;\n }\n\n /**\n * Stop Progressbar\n * @returns {feedGenerator}\n * @private\n */\n _stopProgressBar() {\n clearInterval( this._timer );\n return this;\n }\n\n /**\n * Reset Progressbar\n * @returns {feedGenerator}\n * @private\n */\n _resetProgressBar( update ) {\n this._toggleProgressBar( false );\n this._updateProgressStatus( '' );\n clearInterval( this._timer );\n this._color = false;\n this._timer = null;\n this._progress = 0;\n if ( update ) {\n this._updateProgressBar();\n }\n return this;\n }\n\n /**\n * Show hide the progress bar el\n * @param status\n * @returns {feedGenerator}\n * @private\n */\n _toggleProgressBar( status ) {\n let table = $('#feed_progress_table');\n if ( status ) {\n table.show();\n } else {\n table.hide();\n }\n return this;\n }\n\n /**\n * Update Progress bar text status\n * @param {string} status\n * @returns {feedGenerator}\n * @private\n */\n _updateProgressStatus( status ) {\n $( '.feed-progress-status' ).html( status );\n return this;\n }\n\n _getErrorMessageByCode( error ){\n let progress_message = $( '.feed-progress-status' );\n progress_message.css( {'color':this._color});\n $( '.feed-progress-percentage' ).css( {'color':this._color});\n $( '.wpf_spin' ).css( {'color':this._color});\n\n let message=error.status +' : '+ error.statusText+'. ';\n if(500===error.status){\n message+= \"Please increase your PHP max_execution_time. Please <a target='_blank' href='https://webappick.com/docs/woo-feed/faq-for-woocommerce-product-feed/how-to-solve-processing-10-feed-generation-stuck-error/'>read this doc</a>.\";\n }\n\n this._updateProgressStatus(message);\n\n }\n\n /**\n * Update Progress Data\n * hooked with setInterval\n * @private\n */\n _updateProgressBar() {\n let percentage = $( '.feed-progress-percentage' ),\n bar = $( '.feed-progress-bar-fill' ),\n _progress = `${Math.round( this._progress )}%`;\n bar.css( {\n width: _progress,\n } );\n percentage.text( _progress );\n }\n }\n // expose to the global scope\n window.wf = {\n helper: helper,\n feedEditor: feedEditor,\n generator: feedGenerator,\n };\n\n $(window).on('load', function() {\n // Template loading ui conflict\n if ($(location).attr(\"href\").match(/webappick.*feed/g) !== null) {\n $('#wpbody-content').addClass('woofeed-body-content');\n }\n\n // ClipBoardJS\n clip();\n // postbox toggle\n postboxes.add_postbox_toggles(pagenow);\n // initialize generator\n let generator = new feedGenerator();\n generator.init();\n // noinspection JSUnresolvedVariable\n if( '' !== opts.generator.feed && opts.generator.regenerate ) {\n\n }\n // initialize editor\n feedEditor.init();\n helper.common(); // Generate Feed Add Table Row\n tooltip();\n // validate feed editor\n $(\".generateFeed\").validate();\n\n // document events\n $(document)\n .on('blur', 'input[name=\"wfDAttributeName\"]', function(e) {\n e.preventDefault();\n let attr_name = $(this).val();\n attr_name = attr_name.toLowerCase();\n attr_name = attr_name.split(' ').join('_');\n\n $('#wfDAttributeCode').val(attr_name);\n\n })\n .on('click', '[data-toggle_slide]', function(e) {\n e.preventDefault();\n $($(this).data('toggle_slide')).slideToggle('fast');\n })\n // XML Feed Wrapper\n .on('click', '#wf_newRow', function () {\n let tbody = $('#table-1 tbody'),\n template = $('#feed_config_template').text().trim().replace(/__idx__/g, tbody.find('tr').length);\n tbody.append(template);\n helper.fancySelect($('.outputType'));\n })\n // feed delete alert.\n .on('click', '.single-feed-delete', function (event) {\n event.preventDefault();\n // noinspection JSUnresolvedVariable\n if (confirm(opts.form.del_confirm)) {\n window.location.href = $(this).attr('val');\n }\n })\n // clear cache data.\n .on('click', '.wf_clean_cache_wrapper', function(event) {\n event.preventDefault();\n var nonce = $('.woo-feed-clean-cache-nonce').val();\n var loader = $('.woo-feed-cache-loader');\n\n //show loader\n loader.show();\n\n // passed cache nonce\n wpAjax.post('clear_cache_data', {\n _ajax_clean_nonce: nonce\n }).then(function (response) {\n if( response.success ) {\n loader.hide(); //hide loader\n location.reload();\n }\n }).fail(function () {\n console.log('something wrong');\n });\n\n })// Copy Status\n .on('click', '#woo-feed-copy-status-btn', function(event) {\n event.preventDefault();\n let button = $('#woo-feed-copy-status-btn');\n let status_area = $('#woo-feed-status-area');\n button.val('Copied');\n status_area.css('visibility','visible');\n status_area.select();\n\n document.execCommand('copy');\n })\n // feed value dropdown change.\n .on('change', '.wf_attr.wf_attributes', function(event) {\n event.preventDefault();\n\n $('.fancy-picker-picked').trigger(\"click\"); // trigger fancy select box clicked\n\n // price attributes\n var price_attributes = ['price', 'current_price', 'sale_price', 'price_with_tax', 'current_price_with_tax', 'sale_price_with_tax', 'shipping_cost'];\n // current value\n var current_attribute_value = $(this).val();\n var outputSelect = $(this).parents('tr').find('.outputType');\n var fancyOption = $(this).parents('tr').find('.fancy-picker-content .fancy-picker-option');\n var fancyDataPicker = $(this).parents('tr').find('.fancy-picker-data span');\n var selectIf, selectKey;\n var currency;\n\n // when any attribute is selected, pick the key\n if( price_attributes.includes(current_attribute_value) ) {\n // when select any price attribute\n selectIf = 'for_price';\n selectKey = \"Price\";\n } else if ( \"\" !== current_attribute_value && -1 !== current_attribute_value.indexOf('wf_taxo') ) {\n\n // when select any custom taxonomy\n selectIf = 'for_custom_taxo';\n selectKey = \"parent_if_empty\";\n } else {\n\n selectIf = 'for_all';\n selectKey = 'Default';\n }\n\n // remove selected class from old selected option\n fancyOption.removeClass('selected');\n\n // when value dropdown is selected as price or any custom taxonomy\n if( selectIf === 'for_custom_taxo' || selectIf === 'for_price' ) {\n // update \"Option Type\" when select key matches\n fancyOption.each(function() {\n if( selectKey === $(this).text() ) {\n $(this).addClass('selected');\n fancyDataPicker.text(selectKey);\n outputSelect.find(\"option\").text(selectKey);\n outputSelect.find(\"option\").val( $(this).data('value') );\n }\n });\n\n if( \"for_price\" === selectIf ) {\n var feedCurrency = $('#feedCurrency').val();\n if( \"undefined\" !== typeof feedCurrency && null !== feedCurrency ) {\n currency = feedCurrency;\n }else {\n currency = wpf_ajax_obj.woocommerce.currency;\n }\n\n //for price add currency to the suffix\n $(this).closest(\"tr\").find(\"td:eq(5) input\").val(\" \" + currency);\n }\n\n } else {\n fancyOption.each(function(){\n if( selectKey === $(this).text() ){\n $(this).addClass('selected');\n fancyDataPicker.text(selectKey);\n outputSelect.find(\"option\").text(selectKey);\n outputSelect.find(\"option\").val( $(this).data(\"value\") );\n }\n });\n\n $(this).closest(\"tr\").find(\"td:eq(5) input\").val(\"\");\n }\n\n })\n // bulk delete alert.\n .on('click', '#doaction, #doaction2', function () {\n // noinspection JSUnresolvedVariable\n return confirm(opts.form.del_confirm_multi);\n })\n // Generate Feed Table Row Delete\n .on('change', '.dType', function () {\n let self = $(this),\n type = self.val(),\n row = self.closest('tr');\n\n if (type === 'pattern') {\n row.find('.value_attribute').hide();\n row.find('.value_pattern').show();\n } else if (type === 'attribute') {\n row.find('.value_attribute').show();\n row.find('.value_pattern').hide();\n } else if (type === 'remove') {\n row.find('.value_attribute').hide();\n row.find('.value_pattern').hide();\n }\n })\n // Generate Feed Form Submit\n .on('click', '.delRow', function (e) {\n e.preventDefault();\n $(this).closest('tr').remove();\n helper.reindex_config_table();\n })\n .on('submit', '#generateFeed', function () {\n // Feed Generating form validation\n $(this).validate();\n\n if ($(this).valid()) {\n $(\".makeFeedResponse\")\n .show()\n .html(`<b style=\"color: darkblue;\"><i class=\"dashicons dashicons-sos wpf_spin\"></i> ${opts.form.generate}</b>`); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html, WordPressVIPMinimum.JS.StringConcat.Found\n }\n })\n // Generate Update Feed Form Submit\n .on('submit', '#updatefeed', function (e, data) {\n // Feed Generating form validation\n $(this).validate();\n\n if ($(this).valid()) {\n $(\".makeFeedResponse\")\n .show()\n .html(`<b style=\"color: darkblue;\"><i class=\"dashicons dashicons-sos wpf_spin\"></i> ${data && data.save ? opts.form.save : opts.form.generate}</b>`); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html, WordPressVIPMinimum.JS.StringConcat.Found\n }\n })\n .on( 'ready woo_feed_config_loaded', function(){\n\n if( $('#ftpenabled').val() === '0' ){\n $('.google-merchant-message').hide('slow');\n $('.woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) input, .woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) select').attr('disabled','disabled');\n } else {\n if( $('#provider').val() === 'google' ) {\n $('.google-merchant-message').show('slow');\n } else {\n $('.google-merchant-message').hide('slow');\n }\n $('.woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) input, .woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) select').removeAttr('disabled');\n }\n\n $('#ftpenabled').on('change', function(){\n if( $('#ftpenabled').val() === '0' ){\n $('.google-merchant-message').hide('slow');\n $('.woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) input, .woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) select').attr('disabled','disabled');\n } else {\n\n $('.woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) input, .woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) select').removeAttr('disabled');\n\n // Google merchant specific message\n if( $('#provider').val() === 'google' ){\n $('.google-merchant-message').show('slow');\n } else {\n $('.google-merchant-message').hide('slow');\n }\n\n }\n });\n })\n .on('change', '.ftporsftp', function () {\n let server = $(this).val(),\n status = $('.ssh2_status');\n\n if (server === 'sftp') {\n // noinspection JSUnresolvedVariable\n status.show().css('color', 'dodgerblue').text(opts.form.sftp_checking);\n wpAjax.post('get_ssh2_status', {\n _ajax_nonce: opts.nonce,\n server: server\n }).then(function (response) {\n if (response === 'exists') {\n // noinspection JSUnresolvedVariable\n status.css('color', '#2CC185').text(opts.form.sftp_available);\n setTimeout(function () {\n status.hide();\n }, 1500);\n } else {\n // noinspection JSUnresolvedVariable\n status.show().css('color', 'red').text(opts.form.sftp_warning);\n }\n }).fail(function (e) {\n status.hide();\n helper.ajax_fail(e);\n });\n } else {\n status.hide();\n }\n })\n .on('click', '[name=\"save_feed_config\"]', function (e) {\n e.preventDefault();\n $('#updatefeed').trigger('submit', {\n save: true\n });\n })\n .on('change', '#provider', function (event) {\n event.preventDefault();\n\n let merchant = $(this).val(),\n templateName = $(this).find(':selected').text(),\n name = $('#filename').val(),\n feedType = $(\"#feedType\"),\n feedForm = $(\"#providerPage\"),\n merchantInfo = $('#feed_merchant_info'); // set loading..\n\n // noinspection JSUnresolvedVariable\n feedForm.html('<h3><span style=\"float:none;margin: -3px 0 0;\" class=\"spinner is-active\"></span> ' + opts.form.loading_tmpl + '</h3>'); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html, WordPressVIPMinimum.JS.StringConcat.Found\n\n merchantInfo.find('.spinner').addClass('is-active');\n feedType.disabled(!0); // disable dropdown\n\n feedType.parent().find('.spinner').addClass('is-active');\n merchantInfo.find('.merchant-info-section .data').html(''); // remove previous data\n // Get Merchant info for selected Provider/Merchant\n\n if (merchantInfoCache.hasOwnProperty(merchant)) {\n feedEditor.renderMerchantInfo(merchantInfo, feedType, merchantInfoCache[merchant]);\n\n /**\n * Triggers after merchant configuration is fetched & loaded\n * */\n $(document).trigger('woo_feed_config_loaded');\n\n } else {\n wpAjax.send('woo_feed_get_merchant_info', {\n type: 'GET',\n data: {\n nonce: opts.nonce,\n provider: merchant,\n templateName: templateName\n }\n }).then(function (r) {\n merchantInfoCache[merchant] = r;\n feedEditor.renderMerchantInfo(merchantInfo, feedType, r);\n }).then(function(){\n\n /**\n * Triggers after merchant configuration is fetched & loaded\n * */\n $(document).trigger('woo_feed_config_loaded');\n\n }).fail(helper.ajax_fail);\n } // Get FeedForm For Selected Provider/Merchant\n\n\n if (merchantTemplateCache.hasOwnProperty(merchant)) {\n feedEditor.renderMerchantTemplate(feedForm, merchantTemplateCache[merchant]);\n\n /**\n * Triggers after merchant configuration is fetched & loaded\n * */\n $(document).trigger('woo_feed_config_loaded');\n\n } else {\n wpAjax.post('get_feed_merchant', {\n _ajax_nonce: opts.nonce,\n merchant: merchant\n }).then(function (r) {\n merchantTemplateCache[merchant] = r;\n feedEditor.renderMerchantTemplate(feedForm, r);\n $('#utm_source').val(templateName);\n $('#utm_campaign').val(name);\n //when merchant is bing, change delimiter and enclosure\n if( 'bing' === merchant ) {\n //delimiter value\n $(\"#delimiter option\").removeAttr('selected');\n $(\"#delimiter option[value=\\\"tab\\\"]\").attr('selected', 'selected');\n\n //enclosure value\n $(\"#enclosure option\").removeAttr('selected');\n $(\"#enclosure option[value=\\\" \\\"]\").attr('selected', 'selected');\n }\n\n //reviewer options hide\n if( 'google_product_review' !== merchant) {\n $('.wf_attributes option[value=\"reviewer_name\"]').hide();\n }\n }).then(function(){\n\n /**\n * Triggers after merchant configuration is fetched & loaded\n * */\n $(document).trigger('woo_feed_config_loaded');\n\n }).fail(helper.ajax_fail);\n }\n })\n // Feed Active and Inactive status change via ajax\n .on('change', '.woo_feed_status_input', function () {\n let self = $(this);\n wpAjax.post('update_feed_status', {\n _ajax_nonce: opts.nonce,\n feedName: self.val(),\n status: self[0].checked ? 1 : 0\n });\n });\n // event with trigger\n $(document)\n .on('change', '[name=\"is_outOfStock\"], [name=\"product_visibility\"]', function () {\n let outOfStockVisibilityRow = $('.out-of-stock-visibility');\n if ($('[name=\"is_outOfStock\"]:checked').val() === 'n' && $('[name=\"product_visibility\"]:checked').val() === '1') {\n outOfStockVisibilityRow.show();\n } else {\n outOfStockVisibilityRow.hide();\n }\n })\n .on('change', '.attr_type', function () {\n // Attribute type selection\n let self = $(this),\n type = self.val(),\n row = self.closest('tr');\n\n if (type === 'pattern') {\n row.find('.wf_attr').hide();\n row.find('.wf_attr').val('');\n row.find('.wf_default').show();\n } else {\n row.find('.wf_attr').show();\n row.find('.wf_default').hide();\n row.find('.wf_default').val('');\n }\n })\n .on('change', '.wf_mattributes, .attr_type', function () {\n let row = $(this).closest('tr'),\n attribute = row.find('.wf_mattributes'),\n type = row.find('.attr_type'),\n valueColumn = row.find('td:eq(4)'),\n provider = $('#provider').val();\n\n // noinspection JSUnresolvedVariable\n if (opts.form.google_category.hasOwnProperty(attribute.val()) && type.val() === 'pattern' && helper.in_array(provider, opts.form.google_category[attribute.val()])) {\n if (valueColumn.find('select.selectize').length === 0) {\n valueColumn.find('input.wf_default').remove();\n valueColumn.append('<span class=\"wf_default wf_attributes\"><select name=\"default[]\" class=\"selectize\"></select></span>');\n // noinspection JSUnresolvedVariable\n valueColumn.append(`<span style=\"font-size:x-small;\"><a style=\"color: red\" href=\"https://webappick.com/docs/woo-feed/feed-configuration/how-to-map-store-category-with-merchant-category/\" target=\"_blank\">${opts.learn_more}</a></span>`);\n\n if (!googleCategories || !facebookCategories) {\n valueColumn.append('<span class=\"spinner is-active\" style=\"margin: 0;\"></span>');\n }\n\n let select = valueColumn.find('.wf_attributes select');\n // noinspection JSUnresolvedVariable\n helper.selectize(select, {\n preload: true,\n placeholder: opts.form.select_category,\n load: function load(query, cb) {\n if (!googleCategories) {\n wpAjax.send('get_google_categories', {\n type: 'GET',\n data: {\n _ajax_nonce: opts.nonce,\n action: \"get_google_categories\",\n provider: provider\n }\n }).then(function (r) {\n googleCategories = r;\n cb(googleCategories);\n valueColumn.find('.spinner').remove();\n }).fail(helper.ajax_fail);\n } else {\n cb(googleCategories);\n }\n\n //for facebook product category merchant attribute\n if (!facebookCategories && \"facebook\" === provider && \"fb_product_category\" === attribute.val()) {\n wpAjax.send('get_facebook_categories', {\n type: 'GET',\n data: {\n _ajax_nonce: opts.nonce,\n action: \"get_facebook_categories\",\n provider: provider\n }\n }).then(function (r) {\n facebookCategories = r;\n cb(facebookCategories);\n valueColumn.find('.spinner').remove();\n }).fail(helper.ajax_fail);\n } else {\n cb(facebookCategories);\n }\n }\n });\n }\n } else {\n if ( attribute.val() !== 'current_category' && valueColumn.find('input.wf_default').length === 0) {\n valueColumn.find('span').remove();\n valueColumn.append('<input autocomplete=\"off\" class=\"wf_default wf_attributes\" type=\"text\" name=\"default[]\" value=\"\">');\n\n if (type.val() !== 'pattern') {\n valueColumn.find('input.wf_default').hide();\n }\n }\n }\n })\n .on('change', '#feedType,#provider', function (e) {\n let type = $('#feedType').val(),\n provider = $('#provider').val(),\n itemWrapper = $('.itemWrapper'),\n wf_csv_txt = $('.wf_csvtxt');\n\n // noinspection JSUnresolvedVariable\n if (type !== '' && helper.in_array(provider, opts.form.item_wrapper_hidden)) {\n itemWrapper.hide();\n }\n\n //when feed type is changed\n if( 'feedType' === e.target.id ) {\n if (type === 'csv' || type === 'txt' || type === 'tsv') {\n wf_csv_txt.show();\n itemWrapper.hide();\n \n if( 'tsv' === type ) {\n $('#delimiter option:last').prop(\"selected\", \"selected\");\n } else if( 'csv' === type ) {\n $('#delimiter option:first').prop(\"selected\", \"selected\");\n }\n } else if( 'xml' === type && \"custom\" === provider ) {\n itemWrapper.show();\n wf_csv_txt.hide();\n } else if( 'json' === type ) {\n wf_csv_txt.hide();\n }\n }\n\n // when template is not custom template 1 hide the item wrapper\n if( \"custom\" !== provider ) {\n itemWrapper.hide();\n }\n\n })\n .trigger('change');\n\n\n $(document)\n\t\t\t.on('click', '.woofeed-custom-fields [id*=\"-switcher\"]', function () {\n\t\t\t $(this).closest('td').find('.switch-loader').show();\n\t\t\t\tlet field = $(this).attr( 'id' ).split( '-' )[0],\n\t\t\t\t\tisTaxonomy = $(this).data( 'taxonomy' ),\n\t\t\t\t\tstatus = $(this).prop( 'checked' );\n\t\t\t\tnew WooFeedCustomFields( field, status, isTaxonomy );\n\n\t\t\t})\n\n\t\t\t// Remove sticky cart on feature page\n\t\t\t.ready(function() {\n\t\t\t\tvar s = $(\".wapk-feed-buy-now-container\");\n\t\t\t\t$(window).scroll(function() {\n\t\t\t\t\tvar windowpos = $(window).scrollTop();\n\t\t\t\t\tif ( windowpos <= 5000 ) {\n\t\t\t\t\t\ts.addClass(\"fixed\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\ts.removeClass(\"fixed\");\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n });\n\n $(document)\n\t\t.on('click', '#woo-feed-debug-log-download', function (e) {\n\t\t\te.preventDefault();\n\t\t\t$(\"<a />\", {\n\t\t\t\tdownload: new Date() + \".log\",\n\t\t\t\thref: URL.createObjectURL(\n\t\t\t\t\tnew Blob([$(\"#woo-feed-debug-log\").val()], {\n\t\t\t\t\t\ttype: \"text/plain\"\n\t\t\t\t\t})),\n\t\t\t}).appendTo(\"body\")[0].click();\n\t\t})\n\t\t.on('keyup', '#filename', function() {\n\t\t\tvar name = $('#filename').val();\n\t\t\t$('#utm_campaign').val(name);\n\t\t})\n\n .on('click', '.wf-tab-name', function(e) {\n $('.wf-tab-name.activate').removeClass('activate');\n $(this).addClass('activate');\n\n let for_attr = $(this).attr('for');\n $('.wf_tabs li.active').removeClass('active');\n $('.wf_tabs .wf-tab-content#' + for_attr).parent().addClass('active');\n })\n\n\t\t.on('change', '#category-mapping-form #providers', function() {\n\t\t\tvar provider = $(this).find(':selected').val(),\n\t\t\t\tgoogleMap = ['google', 'facebook', 'pinterest', 'bing', 'bing_local_inventory', 'snapchat'];\n\n //add snipper element\n $('.woo-feed-category-mapping-config-table').prepend('<div class=\"woo-feed-cat-map-spinner\"><h3><span style=\"float:none;margin: -3px 0 0;\" class=\"spinner is-active\"></span> Loading Mapping...</h3></div>');\n\n\t\t\tif( googleMap.indexOf(provider) !== -1 ) {\n\t\t\t\t$('input[id*=\"cat_mapping_\"]').css('display', 'none');\n\t\t\t\t$('.wf_default.wf_attributes').css('display', 'block').css('width', '100%');\n\n var cat_init = new WooFeedMapCategories();\n if( \"facebook\" === provider ) {\n cat_init.wooFeed_get_facebook_categories();\n } else {\n cat_init.wooFeed_get_google_categories();\n }\n\n } else {\n\t\t\t\t$('input[id*=\"cat_mapping_\"]').css('display', 'block');\n\t\t\t\t$('.wf_default.wf_attributes').css('display', 'none').css('width', '100%');\n\t\t\t}\n\t\t})\n\n // Copy parent category ids to child categories.\n\t\t.on('click', 'span[id*=\"cat-map-\"]', function(e) {\n\t\t\te.preventDefault();\n\t\t\tvar providerName = $('#category-mapping-form #providers').val(),\n\t\t\t\tgoogleMap = ['google', 'facebook', 'pinterest', 'bing', 'bing_local_inventory', 'snapchat'],\n\t\t\t\tcatId = $(this).attr('id').replace(/[^\\d.]/g, ''),\n\t\t\t\tgroupId = 'group-child-' + catId;\n\n\t\t\tif( googleMap.indexOf(providerName) !== -1) {\n\t\t\t\tvar catField = $(this).parents('tr').find('.selectized').val();\n\n\t\t\t\tif (catField) {\n\t\t\t\t\t$('.' + groupId).parents('tr').find('select').each(function (i, v) {\n\t\t\t\t\t\t$(v).data('selectize').setValue(catField);\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\tvar value = $('#cat_mapping_'+catId).val();\n\t\t\t\t$('.'+groupId).parents('tr').find('input').val(value);\n\t\t\t}\n\n\t\t});\n\n $(document).ready(function () {\n var provider = $(\"#providers\").val();\n var cat_init = new WooFeedMapCategories();\n\n var url = new URL(window.location.href);\n var cat_mapping_action = url.searchParams.get(\"action\");\n\n if( \"edit-mapping\" === cat_mapping_action ) {\n $('.woo-feed-category-mapping-config-table').prepend('<div class=\"woo-feed-cat-map-spinner\"><h3><span style=\"float:none;margin: -3px 0 0;\" class=\"spinner is-active\"></span> Loading Mapping...</h3></div>');\n\n if( \"facebook\" === provider ) {\n cat_init.wooFeed_get_facebook_categories();\n } else {\n cat_init.wooFeed_get_google_categories();\n }\n }\n\n });\n\n /*\n * Issue fix for feed edit page unsupported `Feed Type` not disabling\n *\n * @since 4.4.22\n * */\n $(document).on( \"feed_editor_init\", function(){\n\n let types = $('.merchant-info-section.feed_file_type .data').html().split(\",\").map(function(t) {\n return t.trim().toLowerCase();\n });\n\n let feedType = $(\"#feedType\");\n\n if (types.length) {\n feedType.find('option').each(function() {\n let opt = $(this);\n opt.val() && !helper.in_array(opt.val(), types) ? opt.disabled(!0) : opt.disabled(!1);\n });\n if (types.length === 1) feedType.find('option[value=\"' + types[0] + '\"]').attr('selected', 'selected');\n } else feedType.find('option').disabled(!1);\n\n } );\n\n /**\n * Automatically adding postfix for corresponding attribute selection.\n *\n * @since 4.4.32\n */\n $(document).on('ready', function(){\n\n function update_postfix(){\n var attribute_list = {\n\n 'price': wpf_ajax_obj.woocommerce.currency,\n 'current_price': wpf_ajax_obj.woocommerce.currency,\n 'sale_price': wpf_ajax_obj.woocommerce.currency,\n 'price_with_tax': wpf_ajax_obj.woocommerce.currency,\n 'current_price_with_tax': wpf_ajax_obj.woocommerce.currency,\n 'sale_price_with_tax': wpf_ajax_obj.woocommerce.currency,\n\n\n 'weight': wpf_ajax_obj.woocommerce.weight,\n 'weight_unit': wpf_ajax_obj.woocommerce.weight,\n\n\n 'height': wpf_ajax_obj.woocommerce.dimension,\n 'length': wpf_ajax_obj.woocommerce.dimension,\n 'width': wpf_ajax_obj.woocommerce.dimension\n\n };\n\n if (typeof wpf_ajax_obj.feed_rules !== 'undefined' && wpf_ajax_obj.feed_rules !== null) {\n var feed_rules = wpf_ajax_obj.feed_rules;\n var current_feed_currency = feed_rules.feedCurrency;\n }\n\n //get current action name of the page\n var queryString = window.location.search;\n var urlParams = new URLSearchParams(queryString);\n var action = urlParams.get('action');\n\n $( '.wf_attr.wf_attributes' ).each( function( key, value){\n\n var attribute_value = $(value).val();\n var current_Value = $( 'input[name^=\"suffix\"]' ).eq( parseInt( key ) ).val();\n\n if( -1 !== $.inArray( current_Value, [\n ' ' + wpf_ajax_obj.woocommerce.currency,\n ' ' + wpf_ajax_obj.woocommerce.weight,\n ' ' + wpf_ajax_obj.woocommerce.dimension\n ] ) ){\n $( 'input[name^=\"suffix\"]' ).eq( parseInt( key ) ).val('');\n }\n\n $.each(attribute_list, function (_key, _value){\n if( attribute_value === _key ){\n _value = null !== current_feed_currency && \"undefined\" !== typeof current_feed_currency ? current_feed_currency : _value;\n\n if( \"undefined\" !== action && \"edit-feed\" !== action ) {\n $( 'input[name^=\"suffix\"]' ).eq( parseInt( key ) ).val( ' ' + _value );\n } else {\n $( 'input[name^=\"suffix\"]' ).eq( parseInt( key ) ).val( current_Value );\n }\n\n }\n });\n } );\n\n $(document).trigger( 'feedEditor.after.free.postfix.update' );\n }\n\n $(document).on('feedEditor.init', function(){\n update_postfix();\n });\n\n });\n\n})(jQuery, window, document, wp.ajax, wpf_ajax_obj);\n"]}
1
+ {"version":3,"sources":["woo-feed-admin.js"],"names":["_defineProperties","target","props","descriptor","i","enumerable","configurable","writable","Object","defineProperty","key","_createClass","Constructor","protoProps","staticProps","prototype","window","wpAjax","$","document","opts","self","prop","status","addClass","removeClass","hasClass","currentTarget","clearTooltip","userAgent","actionMsg","match","actionKey","index","join","removeAttr","elem","attr","msg","extend","_default","_args","option","ClipboardJS","isSupported","test","navigator","$copyBtn","feedGenerator","this","on","event","action","_loop","ajax_fail","alert","url","data","_classCallCheck","WooFeedCustomFields","productCustomFields","field","isTaxonomy","value","ajax","nonce","method","response","wpf_ajax_obj","wpf_ajax_url","success","_this","cacheClear","closest","find","hide","selectize","WooFeedMapCategories","options","render","send","type","item","_ajax_nonce","valueField","helper","labelField","placeholder","searchField","escape","concat","text","remove","googleCategories","fail","onDrop","column_count","containerSelector","e","hasOwnProperty","error","statusText","sortable","column","each","_super","length","wf_sortable","itemPath","handle","el","$item","container","create","group","draggedClass","plugins","bodyClass","numb","needle","replace","_onDrop","selectize_render_item","config","not","fancySelect","split","map","s","trim","reindex_config_table","itemSelector","common","init","renderMerchantInfo","form","k","opt","merchantInfo","feedType","r","types","html","t","toLowerCase","na","disabled","trigger","val","in_array","_loop2","contentSettings","feedForm","feedEditor","is","merchantInfoCache","tooltip","css","top","merchantTemplateCache","title","_feed","_current_btn","feed","_limit","generator","limit","_color","_product_ids","_progress_per_batch","_refresh","isRegenerating","_all_btn","generate","clip","clipboard","showTooltip","condition","then","URLSearchParams","preventDefault","parent","_progress","_log","_total_batch","_regenerate","regenerate","page_name","_block_button","_current_btn_label","post","_updateProgressStatus","message","product","_this2","_process_batch","setTimeout","_stopProgressBar","_current_batch","_save_feed_file","loop","_unblock_button","_resetProgressBar","console","refreshInterval","arguments","undefined","products","clearInterval","_timer","setInterval","_toggleProgressBar","table","show","color","width","wf","pagenow","attr_name","hover","appendTo","left","pageX","confirm","href","slideToggle","loader","_updateProgressBar","location","reload","button","status_area","select","execCommand","current_attribute_value","fancyOption","fancyDataPicker","selectIf","currency","price_attributes","selectKey","parents","includes","indexOf","outputSelect","feedCurrency","woocommerce","del_confirm_multi","row","validate","template","_ajax_clean_nonce","valid","save","server","sftp_checking","sftp_available","merchant","sftp_warning","name","templateName","loading_tmpl","provider","renderMerchantTemplate","checked","valueColumn","attribute","preload","google_category","query","learn_more","append","cb","facebookCategories","outOfStockVisibilityRow","wf_csv_txt","itemWrapper","item_wrapper_hidden","id","ready","windowpos","load","download","URL","scrollTop","googleMap","Date","click","cat_init","wooFeed_get_facebook_categories","wooFeed_get_google_categories","for_attr","prepend","setValue","catField","catId","groupId","searchParams","v","get","attribute_list","current_feed_currency","price_with_tax","current_price_with_tax","queryString","sale_price_with_tax","urlParams","weight","weight_unit","attribute_value","current_Value","dimension","search","eq","parseInt","inArray","_key","_value","update_postfix"],"mappings":"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","file":"woo-feed-admin.min.js","sourcesContent":["// noinspection JSUnresolvedletiable\n/**!\n * WooFeed Scripts\n * @version 3.3.6\n * @package WooFeed\n * @copyright 2020 WebAppick\n *\n */\n/* global ajaxurl, wpAjax, postboxes, pagenow, alert, deleteUserSetting, typenow, adminpage, thousandsSeparator, decimalPoint, isRtl */\n// noinspection JSUnresolvedVariable\n(function($, window, document, wpAjax, opts) {\n \"use strict\";\n /**\n * All of the code for your admin-facing JavaScript source\n * should reside in this file.\n *\n * Note: It has been assumed you will write jQuery code here, so the\n * $ function reference has been prepared for usage within the scope\n * of this function.\n *\n * This enables you to define handlers, for when the DOM is ready:\n */\n\n /**\n * disable element utility\n *\n * @since 3.1.9\n *\n * @param {*} status\n * @returns {$|HTMLElement}\n */\n $.fn.disabled = function(status) {\n $(this).each(function() {\n let self = $(this),\n prop = 'disabled';\n\n if (typeof self.prop(prop) !== 'undefined') {\n self.prop(prop, status === void 0 || status === true);\n } else {\n !0 === status ? self.addClass(prop) : self.removeClass(prop);\n }\n });\n return self; // method chaining\n };\n\n /**\n * Check if a HTMLElement or jQuery is disabled\n */\n $.fn.isDisabled = function() {\n let self = $(this),\n prop = 'disabled';\n return typeof self.prop(prop) !== 'undefined' ? self.prop(prop) : self.hasClass(prop);\n };\n\n /**\n * Clear Tooltip for clip board js\n * @param {Object} event\n */\n const clearTooltip = (event) => {\n $(event.currentTarget).removeClass( (index, className) => (className.match(/\\btooltipped-\\S+/g) || []).join(' ') ).removeClass('tooltipped').removeAttr('aria-label');\n };\n\n const showTooltip = (elem, msg) => {\n $(elem).addClass('tooltipped tooltipped-s').attr('aria-label', msg);\n };\n\n const fallbackMessage = (action) =>{\n let actionMsg,\n actionKey = action === 'cut' ? 'X' : 'C';\n\n if (/iPhone|iPad/i.test(navigator.userAgent)) {\n actionMsg = 'No support :(';\n } else if (/Mac/i.test(navigator.userAgent)) {\n actionMsg = 'Press ⌘-' + actionKey + ' to ' + action;\n } else {\n actionMsg = 'Press Ctrl-' + actionKey + ' to ' + action;\n }\n\n return actionMsg;\n };\n\n /**\n * Alias of jQuery.extend()\n * @param {Object} _default\n * @param {Object} _args\n */\n const extend = (_default, _args) => $.extend(true, {}, _default, _args);\n\n\t/*\n\t* Handles product attributes\n\t*\n\t* @since 4.4.18\n\t* */\n\tclass WooFeedCustomFields {\n\n\t\tconstructor( field, status, isTaxonomy ) {\n\t\t\tthis.productCustomFields( field, status, isTaxonomy );\n\t\t}\n\n\t\tcacheClear() {\n\t\t\tlet data = {\n\t\t\t\taction: 'woo_feed_product_attribute_cache_remove',\n\t\t\t\tnonce: wpf_ajax_obj.ajax.nonce,\n\t\t\t};\n\t\t\t$.ajax({\n\t\t\t\tmethod: 'POST',\n\t\t\t\turl: wpf_ajax_obj.wpf_ajax_url,\n\t\t\t\tdata\n\t\t\t});\n\t\t}\n\n\t\tproductCustomFields( field, status = false, isTaxonomy ) {\n\t\t\tlet data = {\n\t\t\t\taction: 'woo_feed_custom_fields_status_change',\n\t\t\t\tnonce: wpf_ajax_obj.ajax.nonce,\n\t\t\t\tfield,\n\t\t\t\tstatus,\n\t\t\t\tisTaxonomy\n\t\t\t};\n\t\t\t$.ajax({\n\t\t\t\tmethod: 'POST',\n\t\t\t\turl: wpf_ajax_obj.wpf_ajax_url,\n\t\t\t\tdata,\n\t\t\t\tsuccess: ( response ) => {\n\t\t\t\t\tif( response.success ) {\n\t\t\t\t\t\tthis.cacheClear();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.log( response );\n\t\t\t\t\t}\n $('#'+field+'-switcher').closest('td').find('.switch-loader').hide();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n /*\n * Handles product categories\n *\n * @since 4.4.39\n * */\n class WooFeedMapCategories {\n wooFeed_get_google_categories () {\n wpAjax.send('get_google_categories', {\n type: 'GET',\n data: {\n _ajax_nonce: opts.nonce,\n action: \"get_google_categories\",\n // provider: provider\n }\n }).then(function (response) {\n $('.selectize-google-category').selectize({\n valueField: 'value',\n labelField: 'text',\n placeholder: 'Select a category',\n searchField: ['value', 'text'],\n options: response,\n render: {\n option: (data, escape) => `<div class=\"item wapk-selectize-item\">${escape(data.value + ' - ' + data.text)}</div>`,\n item: (data, escape) => `<div class=\"item wapk-selectize-item\">${escape(data.value + ' - ' + data.text)}</div>`\n }\n });\n\n //remove spinner element\n $('.woo-feed-cat-map-spinner').remove();\n }).fail(helper.ajax_fail);\n }\n\n wooFeed_get_facebook_categories() {\n // get facebook categories\n wpAjax.send('get_facebook_categories', {\n type: 'GET',\n data: {\n _ajax_nonce: opts.nonce,\n action: \"get_facebook_categories\",\n // provider: provider\n }\n }).then(function (response) {\n $('.selectize-google-category').selectize({\n valueField: 'value',\n labelField: 'text',\n placeholder: 'Select a Facebook category',\n searchField: ['value', 'text'],\n options: response,\n render: {\n option: (data, escape) => `<div class=\"item wapk-selectize-item\">${escape(data.value + ' - ' + data.text)}</div>`,\n item: (data, escape) => `<div class=\"item wapk-selectize-item\">${escape(data.value + ' - ' + data.text)}</div>`\n }\n });\n\n //remove spinner element\n $('.woo-feed-cat-map-spinner').remove();\n }).fail(helper.ajax_fail);\n }\n }\n\n let $copyBtn,\n clipboard,\n googleCategories,\n facebookCategories,\n helper = {\n in_array: (needle, haystack) => {\n try {\n return haystack.indexOf(needle) !== -1;\n } catch (e) {\n return false;\n }\n },\n selectize_render_item: (data, escape) => `<div class=\"item wapk-selectize-item\">${escape(data.text)}</div>`, // phpcs:ignore WordPressVIPMinimum.JS.StringConcat.Found,\n ajax_fail: e => {\n console.warn(e);\n alert(e.hasOwnProperty('statusText') && e.hasOwnProperty('status') ? opts.ajax.error + '\\n' + e.statusText + ' (' + e.status + ')' : e);\n },\n /**\n * Initialize Sortable\n * @param {$|HTMLElement} el\n * @param {object} config\n * @param {int|boolean} column\n * @param {function} onDrop\n * @return {$|HTMLElement}\n */\n sortable: (el, config, column, onDrop) => {\n return (el || $('.sorted_table')).each(function() {\n let self = $(this),\n column_count = self.find('tbody > tr:eq(0) > td').length || column || 9;\n self.wf_sortable(extend({\n containerSelector: 'table',\n itemPath: '> tbody',\n itemSelector: 'tr',\n handle: 'i.wf_sortedtable',\n placeholder: `<tr class=\"placeholder\"><td colspan=\"${column_count}\"></td></tr>`,\n onDrop: ($item, container, _super, event) => {\n $item.removeClass(container.group.options.draggedClass).removeAttr('style');\n $(\"body\").removeClass(container.group.options.bodyClass);\n var numb = $item.find(\".wf_mattributes\").attr(\"name\").replace(/\\D/g, \"\");\n $item.find(\"input.wf_attributes\").attr(\"name\", \"default[\"+ numb +\"]\");\n if ( onDrop && 'function' === typeof( onDrop ) ) {\n onDrop( $item, container, _super, event );\n }\n },\n }, config));\n });\n },\n selectize: (el, config) => {\n return (el || $('select.selectize')).not('.selectized').not('.selectize-google-category').each(function() {\n let self = $(this);\n self.selectize(extend({\n create: self.data('create') || false,\n plugins: self.data('plugins') ? self.data('plugins').split(',').map(function(s) {\n return s.trim();\n }) : [],\n //['remove_button'],\n render: {\n item: helper.selectize_render_item\n }\n }, config));\n });\n },\n fancySelect: (el, config) => {\n return (el || $('select.fancySelect')).not('.FancySelectInit').each(function() {\n let self = $(this);\n self.fancySelect(extend({\n maxItemShow: 3\n }, config));\n });\n },\n reindex_config_table: () => {\n $('#table-1').find('tbody tr').each( ( x, el ) => {\n $(el).find('[name]').each( ( x1, el ) => {\n $(el).attr('name', $(el).attr('name').replace(/(\\[\\d\\])/g, `[${x}]`));\n } );\n } );\n },\n common: () => {\n helper.sortable( $('.sorted_table'), {}, 9, helper.reindex_config_table );\n helper.selectize();\n helper.fancySelect($('.outputType'));\n }\n },\n // helper functions\n feedEditor = {\n /**\n * The Editor Form Elem.\n * @type {$|HTMLElement}\n */\n form: null,\n\n /**\n * Initialize The Feed Editor {Tabs...}\n * @returns {void}\n */\n init: function () {\n let self = this;\n self.form = $('.generateFeed');\n if (!self.form.length) return;\n helper.common();\n // noinspection JSUnresolvedVariable\n $(document).trigger('feed_editor_init');\n $(document).trigger(new jQuery.Event('feedEditor.init', {\n target: this.form\n }));\n },\n\n /**\n * Render Merchant info ajax response and handle allowed feed type for selected merchant\n * @param {$|HTMLElement} merchantInfo jQuery dom object\n * @param {$|HTMLElement} feedType jQuery dom object\n * @param {Object} r ajax response object\n */\n renderMerchantInfo: function (merchantInfo, feedType, r) {\n for (let k in r) {\n if (r.hasOwnProperty(k)) {\n merchantInfo.find('.merchant-info-section.' + k + ' .data').html(r[k]); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html\n\n if ('feed_file_type' === k) {\n (function() {\n let types = r[k].split(\",\").map(function(t) {\n return t.trim().toLowerCase();\n }).filter(function(t) {\n // noinspection JSUnresolvedVariable\n return t !== '' && t !== opts.na.toLowerCase();\n });\n\n if (types.length) {\n feedType.find('option').removeAttr('selected').each(function() {\n let opt = $(this);\n opt.val() && !helper.in_array(opt.val(), types) ? opt.disabled(!0) : opt.disabled(!1);\n });\n if (types.length === 1) feedType.find('option[value=\"' + types[0] + '\"]').attr('selected', 'selected');\n } else feedType.find('option').disabled(!1);\n })();\n }\n }\n }\n\n merchantInfo.find('.spinner').removeClass('is-active');\n feedType.disabled(!1);\n feedType.trigger('change');\n\n /**\n * Triggers after merchant configuration is fetched & loaded\n * */\n $(document).trigger('woo_feed_config_loaded');\n\n feedType.parent().find('.spinner').removeClass('is-active');\n },\n\n /**\n * Render Feed Template Tabs and settings while creating new feed.\n * @param {$|HTMLElement} feedForm feed from query dom object\n * @param {object} r merchant template ajax response object\n */\n renderMerchantTemplate: function (feedForm, r) {\n let _loop = function _loop(k) {\n if (r.hasOwnProperty(k)) {\n if ('tabs' === k) {\n // noinspection JSUnresolvedFunction\n feedForm.html(r[k]); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html\n } else {\n let contentSettings = $('[name=\"' + k + '\"]');\n\n if (contentSettings.length) {\n contentSettings.each(function() {\n let elem = $(this);\n\n if (elem.is('select')) {\n elem.find('[value=\"' + r[k] + '\"]').prop('selected', true);\n } else if ((elem.is('[type=checkbox]') || elem.is('[type=radio]')) && elem.val() === r[k]) {\n elem.prop('checked', true);\n } else {\n elem.val(r[k]); // type=text\n }\n }).trigger('change');\n }\n }\n }\n };\n\n for (let k in r) {\n _loop(k);\n }\n\n feedEditor.init();\n }\n },\n // Feed Editor Table\n merchantInfoCache = [],\n merchantTemplateCache = [],\n tooltip = () => {\n // Tooltip only Text\n $('.wfmasterTooltip')\n .hover(function () {\n // Hover over code\n let self = $(this), title = self.attr('wftitle');\n self.data('tipText', title).removeAttr('wftitle');\n $('<p class=\"wftooltip\"></p>').text(title).appendTo('body').fadeIn('slow');\n }, function () {\n // Hover out code\n let self = $(this);\n self.attr('wftitle', self.data('tipText'));\n $('.wftooltip').remove();\n })\n .mousemove(function (e) {\n $('.wftooltip').css({\n top: e.pageY + 10,\n left: e.pageX + 20\n });\n });\n },\n clip = () => {\n $copyBtn = $('.toClipboard');\n if (!ClipboardJS.isSupported() || /iPhone|iPad/i.test(navigator.userAgent)) {\n $copyBtn.find('img').hide(0);\n } else {\n $copyBtn.each(function() {\n $(this).on('mouseleave', clearTooltip).on('blur', clearTooltip);\n });\n clipboard = new ClipboardJS('.toClipboard');\n clipboard.on('error', function(event) {\n showTooltip(event.trigger, fallbackMessage(event.action));\n }).on('success', function(event) {\n showTooltip(event.trigger, 'Copied');\n });\n }\n };\n\n /**\n * Feed Generator Module\n */\n class feedGenerator {\n\n /**\n * Constructor\n * @constructor\n */\n constructor() {\n this._feed = opts.generator.feed; // wf_config+xxxx\n this._limit = opts.generator.limit;\n this._progress = 0;\n this._timer = null;\n this._color = false;\n // batch info\n this._total_batch = 0;\n this._current_batch = 0;\n this._product_ids = [];\n this._progress_per_batch = 0;\n this._refresh = true;\n // noinspection JSUnresolvedVariable\n this._regenerate = opts.generator.regenerate;\n window.isRegenerating = false;\n this._all_btn = $('.wpf_regenerate');\n this._current_btn = $(`#${this._feed.replace( 'wf_config', 'wf_feed_' )}`);\n this._current_btn_label = '';\n }\n\n /**\n * Init Hooks (Event)\n * @return {feedGenerator}\n */\n init() {\n let self = this;\n if ( '' !== this._feed && this._regenerate && false === window.isRegenerating ) {\n this.generate();\n }\n\n //thickbox body add feed plugin class to make it unique and custom style\n let current_page_query = window.location.search;\n let params = new URLSearchParams(current_page_query);\n let page_name = params.get(\"page\");\n if( \"webappick-manage-feeds\" === page_name ) {\n $('body').addClass('woo-import-popup-body');\n }\n\n $(document).on('click', '.woo-feed-campaign-close-button', function(event) {\n event.preventDefault();\n\n $(this).parent('.woo-feed-promotion').hide();\n let condition = $(this).data('condition');\n if(1 === condition) {\n wpAjax.post( 'woo_feed_hide_promotion', {\n _ajax_nonce: opts.nonce,\n condition: condition,\n } ).then( response => {\n self._log( response );\n } ).fail( error => {\n self._log( error );\n self._updateProgressStatus( error.message );\n self._color = 'red';\n } );\n }\n });\n\n $(document).on('click', '.wpf_regenerate', function(event) {\n event.preventDefault();\n self._current_btn = $( this );\n if( self._current_btn.hasClass('disabled') || window.isRegenerating === true ) return;\n self._feed = self._current_btn.attr('id').replace( 'wf_feed_', 'wf_config' );\n if( '' !== self._feed ) {\n self.generate();\n }\n });\n return this;\n }\n\n _block_button() {\n if ( this._all_btn.length ) {\n this._all_btn.addClass('disabled');\n }\n if ( this._current_btn.length ) {\n this._current_btn.find('span').addClass('wpf_spin reverse_spin');\n this._current_btn_label = this._current_btn.attr('title');\n // noinspection JSUnresolvedVariable\n this._current_btn.attr( 'aria-label', opts.regenerate ).attr( 'title', opts.regenerate );\n }\n }\n\n _unblock_button() {\n if ( this._all_btn.length ) {\n this._all_btn.removeClass('disabled');\n }\n if ( this._current_btn.length ) {\n this._current_btn.find('span').removeClass('wpf_spin');\n this._current_btn.find('span').removeClass('reverse_spin');\n this._current_btn.attr( 'aria-label', this._current_btn_label ).attr( 'title', this._current_btn_label );\n }\n }\n\n /**\n * Generate Feed\n * @return void\n */\n generate() {\n let self = this;\n window.isRegenerating = true;\n this._block_button();\n this._resetProgressBar();\n this._progressBarActive();\n this._log( 'Counting Total Products' );\n this._updateProgressStatus( 'Fetching products.' );\n this._get_product_ids().then( response => {\n this._progress = 10;\n self._log( {response} );\n if(response.success) {\n self._log( `Total ${response.total} Products found.` );\n self._product_ids = response.product;\n self._total_batch = this._product_ids.length;\n self._current_batch = 0;\n self._progress_per_batch = ( 90 - this._progress ) / this._total_batch;\n self._process_batch();\n self._updateProgressStatus( 'Processing Products...' );\n } else {\n self._updateProgressStatus( response.data.message );\n }\n }).fail( error => {\n self._log( error );\n self._updateProgressStatus( error.message );\n self._color = 'red';\n setTimeout( function(){\n self._stopProgressBar();\n self._unblock_button();\n }, 1500 );\n } );\n }\n\n /**\n * Get Product Ids\n * @returns {$.promise}\n * @private\n */\n _get_product_ids() {\n this._progress = 5;\n return wpAjax.post( 'get_product_information', {\n _ajax_nonce: opts.nonce,\n feed: this._feed,\n limit: this._limit,\n } );\n }\n\n /**\n * Run the Batch\n * @private\n */\n _process_batch() {\n let self = this;\n let status = `Processing Batch ${this._current_batch+1} of ${this._total_batch}`;\n this._updateProgressStatus( status );\n this._log( status );\n wpAjax.post( 'make_batch_feed', {\n _ajax_nonce: opts.nonce,\n feed: this._feed,\n products: this._product_ids[this._current_batch],\n loop: this._current_batch,\n } ).then( response => {\n self._current_batch++;\n self._log( `Batch ${self._current_batch} Completed` );\n self._log( response );\n if ( self._current_batch < self._total_batch ) {\n self._process_batch();\n self._progress += self._progress_per_batch;\n }\n if ( self._current_batch === self._total_batch ) {\n self._save_feed_file();\n }\n } ).fail( error => {\n self._log( error );\n self._updateProgressStatus( error.message );\n self._color = 'red';\n setTimeout( function(){\n self._stopProgressBar();\n self._unblock_button();\n }, 1500 );\n } );\n }\n\n /**\n * Save Feed Data from temp to feed file\n * @private\n */\n _save_feed_file() {\n let self = this;\n this._log( 'Saving feed file' );\n this._updateProgressStatus( 'Saving feed file' );\n wpAjax.post( 'save_feed_file', {\n _ajax_nonce: opts.nonce,\n feed: this._feed,\n } ).then( response => {\n self._log( response );\n self._progress = 100;\n if ( self._refresh ) {\n window.location.href = `${opts.pages.list.feed}&link=${response.url}&cat=${response.cat}`;\n }\n setTimeout( function(){\n self._stopProgressBar();\n setTimeout( function(){\n self._resetProgressBar( true );\n self._unblock_button();\n }, 3000 );\n }, 2500 );\n } ).fail( error => {\n self._log( error );\n self._updateProgressStatus( error.message );\n self._color = 'red';\n setTimeout( function(){\n self._stopProgressBar();\n self._unblock_button();\n }, 1500 );\n } );\n }\n\n /**\n * Console log wrapper with debug settings.\n * @param data\n * @returns {feedGenerator}\n * @private\n */\n _log( data ) {\n // noinspection JSUnresolvedVariable\n if ( opts.wpf_debug ) {\n console.log( data );\n }\n return this;\n }\n\n /**\n * Run the progressbar refresh interval\n * @param {int} refreshInterval\n * @returns {feedGenerator}\n * @private\n */\n _progressBarActive( refreshInterval = 0 ) {\n let self = this;\n this._toggleProgressBar( true );\n this._timer = setInterval( function(){\n self._updateProgressBar();\n }, refreshInterval || 1000 );\n return this;\n }\n\n /**\n * Stop Progressbar\n * @returns {feedGenerator}\n * @private\n */\n _stopProgressBar() {\n clearInterval( this._timer );\n return this;\n }\n\n /**\n * Reset Progressbar\n * @returns {feedGenerator}\n * @private\n */\n _resetProgressBar( update ) {\n this._toggleProgressBar( false );\n this._updateProgressStatus( '' );\n clearInterval( this._timer );\n this._color = false;\n this._timer = null;\n this._progress = 0;\n if ( update ) {\n this._updateProgressBar();\n }\n return this;\n }\n\n /**\n * Show hide the progress bar el\n * @param status\n * @returns {feedGenerator}\n * @private\n */\n _toggleProgressBar( status ) {\n let table = $('#feed_progress_table');\n if ( status ) {\n table.show();\n } else {\n table.hide();\n }\n return this;\n }\n\n /**\n * Update Progress bar text status\n * @param {string} status\n * @returns {feedGenerator}\n * @private\n */\n _updateProgressStatus( status ) {\n $( '.feed-progress-status' ).html( status );\n return this;\n }\n\n _getErrorMessageByCode( error ){\n let progress_message = $( '.feed-progress-status' );\n progress_message.css( {'color':this._color});\n $( '.feed-progress-percentage' ).css( {'color':this._color});\n $( '.wpf_spin' ).css( {'color':this._color});\n\n let message=error.status +' : '+ error.statusText+'. ';\n if(500===error.status){\n message+= \"Please increase your PHP max_execution_time. Please <a target='_blank' href='https://webappick.com/docs/woo-feed/faq-for-woocommerce-product-feed/how-to-solve-processing-10-feed-generation-stuck-error/'>read this doc</a>.\";\n }\n\n this._updateProgressStatus(message);\n\n }\n\n /**\n * Update Progress Data\n * hooked with setInterval\n * @private\n */\n _updateProgressBar() {\n let percentage = $( '.feed-progress-percentage' ),\n bar = $( '.feed-progress-bar-fill' ),\n _progress = `${Math.round( this._progress )}%`;\n bar.css( {\n width: _progress,\n } );\n percentage.text( _progress );\n }\n }\n // expose to the global scope\n window.wf = {\n helper: helper,\n feedEditor: feedEditor,\n generator: feedGenerator,\n };\n\n $(window).on('load', function() {\n // Template loading ui conflict\n if ($(location).attr(\"href\").match(/webappick.*feed/g) !== null) {\n $('#wpbody-content').addClass('woofeed-body-content');\n }\n\n // ClipBoardJS\n clip();\n // postbox toggle\n postboxes.add_postbox_toggles(pagenow);\n // initialize generator\n let generator = new feedGenerator();\n generator.init();\n // noinspection JSUnresolvedVariable\n if( '' !== opts.generator.feed && opts.generator.regenerate ) {\n\n }\n // initialize editor\n feedEditor.init();\n helper.common(); // Generate Feed Add Table Row\n tooltip();\n // validate feed editor\n $(\".generateFeed\").validate();\n\n // document events\n $(document)\n .on('blur', 'input[name=\"wfDAttributeName\"]', function(e) {\n e.preventDefault();\n let attr_name = $(this).val();\n attr_name = attr_name.toLowerCase();\n attr_name = attr_name.split(' ').join('_');\n\n $('#wfDAttributeCode').val(attr_name);\n\n })\n .on('click', '[data-toggle_slide]', function(e) {\n e.preventDefault();\n $($(this).data('toggle_slide')).slideToggle('fast');\n })\n // XML Feed Wrapper\n .on('click', '#wf_newRow', function () {\n let tbody = $('#table-1 tbody'),\n template = $('#feed_config_template').text().trim().replace(/__idx__/g, tbody.find('tr').length);\n tbody.append(template);\n helper.fancySelect($('.outputType'));\n })\n // feed delete alert.\n .on('click', '.single-feed-delete', function (event) {\n event.preventDefault();\n // noinspection JSUnresolvedVariable\n if (confirm(opts.form.del_confirm)) {\n window.location.href = $(this).attr('val');\n }\n })\n // clear cache data.\n .on('click', '.wf_clean_cache_wrapper', function(event) {\n event.preventDefault();\n var nonce = $('.woo-feed-clean-cache-nonce').val();\n var loader = $('.woo-feed-cache-loader');\n\n //show loader\n loader.show();\n\n // passed cache nonce\n wpAjax.post('clear_cache_data', {\n _ajax_clean_nonce: nonce\n }).then(function (response) {\n if( response.success ) {\n loader.hide(); //hide loader\n location.reload();\n }\n }).fail(function () {\n console.log('something wrong');\n });\n\n })// Copy Status\n .on('click', '#woo-feed-copy-status-btn', function(event) {\n event.preventDefault();\n let button = $('#woo-feed-copy-status-btn');\n let status_area = $('#woo-feed-status-area');\n button.val('Copied');\n status_area.css('visibility','visible');\n status_area.select();\n\n document.execCommand('copy');\n })\n // feed value dropdown change.\n .on('change', '.wf_attr.wf_attributes', function(event) {\n event.preventDefault();\n\n $('.fancy-picker-picked').trigger(\"click\"); // trigger fancy select box clicked\n\n // price attributes\n var price_attributes = ['price', 'current_price', 'sale_price', 'price_with_tax', 'current_price_with_tax', 'sale_price_with_tax', 'shipping_cost'];\n // current value\n var current_attribute_value = $(this).val();\n var outputSelect = $(this).parents('tr').find('.outputType');\n var fancyOption = $(this).parents('tr').find('.fancy-picker-content .fancy-picker-option');\n var fancyDataPicker = $(this).parents('tr').find('.fancy-picker-data span');\n var selectIf, selectKey;\n var currency;\n\n // when any attribute is selected, pick the key\n if( price_attributes.includes(current_attribute_value) ) {\n // when select any price attribute\n selectIf = 'for_price';\n selectKey = \"Price\";\n } else if ( \"\" !== current_attribute_value && -1 !== current_attribute_value.indexOf('wf_taxo') ) {\n\n // when select any custom taxonomy\n selectIf = 'for_custom_taxo';\n selectKey = \"parent_if_empty\";\n } else {\n\n selectIf = 'for_all';\n selectKey = 'Default';\n }\n\n // remove selected class from old selected option\n fancyOption.removeClass('selected');\n\n // when value dropdown is selected as price or any custom taxonomy\n if( selectIf === 'for_custom_taxo' || selectIf === 'for_price' ) {\n // update \"Option Type\" when select key matches\n fancyOption.each(function() {\n if( selectKey === $(this).text() ) {\n $(this).addClass('selected');\n fancyDataPicker.text(selectKey);\n outputSelect.find(\"option\").text(selectKey);\n outputSelect.find(\"option\").val( $(this).data('value') );\n }\n });\n\n if( \"for_price\" === selectIf ) {\n var feedCurrency = $('#feedCurrency').val();\n if( \"undefined\" !== typeof feedCurrency && null !== feedCurrency ) {\n currency = feedCurrency;\n }else {\n currency = wpf_ajax_obj.woocommerce.currency;\n }\n\n //for price add currency to the suffix\n $(this).closest(\"tr\").find(\"td:eq(5) input\").val(\" \" + currency);\n }\n\n } else {\n fancyOption.each(function(){\n if( selectKey === $(this).text() ){\n $(this).addClass('selected');\n fancyDataPicker.text(selectKey);\n outputSelect.find(\"option\").text(selectKey);\n outputSelect.find(\"option\").val( $(this).data(\"value\") );\n }\n });\n\n $(this).closest(\"tr\").find(\"td:eq(5) input\").val(\"\");\n }\n\n })\n // bulk delete alert.\n .on('click', '#doaction, #doaction2', function () {\n // noinspection JSUnresolvedVariable\n return confirm(opts.form.del_confirm_multi);\n })\n // Generate Feed Table Row Delete\n .on('change', '.dType', function () {\n let self = $(this),\n type = self.val(),\n row = self.closest('tr');\n\n if (type === 'pattern') {\n row.find('.value_attribute').hide();\n row.find('.value_pattern').show();\n } else if (type === 'attribute') {\n row.find('.value_attribute').show();\n row.find('.value_pattern').hide();\n } else if (type === 'remove') {\n row.find('.value_attribute').hide();\n row.find('.value_pattern').hide();\n }\n })\n // Generate Feed Form Submit\n .on('click', '.delRow', function (e) {\n e.preventDefault();\n $(this).closest('tr').remove();\n helper.reindex_config_table();\n })\n .on('submit', '#generateFeed', function () {\n // Feed Generating form validation\n $(this).validate();\n\n if ($(this).valid()) {\n $(\".makeFeedResponse\")\n .show()\n .html(`<b style=\"color: darkblue;\"><i class=\"dashicons dashicons-sos wpf_spin\"></i> ${opts.form.generate}</b>`); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html, WordPressVIPMinimum.JS.StringConcat.Found\n }\n })\n // Generate Update Feed Form Submit\n .on('submit', '#updatefeed', function (e, data) {\n // Feed Generating form validation\n $(this).validate();\n\n if ($(this).valid()) {\n $(\".makeFeedResponse\")\n .show()\n .html(`<b style=\"color: darkblue;\"><i class=\"dashicons dashicons-sos wpf_spin\"></i> ${data && data.save ? opts.form.save : opts.form.generate}</b>`); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html, WordPressVIPMinimum.JS.StringConcat.Found\n }\n })\n .on( 'ready woo_feed_config_loaded', function(){\n\n if( $('#ftpenabled').val() === '0' ){\n $('.google-merchant-message').hide('slow');\n $('.woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) input, .woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) select').attr('disabled','disabled');\n } else {\n if( $('#provider').val() === 'google' ) {\n $('.google-merchant-message').show('slow');\n } else {\n $('.google-merchant-message').hide('slow');\n }\n $('.woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) input, .woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) select').removeAttr('disabled');\n }\n\n $('#ftpenabled').on('change', function(){\n if( $('#ftpenabled').val() === '0' ){\n $('.google-merchant-message').hide('slow');\n $('.woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) input, .woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) select').attr('disabled','disabled');\n } else {\n\n $('.woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) input, .woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) select').removeAttr('disabled');\n\n // Google merchant specific message\n if( $('#provider').val() === 'google' ){\n $('.google-merchant-message').show('slow');\n } else {\n $('.google-merchant-message').hide('slow');\n }\n\n }\n });\n })\n .on('change', '.ftporsftp', function () {\n let server = $(this).val(),\n status = $('.ssh2_status');\n\n if (server === 'sftp') {\n // noinspection JSUnresolvedVariable\n status.show().css('color', 'dodgerblue').text(opts.form.sftp_checking);\n wpAjax.post('get_ssh2_status', {\n _ajax_nonce: opts.nonce,\n server: server\n }).then(function (response) {\n if (response === 'exists') {\n // noinspection JSUnresolvedVariable\n status.css('color', '#2CC185').text(opts.form.sftp_available);\n setTimeout(function () {\n status.hide();\n }, 1500);\n } else {\n // noinspection JSUnresolvedVariable\n status.show().css('color', 'red').text(opts.form.sftp_warning);\n }\n }).fail(function (e) {\n status.hide();\n helper.ajax_fail(e);\n });\n } else {\n status.hide();\n }\n })\n .on('click', '[name=\"save_feed_config\"]', function (e) {\n e.preventDefault();\n $('#updatefeed').trigger('submit', {\n save: true\n });\n })\n .on('change', '#provider', function (event) {\n event.preventDefault();\n\n let merchant = $(this).val(),\n templateName = $(this).find(':selected').text(),\n name = $('#filename').val(),\n feedType = $(\"#feedType\"),\n feedForm = $(\"#providerPage\"),\n merchantInfo = $('#feed_merchant_info'); // set loading..\n\n // noinspection JSUnresolvedVariable\n feedForm.html('<h3><span style=\"float:none;margin: -3px 0 0;\" class=\"spinner is-active\"></span> ' + opts.form.loading_tmpl + '</h3>'); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html, WordPressVIPMinimum.JS.StringConcat.Found\n\n merchantInfo.find('.spinner').addClass('is-active');\n feedType.disabled(!0); // disable dropdown\n\n feedType.parent().find('.spinner').addClass('is-active');\n merchantInfo.find('.merchant-info-section .data').html(''); // remove previous data\n // Get Merchant info for selected Provider/Merchant\n\n if (merchantInfoCache.hasOwnProperty(merchant)) {\n feedEditor.renderMerchantInfo(merchantInfo, feedType, merchantInfoCache[merchant]);\n\n /**\n * Triggers after merchant configuration is fetched & loaded\n * */\n $(document).trigger('woo_feed_config_loaded');\n\n } else {\n wpAjax.send('woo_feed_get_merchant_info', {\n type: 'GET',\n data: {\n nonce: opts.nonce,\n provider: merchant,\n templateName: templateName\n }\n }).then(function (r) {\n merchantInfoCache[merchant] = r;\n feedEditor.renderMerchantInfo(merchantInfo, feedType, r);\n }).then(function(){\n\n /**\n * Triggers after merchant configuration is fetched & loaded\n * */\n $(document).trigger('woo_feed_config_loaded');\n\n }).fail(helper.ajax_fail);\n } // Get FeedForm For Selected Provider/Merchant\n\n\n if (merchantTemplateCache.hasOwnProperty(merchant)) {\n feedEditor.renderMerchantTemplate(feedForm, merchantTemplateCache[merchant]);\n\n /**\n * Triggers after merchant configuration is fetched & loaded\n * */\n $(document).trigger('woo_feed_config_loaded');\n\n } else {\n wpAjax.post('get_feed_merchant', {\n _ajax_nonce: opts.nonce,\n merchant: merchant\n }).then(function (r) {\n merchantTemplateCache[merchant] = r;\n feedEditor.renderMerchantTemplate(feedForm, r);\n $('#utm_source').val(templateName);\n $('#utm_campaign').val(name);\n //when merchant is bing, change delimiter and enclosure\n if( 'bing' === merchant ) {\n //delimiter value\n $(\"#delimiter option\").removeAttr('selected');\n $(\"#delimiter option[value=\\\"tab\\\"]\").attr('selected', 'selected');\n\n //enclosure value\n $(\"#enclosure option\").removeAttr('selected');\n $(\"#enclosure option[value=\\\" \\\"]\").attr('selected', 'selected');\n }\n\n //reviewer options hide\n if( 'google_product_review' !== merchant) {\n $('.wf_attributes option[value=\"reviewer_name\"]').hide();\n }\n }).then(function(){\n\n /**\n * Triggers after merchant configuration is fetched & loaded\n * */\n $(document).trigger('woo_feed_config_loaded');\n\n }).fail(helper.ajax_fail);\n }\n })\n // Feed Active and Inactive status change via ajax\n .on('change', '.woo_feed_status_input', function () {\n let self = $(this);\n wpAjax.post('update_feed_status', {\n _ajax_nonce: opts.nonce,\n feedName: self.val(),\n status: self[0].checked ? 1 : 0\n });\n });\n // event with trigger\n $(document)\n .on('change', '[name=\"is_outOfStock\"], [name=\"product_visibility\"]', function () {\n let outOfStockVisibilityRow = $('.out-of-stock-visibility');\n if ($('[name=\"is_outOfStock\"]:checked').val() === 'n' && $('[name=\"product_visibility\"]:checked').val() === '1') {\n outOfStockVisibilityRow.show();\n } else {\n outOfStockVisibilityRow.hide();\n }\n })\n .on('change', '.attr_type', function () {\n // Attribute type selection\n let self = $(this),\n type = self.val(),\n row = self.closest('tr');\n\n if (type === 'pattern') {\n row.find('.wf_attr').hide();\n row.find('.wf_attr').val('');\n row.find('.wf_default').show();\n } else {\n row.find('.wf_attr').show();\n row.find('.wf_default').hide();\n row.find('.wf_default').val('');\n }\n })\n .on('change', '.wf_mattributes, .attr_type', function () {\n let row = $(this).closest('tr'),\n attribute = row.find('.wf_mattributes'),\n type = row.find('.attr_type'),\n valueColumn = row.find('td:eq(4)'),\n provider = $('#provider').val();\n\n // noinspection JSUnresolvedVariable\n if (opts.form.google_category.hasOwnProperty(attribute.val()) && type.val() === 'pattern' && helper.in_array(provider, opts.form.google_category[attribute.val()])) {\n if (valueColumn.find('select.selectize').length === 0) {\n valueColumn.find('input.wf_default').remove();\n valueColumn.append('<span class=\"wf_default wf_attributes\"><select name=\"default[]\" class=\"selectize\"></select></span>');\n // noinspection JSUnresolvedVariable\n valueColumn.append(`<span style=\"font-size:x-small;\"><a style=\"color: red\" href=\"https://webappick.com/docs/woo-feed/feed-configuration/how-to-map-store-category-with-merchant-category/\" target=\"_blank\">${opts.learn_more}</a></span>`);\n\n if (!googleCategories || !facebookCategories) {\n valueColumn.append('<span class=\"spinner is-active\" style=\"margin: 0;\"></span>');\n }\n\n let select = valueColumn.find('.wf_attributes select');\n // noinspection JSUnresolvedVariable\n helper.selectize(select, {\n preload: true,\n placeholder: opts.form.select_category,\n load: function load(query, cb) {\n if (!googleCategories) {\n wpAjax.send('get_google_categories', {\n type: 'GET',\n data: {\n _ajax_nonce: opts.nonce,\n action: \"get_google_categories\",\n provider: provider\n }\n }).then(function (r) {\n googleCategories = r;\n cb(googleCategories);\n valueColumn.find('.spinner').remove();\n }).fail(helper.ajax_fail);\n } else {\n cb(googleCategories);\n }\n\n //for facebook product category merchant attribute\n if (!facebookCategories && \"facebook\" === provider && \"fb_product_category\" === attribute.val()) {\n wpAjax.send('get_facebook_categories', {\n type: 'GET',\n data: {\n _ajax_nonce: opts.nonce,\n action: \"get_facebook_categories\",\n provider: provider\n }\n }).then(function (r) {\n facebookCategories = r;\n cb(facebookCategories);\n valueColumn.find('.spinner').remove();\n }).fail(helper.ajax_fail);\n } else {\n cb(facebookCategories);\n }\n }\n });\n }\n } else {\n if ( attribute.val() !== 'current_category' && valueColumn.find('input.wf_default').length === 0) {\n valueColumn.find('span').remove();\n valueColumn.append('<input autocomplete=\"off\" class=\"wf_default wf_attributes\" type=\"text\" name=\"default[]\" value=\"\">');\n\n if (type.val() !== 'pattern') {\n valueColumn.find('input.wf_default').hide();\n }\n }\n }\n })\n .on('change', '#feedType,#provider', function (e) {\n let type = $('#feedType').val(),\n provider = $('#provider').val(),\n itemWrapper = $('.itemWrapper'),\n wf_csv_txt = $('.wf_csvtxt');\n\n // noinspection JSUnresolvedVariable\n if (type !== '' && helper.in_array(provider, opts.form.item_wrapper_hidden)) {\n itemWrapper.hide();\n }\n\n //when feed type is changed\n if( 'feedType' === e.target.id ) {\n if (type === 'csv' || type === 'txt' || type === 'tsv') {\n wf_csv_txt.show();\n itemWrapper.hide();\n \n if( 'tsv' === type ) {\n $('#delimiter option:last').prop(\"selected\", \"selected\");\n } else if( 'csv' === type ) {\n $('#delimiter option:first').prop(\"selected\", \"selected\");\n }\n } else if( 'xml' === type && \"custom\" === provider ) {\n itemWrapper.show();\n wf_csv_txt.hide();\n } else if( 'json' === type ) {\n wf_csv_txt.hide();\n }\n }\n\n // when template is not custom template 1 hide the item wrapper\n if( \"custom\" !== provider ) {\n itemWrapper.hide();\n }\n\n })\n .trigger('change');\n\n\n $(document)\n\t\t\t.on('click', '.woofeed-custom-fields [id*=\"-switcher\"]', function () {\n\t\t\t $(this).closest('td').find('.switch-loader').show();\n\t\t\t\tlet field = $(this).attr( 'id' ).split( '-' )[0],\n\t\t\t\t\tisTaxonomy = $(this).data( 'taxonomy' ),\n\t\t\t\t\tstatus = $(this).prop( 'checked' );\n\t\t\t\tnew WooFeedCustomFields( field, status, isTaxonomy );\n\n\t\t\t})\n\n\t\t\t// Remove sticky cart on feature page\n\t\t\t.ready(function() {\n\t\t\t\tvar s = $(\".wapk-feed-buy-now-container\");\n\t\t\t\t$(window).scroll(function() {\n\t\t\t\t\tvar windowpos = $(window).scrollTop();\n\t\t\t\t\tif ( windowpos <= 5000 ) {\n\t\t\t\t\t\ts.addClass(\"fixed\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\ts.removeClass(\"fixed\");\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n });\n\n $(document)\n\t\t.on('click', '#woo-feed-debug-log-download', function (e) {\n\t\t\te.preventDefault();\n\t\t\t$(\"<a />\", {\n\t\t\t\tdownload: new Date() + \".log\",\n\t\t\t\thref: URL.createObjectURL(\n\t\t\t\t\tnew Blob([$(\"#woo-feed-debug-log\").val()], {\n\t\t\t\t\t\ttype: \"text/plain\"\n\t\t\t\t\t})),\n\t\t\t}).appendTo(\"body\")[0].click();\n\t\t})\n\t\t.on('keyup', '#filename', function() {\n\t\t\tvar name = $('#filename').val();\n\t\t\t$('#utm_campaign').val(name);\n\t\t})\n\n .on('click', '.wf-tab-name', function(e) {\n $('.wf-tab-name.activate').removeClass('activate');\n $(this).addClass('activate');\n\n let for_attr = $(this).attr('for');\n $('.wf_tabs li.active').removeClass('active');\n $('.wf_tabs .wf-tab-content#' + for_attr).parent().addClass('active');\n })\n\n\t\t.on('change', '#category-mapping-form #providers', function() {\n\t\t\tvar provider = $(this).find(':selected').val(),\n\t\t\t\tgoogleMap = ['google', 'facebook', 'pinterest', 'bing', 'bing_local_inventory', 'snapchat','tiktok'];\n\n //add snipper element\n $('.woo-feed-category-mapping-config-table').prepend('<div class=\"woo-feed-cat-map-spinner\"><h3><span style=\"float:none;margin: -3px 0 0;\" class=\"spinner is-active\"></span> Loading Mapping...</h3></div>');\n\n\t\t\tif( googleMap.indexOf(provider) !== -1 ) {\n\t\t\t\t$('input[id*=\"cat_mapping_\"]').css('display', 'none');\n\t\t\t\t$('.wf_default.wf_attributes').css('display', 'block').css('width', '100%');\n\n var cat_init = new WooFeedMapCategories();\n if( \"facebook\" === provider ) {\n cat_init.wooFeed_get_facebook_categories();\n } else {\n cat_init.wooFeed_get_google_categories();\n }\n\n } else {\n\t\t\t\t$('input[id*=\"cat_mapping_\"]').css('display', 'block');\n\t\t\t\t$('.wf_default.wf_attributes').css('display', 'none').css('width', '100%');\n\t\t\t}\n\t\t})\n\n // Copy parent category ids to child categories.\n\t\t.on('click', 'span[id*=\"cat-map-\"]', function(e) {\n\t\t\te.preventDefault();\n\t\t\tvar providerName = $('#category-mapping-form #providers').val(),\n\t\t\t\tgoogleMap = ['google', 'facebook', 'pinterest', 'bing', 'bing_local_inventory', 'snapchat','tiktok'],\n\t\t\t\tcatId = $(this).attr('id').replace(/[^\\d.]/g, ''),\n\t\t\t\tgroupId = 'group-child-' + catId;\n\n\t\t\tif( googleMap.indexOf(providerName) !== -1) {\n\t\t\t\tvar catField = $(this).parents('tr').find('.selectized').val();\n\n\t\t\t\tif (catField) {\n\t\t\t\t\t$('.' + groupId).parents('tr').find('select').each(function (i, v) {\n\t\t\t\t\t\t$(v).data('selectize').setValue(catField);\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\tvar value = $('#cat_mapping_'+catId).val();\n\t\t\t\t$('.'+groupId).parents('tr').find('input').val(value);\n\t\t\t}\n\n\t\t});\n\n $(document).ready(function () {\n var provider = $(\"#providers\").val();\n var cat_init = new WooFeedMapCategories();\n\n var url = new URL(window.location.href);\n var cat_mapping_action = url.searchParams.get(\"action\");\n\n if( \"edit-mapping\" === cat_mapping_action ) {\n $('.woo-feed-category-mapping-config-table').prepend('<div class=\"woo-feed-cat-map-spinner\"><h3><span style=\"float:none;margin: -3px 0 0;\" class=\"spinner is-active\"></span> Loading Mapping...</h3></div>');\n\n if( \"facebook\" === provider ) {\n cat_init.wooFeed_get_facebook_categories();\n } else {\n cat_init.wooFeed_get_google_categories();\n }\n }\n\n });\n\n /*\n * Issue fix for feed edit page unsupported `Feed Type` not disabling\n *\n * @since 4.4.22\n * */\n $(document).on( \"feed_editor_init\", function(){\n\n let types = $('.merchant-info-section.feed_file_type .data').html().split(\",\").map(function(t) {\n return t.trim().toLowerCase();\n });\n\n let feedType = $(\"#feedType\");\n\n if (types.length) {\n feedType.find('option').each(function() {\n let opt = $(this);\n opt.val() && !helper.in_array(opt.val(), types) ? opt.disabled(!0) : opt.disabled(!1);\n });\n if (types.length === 1) feedType.find('option[value=\"' + types[0] + '\"]').attr('selected', 'selected');\n } else feedType.find('option').disabled(!1);\n\n } );\n\n /**\n * Automatically adding postfix for corresponding attribute selection.\n *\n * @since 4.4.32\n */\n $(document).on('ready', function(){\n\n function update_postfix(){\n var attribute_list = {\n\n 'price': wpf_ajax_obj.woocommerce.currency,\n 'current_price': wpf_ajax_obj.woocommerce.currency,\n 'sale_price': wpf_ajax_obj.woocommerce.currency,\n 'price_with_tax': wpf_ajax_obj.woocommerce.currency,\n 'current_price_with_tax': wpf_ajax_obj.woocommerce.currency,\n 'sale_price_with_tax': wpf_ajax_obj.woocommerce.currency,\n\n\n 'weight': wpf_ajax_obj.woocommerce.weight,\n 'weight_unit': wpf_ajax_obj.woocommerce.weight,\n\n\n 'height': wpf_ajax_obj.woocommerce.dimension,\n 'length': wpf_ajax_obj.woocommerce.dimension,\n 'width': wpf_ajax_obj.woocommerce.dimension\n\n };\n\n if (typeof wpf_ajax_obj.feed_rules !== 'undefined' && wpf_ajax_obj.feed_rules !== null) {\n var feed_rules = wpf_ajax_obj.feed_rules;\n var current_feed_currency = feed_rules.feedCurrency;\n }\n\n //get current action name of the page\n var queryString = window.location.search;\n var urlParams = new URLSearchParams(queryString);\n var action = urlParams.get('action');\n\n $( '.wf_attr.wf_attributes' ).each( function( key, value){\n\n var attribute_value = $(value).val();\n var current_Value = $( 'input[name^=\"suffix\"]' ).eq( parseInt( key ) ).val();\n\n if( -1 !== $.inArray( current_Value, [\n ' ' + wpf_ajax_obj.woocommerce.currency,\n ' ' + wpf_ajax_obj.woocommerce.weight,\n ' ' + wpf_ajax_obj.woocommerce.dimension\n ] ) ){\n $( 'input[name^=\"suffix\"]' ).eq( parseInt( key ) ).val('');\n }\n\n $.each(attribute_list, function (_key, _value){\n if( attribute_value === _key ){\n _value = null !== current_feed_currency && \"undefined\" !== typeof current_feed_currency ? current_feed_currency : _value;\n\n if( \"undefined\" !== action && \"edit-feed\" !== action ) {\n $( 'input[name^=\"suffix\"]' ).eq( parseInt( key ) ).val( ' ' + _value );\n } else {\n $( 'input[name^=\"suffix\"]' ).eq( parseInt( key ) ).val( current_Value );\n }\n\n }\n });\n } );\n\n $(document).trigger( 'feedEditor.after.free.postfix.update' );\n }\n\n $(document).on('feedEditor.init', function(){\n let provider = $(this).find(':selected').val(),\n googleMap = ['google', 'facebook', 'pinterest', 'bing', 'bing_local_inventory', 'snapchat','tiktok'];\n\n if( googleMap.indexOf(provider) !== -1 ) {\n update_postfix();\n }\n });\n\n });\n\n})(jQuery, window, document, wp.ajax, wpf_ajax_obj);\n"]}
admin/partials/woo-feed-category-mapping.php CHANGED
@@ -14,10 +14,12 @@ if ( ! defined( 'ABSPATH' ) ) {
14
  die();
15
  }
16
 
 
 
17
  $wooFeedDropDown = new Woo_Feed_Dropdown();
18
  $value = array();
19
- if ( isset( $_GET['action'], $_GET['cmapping'] ) ) { // phpcs:ignore
20
- $option = get_option( sanitize_text_field( $_GET['cmapping'] ) ); // phpcs:ignore
21
  $value = maybe_unserialize( $option );
22
  }
23
  ?>
14
  die();
15
  }
16
 
17
+ $action = apply_filters('CTXFEED_filter_securing_input', "GET", @$_GET['action'], "text");
18
+ $cmapping = apply_filters('CTXFEED_filter_securing_input', "GET", @$_GET['cmapping'], "text");
19
  $wooFeedDropDown = new Woo_Feed_Dropdown();
20
  $value = array();
21
+ if ( $action && $cmapping ) { // phpcs:ignore
22
+ $option = get_option( $cmapping ); // phpcs:ignore
23
  $value = maybe_unserialize( $option );
24
  }
25
  ?>
admin/partials/woo-feed-manage-list.php CHANGED
@@ -16,11 +16,18 @@ $fileName = '';
16
  $message = array();
17
  global $regenerating, $regeneratingName, $plugin_page;
18
  $regenerating = false;
 
 
 
 
 
 
 
19
  // phpcs:ignore WordPress.Security.NonceVerification.Recommended
20
- if ( ( isset( $_GET['feed_created'] ) || isset( $_GET['feed_updated'] ) || isset( $_GET['feed_imported'] ) ) && isset( $_GET['feed_regenerate'] ) && 1 == $_GET['feed_regenerate'] ) {
21
  // filename must be wf_config+XXX format for js to work.
22
  // phpcs:ignore WordPress.Security.NonceVerification.Recommended
23
- $fileName = isset( $_GET['feed_name'] ) && ! empty( $_GET['feed_name'] ) ? sanitize_text_field( wp_unslash($_GET['feed_name']) ) : ''; // trigger feed regenerate...
24
  if ( ! empty( $fileName ) ) {
25
  $fileName = woo_feed_extract_feed_option_name( $fileName );
26
  $regeneratingName = $fileName;
16
  $message = array();
17
  global $regenerating, $regeneratingName, $plugin_page;
18
  $regenerating = false;
19
+
20
+ $feed_created = apply_filters('CTXFEED_filter_securing_input', "GET", @$_GET['feed_created'], "text");
21
+ $feed_updated = apply_filters('CTXFEED_filter_securing_input', "GET", @$_GET['feed_updated'], "text");
22
+ $feed_imported = apply_filters('CTXFEED_filter_securing_input', "GET", @$_GET['feed_imported'], "text");
23
+ $feed_regenerate = apply_filters('CTXFEED_filter_securing_input', "GET", @$_GET['feed_regenerate'], "text");
24
+ $feed_name = apply_filters('CTXFEED_filter_securing_input', "GET", @$_GET['feed_name'], "file_name");
25
+
26
  // phpcs:ignore WordPress.Security.NonceVerification.Recommended
27
+ if ( ( $feed_created || $feed_updated || $feed_imported ) && 1 == $feed_regenerate ) {
28
  // filename must be wf_config+XXX format for js to work.
29
  // phpcs:ignore WordPress.Security.NonceVerification.Recommended
30
+ $fileName = $feed_name ? wp_unslash($feed_name) : ''; // trigger feed regenerate...
31
  if ( ! empty( $fileName ) ) {
32
  $fileName = woo_feed_extract_feed_option_name( $fileName );
33
  $regeneratingName = $fileName;
includes/classes/class-woo-feed-constants.php CHANGED
@@ -23,7 +23,7 @@ if( ! class_exists("Woo_Feed_Constants") ) {
23
  * @var string
24
  * @since 3.1.6
25
  */
26
- define( 'WOO_FEED_FREE_VERSION', '4.4.63' );
27
  }
28
 
29
  if ( ! defined( 'WOO_FEED_FREE_PATH' ) ) {
23
  * @var string
24
  * @since 3.1.6
25
  */
26
+ define( 'WOO_FEED_FREE_VERSION', '4.4.64' );
27
  }
28
 
29
  if ( ! defined( 'WOO_FEED_FREE_PATH' ) ) {
includes/classes/class-woo-feed-products-v3.php CHANGED
@@ -10,7 +10,7 @@
10
  use RankMath\Helper;
11
 
12
  if (!defined('ABSPATH')) {
13
- die();
14
  }
15
 
16
  /**
@@ -18,4455 +18,4455 @@ if (!defined('ABSPATH')) {
18
  */
19
  class Woo_Feed_Products_v3
20
  {
21
- /**
22
- * The Increment
23
- * @var int
24
- */
25
- protected $pi = 0;
26
- /**
27
- * Feed file headers
28
- *
29
- * @var string|array
30
- */
31
- public $feedHeader;
32
- /**
33
- * Feed File Body
34
- *
35
- * @var string|array
36
- */
37
- public $feedBody;
38
- /**
39
- * Feed file footer
40
- *
41
- * @var string|array
42
- */
43
- public $feedFooter;
44
- /**
45
- * CSV|TXT column (text|word) enclosure
46
- *
47
- * @var string
48
- */
49
- protected $enclosure;
50
- /**
51
- * CSV|TXT column delimiter
52
- *
53
- * @var string
54
- */
55
- protected $delimiter;
56
- /**
57
- * Feed Rules
58
- *
59
- * @var array
60
- */
61
- protected $config;
62
- /**
63
- * Post status to query
64
- *
65
- * @var string
66
- */
67
- protected $post_status = 'publish';
68
- /**
69
- * Processed Products
70
- *
71
- * @var array
72
- */
73
- public $products = [];
74
 
75
 
76
- /**
77
- * Products IDs
78
- *
79
- * @var array
80
- */
81
- public $product_ids = [];
82
 
83
- /**
84
- * Feed Big Data
85
- *
86
- * @var array
87
- */
88
- public $data = [];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
 
90
  /**
91
- * Processed Products
92
- *
93
- * @var array
94
- */
95
- public $product_types = [
96
- 'simple',
97
- 'variable',
98
- 'variation',
99
- 'grouped',
100
- 'external',
101
- 'composite',
102
- 'bundle',
103
- 'bundled',
104
- 'yith_bundle',
105
- 'yith-composite',
106
- 'subscription',
107
- 'variable-subscription',
108
- 'woosb',
109
- ];
110
- /**
111
- * Query Method Selector
112
  *
 
113
  * @var string
114
  */
115
- protected $queryType = 'wp';
116
- /**
117
- * To replace google product highlight attribute for CSV & TXT feed
118
- * @var array
119
- */
120
- protected $google_product_highlights = array(
121
- 'product highlight 1',
122
- 'product highlight 2',
123
- 'product highlight 3',
124
- 'product highlight 4',
125
- 'product highlight 5',
126
- 'product highlight 6',
127
- 'product highlight 7',
128
- 'product highlight 8',
129
- 'product highlight 9',
130
- 'product highlight 10',
131
- );
132
 
133
- /**
134
- * To replace google additional image link attribute for CSV & TXT feed
135
- * @var array
136
- */
137
- protected $google_additional_image = array(
138
- 'additional image link 1',
139
- 'additional image link 2',
140
- 'additional image link 3',
141
- 'additional image link 4',
142
- 'additional image link 5',
143
- 'additional image link 6',
144
- 'additional image link 7',
145
- 'additional image link 8',
146
- 'additional image link 9',
147
- 'additional image link 10',
148
- );
149
- /**
150
- * Google shipping tax attributes
151
- * @var array
152
- */
153
- /**
154
- * Google shipping tax attributes
155
- *
156
- * @var array
157
- */
158
- protected $google_shipping_tax = array(
159
- 'shipping_country',
160
- 'shipping_region',
161
- 'shipping_postal_code',
162
- 'shipping_service',
163
- 'shipping_price',
164
- 'min_handling_time',
165
- 'max_handling_time',
166
- 'min_transit_time',
167
- 'max_transit_time',
168
- 'tax',
169
- 'tax_country',
170
- 'tax_region',
171
- 'tax_rate',
172
- 'tax_ship',
173
- 'installment_months',
174
- 'installment_amount',
175
- 'subscription_period',
176
- 'subscription_period_length',
177
- 'subscription_amount',
178
- 'section_name',
179
- 'attribute_name',
180
- 'attribute_value',
181
- 'unit_price_value',
182
- 'unit_price_currency',
183
- 'unit_price_unit',
184
- 'additional_variant_label',
185
- 'additional_variant_value',
186
- );
187
- /**
188
- * XML Wrapper Array
189
- * Contains 'header' and 'footer' for template.
190
- * @var array
191
- */
192
- protected $xml_wrapper = [];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193
 
 
 
 
194
 
195
- /**
196
- * Attribute to skip in attribute loop for processing separately
197
- *
198
- * @var array
199
- */
200
- protected $skipped_merchant_attributes = array(
201
- 'google' => array(
202
- 'shipping_country',
203
- 'shipping_region',
204
- 'shipping_postal_code',
205
- 'shipping_service',
206
- 'shipping_price',
207
- 'min_handling_time',
208
- 'max_handling_time',
209
- 'min_transit_time',
210
- 'max_transit_time',
211
- 'tax_country',
212
- 'tax_region',
213
- 'tax_rate',
214
- 'tax_ship',
215
- 'installment_months',
216
- 'installment_amount',
217
- 'subscription_period',
218
- 'subscription_period_length',
219
- 'subscription_amount',
220
- 'section_name',
221
- 'attribute_name',
222
- 'attribute_value',
223
- ),
224
- 'facebook' => array(
225
- 'shipping_country',
226
- 'shipping_region',
227
- 'shipping_service',
228
- 'shipping_price',
229
- 'tax_country',
230
- 'tax_region',
231
- 'tax_rate',
232
- 'tax_ship',
233
- 'installment_months',
234
- 'installment_amount',
235
- 'subscription_period',
236
- 'subscription_period_length',
237
- 'subscription_amount',
238
- 'section_name',
239
- 'attribute_name',
240
- 'attribute_value',
241
- 'unit_price_value',
242
- 'unit_price_currency',
243
- 'unit_price_unit',
244
- 'additional_variant_label',
245
- 'additional_variant_value',
246
- ),
247
- 'bing' => array(
248
- 'shipping_country',
249
- 'shipping_service',
250
- 'shipping_price',
251
- ),
252
- 'pinterest' => array(
253
- 'shipping_country',
254
- 'shipping_service',
255
- 'shipping_price',
256
- 'shipping_region',
257
- 'shipping_postal_code',
258
- 'tax_country',
259
- 'tax_region',
260
- 'tax_rate',
261
- 'tax_ship',
262
- ),
263
- );
264
 
265
- /**
266
- * Already Processed merchant attributes by the attribute loop
267
- * this will ensure unique merchant attribute.
268
- * @see Woo_Feed_Products_v::exclude_current_attribute()
269
- * @var array
270
- */
271
- protected $processed_merchant_attributes = array();
272
 
 
 
 
273
 
274
- /**
275
- * Post meta prefix for dropdown item
276
- * @since 3.1.18
277
- * @var string
278
- */
279
- const POST_META_PREFIX = 'wf_cattr_';
280
 
281
- /**
282
- * Product Attribute (taxonomy & local) Prefix
283
- * @since 3.1.18
284
- * @var string
285
- */
286
- const PRODUCT_ATTRIBUTE_PREFIX = 'wf_attr_';
287
 
288
- /**
289
- * Product Taxonomy Prefix
290
- * @since 3.1.18
291
- * @var string
292
- */
293
- const PRODUCT_TAXONOMY_PREFIX = 'wf_taxo_';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
294
 
295
- /**
296
- * Product Custom Field Prefix
297
- *
298
- * @since 3.1.18
299
- * @var string
300
- */
301
- const PRODUCT_CUSTOM_IDENTIFIER = 'woo_feed_';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
302
 
303
- /**
304
- * Product Category Mapping Prefix
305
- * @since 3.1.18
306
- * @var string
307
- */
308
- const PRODUCT_CATEGORY_MAPPING_PREFIX = 'wf_cmapping_';
309
 
310
- /**
311
- * WordPress Option Prefix
312
- *
313
- * @since 4.3.33
314
- * @var string
315
- * @author Nazrul Islam Nayan
316
- */
317
- const WP_OPTION_PREFIX = 'wf_option_';
318
 
319
- /**
320
- * Advance Custom Field (ACF) Prefix
321
- *
322
- * @since 3.1.18
323
- * @var string
324
- */
325
- const PRODUCT_ACF_FIELDS = 'acf_fields_';
326
 
327
- /**
328
- * Woo_Feed_Products_v3 constructor.
329
- *
330
- * @param $config
331
- * @return void
332
- */
333
- public function __construct($config)
334
- {
335
- $this->config = woo_feed_parse_feed_rules($config);
336
- $this->queryType = woo_feed_get_options('product_query_type');
337
- $this->process_xml_wrapper();
338
- woo_feed_log_feed_process($this->config['filename'], sprintf('Current Query Type is %s', $this->queryType));
339
- }
340
 
341
- /**
342
- * Generate Query Args For WP/WC query class
343
- * @param string $type
344
- * @return array
345
- */
346
- protected function get_query_args($type = 'wc')
347
- {
348
- $args = [];
349
-
350
- // Include Product Variations with db query if configured
351
- $variation_query = woo_feed_get_options('variation_query_type');
352
-
353
- if ('wc' === $type) {
354
- $product_types = $this->product_types;
355
- if ('variable' === $variation_query) {
356
- $variation = array_search('variation', $product_types, true);
357
- if ($variation) {
358
- unset($product_types[$variation]);
359
- }
360
- }
361
-
362
- $args = array(
363
- 'limit' => -1, // phpcs:ignore
364
- 'status' => $this->post_status,
365
- 'type' => $product_types,
366
- 'orderby' => 'date',
367
- 'order' => 'DESC',
368
- 'return' => 'ids',
369
- 'suppress_filters' => false,
370
- );
371
- }
372
 
373
- if ('wp' === $type) {
374
-
375
- $post_type = 'product';
376
- // Include Product Variations with db query if configured
377
- $variation_query = woo_feed_get_options('variation_query_type');
378
- if ('individual' === $variation_query) {
379
- $post_type = ['product', 'product_variation'];
380
- }
381
-
382
- $args = array(
383
- 'posts_per_page' => -1, // phpcs:ignore
384
- 'post_type' => $post_type,
385
- 'post_status' => 'publish',
386
- 'order' => 'DESC',
387
- 'fields' => 'ids',
388
- 'cache_results' => false,
389
- 'update_post_meta_cache' => false,
390
- 'update_post_term_cache' => false,
391
- 'suppress_filters' => false,
392
- );
393
- }
394
- return $args;
395
- }
396
 
397
- /**
398
- * Get Products using WC_Product_Query
399
- *
400
- * @return array
401
- */
402
- public function get_wc_query_products()
403
- {
404
- $args = $this->get_query_args('wc');
405
- if (woo_feed_is_debugging_enabled()) {
406
- woo_feed_log_feed_process($this->config['filename'], 'WC_Product_Query Args::' . PHP_EOL . print_r($args, true)); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
407
- woo_feed_log($this->config['filename'], 'WC_Product_Query Args::' . PHP_EOL . print_r($args, true), 'info'); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
408
- }
409
- $query = new WC_Product_Query($args);
410
- if (woo_feed_is_debugging_enabled()) {
411
- woo_feed_log_feed_process($this->config['filename'], sprintf('WC_Product_Query Args ::' . PHP_EOL . '%s', print_r($args, true))); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
412
- }
413
- return $query->get_products();
414
- }
415
 
416
- /**
417
- * Get Products using WP_Query
418
- *
419
- * return array
420
- */
421
- public function get_wp_query_products()
422
- {
423
- $args = $this->get_query_args('wp');
424
- $query = new WP_Query($args);
425
- if (!is_wp_error($query) && woo_feed_is_debugging_enabled()) {
426
- woo_feed_log_feed_process($this->config['filename'], 'WC_Product_Query Args::' . PHP_EOL . print_r($args, true)); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
427
- woo_feed_log_feed_process($this->config['filename'], sprintf('WP_Query Request ::' . PHP_EOL . '%s', $query->request));
428
- woo_feed_log($this->config['filename'], 'WC_Product_Query Args::' . PHP_EOL . print_r($args, true), 'info'); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
429
- woo_feed_log($this->config['filename'], sprintf('WP_Query Request ::' . PHP_EOL . '%s', $query->request), 'info');
430
- }
431
- return $query->get_posts();
432
- }
433
 
434
- /**
435
- * Get products
436
- *
437
- * @return array
438
- */
439
- public function query_products()
440
- {
441
- $products = [];
442
- if ('wc' == $this->queryType) {
443
- $products = $this->get_wc_query_products();
444
- } elseif ('wp' == $this->queryType) {
445
- $products = $this->get_wp_query_products();
446
- } elseif ('both' == $this->queryType) {
447
- $wc = $this->get_wc_query_products();
448
- $wp = $this->get_wp_query_products();
449
- $products = array_unique(array_merge($wc, $wp));
450
- }
451
 
452
- //set product ids
453
- $this->product_ids = $products;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
454
 
455
- return $products;
456
- }
457
 
458
- /**
459
- * Organize Feed Attribute config
460
- * @return array|bool
461
- */
462
- public function get_attribute_config()
463
- {
464
- if (empty($this->config)) {
465
- return false;
466
- }
467
 
468
- $attributeConfig = array();
469
- $merchantAttributes = $this->config['mattributes'];
470
- if (!empty($merchantAttributes)) {
471
- $i = 0;
472
- foreach ($merchantAttributes as $key => $value) {
473
- $attributeConfig[$i]['mattributes'] = $value;
474
- $attributeConfig[$i]['prefix'] = $this->config['prefix'][$key];
475
- $attributeConfig[$i]['type'] = $this->config['type'][$key];
476
- $attributeConfig[$i]['attributes'] = $this->config['attributes'][$key];
477
- $attributeConfig[$i]['default'] = $this->config['default'][$key];
478
- $attributeConfig[$i]['suffix'] = $this->config['suffix'][$key];
479
- $attributeConfig[$i]['output_type'] = $this->config['output_type'][$key];
480
- $attributeConfig[$i]['limit'] = $this->config['limit'][$key];
481
- $i++;
482
- }
483
- }
484
 
485
- return $attributeConfig;
486
- }
487
 
488
- /**
489
- * Get Product Information according to feed config
490
- *
491
- * @param int[] $productIds
492
- *
493
- * @return array
494
- * @since 3.2.0
495
- *
496
- */
497
- public function get_products($productIds)
498
- {
 
499
 
500
- if (empty($productIds)) {
501
- return [];
502
- }
 
 
503
 
504
- //filter big data
505
- $this->data = apply_filters("woo_feed_feed_big_data", $this->data, $productIds, $this->config);
506
-
507
- /**
508
- * Fires before looping through request product for getting product data
509
- *
510
- * @param int[] $productIds
511
- * @param array $feedConfig
512
- *
513
- * @since 3.2.10
514
- */
515
- do_action('woo_feed_before_product_loop', $productIds, $this->config);
516
-
517
- foreach ($productIds as $key => $pid) {
518
- woo_feed_log_feed_process($this->config['filename'], sprintf('Loading Product Data For %d.', $pid));
519
- $product = wc_get_product($pid);
520
-
521
- if ($this->exclude_from_loop($product)) {
522
- continue;
523
- }
524
-
525
- if ($this->process_variation($product)) {
526
- continue;
527
- }
528
-
529
- if (!$this->filter_product($product)) {
530
- woo_feed_log_feed_process($this->config['filename'], 'Skipping Product :: Matched with filter conditions');
531
- continue;
532
- }
533
-
534
- woo_feed_log_feed_process($this->config['filename'], 'Formatting Feed Data...');
535
-
536
- // Add Single item wrapper before product info loop start
537
- if ('xml' == $this->config['feedType']) {
538
- $this->feedBody .= "\n";
539
- $this->feedBody .= '<' . $this->config['itemWrapper'] . '>';
540
- $this->feedBody .= "\n";
541
- }
542
-
543
- // reset processed attribute list before loop
544
- $this->processed_merchant_attributes = [];
545
-
546
- // Process attribute values
547
- $this->process_attributes($product);
548
-
549
- try {
550
- woo_feed_log_feed_process($this->config['filename'], 'Processing Merchant Specific Fields');
551
- // Process feed data for uncommon merchant feed like Google,Facebook,Pinterest
552
- $this->process_for_merchant($product, $this->pi);
553
- } catch (Exception $e) {
554
- $message = 'Error Processing Merchant Specific Fields.' . PHP_EOL . 'Caught Exception :: ' . $e->getMessage();
555
- woo_feed_log($this->config['filename'], $message, 'critical', $e, true);
556
- woo_feed_log_fatal_error($message, $e);
557
- }
558
-
559
- if ('xml' == $this->config['feedType']) {
560
- if (empty($this->feedHeader)) {
561
- $this->feedHeader = $this->process_xml_feed_header();
562
- $this->feedFooter = $this->process_xml_feed_footer();
563
-
564
- }
565
-
566
- $this->feedBody .= '</' . $this->config['itemWrapper'] . '>';
567
-
568
-
569
- } elseif ('txt' == $this->config['feedType']) {
570
- if (empty($this->feedHeader)) {
571
- $this->process_txt_feed_header();
572
- }
573
- $this->process_txt_feed_body();
574
- } elseif ('csv' == $this->config['feedType'] || 'xls' == $this->config['feedType']) {
575
- if (empty($this->feedHeader)) {
576
- $this->process_csv_feed_header();
577
- }
578
- $this->process_csv_feed_body();
579
- } elseif ('json' == $this->config['feedType']) {
580
- $this->process_json_feed_body();
581
- }
582
- woo_feed_log_feed_process($this->config['filename'], 'Done Formatting...');
583
- $this->pi++;
584
- }
585
 
586
- /**
587
- * Fires after looping through request product for getting product data
588
- *
589
- * @param int[] $productIds
590
- * @param array $feedConfig
591
- *
592
- * @since 3.2.10
593
- */
594
- do_action('woo_feed_after_product_loop', $productIds, $this->config);
595
-
596
- return $this->products;
597
- }
598
 
599
- /**
600
- * Process product variations
601
- * @param WC_Abstract_Legacy_Product $product
602
- *
603
- * @return bool
604
- * @since 3.3.9
605
- */
606
- protected function process_variation($product)
607
- {
608
- // Apply variable and variation settings
609
- if ($product->is_type('variable') && $product->has_child()) {
610
- $this->pi++;
611
-
612
- $variation_query = woo_feed_get_options('variation_query_type');
613
- if ('variable' === $variation_query) {
614
- $variations = $product->get_visible_children();
615
- if (is_array($variations) && (sizeof($variations) > 0)) {
616
- if (woo_feed_is_debugging_enabled()) {
617
- woo_feed_log_feed_process($this->config['filename'], sprintf('Getting Variation Product(s) :: %s', implode(', ', $variations)));
618
- }
619
- $this->get_products($variations);
620
- return true;
621
- }
622
- }
623
- }
624
 
625
- return false;
626
- }
627
 
628
- /**
629
- * Process The Attributes and assign value to merchant attribute
630
- *
631
- * @param WC_Abstract_Legacy_Product $product
632
- *
633
- * @return void
634
- * @since 3.3.9
635
- */
636
- protected function process_attributes($product)
637
- {
638
- // print_r($this->config['attributes']);
639
- // Get Product Attribute values by type and assign to product array
640
- foreach ($this->config['attributes'] as $attr_key => $attribute) {
641
-
642
- $merchant_attribute = isset($this->config['mattributes'][$attr_key]) ? $this->config['mattributes'][$attr_key] : '';
643
-
644
- if ($this->exclude_current_attribute($product, $merchant_attribute, $attribute)) {
645
- continue;
646
- }
647
-
648
- // Add Prefix and Suffix into Output
649
- $prefix = $this->config['prefix'][$attr_key];
650
- $suffix = $this->config['suffix'][$attr_key];
651
- $merchant = $this->config['provider'];
652
- $feedType = $this->config['feedType'];
653
-
654
- if ('pattern' == $this->config['type'][$attr_key]) {
655
- $attributeValue = $this->config['default'][$attr_key];
656
- } else { // Get Pattern value
657
- $attributeValue = $this->getAttributeValueByType($product, $attribute, $merchant_attribute);
658
- }
659
-
660
- // Format Output according to Output Type config.
661
- if (isset($this->config['output_type'][$attr_key])) {
662
- $outputType = $this->config['output_type'][$attr_key];
663
- $attributeValue = $this->format_output($attributeValue, $this->config['output_type'][$attr_key], $product, $attribute, $merchant_attribute);
664
- }
665
-
666
- // Limit Output.
667
- if (isset($this->config['limit'][$attr_key])) {
668
- $attributeValue = $this->crop_string($attributeValue, 0, $this->config['limit'][$attr_key]);
669
- }
670
-
671
- // Process prefix and suffix.
672
- $attributeValue = $this->process_prefix_suffix($attributeValue, $prefix, $suffix, $attribute);
673
-
674
- if ('xml' == $feedType) {
675
-
676
- // Replace XML Nodes according to merchant requirement.
677
- $getReplacedAttribute = woo_feed_replace_to_merchant_attribute($merchant_attribute, $merchant, $feedType);
678
-
679
- // XML does not support space in node. So replace Space with Underscore.
680
- $getReplacedAttribute = str_replace(' ', '_', $getReplacedAttribute);
681
-
682
- // Trim XML Element text & Encode for UTF-8.
683
- if (!empty($attributeValue)) {
684
- $attributeValue = trim($attributeValue);
685
-
686
- if ('custom' === $this->config['provider'] && strpos($attributeValue, '<![CDATA[') === false) {
687
- $attributeValue = htmlentities($attributeValue, ENT_XML1 | ENT_QUOTES, 'UTF-8');
688
- }
689
- }
690
-
691
- // Add closing XML node if value is empty
692
- if ('' !== $attributeValue) {
693
- // Add CDATA wrapper for XML feed to prevent XML error.
694
- $attributeValue = woo_feed_add_cdata($merchant_attribute, $attributeValue, $merchant, $this->config['feedType']);
695
- // print_r($attributeValue);echo"<br/>";
696
- // Strip slash from output.
697
- $attributeValue = stripslashes($attributeValue);
698
- $this->feedBody .= '<' . $getReplacedAttribute . '>' . "$attributeValue" . '</' . $getReplacedAttribute . '>';
699
- $this->feedBody .= "\n";
700
- } else {
701
- $this->feedBody .= '<' . $getReplacedAttribute . '/>';
702
- $this->feedBody .= "\n";
703
- }
704
-
705
- } elseif (in_array($feedType, ['csv', 'tsv', 'xls'], true)) {
706
- $merchant_attribute = woo_feed_replace_to_merchant_attribute($merchant_attribute, $merchant, $feedType);
707
- $merchant_attribute = $this->processStringForCSV($merchant_attribute);
708
-
709
- if ("shipping" === $merchant_attribute && 'bing' == $this->config['provider']) {
710
- $merchant_attribute = 'shipping(country:service:price)';
711
- } elseif ("shipping" === $merchant_attribute) {
712
- $merchant_attribute = 'shipping(country:region:service:price)';
713
- }
714
-
715
- if ("tax" === $merchant_attribute) {
716
- $merchant_attribute = 'tax(country:region:rate:tax_ship)';
717
- }
718
-
719
- $attributeValue = $this->processStringForCSV($attributeValue);
720
-
721
- } elseif ('txt' == $feedType) {
722
- $merchant_attribute = woo_feed_replace_to_merchant_attribute($merchant_attribute, $merchant, $feedType);
723
- $merchant_attribute = $this->processStringForTXT($merchant_attribute);
724
-
725
- if ("shipping" === $merchant_attribute && 'bing' == $this->config['provider']) {
726
- $merchant_attribute = 'shipping(country:service:price)';
727
- } elseif ("shipping" === $merchant_attribute) {
728
- $merchant_attribute = 'shipping(country:region:service:price)';
729
- }
730
-
731
- if ("tax" === $merchant_attribute) {
732
- $merchant_attribute = 'tax(country:region:rate:tax_ship)';
733
- }
734
-
735
- $attributeValue = $this->processStringForTXT($attributeValue);
736
- }
737
-
738
- $this->products[$this->pi][$merchant_attribute] = $attributeValue;
739
- }
740
- }
741
 
742
- /**
743
- * Process Nested Attributes
744
- *
745
- * @return array
746
- * @since 4.0.5
747
- *
748
- */
749
- protected function feed_nested_attributes()
750
- {
751
- return [
752
- 'reviewer' => ['reviewer', 'name'],
753
- 'ratings' => ['ratings', 'overall'],
754
- 'product_url' => ['products', 'product', 'product_url'],
755
- ];
756
- }
757
 
758
- /**
759
- * Process Nested Attributes
760
- *
761
- * @param string $attribute //product feed tag
762
- * @param string $content //product feed content
763
- *
764
- * @return string
765
- * @since 4.0.5
766
- *
767
- */
768
 
769
- protected function nested_attributes_element($attribute, $content)
770
- {
771
- $starter = '';
772
- $finisher = '';
773
- $element = '';
774
 
775
- if (empty($attribute)) {
776
- return $attribute;
777
- }
778
 
779
- $attr_names = $this->feed_nested_attributes();
780
-
781
- foreach ($attr_names as $key => $value) {
782
- if ($key === $attribute) {
783
- //starter tags element
784
- foreach ($value as $item_value) {
785
- $starter .= '<' . strval($item_value) . '>';
786
- }
787
-
788
- //finishing tags element
789
- $rev_value = array_reverse($value);
790
- foreach ($rev_value as $item_value) {
791
- $finisher .= '</' . strval($item_value) . '>';
792
- }
793
- }
794
- }
795
-
796
- $element = $starter . $content . $finisher;
797
-
798
- return $element;
799
- }
800
-
801
- /**
802
- * Check if current product should be processed for feed
803
- * This should be using by Woo_Feed_Products_v3::get_products()
804
- *
805
- * @param WC_Product $product
806
- *
807
- * @return bool
808
- * @since 3.3.9
809
- *
810
- */
811
- protected function exclude_from_loop($product)
812
- {
813
- // Skip for invalid products
814
- if (!is_object($product)) {
815
- woo_feed_log_feed_process($this->config['filename'], 'Skipping Product :: Product data is not a valid WC_Product object.');
816
- return true;
817
- }
818
-
819
- // For WP_Query check available product types
820
- if ('wp' == $this->queryType && !in_array($product->get_type(), $this->product_types, true)) {
821
- woo_feed_log_feed_process($this->config['filename'], sprintf('Skipping Product :: Invalid Post/Product Type : %s.', $product->get_type()));
822
- return true;
823
- }
824
-
825
- // Skip orphaned variation
826
- if ($product->is_type('variation') && !$product->get_parent_id()) {
827
- woo_feed_log_feed_process($this->config['filename'], sprintf('Skipping Product :: Orphaned variation product [id: %s] skipped.', $product->get_id()));
828
- return true;
829
- }
830
 
831
- // Skip for invisible products
832
- if (!$product->is_visible()) {
833
- woo_feed_log_feed_process($this->config['filename'], 'Skipping Product :: Product is not visible.');
834
- return true;
835
- }
836
- return false;
837
- }
838
-
839
- /**
840
- * Check if current attribute/merchant attribute should be processed for feed
841
- * This should be using by Woo_Feed_Products_v3::get_products()
842
- *
843
- * @param WC_Product $product
844
- * @param string $merchant_attribute
845
- * @param string $product_attribute
846
- * @param string $feedType
847
- *
848
- * @return bool
849
- *
850
- * @since 3.3.9
851
- *
852
- */
853
- protected function exclude_current_attribute($product, $merchant_attribute, $product_attribute, $feedType = 'xml')
854
- {
855
-
856
- if (empty($merchant_attribute)) {
857
- return true;
858
- }
859
 
860
- if (
861
- in_array($this->config['provider'], array_keys($this->skipped_merchant_attributes)) &&
862
- in_array($merchant_attribute, $this->skipped_merchant_attributes[$this->config['provider']])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
863
 
864
- ) {
865
- return true;
866
- }
867
 
868
- if ('shopping_ads_excluded_country' !== $merchant_attribute && in_array($merchant_attribute, $this->processed_merchant_attributes)) {
869
- return true;
870
- }
871
 
872
- $this->processed_merchant_attributes[] = $merchant_attribute;
 
873
 
874
- return false;
875
- }
 
 
 
 
876
 
877
- /**
878
- * Wrapper for substr with <![CDATA[string]]> support
879
- *
880
- * @param string $string
881
- * @param int $start
882
- * @param int $limit
883
- *
884
- * @return string
885
- * @see substr
886
- *
887
- */
888
- protected function crop_string($string, $start = 0, $limit = null)
889
- {
890
- $limit = absint($limit);
891
- if ($limit > 0) {
892
- $start = absint($start);
893
- if (strpos($string, '<![CDATA[') !== false) {
894
- $string = str_replace(array('<![CDATA[', ']]>'), array('', ''), $string);
895
- $string = substr($string, $start, $limit);
896
- $string = '<![CDATA[' . $string . ']]>';
897
- } else {
898
- $string = substr($string, $start, $limit);
899
- }
900
- }
901
- return $string;
902
- }
903
 
904
- /**
905
- * Process feed data according to merchant uncommon requirements like Google
906
- *
907
- * @param object $productObj WC_Product
908
- * @param int $index Product Index
909
- *
910
- * @since 3.2.0
911
- */
912
- protected function process_for_merchant($productObj, $index)
913
- {
914
- $product = $this->products[$index];
915
- $merchantAttributes = $this->config['mattributes'];
916
- $s = 0; // Shipping Index
917
- $i = 0; // Installment Index
918
- $t = 0; // Tax Index
919
- $tax = '';
920
- $shipping = '';
921
- $sub = 0;
922
- $subscription = '';
923
- $ins = 0; // Installment Index
924
- $installment = "";
925
- $product_detail = '';
926
- $unit_price = '';
927
- $additional_variant_attribute = '';
928
- $pd = 0;
929
- $up = 0; //Unit Price for facebook
930
- $av = 0; //Additional Variant Attribute for facebook
931
-
932
-
933
- // Format Shipping and Tax data for CSV and TXT feed only for google and facebook
934
-
935
- if ('xml' != $this->config['feedType'] && in_array($this->config['provider'], array('google', 'facebook', 'bing', 'snapchat', 'pinterest'))) {
936
- foreach ($merchantAttributes as $key => $value) {
937
-
938
- if (!in_array($value, $this->google_shipping_tax, true)) {
939
- continue;
940
- }
941
-
942
- # Get value by attribute type with prefix & suffix
943
- $output = $this->process_for_merchant_get_value($productObj, $key);
944
-
945
- if ('shipping_country' == $value) {
946
- $s++;
947
- $shipping .= $output;
948
- }
949
- if ('shipping_region' == $value) {
950
- $shipping .= ':' . $output;
951
- } elseif ('shipping_postal_code' == $value) {
952
- $shipping .= ':' . $output;
953
- }
954
- if ('shipping_service' == $value) {
955
- $shipping .= ':' . $output;
956
- }
957
- if ('shipping_price' == $value) {
958
- $shipping .= ':' . $output;
959
- }
960
-
961
- if ('section_name' == $value) {
962
- $pd++;
963
- $product_detail .= $output;
964
- }
965
- if ('attribute_name' == $value) {
966
- $product_detail .= ':' . $output;
967
- }
968
- if ('attribute_value' == $value) {
969
- $product_detail .= ':' . $output;
970
- }
971
-
972
- //facebook nested attributes
973
- if (isset($this->config['provider']) && "facebook" === $this->config['provider']) {
974
- if ('unit_price_value' == $value) {
975
- $up++;
976
- $unit_price .= $output;
977
- }
978
- if ('unit_price_currency' == $value) {
979
- $unit_price .= ':' . $output;
980
- }
981
- if ('unit_price_unit' == $value) {
982
- $unit_price .= ':' . $output;
983
- }
984
-
985
- if ('additional_variant_label' == $value) {
986
- $av++;
987
- $additional_variant_attribute .= $output;
988
- }
989
- if ('additional_variant_value' == $value) {
990
- $additional_variant_attribute .= ':' . $output;
991
- }
992
-
993
- if (0 < $up) {
994
- $this->products[$this->pi]["unit_price"] = $unit_price;
995
- }
996
-
997
- if (0 < $av) {
998
- $this->products[$this->pi]["additional_variant_attribute"] = $additional_variant_attribute;
999
- }
1000
- }
1001
-
1002
-
1003
- if ('installment_months' == $value) {
1004
- $ins++;
1005
- $installment .= $output;
1006
- }
1007
- if ('installment_amount' == $value) {
1008
- $installment .= ':' . $output;
1009
- }
1010
-
1011
- if ('subscription_period' == $value) {
1012
- $sub++;
1013
- $subscription .= $output;
1014
- }
1015
- if ('subscription_period_length' == $value) {
1016
- $subscription .= ':' . $output;
1017
- }
1018
- if ('subscription_amount' == $value) {
1019
- $subscription .= ':' . $output;
1020
- }
1021
- }
1022
-
1023
- if (0 < $pd) {
1024
- $this->products[$this->pi]["product detail"] = $product_detail;
1025
- }
1026
-
1027
- if (0 < $sub) {
1028
- $this->products[$this->pi]["subscription cost"] = $subscription;
1029
-
1030
- }
1031
-
1032
- if (0 < $ins) {
1033
- $this->products[$this->pi]["installment"] = $installment;
1034
- }
1035
- }
1036
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1037
 
1038
- if (in_array($this->config['provider'], array('google', 'facebook', 'snapchat', 'bing', 'pinterest'))) {
1039
-
1040
-
1041
- // Reformat Shipping attributes for google, facebook
1042
- if ('xml' == $this->config['feedType']) {
1043
- foreach ($merchantAttributes as $key => $value) {
1044
-
1045
- if (!in_array($value, $this->google_shipping_tax)) {
1046
- continue;
1047
- }
1048
-
1049
-
1050
- # Get value by attribute type with prefix & suffix
1051
- $output = $this->process_for_merchant_get_value($productObj, $key);
1052
-
1053
-
1054
- if ('shipping_country' == $value) {
1055
- if (0 == $s) {
1056
- $shipping .= '<g:shipping>';
1057
- $s = 1;
1058
- } else {
1059
- $shipping .= '</g:shipping>' . "\n";
1060
- $shipping .= '<g:shipping>';
1061
- }
1062
- } elseif (!in_array('shipping_country', $merchantAttributes) && 'shipping_price' == $value) {
1063
- if (0 == $s) {
1064
- $shipping .= '<g:shipping>';
1065
- $s = 1;
1066
- } else {
1067
- $shipping .= '</g:shipping>' . "\n";
1068
- $shipping .= '<g:shipping>';
1069
- }
1070
- }
1071
-
1072
- if ('shipping_country' == $value) {
1073
- $shipping .= '<g:country>' . $output . '</g:country>' . "\n";
1074
- } elseif ('shipping_region' == $value) {
1075
- $shipping .= '<g:region>' . $output . '</g:region>' . "\n";
1076
- } elseif ('shipping_region' == $value) {
1077
- $shipping .= '<g:region>' . $output . '</g:region>' . "\n";
1078
- } elseif ('shipping_service' == $value) {
1079
- $shipping .= '<g:service>' . $output . '</g:service>' . "\n";
1080
- } elseif ('shipping_postal_code' == $value) {
1081
- $shipping .= '<g:postal_code>' . $output . '</g:postal_code>' . "\n";
1082
- } elseif ('shipping_price' == $value) {
1083
- $shipping .= '<g:price>' . $output . '</g:price>' . "\n";
1084
- } elseif ('tax_country' == $value) {
1085
- if (0 == $t) {
1086
- $tax .= '<g:tax>';
1087
- $t = 1;
1088
- } else {
1089
- $tax .= '</g:tax>' . "\n";
1090
- $tax .= '<g:tax>';
1091
- }
1092
- $tax .= '<g:country>' . $output . '</g:country>' . "\n";
1093
- } elseif ('tax_region' == $value) {
1094
- $tax .= '<g:region>' . $output . '</g:region>' . "\n";
1095
- } elseif ('tax_rate' == $value) {
1096
- $tax .= '<g:rate>' . $output . '</g:rate>' . "\n";
1097
- } elseif ('tax_ship' == $value) {
1098
- $tax .= '<g:tax_ship>' . $output . '</g:tax_ship>' . "\n";
1099
- } elseif ('subscription_period' == $value) {
1100
- if (0 == $sub) {
1101
- $subscription .= '<g:subscription_cost>';
1102
- $sub = 1;
1103
- } else {
1104
- $subscription .= '</g:subscription_cost>' . "\n";
1105
- $subscription .= '<g:subscription_cost>';
1106
- }
1107
- $subscription .= '<g:period>' . $output . '</g:period>' . "\n";
1108
- } elseif ('subscription_period_length' == $value) {
1109
- $subscription .= '<g:period_length>' . $output . '</g:period_length>' . "\n";
1110
- } elseif ('subscription_amount' == $value) {
1111
- $subscription .= '<g:amount>' . $output . '</g:amount>' . "\n";
1112
- }
1113
-
1114
- if ('section_name' == $value) {
1115
- if (0 == $pd) {
1116
- $product_detail .= '<g:product_detail>';
1117
- $pd = 1;
1118
- } else {
1119
- $product_detail .= '</g:product_detail>' . "\n";
1120
- $product_detail .= '<g:product_detail>';
1121
- }
1122
- } elseif (!in_array('section_name', $merchantAttributes) && 'attribute_name' == $value) {
1123
- if (0 == $pd) {
1124
- $product_detail .= '<g:product_detail>';
1125
- $pd = 1;
1126
- } else {
1127
- $product_detail .= '</g:product_detail>' . "\n";
1128
- $product_detail .= '<g:product_detail>';
1129
- }
1130
- }
1131
-
1132
- if ('section_name' == $value) {
1133
- $product_detail .= '<g:section_name>' . $output . '</g:section_name>' . "\n";
1134
- } elseif ('attribute_name' == $value) {
1135
- $product_detail .= '<g:attribute_name>' . $output . '</g:attribute_name>' . "\n";
1136
- } elseif ('attribute_value' == $value) {
1137
- $product_detail .= '<g:attribute_value>' . $output . '</g:attribute_value>' . "\n";
1138
- }
1139
-
1140
- if (isset($this->config['provider']) && "facebook" === $this->config['provider']) {
1141
-
1142
- // unit_price configure
1143
- if ('unit_price_value' == $value) {
1144
- if (0 == $up) {
1145
- $unit_price .= '<unit_price>';
1146
- $up = 1;
1147
- } else {
1148
- $unit_price .= '</unit_price>' . "\n";
1149
- $unit_price .= '<unit_price>';
1150
- }
1151
- } elseif (!in_array('unit_price_value', $merchantAttributes) && 'unit_price_currency' == $value) {
1152
- if (0 == $up) {
1153
- $unit_price .= '<unit_price>';
1154
- $up = 1;
1155
- } else {
1156
- $unit_price .= '</unit_price>' . "\n";
1157
- $unit_price .= '<unit_price>';
1158
- }
1159
- }
1160
-
1161
- if ('unit_price_value' == $value) {
1162
- $unit_price .= '<value>' . $output . '</value>' . "\n";
1163
- } elseif ('unit_price_currency' == $value) {
1164
- $unit_price .= '<currency>' . $output . '</currency>' . "\n";
1165
- } elseif ('unit_price_unit' == $value) {
1166
- $unit_price .= '<unit>' . $output . '</unit>' . "\n";
1167
- }
1168
-
1169
- // additional_variant_attribute configure
1170
- if ('additional_variant_label' == $value) {
1171
- if (0 == $av) {
1172
- $additional_variant_attribute .= '<additional_variant_attribute>';
1173
- $av = 1;
1174
- } else {
1175
- $additional_variant_attribute .= '</additional_variant_attribute>' . "\n";
1176
- $additional_variant_attribute .= '<additional_variant_attribute>';
1177
- }
1178
- } elseif (!in_array('additional_variant_label', $merchantAttributes) && 'additional_variant_value' == $value) {
1179
- if (0 == $av) {
1180
- $additional_variant_attribute .= '<additional_variant_attribute>';
1181
- $av = 1;
1182
- } else {
1183
- $additional_variant_attribute .= '</additional_variant_attribute>' . "\n";
1184
- $additional_variant_attribute .= '<additional_variant_attribute>';
1185
- }
1186
- }
1187
-
1188
- if ('additional_variant_label' == $value) {
1189
- $additional_variant_attribute .= '<label>' . $output . '</label>' . "\n";
1190
- } elseif ('additional_variant_value' == $value) {
1191
- $additional_variant_attribute .= '<value>' . $output . '</value>' . "\n";
1192
- }
1193
- }
1194
-
1195
-
1196
- if ('installment_months' === $value) {
1197
- if (0 == $ins) {
1198
- $installment .= '<g:installment>';
1199
- $ins = 1;
1200
- } else {
1201
- $installment .= '</g:installment>' . "\n";
1202
- $installment .= '<g:installment>';
1203
- }
1204
- $installment .= '<g:months>' . $output . '</g:months>' . "\n";
1205
- } elseif ('installment_amount' == $value) {
1206
- $installment .= '<g:amount>' . $output . '</g:amount>' . "\n";
1207
- }
1208
- }
1209
-
1210
- if (1 == $pd) {
1211
- $product_detail .= '</g:product_detail>';
1212
- }
1213
-
1214
- if (isset($this->config['provider']) && "facebook" === $this->config['provider']) {
1215
- if (1 == $up) {
1216
- $unit_price .= '</unit_price>';
1217
- }
1218
-
1219
- if (1 == $av) {
1220
- $additional_variant_attribute .= '</additional_variant_attribute>';
1221
- }
1222
-
1223
- $this->feedBody .= $unit_price;
1224
- $this->feedBody .= $additional_variant_attribute;
1225
- }
1226
-
1227
- if (1 == $s) {
1228
- $shipping .= '</g:shipping>';
1229
- }
1230
- if (1 == $t) {
1231
- $tax .= '</g:tax>';
1232
- }
1233
-
1234
- if (1 == $sub) {
1235
- $subscription .= '</g:subscription_cost>';
1236
- }
1237
-
1238
- if (1 == $ins) {
1239
- $installment .= '</g:installment>';
1240
- }
1241
-
1242
- //$this->feedBody .= $shipping;
1243
- //$this->feedBody .= $tax;
1244
- $this->feedBody .= $product_detail;
1245
- $this->feedBody .= $installment;
1246
-
1247
- if ($productObj->is_type('subscription') ||
1248
- $productObj->is_type('variable-subscription') ||
1249
- $productObj->is_type('subscription_variation')) {
1250
- $this->feedBody .= $subscription;
1251
- }
1252
- }
1253
- // ADD g:identifier_exists
1254
- $identifier = array('brand', 'upc', 'sku', 'mpn', 'gtin');
1255
- $countIdentifier = 0;
1256
- if (!in_array('identifier_exists', $merchantAttributes)) {
1257
- if (count(array_intersect_key(array_flip($identifier), $product)) >= 2) {
1258
- // Any 2 required keys exist!
1259
- // @TODO Refactor with OR
1260
- if (array_key_exists('brand', $product) && !empty($product['brand'])) {
1261
- $countIdentifier++;
1262
- }
1263
- if (array_key_exists('upc', $product) && !empty($product['upc'])) {
1264
- $countIdentifier++;
1265
- }
1266
- if (array_key_exists('sku', $product) && !empty($product['sku'])) {
1267
- $countIdentifier++;
1268
- }
1269
- if (array_key_exists('mpn', $product) && !empty($product['mpn'])) {
1270
- $countIdentifier++;
1271
- }
1272
- if (array_key_exists('gtin', $product) && !empty($product['gtin'])) {
1273
- $countIdentifier++;
1274
- }
1275
- }
1276
-
1277
- if ('xml' == $this->config['feedType']) {
1278
- if ($countIdentifier >= 2) {
1279
- $this->feedBody .= '<g:identifier_exists>yes</g:identifier_exists>';
1280
- } else {
1281
- $this->feedBody .= '<g:identifier_exists>no</g:identifier_exists>';
1282
- }
1283
- } else {
1284
- $identifier_exists = 'identifier exists';
1285
- if (in_array($this->config['provider'], array('bing', 'pinterest'))) {
1286
- $identifier_exists = 'identifier_exists';
1287
- }
1288
-
1289
- if ($countIdentifier >= 2) {
1290
- $this->products[$this->pi][$identifier_exists] = 'yes';
1291
- } else {
1292
- $this->products[$this->pi][$identifier_exists] = 'no';
1293
- }
1294
- }
1295
- }
1296
- }
1297
- }
1298
 
1299
- private function process_for_merchant_get_value($productObj, $key)
1300
- {
1301
- $prefix = $this->config['prefix'][$key];
1302
- $suffix = $this->config['suffix'][$key];
1303
- $attribute = $this->config['attributes'][$key];
1304
- $merchant_attribute = $this->config['mattributes'][$key];
1305
-
1306
- if ('pattern' == $this->config['type'][$key]) {// Get Pattern value.
1307
- $output = $this->config['default'][$key];
1308
- $output = $this->apply_filters_to_attribute_value($output, $productObj, $attribute, $merchant_attribute);
1309
- } else {
1310
- $output = $this->getAttributeValueByType($productObj, $attribute, $merchant_attribute);
1311
- }
1312
 
1313
- $output = $this->format_output($output, $this->config['output_type'], $productObj, $attribute, $merchant_attribute);
 
 
 
 
 
 
 
 
 
 
1314
 
1315
- $output = $this->process_prefix_suffix($output, $prefix, $suffix, $attribute = '');
1316
 
1317
- return $output;
1318
- }
 
1319
 
1320
- /**
1321
- * Get Query Type Settings
1322
- * @return string
1323
- */
1324
- public function get_query_type()
1325
- {
1326
- return $this->queryType;
1327
- }
 
1328
 
1329
- public function get_product_types()
1330
- {
1331
- return $this->product_types;
1332
- }
1333
 
1334
- /**
1335
- * Generate TXT Feed Header
1336
- *
1337
- * @return string
1338
- * @since 3.2.0
1339
- *
1340
- */
1341
- protected function process_txt_feed_header()
1342
- {
1343
- // Set Delimiter
1344
- if ('tab' == $this->config['delimiter']) {
1345
- $this->delimiter = "\t";
1346
- } else {
1347
- $this->delimiter = $this->config['delimiter'];
1348
- }
1349
 
1350
- // Set Enclosure
1351
- if (!empty($this->config['enclosure'])) {
1352
- $this->enclosure = $this->config['enclosure'];
1353
- if ('double' == $this->enclosure) {
1354
- $this->enclosure = '"';
1355
- } elseif ('single' == $this->enclosure) {
1356
- $this->enclosure = "'";
1357
- } else {
1358
- $this->enclosure = '';
1359
- }
1360
- } else {
1361
- $this->enclosure = '';
1362
- }
1363
 
1364
- $eol = PHP_EOL;
1365
- if ('trovaprezzi' === $this->config['provider']) {
1366
- $eol = '<endrecord>' . PHP_EOL;
1367
- }
1368
 
1369
- $product = $this->products[$this->pi];
1370
 
1371
- $headers = array_keys($product);
 
1372
 
1373
- $this->feedHeader .= $this->enclosure . implode("$this->enclosure$this->delimiter$this->enclosure", $headers) . $this->enclosure . $eol;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1374
 
1375
- if ('google' === $this->config['provider']) {
1376
- $this->feedHeader = str_replace($this->google_product_highlights, 'product highlight', $this->feedHeader);
1377
- $this->feedHeader = str_replace($this->google_additional_image, 'additional image link', $this->feedHeader);
1378
- }
1379
 
1380
- return $this->feedHeader;
1381
- }
 
1382
 
1383
- /**
1384
- * Generate TXT Feed Body
1385
- *
1386
- * @return string
1387
- * @since 3.2.0
1388
- *
1389
- */
1390
- protected function process_txt_feed_body()
1391
- {
1392
- $productInfo = array_values($this->products[$this->pi]);
1393
- $eol = PHP_EOL;
1394
- if ('trovaprezzi' === $this->config['provider']) {
1395
- $eol = '<endrecord>' . PHP_EOL;
1396
- }
1397
- $this->feedBody .= $this->enclosure . implode("$this->enclosure$this->delimiter$this->enclosure", $productInfo) . $this->enclosure . $eol;
1398
 
1399
- return $this->feedBody;
1400
- }
1401
 
1402
- /**
1403
- * Generate CSV Feed Header
1404
- *
1405
- * @return array
1406
- * @since 3.2.0
1407
- *
1408
- */
1409
- protected function process_csv_feed_header()
1410
- {
1411
- // Set Delimiter
1412
- if ('tab' == $this->config['delimiter']) {
1413
- $this->delimiter = "\t";
1414
- } else {
1415
- $this->delimiter = $this->config['delimiter'];
1416
- }
1417
 
1418
- // Set Enclosure
1419
- if (!empty($this->config['enclosure'])) {
1420
- $this->enclosure = $this->config['enclosure'];
1421
- if ('double' == $this->enclosure) {
1422
- $this->enclosure = '"';
1423
- } elseif ('single' == $this->enclosure) {
1424
- $this->enclosure = "'";
1425
- } else {
1426
- $this->enclosure = '';
1427
- }
1428
- } else {
1429
- $this->enclosure = '';
1430
- }
1431
 
1432
- $product = $this->products[$this->pi];
 
 
 
 
 
 
 
 
1433
 
1434
- $this->feedHeader = array_keys($product);
 
1435
 
1436
- if ('google' === $this->config['provider']) {
1437
- $this->feedHeader = str_replace($this->google_product_highlights, 'product highlight', $this->feedHeader);
1438
- $this->feedHeader = str_replace($this->google_additional_image, 'additional image link', $this->feedHeader);
1439
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1440
 
1441
- return $this->feedHeader;
1442
- }
1443
 
1444
- /**
1445
- * Generate CSV Feed Body
1446
- * @return array
1447
- * @since 3.2.0
1448
- */
1449
- protected function process_csv_feed_body()
1450
- {
1451
- $product = $this->products[$this->pi];
1452
- $this->feedBody[] = array_values($product);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1453
 
1454
- return $this->feedBody;
1455
- }
1456
 
1457
- protected function process_json_feed_body()
1458
- {
1459
- $product = $this->products[$this->pi];
1460
- $this->feedBody[] = $product;
1461
 
1462
- return $this->feedBody;
1463
- }
 
 
 
 
 
 
 
 
 
1464
 
1465
- protected function process_xml_wrapper()
1466
- {
1467
- $itemsWrapperClose = explode(' ', $this->config['itemsWrapper']);
1468
- $itemsWrapperClose = $itemsWrapperClose[0];
1469
- $this->xml_wrapper = [
1470
- 'header' => '<?xml version="1.0" encoding="UTF-8" ?>' . PHP_EOL . '<' . wp_unslash($this->config['itemsWrapper']) . '>',
1471
- 'footer' => PHP_EOL . '</' . $itemsWrapperClose . '>',
1472
- ];
1473
- $this->config['itemWrapper'] = str_replace(' ', '_', $this->config['itemWrapper']);
1474
- $this->config['itemsWrapper'] = str_replace(' ', '_', $this->config['itemsWrapper']);
1475
-
1476
- if (file_exists(WOO_FEED_FREE_ADMIN_PATH . 'partials/templates/' . $this->config['provider'] . '.txt')) {
1477
- $txt = file_get_contents(WOO_FEED_FREE_ADMIN_PATH . 'partials/templates/' . $this->config['provider'] . '.txt');
1478
- $txt = trim($txt);
1479
- $txt = explode('{separator}', $txt);
1480
- if (2 === count($txt)) {
1481
- $this->xml_wrapper['header'] = trim($txt[0]);
1482
- $this->xml_wrapper['footer'] = "\n" . trim($txt[1]);
1483
- }
1484
- }
1485
 
1486
- if (!empty($this->config['extraHeader'])) {
1487
- $this->xml_wrapper['header'] .= PHP_EOL . $this->config['extraHeader'];
1488
- }
1489
 
1490
- // replace template variables.
1491
- $datetime_now = date('Y-m-d H:i:s', strtotime(current_time('mysql'))); // {DateTimeNow}
1492
- if ('pinterest_rss' === $this->config['provider']) { // DATE_RFC822 date format for pinterest rss feed
1493
- $datetime_now = date('r', strtotime(current_time('mysql'))); // {DateTimeNow}
1494
- }
1495
- $blog_name = get_bloginfo('name'); // {BlogName}
1496
- $blog_url = get_bloginfo('url'); // {BlogURL}
1497
- //$blog_desc = get_bloginfo('description'); // {BlogDescription}
1498
- $blog_desc = "CTX Feed - This product feed is generated with the CTX Feed - WooCommerce Product Feed Manager plugin by WebAppick.com. For all your support questions check out our plugin Docs on https://webappick.com/docs or e-mail to: support@webappick.com"; // {BlogDescription}
1499
- $blog_email = get_bloginfo('admin_email'); // {BlogEmail}
1500
-
1501
- $this->xml_wrapper['header'] = str_replace(
1502
- ['{DateTimeNow}', '{BlogName}', '{BlogURL}', '{BlogDescription}', '{BlogEmail}'],
1503
- [$datetime_now, $blog_name, $blog_url, $blog_desc, $blog_email],
1504
- $this->xml_wrapper['header']
1505
- );
1506
- }
1507
 
1508
- /**
1509
- * Make XML feed header
1510
- * @return string
1511
- * @since 3.2.0
1512
- */
1513
- protected function process_xml_feed_header()
1514
- {
1515
- return $this->xml_wrapper['header'];
1516
- }
1517
 
1518
- /**
1519
- * Make XML feed header
1520
- * @return string
1521
- * @since 3.2.0
1522
- */
1523
- protected function process_xml_feed_footer()
1524
- {
1525
- return $this->xml_wrapper['footer'];
1526
- }
1527
 
1528
- /**
1529
- * Process string for TXT CSV Feed
1530
- *
1531
- * @param $string
1532
- *
1533
- * @return mixed|string
1534
- * @since 3.2.0
1535
- *
1536
- */
1537
- protected function processStringForTXT($string)
1538
- {
1539
- if (!empty($string)) {
1540
- $string = html_entity_decode($string, ENT_HTML401 | ENT_QUOTES); // Convert any HTML entities
1541
-
1542
- if (stristr($string, '"')) {
1543
- $string = str_replace('"', '""', $string);
1544
- }
1545
- $string = str_replace("\n", ' ', $string);
1546
- $string = str_replace("\r", ' ', $string);
1547
- $string = str_replace("\t", ' ', $string);
1548
- $string = trim($string);
1549
- $string = stripslashes($string);
1550
-
1551
- return $string;
1552
- } elseif ('0' == $string) {
1553
- return '0';
1554
- } else {
1555
- return '';
1556
- }
1557
- }
1558
 
1559
- /**
1560
- * Process string for CSV
1561
- *
1562
- * @param $string
1563
- *
1564
- * @return mixed|string
1565
- * @since 3.2.0
1566
- *
1567
- */
1568
- protected function processStringForCSV($string)
1569
- {
1570
- if (!empty($string)) {
1571
- $string = str_replace("\n", ' ', $string);
1572
- $string = str_replace("\r", ' ', $string);
1573
- $string = trim($string);
1574
- $string = stripslashes($string);
1575
-
1576
- return $string;
1577
- } elseif ('0' == $string) {
1578
- return '0';
1579
- } else {
1580
- return '';
1581
- }
1582
- }
1583
 
1584
- /**
1585
- * Get Product Attribute Value by Type
1586
- *
1587
- * @param $product WC_Product
1588
- * @param $attribute
1589
- *
1590
- * @return mixed|string
1591
- * @since 3.2.0
1592
- *
1593
- */
1594
- public function getAttributeValueByType($product, $attribute, $merchant_attribute = '')
1595
- {
1596
 
1597
- if (method_exists($this, $attribute)) {
1598
- $output = $this->$attribute($product);
1599
- } elseif ( false !== strpos( $attribute, self::PRODUCT_ACF_FIELDS ) ) {
1600
- $output = $this->getACFField( $product, $attribute );
1601
- } elseif (false !== strpos($attribute, self::PRODUCT_CUSTOM_IDENTIFIER) || woo_feed_strpos_array(array('_identifier_gtin', '_identifier_ean', '_identifier_mpn'), $attribute)) {
1602
- $output = $this->getCustomField($product, $attribute);
1603
- } elseif (false !== strpos($attribute, self::PRODUCT_ATTRIBUTE_PREFIX)) {
1604
- $attribute = str_replace(self::PRODUCT_ATTRIBUTE_PREFIX, '', $attribute);
1605
- $output = $this->getProductAttribute($product, $attribute);
1606
- } elseif (false !== strpos($attribute, self::POST_META_PREFIX)) {
1607
- $attribute = str_replace(self::POST_META_PREFIX, '', $attribute);
1608
- $output = $this->getProductMeta($product, $attribute);
1609
- } elseif (false !== strpos($attribute, self::PRODUCT_TAXONOMY_PREFIX)) {
1610
- $attribute = str_replace(self::PRODUCT_TAXONOMY_PREFIX, '', $attribute);
1611
- $output = $this->getProductTaxonomy($product, $attribute);
1612
- } elseif (false !== strpos($attribute, self::PRODUCT_CATEGORY_MAPPING_PREFIX)) {
1613
- $id = $product->is_type('variation') ? $product->get_parent_id() : $product->get_id();
1614
- $output = woo_feed_get_category_mapping_value($attribute, $id);
1615
- } elseif (false !== strpos($attribute, self::WP_OPTION_PREFIX)) {
1616
- $optionName = str_replace(self::WP_OPTION_PREFIX, '', $attribute);
1617
- $output = get_option($optionName);
1618
- } elseif ('image_' == substr($attribute, 0, 6)) {
1619
- // For additional image method images() will be used with extra parameter - image number
1620
- $imageKey = explode('_', $attribute);
1621
- if (!isset($imageKey[1]) || (isset($imageKey[1]) && (empty($imageKey[1]) || !is_numeric($imageKey[1])))) {
1622
- $imageKey[1] = '';
1623
- }
1624
- $output = call_user_func_array(array($this, 'images'), array($product, $imageKey[1]));
1625
- } else {
1626
- // return the attribute so multiple attribute can be join with separator to make custom attribute.
1627
- $output = $attribute;
1628
- }
1629
 
1630
- // Json encode if value is an array
1631
- if (is_array($output)) {
1632
- $output = wp_json_encode($output);
1633
- }
1634
 
1635
- $output = $this->apply_filters_to_attribute_value($output, $product, $attribute, $merchant_attribute);
 
1636
 
1637
- return $output;
1638
- }
 
 
 
 
 
 
 
 
 
1639
 
1640
- /**
1641
- * Apply Filter to Attribute value
1642
- *
1643
- * @param $output
1644
- * @param $product
1645
- * @param $attribute
1646
- * @param $merchant_attribute
1647
- *
1648
- * @return mixed|void
1649
- */
1650
- protected function apply_filters_to_attribute_value($output, $product, $attribute, $merchant_attribute)
1651
- {
1652
- /**
1653
- * Filter attribute value
1654
- *
1655
- * @param string $output the output
1656
- * @param WC_Abstract_Legacy_Product $product Product Object.
1657
- * @param array feed config/rule
1658
- *
1659
- * @since 3.4.3
1660
- *
1661
- */
1662
- $output = apply_filters('woo_feed_get_attribute', $output, $product, $this->config, $merchant_attribute);
1663
-
1664
- /**
1665
- * Filter attribute value before return based on attribute name
1666
- *
1667
- * @param string $output the output
1668
- * @param WC_Abstract_Legacy_Product $product Product Object.
1669
- * @param array feed config/rule
1670
- *
1671
- * @since 3.3.5
1672
- *
1673
- */
1674
- $output = apply_filters("woo_feed_get_{$attribute}_attribute", $output, $product, $this->config);
1675
-
1676
- /**
1677
- * Filter attribute value before return based on merchant and attribute name
1678
- *
1679
- * @param string $output the output
1680
- * @param WC_Abstract_Legacy_Product $product Product Object.
1681
- * @param array feed config/rule
1682
- *
1683
- * @since 3.3.7
1684
- *
1685
- */
1686
- $output = apply_filters("woo_feed_get_{$this->config['provider']}_{$attribute}_attribute", $output, $product, $this->config);
1687
-
1688
- return $output;
1689
- }
1690
 
 
 
1691
 
1692
- /**
1693
- * Get Product Id
1694
- *
1695
- * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product Product Object.
1696
- *
1697
- * @return mixed
1698
- * @since 3.2.0
1699
- */
1700
- protected function id($product)
1701
- {
1702
- $id = $product->get_id();
1703
-
1704
- return apply_filters('woo_feed_filter_product_id', $id, $product, $this->config);
1705
- }
1706
-
1707
- /**
1708
- * Get Product Title
1709
- *
1710
- * @param WC_Product $product
1711
- *
1712
- * @return mixed
1713
- * @since 3.2.0
1714
- *
1715
- */
1716
- protected function title($product)
1717
- {
1718
- $title = woo_feed_strip_all_tags($this->remove_short_codes($product->get_name()));
1719
-
1720
- // Add all available variation attributes to variation title.
1721
- if ($product->is_type('variation') && !empty($product->get_attributes())) {
1722
- $title = $this->parent_title($product);
1723
- $attributes = [];
1724
- foreach ($product->get_attributes() as $slug => $value) {
1725
- $attribute = $product->get_attribute($slug);
1726
- if (empty($attribute)) {
1727
- continue;
1728
- }
1729
- $attributes[$slug] = $attribute;
1730
- }
1731
-
1732
- // set variation attributes with separator
1733
- if (isset($this->config['provider']) && 'google' === $this->config['provider']) {
1734
- $variation_attributes = implode(' - ', $attributes);
1735
- } else {
1736
- $variation_attributes = implode(', ', $attributes);
1737
- }
1738
-
1739
- //get product title with variation attribute
1740
- $get_with_var_attributes = apply_filters("woo_feed_get_product_title_with_variation_attribute", true, $product, $this->config);
1741
-
1742
- if ($get_with_var_attributes) {
1743
- $title .= " - " . $variation_attributes;
1744
- }
1745
- }
1746
-
1747
- return apply_filters('woo_feed_filter_product_title', $title, $product, $this->config);
1748
- }
1749
-
1750
- /**
1751
- * Get Parent Product Title
1752
- *
1753
- * @param WC_Product $product Product Object.
1754
- *
1755
- * @return mixed
1756
- * @author Nazrul Islam Nayan
1757
- * @since 5.1.8
1758
- */
1759
- protected function parent_title($product)
1760
- {
1761
- if ($product->is_type('variation')) {
1762
- $product = wc_get_product($product->get_parent_id());
1763
- $title = woo_feed_strip_all_tags($this->remove_short_codes($product->get_name()));
1764
- } else {
1765
- $title = $this->title($product);
1766
- }
1767
-
1768
- return apply_filters('woo_feed_filter_product_parent_title', $title, $product, $this->config);
1769
- }
1770
-
1771
- /**
1772
- * Get All in One SEO Canonical URL
1773
- *
1774
- * @param WC_Product $product
1775
- *
1776
- * @return mixed
1777
- * @since 4.4.12
1778
- */
1779
- protected function _aioseop_canonical_url($product)
1780
- {
1781
- $aioseop_canonical_url = '';
1782
- if (is_plugin_active('all-in-one-seo-pack/all_in_one_seo_pack.php') && class_exists('AIOSEO\Plugin\Common\Models\Post')) {
1783
- $post = AIOSEO\Plugin\Common\Models\Post::getPost($product->get_id());
1784
- $aioseop_canonical_url = $post->canonical_url;
1785
- }
1786
-
1787
- return apply_filters('woo_feed_filter_product_aioseop_canonical_url', $aioseop_canonical_url, $product, $this->config);
1788
- }
1789
-
1790
- /**
1791
- * Get Yoast Product Title
1792
- *
1793
- * @param WC_Product $product
1794
- *
1795
- * @return mixed
1796
- * @since 3.2.0
1797
- *
1798
- */
1799
- protected function yoast_wpseo_title($product)
1800
- {
1801
- $product_id = woo_feed_parent_product_id($product);
1802
- $yoast_title = get_post_meta($product_id, '_yoast_wpseo_title', true);
1803
- if (strpos($yoast_title, '%%') !== false) {
1804
- $title = strstr($yoast_title, '%%', true);
1805
- if (empty($title)) {
1806
- $title = get_the_title($product_id);
1807
- }
1808
- $wpseo_titles = get_option('wpseo_titles');
1809
-
1810
- $sep_options = WPSEO_Option_Titles::get_instance()->get_separator_options();
1811
- if (isset($wpseo_titles['separator']) && isset($sep_options[$wpseo_titles['separator']])) {
1812
- $sep = $sep_options[$wpseo_titles['separator']];
1813
- } else {
1814
- $sep = '-'; //setting default separator if Admin didn't set it from backed
1815
- }
1816
-
1817
- $site_title = get_bloginfo('name');
1818
-
1819
- $meta_title = $title . ' ' . $sep . ' ' . $site_title;
1820
-
1821
- if (!empty($meta_title)) {
1822
- $title = $meta_title;
1823
- }
1824
- } elseif (!empty($yoast_title)) {
1825
- $title = $yoast_title;
1826
- } else {
1827
- $title = $this->title($product);
1828
- }
1829
-
1830
- return apply_filters('woo_feed_filter_product_yoast_wpseo_title', $title, $product, $this->config);
1831
- }
1832
-
1833
- /**
1834
- * Get Yoast Canonical URL
1835
- *
1836
- * @param WC_Product $product
1837
- *
1838
- * @return mixed
1839
- * @since 4.3.77
1840
- */
1841
- protected function yoast_canonical_url($product)
1842
- {
1843
- $product_id = woo_feed_parent_product_id($product);
1844
- $yoast_canonical_url = get_post_meta($product_id, '_yoast_wpseo_canonical', true);
1845
-
1846
- return apply_filters('woo_feed_filter_product_yoast_canonical_url', $yoast_canonical_url, $product, $this->config);
1847
- }
1848
-
1849
- /**
1850
- * Get Rank Math Product Title
1851
- *
1852
- * @param WC_Product $product
1853
- *
1854
- * @return mixed
1855
- * @since 5.1.3
1856
- */
1857
- protected function rank_math_title($product)
1858
- {
1859
- $rank_title = '';
1860
- $post_title = '';
1861
- $page = '';
1862
- $sep = '';
1863
- $sitemap = '';
1864
- if (class_exists('RankMath')) {
1865
- $title = get_post_meta($product->get_id(), 'rank_math_title', true);
1866
- if (empty($title)) {
1867
- $title_format = Helper::get_settings("titles.pt_product_title");
1868
- $title_format = $title_format ? $title_format : '%title%';
1869
- $sep = Helper::get_settings('titles.title_separator');
1870
-
1871
- $rank_title = str_replace('%title%', $product->get_title(), $title_format);
1872
- $rank_title = str_replace('%sep%', $sep, $rank_title);
1873
- $rank_title = str_replace('%page%', '', $rank_title);
1874
- $rank_title = str_replace('%sitename%', get_bloginfo('name'), $rank_title);
1875
- } else {
1876
- $rank_title = $title;
1877
- }
1878
- }
1879
-
1880
- return apply_filters('woo_feed_filter_product_rank_math_title', $rank_title, $product, $this->config);
1881
- }
1882
-
1883
- /**
1884
- * Get Rank Math Product Description
1885
- *
1886
- * @param WC_Product $product
1887
- *
1888
- * @return mixed
1889
- * @since 5.1.3
1890
- */
1891
- protected function rank_math_description($product)
1892
- {
1893
- $description = '';
1894
- if (class_exists('RankMath')) {
1895
- $description = get_post_meta($product->get_id(), 'rank_math_description');
1896
- $desc_format = Helper::get_settings("titles.pt_post_description");
1897
-
1898
- if (empty($description)) {
1899
- if (!empty($desc_format) && strpos((string)$desc_format, 'excerpt') !== false) {
1900
- $description = str_replace('%excerpt%', get_the_excerpt($product->get_id()), $desc_format);
1901
- }
1902
-
1903
- // Get Variation Description
1904
- if ($product->is_type('variation') && empty($description)) {
1905
- $parent = wc_get_product($product->get_parent_id());
1906
- $description = $parent->get_description();
1907
- }
1908
- }
1909
-
1910
- if (is_array($description)) {
1911
- $description = reset($description);
1912
- }
1913
-
1914
- $description = $this->remove_short_codes($description);
1915
-
1916
- //strip tags and spacial characters
1917
- $strip_description = woo_feed_strip_all_tags(wp_specialchars_decode($description));
1918
-
1919
- $description = !empty(strlen($strip_description)) && 0 < strlen($strip_description) ? $strip_description : $description;
1920
- }
1921
-
1922
- return apply_filters('woo_feed_filter_product_rank_math_description', $description, $product, $this->config);
1923
- }
1924
-
1925
- /**
1926
- * Get Rank Math Canonical URL
1927
- *
1928
- * @param WC_Product $product
1929
- *
1930
- * @return mixed
1931
- * @since 5.1.6
1932
- */
1933
- protected function rank_math_canonical_url($product)
1934
- {
1935
- $canonical_url = '';
1936
-
1937
- if (class_exists('RankMath')) {
1938
- $post_canonical_url = get_post_meta($product->get_id(), 'rank_math_canonical_url');
1939
-
1940
- if (empty($post_canonical_url)) {
1941
- $canonical_url = get_the_permalink($product->get_id());
1942
- } else {
1943
- $canonical_url = $post_canonical_url;
1944
- }
1945
-
1946
- if (is_array($canonical_url)) {
1947
- $canonical_url = reset($canonical_url);
1948
- }
1949
- }
1950
-
1951
- return apply_filters('woo_feed_filter_product_rank_math_canonical_url', $canonical_url, $product, $this->config);
1952
- }
1953
-
1954
-
1955
- /**
1956
- * Get All In One Product Title
1957
- *
1958
- * @param WC_Product $product
1959
- *
1960
- * @return mixed
1961
- * @since 3.2.0
1962
- *
1963
- */
1964
- protected function _aioseop_title($product)
1965
- {
1966
- $title = '';
1967
- if (is_plugin_active('all-in-one-seo-pack/all_in_one_seo_pack.php') && class_exists('AIOSEO\Plugin\Common\Models\Post')) {
1968
-
1969
- $post = AIOSEO\Plugin\Common\Models\Post::getPost($product->get_id());
1970
- $title = !empty($post->title) ? $post->title : aioseo()->meta->title->getPostTypeTitle('product');
1971
- }
1972
-
1973
- $title = !empty($title) ? $title : $this->title($product);
1974
-
1975
- return apply_filters('woo_feed_filter_product_aioseop_title', $title, $product, $this->config);
1976
- }
1977
-
1978
- /**
1979
- * Get Product Description
1980
- *
1981
- * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product Product Object.
1982
- *
1983
- * @return mixed|string
1984
- * @since 3.2.0
1985
- *
1986
- */
1987
- protected function description($product)
1988
- {
1989
- $description = $product->get_description();
1990
-
1991
- // Get Variation Description
1992
- if ($product->is_type('variation') && empty($description)) {
1993
- $parent = wc_get_product($product->get_parent_id());
1994
-
1995
- if (is_object($parent)) {
1996
- $description = $parent->get_description();
1997
- } else {
1998
- $description = '';
1999
- }
2000
- }
2001
- $description = $this->remove_short_codes($description);
2002
-
2003
- // Add variations attributes after description to prevent Facebook error
2004
- if ('facebook' == $this->config['provider'] && $product->is_type('variation')) {
2005
- $variationInfo = explode('-', $product->get_name());
2006
- if (isset($variationInfo[1])) {
2007
- $extension = $variationInfo[1];
2008
- } else {
2009
- $extension = $product->get_id();
2010
- }
2011
- $description .= ' ' . $extension;
2012
- }
2013
-
2014
- //strip tags and spacial characters
2015
- $strip_description = woo_feed_strip_all_tags(wp_specialchars_decode($description));
2016
-
2017
- $description = !empty(strlen($strip_description)) && 0 < strlen($strip_description) ? $strip_description : $description;
2018
-
2019
- return apply_filters('woo_feed_filter_product_description', $description, $product, $this->config);
2020
- }
2021
-
2022
- /**
2023
- * Get Product Description (with HTML)
2024
- *
2025
- * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product Product Object.
2026
- *
2027
- * @return mixed|string
2028
- * @since 5.2.41
2029
- */
2030
- protected function description_with_html($product)
2031
- {
2032
- $description = $product->get_description();
2033
-
2034
- // Get Variation Description
2035
- if ($product->is_type('variation') && empty($description)) {
2036
- $parent = wc_get_product($product->get_parent_id());
2037
- $description = $parent->get_description();
2038
- }
2039
- $description = $this->remove_short_codes($description);
2040
-
2041
- // Add variations attributes after description to prevent Facebook error
2042
- if ('facebook' === $this->config['provider'] && $product->is_type('variation')) {
2043
- $variationInfo = explode('-', $product->get_name());
2044
- if (isset($variationInfo[1])) {
2045
- $extension = $variationInfo[1];
2046
- } else {
2047
- $extension = $product->get_id();
2048
- }
2049
- $description .= ' ' . $extension;
2050
- }
2051
-
2052
- //remove spacial characters
2053
- $strip_description = wp_check_invalid_utf8(wp_specialchars_decode($description), true);
2054
-
2055
- return apply_filters('woo_feed_filter_product_description_with_html', $description, $product, $this->config);
2056
- }
2057
-
2058
- /**
2059
- * Get Yoast Product Description
2060
- *
2061
- * @param WC_Product $product
2062
- *
2063
- * @return mixed
2064
- * @since 3.2.0
2065
- *
2066
- */
2067
- protected function yoast_wpseo_metadesc($product)
2068
- {
2069
- $product_id = woo_feed_parent_product_id($product);
2070
- $description = '';
2071
- if (class_exists('WPSEO_Frontend')) {
2072
- $description = wpseo_replace_vars(WPSEO_Meta::get_value('metadesc', $product_id),
2073
- get_post($product->get_id()));
2074
- } else {
2075
- $description = YoastSEO()->meta->for_post($product_id)->description;
2076
- }
2077
-
2078
- if (empty($description)) {
2079
- $description = $this->description($product);
2080
- }
2081
-
2082
- return apply_filters('woo_feed_filter_product_yoast_wpseo_metadesc', $description, $product, $this->config);
2083
- }
2084
-
2085
- /**
2086
- * Get All In One Product Description
2087
- *
2088
- * @param WC_Product $product
2089
- *
2090
- * @return mixed
2091
- * @since 3.2.0
2092
- *
2093
- */
2094
- protected function _aioseop_description($product)
2095
- {
2096
- $description = '';
2097
-
2098
- if (is_plugin_active('all-in-one-seo-pack/all_in_one_seo_pack.php') && class_exists('AIOSEO\Plugin\Common\Models\Post')) {
2099
-
2100
- $post = AIOSEO\Plugin\Common\Models\Post::getPost($product->get_id());
2101
- $description = !empty($post->description) ? $post->description : aioseo()->meta->description->getPostTypeDescription('product');
2102
- }
2103
-
2104
- if (empty($description)) {
2105
- $description = $this->description($product);
2106
- }
2107
-
2108
- return apply_filters('woo_feed_filter_product_aioseop_description', $description, $product, $this->config);
2109
- }
2110
-
2111
- /**
2112
- * Get Product Short Description
2113
- *
2114
- * @param WC_Product $product
2115
- *
2116
- * @return mixed|string
2117
- * @since 3.2.0
2118
- *
2119
- */
2120
- protected function short_description($product)
2121
- {
2122
- $short_description = $product->get_short_description();
2123
-
2124
- // Get Variation Short Description
2125
- if ($product->is_type('variation') && empty($short_description)) {
2126
- $parent = wc_get_product($product->get_parent_id());
2127
- $short_description = $parent->get_short_description();
2128
- }
2129
-
2130
-
2131
- $short_description = $this->remove_short_codes($short_description);
2132
-
2133
- //strip tags and spacial characters
2134
- $short_description = woo_feed_strip_all_tags(wp_specialchars_decode($short_description));
2135
-
2136
- return apply_filters('woo_feed_filter_product_short_description', $short_description, $product, $this->config);
2137
- }
2138
-
2139
-
2140
- /**
2141
- * At First convert Short Codes and then Remove failed Short Codes from String
2142
- *
2143
- * @param $content
2144
- *
2145
- * @return mixed|string
2146
- * @since 3.2.0
2147
- *
2148
- */
2149
- protected function remove_short_codes($content)
2150
- {
2151
- if ($content == '') {
2152
- return '';
2153
- }
2154
 
2155
- $content = do_shortcode($content);
 
2156
 
2157
- $content = woo_feed_stripInvalidXml($content);
 
 
 
 
 
 
 
 
 
 
 
2158
 
2159
- // Covers all kinds of shortcodes
2160
- $expression = '/\[\/*[a-zA-Z1-90_| -=\'"\{\}]*\/*\]/m';
2161
 
2162
- $content = preg_replace($expression, '', $content);
 
 
 
 
 
 
 
 
 
 
 
2163
 
2164
- return strip_shortcodes($content);
2165
- }
2166
 
2167
- /*
2168
- * Retrieves product's parent category
2169
  *
2170
- * @param $product A Post/Product object
2171
  *
2172
- * @return WP_Term
2173
- * @since 4.4.19
2174
- * */
2175
- protected function product_parent_category_object($product)
2176
- {
2177
- global $parent_category_memo;
2178
- if (empty($parent_category_memo)) {
2179
- $parent_category_memo = [];
2180
- }
2181
-
2182
- $id = $product->get_id();
2183
- if ($product->is_type('variation')) {
2184
- $id = $product->get_parent_id();
2185
- }
2186
 
2187
- $taxonomy = 'product_cat';
2188
- $categories = wp_get_post_terms($id, $taxonomy);
2189
- $child_category = $categories[count($categories) - 1]; // Last selected category
2190
-
2191
- $parent_category = '';
2192
-
2193
- // Memoization for faster parent retrieval
2194
- if (
2195
- isset($parent_category_memo[$child_category->term_id])
2196
- && !empty($parent_category_memo[$child_category->term_id])
2197
- ) {
2198
- $parent_category = get_term_by('term_id', $parent_category_memo[$child_category->term_id], $taxonomy);
2199
- } else {
2200
- $parent_category = woo_feed_parent_category($child_category, $taxonomy);
2201
- $parent_category_memo[$child_category->term_id] = $parent_category->term_id;
2202
- }
2203
 
2204
- // Yoast SEO primary term fetching
2205
- if (class_exists('WPSEO_Primary_Term')) {
2206
- $wpseo_primary_term = new WPSEO_Primary_Term($taxonomy, $id);
2207
- $parent_category_id = $wpseo_primary_term->get_primary_term();
2208
- if (!empty($parent_category_id)) {
2209
- $parent_category = get_term_by('term_id', $parent_category_id, $taxonomy);
2210
- }
2211
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2212
 
2213
- return $parent_category;
2214
- }
2215
 
2216
- /**
2217
- * Get Product Parent/Main Category
2218
- *
2219
- * @param WC_Product $product
2220
- *
2221
- * @return string
2222
- *
2223
- */
2224
- protected function primary_category($product)
2225
- {
2226
- $parent_category = "";
2227
- $separator = apply_filters('woo_feed_product_type_separator', ' > ', $this->config, $product);
2228
- $full_category = $this->product_type($product);
2229
- if (!empty($full_category)) {
2230
- $full_category_array = explode($separator, $full_category);
2231
- $parent_category = $full_category_array[0];
2232
- }
2233
 
2234
- return apply_filters('woo_feed_filter_product_primary_category', $parent_category, $product, $this->config);
2235
- }
 
2236
 
2237
- /**
2238
- * Get Product Parent/Main Category ID
2239
- *
2240
- * @param WC_Product $product
2241
- *
2242
- * @return string
2243
- *
2244
- */
2245
- protected function primary_category_id($product)
2246
- {
2247
- $parent_category_id = "";
2248
- $separator = apply_filters('woo_feed_product_type_separator', ' > ', $this->config, $product);
2249
- $full_category = $this->product_type($product);
2250
- if (!empty($full_category)) {
2251
- $full_category_array = explode($separator, $full_category);
2252
- $parent_category_obj = get_term_by('name', $full_category_array[0], 'product_cat');
2253
- $parent_category_id = isset($parent_category_obj->term_id) ? $parent_category_obj->term_id : "";
2254
- }
2255
 
2256
- return apply_filters('woo_feed_filter_product_primary_category_id', $parent_category_id, $product, $this->config);
2257
- }
2258
 
2259
- /**
2260
- * Get Product Child Category
2261
- *
2262
- * @param WC_Product $product
2263
- *
2264
- * @return string
2265
- */
2266
- protected function child_category($product)
2267
- {
2268
- $child_category = "";
2269
- $separator = apply_filters('woo_feed_product_type_separator', ' > ', $this->config, $product);
2270
- $full_category = $this->product_type($product);
2271
- if (!empty($full_category)) {
2272
- $full_category_array = explode($separator, $full_category);
2273
- $child_category = end($full_category_array);
2274
- }
2275
-
2276
- return apply_filters('woo_feed_filter_product_child_category', $child_category, $product, $this->config);
2277
- }
2278
-
2279
- /**
2280
- * Get Product Child Category ID
2281
- *
2282
- * @param WC_Product $product
2283
- *
2284
- * @return string
2285
- */
2286
- protected function child_category_id($product)
2287
- {
2288
- $child_category_id = "";
2289
- $separator = apply_filters('woo_feed_product_type_separator', ' > ', $this->config, $product);
2290
- $full_category = $this->product_type($product);
2291
- if (!empty($full_category)) {
2292
- $full_category_array = explode($separator, $full_category);
2293
- $child_category_obj = get_term_by('name', end($full_category_array), 'product_cat');
2294
- $child_category_id = isset($child_category_obj->term_id) ? $child_category_obj->term_id : "";
2295
- }
2296
-
2297
- return apply_filters('woo_feed_filter_product_child_category_id', $child_category_id, $product, $this->config);
2298
- }
2299
-
2300
- /**
2301
- * Get Product Categories
2302
- *
2303
- * @param WC_Product $product
2304
- *
2305
- * @return string
2306
- * @since 3.2.0
2307
- *
2308
- */
2309
- protected function product_type($product)
2310
- {
2311
- $id = $product->get_id();
2312
- if ($product->is_type('variation')) {
2313
- $id = $product->get_parent_id();
2314
- }
2315
-
2316
- $separator = apply_filters('woo_feed_product_type_separator', ' > ', $this->config, $product);
2317
-
2318
- $product_type = woo_feed_strip_all_tags(wc_get_product_category_list($id, $separator));
2319
-
2320
- $product_categories = '';
2321
- $term_list = get_the_terms($id, 'product_cat');
2322
-
2323
- if (is_array($term_list)) {
2324
- $col = array_column($term_list, "term_id");
2325
- array_multisort($col, SORT_ASC, $term_list);
2326
- $term_list = array_column($term_list, "name");
2327
- $product_categories = implode($separator, $term_list);
2328
- }
2329
-
2330
-
2331
- return apply_filters('woo_feed_filter_product_local_category', $product_categories, $product, $this->config);
2332
- }
2333
-
2334
- /**
2335
- * Get Product Full Categories with unselected category parent
2336
- *
2337
- * @param WC_Product $product
2338
- *
2339
- * @return string
2340
- * @since 4.3.47
2341
- */
2342
- protected function product_full_cat($product)
2343
- {
2344
- // $id = $product->get_id();
2345
- // if ($product->is_type('variation')) {
2346
- // $id = $product->get_parent_id();
2347
- // }
2348
- //
2349
- // $separator = apply_filters('woo_feed_product_type_separator', '>', $this->config, $product);
2350
- //
2351
- // $product_type = woo_feed_get_terms_list_hierarchical_order($id);
2352
-
2353
- $product_type = $this->product_type($product);
2354
-
2355
- return apply_filters('woo_feed_filter_product_local_category', $product_type, $product, $this->config);
2356
- }
2357
-
2358
- /**
2359
- * Get Product URL
2360
- *
2361
- * @param WC_Product|WC_Product_Variation $product
2362
- *
2363
- * @return string
2364
- * @since 3.2.0
2365
- *
2366
- */
2367
- protected function link($product)
2368
- {
2369
-
2370
- $link = $product->get_permalink();
2371
-
2372
- $link = $this->add_utm_tracker($link);
2373
- return apply_filters('woo_feed_filter_product_link', $link, $product, $this->config);
2374
- }
2375
-
2376
- /**
2377
- * Adding UTM Tracker Query Arguments to URL
2378
- * @param string $url
2379
- *
2380
- * @return string $url
2381
- * @since 4.4.26
2382
- */
2383
- protected function add_utm_tracker($url)
2384
- {
2385
-
2386
- $utm = $this->config['campaign_parameters'];
2387
-
2388
- if (!empty($utm['utm_source']) && !empty($utm['utm_medium']) && !empty($utm['utm_campaign'])) {
2389
-
2390
- $utm = [
2391
- 'utm_source' => str_replace(' ', '+', $utm['utm_source']),
2392
- 'utm_medium' => str_replace(' ', '+', $utm['utm_medium']),
2393
- 'utm_campaign' => str_replace(' ', '+', $utm['utm_campaign']),
2394
- 'utm_term' => str_replace(' ', '+', $utm['utm_term']),
2395
- 'utm_content' => str_replace(' ', '+', $utm['utm_content']),
2396
- ];
2397
-
2398
- $url = add_query_arg(array_filter($utm), $url);
2399
-
2400
- }
2401
-
2402
- return $url;
2403
- }
2404
-
2405
- /**
2406
- * Get Parent Product URL
2407
- *
2408
- * @param WC_Product $product
2409
- *
2410
- * @return string
2411
- * @author Nazrul Islam Nayan
2412
- * @since 5.1.8
2413
- */
2414
- protected function parent_link($product)
2415
- {
2416
- if ($product->is_type('variation')) {
2417
- $product = wc_get_product($product->get_parent_id());
2418
- $link = $this->link($product);
2419
- } else {
2420
- $link = $this->link($product);
2421
- }
2422
-
2423
- return apply_filters('woo_feed_filter_product_parent_link', $link, $product, $this->config);
2424
- }
2425
-
2426
- /**
2427
- * Get Canonical Link
2428
- * @param WC_Product $product
2429
- * @return mixed
2430
- */
2431
- protected function canonical_link($product)
2432
- {
2433
- if ($product->is_type('variation')) {
2434
- $product = wc_get_product($product->get_parent_id());
2435
- $canonical_link = $product->get_permalink();
2436
- } else {
2437
- $canonical_link = $product->get_permalink();
2438
- }
2439
-
2440
- return apply_filters('woo_feed_filter_product_canonical_link', $canonical_link, $product, $this->config);
2441
- }
2442
-
2443
- /**
2444
- * Get External Product URL
2445
- *
2446
- * @param WC_Product $product
2447
- *
2448
- * @return string
2449
- * @since 3.2.0
2450
- *
2451
- */
2452
- protected function ex_link($product)
2453
- {
2454
- if ($product->is_type('external')) {
2455
- $utm = $this->config['campaign_parameters'];
2456
- if (!empty($utm['utm_source']) && !empty($utm['utm_medium']) && !empty($utm['utm_campaign'])) {
2457
- $utm = [
2458
- 'utm_source' => str_replace(' ', '+', $utm['utm_source']),
2459
- 'utm_medium' => str_replace(' ', '+', $utm['utm_medium']),
2460
- 'utm_campaign' => str_replace(' ', '+', $utm['utm_campaign']),
2461
- 'utm_term' => str_replace(' ', '+', $utm['utm_term']),
2462
- 'utm_content' => str_replace(' ', '+', $utm['utm_content']),
2463
- ];
2464
-
2465
- return add_query_arg(array_filter($utm), $product->get_product_url());
2466
- } else {
2467
- $ex_link = $product->get_product_url();
2468
- }
2469
- } else {
2470
- $ex_link = '';
2471
- }
2472
-
2473
- return apply_filters('woo_feed_filter_product_ex_link', $ex_link, $product, $this->config);
2474
- }
2475
-
2476
- /**
2477
- * Get Product Image
2478
- *
2479
- * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product Product Object.
2480
- *
2481
- * @return mixed
2482
- * @since 3.2.0
2483
- *
2484
- */
2485
- protected function image($product)
2486
- {
2487
- $image = '';
2488
- if ($product->is_type('variation')) {
2489
- // Variation product type
2490
- if (has_post_thumbnail($product->get_id())) {
2491
- $getImage = wp_get_attachment_image_src(get_post_thumbnail_id($product->get_id()), 'single-post-thumbnail');
2492
- $image = woo_feed_get_formatted_url($getImage[0]);
2493
- } elseif (has_post_thumbnail($product->get_parent_id())) {
2494
- $getImage = wp_get_attachment_image_src(get_post_thumbnail_id($product->get_parent_id()), 'single-post-thumbnail');
2495
- $image = woo_feed_get_formatted_url($getImage[0]);
2496
- }
2497
- } elseif (has_post_thumbnail($product->get_id())) { // All product type except variation
2498
- $getImage = wp_get_attachment_image_src(get_post_thumbnail_id($product->get_id()), 'single-post-thumbnail');
2499
- $image = isset($getImage[0]) ? woo_feed_get_formatted_url($getImage[0]) : '';
2500
- }
2501
-
2502
- return apply_filters('woo_feed_filter_product_image', $image, $product, $this->config);
2503
- }
2504
-
2505
- /**
2506
- * Get Product Featured Image. For product variations it will return the variable product image.
2507
- *
2508
- * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product Product Object.
2509
- *
2510
- * @return mixed
2511
- * @since 3.2.0
2512
- *
2513
- */
2514
- protected function feature_image($product)
2515
- {
2516
- if ($product->is_type('variation')) {
2517
- $id = $product->get_parent_id();
2518
- } else {
2519
- $id = $product->get_id();
2520
- }
2521
-
2522
- $getImage = wp_get_attachment_image_src(get_post_thumbnail_id($id), 'single-post-thumbnail');
2523
- $image = isset($getImage[0]) ? woo_feed_get_formatted_url($getImage[0]) : '';
2524
-
2525
- return apply_filters('woo_feed_filter_product_feature_image', $image, $product, $this->config);
2526
- }
2527
-
2528
- /**
2529
- * Get Comma Separated Product Images
2530
- *
2531
- * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product Product Object.
2532
- * @param string $additionalImg Specific Additional Image.
2533
- *
2534
- * @return mixed
2535
- * @since 3.2.0
2536
- *
2537
- */
2538
- protected function images($product, $additionalImg = '')
2539
- {
2540
- $imgUrls = $this->get_product_gallery($product);
2541
- $separator = ',';
2542
-
2543
- // Return Specific Additional Image URL
2544
- if ('' !== $additionalImg) {
2545
- if (array_key_exists($additionalImg, $imgUrls)) {
2546
- $images = $imgUrls[$additionalImg];
2547
- } else {
2548
- $images = '';
2549
- }
2550
- } else {
2551
- if (isset($this->config['provider']) && "idealo" === $this->config['provider']) {
2552
- $separator = ';';
2553
- }
2554
-
2555
- $images = implode($separator, array_filter($imgUrls));
2556
- }
2557
-
2558
- return apply_filters('woo_feed_filter_product_images', $images, $product, $this->config);
2559
- }
2560
-
2561
- /**
2562
- * Get Product Gallery Items (URL) array.
2563
- * This can contains empty array values
2564
- *
2565
- * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product
2566
- *
2567
- * @return string[]
2568
- * @since 3.2.6
2569
- */
2570
- protected function get_product_gallery($product)
2571
- {
2572
- $imgUrls = [];
2573
- $attachmentIds = [];
2574
-
2575
- if ($product->is_type('variation')) {
2576
- if (class_exists('Woo_Variation_Gallery')) {
2577
- /**
2578
- * Get Variation Additional Images for "Additional Variation Images Gallery for WooCommerce"
2579
- * @plugin Additional Variation Images Gallery for WooCommerce
2580
- * @link https://wordpress.org/plugins/woo-variation-gallery/
2581
- */
2582
- $attachmentIds = get_post_meta($product->get_id(), 'woo_variation_gallery_images', true);
2583
- } elseif (class_exists('WooProductVariationGallery')) {
2584
- /**
2585
- * Get Variation Additional Images for "Variation Images Gallery for WooCommerce"
2586
- * @plugin Variation Images Gallery for WooCommerce
2587
- * @link https://wordpress.org/plugins/woo-product-variation-gallery/
2588
- */
2589
- $attachmentIds = get_post_meta($product->get_id(), 'rtwpvg_images', true);
2590
- } elseif (class_exists('WC_Additional_Variation_Images')) {
2591
- /**
2592
- * Get Variation Additional Images for "WooCommerce Additional Variation Images"
2593
- * @plugin WooCommerce Additional Variation Images
2594
- * @link https://woocommerce.com/products/woocommerce-additional-variation-images/
2595
- */
2596
- $attachmentIds = explode(',', get_post_meta($product->get_id(), '_wc_additional_variation_images', true));
2597
- } elseif (class_exists('WOODMART_Theme')) {
2598
- /**
2599
- * Get Variation Additional Images for "WOODMART Theme -> Variation Gallery Images Feature"
2600
- * @theme WOODMART
2601
- * @link https://themeforest.net/item/woodmart-woocommerce-wordpress-theme/20264492
2602
- */
2603
- $var_id = $product->get_id();
2604
- $parent_id = $product->get_parent_id();
2605
-
2606
- $variation_obj = get_post_meta($parent_id, 'woodmart_variation_gallery_data', true);
2607
- if (isset($variation_obj) && isset($variation_obj[$var_id])) {
2608
- $attachmentIds = explode(',', $variation_obj[$var_id]);
2609
- } else {
2610
- $attachmentIds = explode(',', get_post_meta($var_id, 'wd_additional_variation_images_data', true));
2611
- }
2612
- } else {
2613
- /**
2614
- * If any Variation Gallery Image plugin not installed then get Variable Product Additional Image Ids .
2615
- */
2616
- $attachmentIds = wc_get_product($product->get_parent_id())->get_gallery_image_ids();
2617
- }
2618
- }
2619
-
2620
- /**
2621
- * Get Variable Product Gallery Image ids if Product is not a variation
2622
- * or variation does not have any gallery images
2623
- */
2624
- if (empty($attachmentIds)) {
2625
- $attachmentIds = $product->get_gallery_image_ids();
2626
- }
2627
-
2628
- if ($attachmentIds && is_array($attachmentIds)) {
2629
- $mKey = 1;
2630
- foreach ($attachmentIds as $attachmentId) {
2631
- $imgUrls[$mKey] = woo_feed_get_formatted_url(wp_get_attachment_url($attachmentId));
2632
- $mKey++;
2633
- }
2634
- }
2635
-
2636
- return $imgUrls;
2637
- }
2638
-
2639
- /**
2640
- * Get Product Condition
2641
- *
2642
- * @param WC_Product $product
2643
- *
2644
- * @return mixed
2645
- * @since 3.2.0
2646
- *
2647
- */
2648
- protected function condition($product)
2649
- {
2650
- return apply_filters('woo_feed_product_condition', 'new', $product);
2651
- }
2652
-
2653
- /**
2654
- * Get Product Type
2655
- *
2656
- * @param WC_Product $product
2657
- *
2658
- * @return mixed
2659
- * @since 3.2.0
2660
- *
2661
- */
2662
- protected function type($product)
2663
- {
2664
- return apply_filters('woo_feed_filter_product_type', $product->get_type(), $product, $this->config);
2665
- }
2666
-
2667
- /**
2668
- * Get Product is a bundle product or not
2669
- *
2670
- * @param WC_Product $product
2671
- *
2672
- * @return mixed
2673
- * @since 3.2.0
2674
- *
2675
- */
2676
- protected function is_bundle($product)
2677
- {
2678
- if ($product->is_type('bundle') || $product->is_type('yith_bundle')) {
2679
- $is_bundle = 'yes';
2680
- } else {
2681
- $is_bundle = 'no';
2682
- }
2683
-
2684
- return apply_filters('woo_feed_filter_product_is_bundle', $is_bundle, $product, $this->config);
2685
- }
2686
-
2687
- /**
2688
- * Get Product is a multi-pack product or not
2689
- *
2690
- * @param WC_Product $product
2691
- *
2692
- * @return mixed
2693
- * @since 3.2.0
2694
- *
2695
- */
2696
- protected function multipack($product)
2697
- {
2698
- $multi_pack = '';
2699
- if ($product->is_type('grouped')) {
2700
- $multi_pack = (!empty($product->get_children())) ? count($product->get_children()) : '';
2701
- }
2702
-
2703
- return $multi_pack;
2704
- }
2705
-
2706
- /**
2707
- * Get Product visibility status
2708
- *
2709
- * @param WC_Product $product
2710
- *
2711
- * @return mixed
2712
- * @since 3.2.0
2713
- *
2714
- */
2715
- protected function visibility($product)
2716
- {
2717
- return apply_filters('woo_feed_filter_product_visibility', $product->get_catalog_visibility(), $product, $this->config);
2718
- }
2719
-
2720
- /**
2721
- * Get Product Total Rating
2722
- *
2723
- * @param WC_Product $product
2724
- *
2725
- * @return mixed
2726
- * @since 3.2.0
2727
- *
2728
- */
2729
- protected function rating_total($product)
2730
- {
2731
- return apply_filters('woo_feed_filter_product_rating_total', $product->get_rating_count(), $product, $this->config);
2732
- }
2733
-
2734
- /**
2735
- * Get Product average rating
2736
- *
2737
- * @param WC_Product $product
2738
- *
2739
- * @return mixed
2740
- * @since 3.2.0
2741
- *
2742
- */
2743
- protected function rating_average($product)
2744
- {
2745
- return apply_filters('woo_feed_filter_product_rating_average', $product->get_average_rating(), $product, $this->config);
2746
- }
2747
-
2748
- /**
2749
- * Get Product tags
2750
- *
2751
- * @param WC_Product $product
2752
- *
2753
- * @return string
2754
- * @since 3.2.0
2755
- *
2756
- */
2757
- protected function tags($product)
2758
- {
2759
- $id = $product->get_id();
2760
- if ($product->is_type('variation')) {
2761
- $id = $product->get_parent_id();
2762
- }
2763
-
2764
- /**
2765
- * Separator for multiple tags
2766
- * @param string $separator
2767
- * @param array $config
2768
- * @param WC_Abstract_Legacy_Product $product
2769
- * @since 3.4.3
2770
- */
2771
- $separator = apply_filters('woo_feed_tags_separator', ',', $this->config, $product);
2772
-
2773
- $tags = woo_feed_strip_all_tags(get_the_term_list($id, 'product_tag', '', $separator, ''));
2774
-
2775
- return apply_filters('woo_feed_filter_product_tags', $tags, $product, $this->config);
2776
- }
2777
-
2778
- /**
2779
- * Get Product Parent Id
2780
- *
2781
- * @param WC_Product $product
2782
- *
2783
- * @return mixed
2784
- * @since 3.2.0
2785
- *
2786
- */
2787
- protected function item_group_id($product)
2788
- {
2789
- $id = $product->get_id();
2790
- if ($product->is_type('variation')) {
2791
- $id = $product->get_parent_id();
2792
- }
2793
-
2794
- return apply_filters('woo_feed_filter_product_item_group_id', $id, $product, $this->config);
2795
- }
2796
-
2797
- /**
2798
- * Get Product SKU
2799
- *
2800
- * @param WC_Product $product
2801
- *
2802
- * @return mixed
2803
- * @since 3.2.0
2804
- *
2805
- */
2806
- protected function sku($product)
2807
- {
2808
- return apply_filters('woo_feed_filter_product_sku', $product->get_sku(), $product, $this->config);
2809
- }
2810
-
2811
- /**
2812
- * Get Product SKU ID. It should come with after merging of sku and product id with '_' sign.
2813
- *
2814
- * @param WC_Product $product
2815
- *
2816
- * @return string
2817
- * @author Nazrul Islam Nayan
2818
- * @since 4.3.13
2819
- */
2820
- protected function sku_id($product)
2821
- {
2822
- $sku = !empty($product->get_sku()) ? $product->get_sku() . '_' : '';
2823
- $sku_id = $sku . $product->get_id();
2824
-
2825
- return apply_filters('woo_feed_filter_product_sku_id', $sku_id, $product, $this->config);
2826
- }
2827
-
2828
- /**
2829
- * Get Product Parent SKU
2830
- *
2831
- * @param WC_Product $product
2832
- *
2833
- * @return mixed
2834
- * @since 3.2.0
2835
- *
2836
- */
2837
- protected function parent_sku($product)
2838
- {
2839
- if ($product->is_type('variation')) {
2840
- $id = $product->get_parent_id();
2841
- $parent = wc_get_product($id);
2842
-
2843
- $parent_sku = $parent->get_sku();
2844
- } else {
2845
- $parent_sku = $product->get_sku();
2846
- }
2847
-
2848
- return apply_filters('woo_feed_filter_product_parent_sku', $parent_sku, $product, $this->config);
2849
- }
2850
-
2851
- /**
2852
- * Get Product Availability Status
2853
- *
2854
- * @param WC_Product $product
2855
- *
2856
- * @return mixed
2857
- * @since 3.2.0
2858
- *
2859
- */
2860
- protected function availability($product)
2861
- {
2862
- $status = $product->get_stock_status();
2863
- if ('instock' == $status) {
2864
- $status = 'in stock';
2865
- } elseif ('outofstock' == $status) {
2866
- $status = 'out of stock';
2867
- } elseif ('onbackorder' == $status) {
2868
- $status = 'on backorder';
2869
- }
2870
-
2871
- // set (_) as separator for google merchant
2872
- if (isset($this->config['provider']) && 'google' === $this->config['provider']) {
2873
- $status = explode(' ', $status);
2874
- $status = implode('_', $status);
2875
- }
2876
-
2877
- return apply_filters('woo_feed_filter_product_availability', $status, $product, $this->config);
2878
- }
2879
-
2880
- /**
2881
- * Get Product Availability Date
2882
- *
2883
- * @param WC_Product $product
2884
- *
2885
- * @return mixed
2886
- * @author Ohidul Islam
2887
- * @since 3.2.0
2888
- *
2889
- */
2890
- protected function availability_date($product)
2891
- {
2892
-
2893
- $feed_settings = get_option('woo_feed_settings');
2894
-
2895
- $availability_date_settings = isset($feed_settings['woo_feed_identifier']['availability_date'])
2896
- ? $feed_settings['woo_feed_identifier']['availability_date']
2897
- : 'enable';
2898
-
2899
- if ($product->get_stock_status() !== 'onbackorder' || $availability_date_settings === 'disable') {
2900
- return '';
2901
- }
2902
-
2903
- $meta_field_name = 'woo_feed_availability_date';
2904
-
2905
- if ($product->is_type('variation')) {
2906
- $meta_field_name .= '_var';
2907
- }
2908
-
2909
- $availability_date = get_post_meta($product->get_id(), $meta_field_name, true);
2910
-
2911
- if ('' !== $availability_date && in_array($this->config['provider'], [
2912
- 'google',
2913
- 'facebook',
2914
- 'pinterest',
2915
- 'bing',
2916
- 'snapchat',
2917
- ], true)) {
2918
- $availability_date = gmdate('c', strtotime($availability_date));
2919
- }
2920
-
2921
- return apply_filters('woo_feed_filter_product_availability_date', $availability_date, $product, $this->config);
2922
- }
2923
-
2924
- /**
2925
- * Get Product Add to Cart Link
2926
- *
2927
- * @param WC_Product $product
2928
- *
2929
- * @return string
2930
- * @author Nazrul Islam Nayan
2931
- * @since 5.1.8
2932
- */
2933
- protected function add_to_cart_link($product)
2934
- {
2935
- $url = $this->link($product);
2936
- $suffix = 'add-to-cart=' . $product->get_id();
2937
-
2938
- $add_to_cart_link = woo_feed_make_url_with_parameter($url, $suffix);
2939
-
2940
- return apply_filters('woo_feed_filter_product_add_to_cart_link', $add_to_cart_link, $product, $this->config);
2941
- }
2942
-
2943
- /**
2944
- * Get Product Quantity
2945
- *
2946
- * @param WC_Product $product
2947
- *
2948
- * @return mixed
2949
- * @since 3.2.0
2950
- *
2951
- */
2952
- protected function quantity($product)
2953
- {
2954
- $quantity = $product->get_stock_quantity();
2955
- $status = $product->get_stock_status();
2956
-
2957
- //when product is outofstock and it's quantity is empty, set quantity to 0
2958
- if ('outofstock' == $status && empty($quantity)) {
2959
- $quantity = 0;
2960
- }
2961
-
2962
- if ($product->is_type('variable') && $product->has_child()) {
2963
- $visible_children = $product->get_visible_children();
2964
- $qty = array();
2965
- foreach ($visible_children as $key => $child) {
2966
- $childQty = get_post_meta($child, '_stock', true);
2967
- $qty[] = (int)$childQty + 0;
2968
- }
2969
-
2970
- if (isset($this->config['variable_quantity'])) {
2971
- $vaQty = $this->config['variable_quantity'];
2972
- if ('max' == $vaQty) {
2973
- $quantity = max($qty);
2974
- } elseif ('min' == $vaQty) {
2975
- $quantity = min($qty);
2976
- } elseif ('sum' == $vaQty) {
2977
- $quantity = array_sum($qty);
2978
- } elseif ('first' == $vaQty) {
2979
- $quantity = ((int)$qty[0]);
2980
- }
2981
-
2982
- $quantity = array_sum($qty);
2983
- }
2984
- }
2985
-
2986
- return apply_filters('woo_feed_filter_product_quantity', $quantity, $product, $this->config);
2987
- }
2988
-
2989
- /**
2990
- * Get Product Currency
2991
- *
2992
- * @param WC_Product $product
2993
- *
2994
- * @return mixed
2995
- * @since 4.4.39
2996
- *
2997
- */
2998
- protected function currency($product)
2999
- {
3000
- $quantity = get_option('woocommerce_currency');
3001
-
3002
- return apply_filters('woo_feed_filter_product_currency', $quantity, $product, $this->config);
3003
- }
3004
-
3005
- /**
3006
- * Get Store currency code.
3007
- *
3008
- * @param WC_Product $product Product Object
3009
- * @return mixed|string
3010
- * @since 3.2.0
3011
- *
3012
- */
3013
- protected function store_currency($product)
3014
- {
3015
- return get_woocommerce_currency();
3016
- }
3017
-
3018
- /**
3019
- * Get Product Sale Price Start Date
3020
- *
3021
- * @param WC_Product $product
3022
- *
3023
- * @return mixed
3024
- * @since 3.2.0
3025
- *
3026
- */
3027
- protected function sale_price_sdate($product)
3028
- {
3029
- $startDate = $product->get_date_on_sale_from();
3030
- if (is_object($startDate)) {
3031
- $sale_price_sdate = $startDate->date_i18n();
3032
- } else {
3033
- $sale_price_sdate = '';
3034
- }
3035
-
3036
- return apply_filters('woo_feed_filter_product_sale_price_sdate', $sale_price_sdate, $product, $this->config);
3037
- }
3038
-
3039
- /**
3040
- * Get Product Sale Price End Date
3041
- *
3042
- * @param WC_Product $product
3043
- *
3044
- * @return mixed
3045
- * @since 3.2.0
3046
- *
3047
- */
3048
- protected function sale_price_edate($product)
3049
- {
3050
- $endDate = $product->get_date_on_sale_to();
3051
- if (is_object($endDate)) {
3052
- $sale_price_edate = $endDate->date_i18n();
3053
- } else {
3054
- $sale_price_edate = "";
3055
- }
3056
-
3057
- return apply_filters('woo_feed_filter_product_sale_price_edate', $sale_price_edate, $product, $this->config);
3058
- }
3059
-
3060
- /**
3061
- * Get feed currency
3062
- *
3063
- * @return mixed|string
3064
- */
3065
- protected function get_feed_currency()
3066
- {
3067
- $currency = get_woocommerce_currency();
3068
- if (isset($this->config['feedCurrency'])) {
3069
- $currency = $this->config['feedCurrency'];
3070
- }
3071
-
3072
- return $currency;
3073
- }
3074
-
3075
- /**
3076
- * Get Product Price by default WooCommerce Price Type (regular_price|price|sale_price).
3077
- *
3078
- * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product Object
3079
- * @param string $price_type Price Type (regular_price|price|sale_price)
3080
- * @param bool $tax Add tax with price (true|false)
3081
- *
3082
- * @return float|mixed|string|void
3083
- * @since 4.4.14
3084
- *
3085
- * @author Ohidul Islam
3086
- */
3087
- protected function get_price_by_price_type($product, $price_type, $tax)
3088
- {
3089
-
3090
- if ('regular_price' === $price_type) {
3091
- $price = $product->get_regular_price();
3092
- } elseif ('price' === $price_type) {
3093
- $price = $product->get_price();
3094
- } else {
3095
- $price = $product->get_sale_price();
3096
- }
3097
-
3098
- // Get WooCommerce Multi language Price by Currency.
3099
- $price = apply_filters('woo_feed_wcml_price',
3100
- $price, $product->get_id(), $this->get_feed_currency(), '_' . $price_type
3101
- );
3102
-
3103
- // Get Price with tax
3104
- if (true === $tax) {
3105
- $price = woo_feed_get_price_with_tax($price, $product);
3106
- }
3107
-
3108
- return $price;
3109
- }
3110
-
3111
- /**
3112
- * Get Product Price by Product Type.
3113
- *
3114
- * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product Object
3115
- * @param string $price_type Price Type (regular_price|price|sale_price)
3116
- * @param bool $tax Add tax with price (true|false)
3117
- *
3118
- * @return float|int|mixed|string
3119
- * @since 4.4.14
3120
- *
3121
- * @author Ohidul Islam
3122
- */
3123
- protected function get_price_by_product_type($product, $price_type, $tax = false)
3124
- {
3125
- if ($product->is_type('variable')) {
3126
- $price = $this->getVariableProductPrice($product, $price_type, $tax);
3127
- } elseif ($product->is_type('grouped')) {
3128
- $price = $this->getGroupProductPrice($product, $price_type, $tax);
3129
- } elseif ($product->is_type('bundle')) {
3130
- //TODO Diff taxation
3131
- $price = $this->getBundleProductPrice($product, $price_type, $tax);
3132
- } elseif ($product->is_type('composite')) {
3133
- //TODO Diff taxation
3134
- $price = $this->getCompositeProductPrice($product, $price_type, $tax);
3135
- } elseif ($product->is_type('bundled')) {
3136
- // iconic woocommerce product bundled plugin
3137
- $price = $this->iconic_bundle_product_price($product, $price_type, $tax);
3138
- } else {
3139
- $price = $this->get_price_by_price_type($product, $price_type, $tax);
3140
- }
3141
-
3142
- return $price > 0 ? $price : '';
3143
- }
3144
-
3145
- /**
3146
- * Get Product Regular Price
3147
- *
3148
- * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product Object.
3149
- *
3150
- * @return mixed
3151
- * @since 3.2.0
3152
- *
3153
- */
3154
- protected function price($product)
3155
- {
3156
-
3157
- $regular_price = $this->get_price_by_product_type($product, 'regular_price');
3158
-
3159
- return apply_filters('woo_feed_filter_product_price', $regular_price, $product, $this->config, false);
3160
- }
3161
-
3162
- /**
3163
- * Get Product Price
3164
- *
3165
- * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product object.
3166
- *
3167
- * @return int|float|mixed
3168
- * @since 3.2.0
3169
- *
3170
- */
3171
- protected function current_price($product)
3172
- {
3173
-
3174
- $price = $this->get_price_by_product_type($product, 'price');
3175
-
3176
- return apply_filters('woo_feed_filter_product_regular_price', $price, $product, $this->config, false);
3177
- }
3178
-
3179
- /**
3180
- * Get Product Sale Price
3181
- *
3182
- * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product object.
3183
- *
3184
- * @return mixed
3185
- * @since 3.2.0
3186
- *
3187
- */
3188
- protected function sale_price($product)
3189
- {
3190
-
3191
- $sale_price = $this->get_price_by_product_type($product, 'sale_price');
3192
-
3193
- return apply_filters('woo_feed_filter_product_sale_price', $sale_price, $product, $this->config, false);
3194
- }
3195
-
3196
- /**
3197
- * Get Product Regular Price with Tax
3198
- *
3199
- * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product Object.
3200
- *
3201
- * @return mixed
3202
- * @since 3.2.0
3203
- *
3204
- */
3205
- protected function price_with_tax($product)
3206
- {
3207
-
3208
- $regular_price_with_tax = $this->get_price_by_product_type($product, 'regular_price', true);
3209
-
3210
- return apply_filters('woo_feed_filter_product_price_with_tax', $regular_price_with_tax, $product, $this->config, true);
3211
- }
3212
-
3213
- /**
3214
- * Get Product Regular Price with Tax
3215
- *
3216
- * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product object.
3217
- *
3218
- * @return mixed
3219
- * @since 3.2.0
3220
- *
3221
- */
3222
- protected function current_price_with_tax($product)
3223
- {
3224
-
3225
- $price_with_tax = $this->get_price_by_product_type($product, 'price', true);
3226
-
3227
- return apply_filters('woo_feed_filter_product_regular_price_with_tax', $price_with_tax, $product, $this->config, true);
3228
- }
3229
-
3230
- /**
3231
- * Get Product Regular Price with Tax
3232
- *
3233
- * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product object.
3234
- *
3235
- * @return mixed
3236
- * @since 3.2.0
3237
- *
3238
- */
3239
- protected function sale_price_with_tax($product)
3240
- {
3241
-
3242
- $sale_price_with_tax = $this->get_price_by_product_type($product, 'sale_price', true);
3243
-
3244
- return apply_filters('woo_feed_filter_product_sale_price_with_tax', $sale_price_with_tax, $product, $this->config, true);
3245
- }
3246
-
3247
- /**
3248
- * Get Composite Product Price
3249
- *
3250
- * @param WC_Product|WC_Product_Composite|WC_Composite_Products $product Composite Product object.
3251
- * @param string $type Price Type (regular_price|price|sale_price)
3252
- * @param bool $tax Add tax with price (true|false)
3253
- *
3254
- * @return int|float|double
3255
- * @since 3.2.6
3256
- */
3257
- protected function getCompositeProductPrice($product, $type, $tax = false)
3258
- {
3259
- if (class_exists('WC_Product_Composite') && class_exists('WPCleverWooco')) {
3260
- // WPC Composite Product
3261
- return $this->get_wpc_composite_price($product, $type, $tax);
3262
- } elseif (class_exists('WC_Composite_Products')) {
3263
- // WooCommerce Composite Product
3264
- return $this->get_wc_composite_product_price($product, $type, $tax);
3265
- } else {
3266
- // Get Base Price for Others Composite Products.
3267
- // Note*: YITH does not auto select components. So no need to calculate component price.
3268
- return $this->get_price_by_price_type($product, $type, $tax);
3269
- }
3270
- }
3271
-
3272
- /**
3273
- * Get WooCommerce Composite Product Price
3274
- * Plugin URL: https://wordpress.org/plugins/wpc-composite-products/
3275
- * Product Type: composite
3276
- *
3277
- * @param WC_Product|WC_Product_Composite $product
3278
- * @param string $type Price Type (regular_price|price|sale_price)
3279
- * @param bool $tax Add tax with price (true|false)
3280
- * @return float|int|mixed|string|void
3281
- */
3282
- protected function get_wc_composite_product_price($product, $type, $tax)
3283
- {
3284
- $price = 0;
3285
- // Parent Component Price
3286
- $base_price = $this->get_price_by_price_type($product, $type, $tax);
3287
- if (isset($this->config['composite_price']) && 'all_product_price' == $this->config['composite_price']) {
3288
- $composite = new WC_Product_Composite($product);
3289
-
3290
- if ('price' === $type || 'sale_price' === $type) {
3291
- $price = $composite->get_composite_price();
3292
- } else {
3293
- $price = $composite->get_composite_regular_price();
3294
- }
3295
-
3296
- // Get WooCommerce Multi language Price by Currency.
3297
- $price = apply_filters('woo_feed_wcml_price',
3298
- $price, $product->get_id(), $this->get_feed_currency(), '_' . $type
3299
- );
3300
-
3301
- // Get Price with tax
3302
- if (true === $tax) {
3303
- $price = woo_feed_get_price_with_tax($price, $composite);
3304
- }
3305
- } else {
3306
- $price = $base_price;
3307
- }
3308
-
3309
- return $price > 0 ? $price : '';
3310
- }
3311
-
3312
- /**
3313
- * Get WPC Composite Product Price.
3314
- * Plugin URL: https://wordpress.org/plugins/wpc-composite-products/
3315
- * Product Type: composite
3316
- *
3317
- * @param WC_Product|WC_Product_Composite $product
3318
- * @param string $type Price Type (regular_price|price|sale_price)
3319
- * @param bool $tax Add tax with price (true|false)
3320
- * @return float|int|mixed|string|void
3321
- */
3322
- protected function get_wpc_composite_price($product, $type, $tax)
3323
- {
3324
- $price = 0;
3325
- // Parent Component Price
3326
- $base_price = $this->get_price_by_price_type($product, $type, $tax);
3327
- if (isset($this->config['composite_price']) && 'all_product_price' == $this->config['composite_price']) {
3328
- $components_price = 0;
3329
- $components = $product->get_components();
3330
- if (!empty($components) && is_array($components)) {
3331
- foreach ($components as $component) {
3332
- $products = explode(',', $component['products']);
3333
- foreach ($products as $key => $product_id) {
3334
- $default_product = wc_get_product($product_id);
3335
- if (is_object($default_product) && $default_product->is_in_stock()) {
3336
- $quantity = (isset($component['qty']) && $component['qty'] > 0) ? $component['qty'] : 1;
3337
- if ('products' == $component['type'] && empty($component['price'])) {
3338
- $components_price += $this->get_price_by_price_type($default_product, 'price', $tax);
3339
- $components_price *= $quantity;
3340
- } elseif ('products' == $component['type'] && !empty($component['price'])) {
3341
- $clever = new WPCleverWooco();
3342
- $old_price = $this->get_price_by_price_type($default_product, 'price', $tax);
3343
- $new_price = $component['price'];
3344
- $components_price += $clever::wooco_new_price($old_price, $new_price);
3345
- $components_price *= $quantity;
3346
- }
3347
- break; // Get first in stock product from component options.
3348
- }
3349
- }
3350
- }
3351
-
3352
- // Apply discount to components price.
3353
- $discount = $product->get_discount();
3354
- if ($discount > 0) {
3355
- $components_price -= (($discount / 100) * $components_price);
3356
- }
3357
- }
3358
-
3359
- if ('exclude' === $product->get_pricing()) {
3360
- $price = $components_price;
3361
- } elseif ('include' === $product->get_pricing()) {
3362
- $price = $components_price + $base_price;
3363
- } elseif ('only' === $product->get_pricing()) {
3364
- $price = $base_price;
3365
- }
3366
- } else {
3367
- $price = $base_price;
3368
- }
3369
-
3370
- return $price > 0 ? $price : '';
3371
- }
3372
-
3373
- /**
3374
- * Get total price of grouped product
3375
- *
3376
- * @param WC_Product_Grouped $grouped Grouped Product Object
3377
- * @param string $type Price Type (regular_price|price|sale_price)
3378
- * @param bool $tax Add tax with price (true|false)
3379
- *
3380
- * @return int|string
3381
- * @since 3.2.0
3382
- *
3383
- */
3384
- protected function getGroupProductPrice($grouped, $type, $tax = false)
3385
- {
3386
- $groupProductIds = $grouped->get_children();
3387
- $price = 0;
3388
- if (!empty($groupProductIds)) {
3389
- foreach ($groupProductIds as $id) {
3390
- $product = wc_get_product($id);
3391
- if (!is_object($product)) {
3392
- continue; // make sure that the product exists..
3393
- }
3394
-
3395
- $get_price = $this->get_price_by_product_type($product, $type, $tax);
3396
- if (!empty($get_price)) {
3397
- $price += $get_price;
3398
- }
3399
- }
3400
- }
3401
-
3402
- return $price > 0 ? $price : '';
3403
- }
3404
-
3405
- /**
3406
- * Get Variable Product Price
3407
- *
3408
- * @param WC_Product_Variable $variable Variable Product Object
3409
- * @param string $type Price Type (regular_price|price|sale_price)
3410
- * @param bool $tax Add tax with price (true|false)
3411
- *
3412
- * @return int|string
3413
- * @since 3.2.0
3414
- *
3415
- */
3416
- protected function getVariableProductPrice($variable, $type, $tax = false)
3417
- {
3418
- $min_max_first_default = apply_filters('woo_feed_variable_product_price_range', 'min');
3419
- if (isset($this->config['variable_price'])) {
3420
- $min_max_first_default = $this->config['variable_price'];
3421
- }
3422
-
3423
- $price = 0;
3424
- if ('first' == $min_max_first_default) {
3425
- $children = $variable->get_visible_children();
3426
- if (isset($children[0]) && !empty($children[0])) {
3427
- $variation = wc_get_product($children[0]);
3428
- $price = $this->get_price_by_product_type($variation, $type, $tax);
3429
- }
3430
- } else {
3431
- if ('regular_price' == $type) {
3432
- $price = $variable->get_variation_regular_price($min_max_first_default);
3433
- } elseif ('sale_price' == $type) {
3434
- $price = $variable->get_variation_sale_price($min_max_first_default);
3435
- } else {
3436
- $price = $variable->get_variation_price($min_max_first_default);
3437
- }
3438
-
3439
- // Get WooCommerce Multi language Price by Currency.
3440
- $price = apply_filters('woo_feed_wcml_price',
3441
- $price, $variable->get_id(), $this->get_feed_currency(), '_' . $type
3442
- );
3443
-
3444
- // Get Price with tax
3445
- if (true === $tax) {
3446
- $price = woo_feed_get_price_with_tax($price, $variable);
3447
- }
3448
- }
3449
-
3450
- return $price > 0 ? $price : '';
3451
- }
3452
-
3453
- /**
3454
- * Get Bundle Product Price
3455
- *
3456
- * @param WC_Product $product Product object.
3457
- * @param string $type Price Type (regular_price|price|sale_price)
3458
- * @param bool $tax Add tax with price (true|false)
3459
- *
3460
- * @return int|float|string
3461
- * @since 4.3.24
3462
- */
3463
- protected function getBundleProductPrice($product, $type, $tax = false)
3464
- {
3465
- if (class_exists('WC_Product_Bundle')) {//WC_Product_Bundle
3466
- $bundle = new WC_Product_Bundle($product);
3467
- if ('price' === $type || 'sale_price' === $type) {
3468
- $price = $bundle->get_bundle_price();
3469
- } else {
3470
- $price = $bundle->get_bundle_regular_price();
3471
- }
3472
-
3473
- // Get WooCommerce Multi language Price by Currency.
3474
- $price = apply_filters('woo_feed_wcml_price',
3475
- $price, $product->get_id(), $this->get_feed_currency(), '_' . $type
3476
- );
3477
-
3478
- // Get Price with tax
3479
- if (true === $tax) {
3480
- $price = woo_feed_get_price_with_tax($price, $bundle);
3481
- }
3482
- } else {
3483
- // Get Default price for others bundle products.
3484
- $price = $this->get_price_by_price_type($product, $type, $tax);
3485
- }
3486
-
3487
- return $price > 0 ? $price : '';
3488
- }
3489
-
3490
- /**
3491
- * Get price for Iconic woocommerce-bundled-products
3492
- *
3493
- * @param WC_Product $product Product object
3494
- * @param string $type Price Type (regular_price|price|sale_price)
3495
- * @param bool $tax Add tax with price (true|false)
3496
- *
3497
- * @return mixed $bundle_price
3498
- */
3499
- protected function iconic_bundle_product_price($product, $type, $tax = false)
3500
- {
3501
- if (!class_exists('WC_Product_Bundled')) {
3502
- return $product->get_price();
3503
- }
3504
-
3505
- $is_discounted = false;
3506
- $price = $product->get_price();
3507
- $bundle = new WC_Product_Bundled($product->get_id());
3508
- $iconic_bundle_product_type = (!is_null($bundle->options['price_display'])) ? $bundle->options['price_display'] : '';
3509
- $product_ids = $bundle->options['product_ids'];
3510
-
3511
- //set discount
3512
- if (!empty($bundle->options['fixed_discount'])) {
3513
- $is_discounted = true;
3514
- $discount = $bundle->options['fixed_discount'];
3515
- } else {
3516
- $is_discounted = false;
3517
- $discount = 0;
3518
- }
3519
-
3520
- // Get price
3521
- if (is_array($product_ids)) {
3522
- $product_prices = array_map(function ($id) use ($tax, $type, $is_discounted, $discount) {
3523
- $product = wc_get_product($id);
3524
-
3525
- return $this->get_price_by_price_type($product, $type, $tax);
3526
-
3527
- }, $product_ids);
3528
-
3529
- if ('range' === $iconic_bundle_product_type) {
3530
- $price = min($product_prices);
3531
- } else {
3532
- $price = array_sum($product_prices);
3533
- }
3534
- }
3535
-
3536
- // Get sale price if discount enabled
3537
- if ($is_discounted && ('sale_price' === $type || 'price' === $type)) {
3538
- $price -= $discount;
3539
- }
3540
-
3541
- // Get WooCommerce Multi language Price by Currency.
3542
- $price = apply_filters('woo_feed_wcml_price',
3543
- $price, $product->get_id(), $this->get_feed_currency(), '_' . $type
3544
- );
3545
-
3546
- // Get Price with tax
3547
- if (true === $tax) {
3548
- $price = woo_feed_get_price_with_tax($price, $bundle);
3549
- }
3550
-
3551
- return $price > 0 ? $price : '';
3552
- }
3553
-
3554
- /**
3555
- * Get Product Weight
3556
- *
3557
- * @param WC_Product $product
3558
- *
3559
- * @return mixed
3560
- * @since 3.2.0
3561
- *
3562
- */
3563
- protected function weight($product)
3564
- {
3565
- return apply_filters('woo_feed_filter_product_weight', $product->get_weight(), $product, $this->config);
3566
- }
3567
-
3568
- /**
3569
- * Get Product Weight Unit
3570
- *
3571
- * @param WC_Product $product
3572
- *
3573
- * @return mixed
3574
- * @since 5.2.7
3575
- *
3576
- */
3577
- protected function weight_unit($product)
3578
- {
3579
- return apply_filters('woo_feed_filter_product_weight_unit', get_option('woocommerce_weight_unit'), $product, $this->config);
3580
- }
3581
-
3582
- /**
3583
- * Get Product Width
3584
- *
3585
- * @param WC_Product $product
3586
- *
3587
- * @return mixed
3588
- * @since 3.2.0
3589
- *
3590
- */
3591
- protected function width($product)
3592
- {
3593
- return apply_filters('woo_feed_filter_product_width', $product->get_width(), $product, $this->config);
3594
- }
3595
-
3596
- /**
3597
- * Get Product Height
3598
- *
3599
- * @param WC_Product $product
3600
- *
3601
- * @return mixed
3602
- * @since 3.2.0
3603
- *
3604
- */
3605
- protected function height($product)
3606
- {
3607
- return apply_filters('woo_feed_filter_product_height', $product->get_height(), $product, $this->config);
3608
- }
3609
-
3610
- /**
3611
- * Get Product Length
3612
- *
3613
- * @param WC_Product $product
3614
- *
3615
- * @return mixed
3616
- * @since 3.2.0
3617
- *
3618
- */
3619
- protected function length($product)
3620
- {
3621
- return apply_filters('woo_feed_filter_product_length', $product->get_length(), $product, $this->config);
3622
- }
3623
-
3624
- /**
3625
- * Get Product Shipping
3626
- *
3627
- * @param WC_Product $product
3628
- *
3629
- * @return mixed
3630
- * @since 4.3.16
3631
- * @author Nazrul Islam Nayan
3632
- */
3633
- protected function shipping($product)
3634
- {
3635
- $feedBody = '';
3636
- $data = $this->data;
3637
-
3638
- if (isset($data['shipping_zones']) && !empty($data['shipping_zones'])) {
3639
- $zones = $data['shipping_zones'];
3640
-
3641
- if (in_array($this->config['provider'], ['google', 'facebook', 'pinterest', 'bing', 'snapchat'])) {
3642
- $get_shipping = new Woo_Feed_Shipping($this->config);
3643
- $feedBody .= $get_shipping->set_product($product)->set_shipping_zone($zones)->get_google_shipping();
3644
- }
3645
- }
3646
-
3647
- return apply_filters('woo_feed_filter_product_shipping', $feedBody, $product, $this->config);
3648
-
3649
- }
3650
-
3651
- /**
3652
- * Get Product Shipping Cost
3653
- *
3654
- * @param WC_Product $product
3655
- *
3656
- * @return mixed
3657
- * @since 5.1.20
3658
- * @author Nazrul Islam Nayan
3659
- */
3660
- protected function shipping_cost($product)
3661
- {
3662
- $shipping_obj = new Woo_Feed_Shipping($this->config);
3663
- $shipping_obj = $shipping_obj->set_product($product);
3664
-
3665
- return apply_filters('woo_feed_filter_product_shipping_cost', $shipping_obj->get_lowest_shipping_price(), $product, $this->config);
3666
- }
3667
-
3668
- /**
3669
- * Get Product Shipping Class
3670
- *
3671
- * @param WC_Product $product
3672
- *
3673
- * @return mixed
3674
- * @since 3.2.0
3675
- *
3676
- */
3677
- protected function shipping_class($product)
3678
- {
3679
- return apply_filters('woo_feed_filter_product_shipping_class', $product->get_shipping_class(), $product, $this->config);
3680
- }
3681
-
3682
- /**
3683
- * Get Product Author Name
3684
- *
3685
- * @param WC_Product $product
3686
- *
3687
- * @return mixed
3688
- * @since 3.2.0
3689
- *
3690
- */
3691
- protected function author_name($product)
3692
- {
3693
- $post = get_post($product->get_id());
3694
-
3695
- return get_the_author_meta('user_login', $post->post_author);
3696
- }
3697
-
3698
- /**
3699
- * Get Product Author Email
3700
- *
3701
- * @param WC_Product $product
3702
- *
3703
- * @return mixed
3704
- * @since 3.2.0
3705
- *
3706
- */
3707
- protected function author_email($product)
3708
- {
3709
- $post = get_post($product->get_id());
3710
-
3711
- return get_the_author_meta('user_email', $post->post_author);
3712
- }
3713
-
3714
- /**
3715
- * Get Product Created Date
3716
- *
3717
- * @param WC_Product $product
3718
- *
3719
- * @return mixed
3720
- * @since 3.2.0
3721
- *
3722
- */
3723
- protected function date_created($product)
3724
- {
3725
- $date_created = gmdate('Y-m-d', strtotime($product->get_date_created()));
3726
-
3727
- return apply_filters('woo_feed_filter_product_date_created', $date_created, $product, $this->config);
3728
- }
3729
-
3730
- /**
3731
- * Get Product Last Updated Date
3732
- *
3733
- * @param WC_Product $product
3734
- *
3735
- * @return mixed
3736
- * @since 3.2.0
3737
- *
3738
- */
3739
- protected function date_updated($product)
3740
- {
3741
- $date_updated = gmdate('Y-m-d', strtotime($product->get_date_modified()));
3742
-
3743
- return apply_filters('woo_feed_filter_product_date_updated', $date_updated, $product, $this->config);
3744
- }
3745
-
3746
- /**
3747
- * Get Product Tax
3748
- *
3749
- * @param WC_Product $product Product object.
3750
- * @return mixed
3751
- * @since 5.1.20
3752
- * @author Nazrul Islam Nayan
3753
- */
3754
- protected function tax($product)
3755
- {
3756
- $feedBody = '';
3757
- if (in_array($this->config['provider'], ['google', 'facebook', 'pinterest', 'bing', 'snapchat'])) {
3758
- $shipping_obj = new Woo_Feed_Shipping($this->config);
3759
- $shipping_obj = $shipping_obj->set_product($product);
3760
- $feedBody .= $shipping_obj->get_google_tax();
3761
- }
3762
-
3763
- return apply_filters('woo_feed_filter_product_tax', $feedBody, $product, $this->config);
3764
- }
3765
-
3766
- /**
3767
- * Get Product Tax class
3768
- * @param WC_Product $product Product object.
3769
- * @return string
3770
- */
3771
- protected function tax_class($product)
3772
- {
3773
- return apply_filters('woo_feed_filter_product_tax_class', $product->get_tax_class(), $product, $this->config);
3774
- }
3775
-
3776
- /**
3777
- * Get Product Tax Status
3778
- * @param WC_Product $product Product object.
3779
- * @return string
3780
- */
3781
- protected function tax_status($product)
3782
- {
3783
- return apply_filters('woo_feed_filter_product_tax_status', $product->get_tax_status(), $product, $this->config);
3784
- }
3785
-
3786
- /**
3787
- * Get CTX Feed Custom Field value
3788
- *
3789
- * @param WC_Product $product Product object.
3790
- * @param string $field custom field name.
3791
- * @return string
3792
- */
3793
- protected function getCustomField($product, $field)
3794
- {
3795
- $id = $product->get_id();
3796
- $meta = $field;
3797
- if ($product->is_type('variation')) {
3798
- $meta = $field . '_var';
3799
- }
3800
-
3801
- $meta = apply_filters('woo_feed_custom_field_meta', $meta, $product, $field);
3802
-
3803
- $new_meta_key = '';
3804
- $old_meta_key = '';
3805
-
3806
- if (strpos($meta, '_identifier') !== false) {
3807
- $old_meta_key = $meta;
3808
- $new_meta_key = str_replace('_identifier', '', $meta);
3809
- } else {
3810
- $new_meta_key = $meta;
3811
- $old_meta_key = str_replace('woo_feed_', 'woo_feed_identifier_', $meta);
3812
- }
3813
-
3814
- $new_meta_value = $this->getProductMeta($product, $new_meta_key);
3815
- $old_meta_value = $this->getProductMeta($product, $old_meta_key);
3816
-
3817
- if (empty($new_meta_value)) {
3818
- return $old_meta_value;
3819
- } else {
3820
- return $new_meta_value;
3821
- }
3822
-
3823
- }
3824
-
3825
- /**
3826
- * Get Product Sale Price Effected Date for Google Shopping
3827
- *
3828
- * @param WC_Product $product
3829
- *
3830
- * @return string
3831
- * @since 3.2.0
3832
- *
3833
- */
3834
- protected function sale_price_effective_date($product)
3835
- {
3836
- $effective_date = '';
3837
- $from = $this->sale_price_sdate($product);
3838
- $to = $this->sale_price_edate($product);
3839
- if (!empty($from) && !empty($to)) {
3840
- $from = gmdate('c', strtotime($from));
3841
- $to = gmdate('c', strtotime($to));
3842
-
3843
- $effective_date = $from . '/' . $to;
3844
- }
3845
-
3846
- return $effective_date;
3847
- }
3848
-
3849
- /**
3850
- * Ger Product Attribute
3851
- *
3852
- * @param WC_Product $product
3853
- * @param $attr
3854
- *
3855
- * @return string
3856
- * @since 2.2.3
3857
- *
3858
- */
3859
- protected function getProductAttribute($product, $attr)
3860
- {
3861
- $id = $product->get_id();
3862
-
3863
- if (woo_feed_wc_version_check(3.2)) {
3864
- if (woo_feed_wc_version_check(3.6)) {
3865
- $attr = str_replace('pa_', '', $attr);
3866
- }
3867
- $value = $product->get_attribute($attr);
3868
-
3869
- // if empty get attribute of parent post
3870
- if ('' === $value && $product->is_type('variation')) {
3871
- $product = wc_get_product($product->get_parent_id());
3872
- $value = $product->get_attribute($attr);
3873
- }
3874
-
3875
- $getproductattribute = $value;
3876
- } else {
3877
- $getproductattribute = implode(',', wc_get_product_terms($id, $attr, array('fields' => 'names')));
3878
- }
3879
-
3880
- return apply_filters('woo_feed_filter_product_attribute', $getproductattribute, $product, $attr, $this->config);
3881
- }
3882
-
3883
- /**
3884
- * Get Meta
3885
- *
3886
- * @param WC_Product $product
3887
- * @param string $meta post meta key
3888
- *
3889
- * @return mixed|string
3890
- * @since 2.2.3
3891
- *
3892
- */
3893
- protected function getProductMeta($product, $meta)
3894
- {
3895
- $value = get_post_meta($product->get_id(), $meta, true);
3896
- // if empty get meta value of parent post
3897
- if ('' === $value && $product->is_type('variation')) {
3898
- $value = get_post_meta($product->get_parent_id(), $meta, true);
3899
- }
3900
-
3901
- return apply_filters('woo_feed_filter_product_meta', $value, $product, $this->config);
3902
- }
3903
-
3904
- /**
3905
- * Filter Products by Conditions
3906
- *
3907
- * @param WC_Product $product
3908
- *
3909
- * @return bool|array
3910
- * @since 3.2.0
3911
- *
3912
- */
3913
- public function filter_product($product)
3914
- {
3915
- return true;
3916
- }
3917
-
3918
- /**
3919
- * Get Taxonomy
3920
- *
3921
- * @param WC_Product $product
3922
- * @param $taxonomy
3923
- *
3924
- * @return string
3925
- * @since 2.2.3
3926
- *
3927
- */
3928
- protected function getProductTaxonomy($product, $taxonomy)
3929
- {
3930
- $id = $product->get_id();
3931
- if ($product->is_type('variation')) {
3932
- $id = $product->get_parent_id();
3933
- }
3934
-
3935
- $separator = apply_filters('woo_feed_product_taxonomy_term_list_separator', ',', $this->config, $product);
3936
-
3937
- $term_list = get_the_term_list($id, $taxonomy, '', $separator, '');
3938
-
3939
- if (is_object($term_list) && get_class($term_list) === 'WP_Error') {
3940
- $term_list = '';
3941
- }
3942
-
3943
- $getproducttaxonomy = woo_feed_strip_all_tags($term_list);
3944
-
3945
- return apply_filters('woo_feed_filter_product_taxonomy', $getproducttaxonomy, $product, $this->config);
3946
- }
3947
-
3948
- /**
3949
- * Format price value
3950
- *
3951
- * @param string $name Attribute Name
3952
- * @param int $conditionName condition
3953
- * @param int $result price
3954
- *
3955
- * @return mixed
3956
- * @since 3.2.0
3957
- *
3958
- */
3959
- protected function price_format($name, $conditionName, $result)
3960
- {
3961
- $plus = '+';
3962
- $minus = '-';
3963
- $percent = '%';
3964
-
3965
- if (strpos($name, 'price') !== false) {
3966
- if (strpos($result, $plus) !== false && strpos($result, $percent) !== false) {
3967
- $result = str_replace('+', '', $result);
3968
- $result = str_replace('%', '', $result);
3969
- if (is_numeric($result)) {
3970
- $result = $conditionName + (($conditionName * $result) / 100);
3971
- }
3972
- } elseif (strpos($result, $minus) !== false && strpos($result, $percent) !== false) {
3973
- $result = str_replace('-', '', $result);
3974
- $result = str_replace('%', '', $result);
3975
- if (is_numeric($result)) {
3976
- $result = $conditionName - (($conditionName * $result) / 100);
3977
- }
3978
- } elseif (strpos($result, $plus) !== false) {
3979
- $result = str_replace('+', '', $result);
3980
- if (is_numeric($result)) {
3981
- $result = ($conditionName + $result);
3982
- }
3983
- } elseif (strpos($result, $minus) !== false) {
3984
- $result = str_replace('-', '', $result);
3985
- if (is_numeric($result)) {
3986
- $result = $conditionName - $result;
3987
- }
3988
- }
3989
- }
3990
-
3991
- return $result;
3992
- }
3993
-
3994
- /**
3995
- * Format output According to Output Type config
3996
- *
3997
- * @param string $output
3998
- * @param array $outputTypes
3999
- * @param WC_Product $product
4000
- * @param string $productAttribute
4001
- *
4002
- * @return float|int|string
4003
- * @since 3.2.0
4004
- *
4005
- */
4006
- protected function format_output($output, $outputTypes, $product, $productAttribute, $merchant_attribute)
4007
- {
4008
- if (!empty($outputTypes) && is_array($outputTypes)) {
4009
-
4010
- // Format Output According to output type
4011
- if (in_array(2, $outputTypes)) { // Strip Tags
4012
- $output = woo_feed_strip_all_tags(html_entity_decode($output));
4013
- }
4014
-
4015
- if (in_array(3, $outputTypes)) { // UTF-8 Encode
4016
- $output = utf8_encode($output);
4017
- }
4018
-
4019
- if (in_array(4, $outputTypes)) { // htmlentities
4020
- $output = htmlentities($output, ENT_QUOTES, 'UTF-8');
4021
- }
4022
-
4023
- if (in_array(5, $outputTypes)) { // Integer
4024
- $output = intval($output);
4025
- }
4026
-
4027
- if (in_array(6, $outputTypes)) { // Format Price
4028
- if (!empty($output) && $output > 0) {
4029
- $decimals = wc_get_price_decimals();
4030
- $decimal_separator = wc_get_price_decimal_separator();
4031
- $thousand_separator = wc_get_price_thousand_separator();
4032
- $output = (float)$output;
4033
-
4034
- if ("idealo" === $this->config['provider']) {
4035
- $output = number_format($output, $decimals, wp_specialchars_decode(stripslashes($decimal_separator)), wp_specialchars_decode(stripslashes($thousand_separator)));
4036
- } else {
4037
- $output = number_format($output, 2, '.', '');
4038
- }
4039
-
4040
- }
4041
- }
4042
-
4043
- if (in_array(7, $outputTypes)) { // Rounded Price
4044
- if (!empty($output) && $output > 0) {
4045
- $output = round($output);
4046
- $output = number_format($output, 2, '.', '');
4047
- }
4048
- }
4049
-
4050
- if (in_array(8, $outputTypes)) { // Delete Space
4051
- $output = htmlentities($output, null, 'utf-8');
4052
- $output = str_replace("&nbsp;", " ", $output);
4053
- $output = html_entity_decode($output);
4054
- $output = preg_replace("/\\s+/", ' ', $output);
4055
- }
4056
-
4057
- if (in_array(10, $outputTypes)) { // Remove Invalid Character
4058
- $output = woo_feed_stripInvalidXml($output);
4059
- }
4060
-
4061
- if (in_array(11, $outputTypes)) { // Remove ShortCodes
4062
- $output = $this->remove_short_codes($output);
4063
- }
4064
-
4065
- if (in_array(12, $outputTypes)) {
4066
- $output = ucwords(strtolower($output));
4067
- }
4068
-
4069
- if (in_array(13, $outputTypes)) {
4070
- $output = ucfirst(strtolower($output));
4071
- }
4072
-
4073
- if (in_array(14, $outputTypes)) {
4074
- $output = strtoupper(strtolower($output));
4075
- }
4076
-
4077
- if (in_array(15, $outputTypes)) {
4078
- $output = strtolower($output);
4079
- }
4080
-
4081
- if (in_array(16, $outputTypes)) {
4082
- if ('http' == substr($output, 0, 4)) {
4083
- $output = str_replace('http://', 'https://', $output);
4084
- }
4085
- }
4086
-
4087
- if (in_array(17, $outputTypes)) {
4088
- if ('http' == substr($output, 0, 4)) {
4089
- $output = str_replace('https://', 'http://', $output);
4090
- }
4091
- }
4092
-
4093
- if (in_array(18, $outputTypes)) { // only parent
4094
- if ($product->is_type('variation')) {
4095
- $id = $product->get_parent_id();
4096
- $parentProduct = wc_get_product($id);
4097
- $output = $this->getAttributeValueByType($parentProduct, $productAttribute, $merchant_attribute);
4098
- }
4099
- }
4100
-
4101
- if (in_array(19, $outputTypes)) { // child if parent empty
4102
- if ($product->is_type('variation')) {
4103
- $id = $product->get_parent_id();
4104
- $parentProduct = wc_get_product($id);
4105
- $output = $this->getAttributeValueByType($parentProduct, $productAttribute, $merchant_attribute);
4106
- if (empty($output)) {
4107
- $output = $this->getAttributeValueByType($product, $productAttribute, $merchant_attribute);
4108
- }
4109
- }
4110
- }
4111
-
4112
- if (in_array(20, $outputTypes)) { // parent if child empty
4113
- if ($product->is_type('variation')) {
4114
- $output = $this->getAttributeValueByType($product, $productAttribute, $merchant_attribute);
4115
- if (empty($output)) {
4116
- $id = $product->get_parent_id();
4117
- $parentProduct = wc_get_product($id);
4118
- $output = $this->getAttributeValueByType($parentProduct, $productAttribute, $merchant_attribute);
4119
- }
4120
- }
4121
- }
4122
-
4123
- if (in_array(9, $outputTypes) && !empty($output) && 'xml' === $this->config['feedType']) { // Add CDATA
4124
- $output = '<![CDATA[' . $output . ']]>';
4125
- }
4126
- }
4127
-
4128
- return $output;
4129
- }
4130
-
4131
- /**
4132
- * Add Prefix and Suffix with attribute value
4133
- *
4134
- * @param $output
4135
- * @param $prefix
4136
- * @param $suffix
4137
- * @param $attribute
4138
- *
4139
- * @return string
4140
- * @since 3.2.0
4141
- *
4142
- */
4143
- public function process_prefix_suffix($output, $prefix, $suffix, $attribute = '')
4144
- {
4145
- $cdata = false;
4146
- if ('' === $output) {
4147
- return $output;
4148
- }
4149
-
4150
- if (strpos($output, '<![CDATA[') !== false) {
4151
- $cdata = true;
4152
- $output = str_replace(array('<![CDATA[', ']]>'), array('', ''), $output);
4153
- }
4154
-
4155
- // Add Prefix before Output
4156
- if ('' !== $prefix) {
4157
- $output = "$prefix" . $output;
4158
- }
4159
-
4160
- // Add Suffix after Output
4161
- if ('' !== $suffix) {
4162
- if (array_key_exists(trim($suffix), get_woocommerce_currencies())) { // Add space before suffix if attribute contain price.
4163
- $output .= ' ' . $suffix;
4164
- } elseif (substr($output, 0, 4) === 'http') {
4165
- // Parse URL Parameters if available into suffix field
4166
- $output = woo_feed_make_url_with_parameter($output, $suffix);
4167
- } else {
4168
- $output .= (string)$suffix;
4169
- }
4170
- }
4171
-
4172
- if ($cdata) {
4173
- $output = '<![CDATA[' . $output . ']]>';
4174
- }
4175
-
4176
- return "$output";
4177
- }
4178
-
4179
- /**
4180
- * Get Subscription period
4181
- *
4182
- * @param WC_Product $product
4183
- *
4184
- * @return mixed
4185
- * @since 3.6.3
4186
- *
4187
- */
4188
- protected function subscription_period($product)
4189
- {
4190
- if (class_exists('WC_Subscriptions')) {
4191
- return $this->getProductMeta($product, '_subscription_period');
4192
- }
4193
- return '';
4194
- }
4195
-
4196
- /**
4197
- * Get Subscription period interval
4198
- *
4199
- * @param WC_Product $product
4200
- *
4201
- * @return mixed
4202
- * @since 3.6.3
4203
- *
4204
- */
4205
- protected function subscription_period_interval($product)
4206
- {
4207
- if (class_exists('WC_Subscriptions')) {
4208
- return $this->getProductMeta($product, '_subscription_period_interval');
4209
- }
4210
- return '';
4211
- }
4212
-
4213
- /**
4214
- * Get Subscription period interval
4215
- *
4216
- * @param WC_Product $product
4217
- *
4218
- * @return mixed
4219
- * @since 3.6.3
4220
- *
4221
- */
4222
- protected function subscription_amount($product)
4223
- {
4224
- return $this->price($product);
4225
- }
4226
-
4227
- /**
4228
- * Get Installment Amount
4229
- *
4230
- * @param WC_Product $product
4231
- *
4232
- * @return mixed
4233
- * @since 4.3.101
4234
- */
4235
- protected function installment_amount($product)
4236
- {
4237
- return $this->price($product);
4238
- }
4239
-
4240
- /**
4241
- * Get Installment Months
4242
- *
4243
- * @param WC_Product $product
4244
- *
4245
- * @return mixed
4246
- * @since 4.3.101
4247
- */
4248
- protected function installment_months($product)
4249
- {
4250
- if (class_exists('WC_Subscriptions')) {
4251
- return $this->getProductMeta($product, '_subscription_length');
4252
- }
4253
- return '';
4254
- }
4255
-
4256
-
4257
- /**
4258
- * Calculate unit_price_measure. If Unit custom fields by CTX feed are enabled then it will take value
4259
- * from custom fields or it will take values for WooCommerce Germanized Plugin if enabled.
4260
- *
4261
- * If variation values are empty then it will take value from variable product.
4262
- *
4263
- * @param WC_Product $product
4264
- *
4265
- * @return mixed
4266
- * @since 3.6.3
4267
- */
4268
- protected function unit_price_measure($product)
4269
- {
4270
- $unit_price_measure = '';
4271
- $identifiers = woo_feed_get_options('woo_feed_identifier');
4272
- if ('enable' === $identifiers['unit_pricing_base_measure']
4273
- && 'enable' === $identifiers['unit_pricing_measure']
4274
- && 'enable' === $identifiers['unit']
4275
- ) {
4276
- $unit = $this->getCustomField($product, 'woo_feed_unit');
4277
- $unit_price_measure = $this->getCustomField($product, 'woo_feed_unit_pricing_measure');
4278
-
4279
- $unit_price_measure .= " " . $unit;
4280
- }
4281
-
4282
- if (empty($unit_price_measure) && class_exists('WooCommerce_Germanized')) { // For WooCommerce Germanized Plugin
4283
- $unit = $this->getProductMeta($product, '_unit');
4284
- $unit_price_measure = $this->getProductMeta($product, '_unit_product');
4285
-
4286
- $unit_price_measure .= " " . $unit;
4287
- }
4288
-
4289
- return apply_filters('woo_feed_filter_unit_price_measure', $unit_price_measure, $product, $this->config);
4290
- }
4291
-
4292
- /**
4293
- * Calculate unit_price_base_measure. If Unit custom fields by CTX feed are enabled then it will take value
4294
- * from custom fields or it will take values for WooCommerce Germanized Plugin if enabled.
4295
- *
4296
- * If variation values are empty then it will take value from variable product.
4297
- *
4298
- * @param WC_Product $product
4299
- *
4300
- * @return mixed
4301
- * @since 3.6.3
4302
- */
4303
- protected function unit_price_base_measure($product)
4304
- {
4305
- $unit_price_base_measure = '';
4306
- $identifiers = woo_feed_get_options('woo_feed_identifier');
4307
- if ('enable' === $identifiers['unit_pricing_base_measure']
4308
- && 'enable' === $identifiers['unit_pricing_measure']
4309
- && 'enable' === $identifiers['unit']
4310
- ) {
4311
- $unit = $this->getCustomField($product, 'woo_feed_unit');
4312
- $unit_price_base_measure = $this->getCustomField($product, 'woo_feed_unit_pricing_base_measure');
4313
-
4314
- $unit_price_base_measure .= " " . $unit;
4315
- }
4316
-
4317
- if (empty($unit_price_base_measure) && class_exists('WooCommerce_Germanized')) { // For WooCommerce Germanized Plugin
4318
- $unit = $this->getProductMeta($product, '_unit');
4319
- $unit_price_base_measure = $this->getProductMeta($product, '_unit_base');
4320
-
4321
- $unit_price_base_measure .= " " . $unit;
4322
- }
4323
-
4324
- return apply_filters('woo_feed_filter_unit_price_base_measure', $unit_price_base_measure, $product, $this->config);
4325
- }
4326
-
4327
- /**
4328
- * Get GTIN value of WooCommerce Germanized Plugin
4329
- *
4330
- * @param WC_Product $product
4331
- *
4332
- * @return mixed
4333
- * @since 3.6.3
4334
- */
4335
- protected function wc_germanized_gtin($product)
4336
- {
4337
- $wc_germanized_gtin = '';
4338
- if (class_exists('WooCommerce_Germanized')) { // For WooCommerce Germanized Plugin
4339
- $wc_germanized_gtin = $this->getProductMeta($product, '_ts_gtin');
4340
- }
4341
-
4342
- return apply_filters('woo_feed_filter_wc_germanized_gtin', $wc_germanized_gtin, $product, $this->config);
4343
- }
4344
-
4345
- /**
4346
- * Get MPN value of WooCommerce Germanized Plugin
4347
- *
4348
- * @param WC_Product $product
4349
- *
4350
- * @return mixed
4351
- * @since 3.6.3
4352
- */
4353
- protected function wc_germanized_mpn($product)
4354
- {
4355
- $wc_germanized_mpn = '';
4356
- if (class_exists('WooCommerce_Germanized')) { // For WooCommerce Germanized Plugin
4357
- $wc_germanized_mpn = $this->getProductMeta($product, '_ts_mpn');
4358
- }
4359
-
4360
- return apply_filters('woo_feed_filter_wc_germanized_mpn', $wc_germanized_mpn, $product, $this->config);
4361
- }
4362
-
4363
-
4364
- /**
4365
- * Yoast Identifier attribute for gtin8
4366
- *
4367
- * @param WC_Product $product
4368
- *
4369
- * @return mixed
4370
- * @since 4.4.4
4371
- */
4372
- protected function yoast_gtin8($product)
4373
- {
4374
- $yoast_gtin8_value = woo_feed_get_yoast_identifiers_value('gtin8', $product);
4375
-
4376
- return apply_filters('yoast_gtin8_attribute_value', $yoast_gtin8_value, $product);
4377
- }
4378
-
4379
- /**
4380
- * Yoast Identifier attribute for gtin12
4381
- *
4382
- * @param WC_Product $product
4383
- *
4384
- * @return mixed
4385
- * @since 4.4.4
4386
- */
4387
- protected function yoast_gtin12($product)
4388
- {
4389
- $yoast_gtin12_value = woo_feed_get_yoast_identifiers_value('gtin12', $product);
4390
-
4391
- return apply_filters('yoast_gtin12_attribute_value', $yoast_gtin12_value, $product);
4392
- }
4393
-
4394
- /**
4395
- * Yoast Identifier attribute for gtin13
4396
- *
4397
- * @param WC_Product $product
4398
- *
4399
- * @return mixed
4400
- * @since 4.4.4
4401
- */
4402
- protected function yoast_gtin13($product)
4403
- {
4404
- $yoast_gtin13_value = woo_feed_get_yoast_identifiers_value('gtin13', $product);
4405
-
4406
- return apply_filters('yoast_gtin13_attribute_value', $yoast_gtin13_value, $product);
4407
- }
4408
-
4409
- /**
4410
- * Yoast Identifier attribute for gtin12
4411
- *
4412
- * @param WC_Product $product
4413
- *
4414
- * @return mixed
4415
- * @since 4.4.4
4416
- */
4417
- protected function yoast_gtin14($product)
4418
- {
4419
- $yoast_gtin14_value = woo_feed_get_yoast_identifiers_value('gtin14', $product);
4420
-
4421
- return apply_filters('yoast_gtin14_attribute_value', $yoast_gtin14_value, $product);
4422
- }
4423
-
4424
- /**
4425
- * Yoast Identifier attribute for isbn
4426
- *
4427
- * @param WC_Product $product
4428
- *
4429
- * @return mixed
4430
- * @since 4.4.4
4431
- */
4432
- protected function yoast_isbn($product)
4433
- {
4434
- $yoast_isbn_value = woo_feed_get_yoast_identifiers_value('isbn', $product);
4435
-
4436
- return apply_filters('yoast_isbn_attribute_value', $yoast_isbn_value, $product);
4437
- }
4438
-
4439
- /**
4440
- * Yoast Identifier attribute for mpn
4441
- *
4442
- * @param WC_Product $product
4443
- *
4444
- * @return mixed
4445
- * @since 4.4.4
4446
- */
4447
- protected function yoast_mpn($product)
4448
- {
4449
- $yoast_mpn_value = woo_feed_get_yoast_identifiers_value('mpn', $product);
4450
-
4451
- return apply_filters('yoast_mpn_attribute_value', $yoast_mpn_value, $product);
4452
- }
4453
-
4454
- /**
4455
- * Rank Math GTIN Identifier attribute
4456
- *
4457
- * @param WC_Product $product
4458
- *
4459
- * @return mixed
4460
- * @since 5.2.66
4461
- */
4462
- protected function rank_math_gtin($product)
4463
- {
4464
- $product_id = woo_feed_parent_product_id($product);
4465
- $rankmath_gtin_value = get_post_meta($product_id, '_rank_math_gtin_code');
4466
- $rankmath_gtin_value = !empty($rankmath_gtin_value) && is_array($rankmath_gtin_value) ? $rankmath_gtin_value[0] : '';
4467
-
4468
- return apply_filters('rankmath_gtin_attribute_value', $rankmath_gtin_value, $product);
4469
- }
4470
 
4471
  /**
4472
  * Get ACF Field values
10
  use RankMath\Helper;
11
 
12
  if (!defined('ABSPATH')) {
13
+ die();
14
  }
15
 
16
  /**
18
  */
19
  class Woo_Feed_Products_v3
20
  {
21
+ /**
22
+ * The Increment
23
+ * @var int
24
+ */
25
+ protected $pi = 0;
26
+ /**
27
+ * Feed file headers
28
+ *
29
+ * @var string|array
30
+ */
31
+ public $feedHeader;
32
+ /**
33
+ * Feed File Body
34
+ *
35
+ * @var string|array
36
+ */
37
+ public $feedBody;
38
+ /**
39
+ * Feed file footer
40
+ *
41
+ * @var string|array
42
+ */
43
+ public $feedFooter;
44
+ /**
45
+ * CSV|TXT column (text|word) enclosure
46
+ *
47
+ * @var string
48
+ */
49
+ protected $enclosure;
50
+ /**
51
+ * CSV|TXT column delimiter
52
+ *
53
+ * @var string
54
+ */
55
+ protected $delimiter;
56
+ /**
57
+ * Feed Rules
58
+ *
59
+ * @var array
60
+ */
61
+ protected $config;
62
+ /**
63
+ * Post status to query
64
+ *
65
+ * @var string
66
+ */
67
+ protected $post_status = 'publish';
68
+ /**
69
+ * Processed Products
70
+ *
71
+ * @var array
72
+ */
73
+ public $products = [];
74
 
75
 
76
+ /**
77
+ * Products IDs
78
+ *
79
+ * @var array
80
+ */
81
+ public $product_ids = [];
82
 
83
+ /**
84
+ * Feed Big Data
85
+ *
86
+ * @var array
87
+ */
88
+ public $data = [];
89
+
90
+ /**
91
+ * Processed Products
92
+ *
93
+ * @var array
94
+ */
95
+ public $product_types = [
96
+ 'simple',
97
+ 'variable',
98
+ 'variation',
99
+ 'grouped',
100
+ 'external',
101
+ 'composite',
102
+ 'bundle',
103
+ 'bundled',
104
+ 'yith_bundle',
105
+ 'yith-composite',
106
+ 'subscription',
107
+ 'variable-subscription',
108
+ 'woosb',
109
+ ];
110
+ /**
111
+ * Query Method Selector
112
+ *
113
+ * @var string
114
+ */
115
+ protected $queryType = 'wp';
116
+ /**
117
+ * To replace google product highlight attribute for CSV & TXT feed
118
+ * @var array
119
+ */
120
+ protected $google_product_highlights = array(
121
+ 'product highlight 1',
122
+ 'product highlight 2',
123
+ 'product highlight 3',
124
+ 'product highlight 4',
125
+ 'product highlight 5',
126
+ 'product highlight 6',
127
+ 'product highlight 7',
128
+ 'product highlight 8',
129
+ 'product highlight 9',
130
+ 'product highlight 10',
131
+ );
132
+
133
+ /**
134
+ * To replace google additional image link attribute for CSV & TXT feed
135
+ * @var array
136
+ */
137
+ protected $google_additional_image = array(
138
+ 'additional image link 1',
139
+ 'additional image link 2',
140
+ 'additional image link 3',
141
+ 'additional image link 4',
142
+ 'additional image link 5',
143
+ 'additional image link 6',
144
+ 'additional image link 7',
145
+ 'additional image link 8',
146
+ 'additional image link 9',
147
+ 'additional image link 10',
148
+ );
149
+ /**
150
+ * Google shipping tax attributes
151
+ * @var array
152
+ */
153
+ /**
154
+ * Google shipping tax attributes
155
+ *
156
+ * @var array
157
+ */
158
+ protected $google_shipping_tax = array(
159
+ 'shipping_country',
160
+ 'shipping_region',
161
+ 'shipping_postal_code',
162
+ 'shipping_service',
163
+ 'shipping_price',
164
+ 'min_handling_time',
165
+ 'max_handling_time',
166
+ 'min_transit_time',
167
+ 'max_transit_time',
168
+ 'tax',
169
+ 'tax_country',
170
+ 'tax_region',
171
+ 'tax_rate',
172
+ 'tax_ship',
173
+ 'installment_months',
174
+ 'installment_amount',
175
+ 'subscription_period',
176
+ 'subscription_period_length',
177
+ 'subscription_amount',
178
+ 'section_name',
179
+ 'attribute_name',
180
+ 'attribute_value',
181
+ 'unit_price_value',
182
+ 'unit_price_currency',
183
+ 'unit_price_unit',
184
+ 'additional_variant_label',
185
+ 'additional_variant_value',
186
+ );
187
+ /**
188
+ * XML Wrapper Array
189
+ * Contains 'header' and 'footer' for template.
190
+ * @var array
191
+ */
192
+ protected $xml_wrapper = [];
193
+
194
+
195
+ /**
196
+ * Attribute to skip in attribute loop for processing separately
197
+ *
198
+ * @var array
199
+ */
200
+ protected $skipped_merchant_attributes = array(
201
+ 'google' => array(
202
+ 'shipping_country',
203
+ 'shipping_region',
204
+ 'shipping_postal_code',
205
+ 'shipping_service',
206
+ 'shipping_price',
207
+ 'min_handling_time',
208
+ 'max_handling_time',
209
+ 'min_transit_time',
210
+ 'max_transit_time',
211
+ 'tax_country',
212
+ 'tax_region',
213
+ 'tax_rate',
214
+ 'tax_ship',
215
+ 'installment_months',
216
+ 'installment_amount',
217
+ 'subscription_period',
218
+ 'subscription_period_length',
219
+ 'subscription_amount',
220
+ 'section_name',
221
+ 'attribute_name',
222
+ 'attribute_value',
223
+ ),
224
+ 'facebook' => array(
225
+ 'shipping_country',
226
+ 'shipping_region',
227
+ 'shipping_service',
228
+ 'shipping_price',
229
+ 'tax_country',
230
+ 'tax_region',
231
+ 'tax_rate',
232
+ 'tax_ship',
233
+ 'installment_months',
234
+ 'installment_amount',
235
+ 'subscription_period',
236
+ 'subscription_period_length',
237
+ 'subscription_amount',
238
+ 'section_name',
239
+ 'attribute_name',
240
+ 'attribute_value',
241
+ 'unit_price_value',
242
+ 'unit_price_currency',
243
+ 'unit_price_unit',
244
+ 'additional_variant_label',
245
+ 'additional_variant_value',
246
+ ),
247
+ 'bing' => array(
248
+ 'shipping_country',
249
+ 'shipping_service',
250
+ 'shipping_price',
251
+ ),
252
+ 'pinterest' => array(
253
+ 'shipping_country',
254
+ 'shipping_service',
255
+ 'shipping_price',
256
+ 'shipping_region',
257
+ 'shipping_postal_code',
258
+ 'tax_country',
259
+ 'tax_region',
260
+ 'tax_rate',
261
+ 'tax_ship',
262
+ ),
263
+ );
264
+
265
+ /**
266
+ * Already Processed merchant attributes by the attribute loop
267
+ * this will ensure unique merchant attribute.
268
+ * @see Woo_Feed_Products_v::exclude_current_attribute()
269
+ * @var array
270
+ */
271
+ protected $processed_merchant_attributes = array();
272
+
273
+
274
+ /**
275
+ * Post meta prefix for dropdown item
276
+ * @since 3.1.18
277
+ * @var string
278
+ */
279
+ const POST_META_PREFIX = 'wf_cattr_';
280
+
281
+ /**
282
+ * Product Attribute (taxonomy & local) Prefix
283
+ * @since 3.1.18
284
+ * @var string
285
+ */
286
+ const PRODUCT_ATTRIBUTE_PREFIX = 'wf_attr_';
287
+
288
+ /**
289
+ * Product Taxonomy Prefix
290
+ * @since 3.1.18
291
+ * @var string
292
+ */
293
+ const PRODUCT_TAXONOMY_PREFIX = 'wf_taxo_';
294
+
295
+ /**
296
+ * Product Custom Field Prefix
297
+ *
298
+ * @since 3.1.18
299
+ * @var string
300
+ */
301
+ const PRODUCT_CUSTOM_IDENTIFIER = 'woo_feed_';
302
+
303
+ /**
304
+ * Product Category Mapping Prefix
305
+ * @since 3.1.18
306
+ * @var string
307
+ */
308
+ const PRODUCT_CATEGORY_MAPPING_PREFIX = 'wf_cmapping_';
309
+
310
+ /**
311
+ * WordPress Option Prefix
312
+ *
313
+ * @since 4.3.33
314
+ * @var string
315
+ * @author Nazrul Islam Nayan
316
+ */
317
+ const WP_OPTION_PREFIX = 'wf_option_';
318
 
319
  /**
320
+ * Advance Custom Field (ACF) Prefix
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
321
  *
322
+ * @since 3.1.18
323
  * @var string
324
  */
325
+ const PRODUCT_ACF_FIELDS = 'acf_fields_';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
326
 
327
+ /**
328
+ * Woo_Feed_Products_v3 constructor.
329
+ *
330
+ * @param $config
331
+ * @return void
332
+ */
333
+ public function __construct($config)
334
+ {
335
+ $this->config = woo_feed_parse_feed_rules($config);
336
+ $this->queryType = woo_feed_get_options('product_query_type');
337
+ $this->process_xml_wrapper();
338
+ woo_feed_log_feed_process($this->config['filename'], sprintf('Current Query Type is %s', $this->queryType));
339
+ }
340
+
341
+ /**
342
+ * Generate Query Args For WP/WC query class
343
+ * @param string $type
344
+ * @return array
345
+ */
346
+ protected function get_query_args($type = 'wc')
347
+ {
348
+ $args = [];
349
+
350
+ // Include Product Variations with db query if configured
351
+ $variation_query = woo_feed_get_options('variation_query_type');
352
+
353
+ if ('wc' === $type) {
354
+ $product_types = $this->product_types;
355
+ if ('variable' === $variation_query) {
356
+ $variation = array_search('variation', $product_types, true);
357
+ if ($variation) {
358
+ unset($product_types[$variation]);
359
+ }
360
+ }
361
+
362
+ $args = array(
363
+ 'limit' => -1, // phpcs:ignore
364
+ 'status' => $this->post_status,
365
+ 'type' => $product_types,
366
+ 'orderby' => 'date',
367
+ 'order' => 'DESC',
368
+ 'return' => 'ids',
369
+ 'suppress_filters' => false,
370
+ );
371
+ }
372
+
373
+ if ('wp' === $type) {
374
+
375
+ $post_type = 'product';
376
+ // Include Product Variations with db query if configured
377
+ $variation_query = woo_feed_get_options('variation_query_type');
378
+ if ('individual' === $variation_query) {
379
+ $post_type = ['product', 'product_variation'];
380
+ }
381
+
382
+ $args = array(
383
+ 'posts_per_page' => -1, // phpcs:ignore
384
+ 'post_type' => $post_type,
385
+ 'post_status' => 'publish',
386
+ 'order' => 'DESC',
387
+ 'fields' => 'ids',
388
+ 'cache_results' => false,
389
+ 'update_post_meta_cache' => false,
390
+ 'update_post_term_cache' => false,
391
+ 'suppress_filters' => false,
392
+ );
393
+ }
394
+ return $args;
395
+ }
396
+
397
+ /**
398
+ * Get Products using WC_Product_Query
399
+ *
400
+ * @return array
401
+ */
402
+ public function get_wc_query_products()
403
+ {
404
+ $args = $this->get_query_args('wc');
405
+ if (woo_feed_is_debugging_enabled()) {
406
+ woo_feed_log_feed_process($this->config['filename'], 'WC_Product_Query Args::' . PHP_EOL . print_r($args, true)); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
407
+ woo_feed_log($this->config['filename'], 'WC_Product_Query Args::' . PHP_EOL . print_r($args, true), 'info'); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
408
+ }
409
+ $query = new WC_Product_Query($args);
410
+ if (woo_feed_is_debugging_enabled()) {
411
+ woo_feed_log_feed_process($this->config['filename'], sprintf('WC_Product_Query Args ::' . PHP_EOL . '%s', print_r($args, true))); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
412
+ }
413
+ return $query->get_products();
414
+ }
415
+
416
+ /**
417
+ * Get Products using WP_Query
418
+ *
419
+ * return array
420
+ */
421
+ public function get_wp_query_products()
422
+ {
423
+ $args = $this->get_query_args('wp');
424
+ $query = new WP_Query($args);
425
+ if (!is_wp_error($query) && woo_feed_is_debugging_enabled()) {
426
+ woo_feed_log_feed_process($this->config['filename'], 'WC_Product_Query Args::' . PHP_EOL . print_r($args, true)); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
427
+ woo_feed_log_feed_process($this->config['filename'], sprintf('WP_Query Request ::' . PHP_EOL . '%s', $query->request));
428
+ woo_feed_log($this->config['filename'], 'WC_Product_Query Args::' . PHP_EOL . print_r($args, true), 'info'); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
429
+ woo_feed_log($this->config['filename'], sprintf('WP_Query Request ::' . PHP_EOL . '%s', $query->request), 'info');
430
+ }
431
+ return $query->get_posts();
432
+ }
433
+
434
+ /**
435
+ * Get products
436
+ *
437
+ * @return array
438
+ */
439
+ public function query_products()
440
+ {
441
+ $products = [];
442
+ if ('wc' == $this->queryType) {
443
+ $products = $this->get_wc_query_products();
444
+ } elseif ('wp' == $this->queryType) {
445
+ $products = $this->get_wp_query_products();
446
+ } elseif ('both' == $this->queryType) {
447
+ $wc = $this->get_wc_query_products();
448
+ $wp = $this->get_wp_query_products();
449
+ $products = array_unique(array_merge($wc, $wp));
450
+ }
451
+
452
+ //set product ids
453
+ $this->product_ids = $products;
454
+
455
+ return $products;
456
+ }
457
+
458
+ /**
459
+ * Organize Feed Attribute config
460
+ * @return array|bool
461
+ */
462
+ public function get_attribute_config()
463
+ {
464
+ if (empty($this->config)) {
465
+ return false;
466
+ }
467
+
468
+ $attributeConfig = array();
469
+ $merchantAttributes = $this->config['mattributes'];
470
+ if (!empty($merchantAttributes)) {
471
+ $i = 0;
472
+ foreach ($merchantAttributes as $key => $value) {
473
+ $attributeConfig[$i]['mattributes'] = $value;
474
+ $attributeConfig[$i]['prefix'] = $this->config['prefix'][$key];
475
+ $attributeConfig[$i]['type'] = $this->config['type'][$key];
476
+ $attributeConfig[$i]['attributes'] = $this->config['attributes'][$key];
477
+ $attributeConfig[$i]['default'] = $this->config['default'][$key];
478
+ $attributeConfig[$i]['suffix'] = $this->config['suffix'][$key];
479
+ $attributeConfig[$i]['output_type'] = $this->config['output_type'][$key];
480
+ $attributeConfig[$i]['limit'] = $this->config['limit'][$key];
481
+ $i++;
482
+ }
483
+ }
484
+
485
+ return $attributeConfig;
486
+ }
487
+
488
+ /**
489
+ * Get Product Information according to feed config
490
+ *
491
+ * @param int[] $productIds
492
+ *
493
+ * @return array
494
+ * @since 3.2.0
495
+ *
496
+ */
497
+ public function get_products($productIds)
498
+ {
499
+
500
+ if (empty($productIds)) {
501
+ return [];
502
+ }
503
+
504
+ //filter big data
505
+ $this->data = apply_filters("woo_feed_feed_big_data", $this->data, $productIds, $this->config);
506
+
507
+ /**
508
+ * Fires before looping through request product for getting product data
509
+ *
510
+ * @param int[] $productIds
511
+ * @param array $feedConfig
512
+ *
513
+ * @since 3.2.10
514
+ */
515
+ do_action('woo_feed_before_product_loop', $productIds, $this->config);
516
+
517
+ foreach ($productIds as $key => $pid) {
518
+ woo_feed_log_feed_process($this->config['filename'], sprintf('Loading Product Data For %d.', $pid));
519
+ $product = wc_get_product($pid);
520
+
521
+ if ($this->exclude_from_loop($product)) {
522
+ continue;
523
+ }
524
+
525
+ if ($this->process_variation($product)) {
526
+ continue;
527
+ }
528
+
529
+ if (!$this->filter_product($product)) {
530
+ woo_feed_log_feed_process($this->config['filename'], 'Skipping Product :: Matched with filter conditions');
531
+ continue;
532
+ }
533
+
534
+ woo_feed_log_feed_process($this->config['filename'], 'Formatting Feed Data...');
535
+
536
+ // Add Single item wrapper before product info loop start
537
+ if ('xml' == $this->config['feedType']) {
538
+ $this->feedBody .= "\n";
539
+ $this->feedBody .= '<' . $this->config['itemWrapper'] . '>';
540
+ $this->feedBody .= "\n";
541
+ }
542
+
543
+ // reset processed attribute list before loop
544
+ $this->processed_merchant_attributes = [];
545
+
546
+ // Process attribute values
547
+ $this->process_attributes($product);
548
+
549
+ try {
550
+ woo_feed_log_feed_process($this->config['filename'], 'Processing Merchant Specific Fields');
551
+ // Process feed data for uncommon merchant feed like Google,Facebook,Pinterest
552
+ $this->process_for_merchant($product, $this->pi);
553
+ } catch (Exception $e) {
554
+ $message = 'Error Processing Merchant Specific Fields.' . PHP_EOL . 'Caught Exception :: ' . $e->getMessage();
555
+ woo_feed_log($this->config['filename'], $message, 'critical', $e, true);
556
+ woo_feed_log_fatal_error($message, $e);
557
+ }
558
+
559
+ if ('xml' == $this->config['feedType']) {
560
+ if (empty($this->feedHeader)) {
561
+ $this->feedHeader = $this->process_xml_feed_header();
562
+ $this->feedFooter = $this->process_xml_feed_footer();
563
+
564
+ }
565
+
566
+ $this->feedBody .= '</' . $this->config['itemWrapper'] . '>';
567
+
568
+
569
+ } elseif ('txt' == $this->config['feedType']) {
570
+ if (empty($this->feedHeader)) {
571
+ $this->process_txt_feed_header();
572
+ }
573
+ $this->process_txt_feed_body();
574
+ } elseif ('csv' == $this->config['feedType'] || 'xls' == $this->config['feedType']) {
575
+ if (empty($this->feedHeader)) {
576
+ $this->process_csv_feed_header();
577
+ }
578
+ $this->process_csv_feed_body();
579
+ } elseif ('json' == $this->config['feedType']) {
580
+ $this->process_json_feed_body();
581
+ }
582
+ woo_feed_log_feed_process($this->config['filename'], 'Done Formatting...');
583
+ $this->pi++;
584
+ }
585
+
586
+ /**
587
+ * Fires after looping through request product for getting product data
588
+ *
589
+ * @param int[] $productIds
590
+ * @param array $feedConfig
591
+ *
592
+ * @since 3.2.10
593
+ */
594
+ do_action('woo_feed_after_product_loop', $productIds, $this->config);
595
+
596
+ return $this->products;
597
+ }
598
+
599
+ /**
600
+ * Process product variations
601
+ * @param WC_Abstract_Legacy_Product $product
602
+ *
603
+ * @return bool
604
+ * @since 3.3.9
605
+ */
606
+ protected function process_variation($product)
607
+ {
608
+ // Apply variable and variation settings
609
+ if ($product->is_type('variable') && $product->has_child()) {
610
+ $this->pi++;
611
+
612
+ $variation_query = woo_feed_get_options('variation_query_type');
613
+ if ('variable' === $variation_query) {
614
+ $variations = $product->get_visible_children();
615
+ if (is_array($variations) && (sizeof($variations) > 0)) {
616
+ if (woo_feed_is_debugging_enabled()) {
617
+ woo_feed_log_feed_process($this->config['filename'], sprintf('Getting Variation Product(s) :: %s', implode(', ', $variations)));
618
+ }
619
+ $this->get_products($variations);
620
+ return true;
621
+ }
622
+ }
623
+ }
624
+
625
+ return false;
626
+ }
627
+
628
+ /**
629
+ * Process The Attributes and assign value to merchant attribute
630
+ *
631
+ * @param WC_Abstract_Legacy_Product $product
632
+ *
633
+ * @return void
634
+ * @since 3.3.9
635
+ */
636
+ protected function process_attributes($product)
637
+ {
638
+ // print_r($this->config['attributes']);
639
+ // Get Product Attribute values by type and assign to product array
640
+ foreach ($this->config['attributes'] as $attr_key => $attribute) {
641
+
642
+ $merchant_attribute = isset($this->config['mattributes'][$attr_key]) ? $this->config['mattributes'][$attr_key] : '';
643
+
644
+ if ($this->exclude_current_attribute($product, $merchant_attribute, $attribute)) {
645
+ continue;
646
+ }
647
+
648
+ // Add Prefix and Suffix into Output
649
+ $prefix = $this->config['prefix'][$attr_key];
650
+ $suffix = $this->config['suffix'][$attr_key];
651
+ $merchant = $this->config['provider'];
652
+ $feedType = $this->config['feedType'];
653
+
654
+ if ('pattern' == $this->config['type'][$attr_key]) {
655
+ $attributeValue = $this->config['default'][$attr_key];
656
+ } else { // Get Pattern value
657
+ $attributeValue = $this->getAttributeValueByType($product, $attribute, $merchant_attribute);
658
+ }
659
+
660
+ // Format Output according to Output Type config.
661
+ if (isset($this->config['output_type'][$attr_key])) {
662
+ $outputType = $this->config['output_type'][$attr_key];
663
+ $attributeValue = $this->format_output($attributeValue, $this->config['output_type'][$attr_key], $product, $attribute, $merchant_attribute);
664
+ }
665
+
666
+ // Limit Output.
667
+ if (isset($this->config['limit'][$attr_key])) {
668
+ $attributeValue = $this->crop_string($attributeValue, 0, $this->config['limit'][$attr_key]);
669
+ }
670
+
671
+ // Process prefix and suffix.
672
+ $attributeValue = $this->process_prefix_suffix($attributeValue, $prefix, $suffix, $attribute);
673
+
674
+ if ('xml' == $feedType) {
675
+
676
+ // Replace XML Nodes according to merchant requirement.
677
+ $getReplacedAttribute = woo_feed_replace_to_merchant_attribute($merchant_attribute, $merchant, $feedType);
678
+
679
+ // XML does not support space in node. So replace Space with Underscore.
680
+ $getReplacedAttribute = str_replace(' ', '_', $getReplacedAttribute);
681
+
682
+ // Trim XML Element text & Encode for UTF-8.
683
+ if (!empty($attributeValue)) {
684
+ $attributeValue = trim($attributeValue);
685
+
686
+ if ('custom' === $this->config['provider'] && strpos($attributeValue, '<![CDATA[') === false) {
687
+ $attributeValue = htmlentities($attributeValue, ENT_XML1 | ENT_QUOTES, 'UTF-8');
688
+ }
689
+ }
690
+
691
+ // Add closing XML node if value is empty
692
+ if ('' !== $attributeValue) {
693
+ // Add CDATA wrapper for XML feed to prevent XML error.
694
+ $attributeValue = woo_feed_add_cdata($merchant_attribute, $attributeValue, $merchant, $this->config['feedType']);
695
+ // print_r($attributeValue);echo"<br/>";
696
+ // Strip slash from output.
697
+ $attributeValue = stripslashes($attributeValue);
698
+ $this->feedBody .= '<' . $getReplacedAttribute . '>' . "$attributeValue" . '</' . $getReplacedAttribute . '>';
699
+ $this->feedBody .= "\n";
700
+ } else {
701
+ $this->feedBody .= '<' . $getReplacedAttribute . '/>';
702
+ $this->feedBody .= "\n";
703
+ }
704
+
705
+ } elseif (in_array($feedType, ['csv', 'tsv', 'xls'], true)) {
706
+ $merchant_attribute = woo_feed_replace_to_merchant_attribute($merchant_attribute, $merchant, $feedType);
707
+ $merchant_attribute = $this->processStringForCSV($merchant_attribute);
708
+
709
+ if ("shipping" === $merchant_attribute && 'bing' == $this->config['provider']) {
710
+ $merchant_attribute = 'shipping(country:service:price)';
711
+ } elseif ("shipping" === $merchant_attribute) {
712
+ $merchant_attribute = 'shipping(country:region:service:price)';
713
+ }
714
+
715
+ if ("tax" === $merchant_attribute) {
716
+ $merchant_attribute = 'tax(country:region:rate:tax_ship)';
717
+ }
718
+
719
+ $attributeValue = $this->processStringForCSV($attributeValue);
720
+
721
+ } elseif ('txt' == $feedType) {
722
+ $merchant_attribute = woo_feed_replace_to_merchant_attribute($merchant_attribute, $merchant, $feedType);
723
+ $merchant_attribute = $this->processStringForTXT($merchant_attribute);
724
+
725
+ if ("shipping" === $merchant_attribute && 'bing' == $this->config['provider']) {
726
+ $merchant_attribute = 'shipping(country:service:price)';
727
+ } elseif ("shipping" === $merchant_attribute) {
728
+ $merchant_attribute = 'shipping(country:region:service:price)';
729
+ }
730
+
731
+ if ("tax" === $merchant_attribute) {
732
+ $merchant_attribute = 'tax(country:region:rate:tax_ship)';
733
+ }
734
+
735
+ $attributeValue = $this->processStringForTXT($attributeValue);
736
+ }
737
+
738
+ $this->products[$this->pi][$merchant_attribute] = $attributeValue;
739
+ }
740
+ }
741
+
742
+ /**
743
+ * Process Nested Attributes
744
+ *
745
+ * @return array
746
+ * @since 4.0.5
747
+ *
748
+ */
749
+ protected function feed_nested_attributes()
750
+ {
751
+ return [
752
+ 'reviewer' => ['reviewer', 'name'],
753
+ 'ratings' => ['ratings', 'overall'],
754
+ 'product_url' => ['products', 'product', 'product_url'],
755
+ ];
756
+ }
757
+
758
+ /**
759
+ * Process Nested Attributes
760
+ *
761
+ * @param string $attribute //product feed tag
762
+ * @param string $content //product feed content
763
+ *
764
+ * @return string
765
+ * @since 4.0.5
766
+ *
767
+ */
768
+
769
+ protected function nested_attributes_element($attribute, $content)
770
+ {
771
+ $starter = '';
772
+ $finisher = '';
773
+ $element = '';
774
+
775
+ if (empty($attribute)) {
776
+ return $attribute;
777
+ }
778
+
779
+ $attr_names = $this->feed_nested_attributes();
780
+
781
+ foreach ($attr_names as $key => $value) {
782
+ if ($key === $attribute) {
783
+ //starter tags element
784
+ foreach ($value as $item_value) {
785
+ $starter .= '<' . strval($item_value) . '>';
786
+ }
787
+
788
+ //finishing tags element
789
+ $rev_value = array_reverse($value);
790
+ foreach ($rev_value as $item_value) {
791
+ $finisher .= '</' . strval($item_value) . '>';
792
+ }
793
+ }
794
+ }
795
+
796
+ $element = $starter . $content . $finisher;
797
+
798
+ return $element;
799
+ }
800
+
801
+ /**
802
+ * Check if current product should be processed for feed
803
+ * This should be using by Woo_Feed_Products_v3::get_products()
804
+ *
805
+ * @param WC_Product $product
806
+ *
807
+ * @return bool
808
+ * @since 3.3.9
809
+ *
810
+ */
811
+ protected function exclude_from_loop($product)
812
+ {
813
+ // Skip for invalid products
814
+ if (!is_object($product)) {
815
+ woo_feed_log_feed_process($this->config['filename'], 'Skipping Product :: Product data is not a valid WC_Product object.');
816
+ return true;
817
+ }
818
+
819
+ // For WP_Query check available product types
820
+ if ('wp' == $this->queryType && !in_array($product->get_type(), $this->product_types, true)) {
821
+ woo_feed_log_feed_process($this->config['filename'], sprintf('Skipping Product :: Invalid Post/Product Type : %s.', $product->get_type()));
822
+ return true;
823
+ }
824
+
825
+ // Skip orphaned variation
826
+ if ($product->is_type('variation') && !$product->get_parent_id()) {
827
+ woo_feed_log_feed_process($this->config['filename'], sprintf('Skipping Product :: Orphaned variation product [id: %s] skipped.', $product->get_id()));
828
+ return true;
829
+ }
830
+
831
+ // Skip for invisible products
832
+ if (!$product->is_visible()) {
833
+ woo_feed_log_feed_process($this->config['filename'], 'Skipping Product :: Product is not visible.');
834
+ return true;
835
+ }
836
+ return false;
837
+ }
838
+
839
+ /**
840
+ * Check if current attribute/merchant attribute should be processed for feed
841
+ * This should be using by Woo_Feed_Products_v3::get_products()
842
+ *
843
+ * @param WC_Product $product
844
+ * @param string $merchant_attribute
845
+ * @param string $product_attribute
846
+ * @param string $feedType
847
+ *
848
+ * @return bool
849
+ *
850
+ * @since 3.3.9
851
+ *
852
+ */
853
+ protected function exclude_current_attribute($product, $merchant_attribute, $product_attribute, $feedType = 'xml')
854
+ {
855
 
856
+ if (empty($merchant_attribute)) {
857
+ return true;
858
+ }
859
 
860
+ if (
861
+ in_array($this->config['provider'], array_keys($this->skipped_merchant_attributes)) &&
862
+ in_array($merchant_attribute, $this->skipped_merchant_attributes[$this->config['provider']])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
863
 
864
+ ) {
865
+ return true;
866
+ }
 
 
 
 
867
 
868
+ if ('shopping_ads_excluded_country' !== $merchant_attribute && in_array($merchant_attribute, $this->processed_merchant_attributes)) {
869
+ return true;
870
+ }
871
 
872
+ $this->processed_merchant_attributes[] = $merchant_attribute;
 
 
 
 
 
873
 
874
+ return false;
875
+ }
 
 
 
 
876
 
877
+ /**
878
+ * Wrapper for substr with <![CDATA[string]]> support
879
+ *
880
+ * @param string $string
881
+ * @param int $start
882
+ * @param int $limit
883
+ *
884
+ * @return string
885
+ * @see substr
886
+ *
887
+ */
888
+ protected function crop_string($string, $start = 0, $limit = null)
889
+ {
890
+ $limit = absint($limit);
891
+ if ($limit > 0) {
892
+ $start = absint($start);
893
+ if (strpos($string, '<![CDATA[') !== false) {
894
+ $string = str_replace(array('<![CDATA[', ']]>'), array('', ''), $string);
895
+ $string = substr($string, $start, $limit);
896
+ $string = '<![CDATA[' . $string . ']]>';
897
+ } else {
898
+ $string = substr($string, $start, $limit);
899
+ }
900
+ }
901
+ return $string;
902
+ }
903
+
904
+ /**
905
+ * Process feed data according to merchant uncommon requirements like Google
906
+ *
907
+ * @param object $productObj WC_Product
908
+ * @param int $index Product Index
909
+ *
910
+ * @since 3.2.0
911
+ */
912
+ protected function process_for_merchant($productObj, $index)
913
+ {
914
+ $product = $this->products[$index];
915
+ $merchantAttributes = $this->config['mattributes'];
916
+ $s = 0; // Shipping Index
917
+ $i = 0; // Installment Index
918
+ $t = 0; // Tax Index
919
+ $tax = '';
920
+ $shipping = '';
921
+ $sub = 0;
922
+ $subscription = '';
923
+ $ins = 0; // Installment Index
924
+ $installment = "";
925
+ $product_detail = '';
926
+ $unit_price = '';
927
+ $additional_variant_attribute = '';
928
+ $pd = 0;
929
+ $up = 0; //Unit Price for facebook
930
+ $av = 0; //Additional Variant Attribute for facebook
931
+
932
+
933
+ // Format Shipping and Tax data for CSV and TXT feed only for google and facebook
934
+
935
+ if ('xml' != $this->config['feedType'] && in_array($this->config['provider'], array('google', 'facebook', 'bing', 'snapchat', 'pinterest'))) {
936
+ foreach ($merchantAttributes as $key => $value) {
937
+
938
+ if (!in_array($value, $this->google_shipping_tax, true)) {
939
+ continue;
940
+ }
941
+
942
+ # Get value by attribute type with prefix & suffix
943
+ $output = $this->process_for_merchant_get_value($productObj, $key);
944
+
945
+ if ('shipping_country' == $value) {
946
+ $s++;
947
+ $shipping .= $output;
948
+ }
949
+ if ('shipping_region' == $value) {
950
+ $shipping .= ':' . $output;
951
+ } elseif ('shipping_postal_code' == $value) {
952
+ $shipping .= ':' . $output;
953
+ }
954
+ if ('shipping_service' == $value) {
955
+ $shipping .= ':' . $output;
956
+ }
957
+ if ('shipping_price' == $value) {
958
+ $shipping .= ':' . $output;
959
+ }
960
+
961
+ if ('section_name' == $value) {
962
+ $pd++;
963
+ $product_detail .= $output;
964
+ }
965
+ if ('attribute_name' == $value) {
966
+ $product_detail .= ':' . $output;
967
+ }
968
+ if ('attribute_value' == $value) {
969
+ $product_detail .= ':' . $output;
970
+ }
971
+
972
+ //facebook nested attributes
973
+ if (isset($this->config['provider']) && "facebook" === $this->config['provider']) {
974
+ if ('unit_price_value' == $value) {
975
+ $up++;
976
+ $unit_price .= $output;
977
+ }
978
+ if ('unit_price_currency' == $value) {
979
+ $unit_price .= ':' . $output;
980
+ }
981
+ if ('unit_price_unit' == $value) {
982
+ $unit_price .= ':' . $output;
983
+ }
984
+
985
+ if ('additional_variant_label' == $value) {
986
+ $av++;
987
+ $additional_variant_attribute .= $output;
988
+ }
989
+ if ('additional_variant_value' == $value) {
990
+ $additional_variant_attribute .= ':' . $output;
991
+ }
992
+
993
+ if (0 < $up) {
994
+ $this->products[$this->pi]["unit_price"] = $unit_price;
995
+ }
996
+
997
+ if (0 < $av) {
998
+ $this->products[$this->pi]["additional_variant_attribute"] = $additional_variant_attribute;
999
+ }
1000
+ }
1001
+
1002
+
1003
+ if ('installment_months' == $value) {
1004
+ $ins++;
1005
+ $installment .= $output;
1006
+ }
1007
+ if ('installment_amount' == $value) {
1008
+ $installment .= ':' . $output;
1009
+ }
1010
+
1011
+ if ('subscription_period' == $value) {
1012
+ $sub++;
1013
+ $subscription .= $output;
1014
+ }
1015
+ if ('subscription_period_length' == $value) {
1016
+ $subscription .= ':' . $output;
1017
+ }
1018
+ if ('subscription_amount' == $value) {
1019
+ $subscription .= ':' . $output;
1020
+ }
1021
+ }
1022
+
1023
+ if (0 < $pd) {
1024
+ $this->products[$this->pi]["product detail"] = $product_detail;
1025
+ }
1026
+
1027
+ if (0 < $sub) {
1028
+ $this->products[$this->pi]["subscription cost"] = $subscription;
1029
+
1030
+ }
1031
+
1032
+ if (0 < $ins) {
1033
+ $this->products[$this->pi]["installment"] = $installment;
1034
+ }
1035
+ }
1036
+
1037
+
1038
+ if (in_array($this->config['provider'], array('google', 'facebook', 'snapchat', 'bing', 'pinterest'))) {
1039
+
1040
+
1041
+ // Reformat Shipping attributes for google, facebook
1042
+ if ('xml' == $this->config['feedType']) {
1043
+ foreach ($merchantAttributes as $key => $value) {
1044
+
1045
+ if (!in_array($value, $this->google_shipping_tax)) {
1046
+ continue;
1047
+ }
1048
+
1049
+
1050
+ # Get value by attribute type with prefix & suffix
1051
+ $output = $this->process_for_merchant_get_value($productObj, $key);
1052
+
1053
+
1054
+ if ('shipping_country' == $value) {
1055
+ if (0 == $s) {
1056
+ $shipping .= '<g:shipping>';
1057
+ $s = 1;
1058
+ } else {
1059
+ $shipping .= '</g:shipping>' . "\n";
1060
+ $shipping .= '<g:shipping>';
1061
+ }
1062
+ } elseif (!in_array('shipping_country', $merchantAttributes) && 'shipping_price' == $value) {
1063
+ if (0 == $s) {
1064
+ $shipping .= '<g:shipping>';
1065
+ $s = 1;
1066
+ } else {
1067
+ $shipping .= '</g:shipping>' . "\n";
1068
+ $shipping .= '<g:shipping>';
1069
+ }
1070
+ }
1071
+
1072
+ if ('shipping_country' == $value) {
1073
+ $shipping .= '<g:country>' . $output . '</g:country>' . "\n";
1074
+ } elseif ('shipping_region' == $value) {
1075
+ $shipping .= '<g:region>' . $output . '</g:region>' . "\n";
1076
+ } elseif ('shipping_region' == $value) {
1077
+ $shipping .= '<g:region>' . $output . '</g:region>' . "\n";
1078
+ } elseif ('shipping_service' == $value) {
1079
+ $shipping .= '<g:service>' . $output . '</g:service>' . "\n";
1080
+ } elseif ('shipping_postal_code' == $value) {
1081
+ $shipping .= '<g:postal_code>' . $output . '</g:postal_code>' . "\n";
1082
+ } elseif ('shipping_price' == $value) {
1083
+ $shipping .= '<g:price>' . $output . '</g:price>' . "\n";
1084
+ } elseif ('tax_country' == $value) {
1085
+ if (0 == $t) {
1086
+ $tax .= '<g:tax>';
1087
+ $t = 1;
1088
+ } else {
1089
+ $tax .= '</g:tax>' . "\n";
1090
+ $tax .= '<g:tax>';
1091
+ }
1092
+ $tax .= '<g:country>' . $output . '</g:country>' . "\n";
1093
+ } elseif ('tax_region' == $value) {
1094
+ $tax .= '<g:region>' . $output . '</g:region>' . "\n";
1095
+ } elseif ('tax_rate' == $value) {
1096
+ $tax .= '<g:rate>' . $output . '</g:rate>' . "\n";
1097
+ } elseif ('tax_ship' == $value) {
1098
+ $tax .= '<g:tax_ship>' . $output . '</g:tax_ship>' . "\n";
1099
+ } elseif ('subscription_period' == $value) {
1100
+ if (0 == $sub) {
1101
+ $subscription .= '<g:subscription_cost>';
1102
+ $sub = 1;
1103
+ } else {
1104
+ $subscription .= '</g:subscription_cost>' . "\n";
1105
+ $subscription .= '<g:subscription_cost>';
1106
+ }
1107
+ $subscription .= '<g:period>' . $output . '</g:period>' . "\n";
1108
+ } elseif ('subscription_period_length' == $value) {
1109
+ $subscription .= '<g:period_length>' . $output . '</g:period_length>' . "\n";
1110
+ } elseif ('subscription_amount' == $value) {
1111
+ $subscription .= '<g:amount>' . $output . '</g:amount>' . "\n";
1112
+ }
1113
+
1114
+ if ('section_name' == $value) {
1115
+ if (0 == $pd) {
1116
+ $product_detail .= '<g:product_detail>';
1117
+ $pd = 1;
1118
+ } else {
1119
+ $product_detail .= '</g:product_detail>' . "\n";
1120
+ $product_detail .= '<g:product_detail>';
1121
+ }
1122
+ } elseif (!in_array('section_name', $merchantAttributes) && 'attribute_name' == $value) {
1123
+ if (0 == $pd) {
1124
+ $product_detail .= '<g:product_detail>';
1125
+ $pd = 1;
1126
+ } else {
1127
+ $product_detail .= '</g:product_detail>' . "\n";
1128
+ $product_detail .= '<g:product_detail>';
1129
+ }
1130
+ }
1131
+
1132
+ if ('section_name' == $value) {
1133
+ $product_detail .= '<g:section_name>' . $output . '</g:section_name>' . "\n";
1134
+ } elseif ('attribute_name' == $value) {
1135
+ $product_detail .= '<g:attribute_name>' . $output . '</g:attribute_name>' . "\n";
1136
+ } elseif ('attribute_value' == $value) {
1137
+ $product_detail .= '<g:attribute_value>' . $output . '</g:attribute_value>' . "\n";
1138
+ }
1139
+
1140
+ if (isset($this->config['provider']) && "facebook" === $this->config['provider']) {
1141
+
1142
+ // unit_price configure
1143
+ if ('unit_price_value' == $value) {
1144
+ if (0 == $up) {
1145
+ $unit_price .= '<unit_price>';
1146
+ $up = 1;
1147
+ } else {
1148
+ $unit_price .= '</unit_price>' . "\n";
1149
+ $unit_price .= '<unit_price>';
1150
+ }
1151
+ } elseif (!in_array('unit_price_value', $merchantAttributes) && 'unit_price_currency' == $value) {
1152
+ if (0 == $up) {
1153
+ $unit_price .= '<unit_price>';
1154
+ $up = 1;
1155
+ } else {
1156
+ $unit_price .= '</unit_price>' . "\n";
1157
+ $unit_price .= '<unit_price>';
1158
+ }
1159
+ }
1160
+
1161
+ if ('unit_price_value' == $value) {
1162
+ $unit_price .= '<value>' . $output . '</value>' . "\n";
1163
+ } elseif ('unit_price_currency' == $value) {
1164
+ $unit_price .= '<currency>' . $output . '</currency>' . "\n";
1165
+ } elseif ('unit_price_unit' == $value) {
1166
+ $unit_price .= '<unit>' . $output . '</unit>' . "\n";
1167
+ }
1168
+
1169
+ // additional_variant_attribute configure
1170
+ if ('additional_variant_label' == $value) {
1171
+ if (0 == $av) {
1172
+ $additional_variant_attribute .= '<additional_variant_attribute>';
1173
+ $av = 1;
1174
+ } else {
1175
+ $additional_variant_attribute .= '</additional_variant_attribute>' . "\n";
1176
+ $additional_variant_attribute .= '<additional_variant_attribute>';
1177
+ }
1178
+ } elseif (!in_array('additional_variant_label', $merchantAttributes) && 'additional_variant_value' == $value) {
1179
+ if (0 == $av) {
1180
+ $additional_variant_attribute .= '<additional_variant_attribute>';
1181
+ $av = 1;
1182
+ } else {
1183
+ $additional_variant_attribute .= '</additional_variant_attribute>' . "\n";
1184
+ $additional_variant_attribute .= '<additional_variant_attribute>';
1185
+ }
1186
+ }
1187
+
1188
+ if ('additional_variant_label' == $value) {
1189
+ $additional_variant_attribute .= '<label>' . $output . '</label>' . "\n";
1190
+ } elseif ('additional_variant_value' == $value) {
1191
+ $additional_variant_attribute .= '<value>' . $output . '</value>' . "\n";
1192
+ }
1193
+ }
1194
+
1195
+
1196
+ if ('installment_months' === $value) {
1197
+ if (0 == $ins) {
1198
+ $installment .= '<g:installment>';
1199
+ $ins = 1;
1200
+ } else {
1201
+ $installment .= '</g:installment>' . "\n";
1202
+ $installment .= '<g:installment>';
1203
+ }
1204
+ $installment .= '<g:months>' . $output . '</g:months>' . "\n";
1205
+ } elseif ('installment_amount' == $value) {
1206
+ $installment .= '<g:amount>' . $output . '</g:amount>' . "\n";
1207
+ }
1208
+ }
1209
+
1210
+ if (1 == $pd) {
1211
+ $product_detail .= '</g:product_detail>';
1212
+ }
1213
+
1214
+ if (isset($this->config['provider']) && "facebook" === $this->config['provider']) {
1215
+ if (1 == $up) {
1216
+ $unit_price .= '</unit_price>';
1217
+ }
1218
+
1219
+ if (1 == $av) {
1220
+ $additional_variant_attribute .= '</additional_variant_attribute>';
1221
+ }
1222
+
1223
+ $this->feedBody .= $unit_price;
1224
+ $this->feedBody .= $additional_variant_attribute;
1225
+ }
1226
+
1227
+ if (1 == $s) {
1228
+ $shipping .= '</g:shipping>';
1229
+ }
1230
+ if (1 == $t) {
1231
+ $tax .= '</g:tax>';
1232
+ }
1233
+
1234
+ if (1 == $sub) {
1235
+ $subscription .= '</g:subscription_cost>';
1236
+ }
1237
+
1238
+ if (1 == $ins) {
1239
+ $installment .= '</g:installment>';
1240
+ }
1241
+
1242
+ //$this->feedBody .= $shipping;
1243
+ //$this->feedBody .= $tax;
1244
+ $this->feedBody .= $product_detail;
1245
+ $this->feedBody .= $installment;
1246
+
1247
+ if ($productObj->is_type('subscription') ||
1248
+ $productObj->is_type('variable-subscription') ||
1249
+ $productObj->is_type('subscription_variation')) {
1250
+ $this->feedBody .= $subscription;
1251
+ }
1252
+ }
1253
+ // ADD g:identifier_exists
1254
+ $identifier = array('brand', 'upc', 'sku', 'mpn', 'gtin');
1255
+ $countIdentifier = 0;
1256
+ if (!in_array('identifier_exists', $merchantAttributes)) {
1257
+ if (count(array_intersect_key(array_flip($identifier), $product)) >= 2) {
1258
+ // Any 2 required keys exist!
1259
+ // @TODO Refactor with OR
1260
+ if (array_key_exists('brand', $product) && !empty($product['brand'])) {
1261
+ $countIdentifier++;
1262
+ }
1263
+ if (array_key_exists('upc', $product) && !empty($product['upc'])) {
1264
+ $countIdentifier++;
1265
+ }
1266
+ if (array_key_exists('sku', $product) && !empty($product['sku'])) {
1267
+ $countIdentifier++;
1268
+ }
1269
+ if (array_key_exists('mpn', $product) && !empty($product['mpn'])) {
1270
+ $countIdentifier++;
1271
+ }
1272
+ if (array_key_exists('gtin', $product) && !empty($product['gtin'])) {
1273
+ $countIdentifier++;
1274
+ }
1275
+ }
1276
+
1277
+ if ('xml' == $this->config['feedType']) {
1278
+ if ($countIdentifier >= 2) {
1279
+ $this->feedBody .= '<g:identifier_exists>yes</g:identifier_exists>';
1280
+ } else {
1281
+ $this->feedBody .= '<g:identifier_exists>no</g:identifier_exists>';
1282
+ }
1283
+ } else {
1284
+ $identifier_exists = 'identifier exists';
1285
+ if (in_array($this->config['provider'], array('bing', 'pinterest'))) {
1286
+ $identifier_exists = 'identifier_exists';
1287
+ }
1288
+
1289
+ if ($countIdentifier >= 2) {
1290
+ $this->products[$this->pi][$identifier_exists] = 'yes';
1291
+ } else {
1292
+ $this->products[$this->pi][$identifier_exists] = 'no';
1293
+ }
1294
+ }
1295
+ }
1296
+ }
1297
+ }
1298
+
1299
+ private function process_for_merchant_get_value($productObj, $key)
1300
+ {
1301
+ $prefix = $this->config['prefix'][$key];
1302
+ $suffix = $this->config['suffix'][$key];
1303
+ $attribute = $this->config['attributes'][$key];
1304
+ $merchant_attribute = $this->config['mattributes'][$key];
1305
+
1306
+ if ('pattern' == $this->config['type'][$key]) {// Get Pattern value.
1307
+ $output = $this->config['default'][$key];
1308
+ $output = $this->apply_filters_to_attribute_value($output, $productObj, $attribute, $merchant_attribute);
1309
+ } else {
1310
+ $output = $this->getAttributeValueByType($productObj, $attribute, $merchant_attribute);
1311
+ }
1312
+
1313
+ $output = $this->format_output($output, $this->config['output_type'], $productObj, $attribute, $merchant_attribute);
1314
+
1315
+ $output = $this->process_prefix_suffix($output, $prefix, $suffix, $attribute = '');
1316
+
1317
+ return $output;
1318
+ }
1319
+
1320
+ /**
1321
+ * Get Query Type Settings
1322
+ * @return string
1323
+ */
1324
+ public function get_query_type()
1325
+ {
1326
+ return $this->queryType;
1327
+ }
1328
+
1329
+ public function get_product_types()
1330
+ {
1331
+ return $this->product_types;
1332
+ }
1333
+
1334
+ /**
1335
+ * Generate TXT Feed Header
1336
+ *
1337
+ * @return string
1338
+ * @since 3.2.0
1339
+ *
1340
+ */
1341
+ protected function process_txt_feed_header()
1342
+ {
1343
+ // Set Delimiter
1344
+ if ('tab' == $this->config['delimiter']) {
1345
+ $this->delimiter = "\t";
1346
+ } else {
1347
+ $this->delimiter = $this->config['delimiter'];
1348
+ }
1349
+
1350
+ // Set Enclosure
1351
+ if (!empty($this->config['enclosure'])) {
1352
+ $this->enclosure = $this->config['enclosure'];
1353
+ if ('double' == $this->enclosure) {
1354
+ $this->enclosure = '"';
1355
+ } elseif ('single' == $this->enclosure) {
1356
+ $this->enclosure = "'";
1357
+ } else {
1358
+ $this->enclosure = '';
1359
+ }
1360
+ } else {
1361
+ $this->enclosure = '';
1362
+ }
1363
+
1364
+ $eol = PHP_EOL;
1365
+ if ('trovaprezzi' === $this->config['provider']) {
1366
+ $eol = '<endrecord>' . PHP_EOL;
1367
+ }
1368
+
1369
+ $product = $this->products[$this->pi];
1370
+
1371
+ $headers = array_keys($product);
1372
+
1373
+ $this->feedHeader .= $this->enclosure . implode("$this->enclosure$this->delimiter$this->enclosure", $headers) . $this->enclosure . $eol;
1374
+
1375
+ if ('google' === $this->config['provider']) {
1376
+ $this->feedHeader = str_replace($this->google_product_highlights, 'product highlight', $this->feedHeader);
1377
+ $this->feedHeader = str_replace($this->google_additional_image, 'additional image link', $this->feedHeader);
1378
+ }
1379
+
1380
+ return $this->feedHeader;
1381
+ }
1382
+
1383
+ /**
1384
+ * Generate TXT Feed Body
1385
+ *
1386
+ * @return string
1387
+ * @since 3.2.0
1388
+ *
1389
+ */
1390
+ protected function process_txt_feed_body()
1391
+ {
1392
+ $productInfo = array_values($this->products[$this->pi]);
1393
+ $eol = PHP_EOL;
1394
+ if ('trovaprezzi' === $this->config['provider']) {
1395
+ $eol = '<endrecord>' . PHP_EOL;
1396
+ }
1397
+ $this->feedBody .= $this->enclosure . implode("$this->enclosure$this->delimiter$this->enclosure", $productInfo) . $this->enclosure . $eol;
1398
+
1399
+ return $this->feedBody;
1400
+ }
1401
+
1402
+ /**
1403
+ * Generate CSV Feed Header
1404
+ *
1405
+ * @return array
1406
+ * @since 3.2.0
1407
+ *
1408
+ */
1409
+ protected function process_csv_feed_header()
1410
+ {
1411
+ // Set Delimiter
1412
+ if ('tab' == $this->config['delimiter']) {
1413
+ $this->delimiter = "\t";
1414
+ } else {
1415
+ $this->delimiter = $this->config['delimiter'];
1416
+ }
1417
+
1418
+ // Set Enclosure
1419
+ if (!empty($this->config['enclosure'])) {
1420
+ $this->enclosure = $this->config['enclosure'];
1421
+ if ('double' == $this->enclosure) {
1422
+ $this->enclosure = '"';
1423
+ } elseif ('single' == $this->enclosure) {
1424
+ $this->enclosure = "'";
1425
+ } else {
1426
+ $this->enclosure = '';
1427
+ }
1428
+ } else {
1429
+ $this->enclosure = '';
1430
+ }
1431
+
1432
+ $product = $this->products[$this->pi];
1433
+
1434
+ $this->feedHeader = array_keys($product);
1435
+
1436
+ if ('google' === $this->config['provider']) {
1437
+ $this->feedHeader = str_replace($this->google_product_highlights, 'product highlight', $this->feedHeader);
1438
+ $this->feedHeader = str_replace($this->google_additional_image, 'additional image link', $this->feedHeader);
1439
+ }
1440
+
1441
+ return $this->feedHeader;
1442
+ }
1443
+
1444
+ /**
1445
+ * Generate CSV Feed Body
1446
+ * @return array
1447
+ * @since 3.2.0
1448
+ */
1449
+ protected function process_csv_feed_body()
1450
+ {
1451
+ $product = $this->products[$this->pi];
1452
+ $this->feedBody[] = array_values($product);
1453
+
1454
+ return $this->feedBody;
1455
+ }
1456
+
1457
+ protected function process_json_feed_body()
1458
+ {
1459
+ $product = $this->products[$this->pi];
1460
+ $this->feedBody[] = $product;
1461
+
1462
+ return $this->feedBody;
1463
+ }
1464
+
1465
+ protected function process_xml_wrapper()
1466
+ {
1467
+ $itemsWrapperClose = explode(' ', $this->config['itemsWrapper']);
1468
+ $itemsWrapperClose = $itemsWrapperClose[0];
1469
+ $this->xml_wrapper = [
1470
+ 'header' => '<?xml version="1.0" encoding="UTF-8" ?>' . PHP_EOL . '<' . wp_unslash($this->config['itemsWrapper']) . '>',
1471
+ 'footer' => PHP_EOL . '</' . $itemsWrapperClose . '>',
1472
+ ];
1473
+ $this->config['itemWrapper'] = str_replace(' ', '_', $this->config['itemWrapper']);
1474
+ $this->config['itemsWrapper'] = str_replace(' ', '_', $this->config['itemsWrapper']);
1475
+
1476
+ if (file_exists(WOO_FEED_FREE_ADMIN_PATH . 'partials/templates/' . $this->config['provider'] . '.txt')) {
1477
+ $txt = file_get_contents(WOO_FEED_FREE_ADMIN_PATH . 'partials/templates/' . $this->config['provider'] . '.txt');
1478
+ $txt = trim($txt);
1479
+ $txt = explode('{separator}', $txt);
1480
+ if (2 === count($txt)) {
1481
+ $this->xml_wrapper['header'] = trim($txt[0]);
1482
+ $this->xml_wrapper['footer'] = "\n" . trim($txt[1]);
1483
+ }
1484
+ }
1485
+
1486
+ if (!empty($this->config['extraHeader'])) {
1487
+ $this->xml_wrapper['header'] .= PHP_EOL . $this->config['extraHeader'];
1488
+ }
1489
+
1490
+ // replace template variables.
1491
+ $datetime_now = date('Y-m-d H:i:s', strtotime(current_time('mysql'))); // {DateTimeNow}
1492
+ if ('pinterest_rss' === $this->config['provider']) { // DATE_RFC822 date format for pinterest rss feed
1493
+ $datetime_now = date('r', strtotime(current_time('mysql'))); // {DateTimeNow}
1494
+ }
1495
+ $blog_name = get_bloginfo('name'); // {BlogName}
1496
+ $blog_url = get_bloginfo('url'); // {BlogURL}
1497
+ //$blog_desc = get_bloginfo('description'); // {BlogDescription}
1498
+ $blog_desc = "CTX Feed - This product feed is generated with the CTX Feed - WooCommerce Product Feed Manager plugin by WebAppick.com. For all your support questions check out our plugin Docs on https://webappick.com/docs or e-mail to: support@webappick.com"; // {BlogDescription}
1499
+ $blog_email = get_bloginfo('admin_email'); // {BlogEmail}
1500
+
1501
+ $this->xml_wrapper['header'] = str_replace(
1502
+ ['{DateTimeNow}', '{BlogName}', '{BlogURL}', '{BlogDescription}', '{BlogEmail}'],
1503
+ [$datetime_now, $blog_name, $blog_url, $blog_desc, $blog_email],
1504
+ $this->xml_wrapper['header']
1505
+ );
1506
+ }
1507
+
1508
+ /**
1509
+ * Make XML feed header
1510
+ * @return string
1511
+ * @since 3.2.0
1512
+ */
1513
+ protected function process_xml_feed_header()
1514
+ {
1515
+ return $this->xml_wrapper['header'];
1516
+ }
1517
+
1518
+ /**
1519
+ * Make XML feed header
1520
+ * @return string
1521
+ * @since 3.2.0
1522
+ */
1523
+ protected function process_xml_feed_footer()
1524
+ {
1525
+ return $this->xml_wrapper['footer'];
1526
+ }
1527
+
1528
+ /**
1529
+ * Process string for TXT CSV Feed
1530
+ *
1531
+ * @param $string
1532
+ *
1533
+ * @return mixed|string
1534
+ * @since 3.2.0
1535
+ *
1536
+ */
1537
+ protected function processStringForTXT($string)
1538
+ {
1539
+ if (!empty($string)) {
1540
+ $string = html_entity_decode($string, ENT_HTML401 | ENT_QUOTES); // Convert any HTML entities
1541
+
1542
+ if (stristr($string, '"')) {
1543
+ $string = str_replace('"', '""', $string);
1544
+ }
1545
+ $string = str_replace("\n", ' ', $string);
1546
+ $string = str_replace("\r", ' ', $string);
1547
+ $string = str_replace("\t", ' ', $string);
1548
+ $string = trim($string);
1549
+ $string = stripslashes($string);
1550
+
1551
+ return $string;
1552
+ } elseif ('0' == $string) {
1553
+ return '0';
1554
+ } else {
1555
+ return '';
1556
+ }
1557
+ }
1558
+
1559
+ /**
1560
+ * Process string for CSV
1561
+ *
1562
+ * @param $string
1563
+ *
1564
+ * @return mixed|string
1565
+ * @since 3.2.0
1566
+ *
1567
+ */
1568
+ protected function processStringForCSV($string)
1569
+ {
1570
+ if (!empty($string)) {
1571
+ $string = str_replace("\n", ' ', $string);
1572
+ $string = str_replace("\r", ' ', $string);
1573
+ $string = trim($string);
1574
+ $string = stripslashes($string);
1575
+
1576
+ return $string;
1577
+ } elseif ('0' == $string) {
1578
+ return '0';
1579
+ } else {
1580
+ return '';
1581
+ }
1582
+ }
1583
+
1584
+ /**
1585
+ * Get Product Attribute Value by Type
1586
+ *
1587
+ * @param $product WC_Product
1588
+ * @param $attribute
1589
+ *
1590
+ * @return mixed|string
1591
+ * @since 3.2.0
1592
+ *
1593
+ */
1594
+ public function getAttributeValueByType($product, $attribute, $merchant_attribute = '')
1595
+ {
1596
 
1597
+ if (method_exists($this, $attribute)) {
1598
+ $output = $this->$attribute($product);
1599
+ } elseif ( false !== strpos( $attribute, self::PRODUCT_ACF_FIELDS ) ) {
1600
+ $output = $this->getACFField( $product, $attribute );
1601
+ } elseif (false !== strpos($attribute, self::PRODUCT_CUSTOM_IDENTIFIER) || woo_feed_strpos_array(array('_identifier_gtin', '_identifier_ean', '_identifier_mpn'), $attribute)) {
1602
+ $output = $this->getCustomField($product, $attribute);
1603
+ } elseif (false !== strpos($attribute, self::PRODUCT_ATTRIBUTE_PREFIX)) {
1604
+ $attribute = str_replace(self::PRODUCT_ATTRIBUTE_PREFIX, '', $attribute);
1605
+ $output = $this->getProductAttribute($product, $attribute);
1606
+ } elseif (false !== strpos($attribute, self::POST_META_PREFIX)) {
1607
+ $attribute = str_replace(self::POST_META_PREFIX, '', $attribute);
1608
+ $output = $this->getProductMeta($product, $attribute);
1609
+ } elseif (false !== strpos($attribute, self::PRODUCT_TAXONOMY_PREFIX)) {
1610
+ $attribute = str_replace(self::PRODUCT_TAXONOMY_PREFIX, '', $attribute);
1611
+ $output = $this->getProductTaxonomy($product, $attribute);
1612
+ } elseif (false !== strpos($attribute, self::PRODUCT_CATEGORY_MAPPING_PREFIX)) {
1613
+ $id = $product->is_type('variation') ? $product->get_parent_id() : $product->get_id();
1614
+ $output = woo_feed_get_category_mapping_value($attribute, $id);
1615
+ } elseif (false !== strpos($attribute, self::WP_OPTION_PREFIX)) {
1616
+ $optionName = str_replace(self::WP_OPTION_PREFIX, '', $attribute);
1617
+ $output = get_option($optionName);
1618
+ } elseif ('image_' == substr($attribute, 0, 6)) {
1619
+ // For additional image method images() will be used with extra parameter - image number
1620
+ $imageKey = explode('_', $attribute);
1621
+ if (!isset($imageKey[1]) || (isset($imageKey[1]) && (empty($imageKey[1]) || !is_numeric($imageKey[1])))) {
1622
+ $imageKey[1] = '';
1623
+ }
1624
+ $output = call_user_func_array(array($this, 'images'), array($product, $imageKey[1]));
1625
+ } else {
1626
+ // return the attribute so multiple attribute can be join with separator to make custom attribute.
1627
+ $output = $attribute;
1628
+ }
1629
+
1630
+ // Json encode if value is an array
1631
+ if (is_array($output)) {
1632
+ $output = wp_json_encode($output);
1633
+ }
1634
+
1635
+ $output = $this->apply_filters_to_attribute_value($output, $product, $attribute, $merchant_attribute);
1636
+
1637
+ return $output;
1638
+ }
1639
+
1640
+ /**
1641
+ * Apply Filter to Attribute value
1642
+ *
1643
+ * @param $output
1644
+ * @param $product
1645
+ * @param $attribute
1646
+ * @param $merchant_attribute
1647
+ *
1648
+ * @return mixed|void
1649
+ */
1650
+ protected function apply_filters_to_attribute_value($output, $product, $attribute, $merchant_attribute)
1651
+ {
1652
+ /**
1653
+ * Filter attribute value
1654
+ *
1655
+ * @param string $output the output
1656
+ * @param WC_Abstract_Legacy_Product $product Product Object.
1657
+ * @param array feed config/rule
1658
+ *
1659
+ * @since 3.4.3
1660
+ *
1661
+ */
1662
+ $output = apply_filters('woo_feed_get_attribute', $output, $product, $this->config, $merchant_attribute);
1663
+
1664
+ /**
1665
+ * Filter attribute value before return based on attribute name
1666
+ *
1667
+ * @param string $output the output
1668
+ * @param WC_Abstract_Legacy_Product $product Product Object.
1669
+ * @param array feed config/rule
1670
+ *
1671
+ * @since 3.3.5
1672
+ *
1673
+ */
1674
+ $output = apply_filters("woo_feed_get_{$attribute}_attribute", $output, $product, $this->config);
1675
+
1676
+ /**
1677
+ * Filter attribute value before return based on merchant and attribute name
1678
+ *
1679
+ * @param string $output the output
1680
+ * @param WC_Abstract_Legacy_Product $product Product Object.
1681
+ * @param array feed config/rule
1682
+ *
1683
+ * @since 3.3.7
1684
+ *
1685
+ */
1686
+ $output = apply_filters("woo_feed_get_{$this->config['provider']}_{$attribute}_attribute", $output, $product, $this->config);
1687
+
1688
+ return $output;
1689
+ }
1690
+
1691
+
1692
+ /**
1693
+ * Get Product Id
1694
+ *
1695
+ * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product Product Object.
1696
+ *
1697
+ * @return mixed
1698
+ * @since 3.2.0
1699
+ */
1700
+ protected function id($product)
1701
+ {
1702
+ $id = $product->get_id();
1703
+
1704
+ return apply_filters('woo_feed_filter_product_id', $id, $product, $this->config);
1705
+ }
1706
+
1707
+ /**
1708
+ * Get Product Title
1709
+ *
1710
+ * @param WC_Product $product
1711
+ *
1712
+ * @return mixed
1713
+ * @since 3.2.0
1714
+ *
1715
+ */
1716
+ protected function title($product)
1717
+ {
1718
+ $title = woo_feed_strip_all_tags($this->remove_short_codes($product->get_name()));
1719
+
1720
+ // Add all available variation attributes to variation title.
1721
+ if ($product->is_type('variation') && !empty($product->get_attributes())) {
1722
+ $title = $this->parent_title($product);
1723
+ $attributes = [];
1724
+ foreach ($product->get_attributes() as $slug => $value) {
1725
+ $attribute = $product->get_attribute($slug);
1726
+ if (empty($attribute)) {
1727
+ continue;
1728
+ }
1729
+ $attributes[$slug] = $attribute;
1730
+ }
1731
+
1732
+ // set variation attributes with separator
1733
+ if (isset($this->config['provider']) && 'google' === $this->config['provider']) {
1734
+ $variation_attributes = implode(' - ', $attributes);
1735
+ } else {
1736
+ $variation_attributes = implode(', ', $attributes);
1737
+ }
1738
+
1739
+ //get product title with variation attribute
1740
+ $get_with_var_attributes = apply_filters("woo_feed_get_product_title_with_variation_attribute", true, $product, $this->config);
1741
+
1742
+ if ($get_with_var_attributes) {
1743
+ $title .= " - " . $variation_attributes;
1744
+ }
1745
+ }
1746
+
1747
+ return apply_filters('woo_feed_filter_product_title', $title, $product, $this->config);
1748
+ }
1749
+
1750
+ /**
1751
+ * Get Parent Product Title
1752
+ *
1753
+ * @param WC_Product $product Product Object.
1754
+ *
1755
+ * @return mixed
1756
+ * @author Nazrul Islam Nayan
1757
+ * @since 5.1.8
1758
+ */
1759
+ protected function parent_title($product)
1760
+ {
1761
+ if ($product->is_type('variation')) {
1762
+ $product = wc_get_product($product->get_parent_id());
1763
+ $title = woo_feed_strip_all_tags($this->remove_short_codes($product->get_name()));
1764
+ } else {
1765
+ $title = $this->title($product);
1766
+ }
1767
+
1768
+ return apply_filters('woo_feed_filter_product_parent_title', $title, $product, $this->config);
1769
+ }
1770
+
1771
+ /**
1772
+ * Get All in One SEO Canonical URL
1773
+ *
1774
+ * @param WC_Product $product
1775
+ *
1776
+ * @return mixed
1777
+ * @since 4.4.12
1778
+ */
1779
+ protected function _aioseop_canonical_url($product)
1780
+ {
1781
+ $aioseop_canonical_url = '';
1782
+ if (is_plugin_active('all-in-one-seo-pack/all_in_one_seo_pack.php') && class_exists('AIOSEO\Plugin\Common\Models\Post')) {
1783
+ $post = AIOSEO\Plugin\Common\Models\Post::getPost($product->get_id());
1784
+ $aioseop_canonical_url = $post->canonical_url;
1785
+ }
1786
+
1787
+ return apply_filters('woo_feed_filter_product_aioseop_canonical_url', $aioseop_canonical_url, $product, $this->config);
1788
+ }
1789
+
1790
+ /**
1791
+ * Get Yoast Product Title
1792
+ *
1793
+ * @param WC_Product $product
1794
+ *
1795
+ * @return mixed
1796
+ * @since 3.2.0
1797
+ *
1798
+ */
1799
+ protected function yoast_wpseo_title($product)
1800
+ {
1801
+ $product_id = woo_feed_parent_product_id($product);
1802
+ $yoast_title = get_post_meta($product_id, '_yoast_wpseo_title', true);
1803
+ if (strpos($yoast_title, '%%') !== false) {
1804
+ $title = strstr($yoast_title, '%%', true);
1805
+ if (empty($title)) {
1806
+ $title = get_the_title($product_id);
1807
+ }
1808
+ $wpseo_titles = get_option('wpseo_titles');
1809
+
1810
+ $sep_options = WPSEO_Option_Titles::get_instance()->get_separator_options();
1811
+ if (isset($wpseo_titles['separator']) && isset($sep_options[$wpseo_titles['separator']])) {
1812
+ $sep = $sep_options[$wpseo_titles['separator']];
1813
+ } else {
1814
+ $sep = '-'; //setting default separator if Admin didn't set it from backed
1815
+ }
1816
+
1817
+ $site_title = get_bloginfo('name');
1818
+
1819
+ $meta_title = $title . ' ' . $sep . ' ' . $site_title;
1820
+
1821
+ if (!empty($meta_title)) {
1822
+ $title = $meta_title;
1823
+ }
1824
+ } elseif (!empty($yoast_title)) {
1825
+ $title = $yoast_title;
1826
+ } else {
1827
+ $title = $this->title($product);
1828
+ }
1829
+
1830
+ return apply_filters('woo_feed_filter_product_yoast_wpseo_title', $title, $product, $this->config);
1831
+ }
1832
+
1833
+ /**
1834
+ * Get Yoast Canonical URL
1835
+ *
1836
+ * @param WC_Product $product
1837
+ *
1838
+ * @return mixed
1839
+ * @since 4.3.77
1840
+ */
1841
+ protected function yoast_canonical_url($product)
1842
+ {
1843
+ $product_id = woo_feed_parent_product_id($product);
1844
+ $yoast_canonical_url = get_post_meta($product_id, '_yoast_wpseo_canonical', true);
1845
+
1846
+ return apply_filters('woo_feed_filter_product_yoast_canonical_url', $yoast_canonical_url, $product, $this->config);
1847
+ }
1848
+
1849
+ /**
1850
+ * Get Rank Math Product Title
1851
+ *
1852
+ * @param WC_Product $product
1853
+ *
1854
+ * @return mixed
1855
+ * @since 5.1.3
1856
+ */
1857
+ protected function rank_math_title($product)
1858
+ {
1859
+ $rank_title = '';
1860
+ $post_title = '';
1861
+ $page = '';
1862
+ $sep = '';
1863
+ $sitemap = '';
1864
+ if (class_exists('RankMath')) {
1865
+ $title = get_post_meta($product->get_id(), 'rank_math_title', true);
1866
+ if (empty($title)) {
1867
+ $title_format = Helper::get_settings("titles.pt_product_title");
1868
+ $title_format = $title_format ? $title_format : '%title%';
1869
+ $sep = Helper::get_settings('titles.title_separator');
1870
+
1871
+ $rank_title = str_replace('%title%', $product->get_title(), $title_format);
1872
+ $rank_title = str_replace('%sep%', $sep, $rank_title);
1873
+ $rank_title = str_replace('%page%', '', $rank_title);
1874
+ $rank_title = str_replace('%sitename%', get_bloginfo('name'), $rank_title);
1875
+ } else {
1876
+ $rank_title = $title;
1877
+ }
1878
+ }
1879
+
1880
+ return apply_filters('woo_feed_filter_product_rank_math_title', $rank_title, $product, $this->config);
1881
+ }
1882
+
1883
+ /**
1884
+ * Get Rank Math Product Description
1885
+ *
1886
+ * @param WC_Product $product
1887
+ *
1888
+ * @return mixed
1889
+ * @since 5.1.3
1890
+ */
1891
+ protected function rank_math_description($product)
1892
+ {
1893
+ $description = '';
1894
+ if (class_exists('RankMath')) {
1895
+ $description = get_post_meta($product->get_id(), 'rank_math_description');
1896
+ $desc_format = Helper::get_settings("titles.pt_post_description");
1897
+
1898
+ if (empty($description)) {
1899
+ if (!empty($desc_format) && strpos((string)$desc_format, 'excerpt') !== false) {
1900
+ $description = str_replace('%excerpt%', get_the_excerpt($product->get_id()), $desc_format);
1901
+ }
1902
+
1903
+ // Get Variation Description
1904
+ if ($product->is_type('variation') && empty($description)) {
1905
+ $parent = wc_get_product($product->get_parent_id());
1906
+ $description = $parent->get_description();
1907
+ }
1908
+ }
1909
+
1910
+ if (is_array($description)) {
1911
+ $description = reset($description);
1912
+ }
1913
+
1914
+ $description = $this->remove_short_codes($description);
1915
+
1916
+ //strip tags and spacial characters
1917
+ $strip_description = woo_feed_strip_all_tags(wp_specialchars_decode($description));
1918
+
1919
+ $description = !empty(strlen($strip_description)) && 0 < strlen($strip_description) ? $strip_description : $description;
1920
+ }
1921
+
1922
+ return apply_filters('woo_feed_filter_product_rank_math_description', $description, $product, $this->config);
1923
+ }
1924
+
1925
+ /**
1926
+ * Get Rank Math Canonical URL
1927
+ *
1928
+ * @param WC_Product $product
1929
+ *
1930
+ * @return mixed
1931
+ * @since 5.1.6
1932
+ */
1933
+ protected function rank_math_canonical_url($product)
1934
+ {
1935
+ $canonical_url = '';
1936
 
1937
+ if (class_exists('RankMath')) {
1938
+ $post_canonical_url = get_post_meta($product->get_id(), 'rank_math_canonical_url');
 
 
 
 
1939
 
1940
+ if (empty($post_canonical_url)) {
1941
+ $canonical_url = get_the_permalink($product->get_id());
1942
+ } else {
1943
+ $canonical_url = $post_canonical_url;
1944
+ }
 
 
 
1945
 
1946
+ if (is_array($canonical_url)) {
1947
+ $canonical_url = reset($canonical_url);
1948
+ }
1949
+ }
 
 
 
1950
 
1951
+ return apply_filters('woo_feed_filter_product_rank_math_canonical_url', $canonical_url, $product, $this->config);
1952
+ }
 
 
 
 
 
 
 
 
 
 
 
1953
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1954
 
1955
+ /**
1956
+ * Get All In One Product Title
1957
+ *
1958
+ * @param WC_Product $product
1959
+ *
1960
+ * @return mixed
1961
+ * @since 3.2.0
1962
+ *
1963
+ */
1964
+ protected function _aioseop_title($product)
1965
+ {
1966
+ $title = '';
1967
+ if (is_plugin_active('all-in-one-seo-pack/all_in_one_seo_pack.php') && class_exists('AIOSEO\Plugin\Common\Models\Post')) {
 
 
 
 
 
 
 
 
 
 
1968
 
1969
+ $post = AIOSEO\Plugin\Common\Models\Post::getPost($product->get_id());
1970
+ $title = !empty($post->title) ? $post->title : aioseo()->meta->title->getPostTypeTitle('product');
1971
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1972
 
1973
+ $title = !empty($title) ? $title : $this->title($product);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1974
 
1975
+ return apply_filters('woo_feed_filter_product_aioseop_title', $title, $product, $this->config);
1976
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1977
 
1978
+ /**
1979
+ * Get Product Description
1980
+ *
1981
+ * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product Product Object.
1982
+ *
1983
+ * @return mixed|string
1984
+ * @since 3.2.0
1985
+ *
1986
+ */
1987
+ protected function description($product)
1988
+ {
1989
+ $description = $product->get_description();
1990
+
1991
+ // Get Variation Description
1992
+ if ($product->is_type('variation') && empty($description)) {
1993
+ $parent = wc_get_product($product->get_parent_id());
1994
+
1995
+ if (is_object($parent)) {
1996
+ $description = $parent->get_description();
1997
+ } else {
1998
+ $description = '';
1999
+ }
2000
+ }
2001
+ $description = $this->remove_short_codes($description);
2002
+
2003
+ // Add variations attributes after description to prevent Facebook error
2004
+ if ('facebook' == $this->config['provider'] && $product->is_type('variation')) {
2005
+ $variationInfo = explode('-', $product->get_name());
2006
+ if (isset($variationInfo[1])) {
2007
+ $extension = $variationInfo[1];
2008
+ } else {
2009
+ $extension = $product->get_id();
2010
+ }
2011
+ $description .= ' ' . $extension;
2012
+ }
2013
+
2014
+ //strip tags and spacial characters
2015
+ $strip_description = woo_feed_strip_all_tags(wp_specialchars_decode($description));
2016
+
2017
+ $description = !empty(strlen($strip_description)) && 0 < strlen($strip_description) ? $strip_description : $description;
2018
+
2019
+ return apply_filters('woo_feed_filter_product_description', $description, $product, $this->config);
2020
+ }
2021
+
2022
+ /**
2023
+ * Get Product Description (with HTML)
2024
+ *
2025
+ * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product Product Object.
2026
+ *
2027
+ * @return mixed|string
2028
+ * @since 5.2.41
2029
+ */
2030
+ protected function description_with_html($product)
2031
+ {
2032
+ $description = $product->get_description();
2033
+
2034
+ // Get Variation Description
2035
+ if ($product->is_type('variation') && empty($description)) {
2036
+ $parent = wc_get_product($product->get_parent_id());
2037
+ $description = $parent->get_description();
2038
+ }
2039
+ $description = $this->remove_short_codes($description);
2040
+
2041
+ // Add variations attributes after description to prevent Facebook error
2042
+ if ('facebook' === $this->config['provider'] && $product->is_type('variation')) {
2043
+ $variationInfo = explode('-', $product->get_name());
2044
+ if (isset($variationInfo[1])) {
2045
+ $extension = $variationInfo[1];
2046
+ } else {
2047
+ $extension = $product->get_id();
2048
+ }
2049
+ $description .= ' ' . $extension;
2050
+ }
2051
+
2052
+ //remove spacial characters
2053
+ $strip_description = wp_check_invalid_utf8(wp_specialchars_decode($description), true);
2054
+
2055
+ return apply_filters('woo_feed_filter_product_description_with_html', $description, $product, $this->config);
2056
+ }
2057
+
2058
+ /**
2059
+ * Get Yoast Product Description
2060
+ *
2061
+ * @param WC_Product $product
2062
+ *
2063
+ * @return mixed
2064
+ * @since 3.2.0
2065
+ *
2066
+ */
2067
+ protected function yoast_wpseo_metadesc($product)
2068
+ {
2069
+ $product_id = woo_feed_parent_product_id($product);
2070
+ $description = '';
2071
+ if (class_exists('WPSEO_Frontend')) {
2072
+ $description = wpseo_replace_vars(WPSEO_Meta::get_value('metadesc', $product_id),
2073
+ get_post($product->get_id()));
2074
+ } else {
2075
+ $description = YoastSEO()->meta->for_post($product_id)->description;
2076
+ }
2077
+
2078
+ if (empty($description)) {
2079
+ $description = $this->description($product);
2080
+ }
2081
+
2082
+ return apply_filters('woo_feed_filter_product_yoast_wpseo_metadesc', $description, $product, $this->config);
2083
+ }
2084
+
2085
+ /**
2086
+ * Get All In One Product Description
2087
+ *
2088
+ * @param WC_Product $product
2089
+ *
2090
+ * @return mixed
2091
+ * @since 3.2.0
2092
+ *
2093
+ */
2094
+ protected function _aioseop_description($product)
2095
+ {
2096
+ $description = '';
2097
 
2098
+ if (is_plugin_active('all-in-one-seo-pack/all_in_one_seo_pack.php') && class_exists('AIOSEO\Plugin\Common\Models\Post')) {
 
2099
 
2100
+ $post = AIOSEO\Plugin\Common\Models\Post::getPost($product->get_id());
2101
+ $description = !empty($post->description) ? $post->description : aioseo()->meta->description->getPostTypeDescription('product');
2102
+ }
 
 
 
 
 
 
2103
 
2104
+ if (empty($description)) {
2105
+ $description = $this->description($product);
2106
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
2107
 
2108
+ return apply_filters('woo_feed_filter_product_aioseop_description', $description, $product, $this->config);
2109
+ }
2110
 
2111
+ /**
2112
+ * Get Product Short Description
2113
+ *
2114
+ * @param WC_Product $product
2115
+ *
2116
+ * @return mixed|string
2117
+ * @since 3.2.0
2118
+ *
2119
+ */
2120
+ protected function short_description($product)
2121
+ {
2122
+ $short_description = $product->get_short_description();
2123
 
2124
+ // Get Variation Short Description
2125
+ if ($product->is_type('variation') && empty($short_description)) {
2126
+ $parent = wc_get_product($product->get_parent_id());
2127
+ $short_description = $parent->get_short_description();
2128
+ }
2129
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2130
 
2131
+ $short_description = $this->remove_short_codes($short_description);
 
 
 
 
 
 
 
 
 
 
 
2132
 
2133
+ //strip tags and spacial characters
2134
+ $short_description = woo_feed_strip_all_tags(wp_specialchars_decode($short_description));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2135
 
2136
+ return apply_filters('woo_feed_filter_product_short_description', $short_description, $product, $this->config);
2137
+ }
2138
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2139
 
2140
+ /**
2141
+ * At First convert Short Codes and then Remove failed Short Codes from String
2142
+ *
2143
+ * @param $content
2144
+ *
2145
+ * @return mixed|string
2146
+ * @since 3.2.0
2147
+ *
2148
+ */
2149
+ protected function remove_short_codes($content)
2150
+ {
2151
+ if ($content == '') {
2152
+ return '';
2153
+ }
 
2154
 
2155
+ $content = do_shortcode($content);
 
 
 
 
 
 
 
 
 
2156
 
2157
+ $content = woo_feed_stripInvalidXml($content);
 
 
 
 
2158
 
2159
+ // Covers all kinds of shortcodes
2160
+ $expression = '/\[\/*[a-zA-Z1-90_| -=\'"\{\}]*\/*\]/m';
 
2161
 
2162
+ $content = preg_replace($expression, '', $content);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2163
 
2164
+ return strip_shortcodes($content);
2165
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2166
 
2167
+ /*
2168
+ * Retrieves product's parent category
2169
+ *
2170
+ * @param $product A Post/Product object
2171
+ *
2172
+ * @return WP_Term
2173
+ * @since 4.4.19
2174
+ * */
2175
+ protected function product_parent_category_object($product)
2176
+ {
2177
+ global $parent_category_memo;
2178
+ if (empty($parent_category_memo)) {
2179
+ $parent_category_memo = [];
2180
+ }
2181
+
2182
+ $id = $product->get_id();
2183
+ if ($product->is_type('variation')) {
2184
+ $id = $product->get_parent_id();
2185
+ }
2186
+
2187
+ $taxonomy = 'product_cat';
2188
+ $categories = wp_get_post_terms($id, $taxonomy);
2189
+ $child_category = $categories[count($categories) - 1]; // Last selected category
2190
+
2191
+ $parent_category = '';
2192
+
2193
+ // Memoization for faster parent retrieval
2194
+ if (
2195
+ isset($parent_category_memo[$child_category->term_id])
2196
+ && !empty($parent_category_memo[$child_category->term_id])
2197
+ ) {
2198
+ $parent_category = get_term_by('term_id', $parent_category_memo[$child_category->term_id], $taxonomy);
2199
+ } else {
2200
+ $parent_category = woo_feed_parent_category($child_category, $taxonomy);
2201
+ $parent_category_memo[$child_category->term_id] = $parent_category->term_id;
2202
+ }
2203
+
2204
+ // Yoast SEO primary term fetching
2205
+ if (class_exists('WPSEO_Primary_Term')) {
2206
+ $wpseo_primary_term = new WPSEO_Primary_Term($taxonomy, $id);
2207
+ $parent_category_id = $wpseo_primary_term->get_primary_term();
2208
+ if (!empty($parent_category_id)) {
2209
+ $parent_category = get_term_by('term_id', $parent_category_id, $taxonomy);
2210
+ }
2211
+ }
2212
+
2213
+ return $parent_category;
2214
+ }
2215
+
2216
+ /**
2217
+ * Get Product Parent/Main Category
2218
+ *
2219
+ * @param WC_Product $product
2220
+ *
2221
+ * @return string
2222
+ *
2223
+ */
2224
+ protected function primary_category($product)
2225
+ {
2226
+ $parent_category = "";
2227
+ $separator = apply_filters('woo_feed_product_type_separator', ' > ', $this->config, $product);
2228
+ $full_category = $this->product_type($product);
2229
+ if (!empty($full_category)) {
2230
+ $full_category_array = explode($separator, $full_category);
2231
+ $parent_category = $full_category_array[0];
2232
+ }
2233
+
2234
+ return apply_filters('woo_feed_filter_product_primary_category', $parent_category, $product, $this->config);
2235
+ }
2236
+
2237
+ /**
2238
+ * Get Product Parent/Main Category ID
2239
+ *
2240
+ * @param WC_Product $product
2241
+ *
2242
+ * @return string
2243
+ *
2244
+ */
2245
+ protected function primary_category_id($product)
2246
+ {
2247
+ $parent_category_id = "";
2248
+ $separator = apply_filters('woo_feed_product_type_separator', ' > ', $this->config, $product);
2249
+ $full_category = $this->product_type($product);
2250
+ if (!empty($full_category)) {
2251
+ $full_category_array = explode($separator, $full_category);
2252
+ $parent_category_obj = get_term_by('name', $full_category_array[0], 'product_cat');
2253
+ $parent_category_id = isset($parent_category_obj->term_id) ? $parent_category_obj->term_id : "";
2254
+ }
2255
+
2256
+ return apply_filters('woo_feed_filter_product_primary_category_id', $parent_category_id, $product, $this->config);
2257
+ }
2258
+
2259
+ /**
2260
+ * Get Product Child Category
2261
+ *
2262
+ * @param WC_Product $product
2263
+ *
2264
+ * @return string
2265
+ */
2266
+ protected function child_category($product)
2267
+ {
2268
+ $child_category = "";
2269
+ $separator = apply_filters('woo_feed_product_type_separator', ' > ', $this->config, $product);
2270
+ $full_category = $this->product_type($product);
2271
+ if (!empty($full_category)) {
2272
+ $full_category_array = explode($separator, $full_category);
2273
+ $child_category = end($full_category_array);
2274
+ }
2275
+
2276
+ return apply_filters('woo_feed_filter_product_child_category', $child_category, $product, $this->config);
2277
+ }
2278
+
2279
+ /**
2280
+ * Get Product Child Category ID
2281
+ *
2282
+ * @param WC_Product $product
2283
+ *
2284
+ * @return string
2285
+ */
2286
+ protected function child_category_id($product)
2287
+ {
2288
+ $child_category_id = "";
2289
+ $separator = apply_filters('woo_feed_product_type_separator', ' > ', $this->config, $product);
2290
+ $full_category = $this->product_type($product);
2291
+ if (!empty($full_category)) {
2292
+ $full_category_array = explode($separator, $full_category);
2293
+ $child_category_obj = get_term_by('name', end($full_category_array), 'product_cat');
2294
+ $child_category_id = isset($child_category_obj->term_id) ? $child_category_obj->term_id : "";
2295
+ }
2296
+
2297
+ return apply_filters('woo_feed_filter_product_child_category_id', $child_category_id, $product, $this->config);
2298
+ }
2299
+
2300
+ /**
2301
+ * Get Product Categories
2302
+ *
2303
+ * @param WC_Product $product
2304
+ *
2305
+ * @return string
2306
+ * @since 3.2.0
2307
+ *
2308
+ */
2309
+ protected function product_type($product)
2310
+ {
2311
+ $id = $product->get_id();
2312
+ if ($product->is_type('variation')) {
2313
+ $id = $product->get_parent_id();
2314
+ }
2315
 
2316
+ $separator = apply_filters('woo_feed_product_type_separator', ' > ', $this->config, $product);
 
 
2317
 
2318
+ $product_type = woo_feed_strip_all_tags(wc_get_product_category_list($id, $separator));
 
 
2319
 
2320
+ $product_categories = '';
2321
+ $term_list = get_the_terms($id, 'product_cat');
2322
 
2323
+ if (is_array($term_list)) {
2324
+ $col = array_column($term_list, "term_id");
2325
+ array_multisort($col, SORT_ASC, $term_list);
2326
+ $term_list = array_column($term_list, "name");
2327
+ $product_categories = implode($separator, $term_list);
2328
+ }
2329
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2330
 
2331
+ return apply_filters('woo_feed_filter_product_local_category', $product_categories, $product, $this->config);
2332
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2333
 
2334
+ /**
2335
+ * Get Product Full Categories with unselected category parent
2336
+ *
2337
+ * @param WC_Product $product
2338
+ *
2339
+ * @return string
2340
+ * @since 4.3.47
2341
+ */
2342
+ protected function product_full_cat($product)
2343
+ {
2344
+ // $id = $product->get_id();
2345
+ // if ($product->is_type('variation')) {
2346
+ // $id = $product->get_parent_id();
2347
+ // }
2348
+ //
2349
+ // $separator = apply_filters('woo_feed_product_type_separator', '>', $this->config, $product);
2350
+ //
2351
+ // $product_type = woo_feed_get_terms_list_hierarchical_order($id);
2352
 
2353
+ $product_type = $this->product_type($product);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2354
 
2355
+ return apply_filters('woo_feed_filter_product_local_category', $product_type, $product, $this->config);
2356
+ }
 
 
 
 
 
 
 
 
 
 
 
2357
 
2358
+ /**
2359
+ * Get Product URL
2360
+ *
2361
+ * @param WC_Product|WC_Product_Variation $product
2362
+ *
2363
+ * @return string
2364
+ * @since 3.2.0
2365
+ *
2366
+ */
2367
+ protected function link($product)
2368
+ {
2369
 
2370
+ $link = $product->get_permalink();
2371
 
2372
+ $link = $this->add_utm_tracker($link);
2373
+ return apply_filters('woo_feed_filter_product_link', $link, $product, $this->config);
2374
+ }
2375
 
2376
+ /**
2377
+ * Adding UTM Tracker Query Arguments to URL
2378
+ * @param string $url
2379
+ *
2380
+ * @return string $url
2381
+ * @since 4.4.26
2382
+ */
2383
+ protected function add_utm_tracker($url)
2384
+ {
2385
 
2386
+ $utm = $this->config['campaign_parameters'];
 
 
 
2387
 
2388
+ if (!empty($utm['utm_source']) && !empty($utm['utm_medium']) && !empty($utm['utm_campaign'])) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2389
 
2390
+ $utm = [
2391
+ 'utm_source' => str_replace(' ', '+', $utm['utm_source']),
2392
+ 'utm_medium' => str_replace(' ', '+', $utm['utm_medium']),
2393
+ 'utm_campaign' => str_replace(' ', '+', $utm['utm_campaign']),
2394
+ 'utm_term' => str_replace(' ', '+', $utm['utm_term']),
2395
+ 'utm_content' => str_replace(' ', '+', $utm['utm_content']),
2396
+ ];
 
 
 
 
 
 
2397
 
2398
+ $url = add_query_arg(array_filter($utm), $url);
 
 
 
2399
 
2400
+ }
2401
 
2402
+ return $url;
2403
+ }
2404
 
2405
+ /**
2406
+ * Get Parent Product URL
2407
+ *
2408
+ * @param WC_Product $product
2409
+ *
2410
+ * @return string
2411
+ * @author Nazrul Islam Nayan
2412
+ * @since 5.1.8
2413
+ */
2414
+ protected function parent_link($product)
2415
+ {
2416
+ if ($product->is_type('variation')) {
2417
+ $product = wc_get_product($product->get_parent_id());
2418
+ $link = $this->link($product);
2419
+ } else {
2420
+ $link = $this->link($product);
2421
+ }
2422
+
2423
+ return apply_filters('woo_feed_filter_product_parent_link', $link, $product, $this->config);
2424
+ }
2425
+
2426
+ /**
2427
+ * Get Canonical Link
2428
+ * @param WC_Product $product
2429
+ * @return mixed
2430
+ */
2431
+ protected function canonical_link($product)
2432
+ {
2433
+ if ($product->is_type('variation')) {
2434
+ $product = wc_get_product($product->get_parent_id());
2435
+ $canonical_link = $product->get_permalink();
2436
+ } else {
2437
+ $canonical_link = $product->get_permalink();
2438
+ }
2439
+
2440
+ return apply_filters('woo_feed_filter_product_canonical_link', $canonical_link, $product, $this->config);
2441
+ }
2442
+
2443
+ /**
2444
+ * Get External Product URL
2445
+ *
2446
+ * @param WC_Product $product
2447
+ *
2448
+ * @return string
2449
+ * @since 3.2.0
2450
+ *
2451
+ */
2452
+ protected function ex_link($product)
2453
+ {
2454
+ if ($product->is_type('external')) {
2455
+ $utm = $this->config['campaign_parameters'];
2456
+ if (!empty($utm['utm_source']) && !empty($utm['utm_medium']) && !empty($utm['utm_campaign'])) {
2457
+ $utm = [
2458
+ 'utm_source' => str_replace(' ', '+', $utm['utm_source']),
2459
+ 'utm_medium' => str_replace(' ', '+', $utm['utm_medium']),
2460
+ 'utm_campaign' => str_replace(' ', '+', $utm['utm_campaign']),
2461
+ 'utm_term' => str_replace(' ', '+', $utm['utm_term']),
2462
+ 'utm_content' => str_replace(' ', '+', $utm['utm_content']),
2463
+ ];
2464
+
2465
+ return add_query_arg(array_filter($utm), $product->get_product_url());
2466
+ } else {
2467
+ $ex_link = $product->get_product_url();
2468
+ }
2469
+ } else {
2470
+ $ex_link = '';
2471
+ }
2472
+
2473
+ return apply_filters('woo_feed_filter_product_ex_link', $ex_link, $product, $this->config);
2474
+ }
2475
+
2476
+ /**
2477
+ * Get Product Image
2478
+ *
2479
+ * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product Product Object.
2480
+ *
2481
+ * @return mixed
2482
+ * @since 3.2.0
2483
+ *
2484
+ */
2485
+ protected function image($product)
2486
+ {
2487
+ $image = '';
2488
+ if ($product->is_type('variation')) {
2489
+ // Variation product type
2490
+ if (has_post_thumbnail($product->get_id())) {
2491
+ $getImage = wp_get_attachment_image_src(get_post_thumbnail_id($product->get_id()), 'single-post-thumbnail');
2492
+ $image = woo_feed_get_formatted_url($getImage[0]);
2493
+ } elseif (has_post_thumbnail($product->get_parent_id())) {
2494
+ $getImage = wp_get_attachment_image_src(get_post_thumbnail_id($product->get_parent_id()), 'single-post-thumbnail');
2495
+ $image = woo_feed_get_formatted_url($getImage[0]);
2496
+ }
2497
+ } elseif (has_post_thumbnail($product->get_id())) { // All product type except variation
2498
+ $getImage = wp_get_attachment_image_src(get_post_thumbnail_id($product->get_id()), 'single-post-thumbnail');
2499
+ $image = isset($getImage[0]) ? woo_feed_get_formatted_url($getImage[0]) : '';
2500
+ }
2501
+
2502
+ return apply_filters('woo_feed_filter_product_image', $image, $product, $this->config);
2503
+ }
2504
+
2505
+ /**
2506
+ * Get Product Featured Image. For product variations it will return the variable product image.
2507
+ *
2508
+ * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product Product Object.
2509
+ *
2510
+ * @return mixed
2511
+ * @since 3.2.0
2512
+ *
2513
+ */
2514
+ protected function feature_image($product)
2515
+ {
2516
+ if ($product->is_type('variation')) {
2517
+ $id = $product->get_parent_id();
2518
+ } else {
2519
+ $id = $product->get_id();
2520
+ }
2521
+
2522
+ $getImage = wp_get_attachment_image_src(get_post_thumbnail_id($id), 'single-post-thumbnail');
2523
+ $image = isset($getImage[0]) ? woo_feed_get_formatted_url($getImage[0]) : '';
2524
+
2525
+ return apply_filters('woo_feed_filter_product_feature_image', $image, $product, $this->config);
2526
+ }
2527
+
2528
+ /**
2529
+ * Get Comma Separated Product Images
2530
+ *
2531
+ * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product Product Object.
2532
+ * @param string $additionalImg Specific Additional Image.
2533
+ *
2534
+ * @return mixed
2535
+ * @since 3.2.0
2536
+ *
2537
+ */
2538
+ protected function images($product, $additionalImg = '')
2539
+ {
2540
+ $imgUrls = $this->get_product_gallery($product);
2541
+ $separator = ',';
2542
+
2543
+ // Return Specific Additional Image URL
2544
+ if ('' !== $additionalImg) {
2545
+ if (array_key_exists($additionalImg, $imgUrls)) {
2546
+ $images = $imgUrls[$additionalImg];
2547
+ } else {
2548
+ $images = '';
2549
+ }
2550
+ } else {
2551
+ if (isset($this->config['provider']) && "idealo" === $this->config['provider']) {
2552
+ $separator = ';';
2553
+ }
2554
+
2555
+ $images = implode($separator, array_filter($imgUrls));
2556
+ }
2557
+
2558
+ return apply_filters('woo_feed_filter_product_images', $images, $product, $this->config);
2559
+ }
2560
+
2561
+ /**
2562
+ * Get Product Gallery Items (URL) array.
2563
+ * This can contains empty array values
2564
+ *
2565
+ * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product
2566
+ *
2567
+ * @return string[]
2568
+ * @since 3.2.6
2569
+ */
2570
+ protected function get_product_gallery($product)
2571
+ {
2572
+ $imgUrls = [];
2573
+ $attachmentIds = [];
2574
+
2575
+ if ($product->is_type('variation')) {
2576
+ if (class_exists('Woo_Variation_Gallery')) {
2577
+ /**
2578
+ * Get Variation Additional Images for "Additional Variation Images Gallery for WooCommerce"
2579
+ * @plugin Additional Variation Images Gallery for WooCommerce
2580
+ * @link https://wordpress.org/plugins/woo-variation-gallery/
2581
+ */
2582
+ $attachmentIds = get_post_meta($product->get_id(), 'woo_variation_gallery_images', true);
2583
+ } elseif (class_exists('WooProductVariationGallery')) {
2584
+ /**
2585
+ * Get Variation Additional Images for "Variation Images Gallery for WooCommerce"
2586
+ * @plugin Variation Images Gallery for WooCommerce
2587
+ * @link https://wordpress.org/plugins/woo-product-variation-gallery/
2588
+ */
2589
+ $attachmentIds = get_post_meta($product->get_id(), 'rtwpvg_images', true);
2590
+ } elseif (class_exists('WC_Additional_Variation_Images')) {
2591
+ /**
2592
+ * Get Variation Additional Images for "WooCommerce Additional Variation Images"
2593
+ * @plugin WooCommerce Additional Variation Images
2594
+ * @link https://woocommerce.com/products/woocommerce-additional-variation-images/
2595
+ */
2596
+ $attachmentIds = explode(',', get_post_meta($product->get_id(), '_wc_additional_variation_images', true));
2597
+ } elseif (class_exists('WOODMART_Theme')) {
2598
+ /**
2599
+ * Get Variation Additional Images for "WOODMART Theme -> Variation Gallery Images Feature"
2600
+ * @theme WOODMART
2601
+ * @link https://themeforest.net/item/woodmart-woocommerce-wordpress-theme/20264492
2602
+ */
2603
+ $var_id = $product->get_id();
2604
+ $parent_id = $product->get_parent_id();
2605
+
2606
+ $variation_obj = get_post_meta($parent_id, 'woodmart_variation_gallery_data', true);
2607
+ if (isset($variation_obj) && isset($variation_obj[$var_id])) {
2608
+ $attachmentIds = explode(',', $variation_obj[$var_id]);
2609
+ } else {
2610
+ $attachmentIds = explode(',', get_post_meta($var_id, 'wd_additional_variation_images_data', true));
2611
+ }
2612
+ } else {
2613
+ /**
2614
+ * If any Variation Gallery Image plugin not installed then get Variable Product Additional Image Ids .
2615
+ */
2616
+ $attachmentIds = wc_get_product($product->get_parent_id())->get_gallery_image_ids();
2617
+ }
2618
+ }
2619
+
2620
+ /**
2621
+ * Get Variable Product Gallery Image ids if Product is not a variation
2622
+ * or variation does not have any gallery images
2623
+ */
2624
+ if (empty($attachmentIds)) {
2625
+ $attachmentIds = $product->get_gallery_image_ids();
2626
+ }
2627
+
2628
+ if ($attachmentIds && is_array($attachmentIds)) {
2629
+ $mKey = 1;
2630
+ foreach ($attachmentIds as $attachmentId) {
2631
+ $imgUrls[$mKey] = woo_feed_get_formatted_url(wp_get_attachment_url($attachmentId));
2632
+ $mKey++;
2633
+ }
2634
+ }
2635
+
2636
+ return $imgUrls;
2637
+ }
2638
+
2639
+ /**
2640
+ * Get Product Condition
2641
+ *
2642
+ * @param WC_Product $product
2643
+ *
2644
+ * @return mixed
2645
+ * @since 3.2.0
2646
+ *
2647
+ */
2648
+ protected function condition($product)
2649
+ {
2650
+ return apply_filters('woo_feed_product_condition', 'new', $product);
2651
+ }
2652
+
2653
+ /**
2654
+ * Get Product Type
2655
+ *
2656
+ * @param WC_Product $product
2657
+ *
2658
+ * @return mixed
2659
+ * @since 3.2.0
2660
+ *
2661
+ */
2662
+ protected function type($product)
2663
+ {
2664
+ return apply_filters('woo_feed_filter_product_type', $product->get_type(), $product, $this->config);
2665
+ }
2666
+
2667
+ /**
2668
+ * Get Product is a bundle product or not
2669
+ *
2670
+ * @param WC_Product $product
2671
+ *
2672
+ * @return mixed
2673
+ * @since 3.2.0
2674
+ *
2675
+ */
2676
+ protected function is_bundle($product)
2677
+ {
2678
+ if ($product->is_type('bundle') || $product->is_type('yith_bundle')) {
2679
+ $is_bundle = 'yes';
2680
+ } else {
2681
+ $is_bundle = 'no';
2682
+ }
2683
+
2684
+ return apply_filters('woo_feed_filter_product_is_bundle', $is_bundle, $product, $this->config);
2685
+ }
2686
+
2687
+ /**
2688
+ * Get Product is a multi-pack product or not
2689
+ *
2690
+ * @param WC_Product $product
2691
+ *
2692
+ * @return mixed
2693
+ * @since 3.2.0
2694
+ *
2695
+ */
2696
+ protected function multipack($product)
2697
+ {
2698
+ $multi_pack = '';
2699
+ if ($product->is_type('grouped')) {
2700
+ $multi_pack = (!empty($product->get_children())) ? count($product->get_children()) : '';
2701
+ }
2702
+
2703
+ return $multi_pack;
2704
+ }
2705
+
2706
+ /**
2707
+ * Get Product visibility status
2708
+ *
2709
+ * @param WC_Product $product
2710
+ *
2711
+ * @return mixed
2712
+ * @since 3.2.0
2713
+ *
2714
+ */
2715
+ protected function visibility($product)
2716
+ {
2717
+ return apply_filters('woo_feed_filter_product_visibility', $product->get_catalog_visibility(), $product, $this->config);
2718
+ }
2719
+
2720
+ /**
2721
+ * Get Product Total Rating
2722
+ *
2723
+ * @param WC_Product $product
2724
+ *
2725
+ * @return mixed
2726
+ * @since 3.2.0
2727
+ *
2728
+ */
2729
+ protected function rating_total($product)
2730
+ {
2731
+ return apply_filters('woo_feed_filter_product_rating_total', $product->get_rating_count(), $product, $this->config);
2732
+ }
2733
+
2734
+ /**
2735
+ * Get Product average rating
2736
+ *
2737
+ * @param WC_Product $product
2738
+ *
2739
+ * @return mixed
2740
+ * @since 3.2.0
2741
+ *
2742
+ */
2743
+ protected function rating_average($product)
2744
+ {
2745
+ return apply_filters('woo_feed_filter_product_rating_average', $product->get_average_rating(), $product, $this->config);
2746
+ }
2747
+
2748
+ /**
2749
+ * Get Product tags
2750
+ *
2751
+ * @param WC_Product $product
2752
+ *
2753
+ * @return string
2754
+ * @since 3.2.0
2755
+ *
2756
+ */
2757
+ protected function tags($product)
2758
+ {
2759
+ $id = $product->get_id();
2760
+ if ($product->is_type('variation')) {
2761
+ $id = $product->get_parent_id();
2762
+ }
2763
+
2764
+ /**
2765
+ * Separator for multiple tags
2766
+ * @param string $separator
2767
+ * @param array $config
2768
+ * @param WC_Abstract_Legacy_Product $product
2769
+ * @since 3.4.3
2770
+ */
2771
+ $separator = apply_filters('woo_feed_tags_separator', ',', $this->config, $product);
2772
+
2773
+ $tags = woo_feed_strip_all_tags(get_the_term_list($id, 'product_tag', '', $separator, ''));
2774
+
2775
+ return apply_filters('woo_feed_filter_product_tags', $tags, $product, $this->config);
2776
+ }
2777
+
2778
+ /**
2779
+ * Get Product Parent Id
2780
+ *
2781
+ * @param WC_Product $product
2782
+ *
2783
+ * @return mixed
2784
+ * @since 3.2.0
2785
+ *
2786
+ */
2787
+ protected function item_group_id($product)
2788
+ {
2789
+ $id = $product->get_id();
2790
+ if ($product->is_type('variation')) {
2791
+ $id = $product->get_parent_id();
2792
+ }
2793
+
2794
+ return apply_filters('woo_feed_filter_product_item_group_id', $id, $product, $this->config);
2795
+ }
2796
+
2797
+ /**
2798
+ * Get Product SKU
2799
+ *
2800
+ * @param WC_Product $product
2801
+ *
2802
+ * @return mixed
2803
+ * @since 3.2.0
2804
+ *
2805
+ */
2806
+ protected function sku($product)
2807
+ {
2808
+ return apply_filters('woo_feed_filter_product_sku', $product->get_sku(), $product, $this->config);
2809
+ }
2810
+
2811
+ /**
2812
+ * Get Product SKU ID. It should come with after merging of sku and product id with '_' sign.
2813
+ *
2814
+ * @param WC_Product $product
2815
+ *
2816
+ * @return string
2817
+ * @author Nazrul Islam Nayan
2818
+ * @since 4.3.13
2819
+ */
2820
+ protected function sku_id($product)
2821
+ {
2822
+ $sku = !empty($product->get_sku()) ? $product->get_sku() . '_' : '';
2823
+ $sku_id = $sku . $product->get_id();
2824
+
2825
+ return apply_filters('woo_feed_filter_product_sku_id', $sku_id, $product, $this->config);
2826
+ }
2827
+
2828
+ /**
2829
+ * Get Product Parent SKU
2830
+ *
2831
+ * @param WC_Product $product
2832
+ *
2833
+ * @return mixed
2834
+ * @since 3.2.0
2835
+ *
2836
+ */
2837
+ protected function parent_sku($product)
2838
+ {
2839
+ if ($product->is_type('variation')) {
2840
+ $id = $product->get_parent_id();
2841
+ $parent = wc_get_product($id);
2842
+
2843
+ $parent_sku = $parent->get_sku();
2844
+ } else {
2845
+ $parent_sku = $product->get_sku();
2846
+ }
2847
+
2848
+ return apply_filters('woo_feed_filter_product_parent_sku', $parent_sku, $product, $this->config);
2849
+ }
2850
+
2851
+ /**
2852
+ * Get Product Availability Status
2853
+ *
2854
+ * @param WC_Product $product
2855
+ *
2856
+ * @return mixed
2857
+ * @since 3.2.0
2858
+ *
2859
+ */
2860
+ protected function availability($product)
2861
+ {
2862
+ $status = $product->get_stock_status();
2863
+ if ('instock' == $status) {
2864
+ $status = 'in stock';
2865
+ } elseif ('outofstock' == $status) {
2866
+ $status = 'out of stock';
2867
+ } elseif ('onbackorder' == $status) {
2868
+ $status = 'on backorder';
2869
+ }
2870
+
2871
+ // set (_) as separator for google merchant
2872
+ if (isset($this->config['provider']) && 'google' === $this->config['provider']) {
2873
+ $status = explode(' ', $status);
2874
+ $status = implode('_', $status);
2875
+ }
2876
+
2877
+ return apply_filters('woo_feed_filter_product_availability', $status, $product, $this->config);
2878
+ }
2879
+
2880
+ /**
2881
+ * Get Product Availability Date
2882
+ *
2883
+ * @param WC_Product $product
2884
+ *
2885
+ * @return mixed
2886
+ * @author Ohidul Islam
2887
+ * @since 3.2.0
2888
+ *
2889
+ */
2890
+ protected function availability_date($product)
2891
+ {
2892
 
2893
+ $feed_settings = get_option('woo_feed_settings');
 
 
 
2894
 
2895
+ $availability_date_settings = isset($feed_settings['woo_feed_identifier']['availability_date'])
2896
+ ? $feed_settings['woo_feed_identifier']['availability_date']
2897
+ : 'enable';
2898
 
2899
+ if ($product->get_stock_status() !== 'onbackorder' || $availability_date_settings === 'disable') {
2900
+ return '';
2901
+ }
 
 
 
 
 
 
 
 
 
 
 
 
2902
 
2903
+ $meta_field_name = 'woo_feed_availability_date';
 
2904
 
2905
+ if ($product->is_type('variation')) {
2906
+ $meta_field_name .= '_var';
2907
+ }
 
 
 
 
 
 
 
 
 
 
 
 
2908
 
2909
+ $availability_date = get_post_meta($product->get_id(), $meta_field_name, true);
 
 
 
 
 
 
 
 
 
 
 
 
2910
 
2911
+ if ('' !== $availability_date && in_array($this->config['provider'], [
2912
+ 'google',
2913
+ 'facebook',
2914
+ 'pinterest',
2915
+ 'bing',
2916
+ 'snapchat',
2917
+ ], true)) {
2918
+ $availability_date = gmdate('c', strtotime($availability_date));
2919
+ }
2920
 
2921
+ return apply_filters('woo_feed_filter_product_availability_date', $availability_date, $product, $this->config);
2922
+ }
2923
 
2924
+ /**
2925
+ * Get Product Add to Cart Link
2926
+ *
2927
+ * @param WC_Product $product
2928
+ *
2929
+ * @return string
2930
+ * @author Nazrul Islam Nayan
2931
+ * @since 5.1.8
2932
+ */
2933
+ protected function add_to_cart_link($product)
2934
+ {
2935
+ $url = $this->link($product);
2936
+ $suffix = 'add-to-cart=' . $product->get_id();
2937
+
2938
+ $add_to_cart_link = woo_feed_make_url_with_parameter($url, $suffix);
2939
+
2940
+ return apply_filters('woo_feed_filter_product_add_to_cart_link', $add_to_cart_link, $product, $this->config);
2941
+ }
2942
+
2943
+ /**
2944
+ * Get Product Quantity
2945
+ *
2946
+ * @param WC_Product $product
2947
+ *
2948
+ * @return mixed
2949
+ * @since 3.2.0
2950
+ *
2951
+ */
2952
+ protected function quantity($product)
2953
+ {
2954
+ $quantity = $product->get_stock_quantity();
2955
+ $status = $product->get_stock_status();
2956
+
2957
+ //when product is outofstock and it's quantity is empty, set quantity to 0
2958
+ if ('outofstock' == $status && empty($quantity)) {
2959
+ $quantity = 0;
2960
+ }
2961
+
2962
+ if ($product->is_type('variable') && $product->has_child()) {
2963
+ $visible_children = $product->get_visible_children();
2964
+ $qty = array();
2965
+ foreach ($visible_children as $key => $child) {
2966
+ $childQty = get_post_meta($child, '_stock', true);
2967
+ $qty[] = (int)$childQty + 0;
2968
+ }
2969
+
2970
+ if (isset($this->config['variable_quantity'])) {
2971
+ $vaQty = $this->config['variable_quantity'];
2972
+ if ('max' == $vaQty) {
2973
+ $quantity = max($qty);
2974
+ } elseif ('min' == $vaQty) {
2975
+ $quantity = min($qty);
2976
+ } elseif ('sum' == $vaQty) {
2977
+ $quantity = array_sum($qty);
2978
+ } elseif ('first' == $vaQty) {
2979
+ $quantity = ((int)$qty[0]);
2980
+ }
2981
+
2982
+ $quantity = array_sum($qty);
2983
+ }
2984
+ }
2985
+
2986
+ return apply_filters('woo_feed_filter_product_quantity', $quantity, $product, $this->config);
2987
+ }
2988
+
2989
+ /**
2990
+ * Get Product Currency
2991
+ *
2992
+ * @param WC_Product $product
2993
+ *
2994
+ * @return mixed
2995
+ * @since 4.4.39
2996
+ *
2997
+ */
2998
+ protected function currency($product)
2999
+ {
3000
+ $quantity = get_option('woocommerce_currency');
3001
 
3002
+ return apply_filters('woo_feed_filter_product_currency', $quantity, $product, $this->config);
3003
+ }
3004
 
3005
+ /**
3006
+ * Get Store currency code.
3007
+ *
3008
+ * @param WC_Product $product Product Object
3009
+ * @return mixed|string
3010
+ * @since 3.2.0
3011
+ *
3012
+ */
3013
+ protected function store_currency($product)
3014
+ {
3015
+ return get_woocommerce_currency();
3016
+ }
3017
+
3018
+ /**
3019
+ * Get Product Sale Price Start Date
3020
+ *
3021
+ * @param WC_Product $product
3022
+ *
3023
+ * @return mixed
3024
+ * @since 3.2.0
3025
+ *
3026
+ */
3027
+ protected function sale_price_sdate($product)
3028
+ {
3029
+ $startDate = $product->get_date_on_sale_from();
3030
+ if (is_object($startDate)) {
3031
+ $sale_price_sdate = $startDate->date_i18n();
3032
+ } else {
3033
+ $sale_price_sdate = '';
3034
+ }
3035
+
3036
+ return apply_filters('woo_feed_filter_product_sale_price_sdate', $sale_price_sdate, $product, $this->config);
3037
+ }
3038
+
3039
+ /**
3040
+ * Get Product Sale Price End Date
3041
+ *
3042
+ * @param WC_Product $product
3043
+ *
3044
+ * @return mixed
3045
+ * @since 3.2.0
3046
+ *
3047
+ */
3048
+ protected function sale_price_edate($product)
3049
+ {
3050
+ $endDate = $product->get_date_on_sale_to();
3051
+ if (is_object($endDate)) {
3052
+ $sale_price_edate = $endDate->date_i18n();
3053
+ } else {
3054
+ $sale_price_edate = "";
3055
+ }
3056
+
3057
+ return apply_filters('woo_feed_filter_product_sale_price_edate', $sale_price_edate, $product, $this->config);
3058
+ }
3059
+
3060
+ /**
3061
+ * Get feed currency
3062
+ *
3063
+ * @return mixed|string
3064
+ */
3065
+ protected function get_feed_currency()
3066
+ {
3067
+ $currency = get_woocommerce_currency();
3068
+ if (isset($this->config['feedCurrency'])) {
3069
+ $currency = $this->config['feedCurrency'];
3070
+ }
3071
+
3072
+ return $currency;
3073
+ }
3074
+
3075
+ /**
3076
+ * Get Product Price by default WooCommerce Price Type (regular_price|price|sale_price).
3077
+ *
3078
+ * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product Object
3079
+ * @param string $price_type Price Type (regular_price|price|sale_price)
3080
+ * @param bool $tax Add tax with price (true|false)
3081
+ *
3082
+ * @return float|mixed|string|void
3083
+ * @since 4.4.14
3084
+ *
3085
+ * @author Ohidul Islam
3086
+ */
3087
+ protected function get_price_by_price_type($product, $price_type, $tax)
3088
+ {
3089
+
3090
+ if ('regular_price' === $price_type) {
3091
+ $price = $product->get_regular_price();
3092
+ } elseif ('price' === $price_type) {
3093
+ $price = $product->get_price();
3094
+ } else {
3095
+ $price = $product->get_sale_price();
3096
+ }
3097
+
3098
+ // Get WooCommerce Multi language Price by Currency.
3099
+ $price = apply_filters('woo_feed_wcml_price',
3100
+ $price, $product->get_id(), $this->get_feed_currency(), '_' . $price_type
3101
+ );
3102
+
3103
+ // Get Price with tax
3104
+ if (true === $tax) {
3105
+ $price = woo_feed_get_price_with_tax($price, $product);
3106
+ }
3107
+
3108
+ return $price;
3109
+ }
3110
+
3111
+ /**
3112
+ * Get Product Price by Product Type.
3113
+ *
3114
+ * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product Object
3115
+ * @param string $price_type Price Type (regular_price|price|sale_price)
3116
+ * @param bool $tax Add tax with price (true|false)
3117
+ *
3118
+ * @return float|int|mixed|string
3119
+ * @since 4.4.14
3120
+ *
3121
+ * @author Ohidul Islam
3122
+ */
3123
+ protected function get_price_by_product_type($product, $price_type, $tax = false)
3124
+ {
3125
+ if ($product->is_type('variable')) {
3126
+ $price = $this->getVariableProductPrice($product, $price_type, $tax);
3127
+ } elseif ($product->is_type('grouped')) {
3128
+ $price = $this->getGroupProductPrice($product, $price_type, $tax);
3129
+ } elseif ($product->is_type('bundle')) {
3130
+ //TODO Diff taxation
3131
+ $price = $this->getBundleProductPrice($product, $price_type, $tax);
3132
+ } elseif ($product->is_type('composite')) {
3133
+ //TODO Diff taxation
3134
+ $price = $this->getCompositeProductPrice($product, $price_type, $tax);
3135
+ } elseif ($product->is_type('bundled')) {
3136
+ // iconic woocommerce product bundled plugin
3137
+ $price = $this->iconic_bundle_product_price($product, $price_type, $tax);
3138
+ } else {
3139
+ $price = $this->get_price_by_price_type($product, $price_type, $tax);
3140
+ }
3141
+
3142
+ return $price > 0 ? $price : '';
3143
+ }
3144
+
3145
+ /**
3146
+ * Get Product Regular Price
3147
+ *
3148
+ * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product Object.
3149
+ *
3150
+ * @return mixed
3151
+ * @since 3.2.0
3152
+ *
3153
+ */
3154
+ protected function price($product)
3155
+ {
3156
 
3157
+ $regular_price = $this->get_price_by_product_type($product, 'regular_price');
 
3158
 
3159
+ return apply_filters('woo_feed_filter_product_price', $regular_price, $product, $this->config, false);
3160
+ }
 
 
3161
 
3162
+ /**
3163
+ * Get Product Price
3164
+ *
3165
+ * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product object.
3166
+ *
3167
+ * @return int|float|mixed
3168
+ * @since 3.2.0
3169
+ *
3170
+ */
3171
+ protected function current_price($product)
3172
+ {
3173
 
3174
+ $price = $this->get_price_by_product_type($product, 'price');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3175
 
3176
+ return apply_filters('woo_feed_filter_product_regular_price', $price, $product, $this->config, false);
3177
+ }
 
3178
 
3179
+ /**
3180
+ * Get Product Sale Price
3181
+ *
3182
+ * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product object.
3183
+ *
3184
+ * @return mixed
3185
+ * @since 3.2.0
3186
+ *
3187
+ */
3188
+ protected function sale_price($product)
3189
+ {
 
 
 
 
 
 
3190
 
3191
+ $sale_price = $this->get_price_by_product_type($product, 'sale_price');
 
 
 
 
 
 
 
 
3192
 
3193
+ return apply_filters('woo_feed_filter_product_sale_price', $sale_price, $product, $this->config, false);
3194
+ }
 
 
 
 
 
 
 
3195
 
3196
+ /**
3197
+ * Get Product Regular Price with Tax
3198
+ *
3199
+ * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product Object.
3200
+ *
3201
+ * @return mixed
3202
+ * @since 3.2.0
3203
+ *
3204
+ */
3205
+ protected function price_with_tax($product)
3206
+ {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3207
 
3208
+ $regular_price_with_tax = $this->get_price_by_product_type($product, 'regular_price', true);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3209
 
3210
+ return apply_filters('woo_feed_filter_product_price_with_tax', $regular_price_with_tax, $product, $this->config, true);
3211
+ }
 
 
 
 
 
 
 
 
 
 
3212
 
3213
+ /**
3214
+ * Get Product Regular Price with Tax
3215
+ *
3216
+ * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product object.
3217
+ *
3218
+ * @return mixed
3219
+ * @since 3.2.0
3220
+ *
3221
+ */
3222
+ protected function current_price_with_tax($product)
3223
+ {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3224
 
3225
+ $price_with_tax = $this->get_price_by_product_type($product, 'price', true);
 
 
 
3226
 
3227
+ return apply_filters('woo_feed_filter_product_regular_price_with_tax', $price_with_tax, $product, $this->config, true);
3228
+ }
3229
 
3230
+ /**
3231
+ * Get Product Regular Price with Tax
3232
+ *
3233
+ * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product object.
3234
+ *
3235
+ * @return mixed
3236
+ * @since 3.2.0
3237
+ *
3238
+ */
3239
+ protected function sale_price_with_tax($product)
3240
+ {
3241
 
3242
+ $sale_price_with_tax = $this->get_price_by_product_type($product, 'sale_price', true);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3243
 
3244
+ return apply_filters('woo_feed_filter_product_sale_price_with_tax', $sale_price_with_tax, $product, $this->config, true);
3245
+ }
3246
 
3247
+ /**
3248
+ * Get Composite Product Price
3249
+ *
3250
+ * @param WC_Product|WC_Product_Composite|WC_Composite_Products $product Composite Product object.
3251
+ * @param string $type Price Type (regular_price|price|sale_price)
3252
+ * @param bool $tax Add tax with price (true|false)
3253
+ *
3254
+ * @return int|float|double
3255
+ * @since 3.2.6
3256
+ */
3257
+ protected function getCompositeProductPrice($product, $type, $tax = false)
3258
+ {
3259
+ if (class_exists('WC_Product_Composite') && class_exists('WPCleverWooco')) {
3260
+ // WPC Composite Product
3261
+ return $this->get_wpc_composite_price($product, $type, $tax);
3262
+ } elseif (class_exists('WC_Composite_Products')) {
3263
+ // WooCommerce Composite Product
3264
+ return $this->get_wc_composite_product_price($product, $type, $tax);
3265
+ } else {
3266
+ // Get Base Price for Others Composite Products.
3267
+ // Note*: YITH does not auto select components. So no need to calculate component price.
3268
+ return $this->get_price_by_price_type($product, $type, $tax);
3269
+ }
3270
+ }
3271
+
3272
+ /**
3273
+ * Get WooCommerce Composite Product Price
3274
+ * Plugin URL: https://wordpress.org/plugins/wpc-composite-products/
3275
+ * Product Type: composite
3276
+ *
3277
+ * @param WC_Product|WC_Product_Composite $product
3278
+ * @param string $type Price Type (regular_price|price|sale_price)
3279
+ * @param bool $tax Add tax with price (true|false)
3280
+ * @return float|int|mixed|string|void
3281
+ */
3282
+ protected function get_wc_composite_product_price($product, $type, $tax)
3283
+ {
3284
+ $price = 0;
3285
+ // Parent Component Price
3286
+ $base_price = $this->get_price_by_price_type($product, $type, $tax);
3287
+ if (isset($this->config['composite_price']) && 'all_product_price' == $this->config['composite_price']) {
3288
+ $composite = new WC_Product_Composite($product);
3289
+
3290
+ if ('price' === $type || 'sale_price' === $type) {
3291
+ $price = $composite->get_composite_price();
3292
+ } else {
3293
+ $price = $composite->get_composite_regular_price();
3294
+ }
3295
+
3296
+ // Get WooCommerce Multi language Price by Currency.
3297
+ $price = apply_filters('woo_feed_wcml_price',
3298
+ $price, $product->get_id(), $this->get_feed_currency(), '_' . $type
3299
+ );
3300
+
3301
+ // Get Price with tax
3302
+ if (true === $tax) {
3303
+ $price = woo_feed_get_price_with_tax($price, $composite);
3304
+ }
3305
+ } else {
3306
+ $price = $base_price;
3307
+ }
3308
+
3309
+ return $price > 0 ? $price : '';
3310
+ }
3311
+
3312
+ /**
3313
+ * Get WPC Composite Product Price.
3314
+ * Plugin URL: https://wordpress.org/plugins/wpc-composite-products/
3315
+ * Product Type: composite
3316
+ *
3317
+ * @param WC_Product|WC_Product_Composite $product
3318
+ * @param string $type Price Type (regular_price|price|sale_price)
3319
+ * @param bool $tax Add tax with price (true|false)
3320
+ * @return float|int|mixed|string|void
3321
+ */
3322
+ protected function get_wpc_composite_price($product, $type, $tax)
3323
+ {
3324
+ $price = 0;
3325
+ // Parent Component Price
3326
+ $base_price = $this->get_price_by_price_type($product, $type, $tax);
3327
+ if (isset($this->config['composite_price']) && 'all_product_price' == $this->config['composite_price']) {
3328
+ $components_price = 0;
3329
+ $components = $product->get_components();
3330
+ if (!empty($components) && is_array($components)) {
3331
+ foreach ($components as $component) {
3332
+ $products = explode(',', $component['products']);
3333
+ foreach ($products as $key => $product_id) {
3334
+ $default_product = wc_get_product($product_id);
3335
+ if (is_object($default_product) && $default_product->is_in_stock()) {
3336
+ $quantity = (isset($component['qty']) && $component['qty'] > 0) ? $component['qty'] : 1;
3337
+ if ('products' == $component['type'] && empty($component['price'])) {
3338
+ $components_price += $this->get_price_by_price_type($default_product, 'price', $tax);
3339
+ $components_price *= $quantity;
3340
+ } elseif ('products' == $component['type'] && !empty($component['price'])) {
3341
+ $clever = new WPCleverWooco();
3342
+ $old_price = $this->get_price_by_price_type($default_product, 'price', $tax);
3343
+ $new_price = $component['price'];
3344
+ $components_price += $clever::wooco_new_price($old_price, $new_price);
3345
+ $components_price *= $quantity;
3346
+ }
3347
+ break; // Get first in stock product from component options.
3348
+ }
3349
+ }
3350
+ }
3351
+
3352
+ // Apply discount to components price.
3353
+ $discount = $product->get_discount();
3354
+ if ($discount > 0) {
3355
+ $components_price -= (($discount / 100) * $components_price);
3356
+ }
3357
+ }
3358
+
3359
+ if ('exclude' === $product->get_pricing()) {
3360
+ $price = $components_price;
3361
+ } elseif ('include' === $product->get_pricing()) {
3362
+ $price = $components_price + $base_price;
3363
+ } elseif ('only' === $product->get_pricing()) {
3364
+ $price = $base_price;
3365
+ }
3366
+ } else {
3367
+ $price = $base_price;
3368
+ }
3369
+
3370
+ return $price > 0 ? $price : '';
3371
+ }
3372
+
3373
+ /**
3374
+ * Get total price of grouped product
3375
+ *
3376
+ * @param WC_Product_Grouped $grouped Grouped Product Object
3377
+ * @param string $type Price Type (regular_price|price|sale_price)
3378
+ * @param bool $tax Add tax with price (true|false)
3379
+ *
3380
+ * @return int|string
3381
+ * @since 3.2.0
3382
+ *
3383
+ */
3384
+ protected function getGroupProductPrice($grouped, $type, $tax = false)
3385
+ {
3386
+ $groupProductIds = $grouped->get_children();
3387
+ $price = 0;
3388
+ if (!empty($groupProductIds)) {
3389
+ foreach ($groupProductIds as $id) {
3390
+ $product = wc_get_product($id);
3391
+ if (!is_object($product)) {
3392
+ continue; // make sure that the product exists..
3393
+ }
3394
+
3395
+ $get_price = $this->get_price_by_product_type($product, $type, $tax);
3396
+ if (!empty($get_price)) {
3397
+ $price += $get_price;
3398
+ }
3399
+ }
3400
+ }
3401
+
3402
+ return $price > 0 ? $price : '';
3403
+ }
3404
+
3405
+ /**
3406
+ * Get Variable Product Price
3407
+ *
3408
+ * @param WC_Product_Variable $variable Variable Product Object
3409
+ * @param string $type Price Type (regular_price|price|sale_price)
3410
+ * @param bool $tax Add tax with price (true|false)
3411
+ *
3412
+ * @return int|string
3413
+ * @since 3.2.0
3414
+ *
3415
+ */
3416
+ protected function getVariableProductPrice($variable, $type, $tax = false)
3417
+ {
3418
+ $min_max_first_default = apply_filters('woo_feed_variable_product_price_range', 'min');
3419
+ if (isset($this->config['variable_price'])) {
3420
+ $min_max_first_default = $this->config['variable_price'];
3421
+ }
3422
+
3423
+ $price = 0;
3424
+ if ('first' == $min_max_first_default) {
3425
+ $children = $variable->get_visible_children();
3426
+ if (isset($children[0]) && !empty($children[0])) {
3427
+ $variation = wc_get_product($children[0]);
3428
+ $price = $this->get_price_by_product_type($variation, $type, $tax);
3429
+ }
3430
+ } else {
3431
+ if ('regular_price' == $type) {
3432
+ $price = $variable->get_variation_regular_price($min_max_first_default);
3433
+ } elseif ('sale_price' == $type) {
3434
+ $price = $variable->get_variation_sale_price($min_max_first_default);
3435
+ } else {
3436
+ $price = $variable->get_variation_price($min_max_first_default);
3437
+ }
3438
+
3439
+ // Get WooCommerce Multi language Price by Currency.
3440
+ $price = apply_filters('woo_feed_wcml_price',
3441
+ $price, $variable->get_id(), $this->get_feed_currency(), '_' . $type
3442
+ );
3443
+
3444
+ // Get Price with tax
3445
+ if (true === $tax) {
3446
+ $price = woo_feed_get_price_with_tax($price, $variable);
3447
+ }
3448
+ }
3449
+
3450
+ return $price > 0 ? $price : '';
3451
+ }
3452
+
3453
+ /**
3454
+ * Get Bundle Product Price
3455
+ *
3456
+ * @param WC_Product $product Product object.
3457
+ * @param string $type Price Type (regular_price|price|sale_price)
3458
+ * @param bool $tax Add tax with price (true|false)
3459
+ *
3460
+ * @return int|float|string
3461
+ * @since 4.3.24
3462
+ */
3463
+ protected function getBundleProductPrice($product, $type, $tax = false)
3464
+ {
3465
+ if (class_exists('WC_Product_Bundle')) {//WC_Product_Bundle
3466
+ $bundle = new WC_Product_Bundle($product);
3467
+ if ('price' === $type || 'sale_price' === $type) {
3468
+ $price = $bundle->get_bundle_price();
3469
+ } else {
3470
+ $price = $bundle->get_bundle_regular_price();
3471
+ }
3472
+
3473
+ // Get WooCommerce Multi language Price by Currency.
3474
+ $price = apply_filters('woo_feed_wcml_price',
3475
+ $price, $product->get_id(), $this->get_feed_currency(), '_' . $type
3476
+ );
3477
+
3478
+ // Get Price with tax
3479
+ if (true === $tax) {
3480
+ $price = woo_feed_get_price_with_tax($price, $bundle);
3481
+ }
3482
+ } else {
3483
+ // Get Default price for others bundle products.
3484
+ $price = $this->get_price_by_price_type($product, $type, $tax);
3485
+ }
3486
+
3487
+ return $price > 0 ? $price : '';
3488
+ }
3489
+
3490
+ /**
3491
+ * Get price for Iconic woocommerce-bundled-products
3492
+ *
3493
+ * @param WC_Product $product Product object
3494
+ * @param string $type Price Type (regular_price|price|sale_price)
3495
+ * @param bool $tax Add tax with price (true|false)
3496
+ *
3497
+ * @return mixed $bundle_price
3498
+ */
3499
+ protected function iconic_bundle_product_price($product, $type, $tax = false)
3500
+ {
3501
+ if (!class_exists('WC_Product_Bundled')) {
3502
+ return $product->get_price();
3503
+ }
3504
+
3505
+ $is_discounted = false;
3506
+ $price = $product->get_price();
3507
+ $bundle = new WC_Product_Bundled($product->get_id());
3508
+ $iconic_bundle_product_type = (!is_null($bundle->options['price_display'])) ? $bundle->options['price_display'] : '';
3509
+ $product_ids = $bundle->options['product_ids'];
3510
+
3511
+ //set discount
3512
+ if (!empty($bundle->options['fixed_discount'])) {
3513
+ $is_discounted = true;
3514
+ $discount = $bundle->options['fixed_discount'];
3515
+ } else {
3516
+ $is_discounted = false;
3517
+ $discount = 0;
3518
+ }
3519
+
3520
+ // Get price
3521
+ if (is_array($product_ids)) {
3522
+ $product_prices = array_map(function ($id) use ($tax, $type, $is_discounted, $discount) {
3523
+ $product = wc_get_product($id);
3524
+
3525
+ return $this->get_price_by_price_type($product, $type, $tax);
3526
+
3527
+ }, $product_ids);
3528
+
3529
+ if ('range' === $iconic_bundle_product_type) {
3530
+ $price = min($product_prices);
3531
+ } else {
3532
+ $price = array_sum($product_prices);
3533
+ }
3534
+ }
3535
+
3536
+ // Get sale price if discount enabled
3537
+ if ($is_discounted && ('sale_price' === $type || 'price' === $type)) {
3538
+ $price -= $discount;
3539
+ }
3540
+
3541
+ // Get WooCommerce Multi language Price by Currency.
3542
+ $price = apply_filters('woo_feed_wcml_price',
3543
+ $price, $product->get_id(), $this->get_feed_currency(), '_' . $type
3544
+ );
3545
+
3546
+ // Get Price with tax
3547
+ if (true === $tax) {
3548
+ $price = woo_feed_get_price_with_tax($price, $bundle);
3549
+ }
3550
+
3551
+ return $price > 0 ? $price : '';
3552
+ }
3553
+
3554
+ /**
3555
+ * Get Product Weight
3556
+ *
3557
+ * @param WC_Product $product
3558
+ *
3559
+ * @return mixed
3560
+ * @since 3.2.0
3561
+ *
3562
+ */
3563
+ protected function weight($product)
3564
+ {
3565
+ return apply_filters('woo_feed_filter_product_weight', $product->get_weight(), $product, $this->config);
3566
+ }
3567
+
3568
+ /**
3569
+ * Get Product Weight Unit
3570
+ *
3571
+ * @param WC_Product $product
3572
+ *
3573
+ * @return mixed
3574
+ * @since 5.2.7
3575
+ *
3576
+ */
3577
+ protected function weight_unit($product)
3578
+ {
3579
+ return apply_filters('woo_feed_filter_product_weight_unit', get_option('woocommerce_weight_unit'), $product, $this->config);
3580
+ }
3581
+
3582
+ /**
3583
+ * Get Product Width
3584
+ *
3585
+ * @param WC_Product $product
3586
+ *
3587
+ * @return mixed
3588
+ * @since 3.2.0
3589
+ *
3590
+ */
3591
+ protected function width($product)
3592
+ {
3593
+ return apply_filters('woo_feed_filter_product_width', $product->get_width(), $product, $this->config);
3594
+ }
3595
+
3596
+ /**
3597
+ * Get Product Height
3598
+ *
3599
+ * @param WC_Product $product
3600
+ *
3601
+ * @return mixed
3602
+ * @since 3.2.0
3603
+ *
3604
+ */
3605
+ protected function height($product)
3606
+ {
3607
+ return apply_filters('woo_feed_filter_product_height', $product->get_height(), $product, $this->config);
3608
+ }
3609
+
3610
+ /**
3611
+ * Get Product Length
3612
+ *
3613
+ * @param WC_Product $product
3614
+ *
3615
+ * @return mixed
3616
+ * @since 3.2.0
3617
+ *
3618
+ */
3619
+ protected function length($product)
3620
+ {
3621
+ return apply_filters('woo_feed_filter_product_length', $product->get_length(), $product, $this->config);
3622
+ }
3623
+
3624
+ /**
3625
+ * Get Product Shipping
3626
+ *
3627
+ * @param WC_Product $product
3628
+ *
3629
+ * @return mixed
3630
+ * @since 4.3.16
3631
+ * @author Nazrul Islam Nayan
3632
+ */
3633
+ protected function shipping($product)
3634
+ {
3635
+ $feedBody = '';
3636
+ $data = $this->data;
3637
+
3638
+ if (isset($data['shipping_zones']) && !empty($data['shipping_zones'])) {
3639
+ $zones = $data['shipping_zones'];
3640
+
3641
+ if (in_array($this->config['provider'], ['google', 'facebook', 'pinterest', 'bing', 'snapchat'])) {
3642
+ $get_shipping = new Woo_Feed_Shipping($this->config);
3643
+ $feedBody .= $get_shipping->set_product($product)->set_shipping_zone($zones)->get_google_shipping();
3644
+ }
3645
+ }
3646
+
3647
+ return apply_filters('woo_feed_filter_product_shipping', $feedBody, $product, $this->config);
3648
+
3649
+ }
3650
+
3651
+ /**
3652
+ * Get Product Shipping Cost
3653
+ *
3654
+ * @param WC_Product $product
3655
+ *
3656
+ * @return mixed
3657
+ * @since 5.1.20
3658
+ * @author Nazrul Islam Nayan
3659
+ */
3660
+ protected function shipping_cost($product)
3661
+ {
3662
+ $shipping_obj = new Woo_Feed_Shipping($this->config);
3663
+ $shipping_obj = $shipping_obj->set_product($product);
3664
+
3665
+ return apply_filters('woo_feed_filter_product_shipping_cost', $shipping_obj->get_lowest_shipping_price(), $product, $this->config);
3666
+ }
3667
+
3668
+ /**
3669
+ * Get Product Shipping Class
3670
+ *
3671
+ * @param WC_Product $product
3672
+ *
3673
+ * @return mixed
3674
+ * @since 3.2.0
3675
+ *
3676
+ */
3677
+ protected function shipping_class($product)
3678
+ {
3679
+ return apply_filters('woo_feed_filter_product_shipping_class', $product->get_shipping_class(), $product, $this->config);
3680
+ }
3681
+
3682
+ /**
3683
+ * Get Product Author Name
3684
+ *
3685
+ * @param WC_Product $product
3686
+ *
3687
+ * @return mixed
3688
+ * @since 3.2.0
3689
+ *
3690
+ */
3691
+ protected function author_name($product)
3692
+ {
3693
+ $post = get_post($product->get_id());
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3694
 
3695
+ return get_the_author_meta('user_login', $post->post_author);
3696
+ }
3697
 
3698
+ /**
3699
+ * Get Product Author Email
3700
+ *
3701
+ * @param WC_Product $product
3702
+ *
3703
+ * @return mixed
3704
+ * @since 3.2.0
3705
+ *
3706
+ */
3707
+ protected function author_email($product)
3708
+ {
3709
+ $post = get_post($product->get_id());
3710
 
3711
+ return get_the_author_meta('user_email', $post->post_author);
3712
+ }
3713
 
3714
+ /**
3715
+ * Get Product Created Date
3716
+ *
3717
+ * @param WC_Product $product
3718
+ *
3719
+ * @return mixed
3720
+ * @since 3.2.0
3721
+ *
3722
+ */
3723
+ protected function date_created($product)
3724
+ {
3725
+ $date_created = gmdate('Y-m-d', strtotime($product->get_date_created()));
3726
 
3727
+ return apply_filters('woo_feed_filter_product_date_created', $date_created, $product, $this->config);
3728
+ }
3729
 
3730
+ /**
3731
+ * Get Product Last Updated Date
3732
  *
3733
+ * @param WC_Product $product
3734
  *
3735
+ * @return mixed
3736
+ * @since 3.2.0
3737
+ *
3738
+ */
3739
+ protected function date_updated($product)
3740
+ {
3741
+ $date_updated = gmdate('Y-m-d', strtotime($product->get_date_modified()));
 
 
 
 
 
 
 
3742
 
3743
+ return apply_filters('woo_feed_filter_product_date_updated', $date_updated, $product, $this->config);
3744
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3745
 
3746
+ /**
3747
+ * Get Product Tax
3748
+ *
3749
+ * @param WC_Product $product Product object.
3750
+ * @return mixed
3751
+ * @since 5.1.20
3752
+ * @author Nazrul Islam Nayan
3753
+ */
3754
+ protected function tax($product)
3755
+ {
3756
+ $feedBody = '';
3757
+ if (in_array($this->config['provider'], ['google', 'facebook', 'pinterest', 'bing', 'snapchat'])) {
3758
+ $shipping_obj = new Woo_Feed_Shipping($this->config);
3759
+ $shipping_obj = $shipping_obj->set_product($product);
3760
+ $feedBody .= $shipping_obj->get_google_tax();
3761
+ }
3762
+
3763
+ return apply_filters('woo_feed_filter_product_tax', $feedBody, $product, $this->config);
3764
+ }
3765
+
3766
+ /**
3767
+ * Get Product Tax class
3768
+ * @param WC_Product $product Product object.
3769
+ * @return string
3770
+ */
3771
+ protected function tax_class($product)
3772
+ {
3773
+ return apply_filters('woo_feed_filter_product_tax_class', $product->get_tax_class(), $product, $this->config);
3774
+ }
3775
+
3776
+ /**
3777
+ * Get Product Tax Status
3778
+ * @param WC_Product $product Product object.
3779
+ * @return string
3780
+ */
3781
+ protected function tax_status($product)
3782
+ {
3783
+ return apply_filters('woo_feed_filter_product_tax_status', $product->get_tax_status(), $product, $this->config);
3784
+ }
3785
+
3786
+ /**
3787
+ * Get CTX Feed Custom Field value
3788
+ *
3789
+ * @param WC_Product $product Product object.
3790
+ * @param string $field custom field name.
3791
+ * @return string
3792
+ */
3793
+ protected function getCustomField($product, $field)
3794
+ {
3795
+ $id = $product->get_id();
3796
+ $meta = $field;
3797
+ if ($product->is_type('variation')) {
3798
+ $meta = $field . '_var';
3799
+ }
3800
+
3801
+ $meta = apply_filters('woo_feed_custom_field_meta', $meta, $product, $field);
3802
+
3803
+ $new_meta_key = '';
3804
+ $old_meta_key = '';
3805
+
3806
+ if (strpos($meta, '_identifier') !== false) {
3807
+ $old_meta_key = $meta;
3808
+ $new_meta_key = str_replace('_identifier', '', $meta);
3809
+ } else {
3810
+ $new_meta_key = $meta;
3811
+ $old_meta_key = str_replace('woo_feed_', 'woo_feed_identifier_', $meta);
3812
+ }
3813
+
3814
+ $new_meta_value = $this->getProductMeta($product, $new_meta_key);
3815
+ $old_meta_value = $this->getProductMeta($product, $old_meta_key);
3816
+
3817
+ if (empty($new_meta_value)) {
3818
+ return $old_meta_value;
3819
+ } else {
3820
+ return $new_meta_value;
3821
+ }
3822
+
3823
+ }
3824
+
3825
+ /**
3826
+ * Get Product Sale Price Effected Date for Google Shopping
3827
+ *
3828
+ * @param WC_Product $product
3829
+ *
3830
+ * @return string
3831
+ * @since 3.2.0
3832
+ *
3833
+ */
3834
+ protected function sale_price_effective_date($product)
3835
+ {
3836
+ $effective_date = '';
3837
+ $from = $this->sale_price_sdate($product);
3838
+ $to = $this->sale_price_edate($product);
3839
+ if (!empty($from) && !empty($to)) {
3840
+ $from = gmdate('c', strtotime($from));
3841
+ $to = gmdate('c', strtotime($to));
3842
+
3843
+ $effective_date = $from . '/' . $to;
3844
+ }
3845
+
3846
+ return $effective_date;
3847
+ }
3848
+
3849
+ /**
3850
+ * Ger Product Attribute
3851
+ *
3852
+ * @param WC_Product $product
3853
+ * @param $attr
3854
+ *
3855
+ * @return string
3856
+ * @since 2.2.3
3857
+ *
3858
+ */
3859
+ protected function getProductAttribute($product, $attr)
3860
+ {
3861
+ $id = $product->get_id();
3862
+
3863
+ if (woo_feed_wc_version_check(3.2)) {
3864
+ if (woo_feed_wc_version_check(3.6)) {
3865
+ $attr = str_replace('pa_', '', $attr);
3866
+ }
3867
+ $value = $product->get_attribute($attr);
3868
+
3869
+ // if empty get attribute of parent post
3870
+ if ('' === $value && $product->is_type('variation')) {
3871
+ $product = wc_get_product($product->get_parent_id());
3872
+ $value = $product->get_attribute($attr);
3873
+ }
3874
+
3875
+ $getproductattribute = $value;
3876
+ } else {
3877
+ $getproductattribute = implode(',', wc_get_product_terms($id, $attr, array('fields' => 'names')));
3878
+ }
3879
+
3880
+ return apply_filters('woo_feed_filter_product_attribute', $getproductattribute, $product, $attr, $this->config);
3881
+ }
3882
+
3883
+ /**
3884
+ * Get Meta
3885
+ *
3886
+ * @param WC_Product $product
3887
+ * @param string $meta post meta key
3888
+ *
3889
+ * @return mixed|string
3890
+ * @since 2.2.3
3891
+ *
3892
+ */
3893
+ protected function getProductMeta($product, $meta)
3894
+ {
3895
+ $value = get_post_meta($product->get_id(), $meta, true);
3896
+ // if empty get meta value of parent post
3897
+ if ('' === $value && $product->is_type('variation')) {
3898
+ $value = get_post_meta($product->get_parent_id(), $meta, true);
3899
+ }
3900
+
3901
+ return apply_filters('woo_feed_filter_product_meta', $value, $product, $this->config);
3902
+ }
3903
+
3904
+ /**
3905
+ * Filter Products by Conditions
3906
+ *
3907
+ * @param WC_Product $product
3908
+ *
3909
+ * @return bool|array
3910
+ * @since 3.2.0
3911
+ *
3912
+ */
3913
+ public function filter_product($product)
3914
+ {
3915
+ return true;
3916
+ }
3917
+
3918
+ /**
3919
+ * Get Taxonomy
3920
+ *
3921
+ * @param WC_Product $product
3922
+ * @param $taxonomy
3923
+ *
3924
+ * @return string
3925
+ * @since 2.2.3
3926
+ *
3927
+ */
3928
+ protected function getProductTaxonomy($product, $taxonomy)
3929
+ {
3930
+ $id = $product->get_id();
3931
+ if ($product->is_type('variation')) {
3932
+ $id = $product->get_parent_id();
3933
+ }
3934
 
3935
+ $separator = apply_filters('woo_feed_product_taxonomy_term_list_separator', ',', $this->config, $product);
 
3936
 
3937
+ $term_list = get_the_term_list($id, $taxonomy, '', $separator, '');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3938
 
3939
+ if (is_object($term_list) && get_class($term_list) === 'WP_Error') {
3940
+ $term_list = '';
3941
+ }
3942
 
3943
+ $getproducttaxonomy = woo_feed_strip_all_tags($term_list);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3944
 
3945
+ return apply_filters('woo_feed_filter_product_taxonomy', $getproducttaxonomy, $product, $this->config);
3946
+ }
3947
 
3948
+ /**
3949
+ * Format price value
3950
+ *
3951
+ * @param string $name Attribute Name
3952
+ * @param int $conditionName condition
3953
+ * @param int $result price
3954
+ *
3955
+ * @return mixed
3956
+ * @since 3.2.0
3957
+ *
3958
+ */
3959
+ protected function price_format($name, $conditionName, $result)
3960
+ {
3961
+ $plus = '+';
3962
+ $minus = '-';
3963
+ $percent = '%';
3964
+
3965
+ if (strpos($name, 'price') !== false) {
3966
+ if (strpos($result, $plus) !== false && strpos($result, $percent) !== false) {
3967
+ $result = str_replace('+', '', $result);
3968
+ $result = str_replace('%', '', $result);
3969
+ if (is_numeric($result)) {
3970
+ $result = $conditionName + (($conditionName * $result) / 100);
3971
+ }
3972
+ } elseif (strpos($result, $minus) !== false && strpos($result, $percent) !== false) {
3973
+ $result = str_replace('-', '', $result);
3974
+ $result = str_replace('%', '', $result);
3975
+ if (is_numeric($result)) {
3976
+ $result = $conditionName - (($conditionName * $result) / 100);
3977
+ }
3978
+ } elseif (strpos($result, $plus) !== false) {
3979
+ $result = str_replace('+', '', $result);
3980
+ if (is_numeric($result)) {
3981
+ $result = ($conditionName + $result);
3982
+ }
3983
+ } elseif (strpos($result, $minus) !== false) {
3984
+ $result = str_replace('-', '', $result);
3985
+ if (is_numeric($result)) {
3986
+ $result = $conditionName - $result;
3987
+ }
3988
+ }
3989
+ }
3990
+
3991
+ return $result;
3992
+ }
3993
+
3994
+ /**
3995
+ * Format output According to Output Type config
3996
+ *
3997
+ * @param string $output
3998
+ * @param array $outputTypes
3999
+ * @param WC_Product $product
4000
+ * @param string $productAttribute
4001
+ *
4002
+ * @return float|int|string
4003
+ * @since 3.2.0
4004
+ *
4005
+ */
4006
+ protected function format_output($output, $outputTypes, $product, $productAttribute, $merchant_attribute)
4007
+ {
4008
+ if (!empty($outputTypes) && is_array($outputTypes)) {
4009
+
4010
+ // Format Output According to output type
4011
+ if (in_array(2, $outputTypes)) { // Strip Tags
4012
+ $output = woo_feed_strip_all_tags(html_entity_decode($output));
4013
+ }
4014
+
4015
+ if (in_array(3, $outputTypes)) { // UTF-8 Encode
4016
+ $output = utf8_encode($output);
4017
+ }
4018
+
4019
+ if (in_array(4, $outputTypes)) { // htmlentities
4020
+ $output = htmlentities($output, ENT_QUOTES, 'UTF-8');
4021
+ }
4022
+
4023
+ if (in_array(5, $outputTypes)) { // Integer
4024
+ $output = intval($output);
4025
+ }
4026
+
4027
+ if (in_array(6, $outputTypes)) { // Format Price
4028
+ if (!empty($output) && $output > 0) {
4029
+ $decimals = wc_get_price_decimals();
4030
+ $decimal_separator = wc_get_price_decimal_separator();
4031
+ $thousand_separator = wc_get_price_thousand_separator();
4032
+ $output = (float)$output;
4033
+
4034
+ if ("idealo" === $this->config['provider']) {
4035
+ $output = number_format($output, $decimals, wp_specialchars_decode(stripslashes($decimal_separator)), wp_specialchars_decode(stripslashes($thousand_separator)));
4036
+ } else {
4037
+ $output = number_format($output, 2, '.', '');
4038
+ }
4039
+
4040
+ }
4041
+ }
4042
+
4043
+ if (in_array(7, $outputTypes)) { // Rounded Price
4044
+ if (!empty($output) && $output > 0) {
4045
+ $output = round($output);
4046
+ $output = number_format($output, 2, '.', '');
4047
+ }
4048
+ }
4049
+
4050
+ if (in_array(8, $outputTypes)) { // Delete Space
4051
+ $output = htmlentities($output, null, 'utf-8');
4052
+ $output = str_replace("&nbsp;", " ", $output);
4053
+ $output = html_entity_decode($output);
4054
+ $output = preg_replace("/\\s+/", ' ', $output);
4055
+ }
4056
+
4057
+ if (in_array(10, $outputTypes)) { // Remove Invalid Character
4058
+ $output = woo_feed_stripInvalidXml($output);
4059
+ }
4060
+
4061
+ if (in_array(11, $outputTypes)) { // Remove ShortCodes
4062
+ $output = $this->remove_short_codes($output);
4063
+ }
4064
+
4065
+ if (in_array(12, $outputTypes)) {
4066
+ $output = ucwords(strtolower($output));
4067
+ }
4068
+
4069
+ if (in_array(13, $outputTypes)) {
4070
+ $output = ucfirst(strtolower($output));
4071
+ }
4072
+
4073
+ if (in_array(14, $outputTypes)) {
4074
+ $output = strtoupper(strtolower($output));
4075
+ }
4076
+
4077
+ if (in_array(15, $outputTypes)) {
4078
+ $output = strtolower($output);
4079
+ }
4080
+
4081
+ if (in_array(16, $outputTypes)) {
4082
+ if ('http' == substr($output, 0, 4)) {
4083
+ $output = str_replace('http://', 'https://', $output);
4084
+ }
4085
+ }
4086
+
4087
+ if (in_array(17, $outputTypes)) {
4088
+ if ('http' == substr($output, 0, 4)) {
4089
+ $output = str_replace('https://', 'http://', $output);
4090
+ }
4091
+ }
4092
+
4093
+ if (in_array(18, $outputTypes)) { // only parent
4094
+ if ($product->is_type('variation')) {
4095
+ $id = $product->get_parent_id();
4096
+ $parentProduct = wc_get_product($id);
4097
+ $output = $this->getAttributeValueByType($parentProduct, $productAttribute, $merchant_attribute);
4098
+ }
4099
+ }
4100
+
4101
+ if (in_array(19, $outputTypes)) { // child if parent empty
4102
+ if ($product->is_type('variation')) {
4103
+ $id = $product->get_parent_id();
4104
+ $parentProduct = wc_get_product($id);
4105
+ $output = $this->getAttributeValueByType($parentProduct, $productAttribute, $merchant_attribute);
4106
+ if (empty($output)) {
4107
+ $output = $this->getAttributeValueByType($product, $productAttribute, $merchant_attribute);
4108
+ }
4109
+ }
4110
+ }
4111
+
4112
+ if (in_array(20, $outputTypes)) { // parent if child empty
4113
+ if ($product->is_type('variation')) {
4114
+ $output = $this->getAttributeValueByType($product, $productAttribute, $merchant_attribute);
4115
+ if (empty($output)) {
4116
+ $id = $product->get_parent_id();
4117
+ $parentProduct = wc_get_product($id);
4118
+ $output = $this->getAttributeValueByType($parentProduct, $productAttribute, $merchant_attribute);
4119
+ }
4120
+ }
4121
+ }
4122
+
4123
+ if (in_array(9, $outputTypes) && !empty($output) && 'xml' === $this->config['feedType']) { // Add CDATA
4124
+ $output = '<![CDATA[' . $output . ']]>';
4125
+ }
4126
+ }
4127
+
4128
+ return $output;
4129
+ }
4130
+
4131
+ /**
4132
+ * Add Prefix and Suffix with attribute value
4133
+ *
4134
+ * @param $output
4135
+ * @param $prefix
4136
+ * @param $suffix
4137
+ * @param $attribute
4138
+ *
4139
+ * @return string
4140
+ * @since 3.2.0
4141
+ *
4142
+ */
4143
+ public function process_prefix_suffix($output, $prefix, $suffix, $attribute = '')
4144
+ {
4145
+ $cdata = false;
4146
+ if ('' === $output) {
4147
+ return $output;
4148
+ }
4149
+
4150
+ if (strpos($output, '<![CDATA[') !== false) {
4151
+ $cdata = true;
4152
+ $output = str_replace(array('<![CDATA[', ']]>'), array('', ''), $output);
4153
+ }
4154
+
4155
+ // Add Prefix before Output
4156
+ if ('' !== $prefix) {
4157
+ $output = "$prefix" . $output;
4158
+ }
4159
+
4160
+ // Add Suffix after Output
4161
+ if ('' !== $suffix) {
4162
+ if (array_key_exists(trim($suffix), get_woocommerce_currencies())) { // Add space before suffix if attribute contain price.
4163
+ $output .= ' ' . $suffix;
4164
+ } elseif (substr($output, 0, 4) === 'http') {
4165
+ // Parse URL Parameters if available into suffix field
4166
+ $output = woo_feed_make_url_with_parameter($output, $suffix);
4167
+ } else {
4168
+ $output .= (string)$suffix;
4169
+ }
4170
+ }
4171
+
4172
+ if ($cdata) {
4173
+ $output = '<![CDATA[' . $output . ']]>';
4174
+ }
4175
+
4176
+ return "$output";
4177
+ }
4178
+
4179
+ /**
4180
+ * Get Subscription period
4181
+ *
4182
+ * @param WC_Product $product
4183
+ *
4184
+ * @return mixed
4185
+ * @since 3.6.3
4186
+ *
4187
+ */
4188
+ protected function subscription_period($product)
4189
+ {
4190
+ if (class_exists('WC_Subscriptions')) {
4191
+ return $this->getProductMeta($product, '_subscription_period');
4192
+ }
4193
+ return '';
4194
+ }
4195
+
4196
+ /**
4197
+ * Get Subscription period interval
4198
+ *
4199
+ * @param WC_Product $product
4200
+ *
4201
+ * @return mixed
4202
+ * @since 3.6.3
4203
+ *
4204
+ */
4205
+ protected function subscription_period_interval($product)
4206
+ {
4207
+ if (class_exists('WC_Subscriptions')) {
4208
+ return $this->getProductMeta($product, '_subscription_period_interval');
4209
+ }
4210
+ return '';
4211
+ }
4212
+
4213
+ /**
4214
+ * Get Subscription period interval
4215
+ *
4216
+ * @param WC_Product $product
4217
+ *
4218
+ * @return mixed
4219
+ * @since 3.6.3
4220
+ *
4221
+ */
4222
+ protected function subscription_amount($product)
4223
+ {
4224
+ return $this->price($product);
4225
+ }
4226
+
4227
+ /**
4228
+ * Get Installment Amount
4229
+ *
4230
+ * @param WC_Product $product
4231
+ *
4232
+ * @return mixed
4233
+ * @since 4.3.101
4234
+ */
4235
+ protected function installment_amount($product)
4236
+ {
4237
+ return $this->price($product);
4238
+ }
4239
+
4240
+ /**
4241
+ * Get Installment Months
4242
+ *
4243
+ * @param WC_Product $product
4244
+ *
4245
+ * @return mixed
4246
+ * @since 4.3.101
4247
+ */
4248
+ protected function installment_months($product)
4249
+ {
4250
+ if (class_exists('WC_Subscriptions')) {
4251
+ return $this->getProductMeta($product, '_subscription_length');
4252
+ }
4253
+ return '';
4254
+ }
4255
+
4256
+
4257
+ /**
4258
+ * Calculate unit_price_measure. If Unit custom fields by CTX feed are enabled then it will take value
4259
+ * from custom fields or it will take values for WooCommerce Germanized Plugin if enabled.
4260
+ *
4261
+ * If variation values are empty then it will take value from variable product.
4262
+ *
4263
+ * @param WC_Product $product
4264
+ *
4265
+ * @return mixed
4266
+ * @since 3.6.3
4267
+ */
4268
+ protected function unit_price_measure($product)
4269
+ {
4270
+ $unit_price_measure = '';
4271
+ $identifiers = woo_feed_get_options('woo_feed_identifier');
4272
+ if ('enable' === $identifiers['unit_pricing_base_measure']
4273
+ && 'enable' === $identifiers['unit_pricing_measure']
4274
+ && 'enable' === $identifiers['unit']
4275
+ ) {
4276
+ $unit = $this->getCustomField($product, 'woo_feed_unit');
4277
+ $unit_price_measure = $this->getCustomField($product, 'woo_feed_unit_pricing_measure');
4278
+
4279
+ $unit_price_measure .= " " . $unit;
4280
+ }
4281
+
4282
+ if (empty($unit_price_measure) && class_exists('WooCommerce_Germanized')) { // For WooCommerce Germanized Plugin
4283
+ $unit = $this->getProductMeta($product, '_unit');
4284
+ $unit_price_measure = $this->getProductMeta($product, '_unit_product');
4285
+
4286
+ $unit_price_measure .= " " . $unit;
4287
+ }
4288
+
4289
+ return apply_filters('woo_feed_filter_unit_price_measure', $unit_price_measure, $product, $this->config);
4290
+ }
4291
+
4292
+ /**
4293
+ * Calculate unit_price_base_measure. If Unit custom fields by CTX feed are enabled then it will take value
4294
+ * from custom fields or it will take values for WooCommerce Germanized Plugin if enabled.
4295
+ *
4296
+ * If variation values are empty then it will take value from variable product.
4297
+ *
4298
+ * @param WC_Product $product
4299
+ *
4300
+ * @return mixed
4301
+ * @since 3.6.3
4302
+ */
4303
+ protected function unit_price_base_measure($product)
4304
+ {
4305
+ $unit_price_base_measure = '';
4306
+ $identifiers = woo_feed_get_options('woo_feed_identifier');
4307
+ if ('enable' === $identifiers['unit_pricing_base_measure']
4308
+ && 'enable' === $identifiers['unit_pricing_measure']
4309
+ && 'enable' === $identifiers['unit']
4310
+ ) {
4311
+ $unit = $this->getCustomField($product, 'woo_feed_unit');
4312
+ $unit_price_base_measure = $this->getCustomField($product, 'woo_feed_unit_pricing_base_measure');
4313
+
4314
+ $unit_price_base_measure .= " " . $unit;
4315
+ }
4316
+
4317
+ if (empty($unit_price_base_measure) && class_exists('WooCommerce_Germanized')) { // For WooCommerce Germanized Plugin
4318
+ $unit = $this->getProductMeta($product, '_unit');
4319
+ $unit_price_base_measure = $this->getProductMeta($product, '_unit_base');
4320
+
4321
+ $unit_price_base_measure .= " " . $unit;
4322
+ }
4323
+
4324
+ return apply_filters('woo_feed_filter_unit_price_base_measure', $unit_price_base_measure, $product, $this->config);
4325
+ }
4326
+
4327
+ /**
4328
+ * Get GTIN value of WooCommerce Germanized Plugin
4329
+ *
4330
+ * @param WC_Product $product
4331
+ *
4332
+ * @return mixed
4333
+ * @since 3.6.3
4334
+ */
4335
+ protected function wc_germanized_gtin($product)
4336
+ {
4337
+ $wc_germanized_gtin = '';
4338
+ if (class_exists('WooCommerce_Germanized')) { // For WooCommerce Germanized Plugin
4339
+ $wc_germanized_gtin = $this->getProductMeta($product, '_ts_gtin');
4340
+ }
4341
+
4342
+ return apply_filters('woo_feed_filter_wc_germanized_gtin', $wc_germanized_gtin, $product, $this->config);
4343
+ }
4344
+
4345
+ /**
4346
+ * Get MPN value of WooCommerce Germanized Plugin
4347
+ *
4348
+ * @param WC_Product $product
4349
+ *
4350
+ * @return mixed
4351
+ * @since 3.6.3
4352
+ */
4353
+ protected function wc_germanized_mpn($product)
4354
+ {
4355
+ $wc_germanized_mpn = '';
4356
+ if (class_exists('WooCommerce_Germanized')) { // For WooCommerce Germanized Plugin
4357
+ $wc_germanized_mpn = $this->getProductMeta($product, '_ts_mpn');
4358
+ }
4359
+
4360
+ return apply_filters('woo_feed_filter_wc_germanized_mpn', $wc_germanized_mpn, $product, $this->config);
4361
+ }
4362
+
4363
+
4364
+ /**
4365
+ * Yoast Identifier attribute for gtin8
4366
+ *
4367
+ * @param WC_Product $product
4368
+ *
4369
+ * @return mixed
4370
+ * @since 4.4.4
4371
+ */
4372
+ protected function yoast_gtin8($product)
4373
+ {
4374
+ $yoast_gtin8_value = woo_feed_get_yoast_identifiers_value('gtin8', $product);
4375
+
4376
+ return apply_filters('yoast_gtin8_attribute_value', $yoast_gtin8_value, $product);
4377
+ }
4378
+
4379
+ /**
4380
+ * Yoast Identifier attribute for gtin12
4381
+ *
4382
+ * @param WC_Product $product
4383
+ *
4384
+ * @return mixed
4385
+ * @since 4.4.4
4386
+ */
4387
+ protected function yoast_gtin12($product)
4388
+ {
4389
+ $yoast_gtin12_value = woo_feed_get_yoast_identifiers_value('gtin12', $product);
4390
+
4391
+ return apply_filters('yoast_gtin12_attribute_value', $yoast_gtin12_value, $product);
4392
+ }
4393
+
4394
+ /**
4395
+ * Yoast Identifier attribute for gtin13
4396
+ *
4397
+ * @param WC_Product $product
4398
+ *
4399
+ * @return mixed
4400
+ * @since 4.4.4
4401
+ */
4402
+ protected function yoast_gtin13($product)
4403
+ {
4404
+ $yoast_gtin13_value = woo_feed_get_yoast_identifiers_value('gtin13', $product);
4405
+
4406
+ return apply_filters('yoast_gtin13_attribute_value', $yoast_gtin13_value, $product);
4407
+ }
4408
+
4409
+ /**
4410
+ * Yoast Identifier attribute for gtin12
4411
+ *
4412
+ * @param WC_Product $product
4413
+ *
4414
+ * @return mixed
4415
+ * @since 4.4.4
4416
+ */
4417
+ protected function yoast_gtin14($product)
4418
+ {
4419
+ $yoast_gtin14_value = woo_feed_get_yoast_identifiers_value('gtin14', $product);
4420
+
4421
+ return apply_filters('yoast_gtin14_attribute_value', $yoast_gtin14_value, $product);
4422
+ }
4423
+
4424
+ /**
4425
+ * Yoast Identifier attribute for isbn
4426
+ *
4427
+ * @param WC_Product $product
4428
+ *
4429
+ * @return mixed
4430
+ * @since 4.4.4
4431
+ */
4432
+ protected function yoast_isbn($product)
4433
+ {
4434
+ $yoast_isbn_value = woo_feed_get_yoast_identifiers_value('isbn', $product);
4435
+
4436
+ return apply_filters('yoast_isbn_attribute_value', $yoast_isbn_value, $product);
4437
+ }
4438
+
4439
+ /**
4440
+ * Yoast Identifier attribute for mpn
4441
+ *
4442
+ * @param WC_Product $product
4443
+ *
4444
+ * @return mixed
4445
+ * @since 4.4.4
4446
+ */
4447
+ protected function yoast_mpn($product)
4448
+ {
4449
+ $yoast_mpn_value = woo_feed_get_yoast_identifiers_value('mpn', $product);
4450
+
4451
+ return apply_filters('yoast_mpn_attribute_value', $yoast_mpn_value, $product);
4452
+ }
4453
+
4454
+ /**
4455
+ * Rank Math GTIN Identifier attribute
4456
+ *
4457
+ * @param WC_Product $product
4458
+ *
4459
+ * @return mixed
4460
+ * @since 5.2.66
4461
+ */
4462
+ protected function rank_math_gtin($product)
4463
+ {
4464
+ $product_id = woo_feed_parent_product_id($product);
4465
+ $rankmath_gtin_value = get_post_meta($product_id, '_rank_math_gtin_code');
4466
+ $rankmath_gtin_value = !empty($rankmath_gtin_value) && is_array($rankmath_gtin_value) ? $rankmath_gtin_value[0] : '';
4467
+
4468
+ return apply_filters('rankmath_gtin_attribute_value', $rankmath_gtin_value, $product);
4469
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4470
 
4471
  /**
4472
  * Get ACF Field values
includes/feeds/class-woo-feed-review.php CHANGED
@@ -119,9 +119,6 @@ class Woo_Feed_Review {
119
  )
120
  );
121
 
122
- // echo "<pre>";
123
- // print_r($reviews);
124
-
125
  $review = array();
126
  $i=0;
127
  if ( $reviews && is_array($reviews) ) {
@@ -173,13 +170,13 @@ class Woo_Feed_Review {
173
  $attributeValue = ! empty($attributeValue) ? $attributeValue : "";
174
 
175
  if ( "review_temp_gtin" === $merchant_attribute && !empty($attributeValue)) {
176
- $review['review']['products']['product']['product_ids']['gtins']['gtin'] = $attributeValue;
177
  } elseif ( "review_temp_mpn" === $merchant_attribute && !empty($attributeValue)) {
178
- $review['review']['products']['product']['product_ids']['mpns']['mpn'] = $attributeValue;
179
  } elseif ( "review_temp_sku" === $merchant_attribute && !empty($attributeValue)) {
180
- $review['review']['products']['product']['product_ids']['skus']['sku'] = $attributeValue;
181
  } elseif ( "review_temp_brand" === $merchant_attribute && !empty($attributeValue)) {
182
- $review['review']['products']['product']['product_ids']['brands']['brand'] = $attributeValue;
183
  }
184
  }
185
 
@@ -192,6 +189,46 @@ class Woo_Feed_Review {
192
  return $feed;
193
  }
194
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195
  /**
196
  * Convert an array to XML
197
  *
119
  )
120
  );
121
 
 
 
 
122
  $review = array();
123
  $i=0;
124
  if ( $reviews && is_array($reviews) ) {
170
  $attributeValue = ! empty($attributeValue) ? $attributeValue : "";
171
 
172
  if ( "review_temp_gtin" === $merchant_attribute && !empty($attributeValue)) {
173
+ $review['review']['products']['product']['product_ids']['gtins'] = $this->get_product_ids($product,$config, $attr_key, $attribute,$merchant_attribute,'gtin');
174
  } elseif ( "review_temp_mpn" === $merchant_attribute && !empty($attributeValue)) {
175
+ $review['review']['products']['product']['product_ids']['mpns'] = $this->get_product_ids($product,$config, $attr_key, $attribute,$merchant_attribute,'mpn');
176
  } elseif ( "review_temp_sku" === $merchant_attribute && !empty($attributeValue)) {
177
+ $review['review']['products']['product']['product_ids']['skus'] = $this->get_product_ids($product,$config, $attr_key, $attribute,$merchant_attribute,'sku');
178
  } elseif ( "review_temp_brand" === $merchant_attribute && !empty($attributeValue)) {
179
+ $review['review']['products']['product']['product_ids']['brands'] = $this->get_product_ids($product,$config, $attr_key, $attribute,$merchant_attribute,'brand');
180
  }
181
  }
182
 
189
  return $feed;
190
  }
191
 
192
+ /**
193
+ * Get Product Ids associated with a review (Ex: variations)
194
+ *
195
+ * @param $product
196
+ * @param $config
197
+ * @param $attr_key
198
+ * @param $attribute
199
+ * @param $merchant_attribute
200
+ * @param $id_type
201
+ * @return array
202
+ */
203
+ public function get_product_ids($product, $config, $attr_key, $attribute, $merchant_attribute, $id_type)
204
+ {
205
+ if($product->is_type('variable')){
206
+ $variations = $product->get_children();
207
+ if(!empty($variations)){
208
+ $variation_ids = [];
209
+ foreach ($variations as $key=>$variation){
210
+ $product = wc_get_product($variation);
211
+ if ( 'pattern' === $config['type'][ $attr_key ] ) {
212
+ $variation_ids[$key][$id_type] = $config['default'][ $attr_key ];
213
+ }else{
214
+ $variation_ids[$key][$id_type] = $this->products->getAttributeValueByType($product, $attribute, $merchant_attribute);
215
+ }
216
+ }
217
+ return $variation_ids;
218
+ }
219
+ }
220
+
221
+ // For non variation products
222
+ $attributeValue = "";
223
+ if ( 'pattern' === $config['type'][ $attr_key ] ) {
224
+ $attributeValue = $config['default'][ $attr_key ];
225
+ }else{
226
+ $attributeValue = $this->products->getAttributeValueByType($product, $attribute, $merchant_attribute);
227
+ }
228
+
229
+ return [$id_type=>$attributeValue];
230
+ }
231
+
232
  /**
233
  * Convert an array to XML
234
  *
includes/filters/filters.php CHANGED
@@ -18,7 +18,7 @@ function CTXFEED_filter_securing_input_cb($meth = "POST", $inpu = '', $type = "t
18
  $outp = '';
19
  switch ( $type ) {
20
  case "email":
21
- $outp = sanitize_text_email($inpu);
22
  break;
23
 
24
  case "text":
18
  $outp = '';
19
  switch ( $type ) {
20
  case "email":
21
+ $outp = sanitize_email($inpu);
22
  break;
23
 
24
  case "text":
woo-feed.php CHANGED
@@ -10,7 +10,7 @@
10
  * Plugin Name: CTX Feed
11
  * Plugin URI: https://webappick.com/
12
  * Description: Easily generate woocommerce product feed for any marketing channel like Google Shopping(Merchant), Facebook Remarketing, Bing, eBay & more. Support 100+ Merchants.
13
- * Version: 4.4.63
14
  * Author: WebAppick
15
  * Author URI: https://webappick.com/
16
  * License: GPL v2
@@ -163,24 +163,24 @@ if ( ! function_exists( 'woo_feed_get_product_information' ) ) {
163
  }
164
  try {
165
  do_action( 'before_woo_feed_get_product_information', $getConfig );
166
- // if ( isset($getConfig['provider']) && 'googlereview' === $getConfig['provider'] ) {
167
- // $args = array(
168
- // 'post_type' => 'product',
169
- // 'fields' => 'ids',
170
- // 'comment_count' => array(
171
- // 'value' => 0,
172
- // 'compare' => '>',
173
- // ),
174
- // );
175
- //
176
- // $ids = get_posts($args);
177
- //
178
- // }else {
179
- //
180
- // }
 
 
181
 
182
- $products = new Woo_Feed_Products_v3( $getConfig );
183
- $ids = $products->query_products();
184
 
185
  do_action( 'after_woo_feed_get_product_information', $getConfig );
186
  woo_feed_log_feed_process( $getConfig['filename'], sprintf( 'Total %d product found', is_array( $ids ) && ! empty( $ids ) ? count( $ids ) : 0 ) );
10
  * Plugin Name: CTX Feed
11
  * Plugin URI: https://webappick.com/
12
  * Description: Easily generate woocommerce product feed for any marketing channel like Google Shopping(Merchant), Facebook Remarketing, Bing, eBay & more. Support 100+ Merchants.
13
+ * Version: 4.4.64
14
  * Author: WebAppick
15
  * Author URI: https://webappick.com/
16
  * License: GPL v2
163
  }
164
  try {
165
  do_action( 'before_woo_feed_get_product_information', $getConfig );
166
+ if ( isset($getConfig['provider']) && 'googlereview' === $getConfig['provider'] ) {
167
+ $args = array(
168
+ 'post_type' => 'product',
169
+ 'fields' => 'ids',
170
+ 'comment_count' => array(
171
+ 'value' => 0,
172
+ 'compare' => '>',
173
+ ),
174
+ );
175
+
176
+ $ids = get_posts($args);
177
+
178
+ }else {
179
+ $products = new Woo_Feed_Products_v3( $getConfig );
180
+ $ids = $products->query_products();
181
+ }
182
+
183
 
 
 
184
 
185
  do_action( 'after_woo_feed_get_product_information', $getConfig );
186
  woo_feed_log_feed_process( $getConfig['filename'], sprintf( 'Total %d product found', is_array( $ids ) && ! empty( $ids ) ? count( $ids ) : 0 ) );