CTX Feed – WooCommerce Product Feed Manager Plugin - Version 4.5.5

Version Description

(2022-10-17) = * Added: Product Status attribute added.

Download this release

Release Info

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

Code changes from version 4.5.4 to 4.5.5

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: 6.0
7
  Requires PHP: 5.6
8
- Stable tag: 4.5.4
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.5.4 (2022-10-22) =
 
 
 
594
  * Fixed: Minor issues fixed.
595
 
596
  = 4.5.3 (2022-09-22) =
5
  Requires at least: 4.4
6
  Tested Up To: 6.0
7
  Requires PHP: 5.6
8
+ Stable tag: 4.5.5
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
590
 
591
  == Changelog ==
592
 
593
+ = 4.5.5 (2022-10-17) =
594
+ * Added: Product Status attribute added.
595
+
596
+ = 4.5.4 (2022-10-12) =
597
  * Fixed: Minor issues fixed.
598
 
599
  = 4.5.3 (2022-09-22) =
V5/Product/ProductAttributeFactory.php CHANGED
@@ -26,7 +26,7 @@ class ProductAttributeFactory {
26
  * @var $attributes
27
  */
28
  public $attributes;
29
-
30
  /**
31
  * Get Product Attributes
32
  *
@@ -35,7 +35,7 @@ class ProductAttributeFactory {
35
  public static function getAttributes() {
36
  return self::setAttributes();
37
  }
38
-
39
  private static function setAttributes() {
40
  $attributes = [];
41
  $primaryAttributes = [
@@ -81,12 +81,13 @@ class ProductAttributeFactory {
81
  'author_email' => esc_html__( 'Author Email', 'woo-feed' ),
82
  'date_created' => esc_html__( 'Date Created', 'woo-feed' ),
83
  'date_updated' => esc_html__( 'Date Updated', 'woo-feed' ),
 
84
  ]
85
  ];
86
-
87
  $attributes [] = $primaryAttributes;
88
-
89
-
90
  $imageAttributes = [
91
  'optionGroup' => esc_html__( 'Images', 'woo-feed' ),
92
  'options' => [
@@ -105,9 +106,9 @@ class ProductAttributeFactory {
105
  'image_10' => esc_html__( 'Additional Image 10', 'woo-feed' ),
106
  ],
107
  ];
108
-
109
  $attributes [] = $imageAttributes;
110
-
111
  $priceAttributes = [
112
  'optionGroup' => esc_html__( 'Price', 'woo-feed' ),
113
  'options' => [
@@ -123,9 +124,9 @@ class ProductAttributeFactory {
123
  'sale_price_effective_date' => esc_html__( 'Sale Price Effective Date', 'woo-feed' ),
124
  ],
125
  ];
126
-
127
  $attributes [] = $priceAttributes;
128
-
129
  $shippingAttributes = [
130
  'optionGroup' => esc_html__( 'Shipping', 'woo-feed' ),
131
  'options' => [
@@ -139,9 +140,9 @@ class ProductAttributeFactory {
139
  // 'shipping_price' => esc_html__( 'Shipping Cost', 'woo-feed' ),
140
  ],
141
  ];
142
-
143
  $attributes [] = $shippingAttributes;
144
-
145
  $taxAttributes = [
146
  'optionGroup' => esc_html__( 'Tax', 'woo-feed' ),
147
  'options' => [
@@ -156,9 +157,9 @@ class ProductAttributeFactory {
156
  // 'tax_label' => esc_html__( 'Tax Name', 'woo-feed' ),
157
  ],
158
  ];
159
-
160
  $attributes [] = $taxAttributes;
161
-
162
  $subscriptionAttributes = [
163
  'optionGroup' => esc_html__( 'Subscription & Installment', 'woo-feed' ),
164
  'options' => [
@@ -169,7 +170,7 @@ class ProductAttributeFactory {
169
  'installment_amount' => esc_html__( 'Installment Amount', 'woo-feed' ),
170
  ],
171
  ];
172
-
173
  $customXMLAttributes = [
174
  'optionGroup' => esc_html__( 'Custom Template 2 (XML)', 'woo-feed' ),
175
  'options' => [
@@ -178,7 +179,7 @@ class ProductAttributeFactory {
178
  'custom_xml_categories' => esc_html__( 'Product Categories', 'woo-feed' ),
179
  ]
180
  ];
181
-
182
  /**
183
  * Add subscription attributes if WooCommerce Subscription plugin installed.
184
  *
@@ -187,7 +188,7 @@ class ProductAttributeFactory {
187
  if ( class_exists( 'WC_Subscriptions' ) ) {
188
  $attributes[] = $subscriptionAttributes;
189
  }
190
-
191
  $attributes[] = self::getPluginsCustomFields();
192
  $attributes[] = self::getUnitPriceAttributes();
193
  $attributes[] = self::getSeoPluginAttributes();
@@ -201,7 +202,7 @@ class ProductAttributeFactory {
201
  $attributes[] = self::getACFAttributes();
202
  // Custom Fields & Post Metas
203
  $attributes[] = self::getProductMetaKeyAttributes();
204
-
205
  if ( defined( 'WOO_FEED_PRO_VERSION' ) ) { // class_exists( 'Woo_Feed_Products_v3_Pro' )
206
  $attributes [] = self::getMultiLanguageAttributes();
207
  $attributes [] = self::getMultiVendorAttributes();
@@ -212,17 +213,17 @@ class ProductAttributeFactory {
212
  // Custom Template 2 Attributes
213
  $attributes [] = $customXMLAttributes;
214
  }
215
-
216
  return apply_filters( 'woo_feed_product_attribute_dropdown', $attributes );
217
  }
218
-
219
  /**
220
  * Get CTX Feed plugins Custom Fields.
221
  *
222
  * @return array
223
  */
224
  private static function getPluginsCustomFields() {
225
-
226
  $custom_fields = woo_feed_product_custom_fields();
227
  $custom_identifier_filter = new Woo_Feed_Custom_Identifier_Filter( $custom_fields );
228
  $custom_identifier = iterator_to_array( $custom_identifier_filter );
@@ -232,17 +233,17 @@ class ProductAttributeFactory {
232
  $activeAttributes['options'][ 'woo_feed_identifier_' . sanitize_text_field( wp_unslash( $key ) ) ] = sanitize_text_field( $value[0] );
233
  }
234
  }
235
-
236
  return ! empty( $activeAttributes['options'] ) ? $activeAttributes : [];
237
  }
238
-
239
  /**
240
  * Get Unit Price Attributes.
241
  *
242
  * @return array
243
  */
244
  private static function getUnitPriceAttributes() {
245
-
246
  $unitPriceAttributes = [
247
  'optionGroup' => esc_html__( 'Unit Price (CTX Feed)', 'woo-feed' ),
248
  'options' => [
@@ -251,7 +252,7 @@ class ProductAttributeFactory {
251
  'unit_price_base_measure' => esc_html__( 'Unit Price Base Measure', 'woo-feed' ),
252
  ],
253
  ];
254
-
255
  /**
256
  * Get Germanized for WooCommerce plugins unit attributes.
257
  *
@@ -269,17 +270,17 @@ class ProductAttributeFactory {
269
  ];
270
  $unitPriceAttributes += $wcUnitPriceAttributes;
271
  }
272
-
273
  return $unitPriceAttributes;
274
  }
275
-
276
  /**
277
  * Get installed SEO plugin attributes.
278
  *
279
  * @return array
280
  */
281
  private static function getSeoPluginAttributes() {
282
-
283
  $seoAttributes = [];
284
  /**
285
  * Get Yoast SEO Plugin Attributes.
@@ -287,7 +288,7 @@ class ProductAttributeFactory {
287
  * @link https://wordpress.org/plugins/wordpress-seo/
288
  */
289
  if ( class_exists( 'WPSEO_Frontend' ) || class_exists( 'WPSEO_Premium' ) ) {
290
-
291
  $seoAttributes = [
292
  'optionGroup' => esc_html__( 'Yoast SEO', 'woo-feed' ),
293
  'options' => [
@@ -296,7 +297,7 @@ class ProductAttributeFactory {
296
  'yoast_canonical_url' => esc_html__( 'Canonical URL [Yoast SEO]', 'woo-feed' ),
297
  ],
298
  ];
299
-
300
  /**
301
  * Get Yoast WooCommerce SEO plugins Identifier Attributes.
302
  *
@@ -313,7 +314,7 @@ class ProductAttributeFactory {
313
  ];
314
  }
315
  }
316
-
317
  if ( class_exists( 'RankMath' ) || class_exists( 'RankMathPro' ) ) {
318
  $seoAttributes = [
319
  'optionGroup' => esc_html__( 'RANK MATH SEO', 'woo-feed' ),
@@ -323,12 +324,12 @@ class ProductAttributeFactory {
323
  'rank_math_canonical_url' => esc_html__( 'Canonical URL [RankMath SEO]', 'woo-feed' )
324
  ],
325
  ];
326
-
327
  if ( class_exists( 'RankMathPro' ) ) {
328
  $seoAttributes['options'] += [ 'rank_math_gtin' => esc_html__( 'GTIN [RankMath Pro SEO]', 'woo-feed' ) ];
329
  }
330
  }
331
-
332
  if ( class_exists( 'AIOSEO\Plugin\AIOSEO' ) ) {
333
  $seoAttributes = [
334
  'optionGroup' => esc_html__( 'ALL IN ONE SEO', 'woo-feed' ),
@@ -339,10 +340,10 @@ class ProductAttributeFactory {
339
  ],
340
  ];
341
  }
342
-
343
  return $seoAttributes;
344
  }
345
-
346
  /**
347
  * Get Product Global Attributes.
348
  *
@@ -360,13 +361,13 @@ class ProductAttributeFactory {
360
  }
361
  Cache::set( 'getAttributeTaxonomies', $taxonomies );
362
  }
363
-
364
  return [
365
  'optionGroup' => esc_html__( 'Product Attributes', 'woo-feed' ),
366
  'options' => $taxonomies,
367
  ];
368
  }
369
-
370
  /**
371
  * Get Product Custom Attributes.
372
  *
@@ -379,16 +380,16 @@ class ProductAttributeFactory {
379
  $attributes = self::queryVariationsAttributes();
380
  // Get Product Custom Attributes
381
  $attributes += self::queryCustomAttributes();
382
-
383
  Cache::set( 'woo_feed_dropdown_product_custom_attributes', $attributes );
384
  }
385
-
386
  return [
387
  'optionGroup' => esc_html__( 'Product Custom Attributes', 'woo-feed' ),
388
  'options' => $attributes,
389
  ];
390
  }
391
-
392
  /**
393
  * Get Variation Attributes
394
  * Local attributes will be found on variation product meta only with attribute_ suffix
@@ -406,15 +407,15 @@ class ProductAttributeFactory {
406
  )";
407
  // sanitization ok
408
  $localAttributes = $wpdb->get_col( $sql ); // phpcs:ignore
409
-
410
  foreach ( $localAttributes as $localAttribute ) {
411
  $localAttribute = str_replace( 'attribute_', '', $localAttribute );
412
  $attributes[ AttributeValueByType::PRODUCT_ATTRIBUTE_PREFIX . $localAttribute ] = ucwords( str_replace( '-', ' ', $localAttribute ) );
413
  }
414
-
415
  return $attributes;
416
  }
417
-
418
  /**
419
  * Get Product Custom Attributes
420
  */
@@ -435,10 +436,10 @@ class ProductAttributeFactory {
435
  }
436
  }
437
  }
438
-
439
  return $attributes;
440
  }
441
-
442
  /**
443
  * Get All Taxonomy
444
  *
@@ -457,17 +458,17 @@ class ProductAttributeFactory {
457
  'product_shipping_class',
458
  'translation_priority',
459
  );
460
-
461
  /**
462
  * Exclude Taxonomy from dropdown
463
  *
464
  * @param array $user_excludes
465
  * @param array $default_excludes
466
  */
467
-
468
  $user_excludes = apply_filters( 'woo_feed_dropdown_exclude_taxonomy', null, $default_excludes );
469
  $default_excludes = ! empty( $user_excludes ) ? array_merge( $default_excludes, $user_excludes ) : $default_excludes;
470
-
471
  foreach ( get_object_taxonomies( 'product' ) as $value ) {
472
  $value = ! empty( $value ) ? trim( $value ) : $value;
473
  if ( in_array( $value, $default_excludes, true ) || strpos( $value, 'pa_' ) !== false ) {
@@ -476,16 +477,16 @@ class ProductAttributeFactory {
476
  $label = isset( $wp_taxonomies[ $value ] ) ? $wp_taxonomies[ $value ]->label . " [$value]" : $value;
477
  $info[ Woo_Feed_Products_v3::PRODUCT_TAXONOMY_PREFIX . $value ] = $label;
478
  }
479
-
480
  Cache::set( 'woo_feed_dropdown_product_taxonomy', $info );
481
  }
482
-
483
  return [
484
  'optionGroup' => esc_html__( 'Product Taxonomies', 'woo-feed' ),
485
  'options' => $info,
486
  ];
487
  }
488
-
489
  /**
490
  * Get All Options
491
  *
@@ -495,13 +496,13 @@ class ProductAttributeFactory {
495
  $_wp_options = wp_list_pluck( get_option( 'wpfp_option', array() ), 'option_name' );
496
  $_wp_options_val = str_replace( 'wf_option_', '', $_wp_options );
497
  $_wp_options = array_combine( $_wp_options, $_wp_options_val );
498
-
499
  return [
500
  'optionGroup' => esc_html__( 'Options', 'woo-feed' ),
501
  'options' => $_wp_options,
502
  ];
503
  }
504
-
505
  /**
506
  * Get Category Mappings
507
  *
@@ -524,13 +525,13 @@ class ProductAttributeFactory {
524
  );
525
  }
526
  }
527
-
528
  return [
529
  'optionGroup' => esc_html__( 'Category Mapping', 'woo-feed' ),
530
  'options' => $info,
531
  ];
532
  }
533
-
534
  /**
535
  * Get Advance Custom Field (ACF) field list
536
  *
@@ -561,17 +562,17 @@ class ProductAttributeFactory {
561
  $options[ 'acf_fields_' . $field->post_name ] = $field->post_title;
562
  }
563
  }
564
-
565
  Cache::set( 'acf_field_list', $options );
566
  }
567
  }
568
-
569
  return [
570
  'optionGroup' => esc_html__( 'Advance Custom Fields (ACF)', 'woo-feed' ),
571
  'options' => $options,
572
  ];
573
  }
574
-
575
  /**
576
  * Get All Custom Attributes
577
  *
@@ -583,7 +584,7 @@ class ProductAttributeFactory {
583
  global $wpdb;
584
  $info = [];
585
  // Load the main attributes.
586
-
587
  $default_exclude_keys = [
588
  // WP internals.
589
  '_edit_lock',
@@ -617,7 +618,7 @@ class ProductAttributeFactory {
617
  'frs_woo_product_tabs',
618
  // WooCommerce Custom Product Tabs http://www.skyverge.com/.
619
  ];
620
-
621
  /**
622
  * Exclude meta keys from dropdown
623
  *
@@ -625,15 +626,15 @@ class ProductAttributeFactory {
625
  * @param array $default_exclude_keys Exclude keys by default.
626
  */
627
  $user_exclude = apply_filters( 'woo_feed_dropdown_exclude_meta_keys', null, $default_exclude_keys );
628
-
629
  if ( is_array( $user_exclude ) && ! empty( $user_exclude ) ) {
630
  $user_exclude = esc_sql( $user_exclude );
631
  $default_exclude_keys = array_merge( $default_exclude_keys, $user_exclude );
632
  }
633
-
634
  $default_exclude_keys = array_map( 'esc_sql', $default_exclude_keys );
635
  $exclude_keys = '\'' . implode( '\', \'', $default_exclude_keys ) . '\'';
636
-
637
  $default_exclude_key_patterns = [
638
  '%_et_pb_%', // Divi builder data
639
  'attribute_%', // Exclude product attributes from meta list
@@ -644,7 +645,7 @@ class ProductAttributeFactory {
644
  '_wpml_%', // wpml metas
645
  '_oh_add_script_%', // SOGO Add Script to Individual Pages Header Footer.
646
  ];
647
-
648
  /**
649
  * Exclude meta key patterns from dropdown
650
  *
@@ -659,12 +660,12 @@ class ProductAttributeFactory {
659
  foreach ( $default_exclude_key_patterns as $pattern ) {
660
  $exclude_key_patterns .= $wpdb->prepare( ' AND meta_key NOT LIKE %s', $pattern );
661
  }
662
-
663
  $sql = sprintf( /** @lang text */ "SELECT DISTINCT( meta_key ) FROM %s WHERE 1=1 AND post_id IN ( SELECT ID FROM %s WHERE post_type = 'product' OR post_type = 'product_variation' ) AND ( meta_key NOT IN ( %s ) %s )", $wpdb->postmeta, $wpdb->posts, $exclude_keys, $exclude_key_patterns );
664
-
665
  // sql escaped, cached
666
  $data = $wpdb->get_results( $sql ); // phpcs:ignore
667
-
668
  if ( count( $data ) ) {
669
  foreach ( $data as $value ) {
670
  //TODO Remove ACF Fields
@@ -673,13 +674,13 @@ class ProductAttributeFactory {
673
  }
674
  Cache::set( 'woo_feed_dropdown_meta_keys', $info );
675
  }
676
-
677
  return [
678
  'optionGroup' => esc_html__( 'Custom Fields & Post Metas', 'woo-feed' ),
679
  'options' => $info,
680
  ];
681
  }
682
-
683
  /**
684
  * Get Dynamic Attribute List
685
  *
@@ -687,7 +688,7 @@ class ProductAttributeFactory {
687
  */
688
  private static function getDynamicAttributes() {
689
  global $wpdb;
690
-
691
  // Load Custom Category Mapped Attributes
692
  $info = array();
693
  // query escaped and cached
@@ -703,13 +704,13 @@ class ProductAttributeFactory {
703
  );
704
  }
705
  }
706
-
707
  return [
708
  'optionGroup' => esc_html__( 'Dynamic Attributes', 'woo-feed' ),
709
  'options' => $info,
710
  ];
711
  }
712
-
713
  /**
714
  * Get Attribute Mappings
715
  *
@@ -727,13 +728,13 @@ class ProductAttributeFactory {
727
  $info[ $value->option_name ] = is_array( $opts ) && isset( $opts['name'] ) ? $opts['name'] : str_replace( AttributeValueByType::PRODUCT_ATTRIBUTE_MAPPING_PREFIX, '', $value->option_name );
728
  }
729
  }
730
-
731
  return [
732
  'optionGroup' => esc_html__( 'Attribute Mappings', 'woo-feed' ),
733
  'options' => $info,
734
  ];
735
  }
736
-
737
  /**
738
  * @return array
739
  */
@@ -747,10 +748,10 @@ class ProductAttributeFactory {
747
  ]
748
  ];
749
  }
750
-
751
  return $attributes;
752
  }
753
-
754
  /**
755
  * @return array
756
  */
@@ -764,7 +765,7 @@ class ProductAttributeFactory {
764
  ]
765
  ];
766
  }
767
-
768
  return $attributes;
769
  }
770
  }
26
  * @var $attributes
27
  */
28
  public $attributes;
29
+
30
  /**
31
  * Get Product Attributes
32
  *
35
  public static function getAttributes() {
36
  return self::setAttributes();
37
  }
38
+
39
  private static function setAttributes() {
40
  $attributes = [];
41
  $primaryAttributes = [
81
  'author_email' => esc_html__( 'Author Email', 'woo-feed' ),
82
  'date_created' => esc_html__( 'Date Created', 'woo-feed' ),
83
  'date_updated' => esc_html__( 'Date Updated', 'woo-feed' ),
84
+ 'product_status' => esc_html__( 'Product Status', 'woo-feed' ),
85
  ]
86
  ];
87
+
88
  $attributes [] = $primaryAttributes;
89
+
90
+
91
  $imageAttributes = [
92
  'optionGroup' => esc_html__( 'Images', 'woo-feed' ),
93
  'options' => [
106
  'image_10' => esc_html__( 'Additional Image 10', 'woo-feed' ),
107
  ],
108
  ];
109
+
110
  $attributes [] = $imageAttributes;
111
+
112
  $priceAttributes = [
113
  'optionGroup' => esc_html__( 'Price', 'woo-feed' ),
114
  'options' => [
124
  'sale_price_effective_date' => esc_html__( 'Sale Price Effective Date', 'woo-feed' ),
125
  ],
126
  ];
127
+
128
  $attributes [] = $priceAttributes;
129
+
130
  $shippingAttributes = [
131
  'optionGroup' => esc_html__( 'Shipping', 'woo-feed' ),
132
  'options' => [
140
  // 'shipping_price' => esc_html__( 'Shipping Cost', 'woo-feed' ),
141
  ],
142
  ];
143
+
144
  $attributes [] = $shippingAttributes;
145
+
146
  $taxAttributes = [
147
  'optionGroup' => esc_html__( 'Tax', 'woo-feed' ),
148
  'options' => [
157
  // 'tax_label' => esc_html__( 'Tax Name', 'woo-feed' ),
158
  ],
159
  ];
160
+
161
  $attributes [] = $taxAttributes;
162
+
163
  $subscriptionAttributes = [
164
  'optionGroup' => esc_html__( 'Subscription & Installment', 'woo-feed' ),
165
  'options' => [
170
  'installment_amount' => esc_html__( 'Installment Amount', 'woo-feed' ),
171
  ],
172
  ];
173
+
174
  $customXMLAttributes = [
175
  'optionGroup' => esc_html__( 'Custom Template 2 (XML)', 'woo-feed' ),
176
  'options' => [
179
  'custom_xml_categories' => esc_html__( 'Product Categories', 'woo-feed' ),
180
  ]
181
  ];
182
+
183
  /**
184
  * Add subscription attributes if WooCommerce Subscription plugin installed.
185
  *
188
  if ( class_exists( 'WC_Subscriptions' ) ) {
189
  $attributes[] = $subscriptionAttributes;
190
  }
191
+
192
  $attributes[] = self::getPluginsCustomFields();
193
  $attributes[] = self::getUnitPriceAttributes();
194
  $attributes[] = self::getSeoPluginAttributes();
202
  $attributes[] = self::getACFAttributes();
203
  // Custom Fields & Post Metas
204
  $attributes[] = self::getProductMetaKeyAttributes();
205
+
206
  if ( defined( 'WOO_FEED_PRO_VERSION' ) ) { // class_exists( 'Woo_Feed_Products_v3_Pro' )
207
  $attributes [] = self::getMultiLanguageAttributes();
208
  $attributes [] = self::getMultiVendorAttributes();
213
  // Custom Template 2 Attributes
214
  $attributes [] = $customXMLAttributes;
215
  }
216
+
217
  return apply_filters( 'woo_feed_product_attribute_dropdown', $attributes );
218
  }
219
+
220
  /**
221
  * Get CTX Feed plugins Custom Fields.
222
  *
223
  * @return array
224
  */
225
  private static function getPluginsCustomFields() {
226
+
227
  $custom_fields = woo_feed_product_custom_fields();
228
  $custom_identifier_filter = new Woo_Feed_Custom_Identifier_Filter( $custom_fields );
229
  $custom_identifier = iterator_to_array( $custom_identifier_filter );
233
  $activeAttributes['options'][ 'woo_feed_identifier_' . sanitize_text_field( wp_unslash( $key ) ) ] = sanitize_text_field( $value[0] );
234
  }
235
  }
236
+
237
  return ! empty( $activeAttributes['options'] ) ? $activeAttributes : [];
238
  }
239
+
240
  /**
241
  * Get Unit Price Attributes.
242
  *
243
  * @return array
244
  */
245
  private static function getUnitPriceAttributes() {
246
+
247
  $unitPriceAttributes = [
248
  'optionGroup' => esc_html__( 'Unit Price (CTX Feed)', 'woo-feed' ),
249
  'options' => [
252
  'unit_price_base_measure' => esc_html__( 'Unit Price Base Measure', 'woo-feed' ),
253
  ],
254
  ];
255
+
256
  /**
257
  * Get Germanized for WooCommerce plugins unit attributes.
258
  *
270
  ];
271
  $unitPriceAttributes += $wcUnitPriceAttributes;
272
  }
273
+
274
  return $unitPriceAttributes;
275
  }
276
+
277
  /**
278
  * Get installed SEO plugin attributes.
279
  *
280
  * @return array
281
  */
282
  private static function getSeoPluginAttributes() {
283
+
284
  $seoAttributes = [];
285
  /**
286
  * Get Yoast SEO Plugin Attributes.
288
  * @link https://wordpress.org/plugins/wordpress-seo/
289
  */
290
  if ( class_exists( 'WPSEO_Frontend' ) || class_exists( 'WPSEO_Premium' ) ) {
291
+
292
  $seoAttributes = [
293
  'optionGroup' => esc_html__( 'Yoast SEO', 'woo-feed' ),
294
  'options' => [
297
  'yoast_canonical_url' => esc_html__( 'Canonical URL [Yoast SEO]', 'woo-feed' ),
298
  ],
299
  ];
300
+
301
  /**
302
  * Get Yoast WooCommerce SEO plugins Identifier Attributes.
303
  *
314
  ];
315
  }
316
  }
317
+
318
  if ( class_exists( 'RankMath' ) || class_exists( 'RankMathPro' ) ) {
319
  $seoAttributes = [
320
  'optionGroup' => esc_html__( 'RANK MATH SEO', 'woo-feed' ),
324
  'rank_math_canonical_url' => esc_html__( 'Canonical URL [RankMath SEO]', 'woo-feed' )
325
  ],
326
  ];
327
+
328
  if ( class_exists( 'RankMathPro' ) ) {
329
  $seoAttributes['options'] += [ 'rank_math_gtin' => esc_html__( 'GTIN [RankMath Pro SEO]', 'woo-feed' ) ];
330
  }
331
  }
332
+
333
  if ( class_exists( 'AIOSEO\Plugin\AIOSEO' ) ) {
334
  $seoAttributes = [
335
  'optionGroup' => esc_html__( 'ALL IN ONE SEO', 'woo-feed' ),
340
  ],
341
  ];
342
  }
343
+
344
  return $seoAttributes;
345
  }
346
+
347
  /**
348
  * Get Product Global Attributes.
349
  *
361
  }
362
  Cache::set( 'getAttributeTaxonomies', $taxonomies );
363
  }
364
+
365
  return [
366
  'optionGroup' => esc_html__( 'Product Attributes', 'woo-feed' ),
367
  'options' => $taxonomies,
368
  ];
369
  }
370
+
371
  /**
372
  * Get Product Custom Attributes.
373
  *
380
  $attributes = self::queryVariationsAttributes();
381
  // Get Product Custom Attributes
382
  $attributes += self::queryCustomAttributes();
383
+
384
  Cache::set( 'woo_feed_dropdown_product_custom_attributes', $attributes );
385
  }
386
+
387
  return [
388
  'optionGroup' => esc_html__( 'Product Custom Attributes', 'woo-feed' ),
389
  'options' => $attributes,
390
  ];
391
  }
392
+
393
  /**
394
  * Get Variation Attributes
395
  * Local attributes will be found on variation product meta only with attribute_ suffix
407
  )";
408
  // sanitization ok
409
  $localAttributes = $wpdb->get_col( $sql ); // phpcs:ignore
410
+
411
  foreach ( $localAttributes as $localAttribute ) {
412
  $localAttribute = str_replace( 'attribute_', '', $localAttribute );
413
  $attributes[ AttributeValueByType::PRODUCT_ATTRIBUTE_PREFIX . $localAttribute ] = ucwords( str_replace( '-', ' ', $localAttribute ) );
414
  }
415
+
416
  return $attributes;
417
  }
418
+
419
  /**
420
  * Get Product Custom Attributes
421
  */
436
  }
437
  }
438
  }
439
+
440
  return $attributes;
441
  }
442
+
443
  /**
444
  * Get All Taxonomy
445
  *
458
  'product_shipping_class',
459
  'translation_priority',
460
  );
461
+
462
  /**
463
  * Exclude Taxonomy from dropdown
464
  *
465
  * @param array $user_excludes
466
  * @param array $default_excludes
467
  */
468
+
469
  $user_excludes = apply_filters( 'woo_feed_dropdown_exclude_taxonomy', null, $default_excludes );
470
  $default_excludes = ! empty( $user_excludes ) ? array_merge( $default_excludes, $user_excludes ) : $default_excludes;
471
+
472
  foreach ( get_object_taxonomies( 'product' ) as $value ) {
473
  $value = ! empty( $value ) ? trim( $value ) : $value;
474
  if ( in_array( $value, $default_excludes, true ) || strpos( $value, 'pa_' ) !== false ) {
477
  $label = isset( $wp_taxonomies[ $value ] ) ? $wp_taxonomies[ $value ]->label . " [$value]" : $value;
478
  $info[ Woo_Feed_Products_v3::PRODUCT_TAXONOMY_PREFIX . $value ] = $label;
479
  }
480
+
481
  Cache::set( 'woo_feed_dropdown_product_taxonomy', $info );
482
  }
483
+
484
  return [
485
  'optionGroup' => esc_html__( 'Product Taxonomies', 'woo-feed' ),
486
  'options' => $info,
487
  ];
488
  }
489
+
490
  /**
491
  * Get All Options
492
  *
496
  $_wp_options = wp_list_pluck( get_option( 'wpfp_option', array() ), 'option_name' );
497
  $_wp_options_val = str_replace( 'wf_option_', '', $_wp_options );
498
  $_wp_options = array_combine( $_wp_options, $_wp_options_val );
499
+
500
  return [
501
  'optionGroup' => esc_html__( 'Options', 'woo-feed' ),
502
  'options' => $_wp_options,
503
  ];
504
  }
505
+
506
  /**
507
  * Get Category Mappings
508
  *
525
  );
526
  }
527
  }
528
+
529
  return [
530
  'optionGroup' => esc_html__( 'Category Mapping', 'woo-feed' ),
531
  'options' => $info,
532
  ];
533
  }
534
+
535
  /**
536
  * Get Advance Custom Field (ACF) field list
537
  *
562
  $options[ 'acf_fields_' . $field->post_name ] = $field->post_title;
563
  }
564
  }
565
+
566
  Cache::set( 'acf_field_list', $options );
567
  }
568
  }
569
+
570
  return [
571
  'optionGroup' => esc_html__( 'Advance Custom Fields (ACF)', 'woo-feed' ),
572
  'options' => $options,
573
  ];
574
  }
575
+
576
  /**
577
  * Get All Custom Attributes
578
  *
584
  global $wpdb;
585
  $info = [];
586
  // Load the main attributes.
587
+
588
  $default_exclude_keys = [
589
  // WP internals.
590
  '_edit_lock',
618
  'frs_woo_product_tabs',
619
  // WooCommerce Custom Product Tabs http://www.skyverge.com/.
620
  ];
621
+
622
  /**
623
  * Exclude meta keys from dropdown
624
  *
626
  * @param array $default_exclude_keys Exclude keys by default.
627
  */
628
  $user_exclude = apply_filters( 'woo_feed_dropdown_exclude_meta_keys', null, $default_exclude_keys );
629
+
630
  if ( is_array( $user_exclude ) && ! empty( $user_exclude ) ) {
631
  $user_exclude = esc_sql( $user_exclude );
632
  $default_exclude_keys = array_merge( $default_exclude_keys, $user_exclude );
633
  }
634
+
635
  $default_exclude_keys = array_map( 'esc_sql', $default_exclude_keys );
636
  $exclude_keys = '\'' . implode( '\', \'', $default_exclude_keys ) . '\'';
637
+
638
  $default_exclude_key_patterns = [
639
  '%_et_pb_%', // Divi builder data
640
  'attribute_%', // Exclude product attributes from meta list
645
  '_wpml_%', // wpml metas
646
  '_oh_add_script_%', // SOGO Add Script to Individual Pages Header Footer.
647
  ];
648
+
649
  /**
650
  * Exclude meta key patterns from dropdown
651
  *
660
  foreach ( $default_exclude_key_patterns as $pattern ) {
661
  $exclude_key_patterns .= $wpdb->prepare( ' AND meta_key NOT LIKE %s', $pattern );
662
  }
663
+
664
  $sql = sprintf( /** @lang text */ "SELECT DISTINCT( meta_key ) FROM %s WHERE 1=1 AND post_id IN ( SELECT ID FROM %s WHERE post_type = 'product' OR post_type = 'product_variation' ) AND ( meta_key NOT IN ( %s ) %s )", $wpdb->postmeta, $wpdb->posts, $exclude_keys, $exclude_key_patterns );
665
+
666
  // sql escaped, cached
667
  $data = $wpdb->get_results( $sql ); // phpcs:ignore
668
+
669
  if ( count( $data ) ) {
670
  foreach ( $data as $value ) {
671
  //TODO Remove ACF Fields
674
  }
675
  Cache::set( 'woo_feed_dropdown_meta_keys', $info );
676
  }
677
+
678
  return [
679
  'optionGroup' => esc_html__( 'Custom Fields & Post Metas', 'woo-feed' ),
680
  'options' => $info,
681
  ];
682
  }
683
+
684
  /**
685
  * Get Dynamic Attribute List
686
  *
688
  */
689
  private static function getDynamicAttributes() {
690
  global $wpdb;
691
+
692
  // Load Custom Category Mapped Attributes
693
  $info = array();
694
  // query escaped and cached
704
  );
705
  }
706
  }
707
+
708
  return [
709
  'optionGroup' => esc_html__( 'Dynamic Attributes', 'woo-feed' ),
710
  'options' => $info,
711
  ];
712
  }
713
+
714
  /**
715
  * Get Attribute Mappings
716
  *
728
  $info[ $value->option_name ] = is_array( $opts ) && isset( $opts['name'] ) ? $opts['name'] : str_replace( AttributeValueByType::PRODUCT_ATTRIBUTE_MAPPING_PREFIX, '', $value->option_name );
729
  }
730
  }
731
+
732
  return [
733
  'optionGroup' => esc_html__( 'Attribute Mappings', 'woo-feed' ),
734
  'options' => $info,
735
  ];
736
  }
737
+
738
  /**
739
  * @return array
740
  */
748
  ]
749
  ];
750
  }
751
+
752
  return $attributes;
753
  }
754
+
755
  /**
756
  * @return array
757
  */
765
  ]
766
  ];
767
  }
768
+
769
  return $attributes;
770
  }
771
  }
V5/Query/WCQuery.php CHANGED
@@ -1,5 +1,6 @@
1
  <?php
2
  namespace CTXFeed\V5\Query;
 
3
  use CTXFeed\V5\Utility\Settings;
4
  use WC_Product_Query;
5
 
@@ -115,4 +116,4 @@ class WCQuery implements QueryInterface {
115
  public function product_ids() {
116
  return ( new WC_Product_Query( $this->arguments ) )->get_products();
117
  }
118
- }
1
  <?php
2
  namespace CTXFeed\V5\Query;
3
+
4
  use CTXFeed\V5\Utility\Settings;
5
  use WC_Product_Query;
6
 
116
  public function product_ids() {
117
  return ( new WC_Product_Query( $this->arguments ) )->get_products();
118
  }
119
+ }
admin/css/woo-feed-admin.css CHANGED
@@ -72,6 +72,19 @@
72
  font-size: 18px;
73
  }
74
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  .woo_feed_manage_list_table .wf_update_interval_btn {
76
  background: linear-gradient(125deg, #3cb0fd 0, #6c5ce7 140%);
77
  border: none;
72
  font-size: 18px;
73
  }
74
 
75
+ .woo-feed-ctx-halloween-notice {
76
+ min-height: 168px;
77
+ background-size: contain !important;
78
+ border: none;
79
+ display: block;
80
+ margin-left: 0;
81
+ margin-top: 40px;
82
+ }
83
+ .woo-feed-ctx-halloween-notice button::before {
84
+ color: #fbfbfb;
85
+ font-size: 18px;
86
+ }
87
+
88
  .woo_feed_manage_list_table .wf_update_interval_btn {
89
  background: linear-gradient(125deg, #3cb0fd 0, #6c5ce7 140%);
90
  border: none;
admin/css/woo-feed-admin.min.css CHANGED
@@ -1 +1 @@
1
- .wpf_spin{-webkit-animation:spin 1s infinite linear;animation:spin 1s infinite linear}.wpf_spin.reverse_spin{animation-direction:reverse}.wpf_regenerate.disabled{color:#737373;box-shadow:none;cursor:not-allowed}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.webappick-info{color:#42a5fa}.wfbtn{background:#3498db;background-image:linear-gradient(125deg,#3cb0fd 0,#152f8c 140%);border-radius:3px;box-shadow:inset 0 1px 3px #666;font-family:Arial,sans-serif;color:#fff;font-size:20px;padding:10px 20px 10px 20px;border:solid #2b698f 0;text-decoration:none}.wfbtn:hover{background:#3cb0fd;background-image:linear-gradient(to bottom,#3cb0fd,#3498db);text-decoration:none}.woo-feed-ctx-startup-notice{min-height:168px;background-size:contain!important;border:none;display:block;margin-left:0;margin-top:40px}.woo-feed-ctx-startup-notice button::before{color:#fbfbfb;font-size:18px}.woo_feed_manage_list_table .wf_update_interval_btn{background:linear-gradient(125deg,#3cb0fd 0,#6c5ce7 140%);border:none}.woo_feed_manage_list_table .wf_update_interval_btn:hover{background:linear-gradient(125deg,#3cb0fd 0,#6c5ce7 140%)}.woo-feed-promotion{position:relative;display:none}.woo-feed-promotion .woo-feed-campaign-close-button{position:absolute;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);right:15px;width:24px;height:24px;border-radius:12px;background:#595d6b;line-height:24px;color:#fff;cursor:pointer;transition:.3s ease}.woo-feed-promotion .woo-feed-campaign-close-button:hover{background:#fff;color:#d61e48}.wftooltip{display:none;position:absolute;border:1px solid #333;background-color:#161616;border-radius:5px;padding:10px;color:#fff;font-size:12px}.feed-actions .makeFeedResponse{width:70%;color:green}.woo-feed-mapping-input{width:100%}.requiredIn{color:red}.generalInput{width:200px}.generalInput:not(.selectize-control){margin:5px auto}.error{color:red}.widefat td input,.widefat td select{max-width:100%}.woo-feed-btn-bg-gradient-blue,[data-class=woo-feed-btn-bg-gradient-blue]{background:linear-gradient(125deg,#3cb0fd 0,#6c5ce7 140%)!important;border:none;outline:0;border-width:0!important;box-shadow:none!important;transition:1s lenear;font-weight:500;color:#fff!important}.woo-feed-btn-bg-gradient-blue:hover,[data-class=woo-feed-btn-bg-gradient-blue]:hover{background:#3cb0fd!important}.woo-feed-btn-bg-gradient-red{background:linear-gradient(125deg,#eb4d4b 0,#ff9671 140%)!important;border:none;outline:0;border-width:0!important;box-shadow:none!important;transition:1s lenear;font-weight:500;color:#fff!important}.woo-feed-btn-bg-gradient-red:hover{background:#fc5c65!important}.woo-feed-btn-bg-gradient-purple{background:linear-gradient(67.36deg,#9733ee 3.09%,#da22ff 64.97%)!important;border:none;outline:0;border-width:0!important;box-shadow:none!important;transition:1s lenear;font-weight:500;color:#fff!important}.woo-feed-btn-bg-gradient-purple:hover{background:#a203fb!important}.woo-feed-light-btn-bg-gradient-blue{background:linear-gradient(125deg,#3cb0fd 0,#6c5ce7 140%)!important}#wf_newRow{margin-left:0}.mtable tbody tr{height:25px;border:1px solid #ccc;text-align:left;-ms-flex-align:baseline;align-items:baseline;font-weight:700}.mtable th:nth-child(1){width:17px}.mtable th:nth-child(2){width:160px}.mtable th:nth-child(3){width:100px}.mtable th:nth-child(4){width:100px}.mtable th:nth-child(5){width:150px}.mtable th:nth-child(6){width:100px}.mtable th:nth-child(7){width:150px}.mtable th:nth-child(8){width:90px}.mtable th:nth-child(9){width:29px}.mtable2 tbody tr{height:25px;border:1px solid #ccc;text-align:left;-ms-flex-align:baseline;align-items:baseline;font-weight:700}.mtable2 th:nth-child(1){width:30px}.mtable2 th:nth-child(2){width:150px}.mtable2 th:nth-child(3){width:230px}.mtable2 th:nth-child(4){width:220px}.mtable2 th:nth-child(7){width:50px}.mtable2 th:nth-child(8){width:50px}.mtable2 th:nth-child(9){width:29px}.wp-admin select.wf_mattributes{width:150px;left:0;height:25px}div#wf-tab-content1 select:not([name^=output_type]){width:100%}div#wf-tab-content1 input{width:100%}div#wf-tab-content1 .dashicons{vertical-align:middle}.wf_attributes{width:150px;left:0}.wf_compare{max-width:245px;left:0}.wf_ps{width:100px;left:0}.wf_sortedtable{cursor:move}.sorted_table{position:relative}.sorted_table .dragged{position:absolute;opacity:.8;z-index:9999;background:#fff;width:100%;display:table}.sorted_table tbody tr.placeholder td{border:1px dashed #2cc185;height:46px}.wfnoempty{width:120px}.woofeed-body-content #providerPage{display:-ms-flexbox;display:flex;-ms-flex-direction:column-reverse;flex-direction:column-reverse}#providerPageWrapper{display:-ms-flexbox;display:flex;-ms-flex-direction:column-reverse;flex-direction:column-reverse}#providerPageWrapper .wf_tabs{position:relative;margin:0 auto;width:100%;list-style:none}#providerPageWrapper .wf_tabs:after{display:table;clear:both;content:""}#providerPageWrapper .wf_tabs li{background:#fff;float:left;display:none;border:2px solid #ccc}#providerPageWrapper .wf_tabs li.active{display:block}#providerPageWrapper .wf_tabs li .wf-tab-content{z-index:2;width:100%;font-size:.9rem;display:block;left:0}#providerPageWrapper .wf_tabs li .wf-tab-content .feed-actions{border:none;border-top:2px solid #ccc}#providerPageWrapper #tabName{display:-ms-flexbox;display:flex;-ms-flex-pack:start;justify-content:flex-start;-ms-flex-align:start;align-items:flex-start}#providerPageWrapper #tabName .tab-name{min-width:300px;border:2px solid #ccc;border-bottom:none}#providerPageWrapper #tabName .tab-name input[type=radio]{display:none}#providerPageWrapper #tabName .tab-name label.activate{background:#2cc185;color:#fff}.wf-tab-name{display:block;padding:15px;font-size:15px;font-weight:700;line-height:1;background:#fff;cursor:pointer;position:relative;text-align:center;text-transform:uppercase;color:#2cc185}.wf-tab-name:hover{background:#2cc185;color:#fff}.wf_tabs [id^=tab]:checked+label{background:#2cc185;color:#fff}.wf_tabs [id^=tab]:checked~[id^=wf-tab-content]{display:block}div#wf-tab-content2 table:first-child{padding:10px 0}div#wf-tab-content2 table:first-child td:nth-child(1){width:260px}div#wf-tab-content2 table:first-child td:nth-child(2){width:260px}table.feed-actions tr td:last-child{text-align:right}select.selectize{display:none}body.no-js select.selectize{display:block!important}.wp-list-table .option_name .wf_feed_option_name_link{font-weight:700;color:#30336b}.wp-list-table #option_name a{color:#32373c}.selectize-dropdown .active{background-color:#edf9ff}.selectize-dropdown .create{padding:5px 8px}.wapk-selectize-item{background:#0073aa!important;color:#f1f1f1!important;border-color:#0073aa!important;padding-left:5px;padding-right:5px;border-radius:3px}.selectize-google-category .selectize-input{padding-right:30px}.selectize-google-category .selectize-dropdown-content{padding:0 8px}.selectize-google-category .selectize-dropdown-content .wapk-selectize-item{color:#000!important;background-color:#edf0f2!important;margin-bottom:3px!important;padding:3px 8px!important;transition-duration:.6s}.selectize-google-category .selectize-dropdown-content .wapk-selectize-item.active{background-color:#a2c8e1!important;transition-duration:.6s}.selectize-input.full #googleTaxonomyId-selectized{opacity:0;position:absolute;left:-10000px}.selectize-dropdown [data-selectable].option{cursor:default}.selectize-control.plugin-remove_button [data-value] .remove{border-left:1px solid #f1f1f1!important}.selectize-dropdown .optgroup-header{font-weight:700;background:#efefef;color:#5a5a5a}.selectize-dropdown [data-selectable].option{cursor:pointer}.wf_status_wrap label{width:55px;height:28px;box-sizing:border-box;float:left;border-radius:100px;position:relative;cursor:pointer;transition:.3s ease;background:linear-gradient(125deg,#e2e2e2 0,#ccc 140%)}input[class=woo_feed_status_input]:checked+label{background:linear-gradient(125deg,#3cb0fd 0,#6c5ce7 140%)}input[class=woo_feed_status_input]:checked+label:before{left:29px}.wf_status_wrap label:before{transition:.3s ease;content:"";width:20px;height:20px;position:absolute;background:#fff;left:6px;top:4px;box-sizing:border-box;color:#000;border-radius:100px;box-shadow:0 1.5px 2px 0 #000}.view span.dashicons.dashicons-external{color:#22a6b3}.view span.dashicons.dashicons-sos{color:#22a6b3}.view span.dashicons.dashicons-download{color:#ee5253}.view span.dashicons.dashicons-media-code{color:#576574}.column-url,.widefat td.column-url,.widefat th.column-url{color:#1e8f9a;font-weight:700}.feed-progress-container{width:100%;color:#fff;text-align:center;font-weight:300}.feed-progress-bar{width:100%;background:#eee;padding:3px;border-radius:50px;box-shadow:inset 0 1px 3px rgba(0,0,0,.2)}.feed-progress-bar-fill{height:20px;display:block;background:linear-gradient(to right top,#10ac84,#13b389,#15ba8f,#18c194,#1ac89a,#13cba1,#0acfa9,#00d2b0,#00d2ba,#00d2c3,#00d2cb,#00d2d3);width:0;border-radius:50px;transition:width .8s ease}.feed-progress-status{float:left;font-weight:700;color:#00008b}.feed-progress-percentage{text-align:right;font-weight:bolder;color:#1dd1a1;font-family:"Arial Black",sans-serif;font-size:large}#wpbody-content.woofeed-body-content{overflow:visible!important}.clippy{position:relative;width:13px;margin-top:-3px;margin-left:3px;top:3px}.column-url .clippy{display:none}.column-url:hover .clippy{display:inline-block}.tooltipped{position:relative}.tooltipped:after{position:absolute;z-index:1000000;display:none;padding:5px 8px;font:normal normal 11px/1.5 Helvetica,arial,nimbussansl,liberationsans,freesans,clean,sans-serif,"Segoe UI Emoji","Segoe UI Symbol";color:#fff;text-align:center;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-wrap:break-word;white-space:pre;pointer-events:none;content:attr(aria-label);background:rgba(0,0,0,.8);border-radius:3px;-webkit-font-smoothing:subpixel-antialiased}.tooltipped:before{position:absolute;z-index:1000001;display:none;width:0;height:0;color:rgba(0,0,0,.8);pointer-events:none;content:"";border:5px solid transparent}.tooltipped:hover:before{display:inline-block;text-decoration:none}.tooltipped:hover:after{display:inline-block;text-decoration:none}.tooltipped:active:before{display:inline-block;text-decoration:none}.tooltipped:active:after{display:inline-block;text-decoration:none}.tooltipped:focus:before{display:inline-block;text-decoration:none}.tooltipped:focus:after{display:inline-block;text-decoration:none}.tooltipped-multiline:hover:after{display:table-cell}.tooltipped-multiline:active:after{display:table-cell}.tooltipped-multiline:focus:after{display:table-cell}.tooltipped-multiline:after{width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:250px;word-break:break-word;word-wrap:normal;white-space:pre-line;border-collapse:separate}.tooltipped-s:after{top:100%;right:50%;margin-top:5px;-webkit-transform:translateX(50%);transform:translateX(50%)}.tooltipped-s:before{top:auto;right:50%;bottom:-5px;margin-right:-5px;border-bottom-color:rgba(0,0,0,.8)}.tooltipped-se:after{top:100%;margin-top:5px;right:auto;left:50%;margin-left:-15px}.tooltipped-se:before{top:auto;right:50%;bottom:-5px;margin-right:-5px;border-bottom-color:rgba(0,0,0,.8)}.tooltipped-sw:after{top:100%;right:50%;margin-top:5px;margin-right:-15px}.tooltipped-sw:before{top:auto;right:50%;bottom:-5px;margin-right:-5px;border-bottom-color:rgba(0,0,0,.8)}.tooltipped-n:after{right:50%;bottom:100%;margin-bottom:5px;-webkit-transform:translateX(50%);transform:translateX(50%)}.tooltipped-n:before{top:-5px;right:50%;bottom:auto;margin-right:-5px;border-top-color:rgba(0,0,0,.8)}.tooltipped-ne:after{bottom:100%;margin-bottom:5px;right:auto;left:50%;margin-left:-15px}.tooltipped-ne:before{top:-5px;right:50%;bottom:auto;margin-right:-5px;border-top-color:rgba(0,0,0,.8)}.tooltipped-nw:after{right:50%;bottom:100%;margin-bottom:5px;margin-right:-15px}.tooltipped-nw:before{top:-5px;right:50%;bottom:auto;margin-right:-5px;border-top-color:rgba(0,0,0,.8)}.tooltipped-w:after{right:100%;bottom:50%;margin-right:5px;-webkit-transform:translateY(50%);transform:translateY(50%)}.tooltipped-w:before{top:50%;bottom:50%;left:-5px;margin-top:-5px;border-left-color:rgba(0,0,0,.8)}.tooltipped-e:after{bottom:50%;left:100%;margin-left:5px;-webkit-transform:translateY(50%);transform:translateY(50%)}.tooltipped-e:before{top:50%;right:-5px;bottom:50%;margin-top:-5px;border-right-color:rgba(0,0,0,.8)}.tooltipped-multiline.tooltipped-s:after{right:auto;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}.tooltipped-multiline.tooltipped-n:after{right:auto;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}.tooltipped-multiline.tooltipped-w:after{right:100%}.tooltipped-multiline.tooltipped-e:after{right:100%}.tooltipped-sticky:before{display:inline-block}.tooltipped-sticky:after{display:inline-block}.tooltipped-sticky.tooltipped-multiline:after{display:table-cell}.fullscreen-overlay-enabled.dark-theme .tooltipped:after{color:#000;background:rgba(255,255,255,.8)}.fullscreen-overlay-enabled.dark-theme .tooltipped .tooltipped-s:before{border-bottom-color:rgba(255,255,255,.8)}.fullscreen-overlay-enabled.dark-theme .tooltipped .tooltipped-se:before{border-bottom-color:rgba(255,255,255,.8)}.fullscreen-overlay-enabled.dark-theme .tooltipped .tooltipped-sw:before{border-bottom-color:rgba(255,255,255,.8)}.fullscreen-overlay-enabled.dark-theme .tooltipped.tooltipped-n:before{border-top-color:rgba(255,255,255,.8)}.fullscreen-overlay-enabled.dark-theme .tooltipped.tooltipped-ne:before{border-top-color:rgba(255,255,255,.8)}.fullscreen-overlay-enabled.dark-theme .tooltipped.tooltipped-nw:before{border-top-color:rgba(255,255,255,.8)}.fullscreen-overlay-enabled.dark-theme .tooltipped.tooltipped-e:before{border-right-color:rgba(255,255,255,.8)}.fullscreen-overlay-enabled.dark-theme .tooltipped.tooltipped-w:before{border-left-color:rgba(255,255,255,.8)}@media screen and (min-width:0\0){.tooltipped-multiline:after{width:250px}}ul.tracker_collection_list{list-style:initial;padding:initial;margin:-10px 0 0 30px;font-size:11px!important}ul.tracker_collection_list li{margin:0}table.wf-info-table,table.wf-rate-table{vertical-align:middle;text-align:center;max-width:100%;font-weight:500;margin-top:10px}table.wf-info-table th,table.wf-rate-table th{text-align:center}table.wf-info-table th .woo-feed-top-header,table.wf-rate-table th .woo-feed-top-header{display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between;-ms-flex-align:center;align-items:center}table.wf-info-table th .woo-feed-top-header .get-woo-feed-pro,table.wf-rate-table th .woo-feed-top-header .get-woo-feed-pro{margin-left:20px}table.wf-info-table th .woo-feed-top-header .get-woo-feed-pro img,table.wf-rate-table th .woo-feed-top-header .get-woo-feed-pro img{width:172px}table.wf-info-table th .woo-feed-top-header .woo-feed-top-buttons,table.wf-rate-table th .woo-feed-top-header .woo-feed-top-buttons{float:right;display:-ms-flexbox;display:flex;border-radius:7px;-ms-flex-pack:center;justify-content:center;-ms-flex-align:center;align-items:center}table.wf-info-table th .woo-feed-top-header .woo-feed-top-buttons a,table.wf-rate-table th .woo-feed-top-header .woo-feed-top-buttons a{padding:8px 20px;background:#576574;color:#fff;box-sizing:border-box;display:inline-block;transition:.3s ease}table.wf-info-table th .woo-feed-top-header .woo-feed-top-buttons a.woo-feed-doc-link,table.wf-rate-table th .woo-feed-top-header .woo-feed-top-buttons a.woo-feed-doc-link{background:#576574;border-top-left-radius:5px;border-bottom-left-radius:5px}table.wf-info-table th .woo-feed-top-header .woo-feed-top-buttons a.woo-feed-video-link,table.wf-rate-table th .woo-feed-top-header .woo-feed-top-buttons a.woo-feed-video-link{background:#ee5253}table.wf-info-table th .woo-feed-top-header .woo-feed-top-buttons a.woo-feed-support-link,table.wf-rate-table th .woo-feed-top-header .woo-feed-top-buttons a.woo-feed-support-link{background:#22a6b3;border-top-right-radius:5px;border-bottom-right-radius:5px}table.wf-info-table th .woo-feed-top-header .woo-feed-top-buttons a span.dashicons,table.wf-rate-table th .woo-feed-top-header .woo-feed-top-buttons a span.dashicons{font-size:18px;line-height:1.2}table.wf-info-table th .woo-feed-top-header .woo-feed-top-buttons a:hover,table.wf-rate-table th .woo-feed-top-header .woo-feed-top-buttons a:hover{background:#30336b;box-shadow:0 0 33px 0 rgba(0,0,0,.12)}table.wf-info-table strong,table.wf-rate-table strong{font-weight:700}table.wf-info-table th:first-child img{margin:0 0 -5px 5px}table.wf-rate-table a{color:#0073aa}table.wf-rate-table a.review-star:after{content:"\f155\f155\f155\f155\f155"!important;font-family:dashicons;font-size:10px;font-weight:100;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;color:#0073aa;text-decoration:underline}#adminmenu #toplevel_page_webappick-manage-feeds div.wp-menu-image::before{content:"";background:url(../images/woo-feed-icon.svg) no-repeat center center;background-size:20px 20px;opacity:.6}#adminmenu #toplevel_page_webappick-manage-feeds:hover div.wp-menu-image::before{opacity:1}#adminmenu #toplevel_page_webappick-manage-feeds.wp-has-current-submenu div.wp-menu-image::before{opacity:1}.wapk-admin,.wapk-admin *{box-sizing:border-box}.wapk-admin{position:relative;display:block;-webkit-hyphens:manual;-ms-hyphens:manual;-moz-hyphens:manual;hyphens:manual;color:#1b2730;margin:0 0 0 -10px}@media screen and (min-width:783px){.wapk-admin{margin:0 0 0 -20px}}.text-center{text-align:center}.wapk-admin h1,.wapk-admin h2,.wapk-admin h3,.wapk-admin h4,.wapk-admin h5,.wapk-admin h6,.wapk-admin p{color:#1b2730}.wapk-admin sup{vertical-align:baseline;position:relative;top:-6px}.wapk-admin sub{vertical-align:baseline;position:relative;top:4px}.wapk-admin .wapk-section{margin:10px 20px 0 22px;position:relative;display:block}.wapk-admin .wapk-section [class$=icon32]+h2{font-size:23px;font-weight:400;margin:0;padding:9px 0 4px 0;line-height:1.3}.wapk-admin .wapk-section h1{font-size:23px;font-weight:400;margin:0;padding:9px 0 4px 0;line-height:1.3}.wapk-admin .wapk-section>h2:first-child{font-size:23px;font-weight:400;margin:0;padding:9px 0 4px 0;line-height:1.3}.wapk-admin>.notice{margin:10px 20px 0 22px;position:relative;display:block}.wapk-admin span.help{display:block;float:left;width:100%;font-size:.9em;color:#636363;margin-top:5px;font-weight:500}.wapk-admin span.help .dashicons{width:11px;height:12px;font-size:inherit;vertical-align:middle}.clear:after{content:"";display:table;clear:both}.wapk-feed-docs .postbox{width:355px;margin-right:20px;display:inline-block;vertical-align:top}.wapk-feed-docs .postbox .hndle{font-size:14px;padding:8px 12px;margin:0;line-height:1.4;cursor:pointer}.wapk-feed-docs .postbox .dashicons{color:#ccc}.wapk-feed-docs .postbox a{text-decoration:none}.wapk-feed-docs .postbox .inside{margin-bottom:0}.wapk-feed-docs .postbox ul{margin-bottom:0}.wapk-feed-docs .postbox .toggle-indicator:before{content:"\f142";display:inline-block;font:400 20px/1 dashicons;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-decoration:none!important}.wapk-feed-docs .postbox li{width:100%;display:block;float:left}.wapk-feed-docs .postbox li span{display:inline-block;float:left;margin-right:4px}.wapk-feed-docs .postbox li a{display:inline-block;float:left;width:calc(100% - 24px)}.wapk-feed-docs .postbox.closed .toggle-indicator:before{content:"\f140"}.wapk-section #post-body.columns-2 #side-sortables{min-height:196px}#poststuff #feed_merchant_info .inside{margin:0;padding:0}#feed_merchant_info ul.data{margin-left:24px;margin-top:5px}#feed_merchant_info ul.data li{margin-bottom:5px}.merchant-info-section{padding:6px 10px 8px}.merchant-info-section.woo-feed-open-file{text-align:center}.merchant-info-section.woo-feed-open-file a{line-height:1.5;text-decoration:none}.generateFeed .wf-tab-content table:first-child{border:none;box-shadow:none}.generateFeed table th{font-weight:700}@media only screen and (max-width:850px){.wapk-feed-docs .postbox{display:block;width:auto;float:none;margin-right:auto}}.wp-submenu li span.woo-feed-docs{font-weight:700;color:#f18500}.wp-submenu li:hover span.woo-feed-docs{color:#ce7304}.wp-submenu li.current span.woo-feed-docs{color:#ce7304}.wapk-admin .wapk-feed-docs .postbox .hndle{cursor:default}.wapk-cta{position:relative;display:-ms-flexbox;display:flex;width:100%;padding:100px 15px;background:linear-gradient(45deg,#6cd5ff 33%,#c2efef 100%);-ms-flex-pack:center;justify-content:center;-ms-flex-align:center;align-items:center}.wapk-cta-icon .dashicons{font-size:100px;width:100px;height:auto;margin:0 10px -8px 0;color:#02658c}.wapk-cta-content{width:50%}.wapk-cta-content h2{font-size:2em;margin:.5em 0}.wapk-cta-action a.wapk-button{font-size:24px;height:auto!important;padding:10px 20px}@media (max-width:600px){.wapk-cta{display:block;text-align:center;padding:4em 0}.wapk-cta-content{width:100%;margin:2em 0}}.wapk-button{color:#00d4d4;border-color:#00d4d4;display:inline-block;text-decoration:none;font-size:13px;line-height:2.15384615;min-height:30px;margin:0;padding:0 10px;cursor:pointer;border-width:1px;border-style:solid;-webkit-appearance:none;border-radius:3px;white-space:nowrap;box-sizing:border-box}.wapk-button>svg{width:15px;margin-left:5px;fill:#00d4d4}.wapk-button>.dashicons{color:#00d4d4}.wapk-button:hover{border-color:#0bb;color:#0bb}.wapk-button:hover>svg{fill:#0bb}.wapk-button:hover>.dashicons{color:#0bb}.wapk-button:focus{border-color:#00d4d4;color:#0bb;box-shadow:0 0 0 1px #00d4d4}.wapk-button:focus>svg{fill:#0bb}.wapk-button:focus>.dashicons{color:#0bb}.wapk-button:active{background:#0bb;border-color:#0bb}.wapk-button-secondary{color:#00d4d4;border-color:#00d4d4;display:inline-block;text-decoration:none;font-size:13px;line-height:2.15384615;min-height:30px;margin:0;padding:0 10px;cursor:pointer;border-width:1px;border-style:solid;-webkit-appearance:none;border-radius:3px;white-space:nowrap;box-sizing:border-box}.wapk-button-secondary>svg{width:15px;margin-left:5px;fill:#00d4d4}.wapk-button-secondary>.dashicons{color:#00d4d4}.wapk-button-secondary:hover{border-color:#0bb;color:#0bb}.wapk-button-secondary:hover>svg{fill:#0bb}.wapk-button-secondary:hover>.dashicons{color:#0bb}.wapk-button-secondary:focus{border-color:#00d4d4;color:#0bb;box-shadow:0 0 0 1px #00d4d4}.wapk-button-secondary:focus>svg{fill:#0bb}.wapk-button-secondary:focus>.dashicons{color:#0bb}.wapk-button-primary{display:inline-block;text-decoration:none;font-size:13px;line-height:2.15384615;min-height:30px;margin:0;padding:0 10px;cursor:pointer;border-width:1px;border-style:solid;-webkit-appearance:none;border-radius:3px;white-space:nowrap;box-sizing:border-box;background:#00d4d4;border-color:#00d4d4;color:#fff;box-shadow:0 1px 0 #0bb;text-shadow:0 -1px 1px #0bb,1px 0 1px #0bb,0 1px 1px #0bb,-1px 0 1px #0bb}.wapk-button-primary>svg{fill:#fff}.wapk-button-primary:hover{background:#00e3e3;border-color:#00c5c5;color:#fff}.wapk-button-primary:hover>svg{fill:#fff}.wapk-button-primary:focus{background:#00e3e3;border-color:#00c5c5;color:#fff;box-shadow:0 0 0 1px #fff,0 0 0 3px #00d4d4}.wapk-button-primary:focus>svg{fill:#fff}.wapk-button-primary:active{background:#0bb;border-color:#0bb;color:#fff}.wapk-button-primary:active>svg{fill:#fff}.wapk-button-primary:disabled{color:#c7d1d1!important;background:#2ff!important;border-color:#2ff!important;text-shadow:none!important}.wapk-button-primary:disabled>svg{fill:#c7d1d1!important}.wapk-button.hover{border-color:#0bb;color:#0bb}.wapk-button.hover>svg{fill:#0bb}.wapk-button.hover>.dashicons{color:#0bb}.wapk-button.focus{border-color:#00d4d4;color:#0bb;box-shadow:0 0 0 1px #00d4d4}.wapk-button.focus>svg{fill:#0bb}.wapk-button.focus>.dashicons{color:#0bb}.wapk-button.active{border-color:#0bb;color:#0bb;box-shadow:inset 0 2px 5px -3px #0bb}.wapk-button.active:focus{border-color:#0bb;color:#0bb;box-shadow:inset 0 2px 5px -3px #0bb}.wapk-button.active:focus>svg{fill:#0bb}.wapk-button.active:focus>.dashicons{color:#0bb}.wapk-button.active:hover{border-color:#0bb;color:#0bb;box-shadow:inset 0 2px 5px -3px #0bb}.wapk-button.active:hover>svg{fill:#0bb}.wapk-button.active:hover>.dashicons{color:#0bb}.wapk-button.active>svg{fill:#0bb}.wapk-button.active>.dashicons{color:#0bb}.wapk-button-primary.active{background:#00d4d4;color:#fff;border-color:#088;box-shadow:inset 0 2px 5px -3px #000}.wapk-button-primary.active:focus{background:#00d4d4;color:#fff;border-color:#088;box-shadow:inset 0 2px 5px -3px #000}.wapk-button-primary.active:focus>svg{fill:#fff}.wapk-button-primary.active:hover{background:#00d4d4;color:#fff;border-color:#088;box-shadow:inset 0 2px 5px -3px #000}.wapk-button-primary.active:hover>svg{fill:#fff}.wapk-button-primary.active>svg{fill:#fff}.wapk-button-primary[disabled]{color:#c7d1d1!important;background:#2ff!important;border-color:#2ff!important;text-shadow:none!important}.wapk-button-primary[disabled]>svg{fill:#c7d1d1!important}.wapk-button-primary.wapk-button-primary-disabled{color:#c7d1d1!important;background:#2ff!important;border-color:#2ff!important;text-shadow:none!important}.wapk-button-primary.wapk-button-primary-disabled>svg{fill:#c7d1d1!important}.wapk-button-primary.disabled{color:#c7d1d1!important;background:#2ff!important;border-color:#2ff!important;text-shadow:none!important}.wapk-button-primary.disabled>svg{fill:#c7d1d1!important}.wapk-button-primary.wapk-button-hero{box-shadow:0 2px 0 #0bb}.wapk-button-primary.wapk-button-hero:focus{box-shadow:0 2px 0 #0bb,0 1px 0 #00c5c5,0 0 2px 1px #0ee}.wapk-button-primary.wapk-button-hero:active{box-shadow:inset 0 3px 0 #00a1a1}.wapk-button-primary.wapk-button-hero.active{box-shadow:inset 0 3px 0 #00a1a1}.wapk-button-primary.wapk-button-hero.active:focus,.wapk-button-primary.wapk-button-hero.active:hover{box-shadow:inset 0 3px 0 #00a1a1}.wapk-button-group>.wapk-button.active{border-color:#00d4d4}.wapk-button.wapk-button-xl{height:30px;line-height:28px;padding:0 12px 2px}.wapk-button-group.wapk-button-xl .wapk-button{height:30px;line-height:28px;padding:0 12px 2px}.wapk-button.wapk-button-hero{font-size:18px;height:50px;line-height:48px;padding:0 36px;min-height:46px}.wapk-button-group.wapk-button-hero .wapk-button{font-size:18px;height:50px;line-height:48px;padding:0 36px;min-height:46px}@media screen and (min-width:782px){th#provider,th#status{width:80px}th#type{width:50px}th#option_name{width:100px}td.option_name.column-option_name>span:first-child{display:none}th#last_updated{width:90px}th#view{width:135px}}@media screen and (min-width:960px){th#provider,th#status{width:100px}th#type{width:80px}th#option_name{width:150px}th#last_updated{width:140px}}@media screen and (max-width:782px){table.wf-info-table{margin-top:10px}table.wf-info-table th:first-child img{margin:0 auto;display:block}.wapk-button.wapk-button-xl{padding:6px 14px;line-height:normal;font-size:14px;vertical-align:middle;height:auto;margin-bottom:4px}}.wapk-feed-docs .wapk-feed-cta{margin:0}.campaign_configurator{background:#fff;padding:20px 0}.campaign_configurator table{margin:0 auto;width:51%;min-width:574px;border:none;box-shadow:none}.campaign_configurator th{min-width:120px}@media screen and (max-width:782px){.campaign_configurator{padding:0}.campaign_configurator table{width:auto;min-width:auto;max-width:100%}.campaign_configurator th{min-width:auto}}#wf-tab-content-config td>input:not([type=checkbox]):not([type=radio]),#wf-tab-content-config td>select,#wf-tab-content-config td>textarea{width:100%!important}.woo-feed-filters td>div:nth-child(2n):not(.clear):not(.selectize):not(.counter){width:120px;display:block}.woo-feed-filters td>div:not(.clear){float:left;margin-right:10px}.woo-feed-filters tr>td:first-child{width:290px;padding-left:40px}.woo-feed-filters,.woo-feed-ftp{margin:15px auto 25px}.wf_clean_cache_wrapper{display:-ms-flexbox;display:flex;margin-left:auto}@-webkit-keyframes LoaderClockWise{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes LoaderClockWise{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.woo-feed-cache-loader{width:18px;margin-right:5px;animation:LoaderClockWise 1s linear infinite;-webkit-animation:LoaderClockWise 1s linear infinite;display:none}.woo-feed-table-heading .woo-feed-table-heading-title{float:left;margin-right:auto;display:inline-block;line-height:30px}.woo-feed-table-heading .wf_clean_cache_wrapper{float:right;font-weight:400}.wf_clean_cache_wrapper button{background:linear-gradient(125deg,#eb4d4b 0,#ff9671 140%);color:#fff;border:none;font-weight:500;display:inline-block;text-decoration:none;font-size:13px;line-height:2.15384615;min-height:30px;margin:0;padding:0 10px;border-radius:3px;cursor:pointer;outline:0}.wf_clean_cache_wrapper button:hover{background:#ff7979;color:#fff}input[type=submit][data-id=wf_action_submit]{background:linear-gradient(125deg,#3cb0fd 0,#6c5ce7 140%);color:#fff;border:1px;padding:0 20px}input[type=submit][data-id=wf_action_submit]:hover{background:linear-gradient(125deg,#3cb0fd 0,#6c5ce7 140%);color:#fff}.woo-import-popup-body #TB_window{width:500px!important}.woo-import-popup-body #TB_window #TB_title{border:none;background:#fff;text-align:center;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;-ms-flex-align:center;align-items:center;height:35px!important}.woo-import-popup-body #TB_window #TB_title #TB_ajaxWindowTitle{color:#30336b;font-weight:700}.woo-import-popup-body #TB_window #TB_closeWindowButton{top:-14.5px;right:-14.5px;border:none;outline:0}.woo-import-popup-body #TB_window #TB_closeWindowButton .tb-close-icon{background:#ff5e55;color:#fff;border-radius:50%}.woo-import-popup-body #TB_window #TB_closeWindowButton:focus{outline:0;border:0}.woo-import-popup-body #TB_window #TB_ajaxContent{position:relative;width:100%!important;height:auto!important;border:none;box-sizing:border-box;overflow:hidden;background:#f7fcff;padding:30px 20px}.woo-import-popup-body #TB_window #TB_ajaxContent:before{content:"";width:115%;display:block;background:#4bcffa;position:absolute;height:130%;z-index:0;left:-36%;top:-85px;-webkit-transform:rotate(115deg);transform:rotate(115deg)}.woo-import-popup-body #TB_window #TB_ajaxContent table{border:none;position:relative;z-index:1;border-radius:3px;text-align:center;padding:20px;box-shadow:0 12px 20px -17px #000}.woo-import-popup-body #TB_window #TB_ajaxContent table input{width:60%}.woo-import-popup-body #TB_window #TB_ajaxContent table input:focus{outline:2px solid #68b8f7}.woo-import-popup-body #TB_window #TB_ajaxContent table input[type=file]{padding:3px 0;cursor:pointer}.woo-import-popup-body #TB_window #TB_ajaxContent table input[type=text]{border-radius:25px;font-size:14px;padding:1px 20px;text-align:center}.woo-import-popup-body #TB_window #TB_ajaxContent table input[type=submit]{background:#17c0eb;border-radius:25px;border:0;box-shadow:1px 4px 7px -3px #45364a;font-weight:600;transition:.3s ease}.woo-import-popup-body #TB_window #TB_ajaxContent table input[type=submit]:hover{-webkit-transform:translateY(-2px);transform:translateY(-2px)}.woo-feed-notice{position:relative}.woo-feed-notice .woo-feed-review-notice-logo{width:90px;height:90px;float:left;margin-right:5px;background:url(../images/woo-feed-logo.svg) no-repeat}.woo-feed-notice .woo-feed-review-btn-dismiss{display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;-ms-flex-line-pack:center;align-content:center;position:absolute;top:7px;right:7px;background:0 0;border:none;cursor:pointer}.woo-feed-notice .woo-feed-review-btn-dismiss span{line-height:18px}.woo-feed-notice .woo-feed-review-btn-dismiss:before{background:0 0;color:#787c82;content:"\f153";display:block;font:normal 16px/20px dashicons;speak:never;height:20px;text-align:center;width:20px;-webkit-font-smoothing:antialiased}.woo-feed-notice .woo-feed-review-btn-dismiss:hover:before{color:#d63638}.woo-feed-status-table-wrapper .woo-feed-status-table{width:100%;max-width:900px;border-collapse:collapse;border-spacing:.5rem;box-shadow:0 0 20px rgba(0,0,0,.1)}.woo-feed-status-table-wrapper .woo-feed-status-table tr:nth-child(even){background:#f1f1f1}.woo-feed-status-table-wrapper .woo-feed-status-table tr:nth-child(odd){background:#fafafc}.woo-feed-status-table-wrapper .woo-feed-status-table tr th{background:#353b48;color:#fff}.woo-feed-status-table-wrapper .woo-feed-status-table tr th.woo-feed-status-message-header{display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between;-ms-flex-align:center;align-items:center}.woo-feed-status-table-wrapper .woo-feed-status-table tr th.woo-feed-status-message-header #woo-feed-copy-status-btn{background:linear-gradient(125deg,#3cb0fd 0,#6c5ce7 140%);border:none}.woo-feed-status-table-wrapper .woo-feed-status-table tr td,.woo-feed-status-table-wrapper .woo-feed-status-table tr th{padding:.5rem 20px;text-align:left}.woo-feed-status-table-wrapper .woo-feed-status-table tr td.woo-feed-status-page-btn-group{display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between;-ms-flex-align:center;align-items:center}.woo-feed-status-table-wrapper .woo-feed-status-table tr td.woo-feed-status-page-btn-group .wf_clean_cache_wrapper{margin:initial}.woo-feed-status-table-wrapper .woo-feed-status-table tr td.woo-feed-status-page-btn-group button,.woo-feed-status-table-wrapper .woo-feed-status-table tr td.woo-feed-status-page-btn-group input[type=button]{height:38px;padding:0 30px;font-size:16px;font-weight:500;border:none;outline:0}input[id^=woo_feed_identifier_]{display:block;width:100%!important}#taxonomy-woo-feed-brand #newwoo-feed-brand_parent,.taxonomy-woo-feed-brand .form-field.term-parent-wrap{display:none}.wapk-admin .switch{position:relative;display:inline-block;width:55px;height:28px}.wapk-admin .switch input{opacity:0;width:0;height:0}.wapk-admin .slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc;transition:.4s}.wapk-admin .slider:before{position:absolute;content:"";height:20px;width:20px;left:4px;bottom:4px;background-color:#fff;transition:.4s}.wapk-admin input:checked+.slider{background:linear-gradient(125deg,#3cb0fd 0,#6c5ce7 140%)}.wapk-admin input:focus+.slider{box-shadow:0 0 1px #2196f3}.wapk-admin input:checked+.slider:before{-webkit-transform:translateX(26px);transform:translateX(26px)}.wapk-admin .slider.round{border-radius:34px}.wapk-admin .slider.round:before{border-radius:50%}.woo-feed-category-mapping-config-table{position:relative}.woo-feed-category-mapping-config-table .woo-feed-cat-map-spinner{display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;width:100%;height:100%;position:absolute;top:0;left:0;background:rgba(235,235,235,.9);z-index:999;padding-top:250px}span[id*=cat-map-]{cursor:pointer;position:relative;top:5px}
1
+ .wpf_spin{-webkit-animation:spin 1s infinite linear;animation:spin 1s infinite linear}.wpf_spin.reverse_spin{animation-direction:reverse}.wpf_regenerate.disabled{color:#737373;box-shadow:none;cursor:not-allowed}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.webappick-info{color:#42a5fa}.wfbtn{background:#3498db;background-image:linear-gradient(125deg,#3cb0fd 0,#152f8c 140%);border-radius:3px;box-shadow:inset 0 1px 3px #666;font-family:Arial,sans-serif;color:#fff;font-size:20px;padding:10px 20px 10px 20px;border:solid #2b698f 0;text-decoration:none}.wfbtn:hover{background:#3cb0fd;background-image:linear-gradient(to bottom,#3cb0fd,#3498db);text-decoration:none}.woo-feed-ctx-startup-notice{min-height:168px;background-size:contain!important;border:none;display:block;margin-left:0;margin-top:40px}.woo-feed-ctx-startup-notice button::before{color:#fbfbfb;font-size:18px}.woo-feed-ctx-halloween-notice{min-height:168px;background-size:contain!important;border:none;display:block;margin-left:0;margin-top:40px}.woo-feed-ctx-halloween-notice button::before{color:#fbfbfb;font-size:18px}.woo_feed_manage_list_table .wf_update_interval_btn{background:linear-gradient(125deg,#3cb0fd 0,#6c5ce7 140%);border:none}.woo_feed_manage_list_table .wf_update_interval_btn:hover{background:linear-gradient(125deg,#3cb0fd 0,#6c5ce7 140%)}.woo-feed-promotion{position:relative;display:none}.woo-feed-promotion .woo-feed-campaign-close-button{position:absolute;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);right:15px;width:24px;height:24px;border-radius:12px;background:#595d6b;line-height:24px;color:#fff;cursor:pointer;transition:.3s ease}.woo-feed-promotion .woo-feed-campaign-close-button:hover{background:#fff;color:#d61e48}.wftooltip{display:none;position:absolute;border:1px solid #333;background-color:#161616;border-radius:5px;padding:10px;color:#fff;font-size:12px}.feed-actions .makeFeedResponse{width:70%;color:green}.woo-feed-mapping-input{width:100%}.requiredIn{color:red}.generalInput{width:200px}.generalInput:not(.selectize-control){margin:5px auto}.error{color:red}.widefat td input,.widefat td select{max-width:100%}.woo-feed-btn-bg-gradient-blue,[data-class=woo-feed-btn-bg-gradient-blue]{background:linear-gradient(125deg,#3cb0fd 0,#6c5ce7 140%)!important;border:none;outline:0;border-width:0!important;box-shadow:none!important;transition:1s lenear;font-weight:500;color:#fff!important}.woo-feed-btn-bg-gradient-blue:hover,[data-class=woo-feed-btn-bg-gradient-blue]:hover{background:#3cb0fd!important}.woo-feed-btn-bg-gradient-red{background:linear-gradient(125deg,#eb4d4b 0,#ff9671 140%)!important;border:none;outline:0;border-width:0!important;box-shadow:none!important;transition:1s lenear;font-weight:500;color:#fff!important}.woo-feed-btn-bg-gradient-red:hover{background:#fc5c65!important}.woo-feed-btn-bg-gradient-purple{background:linear-gradient(67.36deg,#9733ee 3.09%,#da22ff 64.97%)!important;border:none;outline:0;border-width:0!important;box-shadow:none!important;transition:1s lenear;font-weight:500;color:#fff!important}.woo-feed-btn-bg-gradient-purple:hover{background:#a203fb!important}.woo-feed-light-btn-bg-gradient-blue{background:linear-gradient(125deg,#3cb0fd 0,#6c5ce7 140%)!important}#wf_newRow{margin-left:0}.mtable tbody tr{height:25px;border:1px solid #ccc;text-align:left;-ms-flex-align:baseline;align-items:baseline;font-weight:700}.mtable th:nth-child(1){width:17px}.mtable th:nth-child(2){width:160px}.mtable th:nth-child(3){width:100px}.mtable th:nth-child(4){width:100px}.mtable th:nth-child(5){width:150px}.mtable th:nth-child(6){width:100px}.mtable th:nth-child(7){width:150px}.mtable th:nth-child(8){width:90px}.mtable th:nth-child(9){width:29px}.mtable2 tbody tr{height:25px;border:1px solid #ccc;text-align:left;-ms-flex-align:baseline;align-items:baseline;font-weight:700}.mtable2 th:nth-child(1){width:30px}.mtable2 th:nth-child(2){width:150px}.mtable2 th:nth-child(3){width:230px}.mtable2 th:nth-child(4){width:220px}.mtable2 th:nth-child(7){width:50px}.mtable2 th:nth-child(8){width:50px}.mtable2 th:nth-child(9){width:29px}.wp-admin select.wf_mattributes{width:150px;left:0;height:25px}div#wf-tab-content1 select:not([name^=output_type]){width:100%}div#wf-tab-content1 input{width:100%}div#wf-tab-content1 .dashicons{vertical-align:middle}.wf_attributes{width:150px;left:0}.wf_compare{max-width:245px;left:0}.wf_ps{width:100px;left:0}.wf_sortedtable{cursor:move}.sorted_table{position:relative}.sorted_table .dragged{position:absolute;opacity:.8;z-index:9999;background:#fff;width:100%;display:table}.sorted_table tbody tr.placeholder td{border:1px dashed #2cc185;height:46px}.wfnoempty{width:120px}.woofeed-body-content #providerPage{display:-ms-flexbox;display:flex;-ms-flex-direction:column-reverse;flex-direction:column-reverse}#providerPageWrapper{display:-ms-flexbox;display:flex;-ms-flex-direction:column-reverse;flex-direction:column-reverse}#providerPageWrapper .wf_tabs{position:relative;margin:0 auto;width:100%;list-style:none}#providerPageWrapper .wf_tabs:after{display:table;clear:both;content:""}#providerPageWrapper .wf_tabs li{background:#fff;float:left;display:none;border:2px solid #ccc}#providerPageWrapper .wf_tabs li.active{display:block}#providerPageWrapper .wf_tabs li .wf-tab-content{z-index:2;width:100%;font-size:.9rem;display:block;left:0}#providerPageWrapper .wf_tabs li .wf-tab-content .feed-actions{border:none;border-top:2px solid #ccc}#providerPageWrapper #tabName{display:-ms-flexbox;display:flex;-ms-flex-pack:start;justify-content:flex-start;-ms-flex-align:start;align-items:flex-start}#providerPageWrapper #tabName .tab-name{min-width:300px;border:2px solid #ccc;border-bottom:none}#providerPageWrapper #tabName .tab-name input[type=radio]{display:none}#providerPageWrapper #tabName .tab-name label.activate{background:#2cc185;color:#fff}.wf-tab-name{display:block;padding:15px;font-size:15px;font-weight:700;line-height:1;background:#fff;cursor:pointer;position:relative;text-align:center;text-transform:uppercase;color:#2cc185}.wf-tab-name:hover{background:#2cc185;color:#fff}.wf_tabs [id^=tab]:checked+label{background:#2cc185;color:#fff}.wf_tabs [id^=tab]:checked~[id^=wf-tab-content]{display:block}div#wf-tab-content2 table:first-child{padding:10px 0}div#wf-tab-content2 table:first-child td:nth-child(1){width:260px}div#wf-tab-content2 table:first-child td:nth-child(2){width:260px}table.feed-actions tr td:last-child{text-align:right}select.selectize{display:none}body.no-js select.selectize{display:block!important}.wp-list-table .option_name .wf_feed_option_name_link{font-weight:700;color:#30336b}.wp-list-table #option_name a{color:#32373c}.selectize-dropdown .active{background-color:#edf9ff}.selectize-dropdown .create{padding:5px 8px}.wapk-selectize-item{background:#0073aa!important;color:#f1f1f1!important;border-color:#0073aa!important;padding-left:5px;padding-right:5px;border-radius:3px}.selectize-google-category .selectize-input{padding-right:30px}.selectize-google-category .selectize-dropdown-content{padding:0 8px}.selectize-google-category .selectize-dropdown-content .wapk-selectize-item{color:#000!important;background-color:#edf0f2!important;margin-bottom:3px!important;padding:3px 8px!important;transition-duration:.6s}.selectize-google-category .selectize-dropdown-content .wapk-selectize-item.active{background-color:#a2c8e1!important;transition-duration:.6s}.selectize-input.full #googleTaxonomyId-selectized{opacity:0;position:absolute;left:-10000px}.selectize-dropdown [data-selectable].option{cursor:default}.selectize-control.plugin-remove_button [data-value] .remove{border-left:1px solid #f1f1f1!important}.selectize-dropdown .optgroup-header{font-weight:700;background:#efefef;color:#5a5a5a}.selectize-dropdown [data-selectable].option{cursor:pointer}.wf_status_wrap label{width:55px;height:28px;box-sizing:border-box;float:left;border-radius:100px;position:relative;cursor:pointer;transition:.3s ease;background:linear-gradient(125deg,#e2e2e2 0,#ccc 140%)}input[class=woo_feed_status_input]:checked+label{background:linear-gradient(125deg,#3cb0fd 0,#6c5ce7 140%)}input[class=woo_feed_status_input]:checked+label:before{left:29px}.wf_status_wrap label:before{transition:.3s ease;content:"";width:20px;height:20px;position:absolute;background:#fff;left:6px;top:4px;box-sizing:border-box;color:#000;border-radius:100px;box-shadow:0 1.5px 2px 0 #000}.view span.dashicons.dashicons-external{color:#22a6b3}.view span.dashicons.dashicons-sos{color:#22a6b3}.view span.dashicons.dashicons-download{color:#ee5253}.view span.dashicons.dashicons-media-code{color:#576574}.column-url,.widefat td.column-url,.widefat th.column-url{color:#1e8f9a;font-weight:700}.feed-progress-container{width:100%;color:#fff;text-align:center;font-weight:300}.feed-progress-bar{width:100%;background:#eee;padding:3px;border-radius:50px;box-shadow:inset 0 1px 3px rgba(0,0,0,.2)}.feed-progress-bar-fill{height:20px;display:block;background:linear-gradient(to right top,#10ac84,#13b389,#15ba8f,#18c194,#1ac89a,#13cba1,#0acfa9,#00d2b0,#00d2ba,#00d2c3,#00d2cb,#00d2d3);width:0;border-radius:50px;transition:width .8s ease}.feed-progress-status{float:left;font-weight:700;color:#00008b}.feed-progress-percentage{text-align:right;font-weight:bolder;color:#1dd1a1;font-family:"Arial Black",sans-serif;font-size:large}#wpbody-content.woofeed-body-content{overflow:visible!important}.clippy{position:relative;width:13px;margin-top:-3px;margin-left:3px;top:3px}.column-url .clippy{display:none}.column-url:hover .clippy{display:inline-block}.tooltipped{position:relative}.tooltipped:after{position:absolute;z-index:1000000;display:none;padding:5px 8px;font:normal normal 11px/1.5 Helvetica,arial,nimbussansl,liberationsans,freesans,clean,sans-serif,"Segoe UI Emoji","Segoe UI Symbol";color:#fff;text-align:center;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-wrap:break-word;white-space:pre;pointer-events:none;content:attr(aria-label);background:rgba(0,0,0,.8);border-radius:3px;-webkit-font-smoothing:subpixel-antialiased}.tooltipped:before{position:absolute;z-index:1000001;display:none;width:0;height:0;color:rgba(0,0,0,.8);pointer-events:none;content:"";border:5px solid transparent}.tooltipped:hover:before{display:inline-block;text-decoration:none}.tooltipped:hover:after{display:inline-block;text-decoration:none}.tooltipped:active:before{display:inline-block;text-decoration:none}.tooltipped:active:after{display:inline-block;text-decoration:none}.tooltipped:focus:before{display:inline-block;text-decoration:none}.tooltipped:focus:after{display:inline-block;text-decoration:none}.tooltipped-multiline:hover:after{display:table-cell}.tooltipped-multiline:active:after{display:table-cell}.tooltipped-multiline:focus:after{display:table-cell}.tooltipped-multiline:after{width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:250px;word-break:break-word;word-wrap:normal;white-space:pre-line;border-collapse:separate}.tooltipped-s:after{top:100%;right:50%;margin-top:5px;-webkit-transform:translateX(50%);transform:translateX(50%)}.tooltipped-s:before{top:auto;right:50%;bottom:-5px;margin-right:-5px;border-bottom-color:rgba(0,0,0,.8)}.tooltipped-se:after{top:100%;margin-top:5px;right:auto;left:50%;margin-left:-15px}.tooltipped-se:before{top:auto;right:50%;bottom:-5px;margin-right:-5px;border-bottom-color:rgba(0,0,0,.8)}.tooltipped-sw:after{top:100%;right:50%;margin-top:5px;margin-right:-15px}.tooltipped-sw:before{top:auto;right:50%;bottom:-5px;margin-right:-5px;border-bottom-color:rgba(0,0,0,.8)}.tooltipped-n:after{right:50%;bottom:100%;margin-bottom:5px;-webkit-transform:translateX(50%);transform:translateX(50%)}.tooltipped-n:before{top:-5px;right:50%;bottom:auto;margin-right:-5px;border-top-color:rgba(0,0,0,.8)}.tooltipped-ne:after{bottom:100%;margin-bottom:5px;right:auto;left:50%;margin-left:-15px}.tooltipped-ne:before{top:-5px;right:50%;bottom:auto;margin-right:-5px;border-top-color:rgba(0,0,0,.8)}.tooltipped-nw:after{right:50%;bottom:100%;margin-bottom:5px;margin-right:-15px}.tooltipped-nw:before{top:-5px;right:50%;bottom:auto;margin-right:-5px;border-top-color:rgba(0,0,0,.8)}.tooltipped-w:after{right:100%;bottom:50%;margin-right:5px;-webkit-transform:translateY(50%);transform:translateY(50%)}.tooltipped-w:before{top:50%;bottom:50%;left:-5px;margin-top:-5px;border-left-color:rgba(0,0,0,.8)}.tooltipped-e:after{bottom:50%;left:100%;margin-left:5px;-webkit-transform:translateY(50%);transform:translateY(50%)}.tooltipped-e:before{top:50%;right:-5px;bottom:50%;margin-top:-5px;border-right-color:rgba(0,0,0,.8)}.tooltipped-multiline.tooltipped-s:after{right:auto;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}.tooltipped-multiline.tooltipped-n:after{right:auto;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}.tooltipped-multiline.tooltipped-w:after{right:100%}.tooltipped-multiline.tooltipped-e:after{right:100%}.tooltipped-sticky:before{display:inline-block}.tooltipped-sticky:after{display:inline-block}.tooltipped-sticky.tooltipped-multiline:after{display:table-cell}.fullscreen-overlay-enabled.dark-theme .tooltipped:after{color:#000;background:rgba(255,255,255,.8)}.fullscreen-overlay-enabled.dark-theme .tooltipped .tooltipped-s:before{border-bottom-color:rgba(255,255,255,.8)}.fullscreen-overlay-enabled.dark-theme .tooltipped .tooltipped-se:before{border-bottom-color:rgba(255,255,255,.8)}.fullscreen-overlay-enabled.dark-theme .tooltipped .tooltipped-sw:before{border-bottom-color:rgba(255,255,255,.8)}.fullscreen-overlay-enabled.dark-theme .tooltipped.tooltipped-n:before{border-top-color:rgba(255,255,255,.8)}.fullscreen-overlay-enabled.dark-theme .tooltipped.tooltipped-ne:before{border-top-color:rgba(255,255,255,.8)}.fullscreen-overlay-enabled.dark-theme .tooltipped.tooltipped-nw:before{border-top-color:rgba(255,255,255,.8)}.fullscreen-overlay-enabled.dark-theme .tooltipped.tooltipped-e:before{border-right-color:rgba(255,255,255,.8)}.fullscreen-overlay-enabled.dark-theme .tooltipped.tooltipped-w:before{border-left-color:rgba(255,255,255,.8)}@media screen and (min-width:0\0){.tooltipped-multiline:after{width:250px}}ul.tracker_collection_list{list-style:initial;padding:initial;margin:-10px 0 0 30px;font-size:11px!important}ul.tracker_collection_list li{margin:0}table.wf-info-table,table.wf-rate-table{vertical-align:middle;text-align:center;max-width:100%;font-weight:500;margin-top:10px}table.wf-info-table th,table.wf-rate-table th{text-align:center}table.wf-info-table th .woo-feed-top-header,table.wf-rate-table th .woo-feed-top-header{display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between;-ms-flex-align:center;align-items:center}table.wf-info-table th .woo-feed-top-header .get-woo-feed-pro,table.wf-rate-table th .woo-feed-top-header .get-woo-feed-pro{margin-left:20px}table.wf-info-table th .woo-feed-top-header .get-woo-feed-pro img,table.wf-rate-table th .woo-feed-top-header .get-woo-feed-pro img{width:172px}table.wf-info-table th .woo-feed-top-header .woo-feed-top-buttons,table.wf-rate-table th .woo-feed-top-header .woo-feed-top-buttons{float:right;display:-ms-flexbox;display:flex;border-radius:7px;-ms-flex-pack:center;justify-content:center;-ms-flex-align:center;align-items:center}table.wf-info-table th .woo-feed-top-header .woo-feed-top-buttons a,table.wf-rate-table th .woo-feed-top-header .woo-feed-top-buttons a{padding:8px 20px;background:#576574;color:#fff;box-sizing:border-box;display:inline-block;transition:.3s ease}table.wf-info-table th .woo-feed-top-header .woo-feed-top-buttons a.woo-feed-doc-link,table.wf-rate-table th .woo-feed-top-header .woo-feed-top-buttons a.woo-feed-doc-link{background:#576574;border-top-left-radius:5px;border-bottom-left-radius:5px}table.wf-info-table th .woo-feed-top-header .woo-feed-top-buttons a.woo-feed-video-link,table.wf-rate-table th .woo-feed-top-header .woo-feed-top-buttons a.woo-feed-video-link{background:#ee5253}table.wf-info-table th .woo-feed-top-header .woo-feed-top-buttons a.woo-feed-support-link,table.wf-rate-table th .woo-feed-top-header .woo-feed-top-buttons a.woo-feed-support-link{background:#22a6b3;border-top-right-radius:5px;border-bottom-right-radius:5px}table.wf-info-table th .woo-feed-top-header .woo-feed-top-buttons a span.dashicons,table.wf-rate-table th .woo-feed-top-header .woo-feed-top-buttons a span.dashicons{font-size:18px;line-height:1.2}table.wf-info-table th .woo-feed-top-header .woo-feed-top-buttons a:hover,table.wf-rate-table th .woo-feed-top-header .woo-feed-top-buttons a:hover{background:#30336b;box-shadow:0 0 33px 0 rgba(0,0,0,.12)}table.wf-info-table strong,table.wf-rate-table strong{font-weight:700}table.wf-info-table th:first-child img{margin:0 0 -5px 5px}table.wf-rate-table a{color:#0073aa}table.wf-rate-table a.review-star:after{content:"\f155\f155\f155\f155\f155"!important;font-family:dashicons;font-size:10px;font-weight:100;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;color:#0073aa;text-decoration:underline}#adminmenu #toplevel_page_webappick-manage-feeds div.wp-menu-image::before{content:"";background:url(../images/woo-feed-icon.svg) no-repeat center center;background-size:20px 20px;opacity:.6}#adminmenu #toplevel_page_webappick-manage-feeds:hover div.wp-menu-image::before{opacity:1}#adminmenu #toplevel_page_webappick-manage-feeds.wp-has-current-submenu div.wp-menu-image::before{opacity:1}.wapk-admin,.wapk-admin *{box-sizing:border-box}.wapk-admin{position:relative;display:block;-webkit-hyphens:manual;-ms-hyphens:manual;-moz-hyphens:manual;hyphens:manual;color:#1b2730;margin:0 0 0 -10px}@media screen and (min-width:783px){.wapk-admin{margin:0 0 0 -20px}}.text-center{text-align:center}.wapk-admin h1,.wapk-admin h2,.wapk-admin h3,.wapk-admin h4,.wapk-admin h5,.wapk-admin h6,.wapk-admin p{color:#1b2730}.wapk-admin sup{vertical-align:baseline;position:relative;top:-6px}.wapk-admin sub{vertical-align:baseline;position:relative;top:4px}.wapk-admin .wapk-section{margin:10px 20px 0 22px;position:relative;display:block}.wapk-admin .wapk-section [class$=icon32]+h2{font-size:23px;font-weight:400;margin:0;padding:9px 0 4px 0;line-height:1.3}.wapk-admin .wapk-section h1{font-size:23px;font-weight:400;margin:0;padding:9px 0 4px 0;line-height:1.3}.wapk-admin .wapk-section>h2:first-child{font-size:23px;font-weight:400;margin:0;padding:9px 0 4px 0;line-height:1.3}.wapk-admin>.notice{margin:10px 20px 0 22px;position:relative;display:block}.wapk-admin span.help{display:block;float:left;width:100%;font-size:.9em;color:#636363;margin-top:5px;font-weight:500}.wapk-admin span.help .dashicons{width:11px;height:12px;font-size:inherit;vertical-align:middle}.clear:after{content:"";display:table;clear:both}.wapk-feed-docs .postbox{width:355px;margin-right:20px;display:inline-block;vertical-align:top}.wapk-feed-docs .postbox .hndle{font-size:14px;padding:8px 12px;margin:0;line-height:1.4;cursor:pointer}.wapk-feed-docs .postbox .dashicons{color:#ccc}.wapk-feed-docs .postbox a{text-decoration:none}.wapk-feed-docs .postbox .inside{margin-bottom:0}.wapk-feed-docs .postbox ul{margin-bottom:0}.wapk-feed-docs .postbox .toggle-indicator:before{content:"\f142";display:inline-block;font:400 20px/1 dashicons;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-decoration:none!important}.wapk-feed-docs .postbox li{width:100%;display:block;float:left}.wapk-feed-docs .postbox li span{display:inline-block;float:left;margin-right:4px}.wapk-feed-docs .postbox li a{display:inline-block;float:left;width:calc(100% - 24px)}.wapk-feed-docs .postbox.closed .toggle-indicator:before{content:"\f140"}.wapk-section #post-body.columns-2 #side-sortables{min-height:196px}#poststuff #feed_merchant_info .inside{margin:0;padding:0}#feed_merchant_info ul.data{margin-left:24px;margin-top:5px}#feed_merchant_info ul.data li{margin-bottom:5px}.merchant-info-section{padding:6px 10px 8px}.merchant-info-section.woo-feed-open-file{text-align:center}.merchant-info-section.woo-feed-open-file a{line-height:1.5;text-decoration:none}.generateFeed .wf-tab-content table:first-child{border:none;box-shadow:none}.generateFeed table th{font-weight:700}@media only screen and (max-width:850px){.wapk-feed-docs .postbox{display:block;width:auto;float:none;margin-right:auto}}.wp-submenu li span.woo-feed-docs{font-weight:700;color:#f18500}.wp-submenu li:hover span.woo-feed-docs{color:#ce7304}.wp-submenu li.current span.woo-feed-docs{color:#ce7304}.wapk-admin .wapk-feed-docs .postbox .hndle{cursor:default}.wapk-cta{position:relative;display:-ms-flexbox;display:flex;width:100%;padding:100px 15px;background:linear-gradient(45deg,#6cd5ff 33%,#c2efef 100%);-ms-flex-pack:center;justify-content:center;-ms-flex-align:center;align-items:center}.wapk-cta-icon .dashicons{font-size:100px;width:100px;height:auto;margin:0 10px -8px 0;color:#02658c}.wapk-cta-content{width:50%}.wapk-cta-content h2{font-size:2em;margin:.5em 0}.wapk-cta-action a.wapk-button{font-size:24px;height:auto!important;padding:10px 20px}@media (max-width:600px){.wapk-cta{display:block;text-align:center;padding:4em 0}.wapk-cta-content{width:100%;margin:2em 0}}.wapk-button{color:#00d4d4;border-color:#00d4d4;display:inline-block;text-decoration:none;font-size:13px;line-height:2.15384615;min-height:30px;margin:0;padding:0 10px;cursor:pointer;border-width:1px;border-style:solid;-webkit-appearance:none;border-radius:3px;white-space:nowrap;box-sizing:border-box}.wapk-button>svg{width:15px;margin-left:5px;fill:#00d4d4}.wapk-button>.dashicons{color:#00d4d4}.wapk-button:hover{border-color:#0bb;color:#0bb}.wapk-button:hover>svg{fill:#0bb}.wapk-button:hover>.dashicons{color:#0bb}.wapk-button:focus{border-color:#00d4d4;color:#0bb;box-shadow:0 0 0 1px #00d4d4}.wapk-button:focus>svg{fill:#0bb}.wapk-button:focus>.dashicons{color:#0bb}.wapk-button:active{background:#0bb;border-color:#0bb}.wapk-button-secondary{color:#00d4d4;border-color:#00d4d4;display:inline-block;text-decoration:none;font-size:13px;line-height:2.15384615;min-height:30px;margin:0;padding:0 10px;cursor:pointer;border-width:1px;border-style:solid;-webkit-appearance:none;border-radius:3px;white-space:nowrap;box-sizing:border-box}.wapk-button-secondary>svg{width:15px;margin-left:5px;fill:#00d4d4}.wapk-button-secondary>.dashicons{color:#00d4d4}.wapk-button-secondary:hover{border-color:#0bb;color:#0bb}.wapk-button-secondary:hover>svg{fill:#0bb}.wapk-button-secondary:hover>.dashicons{color:#0bb}.wapk-button-secondary:focus{border-color:#00d4d4;color:#0bb;box-shadow:0 0 0 1px #00d4d4}.wapk-button-secondary:focus>svg{fill:#0bb}.wapk-button-secondary:focus>.dashicons{color:#0bb}.wapk-button-primary{display:inline-block;text-decoration:none;font-size:13px;line-height:2.15384615;min-height:30px;margin:0;padding:0 10px;cursor:pointer;border-width:1px;border-style:solid;-webkit-appearance:none;border-radius:3px;white-space:nowrap;box-sizing:border-box;background:#00d4d4;border-color:#00d4d4;color:#fff;box-shadow:0 1px 0 #0bb;text-shadow:0 -1px 1px #0bb,1px 0 1px #0bb,0 1px 1px #0bb,-1px 0 1px #0bb}.wapk-button-primary>svg{fill:#fff}.wapk-button-primary:hover{background:#00e3e3;border-color:#00c5c5;color:#fff}.wapk-button-primary:hover>svg{fill:#fff}.wapk-button-primary:focus{background:#00e3e3;border-color:#00c5c5;color:#fff;box-shadow:0 0 0 1px #fff,0 0 0 3px #00d4d4}.wapk-button-primary:focus>svg{fill:#fff}.wapk-button-primary:active{background:#0bb;border-color:#0bb;color:#fff}.wapk-button-primary:active>svg{fill:#fff}.wapk-button-primary:disabled{color:#c7d1d1!important;background:#2ff!important;border-color:#2ff!important;text-shadow:none!important}.wapk-button-primary:disabled>svg{fill:#c7d1d1!important}.wapk-button.hover{border-color:#0bb;color:#0bb}.wapk-button.hover>svg{fill:#0bb}.wapk-button.hover>.dashicons{color:#0bb}.wapk-button.focus{border-color:#00d4d4;color:#0bb;box-shadow:0 0 0 1px #00d4d4}.wapk-button.focus>svg{fill:#0bb}.wapk-button.focus>.dashicons{color:#0bb}.wapk-button.active{border-color:#0bb;color:#0bb;box-shadow:inset 0 2px 5px -3px #0bb}.wapk-button.active:focus{border-color:#0bb;color:#0bb;box-shadow:inset 0 2px 5px -3px #0bb}.wapk-button.active:focus>svg{fill:#0bb}.wapk-button.active:focus>.dashicons{color:#0bb}.wapk-button.active:hover{border-color:#0bb;color:#0bb;box-shadow:inset 0 2px 5px -3px #0bb}.wapk-button.active:hover>svg{fill:#0bb}.wapk-button.active:hover>.dashicons{color:#0bb}.wapk-button.active>svg{fill:#0bb}.wapk-button.active>.dashicons{color:#0bb}.wapk-button-primary.active{background:#00d4d4;color:#fff;border-color:#088;box-shadow:inset 0 2px 5px -3px #000}.wapk-button-primary.active:focus{background:#00d4d4;color:#fff;border-color:#088;box-shadow:inset 0 2px 5px -3px #000}.wapk-button-primary.active:focus>svg{fill:#fff}.wapk-button-primary.active:hover{background:#00d4d4;color:#fff;border-color:#088;box-shadow:inset 0 2px 5px -3px #000}.wapk-button-primary.active:hover>svg{fill:#fff}.wapk-button-primary.active>svg{fill:#fff}.wapk-button-primary[disabled]{color:#c7d1d1!important;background:#2ff!important;border-color:#2ff!important;text-shadow:none!important}.wapk-button-primary[disabled]>svg{fill:#c7d1d1!important}.wapk-button-primary.wapk-button-primary-disabled{color:#c7d1d1!important;background:#2ff!important;border-color:#2ff!important;text-shadow:none!important}.wapk-button-primary.wapk-button-primary-disabled>svg{fill:#c7d1d1!important}.wapk-button-primary.disabled{color:#c7d1d1!important;background:#2ff!important;border-color:#2ff!important;text-shadow:none!important}.wapk-button-primary.disabled>svg{fill:#c7d1d1!important}.wapk-button-primary.wapk-button-hero{box-shadow:0 2px 0 #0bb}.wapk-button-primary.wapk-button-hero:focus{box-shadow:0 2px 0 #0bb,0 1px 0 #00c5c5,0 0 2px 1px #0ee}.wapk-button-primary.wapk-button-hero:active{box-shadow:inset 0 3px 0 #00a1a1}.wapk-button-primary.wapk-button-hero.active{box-shadow:inset 0 3px 0 #00a1a1}.wapk-button-primary.wapk-button-hero.active:focus,.wapk-button-primary.wapk-button-hero.active:hover{box-shadow:inset 0 3px 0 #00a1a1}.wapk-button-group>.wapk-button.active{border-color:#00d4d4}.wapk-button.wapk-button-xl{height:30px;line-height:28px;padding:0 12px 2px}.wapk-button-group.wapk-button-xl .wapk-button{height:30px;line-height:28px;padding:0 12px 2px}.wapk-button.wapk-button-hero{font-size:18px;height:50px;line-height:48px;padding:0 36px;min-height:46px}.wapk-button-group.wapk-button-hero .wapk-button{font-size:18px;height:50px;line-height:48px;padding:0 36px;min-height:46px}@media screen and (min-width:782px){th#provider,th#status{width:80px}th#type{width:50px}th#option_name{width:100px}td.option_name.column-option_name>span:first-child{display:none}th#last_updated{width:90px}th#view{width:135px}}@media screen and (min-width:960px){th#provider,th#status{width:100px}th#type{width:80px}th#option_name{width:150px}th#last_updated{width:140px}}@media screen and (max-width:782px){table.wf-info-table{margin-top:10px}table.wf-info-table th:first-child img{margin:0 auto;display:block}.wapk-button.wapk-button-xl{padding:6px 14px;line-height:normal;font-size:14px;vertical-align:middle;height:auto;margin-bottom:4px}}.wapk-feed-docs .wapk-feed-cta{margin:0}.campaign_configurator{background:#fff;padding:20px 0}.campaign_configurator table{margin:0 auto;width:51%;min-width:574px;border:none;box-shadow:none}.campaign_configurator th{min-width:120px}@media screen and (max-width:782px){.campaign_configurator{padding:0}.campaign_configurator table{width:auto;min-width:auto;max-width:100%}.campaign_configurator th{min-width:auto}}#wf-tab-content-config td>input:not([type=checkbox]):not([type=radio]),#wf-tab-content-config td>select,#wf-tab-content-config td>textarea{width:100%!important}.woo-feed-filters td>div:nth-child(2n):not(.clear):not(.selectize):not(.counter){width:120px;display:block}.woo-feed-filters td>div:not(.clear){float:left;margin-right:10px}.woo-feed-filters tr>td:first-child{width:290px;padding-left:40px}.woo-feed-filters,.woo-feed-ftp{margin:15px auto 25px}.wf_clean_cache_wrapper{display:-ms-flexbox;display:flex;margin-left:auto}@-webkit-keyframes LoaderClockWise{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes LoaderClockWise{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.woo-feed-cache-loader{width:18px;margin-right:5px;animation:LoaderClockWise 1s linear infinite;-webkit-animation:LoaderClockWise 1s linear infinite;display:none}.woo-feed-table-heading .woo-feed-table-heading-title{float:left;margin-right:auto;display:inline-block;line-height:30px}.woo-feed-table-heading .wf_clean_cache_wrapper{float:right;font-weight:400}.wf_clean_cache_wrapper button{background:linear-gradient(125deg,#eb4d4b 0,#ff9671 140%);color:#fff;border:none;font-weight:500;display:inline-block;text-decoration:none;font-size:13px;line-height:2.15384615;min-height:30px;margin:0;padding:0 10px;border-radius:3px;cursor:pointer;outline:0}.wf_clean_cache_wrapper button:hover{background:#ff7979;color:#fff}input[type=submit][data-id=wf_action_submit]{background:linear-gradient(125deg,#3cb0fd 0,#6c5ce7 140%);color:#fff;border:1px;padding:0 20px}input[type=submit][data-id=wf_action_submit]:hover{background:linear-gradient(125deg,#3cb0fd 0,#6c5ce7 140%);color:#fff}.woo-import-popup-body #TB_window{width:500px!important}.woo-import-popup-body #TB_window #TB_title{border:none;background:#fff;text-align:center;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;-ms-flex-align:center;align-items:center;height:35px!important}.woo-import-popup-body #TB_window #TB_title #TB_ajaxWindowTitle{color:#30336b;font-weight:700}.woo-import-popup-body #TB_window #TB_closeWindowButton{top:-14.5px;right:-14.5px;border:none;outline:0}.woo-import-popup-body #TB_window #TB_closeWindowButton .tb-close-icon{background:#ff5e55;color:#fff;border-radius:50%}.woo-import-popup-body #TB_window #TB_closeWindowButton:focus{outline:0;border:0}.woo-import-popup-body #TB_window #TB_ajaxContent{position:relative;width:100%!important;height:auto!important;border:none;box-sizing:border-box;overflow:hidden;background:#f7fcff;padding:30px 20px}.woo-import-popup-body #TB_window #TB_ajaxContent:before{content:"";width:115%;display:block;background:#4bcffa;position:absolute;height:130%;z-index:0;left:-36%;top:-85px;-webkit-transform:rotate(115deg);transform:rotate(115deg)}.woo-import-popup-body #TB_window #TB_ajaxContent table{border:none;position:relative;z-index:1;border-radius:3px;text-align:center;padding:20px;box-shadow:0 12px 20px -17px #000}.woo-import-popup-body #TB_window #TB_ajaxContent table input{width:60%}.woo-import-popup-body #TB_window #TB_ajaxContent table input:focus{outline:2px solid #68b8f7}.woo-import-popup-body #TB_window #TB_ajaxContent table input[type=file]{padding:3px 0;cursor:pointer}.woo-import-popup-body #TB_window #TB_ajaxContent table input[type=text]{border-radius:25px;font-size:14px;padding:1px 20px;text-align:center}.woo-import-popup-body #TB_window #TB_ajaxContent table input[type=submit]{background:#17c0eb;border-radius:25px;border:0;box-shadow:1px 4px 7px -3px #45364a;font-weight:600;transition:.3s ease}.woo-import-popup-body #TB_window #TB_ajaxContent table input[type=submit]:hover{-webkit-transform:translateY(-2px);transform:translateY(-2px)}.woo-feed-notice{position:relative}.woo-feed-notice .woo-feed-review-notice-logo{width:90px;height:90px;float:left;margin-right:5px;background:url(../images/woo-feed-logo.svg) no-repeat}.woo-feed-notice .woo-feed-review-btn-dismiss{display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;-ms-flex-line-pack:center;align-content:center;position:absolute;top:7px;right:7px;background:0 0;border:none;cursor:pointer}.woo-feed-notice .woo-feed-review-btn-dismiss span{line-height:18px}.woo-feed-notice .woo-feed-review-btn-dismiss:before{background:0 0;color:#787c82;content:"\f153";display:block;font:normal 16px/20px dashicons;speak:never;height:20px;text-align:center;width:20px;-webkit-font-smoothing:antialiased}.woo-feed-notice .woo-feed-review-btn-dismiss:hover:before{color:#d63638}.woo-feed-status-table-wrapper .woo-feed-status-table{width:100%;max-width:900px;border-collapse:collapse;border-spacing:.5rem;box-shadow:0 0 20px rgba(0,0,0,.1)}.woo-feed-status-table-wrapper .woo-feed-status-table tr:nth-child(even){background:#f1f1f1}.woo-feed-status-table-wrapper .woo-feed-status-table tr:nth-child(odd){background:#fafafc}.woo-feed-status-table-wrapper .woo-feed-status-table tr th{background:#353b48;color:#fff}.woo-feed-status-table-wrapper .woo-feed-status-table tr th.woo-feed-status-message-header{display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between;-ms-flex-align:center;align-items:center}.woo-feed-status-table-wrapper .woo-feed-status-table tr th.woo-feed-status-message-header #woo-feed-copy-status-btn{background:linear-gradient(125deg,#3cb0fd 0,#6c5ce7 140%);border:none}.woo-feed-status-table-wrapper .woo-feed-status-table tr td,.woo-feed-status-table-wrapper .woo-feed-status-table tr th{padding:.5rem 20px;text-align:left}.woo-feed-status-table-wrapper .woo-feed-status-table tr td.woo-feed-status-page-btn-group{display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between;-ms-flex-align:center;align-items:center}.woo-feed-status-table-wrapper .woo-feed-status-table tr td.woo-feed-status-page-btn-group .wf_clean_cache_wrapper{margin:initial}.woo-feed-status-table-wrapper .woo-feed-status-table tr td.woo-feed-status-page-btn-group button,.woo-feed-status-table-wrapper .woo-feed-status-table tr td.woo-feed-status-page-btn-group input[type=button]{height:38px;padding:0 30px;font-size:16px;font-weight:500;border:none;outline:0}input[id^=woo_feed_identifier_]{display:block;width:100%!important}#taxonomy-woo-feed-brand #newwoo-feed-brand_parent,.taxonomy-woo-feed-brand .form-field.term-parent-wrap{display:none}.wapk-admin .switch{position:relative;display:inline-block;width:55px;height:28px}.wapk-admin .switch input{opacity:0;width:0;height:0}.wapk-admin .slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc;transition:.4s}.wapk-admin .slider:before{position:absolute;content:"";height:20px;width:20px;left:4px;bottom:4px;background-color:#fff;transition:.4s}.wapk-admin input:checked+.slider{background:linear-gradient(125deg,#3cb0fd 0,#6c5ce7 140%)}.wapk-admin input:focus+.slider{box-shadow:0 0 1px #2196f3}.wapk-admin input:checked+.slider:before{-webkit-transform:translateX(26px);transform:translateX(26px)}.wapk-admin .slider.round{border-radius:34px}.wapk-admin .slider.round:before{border-radius:50%}.woo-feed-category-mapping-config-table{position:relative}.woo-feed-category-mapping-config-table .woo-feed-cat-map-spinner{display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;width:100%;height:100%;position:absolute;top:0;left:0;background:rgba(235,235,235,.9);z-index:999;padding-top:250px}span[id*=cat-map-]{cursor:pointer;position:relative;top:5px}
admin/images/woo_feed_halloween_notice.png ADDED
Binary file
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.5.3' );
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.5.5' );
27
  }
28
 
29
  if ( ! defined( 'WOO_FEED_FREE_PATH' ) ) {
includes/classes/class-woo-feed-product-attributes.php CHANGED
@@ -139,6 +139,7 @@ class Woo_Feed_Product_Attributes {
139
  'author_email' => esc_html__( 'Author Email', 'woo-feed' ),
140
  'date_created' => esc_html__( 'Date Created', 'woo-feed' ),
141
  'date_updated' => esc_html__( 'Date Updated', 'woo-feed' ),
 
142
  ]
143
  ];
144
 
139
  'author_email' => esc_html__( 'Author Email', 'woo-feed' ),
140
  'date_created' => esc_html__( 'Date Created', 'woo-feed' ),
141
  'date_updated' => esc_html__( 'Date Updated', 'woo-feed' ),
142
+ 'product_status' => esc_html__( 'Product Status', 'woo-feed' ),
143
  ]
144
  ];
145
 
includes/classes/class-woo-feed-products-v3.php CHANGED
@@ -71,22 +71,22 @@ class Woo_Feed_Products_v3 {
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
  *
@@ -130,7 +130,7 @@ class Woo_Feed_Products_v3 {
130
  'product highlight 9',
131
  'product highlight 10',
132
  );
133
-
134
  /**
135
  * To replace google additional image link attribute for CSV & TXT feed
136
  *
@@ -194,8 +194,8 @@ class Woo_Feed_Products_v3 {
194
  * @var array
195
  */
196
  protected $xml_wrapper = [];
197
-
198
-
199
  /**
200
  * Attribute to skip in attribute loop for processing separately
201
  *
@@ -265,7 +265,7 @@ class Woo_Feed_Products_v3 {
265
  'tax_ship',
266
  ),
267
  );
268
-
269
  /**
270
  * Already Processed merchant attributes by the attribute loop
271
  * this will ensure unique merchant attribute.
@@ -274,8 +274,8 @@ class Woo_Feed_Products_v3 {
274
  * @var array
275
  */
276
  protected $processed_merchant_attributes = array();
277
-
278
-
279
  /**
280
  * Post meta prefix for dropdown item
281
  *
@@ -283,7 +283,7 @@ class Woo_Feed_Products_v3 {
283
  * @var string
284
  */
285
  const POST_META_PREFIX = 'wf_cattr_';
286
-
287
  /**
288
  * Product Attribute (taxonomy & local) Prefix
289
  *
@@ -291,7 +291,7 @@ class Woo_Feed_Products_v3 {
291
  * @var string
292
  */
293
  const PRODUCT_ATTRIBUTE_PREFIX = 'wf_attr_';
294
-
295
  /**
296
  * Product Taxonomy Prefix
297
  *
@@ -299,7 +299,7 @@ class Woo_Feed_Products_v3 {
299
  * @var string
300
  */
301
  const PRODUCT_TAXONOMY_PREFIX = 'wf_taxo_';
302
-
303
  /**
304
  * Product Custom Field Prefix
305
  *
@@ -307,7 +307,7 @@ class Woo_Feed_Products_v3 {
307
  * @var string
308
  */
309
  const PRODUCT_CUSTOM_IDENTIFIER = 'woo_feed_';
310
-
311
  /**
312
  * Product Category Mapping Prefix
313
  *
@@ -315,7 +315,7 @@ class Woo_Feed_Products_v3 {
315
  * @var string
316
  */
317
  const PRODUCT_CATEGORY_MAPPING_PREFIX = 'wf_cmapping_';
318
-
319
  /**
320
  * WordPress Option Prefix
321
  *
@@ -324,7 +324,7 @@ class Woo_Feed_Products_v3 {
324
  * @var string
325
  */
326
  const WP_OPTION_PREFIX = 'wf_option_';
327
-
328
  /**
329
  * Advance Custom Field (ACF) Prefix
330
  *
@@ -332,7 +332,7 @@ class Woo_Feed_Products_v3 {
332
  * @var string
333
  */
334
  const PRODUCT_ACF_FIELDS = 'acf_fields_';
335
-
336
  /**
337
  * Woo_Feed_Products_v3 constructor.
338
  *
@@ -346,7 +346,7 @@ class Woo_Feed_Products_v3 {
346
  $this->process_xml_wrapper();
347
  woo_feed_log_feed_process( $this->config['filename'], sprintf( 'Current Query Type is %s', $this->queryType ) );
348
  }
349
-
350
  /**
351
  * Generate Query Args For WP/WC query class
352
  *
@@ -356,10 +356,10 @@ class Woo_Feed_Products_v3 {
356
  */
357
  protected function get_query_args( $type = 'wc' ) {
358
  $args = [];
359
-
360
  // Include Product Variations with db query if configured
361
  $variation_query = woo_feed_get_options( 'variation_query_type' );
362
-
363
  if ( 'wc' === $type ) {
364
  $product_types = $this->product_types;
365
  if ( 'variable' === $variation_query ) {
@@ -368,7 +368,7 @@ class Woo_Feed_Products_v3 {
368
  unset( $product_types[ $variation ] );
369
  }
370
  }
371
-
372
  $args = array(
373
  'limit' => - 1, // phpcs:ignore
374
  'status' => $this->post_status,
@@ -379,16 +379,16 @@ class Woo_Feed_Products_v3 {
379
  'suppress_filters' => false,
380
  );
381
  }
382
-
383
  if ( 'wp' === $type ) {
384
-
385
  $post_type = 'product';
386
  // Include Product Variations with db query if configured
387
  $variation_query = woo_feed_get_options( 'variation_query_type' );
388
  if ( 'individual' === $variation_query ) {
389
  $post_type = [ 'product', 'product_variation' ];
390
  }
391
-
392
  $args = array(
393
  'posts_per_page' => - 1, // phpcs:ignore
394
  'post_type' => $post_type,
@@ -401,10 +401,10 @@ class Woo_Feed_Products_v3 {
401
  'suppress_filters' => false,
402
  );
403
  }
404
-
405
  return $args;
406
  }
407
-
408
  /**
409
  * Get Products using WC_Product_Query
410
  *
@@ -420,10 +420,10 @@ class Woo_Feed_Products_v3 {
420
  if ( woo_feed_is_debugging_enabled() ) {
421
  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
422
  }
423
-
424
  return $query->get_products();
425
  }
426
-
427
  /**
428
  * Get Products using WP_Query
429
  *
@@ -438,10 +438,10 @@ class Woo_Feed_Products_v3 {
438
  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
439
  woo_feed_log( $this->config['filename'], sprintf( 'WP_Query Request ::' . PHP_EOL . '%s', $query->request ), 'info' );
440
  }
441
-
442
  return $query->get_posts();
443
  }
444
-
445
  /**
446
  * Get products
447
  *
@@ -458,13 +458,13 @@ class Woo_Feed_Products_v3 {
458
  $wp = $this->get_wp_query_products();
459
  $products = array_unique( array_merge( $wc, $wp ) );
460
  }
461
-
462
  //set product ids
463
  $this->product_ids = $products;
464
-
465
  return $products;
466
  }
467
-
468
  /**
469
  * Organize Feed Attribute config
470
  *
@@ -474,7 +474,7 @@ class Woo_Feed_Products_v3 {
474
  if ( empty( $this->config ) ) {
475
  return false;
476
  }
477
-
478
  $attributeConfig = array();
479
  $merchantAttributes = $this->config['mattributes'];
480
  if ( ! empty( $merchantAttributes ) ) {
@@ -491,10 +491,10 @@ class Woo_Feed_Products_v3 {
491
  $i ++;
492
  }
493
  }
494
-
495
  return $attributeConfig;
496
  }
497
-
498
  /**
499
  * Get Product Information according to feed config
500
  *
@@ -505,14 +505,14 @@ class Woo_Feed_Products_v3 {
505
  *
506
  */
507
  public function get_products( $productIds ) {
508
-
509
  if ( empty( $productIds ) ) {
510
  return [];
511
  }
512
-
513
  //filter big data
514
  $this->data = apply_filters( "woo_feed_feed_big_data", $this->data, $productIds, $this->config );
515
-
516
  /**
517
  * Fires before looping through request product for getting product data
518
  *
@@ -522,39 +522,39 @@ class Woo_Feed_Products_v3 {
522
  * @since 3.2.10
523
  */
524
  do_action( 'woo_feed_before_product_loop', $productIds, $this->config );
525
-
526
  foreach ( $productIds as $key => $pid ) {
527
  woo_feed_log_feed_process( $this->config['filename'], sprintf( 'Loading Product Data For %d.', $pid ) );
528
  $product = wc_get_product( $pid );
529
-
530
  if ( $this->exclude_from_loop( $product ) ) {
531
  continue;
532
  }
533
-
534
  if ( $this->process_variation( $product ) ) {
535
  continue;
536
  }
537
-
538
  if ( ! $this->filter_product( $product ) ) {
539
  woo_feed_log_feed_process( $this->config['filename'], 'Skipping Product :: Matched with filter conditions' );
540
  continue;
541
  }
542
-
543
  woo_feed_log_feed_process( $this->config['filename'], 'Formatting Feed Data...' );
544
-
545
  // Add Single item wrapper before product info loop start
546
  if ( 'xml' == $this->config['feedType'] ) {
547
  $this->feedBody .= "\n";
548
  $this->feedBody .= '<' . $this->config['itemWrapper'] . '>';
549
  $this->feedBody .= "\n";
550
  }
551
-
552
  // reset processed attribute list before loop
553
  $this->processed_merchant_attributes = [];
554
-
555
  // Process attribute values
556
  $this->process_attributes( $product );
557
-
558
  try {
559
  woo_feed_log_feed_process( $this->config['filename'], 'Processing Merchant Specific Fields' );
560
  // Process feed data for uncommon merchant feed like Google,Facebook,Pinterest
@@ -564,17 +564,17 @@ class Woo_Feed_Products_v3 {
564
  woo_feed_log( $this->config['filename'], $message, 'critical', $e, true );
565
  woo_feed_log_fatal_error( $message, $e );
566
  }
567
-
568
  if ( 'xml' == $this->config['feedType'] ) {
569
  if ( empty( $this->feedHeader ) ) {
570
  $this->feedHeader = $this->process_xml_feed_header();
571
  $this->feedFooter = $this->process_xml_feed_footer();
572
-
573
  }
574
-
575
  $this->feedBody .= '</' . $this->config['itemWrapper'] . '>';
576
-
577
-
578
  } elseif ( 'txt' == $this->config['feedType'] ) {
579
  if ( empty( $this->feedHeader ) ) {
580
  $this->process_txt_feed_header();
@@ -591,7 +591,7 @@ class Woo_Feed_Products_v3 {
591
  woo_feed_log_feed_process( $this->config['filename'], 'Done Formatting...' );
592
  $this->pi ++;
593
  }
594
-
595
  /**
596
  * Fires after looping through request product for getting product data
597
  *
@@ -601,10 +601,10 @@ class Woo_Feed_Products_v3 {
601
  * @since 3.2.10
602
  */
603
  do_action( 'woo_feed_after_product_loop', $productIds, $this->config );
604
-
605
  return $this->products;
606
  }
607
-
608
  /**
609
  * Process product variations
610
  *
@@ -617,7 +617,7 @@ class Woo_Feed_Products_v3 {
617
  // Apply variable and variation settings
618
  if ( $product->is_type( 'variable' ) && $product->has_child() ) {
619
  $this->pi ++;
620
-
621
  $variation_query = woo_feed_get_options( 'variation_query_type' );
622
  if ( 'variable' === $variation_query ) {
623
  $variations = $product->get_visible_children();
@@ -628,13 +628,13 @@ class Woo_Feed_Products_v3 {
628
  $this->get_products( $variations );
629
  }
630
  }
631
-
632
  return true;
633
  }
634
-
635
  return false;
636
  }
637
-
638
  /**
639
  * Process The Attributes and assign value to merchant attribute
640
  *
@@ -647,56 +647,56 @@ class Woo_Feed_Products_v3 {
647
  // print_r($this->config['attributes']);
648
  // Get Product Attribute values by type and assign to product array
649
  foreach ( $this->config['attributes'] as $attr_key => $attribute ) {
650
-
651
  $merchant_attribute = isset( $this->config['mattributes'][ $attr_key ] ) ? $this->config['mattributes'][ $attr_key ] : '';
652
-
653
  if ( $this->exclude_current_attribute( $product, $merchant_attribute, $attribute ) ) {
654
  continue;
655
  }
656
-
657
  // Add Prefix and Suffix into Output
658
  $prefix = $this->config['prefix'][ $attr_key ];
659
  $suffix = $this->config['suffix'][ $attr_key ];
660
  $merchant = $this->config['provider'];
661
  $feedType = $this->config['feedType'];
662
-
663
  if ( 'pattern' == $this->config['type'][ $attr_key ] ) {
664
  $attributeValue = $this->config['default'][ $attr_key ];
665
  } else { // Get Pattern value
666
  $attributeValue = $this->getAttributeValueByType( $product, $attribute, $merchant_attribute );
667
  }
668
-
669
  // Format Output according to Output Type config.
670
  if ( isset( $this->config['output_type'][ $attr_key ] ) ) {
671
  $outputType = $this->config['output_type'][ $attr_key ];
672
  $attributeValue = $this->format_output( $attributeValue, $this->config['output_type'][ $attr_key ], $product, $attribute, $merchant_attribute );
673
  }
674
-
675
  // Limit Output.
676
  if ( isset( $this->config['limit'][ $attr_key ] ) ) {
677
  $attributeValue = $this->crop_string( $attributeValue, 0, $this->config['limit'][ $attr_key ] );
678
  }
679
-
680
  // Process prefix and suffix.
681
  $attributeValue = $this->process_prefix_suffix( $attributeValue, $prefix, $suffix, $attribute );
682
-
683
  if ( 'xml' == $feedType ) {
684
-
685
  // Replace XML Nodes according to merchant requirement.
686
  $getReplacedAttribute = woo_feed_replace_to_merchant_attribute( $merchant_attribute, $merchant, $feedType );
687
-
688
  // XML does not support space in node. So replace Space with Underscore.
689
  $getReplacedAttribute = str_replace( ' ', '_', $getReplacedAttribute );
690
-
691
  // Trim XML Element text & Encode for UTF-8.
692
  if ( ! empty( $attributeValue ) ) {
693
  $attributeValue = trim( $attributeValue );
694
-
695
  if ( 'custom' === $this->config['provider'] && strpos( $attributeValue, '<![CDATA[' ) === false ) {
696
  $attributeValue = htmlentities( $attributeValue, ENT_XML1 | ENT_QUOTES, 'UTF-8' );
697
  }
698
  }
699
-
700
  // Add closing XML node if value is empty
701
  if ( '' !== $attributeValue ) {
702
  // Add CDATA wrapper for XML feed to prevent XML error.
@@ -710,44 +710,44 @@ class Woo_Feed_Products_v3 {
710
  $this->feedBody .= '<' . $getReplacedAttribute . '/>';
711
  $this->feedBody .= "\n";
712
  }
713
-
714
  } elseif ( in_array( $feedType, [ 'csv', 'tsv', 'xls' ], true ) ) {
715
  $merchant_attribute = woo_feed_replace_to_merchant_attribute( $merchant_attribute, $merchant, $feedType );
716
  $merchant_attribute = $this->processStringForCSV( $merchant_attribute );
717
-
718
  if ( "shipping" === $merchant_attribute && 'bing' == $this->config['provider'] ) {
719
  $merchant_attribute = 'shipping(country:service:price)';
720
  } elseif ( "shipping" === $merchant_attribute ) {
721
  $merchant_attribute = 'shipping(country:region:service:price)';
722
  }
723
-
724
  if ( "tax" === $merchant_attribute ) {
725
  $merchant_attribute = 'tax(country:region:rate:tax_ship)';
726
  }
727
-
728
  $attributeValue = $this->processStringForCSV( $attributeValue );
729
-
730
  } elseif ( 'txt' == $feedType ) {
731
  $merchant_attribute = woo_feed_replace_to_merchant_attribute( $merchant_attribute, $merchant, $feedType );
732
  $merchant_attribute = $this->processStringForTXT( $merchant_attribute );
733
-
734
  if ( "shipping" === $merchant_attribute && 'bing' == $this->config['provider'] ) {
735
  $merchant_attribute = 'shipping(country:service:price)';
736
  } elseif ( "shipping" === $merchant_attribute ) {
737
  $merchant_attribute = 'shipping(country:region:service:price)';
738
  }
739
-
740
  if ( "tax" === $merchant_attribute ) {
741
  $merchant_attribute = 'tax(country:region:rate:tax_ship)';
742
  }
743
-
744
  $attributeValue = $this->processStringForTXT( $attributeValue );
745
  }
746
-
747
  $this->products[ $this->pi ][ $merchant_attribute ] = $attributeValue;
748
  }
749
  }
750
-
751
  /**
752
  * Process Nested Attributes
753
  *
@@ -762,7 +762,7 @@ class Woo_Feed_Products_v3 {
762
  'product_url' => [ 'products', 'product', 'product_url' ],
763
  ];
764
  }
765
-
766
  /**
767
  * Process Nested Attributes
768
  *
@@ -773,25 +773,25 @@ class Woo_Feed_Products_v3 {
773
  * @since 4.0.5
774
  *
775
  */
776
-
777
  protected function nested_attributes_element( $attribute, $content ) {
778
  $starter = '';
779
  $finisher = '';
780
  $element = '';
781
-
782
  if ( empty( $attribute ) ) {
783
  return $attribute;
784
  }
785
-
786
  $attr_names = $this->feed_nested_attributes();
787
-
788
  foreach ( $attr_names as $key => $value ) {
789
  if ( $key === $attribute ) {
790
  //starter tags element
791
  foreach ( $value as $item_value ) {
792
  $starter .= '<' . strval( $item_value ) . '>';
793
  }
794
-
795
  //finishing tags element
796
  $rev_value = array_reverse( $value );
797
  foreach ( $rev_value as $item_value ) {
@@ -799,12 +799,12 @@ class Woo_Feed_Products_v3 {
799
  }
800
  }
801
  }
802
-
803
  $element = $starter . $content . $finisher;
804
-
805
  return $element;
806
  }
807
-
808
  /**
809
  * Check if current product should be processed for feed
810
  * This should be using by Woo_Feed_Products_v3::get_products()
@@ -819,34 +819,34 @@ class Woo_Feed_Products_v3 {
819
  // Skip for invalid products
820
  if ( ! is_object( $product ) ) {
821
  woo_feed_log_feed_process( $this->config['filename'], 'Skipping Product :: Product data is not a valid WC_Product object.' );
822
-
823
  return true;
824
  }
825
-
826
  // For WP_Query check available product types
827
  if ( 'wp' == $this->queryType && ! in_array( $product->get_type(), $this->product_types, true ) ) {
828
  woo_feed_log_feed_process( $this->config['filename'], sprintf( 'Skipping Product :: Invalid Post/Product Type : %s.', $product->get_type() ) );
829
-
830
  return true;
831
  }
832
-
833
  // Skip orphaned variation
834
  if ( $product->is_type( 'variation' ) && ! $product->get_parent_id() ) {
835
  woo_feed_log_feed_process( $this->config['filename'], sprintf( 'Skipping Product :: Orphaned variation product [id: %s] skipped.', $product->get_id() ) );
836
-
837
  return true;
838
  }
839
-
840
  // Skip for invisible products
841
  if ( ! $product->is_visible() ) {
842
  woo_feed_log_feed_process( $this->config['filename'], 'Skipping Product :: Product is not visible.' );
843
-
844
  return true;
845
  }
846
-
847
  return false;
848
  }
849
-
850
  /**
851
  * Check if current attribute/merchant attribute should be processed for feed
852
  * This should be using by Woo_Feed_Products_v3::get_products()
@@ -862,28 +862,28 @@ class Woo_Feed_Products_v3 {
862
  *
863
  */
864
  protected function exclude_current_attribute( $product, $merchant_attribute, $product_attribute, $feedType = 'xml' ) {
865
-
866
  if ( empty( $merchant_attribute ) ) {
867
  return true;
868
  }
869
-
870
  if (
871
  in_array( $this->config['provider'], array_keys( $this->skipped_merchant_attributes ) ) &&
872
  in_array( $merchant_attribute, $this->skipped_merchant_attributes[ $this->config['provider'] ] )
873
-
874
  ) {
875
  return true;
876
  }
877
-
878
  if ( 'shopping_ads_excluded_country' !== $merchant_attribute && in_array( $merchant_attribute, $this->processed_merchant_attributes ) ) {
879
  return true;
880
  }
881
-
882
  $this->processed_merchant_attributes[] = $merchant_attribute;
883
-
884
  return false;
885
  }
886
-
887
  /**
888
  * Wrapper for substr with <![CDATA[string]]> support
889
  *
@@ -907,10 +907,10 @@ class Woo_Feed_Products_v3 {
907
  $string = substr( $string, $start, $limit );
908
  }
909
  }
910
-
911
  return $string;
912
  }
913
-
914
  /**
915
  * Process feed data according to merchant uncommon requirements like Google
916
  *
@@ -937,10 +937,10 @@ class Woo_Feed_Products_v3 {
937
  $pd = 0;
938
  $up = 0; //Unit Price for facebook
939
  $av = 0; //Additional Variant Attribute for facebook
940
-
941
-
942
  // Format Shipping and Tax data for CSV and TXT feed only for google and facebook
943
-
944
  if ( 'xml' != $this->config['feedType'] && in_array( $this->config['provider'], array(
945
  'google',
946
  'facebook',
@@ -949,14 +949,14 @@ class Woo_Feed_Products_v3 {
949
  'pinterest'
950
  ) ) ) {
951
  foreach ( $merchantAttributes as $key => $value ) {
952
-
953
  if ( ! in_array( $value, $this->google_shipping_tax, true ) ) {
954
  continue;
955
  }
956
-
957
  # Get value by attribute type with prefix & suffix
958
  $output = $this->process_for_merchant_get_value( $productObj, $key );
959
-
960
  if ( 'shipping_country' == $value ) {
961
  $s ++;
962
  $shipping .= $output;
@@ -972,7 +972,7 @@ class Woo_Feed_Products_v3 {
972
  if ( 'shipping_price' == $value ) {
973
  $shipping .= ':' . $output;
974
  }
975
-
976
  if ( 'section_name' == $value ) {
977
  $pd ++;
978
  $product_detail .= $output;
@@ -983,7 +983,7 @@ class Woo_Feed_Products_v3 {
983
  if ( 'attribute_value' == $value ) {
984
  $product_detail .= ':' . $output;
985
  }
986
-
987
  //facebook nested attributes
988
  if ( isset( $this->config['provider'] ) && "facebook" === $this->config['provider'] ) {
989
  if ( 'unit_price_value' == $value ) {
@@ -996,7 +996,7 @@ class Woo_Feed_Products_v3 {
996
  if ( 'unit_price_unit' == $value ) {
997
  $unit_price .= ':' . $output;
998
  }
999
-
1000
  if ( 'additional_variant_label' == $value ) {
1001
  $av ++;
1002
  $additional_variant_attribute .= $output;
@@ -1004,17 +1004,17 @@ class Woo_Feed_Products_v3 {
1004
  if ( 'additional_variant_value' == $value ) {
1005
  $additional_variant_attribute .= ':' . $output;
1006
  }
1007
-
1008
  if ( 0 < $up ) {
1009
  $this->products[ $this->pi ]["unit_price"] = $unit_price;
1010
  }
1011
-
1012
  if ( 0 < $av ) {
1013
  $this->products[ $this->pi ]["additional_variant_attribute"] = $additional_variant_attribute;
1014
  }
1015
  }
1016
-
1017
-
1018
  if ( 'installment_months' == $value ) {
1019
  $ins ++;
1020
  $installment .= $output;
@@ -1022,7 +1022,7 @@ class Woo_Feed_Products_v3 {
1022
  if ( 'installment_amount' == $value ) {
1023
  $installment .= ':' . $output;
1024
  }
1025
-
1026
  if ( 'subscription_period' == $value ) {
1027
  $sub ++;
1028
  $subscription .= $output;
@@ -1034,38 +1034,38 @@ class Woo_Feed_Products_v3 {
1034
  $subscription .= ':' . $output;
1035
  }
1036
  }
1037
-
1038
  if ( 0 < $pd ) {
1039
  $this->products[ $this->pi ]["product detail"] = $product_detail;
1040
  }
1041
-
1042
  if ( 0 < $sub ) {
1043
  $this->products[ $this->pi ]["subscription cost"] = $subscription;
1044
-
1045
  }
1046
-
1047
  if ( 0 < $ins ) {
1048
  $this->products[ $this->pi ]["installment"] = $installment;
1049
  }
1050
  }
1051
-
1052
-
1053
  if ( in_array( $this->config['provider'], array( 'google', 'facebook', 'snapchat', 'bing', 'pinterest' ) ) ) {
1054
-
1055
-
1056
  // Reformat Shipping attributes for google, facebook
1057
  if ( 'xml' == $this->config['feedType'] ) {
1058
  foreach ( $merchantAttributes as $key => $value ) {
1059
-
1060
  if ( ! in_array( $value, $this->google_shipping_tax ) ) {
1061
  continue;
1062
  }
1063
-
1064
-
1065
  # Get value by attribute type with prefix & suffix
1066
  $output = $this->process_for_merchant_get_value( $productObj, $key );
1067
-
1068
-
1069
  if ( 'shipping_country' == $value ) {
1070
  if ( 0 == $s ) {
1071
  $shipping .= '<g:shipping>';
@@ -1083,7 +1083,7 @@ class Woo_Feed_Products_v3 {
1083
  $shipping .= '<g:shipping>';
1084
  }
1085
  }
1086
-
1087
  if ( 'shipping_country' == $value ) {
1088
  $shipping .= '<g:country>' . $output . '</g:country>' . "\n";
1089
  } elseif ( 'shipping_region' == $value ) {
@@ -1125,7 +1125,7 @@ class Woo_Feed_Products_v3 {
1125
  } elseif ( 'subscription_amount' == $value ) {
1126
  $subscription .= '<g:amount>' . $output . '</g:amount>' . "\n";
1127
  }
1128
-
1129
  if ( 'section_name' == $value ) {
1130
  if ( 0 == $pd ) {
1131
  $product_detail .= '<g:product_detail>';
@@ -1143,7 +1143,7 @@ class Woo_Feed_Products_v3 {
1143
  $product_detail .= '<g:product_detail>';
1144
  }
1145
  }
1146
-
1147
  if ( 'section_name' == $value ) {
1148
  $product_detail .= '<g:section_name>' . $output . '</g:section_name>' . "\n";
1149
  } elseif ( 'attribute_name' == $value ) {
@@ -1151,9 +1151,9 @@ class Woo_Feed_Products_v3 {
1151
  } elseif ( 'attribute_value' == $value ) {
1152
  $product_detail .= '<g:attribute_value>' . $output . '</g:attribute_value>' . "\n";
1153
  }
1154
-
1155
  if ( isset( $this->config['provider'] ) && "facebook" === $this->config['provider'] ) {
1156
-
1157
  // unit_price configure
1158
  if ( 'unit_price_value' == $value ) {
1159
  if ( 0 == $up ) {
@@ -1172,7 +1172,7 @@ class Woo_Feed_Products_v3 {
1172
  $unit_price .= '<unit_price>';
1173
  }
1174
  }
1175
-
1176
  if ( 'unit_price_value' == $value ) {
1177
  $unit_price .= '<value>' . $output . '</value>' . "\n";
1178
  } elseif ( 'unit_price_currency' == $value ) {
@@ -1180,7 +1180,7 @@ class Woo_Feed_Products_v3 {
1180
  } elseif ( 'unit_price_unit' == $value ) {
1181
  $unit_price .= '<unit>' . $output . '</unit>' . "\n";
1182
  }
1183
-
1184
  // additional_variant_attribute configure
1185
  if ( 'additional_variant_label' == $value ) {
1186
  if ( 0 == $av ) {
@@ -1199,15 +1199,15 @@ class Woo_Feed_Products_v3 {
1199
  $additional_variant_attribute .= '<additional_variant_attribute>';
1200
  }
1201
  }
1202
-
1203
  if ( 'additional_variant_label' == $value ) {
1204
  $additional_variant_attribute .= '<label>' . $output . '</label>' . "\n";
1205
  } elseif ( 'additional_variant_value' == $value ) {
1206
  $additional_variant_attribute .= '<value>' . $output . '</value>' . "\n";
1207
  }
1208
  }
1209
-
1210
-
1211
  if ( 'installment_months' === $value ) {
1212
  if ( 0 == $ins ) {
1213
  $installment .= '<g:installment>';
@@ -1221,44 +1221,44 @@ class Woo_Feed_Products_v3 {
1221
  $installment .= '<g:amount>' . $output . '</g:amount>' . "\n";
1222
  }
1223
  }
1224
-
1225
  if ( 1 == $pd ) {
1226
  $product_detail .= '</g:product_detail>';
1227
  }
1228
-
1229
  if ( isset( $this->config['provider'] ) && "facebook" === $this->config['provider'] ) {
1230
  if ( 1 == $up ) {
1231
  $unit_price .= '</unit_price>';
1232
  }
1233
-
1234
  if ( 1 == $av ) {
1235
  $additional_variant_attribute .= '</additional_variant_attribute>';
1236
  }
1237
-
1238
  $this->feedBody .= $unit_price;
1239
  $this->feedBody .= $additional_variant_attribute;
1240
  }
1241
-
1242
  if ( 1 == $s ) {
1243
  $shipping .= '</g:shipping>';
1244
  }
1245
  if ( 1 == $t ) {
1246
  $tax .= '</g:tax>';
1247
  }
1248
-
1249
  if ( 1 == $sub ) {
1250
  $subscription .= '</g:subscription_cost>';
1251
  }
1252
-
1253
  if ( 1 == $ins ) {
1254
  $installment .= '</g:installment>';
1255
  }
1256
-
1257
  //$this->feedBody .= $shipping;
1258
  //$this->feedBody .= $tax;
1259
  $this->feedBody .= $product_detail;
1260
  $this->feedBody .= $installment;
1261
-
1262
  if ( $productObj->is_type( 'subscription' ) ||
1263
  $productObj->is_type( 'variable-subscription' ) ||
1264
  $productObj->is_type( 'subscription_variation' ) ) {
@@ -1288,7 +1288,7 @@ class Woo_Feed_Products_v3 {
1288
  $countIdentifier ++;
1289
  }
1290
  }
1291
-
1292
  if ( 'xml' == $this->config['feedType'] ) {
1293
  if ( $countIdentifier >= 2 ) {
1294
  $this->feedBody .= '<g:identifier_exists>yes</g:identifier_exists>';
@@ -1300,7 +1300,7 @@ class Woo_Feed_Products_v3 {
1300
  if ( in_array( $this->config['provider'], array( 'bing', 'pinterest' ) ) ) {
1301
  $identifier_exists = 'identifier_exists';
1302
  }
1303
-
1304
  if ( $countIdentifier >= 2 ) {
1305
  $this->products[ $this->pi ][ $identifier_exists ] = 'yes';
1306
  } else {
@@ -1310,27 +1310,27 @@ class Woo_Feed_Products_v3 {
1310
  }
1311
  }
1312
  }
1313
-
1314
  private function process_for_merchant_get_value( $productObj, $key ) {
1315
  $prefix = $this->config['prefix'][ $key ];
1316
  $suffix = $this->config['suffix'][ $key ];
1317
  $attribute = $this->config['attributes'][ $key ];
1318
  $merchant_attribute = $this->config['mattributes'][ $key ];
1319
-
1320
  if ( 'pattern' == $this->config['type'][ $key ] ) {// Get Pattern value.
1321
  $output = $this->config['default'][ $key ];
1322
  $output = $this->apply_filters_to_attribute_value( $output, $productObj, $attribute, $merchant_attribute );
1323
  } else {
1324
  $output = $this->getAttributeValueByType( $productObj, $attribute, $merchant_attribute );
1325
  }
1326
-
1327
  $output = $this->format_output( $output, $this->config['output_type'], $productObj, $attribute, $merchant_attribute );
1328
-
1329
  $output = $this->process_prefix_suffix( $output, $prefix, $suffix, $attribute = '' );
1330
-
1331
  return $output;
1332
  }
1333
-
1334
  /**
1335
  * Get Query Type Settings
1336
  *
@@ -1339,11 +1339,11 @@ class Woo_Feed_Products_v3 {
1339
  public function get_query_type() {
1340
  return $this->queryType;
1341
  }
1342
-
1343
  public function get_product_types() {
1344
  return $this->product_types;
1345
  }
1346
-
1347
  /**
1348
  * Generate TXT Feed Header
1349
  *
@@ -1358,7 +1358,7 @@ class Woo_Feed_Products_v3 {
1358
  } else {
1359
  $this->delimiter = $this->config['delimiter'];
1360
  }
1361
-
1362
  // Set Enclosure
1363
  if ( ! empty( $this->config['enclosure'] ) ) {
1364
  $this->enclosure = $this->config['enclosure'];
@@ -1372,26 +1372,26 @@ class Woo_Feed_Products_v3 {
1372
  } else {
1373
  $this->enclosure = '';
1374
  }
1375
-
1376
  $eol = PHP_EOL;
1377
  if ( 'trovaprezzi' === $this->config['provider'] ) {
1378
  $eol = '<endrecord>' . PHP_EOL;
1379
  }
1380
-
1381
  $product = $this->products[ $this->pi ];
1382
-
1383
  $headers = array_keys( $product );
1384
-
1385
  $this->feedHeader .= $this->enclosure . implode( "$this->enclosure$this->delimiter$this->enclosure", $headers ) . $this->enclosure . $eol;
1386
-
1387
  if ( 'google' === $this->config['provider'] ) {
1388
  $this->feedHeader = str_replace( $this->google_product_highlights, 'product highlight', $this->feedHeader );
1389
  $this->feedHeader = str_replace( $this->google_additional_image, 'additional image link', $this->feedHeader );
1390
  }
1391
-
1392
  return $this->feedHeader;
1393
  }
1394
-
1395
  /**
1396
  * Generate TXT Feed Body
1397
  *
@@ -1406,10 +1406,10 @@ class Woo_Feed_Products_v3 {
1406
  $eol = '<endrecord>' . PHP_EOL;
1407
  }
1408
  $this->feedBody .= $this->enclosure . implode( "$this->enclosure$this->delimiter$this->enclosure", $productInfo ) . $this->enclosure . $eol;
1409
-
1410
  return $this->feedBody;
1411
  }
1412
-
1413
  /**
1414
  * Generate CSV Feed Header
1415
  *
@@ -1424,7 +1424,7 @@ class Woo_Feed_Products_v3 {
1424
  } else {
1425
  $this->delimiter = $this->config['delimiter'];
1426
  }
1427
-
1428
  // Set Enclosure
1429
  if ( ! empty( $this->config['enclosure'] ) ) {
1430
  $this->enclosure = $this->config['enclosure'];
@@ -1438,19 +1438,19 @@ class Woo_Feed_Products_v3 {
1438
  } else {
1439
  $this->enclosure = '';
1440
  }
1441
-
1442
  $product = $this->products[ $this->pi ];
1443
-
1444
  $this->feedHeader = array_keys( $product );
1445
-
1446
  if ( 'google' === $this->config['provider'] ) {
1447
  $this->feedHeader = str_replace( $this->google_product_highlights, 'product highlight', $this->feedHeader );
1448
  $this->feedHeader = str_replace( $this->google_additional_image, 'additional image link', $this->feedHeader );
1449
  }
1450
-
1451
  return $this->feedHeader;
1452
  }
1453
-
1454
  /**
1455
  * Generate CSV Feed Body
1456
  *
@@ -1460,17 +1460,17 @@ class Woo_Feed_Products_v3 {
1460
  protected function process_csv_feed_body() {
1461
  $product = $this->products[ $this->pi ];
1462
  $this->feedBody[] = array_values( $product );
1463
-
1464
  return $this->feedBody;
1465
  }
1466
-
1467
  protected function process_json_feed_body() {
1468
  $product = $this->products[ $this->pi ];
1469
  $this->feedBody[] = $product;
1470
-
1471
  return $this->feedBody;
1472
  }
1473
-
1474
  protected function process_xml_wrapper() {
1475
  $itemsWrapperClose = explode( ' ', $this->config['itemsWrapper'] );
1476
  $itemsWrapperClose = $itemsWrapperClose[0];
@@ -1480,7 +1480,7 @@ class Woo_Feed_Products_v3 {
1480
  ];
1481
  $this->config['itemWrapper'] = str_replace( ' ', '_', $this->config['itemWrapper'] );
1482
  $this->config['itemsWrapper'] = str_replace( ' ', '_', $this->config['itemsWrapper'] );
1483
-
1484
  if ( file_exists( WOO_FEED_FREE_ADMIN_PATH . 'partials/templates/' . $this->config['provider'] . '.txt' ) ) {
1485
  $txt = file_get_contents( WOO_FEED_FREE_ADMIN_PATH . 'partials/templates/' . $this->config['provider'] . '.txt' );
1486
  $txt = trim( $txt );
@@ -1490,11 +1490,11 @@ class Woo_Feed_Products_v3 {
1490
  $this->xml_wrapper['footer'] = "\n" . trim( $txt[1] );
1491
  }
1492
  }
1493
-
1494
  if ( ! empty( $this->config['extraHeader'] ) ) {
1495
  $this->xml_wrapper['header'] .= PHP_EOL . $this->config['extraHeader'];
1496
  }
1497
-
1498
  // replace template variables.
1499
  $datetime_now = date( 'Y-m-d H:i:s', strtotime( current_time( 'mysql' ) ) ); // {DateTimeNow}
1500
  if ( 'pinterest_rss' === $this->config['provider'] ) { // DATE_RFC822 date format for pinterest rss feed
@@ -1505,14 +1505,14 @@ class Woo_Feed_Products_v3 {
1505
  //$blog_desc = get_bloginfo('description'); // {BlogDescription}
1506
  $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}
1507
  $blog_email = get_bloginfo( 'admin_email' ); // {BlogEmail}
1508
-
1509
  $this->xml_wrapper['header'] = str_replace(
1510
  [ '{DateTimeNow}', '{BlogName}', '{BlogURL}', '{BlogDescription}', '{BlogEmail}' ],
1511
  [ $datetime_now, $blog_name, $blog_url, $blog_desc, $blog_email ],
1512
  $this->xml_wrapper['header']
1513
  );
1514
  }
1515
-
1516
  /**
1517
  * Make XML feed header
1518
  *
@@ -1522,7 +1522,7 @@ class Woo_Feed_Products_v3 {
1522
  protected function process_xml_feed_header() {
1523
  return $this->xml_wrapper['header'];
1524
  }
1525
-
1526
  /**
1527
  * Make XML feed header
1528
  *
@@ -1532,7 +1532,7 @@ class Woo_Feed_Products_v3 {
1532
  protected function process_xml_feed_footer() {
1533
  return $this->xml_wrapper['footer'];
1534
  }
1535
-
1536
  /**
1537
  * Process string for TXT CSV Feed
1538
  *
@@ -1545,7 +1545,7 @@ class Woo_Feed_Products_v3 {
1545
  protected function processStringForTXT( $string ) {
1546
  if ( ! empty( $string ) ) {
1547
  $string = html_entity_decode( $string, ENT_HTML401 | ENT_QUOTES ); // Convert any HTML entities
1548
-
1549
  if ( stristr( $string, '"' ) ) {
1550
  $string = str_replace( '"', '""', $string );
1551
  }
@@ -1554,7 +1554,7 @@ class Woo_Feed_Products_v3 {
1554
  $string = str_replace( "\t", ' ', $string );
1555
  $string = trim( $string );
1556
  $string = stripslashes( $string );
1557
-
1558
  return $string;
1559
  } elseif ( '0' == $string ) {
1560
  return '0';
@@ -1562,7 +1562,7 @@ class Woo_Feed_Products_v3 {
1562
  return '';
1563
  }
1564
  }
1565
-
1566
  /**
1567
  * Process string for CSV
1568
  *
@@ -1578,7 +1578,7 @@ class Woo_Feed_Products_v3 {
1578
  $string = str_replace( "\r", ' ', $string );
1579
  $string = trim( $string );
1580
  $string = stripslashes( $string );
1581
-
1582
  return $string;
1583
  } elseif ( '0' == $string ) {
1584
  return '0';
@@ -1586,7 +1586,7 @@ class Woo_Feed_Products_v3 {
1586
  return '';
1587
  }
1588
  }
1589
-
1590
  /**
1591
  * Get Product Attribute Value by Type
1592
  *
@@ -1598,7 +1598,7 @@ class Woo_Feed_Products_v3 {
1598
  *
1599
  */
1600
  public function getAttributeValueByType( $product, $attribute, $merchant_attribute = '' ) {
1601
-
1602
  if ( method_exists( $this, $attribute ) ) {
1603
  $output = $this->$attribute( $product );
1604
  } elseif ( false !== strpos( $attribute, self::PRODUCT_ACF_FIELDS ) ) {
@@ -1635,17 +1635,17 @@ class Woo_Feed_Products_v3 {
1635
  // return the attribute so multiple attribute can be join with separator to make custom attribute.
1636
  $output = $attribute;
1637
  }
1638
-
1639
  // Json encode if value is an array
1640
  if ( is_array( $output ) ) {
1641
  $output = wp_json_encode( $output );
1642
  }
1643
-
1644
  $output = $this->apply_filters_to_attribute_value( $output, $product, $attribute, $merchant_attribute );
1645
-
1646
  return $output;
1647
  }
1648
-
1649
  /**
1650
  * Apply Filter to Attribute value
1651
  *
@@ -1668,7 +1668,7 @@ class Woo_Feed_Products_v3 {
1668
  *
1669
  */
1670
  $output = apply_filters( 'woo_feed_get_attribute', $output, $product, $this->config, $merchant_attribute );
1671
-
1672
  /**
1673
  * Filter attribute value before return based on attribute name
1674
  *
@@ -1680,7 +1680,7 @@ class Woo_Feed_Products_v3 {
1680
  *
1681
  */
1682
  $output = apply_filters( "woo_feed_get_{$attribute}_attribute", $output, $product, $this->config );
1683
-
1684
  /**
1685
  * Filter attribute value before return based on merchant and attribute name
1686
  *
@@ -1692,11 +1692,11 @@ class Woo_Feed_Products_v3 {
1692
  *
1693
  */
1694
  $output = apply_filters( "woo_feed_get_{$this->config['provider']}_{$attribute}_attribute", $output, $product, $this->config );
1695
-
1696
  return $output;
1697
  }
1698
-
1699
-
1700
  /**
1701
  * Get Product Id
1702
  *
@@ -1708,10 +1708,10 @@ class Woo_Feed_Products_v3 {
1708
  */
1709
  protected function id( $product ) {
1710
  $id = $product->get_id();
1711
-
1712
  return apply_filters( 'woo_feed_filter_product_id', $id, $product, $this->config );
1713
  }
1714
-
1715
  /**
1716
  * Get Product Title
1717
  *
@@ -1723,7 +1723,7 @@ class Woo_Feed_Products_v3 {
1723
  */
1724
  protected function title( $product ) {
1725
  $title = woo_feed_strip_all_tags( $this->remove_short_codes( $product->get_name() ) );
1726
-
1727
  // Add all available variation attributes to variation title.
1728
  if ( $product->is_type( 'variation' ) && ! empty( $product->get_attributes() ) ) {
1729
  $title = $this->parent_title( $product );
@@ -1735,25 +1735,25 @@ class Woo_Feed_Products_v3 {
1735
  }
1736
  $attributes[ $slug ] = $attribute;
1737
  }
1738
-
1739
  // set variation attributes with separator
1740
  if ( isset( $this->config['provider'] ) && 'google' === $this->config['provider'] ) {
1741
  $variation_attributes = implode( ' - ', $attributes );
1742
  } else {
1743
  $variation_attributes = implode( ', ', $attributes );
1744
  }
1745
-
1746
  //get product title with variation attribute
1747
  $get_with_var_attributes = apply_filters( "woo_feed_get_product_title_with_variation_attribute", true, $product, $this->config );
1748
-
1749
  if ( $get_with_var_attributes ) {
1750
  $title .= " - " . $variation_attributes;
1751
  }
1752
  }
1753
-
1754
  return apply_filters( 'woo_feed_filter_product_title', $title, $product, $this->config );
1755
  }
1756
-
1757
  /**
1758
  * Get Parent Product Title
1759
  *
@@ -1770,10 +1770,10 @@ class Woo_Feed_Products_v3 {
1770
  } else {
1771
  $title = $this->title( $product );
1772
  }
1773
-
1774
  return apply_filters( 'woo_feed_filter_product_parent_title', $title, $product, $this->config );
1775
  }
1776
-
1777
  /**
1778
  * Get All in One SEO Canonical URL
1779
  *
@@ -1788,10 +1788,10 @@ class Woo_Feed_Products_v3 {
1788
  $post = AIOSEO\Plugin\Common\Models\Post::getPost( $product->get_id() );
1789
  $aioseop_canonical_url = $post->canonical_url;
1790
  }
1791
-
1792
  return apply_filters( 'woo_feed_filter_product_aioseop_canonical_url', $aioseop_canonical_url, $product, $this->config );
1793
  }
1794
-
1795
  /**
1796
  * Get Yoast Product Title
1797
  *
@@ -1810,18 +1810,18 @@ class Woo_Feed_Products_v3 {
1810
  $title = get_the_title( $product_id );
1811
  }
1812
  $wpseo_titles = get_option( 'wpseo_titles' );
1813
-
1814
  $sep_options = WPSEO_Option_Titles::get_instance()->get_separator_options();
1815
  if ( isset( $wpseo_titles['separator'] ) && isset( $sep_options[ $wpseo_titles['separator'] ] ) ) {
1816
  $sep = $sep_options[ $wpseo_titles['separator'] ];
1817
  } else {
1818
  $sep = '-'; //setting default separator if Admin didn't set it from backed
1819
  }
1820
-
1821
  $site_title = get_bloginfo( 'name' );
1822
-
1823
  $meta_title = $title . ' ' . $sep . ' ' . $site_title;
1824
-
1825
  if ( ! empty( $meta_title ) ) {
1826
  $title = $meta_title;
1827
  }
@@ -1830,10 +1830,10 @@ class Woo_Feed_Products_v3 {
1830
  } else {
1831
  $title = $this->title( $product );
1832
  }
1833
-
1834
  return apply_filters( 'woo_feed_filter_product_yoast_wpseo_title', $title, $product, $this->config );
1835
  }
1836
-
1837
  /**
1838
  * Get Yoast Canonical URL
1839
  *
@@ -1845,10 +1845,10 @@ class Woo_Feed_Products_v3 {
1845
  protected function yoast_canonical_url( $product ) {
1846
  $product_id = woo_feed_parent_product_id( $product );
1847
  $yoast_canonical_url = get_post_meta( $product_id, '_yoast_wpseo_canonical', true );
1848
-
1849
  return apply_filters( 'woo_feed_filter_product_yoast_canonical_url', $yoast_canonical_url, $product, $this->config );
1850
  }
1851
-
1852
  /**
1853
  * Get Rank Math Product Title
1854
  *
@@ -1869,7 +1869,7 @@ class Woo_Feed_Products_v3 {
1869
  $title_format = Helper::get_settings( "titles.pt_product_title" );
1870
  $title_format = $title_format ? $title_format : '%title%';
1871
  $sep = Helper::get_settings( 'titles.title_separator' );
1872
-
1873
  $rank_title = str_replace( '%title%', $product->get_title(), $title_format );
1874
  $rank_title = str_replace( '%sep%', $sep, $rank_title );
1875
  $rank_title = str_replace( '%page%', '', $rank_title );
@@ -1878,10 +1878,10 @@ class Woo_Feed_Products_v3 {
1878
  $rank_title = $title;
1879
  }
1880
  }
1881
-
1882
  return apply_filters( 'woo_feed_filter_product_rank_math_title', $rank_title, $product, $this->config );
1883
  }
1884
-
1885
  /**
1886
  * Get Rank Math Product Description
1887
  *
@@ -1895,34 +1895,34 @@ class Woo_Feed_Products_v3 {
1895
  if ( class_exists( 'RankMath' ) ) {
1896
  $description = get_post_meta( $product->get_id(), 'rank_math_description' );
1897
  $desc_format = Helper::get_settings( "titles.pt_post_description" );
1898
-
1899
  if ( empty( $description ) ) {
1900
  if ( ! empty( $desc_format ) && strpos( (string) $desc_format, 'excerpt' ) !== false ) {
1901
  $description = str_replace( '%excerpt%', get_the_excerpt( $product->get_id() ), $desc_format );
1902
  }
1903
-
1904
  // Get Variation Description
1905
  if ( $product->is_type( 'variation' ) && empty( $description ) ) {
1906
  $parent = wc_get_product( $product->get_parent_id() );
1907
  $description = $parent->get_description();
1908
  }
1909
  }
1910
-
1911
  if ( is_array( $description ) ) {
1912
  $description = reset( $description );
1913
  }
1914
-
1915
  $description = $this->remove_short_codes( $description );
1916
-
1917
  //strip tags and spacial characters
1918
  $strip_description = woo_feed_strip_all_tags( wp_specialchars_decode( $description ) );
1919
-
1920
  $description = ! empty( strlen( $strip_description ) ) && 0 < strlen( $strip_description ) ? $strip_description : $description;
1921
  }
1922
-
1923
  return apply_filters( 'woo_feed_filter_product_rank_math_description', $description, $product, $this->config );
1924
  }
1925
-
1926
  /**
1927
  * Get Rank Math Canonical URL
1928
  *
@@ -1933,25 +1933,25 @@ class Woo_Feed_Products_v3 {
1933
  */
1934
  protected function rank_math_canonical_url( $product ) {
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
  *
@@ -1964,16 +1964,16 @@ class Woo_Feed_Products_v3 {
1964
  protected function _aioseop_title( $product ) {
1965
  $title = '';
1966
  if ( is_plugin_active( 'all-in-one-seo-pack/all_in_one_seo_pack.php' ) && class_exists( 'AIOSEO\Plugin\Common\Models\Post' ) ) {
1967
-
1968
  $post = AIOSEO\Plugin\Common\Models\Post::getPost( $product->get_id() );
1969
  $title = ! empty( $post->title ) ? $post->title : aioseo()->meta->title->getPostTypeTitle( 'product' );
1970
  }
1971
-
1972
  $title = ! empty( $title ) ? $title : $this->title( $product );
1973
-
1974
  return apply_filters( 'woo_feed_filter_product_aioseop_title', $title, $product, $this->config );
1975
  }
1976
-
1977
  /**
1978
  * Get Product Description
1979
  *
@@ -1986,11 +1986,11 @@ class Woo_Feed_Products_v3 {
1986
  */
1987
  protected function description( $product ) {
1988
  $description = $product->get_description();
1989
-
1990
  // Get Variation Description
1991
  if ( $product->is_type( 'variation' ) && empty( $description ) ) {
1992
  $parent = wc_get_product( $product->get_parent_id() );
1993
-
1994
  if ( is_object( $parent ) ) {
1995
  $description = $parent->get_description();
1996
  } else {
@@ -1998,7 +1998,7 @@ class Woo_Feed_Products_v3 {
1998
  }
1999
  }
2000
  $description = $this->remove_short_codes( $description );
2001
-
2002
  // Add variations attributes after description to prevent Facebook error
2003
  if ( 'facebook' == $this->config['provider'] && $product->is_type( 'variation' ) ) {
2004
  $variationInfo = explode( '-', $product->get_name() );
@@ -2009,15 +2009,15 @@ class Woo_Feed_Products_v3 {
2009
  }
2010
  $description .= ' ' . $extension;
2011
  }
2012
-
2013
  //strip tags and spacial characters
2014
  $strip_description = woo_feed_strip_all_tags( wp_specialchars_decode( $description ) );
2015
-
2016
  $description = ! empty( strlen( $strip_description ) ) && 0 < strlen( $strip_description ) ? $strip_description : $description;
2017
-
2018
  return apply_filters( 'woo_feed_filter_product_description', $description, $product, $this->config );
2019
  }
2020
-
2021
  /**
2022
  * Get Product Description (with HTML)
2023
  *
@@ -2029,14 +2029,14 @@ class Woo_Feed_Products_v3 {
2029
  */
2030
  protected function description_with_html( $product ) {
2031
  $description = $product->get_description();
2032
-
2033
  // Get Variation Description
2034
  if ( $product->is_type( 'variation' ) && empty( $description ) ) {
2035
  $parent = wc_get_product( $product->get_parent_id() );
2036
  $description = $parent->get_description();
2037
  }
2038
  $description = $this->remove_short_codes( $description );
2039
-
2040
  // Add variations attributes after description to prevent Facebook error
2041
  if ( 'facebook' === $this->config['provider'] && $product->is_type( 'variation' ) ) {
2042
  $variationInfo = explode( '-', $product->get_name() );
@@ -2047,13 +2047,13 @@ class Woo_Feed_Products_v3 {
2047
  }
2048
  $description .= ' ' . $extension;
2049
  }
2050
-
2051
  //remove spacial characters
2052
  $strip_description = wp_check_invalid_utf8( wp_specialchars_decode( $description ), true );
2053
-
2054
  return apply_filters( 'woo_feed_filter_product_description_with_html', $description, $product, $this->config );
2055
  }
2056
-
2057
  /**
2058
  * Get Yoast Product Description
2059
  *
@@ -2072,14 +2072,14 @@ class Woo_Feed_Products_v3 {
2072
  } else {
2073
  $description = YoastSEO()->meta->for_post( $product_id )->description;
2074
  }
2075
-
2076
  if ( empty( $description ) ) {
2077
  $description = $this->description( $product );
2078
  }
2079
-
2080
  return apply_filters( 'woo_feed_filter_product_yoast_wpseo_metadesc', $description, $product, $this->config );
2081
  }
2082
-
2083
  /**
2084
  * Get All In One Product Description
2085
  *
@@ -2091,20 +2091,20 @@ class Woo_Feed_Products_v3 {
2091
  */
2092
  protected function _aioseop_description( $product ) {
2093
  $description = '';
2094
-
2095
  if ( is_plugin_active( 'all-in-one-seo-pack/all_in_one_seo_pack.php' ) && class_exists( 'AIOSEO\Plugin\Common\Models\Post' ) ) {
2096
-
2097
  $post = AIOSEO\Plugin\Common\Models\Post::getPost( $product->get_id() );
2098
  $description = ! empty( $post->description ) ? $post->description : aioseo()->meta->description->getPostTypeDescription( 'product' );
2099
  }
2100
-
2101
  if ( empty( $description ) ) {
2102
  $description = $this->description( $product );
2103
  }
2104
-
2105
  return apply_filters( 'woo_feed_filter_product_aioseop_description', $description, $product, $this->config );
2106
  }
2107
-
2108
  /**
2109
  * Get Product Short Description
2110
  *
@@ -2116,23 +2116,23 @@ class Woo_Feed_Products_v3 {
2116
  */
2117
  protected function short_description( $product ) {
2118
  $short_description = $product->get_short_description();
2119
-
2120
  // Get Variation Short Description
2121
  if ( $product->is_type( 'variation' ) && empty( $short_description ) ) {
2122
  $parent = wc_get_product( $product->get_parent_id() );
2123
  $short_description = $parent->get_short_description();
2124
  }
2125
-
2126
-
2127
  $short_description = $this->remove_short_codes( $short_description );
2128
-
2129
  //strip tags and spacial characters
2130
  $short_description = woo_feed_strip_all_tags( wp_specialchars_decode( $short_description ) );
2131
-
2132
  return apply_filters( 'woo_feed_filter_product_short_description', $short_description, $product, $this->config );
2133
  }
2134
-
2135
-
2136
  /**
2137
  * At First convert Short Codes and then Remove failed Short Codes from String
2138
  *
@@ -2146,19 +2146,19 @@ class Woo_Feed_Products_v3 {
2146
  if ( $content == '' ) {
2147
  return '';
2148
  }
2149
-
2150
  $content = do_shortcode( $content );
2151
-
2152
  $content = woo_feed_stripInvalidXml( $content );
2153
-
2154
  // Covers all kinds of shortcodes
2155
  $expression = '/\[\/*[a-zA-Z1-90_| -=\'"\{\}]*\/*\]/m';
2156
-
2157
  $content = preg_replace( $expression, '', $content );
2158
-
2159
  return strip_shortcodes( $content );
2160
  }
2161
-
2162
  /*
2163
  * Retrieves product's parent category
2164
  *
@@ -2172,18 +2172,18 @@ class Woo_Feed_Products_v3 {
2172
  if ( empty( $parent_category_memo ) ) {
2173
  $parent_category_memo = [];
2174
  }
2175
-
2176
  $id = $product->get_id();
2177
  if ( $product->is_type( 'variation' ) ) {
2178
  $id = $product->get_parent_id();
2179
  }
2180
-
2181
  $taxonomy = 'product_cat';
2182
  $categories = wp_get_post_terms( $id, $taxonomy );
2183
  $child_category = $categories[ count( $categories ) - 1 ]; // Last selected category
2184
-
2185
  $parent_category = '';
2186
-
2187
  // Memoization for faster parent retrieval
2188
  if (
2189
  isset( $parent_category_memo[ $child_category->term_id ] )
@@ -2194,7 +2194,7 @@ class Woo_Feed_Products_v3 {
2194
  $parent_category = woo_feed_parent_category( $child_category, $taxonomy );
2195
  $parent_category_memo[ $child_category->term_id ] = $parent_category->term_id;
2196
  }
2197
-
2198
  // Yoast SEO primary term fetching
2199
  if ( class_exists( 'WPSEO_Primary_Term' ) ) {
2200
  $wpseo_primary_term = new WPSEO_Primary_Term( $taxonomy, $id );
@@ -2203,10 +2203,10 @@ class Woo_Feed_Products_v3 {
2203
  $parent_category = get_term_by( 'term_id', $parent_category_id, $taxonomy );
2204
  }
2205
  }
2206
-
2207
  return $parent_category;
2208
  }
2209
-
2210
  /**
2211
  * Get Product Parent/Main Category
2212
  *
@@ -2223,10 +2223,10 @@ class Woo_Feed_Products_v3 {
2223
  $full_category_array = explode( $separator, $full_category );
2224
  $parent_category = $full_category_array[0];
2225
  }
2226
-
2227
  return apply_filters( 'woo_feed_filter_product_primary_category', $parent_category, $product, $this->config );
2228
  }
2229
-
2230
  /**
2231
  * Get Product Parent/Main Category ID
2232
  *
@@ -2244,10 +2244,10 @@ class Woo_Feed_Products_v3 {
2244
  $parent_category_obj = get_term_by( 'name', $full_category_array[0], 'product_cat' );
2245
  $parent_category_id = isset( $parent_category_obj->term_id ) ? $parent_category_obj->term_id : "";
2246
  }
2247
-
2248
  return apply_filters( 'woo_feed_filter_product_primary_category_id', $parent_category_id, $product, $this->config );
2249
  }
2250
-
2251
  /**
2252
  * Get Product Child Category
2253
  *
@@ -2263,10 +2263,10 @@ class Woo_Feed_Products_v3 {
2263
  $full_category_array = explode( $separator, $full_category );
2264
  $child_category = end( $full_category_array );
2265
  }
2266
-
2267
  return apply_filters( 'woo_feed_filter_product_child_category', $child_category, $product, $this->config );
2268
  }
2269
-
2270
  /**
2271
  * Get Product Child Category ID
2272
  *
@@ -2283,10 +2283,10 @@ class Woo_Feed_Products_v3 {
2283
  $child_category_obj = get_term_by( 'name', end( $full_category_array ), 'product_cat' );
2284
  $child_category_id = isset( $child_category_obj->term_id ) ? $child_category_obj->term_id : "";
2285
  }
2286
-
2287
  return apply_filters( 'woo_feed_filter_product_child_category_id', $child_category_id, $product, $this->config );
2288
  }
2289
-
2290
  /**
2291
  * Get Product Categories
2292
  *
@@ -2301,25 +2301,35 @@ class Woo_Feed_Products_v3 {
2301
  if ( $product->is_type( 'variation' ) ) {
2302
  $id = $product->get_parent_id();
2303
  }
2304
-
2305
  $separator = apply_filters( 'woo_feed_product_type_separator', ' > ', $this->config, $product );
2306
-
2307
  $product_type = woo_feed_strip_all_tags( wc_get_product_category_list( $id, $separator ) );
2308
-
2309
  $product_categories = '';
2310
  $term_list = get_the_terms( $id, 'product_cat' );
2311
-
2312
  if ( is_array( $term_list ) ) {
2313
  $col = array_column( $term_list, "term_id" );
2314
  array_multisort( $col, SORT_ASC, $term_list );
2315
  $term_list = array_column( $term_list, "name" );
2316
  $product_categories = implode( $separator, $term_list );
2317
  }
2318
-
2319
-
2320
  return apply_filters( 'woo_feed_filter_product_local_category', $product_categories, $product, $this->config );
2321
  }
2322
-
 
 
 
 
 
 
 
 
 
 
2323
  /**
2324
  * Get Product Full Categories with unselected category parent
2325
  *
@@ -2337,12 +2347,12 @@ class Woo_Feed_Products_v3 {
2337
  // $separator = apply_filters('woo_feed_product_type_separator', '>', $this->config, $product);
2338
  //
2339
  // $product_type = woo_feed_get_terms_list_hierarchical_order($id);
2340
-
2341
  $product_type = $this->product_type( $product );
2342
-
2343
  return apply_filters( 'woo_feed_filter_product_local_category', $product_type, $product, $this->config );
2344
  }
2345
-
2346
  /**
2347
  * Get Product URL
2348
  *
@@ -2353,14 +2363,14 @@ class Woo_Feed_Products_v3 {
2353
  *
2354
  */
2355
  protected function link( $product ) {
2356
-
2357
  $link = $product->get_permalink();
2358
-
2359
  $link = $this->add_utm_tracker( $link );
2360
-
2361
  return apply_filters( 'woo_feed_filter_product_link', $link, $product, $this->config );
2362
  }
2363
-
2364
  /**
2365
  * Adding UTM Tracker Query Arguments to URL
2366
  *
@@ -2370,11 +2380,11 @@ class Woo_Feed_Products_v3 {
2370
  * @since 4.4.26
2371
  */
2372
  protected function add_utm_tracker( $url ) {
2373
-
2374
  $utm = $this->config['campaign_parameters'];
2375
-
2376
  if ( ! empty( $utm['utm_source'] ) && ! empty( $utm['utm_medium'] ) && ! empty( $utm['utm_campaign'] ) ) {
2377
-
2378
  $utm = [
2379
  'utm_source' => str_replace( ' ', '+', $utm['utm_source'] ),
2380
  'utm_medium' => str_replace( ' ', '+', $utm['utm_medium'] ),
@@ -2382,14 +2392,14 @@ class Woo_Feed_Products_v3 {
2382
  'utm_term' => str_replace( ' ', '+', $utm['utm_term'] ),
2383
  'utm_content' => str_replace( ' ', '+', $utm['utm_content'] ),
2384
  ];
2385
-
2386
  $url = add_query_arg( array_filter( $utm ), $url );
2387
-
2388
  }
2389
-
2390
  return $url;
2391
  }
2392
-
2393
  /**
2394
  * Get Parent Product URL
2395
  *
@@ -2406,10 +2416,10 @@ class Woo_Feed_Products_v3 {
2406
  } else {
2407
  $link = $this->link( $product );
2408
  }
2409
-
2410
  return apply_filters( 'woo_feed_filter_product_parent_link', $link, $product, $this->config );
2411
  }
2412
-
2413
  /**
2414
  * Get Canonical Link
2415
  *
@@ -2424,10 +2434,10 @@ class Woo_Feed_Products_v3 {
2424
  } else {
2425
  $canonical_link = $product->get_permalink();
2426
  }
2427
-
2428
  return apply_filters( 'woo_feed_filter_product_canonical_link', $canonical_link, $product, $this->config );
2429
  }
2430
-
2431
  /**
2432
  * Get External Product URL
2433
  *
@@ -2448,7 +2458,7 @@ class Woo_Feed_Products_v3 {
2448
  'utm_term' => str_replace( ' ', '+', $utm['utm_term'] ),
2449
  'utm_content' => str_replace( ' ', '+', $utm['utm_content'] ),
2450
  ];
2451
-
2452
  return add_query_arg( array_filter( $utm ), $product->get_product_url() );
2453
  } else {
2454
  $ex_link = $product->get_product_url();
@@ -2456,10 +2466,10 @@ class Woo_Feed_Products_v3 {
2456
  } else {
2457
  $ex_link = '';
2458
  }
2459
-
2460
  return apply_filters( 'woo_feed_filter_product_ex_link', $ex_link, $product, $this->config );
2461
  }
2462
-
2463
  /**
2464
  * Get Product Image
2465
  *
@@ -2485,10 +2495,10 @@ class Woo_Feed_Products_v3 {
2485
  $getImage = wp_get_attachment_image_src( get_post_thumbnail_id( $product->get_id() ), 'single-post-thumbnail' );
2486
  $image = isset( $getImage[0] ) ? woo_feed_get_formatted_url( $getImage[0] ) : '';
2487
  }
2488
-
2489
  return apply_filters( 'woo_feed_filter_product_image', $image, $product, $this->config );
2490
  }
2491
-
2492
  /**
2493
  * Get Product Featured Image. For product variations it will return the variable product image.
2494
  *
@@ -2505,13 +2515,13 @@ class Woo_Feed_Products_v3 {
2505
  } else {
2506
  $id = $product->get_id();
2507
  }
2508
-
2509
  $getImage = wp_get_attachment_image_src( get_post_thumbnail_id( $id ), 'single-post-thumbnail' );
2510
  $image = isset( $getImage[0] ) ? woo_feed_get_formatted_url( $getImage[0] ) : '';
2511
-
2512
  return apply_filters( 'woo_feed_filter_product_feature_image', $image, $product, $this->config );
2513
  }
2514
-
2515
  /**
2516
  * Get Comma Separated Product Images
2517
  *
@@ -2528,7 +2538,7 @@ class Woo_Feed_Products_v3 {
2528
  protected function images( $product, $additionalImg = '' ) {
2529
  $imgUrls = $this->get_product_gallery( $product );
2530
  $separator = ',';
2531
-
2532
  // Return Specific Additional Image URL
2533
  if ( '' !== $additionalImg ) {
2534
  if ( array_key_exists( $additionalImg, $imgUrls ) ) {
@@ -2540,13 +2550,13 @@ class Woo_Feed_Products_v3 {
2540
  if ( isset( $this->config['provider'] ) && "idealo" === $this->config['provider'] ) {
2541
  $separator = ';';
2542
  }
2543
-
2544
  $images = implode( $separator, array_filter( $imgUrls ) );
2545
  }
2546
-
2547
  return apply_filters( 'woo_feed_filter_product_images', $images, $product, $this->config );
2548
  }
2549
-
2550
  /**
2551
  * Get Product Gallery Items (URL) array.
2552
  * This can contains empty array values
@@ -2559,7 +2569,7 @@ class Woo_Feed_Products_v3 {
2559
  protected function get_product_gallery( $product ) {
2560
  $imgUrls = [];
2561
  $attachmentIds = [];
2562
-
2563
  if ( $product->is_type( 'variation' ) ) {
2564
  if ( class_exists( 'Woo_Variation_Gallery' ) ) {
2565
  /**
@@ -2594,7 +2604,7 @@ class Woo_Feed_Products_v3 {
2594
  */
2595
  $var_id = $product->get_id();
2596
  $parent_id = $product->get_parent_id();
2597
-
2598
  $variation_obj = get_post_meta( $parent_id, 'woodmart_variation_gallery_data', true );
2599
  if ( isset( $variation_obj ) && isset( $variation_obj[ $var_id ] ) ) {
2600
  $attachmentIds = explode( ',', $variation_obj[ $var_id ] );
@@ -2608,7 +2618,7 @@ class Woo_Feed_Products_v3 {
2608
  $attachmentIds = wc_get_product( $product->get_parent_id() )->get_gallery_image_ids();
2609
  }
2610
  }
2611
-
2612
  /**
2613
  * Get Variable Product Gallery Image ids if Product is not a variation
2614
  * or variation does not have any gallery images
@@ -2616,7 +2626,7 @@ class Woo_Feed_Products_v3 {
2616
  if ( empty( $attachmentIds ) ) {
2617
  $attachmentIds = $product->get_gallery_image_ids();
2618
  }
2619
-
2620
  if ( $attachmentIds && is_array( $attachmentIds ) ) {
2621
  $mKey = 1;
2622
  foreach ( $attachmentIds as $attachmentId ) {
@@ -2624,10 +2634,10 @@ class Woo_Feed_Products_v3 {
2624
  $mKey ++;
2625
  }
2626
  }
2627
-
2628
  return $imgUrls;
2629
  }
2630
-
2631
  /**
2632
  * Get Product Condition
2633
  *
@@ -2640,7 +2650,7 @@ class Woo_Feed_Products_v3 {
2640
  protected function condition( $product ) {
2641
  return apply_filters( 'woo_feed_product_condition', 'new', $product );
2642
  }
2643
-
2644
  /**
2645
  * Get Product Type
2646
  *
@@ -2653,7 +2663,7 @@ class Woo_Feed_Products_v3 {
2653
  protected function type( $product ) {
2654
  return apply_filters( 'woo_feed_filter_product_type', $product->get_type(), $product, $this->config );
2655
  }
2656
-
2657
  /**
2658
  * Get Product is a bundle product or not
2659
  *
@@ -2669,10 +2679,10 @@ class Woo_Feed_Products_v3 {
2669
  } else {
2670
  $is_bundle = 'no';
2671
  }
2672
-
2673
  return apply_filters( 'woo_feed_filter_product_is_bundle', $is_bundle, $product, $this->config );
2674
  }
2675
-
2676
  /**
2677
  * Get Product is a multi-pack product or not
2678
  *
@@ -2687,10 +2697,10 @@ class Woo_Feed_Products_v3 {
2687
  if ( $product->is_type( 'grouped' ) ) {
2688
  $multi_pack = ( ! empty( $product->get_children() ) ) ? count( $product->get_children() ) : '';
2689
  }
2690
-
2691
  return $multi_pack;
2692
  }
2693
-
2694
  /**
2695
  * Get Product visibility status
2696
  *
@@ -2703,7 +2713,7 @@ class Woo_Feed_Products_v3 {
2703
  protected function visibility( $product ) {
2704
  return apply_filters( 'woo_feed_filter_product_visibility', $product->get_catalog_visibility(), $product, $this->config );
2705
  }
2706
-
2707
  /**
2708
  * Get Product Total Rating
2709
  *
@@ -2716,7 +2726,7 @@ class Woo_Feed_Products_v3 {
2716
  protected function rating_total( $product ) {
2717
  return apply_filters( 'woo_feed_filter_product_rating_total', $product->get_rating_count(), $product, $this->config );
2718
  }
2719
-
2720
  /**
2721
  * Get Product average rating
2722
  *
@@ -2729,7 +2739,7 @@ class Woo_Feed_Products_v3 {
2729
  protected function rating_average( $product ) {
2730
  return apply_filters( 'woo_feed_filter_product_rating_average', $product->get_average_rating(), $product, $this->config );
2731
  }
2732
-
2733
  /**
2734
  * Get Product tags
2735
  *
@@ -2744,7 +2754,7 @@ class Woo_Feed_Products_v3 {
2744
  if ( $product->is_type( 'variation' ) ) {
2745
  $id = $product->get_parent_id();
2746
  }
2747
-
2748
  /**
2749
  * Separator for multiple tags
2750
  *
@@ -2755,12 +2765,12 @@ class Woo_Feed_Products_v3 {
2755
  * @since 3.4.3
2756
  */
2757
  $separator = apply_filters( 'woo_feed_tags_separator', ',', $this->config, $product );
2758
-
2759
  $tags = woo_feed_strip_all_tags( get_the_term_list( $id, 'product_tag', '', $separator, '' ) );
2760
-
2761
  return apply_filters( 'woo_feed_filter_product_tags', $tags, $product, $this->config );
2762
  }
2763
-
2764
  /**
2765
  * Get Product Parent Id
2766
  *
@@ -2775,10 +2785,10 @@ class Woo_Feed_Products_v3 {
2775
  if ( $product->is_type( 'variation' ) ) {
2776
  $id = $product->get_parent_id();
2777
  }
2778
-
2779
  return apply_filters( 'woo_feed_filter_product_item_group_id', $id, $product, $this->config );
2780
  }
2781
-
2782
  /**
2783
  * Get Product SKU
2784
  *
@@ -2791,7 +2801,7 @@ class Woo_Feed_Products_v3 {
2791
  protected function sku( $product ) {
2792
  return apply_filters( 'woo_feed_filter_product_sku', $product->get_sku(), $product, $this->config );
2793
  }
2794
-
2795
  /**
2796
  * Get Product SKU ID. It should come with after merging of sku and product id with '_' sign.
2797
  *
@@ -2804,10 +2814,10 @@ class Woo_Feed_Products_v3 {
2804
  protected function sku_id( $product ) {
2805
  $sku = ! empty( $product->get_sku() ) ? $product->get_sku() . '_' : '';
2806
  $sku_id = $sku . $product->get_id();
2807
-
2808
  return apply_filters( 'woo_feed_filter_product_sku_id', $sku_id, $product, $this->config );
2809
  }
2810
-
2811
  /**
2812
  * Get Product Parent SKU
2813
  *
@@ -2821,15 +2831,15 @@ class Woo_Feed_Products_v3 {
2821
  if ( $product->is_type( 'variation' ) ) {
2822
  $id = $product->get_parent_id();
2823
  $parent = wc_get_product( $id );
2824
-
2825
  $parent_sku = $parent->get_sku();
2826
  } else {
2827
  $parent_sku = $product->get_sku();
2828
  }
2829
-
2830
  return apply_filters( 'woo_feed_filter_product_parent_sku', $parent_sku, $product, $this->config );
2831
  }
2832
-
2833
  /**
2834
  * Get Product Availability Status
2835
  *
@@ -2848,16 +2858,16 @@ class Woo_Feed_Products_v3 {
2848
  } elseif ( 'onbackorder' == $status ) {
2849
  $status = 'on backorder';
2850
  }
2851
-
2852
  // set (_) as separator for google merchant
2853
  if ( isset( $this->config['provider'] ) && 'google' === $this->config['provider'] ) {
2854
  $status = explode( ' ', $status );
2855
  $status = implode( '_', $status );
2856
  }
2857
-
2858
  return apply_filters( 'woo_feed_filter_product_availability', $status, $product, $this->config );
2859
  }
2860
-
2861
  /**
2862
  * Get Product Availability Date
2863
  *
@@ -2869,25 +2879,25 @@ class Woo_Feed_Products_v3 {
2869
  * @author Ohidul Islam
2870
  */
2871
  protected function availability_date( $product ) {
2872
-
2873
  $feed_settings = get_option( 'woo_feed_settings' );
2874
-
2875
  $availability_date_settings = isset( $feed_settings['woo_feed_identifier']['availability_date'] )
2876
  ? $feed_settings['woo_feed_identifier']['availability_date']
2877
  : 'enable';
2878
-
2879
  if ( $product->get_stock_status() !== 'onbackorder' || $availability_date_settings === 'disable' ) {
2880
  return '';
2881
  }
2882
-
2883
  $meta_field_name = 'woo_feed_availability_date';
2884
-
2885
  if ( $product->is_type( 'variation' ) ) {
2886
  $meta_field_name .= '_var';
2887
  }
2888
-
2889
  $availability_date = get_post_meta( $product->get_id(), $meta_field_name, true );
2890
-
2891
  if ( '' !== $availability_date && in_array( $this->config['provider'], [
2892
  'google',
2893
  'facebook',
@@ -2897,10 +2907,10 @@ class Woo_Feed_Products_v3 {
2897
  ], true ) ) {
2898
  $availability_date = gmdate( 'c', strtotime( $availability_date ) );
2899
  }
2900
-
2901
  return apply_filters( 'woo_feed_filter_product_availability_date', $availability_date, $product, $this->config );
2902
  }
2903
-
2904
  /**
2905
  * Get Product Add to Cart Link
2906
  *
@@ -2913,12 +2923,12 @@ class Woo_Feed_Products_v3 {
2913
  protected function add_to_cart_link( $product ) {
2914
  $url = $this->link( $product );
2915
  $suffix = 'add-to-cart=' . $product->get_id();
2916
-
2917
  $add_to_cart_link = woo_feed_make_url_with_parameter( $url, $suffix );
2918
-
2919
  return apply_filters( 'woo_feed_filter_product_add_to_cart_link', $add_to_cart_link, $product, $this->config );
2920
  }
2921
-
2922
  /**
2923
  * Get Product Quantity
2924
  *
@@ -2931,12 +2941,12 @@ class Woo_Feed_Products_v3 {
2931
  protected function quantity( $product ) {
2932
  $quantity = $product->get_stock_quantity();
2933
  $status = $product->get_stock_status();
2934
-
2935
  //when product is outofstock and it's quantity is empty, set quantity to 0
2936
  if ( 'outofstock' == $status && empty( $quantity ) ) {
2937
  $quantity = 0;
2938
  }
2939
-
2940
  if ( $product->is_type( 'variable' ) && $product->has_child() ) {
2941
  $visible_children = $product->get_visible_children();
2942
  $qty = array();
@@ -2944,7 +2954,7 @@ class Woo_Feed_Products_v3 {
2944
  $childQty = get_post_meta( $child, '_stock', true );
2945
  $qty[] = (int) $childQty + 0;
2946
  }
2947
-
2948
  if ( isset( $this->config['variable_quantity'] ) ) {
2949
  $vaQty = $this->config['variable_quantity'];
2950
  if ( 'max' == $vaQty ) {
@@ -2956,14 +2966,14 @@ class Woo_Feed_Products_v3 {
2956
  } elseif ( 'first' == $vaQty ) {
2957
  $quantity = ( (int) $qty[0] );
2958
  }
2959
-
2960
  $quantity = array_sum( $qty );
2961
  }
2962
  }
2963
-
2964
  return apply_filters( 'woo_feed_filter_product_quantity', $quantity, $product, $this->config );
2965
  }
2966
-
2967
  /**
2968
  * Get Product Currency
2969
  *
@@ -2975,10 +2985,10 @@ class Woo_Feed_Products_v3 {
2975
  */
2976
  protected function currency( $product ) {
2977
  $quantity = get_option( 'woocommerce_currency' );
2978
-
2979
  return apply_filters( 'woo_feed_filter_product_currency', $quantity, $product, $this->config );
2980
  }
2981
-
2982
  /**
2983
  * Get Store currency code.
2984
  *
@@ -2991,7 +3001,7 @@ class Woo_Feed_Products_v3 {
2991
  protected function store_currency( $product ) {
2992
  return get_woocommerce_currency();
2993
  }
2994
-
2995
  /**
2996
  * Get Product Sale Price Start Date
2997
  *
@@ -3008,10 +3018,10 @@ class Woo_Feed_Products_v3 {
3008
  } else {
3009
  $sale_price_sdate = '';
3010
  }
3011
-
3012
  return apply_filters( 'woo_feed_filter_product_sale_price_sdate', $sale_price_sdate, $product, $this->config );
3013
  }
3014
-
3015
  /**
3016
  * Get Product Sale Price End Date
3017
  *
@@ -3028,10 +3038,10 @@ class Woo_Feed_Products_v3 {
3028
  } else {
3029
  $sale_price_edate = "";
3030
  }
3031
-
3032
  return apply_filters( 'woo_feed_filter_product_sale_price_edate', $sale_price_edate, $product, $this->config );
3033
  }
3034
-
3035
  /**
3036
  * Get feed currency
3037
  *
@@ -3042,10 +3052,10 @@ class Woo_Feed_Products_v3 {
3042
  if ( isset( $this->config['feedCurrency'] ) ) {
3043
  $currency = $this->config['feedCurrency'];
3044
  }
3045
-
3046
  return $currency;
3047
  }
3048
-
3049
  /**
3050
  * Get Product Price by default WooCommerce Price Type (regular_price|price|sale_price).
3051
  *
@@ -3059,7 +3069,7 @@ class Woo_Feed_Products_v3 {
3059
  * @author Ohidul Islam
3060
  */
3061
  protected function get_price_by_price_type( $product, $price_type, $tax ) {
3062
-
3063
  if ( 'regular_price' === $price_type ) {
3064
  $price = $product->get_regular_price();
3065
  } elseif ( 'price' === $price_type ) {
@@ -3067,20 +3077,20 @@ class Woo_Feed_Products_v3 {
3067
  } else {
3068
  $price = $product->get_sale_price();
3069
  }
3070
-
3071
  // Get WooCommerce Multi language Price by Currency.
3072
  $price = apply_filters( 'woo_feed_wcml_price',
3073
  $price, $product->get_id(), $this->get_feed_currency(), '_' . $price_type
3074
  );
3075
-
3076
  // Get Price with tax
3077
  if ( true === $tax ) {
3078
  $price = woo_feed_get_price_with_tax( $price, $product );
3079
  }
3080
-
3081
  return $price;
3082
  }
3083
-
3084
  /**
3085
  * Get Product Price by Product Type.
3086
  *
@@ -3110,10 +3120,10 @@ class Woo_Feed_Products_v3 {
3110
  } else {
3111
  $price = $this->get_price_by_price_type( $product, $price_type, $tax );
3112
  }
3113
-
3114
  return $price > 0 ? $price : '';
3115
  }
3116
-
3117
  /**
3118
  * Get Product Regular Price
3119
  *
@@ -3124,12 +3134,12 @@ class Woo_Feed_Products_v3 {
3124
  *
3125
  */
3126
  protected function price( $product ) {
3127
-
3128
  $regular_price = $this->get_price_by_product_type( $product, 'regular_price' );
3129
-
3130
  return apply_filters( 'woo_feed_filter_product_price', $regular_price, $product, $this->config, false );
3131
  }
3132
-
3133
  /**
3134
  * Get Product Price
3135
  *
@@ -3140,12 +3150,12 @@ class Woo_Feed_Products_v3 {
3140
  *
3141
  */
3142
  protected function current_price( $product ) {
3143
-
3144
  $price = $this->get_price_by_product_type( $product, 'price' );
3145
-
3146
  return apply_filters( 'woo_feed_filter_product_regular_price', $price, $product, $this->config, false );
3147
  }
3148
-
3149
  /**
3150
  * Get Product Sale Price
3151
  *
@@ -3156,12 +3166,12 @@ class Woo_Feed_Products_v3 {
3156
  *
3157
  */
3158
  protected function sale_price( $product ) {
3159
-
3160
  $sale_price = $this->get_price_by_product_type( $product, 'sale_price' );
3161
-
3162
  return apply_filters( 'woo_feed_filter_product_sale_price', $sale_price, $product, $this->config, false );
3163
  }
3164
-
3165
  /**
3166
  * Get Product Regular Price with Tax
3167
  *
@@ -3172,12 +3182,12 @@ class Woo_Feed_Products_v3 {
3172
  *
3173
  */
3174
  protected function price_with_tax( $product ) {
3175
-
3176
  $regular_price_with_tax = $this->get_price_by_product_type( $product, 'regular_price', true );
3177
-
3178
  return apply_filters( 'woo_feed_filter_product_price_with_tax', $regular_price_with_tax, $product, $this->config, true );
3179
  }
3180
-
3181
  /**
3182
  * Get Product Regular Price with Tax
3183
  *
@@ -3188,12 +3198,12 @@ class Woo_Feed_Products_v3 {
3188
  *
3189
  */
3190
  protected function current_price_with_tax( $product ) {
3191
-
3192
  $price_with_tax = $this->get_price_by_product_type( $product, 'price', true );
3193
-
3194
  return apply_filters( 'woo_feed_filter_product_regular_price_with_tax', $price_with_tax, $product, $this->config, true );
3195
  }
3196
-
3197
  /**
3198
  * Get Product Regular Price with Tax
3199
  *
@@ -3204,12 +3214,12 @@ class Woo_Feed_Products_v3 {
3204
  *
3205
  */
3206
  protected function sale_price_with_tax( $product ) {
3207
-
3208
  $sale_price_with_tax = $this->get_price_by_product_type( $product, 'sale_price', true );
3209
-
3210
  return apply_filters( 'woo_feed_filter_product_sale_price_with_tax', $sale_price_with_tax, $product, $this->config, true );
3211
  }
3212
-
3213
  /**
3214
  * Get Composite Product Price
3215
  *
@@ -3233,7 +3243,7 @@ class Woo_Feed_Products_v3 {
3233
  return $this->get_price_by_price_type( $product, $type, $tax );
3234
  }
3235
  }
3236
-
3237
  /**
3238
  * Get WooCommerce Composite Product Price
3239
  * Plugin URL: https://wordpress.org/plugins/wpc-composite-products/
@@ -3251,18 +3261,18 @@ class Woo_Feed_Products_v3 {
3251
  $base_price = $this->get_price_by_price_type( $product, $type, $tax );
3252
  if ( isset( $this->config['composite_price'] ) && 'all_product_price' == $this->config['composite_price'] ) {
3253
  $composite = new WC_Product_Composite( $product );
3254
-
3255
  if ( 'price' === $type || 'sale_price' === $type ) {
3256
  $price = $composite->get_composite_price();
3257
  } else {
3258
  $price = $composite->get_composite_regular_price();
3259
  }
3260
-
3261
  // Get WooCommerce Multi language Price by Currency.
3262
  $price = apply_filters( 'woo_feed_wcml_price',
3263
  $price, $product->get_id(), $this->get_feed_currency(), '_' . $type
3264
  );
3265
-
3266
  // Get Price with tax
3267
  if ( true === $tax ) {
3268
  $price = woo_feed_get_price_with_tax( $price, $composite );
@@ -3270,10 +3280,10 @@ class Woo_Feed_Products_v3 {
3270
  } else {
3271
  $price = $base_price;
3272
  }
3273
-
3274
  return $price > 0 ? $price : '';
3275
  }
3276
-
3277
  /**
3278
  * Get WPC Composite Product Price.
3279
  * Plugin URL: https://wordpress.org/plugins/wpc-composite-products/
@@ -3313,14 +3323,14 @@ class Woo_Feed_Products_v3 {
3313
  }
3314
  }
3315
  }
3316
-
3317
  // Apply discount to components price.
3318
  $discount = $product->get_discount();
3319
  if ( $discount > 0 ) {
3320
  $components_price -= ( ( $discount / 100 ) * $components_price );
3321
  }
3322
  }
3323
-
3324
  if ( 'exclude' === $product->get_pricing() ) {
3325
  $price = $components_price;
3326
  } elseif ( 'include' === $product->get_pricing() ) {
@@ -3331,10 +3341,10 @@ class Woo_Feed_Products_v3 {
3331
  } else {
3332
  $price = $base_price;
3333
  }
3334
-
3335
  return $price > 0 ? $price : '';
3336
  }
3337
-
3338
  /**
3339
  * Get total price of grouped product
3340
  *
@@ -3355,17 +3365,17 @@ class Woo_Feed_Products_v3 {
3355
  if ( ! is_object( $product ) ) {
3356
  continue; // make sure that the product exists..
3357
  }
3358
-
3359
  $get_price = $this->get_price_by_product_type( $product, $type, $tax );
3360
  if ( ! empty( $get_price ) ) {
3361
  $price += $get_price;
3362
  }
3363
  }
3364
  }
3365
-
3366
  return $price > 0 ? $price : '';
3367
  }
3368
-
3369
  /**
3370
  * Get Variable Product Price
3371
  *
@@ -3382,7 +3392,7 @@ class Woo_Feed_Products_v3 {
3382
  if ( isset( $this->config['variable_price'] ) ) {
3383
  $min_max_first_default = $this->config['variable_price'];
3384
  }
3385
-
3386
  $price = 0;
3387
  if ( 'first' == $min_max_first_default ) {
3388
  $children = $variable->get_visible_children();
@@ -3398,21 +3408,21 @@ class Woo_Feed_Products_v3 {
3398
  } else {
3399
  $price = $variable->get_variation_price( $min_max_first_default );
3400
  }
3401
-
3402
  // Get WooCommerce Multi language Price by Currency.
3403
  $price = apply_filters( 'woo_feed_wcml_price',
3404
  $price, $variable->get_id(), $this->get_feed_currency(), '_' . $type
3405
  );
3406
-
3407
  // Get Price with tax
3408
  if ( true === $tax ) {
3409
  $price = woo_feed_get_price_with_tax( $price, $variable );
3410
  }
3411
  }
3412
-
3413
  return $price > 0 ? $price : '';
3414
  }
3415
-
3416
  /**
3417
  * Get Bundle Product Price
3418
  *
@@ -3431,12 +3441,12 @@ class Woo_Feed_Products_v3 {
3431
  } else {
3432
  $price = $bundle->get_bundle_regular_price();
3433
  }
3434
-
3435
  // Get WooCommerce Multi language Price by Currency.
3436
  $price = apply_filters( 'woo_feed_wcml_price',
3437
  $price, $product->get_id(), $this->get_feed_currency(), '_' . $type
3438
  );
3439
-
3440
  // Get Price with tax
3441
  if ( true === $tax ) {
3442
  $price = woo_feed_get_price_with_tax( $price, $bundle );
@@ -3445,10 +3455,10 @@ class Woo_Feed_Products_v3 {
3445
  // Get Default price for others bundle products.
3446
  $price = $this->get_price_by_price_type( $product, $type, $tax );
3447
  }
3448
-
3449
  return $price > 0 ? $price : '';
3450
  }
3451
-
3452
  /**
3453
  * Get price for Iconic woocommerce-bundled-products
3454
  *
@@ -3462,13 +3472,13 @@ class Woo_Feed_Products_v3 {
3462
  if ( ! class_exists( 'WC_Product_Bundled' ) ) {
3463
  return $product->get_price();
3464
  }
3465
-
3466
  $is_discounted = false;
3467
  $price = $product->get_price();
3468
  $bundle = new WC_Product_Bundled( $product->get_id() );
3469
  $iconic_bundle_product_type = ( ! is_null( $bundle->options['price_display'] ) ) ? $bundle->options['price_display'] : '';
3470
  $product_ids = $bundle->options['product_ids'];
3471
-
3472
  //set discount
3473
  if ( ! empty( $bundle->options['fixed_discount'] ) ) {
3474
  $is_discounted = true;
@@ -3477,41 +3487,41 @@ class Woo_Feed_Products_v3 {
3477
  $is_discounted = false;
3478
  $discount = 0;
3479
  }
3480
-
3481
  // Get price
3482
  if ( is_array( $product_ids ) ) {
3483
  $product_prices = array_map( function ( $id ) use ( $tax, $type, $is_discounted, $discount ) {
3484
  $product = wc_get_product( $id );
3485
-
3486
  return $this->get_price_by_price_type( $product, $type, $tax );
3487
-
3488
  }, $product_ids );
3489
-
3490
  if ( 'range' === $iconic_bundle_product_type ) {
3491
  $price = min( $product_prices );
3492
  } else {
3493
  $price = array_sum( $product_prices );
3494
  }
3495
  }
3496
-
3497
  // Get sale price if discount enabled
3498
  if ( $is_discounted && ( 'sale_price' === $type || 'price' === $type ) ) {
3499
  $price -= $discount;
3500
  }
3501
-
3502
  // Get WooCommerce Multi language Price by Currency.
3503
  $price = apply_filters( 'woo_feed_wcml_price',
3504
  $price, $product->get_id(), $this->get_feed_currency(), '_' . $type
3505
  );
3506
-
3507
  // Get Price with tax
3508
  if ( true === $tax ) {
3509
  $price = woo_feed_get_price_with_tax( $price, $bundle );
3510
  }
3511
-
3512
  return $price > 0 ? $price : '';
3513
  }
3514
-
3515
  /**
3516
  * Get Product Weight
3517
  *
@@ -3524,7 +3534,7 @@ class Woo_Feed_Products_v3 {
3524
  protected function weight( $product ) {
3525
  return apply_filters( 'woo_feed_filter_product_weight', $product->get_weight(), $product, $this->config );
3526
  }
3527
-
3528
  /**
3529
  * Get Product Weight Unit
3530
  *
@@ -3537,7 +3547,7 @@ class Woo_Feed_Products_v3 {
3537
  protected function weight_unit( $product ) {
3538
  return apply_filters( 'woo_feed_filter_product_weight_unit', get_option( 'woocommerce_weight_unit' ), $product, $this->config );
3539
  }
3540
-
3541
  /**
3542
  * Get Product Width
3543
  *
@@ -3550,7 +3560,7 @@ class Woo_Feed_Products_v3 {
3550
  protected function width( $product ) {
3551
  return apply_filters( 'woo_feed_filter_product_width', $product->get_width(), $product, $this->config );
3552
  }
3553
-
3554
  /**
3555
  * Get Product Height
3556
  *
@@ -3563,7 +3573,7 @@ class Woo_Feed_Products_v3 {
3563
  protected function height( $product ) {
3564
  return apply_filters( 'woo_feed_filter_product_height', $product->get_height(), $product, $this->config );
3565
  }
3566
-
3567
  /**
3568
  * Get Product Length
3569
  *
@@ -3576,7 +3586,7 @@ class Woo_Feed_Products_v3 {
3576
  protected function length( $product ) {
3577
  return apply_filters( 'woo_feed_filter_product_length', $product->get_length(), $product, $this->config );
3578
  }
3579
-
3580
  /**
3581
  * Get Product Shipping
3582
  *
@@ -3589,20 +3599,20 @@ class Woo_Feed_Products_v3 {
3589
  protected function shipping( $product ) {
3590
  $feedBody = '';
3591
  $data = $this->data;
3592
-
3593
  if ( isset( $data['shipping_zones'] ) && ! empty( $data['shipping_zones'] ) ) {
3594
  $zones = $data['shipping_zones'];
3595
-
3596
  if ( in_array( $this->config['provider'], [ 'google', 'facebook', 'pinterest', 'bing', 'snapchat' ] ) ) {
3597
  $get_shipping = new Woo_Feed_Shipping( $this->config );
3598
  $feedBody .= $get_shipping->set_product( $product )->set_shipping_zone( $zones )->get_google_shipping();
3599
  }
3600
  }
3601
-
3602
  return apply_filters( 'woo_feed_filter_product_shipping', $feedBody, $product, $this->config );
3603
-
3604
  }
3605
-
3606
  /**
3607
  * Get Product Shipping Cost
3608
  *
@@ -3615,10 +3625,10 @@ class Woo_Feed_Products_v3 {
3615
  protected function shipping_cost( $product ) {
3616
  $shipping_obj = new Woo_Feed_Shipping( $this->config );
3617
  $shipping_obj = $shipping_obj->set_product( $product );
3618
-
3619
  return apply_filters( 'woo_feed_filter_product_shipping_cost', $shipping_obj->get_lowest_shipping_price(), $product, $this->config );
3620
  }
3621
-
3622
  /**
3623
  * Get Product Shipping Class
3624
  *
@@ -3631,7 +3641,7 @@ class Woo_Feed_Products_v3 {
3631
  protected function shipping_class( $product ) {
3632
  return apply_filters( 'woo_feed_filter_product_shipping_class', $product->get_shipping_class(), $product, $this->config );
3633
  }
3634
-
3635
  /**
3636
  * Get Product Author Name
3637
  *
@@ -3643,10 +3653,10 @@ class Woo_Feed_Products_v3 {
3643
  */
3644
  protected function author_name( $product ) {
3645
  $post = get_post( $product->get_id() );
3646
-
3647
  return get_the_author_meta( 'user_login', $post->post_author );
3648
  }
3649
-
3650
  /**
3651
  * Get Product Author Email
3652
  *
@@ -3658,10 +3668,10 @@ class Woo_Feed_Products_v3 {
3658
  */
3659
  protected function author_email( $product ) {
3660
  $post = get_post( $product->get_id() );
3661
-
3662
  return get_the_author_meta( 'user_email', $post->post_author );
3663
  }
3664
-
3665
  /**
3666
  * Get Product Created Date
3667
  *
@@ -3673,10 +3683,10 @@ class Woo_Feed_Products_v3 {
3673
  */
3674
  protected function date_created( $product ) {
3675
  $date_created = gmdate( 'Y-m-d', strtotime( $product->get_date_created() ) );
3676
-
3677
  return apply_filters( 'woo_feed_filter_product_date_created', $date_created, $product, $this->config );
3678
  }
3679
-
3680
  /**
3681
  * Get Product Last Updated Date
3682
  *
@@ -3688,10 +3698,10 @@ class Woo_Feed_Products_v3 {
3688
  */
3689
  protected function date_updated( $product ) {
3690
  $date_updated = gmdate( 'Y-m-d', strtotime( $product->get_date_modified() ) );
3691
-
3692
  return apply_filters( 'woo_feed_filter_product_date_updated', $date_updated, $product, $this->config );
3693
  }
3694
-
3695
  /**
3696
  * Get Product Tax
3697
  *
@@ -3708,10 +3718,10 @@ class Woo_Feed_Products_v3 {
3708
  $shipping_obj = $shipping_obj->set_product( $product );
3709
  $feedBody .= $shipping_obj->get_google_tax();
3710
  }
3711
-
3712
  return apply_filters( 'woo_feed_filter_product_tax', $feedBody, $product, $this->config );
3713
  }
3714
-
3715
  /**
3716
  * Get Product Tax class
3717
  *
@@ -3722,7 +3732,7 @@ class Woo_Feed_Products_v3 {
3722
  protected function tax_class( $product ) {
3723
  return apply_filters( 'woo_feed_filter_product_tax_class', $product->get_tax_class(), $product, $this->config );
3724
  }
3725
-
3726
  /**
3727
  * Get Product Tax Status
3728
  *
@@ -3733,7 +3743,7 @@ class Woo_Feed_Products_v3 {
3733
  protected function tax_status( $product ) {
3734
  return apply_filters( 'woo_feed_filter_product_tax_status', $product->get_tax_status(), $product, $this->config );
3735
  }
3736
-
3737
  /**
3738
  * Get CTX Feed Custom Field value
3739
  *
@@ -3748,12 +3758,12 @@ class Woo_Feed_Products_v3 {
3748
  if ( $product->is_type( 'variation' ) ) {
3749
  $meta = $field . '_var';
3750
  }
3751
-
3752
  $meta = apply_filters( 'woo_feed_custom_field_meta', $meta, $product, $field );
3753
-
3754
  $new_meta_key = '';
3755
  $old_meta_key = '';
3756
-
3757
  if ( strpos( $meta, '_identifier' ) !== false ) {
3758
  $old_meta_key = $meta;
3759
  $new_meta_key = str_replace( '_identifier', '', $meta );
@@ -3761,18 +3771,18 @@ class Woo_Feed_Products_v3 {
3761
  $new_meta_key = $meta;
3762
  $old_meta_key = str_replace( 'woo_feed_', 'woo_feed_identifier_', $meta );
3763
  }
3764
-
3765
  $new_meta_value = $this->getProductMeta( $product, $new_meta_key );
3766
  $old_meta_value = $this->getProductMeta( $product, $old_meta_key );
3767
-
3768
  if ( empty( $new_meta_value ) ) {
3769
  return $old_meta_value;
3770
  }
3771
-
3772
  return $new_meta_value;
3773
-
3774
  }
3775
-
3776
  /**
3777
  * Get Product Sale Price Effected Date for Google Shopping
3778
  *
@@ -3789,13 +3799,13 @@ class Woo_Feed_Products_v3 {
3789
  if ( ! empty( $from ) && ! empty( $to ) ) {
3790
  $from = gmdate( 'c', strtotime( $from ) );
3791
  $to = gmdate( 'c', strtotime( $to ) );
3792
-
3793
  $effective_date = $from . '/' . $to;
3794
  }
3795
-
3796
  return $effective_date;
3797
  }
3798
-
3799
  /**
3800
  * Ger Product Attribute
3801
  *
@@ -3808,27 +3818,27 @@ class Woo_Feed_Products_v3 {
3808
  */
3809
  protected function getProductAttribute( $product, $attr ) {
3810
  $id = $product->get_id();
3811
-
3812
  if ( woo_feed_wc_version_check( 3.2 ) ) {
3813
  if ( woo_feed_wc_version_check( 3.6 ) ) {
3814
  $attr = str_replace( 'pa_', '', $attr );
3815
  }
3816
  $value = $product->get_attribute( $attr );
3817
-
3818
  // if empty get attribute of parent post
3819
  if ( '' === $value && $product->is_type( 'variation' ) ) {
3820
  $product = wc_get_product( $product->get_parent_id() );
3821
  $value = $product->get_attribute( $attr );
3822
  }
3823
-
3824
  $getproductattribute = $value;
3825
  } else {
3826
  $getproductattribute = implode( ',', wc_get_product_terms( $id, $attr, array( 'fields' => 'names' ) ) );
3827
  }
3828
-
3829
  return apply_filters( 'woo_feed_filter_product_attribute', $getproductattribute, $attr, $product, $this->config );
3830
  }
3831
-
3832
  /**
3833
  * Get Meta
3834
  *
@@ -3845,10 +3855,10 @@ class Woo_Feed_Products_v3 {
3845
  if ( '' === $value && $product->is_type( 'variation' ) ) {
3846
  $value = get_post_meta( $product->get_parent_id(), $meta, true );
3847
  }
3848
-
3849
  return apply_filters( 'woo_feed_filter_product_meta', $value, $product, $this->config );
3850
  }
3851
-
3852
  /**
3853
  * Filter Products by Conditions
3854
  *
@@ -3861,7 +3871,7 @@ class Woo_Feed_Products_v3 {
3861
  public function filter_product( $product ) {
3862
  return true;
3863
  }
3864
-
3865
  /**
3866
  * Get Taxonomy
3867
  *
@@ -3877,20 +3887,20 @@ class Woo_Feed_Products_v3 {
3877
  if ( $product->is_type( 'variation' ) ) {
3878
  $id = $product->get_parent_id();
3879
  }
3880
-
3881
  $separator = apply_filters( 'woo_feed_product_taxonomy_term_list_separator', ',', $this->config, $product );
3882
-
3883
  $term_list = get_the_term_list( $id, $taxonomy, '', $separator, '' );
3884
-
3885
  if ( is_object( $term_list ) && get_class( $term_list ) === 'WP_Error' ) {
3886
  $term_list = '';
3887
  }
3888
-
3889
  $getproducttaxonomy = woo_feed_strip_all_tags( $term_list );
3890
-
3891
  return apply_filters( 'woo_feed_filter_product_taxonomy', $getproducttaxonomy, $product, $this->config );
3892
  }
3893
-
3894
  /**
3895
  * Format price value
3896
  *
@@ -3906,7 +3916,7 @@ class Woo_Feed_Products_v3 {
3906
  $plus = '+';
3907
  $minus = '-';
3908
  $percent = '%';
3909
-
3910
  if ( strpos( $name, 'price' ) !== false ) {
3911
  if ( strpos( $result, $plus ) !== false && strpos( $result, $percent ) !== false ) {
3912
  $result = str_replace( '+', '', $result );
@@ -3932,10 +3942,10 @@ class Woo_Feed_Products_v3 {
3932
  }
3933
  }
3934
  }
3935
-
3936
  return $result;
3937
  }
3938
-
3939
  /**
3940
  * Format output According to Output Type config
3941
  *
@@ -3950,92 +3960,92 @@ class Woo_Feed_Products_v3 {
3950
  */
3951
  protected function format_output( $output, $outputTypes, $product, $productAttribute, $merchant_attribute ) {
3952
  if ( ! empty( $outputTypes ) && is_array( $outputTypes ) ) {
3953
-
3954
  // Format Output According to output type
3955
  if ( in_array( 2, $outputTypes ) ) { // Strip Tags
3956
  $output = woo_feed_strip_all_tags( html_entity_decode( $output ) );
3957
  }
3958
-
3959
  if ( in_array( 3, $outputTypes ) ) { // UTF-8 Encode
3960
  $output = utf8_encode( $output );
3961
  }
3962
-
3963
  if ( in_array( 4, $outputTypes ) ) { // htmlentities
3964
  $output = htmlentities( $output, ENT_QUOTES, 'UTF-8' );
3965
  }
3966
-
3967
  if ( in_array( 5, $outputTypes ) ) { // Integer
3968
  $output = intval( $output );
3969
  }
3970
-
3971
  if ( in_array( 6, $outputTypes ) ) { // Format Price
3972
  if ( ! empty( $output ) && $output > 0 ) {
3973
  $decimals = wc_get_price_decimals();
3974
  $decimal_separator = wc_get_price_decimal_separator();
3975
  $thousand_separator = wc_get_price_thousand_separator();
3976
  $output = (float) $output;
3977
-
3978
  if ( "idealo" === $this->config['provider'] ) {
3979
  $output = number_format( $output, $decimals, wp_specialchars_decode( stripslashes( $decimal_separator ) ), wp_specialchars_decode( stripslashes( $thousand_separator ) ) );
3980
  } else {
3981
  $output = number_format( $output, 2, '.', '' );
3982
  }
3983
-
3984
  }
3985
  }
3986
-
3987
  if ( in_array( 7, $outputTypes ) ) { // Rounded Price
3988
  if ( ! empty( $output ) && $output > 0 ) {
3989
  $output = round( $output );
3990
  $output = number_format( $output, 2, '.', '' );
3991
  }
3992
  }
3993
-
3994
  if ( in_array( 8, $outputTypes ) ) { // Delete Space
3995
  $output = htmlentities( $output, null, 'utf-8' );
3996
  $output = str_replace( "&nbsp;", " ", $output );
3997
  $output = html_entity_decode( $output );
3998
  $output = preg_replace( "/\\s+/", ' ', $output );
3999
  }
4000
-
4001
  if ( in_array( 10, $outputTypes ) ) { // Remove Invalid Character
4002
  $output = woo_feed_stripInvalidXml( $output );
4003
  }
4004
-
4005
  if ( in_array( 11, $outputTypes ) ) { // Remove ShortCodes
4006
  $output = $this->remove_short_codes( $output );
4007
  }
4008
-
4009
  if ( in_array( 12, $outputTypes ) ) {
4010
  //$output = ucwords(mb_strtolower($output));
4011
  $output = mb_convert_case( $output, MB_CASE_TITLE );
4012
  }
4013
-
4014
  if ( in_array( 13, $outputTypes ) ) {
4015
  //$output = ucfirst(strtolower($output));
4016
  $output = mb_strtoupper( mb_substr( $output, 0, 1 ) ) . mb_substr( $output, 1 );
4017
  }
4018
-
4019
  if ( in_array( 14, $outputTypes ) ) {
4020
  $output = mb_strtoupper( mb_strtolower( $output ) );
4021
  }
4022
-
4023
  if ( in_array( 15, $outputTypes ) ) {
4024
  $output = mb_strtolower( $output );
4025
  }
4026
-
4027
  if ( in_array( 16, $outputTypes ) ) {
4028
  if ( 'http' == substr( $output, 0, 4 ) ) {
4029
  $output = str_replace( 'http://', 'https://', $output );
4030
  }
4031
  }
4032
-
4033
  if ( in_array( 17, $outputTypes ) ) {
4034
  if ( 'http' == substr( $output, 0, 4 ) ) {
4035
  $output = str_replace( 'https://', 'http://', $output );
4036
  }
4037
  }
4038
-
4039
  if ( in_array( 18, $outputTypes ) ) { // only parent
4040
  if ( $product->is_type( 'variation' ) ) {
4041
  $id = $product->get_parent_id();
@@ -4043,7 +4053,7 @@ class Woo_Feed_Products_v3 {
4043
  $output = $this->getAttributeValueByType( $parentProduct, $productAttribute, $merchant_attribute );
4044
  }
4045
  }
4046
-
4047
  if ( in_array( 19, $outputTypes ) ) { // child if parent empty
4048
  if ( $product->is_type( 'variation' ) ) {
4049
  $id = $product->get_parent_id();
@@ -4054,7 +4064,7 @@ class Woo_Feed_Products_v3 {
4054
  }
4055
  }
4056
  }
4057
-
4058
  if ( in_array( 20, $outputTypes ) ) { // parent if child empty
4059
  if ( $product->is_type( 'variation' ) ) {
4060
  $output = $this->getAttributeValueByType( $product, $productAttribute, $merchant_attribute );
@@ -4065,15 +4075,15 @@ class Woo_Feed_Products_v3 {
4065
  }
4066
  }
4067
  }
4068
-
4069
  if ( in_array( 9, $outputTypes ) && ! empty( $output ) && 'xml' === $this->config['feedType'] ) { // Add CDATA
4070
  $output = '<![CDATA[' . $output . ']]>';
4071
  }
4072
  }
4073
-
4074
  return $output;
4075
  }
4076
-
4077
  /**
4078
  * Add Prefix and Suffix with attribute value
4079
  *
@@ -4091,17 +4101,17 @@ class Woo_Feed_Products_v3 {
4091
  if ( '' === $output ) {
4092
  return $output;
4093
  }
4094
-
4095
  if ( strpos( $output, '<![CDATA[' ) !== false ) {
4096
  $cdata = true;
4097
  $output = str_replace( array( '<![CDATA[', ']]>' ), array( '', '' ), $output );
4098
  }
4099
-
4100
  // Add Prefix before Output
4101
  if ( '' !== $prefix ) {
4102
  $output = "$prefix" . $output;
4103
  }
4104
-
4105
  // Add Suffix after Output
4106
  if ( '' !== $suffix ) {
4107
  if ( array_key_exists( trim( $suffix ), get_woocommerce_currencies() ) ) { // Add space before suffix if attribute contain price.
@@ -4113,14 +4123,14 @@ class Woo_Feed_Products_v3 {
4113
  $output .= (string) $suffix;
4114
  }
4115
  }
4116
-
4117
  if ( $cdata ) {
4118
  $output = '<![CDATA[' . $output . ']]>';
4119
  }
4120
-
4121
  return "$output";
4122
  }
4123
-
4124
  /**
4125
  * Get Subscription period
4126
  *
@@ -4134,10 +4144,10 @@ class Woo_Feed_Products_v3 {
4134
  if ( class_exists( 'WC_Subscriptions' ) ) {
4135
  return $this->getProductMeta( $product, '_subscription_period' );
4136
  }
4137
-
4138
  return '';
4139
  }
4140
-
4141
  /**
4142
  * Get Subscription period interval
4143
  *
@@ -4151,10 +4161,10 @@ class Woo_Feed_Products_v3 {
4151
  if ( class_exists( 'WC_Subscriptions' ) ) {
4152
  return $this->getProductMeta( $product, '_subscription_period_interval' );
4153
  }
4154
-
4155
  return '';
4156
  }
4157
-
4158
  /**
4159
  * Get Subscription period interval
4160
  *
@@ -4167,7 +4177,7 @@ class Woo_Feed_Products_v3 {
4167
  protected function subscription_amount( $product ) {
4168
  return $this->price( $product );
4169
  }
4170
-
4171
  /**
4172
  * Get Installment Amount
4173
  *
@@ -4179,7 +4189,7 @@ class Woo_Feed_Products_v3 {
4179
  protected function installment_amount( $product ) {
4180
  return $this->price( $product );
4181
  }
4182
-
4183
  /**
4184
  * Get Installment Months
4185
  *
@@ -4192,11 +4202,11 @@ class Woo_Feed_Products_v3 {
4192
  if ( class_exists( 'WC_Subscriptions' ) ) {
4193
  return $this->getProductMeta( $product, '_subscription_length' );
4194
  }
4195
-
4196
  return '';
4197
  }
4198
-
4199
-
4200
  /**
4201
  * Calculate unit_price_measure. If Unit custom fields by CTX feed are enabled then it will take value
4202
  * from custom fields or it will take values for WooCommerce Germanized Plugin if enabled.
@@ -4217,20 +4227,20 @@ class Woo_Feed_Products_v3 {
4217
  ) {
4218
  $unit = $this->getCustomField( $product, 'woo_feed_unit' );
4219
  $unit_price_measure = $this->getCustomField( $product, 'woo_feed_unit_pricing_measure' );
4220
-
4221
  $unit_price_measure .= " " . $unit;
4222
  }
4223
-
4224
  if ( empty( $unit_price_measure ) && class_exists( 'WooCommerce_Germanized' ) ) { // For WooCommerce Germanized Plugin
4225
  $unit = $this->getProductMeta( $product, '_unit' );
4226
  $unit_price_measure = $this->getProductMeta( $product, '_unit_product' );
4227
-
4228
  $unit_price_measure .= " " . $unit;
4229
  }
4230
-
4231
  return apply_filters( 'woo_feed_filter_unit_price_measure', $unit_price_measure, $product, $this->config );
4232
  }
4233
-
4234
  /**
4235
  * Calculate unit_price_base_measure. If Unit custom fields by CTX feed are enabled then it will take value
4236
  * from custom fields or it will take values for WooCommerce Germanized Plugin if enabled.
@@ -4251,20 +4261,20 @@ class Woo_Feed_Products_v3 {
4251
  ) {
4252
  $unit = $this->getCustomField( $product, 'woo_feed_unit' );
4253
  $unit_price_base_measure = $this->getCustomField( $product, 'woo_feed_unit_pricing_base_measure' );
4254
-
4255
  $unit_price_base_measure .= " " . $unit;
4256
  }
4257
-
4258
  if ( empty( $unit_price_base_measure ) && class_exists( 'WooCommerce_Germanized' ) ) { // For WooCommerce Germanized Plugin
4259
  $unit = $this->getProductMeta( $product, '_unit' );
4260
  $unit_price_base_measure = $this->getProductMeta( $product, '_unit_base' );
4261
-
4262
  $unit_price_base_measure .= " " . $unit;
4263
  }
4264
-
4265
  return apply_filters( 'woo_feed_filter_unit_price_base_measure', $unit_price_base_measure, $product, $this->config );
4266
  }
4267
-
4268
  /**
4269
  * Get GTIN value of WooCommerce Germanized Plugin
4270
  *
@@ -4278,10 +4288,10 @@ class Woo_Feed_Products_v3 {
4278
  if ( class_exists( 'WooCommerce_Germanized' ) ) { // For WooCommerce Germanized Plugin
4279
  $wc_germanized_gtin = $this->getProductMeta( $product, '_ts_gtin' );
4280
  }
4281
-
4282
  return apply_filters( 'woo_feed_filter_wc_germanized_gtin', $wc_germanized_gtin, $product, $this->config );
4283
  }
4284
-
4285
  /**
4286
  * Get MPN value of WooCommerce Germanized Plugin
4287
  *
@@ -4295,11 +4305,11 @@ class Woo_Feed_Products_v3 {
4295
  if ( class_exists( 'WooCommerce_Germanized' ) ) { // For WooCommerce Germanized Plugin
4296
  $wc_germanized_mpn = $this->getProductMeta( $product, '_ts_mpn' );
4297
  }
4298
-
4299
  return apply_filters( 'woo_feed_filter_wc_germanized_mpn', $wc_germanized_mpn, $product, $this->config );
4300
  }
4301
-
4302
-
4303
  /**
4304
  * Yoast Identifier attribute for gtin8
4305
  *
@@ -4310,10 +4320,10 @@ class Woo_Feed_Products_v3 {
4310
  */
4311
  protected function yoast_gtin8( $product ) {
4312
  $yoast_gtin8_value = woo_feed_get_yoast_identifiers_value( 'gtin8', $product );
4313
-
4314
  return apply_filters( 'yoast_gtin8_attribute_value', $yoast_gtin8_value, $product );
4315
  }
4316
-
4317
  /**
4318
  * Yoast Identifier attribute for gtin12
4319
  *
@@ -4324,10 +4334,10 @@ class Woo_Feed_Products_v3 {
4324
  */
4325
  protected function yoast_gtin12( $product ) {
4326
  $yoast_gtin12_value = woo_feed_get_yoast_identifiers_value( 'gtin12', $product );
4327
-
4328
  return apply_filters( 'yoast_gtin12_attribute_value', $yoast_gtin12_value, $product );
4329
  }
4330
-
4331
  /**
4332
  * Yoast Identifier attribute for gtin13
4333
  *
@@ -4338,10 +4348,10 @@ class Woo_Feed_Products_v3 {
4338
  */
4339
  protected function yoast_gtin13( $product ) {
4340
  $yoast_gtin13_value = woo_feed_get_yoast_identifiers_value( 'gtin13', $product );
4341
-
4342
  return apply_filters( 'yoast_gtin13_attribute_value', $yoast_gtin13_value, $product );
4343
  }
4344
-
4345
  /**
4346
  * Yoast Identifier attribute for gtin12
4347
  *
@@ -4352,10 +4362,10 @@ class Woo_Feed_Products_v3 {
4352
  */
4353
  protected function yoast_gtin14( $product ) {
4354
  $yoast_gtin14_value = woo_feed_get_yoast_identifiers_value( 'gtin14', $product );
4355
-
4356
  return apply_filters( 'yoast_gtin14_attribute_value', $yoast_gtin14_value, $product );
4357
  }
4358
-
4359
  /**
4360
  * Yoast Identifier attribute for isbn
4361
  *
@@ -4366,10 +4376,10 @@ class Woo_Feed_Products_v3 {
4366
  */
4367
  protected function yoast_isbn( $product ) {
4368
  $yoast_isbn_value = woo_feed_get_yoast_identifiers_value( 'isbn', $product );
4369
-
4370
  return apply_filters( 'yoast_isbn_attribute_value', $yoast_isbn_value, $product );
4371
  }
4372
-
4373
  /**
4374
  * Yoast Identifier attribute for mpn
4375
  *
@@ -4380,10 +4390,10 @@ class Woo_Feed_Products_v3 {
4380
  */
4381
  protected function yoast_mpn( $product ) {
4382
  $yoast_mpn_value = woo_feed_get_yoast_identifiers_value( 'mpn', $product );
4383
-
4384
  return apply_filters( 'yoast_mpn_attribute_value', $yoast_mpn_value, $product );
4385
  }
4386
-
4387
  /**
4388
  * Rank Math GTIN Identifier attribute
4389
  *
@@ -4396,10 +4406,10 @@ class Woo_Feed_Products_v3 {
4396
  $product_id = woo_feed_parent_product_id( $product );
4397
  $rankmath_gtin_value = get_post_meta( $product_id, '_rank_math_gtin_code' );
4398
  $rankmath_gtin_value = ! empty( $rankmath_gtin_value ) && is_array( $rankmath_gtin_value ) ? $rankmath_gtin_value[0] : '';
4399
-
4400
  return apply_filters( 'rankmath_gtin_attribute_value', $rankmath_gtin_value, $product );
4401
  }
4402
-
4403
  /**
4404
  * Get ACF Field values
4405
  *
@@ -4413,7 +4423,7 @@ class Woo_Feed_Products_v3 {
4413
  if ( class_exists( 'ACF' ) ) {
4414
  return get_field( $field, $product->get_id() );
4415
  }
4416
-
4417
  return '';
4418
  }
4419
  }
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
  *
130
  'product highlight 9',
131
  'product highlight 10',
132
  );
133
+
134
  /**
135
  * To replace google additional image link attribute for CSV & TXT feed
136
  *
194
  * @var array
195
  */
196
  protected $xml_wrapper = [];
197
+
198
+
199
  /**
200
  * Attribute to skip in attribute loop for processing separately
201
  *
265
  'tax_ship',
266
  ),
267
  );
268
+
269
  /**
270
  * Already Processed merchant attributes by the attribute loop
271
  * this will ensure unique merchant attribute.
274
  * @var array
275
  */
276
  protected $processed_merchant_attributes = array();
277
+
278
+
279
  /**
280
  * Post meta prefix for dropdown item
281
  *
283
  * @var string
284
  */
285
  const POST_META_PREFIX = 'wf_cattr_';
286
+
287
  /**
288
  * Product Attribute (taxonomy & local) Prefix
289
  *
291
  * @var string
292
  */
293
  const PRODUCT_ATTRIBUTE_PREFIX = 'wf_attr_';
294
+
295
  /**
296
  * Product Taxonomy Prefix
297
  *
299
  * @var string
300
  */
301
  const PRODUCT_TAXONOMY_PREFIX = 'wf_taxo_';
302
+
303
  /**
304
  * Product Custom Field Prefix
305
  *
307
  * @var string
308
  */
309
  const PRODUCT_CUSTOM_IDENTIFIER = 'woo_feed_';
310
+
311
  /**
312
  * Product Category Mapping Prefix
313
  *
315
  * @var string
316
  */
317
  const PRODUCT_CATEGORY_MAPPING_PREFIX = 'wf_cmapping_';
318
+
319
  /**
320
  * WordPress Option Prefix
321
  *
324
  * @var string
325
  */
326
  const WP_OPTION_PREFIX = 'wf_option_';
327
+
328
  /**
329
  * Advance Custom Field (ACF) Prefix
330
  *
332
  * @var string
333
  */
334
  const PRODUCT_ACF_FIELDS = 'acf_fields_';
335
+
336
  /**
337
  * Woo_Feed_Products_v3 constructor.
338
  *
346
  $this->process_xml_wrapper();
347
  woo_feed_log_feed_process( $this->config['filename'], sprintf( 'Current Query Type is %s', $this->queryType ) );
348
  }
349
+
350
  /**
351
  * Generate Query Args For WP/WC query class
352
  *
356
  */
357
  protected function get_query_args( $type = 'wc' ) {
358
  $args = [];
359
+
360
  // Include Product Variations with db query if configured
361
  $variation_query = woo_feed_get_options( 'variation_query_type' );
362
+
363
  if ( 'wc' === $type ) {
364
  $product_types = $this->product_types;
365
  if ( 'variable' === $variation_query ) {
368
  unset( $product_types[ $variation ] );
369
  }
370
  }
371
+
372
  $args = array(
373
  'limit' => - 1, // phpcs:ignore
374
  'status' => $this->post_status,
379
  'suppress_filters' => false,
380
  );
381
  }
382
+
383
  if ( 'wp' === $type ) {
384
+
385
  $post_type = 'product';
386
  // Include Product Variations with db query if configured
387
  $variation_query = woo_feed_get_options( 'variation_query_type' );
388
  if ( 'individual' === $variation_query ) {
389
  $post_type = [ 'product', 'product_variation' ];
390
  }
391
+
392
  $args = array(
393
  'posts_per_page' => - 1, // phpcs:ignore
394
  'post_type' => $post_type,
401
  'suppress_filters' => false,
402
  );
403
  }
404
+
405
  return $args;
406
  }
407
+
408
  /**
409
  * Get Products using WC_Product_Query
410
  *
420
  if ( woo_feed_is_debugging_enabled() ) {
421
  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
422
  }
423
+
424
  return $query->get_products();
425
  }
426
+
427
  /**
428
  * Get Products using WP_Query
429
  *
438
  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
439
  woo_feed_log( $this->config['filename'], sprintf( 'WP_Query Request ::' . PHP_EOL . '%s', $query->request ), 'info' );
440
  }
441
+
442
  return $query->get_posts();
443
  }
444
+
445
  /**
446
  * Get products
447
  *
458
  $wp = $this->get_wp_query_products();
459
  $products = array_unique( array_merge( $wc, $wp ) );
460
  }
461
+
462
  //set product ids
463
  $this->product_ids = $products;
464
+
465
  return $products;
466
  }
467
+
468
  /**
469
  * Organize Feed Attribute config
470
  *
474
  if ( empty( $this->config ) ) {
475
  return false;
476
  }
477
+
478
  $attributeConfig = array();
479
  $merchantAttributes = $this->config['mattributes'];
480
  if ( ! empty( $merchantAttributes ) ) {
491
  $i ++;
492
  }
493
  }
494
+
495
  return $attributeConfig;
496
  }
497
+
498
  /**
499
  * Get Product Information according to feed config
500
  *
505
  *
506
  */
507
  public function get_products( $productIds ) {
508
+
509
  if ( empty( $productIds ) ) {
510
  return [];
511
  }
512
+
513
  //filter big data
514
  $this->data = apply_filters( "woo_feed_feed_big_data", $this->data, $productIds, $this->config );
515
+
516
  /**
517
  * Fires before looping through request product for getting product data
518
  *
522
  * @since 3.2.10
523
  */
524
  do_action( 'woo_feed_before_product_loop', $productIds, $this->config );
525
+
526
  foreach ( $productIds as $key => $pid ) {
527
  woo_feed_log_feed_process( $this->config['filename'], sprintf( 'Loading Product Data For %d.', $pid ) );
528
  $product = wc_get_product( $pid );
529
+
530
  if ( $this->exclude_from_loop( $product ) ) {
531
  continue;
532
  }
533
+
534
  if ( $this->process_variation( $product ) ) {
535
  continue;
536
  }
537
+
538
  if ( ! $this->filter_product( $product ) ) {
539
  woo_feed_log_feed_process( $this->config['filename'], 'Skipping Product :: Matched with filter conditions' );
540
  continue;
541
  }
542
+
543
  woo_feed_log_feed_process( $this->config['filename'], 'Formatting Feed Data...' );
544
+
545
  // Add Single item wrapper before product info loop start
546
  if ( 'xml' == $this->config['feedType'] ) {
547
  $this->feedBody .= "\n";
548
  $this->feedBody .= '<' . $this->config['itemWrapper'] . '>';
549
  $this->feedBody .= "\n";
550
  }
551
+
552
  // reset processed attribute list before loop
553
  $this->processed_merchant_attributes = [];
554
+
555
  // Process attribute values
556
  $this->process_attributes( $product );
557
+
558
  try {
559
  woo_feed_log_feed_process( $this->config['filename'], 'Processing Merchant Specific Fields' );
560
  // Process feed data for uncommon merchant feed like Google,Facebook,Pinterest
564
  woo_feed_log( $this->config['filename'], $message, 'critical', $e, true );
565
  woo_feed_log_fatal_error( $message, $e );
566
  }
567
+
568
  if ( 'xml' == $this->config['feedType'] ) {
569
  if ( empty( $this->feedHeader ) ) {
570
  $this->feedHeader = $this->process_xml_feed_header();
571
  $this->feedFooter = $this->process_xml_feed_footer();
572
+
573
  }
574
+
575
  $this->feedBody .= '</' . $this->config['itemWrapper'] . '>';
576
+
577
+
578
  } elseif ( 'txt' == $this->config['feedType'] ) {
579
  if ( empty( $this->feedHeader ) ) {
580
  $this->process_txt_feed_header();
591
  woo_feed_log_feed_process( $this->config['filename'], 'Done Formatting...' );
592
  $this->pi ++;
593
  }
594
+
595
  /**
596
  * Fires after looping through request product for getting product data
597
  *
601
  * @since 3.2.10
602
  */
603
  do_action( 'woo_feed_after_product_loop', $productIds, $this->config );
604
+
605
  return $this->products;
606
  }
607
+
608
  /**
609
  * Process product variations
610
  *
617
  // Apply variable and variation settings
618
  if ( $product->is_type( 'variable' ) && $product->has_child() ) {
619
  $this->pi ++;
620
+
621
  $variation_query = woo_feed_get_options( 'variation_query_type' );
622
  if ( 'variable' === $variation_query ) {
623
  $variations = $product->get_visible_children();
628
  $this->get_products( $variations );
629
  }
630
  }
631
+
632
  return true;
633
  }
634
+
635
  return false;
636
  }
637
+
638
  /**
639
  * Process The Attributes and assign value to merchant attribute
640
  *
647
  // print_r($this->config['attributes']);
648
  // Get Product Attribute values by type and assign to product array
649
  foreach ( $this->config['attributes'] as $attr_key => $attribute ) {
650
+
651
  $merchant_attribute = isset( $this->config['mattributes'][ $attr_key ] ) ? $this->config['mattributes'][ $attr_key ] : '';
652
+
653
  if ( $this->exclude_current_attribute( $product, $merchant_attribute, $attribute ) ) {
654
  continue;
655
  }
656
+
657
  // Add Prefix and Suffix into Output
658
  $prefix = $this->config['prefix'][ $attr_key ];
659
  $suffix = $this->config['suffix'][ $attr_key ];
660
  $merchant = $this->config['provider'];
661
  $feedType = $this->config['feedType'];
662
+
663
  if ( 'pattern' == $this->config['type'][ $attr_key ] ) {
664
  $attributeValue = $this->config['default'][ $attr_key ];
665
  } else { // Get Pattern value
666
  $attributeValue = $this->getAttributeValueByType( $product, $attribute, $merchant_attribute );
667
  }
668
+
669
  // Format Output according to Output Type config.
670
  if ( isset( $this->config['output_type'][ $attr_key ] ) ) {
671
  $outputType = $this->config['output_type'][ $attr_key ];
672
  $attributeValue = $this->format_output( $attributeValue, $this->config['output_type'][ $attr_key ], $product, $attribute, $merchant_attribute );
673
  }
674
+
675
  // Limit Output.
676
  if ( isset( $this->config['limit'][ $attr_key ] ) ) {
677
  $attributeValue = $this->crop_string( $attributeValue, 0, $this->config['limit'][ $attr_key ] );
678
  }
679
+
680
  // Process prefix and suffix.
681
  $attributeValue = $this->process_prefix_suffix( $attributeValue, $prefix, $suffix, $attribute );
682
+
683
  if ( 'xml' == $feedType ) {
684
+
685
  // Replace XML Nodes according to merchant requirement.
686
  $getReplacedAttribute = woo_feed_replace_to_merchant_attribute( $merchant_attribute, $merchant, $feedType );
687
+
688
  // XML does not support space in node. So replace Space with Underscore.
689
  $getReplacedAttribute = str_replace( ' ', '_', $getReplacedAttribute );
690
+
691
  // Trim XML Element text & Encode for UTF-8.
692
  if ( ! empty( $attributeValue ) ) {
693
  $attributeValue = trim( $attributeValue );
694
+
695
  if ( 'custom' === $this->config['provider'] && strpos( $attributeValue, '<![CDATA[' ) === false ) {
696
  $attributeValue = htmlentities( $attributeValue, ENT_XML1 | ENT_QUOTES, 'UTF-8' );
697
  }
698
  }
699
+
700
  // Add closing XML node if value is empty
701
  if ( '' !== $attributeValue ) {
702
  // Add CDATA wrapper for XML feed to prevent XML error.
710
  $this->feedBody .= '<' . $getReplacedAttribute . '/>';
711
  $this->feedBody .= "\n";
712
  }
713
+
714
  } elseif ( in_array( $feedType, [ 'csv', 'tsv', 'xls' ], true ) ) {
715
  $merchant_attribute = woo_feed_replace_to_merchant_attribute( $merchant_attribute, $merchant, $feedType );
716
  $merchant_attribute = $this->processStringForCSV( $merchant_attribute );
717
+
718
  if ( "shipping" === $merchant_attribute && 'bing' == $this->config['provider'] ) {
719
  $merchant_attribute = 'shipping(country:service:price)';
720
  } elseif ( "shipping" === $merchant_attribute ) {
721
  $merchant_attribute = 'shipping(country:region:service:price)';
722
  }
723
+
724
  if ( "tax" === $merchant_attribute ) {
725
  $merchant_attribute = 'tax(country:region:rate:tax_ship)';
726
  }
727
+
728
  $attributeValue = $this->processStringForCSV( $attributeValue );
729
+
730
  } elseif ( 'txt' == $feedType ) {
731
  $merchant_attribute = woo_feed_replace_to_merchant_attribute( $merchant_attribute, $merchant, $feedType );
732
  $merchant_attribute = $this->processStringForTXT( $merchant_attribute );
733
+
734
  if ( "shipping" === $merchant_attribute && 'bing' == $this->config['provider'] ) {
735
  $merchant_attribute = 'shipping(country:service:price)';
736
  } elseif ( "shipping" === $merchant_attribute ) {
737
  $merchant_attribute = 'shipping(country:region:service:price)';
738
  }
739
+
740
  if ( "tax" === $merchant_attribute ) {
741
  $merchant_attribute = 'tax(country:region:rate:tax_ship)';
742
  }
743
+
744
  $attributeValue = $this->processStringForTXT( $attributeValue );
745
  }
746
+
747
  $this->products[ $this->pi ][ $merchant_attribute ] = $attributeValue;
748
  }
749
  }
750
+
751
  /**
752
  * Process Nested Attributes
753
  *
762
  'product_url' => [ 'products', 'product', 'product_url' ],
763
  ];
764
  }
765
+
766
  /**
767
  * Process Nested Attributes
768
  *
773
  * @since 4.0.5
774
  *
775
  */
776
+
777
  protected function nested_attributes_element( $attribute, $content ) {
778
  $starter = '';
779
  $finisher = '';
780
  $element = '';
781
+
782
  if ( empty( $attribute ) ) {
783
  return $attribute;
784
  }
785
+
786
  $attr_names = $this->feed_nested_attributes();
787
+
788
  foreach ( $attr_names as $key => $value ) {
789
  if ( $key === $attribute ) {
790
  //starter tags element
791
  foreach ( $value as $item_value ) {
792
  $starter .= '<' . strval( $item_value ) . '>';
793
  }
794
+
795
  //finishing tags element
796
  $rev_value = array_reverse( $value );
797
  foreach ( $rev_value as $item_value ) {
799
  }
800
  }
801
  }
802
+
803
  $element = $starter . $content . $finisher;
804
+
805
  return $element;
806
  }
807
+
808
  /**
809
  * Check if current product should be processed for feed
810
  * This should be using by Woo_Feed_Products_v3::get_products()
819
  // Skip for invalid products
820
  if ( ! is_object( $product ) ) {
821
  woo_feed_log_feed_process( $this->config['filename'], 'Skipping Product :: Product data is not a valid WC_Product object.' );
822
+
823
  return true;
824
  }
825
+
826
  // For WP_Query check available product types
827
  if ( 'wp' == $this->queryType && ! in_array( $product->get_type(), $this->product_types, true ) ) {
828
  woo_feed_log_feed_process( $this->config['filename'], sprintf( 'Skipping Product :: Invalid Post/Product Type : %s.', $product->get_type() ) );
829
+
830
  return true;
831
  }
832
+
833
  // Skip orphaned variation
834
  if ( $product->is_type( 'variation' ) && ! $product->get_parent_id() ) {
835
  woo_feed_log_feed_process( $this->config['filename'], sprintf( 'Skipping Product :: Orphaned variation product [id: %s] skipped.', $product->get_id() ) );
836
+
837
  return true;
838
  }
839
+
840
  // Skip for invisible products
841
  if ( ! $product->is_visible() ) {
842
  woo_feed_log_feed_process( $this->config['filename'], 'Skipping Product :: Product is not visible.' );
843
+
844
  return true;
845
  }
846
+
847
  return false;
848
  }
849
+
850
  /**
851
  * Check if current attribute/merchant attribute should be processed for feed
852
  * This should be using by Woo_Feed_Products_v3::get_products()
862
  *
863
  */
864
  protected function exclude_current_attribute( $product, $merchant_attribute, $product_attribute, $feedType = 'xml' ) {
865
+
866
  if ( empty( $merchant_attribute ) ) {
867
  return true;
868
  }
869
+
870
  if (
871
  in_array( $this->config['provider'], array_keys( $this->skipped_merchant_attributes ) ) &&
872
  in_array( $merchant_attribute, $this->skipped_merchant_attributes[ $this->config['provider'] ] )
873
+
874
  ) {
875
  return true;
876
  }
877
+
878
  if ( 'shopping_ads_excluded_country' !== $merchant_attribute && in_array( $merchant_attribute, $this->processed_merchant_attributes ) ) {
879
  return true;
880
  }
881
+
882
  $this->processed_merchant_attributes[] = $merchant_attribute;
883
+
884
  return false;
885
  }
886
+
887
  /**
888
  * Wrapper for substr with <![CDATA[string]]> support
889
  *
907
  $string = substr( $string, $start, $limit );
908
  }
909
  }
910
+
911
  return $string;
912
  }
913
+
914
  /**
915
  * Process feed data according to merchant uncommon requirements like Google
916
  *
937
  $pd = 0;
938
  $up = 0; //Unit Price for facebook
939
  $av = 0; //Additional Variant Attribute for facebook
940
+
941
+
942
  // Format Shipping and Tax data for CSV and TXT feed only for google and facebook
943
+
944
  if ( 'xml' != $this->config['feedType'] && in_array( $this->config['provider'], array(
945
  'google',
946
  'facebook',
949
  'pinterest'
950
  ) ) ) {
951
  foreach ( $merchantAttributes as $key => $value ) {
952
+
953
  if ( ! in_array( $value, $this->google_shipping_tax, true ) ) {
954
  continue;
955
  }
956
+
957
  # Get value by attribute type with prefix & suffix
958
  $output = $this->process_for_merchant_get_value( $productObj, $key );
959
+
960
  if ( 'shipping_country' == $value ) {
961
  $s ++;
962
  $shipping .= $output;
972
  if ( 'shipping_price' == $value ) {
973
  $shipping .= ':' . $output;
974
  }
975
+
976
  if ( 'section_name' == $value ) {
977
  $pd ++;
978
  $product_detail .= $output;
983
  if ( 'attribute_value' == $value ) {
984
  $product_detail .= ':' . $output;
985
  }
986
+
987
  //facebook nested attributes
988
  if ( isset( $this->config['provider'] ) && "facebook" === $this->config['provider'] ) {
989
  if ( 'unit_price_value' == $value ) {
996
  if ( 'unit_price_unit' == $value ) {
997
  $unit_price .= ':' . $output;
998
  }
999
+
1000
  if ( 'additional_variant_label' == $value ) {
1001
  $av ++;
1002
  $additional_variant_attribute .= $output;
1004
  if ( 'additional_variant_value' == $value ) {
1005
  $additional_variant_attribute .= ':' . $output;
1006
  }
1007
+
1008
  if ( 0 < $up ) {
1009
  $this->products[ $this->pi ]["unit_price"] = $unit_price;
1010
  }
1011
+
1012
  if ( 0 < $av ) {
1013
  $this->products[ $this->pi ]["additional_variant_attribute"] = $additional_variant_attribute;
1014
  }
1015
  }
1016
+
1017
+
1018
  if ( 'installment_months' == $value ) {
1019
  $ins ++;
1020
  $installment .= $output;
1022
  if ( 'installment_amount' == $value ) {
1023
  $installment .= ':' . $output;
1024
  }
1025
+
1026
  if ( 'subscription_period' == $value ) {
1027
  $sub ++;
1028
  $subscription .= $output;
1034
  $subscription .= ':' . $output;
1035
  }
1036
  }
1037
+
1038
  if ( 0 < $pd ) {
1039
  $this->products[ $this->pi ]["product detail"] = $product_detail;
1040
  }
1041
+
1042
  if ( 0 < $sub ) {
1043
  $this->products[ $this->pi ]["subscription cost"] = $subscription;
1044
+
1045
  }
1046
+
1047
  if ( 0 < $ins ) {
1048
  $this->products[ $this->pi ]["installment"] = $installment;
1049
  }
1050
  }
1051
+
1052
+
1053
  if ( in_array( $this->config['provider'], array( 'google', 'facebook', 'snapchat', 'bing', 'pinterest' ) ) ) {
1054
+
1055
+
1056
  // Reformat Shipping attributes for google, facebook
1057
  if ( 'xml' == $this->config['feedType'] ) {
1058
  foreach ( $merchantAttributes as $key => $value ) {
1059
+
1060
  if ( ! in_array( $value, $this->google_shipping_tax ) ) {
1061
  continue;
1062
  }
1063
+
1064
+
1065
  # Get value by attribute type with prefix & suffix
1066
  $output = $this->process_for_merchant_get_value( $productObj, $key );
1067
+
1068
+
1069
  if ( 'shipping_country' == $value ) {
1070
  if ( 0 == $s ) {
1071
  $shipping .= '<g:shipping>';
1083
  $shipping .= '<g:shipping>';
1084
  }
1085
  }
1086
+
1087
  if ( 'shipping_country' == $value ) {
1088
  $shipping .= '<g:country>' . $output . '</g:country>' . "\n";
1089
  } elseif ( 'shipping_region' == $value ) {
1125
  } elseif ( 'subscription_amount' == $value ) {
1126
  $subscription .= '<g:amount>' . $output . '</g:amount>' . "\n";
1127
  }
1128
+
1129
  if ( 'section_name' == $value ) {
1130
  if ( 0 == $pd ) {
1131
  $product_detail .= '<g:product_detail>';
1143
  $product_detail .= '<g:product_detail>';
1144
  }
1145
  }
1146
+
1147
  if ( 'section_name' == $value ) {
1148
  $product_detail .= '<g:section_name>' . $output . '</g:section_name>' . "\n";
1149
  } elseif ( 'attribute_name' == $value ) {
1151
  } elseif ( 'attribute_value' == $value ) {
1152
  $product_detail .= '<g:attribute_value>' . $output . '</g:attribute_value>' . "\n";
1153
  }
1154
+
1155
  if ( isset( $this->config['provider'] ) && "facebook" === $this->config['provider'] ) {
1156
+
1157
  // unit_price configure
1158
  if ( 'unit_price_value' == $value ) {
1159
  if ( 0 == $up ) {
1172
  $unit_price .= '<unit_price>';
1173
  }
1174
  }
1175
+
1176
  if ( 'unit_price_value' == $value ) {
1177
  $unit_price .= '<value>' . $output . '</value>' . "\n";
1178
  } elseif ( 'unit_price_currency' == $value ) {
1180
  } elseif ( 'unit_price_unit' == $value ) {
1181
  $unit_price .= '<unit>' . $output . '</unit>' . "\n";
1182
  }
1183
+
1184
  // additional_variant_attribute configure
1185
  if ( 'additional_variant_label' == $value ) {
1186
  if ( 0 == $av ) {
1199
  $additional_variant_attribute .= '<additional_variant_attribute>';
1200
  }
1201
  }
1202
+
1203
  if ( 'additional_variant_label' == $value ) {
1204
  $additional_variant_attribute .= '<label>' . $output . '</label>' . "\n";
1205
  } elseif ( 'additional_variant_value' == $value ) {
1206
  $additional_variant_attribute .= '<value>' . $output . '</value>' . "\n";
1207
  }
1208
  }
1209
+
1210
+
1211
  if ( 'installment_months' === $value ) {
1212
  if ( 0 == $ins ) {
1213
  $installment .= '<g:installment>';
1221
  $installment .= '<g:amount>' . $output . '</g:amount>' . "\n";
1222
  }
1223
  }
1224
+
1225
  if ( 1 == $pd ) {
1226
  $product_detail .= '</g:product_detail>';
1227
  }
1228
+
1229
  if ( isset( $this->config['provider'] ) && "facebook" === $this->config['provider'] ) {
1230
  if ( 1 == $up ) {
1231
  $unit_price .= '</unit_price>';
1232
  }
1233
+
1234
  if ( 1 == $av ) {
1235
  $additional_variant_attribute .= '</additional_variant_attribute>';
1236
  }
1237
+
1238
  $this->feedBody .= $unit_price;
1239
  $this->feedBody .= $additional_variant_attribute;
1240
  }
1241
+
1242
  if ( 1 == $s ) {
1243
  $shipping .= '</g:shipping>';
1244
  }
1245
  if ( 1 == $t ) {
1246
  $tax .= '</g:tax>';
1247
  }
1248
+
1249
  if ( 1 == $sub ) {
1250
  $subscription .= '</g:subscription_cost>';
1251
  }
1252
+
1253
  if ( 1 == $ins ) {
1254
  $installment .= '</g:installment>';
1255
  }
1256
+
1257
  //$this->feedBody .= $shipping;
1258
  //$this->feedBody .= $tax;
1259
  $this->feedBody .= $product_detail;
1260
  $this->feedBody .= $installment;
1261
+
1262
  if ( $productObj->is_type( 'subscription' ) ||
1263
  $productObj->is_type( 'variable-subscription' ) ||
1264
  $productObj->is_type( 'subscription_variation' ) ) {
1288
  $countIdentifier ++;
1289
  }
1290
  }
1291
+
1292
  if ( 'xml' == $this->config['feedType'] ) {
1293
  if ( $countIdentifier >= 2 ) {
1294
  $this->feedBody .= '<g:identifier_exists>yes</g:identifier_exists>';
1300
  if ( in_array( $this->config['provider'], array( 'bing', 'pinterest' ) ) ) {
1301
  $identifier_exists = 'identifier_exists';
1302
  }
1303
+
1304
  if ( $countIdentifier >= 2 ) {
1305
  $this->products[ $this->pi ][ $identifier_exists ] = 'yes';
1306
  } else {
1310
  }
1311
  }
1312
  }
1313
+
1314
  private function process_for_merchant_get_value( $productObj, $key ) {
1315
  $prefix = $this->config['prefix'][ $key ];
1316
  $suffix = $this->config['suffix'][ $key ];
1317
  $attribute = $this->config['attributes'][ $key ];
1318
  $merchant_attribute = $this->config['mattributes'][ $key ];
1319
+
1320
  if ( 'pattern' == $this->config['type'][ $key ] ) {// Get Pattern value.
1321
  $output = $this->config['default'][ $key ];
1322
  $output = $this->apply_filters_to_attribute_value( $output, $productObj, $attribute, $merchant_attribute );
1323
  } else {
1324
  $output = $this->getAttributeValueByType( $productObj, $attribute, $merchant_attribute );
1325
  }
1326
+
1327
  $output = $this->format_output( $output, $this->config['output_type'], $productObj, $attribute, $merchant_attribute );
1328
+
1329
  $output = $this->process_prefix_suffix( $output, $prefix, $suffix, $attribute = '' );
1330
+
1331
  return $output;
1332
  }
1333
+
1334
  /**
1335
  * Get Query Type Settings
1336
  *
1339
  public function get_query_type() {
1340
  return $this->queryType;
1341
  }
1342
+
1343
  public function get_product_types() {
1344
  return $this->product_types;
1345
  }
1346
+
1347
  /**
1348
  * Generate TXT Feed Header
1349
  *
1358
  } else {
1359
  $this->delimiter = $this->config['delimiter'];
1360
  }
1361
+
1362
  // Set Enclosure
1363
  if ( ! empty( $this->config['enclosure'] ) ) {
1364
  $this->enclosure = $this->config['enclosure'];
1372
  } else {
1373
  $this->enclosure = '';
1374
  }
1375
+
1376
  $eol = PHP_EOL;
1377
  if ( 'trovaprezzi' === $this->config['provider'] ) {
1378
  $eol = '<endrecord>' . PHP_EOL;
1379
  }
1380
+
1381
  $product = $this->products[ $this->pi ];
1382
+
1383
  $headers = array_keys( $product );
1384
+
1385
  $this->feedHeader .= $this->enclosure . implode( "$this->enclosure$this->delimiter$this->enclosure", $headers ) . $this->enclosure . $eol;
1386
+
1387
  if ( 'google' === $this->config['provider'] ) {
1388
  $this->feedHeader = str_replace( $this->google_product_highlights, 'product highlight', $this->feedHeader );
1389
  $this->feedHeader = str_replace( $this->google_additional_image, 'additional image link', $this->feedHeader );
1390
  }
1391
+
1392
  return $this->feedHeader;
1393
  }
1394
+
1395
  /**
1396
  * Generate TXT Feed Body
1397
  *
1406
  $eol = '<endrecord>' . PHP_EOL;
1407
  }
1408
  $this->feedBody .= $this->enclosure . implode( "$this->enclosure$this->delimiter$this->enclosure", $productInfo ) . $this->enclosure . $eol;
1409
+
1410
  return $this->feedBody;
1411
  }
1412
+
1413
  /**
1414
  * Generate CSV Feed Header
1415
  *
1424
  } else {
1425
  $this->delimiter = $this->config['delimiter'];
1426
  }
1427
+
1428
  // Set Enclosure
1429
  if ( ! empty( $this->config['enclosure'] ) ) {
1430
  $this->enclosure = $this->config['enclosure'];
1438
  } else {
1439
  $this->enclosure = '';
1440
  }
1441
+
1442
  $product = $this->products[ $this->pi ];
1443
+
1444
  $this->feedHeader = array_keys( $product );
1445
+
1446
  if ( 'google' === $this->config['provider'] ) {
1447
  $this->feedHeader = str_replace( $this->google_product_highlights, 'product highlight', $this->feedHeader );
1448
  $this->feedHeader = str_replace( $this->google_additional_image, 'additional image link', $this->feedHeader );
1449
  }
1450
+
1451
  return $this->feedHeader;
1452
  }
1453
+
1454
  /**
1455
  * Generate CSV Feed Body
1456
  *
1460
  protected function process_csv_feed_body() {
1461
  $product = $this->products[ $this->pi ];
1462
  $this->feedBody[] = array_values( $product );
1463
+
1464
  return $this->feedBody;
1465
  }
1466
+
1467
  protected function process_json_feed_body() {
1468
  $product = $this->products[ $this->pi ];
1469
  $this->feedBody[] = $product;
1470
+
1471
  return $this->feedBody;
1472
  }
1473
+
1474
  protected function process_xml_wrapper() {
1475
  $itemsWrapperClose = explode( ' ', $this->config['itemsWrapper'] );
1476
  $itemsWrapperClose = $itemsWrapperClose[0];
1480
  ];
1481
  $this->config['itemWrapper'] = str_replace( ' ', '_', $this->config['itemWrapper'] );
1482
  $this->config['itemsWrapper'] = str_replace( ' ', '_', $this->config['itemsWrapper'] );
1483
+
1484
  if ( file_exists( WOO_FEED_FREE_ADMIN_PATH . 'partials/templates/' . $this->config['provider'] . '.txt' ) ) {
1485
  $txt = file_get_contents( WOO_FEED_FREE_ADMIN_PATH . 'partials/templates/' . $this->config['provider'] . '.txt' );
1486
  $txt = trim( $txt );
1490
  $this->xml_wrapper['footer'] = "\n" . trim( $txt[1] );
1491
  }
1492
  }
1493
+
1494
  if ( ! empty( $this->config['extraHeader'] ) ) {
1495
  $this->xml_wrapper['header'] .= PHP_EOL . $this->config['extraHeader'];
1496
  }
1497
+
1498
  // replace template variables.
1499
  $datetime_now = date( 'Y-m-d H:i:s', strtotime( current_time( 'mysql' ) ) ); // {DateTimeNow}
1500
  if ( 'pinterest_rss' === $this->config['provider'] ) { // DATE_RFC822 date format for pinterest rss feed
1505
  //$blog_desc = get_bloginfo('description'); // {BlogDescription}
1506
  $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}
1507
  $blog_email = get_bloginfo( 'admin_email' ); // {BlogEmail}
1508
+
1509
  $this->xml_wrapper['header'] = str_replace(
1510
  [ '{DateTimeNow}', '{BlogName}', '{BlogURL}', '{BlogDescription}', '{BlogEmail}' ],
1511
  [ $datetime_now, $blog_name, $blog_url, $blog_desc, $blog_email ],
1512
  $this->xml_wrapper['header']
1513
  );
1514
  }
1515
+
1516
  /**
1517
  * Make XML feed header
1518
  *
1522
  protected function process_xml_feed_header() {
1523
  return $this->xml_wrapper['header'];
1524
  }
1525
+
1526
  /**
1527
  * Make XML feed header
1528
  *
1532
  protected function process_xml_feed_footer() {
1533
  return $this->xml_wrapper['footer'];
1534
  }
1535
+
1536
  /**
1537
  * Process string for TXT CSV Feed
1538
  *
1545
  protected function processStringForTXT( $string ) {
1546
  if ( ! empty( $string ) ) {
1547
  $string = html_entity_decode( $string, ENT_HTML401 | ENT_QUOTES ); // Convert any HTML entities
1548
+
1549
  if ( stristr( $string, '"' ) ) {
1550
  $string = str_replace( '"', '""', $string );
1551
  }
1554
  $string = str_replace( "\t", ' ', $string );
1555
  $string = trim( $string );
1556
  $string = stripslashes( $string );
1557
+
1558
  return $string;
1559
  } elseif ( '0' == $string ) {
1560
  return '0';
1562
  return '';
1563
  }
1564
  }
1565
+
1566
  /**
1567
  * Process string for CSV
1568
  *
1578
  $string = str_replace( "\r", ' ', $string );
1579
  $string = trim( $string );
1580
  $string = stripslashes( $string );
1581
+
1582
  return $string;
1583
  } elseif ( '0' == $string ) {
1584
  return '0';
1586
  return '';
1587
  }
1588
  }
1589
+
1590
  /**
1591
  * Get Product Attribute Value by Type
1592
  *
1598
  *
1599
  */
1600
  public function getAttributeValueByType( $product, $attribute, $merchant_attribute = '' ) {
1601
+
1602
  if ( method_exists( $this, $attribute ) ) {
1603
  $output = $this->$attribute( $product );
1604
  } elseif ( false !== strpos( $attribute, self::PRODUCT_ACF_FIELDS ) ) {
1635
  // return the attribute so multiple attribute can be join with separator to make custom attribute.
1636
  $output = $attribute;
1637
  }
1638
+
1639
  // Json encode if value is an array
1640
  if ( is_array( $output ) ) {
1641
  $output = wp_json_encode( $output );
1642
  }
1643
+
1644
  $output = $this->apply_filters_to_attribute_value( $output, $product, $attribute, $merchant_attribute );
1645
+
1646
  return $output;
1647
  }
1648
+
1649
  /**
1650
  * Apply Filter to Attribute value
1651
  *
1668
  *
1669
  */
1670
  $output = apply_filters( 'woo_feed_get_attribute', $output, $product, $this->config, $merchant_attribute );
1671
+
1672
  /**
1673
  * Filter attribute value before return based on attribute name
1674
  *
1680
  *
1681
  */
1682
  $output = apply_filters( "woo_feed_get_{$attribute}_attribute", $output, $product, $this->config );
1683
+
1684
  /**
1685
  * Filter attribute value before return based on merchant and attribute name
1686
  *
1692
  *
1693
  */
1694
  $output = apply_filters( "woo_feed_get_{$this->config['provider']}_{$attribute}_attribute", $output, $product, $this->config );
1695
+
1696
  return $output;
1697
  }
1698
+
1699
+
1700
  /**
1701
  * Get Product Id
1702
  *
1708
  */
1709
  protected function id( $product ) {
1710
  $id = $product->get_id();
1711
+
1712
  return apply_filters( 'woo_feed_filter_product_id', $id, $product, $this->config );
1713
  }
1714
+
1715
  /**
1716
  * Get Product Title
1717
  *
1723
  */
1724
  protected function title( $product ) {
1725
  $title = woo_feed_strip_all_tags( $this->remove_short_codes( $product->get_name() ) );
1726
+
1727
  // Add all available variation attributes to variation title.
1728
  if ( $product->is_type( 'variation' ) && ! empty( $product->get_attributes() ) ) {
1729
  $title = $this->parent_title( $product );
1735
  }
1736
  $attributes[ $slug ] = $attribute;
1737
  }
1738
+
1739
  // set variation attributes with separator
1740
  if ( isset( $this->config['provider'] ) && 'google' === $this->config['provider'] ) {
1741
  $variation_attributes = implode( ' - ', $attributes );
1742
  } else {
1743
  $variation_attributes = implode( ', ', $attributes );
1744
  }
1745
+
1746
  //get product title with variation attribute
1747
  $get_with_var_attributes = apply_filters( "woo_feed_get_product_title_with_variation_attribute", true, $product, $this->config );
1748
+
1749
  if ( $get_with_var_attributes ) {
1750
  $title .= " - " . $variation_attributes;
1751
  }
1752
  }
1753
+
1754
  return apply_filters( 'woo_feed_filter_product_title', $title, $product, $this->config );
1755
  }
1756
+
1757
  /**
1758
  * Get Parent Product Title
1759
  *
1770
  } else {
1771
  $title = $this->title( $product );
1772
  }
1773
+
1774
  return apply_filters( 'woo_feed_filter_product_parent_title', $title, $product, $this->config );
1775
  }
1776
+
1777
  /**
1778
  * Get All in One SEO Canonical URL
1779
  *
1788
  $post = AIOSEO\Plugin\Common\Models\Post::getPost( $product->get_id() );
1789
  $aioseop_canonical_url = $post->canonical_url;
1790
  }
1791
+
1792
  return apply_filters( 'woo_feed_filter_product_aioseop_canonical_url', $aioseop_canonical_url, $product, $this->config );
1793
  }
1794
+
1795
  /**
1796
  * Get Yoast Product Title
1797
  *
1810
  $title = get_the_title( $product_id );
1811
  }
1812
  $wpseo_titles = get_option( 'wpseo_titles' );
1813
+
1814
  $sep_options = WPSEO_Option_Titles::get_instance()->get_separator_options();
1815
  if ( isset( $wpseo_titles['separator'] ) && isset( $sep_options[ $wpseo_titles['separator'] ] ) ) {
1816
  $sep = $sep_options[ $wpseo_titles['separator'] ];
1817
  } else {
1818
  $sep = '-'; //setting default separator if Admin didn't set it from backed
1819
  }
1820
+
1821
  $site_title = get_bloginfo( 'name' );
1822
+
1823
  $meta_title = $title . ' ' . $sep . ' ' . $site_title;
1824
+
1825
  if ( ! empty( $meta_title ) ) {
1826
  $title = $meta_title;
1827
  }
1830
  } else {
1831
  $title = $this->title( $product );
1832
  }
1833
+
1834
  return apply_filters( 'woo_feed_filter_product_yoast_wpseo_title', $title, $product, $this->config );
1835
  }
1836
+
1837
  /**
1838
  * Get Yoast Canonical URL
1839
  *
1845
  protected function yoast_canonical_url( $product ) {
1846
  $product_id = woo_feed_parent_product_id( $product );
1847
  $yoast_canonical_url = get_post_meta( $product_id, '_yoast_wpseo_canonical', true );
1848
+
1849
  return apply_filters( 'woo_feed_filter_product_yoast_canonical_url', $yoast_canonical_url, $product, $this->config );
1850
  }
1851
+
1852
  /**
1853
  * Get Rank Math Product Title
1854
  *
1869
  $title_format = Helper::get_settings( "titles.pt_product_title" );
1870
  $title_format = $title_format ? $title_format : '%title%';
1871
  $sep = Helper::get_settings( 'titles.title_separator' );
1872
+
1873
  $rank_title = str_replace( '%title%', $product->get_title(), $title_format );
1874
  $rank_title = str_replace( '%sep%', $sep, $rank_title );
1875
  $rank_title = str_replace( '%page%', '', $rank_title );
1878
  $rank_title = $title;
1879
  }
1880
  }
1881
+
1882
  return apply_filters( 'woo_feed_filter_product_rank_math_title', $rank_title, $product, $this->config );
1883
  }
1884
+
1885
  /**
1886
  * Get Rank Math Product Description
1887
  *
1895
  if ( class_exists( 'RankMath' ) ) {
1896
  $description = get_post_meta( $product->get_id(), 'rank_math_description' );
1897
  $desc_format = Helper::get_settings( "titles.pt_post_description" );
1898
+
1899
  if ( empty( $description ) ) {
1900
  if ( ! empty( $desc_format ) && strpos( (string) $desc_format, 'excerpt' ) !== false ) {
1901
  $description = str_replace( '%excerpt%', get_the_excerpt( $product->get_id() ), $desc_format );
1902
  }
1903
+
1904
  // Get Variation Description
1905
  if ( $product->is_type( 'variation' ) && empty( $description ) ) {
1906
  $parent = wc_get_product( $product->get_parent_id() );
1907
  $description = $parent->get_description();
1908
  }
1909
  }
1910
+
1911
  if ( is_array( $description ) ) {
1912
  $description = reset( $description );
1913
  }
1914
+
1915
  $description = $this->remove_short_codes( $description );
1916
+
1917
  //strip tags and spacial characters
1918
  $strip_description = woo_feed_strip_all_tags( wp_specialchars_decode( $description ) );
1919
+
1920
  $description = ! empty( strlen( $strip_description ) ) && 0 < strlen( $strip_description ) ? $strip_description : $description;
1921
  }
1922
+
1923
  return apply_filters( 'woo_feed_filter_product_rank_math_description', $description, $product, $this->config );
1924
  }
1925
+
1926
  /**
1927
  * Get Rank Math Canonical URL
1928
  *
1933
  */
1934
  protected function rank_math_canonical_url( $product ) {
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
  *
1964
  protected function _aioseop_title( $product ) {
1965
  $title = '';
1966
  if ( is_plugin_active( 'all-in-one-seo-pack/all_in_one_seo_pack.php' ) && class_exists( 'AIOSEO\Plugin\Common\Models\Post' ) ) {
1967
+
1968
  $post = AIOSEO\Plugin\Common\Models\Post::getPost( $product->get_id() );
1969
  $title = ! empty( $post->title ) ? $post->title : aioseo()->meta->title->getPostTypeTitle( 'product' );
1970
  }
1971
+
1972
  $title = ! empty( $title ) ? $title : $this->title( $product );
1973
+
1974
  return apply_filters( 'woo_feed_filter_product_aioseop_title', $title, $product, $this->config );
1975
  }
1976
+
1977
  /**
1978
  * Get Product Description
1979
  *
1986
  */
1987
  protected function description( $product ) {
1988
  $description = $product->get_description();
1989
+
1990
  // Get Variation Description
1991
  if ( $product->is_type( 'variation' ) && empty( $description ) ) {
1992
  $parent = wc_get_product( $product->get_parent_id() );
1993
+
1994
  if ( is_object( $parent ) ) {
1995
  $description = $parent->get_description();
1996
  } else {
1998
  }
1999
  }
2000
  $description = $this->remove_short_codes( $description );
2001
+
2002
  // Add variations attributes after description to prevent Facebook error
2003
  if ( 'facebook' == $this->config['provider'] && $product->is_type( 'variation' ) ) {
2004
  $variationInfo = explode( '-', $product->get_name() );
2009
  }
2010
  $description .= ' ' . $extension;
2011
  }
2012
+
2013
  //strip tags and spacial characters
2014
  $strip_description = woo_feed_strip_all_tags( wp_specialchars_decode( $description ) );
2015
+
2016
  $description = ! empty( strlen( $strip_description ) ) && 0 < strlen( $strip_description ) ? $strip_description : $description;
2017
+
2018
  return apply_filters( 'woo_feed_filter_product_description', $description, $product, $this->config );
2019
  }
2020
+
2021
  /**
2022
  * Get Product Description (with HTML)
2023
  *
2029
  */
2030
  protected function description_with_html( $product ) {
2031
  $description = $product->get_description();
2032
+
2033
  // Get Variation Description
2034
  if ( $product->is_type( 'variation' ) && empty( $description ) ) {
2035
  $parent = wc_get_product( $product->get_parent_id() );
2036
  $description = $parent->get_description();
2037
  }
2038
  $description = $this->remove_short_codes( $description );
2039
+
2040
  // Add variations attributes after description to prevent Facebook error
2041
  if ( 'facebook' === $this->config['provider'] && $product->is_type( 'variation' ) ) {
2042
  $variationInfo = explode( '-', $product->get_name() );
2047
  }
2048
  $description .= ' ' . $extension;
2049
  }
2050
+
2051
  //remove spacial characters
2052
  $strip_description = wp_check_invalid_utf8( wp_specialchars_decode( $description ), true );
2053
+
2054
  return apply_filters( 'woo_feed_filter_product_description_with_html', $description, $product, $this->config );
2055
  }
2056
+
2057
  /**
2058
  * Get Yoast Product Description
2059
  *
2072
  } else {
2073
  $description = YoastSEO()->meta->for_post( $product_id )->description;
2074
  }
2075
+
2076
  if ( empty( $description ) ) {
2077
  $description = $this->description( $product );
2078
  }
2079
+
2080
  return apply_filters( 'woo_feed_filter_product_yoast_wpseo_metadesc', $description, $product, $this->config );
2081
  }
2082
+
2083
  /**
2084
  * Get All In One Product Description
2085
  *
2091
  */
2092
  protected function _aioseop_description( $product ) {
2093
  $description = '';
2094
+
2095
  if ( is_plugin_active( 'all-in-one-seo-pack/all_in_one_seo_pack.php' ) && class_exists( 'AIOSEO\Plugin\Common\Models\Post' ) ) {
2096
+
2097
  $post = AIOSEO\Plugin\Common\Models\Post::getPost( $product->get_id() );
2098
  $description = ! empty( $post->description ) ? $post->description : aioseo()->meta->description->getPostTypeDescription( 'product' );
2099
  }
2100
+
2101
  if ( empty( $description ) ) {
2102
  $description = $this->description( $product );
2103
  }
2104
+
2105
  return apply_filters( 'woo_feed_filter_product_aioseop_description', $description, $product, $this->config );
2106
  }
2107
+
2108
  /**
2109
  * Get Product Short Description
2110
  *
2116
  */
2117
  protected function short_description( $product ) {
2118
  $short_description = $product->get_short_description();
2119
+
2120
  // Get Variation Short Description
2121
  if ( $product->is_type( 'variation' ) && empty( $short_description ) ) {
2122
  $parent = wc_get_product( $product->get_parent_id() );
2123
  $short_description = $parent->get_short_description();
2124
  }
2125
+
2126
+
2127
  $short_description = $this->remove_short_codes( $short_description );
2128
+
2129
  //strip tags and spacial characters
2130
  $short_description = woo_feed_strip_all_tags( wp_specialchars_decode( $short_description ) );
2131
+
2132
  return apply_filters( 'woo_feed_filter_product_short_description', $short_description, $product, $this->config );
2133
  }
2134
+
2135
+
2136
  /**
2137
  * At First convert Short Codes and then Remove failed Short Codes from String
2138
  *
2146
  if ( $content == '' ) {
2147
  return '';
2148
  }
2149
+
2150
  $content = do_shortcode( $content );
2151
+
2152
  $content = woo_feed_stripInvalidXml( $content );
2153
+
2154
  // Covers all kinds of shortcodes
2155
  $expression = '/\[\/*[a-zA-Z1-90_| -=\'"\{\}]*\/*\]/m';
2156
+
2157
  $content = preg_replace( $expression, '', $content );
2158
+
2159
  return strip_shortcodes( $content );
2160
  }
2161
+
2162
  /*
2163
  * Retrieves product's parent category
2164
  *
2172
  if ( empty( $parent_category_memo ) ) {
2173
  $parent_category_memo = [];
2174
  }
2175
+
2176
  $id = $product->get_id();
2177
  if ( $product->is_type( 'variation' ) ) {
2178
  $id = $product->get_parent_id();
2179
  }
2180
+
2181
  $taxonomy = 'product_cat';
2182
  $categories = wp_get_post_terms( $id, $taxonomy );
2183
  $child_category = $categories[ count( $categories ) - 1 ]; // Last selected category
2184
+
2185
  $parent_category = '';
2186
+
2187
  // Memoization for faster parent retrieval
2188
  if (
2189
  isset( $parent_category_memo[ $child_category->term_id ] )
2194
  $parent_category = woo_feed_parent_category( $child_category, $taxonomy );
2195
  $parent_category_memo[ $child_category->term_id ] = $parent_category->term_id;
2196
  }
2197
+
2198
  // Yoast SEO primary term fetching
2199
  if ( class_exists( 'WPSEO_Primary_Term' ) ) {
2200
  $wpseo_primary_term = new WPSEO_Primary_Term( $taxonomy, $id );
2203
  $parent_category = get_term_by( 'term_id', $parent_category_id, $taxonomy );
2204
  }
2205
  }
2206
+
2207
  return $parent_category;
2208
  }
2209
+
2210
  /**
2211
  * Get Product Parent/Main Category
2212
  *
2223
  $full_category_array = explode( $separator, $full_category );
2224
  $parent_category = $full_category_array[0];
2225
  }
2226
+
2227
  return apply_filters( 'woo_feed_filter_product_primary_category', $parent_category, $product, $this->config );
2228
  }
2229
+
2230
  /**
2231
  * Get Product Parent/Main Category ID
2232
  *
2244
  $parent_category_obj = get_term_by( 'name', $full_category_array[0], 'product_cat' );
2245
  $parent_category_id = isset( $parent_category_obj->term_id ) ? $parent_category_obj->term_id : "";
2246
  }
2247
+
2248
  return apply_filters( 'woo_feed_filter_product_primary_category_id', $parent_category_id, $product, $this->config );
2249
  }
2250
+
2251
  /**
2252
  * Get Product Child Category
2253
  *
2263
  $full_category_array = explode( $separator, $full_category );
2264
  $child_category = end( $full_category_array );
2265
  }
2266
+
2267
  return apply_filters( 'woo_feed_filter_product_child_category', $child_category, $product, $this->config );
2268
  }
2269
+
2270
  /**
2271
  * Get Product Child Category ID
2272
  *
2283
  $child_category_obj = get_term_by( 'name', end( $full_category_array ), 'product_cat' );
2284
  $child_category_id = isset( $child_category_obj->term_id ) ? $child_category_obj->term_id : "";
2285
  }
2286
+
2287
  return apply_filters( 'woo_feed_filter_product_child_category_id', $child_category_id, $product, $this->config );
2288
  }
2289
+
2290
  /**
2291
  * Get Product Categories
2292
  *
2301
  if ( $product->is_type( 'variation' ) ) {
2302
  $id = $product->get_parent_id();
2303
  }
2304
+
2305
  $separator = apply_filters( 'woo_feed_product_type_separator', ' > ', $this->config, $product );
2306
+
2307
  $product_type = woo_feed_strip_all_tags( wc_get_product_category_list( $id, $separator ) );
2308
+
2309
  $product_categories = '';
2310
  $term_list = get_the_terms( $id, 'product_cat' );
2311
+
2312
  if ( is_array( $term_list ) ) {
2313
  $col = array_column( $term_list, "term_id" );
2314
  array_multisort( $col, SORT_ASC, $term_list );
2315
  $term_list = array_column( $term_list, "name" );
2316
  $product_categories = implode( $separator, $term_list );
2317
  }
2318
+
2319
+
2320
  return apply_filters( 'woo_feed_filter_product_local_category', $product_categories, $product, $this->config );
2321
  }
2322
+
2323
+ /**
2324
+ * @param \WC_Product $product
2325
+ *
2326
+ * @return void
2327
+ */
2328
+ public function product_status( $product ) {
2329
+ $status = $product->get_status();
2330
+ return apply_filters( 'woo_feed_filter_product_status', $status, $product, $this->config );
2331
+ }
2332
+
2333
  /**
2334
  * Get Product Full Categories with unselected category parent
2335
  *
2347
  // $separator = apply_filters('woo_feed_product_type_separator', '>', $this->config, $product);
2348
  //
2349
  // $product_type = woo_feed_get_terms_list_hierarchical_order($id);
2350
+
2351
  $product_type = $this->product_type( $product );
2352
+
2353
  return apply_filters( 'woo_feed_filter_product_local_category', $product_type, $product, $this->config );
2354
  }
2355
+
2356
  /**
2357
  * Get Product URL
2358
  *
2363
  *
2364
  */
2365
  protected function link( $product ) {
2366
+
2367
  $link = $product->get_permalink();
2368
+
2369
  $link = $this->add_utm_tracker( $link );
2370
+
2371
  return apply_filters( 'woo_feed_filter_product_link', $link, $product, $this->config );
2372
  }
2373
+
2374
  /**
2375
  * Adding UTM Tracker Query Arguments to URL
2376
  *
2380
  * @since 4.4.26
2381
  */
2382
  protected function add_utm_tracker( $url ) {
2383
+
2384
  $utm = $this->config['campaign_parameters'];
2385
+
2386
  if ( ! empty( $utm['utm_source'] ) && ! empty( $utm['utm_medium'] ) && ! empty( $utm['utm_campaign'] ) ) {
2387
+
2388
  $utm = [
2389
  'utm_source' => str_replace( ' ', '+', $utm['utm_source'] ),
2390
  'utm_medium' => str_replace( ' ', '+', $utm['utm_medium'] ),
2392
  'utm_term' => str_replace( ' ', '+', $utm['utm_term'] ),
2393
  'utm_content' => str_replace( ' ', '+', $utm['utm_content'] ),
2394
  ];
2395
+
2396
  $url = add_query_arg( array_filter( $utm ), $url );
2397
+
2398
  }
2399
+
2400
  return $url;
2401
  }
2402
+
2403
  /**
2404
  * Get Parent Product URL
2405
  *
2416
  } else {
2417
  $link = $this->link( $product );
2418
  }
2419
+
2420
  return apply_filters( 'woo_feed_filter_product_parent_link', $link, $product, $this->config );
2421
  }
2422
+
2423
  /**
2424
  * Get Canonical Link
2425
  *
2434
  } else {
2435
  $canonical_link = $product->get_permalink();
2436
  }
2437
+
2438
  return apply_filters( 'woo_feed_filter_product_canonical_link', $canonical_link, $product, $this->config );
2439
  }
2440
+
2441
  /**
2442
  * Get External Product URL
2443
  *
2458
  'utm_term' => str_replace( ' ', '+', $utm['utm_term'] ),
2459
  'utm_content' => str_replace( ' ', '+', $utm['utm_content'] ),
2460
  ];
2461
+
2462
  return add_query_arg( array_filter( $utm ), $product->get_product_url() );
2463
  } else {
2464
  $ex_link = $product->get_product_url();
2466
  } else {
2467
  $ex_link = '';
2468
  }
2469
+
2470
  return apply_filters( 'woo_feed_filter_product_ex_link', $ex_link, $product, $this->config );
2471
  }
2472
+
2473
  /**
2474
  * Get Product Image
2475
  *
2495
  $getImage = wp_get_attachment_image_src( get_post_thumbnail_id( $product->get_id() ), 'single-post-thumbnail' );
2496
  $image = isset( $getImage[0] ) ? woo_feed_get_formatted_url( $getImage[0] ) : '';
2497
  }
2498
+
2499
  return apply_filters( 'woo_feed_filter_product_image', $image, $product, $this->config );
2500
  }
2501
+
2502
  /**
2503
  * Get Product Featured Image. For product variations it will return the variable product image.
2504
  *
2515
  } else {
2516
  $id = $product->get_id();
2517
  }
2518
+
2519
  $getImage = wp_get_attachment_image_src( get_post_thumbnail_id( $id ), 'single-post-thumbnail' );
2520
  $image = isset( $getImage[0] ) ? woo_feed_get_formatted_url( $getImage[0] ) : '';
2521
+
2522
  return apply_filters( 'woo_feed_filter_product_feature_image', $image, $product, $this->config );
2523
  }
2524
+
2525
  /**
2526
  * Get Comma Separated Product Images
2527
  *
2538
  protected function images( $product, $additionalImg = '' ) {
2539
  $imgUrls = $this->get_product_gallery( $product );
2540
  $separator = ',';
2541
+
2542
  // Return Specific Additional Image URL
2543
  if ( '' !== $additionalImg ) {
2544
  if ( array_key_exists( $additionalImg, $imgUrls ) ) {
2550
  if ( isset( $this->config['provider'] ) && "idealo" === $this->config['provider'] ) {
2551
  $separator = ';';
2552
  }
2553
+
2554
  $images = implode( $separator, array_filter( $imgUrls ) );
2555
  }
2556
+
2557
  return apply_filters( 'woo_feed_filter_product_images', $images, $product, $this->config );
2558
  }
2559
+
2560
  /**
2561
  * Get Product Gallery Items (URL) array.
2562
  * This can contains empty array values
2569
  protected function get_product_gallery( $product ) {
2570
  $imgUrls = [];
2571
  $attachmentIds = [];
2572
+
2573
  if ( $product->is_type( 'variation' ) ) {
2574
  if ( class_exists( 'Woo_Variation_Gallery' ) ) {
2575
  /**
2604
  */
2605
  $var_id = $product->get_id();
2606
  $parent_id = $product->get_parent_id();
2607
+
2608
  $variation_obj = get_post_meta( $parent_id, 'woodmart_variation_gallery_data', true );
2609
  if ( isset( $variation_obj ) && isset( $variation_obj[ $var_id ] ) ) {
2610
  $attachmentIds = explode( ',', $variation_obj[ $var_id ] );
2618
  $attachmentIds = wc_get_product( $product->get_parent_id() )->get_gallery_image_ids();
2619
  }
2620
  }
2621
+
2622
  /**
2623
  * Get Variable Product Gallery Image ids if Product is not a variation
2624
  * or variation does not have any gallery images
2626
  if ( empty( $attachmentIds ) ) {
2627
  $attachmentIds = $product->get_gallery_image_ids();
2628
  }
2629
+
2630
  if ( $attachmentIds && is_array( $attachmentIds ) ) {
2631
  $mKey = 1;
2632
  foreach ( $attachmentIds as $attachmentId ) {
2634
  $mKey ++;
2635
  }
2636
  }
2637
+
2638
  return $imgUrls;
2639
  }
2640
+
2641
  /**
2642
  * Get Product Condition
2643
  *
2650
  protected function condition( $product ) {
2651
  return apply_filters( 'woo_feed_product_condition', 'new', $product );
2652
  }
2653
+
2654
  /**
2655
  * Get Product Type
2656
  *
2663
  protected function type( $product ) {
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
  *
2679
  } else {
2680
  $is_bundle = 'no';
2681
  }
2682
+
2683
  return apply_filters( 'woo_feed_filter_product_is_bundle', $is_bundle, $product, $this->config );
2684
  }
2685
+
2686
  /**
2687
  * Get Product is a multi-pack product or not
2688
  *
2697
  if ( $product->is_type( 'grouped' ) ) {
2698
  $multi_pack = ( ! empty( $product->get_children() ) ) ? count( $product->get_children() ) : '';
2699
  }
2700
+
2701
  return $multi_pack;
2702
  }
2703
+
2704
  /**
2705
  * Get Product visibility status
2706
  *
2713
  protected function visibility( $product ) {
2714
  return apply_filters( 'woo_feed_filter_product_visibility', $product->get_catalog_visibility(), $product, $this->config );
2715
  }
2716
+
2717
  /**
2718
  * Get Product Total Rating
2719
  *
2726
  protected function rating_total( $product ) {
2727
  return apply_filters( 'woo_feed_filter_product_rating_total', $product->get_rating_count(), $product, $this->config );
2728
  }
2729
+
2730
  /**
2731
  * Get Product average rating
2732
  *
2739
  protected function rating_average( $product ) {
2740
  return apply_filters( 'woo_feed_filter_product_rating_average', $product->get_average_rating(), $product, $this->config );
2741
  }
2742
+
2743
  /**
2744
  * Get Product tags
2745
  *
2754
  if ( $product->is_type( 'variation' ) ) {
2755
  $id = $product->get_parent_id();
2756
  }
2757
+
2758
  /**
2759
  * Separator for multiple tags
2760
  *
2765
  * @since 3.4.3
2766
  */
2767
  $separator = apply_filters( 'woo_feed_tags_separator', ',', $this->config, $product );
2768
+
2769
  $tags = woo_feed_strip_all_tags( get_the_term_list( $id, 'product_tag', '', $separator, '' ) );
2770
+
2771
  return apply_filters( 'woo_feed_filter_product_tags', $tags, $product, $this->config );
2772
  }
2773
+
2774
  /**
2775
  * Get Product Parent Id
2776
  *
2785
  if ( $product->is_type( 'variation' ) ) {
2786
  $id = $product->get_parent_id();
2787
  }
2788
+
2789
  return apply_filters( 'woo_feed_filter_product_item_group_id', $id, $product, $this->config );
2790
  }
2791
+
2792
  /**
2793
  * Get Product SKU
2794
  *
2801
  protected function sku( $product ) {
2802
  return apply_filters( 'woo_feed_filter_product_sku', $product->get_sku(), $product, $this->config );
2803
  }
2804
+
2805
  /**
2806
  * Get Product SKU ID. It should come with after merging of sku and product id with '_' sign.
2807
  *
2814
  protected function sku_id( $product ) {
2815
  $sku = ! empty( $product->get_sku() ) ? $product->get_sku() . '_' : '';
2816
  $sku_id = $sku . $product->get_id();
2817
+
2818
  return apply_filters( 'woo_feed_filter_product_sku_id', $sku_id, $product, $this->config );
2819
  }
2820
+
2821
  /**
2822
  * Get Product Parent SKU
2823
  *
2831
  if ( $product->is_type( 'variation' ) ) {
2832
  $id = $product->get_parent_id();
2833
  $parent = wc_get_product( $id );
2834
+
2835
  $parent_sku = $parent->get_sku();
2836
  } else {
2837
  $parent_sku = $product->get_sku();
2838
  }
2839
+
2840
  return apply_filters( 'woo_feed_filter_product_parent_sku', $parent_sku, $product, $this->config );
2841
  }
2842
+
2843
  /**
2844
  * Get Product Availability Status
2845
  *
2858
  } elseif ( 'onbackorder' == $status ) {
2859
  $status = 'on backorder';
2860
  }
2861
+
2862
  // set (_) as separator for google merchant
2863
  if ( isset( $this->config['provider'] ) && 'google' === $this->config['provider'] ) {
2864
  $status = explode( ' ', $status );
2865
  $status = implode( '_', $status );
2866
  }
2867
+
2868
  return apply_filters( 'woo_feed_filter_product_availability', $status, $product, $this->config );
2869
  }
2870
+
2871
  /**
2872
  * Get Product Availability Date
2873
  *
2879
  * @author Ohidul Islam
2880
  */
2881
  protected function availability_date( $product ) {
2882
+
2883
  $feed_settings = get_option( 'woo_feed_settings' );
2884
+
2885
  $availability_date_settings = isset( $feed_settings['woo_feed_identifier']['availability_date'] )
2886
  ? $feed_settings['woo_feed_identifier']['availability_date']
2887
  : 'enable';
2888
+
2889
  if ( $product->get_stock_status() !== 'onbackorder' || $availability_date_settings === 'disable' ) {
2890
  return '';
2891
  }
2892
+
2893
  $meta_field_name = 'woo_feed_availability_date';
2894
+
2895
  if ( $product->is_type( 'variation' ) ) {
2896
  $meta_field_name .= '_var';
2897
  }
2898
+
2899
  $availability_date = get_post_meta( $product->get_id(), $meta_field_name, true );
2900
+
2901
  if ( '' !== $availability_date && in_array( $this->config['provider'], [
2902
  'google',
2903
  'facebook',
2907
  ], true ) ) {
2908
  $availability_date = gmdate( 'c', strtotime( $availability_date ) );
2909
  }
2910
+
2911
  return apply_filters( 'woo_feed_filter_product_availability_date', $availability_date, $product, $this->config );
2912
  }
2913
+
2914
  /**
2915
  * Get Product Add to Cart Link
2916
  *
2923
  protected function add_to_cart_link( $product ) {
2924
  $url = $this->link( $product );
2925
  $suffix = 'add-to-cart=' . $product->get_id();
2926
+
2927
  $add_to_cart_link = woo_feed_make_url_with_parameter( $url, $suffix );
2928
+
2929
  return apply_filters( 'woo_feed_filter_product_add_to_cart_link', $add_to_cart_link, $product, $this->config );
2930
  }
2931
+
2932
  /**
2933
  * Get Product Quantity
2934
  *
2941
  protected function quantity( $product ) {
2942
  $quantity = $product->get_stock_quantity();
2943
  $status = $product->get_stock_status();
2944
+
2945
  //when product is outofstock and it's quantity is empty, set quantity to 0
2946
  if ( 'outofstock' == $status && empty( $quantity ) ) {
2947
  $quantity = 0;
2948
  }
2949
+
2950
  if ( $product->is_type( 'variable' ) && $product->has_child() ) {
2951
  $visible_children = $product->get_visible_children();
2952
  $qty = array();
2954
  $childQty = get_post_meta( $child, '_stock', true );
2955
  $qty[] = (int) $childQty + 0;
2956
  }
2957
+
2958
  if ( isset( $this->config['variable_quantity'] ) ) {
2959
  $vaQty = $this->config['variable_quantity'];
2960
  if ( 'max' == $vaQty ) {
2966
  } elseif ( 'first' == $vaQty ) {
2967
  $quantity = ( (int) $qty[0] );
2968
  }
2969
+
2970
  $quantity = array_sum( $qty );
2971
  }
2972
  }
2973
+
2974
  return apply_filters( 'woo_feed_filter_product_quantity', $quantity, $product, $this->config );
2975
  }
2976
+
2977
  /**
2978
  * Get Product Currency
2979
  *
2985
  */
2986
  protected function currency( $product ) {
2987
  $quantity = get_option( 'woocommerce_currency' );
2988
+
2989
  return apply_filters( 'woo_feed_filter_product_currency', $quantity, $product, $this->config );
2990
  }
2991
+
2992
  /**
2993
  * Get Store currency code.
2994
  *
3001
  protected function store_currency( $product ) {
3002
  return get_woocommerce_currency();
3003
  }
3004
+
3005
  /**
3006
  * Get Product Sale Price Start Date
3007
  *
3018
  } else {
3019
  $sale_price_sdate = '';
3020
  }
3021
+
3022
  return apply_filters( 'woo_feed_filter_product_sale_price_sdate', $sale_price_sdate, $product, $this->config );
3023
  }
3024
+
3025
  /**
3026
  * Get Product Sale Price End Date
3027
  *
3038
  } else {
3039
  $sale_price_edate = "";
3040
  }
3041
+
3042
  return apply_filters( 'woo_feed_filter_product_sale_price_edate', $sale_price_edate, $product, $this->config );
3043
  }
3044
+
3045
  /**
3046
  * Get feed currency
3047
  *
3052
  if ( isset( $this->config['feedCurrency'] ) ) {
3053
  $currency = $this->config['feedCurrency'];
3054
  }
3055
+
3056
  return $currency;
3057
  }
3058
+
3059
  /**
3060
  * Get Product Price by default WooCommerce Price Type (regular_price|price|sale_price).
3061
  *
3069
  * @author Ohidul Islam
3070
  */
3071
  protected function get_price_by_price_type( $product, $price_type, $tax ) {
3072
+
3073
  if ( 'regular_price' === $price_type ) {
3074
  $price = $product->get_regular_price();
3075
  } elseif ( 'price' === $price_type ) {
3077
  } else {
3078
  $price = $product->get_sale_price();
3079
  }
3080
+
3081
  // Get WooCommerce Multi language Price by Currency.
3082
  $price = apply_filters( 'woo_feed_wcml_price',
3083
  $price, $product->get_id(), $this->get_feed_currency(), '_' . $price_type
3084
  );
3085
+
3086
  // Get Price with tax
3087
  if ( true === $tax ) {
3088
  $price = woo_feed_get_price_with_tax( $price, $product );
3089
  }
3090
+
3091
  return $price;
3092
  }
3093
+
3094
  /**
3095
  * Get Product Price by Product Type.
3096
  *
3120
  } else {
3121
  $price = $this->get_price_by_price_type( $product, $price_type, $tax );
3122
  }
3123
+
3124
  return $price > 0 ? $price : '';
3125
  }
3126
+
3127
  /**
3128
  * Get Product Regular Price
3129
  *
3134
  *
3135
  */
3136
  protected function price( $product ) {
3137
+
3138
  $regular_price = $this->get_price_by_product_type( $product, 'regular_price' );
3139
+
3140
  return apply_filters( 'woo_feed_filter_product_price', $regular_price, $product, $this->config, false );
3141
  }
3142
+
3143
  /**
3144
  * Get Product Price
3145
  *
3150
  *
3151
  */
3152
  protected function current_price( $product ) {
3153
+
3154
  $price = $this->get_price_by_product_type( $product, 'price' );
3155
+
3156
  return apply_filters( 'woo_feed_filter_product_regular_price', $price, $product, $this->config, false );
3157
  }
3158
+
3159
  /**
3160
  * Get Product Sale Price
3161
  *
3166
  *
3167
  */
3168
  protected function sale_price( $product ) {
3169
+
3170
  $sale_price = $this->get_price_by_product_type( $product, 'sale_price' );
3171
+
3172
  return apply_filters( 'woo_feed_filter_product_sale_price', $sale_price, $product, $this->config, false );
3173
  }
3174
+
3175
  /**
3176
  * Get Product Regular Price with Tax
3177
  *
3182
  *
3183
  */
3184
  protected function price_with_tax( $product ) {
3185
+
3186
  $regular_price_with_tax = $this->get_price_by_product_type( $product, 'regular_price', true );
3187
+
3188
  return apply_filters( 'woo_feed_filter_product_price_with_tax', $regular_price_with_tax, $product, $this->config, true );
3189
  }
3190
+
3191
  /**
3192
  * Get Product Regular Price with Tax
3193
  *
3198
  *
3199
  */
3200
  protected function current_price_with_tax( $product ) {
3201
+
3202
  $price_with_tax = $this->get_price_by_product_type( $product, 'price', true );
3203
+
3204
  return apply_filters( 'woo_feed_filter_product_regular_price_with_tax', $price_with_tax, $product, $this->config, true );
3205
  }
3206
+
3207
  /**
3208
  * Get Product Regular Price with Tax
3209
  *
3214
  *
3215
  */
3216
  protected function sale_price_with_tax( $product ) {
3217
+
3218
  $sale_price_with_tax = $this->get_price_by_product_type( $product, 'sale_price', true );
3219
+
3220
  return apply_filters( 'woo_feed_filter_product_sale_price_with_tax', $sale_price_with_tax, $product, $this->config, true );
3221
  }
3222
+
3223
  /**
3224
  * Get Composite Product Price
3225
  *
3243
  return $this->get_price_by_price_type( $product, $type, $tax );
3244
  }
3245
  }
3246
+
3247
  /**
3248
  * Get WooCommerce Composite Product Price
3249
  * Plugin URL: https://wordpress.org/plugins/wpc-composite-products/
3261
  $base_price = $this->get_price_by_price_type( $product, $type, $tax );
3262
  if ( isset( $this->config['composite_price'] ) && 'all_product_price' == $this->config['composite_price'] ) {
3263
  $composite = new WC_Product_Composite( $product );
3264
+
3265
  if ( 'price' === $type || 'sale_price' === $type ) {
3266
  $price = $composite->get_composite_price();
3267
  } else {
3268
  $price = $composite->get_composite_regular_price();
3269
  }
3270
+
3271
  // Get WooCommerce Multi language Price by Currency.
3272
  $price = apply_filters( 'woo_feed_wcml_price',
3273
  $price, $product->get_id(), $this->get_feed_currency(), '_' . $type
3274
  );
3275
+
3276
  // Get Price with tax
3277
  if ( true === $tax ) {
3278
  $price = woo_feed_get_price_with_tax( $price, $composite );
3280
  } else {
3281
  $price = $base_price;
3282
  }
3283
+
3284
  return $price > 0 ? $price : '';
3285
  }
3286
+
3287
  /**
3288
  * Get WPC Composite Product Price.
3289
  * Plugin URL: https://wordpress.org/plugins/wpc-composite-products/
3323
  }
3324
  }
3325
  }
3326
+
3327
  // Apply discount to components price.
3328
  $discount = $product->get_discount();
3329
  if ( $discount > 0 ) {
3330
  $components_price -= ( ( $discount / 100 ) * $components_price );
3331
  }
3332
  }
3333
+
3334
  if ( 'exclude' === $product->get_pricing() ) {
3335
  $price = $components_price;
3336
  } elseif ( 'include' === $product->get_pricing() ) {
3341
  } else {
3342
  $price = $base_price;
3343
  }
3344
+
3345
  return $price > 0 ? $price : '';
3346
  }
3347
+
3348
  /**
3349
  * Get total price of grouped product
3350
  *
3365
  if ( ! is_object( $product ) ) {
3366
  continue; // make sure that the product exists..
3367
  }
3368
+
3369
  $get_price = $this->get_price_by_product_type( $product, $type, $tax );
3370
  if ( ! empty( $get_price ) ) {
3371
  $price += $get_price;
3372
  }
3373
  }
3374
  }
3375
+
3376
  return $price > 0 ? $price : '';
3377
  }
3378
+
3379
  /**
3380
  * Get Variable Product Price
3381
  *
3392
  if ( isset( $this->config['variable_price'] ) ) {
3393
  $min_max_first_default = $this->config['variable_price'];
3394
  }
3395
+
3396
  $price = 0;
3397
  if ( 'first' == $min_max_first_default ) {
3398
  $children = $variable->get_visible_children();
3408
  } else {
3409
  $price = $variable->get_variation_price( $min_max_first_default );
3410
  }
3411
+
3412
  // Get WooCommerce Multi language Price by Currency.
3413
  $price = apply_filters( 'woo_feed_wcml_price',
3414
  $price, $variable->get_id(), $this->get_feed_currency(), '_' . $type
3415
  );
3416
+
3417
  // Get Price with tax
3418
  if ( true === $tax ) {
3419
  $price = woo_feed_get_price_with_tax( $price, $variable );
3420
  }
3421
  }
3422
+
3423
  return $price > 0 ? $price : '';
3424
  }
3425
+
3426
  /**
3427
  * Get Bundle Product Price
3428
  *
3441
  } else {
3442
  $price = $bundle->get_bundle_regular_price();
3443
  }
3444
+
3445
  // Get WooCommerce Multi language Price by Currency.
3446
  $price = apply_filters( 'woo_feed_wcml_price',
3447
  $price, $product->get_id(), $this->get_feed_currency(), '_' . $type
3448
  );
3449
+
3450
  // Get Price with tax
3451
  if ( true === $tax ) {
3452
  $price = woo_feed_get_price_with_tax( $price, $bundle );
3455
  // Get Default price for others bundle products.
3456
  $price = $this->get_price_by_price_type( $product, $type, $tax );
3457
  }
3458
+
3459
  return $price > 0 ? $price : '';
3460
  }
3461
+
3462
  /**
3463
  * Get price for Iconic woocommerce-bundled-products
3464
  *
3472
  if ( ! class_exists( 'WC_Product_Bundled' ) ) {
3473
  return $product->get_price();
3474
  }
3475
+
3476
  $is_discounted = false;
3477
  $price = $product->get_price();
3478
  $bundle = new WC_Product_Bundled( $product->get_id() );
3479
  $iconic_bundle_product_type = ( ! is_null( $bundle->options['price_display'] ) ) ? $bundle->options['price_display'] : '';
3480
  $product_ids = $bundle->options['product_ids'];
3481
+
3482
  //set discount
3483
  if ( ! empty( $bundle->options['fixed_discount'] ) ) {
3484
  $is_discounted = true;
3487
  $is_discounted = false;
3488
  $discount = 0;
3489
  }
3490
+
3491
  // Get price
3492
  if ( is_array( $product_ids ) ) {
3493
  $product_prices = array_map( function ( $id ) use ( $tax, $type, $is_discounted, $discount ) {
3494
  $product = wc_get_product( $id );
3495
+
3496
  return $this->get_price_by_price_type( $product, $type, $tax );
3497
+
3498
  }, $product_ids );
3499
+
3500
  if ( 'range' === $iconic_bundle_product_type ) {
3501
  $price = min( $product_prices );
3502
  } else {
3503
  $price = array_sum( $product_prices );
3504
  }
3505
  }
3506
+
3507
  // Get sale price if discount enabled
3508
  if ( $is_discounted && ( 'sale_price' === $type || 'price' === $type ) ) {
3509
  $price -= $discount;
3510
  }
3511
+
3512
  // Get WooCommerce Multi language Price by Currency.
3513
  $price = apply_filters( 'woo_feed_wcml_price',
3514
  $price, $product->get_id(), $this->get_feed_currency(), '_' . $type
3515
  );
3516
+
3517
  // Get Price with tax
3518
  if ( true === $tax ) {
3519
  $price = woo_feed_get_price_with_tax( $price, $bundle );
3520
  }
3521
+
3522
  return $price > 0 ? $price : '';
3523
  }
3524
+
3525
  /**
3526
  * Get Product Weight
3527
  *
3534
  protected function weight( $product ) {
3535
  return apply_filters( 'woo_feed_filter_product_weight', $product->get_weight(), $product, $this->config );
3536
  }
3537
+
3538
  /**
3539
  * Get Product Weight Unit
3540
  *
3547
  protected function weight_unit( $product ) {
3548
  return apply_filters( 'woo_feed_filter_product_weight_unit', get_option( 'woocommerce_weight_unit' ), $product, $this->config );
3549
  }
3550
+
3551
  /**
3552
  * Get Product Width
3553
  *
3560
  protected function width( $product ) {
3561
  return apply_filters( 'woo_feed_filter_product_width', $product->get_width(), $product, $this->config );
3562
  }
3563
+
3564
  /**
3565
  * Get Product Height
3566
  *
3573
  protected function height( $product ) {
3574
  return apply_filters( 'woo_feed_filter_product_height', $product->get_height(), $product, $this->config );
3575
  }
3576
+
3577
  /**
3578
  * Get Product Length
3579
  *
3586
  protected function length( $product ) {
3587
  return apply_filters( 'woo_feed_filter_product_length', $product->get_length(), $product, $this->config );
3588
  }
3589
+
3590
  /**
3591
  * Get Product Shipping
3592
  *
3599
  protected function shipping( $product ) {
3600
  $feedBody = '';
3601
  $data = $this->data;
3602
+
3603
  if ( isset( $data['shipping_zones'] ) && ! empty( $data['shipping_zones'] ) ) {
3604
  $zones = $data['shipping_zones'];
3605
+
3606
  if ( in_array( $this->config['provider'], [ 'google', 'facebook', 'pinterest', 'bing', 'snapchat' ] ) ) {
3607
  $get_shipping = new Woo_Feed_Shipping( $this->config );
3608
  $feedBody .= $get_shipping->set_product( $product )->set_shipping_zone( $zones )->get_google_shipping();
3609
  }
3610
  }
3611
+
3612
  return apply_filters( 'woo_feed_filter_product_shipping', $feedBody, $product, $this->config );
3613
+
3614
  }
3615
+
3616
  /**
3617
  * Get Product Shipping Cost
3618
  *
3625
  protected function shipping_cost( $product ) {
3626
  $shipping_obj = new Woo_Feed_Shipping( $this->config );
3627
  $shipping_obj = $shipping_obj->set_product( $product );
3628
+
3629
  return apply_filters( 'woo_feed_filter_product_shipping_cost', $shipping_obj->get_lowest_shipping_price(), $product, $this->config );
3630
  }
3631
+
3632
  /**
3633
  * Get Product Shipping Class
3634
  *
3641
  protected function shipping_class( $product ) {
3642
  return apply_filters( 'woo_feed_filter_product_shipping_class', $product->get_shipping_class(), $product, $this->config );
3643
  }
3644
+
3645
  /**
3646
  * Get Product Author Name
3647
  *
3653
  */
3654
  protected function author_name( $product ) {
3655
  $post = get_post( $product->get_id() );
3656
+
3657
  return get_the_author_meta( 'user_login', $post->post_author );
3658
  }
3659
+
3660
  /**
3661
  * Get Product Author Email
3662
  *
3668
  */
3669
  protected function author_email( $product ) {
3670
  $post = get_post( $product->get_id() );
3671
+
3672
  return get_the_author_meta( 'user_email', $post->post_author );
3673
  }
3674
+
3675
  /**
3676
  * Get Product Created Date
3677
  *
3683
  */
3684
  protected function date_created( $product ) {
3685
  $date_created = gmdate( 'Y-m-d', strtotime( $product->get_date_created() ) );
3686
+
3687
  return apply_filters( 'woo_feed_filter_product_date_created', $date_created, $product, $this->config );
3688
  }
3689
+
3690
  /**
3691
  * Get Product Last Updated Date
3692
  *
3698
  */
3699
  protected function date_updated( $product ) {
3700
  $date_updated = gmdate( 'Y-m-d', strtotime( $product->get_date_modified() ) );
3701
+
3702
  return apply_filters( 'woo_feed_filter_product_date_updated', $date_updated, $product, $this->config );
3703
  }
3704
+
3705
  /**
3706
  * Get Product Tax
3707
  *
3718
  $shipping_obj = $shipping_obj->set_product( $product );
3719
  $feedBody .= $shipping_obj->get_google_tax();
3720
  }
3721
+
3722
  return apply_filters( 'woo_feed_filter_product_tax', $feedBody, $product, $this->config );
3723
  }
3724
+
3725
  /**
3726
  * Get Product Tax class
3727
  *
3732
  protected function tax_class( $product ) {
3733
  return apply_filters( 'woo_feed_filter_product_tax_class', $product->get_tax_class(), $product, $this->config );
3734
  }
3735
+
3736
  /**
3737
  * Get Product Tax Status
3738
  *
3743
  protected function tax_status( $product ) {
3744
  return apply_filters( 'woo_feed_filter_product_tax_status', $product->get_tax_status(), $product, $this->config );
3745
  }
3746
+
3747
  /**
3748
  * Get CTX Feed Custom Field value
3749
  *
3758
  if ( $product->is_type( 'variation' ) ) {
3759
  $meta = $field . '_var';
3760
  }
3761
+
3762
  $meta = apply_filters( 'woo_feed_custom_field_meta', $meta, $product, $field );
3763
+
3764
  $new_meta_key = '';
3765
  $old_meta_key = '';
3766
+
3767
  if ( strpos( $meta, '_identifier' ) !== false ) {
3768
  $old_meta_key = $meta;
3769
  $new_meta_key = str_replace( '_identifier', '', $meta );
3771
  $new_meta_key = $meta;
3772
  $old_meta_key = str_replace( 'woo_feed_', 'woo_feed_identifier_', $meta );
3773
  }
3774
+
3775
  $new_meta_value = $this->getProductMeta( $product, $new_meta_key );
3776
  $old_meta_value = $this->getProductMeta( $product, $old_meta_key );
3777
+
3778
  if ( empty( $new_meta_value ) ) {
3779
  return $old_meta_value;
3780
  }
3781
+
3782
  return $new_meta_value;
3783
+
3784
  }
3785
+
3786
  /**
3787
  * Get Product Sale Price Effected Date for Google Shopping
3788
  *
3799
  if ( ! empty( $from ) && ! empty( $to ) ) {
3800
  $from = gmdate( 'c', strtotime( $from ) );
3801
  $to = gmdate( 'c', strtotime( $to ) );
3802
+
3803
  $effective_date = $from . '/' . $to;
3804
  }
3805
+
3806
  return $effective_date;
3807
  }
3808
+
3809
  /**
3810
  * Ger Product Attribute
3811
  *
3818
  */
3819
  protected function getProductAttribute( $product, $attr ) {
3820
  $id = $product->get_id();
3821
+
3822
  if ( woo_feed_wc_version_check( 3.2 ) ) {
3823
  if ( woo_feed_wc_version_check( 3.6 ) ) {
3824
  $attr = str_replace( 'pa_', '', $attr );
3825
  }
3826
  $value = $product->get_attribute( $attr );
3827
+
3828
  // if empty get attribute of parent post
3829
  if ( '' === $value && $product->is_type( 'variation' ) ) {
3830
  $product = wc_get_product( $product->get_parent_id() );
3831
  $value = $product->get_attribute( $attr );
3832
  }
3833
+
3834
  $getproductattribute = $value;
3835
  } else {
3836
  $getproductattribute = implode( ',', wc_get_product_terms( $id, $attr, array( 'fields' => 'names' ) ) );
3837
  }
3838
+
3839
  return apply_filters( 'woo_feed_filter_product_attribute', $getproductattribute, $attr, $product, $this->config );
3840
  }
3841
+
3842
  /**
3843
  * Get Meta
3844
  *
3855
  if ( '' === $value && $product->is_type( 'variation' ) ) {
3856
  $value = get_post_meta( $product->get_parent_id(), $meta, true );
3857
  }
3858
+
3859
  return apply_filters( 'woo_feed_filter_product_meta', $value, $product, $this->config );
3860
  }
3861
+
3862
  /**
3863
  * Filter Products by Conditions
3864
  *
3871
  public function filter_product( $product ) {
3872
  return true;
3873
  }
3874
+
3875
  /**
3876
  * Get Taxonomy
3877
  *
3887
  if ( $product->is_type( 'variation' ) ) {
3888
  $id = $product->get_parent_id();
3889
  }
3890
+
3891
  $separator = apply_filters( 'woo_feed_product_taxonomy_term_list_separator', ',', $this->config, $product );
3892
+
3893
  $term_list = get_the_term_list( $id, $taxonomy, '', $separator, '' );
3894
+
3895
  if ( is_object( $term_list ) && get_class( $term_list ) === 'WP_Error' ) {
3896
  $term_list = '';
3897
  }
3898
+
3899
  $getproducttaxonomy = woo_feed_strip_all_tags( $term_list );
3900
+
3901
  return apply_filters( 'woo_feed_filter_product_taxonomy', $getproducttaxonomy, $product, $this->config );
3902
  }
3903
+
3904
  /**
3905
  * Format price value
3906
  *
3916
  $plus = '+';
3917
  $minus = '-';
3918
  $percent = '%';
3919
+
3920
  if ( strpos( $name, 'price' ) !== false ) {
3921
  if ( strpos( $result, $plus ) !== false && strpos( $result, $percent ) !== false ) {
3922
  $result = str_replace( '+', '', $result );
3942
  }
3943
  }
3944
  }
3945
+
3946
  return $result;
3947
  }
3948
+
3949
  /**
3950
  * Format output According to Output Type config
3951
  *
3960
  */
3961
  protected function format_output( $output, $outputTypes, $product, $productAttribute, $merchant_attribute ) {
3962
  if ( ! empty( $outputTypes ) && is_array( $outputTypes ) ) {
3963
+
3964
  // Format Output According to output type
3965
  if ( in_array( 2, $outputTypes ) ) { // Strip Tags
3966
  $output = woo_feed_strip_all_tags( html_entity_decode( $output ) );
3967
  }
3968
+
3969
  if ( in_array( 3, $outputTypes ) ) { // UTF-8 Encode
3970
  $output = utf8_encode( $output );
3971
  }
3972
+
3973
  if ( in_array( 4, $outputTypes ) ) { // htmlentities
3974
  $output = htmlentities( $output, ENT_QUOTES, 'UTF-8' );
3975
  }
3976
+
3977
  if ( in_array( 5, $outputTypes ) ) { // Integer
3978
  $output = intval( $output );
3979
  }
3980
+
3981
  if ( in_array( 6, $outputTypes ) ) { // Format Price
3982
  if ( ! empty( $output ) && $output > 0 ) {
3983
  $decimals = wc_get_price_decimals();
3984
  $decimal_separator = wc_get_price_decimal_separator();
3985
  $thousand_separator = wc_get_price_thousand_separator();
3986
  $output = (float) $output;
3987
+
3988
  if ( "idealo" === $this->config['provider'] ) {
3989
  $output = number_format( $output, $decimals, wp_specialchars_decode( stripslashes( $decimal_separator ) ), wp_specialchars_decode( stripslashes( $thousand_separator ) ) );
3990
  } else {
3991
  $output = number_format( $output, 2, '.', '' );
3992
  }
3993
+
3994
  }
3995
  }
3996
+
3997
  if ( in_array( 7, $outputTypes ) ) { // Rounded Price
3998
  if ( ! empty( $output ) && $output > 0 ) {
3999
  $output = round( $output );
4000
  $output = number_format( $output, 2, '.', '' );
4001
  }
4002
  }
4003
+
4004
  if ( in_array( 8, $outputTypes ) ) { // Delete Space
4005
  $output = htmlentities( $output, null, 'utf-8' );
4006
  $output = str_replace( "&nbsp;", " ", $output );
4007
  $output = html_entity_decode( $output );
4008
  $output = preg_replace( "/\\s+/", ' ', $output );
4009
  }
4010
+
4011
  if ( in_array( 10, $outputTypes ) ) { // Remove Invalid Character
4012
  $output = woo_feed_stripInvalidXml( $output );
4013
  }
4014
+
4015
  if ( in_array( 11, $outputTypes ) ) { // Remove ShortCodes
4016
  $output = $this->remove_short_codes( $output );
4017
  }
4018
+
4019
  if ( in_array( 12, $outputTypes ) ) {
4020
  //$output = ucwords(mb_strtolower($output));
4021
  $output = mb_convert_case( $output, MB_CASE_TITLE );
4022
  }
4023
+
4024
  if ( in_array( 13, $outputTypes ) ) {
4025
  //$output = ucfirst(strtolower($output));
4026
  $output = mb_strtoupper( mb_substr( $output, 0, 1 ) ) . mb_substr( $output, 1 );
4027
  }
4028
+
4029
  if ( in_array( 14, $outputTypes ) ) {
4030
  $output = mb_strtoupper( mb_strtolower( $output ) );
4031
  }
4032
+
4033
  if ( in_array( 15, $outputTypes ) ) {
4034
  $output = mb_strtolower( $output );
4035
  }
4036
+
4037
  if ( in_array( 16, $outputTypes ) ) {
4038
  if ( 'http' == substr( $output, 0, 4 ) ) {
4039
  $output = str_replace( 'http://', 'https://', $output );
4040
  }
4041
  }
4042
+
4043
  if ( in_array( 17, $outputTypes ) ) {
4044
  if ( 'http' == substr( $output, 0, 4 ) ) {
4045
  $output = str_replace( 'https://', 'http://', $output );
4046
  }
4047
  }
4048
+
4049
  if ( in_array( 18, $outputTypes ) ) { // only parent
4050
  if ( $product->is_type( 'variation' ) ) {
4051
  $id = $product->get_parent_id();
4053
  $output = $this->getAttributeValueByType( $parentProduct, $productAttribute, $merchant_attribute );
4054
  }
4055
  }
4056
+
4057
  if ( in_array( 19, $outputTypes ) ) { // child if parent empty
4058
  if ( $product->is_type( 'variation' ) ) {
4059
  $id = $product->get_parent_id();
4064
  }
4065
  }
4066
  }
4067
+
4068
  if ( in_array( 20, $outputTypes ) ) { // parent if child empty
4069
  if ( $product->is_type( 'variation' ) ) {
4070
  $output = $this->getAttributeValueByType( $product, $productAttribute, $merchant_attribute );
4075
  }
4076
  }
4077
  }
4078
+
4079
  if ( in_array( 9, $outputTypes ) && ! empty( $output ) && 'xml' === $this->config['feedType'] ) { // Add CDATA
4080
  $output = '<![CDATA[' . $output . ']]>';
4081
  }
4082
  }
4083
+
4084
  return $output;
4085
  }
4086
+
4087
  /**
4088
  * Add Prefix and Suffix with attribute value
4089
  *
4101
  if ( '' === $output ) {
4102
  return $output;
4103
  }
4104
+
4105
  if ( strpos( $output, '<![CDATA[' ) !== false ) {
4106
  $cdata = true;
4107
  $output = str_replace( array( '<![CDATA[', ']]>' ), array( '', '' ), $output );
4108
  }
4109
+
4110
  // Add Prefix before Output
4111
  if ( '' !== $prefix ) {
4112
  $output = "$prefix" . $output;
4113
  }
4114
+
4115
  // Add Suffix after Output
4116
  if ( '' !== $suffix ) {
4117
  if ( array_key_exists( trim( $suffix ), get_woocommerce_currencies() ) ) { // Add space before suffix if attribute contain price.
4123
  $output .= (string) $suffix;
4124
  }
4125
  }
4126
+
4127
  if ( $cdata ) {
4128
  $output = '<![CDATA[' . $output . ']]>';
4129
  }
4130
+
4131
  return "$output";
4132
  }
4133
+
4134
  /**
4135
  * Get Subscription period
4136
  *
4144
  if ( class_exists( 'WC_Subscriptions' ) ) {
4145
  return $this->getProductMeta( $product, '_subscription_period' );
4146
  }
4147
+
4148
  return '';
4149
  }
4150
+
4151
  /**
4152
  * Get Subscription period interval
4153
  *
4161
  if ( class_exists( 'WC_Subscriptions' ) ) {
4162
  return $this->getProductMeta( $product, '_subscription_period_interval' );
4163
  }
4164
+
4165
  return '';
4166
  }
4167
+
4168
  /**
4169
  * Get Subscription period interval
4170
  *
4177
  protected function subscription_amount( $product ) {
4178
  return $this->price( $product );
4179
  }
4180
+
4181
  /**
4182
  * Get Installment Amount
4183
  *
4189
  protected function installment_amount( $product ) {
4190
  return $this->price( $product );
4191
  }
4192
+
4193
  /**
4194
  * Get Installment Months
4195
  *
4202
  if ( class_exists( 'WC_Subscriptions' ) ) {
4203
  return $this->getProductMeta( $product, '_subscription_length' );
4204
  }
4205
+
4206
  return '';
4207
  }
4208
+
4209
+
4210
  /**
4211
  * Calculate unit_price_measure. If Unit custom fields by CTX feed are enabled then it will take value
4212
  * from custom fields or it will take values for WooCommerce Germanized Plugin if enabled.
4227
  ) {
4228
  $unit = $this->getCustomField( $product, 'woo_feed_unit' );
4229
  $unit_price_measure = $this->getCustomField( $product, 'woo_feed_unit_pricing_measure' );
4230
+
4231
  $unit_price_measure .= " " . $unit;
4232
  }
4233
+
4234
  if ( empty( $unit_price_measure ) && class_exists( 'WooCommerce_Germanized' ) ) { // For WooCommerce Germanized Plugin
4235
  $unit = $this->getProductMeta( $product, '_unit' );
4236
  $unit_price_measure = $this->getProductMeta( $product, '_unit_product' );
4237
+
4238
  $unit_price_measure .= " " . $unit;
4239
  }
4240
+
4241
  return apply_filters( 'woo_feed_filter_unit_price_measure', $unit_price_measure, $product, $this->config );
4242
  }
4243
+
4244
  /**
4245
  * Calculate unit_price_base_measure. If Unit custom fields by CTX feed are enabled then it will take value
4246
  * from custom fields or it will take values for WooCommerce Germanized Plugin if enabled.
4261
  ) {
4262
  $unit = $this->getCustomField( $product, 'woo_feed_unit' );
4263
  $unit_price_base_measure = $this->getCustomField( $product, 'woo_feed_unit_pricing_base_measure' );
4264
+
4265
  $unit_price_base_measure .= " " . $unit;
4266
  }
4267
+
4268
  if ( empty( $unit_price_base_measure ) && class_exists( 'WooCommerce_Germanized' ) ) { // For WooCommerce Germanized Plugin
4269
  $unit = $this->getProductMeta( $product, '_unit' );
4270
  $unit_price_base_measure = $this->getProductMeta( $product, '_unit_base' );
4271
+
4272
  $unit_price_base_measure .= " " . $unit;
4273
  }
4274
+
4275
  return apply_filters( 'woo_feed_filter_unit_price_base_measure', $unit_price_base_measure, $product, $this->config );
4276
  }
4277
+
4278
  /**
4279
  * Get GTIN value of WooCommerce Germanized Plugin
4280
  *
4288
  if ( class_exists( 'WooCommerce_Germanized' ) ) { // For WooCommerce Germanized Plugin
4289
  $wc_germanized_gtin = $this->getProductMeta( $product, '_ts_gtin' );
4290
  }
4291
+
4292
  return apply_filters( 'woo_feed_filter_wc_germanized_gtin', $wc_germanized_gtin, $product, $this->config );
4293
  }
4294
+
4295
  /**
4296
  * Get MPN value of WooCommerce Germanized Plugin
4297
  *
4305
  if ( class_exists( 'WooCommerce_Germanized' ) ) { // For WooCommerce Germanized Plugin
4306
  $wc_germanized_mpn = $this->getProductMeta( $product, '_ts_mpn' );
4307
  }
4308
+
4309
  return apply_filters( 'woo_feed_filter_wc_germanized_mpn', $wc_germanized_mpn, $product, $this->config );
4310
  }
4311
+
4312
+
4313
  /**
4314
  * Yoast Identifier attribute for gtin8
4315
  *
4320
  */
4321
  protected function yoast_gtin8( $product ) {
4322
  $yoast_gtin8_value = woo_feed_get_yoast_identifiers_value( 'gtin8', $product );
4323
+
4324
  return apply_filters( 'yoast_gtin8_attribute_value', $yoast_gtin8_value, $product );
4325
  }
4326
+
4327
  /**
4328
  * Yoast Identifier attribute for gtin12
4329
  *
4334
  */
4335
  protected function yoast_gtin12( $product ) {
4336
  $yoast_gtin12_value = woo_feed_get_yoast_identifiers_value( 'gtin12', $product );
4337
+
4338
  return apply_filters( 'yoast_gtin12_attribute_value', $yoast_gtin12_value, $product );
4339
  }
4340
+
4341
  /**
4342
  * Yoast Identifier attribute for gtin13
4343
  *
4348
  */
4349
  protected function yoast_gtin13( $product ) {
4350
  $yoast_gtin13_value = woo_feed_get_yoast_identifiers_value( 'gtin13', $product );
4351
+
4352
  return apply_filters( 'yoast_gtin13_attribute_value', $yoast_gtin13_value, $product );
4353
  }
4354
+
4355
  /**
4356
  * Yoast Identifier attribute for gtin12
4357
  *
4362
  */
4363
  protected function yoast_gtin14( $product ) {
4364
  $yoast_gtin14_value = woo_feed_get_yoast_identifiers_value( 'gtin14', $product );
4365
+
4366
  return apply_filters( 'yoast_gtin14_attribute_value', $yoast_gtin14_value, $product );
4367
  }
4368
+
4369
  /**
4370
  * Yoast Identifier attribute for isbn
4371
  *
4376
  */
4377
  protected function yoast_isbn( $product ) {
4378
  $yoast_isbn_value = woo_feed_get_yoast_identifiers_value( 'isbn', $product );
4379
+
4380
  return apply_filters( 'yoast_isbn_attribute_value', $yoast_isbn_value, $product );
4381
  }
4382
+
4383
  /**
4384
  * Yoast Identifier attribute for mpn
4385
  *
4390
  */
4391
  protected function yoast_mpn( $product ) {
4392
  $yoast_mpn_value = woo_feed_get_yoast_identifiers_value( 'mpn', $product );
4393
+
4394
  return apply_filters( 'yoast_mpn_attribute_value', $yoast_mpn_value, $product );
4395
  }
4396
+
4397
  /**
4398
  * Rank Math GTIN Identifier attribute
4399
  *
4406
  $product_id = woo_feed_parent_product_id( $product );
4407
  $rankmath_gtin_value = get_post_meta( $product_id, '_rank_math_gtin_code' );
4408
  $rankmath_gtin_value = ! empty( $rankmath_gtin_value ) && is_array( $rankmath_gtin_value ) ? $rankmath_gtin_value[0] : '';
4409
+
4410
  return apply_filters( 'rankmath_gtin_attribute_value', $rankmath_gtin_value, $product );
4411
  }
4412
+
4413
  /**
4414
  * Get ACF Field values
4415
  *
4423
  if ( class_exists( 'ACF' ) ) {
4424
  return get_field( $field, $product->get_id() );
4425
  }
4426
+
4427
  return '';
4428
  }
4429
  }
includes/helper.php CHANGED
@@ -276,6 +276,52 @@ if ( ! function_exists( 'woo_feed_black_friday_notice' ) ) {
276
  }
277
  }
278
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
279
  if ( ! function_exists( 'woo_feed_progress_bar' ) ) {
280
  /**
281
  * Feed Progress Bar
@@ -3310,6 +3356,36 @@ if ( ! function_exists( 'woo_feed_save_black_friday_notice_2021_notice' ) ) {
3310
  }
3311
  add_action( 'wp_ajax_woo_feed_save_black_friday_notice_2021_notice', 'woo_feed_save_black_friday_notice_2021_notice' );
3312
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3313
  if ( ! function_exists( 'woo_feed_hide_promotion' ) ) {
3314
  /**
3315
  * Update option to hide promotion.
276
  }
277
  }
278
  }
279
+
280
+
281
+
282
+ if ( ! function_exists( 'woo_feed_halloween_notice' ) ) {
283
+ /**
284
+ * CTX Feed Halloween Notice
285
+ *
286
+ * @since 4.5.3
287
+ * @author Nashir Uddin
288
+ */
289
+ function woo_feed_halloween_notice() {
290
+ $user_id = get_current_user_id();
291
+ if ( ! get_user_meta( $user_id, 'woo_feed_halloween_notice_dismissed' ) ) {
292
+ ob_start();
293
+ ?>
294
+ <script type="text/javascript">
295
+ (function ($) {
296
+ $(document).on('click', '.woo-feed-ctx-halloween-notice button.notice-dismiss', function (e) {
297
+ e.preventDefault();
298
+ let nonce = $('#woo_feed_to_ctx_feed_halloween_nonce').val();
299
+
300
+ //woo feed halloween cancel callback
301
+ wp.ajax.post('woo_feed_save_halloween_notice', {
302
+ _wp_ajax_nonce: nonce,
303
+ clicked: true,
304
+ }).then(response => {
305
+ console.log(response);
306
+ }).fail(error => {
307
+ console.log(error);
308
+ });
309
+ });
310
+ })(jQuery)
311
+ </script>
312
+ <a target="_blank" href="https://webappick.com/plugin/woocommerce-product-feed-pro/?utm_source=hw&utm_medium=ctx-plugin-banner&utm_campaign=hw-cm-22"
313
+ class="notice woo-feed-ctx-halloween-notice is-dismissible"
314
+ style="background: url(<?php echo WOO_FEED_PLUGIN_URL . "admin/images/woo_feed_halloween_notice.png"; ?>) no-repeat top center;">
315
+ <input type="hidden" id="woo_feed_to_ctx_feed_halloween_nonce"
316
+ value="<?php echo wp_create_nonce( 'woo-feed-to-ctx-feed-halloween-nonce' ); ?>">
317
+ </a>
318
+ <?php
319
+ $image = ob_get_contents();
320
+ }
321
+ }
322
+ }
323
+
324
+
325
  if ( ! function_exists( 'woo_feed_progress_bar' ) ) {
326
  /**
327
  * Feed Progress Bar
3356
  }
3357
  add_action( 'wp_ajax_woo_feed_save_black_friday_notice_2021_notice', 'woo_feed_save_black_friday_notice_2021_notice' );
3358
 
3359
+
3360
+ if ( ! function_exists( 'woo_feed_save_halloween_notice' ) ) {
3361
+ /**
3362
+ * Update user meta to work ctx startup notice once.
3363
+ *
3364
+ * @param int _ajax_nonce nonce number.
3365
+ *
3366
+ * @since 4.5.3
3367
+ * @author Nashir Uddin
3368
+ */
3369
+ function woo_feed_save_halloween_notice() {
3370
+ if ( isset( $_REQUEST['_wp_ajax_nonce'] ) && wp_verify_nonce( wp_unslash( $_REQUEST['_wp_ajax_nonce'] ), 'woo-feed-to-ctx-feed-halloween-nonce' ) ) { //phpcs:ignore
3371
+ $user_id = get_current_user_id();
3372
+ if ( isset( $_REQUEST['clicked'] ) ) {
3373
+ $updated_user_meta = add_user_meta( $user_id, 'woo_feed_halloween_notice_dismissed', 'true', true );
3374
+
3375
+ if ( $updated_user_meta ) {
3376
+ wp_send_json_success( esc_html__( 'User meta updated successfully.', 'woo-feed' ) );
3377
+ } else {
3378
+ wp_send_json_error( esc_html__( 'Something is wrong.', 'woo-feed' ) );
3379
+ }
3380
+ }
3381
+ } else {
3382
+ wp_send_json_error( esc_html__( 'Invalid Request.', 'woo-feed' ) );
3383
+ }
3384
+ wp_die();
3385
+ }
3386
+ }
3387
+ add_action( 'wp_ajax_woo_feed_save_halloween_notice', 'woo_feed_save_halloween_notice' );
3388
+
3389
  if ( ! function_exists( 'woo_feed_hide_promotion' ) ) {
3390
  /**
3391
  * Update option to hide promotion.
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.5.4
14
  * Author: WebAppick
15
  * Author URI: https://webappick.com/
16
  * License: GPL v2
@@ -132,6 +132,7 @@ if ( ! function_exists( 'run_woo_feed' ) ) {
132
  add_action( 'plugins_loaded', array( $plugin, 'run' ), PHP_INT_MAX );
133
  add_action( 'admin_notices', 'wooFeed_Admin_Notices' );
134
  //add_action( 'admin_notices', 'woo_feed_black_friday_notice' );
 
135
  WooFeedWebAppickAPI::getInstance();
136
 
137
  }
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.5.5
14
  * Author: WebAppick
15
  * Author URI: https://webappick.com/
16
  * License: GPL v2
132
  add_action( 'plugins_loaded', array( $plugin, 'run' ), PHP_INT_MAX );
133
  add_action( 'admin_notices', 'wooFeed_Admin_Notices' );
134
  //add_action( 'admin_notices', 'woo_feed_black_friday_notice' );
135
+ add_action( 'admin_notices', 'woo_feed_halloween_notice' );
136
  WooFeedWebAppickAPI::getInstance();
137
 
138
  }