CTX Feed – WooCommerce Product Feed Manager Plugin - Version 4.4.68

Version Description

Download this release

Release Info

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

Code changes from version 4.4.67 to 4.4.68

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.4.67
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -589,6 +589,14 @@ Using pro version:
589
  4. Category Mapping
590
 
591
  == Changelog ==
 
 
 
 
 
 
 
 
592
  = 4.4.67 (2022-06-10) =
593
  * Fixed: Wanted a one star review.
594
  * Fixed: WPML Notice dismiss button not working.
5
  Requires at least: 4.4
6
  Tested Up To: 6.0
7
  Requires PHP: 5.6
8
+ Stable tag: 4.4.68
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
589
  4. Category Mapping
590
 
591
  == Changelog ==
592
+ = 4.4.67 (2022-06-29) =
593
+ * Fixed: Feed import issue solved
594
+ * Fixed: Feed template loading issue solved
595
+ * Fixed: Google Review feed issue fixed
596
+ * Fixed: Facebook variable product remove
597
+ * Fixed: String case convert issue fixed
598
+ * Fixed: Refactoring Product attributes dropdown
599
+
600
  = 4.4.67 (2022-06-10) =
601
  * Fixed: Wanted a one star review.
602
  * Fixed: WPML Notice dismiss button not working.
admin/class-woo-feed-admin.php CHANGED
@@ -11,7 +11,7 @@
11
  * @author Ohidul Islam <wahid@webappick.com>
12
  */
13
  class Woo_Feed_Admin {
14
-
15
  /**
16
  * The ID of this plugin.
17
  *
@@ -20,7 +20,7 @@ class Woo_Feed_Admin {
20
  * @var string $woo_feed The ID of this plugin.
21
  */
22
  private $woo_feed;
23
-
24
  /**
25
  * The version of this plugin.
26
  *
@@ -29,7 +29,7 @@ class Woo_Feed_Admin {
29
  * @var string $version The current version of this plugin.
30
  */
31
  private $version;
32
-
33
  /**
34
  * Initialize the class and set its properties.
35
  *
@@ -40,12 +40,12 @@ class Woo_Feed_Admin {
40
  *
41
  */
42
  public function __construct( $woo_feed, $version ) {
43
-
44
  $this->woo_feed = $woo_feed;
45
  $this->version = $version;
46
-
47
  }
48
-
49
  /**
50
  * Register the stylesheets for the admin area.
51
  *
@@ -83,7 +83,7 @@ class Woo_Feed_Admin {
83
  wp_enqueue_style( $this->woo_feed );
84
  wp_enqueue_style( $this->woo_feed . '-pro' );
85
  }
86
-
87
  /**
88
  * Register the JavaScript for the admin area.
89
  *
@@ -108,7 +108,8 @@ class Woo_Feed_Admin {
108
  $js_dequeue_handles = woo_feed_get_js_dequeue_handles_list();
109
 
110
  $page = apply_filters('CTXFEED_filter_securing_input', "GET", @$_GET['page'], "text");
111
- if ( $page ) {
 
112
  $woo_feed_plugin_pages = woo_feed_get_plugin_pages_slugs();
113
 
114
  if ( in_array($page, $woo_feed_plugin_pages) ) {
@@ -131,7 +132,7 @@ class Woo_Feed_Admin {
131
  wp_register_script( 'jquery-validate', plugin_dir_url( __FILE__ ) . 'js/jquery.validate.min.js', array( 'jquery' ), $this->version, false );
132
  wp_register_script( 'jquery-validate-additional-methods', plugin_dir_url( __FILE__ ) . 'js/additional-methods.min.js', array( 'jquery', 'jquery-validate' ), $this->version, false );
133
  wp_register_script( 'jquery-sortable', plugin_dir_url( __FILE__ ) . 'js/jquery-sortable' . $ext, array( 'jquery' ), $this->version, false );
134
-
135
  $feedScriptDependency = [
136
  'jquery',
137
  'clipboard',
@@ -148,7 +149,7 @@ class Woo_Feed_Admin {
148
  'jquery-touch-punch',
149
  'fancy-select',
150
  ];
151
-
152
  wp_register_script( $this->woo_feed, plugin_dir_url( __FILE__ ) . 'js/woo-feed-admin' . $ext, $feedScriptDependency, $this->version, false );
153
 
154
  //get feed options with which feed is previously generated
@@ -229,7 +230,7 @@ class Woo_Feed_Admin {
229
  }
230
  wp_localize_script( $this->woo_feed, 'wpf_ajax_obj', $js_opts );
231
  wp_enqueue_script( $this->woo_feed );
232
-
233
  if ( 'woo-feed_page_webappick-feed-pro-vs-free' === $hook ) {
234
  wp_register_script( 'jquery-slick', plugin_dir_url( __FILE__ ) . 'js/slick' . $ext, array( 'jquery' ), $this->version, false );
235
  wp_register_script( $this->woo_feed . '-pro', plugin_dir_url( __FILE__ ) . 'js/woo-feed-admin-pro' . $ext, [ $this->woo_feed, 'jquery-slick' ], $this->version, false );
@@ -237,14 +238,14 @@ class Woo_Feed_Admin {
237
  }
238
  }
239
  }
240
-
241
  /**
242
  * Add Go to Pro and Documentation link
243
  * @param array $links
244
  * @return array
245
  */
246
  public function woo_feed_plugin_action_links( $links ) {
247
-
248
  $links[] = '<a style="color: #389e38; font-weight: bold;" href="https://webappick.com/plugin/woocommerce-product-feed-pro/?utm_source=freePlugin&utm_medium=go_premium&utm_campaign=free_to_pro&utm_term=wooFeed" target="_blank">' . __( 'Get Pro', 'woo-feed' ) . '</a>';
249
  /** @noinspection HtmlUnknownTarget */
250
  $links[] = sprintf( '<a style="color:#ce7304; font-weight: bold;" href="%s">%s</a>', esc_url( admin_url( 'admin.php?page=webappick-feed-docs' ) ), __( 'Docs', 'woo-feed' ) );
@@ -252,7 +253,7 @@ class Woo_Feed_Admin {
252
  $links[] = sprintf( '<a href="%s">%s</a>', esc_url( admin_url( 'admin.php?page=webappick-feed-settings' ) ), __( 'Settings', 'woo-feed' ) );
253
  return $links;
254
  }
255
-
256
  /**
257
  * Register the Plugin's Admin Pages for the admin area.
258
  *
@@ -281,7 +282,7 @@ class Woo_Feed_Admin {
281
  add_submenu_page( 'webappick-manage-feeds', __( 'Documentation', 'woo-feed' ), '<span class="woo-feed-docs">' . __( 'Docs', 'woo-feed' ) . '</span>', 'manage_woocommerce', 'webappick-feed-docs', array( WooFeedDocs::getInstance(), 'woo_feed_docs' ) );
282
  }
283
  }
284
-
285
  /**
286
  * Redirect user to with new menu slug (if user browser any bookmarked url)
287
  * @return void
11
  * @author Ohidul Islam <wahid@webappick.com>
12
  */
13
  class Woo_Feed_Admin {
14
+
15
  /**
16
  * The ID of this plugin.
17
  *
20
  * @var string $woo_feed The ID of this plugin.
21
  */
22
  private $woo_feed;
23
+
24
  /**
25
  * The version of this plugin.
26
  *
29
  * @var string $version The current version of this plugin.
30
  */
31
  private $version;
32
+
33
  /**
34
  * Initialize the class and set its properties.
35
  *
40
  *
41
  */
42
  public function __construct( $woo_feed, $version ) {
43
+
44
  $this->woo_feed = $woo_feed;
45
  $this->version = $version;
46
+
47
  }
48
+
49
  /**
50
  * Register the stylesheets for the admin area.
51
  *
83
  wp_enqueue_style( $this->woo_feed );
84
  wp_enqueue_style( $this->woo_feed . '-pro' );
85
  }
86
+
87
  /**
88
  * Register the JavaScript for the admin area.
89
  *
108
  $js_dequeue_handles = woo_feed_get_js_dequeue_handles_list();
109
 
110
  $page = apply_filters('CTXFEED_filter_securing_input', "GET", @$_GET['page'], "text");
111
+
112
+ if ( isset($page) ) {
113
  $woo_feed_plugin_pages = woo_feed_get_plugin_pages_slugs();
114
 
115
  if ( in_array($page, $woo_feed_plugin_pages) ) {
132
  wp_register_script( 'jquery-validate', plugin_dir_url( __FILE__ ) . 'js/jquery.validate.min.js', array( 'jquery' ), $this->version, false );
133
  wp_register_script( 'jquery-validate-additional-methods', plugin_dir_url( __FILE__ ) . 'js/additional-methods.min.js', array( 'jquery', 'jquery-validate' ), $this->version, false );
134
  wp_register_script( 'jquery-sortable', plugin_dir_url( __FILE__ ) . 'js/jquery-sortable' . $ext, array( 'jquery' ), $this->version, false );
135
+
136
  $feedScriptDependency = [
137
  'jquery',
138
  'clipboard',
149
  'jquery-touch-punch',
150
  'fancy-select',
151
  ];
152
+
153
  wp_register_script( $this->woo_feed, plugin_dir_url( __FILE__ ) . 'js/woo-feed-admin' . $ext, $feedScriptDependency, $this->version, false );
154
 
155
  //get feed options with which feed is previously generated
230
  }
231
  wp_localize_script( $this->woo_feed, 'wpf_ajax_obj', $js_opts );
232
  wp_enqueue_script( $this->woo_feed );
233
+
234
  if ( 'woo-feed_page_webappick-feed-pro-vs-free' === $hook ) {
235
  wp_register_script( 'jquery-slick', plugin_dir_url( __FILE__ ) . 'js/slick' . $ext, array( 'jquery' ), $this->version, false );
236
  wp_register_script( $this->woo_feed . '-pro', plugin_dir_url( __FILE__ ) . 'js/woo-feed-admin-pro' . $ext, [ $this->woo_feed, 'jquery-slick' ], $this->version, false );
238
  }
239
  }
240
  }
241
+
242
  /**
243
  * Add Go to Pro and Documentation link
244
  * @param array $links
245
  * @return array
246
  */
247
  public function woo_feed_plugin_action_links( $links ) {
248
+
249
  $links[] = '<a style="color: #389e38; font-weight: bold;" href="https://webappick.com/plugin/woocommerce-product-feed-pro/?utm_source=freePlugin&utm_medium=go_premium&utm_campaign=free_to_pro&utm_term=wooFeed" target="_blank">' . __( 'Get Pro', 'woo-feed' ) . '</a>';
250
  /** @noinspection HtmlUnknownTarget */
251
  $links[] = sprintf( '<a style="color:#ce7304; font-weight: bold;" href="%s">%s</a>', esc_url( admin_url( 'admin.php?page=webappick-feed-docs' ) ), __( 'Docs', 'woo-feed' ) );
253
  $links[] = sprintf( '<a href="%s">%s</a>', esc_url( admin_url( 'admin.php?page=webappick-feed-settings' ) ), __( 'Settings', 'woo-feed' ) );
254
  return $links;
255
  }
256
+
257
  /**
258
  * Register the Plugin's Admin Pages for the admin area.
259
  *
282
  add_submenu_page( 'webappick-manage-feeds', __( 'Documentation', 'woo-feed' ), '<span class="woo-feed-docs">' . __( 'Docs', 'woo-feed' ) . '</span>', 'manage_woocommerce', 'webappick-feed-docs', array( WooFeedDocs::getInstance(), 'woo_feed_docs' ) );
283
  }
284
  }
285
+
286
  /**
287
  * Redirect user to with new menu slug (if user browser any bookmarked url)
288
  * @return void
admin/js/clipboard.min.js ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ /*!
2
+ * clipboard.js v2.0.4
3
+ * https://zenorocha.github.io/clipboard.js
4
+ *
5
+ * Licensed MIT © Zeno Rocha
6
+ */
7
+ !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return function(n){var o={};function r(t){if(o[t])return o[t].exports;var e=o[t]={i:t,l:!1,exports:{}};return n[t].call(e.exports,e,e.exports,r),e.l=!0,e.exports}return r.m=n,r.c=o,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=0)}([function(t,e,n){"use strict";var r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i=function(){function o(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}return function(t,e,n){return e&&o(t.prototype,e),n&&o(t,n),t}}(),a=o(n(1)),c=o(n(3)),u=o(n(4));function o(t){return t&&t.__esModule?t:{default:t}}var l=function(t){function o(t,e){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,o);var n=function(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}(this,(o.__proto__||Object.getPrototypeOf(o)).call(this));return n.resolveOptions(e),n.listenClick(t),n}return function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}(o,c.default),i(o,[{key:"resolveOptions",value:function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{};this.action="function"==typeof t.action?t.action:this.defaultAction,this.target="function"==typeof t.target?t.target:this.defaultTarget,this.text="function"==typeof t.text?t.text:this.defaultText,this.container="object"===r(t.container)?t.container:document.body}},{key:"listenClick",value:function(t){var e=this;this.listener=(0,u.default)(t,"click",function(t){return e.onClick(t)})}},{key:"onClick",value:function(t){var e=t.delegateTarget||t.currentTarget;this.clipboardAction&&(this.clipboardAction=null),this.clipboardAction=new a.default({action:this.action(e),target:this.target(e),text:this.text(e),container:this.container,trigger:e,emitter:this})}},{key:"defaultAction",value:function(t){return s("action",t)}},{key:"defaultTarget",value:function(t){var e=s("target",t);if(e)return document.querySelector(e)}},{key:"defaultText",value:function(t){return s("text",t)}},{key:"destroy",value:function(){this.listener.destroy(),this.clipboardAction&&(this.clipboardAction.destroy(),this.clipboardAction=null)}}],[{key:"isSupported",value:function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:["copy","cut"],e="string"==typeof t?[t]:t,n=!!document.queryCommandSupported;return e.forEach(function(t){n=n&&!!document.queryCommandSupported(t)}),n}}]),o}();function s(t,e){var n="data-clipboard-"+t;if(e.hasAttribute(n))return e.getAttribute(n)}t.exports=l},function(t,e,n){"use strict";var o,r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i=function(){function o(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}return function(t,e,n){return e&&o(t.prototype,e),n&&o(t,n),t}}(),a=n(2),c=(o=a)&&o.__esModule?o:{default:o};var u=function(){function e(t){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,e),this.resolveOptions(t),this.initSelection()}return i(e,[{key:"resolveOptions",value:function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{};this.action=t.action,this.container=t.container,this.emitter=t.emitter,this.target=t.target,this.text=t.text,this.trigger=t.trigger,this.selectedText=""}},{key:"initSelection",value:function(){this.text?this.selectFake():this.target&&this.selectTarget()}},{key:"selectFake",value:function(){var t=this,e="rtl"==document.documentElement.getAttribute("dir");this.removeFake(),this.fakeHandlerCallback=function(){return t.removeFake()},this.fakeHandler=this.container.addEventListener("click",this.fakeHandlerCallback)||!0,this.fakeElem=document.createElement("textarea"),this.fakeElem.style.fontSize="12pt",this.fakeElem.style.border="0",this.fakeElem.style.padding="0",this.fakeElem.style.margin="0",this.fakeElem.style.position="absolute",this.fakeElem.style[e?"right":"left"]="-9999px";var n=window.pageYOffset||document.documentElement.scrollTop;this.fakeElem.style.top=n+"px",this.fakeElem.setAttribute("readonly",""),this.fakeElem.value=this.text,this.container.appendChild(this.fakeElem),this.selectedText=(0,c.default)(this.fakeElem),this.copyText()}},{key:"removeFake",value:function(){this.fakeHandler&&(this.container.removeEventListener("click",this.fakeHandlerCallback),this.fakeHandler=null,this.fakeHandlerCallback=null),this.fakeElem&&(this.container.removeChild(this.fakeElem),this.fakeElem=null)}},{key:"selectTarget",value:function(){this.selectedText=(0,c.default)(this.target),this.copyText()}},{key:"copyText",value:function(){var e=void 0;try{e=document.execCommand(this.action)}catch(t){e=!1}this.handleResult(e)}},{key:"handleResult",value:function(t){this.emitter.emit(t?"success":"error",{action:this.action,text:this.selectedText,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)})}},{key:"clearSelection",value:function(){this.trigger&&this.trigger.focus(),window.getSelection().removeAllRanges()}},{key:"destroy",value:function(){this.removeFake()}},{key:"action",set:function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:"copy";if(this._action=t,"copy"!==this._action&&"cut"!==this._action)throw new Error('Invalid "action" value, use either "copy" or "cut"')},get:function(){return this._action}},{key:"target",set:function(t){if(void 0!==t){if(!t||"object"!==(void 0===t?"undefined":r(t))||1!==t.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===this.action&&t.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===this.action&&(t.hasAttribute("readonly")||t.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');this._target=t}},get:function(){return this._target}}]),e}();t.exports=u},function(t,e){t.exports=function(t){var e;if("SELECT"===t.nodeName)t.focus(),e=t.value;else if("INPUT"===t.nodeName||"TEXTAREA"===t.nodeName){var n=t.hasAttribute("readonly");n||t.setAttribute("readonly",""),t.select(),t.setSelectionRange(0,t.value.length),n||t.removeAttribute("readonly"),e=t.value}else{t.hasAttribute("contenteditable")&&t.focus();var o=window.getSelection(),r=document.createRange();r.selectNodeContents(t),o.removeAllRanges(),o.addRange(r),e=o.toString()}return e}},function(t,e){function n(){}n.prototype={on:function(t,e,n){var o=this.e||(this.e={});return(o[t]||(o[t]=[])).push({fn:e,ctx:n}),this},once:function(t,e,n){var o=this;function r(){o.off(t,r),e.apply(n,arguments)}return r._=e,this.on(t,r,n)},emit:function(t){for(var e=[].slice.call(arguments,1),n=((this.e||(this.e={}))[t]||[]).slice(),o=0,r=n.length;o<r;o++)n[o].fn.apply(n[o].ctx,e);return this},off:function(t,e){var n=this.e||(this.e={}),o=n[t],r=[];if(o&&e)for(var i=0,a=o.length;i<a;i++)o[i].fn!==e&&o[i].fn._!==e&&r.push(o[i]);return r.length?n[t]=r:delete n[t],this}},t.exports=n},function(t,e,n){var d=n(5),h=n(6);t.exports=function(t,e,n){if(!t&&!e&&!n)throw new Error("Missing required arguments");if(!d.string(e))throw new TypeError("Second argument must be a String");if(!d.fn(n))throw new TypeError("Third argument must be a Function");if(d.node(t))return s=e,f=n,(l=t).addEventListener(s,f),{destroy:function(){l.removeEventListener(s,f)}};if(d.nodeList(t))return a=t,c=e,u=n,Array.prototype.forEach.call(a,function(t){t.addEventListener(c,u)}),{destroy:function(){Array.prototype.forEach.call(a,function(t){t.removeEventListener(c,u)})}};if(d.string(t))return o=t,r=e,i=n,h(document.body,o,r,i);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList");var o,r,i,a,c,u,l,s,f}},function(t,n){n.node=function(t){return void 0!==t&&t instanceof HTMLElement&&1===t.nodeType},n.nodeList=function(t){var e=Object.prototype.toString.call(t);return void 0!==t&&("[object NodeList]"===e||"[object HTMLCollection]"===e)&&"length"in t&&(0===t.length||n.node(t[0]))},n.string=function(t){return"string"==typeof t||t instanceof String},n.fn=function(t){return"[object Function]"===Object.prototype.toString.call(t)}},function(t,e,n){var a=n(7);function i(t,e,n,o,r){var i=function(e,n,t,o){return function(t){t.delegateTarget=a(t.target,n),t.delegateTarget&&o.call(e,t)}}.apply(this,arguments);return t.addEventListener(n,i,r),{destroy:function(){t.removeEventListener(n,i,r)}}}t.exports=function(t,e,n,o,r){return"function"==typeof t.addEventListener?i.apply(null,arguments):"function"==typeof n?i.bind(null,document).apply(null,arguments):("string"==typeof t&&(t=document.querySelectorAll(t)),Array.prototype.map.call(t,function(t){return i(t,e,n,o,r)}))}},function(t,e){if("undefined"!=typeof Element&&!Element.prototype.matches){var n=Element.prototype;n.matches=n.matchesSelector||n.mozMatchesSelector||n.msMatchesSelector||n.oMatchesSelector||n.webkitMatchesSelector}t.exports=function(t,e){for(;t&&9!==t.nodeType;){if("function"==typeof t.matches&&t.matches(e))return t;t=t.parentNode}}}])});
admin/js/woo-feed-admin.min.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _defineProperties(e,t){for(var o=0;o<t.length;o++){var a=t[o];a.enumerable=a.enumerable||!1,a.configurable=!0,"value"in a&&(a.writable=!0),Object.defineProperty(e,a.key,a)}}function _createClass(e,t,o){return t&&_defineProperties(e.prototype,t),o&&_defineProperties(e,o),e}!function(s,a,c,l,d){s.fn.disabled=function(o){return s(this).each(function(){var e=s(this),t="disabled";void 0!==e.prop(t)?e.prop(t,void 0===o||!0===o):!0===o?e.addClass(t):e.removeClass(t)}),self},s.fn.isDisabled=function(){var e=s(this),t="disabled";return void 0!==e.prop(t)?e.prop(t):e.hasClass(t)};function e(e){s(e.currentTarget).removeClass(function(e,t){return(t.match(/\btooltipped-\S+/g)||[]).join(" ")}).removeClass("tooltipped").removeAttr("aria-label")}function o(e,t){s(e).addClass("tooltipped tooltipped-s").attr("aria-label",t)}function n(e,t){return s.extend(!0,{},e,t)}function t(){i=s(".toClipboard"),!ClipboardJS.isSupported()||/iPhone|iPad/i.test(navigator.userAgent)?i.find("img").hide(0):(i.each(function(){s(this).on("mouseleave",e).on("blur",e)}),new ClipboardJS(".toClipboard").on("error",function(e){var t;o(e.trigger,(t=e.action,e="cut"===t?"X":"C",t=/iPhone|iPad/i.test(navigator.userAgent)?"No support :(":/Mac/i.test(navigator.userAgent)?"Press ⌘-"+e+" to "+t:"Press Ctrl-"+e+" to "+t))}).on("success",function(e){o(e.trigger,"Copied")}))}var i,r,f,_=function(){function a(e,t,o){_classCallCheck(this,a),this.productCustomFields(e,t,o)}return _createClass(a,[{key:"cacheClear",value:function(){var e={action:"woo_feed_product_attribute_cache_remove",nonce:wpf_ajax_obj.ajax.nonce};s.ajax({method:"POST",url:wpf_ajax_obj.wpf_ajax_url,data:e})}},{key:"productCustomFields",value:function(t){var o=this,e={action:"woo_feed_custom_fields_status_change",nonce:wpf_ajax_obj.ajax.nonce,field:t,status:1<arguments.length&&void 0!==arguments[1]&&arguments[1],isTaxonomy:2<arguments.length?arguments[2]:void 0};s.ajax({method:"POST",url:wpf_ajax_obj.wpf_ajax_url,data:e,success:function(e){e.success?o.cacheClear():console.log(e),s("#"+t+"-switcher").closest("td").find(".switch-loader").hide()}})}}]),a}(),p=function(){function e(){_classCallCheck(this,e)}return _createClass(e,[{key:"wooFeed_get_google_categories",value:function(){l.send("get_google_categories",{type:"GET",data:{_ajax_nonce:d.nonce,action:"get_google_categories"}}).then(function(e){s(".selectize-google-category").selectize({valueField:"value",labelField:"text",placeholder:"Select a category",searchField:["value","text"],options:e,render:{option:function(e,t){return'<div class="item wapk-selectize-item">'.concat(t(e.value+" - "+e.text),"</div>")},item:function(e,t){return'<div class="item wapk-selectize-item">'.concat(t(e.value+" - "+e.text),"</div>")}}}),s(".woo-feed-cat-map-spinner").remove()}).fail(u.ajax_fail)}},{key:"wooFeed_get_facebook_categories",value:function(){l.send("get_facebook_categories",{type:"GET",data:{_ajax_nonce:d.nonce,action:"get_facebook_categories"}}).then(function(e){s(".selectize-google-category").selectize({valueField:"value",labelField:"text",placeholder:"Select a Facebook category",searchField:["value","text"],options:e,render:{option:function(e,t){return'<div class="item wapk-selectize-item">'.concat(t(e.value+" - "+e.text),"</div>")},item:function(e,t){return'<div class="item wapk-selectize-item">'.concat(t(e.value+" - "+e.text),"</div>")}}}),s(".woo-feed-cat-map-spinner").remove()}).fail(u.ajax_fail)}}]),e}(),u={in_array:function(e,t){try{return-1!==t.indexOf(e)}catch(e){return!1}},selectize_render_item:function(e,t){return'<div class="item wapk-selectize-item">'.concat(t(e.text),"</div>")},ajax_fail:function(e){console.warn(e),alert(e.hasOwnProperty("statusText")&&e.hasOwnProperty("status")?d.ajax.error+"\n"+e.statusText+" ("+e.status+")":e)},sortable:function(e,o,a,i){return(e||s(".sorted_table")).each(function(){var e=s(this),t=e.find("tbody > tr:eq(0) > td").length||a||9;e.wf_sortable(n({containerSelector:"table",itemPath:"> tbody",itemSelector:"tr",handle:"i.wf_sortedtable",placeholder:'<tr class="placeholder"><td colspan="'.concat(t,'"></td></tr>'),onDrop:function(e,t,o,a){e.removeClass(t.group.options.draggedClass).removeAttr("style"),s("body").removeClass(t.group.options.bodyClass);var n=e.find(".wf_mattributes").attr("name").replace(/\D/g,"");e.find("input.wf_attributes").attr("name","default["+n+"]"),i&&"function"==typeof i&&i(e,t,o,a)}},o))})},selectize:function(e,t){return(e||s("select.selectize")).not(".selectized").not(".selectize-google-category").each(function(){var e=s(this);e.selectize(n({create:e.data("create")||!1,plugins:e.data("plugins")?e.data("plugins").split(",").map(function(e){return e.trim()}):[],render:{item:u.selectize_render_item}},t))})},fancySelect:function(e,t){return(e||s("select.fancySelect")).not(".FancySelectInit").each(function(){s(this).fancySelect(n({maxItemShow:3},t))})},reindex_config_table:function(){s("#table-1").find("tbody tr").each(function(o,e){s(e).find("[name]").each(function(e,t){s(t).attr("name",s(t).attr("name").replace(/(\[\d\])/g,"[".concat(o,"]")))})})},common:function(){u.sortable(s(".sorted_table"),{},9,u.reindex_config_table),u.selectize(),u.fancySelect(s(".outputType"))}},h={form:null,init:function(){this.form=s(".generateFeed"),this.form.length&&(u.common(),s(c).trigger("feed_editor_init"),s(c).trigger(new jQuery.Event("feedEditor.init",{target:this.form})))},renderMerchantInfo:function(o,a,n){for(var e in n)!function(e){var t;n.hasOwnProperty(e)&&(o.find(".merchant-info-section."+e+" .data").html(n[e]),"feed_file_type"===e&&((t=n[e].split(",").map(function(e){return e.trim().toLowerCase()}).filter(function(e){return""!==e&&e!==d.na.toLowerCase()})).length?(a.find("option").removeAttr("selected").each(function(){var e=s(this);e.val()&&!u.in_array(e.val(),t)?e.disabled(!0):e.disabled(!1)}),1===t.length&&a.find('option[value="'+t[0]+'"]').attr("selected","selected")):a.find("option").disabled(!1)))}(e);o.find(".spinner").removeClass("is-active"),a.disabled(!1),a.trigger("change"),s(c).trigger("woo_feed_config_loaded"),a.parent().find(".spinner").removeClass("is-active")},renderMerchantTemplate:function(o,a){for(var e in a)!function(t){var e;a.hasOwnProperty(t)&&("tabs"===t?o.html(a[t]):(e=s('[name="'+t+'"]')).length&&e.each(function(){var e=s(this);e.is("select")?e.find('[value="'+a[t]+'"]').prop("selected",!0):(e.is("[type=checkbox]")||e.is("[type=radio]"))&&e.val()===a[t]?e.prop("checked",!0):e.val(a[t])}).trigger("change"))}(e);h.init()}},g=[],v=[],m=function(){function e(){_classCallCheck(this,e),this._feed=d.generator.feed,this._limit=d.generator.limit,this._progress=0,this._timer=null,this._color=!1,this._total_batch=0,this._current_batch=0,this._product_ids=[],this._progress_per_batch=0,this._refresh=!0,this._regenerate=d.generator.regenerate,a.isRegenerating=!1,this._all_btn=s(".wpf_regenerate"),this._current_btn=s("#".concat(this._feed.replace("wf_config","wf_feed_"))),this._current_btn_label=""}return _createClass(e,[{key:"init",value:function(){var t=this;""!==this._feed&&this._regenerate&&!1===a.isRegenerating&&this.generate();var e=a.location.search;return"webappick-manage-feeds"===new URLSearchParams(e).get("page")&&s("body").addClass("woo-import-popup-body"),s(c).on("click",".woo-feed-campaign-close-button",function(e){e.preventDefault(),s(this).parent(".woo-feed-promotion").hide();e=s(this).data("condition");1===e&&l.post("woo_feed_hide_promotion",{_ajax_nonce:d.nonce,condition:e}).then(function(e){t._log(e)}).fail(function(e){t._log(e),t._updateProgressStatus(e.message),t._color="red"})}),s(c).on("click",".wpf_regenerate",function(e){e.preventDefault(),t._current_btn=s(this),t._current_btn.hasClass("disabled")||!0===a.isRegenerating||(t._feed=t._current_btn.attr("id").replace("wf_feed_","wf_config"),""!==t._feed&&t.generate())}),this}},{key:"_block_button",value:function(){this._all_btn.length&&this._all_btn.addClass("disabled"),this._current_btn.length&&(this._current_btn.find("span").addClass("wpf_spin reverse_spin"),this._current_btn_label=this._current_btn.attr("title"),this._current_btn.attr("aria-label",d.regenerate).attr("title",d.regenerate))}},{key:"_unblock_button",value:function(){this._all_btn.length&&this._all_btn.removeClass("disabled"),this._current_btn.length&&(this._current_btn.find("span").removeClass("wpf_spin"),this._current_btn.find("span").removeClass("reverse_spin"),this._current_btn.attr("aria-label",this._current_btn_label).attr("title",this._current_btn_label))}},{key:"generate",value:function(){var t=this,o=this;a.isRegenerating=!0,this._block_button(),this._resetProgressBar(),this._progressBarActive(),this._log("Counting Total Products"),this._updateProgressStatus("Fetching products."),this._get_product_ids().then(function(e){t._progress=10,o._log({response:e}),e.success?(o._log("Total ".concat(e.total," Products found.")),o._product_ids=e.product,o._total_batch=t._product_ids.length,o._current_batch=0,o._progress_per_batch=(90-t._progress)/t._total_batch,o._process_batch(),o._updateProgressStatus("Processing Products...")):o._updateProgressStatus(e.data.message)}).fail(function(e){o._log(e),o._updateProgressStatus(e.message),o._color="red",setTimeout(function(){o._stopProgressBar(),o._unblock_button()},1500)})}},{key:"_get_product_ids",value:function(){return this._progress=5,l.post("get_product_information",{_ajax_nonce:d.nonce,feed:this._feed,limit:this._limit})}},{key:"_process_batch",value:function(){var t=this,e="Processing Batch ".concat(this._current_batch+1," of ").concat(this._total_batch);this._updateProgressStatus(e),this._log(e),l.post("make_batch_feed",{_ajax_nonce:d.nonce,feed:this._feed,products:this._product_ids[this._current_batch],loop:this._current_batch}).then(function(e){t._current_batch++,t._log("Batch ".concat(t._current_batch," Completed")),t._log(e),t._current_batch<t._total_batch&&(t._process_batch(),t._progress+=t._progress_per_batch),t._current_batch===t._total_batch&&t._save_feed_file()}).fail(function(e){t._log(e),t._updateProgressStatus(e.message),t._color="red",setTimeout(function(){t._stopProgressBar(),t._unblock_button()},1500)})}},{key:"_save_feed_file",value:function(){var t=this;this._log("Saving feed file"),this._updateProgressStatus("Saving feed file"),l.post("save_feed_file",{_ajax_nonce:d.nonce,feed:this._feed}).then(function(e){t._log(e),t._progress=100,t._refresh&&(a.location.href="".concat(d.pages.list.feed,"&link=").concat(e.url,"&cat=").concat(e.cat)),setTimeout(function(){t._stopProgressBar(),setTimeout(function(){t._resetProgressBar(!0),t._unblock_button()},3e3)},2500)}).fail(function(e){t._log(e),t._updateProgressStatus(e.message),t._color="red",setTimeout(function(){t._stopProgressBar(),t._unblock_button()},1500)})}},{key:"_log",value:function(e){return d.wpf_debug&&console.log(e),this}},{key:"_progressBarActive",value:function(){var e=0<arguments.length&&void 0!==arguments[0]?arguments[0]:0,t=this;return this._toggleProgressBar(!0),this._timer=setInterval(function(){t._updateProgressBar()},e||1e3),this}},{key:"_stopProgressBar",value:function(){return clearInterval(this._timer),this}},{key:"_resetProgressBar",value:function(e){return this._toggleProgressBar(!1),this._updateProgressStatus(""),clearInterval(this._timer),this._color=!1,this._timer=null,this._progress=0,e&&this._updateProgressBar(),this}},{key:"_toggleProgressBar",value:function(e){var t=s("#feed_progress_table");return e?t.show():t.hide(),this}},{key:"_updateProgressStatus",value:function(e){return s(".feed-progress-status").html(e),this}},{key:"_getErrorMessageByCode",value:function(e){s(".feed-progress-status").css({color:this._color}),s(".feed-progress-percentage").css({color:this._color}),s(".wpf_spin").css({color:this._color});var t=e.status+" : "+e.statusText+". ";500===e.status&&(t+="Please increase your PHP max_execution_time. Please <a target='_blank' href='https://webappick.com/docs/woo-feed/faq-for-woocommerce-product-feed/how-to-solve-processing-10-feed-generation-stuck-error/'>read this doc</a>."),this._updateProgressStatus(t)}},{key:"_updateProgressBar",value:function(){var e=s(".feed-progress-percentage"),t=s(".feed-progress-bar-fill"),o="".concat(Math.round(this._progress),"%");t.css({width:o}),e.text(o)}}]),e}();a.wf={helper:u,feedEditor:h,generator:m},s(a).on("load",function(){null!==s(location).attr("href").match(/webappick.*feed/g)&&s("#wpbody-content").addClass("woofeed-body-content"),t(),postboxes.add_postbox_toggles(pagenow),(new m).init(),""!==d.generator.feed&&d.generator.regenerate,h.init(),u.common(),s(".wfmasterTooltip").hover(function(){var e=s(this),t=e.attr("wftitle");e.data("tipText",t).removeAttr("wftitle"),s('<p class="wftooltip"></p>').text(t).appendTo("body").fadeIn("slow")},function(){var e=s(this);e.attr("wftitle",e.data("tipText")),s(".wftooltip").remove()}).mousemove(function(e){s(".wftooltip").css({top:e.pageY+10,left:e.pageX+20})}),s(".generateFeed").validate(),s(c).on("blur",'input[name="wfDAttributeName"]',function(e){e.preventDefault();e=s(this).val();e=(e=e.toLowerCase()).split(" ").join("_"),s("#wfDAttributeCode").val(e)}).on("click","[data-toggle_slide]",function(e){e.preventDefault(),s(s(this).data("toggle_slide")).slideToggle("fast")}).on("click","#wf_newRow",function(){var e=s("#table-1 tbody"),t=s("#feed_config_template").text().trim().replace(/__idx__/g,e.find("tr").length);e.append(t),u.fancySelect(s(".outputType"))}).on("click",".single-feed-delete",function(e){e.preventDefault(),confirm(d.form.del_confirm)&&(a.location.href=s(this).attr("val"))}).on("click",".wf_clean_cache_wrapper",function(e){e.preventDefault();var e=s(".woo-feed-clean-cache-nonce").val(),t=s(".woo-feed-cache-loader");t.show(),l.post("clear_cache_data",{_ajax_clean_nonce:e}).then(function(e){e.success&&(t.hide(),location.reload())}).fail(function(){console.log("something wrong")})}).on("click","#woo-feed-copy-status-btn",function(e){e.preventDefault();var t=s("#woo-feed-copy-status-btn"),e=s("#woo-feed-status-area");t.val("Copied"),e.css("visibility","visible"),e.select(),c.execCommand("copy")}).on("change",".wf_attr.wf_attributes",function(e){e.preventDefault(),s(".fancy-picker-picked").trigger("click");var t,o=s(this).val(),a=s(this).parents("tr").find(".outputType"),e=s(this).parents("tr").find(".fancy-picker-content .fancy-picker-option"),n=s(this).parents("tr").find(".fancy-picker-data span"),i=["price","current_price","sale_price","price_with_tax","current_price_with_tax","sale_price_with_tax","shipping_cost"].includes(o)?(t="for_price","Price"):""!==o&&-1!==o.indexOf("wf_taxo")?(t="for_custom_taxo","parent_if_empty"):(t="for_all","Default");e.removeClass("selected"),"for_custom_taxo"===t||"for_price"===t?(e.each(function(){i===s(this).text()&&(s(this).addClass("selected"),n.text(i),a.find("option").text(i),a.find("option").val(s(this).data("value")))}),"for_price"===t&&(t=null!=(t=s("#feedCurrency").val())?t:wpf_ajax_obj.woocommerce.currency,s(this).closest("tr").find("td:eq(5) input").val(" "+t))):(e.each(function(){i===s(this).text()&&(s(this).addClass("selected"),n.text(i),a.find("option").text(i),a.find("option").val(s(this).data("value")))}),s(this).closest("tr").find("td:eq(5) input").val(""))}).on("click","#doaction, #doaction2",function(){return confirm(d.form.del_confirm_multi)}).on("change",".dType",function(){var e=s(this),t=e.val(),e=e.closest("tr");"pattern"===t?(e.find(".value_attribute").hide(),e.find(".value_pattern").show()):"attribute"===t?(e.find(".value_attribute").show(),e.find(".value_pattern").hide()):"remove"===t&&(e.find(".value_attribute").hide(),e.find(".value_pattern").hide())}).on("click",".delRow",function(e){e.preventDefault(),s(this).closest("tr").remove(),u.reindex_config_table()}).on("submit","#generateFeed",function(){s(this).validate(),s(this).valid()&&s(".makeFeedResponse").show().html('<b style="color: darkblue;"><i class="dashicons dashicons-sos wpf_spin"></i> '.concat(d.form.generate,"</b>"))}).on("submit","#updatefeed",function(e,t){s(this).validate(),s(this).valid()&&s(".makeFeedResponse").show().html('<b style="color: darkblue;"><i class="dashicons dashicons-sos wpf_spin"></i> '.concat(t&&t.save?d.form.save:d.form.generate,"</b>"))}).on("ready woo_feed_config_loaded",function(){"0"===s("#ftpenabled").val()?(s(".google-merchant-message").hide("slow"),s(".woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) input, .woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) select").attr("disabled","disabled")):("google"===s("#provider").val()?s(".google-merchant-message").show("slow"):s(".google-merchant-message").hide("slow"),s(".woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) input, .woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) select").removeAttr("disabled")),s("#ftpenabled").on("change",function(){"0"===s("#ftpenabled").val()?(s(".google-merchant-message").hide("slow"),s(".woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) input, .woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) select").attr("disabled","disabled")):(s(".woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) input, .woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) select").removeAttr("disabled"),"google"===s("#provider").val()?s(".google-merchant-message").show("slow"):s(".google-merchant-message").hide("slow"))})}).on("change",".ftporsftp",function(){var e=s(this).val(),t=s(".ssh2_status");"sftp"===e?(t.show().css("color","dodgerblue").text(d.form.sftp_checking),l.post("get_ssh2_status",{_ajax_nonce:d.nonce,server:e}).then(function(e){"exists"===e?(t.css("color","#2CC185").text(d.form.sftp_available),setTimeout(function(){t.hide()},1500)):t.show().css("color","red").text(d.form.sftp_warning)}).fail(function(e){t.hide(),u.ajax_fail(e)})):t.hide()}).on("click",'[name="save_feed_config"]',function(e){e.preventDefault(),s("#updatefeed").trigger("submit",{save:!0})}).on("change","#provider",function(e){e.preventDefault();var t=s(this).val(),o=s(this).find(":selected").text(),a=s("#filename").val(),n=s("#feedType"),i=s("#providerPage"),r=s("#feed_merchant_info");i.html('<h3><span style="float:none;margin: -3px 0 0;" class="spinner is-active"></span> '+d.form.loading_tmpl+"</h3>"),r.find(".spinner").addClass("is-active"),n.disabled(!0),n.parent().find(".spinner").addClass("is-active"),r.find(".merchant-info-section .data").html(""),g.hasOwnProperty(t)?(h.renderMerchantInfo(r,n,g[t]),s(c).trigger("woo_feed_config_loaded")):l.send("woo_feed_get_merchant_info",{type:"GET",data:{nonce:d.nonce,provider:t,templateName:o}}).then(function(e){g[t]=e,h.renderMerchantInfo(r,n,e)}).then(function(){s(c).trigger("woo_feed_config_loaded")}).fail(u.ajax_fail),v.hasOwnProperty(t)?(h.renderMerchantTemplate(i,v[t]),s(c).trigger("woo_feed_config_loaded")):l.post("get_feed_merchant",{_ajax_nonce:d.nonce,merchant:t}).then(function(e){v[t]=e,h.renderMerchantTemplate(i,e),s("#utm_source").val(o),s("#utm_campaign").val(a),"bing"===t&&(s("#delimiter option").removeAttr("selected"),s('#delimiter option[value="tab"]').attr("selected","selected"),s("#enclosure option").removeAttr("selected"),s('#enclosure option[value=" "]').attr("selected","selected")),"google_product_review"!==t&&s('.wf_attributes option[value="reviewer_name"]').hide()}).then(function(){s(c).trigger("woo_feed_config_loaded")}).fail(u.ajax_fail)}).on("change",".woo_feed_status_input",function(){var e=s(this);l.post("update_feed_status",{_ajax_nonce:d.nonce,feedName:e.val(),status:e[0].checked?1:0})}),s(c).on("change",'[name="is_outOfStock"], [name="product_visibility"]',function(){var e=s(".out-of-stock-visibility");"n"===s('[name="is_outOfStock"]:checked').val()&&"1"===s('[name="product_visibility"]:checked').val()?e.show():e.hide()}).on("change",".attr_type",function(){var e=s(this),t=e.val(),e=e.closest("tr");"pattern"===t?(e.find(".wf_attr").hide(),e.find(".wf_attr").val(""),e.find(".wf_default").show()):(e.find(".wf_attr").show(),e.find(".wf_default").hide(),e.find(".wf_default").val(""))}).on("change",".wf_mattributes, .attr_type",function(){var e=s(this).closest("tr"),o=e.find(".wf_mattributes"),t=e.find(".attr_type"),a=e.find("td:eq(4)"),n=s("#provider").val();d.form.google_category.hasOwnProperty(o.val())&&"pattern"===t.val()&&u.in_array(n,d.form.google_category[o.val()])?0===a.find("select.selectize").length&&(a.find("input.wf_default").remove(),a.append('<span class="wf_default wf_attributes"><select name="default[]" class="selectize"></select></span>'),a.append('<span style="font-size:x-small;"><a style="color: red" href="https://webappick.com/docs/woo-feed/feed-configuration/how-to-map-store-category-with-merchant-category/" target="_blank">'.concat(d.learn_more,"</a></span>")),r&&f||a.append('<span class="spinner is-active" style="margin: 0;"></span>'),e=a.find(".wf_attributes select"),u.selectize(e,{preload:!0,placeholder:d.form.select_category,load:function(e,t){r?t(r):l.send("get_google_categories",{type:"GET",data:{_ajax_nonce:d.nonce,action:"get_google_categories",provider:n}}).then(function(e){t(r=e),a.find(".spinner").remove()}).fail(u.ajax_fail),f||"facebook"!==n||"fb_product_category"!==o.val()?t(f):l.send("get_facebook_categories",{type:"GET",data:{_ajax_nonce:d.nonce,action:"get_facebook_categories",provider:n}}).then(function(e){t(f=e),a.find(".spinner").remove()}).fail(u.ajax_fail)}})):"current_category"!==o.val()&&0===a.find("input.wf_default").length&&(a.find("span").remove(),a.append('<input autocomplete="off" class="wf_default wf_attributes" type="text" name="default[]" value="">'),"pattern"!==t.val()&&a.find("input.wf_default").hide())}).on("change","#feedType,#provider",function(e){var t=s("#feedType").val(),o=s("#provider").val(),a=s(".itemWrapper"),n=s(".wf_csvtxt");""!==t&&u.in_array(o,d.form.item_wrapper_hidden)&&a.hide(),"feedType"===e.target.id&&("csv"===t||"txt"===t||"tsv"===t?(n.show(),a.hide(),"tsv"===t?s("#delimiter option:last").prop("selected","selected"):"csv"===t&&s("#delimiter option:first").prop("selected","selected")):"xml"===t&&"custom"===o?(a.show(),n.hide()):"json"===t&&n.hide()),"custom"!==o&&a.hide()}).trigger("change"),s(c).on("click",'.woofeed-custom-fields [id*="-switcher"]',function(){s(this).closest("td").find(".switch-loader").show();var e=s(this).attr("id").split("-")[0],t=s(this).data("taxonomy"),o=s(this).prop("checked");new _(e,o,t)}).ready(function(){var e=s(".wapk-feed-buy-now-container");s(a).scroll(function(){s(a).scrollTop()<=5e3?e.addClass("fixed"):e.removeClass("fixed")})})}),s(c).on("click","#woo-feed-debug-log-download",function(e){e.preventDefault(),s("<a />",{download:new Date+".log",href:URL.createObjectURL(new Blob([s("#woo-feed-debug-log").val()],{type:"text/plain"}))}).appendTo("body")[0].click()}).on("keyup","#filename",function(){var e=s("#filename").val();s("#utm_campaign").val(e)}).on("click",".wf-tab-name",function(e){s(".wf-tab-name.activate").removeClass("activate"),s(this).addClass("activate");var t=s(this).attr("for");s(".wf_tabs li.active").removeClass("active"),s(".wf_tabs .wf-tab-content#"+t).parent().addClass("active")}).on("change","#category-mapping-form #providers",function(){var e,t=s(this).find(":selected").val();s(".woo-feed-category-mapping-config-table").prepend('<div class="woo-feed-cat-map-spinner"><h3><span style="float:none;margin: -3px 0 0;" class="spinner is-active"></span> Loading Mapping...</h3></div>'),-1!==["google","facebook","pinterest","bing","bing_local_inventory","snapchat","tiktok"].indexOf(t)?(s('input[id*="cat_mapping_"]').css("display","none"),s(".wf_default.wf_attributes").css("display","block").css("width","100%"),e=new p,"facebook"===t?e.wooFeed_get_facebook_categories():e.wooFeed_get_google_categories()):(s('input[id*="cat_mapping_"]').css("display","block"),s(".wf_default.wf_attributes").css("display","none").css("width","100%"))}).on("click",'span[id*="cat-map-"]',function(e){e.preventDefault();var o,t=s("#category-mapping-form #providers").val(),a=s(this).attr("id").replace(/[^\d.]/g,""),e="group-child-"+a;-1!==["google","facebook","pinterest","bing","bing_local_inventory","snapchat","tiktok"].indexOf(t)?(o=s(this).parents("tr").find(".selectized").val())&&s("."+e).parents("tr").find("select").each(function(e,t){s(t).data("selectize").setValue(o)}):(a=s("#cat_mapping_"+a).val(),s("."+e).parents("tr").find("input").val(a))}),s(c).ready(function(){var e=s("#providers").val(),t=new p;"edit-mapping"===new URL(a.location.href).searchParams.get("action")&&(s(".woo-feed-category-mapping-config-table").prepend('<div class="woo-feed-cat-map-spinner"><h3><span style="float:none;margin: -3px 0 0;" class="spinner is-active"></span> Loading Mapping...</h3></div>'),"facebook"===e?t.wooFeed_get_facebook_categories():t.wooFeed_get_google_categories())}),s(c).on("feed_editor_init",function(){var t=s(".merchant-info-section.feed_file_type .data").html().split(",").map(function(e){return e.trim().toLowerCase()}),e=s("#feedType");t.length?(e.find("option").each(function(){var e=s(this);e.val()&&!u.in_array(e.val(),t)?e.disabled(!0):e.disabled(!1)}),1===t.length&&e.find('option[value="'+t[0]+'"]').attr("selected","selected")):e.find("option").disabled(!1)}),s(c).on("ready",function(){s(c).on("feedEditor.init",function(){var e=s(this).find(":selected").val();-1!==["google","facebook","pinterest","bing","bing_local_inventory","snapchat","tiktok"].indexOf(e)&&function(){var i,t={price:wpf_ajax_obj.woocommerce.currency,current_price:wpf_ajax_obj.woocommerce.currency,sale_price:wpf_ajax_obj.woocommerce.currency,price_with_tax:wpf_ajax_obj.woocommerce.currency,current_price_with_tax:wpf_ajax_obj.woocommerce.currency,sale_price_with_tax:wpf_ajax_obj.woocommerce.currency,weight:wpf_ajax_obj.woocommerce.weight,weight_unit:wpf_ajax_obj.woocommerce.weight,height:wpf_ajax_obj.woocommerce.dimension,length:wpf_ajax_obj.woocommerce.dimension,width:wpf_ajax_obj.woocommerce.dimension};void 0!==wpf_ajax_obj.feed_rules&&null!==wpf_ajax_obj.feed_rules&&(i=wpf_ajax_obj.feed_rules.feedCurrency);var e=a.location.search,r=new URLSearchParams(e).get("action");s(".wf_attr.wf_attributes").each(function(o,e){var a=s(e).val(),n=s('input[name^="suffix"]').eq(parseInt(o)).val();-1!==s.inArray(n,[" "+wpf_ajax_obj.woocommerce.currency," "+wpf_ajax_obj.woocommerce.weight," "+wpf_ajax_obj.woocommerce.dimension])&&s('input[name^="suffix"]').eq(parseInt(o)).val(""),s.each(t,function(e,t){a===e&&(t=null!=i?i:t,"undefined"!==r&&"edit-feed"!==r?s('input[name^="suffix"]').eq(parseInt(o)).val(" "+t):s('input[name^="suffix"]').eq(parseInt(o)).val(n))})}),s(c).trigger("feedEditor.after.free.postfix.update")}()})})}(jQuery,window,document,wp.ajax,wpf_ajax_obj);
2
  //# sourceMappingURL=woo-feed-admin.min.js.map
1
+ "use strict";function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _defineProperties(e,t){for(var o=0;o<t.length;o++){var a=t[o];a.enumerable=a.enumerable||!1,a.configurable=!0,"value"in a&&(a.writable=!0),Object.defineProperty(e,a.key,a)}}function _createClass(e,t,o){return t&&_defineProperties(e.prototype,t),o&&_defineProperties(e,o),e}!function(s,a,c,l,d){s.fn.disabled=function(o){return s(this).each(function(){var e=s(this),t="disabled";void 0!==e.prop(t)?e.prop(t,void 0===o||!0===o):!0===o?e.addClass(t):e.removeClass(t)}),self},s.fn.isDisabled=function(){var e=s(this),t="disabled";return void 0!==e.prop(t)?e.prop(t):e.hasClass(t)};function e(e){s(e.currentTarget).removeClass(function(e,t){return(t.match(/\btooltipped-\S+/g)||[]).join(" ")}).removeClass("tooltipped").removeAttr("aria-label")}function o(e,t){s(e).addClass("tooltipped tooltipped-s").attr("aria-label",t)}function n(e,t){return s.extend(!0,{},e,t)}function t(){i=s(".toClipboard"),!ClipboardJS.isSupported()||/iPhone|iPad/i.test(navigator.userAgent)?i.find("img").hide(0):(i.each(function(){s(this).on("mouseleave",e).on("blur",e)}),new ClipboardJS(".toClipboard").on("error",function(e){var t;o(e.trigger,(t=e.action,e="cut"===t?"X":"C",t=/iPhone|iPad/i.test(navigator.userAgent)?"No support :(":/Mac/i.test(navigator.userAgent)?"Press ⌘-"+e+" to "+t:"Press Ctrl-"+e+" to "+t))}).on("success",function(e){o(e.trigger,"Copied")}))}var i,r,f,_=function(){function a(e,t,o){_classCallCheck(this,a),this.productCustomFields(e,t,o)}return _createClass(a,[{key:"cacheClear",value:function(){var e={action:"woo_feed_product_attribute_cache_remove",nonce:wpf_ajax_obj.ajax.nonce};s.ajax({method:"POST",url:wpf_ajax_obj.wpf_ajax_url,data:e})}},{key:"productCustomFields",value:function(t){var o=this,e={action:"woo_feed_custom_fields_status_change",nonce:wpf_ajax_obj.ajax.nonce,field:t,status:1<arguments.length&&void 0!==arguments[1]&&arguments[1],isTaxonomy:2<arguments.length?arguments[2]:void 0};s.ajax({method:"POST",url:wpf_ajax_obj.wpf_ajax_url,data:e,success:function(e){e.success?o.cacheClear():console.log(e),s("#"+t+"-switcher").closest("td").find(".switch-loader").hide()}})}}]),a}(),p=function(){function e(){_classCallCheck(this,e)}return _createClass(e,[{key:"wooFeed_get_google_categories",value:function(){l.send("get_google_categories",{type:"GET",data:{_ajax_nonce:d.nonce,action:"get_google_categories"}}).then(function(e){s(".selectize-google-category").selectize({valueField:"value",labelField:"text",placeholder:"Select a category",searchField:["value","text"],options:e,render:{option:function(e,t){return'<div class="item wapk-selectize-item">'.concat(t(e.value+" - "+e.text),"</div>")},item:function(e,t){return'<div class="item wapk-selectize-item">'.concat(t(e.value+" - "+e.text),"</div>")}}}),s(".woo-feed-cat-map-spinner").remove()}).fail(u.ajax_fail)}},{key:"wooFeed_get_facebook_categories",value:function(){l.send("get_facebook_categories",{type:"GET",data:{_ajax_nonce:d.nonce,action:"get_facebook_categories"}}).then(function(e){s(".selectize-google-category").selectize({valueField:"value",labelField:"text",placeholder:"Select a Facebook category",searchField:["value","text"],options:e,render:{option:function(e,t){return'<div class="item wapk-selectize-item">'.concat(t(e.value+" - "+e.text),"</div>")},item:function(e,t){return'<div class="item wapk-selectize-item">'.concat(t(e.value+" - "+e.text),"</div>")}}}),s(".woo-feed-cat-map-spinner").remove()}).fail(u.ajax_fail)}}]),e}(),u={in_array:function(e,t){try{return-1!==t.indexOf(e)}catch(e){return!1}},selectize_render_item:function(e,t){return'<div class="item wapk-selectize-item">'.concat(t(e.text),"</div>")},ajax_fail:function(e){console.warn(e),alert(e.hasOwnProperty("statusText")&&e.hasOwnProperty("status")?d.ajax.error+"\n"+e.statusText+" ("+e.status+")":e)},sortable:function(e,o,a,i){return(e||s(".sorted_table")).each(function(){var e=s(this),t=e.find("tbody > tr:eq(0) > td").length||a||9;e.wf_sortable(n({containerSelector:"table",itemPath:"> tbody",itemSelector:"tr",handle:"i.wf_sortedtable",placeholder:'<tr class="placeholder"><td colspan="'.concat(t,'"></td></tr>'),onDrop:function(e,t,o,a){e.removeClass(t.group.options.draggedClass).removeAttr("style"),s("body").removeClass(t.group.options.bodyClass);var n=e.find(".wf_mattributes").attr("name").replace(/\D/g,"");e.find("input.wf_attributes").attr("name","default["+n+"]"),i&&"function"==typeof i&&i(e,t,o,a)}},o))})},selectize:function(e,t){return(e||s("select.selectize")).not(".selectized").not(".selectize-google-category").each(function(){var e=s(this);e.selectize(n({create:e.data("create")||!1,plugins:e.data("plugins")?e.data("plugins").split(",").map(function(e){return e.trim()}):[],render:{item:u.selectize_render_item}},t))})},fancySelect:function(e,t){return(e||s("select.fancySelect")).not(".FancySelectInit").each(function(){s(this).fancySelect(n({maxItemShow:3},t))})},reindex_config_table:function(){s("#table-1").find("tbody tr").each(function(o,e){s(e).find("[name]").each(function(e,t){s(t).attr("name",s(t).attr("name").replace(/(\[\d\])/g,"[".concat(o,"]")))})})},common:function(){u.sortable(s(".sorted_table"),{},9,u.reindex_config_table),u.selectize(),u.fancySelect(s(".outputType"))}},h={form:null,init:function(){this.form=s(".generateFeed"),this.form.length&&(u.common(),s(c).trigger("feed_editor_init"),s(c).trigger(new jQuery.Event("feedEditor.init",{target:this.form})))},renderMerchantInfo:function(o,a,n){for(var e in n)!function(e){var t;n.hasOwnProperty(e)&&(o.find(".merchant-info-section."+e+" .data").html(n[e]),"feed_file_type"===e&&((t=n[e].split(",").map(function(e){return e.trim().toLowerCase()}).filter(function(e){return""!==e&&e!==d.na.toLowerCase()})).length?(a.find("option").removeAttr("selected").each(function(){var e=s(this);e.val()&&!u.in_array(e.val(),t)?e.disabled(!0):e.disabled(!1)}),1===t.length&&a.find('option[value="'+t[0]+'"]').attr("selected","selected")):a.find("option").disabled(!1)))}(e);o.find(".spinner").removeClass("is-active"),a.disabled(!1),a.trigger("change"),s(c).trigger("woo_feed_config_loaded"),a.parent().find(".spinner").removeClass("is-active")},renderMerchantTemplate:function(o,a){for(var e in a)!function(t){var e;a.hasOwnProperty(t)&&("tabs"===t?o.html(a[t]):(e=s('[name="'+t+'"]')).length&&e.each(function(){var e=s(this);e.is("select")?e.find('[value="'+a[t]+'"]').prop("selected",!0):(e.is("[type=checkbox]")||e.is("[type=radio]"))&&e.val()===a[t]?e.prop("checked",!0):e.val(a[t])}).trigger("change"))}(e);h.init()}},g=[],v=[],m=function(){function e(){_classCallCheck(this,e),this._feed=d.generator.feed,this._limit=d.generator.limit,this._progress=0,this._timer=null,this._color=!1,this._total_batch=0,this._current_batch=0,this._product_ids=[],this._progress_per_batch=0,this._refresh=!0,this._regenerate=d.generator.regenerate,a.isRegenerating=!1,this._all_btn=s(".wpf_regenerate"),this._current_btn=s("#".concat(this._feed.replace("wf_config","wf_feed_"))),this._current_btn_label=""}return _createClass(e,[{key:"init",value:function(){var t=this;""!==this._feed&&this._regenerate&&!1===a.isRegenerating&&this.generate();var e=a.location.search;return"webappick-manage-feeds"===new URLSearchParams(e).get("page")&&s("body").addClass("woo-import-popup-body"),s(c).on("click",".woo-feed-campaign-close-button",function(e){e.preventDefault(),s(this).parent(".woo-feed-promotion").hide();e=s(this).data("condition");1===e&&l.post("woo_feed_hide_promotion",{_ajax_nonce:d.nonce,condition:e}).then(function(e){t._log(e)}).fail(function(e){t._log(e),t._updateProgressStatus(e.message),t._color="red"})}),s(c).on("click",".wpf_regenerate",function(e){e.preventDefault(),t._current_btn=s(this),t._current_btn.hasClass("disabled")||!0===a.isRegenerating||(t._feed=t._current_btn.attr("id").replace("wf_feed_","wf_config"),""!==t._feed&&t.generate())}),this}},{key:"_block_button",value:function(){this._all_btn.length&&this._all_btn.addClass("disabled"),this._current_btn.length&&(this._current_btn.find("span").addClass("wpf_spin reverse_spin"),this._current_btn_label=this._current_btn.attr("title"),this._current_btn.attr("aria-label",d.regenerate).attr("title",d.regenerate))}},{key:"_unblock_button",value:function(){this._all_btn.length&&this._all_btn.removeClass("disabled"),this._current_btn.length&&(this._current_btn.find("span").removeClass("wpf_spin"),this._current_btn.find("span").removeClass("reverse_spin"),this._current_btn.attr("aria-label",this._current_btn_label).attr("title",this._current_btn_label))}},{key:"generate",value:function(){var t=this,o=this;a.isRegenerating=!0,this._block_button(),this._resetProgressBar(),this._progressBarActive(),this._log("Counting Total Products"),this._updateProgressStatus("Fetching products."),this._get_product_ids().then(function(e){t._progress=10,o._log({response:e}),e.success?(o._log("Total ".concat(e.total," Products found.")),o._product_ids=e.product,o._total_batch=t._product_ids.length,o._current_batch=0,o._progress_per_batch=(90-t._progress)/t._total_batch,o._process_batch(),o._updateProgressStatus("Processing Products...")):o._updateProgressStatus(e.data.message)}).fail(function(e){o._log(e),o._updateProgressStatus(e.message),o._color="red",setTimeout(function(){o._stopProgressBar(),o._unblock_button()},1500)})}},{key:"_get_product_ids",value:function(){return this._progress=5,l.post("get_product_information",{_ajax_nonce:d.nonce,feed:this._feed,limit:this._limit})}},{key:"_process_batch",value:function(){var t=this,e="Processing Batch ".concat(this._current_batch+1," of ").concat(this._total_batch);this._updateProgressStatus(e),this._log(e),l.post("make_batch_feed",{_ajax_nonce:d.nonce,feed:this._feed,products:this._product_ids[this._current_batch],loop:this._current_batch}).then(function(e){t._current_batch++,t._log("Batch ".concat(t._current_batch," Completed")),t._log(e),t._current_batch<t._total_batch&&(t._process_batch(),t._progress+=t._progress_per_batch),t._current_batch===t._total_batch&&t._save_feed_file()}).fail(function(e){t._log(e),t._updateProgressStatus(e.message),t._color="red",setTimeout(function(){t._stopProgressBar(),t._unblock_button()},1500)})}},{key:"_save_feed_file",value:function(){var t=this;this._log("Saving feed file"),this._updateProgressStatus("Saving feed file"),l.post("save_feed_file",{_ajax_nonce:d.nonce,feed:this._feed}).then(function(e){t._log(e),t._progress=100,t._refresh&&(a.location.href="".concat(d.pages.list.feed,"&link=").concat(e.url,"&cat=").concat(e.cat)),setTimeout(function(){t._stopProgressBar(),setTimeout(function(){t._resetProgressBar(!0),t._unblock_button()},3e3)},2500)}).fail(function(e){t._log(e),t._updateProgressStatus(e.message),t._color="red",setTimeout(function(){t._stopProgressBar(),t._unblock_button()},1500)})}},{key:"_log",value:function(e){return d.wpf_debug&&console.log(e),this}},{key:"_progressBarActive",value:function(){var e=0<arguments.length&&void 0!==arguments[0]?arguments[0]:0,t=this;return this._toggleProgressBar(!0),this._timer=setInterval(function(){t._updateProgressBar()},e||1e3),this}},{key:"_stopProgressBar",value:function(){return clearInterval(this._timer),this}},{key:"_resetProgressBar",value:function(e){return this._toggleProgressBar(!1),this._updateProgressStatus(""),clearInterval(this._timer),this._color=!1,this._timer=null,this._progress=0,e&&this._updateProgressBar(),this}},{key:"_toggleProgressBar",value:function(e){var t=s("#feed_progress_table");return e?t.show():t.hide(),this}},{key:"_updateProgressStatus",value:function(e){return s(".feed-progress-status").html(e),this}},{key:"_getErrorMessageByCode",value:function(e){s(".feed-progress-status").css({color:this._color}),s(".feed-progress-percentage").css({color:this._color}),s(".wpf_spin").css({color:this._color});var t=e.status+" : "+e.statusText+". ";500===e.status&&(t+="Please increase your PHP max_execution_time. Please <a target='_blank' href='https://webappick.com/docs/woo-feed/faq-for-woocommerce-product-feed/how-to-solve-processing-10-feed-generation-stuck-error/'>read this doc</a>."),this._updateProgressStatus(t)}},{key:"_updateProgressBar",value:function(){var e=s(".feed-progress-percentage"),t=s(".feed-progress-bar-fill"),o="".concat(Math.round(this._progress),"%");t.css({width:o}),e.text(o)}}]),e}();a.wf={helper:u,feedEditor:h,generator:m},s(a).on("load",function(){null!==s(location).attr("href").match(/webappick.*feed/g)&&s("#wpbody-content").addClass("woofeed-body-content"),t(),postboxes.add_postbox_toggles(pagenow),(new m).init(),""!==d.generator.feed&&d.generator.regenerate,h.init(),u.common(),s(".wfmasterTooltip").hover(function(){var e=s(this),t=e.attr("wftitle");e.data("tipText",t).removeAttr("wftitle"),s('<p class="wftooltip"></p>').text(t).appendTo("body").fadeIn("slow")},function(){var e=s(this);e.attr("wftitle",e.data("tipText")),s(".wftooltip").remove()}).mousemove(function(e){s(".wftooltip").css({top:e.pageY+10,left:e.pageX+20})}),s(".generateFeed").validate(),s(c).on("blur",'input[name="wfDAttributeName"]',function(e){e.preventDefault();e=s(this).val();e=(e=e.toLowerCase()).split(" ").join("_"),s("#wfDAttributeCode").val(e)}).on("click","[data-toggle_slide]",function(e){e.preventDefault(),s(s(this).data("toggle_slide")).slideToggle("fast")}).on("click","#wf_newRow",function(){var e=s("#table-1 tbody"),t=s("#feed_config_template").text().trim().replace(/__idx__/g,e.find("tr").length);e.append(t),u.fancySelect(s(".outputType"))}).on("click",".single-feed-delete",function(e){e.preventDefault(),confirm(d.form.del_confirm)&&(a.location.href=s(this).attr("val"))}).on("click",".wf_clean_cache_wrapper",function(e){e.preventDefault();var e=s(".woo-feed-clean-cache-nonce").val(),t=s(".woo-feed-cache-loader");t.show(),l.post("clear_cache_data",{_ajax_clean_nonce:e}).then(function(e){e.success&&(t.hide(),location.reload())}).fail(function(){console.log("something wrong")})}).on("click","#woo-feed-copy-status-btn",function(e){e.preventDefault();var t=s("#woo-feed-copy-status-btn"),e=s("#woo-feed-status-area");t.val("Copied"),e.css("visibility","visible"),e.select(),c.execCommand("copy")}).on("change",".wf_attr.wf_attributes",function(e){e.preventDefault(),s(".fancy-picker-picked").trigger("click");var t,o=s(this).val(),a=s(this).parents("tr").find(".outputType"),e=s(this).parents("tr").find(".fancy-picker-content .fancy-picker-option"),n=s(this).parents("tr").find(".fancy-picker-data span"),i=["price","current_price","sale_price","price_with_tax","current_price_with_tax","sale_price_with_tax","shipping_cost"].includes(o)?(t="for_price","Price"):""!==o&&-1!==o.indexOf("wf_taxo")?(t="for_custom_taxo","parent_if_empty"):(t="for_all","Default");e.removeClass("selected"),"for_custom_taxo"===t||"for_price"===t?(e.each(function(){i===s(this).text()&&(s(this).addClass("selected"),n.text(i),a.find("option").text(i),a.find("option").val(s(this).data("value")))}),"for_price"===t&&(t=null!=(t=s("#feedCurrency").val())?t:wpf_ajax_obj.woocommerce.currency,s(this).closest("tr").find("td:eq(5) input").val(" "+t))):(e.each(function(){i===s(this).text()&&(s(this).addClass("selected"),n.text(i),a.find("option").text(i),a.find("option").val(s(this).data("value")))}),s(this).closest("tr").find("td:eq(5) input").val(""))}).on("click","#doaction, #doaction2",function(){return confirm(d.form.del_confirm_multi)}).on("change",".dType",function(){var e=s(this),t=e.val(),e=e.closest("tr");"pattern"===t?(e.find(".value_attribute").hide(),e.find(".value_pattern").show()):"attribute"===t?(e.find(".value_attribute").show(),e.find(".value_pattern").hide()):"remove"===t&&(e.find(".value_attribute").hide(),e.find(".value_pattern").hide())}).on("click",".delRow",function(e){e.preventDefault(),s(this).closest("tr").remove(),u.reindex_config_table()}).on("submit","#generateFeed",function(){s(this).validate(),s(this).valid()&&s(".makeFeedResponse").show().html('<b style="color: darkblue;"><i class="dashicons dashicons-sos wpf_spin"></i> '.concat(d.form.generate,"</b>"))}).on("submit","#updatefeed",function(e,t){s(this).validate(),s(this).valid()&&s(".makeFeedResponse").show().html('<b style="color: darkblue;"><i class="dashicons dashicons-sos wpf_spin"></i> '.concat(t&&t.save?d.form.save:d.form.generate,"</b>"))}).on("ready woo_feed_config_loaded",function(){"0"===s("#ftpenabled").val()?(s(".google-merchant-message").hide("slow"),s(".woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) input, .woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) select").attr("disabled","disabled")):("google"===s("#provider").val()?s(".google-merchant-message").show("slow"):s(".google-merchant-message").hide("slow"),s(".woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) input, .woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) select").removeAttr("disabled")),s("#ftpenabled").on("change",function(){"0"===s("#ftpenabled").val()?(s(".google-merchant-message").hide("slow"),s(".woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) input, .woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) select").attr("disabled","disabled")):(s(".woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) input, .woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) select").removeAttr("disabled"),"google"===s("#provider").val()?s(".google-merchant-message").show("slow"):s(".google-merchant-message").hide("slow"))})}).on("change",".ftporsftp",function(){var e=s(this).val(),t=s(".ssh2_status");"sftp"===e?(t.show().css("color","dodgerblue").text(d.form.sftp_checking),l.post("get_ssh2_status",{_ajax_nonce:d.nonce,server:e}).then(function(e){"exists"===e?(t.css("color","#2CC185").text(d.form.sftp_available),setTimeout(function(){t.hide()},1500)):t.show().css("color","red").text(d.form.sftp_warning)}).fail(function(e){t.hide(),u.ajax_fail(e)})):t.hide()}).on("click",'[name="save_feed_config"]',function(e){e.preventDefault(),s("#updatefeed").trigger("submit",{save:!0})}).on("change","#provider",function(e){e.preventDefault();var t=s(this).val(),o=s(this).find(":selected").text(),a=s("#filename").val(),n=s("#feedType"),i=s("#providerPage"),r=s("#feed_merchant_info");i.html('<h3><span style="float:none;margin: -3px 0 0;" class="spinner is-active"></span> '+d.form.loading_tmpl+"</h3>"),r.find(".spinner").addClass("is-active"),n.disabled(!0),n.parent().find(".spinner").addClass("is-active"),r.find(".merchant-info-section .data").html(""),g.hasOwnProperty(t)?(h.renderMerchantInfo(r,n,g[t]),s(c).trigger("woo_feed_config_loaded")):l.send("woo_feed_get_merchant_info",{type:"GET",data:{nonce:d.nonce,provider:t,templateName:o}}).then(function(e){g[t]=e,h.renderMerchantInfo(r,n,e)}).then(function(){s(c).trigger("woo_feed_config_loaded")}).fail(u.ajax_fail),v.hasOwnProperty(t)?(h.renderMerchantTemplate(i,v[t]),s(c).trigger("woo_feed_config_loaded")):l.post("get_feed_merchant",{_ajax_nonce:d.nonce,merchant:t}).then(function(e){v[t]=e,h.renderMerchantTemplate(i,e),s("#utm_source").val(o),s("#utm_campaign").val(a),"bing"===t&&(s("#delimiter option").removeAttr("selected"),s('#delimiter option[value="tab"]').attr("selected","selected"),s("#enclosure option").removeAttr("selected"),s('#enclosure option[value=" "]').attr("selected","selected")),"google_product_review"!==t&&s('.wf_attributes option[value="reviewer_name"]').hide()}).then(function(){s(c).trigger("woo_feed_config_loaded")}).fail(u.ajax_fail)}).on("change",".woo_feed_status_input",function(){var e=s(this);l.post("update_feed_status",{_ajax_nonce:d.nonce,feedName:e.val(),status:e[0].checked?1:0})}),s(c).on("change",'[name="is_outOfStock"], [name="product_visibility"]',function(){var e=s(".out-of-stock-visibility");"n"===s('[name="is_outOfStock"]:checked').val()&&"1"===s('[name="product_visibility"]:checked').val()?e.show():e.hide()}).on("change",".attr_type",function(){var e=s(this),t=e.val(),e=e.closest("tr");"pattern"===t?(e.find(".wf_attr").hide(),e.find(".wf_attr").val(""),e.find(".wf_default").show()):(e.find(".wf_attr").show(),e.find(".wf_default").hide(),e.find(".wf_default").val(""))}).on("change",".wf_mattributes, .attr_type",function(){var e=s(this).closest("tr"),o=e.find(".wf_mattributes"),t=e.find(".attr_type"),a=e.find("td:eq(4)"),n=s("#provider").val();d.form.google_category.hasOwnProperty(o.val())&&"pattern"===t.val()&&u.in_array(n,d.form.google_category[o.val()])?0===a.find("select.selectize").length&&(a.find("input.wf_default").remove(),a.append('<span class="wf_default wf_attributes"><select name="default[]" class="selectize"></select></span>'),a.append('<span style="font-size:x-small;"><a style="color: red" href="https://webappick.com/docs/woo-feed/feed-configuration/how-to-map-store-category-with-merchant-category/" target="_blank">'.concat(d.learn_more,"</a></span>")),r&&f||a.append('<span class="spinner is-active" style="margin: 0;"></span>'),e=a.find(".wf_attributes select"),u.selectize(e,{preload:!0,placeholder:d.form.select_category,load:function(e,t){r?t(r):l.send("get_google_categories",{type:"GET",data:{_ajax_nonce:d.nonce,action:"get_google_categories",provider:n}}).then(function(e){t(r=e),a.find(".spinner").remove()}).fail(u.ajax_fail),f||"facebook"!==n||"fb_product_category"!==o.val()?t(f):l.send("get_facebook_categories",{type:"GET",data:{_ajax_nonce:d.nonce,action:"get_facebook_categories",provider:n}}).then(function(e){t(f=e),a.find(".spinner").remove()}).fail(u.ajax_fail)}})):"current_category"!==o.val()&&0===a.find("input.wf_default").length&&(a.find("span").remove(),a.append('<input autocomplete="off" class="wf_default wf_attributes" type="text" name="default[]" value="">'),"pattern"!==t.val()&&a.find("input.wf_default").hide())}).on("change","#feedType,#provider",function(e){var t=s("#feedType").val(),o=s("#provider").val(),a=s(".itemWrapper"),n=s(".wf_csvtxt");""!==t&&u.in_array(o,d.form.item_wrapper_hidden)&&a.hide(),"feedType"===e.target.id&&("csv"===t||"txt"===t||"tsv"===t?(n.show(),a.hide(),"tsv"===t?s("#delimiter option:last").prop("selected","selected"):"csv"===t&&s("#delimiter option:first").prop("selected","selected")):"xml"===t&&"custom"===o?(a.show(),n.hide()):"json"===t&&n.hide()),"custom"!==o&&a.hide()}).trigger("change"),s(c).on("click",'.woofeed-custom-fields [id*="-switcher"]',function(){s(this).closest("td").find(".switch-loader").show();var e=s(this).attr("id").split("-")[0],t=s(this).data("taxonomy"),o=s(this).prop("checked");new _(e,o,t)}).ready(function(){var e=s(".wapk-feed-buy-now-container");s(a).scroll(function(){s(a).scrollTop()<=5e3?e.addClass("fixed"):e.removeClass("fixed")})})}),s(c).on("click","#woo-feed-debug-log-download",function(e){e.preventDefault(),s("<a />",{download:new Date+".log",href:URL.createObjectURL(new Blob([s("#woo-feed-debug-log").val()],{type:"text/plain"}))}).appendTo("body")[0].click()}).on("keyup","#filename",function(){var e=s("#filename").val();s("#utm_campaign").val(e)}).on("click",".wf-tab-name",function(e){s(".wf-tab-name.activate").removeClass("activate"),s(this).addClass("activate");var t=s(this).attr("for");s(".wf_tabs li.active").removeClass("active"),s(".wf_tabs .wf-tab-content#"+t).parent().addClass("active")}).on("change","#category-mapping-form #providers",function(){var e,t=s(this).find(":selected").val();s(".woo-feed-category-mapping-config-table").prepend('<div class="woo-feed-cat-map-spinner"><h3><span style="float:none;margin: -3px 0 0;" class="spinner is-active"></span> Loading Mapping...</h3></div>'),-1!==["google","facebook","pinterest","bing","bing_local_inventory","snapchat","tiktok"].indexOf(t)?(s('input[id*="cat_mapping_"]').css("display","none"),s(".wf_default.wf_attributes").css("display","block").css("width","100%"),e=new p,"facebook"===t?e.wooFeed_get_facebook_categories():e.wooFeed_get_google_categories()):(s('input[id*="cat_mapping_"]').css("display","block"),s(".wf_default.wf_attributes").css("display","none").css("width","100%"),s(".woo-feed-category-mapping-config-table .woo-feed-cat-map-spinner").css("display","none"))}).on("click",'span[id*="cat-map-"]',function(e){e.preventDefault();var o,t=s("#category-mapping-form #providers").val(),a=s(this).attr("id").replace(/[^\d.]/g,""),e="group-child-"+a;-1!==["google","facebook","pinterest","bing","bing_local_inventory","snapchat","tiktok"].indexOf(t)?(o=s(this).parents("tr").find(".selectized").val())&&s("."+e).parents("tr").find("select").each(function(e,t){s(t).data("selectize").setValue(o)}):(a=s("#cat_mapping_"+a).val(),s("."+e).parents("tr").find("input").val(a))}),s(c).ready(function(){var e=s("#providers").val(),t=new p;"edit-mapping"===new URL(a.location.href).searchParams.get("action")&&(s(".woo-feed-category-mapping-config-table").prepend('<div class="woo-feed-cat-map-spinner"><h3><span style="float:none;margin: -3px 0 0;" class="spinner is-active"></span> Loading Mapping...</h3></div>'),"facebook"===e?t.wooFeed_get_facebook_categories():t.wooFeed_get_google_categories())}),s(c).on("feed_editor_init",function(){var t=s(".merchant-info-section.feed_file_type .data").html().split(",").map(function(e){return e.trim().toLowerCase()}),e=s("#feedType");t.length?(e.find("option").each(function(){var e=s(this);e.val()&&!u.in_array(e.val(),t)?e.disabled(!0):e.disabled(!1)}),1===t.length&&e.find('option[value="'+t[0]+'"]').attr("selected","selected")):e.find("option").disabled(!1)}),s(c).on("ready",function(){s(c).on("feedEditor.init",function(){var e=s(this).find(":selected").val();-1!==["google","facebook","pinterest","bing","bing_local_inventory","snapchat","tiktok"].indexOf(e)&&function(){var i,t={price:wpf_ajax_obj.woocommerce.currency,current_price:wpf_ajax_obj.woocommerce.currency,sale_price:wpf_ajax_obj.woocommerce.currency,price_with_tax:wpf_ajax_obj.woocommerce.currency,current_price_with_tax:wpf_ajax_obj.woocommerce.currency,sale_price_with_tax:wpf_ajax_obj.woocommerce.currency,weight:wpf_ajax_obj.woocommerce.weight,weight_unit:wpf_ajax_obj.woocommerce.weight,height:wpf_ajax_obj.woocommerce.dimension,length:wpf_ajax_obj.woocommerce.dimension,width:wpf_ajax_obj.woocommerce.dimension};void 0!==wpf_ajax_obj.feed_rules&&null!==wpf_ajax_obj.feed_rules&&(i=wpf_ajax_obj.feed_rules.feedCurrency);var e=a.location.search,r=new URLSearchParams(e).get("action");s(".wf_attr.wf_attributes").each(function(o,e){var a=s(e).val(),n=s('input[name^="suffix"]').eq(parseInt(o)).val();-1!==s.inArray(n,[" "+wpf_ajax_obj.woocommerce.currency," "+wpf_ajax_obj.woocommerce.weight," "+wpf_ajax_obj.woocommerce.dimension])&&s('input[name^="suffix"]').eq(parseInt(o)).val(""),s.each(t,function(e,t){a===e&&(t=null!=i?i:t,"undefined"!==r&&"edit-feed"!==r?s('input[name^="suffix"]').eq(parseInt(o)).val(" "+t):s('input[name^="suffix"]').eq(parseInt(o)).val(n))})}),s(c).trigger("feedEditor.after.free.postfix.update")}()})})}(jQuery,window,document,wp.ajax,wpf_ajax_obj);
2
  //# sourceMappingURL=woo-feed-admin.min.js.map
admin/js/woo-feed-admin.min.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["woo-feed-admin.js"],"names":["_defineProperties","target","props","descriptor","i","enumerable","configurable","writable","Object","defineProperty","key","_createClass","Constructor","protoProps","staticProps","prototype","window","wpAjax","$","document","opts","self","prop","status","addClass","removeClass","hasClass","currentTarget","clearTooltip","userAgent","actionMsg","match","actionKey","index","join","removeAttr","elem","attr","msg","extend","_default","_args","option","ClipboardJS","isSupported","test","navigator","$copyBtn","feedGenerator","this","on","event","action","_loop","ajax_fail","alert","url","data","_classCallCheck","WooFeedCustomFields","productCustomFields","field","isTaxonomy","value","ajax","nonce","method","response","wpf_ajax_obj","wpf_ajax_url","success","_this","cacheClear","closest","find","hide","selectize","WooFeedMapCategories","options","render","send","type","item","_ajax_nonce","valueField","helper","labelField","placeholder","searchField","escape","concat","text","remove","googleCategories","fail","onDrop","column_count","containerSelector","e","hasOwnProperty","error","statusText","sortable","column","each","_super","length","wf_sortable","itemPath","handle","el","$item","container","create","group","draggedClass","plugins","bodyClass","numb","needle","replace","_onDrop","selectize_render_item","config","not","fancySelect","split","map","s","trim","reindex_config_table","itemSelector","common","init","renderMerchantInfo","form","k","opt","merchantInfo","feedType","r","types","html","t","toLowerCase","na","disabled","trigger","val","in_array","_loop2","contentSettings","feedForm","feedEditor","is","merchantInfoCache","tooltip","css","top","merchantTemplateCache","title","_feed","_current_btn","feed","_limit","generator","limit","_color","_product_ids","_progress_per_batch","_refresh","isRegenerating","_all_btn","generate","clip","clipboard","showTooltip","condition","then","URLSearchParams","preventDefault","parent","_progress","_log","_total_batch","_regenerate","regenerate","page_name","_block_button","_current_btn_label","post","_updateProgressStatus","message","product","_this2","_process_batch","setTimeout","_stopProgressBar","_current_batch","_save_feed_file","loop","_unblock_button","_resetProgressBar","console","refreshInterval","arguments","undefined","products","clearInterval","_timer","setInterval","_toggleProgressBar","table","show","color","width","wf","pagenow","attr_name","hover","appendTo","left","pageX","confirm","href","slideToggle","loader","_updateProgressBar","location","reload","button","status_area","select","execCommand","current_attribute_value","fancyOption","fancyDataPicker","selectIf","currency","price_attributes","selectKey","parents","includes","indexOf","outputSelect","feedCurrency","woocommerce","del_confirm_multi","row","validate","template","_ajax_clean_nonce","valid","save","server","sftp_checking","sftp_available","merchant","sftp_warning","name","templateName","loading_tmpl","provider","renderMerchantTemplate","checked","valueColumn","attribute","preload","google_category","query","learn_more","append","cb","facebookCategories","outOfStockVisibilityRow","wf_csv_txt","itemWrapper","item_wrapper_hidden","id","ready","windowpos","load","download","URL","scrollTop","googleMap","Date","click","cat_init","wooFeed_get_facebook_categories","wooFeed_get_google_categories","for_attr","prepend","setValue","catField","catId","groupId","searchParams","v","get","attribute_list","current_feed_currency","price_with_tax","current_price_with_tax","queryString","sale_price_with_tax","urlParams","weight","weight_unit","attribute_value","current_Value","dimension","search","eq","parseInt","inArray","_key","_value","update_postfix"],"mappings":"yHAAA,SAAAA,kBAAAC,EAAAC,G,4BACA,IAAAC,EAAAD,EAAAE,GACAD,EAAAE,WAAAF,EAAAE,aAAA,EACAF,EAAAG,cAAA,EACA,UAAAH,IAAAA,EAAAI,UAAA,GACAC,OAAAC,eAAAR,EAAAE,EAAAO,IAAAP,IALA,SAAAQ,aAAAC,EAAAC,EAAAC,GAEA,OAOAD,GAAAb,kBAAAY,EAAAG,UAAAF,GARAC,GAAAE,kBAAAC,EAAAH,GACAF,GAcA,SAAAM,EAAAF,EAAAG,EAAAF,EAAAG,G,yDAqBgBC,IAAAA,EAAAA,EAAAA,MADJC,EAAAD,gBAIC,IAAAA,EAAAA,KAAAC,GAHGD,EAAAA,KAAAA,OAAAA,IAAAA,IAAAA,IAAAA,IAQZ,IAAAE,EAAAF,EAAAG,SAAAF,GAAAD,EAAAI,YAAAH,K,iCAII,IACIA,EAAAA,EAAAA,MACJJ,EAAA,WAHJ,YACI,IAAAG,EAAAC,KAAAA,GAAAD,EAAAC,KAAAA,GAAAD,EAAAK,SAAAJ,IAUQK,SAWRC,EAXoCC,GAAAC,EAAAA,EAAAA,eAAiCC,YAAMC,SAAhBC,EAA4CC,GAAYT,OAAAA,EAAAA,MAAAA,sBAAAA,IAAAA,KAAAA,OADvHK,YAAA,cAAAK,WAAAH,cAKYR,SAANY,EAAAA,EAAAA,GADNlB,EAPJkB,GAAAZ,SAAA,2BAAAa,KAAA,aAAAC,G,gBAtDA,OAAApB,EAAAqB,QAAA,EAAA,GAAAC,EAAAC,GA4JwBC,SAkNgBN,IAEAA,EAAAA,EAAAA,iBAEPO,YAAAC,eAAA,eAAAC,KAAAC,UAAAjB,W,uBAlXjCkB,EAmX6BC,KAAAA,WAER9B,EAAA+B,MAAAC,GAAA,aAAAtB,GAAAsB,GAAA,OAAAtB,KA0DrB,IAAAe,YAAA,gBAvDgBO,GAAA,QAAA,SAAAC,GAtTR,IAAAC,EAuTYC,EAAAA,EAAAA,SAvTZD,EAuTYD,EAAAC,OApTZpB,EAAA,QAAAoB,EAAA,IAAA,IACItB,E,yCAAY,gBAAZS,OAAAM,KAAAC,UAAAN,WAAAV,WAAAA,EAAAA,OAAAA,EAGH,cAAAE,EAAA,OAAAoB,MAgTWF,GAAA,UAAA,SAAAC,G,yBA/TVA,IAjDmCG,EA8JjCC,EACAtC,EAhFZuC,EAHI,WAIJC,SAAAA,EAAAA,EAAAA,EAAAA,GAJIC,gBAAAT,KAAAU,GArFJV,KAAAW,oBAAAC,EAAAtC,EAAAuC,GAAA,OA8G2DnD,aAAAgD,EAAA,CAAA,C,iBAAAI,MAAA,WAAA,IAAAN,EAAbK,CArGDV,OAmFtCO,0CAELP,MAAAA,aAAAY,KAAAC,OAoBEJ,EAAAA,KAAAA,CAnBDtC,OAAAA,OACAuC,IAAAA,aAAAA,aAJIH,KAnFsCF,MAAAD,CA0F1CC,IAAAA,sBACCL,MAAAA,SAAAA,GACAa,IAAAA,EAAAA,KAIAT,EAAAA,C,8CACAC,MAAAA,aAAAA,KAAAA,MAHMI,MAAAA,EA9FmCtC,OA8FxCyC,EAFDC,UAECD,aAAAA,IAAAA,UAAAA,IAAAA,UAAAA,GA9FwCF,WA+FzCI,EAAAA,UAAQC,OAARD,UAAAA,QAAAA,G,QAxGJA,OAAA,OAAAV,IAAAY,aAAAC,aA8G2DZ,KAAAA,EAyB3Da,QAAA,SAAAH,GAzB2DA,EAAAG,QAAAC,EAAAC,a,eA9G3DtD,EAAA,IAAA2C,EAAA,aAAAY,QAAA,MAAAC,KAAA,kBAAAC,cAAAhB,EAqFI,GAqCAW,EAAyBM,WACpBT,SAAAA,IACEK,gBAAAA,KAALK,GAnHuC,OAsHvCC,aAAAA,EALuB,CAAA,CAiCTC,IAAAA,gCA3BMlB,MAAAA,WAAM5C,EAAA+D,KAAA,wBAAA,CAAAC,KAAA,MAC3BC,KAAAA,CAAAC,YAAA/D,EAAA6C,MAAAb,OAAA,2B,iBAxHwClC,EAAAA,8BAAA0D,UAAA,CAAAQ,WAAAC,QA6HzCC,WAAA,OAtIJC,YAAA,oBAAAC,YAAA,CAAA,QAAA,QAAAV,QAwIAX,EACAY,OAAA,CACA9D,OAAA+D,SAAAvB,EAAAgC,GA+BgBR,MAAI,yCA/BpBS,OAAAD,EAAAhC,EAAAM,MAAA,MAAAN,EAAAkC,MAAA,WACUd,KAAAA,SAlImCzD,EAAA6C,GAAAb,MAAAA,yCAAAsC,OAAAD,EAAAhC,EAAAM,MAAA,MAAAN,EAAAkC,MAAA,cAAAP,EAAAA,6BAAAQ,WAmIrCN,KAAAA,EAAAA,aAEcE,CACAV,IAAAA,kCACFK,MAAAA,WACQlE,EAAA+D,KAAA,0BAAA,CAAAC,KAAA,MAuCJC,KAAAA,CAAMC,YAAA/D,EAAA6C,MAAAb,OAAA,6B,iBAjCVkC,EAAAA,8BAAAA,UAAAA,CACAC,WAAAA,QACAC,WAAAA,OAzJpBD,YAAA,6B,6BAAAT,QAAAX,EAAAY,OAAA,C,qBA4JwBrC,MAAAA,yCAAAA,OAAAA,EAAAA,EAAAA,MAAAA,MAAAA,EAAAA,MAAAA,WAAQmD,KAAAA,SAARnD,EAAAA,GACAwC,MAAAA,yCADAxC,OAAAA,EAAAA,EAAAA,MAAAA,MAAAA,EAAAA,MAAAA,cA8CPxB,EA/CW,6BA+CA0E,WAxCVE,KAAAT,EAAA/B,eAzJ2BuB,EAiHhBD,G,GA+CbK,SAAAA,SAAAA,EAAAA,GACAxB,IACI0B,OAAAA,IAAAA,EAAAA,QAAAA,GACA/B,MAAAA,GA2CpB,OAAA,IAvCgBlC,sBAAAA,SAAAA,EAAAA,GACIkE,MAAAA,yCADsCW,OAAAN,EAAAhC,EAAAkC,MAAA,WAGtCJ,UACWS,SAJ2BtB,GAK/BrD,QAAE8C,KAAAA,GACD8B,MAAAA,EAAAA,eAAA,eAN8BC,EAAAC,eAAA,UAAA/E,EAAA4C,KAAAoC,MAAA,KAAAF,EAAAG,WAAA,KAAAH,EAAA3E,OAAA,IAAA2E,IAaxCI,SAAA,SAA6BV,EAAAA,EAA/BW,EAAAR,GArBJA,OAAAA,GAAAA,EAAAA,kBAAAS,KAAAC,WAuBH,IAAApF,EAAAH,EAAA+B,MAtLoC+C,EAAA3E,EAAAqD,KAAA,yBAAAgC,QAAAH,GAAA,EAuKalF,EAAAsF,YAK/BpE,EAAA,CA5KkB0D,kBAyKzBX,QArBUsB,SAAA,UAoFlBhC,aAAW,KA/CnBiC,OAAAC,mBAAAvB,YAAArE,wCAAAwE,OAAAM,EAAA,gBAEIH,OAFJjB,SAAAmC,EAAAC,EAAAP,EAAAtD,GAAA8D,EAAAA,YAAAxD,EAAAyD,MAAApC,QAAAqC,cAAAhF,WAAA,SAIaiF,EAAAA,QAAA3F,YAAAuF,EAAAE,MAAA7F,QAAAgG,WACK,IAAAC,EAAAP,EAACQ,KAAD,mBAAAlF,KAAA,QAAAmF,QAAA,MAAA,IACFT,EAFHrC,KAJb,uBAAArC,KAAA,OAAA,WAAAiF,EAAA,KAQwBvC,GAAA,mBAAA0C,GACRvC,EAAA6B,EAAA1B,EAAAqC,EAAAA,KAThBC,OAYqH/C,UAAAkC,SAAAA,EAAAa,GAClG,OAAAtG,GAAAH,EAAA,qBAAA0G,IAAA,eAAAA,IAAA,8BAAApB,KAAA,WACPnF,IAAAA,EAAAwG,EAAAA,MACQ1B,EAAAA,UAAAA,EAAe,CADvBc,OAVCU,EAUDlE,KAAA,YAAA,EAsDC2D,QAxDwG/F,EAAAoC,KAAA,WAAApC,EAAAoC,KAAA,WAAAqE,MAAA,KAAAC,IAAA,SAAAC,GAjD3F,OAAAA,EAAAC,SAuD9BC,GAEAhH,OAAAwD,CACAxD,KAAA4F,EAAAY,wBAFAC,OAO0BtC,YAAMiB,SAAAQ,EAANa,GACEtC,OAAKyB,GAAAlC,EAAAA,uBAALgD,IAAA,oBAAApB,KAAA,WACJR,EAAAA,MACCW,YAAAA,EAAAA,CAnEDjE,YAAAA,GAqEAkE,OAGArB,qBAAAA,WACAQ,EAAAA,YAAAA,KAAAA,YAAAA,KAAAA,SAAAA,EAAAA,GACIgB,EAAAA,GAAAA,KAAAA,UAAAA,KAAAA,SAAAA,EAAAA,GACA7F,EAAE4F,GAAAzE,KALN8F,OAAAA,EAAAA,GAAAA,KAAAA,QAAAA,QAAAA,YAAAA,IAAAA,OAAAA,EAAAA,YAQIC,OAAA,WACIrC,EAAAA,SAAAA,EAAAA,iBAAAA,GAAAA,EAAAA,EAAAA,sBACHsC,EAAAzD,YACJS,EAAAhE,YAAAH,EAAA,kB,GASDkG,KApBAe,KAwBQE,KAAA,WANUpF,KAF1BqF,KAAAA,EAAAA,iBAE0BrF,KAF1BsF,KAAA7B,SAcSrB,EAAA+C,S,iCAGLlH,EAAAC,GAAiBoB,QAAAA,IAAAA,OAAOiG,MAAA,kBAAA,CACPvI,OAAAgD,KAAAsF,UA9DpBD,mBAAAG,SAAAC,EAAAC,EAAAC,GA+FDvD,IAtBUoD,IAsBVpD,KAAAA,GAtBUoD,SAAApD,GA7EtB,IAmFIwD,EAL2BD,EAAAzC,eAPnBqC,KAQAE,EAAAhE,KAAAmE,0BAAAnE,EAAA,UAAAoE,KAAAF,EAAAC,IAEH,mBAfwBL,KAiB7BK,EAAAD,EAAAJ,GAAAV,MAAA,KAAAC,IAAA,SAAAgB,GAnCQ,OAAAA,EAAAd,OAAAe,gB,mBA5CC,MAAA,KAAAD,GAAAA,IAAA3H,EAAA6H,GAAAD,iBAkFjBtC,QACAiC,EAAAO,KAAA,UAAA/G,WAAA,YAAAqE,KAAA,WACAmC,IAAAF,EAAAU,EAAAlG,MAuDgBwF,EAAAW,QAAA/D,EAAAgE,SAAAZ,EAAAW,MAAAP,GAAAJ,EAAAS,UAAA,GAAAT,EAAAS,UAAA,KAnDhB,IAAAL,EAAAnC,QAAAiC,EAAAjE,KAAA,iBAAAmE,EAAA,GAAA,MAAAxG,KAAA,WAAA,a,gCA6DAiH,CAAAd,GAlDoBvI,EAAAA,KAAAA,YAAasI,YAAAA,aADjBI,EAAAtF,UAAA,GAlBKsF,EAAAQ,QAAAhD,UA0BrBjF,EAAAC,GAAAoI,QAAAA,0B,sDASwCnH,uBAAA,SAAAoH,EAAAZ,GAsBfO,IArB8B,IAqBtB1F,KAAAmF,GArBsB,SAAKb,GACRiB,IA0D/BO,EA1D+BP,EAAAA,eAAAA,KACE,SAAAR,EAELgB,EAAAV,KAAAF,EAAAJ,KAuD5Be,EAAArI,EAAA,UAAAsH,EAAA,O,QAlDmBe,EAAY/C,KAAA,WACZiC,IAAArG,EAAAqG,EAAAA,M,eAHRgB,EAAAA,KAMOd,WANPC,EAAAJ,GAAA,MAAAlH,KAAA,YAAA,IARJc,EAAAsH,GAAA,oBAAAtH,EAAAsH,GAAA,kBAAAtH,EAAAgH,QAAAR,EAAAJ,GA7JJ9F,EAAAA,KAAAA,WAAAA,GAuJ6CiH,EAAAA,IAAAf,EAAAJ,MACrDoB,QAAA,WA6BA1I,CAAAsH,GA2DIiB,EAAQpB,SAnDhBnH,EAAA2I,GACZC,EADY,GAwCJC,EAAAA,WAMgB1I,SAAOH,IAAS8I,gBAAQ3I,KAAAA,GAE1B4B,KAAAgH,MAAAC,EAAAA,UAAAC,KAEFlH,KAAAmH,OAAAhJ,EAAAiJ,UAAAC,MAEAjJ,KAAAA,UAAAA,EACAH,KAAAA,OAAAA,KACH+B,KAAAsH,QAAA,E,0CA/YjBtH,KAAAuH,aAAA,GAAAvH,KAAAwH,oBAAA,EAAAxH,KAAAyH,UAkZwBZ,E,wCADJ9I,EAAA2J,gBAAAV,EAbRhH,KAAA2H,SAAAC,EAAAA,mBAlMR5H,KAAAiH,aAsNgBhJ,EAAA,IAAAwE,OAAAzC,KAAAgH,MAAAzC,QAAA,YAAA,c,2BA/YyBsD,OAoZvBnK,aAAAqC,EAAA,CAAA,C,WAEN+H,MAAAA,WACU7H,IAAAA,EAAGD,KAGT+H,KAAY7H,KAAAA,OAADF,KAAgBQ,cAA3B,IAAAuH,EAAAA,gB,gBAKhBC,IAAAA,EAAAA,EAAAA,SAAAA,OA8BJ,MA6BwB5J,2BA1DxB6J,IAAAC,gBAAAhH,GACAA,IAAAA,S,4CAGQ9C,EAAAA,GAAAA,GAAAkJ,QAAA,kCAAA,SAAApH,GACRA,EAAAiI,iBACAlK,EAAA+B,MAAAoI,OAAA,uBAAA1G,OAhBgBoG,EAAAA,EAAAA,MAAAA,KAAAA,aA4EA5H,IAAK8H,GAzDT5J,EAAAA,KAAaD,0BAAb,CA2DI+D,YAAS+E,EAAAA,MA1DRE,UAAShJ,I,iBACTkK,EAAAA,KAALnH,KACc9C,KAAAA,SAAdwJ,GACAxJ,EAAAkK,KAAAnF,GAEKoF,EAAAA,sBAAAA,EAAAA,SAxbjBnK,EAAAkJ,OAAA,UAwfgBrJ,EAAAC,GAAKyJ,GAAAA,QAASpJ,kBAAd,SAAA2B,GA1DCsI,EAAAA,iB,uBACCpK,EAACsJ,aAAAA,SAAD,cAAN,IAAA3J,EAAA2J,iBACKC,EAAAA,MAALV,EAAAA,aAAkB7H,KAAlBb,MAAAA,QAAA,WAAA,aACK0I,KAAAA,EAAAA,O,gBAKjBjH,OAtcA,CAAAvC,IAAA,gBAmgBYqD,MAAA,WACId,KAAA2H,SAAKA,QA3fwB3H,KAAA2H,SAAApJ,SAAA,YAgcrCyB,KAAAiH,aAAAA,S,yHAESjH,KAAAiH,aAAA7H,KAAA,aAAAjB,EAAAsK,YAAArJ,KAAA,QAAAjB,EAAAsK,eAmEjB,CA9DYhL,IAAA,kBACAqD,MAAA,W,sBAjdZd,KAAA2H,SAAAnJ,YAAA,YAkdgBkK,KAAAA,aAAAA,S,uDACA3K,KAAAA,aAAA2J,KAAAA,QAAAlJ,YAAA,gBACEwB,KAAAiH,aAAA0B,KAAA,aAAA3I,KAAA4I,oBAAAxJ,KAAA,QAAAY,KAAA4I,uBAIF1I,C,eAEEY,MAAA,WACEkH,IAAAA,EAAAA,KAgEJ5J,EAAKkK,KAAOpH,EAAAA,gBAAAA,E,qBA9DD2H,KAAAA,oBACH3G,KAAAA,qBAEM9D,KAAAA,KAAAA,2B,0FAGDkK,EAAAA,UAAMnF,GACN2F,EAAAA,KAAAA,CAkEZ5H,SAAAA,I,WA/DA9C,EAAAA,KAAA0K,SAAAA,OAAAA,EAAA3F,MAAA4F,qBAhBL3K,EAAAA,aAAA8C,EAAA8H,QAmBE9K,EAAAA,aAAa+K,EAAS1B,aAAA9D,OACd0E,EAAAA,eAAAA,E,sDAEF/J,EAHO8K,iBAsElB9K,EAAA0K,sBAAA,2BA/DQ1K,EAAA0K,sBAAA5H,EAAAV,KAAAuI,WAELlG,KAAA,SAAAM,GACH/E,EAAAkK,KAAAnF,GApfT/E,EAAA0K,sBAAA3F,EAAA4F,SAAA3K,EAAAkJ,OAS6C,MAAA6B,WAAAd,WAAAjK,EAAAgL,mBA+exBzB,EAAAA,mBACRN,UAzfb,CAAA5J,IAAA,mBAggBSqD,MAAA,W,OAvfoCd,KAAAqI,UAAA,E,kCAAAnG,YAAA4G,EAAAA,M,gBAAAzB,MAAArH,KAAAmH,WAskB7B/I,C,qBAvEK6I,MAAAA,W,WAyEL7I,EAAKkK,oBAAL7F,OAAAzC,KAAAqJ,eAAA,EAAA,QAAA5G,OAAAzC,KAAAuI,cAxEKtB,KAAAA,sBAAAA,G,aAIbjJ,EAAA6K,KAAA,kBAAA,C,oBACR3B,KAAAlH,KAAA5B,MACAA,SAAAA,KAAAkL,aAAAtJ,KAAAqJ,gBACAE,KAAAvJ,KAAAqJ,iBAyEapB,KAAGpF,SAAM3B,GAhlBuB9C,EAAAA,iBAAAA,EAAAA,KAAA0K,SAAAA,OAAAA,EAAAO,eAAA,eAwgBrCjL,EAAAA,KAAAkJ,GA6EYlJ,EAAAA,eAAKgL,EAALb,e,mBA3EDb,EAFAW,WAAAjK,EAAAoJ,qBAIPpJ,EAAAiL,iBAAAjL,EAAAmK,cAgFZnK,EAAAkL,oBAEAzG,KAAA,SAAAM,G,UAvmBA/E,EAAA0K,sBAAA3F,EAAA4F,SAymBY3K,EAAAkJ,OAAW,M,sBAjFXlJ,EAAAgL,mBAmFAhL,EAAAoL,mB,WAOI/L,IAAA,kBAtFGyD,MAAAA,WACMoH,IAAAA,EAAAA,KAwFTa,KAAAA,KAAAA,oB,+CArFSE,EAAAA,KAAAA,iBAAAA,C,oBACA7B,KAAAA,KAAAA,QAyFJS,KAAA,SA3FIM,GAGAW,EAAAA,KAAAA,GACD9K,EAAAA,UAAC0K,IAPT1K,EAQOqJ,W,2FAGFrJ,WAAA,W,qBA4FJ+K,WA7FA,WAGD/K,EAhBJqL,mBAAA,GAkBIN,EAAAA,mBACI/K,MA6FpB,QA5FoBA,KAAAA,SAAAA,GACHA,EAAAkK,KAAAnF,G,mCA9iBjB/E,EAAAkJ,OAAA,MAAA6B,WAgjBS,WAED/K,EAAAgL,mBAERM,EAAAA,mBACA,U,CArjBAjM,IAAA,OAAAqD,MAAA,SAAAN,G,OA4jB4B2G,EAAAA,WAHhBuC,QAAAtL,IAAAoC,G,OAaA,CAkGZ/C,IAAA,qB,iBAxqBA,IAAAkM,EAAA,EAAAC,UAAAnG,aAAAoG,IAAAD,UAAA,GAAAA,UAAA,GAAA,EAAAxL,EAAA4B,KA4kBgB8J,OA8FJC,KAAAA,oBAAoBC,GAEvBhK,KAAAgK,OAAAC,YAAA,WAlGO/H,EAAAA,sBACAgF,GAAAA,KACA4C,O,CAIA1L,IAAAA,mB,iBACAA,OAqGJ2L,cAAAA,KAAeC,QArGX5L,OAIC,CAyGRX,IAAA,oBAvGWW,MAAAA,SAAAA,GAmHP,OAlHI4B,KAAAkK,oBAAA,GAED9L,KAAAA,sBAAAA,IACAA,cAAAA,KAAAA,Q,eA3lBhB4B,KAAAgK,OAAA,KAAAhK,KAAAqI,UAAA,EA4lBgBjK,G,0BACA+K,OAsHhB,CA1sB6C1L,IAAA,qBAAAqD,MAAA,SAAAxC,G,gCAT7C,OAAAA,EAAA6L,EAAAC,OAwtBYD,EAAAzI,OAxtBZ1B,OA8mBgBkH,CAAWF,IAAAA,wBAAAA,MAAXE,SAAAA,G,OAEA9I,EAAAA,yBAAAE,KAAW4C,G,OACNmH,CAmHR5K,IAAA,yB,kBAjHOM,EAAAA,yBAqHX6I,IAAA,CAlHWxI,MAAAA,KAAAA,SACA+K,EAAAA,6BAAAA,IAAAA,CACI/K,MAAAA,KAAAA,S,oBAxnBxBiM,MAAArK,KAAAsH,SAAA,IAAAyB,EAynBwB3K,EAAAA,OAAAA,MAAAA,EAAKoL,WAAAA,KACR,MALLrG,EAAA7E,SAKKyK,GAECV,iOAwHNiC,KAAAA,sBAAOjC,K,0BAMnBtK,MAAOwM,WAxHSnM,IAAAA,EAwHJH,EAAA,6BAvHCuI,EAAAA,EAAAA,2BACJY,EAxBDrH,GAAAA,OAAAA,KAAAA,MAAAA,KAAAA,WAAAA,KA4BZhC,EAAAA,IAAAkC,CACAqK,MAAAjC,IAEApK,EAAAyE,KAAA2F,OAloB6CtI,EAwXrC+G,GA+QQ4C,EAAAA,GAAAA,CACHtC,OAAAA,E,aACDA,UAAArH,G,0BAMZ,OAAAqC,EAAAA,UAAAhD,KAAA,QAAAN,MAAA,qB,0DAIoBmE,UAAAkF,oBAAAqC,UACiBC,IAAAA,GAiIjBA,OArxByB,KAypBpCtM,EAzpBoCiJ,UAypBpCF,MAAA/I,EAzpBoCiJ,UAypBpCqB,WAITjC,EACApB,OA9pB6ChD,EA+pB7C+C,SA3UAlH,EAlBiB,oBAAAyM,MAAA,WA/KOjL,IAmMRoI,EAAS5J,EAAA+B,MACD2F,EAAEzC,EAAAA,KAAAA,W,0CACFjF,EAAA,6BAAIyE,KAAcqE,GAAA4D,SAAA/K,QAAAC,OAAAjB,SACdkB,WADJA,IAAAA,EAGOyD,EAAAA,MACC+C,EAAAA,KAAAA,UAAelI,EAAAoC,KAAK7B,YAyDnCV,EAAA,cA7DO0E,WAMQ2D,UAAAA,SAAgB7C,GAChB6C,EAAAA,cAAeM,IAAA,CACPzH,IAAAA,EAAAA,MAASe,GAyDhC0K,KA1DetE,EA0DVuE,MA1DUvE,OAiUxBlE,EAAAA,iBAAAwC,WAhqBqC3G,EAAAC,GAmqBpC+B,GAAA,OAAA,iCAAA,SAAAgD,GAED/C,EAAAA,iB,gBAGRnC,GADA0M,EAAAK,EAAAxF,eACAyF,MAAA9M,KAAAgB,KAAAG,KACAnB,EAAA,qBAAAkI,IAAAsE,KAzqB6CxK,GAAA,QAAA,sBAAA,SAAAgD,GAAAA,EAAAhD,iBA0qBrCC,EAAAA,EAAAA,MAAAiI,KAAAA,iBAAA6C,YAAA,UAuIQ/K,GAAA,QAAIgL,aAAW,W,0BApInBlB,EAAeK,EAAfL,yBAEKC,OAAAA,OAAAA,QAAAA,WAAAA,EAAAA,KAAAA,MAAAA,Q,YACA3B,EAAAA,YAALpK,EAAA,kBAAAgC,GAAA,QACc,sBAAA,SAAAC,GACLgL,EAAAA,iB,8BA0IGC,EAAAA,SAASC,KAATnN,EAAA+B,MAAAZ,KAAA,UArIhBsK,GAAAA,QAAA,0BAAA,SAAAxJ,GACRA,EARiBmI,iBAUjB,IAAArH,EAAA/C,EAAA,+BAAAkI,MA1rB6C8E,EAAAhN,EA2rB7C,0BA0IgBgN,EAAII,OAr0ByBA,EAAAA,KAAAlF,mBAAA,CA6rBrCmF,kBAAAtK,IACQmJ,KAAAA,SAAUoB,GACTjN,EAASkN,UA/rBmBP,EA+rBjCvJ,OAICxB,SAAAiI,YAILtF,KAAA,W,mCAGR5C,GAAA,QAAAwL,4BAAAtF,SAAAjG,GACAA,EAAAiI,iBACA,IAAAkD,EAAAK,EAAAA,6BA6IgBJ,EAAIK,EAAAA,yBAz1ByBN,EAAAO,IAAAA,UAAAN,EAAAO,IAksB7B,aAYD,W,WACI3N,EAAP4N,YAAAA,UA/sBiCF,GAAAA,SAAA,yBAAA,SAAA1L,GAAA6L,EAAAA,iBAktBrC9N,EAAA,wBAAAwN,QAAAA,SAEIM,IAgCOhM,EA/BP6L,EAAA3N,EAAA+B,MAAAmG,MACG4F,EAAmB9N,EAAA+B,MAAnBgM,QAAA,MAAAvK,KAAA,eApBCiK,EAsBA3C,EAAAA,MAAAA,QAAAA,MAAAA,KAAAA,8C,wDAOPgD,EAXG,CAAA,QAAA,gBAAA,aAAA,iBAAA,yBAAA,sBAAA,iBAOCE,SAAAR,IAEI3C,EAAAA,YAERiD,SAED,KAAAxN,IAAA,IAAAkN,EAAAS,QAAA,YAERC,EAAAA,kBACAA,oBAsJqBP,EA7JJ9C,U,WAUS4C,EAAMlN,YAAA,YAEP,oBAAAoN,GAAA,cAAAA,GACJF,EAATnI,KAAA,W,kDAGiB8E,EAAAA,KAAjB0D,GACHI,EAAA1K,KAAA,UAAAiB,KAAAqJ,GA0JQI,EAAM1K,KAAA,UAAA0E,IAAAlI,EAAA+B,MAAAQ,KAAA,aAIKmL,cAAAA,IAxJT5L,EADCyG,OAFJ2F,EAAAlO,EAAAwD,iBAAAiB,OAjvB6B0J,EAwvBrCjL,aAAAkL,YAAAR,SAOA5N,EAAA+B,MAAA8K,QAAA3M,MAAAmH,KAAAgH,kBAAAnG,IAAA,IAAA0F,MAGIzE,EAAgBrH,KAAAA,WAAhBqH,IAEJjB,EAAAnG,MAFIoH,SAAAA,EAAAA,MA6JW7I,SAAQiD,Y,UAEf2K,EAAa1K,KAAA,UAAWiB,KAAAqJ,GACpBQ,EAAS9K,KAAA,UAAA0E,IAAoBzE,EAAAA,MAA7BlB,KAAA,aAGA+L,EAAAA,MAAI9K,QAAK,MAAAA,KAAA,kBAAT0E,IAAA,OAxJVoG,GAAAA,QAAiBC,wBAEnB9K,WAEKzB,OAAAA,QAAAA,EAAAA,KAAAA,qBAjxBgCA,GAoxBzBwK,SApxByB,SAAA,WAqxBhBxH,IAAA7E,EAAGqM,EAAAA,MAEdxM,EAAAG,EAAAoD,MAGFY,EAAAA,EAAS6C,QAAAA,MAIb,YAAAjD,GAdJ/D,EAeiBwD,KAfjB,oBAAAC,O,iCAiBoB,cAAIM,GACHyK,EAAAA,KAAAA,oBACMxO,OAGVsO,EAAA9K,KAAA,kBAAAC,QAsJb,WAAAM,IA57BiCuK,EAyyBzBzB,KAAAA,oBAAJpJ,OACWyJ,EAAAA,KAAAA,kBAAAA,UA1BnBlL,GAAA,QA8BiB,UA9BjB,SA8BiBgD,GACHkF,EAAAA,iBAsJLlK,EAAA+B,MAAAwB,QAAA,MAAAmB,SAjJMyH,EAmJNnF,yBA/IGyH,GAAAA,SAAAA,gBAAAA,WAEYzO,EAAAA,MAACoD,WAmJbpD,EAAA+B,MAAM2M,SAjJOvB,EAAAA,qBAAThB,OAAAvE,KAASuF,gFAAAA,OAAAA,EAAAA,KAAAA,SAAAA,WAGDnL,GAAA,SAAA,cAAA,SAAAgD,EAAAzC,GARhBvC,EAAAA,MAAAuO,W,iBAaMrE,EAAAA,qBAANiC,OAAMjC,KAAN,gFAAA1F,OAAAjC,GAAAA,EAAAoM,KAAAzO,EAAAmH,KAAAsH,KAAAzO,EAAAmH,KAAAsC,SAAA,WAEkB3J,GAAAA,+BAAlByD,WACA,MAAWzD,EAAAA,eAAXkI,OACAlI,EAAA,4BAAgByD,KAAA,QAGP8J,EAAAA,iHAATpM,KAASoM,WAAT,cAIA,WAAMrD,EAAAA,aAANhC,MAEElI,EAAAA,4BAADmM,KAAC,QAgJUnM,EAAAA,4BAAEyD,KAAD,QA1ITyK,EAAAA,iHAnBEhE,WAAAA,aAsBFyD,EAAAA,eAGJ3L,GAAA,SAAA,W,8BACI6L,EAAAA,4BAA0BL,KAAAA,QAC1BxN,EAAA,iHAAAmB,KAAA,WAAA,cAEYpB,EAAAA,iHAAZkB,WAAA,YAGA2N,WAAAA,EAAAA,aAAAA,MAHA5O,EAAA,4BAIAmM,KAAA,QAEGnM,EAAA,4BAAAyD,KAAA,aAgJMzB,GAAA,SAAE,aA7IC,WA8IP,IAAA4M,EAlJO5O,EAkJD+B,MAAAmG,MA1IH3H,EAAAA,EAAAA,gBAGK,SAAAqO,GAEbvO,EAAAA,OAAiBoD,IAAjB,QAAA,cAAAgB,KAAAvE,EAAAmH,KAAAwH,eACiB1K,EAAAA,KAAO,kBAAP,CACD7D,YApBJJ,EAAA6C,MAqBJ2K,OAAAA,IACAQ,KAAAA,SAAAA,GACAA,WAAAA,GA6IZlJ,EAAEkF,IAAAA,QAAF,WAAAzF,KAAAvE,EAAAmH,KAAAyH,gBAzIQ9O,WAAA,WACImO,EAAY1K,QADhB,OAQApD,EAAA0O,OAAApG,IAAA,QAAA,OAAAlE,KAAAvE,EAAAmH,KAAA2H,gBAAApK,KA2IJqK,SAASjK,GA3IL3E,EACQkD,OADRY,EAEHmE,UAAAtD,M,8DAOOkJ,EAAAA,iBACAA,EAAAA,eAAa1K,QAfb,SAeA,C,YAIAD,GAAAA,SAAR,YAAA,SAAAtB,GACHA,EAAAiI,iB,oBAnITgF,EAuIiBzG,EAAAA,MAAAjF,KAAAyB,aAAyB8J,OAClCxG,EAAAA,EAAAA,aAAAnB,MAGJK,EAAAzH,EAAA,aA3IJsI,EAAAtI,EAAA,iBA6IQwH,EAAAxH,EAAA,uBAyICsI,EAtRTV,KAsRe,oFAAA1H,EAAAmH,KAAA8H,aAAA,SApIMpL,EAAAP,KADW,YAAAlD,SAAA,aAEXiC,EAAAA,UAAA,GAEA6M,EAAAA,SAAT5L,KAA6B2I,YAFpB7L,SAAA,aAGA4O,EAAAA,KAAAA,gCAATA,KAAAA,IAGSzG,EAAAA,eAATf,IACHa,EAAAA,mBAAAnB,EAAAI,EAAAC,EAAAsH,IAQS/O,EAAAA,GAAAC,QAlKlBgI,2BAySSlI,EAAC+D,KAAA,6BAAA,C,iBA/HDf,MAAA8F,EAAAA,MAELN,SAAAA,EAEI2G,aAAAA,KAmIhBlF,KAAA,SAAAtC,G,OAhI4BgH,EAAAA,mBAASlH,EAAAC,EAATiH,KAPX1E,KAAA,WAagChK,EAAAC,GAI3BgI,QAAA,4BACCY,KAAAA,EAAAA,W,qBAKFN,EAAA8G,uBAAA/G,EAAAO,EAAAkG,IAKG/O,EAAAA,GAAiBkI,QAAAA,2BAEfnI,EAbJ6K,KAgBI,oBAAA,C,iCA8HFZ,KAAA,SAAItC,GA3HA1H,EAAekI,GAAAA,EACbK,EAAA8G,uBAAA/G,EAAAZ,GACC1H,EAAA,eAAAkI,IAAAgH,GAENlP,EAAA,iBAAAkI,IAAA+G,GAGR,SAAAF,IAIc/O,EAAA,qBAADoC,WAlCb,YA6JApC,EAAA,kCAAAmB,KAAA,WAAA,YAvHGd,EAAO8L,qBAAWlL,WAAA,YACX2J,EAAAA,gCAAAA,KAAAA,WAAAA,aAIC3H,0BAAa8L,GAJU/O,EAC3BiE,gDAAAA,S,gBAUIjE,EAAAC,GAAAgI,QAAA,4BACOkE,KAAAA,EAAAA,aAGJ1I,GAAAA,SAAAA,yBAAAA,WACPU,IAhBJnC,EAAAhC,EAAA+B,MAkBGhC,EAAA6K,KAAA,qBAAA,CACInH,YAAPzD,EAAA+C,MAAOU,SACVtD,EAAAA,MADUsD,OAGF6K,EAAAnO,GAAAmP,QAAA,EAHE7L,MAKX6K,EAAAA,GAAA9K,GAAA,SAAA,sDAAA,WAIU8K,IAAAA,EAAuBrM,EAAAA,4BAGrB,MAAAqM,EAAAA,kCAAApG,OAAA,MAAAlI,EAAA,uCAAAkI,MACRgH,EAAiB/C,OAEjB1E,EAAAA,SAIJzF,GAAA,SAAA,aAAA,WAAA,IAAA7B,EACcH,EAAA+B,MADdgC,EAyHIwL,EAAAA,MAzHJjB,EAGa9K,EAAAA,QAAK,MAGAA,YAAT2G,GACI3G,EAAAA,KAAK+L,YAAA/L,OAClB+L,EAAAA,KAAAA,YAAA/L,IAAA,IAwHQ+L,EAAAA,KAAAA,eAAApD,SArHO/E,EAAAA,KAAAA,YAAAA,O,6BAG/BkH,EAAA9K,KAAA,eAAAmB,IAAA,OAwHyB3C,GAAA,SAAA,8BAAA,W,4BApHFwN,EAAAlC,EAAA9J,KAAA+L,mB,uBACuCpL,EAAAT,EAAAA,KAAA4J,YAEhCmC,EAAAA,EAAAA,aAFgCvH,MAIxB6G,EAAAA,KAFRW,gBAAAC,eAAAH,EAAAtH,QAAA,YAAAnE,EAAAmE,OAAA/D,EAAAgE,SAAAiH,EAAAlP,EAAAmH,KAAAqI,gBAAAF,EAAAtH,QAGYgH,IAAAA,EAAAA,KAAAA,oBAAAA,SAHZnP,EAAAA,KAAA,oBAAA2E,SAKWX,EAAAA,OAAA,sGAEayD,EAAAA,OAAAA,0LAD9BhD,OAAAtE,EAAA0P,WAAA,gBAIAR,GAAAA,GAJAG,EAAAM,OAAA,8DARJC,EAAAA,EAAAnL,KAAAA,yBAuIiBR,EAAAT,UAAEkB,EAAW,CACjB6K,SAnISP,EAgBAjK,YAAAA,EAAAA,KAAAA,gBACXoK,KAAAA,SAG/BM,EAAAG,G,EAgIqCA,EAAAnL,G,gCA/HrCZ,KAAA,MAoHoChE,KAAAA,CAnHIgE,YAAA7D,EAAA6C,MAEjBR,OAAAA,wBAC8B0B,SAAAA,KAEnB8K,KAAAA,SAAAA,GA8GyCe,EAjHpDnL,EAAA+C,GAMY2H,EAAAA,KAAAA,YAAX3K,WACqBwK,KAAAA,EAArBa,WAMMA,GAAA,aAAAX,GAAA,wBAAAI,EAAAtH,MAkBF/D,EAAAA,GA5DkCpE,EAAA+D,KAAA,0BAAA,CA6ChCC,KAAA,MA1DLoG,KA2DK,CAGNlG,YAAAiE,EAAAnF,MAiHAwM,OAAAA,0BACAA,SAAAA,KAhHMvF,KAAAjG,SAAA2D,GAEFoI,EADHP,EAAA7H,GAGD6H,EAAA/L,KAAA,YAAAkB,WACxBE,KAAAT,EAAA/B,eAY8BjC,qBAAAA,EAAAA,OAAAA,IAAAA,EAAAA,KAAAA,oBAAAA,SACFA,EAGpBqD,KAAA,QAAAkB,S,+GA+GY,YAAJX,EAAImE,OA7GJqH,EADR/L,KACkB,oBAAAC,UAGNuM,GAAAA,SAAAA,sBAAA,SAAAhL,GACGhF,IAAAA,EAAAA,EAAA,aAAAkI,MACH8H,EAFAA,EAEuB,aAACvM,MAC3BzD,EAAAA,EAAA,gBAESiQ,EAAAjQ,EAAA,cAEVkQ,KAAAA,GAAA/D,EAAAhE,SAAAiH,EAAAlP,EAAAmH,KAAA8I,sBACgBjI,EAAAA,OA3BR,aAiCJlD,EAAAjG,OAAAqR,K,0CACGF,EAAAzM,OAEM,QAAAM,EA/IG1D,EAmJhB4H,0BAnJgB5H,KAAAA,WAAAA,YAoJhB2B,QAAA+B,GAAA/D,EAAA,2BAIgBI,KAAA,WAEhB+L,aACAvJ,QAAc8M,GAAAA,WAALrI,GA2GrB6I,EA1GgB/D,OACIoD,EAAAA,QAgHrB,SAAAxL,GA3GqBsM,EAAA5M,QAIA,WAAA6M,GA6GlBxJ,EAAExG,SA1GoBmP,QAAAA,UACApL,EAAAA,GAAAA,GAAAA,QAAAA,2CAAAA,WACAkM,EAAAA,MAPHhN,QAAA,MAAAC,KAAA,kBAAA2I,OAQO,IAxBhBxJ,EAAA3C,EAAA+B,MAAAZ,KAAA,MAAAyF,MAAA,KAAA,GA3gBhBhE,EAAA5C,EAAA+B,MAAAQ,KAAA,YAsiBwCA,EAAAA,EACI0B,MAAAA,KAAAA,WACA/B,IAAAA,EAAAA,EAAAA,EAAAA,KAFEsO,MAAAA,WAF2B1D,IAAAA,EAAA9M,EAAAyQ,gCASjCX,EAAAA,GAAAA,OAAAA,WATiC9P,EAAAF,GAAA4Q,aAarCZ,IACHhJ,EAAAxG,SAhB0B,SAoBvBP,EAhBIwC,YAgBJxC,eAEUC,EAAAA,GAAAgC,GAAA,QAAA,+BAAA1B,SAAA0E,GAF6BA,EAhBnCzC,iBA0BAgN,EAAAA,QAAAA,CAAAA,SACHoB,IAAAC,KAXD,O,oEAcH5Q,KAAA,kBArCgB0M,SAAAiE,QAAzB1C,GAAyB4C,UAwC5B7Q,GAAA,QAAA,YAAA,WACJA,IAAAA,EAAAA,EAAA,aAAAkI,MAEOqH,EAAAA,iBAAiBrH,IAAQxD,K,sCACzB6K,EAAAA,yBAAmBH,YAAA,YA6GvB0B,EAAAA,MAAAA,SAASC,YA3GDhN,IAAAA,EAAA/D,EAAA+B,MAAAZ,KAAA,OACAoO,EAAAA,sBAAiByB,YAAAA,UACpBhR,EAAA,4BAAAiR,GAAA9G,SAAA7J,SAAA,YAER0B,GAlDgC,SAkDhC,oCAAA,WACJhC,IAUI8Q,EAVJ9Q,EAjGLA,EAAA+B,MAAAyB,KAAA,aAkGkB0E,MACVlI,EA9CwBuC,2CA6JhC2O,QAAA,yJAxGYhB,IAPJ,CAAA,SAAA,WAAWvH,YAAX,OAAA,uBAAA,WAAA,UAOIuH,QAAAA,IACHlQ,EAAA,6BAED2I,IAAA,UAAA,QAFC3I,EAAA,6BA2GU2I,IAAA,UAAY,SAAaA,IAApC,QAA4C,QA3G3CmI,EA4GH,IAADnN,E,eAvGWsM,EAAAA,kC,oCAKCjQ,EAAAA,6BAAUmR,IAAAA,UAAiBC,SACxBpR,EAAAA,6BAFAA,IAAAA,UAAAA,QAAAA,IAAAA,QAAAA,WAMJiQ,GAAAA,QAAAA,uBAAAoB,SAAAnJ,GACHlI,EAAAA,iBACGiQ,IAadhQ,EAbcgQ,EAAAA,EAAAA,qCAAAA,MA8GnBoB,EAACpR,EAAF8B,MAAAZ,KAAkB,MAAAmF,QAAY,UAAA,IAzGlBgL,EAAIlC,eAAaA,GAKpBnH,IAjF2B1F,CAAAA,SAAAA,WAAAA,YAAAA,OAAAA,uBAAAA,WAAAA,UAiFnB0L,QAtIbnO,IAyIEG,EAAAA,EAAAA,MACM8N,QAAAwD,MAAAA,KAAA,eADNtR,QAIL2C,EAAAA,IAAAA,GAAAA,QAAAA,MAAAA,KAAAA,UAAAA,KADDsO,SAAAhS,EAAAsS,G,sCASUV,EAAAA,EAAAE,gBAAAA,GAAAA,MACRlR,EAAAA,IAAAA,GAAAA,QAAAA,MAAAA,KAAAA,SAAAA,IAAAA,MAIAE,EAAAC,GAAAoQ,MAAA,WACAvJ,IAAAA,EAAAA,EAAAA,cAAAA,MACAgK,EAAA,IAAAnN,EArhBF1D,iBAshBC,IAAAwQ,IAAA3Q,EAAAoN,SAAAJ,MACDyE,aAAAE,IAAA,YAKCvH,EAAAA,2CAAFgH,QAAA,wJAAEhH,aAAAA,EAKCnG,EAAI0D,kCAEJiF,EAASsE,mCAiBZhR,EAAAC,GAAA+B,GAAA,mBAAA,WA4FH,IAAA2F,EAAA3H,EAAA,+CAAA4H,OAAAhB,MAAA,KAAAC,IAAA,SAAAgB,GAxFY7H,OAAAA,EAAAA,OAAAA,gBA0FNC,EAAaD,EAAA,aAtFb2H,EAAA+J,QA2FUjK,EAAAjE,KAASN,UAAAA,KAAakL,WAxFlB,IAAA7G,EAAAvH,EAAA+B,MACQwF,EAAAW,QAAA/D,EAAC4M,SAAAA,EAAAA,MAAAA,GAATnD,EAJd5F,UAAA,GAAAT,EAAAS,UAAA,KAMsB,IAAAL,EAAAnC,QAAAiC,EAACuJ,KAAAA,iBAATpD,EAAAA,GANd,MAAAzM,KAAA,WAAA,aAOWsG,EAAAjE,KAAA,UAAAN,UAAAA,KAgBVyN,EAAAA,GAAAA,GAAAA,QAAU1C,2LACTmD,WAuFQ,IA5DGO,EA4DHD,EAAIC,CArFZP,MAEAI,aAAAA,YAAAA,S,6FADHI,eAAA1O,aAAAgK,YAAAU,SAGAiE,uBAAA5H,aAAA6H,YAAAlE,SAEKmE,oBAAAC,aAAA5D,YAAAR,SAEJ5N,OAAIsR,aAAAA,YAA4BW,OApElCC,YAAAC,aAAAtP,YAAAoP,OAyEY5B,OAAM+B,aAAYhE,YAAAiE,U,0CAEdhG,MAAGnJ,aAAIS,YAAAA,gB,8DAURgO,EADMZ,aAAAA,WACN5C,cAZfnO,IAAAA,EAAAF,EAAAoN,SAAAoF,OAoBJtS,EADI,IAAAiK,gBAAA6H,GACJL,IAAA,UACAzR,EAAA,0BAAAsF,KAAA,SAAA9F,EAAAqD,GAEA,IAAAsP,EAAAnS,EAAA6C,GAAAqF,MAiFiBkK,EA7FOpS,EAAA,yBAAAuS,GAAAC,SAAAhT,IAAA0I,OAgBJjI,IAAAA,EAARwS,QAAAL,EAAO,CAAA,IAAAlP,aAAAkL,YAAPR,SAAA,IAAA1K,aAAAkL,YAAA6D,OAAA,IAAA/O,aAAAkL,YAAAiE,aADJrS,EAAA,yBAAAuS,GAAAC,SAAAhT,IAAA0I,IAAA,IAMIP,EAAAA,KAAMnC,EAAQ,SAAAkN,EAAAC,GAAdhL,IACA+K,I,cAAAE,cAAA1Q,GAAA,cAAAA,EAIIyF,EAAAA,yBAAAA,GAAAA,SAAAA,IAAAA,IAAAA,IAAAA,GAUZ3H,EAAA,yBAAAuS,GAAAC,SAAAhT,IAAA0I,IAAAkK,oEAn4CJ","file":"woo-feed-admin.min.js","sourcesContent":["// noinspection JSUnresolvedletiable\n/**!\n * WooFeed Scripts\n * @version 3.3.6\n * @package WooFeed\n * @copyright 2020 WebAppick\n *\n */\n/* global ajaxurl, wpAjax, postboxes, pagenow, alert, deleteUserSetting, typenow, adminpage, thousandsSeparator, decimalPoint, isRtl */\n// noinspection JSUnresolvedVariable\n(function($, window, document, wpAjax, opts) {\n \"use strict\";\n /**\n * All of the code for your admin-facing JavaScript source\n * should reside in this file.\n *\n * Note: It has been assumed you will write jQuery code here, so the\n * $ function reference has been prepared for usage within the scope\n * of this function.\n *\n * This enables you to define handlers, for when the DOM is ready:\n */\n\n /**\n * disable element utility\n *\n * @since 3.1.9\n *\n * @param {*} status\n * @returns {$|HTMLElement}\n */\n $.fn.disabled = function(status) {\n $(this).each(function() {\n let self = $(this),\n prop = 'disabled';\n\n if (typeof self.prop(prop) !== 'undefined') {\n self.prop(prop, status === void 0 || status === true);\n } else {\n !0 === status ? self.addClass(prop) : self.removeClass(prop);\n }\n });\n return self; // method chaining\n };\n\n /**\n * Check if a HTMLElement or jQuery is disabled\n */\n $.fn.isDisabled = function() {\n let self = $(this),\n prop = 'disabled';\n return typeof self.prop(prop) !== 'undefined' ? self.prop(prop) : self.hasClass(prop);\n };\n\n /**\n * Clear Tooltip for clip board js\n * @param {Object} event\n */\n const clearTooltip = (event) => {\n $(event.currentTarget).removeClass( (index, className) => (className.match(/\\btooltipped-\\S+/g) || []).join(' ') ).removeClass('tooltipped').removeAttr('aria-label');\n };\n\n const showTooltip = (elem, msg) => {\n $(elem).addClass('tooltipped tooltipped-s').attr('aria-label', msg);\n };\n\n const fallbackMessage = (action) =>{\n let actionMsg,\n actionKey = action === 'cut' ? 'X' : 'C';\n\n if (/iPhone|iPad/i.test(navigator.userAgent)) {\n actionMsg = 'No support :(';\n } else if (/Mac/i.test(navigator.userAgent)) {\n actionMsg = 'Press ⌘-' + actionKey + ' to ' + action;\n } else {\n actionMsg = 'Press Ctrl-' + actionKey + ' to ' + action;\n }\n\n return actionMsg;\n };\n\n /**\n * Alias of jQuery.extend()\n * @param {Object} _default\n * @param {Object} _args\n */\n const extend = (_default, _args) => $.extend(true, {}, _default, _args);\n\n\t/*\n\t* Handles product attributes\n\t*\n\t* @since 4.4.18\n\t* */\n\tclass WooFeedCustomFields {\n\n\t\tconstructor( field, status, isTaxonomy ) {\n\t\t\tthis.productCustomFields( field, status, isTaxonomy );\n\t\t}\n\n\t\tcacheClear() {\n\t\t\tlet data = {\n\t\t\t\taction: 'woo_feed_product_attribute_cache_remove',\n\t\t\t\tnonce: wpf_ajax_obj.ajax.nonce,\n\t\t\t};\n\t\t\t$.ajax({\n\t\t\t\tmethod: 'POST',\n\t\t\t\turl: wpf_ajax_obj.wpf_ajax_url,\n\t\t\t\tdata\n\t\t\t});\n\t\t}\n\n\t\tproductCustomFields( field, status = false, isTaxonomy ) {\n\t\t\tlet data = {\n\t\t\t\taction: 'woo_feed_custom_fields_status_change',\n\t\t\t\tnonce: wpf_ajax_obj.ajax.nonce,\n\t\t\t\tfield,\n\t\t\t\tstatus,\n\t\t\t\tisTaxonomy\n\t\t\t};\n\t\t\t$.ajax({\n\t\t\t\tmethod: 'POST',\n\t\t\t\turl: wpf_ajax_obj.wpf_ajax_url,\n\t\t\t\tdata,\n\t\t\t\tsuccess: ( response ) => {\n\t\t\t\t\tif( response.success ) {\n\t\t\t\t\t\tthis.cacheClear();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.log( response );\n\t\t\t\t\t}\n $('#'+field+'-switcher').closest('td').find('.switch-loader').hide();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n /*\n * Handles product categories\n *\n * @since 4.4.39\n * */\n class WooFeedMapCategories {\n wooFeed_get_google_categories () {\n wpAjax.send('get_google_categories', {\n type: 'GET',\n data: {\n _ajax_nonce: opts.nonce,\n action: \"get_google_categories\",\n // provider: provider\n }\n }).then(function (response) {\n $('.selectize-google-category').selectize({\n valueField: 'value',\n labelField: 'text',\n placeholder: 'Select a category',\n searchField: ['value', 'text'],\n options: response,\n render: {\n option: (data, escape) => `<div class=\"item wapk-selectize-item\">${escape(data.value + ' - ' + data.text)}</div>`,\n item: (data, escape) => `<div class=\"item wapk-selectize-item\">${escape(data.value + ' - ' + data.text)}</div>`\n }\n });\n\n //remove spinner element\n $('.woo-feed-cat-map-spinner').remove();\n }).fail(helper.ajax_fail);\n }\n\n wooFeed_get_facebook_categories() {\n // get facebook categories\n wpAjax.send('get_facebook_categories', {\n type: 'GET',\n data: {\n _ajax_nonce: opts.nonce,\n action: \"get_facebook_categories\",\n // provider: provider\n }\n }).then(function (response) {\n $('.selectize-google-category').selectize({\n valueField: 'value',\n labelField: 'text',\n placeholder: 'Select a Facebook category',\n searchField: ['value', 'text'],\n options: response,\n render: {\n option: (data, escape) => `<div class=\"item wapk-selectize-item\">${escape(data.value + ' - ' + data.text)}</div>`,\n item: (data, escape) => `<div class=\"item wapk-selectize-item\">${escape(data.value + ' - ' + data.text)}</div>`\n }\n });\n\n //remove spinner element\n $('.woo-feed-cat-map-spinner').remove();\n }).fail(helper.ajax_fail);\n }\n }\n\n let $copyBtn,\n clipboard,\n googleCategories,\n facebookCategories,\n helper = {\n in_array: (needle, haystack) => {\n try {\n return haystack.indexOf(needle) !== -1;\n } catch (e) {\n return false;\n }\n },\n selectize_render_item: (data, escape) => `<div class=\"item wapk-selectize-item\">${escape(data.text)}</div>`, // phpcs:ignore WordPressVIPMinimum.JS.StringConcat.Found,\n ajax_fail: e => {\n console.warn(e);\n alert(e.hasOwnProperty('statusText') && e.hasOwnProperty('status') ? opts.ajax.error + '\\n' + e.statusText + ' (' + e.status + ')' : e);\n },\n /**\n * Initialize Sortable\n * @param {$|HTMLElement} el\n * @param {object} config\n * @param {int|boolean} column\n * @param {function} onDrop\n * @return {$|HTMLElement}\n */\n sortable: (el, config, column, onDrop) => {\n return (el || $('.sorted_table')).each(function() {\n let self = $(this),\n column_count = self.find('tbody > tr:eq(0) > td').length || column || 9;\n self.wf_sortable(extend({\n containerSelector: 'table',\n itemPath: '> tbody',\n itemSelector: 'tr',\n handle: 'i.wf_sortedtable',\n placeholder: `<tr class=\"placeholder\"><td colspan=\"${column_count}\"></td></tr>`,\n onDrop: ($item, container, _super, event) => {\n $item.removeClass(container.group.options.draggedClass).removeAttr('style');\n $(\"body\").removeClass(container.group.options.bodyClass);\n var numb = $item.find(\".wf_mattributes\").attr(\"name\").replace(/\\D/g, \"\");\n $item.find(\"input.wf_attributes\").attr(\"name\", \"default[\"+ numb +\"]\");\n if ( onDrop && 'function' === typeof( onDrop ) ) {\n onDrop( $item, container, _super, event );\n }\n },\n }, config));\n });\n },\n selectize: (el, config) => {\n return (el || $('select.selectize')).not('.selectized').not('.selectize-google-category').each(function() {\n let self = $(this);\n self.selectize(extend({\n create: self.data('create') || false,\n plugins: self.data('plugins') ? self.data('plugins').split(',').map(function(s) {\n return s.trim();\n }) : [],\n //['remove_button'],\n render: {\n item: helper.selectize_render_item\n }\n }, config));\n });\n },\n fancySelect: (el, config) => {\n return (el || $('select.fancySelect')).not('.FancySelectInit').each(function() {\n let self = $(this);\n self.fancySelect(extend({\n maxItemShow: 3\n }, config));\n });\n },\n reindex_config_table: () => {\n $('#table-1').find('tbody tr').each( ( x, el ) => {\n $(el).find('[name]').each( ( x1, el ) => {\n $(el).attr('name', $(el).attr('name').replace(/(\\[\\d\\])/g, `[${x}]`));\n } );\n } );\n },\n common: () => {\n helper.sortable( $('.sorted_table'), {}, 9, helper.reindex_config_table );\n helper.selectize();\n helper.fancySelect($('.outputType'));\n }\n },\n // helper functions\n feedEditor = {\n /**\n * The Editor Form Elem.\n * @type {$|HTMLElement}\n */\n form: null,\n\n /**\n * Initialize The Feed Editor {Tabs...}\n * @returns {void}\n */\n init: function () {\n let self = this;\n self.form = $('.generateFeed');\n if (!self.form.length) return;\n helper.common();\n // noinspection JSUnresolvedVariable\n $(document).trigger('feed_editor_init');\n $(document).trigger(new jQuery.Event('feedEditor.init', {\n target: this.form\n }));\n },\n\n /**\n * Render Merchant info ajax response and handle allowed feed type for selected merchant\n * @param {$|HTMLElement} merchantInfo jQuery dom object\n * @param {$|HTMLElement} feedType jQuery dom object\n * @param {Object} r ajax response object\n */\n renderMerchantInfo: function (merchantInfo, feedType, r) {\n for (let k in r) {\n if (r.hasOwnProperty(k)) {\n merchantInfo.find('.merchant-info-section.' + k + ' .data').html(r[k]); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html\n\n if ('feed_file_type' === k) {\n (function() {\n let types = r[k].split(\",\").map(function(t) {\n return t.trim().toLowerCase();\n }).filter(function(t) {\n // noinspection JSUnresolvedVariable\n return t !== '' && t !== opts.na.toLowerCase();\n });\n\n if (types.length) {\n feedType.find('option').removeAttr('selected').each(function() {\n let opt = $(this);\n opt.val() && !helper.in_array(opt.val(), types) ? opt.disabled(!0) : opt.disabled(!1);\n });\n if (types.length === 1) feedType.find('option[value=\"' + types[0] + '\"]').attr('selected', 'selected');\n } else feedType.find('option').disabled(!1);\n })();\n }\n }\n }\n\n merchantInfo.find('.spinner').removeClass('is-active');\n feedType.disabled(!1);\n feedType.trigger('change');\n\n /**\n * Triggers after merchant configuration is fetched & loaded\n * */\n $(document).trigger('woo_feed_config_loaded');\n\n feedType.parent().find('.spinner').removeClass('is-active');\n },\n\n /**\n * Render Feed Template Tabs and settings while creating new feed.\n * @param {$|HTMLElement} feedForm feed from query dom object\n * @param {object} r merchant template ajax response object\n */\n renderMerchantTemplate: function (feedForm, r) {\n let _loop = function _loop(k) {\n if (r.hasOwnProperty(k)) {\n if ('tabs' === k) {\n // noinspection JSUnresolvedFunction\n feedForm.html(r[k]); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html\n } else {\n let contentSettings = $('[name=\"' + k + '\"]');\n\n if (contentSettings.length) {\n contentSettings.each(function() {\n let elem = $(this);\n\n if (elem.is('select')) {\n elem.find('[value=\"' + r[k] + '\"]').prop('selected', true);\n } else if ((elem.is('[type=checkbox]') || elem.is('[type=radio]')) && elem.val() === r[k]) {\n elem.prop('checked', true);\n } else {\n elem.val(r[k]); // type=text\n }\n }).trigger('change');\n }\n }\n }\n };\n\n for (let k in r) {\n _loop(k);\n }\n\n feedEditor.init();\n }\n },\n // Feed Editor Table\n merchantInfoCache = [],\n merchantTemplateCache = [],\n tooltip = () => {\n // Tooltip only Text\n $('.wfmasterTooltip')\n .hover(function () {\n // Hover over code\n let self = $(this), title = self.attr('wftitle');\n self.data('tipText', title).removeAttr('wftitle');\n $('<p class=\"wftooltip\"></p>').text(title).appendTo('body').fadeIn('slow');\n }, function () {\n // Hover out code\n let self = $(this);\n self.attr('wftitle', self.data('tipText'));\n $('.wftooltip').remove();\n })\n .mousemove(function (e) {\n $('.wftooltip').css({\n top: e.pageY + 10,\n left: e.pageX + 20\n });\n });\n },\n clip = () => {\n $copyBtn = $('.toClipboard');\n if (!ClipboardJS.isSupported() || /iPhone|iPad/i.test(navigator.userAgent)) {\n $copyBtn.find('img').hide(0);\n } else {\n $copyBtn.each(function() {\n $(this).on('mouseleave', clearTooltip).on('blur', clearTooltip);\n });\n clipboard = new ClipboardJS('.toClipboard');\n clipboard.on('error', function(event) {\n showTooltip(event.trigger, fallbackMessage(event.action));\n }).on('success', function(event) {\n showTooltip(event.trigger, 'Copied');\n });\n }\n };\n\n /**\n * Feed Generator Module\n */\n class feedGenerator {\n\n /**\n * Constructor\n * @constructor\n */\n constructor() {\n this._feed = opts.generator.feed; // wf_config+xxxx\n this._limit = opts.generator.limit;\n this._progress = 0;\n this._timer = null;\n this._color = false;\n // batch info\n this._total_batch = 0;\n this._current_batch = 0;\n this._product_ids = [];\n this._progress_per_batch = 0;\n this._refresh = true;\n // noinspection JSUnresolvedVariable\n this._regenerate = opts.generator.regenerate;\n window.isRegenerating = false;\n this._all_btn = $('.wpf_regenerate');\n this._current_btn = $(`#${this._feed.replace( 'wf_config', 'wf_feed_' )}`);\n this._current_btn_label = '';\n }\n\n /**\n * Init Hooks (Event)\n * @return {feedGenerator}\n */\n init() {\n let self = this;\n if ( '' !== this._feed && this._regenerate && false === window.isRegenerating ) {\n this.generate();\n }\n\n //thickbox body add feed plugin class to make it unique and custom style\n let current_page_query = window.location.search;\n let params = new URLSearchParams(current_page_query);\n let page_name = params.get(\"page\");\n if( \"webappick-manage-feeds\" === page_name ) {\n $('body').addClass('woo-import-popup-body');\n }\n\n $(document).on('click', '.woo-feed-campaign-close-button', function(event) {\n event.preventDefault();\n\n $(this).parent('.woo-feed-promotion').hide();\n let condition = $(this).data('condition');\n if(1 === condition) {\n wpAjax.post( 'woo_feed_hide_promotion', {\n _ajax_nonce: opts.nonce,\n condition: condition,\n } ).then( response => {\n self._log( response );\n } ).fail( error => {\n self._log( error );\n self._updateProgressStatus( error.message );\n self._color = 'red';\n } );\n }\n });\n\n $(document).on('click', '.wpf_regenerate', function(event) {\n event.preventDefault();\n self._current_btn = $( this );\n if( self._current_btn.hasClass('disabled') || window.isRegenerating === true ) return;\n self._feed = self._current_btn.attr('id').replace( 'wf_feed_', 'wf_config' );\n if( '' !== self._feed ) {\n self.generate();\n }\n });\n return this;\n }\n\n _block_button() {\n if ( this._all_btn.length ) {\n this._all_btn.addClass('disabled');\n }\n if ( this._current_btn.length ) {\n this._current_btn.find('span').addClass('wpf_spin reverse_spin');\n this._current_btn_label = this._current_btn.attr('title');\n // noinspection JSUnresolvedVariable\n this._current_btn.attr( 'aria-label', opts.regenerate ).attr( 'title', opts.regenerate );\n }\n }\n\n _unblock_button() {\n if ( this._all_btn.length ) {\n this._all_btn.removeClass('disabled');\n }\n if ( this._current_btn.length ) {\n this._current_btn.find('span').removeClass('wpf_spin');\n this._current_btn.find('span').removeClass('reverse_spin');\n this._current_btn.attr( 'aria-label', this._current_btn_label ).attr( 'title', this._current_btn_label );\n }\n }\n\n /**\n * Generate Feed\n * @return void\n */\n generate() {\n let self = this;\n window.isRegenerating = true;\n this._block_button();\n this._resetProgressBar();\n this._progressBarActive();\n this._log( 'Counting Total Products' );\n this._updateProgressStatus( 'Fetching products.' );\n this._get_product_ids().then( response => {\n this._progress = 10;\n self._log( {response} );\n if(response.success) {\n self._log( `Total ${response.total} Products found.` );\n self._product_ids = response.product;\n self._total_batch = this._product_ids.length;\n self._current_batch = 0;\n self._progress_per_batch = ( 90 - this._progress ) / this._total_batch;\n self._process_batch();\n self._updateProgressStatus( 'Processing Products...' );\n } else {\n self._updateProgressStatus( response.data.message );\n }\n }).fail( error => {\n self._log( error );\n self._updateProgressStatus( error.message );\n self._color = 'red';\n setTimeout( function(){\n self._stopProgressBar();\n self._unblock_button();\n }, 1500 );\n } );\n }\n\n /**\n * Get Product Ids\n * @returns {$.promise}\n * @private\n */\n _get_product_ids() {\n this._progress = 5;\n return wpAjax.post( 'get_product_information', {\n _ajax_nonce: opts.nonce,\n feed: this._feed,\n limit: this._limit,\n } );\n }\n\n /**\n * Run the Batch\n * @private\n */\n _process_batch() {\n let self = this;\n let status = `Processing Batch ${this._current_batch+1} of ${this._total_batch}`;\n this._updateProgressStatus( status );\n this._log( status );\n wpAjax.post( 'make_batch_feed', {\n _ajax_nonce: opts.nonce,\n feed: this._feed,\n products: this._product_ids[this._current_batch],\n loop: this._current_batch,\n } ).then( response => {\n self._current_batch++;\n self._log( `Batch ${self._current_batch} Completed` );\n self._log( response );\n if ( self._current_batch < self._total_batch ) {\n self._process_batch();\n self._progress += self._progress_per_batch;\n }\n if ( self._current_batch === self._total_batch ) {\n self._save_feed_file();\n }\n } ).fail( error => {\n self._log( error );\n self._updateProgressStatus( error.message );\n self._color = 'red';\n setTimeout( function(){\n self._stopProgressBar();\n self._unblock_button();\n }, 1500 );\n } );\n }\n\n /**\n * Save Feed Data from temp to feed file\n * @private\n */\n _save_feed_file() {\n let self = this;\n this._log( 'Saving feed file' );\n this._updateProgressStatus( 'Saving feed file' );\n wpAjax.post( 'save_feed_file', {\n _ajax_nonce: opts.nonce,\n feed: this._feed,\n } ).then( response => {\n self._log( response );\n self._progress = 100;\n if ( self._refresh ) {\n window.location.href = `${opts.pages.list.feed}&link=${response.url}&cat=${response.cat}`;\n }\n setTimeout( function(){\n self._stopProgressBar();\n setTimeout( function(){\n self._resetProgressBar( true );\n self._unblock_button();\n }, 3000 );\n }, 2500 );\n } ).fail( error => {\n self._log( error );\n self._updateProgressStatus( error.message );\n self._color = 'red';\n setTimeout( function(){\n self._stopProgressBar();\n self._unblock_button();\n }, 1500 );\n } );\n }\n\n /**\n * Console log wrapper with debug settings.\n * @param data\n * @returns {feedGenerator}\n * @private\n */\n _log( data ) {\n // noinspection JSUnresolvedVariable\n if ( opts.wpf_debug ) {\n console.log( data );\n }\n return this;\n }\n\n /**\n * Run the progressbar refresh interval\n * @param {int} refreshInterval\n * @returns {feedGenerator}\n * @private\n */\n _progressBarActive( refreshInterval = 0 ) {\n let self = this;\n this._toggleProgressBar( true );\n this._timer = setInterval( function(){\n self._updateProgressBar();\n }, refreshInterval || 1000 );\n return this;\n }\n\n /**\n * Stop Progressbar\n * @returns {feedGenerator}\n * @private\n */\n _stopProgressBar() {\n clearInterval( this._timer );\n return this;\n }\n\n /**\n * Reset Progressbar\n * @returns {feedGenerator}\n * @private\n */\n _resetProgressBar( update ) {\n this._toggleProgressBar( false );\n this._updateProgressStatus( '' );\n clearInterval( this._timer );\n this._color = false;\n this._timer = null;\n this._progress = 0;\n if ( update ) {\n this._updateProgressBar();\n }\n return this;\n }\n\n /**\n * Show hide the progress bar el\n * @param status\n * @returns {feedGenerator}\n * @private\n */\n _toggleProgressBar( status ) {\n let table = $('#feed_progress_table');\n if ( status ) {\n table.show();\n } else {\n table.hide();\n }\n return this;\n }\n\n /**\n * Update Progress bar text status\n * @param {string} status\n * @returns {feedGenerator}\n * @private\n */\n _updateProgressStatus( status ) {\n $( '.feed-progress-status' ).html( status );\n return this;\n }\n\n _getErrorMessageByCode( error ){\n let progress_message = $( '.feed-progress-status' );\n progress_message.css( {'color':this._color});\n $( '.feed-progress-percentage' ).css( {'color':this._color});\n $( '.wpf_spin' ).css( {'color':this._color});\n\n let message=error.status +' : '+ error.statusText+'. ';\n if(500===error.status){\n message+= \"Please increase your PHP max_execution_time. Please <a target='_blank' href='https://webappick.com/docs/woo-feed/faq-for-woocommerce-product-feed/how-to-solve-processing-10-feed-generation-stuck-error/'>read this doc</a>.\";\n }\n\n this._updateProgressStatus(message);\n\n }\n\n /**\n * Update Progress Data\n * hooked with setInterval\n * @private\n */\n _updateProgressBar() {\n let percentage = $( '.feed-progress-percentage' ),\n bar = $( '.feed-progress-bar-fill' ),\n _progress = `${Math.round( this._progress )}%`;\n bar.css( {\n width: _progress,\n } );\n percentage.text( _progress );\n }\n }\n // expose to the global scope\n window.wf = {\n helper: helper,\n feedEditor: feedEditor,\n generator: feedGenerator,\n };\n\n $(window).on('load', function() {\n // Template loading ui conflict\n if ($(location).attr(\"href\").match(/webappick.*feed/g) !== null) {\n $('#wpbody-content').addClass('woofeed-body-content');\n }\n\n // ClipBoardJS\n clip();\n // postbox toggle\n postboxes.add_postbox_toggles(pagenow);\n // initialize generator\n let generator = new feedGenerator();\n generator.init();\n // noinspection JSUnresolvedVariable\n if( '' !== opts.generator.feed && opts.generator.regenerate ) {\n\n }\n // initialize editor\n feedEditor.init();\n helper.common(); // Generate Feed Add Table Row\n tooltip();\n // validate feed editor\n $(\".generateFeed\").validate();\n\n // document events\n $(document)\n .on('blur', 'input[name=\"wfDAttributeName\"]', function(e) {\n e.preventDefault();\n let attr_name = $(this).val();\n attr_name = attr_name.toLowerCase();\n attr_name = attr_name.split(' ').join('_');\n\n $('#wfDAttributeCode').val(attr_name);\n\n })\n .on('click', '[data-toggle_slide]', function(e) {\n e.preventDefault();\n $($(this).data('toggle_slide')).slideToggle('fast');\n })\n // XML Feed Wrapper\n .on('click', '#wf_newRow', function () {\n let tbody = $('#table-1 tbody'),\n template = $('#feed_config_template').text().trim().replace(/__idx__/g, tbody.find('tr').length);\n tbody.append(template);\n helper.fancySelect($('.outputType'));\n })\n // feed delete alert.\n .on('click', '.single-feed-delete', function (event) {\n event.preventDefault();\n // noinspection JSUnresolvedVariable\n if (confirm(opts.form.del_confirm)) {\n window.location.href = $(this).attr('val');\n }\n })\n // clear cache data.\n .on('click', '.wf_clean_cache_wrapper', function(event) {\n event.preventDefault();\n var nonce = $('.woo-feed-clean-cache-nonce').val();\n var loader = $('.woo-feed-cache-loader');\n\n //show loader\n loader.show();\n\n // passed cache nonce\n wpAjax.post('clear_cache_data', {\n _ajax_clean_nonce: nonce\n }).then(function (response) {\n if( response.success ) {\n loader.hide(); //hide loader\n location.reload();\n }\n }).fail(function () {\n console.log('something wrong');\n });\n\n })// Copy Status\n .on('click', '#woo-feed-copy-status-btn', function(event) {\n event.preventDefault();\n let button = $('#woo-feed-copy-status-btn');\n let status_area = $('#woo-feed-status-area');\n button.val('Copied');\n status_area.css('visibility','visible');\n status_area.select();\n\n document.execCommand('copy');\n })\n // feed value dropdown change.\n .on('change', '.wf_attr.wf_attributes', function(event) {\n event.preventDefault();\n\n $('.fancy-picker-picked').trigger(\"click\"); // trigger fancy select box clicked\n\n // price attributes\n var price_attributes = ['price', 'current_price', 'sale_price', 'price_with_tax', 'current_price_with_tax', 'sale_price_with_tax', 'shipping_cost'];\n // current value\n var current_attribute_value = $(this).val();\n var outputSelect = $(this).parents('tr').find('.outputType');\n var fancyOption = $(this).parents('tr').find('.fancy-picker-content .fancy-picker-option');\n var fancyDataPicker = $(this).parents('tr').find('.fancy-picker-data span');\n var selectIf, selectKey;\n var currency;\n\n // when any attribute is selected, pick the key\n if( price_attributes.includes(current_attribute_value) ) {\n // when select any price attribute\n selectIf = 'for_price';\n selectKey = \"Price\";\n } else if ( \"\" !== current_attribute_value && -1 !== current_attribute_value.indexOf('wf_taxo') ) {\n\n // when select any custom taxonomy\n selectIf = 'for_custom_taxo';\n selectKey = \"parent_if_empty\";\n } else {\n\n selectIf = 'for_all';\n selectKey = 'Default';\n }\n\n // remove selected class from old selected option\n fancyOption.removeClass('selected');\n\n // when value dropdown is selected as price or any custom taxonomy\n if( selectIf === 'for_custom_taxo' || selectIf === 'for_price' ) {\n // update \"Option Type\" when select key matches\n fancyOption.each(function() {\n if( selectKey === $(this).text() ) {\n $(this).addClass('selected');\n fancyDataPicker.text(selectKey);\n outputSelect.find(\"option\").text(selectKey);\n outputSelect.find(\"option\").val( $(this).data('value') );\n }\n });\n\n if( \"for_price\" === selectIf ) {\n var feedCurrency = $('#feedCurrency').val();\n if( \"undefined\" !== typeof feedCurrency && null !== feedCurrency ) {\n currency = feedCurrency;\n }else {\n currency = wpf_ajax_obj.woocommerce.currency;\n }\n\n //for price add currency to the suffix\n $(this).closest(\"tr\").find(\"td:eq(5) input\").val(\" \" + currency);\n }\n\n } else {\n fancyOption.each(function(){\n if( selectKey === $(this).text() ){\n $(this).addClass('selected');\n fancyDataPicker.text(selectKey);\n outputSelect.find(\"option\").text(selectKey);\n outputSelect.find(\"option\").val( $(this).data(\"value\") );\n }\n });\n\n $(this).closest(\"tr\").find(\"td:eq(5) input\").val(\"\");\n }\n\n })\n // bulk delete alert.\n .on('click', '#doaction, #doaction2', function () {\n // noinspection JSUnresolvedVariable\n return confirm(opts.form.del_confirm_multi);\n })\n // Generate Feed Table Row Delete\n .on('change', '.dType', function () {\n let self = $(this),\n type = self.val(),\n row = self.closest('tr');\n\n if (type === 'pattern') {\n row.find('.value_attribute').hide();\n row.find('.value_pattern').show();\n } else if (type === 'attribute') {\n row.find('.value_attribute').show();\n row.find('.value_pattern').hide();\n } else if (type === 'remove') {\n row.find('.value_attribute').hide();\n row.find('.value_pattern').hide();\n }\n })\n // Generate Feed Form Submit\n .on('click', '.delRow', function (e) {\n e.preventDefault();\n $(this).closest('tr').remove();\n helper.reindex_config_table();\n })\n .on('submit', '#generateFeed', function () {\n // Feed Generating form validation\n $(this).validate();\n\n if ($(this).valid()) {\n $(\".makeFeedResponse\")\n .show()\n .html(`<b style=\"color: darkblue;\"><i class=\"dashicons dashicons-sos wpf_spin\"></i> ${opts.form.generate}</b>`); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html, WordPressVIPMinimum.JS.StringConcat.Found\n }\n })\n // Generate Update Feed Form Submit\n .on('submit', '#updatefeed', function (e, data) {\n // Feed Generating form validation\n $(this).validate();\n\n if ($(this).valid()) {\n $(\".makeFeedResponse\")\n .show()\n .html(`<b style=\"color: darkblue;\"><i class=\"dashicons dashicons-sos wpf_spin\"></i> ${data && data.save ? opts.form.save : opts.form.generate}</b>`); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html, WordPressVIPMinimum.JS.StringConcat.Found\n }\n })\n .on( 'ready woo_feed_config_loaded', function(){\n\n if( $('#ftpenabled').val() === '0' ){\n $('.google-merchant-message').hide('slow');\n $('.woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) input, .woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) select').attr('disabled','disabled');\n } else {\n if( $('#provider').val() === 'google' ) {\n $('.google-merchant-message').show('slow');\n } else {\n $('.google-merchant-message').hide('slow');\n }\n $('.woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) input, .woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) select').removeAttr('disabled');\n }\n\n $('#ftpenabled').on('change', function(){\n if( $('#ftpenabled').val() === '0' ){\n $('.google-merchant-message').hide('slow');\n $('.woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) input, .woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) select').attr('disabled','disabled');\n } else {\n\n $('.woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) input, .woo-feed-ftp .ftpconfig tr:not(.ftpcontroller) select').removeAttr('disabled');\n\n // Google merchant specific message\n if( $('#provider').val() === 'google' ){\n $('.google-merchant-message').show('slow');\n } else {\n $('.google-merchant-message').hide('slow');\n }\n\n }\n });\n })\n .on('change', '.ftporsftp', function () {\n let server = $(this).val(),\n status = $('.ssh2_status');\n\n if (server === 'sftp') {\n // noinspection JSUnresolvedVariable\n status.show().css('color', 'dodgerblue').text(opts.form.sftp_checking);\n wpAjax.post('get_ssh2_status', {\n _ajax_nonce: opts.nonce,\n server: server\n }).then(function (response) {\n if (response === 'exists') {\n // noinspection JSUnresolvedVariable\n status.css('color', '#2CC185').text(opts.form.sftp_available);\n setTimeout(function () {\n status.hide();\n }, 1500);\n } else {\n // noinspection JSUnresolvedVariable\n status.show().css('color', 'red').text(opts.form.sftp_warning);\n }\n }).fail(function (e) {\n status.hide();\n helper.ajax_fail(e);\n });\n } else {\n status.hide();\n }\n })\n .on('click', '[name=\"save_feed_config\"]', function (e) {\n e.preventDefault();\n $('#updatefeed').trigger('submit', {\n save: true\n });\n })\n .on('change', '#provider', function (event) {\n event.preventDefault();\n\n let merchant = $(this).val(),\n templateName = $(this).find(':selected').text(),\n name = $('#filename').val(),\n feedType = $(\"#feedType\"),\n feedForm = $(\"#providerPage\"),\n merchantInfo = $('#feed_merchant_info'); // set loading..\n\n // noinspection JSUnresolvedVariable\n feedForm.html('<h3><span style=\"float:none;margin: -3px 0 0;\" class=\"spinner is-active\"></span> ' + opts.form.loading_tmpl + '</h3>'); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html, WordPressVIPMinimum.JS.StringConcat.Found\n\n merchantInfo.find('.spinner').addClass('is-active');\n feedType.disabled(!0); // disable dropdown\n\n feedType.parent().find('.spinner').addClass('is-active');\n merchantInfo.find('.merchant-info-section .data').html(''); // remove previous data\n // Get Merchant info for selected Provider/Merchant\n\n if (merchantInfoCache.hasOwnProperty(merchant)) {\n feedEditor.renderMerchantInfo(merchantInfo, feedType, merchantInfoCache[merchant]);\n\n /**\n * Triggers after merchant configuration is fetched & loaded\n * */\n $(document).trigger('woo_feed_config_loaded');\n\n } else {\n wpAjax.send('woo_feed_get_merchant_info', {\n type: 'GET',\n data: {\n nonce: opts.nonce,\n provider: merchant,\n templateName: templateName\n }\n }).then(function (r) {\n merchantInfoCache[merchant] = r;\n feedEditor.renderMerchantInfo(merchantInfo, feedType, r);\n }).then(function(){\n\n /**\n * Triggers after merchant configuration is fetched & loaded\n * */\n $(document).trigger('woo_feed_config_loaded');\n\n }).fail(helper.ajax_fail);\n } // Get FeedForm For Selected Provider/Merchant\n\n\n if (merchantTemplateCache.hasOwnProperty(merchant)) {\n feedEditor.renderMerchantTemplate(feedForm, merchantTemplateCache[merchant]);\n\n /**\n * Triggers after merchant configuration is fetched & loaded\n * */\n $(document).trigger('woo_feed_config_loaded');\n\n } else {\n wpAjax.post('get_feed_merchant', {\n _ajax_nonce: opts.nonce,\n merchant: merchant\n }).then(function (r) {\n merchantTemplateCache[merchant] = r;\n feedEditor.renderMerchantTemplate(feedForm, r);\n $('#utm_source').val(templateName);\n $('#utm_campaign').val(name);\n //when merchant is bing, change delimiter and enclosure\n if( 'bing' === merchant ) {\n //delimiter value\n $(\"#delimiter option\").removeAttr('selected');\n $(\"#delimiter option[value=\\\"tab\\\"]\").attr('selected', 'selected');\n\n //enclosure value\n $(\"#enclosure option\").removeAttr('selected');\n $(\"#enclosure option[value=\\\" \\\"]\").attr('selected', 'selected');\n }\n\n //reviewer options hide\n if( 'google_product_review' !== merchant) {\n $('.wf_attributes option[value=\"reviewer_name\"]').hide();\n }\n }).then(function(){\n\n /**\n * Triggers after merchant configuration is fetched & loaded\n * */\n $(document).trigger('woo_feed_config_loaded');\n\n }).fail(helper.ajax_fail);\n }\n })\n // Feed Active and Inactive status change via ajax\n .on('change', '.woo_feed_status_input', function () {\n let self = $(this);\n wpAjax.post('update_feed_status', {\n _ajax_nonce: opts.nonce,\n feedName: self.val(),\n status: self[0].checked ? 1 : 0\n });\n });\n // event with trigger\n $(document)\n .on('change', '[name=\"is_outOfStock\"], [name=\"product_visibility\"]', function () {\n let outOfStockVisibilityRow = $('.out-of-stock-visibility');\n if ($('[name=\"is_outOfStock\"]:checked').val() === 'n' && $('[name=\"product_visibility\"]:checked').val() === '1') {\n outOfStockVisibilityRow.show();\n } else {\n outOfStockVisibilityRow.hide();\n }\n })\n .on('change', '.attr_type', function () {\n // Attribute type selection\n let self = $(this),\n type = self.val(),\n row = self.closest('tr');\n\n if (type === 'pattern') {\n row.find('.wf_attr').hide();\n row.find('.wf_attr').val('');\n row.find('.wf_default').show();\n } else {\n row.find('.wf_attr').show();\n row.find('.wf_default').hide();\n row.find('.wf_default').val('');\n }\n })\n .on('change', '.wf_mattributes, .attr_type', function () {\n let row = $(this).closest('tr'),\n attribute = row.find('.wf_mattributes'),\n type = row.find('.attr_type'),\n valueColumn = row.find('td:eq(4)'),\n provider = $('#provider').val();\n\n // noinspection JSUnresolvedVariable\n if (opts.form.google_category.hasOwnProperty(attribute.val()) && type.val() === 'pattern' && helper.in_array(provider, opts.form.google_category[attribute.val()])) {\n if (valueColumn.find('select.selectize').length === 0) {\n valueColumn.find('input.wf_default').remove();\n valueColumn.append('<span class=\"wf_default wf_attributes\"><select name=\"default[]\" class=\"selectize\"></select></span>');\n // noinspection JSUnresolvedVariable\n valueColumn.append(`<span style=\"font-size:x-small;\"><a style=\"color: red\" href=\"https://webappick.com/docs/woo-feed/feed-configuration/how-to-map-store-category-with-merchant-category/\" target=\"_blank\">${opts.learn_more}</a></span>`);\n\n if (!googleCategories || !facebookCategories) {\n valueColumn.append('<span class=\"spinner is-active\" style=\"margin: 0;\"></span>');\n }\n\n let select = valueColumn.find('.wf_attributes select');\n // noinspection JSUnresolvedVariable\n helper.selectize(select, {\n preload: true,\n placeholder: opts.form.select_category,\n load: function load(query, cb) {\n if (!googleCategories) {\n wpAjax.send('get_google_categories', {\n type: 'GET',\n data: {\n _ajax_nonce: opts.nonce,\n action: \"get_google_categories\",\n provider: provider\n }\n }).then(function (r) {\n googleCategories = r;\n cb(googleCategories);\n valueColumn.find('.spinner').remove();\n }).fail(helper.ajax_fail);\n } else {\n cb(googleCategories);\n }\n\n //for facebook product category merchant attribute\n if (!facebookCategories && \"facebook\" === provider && \"fb_product_category\" === attribute.val()) {\n wpAjax.send('get_facebook_categories', {\n type: 'GET',\n data: {\n _ajax_nonce: opts.nonce,\n action: \"get_facebook_categories\",\n provider: provider\n }\n }).then(function (r) {\n facebookCategories = r;\n cb(facebookCategories);\n valueColumn.find('.spinner').remove();\n }).fail(helper.ajax_fail);\n } else {\n cb(facebookCategories);\n }\n }\n });\n }\n } else {\n if ( attribute.val() !== 'current_category' && valueColumn.find('input.wf_default').length === 0) {\n valueColumn.find('span').remove();\n valueColumn.append('<input autocomplete=\"off\" class=\"wf_default wf_attributes\" type=\"text\" name=\"default[]\" value=\"\">');\n\n if (type.val() !== 'pattern') {\n valueColumn.find('input.wf_default').hide();\n }\n }\n }\n })\n .on('change', '#feedType,#provider', function (e) {\n let type = $('#feedType').val(),\n provider = $('#provider').val(),\n itemWrapper = $('.itemWrapper'),\n wf_csv_txt = $('.wf_csvtxt');\n\n // noinspection JSUnresolvedVariable\n if (type !== '' && helper.in_array(provider, opts.form.item_wrapper_hidden)) {\n itemWrapper.hide();\n }\n\n //when feed type is changed\n if( 'feedType' === e.target.id ) {\n if (type === 'csv' || type === 'txt' || type === 'tsv') {\n wf_csv_txt.show();\n itemWrapper.hide();\n \n if( 'tsv' === type ) {\n $('#delimiter option:last').prop(\"selected\", \"selected\");\n } else if( 'csv' === type ) {\n $('#delimiter option:first').prop(\"selected\", \"selected\");\n }\n } else if( 'xml' === type && \"custom\" === provider ) {\n itemWrapper.show();\n wf_csv_txt.hide();\n } else if( 'json' === type ) {\n wf_csv_txt.hide();\n }\n }\n\n // when template is not custom template 1 hide the item wrapper\n if( \"custom\" !== provider ) {\n itemWrapper.hide();\n }\n\n })\n .trigger('change');\n\n\n $(document)\n\t\t\t.on('click', '.woofeed-custom-fields [id*=\"-switcher\"]', function () {\n\t\t\t $(this).closest('td').find('.switch-loader').show();\n\t\t\t\tlet field = $(this).attr( 'id' ).split( '-' )[0],\n\t\t\t\t\tisTaxonomy = $(this).data( 'taxonomy' ),\n\t\t\t\t\tstatus = $(this).prop( 'checked' );\n\t\t\t\tnew WooFeedCustomFields( field, status, isTaxonomy );\n\n\t\t\t})\n\n\t\t\t// Remove sticky cart on feature page\n\t\t\t.ready(function() {\n\t\t\t\tvar s = $(\".wapk-feed-buy-now-container\");\n\t\t\t\t$(window).scroll(function() {\n\t\t\t\t\tvar windowpos = $(window).scrollTop();\n\t\t\t\t\tif ( windowpos <= 5000 ) {\n\t\t\t\t\t\ts.addClass(\"fixed\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\ts.removeClass(\"fixed\");\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n });\n\n $(document)\n\t\t.on('click', '#woo-feed-debug-log-download', function (e) {\n\t\t\te.preventDefault();\n\t\t\t$(\"<a />\", {\n\t\t\t\tdownload: new Date() + \".log\",\n\t\t\t\thref: URL.createObjectURL(\n\t\t\t\t\tnew Blob([$(\"#woo-feed-debug-log\").val()], {\n\t\t\t\t\t\ttype: \"text/plain\"\n\t\t\t\t\t})),\n\t\t\t}).appendTo(\"body\")[0].click();\n\t\t})\n\t\t.on('keyup', '#filename', function() {\n\t\t\tvar name = $('#filename').val();\n\t\t\t$('#utm_campaign').val(name);\n\t\t})\n\n .on('click', '.wf-tab-name', function(e) {\n $('.wf-tab-name.activate').removeClass('activate');\n $(this).addClass('activate');\n\n let for_attr = $(this).attr('for');\n $('.wf_tabs li.active').removeClass('active');\n $('.wf_tabs .wf-tab-content#' + for_attr).parent().addClass('active');\n })\n\n\t\t.on('change', '#category-mapping-form #providers', function() {\n\t\t\tvar provider = $(this).find(':selected').val(),\n\t\t\t\tgoogleMap = ['google', 'facebook', 'pinterest', 'bing', 'bing_local_inventory', 'snapchat','tiktok'];\n\n //add snipper element\n $('.woo-feed-category-mapping-config-table').prepend('<div class=\"woo-feed-cat-map-spinner\"><h3><span style=\"float:none;margin: -3px 0 0;\" class=\"spinner is-active\"></span> Loading Mapping...</h3></div>');\n\n\t\t\tif( googleMap.indexOf(provider) !== -1 ) {\n\t\t\t\t$('input[id*=\"cat_mapping_\"]').css('display', 'none');\n\t\t\t\t$('.wf_default.wf_attributes').css('display', 'block').css('width', '100%');\n\n var cat_init = new WooFeedMapCategories();\n if( \"facebook\" === provider ) {\n cat_init.wooFeed_get_facebook_categories();\n } else {\n cat_init.wooFeed_get_google_categories();\n }\n\n } else {\n\t\t\t\t$('input[id*=\"cat_mapping_\"]').css('display', 'block');\n\t\t\t\t$('.wf_default.wf_attributes').css('display', 'none').css('width', '100%');\n\t\t\t}\n\t\t})\n\n // Copy parent category ids to child categories.\n\t\t.on('click', 'span[id*=\"cat-map-\"]', function(e) {\n\t\t\te.preventDefault();\n\t\t\tvar providerName = $('#category-mapping-form #providers').val(),\n\t\t\t\tgoogleMap = ['google', 'facebook', 'pinterest', 'bing', 'bing_local_inventory', 'snapchat','tiktok'],\n\t\t\t\tcatId = $(this).attr('id').replace(/[^\\d.]/g, ''),\n\t\t\t\tgroupId = 'group-child-' + catId;\n\n\t\t\tif( googleMap.indexOf(providerName) !== -1) {\n\t\t\t\tvar catField = $(this).parents('tr').find('.selectized').val();\n\n\t\t\t\tif (catField) {\n\t\t\t\t\t$('.' + groupId).parents('tr').find('select').each(function (i, v) {\n\t\t\t\t\t\t$(v).data('selectize').setValue(catField);\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\tvar value = $('#cat_mapping_'+catId).val();\n\t\t\t\t$('.'+groupId).parents('tr').find('input').val(value);\n\t\t\t}\n\n\t\t});\n\n $(document).ready(function () {\n var provider = $(\"#providers\").val();\n var cat_init = new WooFeedMapCategories();\n\n var url = new URL(window.location.href);\n var cat_mapping_action = url.searchParams.get(\"action\");\n\n if( \"edit-mapping\" === cat_mapping_action ) {\n $('.woo-feed-category-mapping-config-table').prepend('<div class=\"woo-feed-cat-map-spinner\"><h3><span style=\"float:none;margin: -3px 0 0;\" class=\"spinner is-active\"></span> Loading Mapping...</h3></div>');\n\n if( \"facebook\" === provider ) {\n cat_init.wooFeed_get_facebook_categories();\n } else {\n cat_init.wooFeed_get_google_categories();\n }\n }\n\n });\n\n /*\n * Issue fix for feed edit page unsupported `Feed Type` not disabling\n *\n * @since 4.4.22\n * */\n $(document).on( \"feed_editor_init\", function(){\n\n let types = $('.merchant-info-section.feed_file_type .data').html().split(\",\").map(function(t) {\n return t.trim().toLowerCase();\n });\n\n let feedType = $(\"#feedType\");\n\n if (types.length) {\n feedType.find('option').each(function() {\n let opt = $(this);\n opt.val() && !helper.in_array(opt.val(), types) ? opt.disabled(!0) : opt.disabled(!1);\n });\n if (types.length === 1) feedType.find('option[value=\"' + types[0] + '\"]').attr('selected', 'selected');\n } else feedType.find('option').disabled(!1);\n\n } );\n\n /**\n * Automatically adding postfix for corresponding attribute selection.\n *\n * @since 4.4.32\n */\n $(document).on('ready', function(){\n\n function update_postfix(){\n var attribute_list = {\n\n 'price': wpf_ajax_obj.woocommerce.currency,\n 'current_price': wpf_ajax_obj.woocommerce.currency,\n 'sale_price': wpf_ajax_obj.woocommerce.currency,\n 'price_with_tax': wpf_ajax_obj.woocommerce.currency,\n 'current_price_with_tax': wpf_ajax_obj.woocommerce.currency,\n 'sale_price_with_tax': wpf_ajax_obj.woocommerce.currency,\n\n\n 'weight': wpf_ajax_obj.woocommerce.weight,\n 'weight_unit': wpf_ajax_obj.woocommerce.weight,\n\n\n 'height': wpf_ajax_obj.woocommerce.dimension,\n 'length': wpf_ajax_obj.woocommerce.dimension,\n 'width': wpf_ajax_obj.woocommerce.dimension\n\n };\n\n if (typeof wpf_ajax_obj.feed_rules !== 'undefined' && wpf_ajax_obj.feed_rules !== null) {\n var feed_rules = wpf_ajax_obj.feed_rules;\n var current_feed_currency = feed_rules.feedCurrency;\n }\n\n //get current action name of the page\n var queryString = window.location.search;\n var urlParams = new URLSearchParams(queryString);\n var action = urlParams.get('action');\n\n $( '.wf_attr.wf_attributes' ).each( function( key, value){\n\n var attribute_value = $(value).val();\n var current_Value = $( 'input[name^=\"suffix\"]' ).eq( parseInt( key ) ).val();\n\n if( -1 !== $.inArray( current_Value, [\n ' ' + wpf_ajax_obj.woocommerce.currency,\n ' ' + wpf_ajax_obj.woocommerce.weight,\n ' ' + wpf_ajax_obj.woocommerce.dimension\n ] ) ){\n $( 'input[name^=\"suffix\"]' ).eq( parseInt( key ) ).val('');\n }\n\n $.each(attribute_list, function (_key, _value){\n if( attribute_value === _key ){\n _value = null !== current_feed_currency && \"undefined\" !== typeof current_feed_currency ? current_feed_currency : _value;\n\n if( \"undefined\" !== action && \"edit-feed\" !== action ) {\n $( 'input[name^=\"suffix\"]' ).eq( parseInt( key ) ).val( ' ' + _value );\n } else {\n $( 'input[name^=\"suffix\"]' ).eq( parseInt( key ) ).val( current_Value );\n }\n\n }\n });\n } );\n\n $(document).trigger( 'feedEditor.after.free.postfix.update' );\n }\n\n $(document).on('feedEditor.init', function(){\n let provider = $(this).find(':selected').val(),\n googleMap = ['google', 'facebook', 'pinterest', 'bing', 'bing_local_inventory', 'snapchat','tiktok'];\n\n if( googleMap.indexOf(provider) !== -1 ) {\n update_postfix();\n }\n });\n\n });\n\n})(jQuery, window, document, wp.ajax, wpf_ajax_obj);\n"]}
 
admin/partials/woo-feed-edit-config.php CHANGED
@@ -58,7 +58,7 @@ if ( ! defined( 'ABSPATH' ) ) {
58
  <select <?php echo ( 'attribute' == $attr_type[ $k ] ) ? '' : 'style=" display: none;" '; ?>name="attributes[<?php echo esc_attr( $k ); ?>]" class="wf_attr wf_attributes">
59
  <?php
60
  // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
61
- echo $wooFeedDropDown->product_attributes_dropdown( esc_attr( $wooAttributes[ $k ] ) );
62
  ?>
63
  </select>
64
  <?php if ( woo_feed_merchant_require_google_category( $feedRules['provider'], $mAttribute ) ) { ?>
@@ -134,7 +134,7 @@ if ( ! defined( 'ABSPATH' ) ) {
134
  <select name="attributes[__idx__]" required="required" class="wf_validate_attr wf_attr wf_attributes">
135
  <?php
136
  // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
137
- echo $wooFeedDropDown->product_attributes_dropdown();
138
  ?>
139
  </select>
140
  <input value="" type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style="display:none;">
58
  <select <?php echo ( 'attribute' == $attr_type[ $k ] ) ? '' : 'style=" display: none;" '; ?>name="attributes[<?php echo esc_attr( $k ); ?>]" class="wf_attr wf_attributes">
59
  <?php
60
  // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
61
+ echo woo_feed_get_product_attributes( esc_attr( $wooAttributes[ $k ] ) );
62
  ?>
63
  </select>
64
  <?php if ( woo_feed_merchant_require_google_category( $feedRules['provider'], $mAttribute ) ) { ?>
134
  <select name="attributes[__idx__]" required="required" class="wf_validate_attr wf_attr wf_attributes">
135
  <?php
136
  // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
137
+ echo woo_feed_get_product_attributes();
138
  ?>
139
  </select>
140
  <input value="" type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style="display:none;">
includes/Tracker/Base.php CHANGED
@@ -62,7 +62,7 @@ abstract Class Base{
62
  if ( is_product() ) {
63
  $event = 'product_view';
64
  $add_to_cart = sanitize_text_field( $_POST['add-to-cart'] );
65
- if ( ! empty($addToCart) ) {
66
  $event = 'add_to_cart';
67
  }
68
  } elseif ( is_wc_endpoint_url('order-received') ) {
62
  if ( is_product() ) {
63
  $event = 'product_view';
64
  $add_to_cart = sanitize_text_field( $_POST['add-to-cart'] );
65
+ if ( ! empty($add_to_cart) ) {
66
  $event = 'add_to_cart';
67
  }
68
  } elseif ( is_wc_endpoint_url('order-received') ) {
includes/class-woo-feed.php CHANGED
@@ -133,6 +133,10 @@ class Woo_Feed {
133
  * The class contain merchant attributes
134
  */
135
  require_once WOO_FEED_FREE_PATH . 'includes/classes/class-woo-feed-default-attributes.php';
 
 
 
 
136
 
137
  /**
138
  * The class responsible for generating feed
133
  * The class contain merchant attributes
134
  */
135
  require_once WOO_FEED_FREE_PATH . 'includes/classes/class-woo-feed-default-attributes.php';
136
+ /**
137
+ * The class contain product attributes
138
+ */
139
+ require_once WOO_FEED_FREE_PATH . 'includes/classes/class-woo-feed-product-attributes.php';
140
 
141
  /**
142
  * The class responsible for generating feed
includes/classes/class-woo-feed-constants.php CHANGED
@@ -23,7 +23,7 @@ if( ! class_exists("Woo_Feed_Constants") ) {
23
  * @var string
24
  * @since 3.1.6
25
  */
26
- define( 'WOO_FEED_FREE_VERSION', '4.4.67' );
27
  }
28
 
29
  if ( ! defined( 'WOO_FEED_FREE_PATH' ) ) {
23
  * @var string
24
  * @since 3.1.6
25
  */
26
+ define( 'WOO_FEED_FREE_VERSION', '4.4.68' );
27
  }
28
 
29
  if ( ! defined( 'WOO_FEED_FREE_PATH' ) ) {
includes/classes/class-woo-feed-default-attributes.php CHANGED
@@ -630,10 +630,7 @@ class Woo_Feed_Default_Attributes {
630
  = array(
631
  'description' => array( 'description', true ),
632
  );
633
-
634
- public function __construct() {
635
-
636
- }
637
 
638
  /**
639
  * Google Attribute List
630
  = array(
631
  'description' => array( 'description', true ),
632
  );
633
+
 
 
 
634
 
635
  /**
636
  * Google Attribute List
includes/classes/class-woo-feed-dropdown.php CHANGED
@@ -54,6 +54,65 @@ class Woo_Feed_Dropdown {
54
 
55
  return apply_filters('woo_feed_output_types', $output_types);
56
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
 
58
  /**
59
  * Dropdown of Merchant List
@@ -232,688 +291,6 @@ class Woo_Feed_Dropdown {
232
  return $taxonomy;
233
  }
234
 
235
- /**
236
- * Get product related post meta keys (filtered)
237
- *
238
- * @return array
239
- */
240
- protected function getCustomAttributes() {
241
- $attributes = woo_feed_get_cached_data( 'woo_feed_dropdown_product_custom_attributes' );
242
- if ( false === $attributes ) {
243
- // Get Variation Attributes
244
- global $wpdb;
245
- $attributes = array();
246
- $sql = "SELECT DISTINCT( meta_key ) FROM $wpdb->postmeta
247
- WHERE post_id IN (
248
- SELECT ID FROM $wpdb->posts WHERE post_type = 'product_variation' -- local attributes will be found on variation product meta only with attribute_ suffix
249
- ) AND (
250
- meta_key LIKE 'attribute_%' -- include only product attributes from meta list
251
- AND meta_key NOT LIKE 'attribute_pa_%'
252
- )";
253
- // sanitization ok
254
- $localAttributes = $wpdb->get_col( $sql ); // phpcs:ignore
255
- foreach ( $localAttributes as $localAttribute ) {
256
- $localAttribute = str_replace( 'attribute_', '', $localAttribute );
257
- $attributes[ Woo_Feed_Products_v3::PRODUCT_ATTRIBUTE_PREFIX . $localAttribute ] = ucwords( str_replace( '-', ' ', $localAttribute ) );
258
- }
259
-
260
- // Get Product Custom Attributes
261
- $sql = 'SELECT meta.meta_id, meta.meta_key as name, meta.meta_value as type FROM ' . $wpdb->postmeta . ' AS meta, ' . $wpdb->posts . " AS posts WHERE meta.post_id = posts.id AND posts.post_type LIKE '%product%' AND meta.meta_key='_product_attributes';";
262
- $customAttributes = $wpdb->get_results( $sql ); // phpcs:ignore
263
-
264
- if ( ! empty( $customAttributes ) ) {
265
- foreach ( $customAttributes as $value ) {
266
- $product_attr = maybe_unserialize( $value->type );
267
- if ( ! empty( $product_attr ) && is_array( $product_attr ) ) {
268
- foreach ( $product_attr as $key => $arr_value ) {
269
- if ( strpos( $key, 'pa_' ) === false ) {
270
- $attributes[ Woo_Feed_Products_v3::PRODUCT_ATTRIBUTE_PREFIX . $key ] = ucwords( str_replace( '-', ' ', $arr_value['name'] ) );
271
- }
272
- }
273
- }
274
- }
275
- }
276
- woo_feed_set_cache_data( 'woo_feed_dropdown_product_custom_attributes', $attributes );
277
- }
278
-
279
- // @TODO implement filter hook
280
- return (array) $attributes;
281
- }
282
-
283
- /**
284
- * Get All Taxonomy
285
- *
286
- * @return array
287
- */
288
- protected function getAllTaxonomy() {
289
- // $info = woo_feed_get_cached_data( 'woo_feed_dropdown_product_taxonomy' );
290
- //
291
- // if ( false === $info ) {
292
-
293
- $data = get_object_taxonomies( 'product' );
294
- $info = array();
295
- global $wp_taxonomies;
296
- $default_excludes = array(
297
- 'product_type',
298
- 'product_visibility',
299
- 'product_cat',
300
- 'product_tag',
301
- 'product_shipping_class',
302
- 'translation_priority',
303
- );
304
-
305
- /**
306
- * Exclude Taxonomy from dropdown
307
- *
308
- * @param array $user_excludes
309
- * @param array $default_excludes
310
- */
311
- $user_excludes = apply_filters( 'woo_feed_dropdown_exclude_taxonomy', null, $default_excludes );
312
- if ( is_array( $user_excludes ) && ! empty( $user_excludes ) ) {
313
- $default_excludes = array_merge( $default_excludes, $user_excludes );
314
- }
315
-
316
- if ( count( $data ) ) {
317
- foreach ( $data as $key => $value ) {
318
- if ( in_array($value, $default_excludes, true) || strpos( $value, 'pa_' ) !== false ) {
319
- continue;
320
- }
321
- $label = isset( $wp_taxonomies[ $value ] ) ? $wp_taxonomies[ $value ]->label . " [{$value}]" : $value;
322
- $info[ Woo_Feed_Products_v3::PRODUCT_TAXONOMY_PREFIX . $value ] = $label;
323
- }
324
- }
325
- // woo_feed_set_cache_data( 'woo_feed_dropdown_product_taxonomy', $info );
326
- // }
327
-
328
- return (array) $info;
329
- }
330
-
331
- /**
332
- * Get All Options
333
- *
334
- * @return array
335
- */
336
- protected function getAllOptions() {
337
- $_wp_options = wp_list_pluck( get_option( 'wpfp_option', array() ), 'option_name');
338
- $_wp_options_val = str_replace('wf_option_', '', $_wp_options);
339
- $_wp_options = array_combine($_wp_options, $_wp_options_val);
340
-
341
- return $_wp_options;
342
- }
343
-
344
- // Product Attribute DropDowns.
345
-
346
- /**
347
- * Get All Default WooCommerce Attributes
348
- * @return array
349
- */
350
- protected function getAttributeTaxonomies() {
351
- $taxonomies = woo_feed_get_cached_data( 'getAttributeTaxonomies' );
352
- if ( false === $taxonomies ) {
353
- // Load the main attributes
354
- $globalAttributes = wc_get_attribute_taxonomy_labels();
355
- if ( count( $globalAttributes ) ) {
356
- foreach ( $globalAttributes as $key => $value ) {
357
- $taxonomies[ Woo_Feed_Products_v3::PRODUCT_ATTRIBUTE_PREFIX . 'pa_' . $key ] = $value;
358
- }
359
- }
360
- woo_feed_set_cache_data( 'getAttributeTaxonomies', $taxonomies );
361
- }
362
-
363
- return $taxonomies;
364
- }
365
-
366
- /**
367
- * Get All Custom Attributes
368
- *
369
- * @return array
370
- */
371
- protected function getProductMetaKeys() {
372
- $info = woo_feed_get_cached_data( 'woo_feed_dropdown_meta_keys' );
373
- if ( false === $info ) {
374
- global $wpdb;
375
- $info = [];
376
- // Load the main attributes.
377
-
378
- $default_exclude_keys = [
379
- // WP internals.
380
- '_edit_lock',
381
- '_wp_old_slug',
382
- '_edit_last',
383
- '_wp_old_date',
384
- // WC internals.
385
- '_downloadable_files',
386
- '_sku',
387
- '_weight',
388
- '_width',
389
- '_height',
390
- '_length',
391
- '_file_path',
392
- '_file_paths',
393
- '_default_attributes',
394
- '_product_attributes',
395
- '_children',
396
- '_variation_description',
397
- // ignore variation description, engine will get child product description from WC CRUD WC_Product::get_description().
398
- // Plugin Data.
399
- '_wpcom_is_markdown',
400
- // JetPack Meta.
401
- '_yith_wcpb_bundle_data',
402
- // Yith product bundle data.
403
- '_et_builder_version',
404
- // Divi builder data.
405
- '_vc_post_settings',
406
- // Visual Composer (WP Bakery) data.
407
- '_enable_sidebar',
408
- 'frs_woo_product_tabs',
409
- // WooCommerce Custom Product Tabs http://www.skyverge.com/.
410
- ];
411
-
412
- /**
413
- * Exclude meta keys from dropdown
414
- *
415
- * @param array $exclude meta keys to exclude.
416
- * @param array $default_exclude_keys Exclude keys by default.
417
- */
418
- $user_exclude = apply_filters( 'woo_feed_dropdown_exclude_meta_keys', null, $default_exclude_keys );
419
-
420
- if ( is_array( $user_exclude ) && ! empty( $user_exclude ) ) {
421
- $user_exclude = esc_sql( $user_exclude );
422
- $default_exclude_keys = array_merge( $default_exclude_keys, $user_exclude );
423
- }
424
-
425
- $default_exclude_keys = array_map( 'esc_sql', $default_exclude_keys );
426
- $exclude_keys = '\'' . implode( '\', \'', $default_exclude_keys ) . '\'';
427
-
428
- $default_exclude_key_patterns = [
429
- '%_et_pb_%', // Divi builder data
430
- 'attribute_%', // Exclude product attributes from meta list
431
- '_yoast_wpseo_%', // Yoast SEO Data
432
- '_acf-%', // ACF duplicate fields
433
- '_aioseop_%', // All In One SEO Pack Data
434
- '_oembed%', // exclude oEmbed cache meta
435
- '_wpml_%', // wpml metas
436
- '_oh_add_script_%', // SOGO Add Script to Individual Pages Header Footer.
437
- ];
438
-
439
- /**
440
- * Exclude meta key patterns from dropdown
441
- *
442
- * @param array $exclude meta keys to exclude.
443
- * @param array $default_exclude_key_patterns Exclude keys by default.
444
- */
445
- $user_exclude_patterns = apply_filters( 'woo_feed_dropdown_exclude_meta_keys_pattern', null, $default_exclude_key_patterns );
446
- if ( is_array( $user_exclude_patterns ) && ! empty( $user_exclude_patterns ) ) {
447
- $default_exclude_key_patterns = array_merge( $default_exclude_key_patterns, $user_exclude_patterns );
448
- }
449
- $exclude_key_patterns = '';
450
- foreach ( $default_exclude_key_patterns as $pattern ) {
451
- $exclude_key_patterns .= $wpdb->prepare( ' AND meta_key NOT LIKE %s', $pattern );
452
- }
453
-
454
- $sql = "SELECT DISTINCT( meta_key ) FROM $wpdb->postmeta WHERE 1=1 AND post_id IN ( SELECT ID FROM $wpdb->posts WHERE post_type = 'product' OR post_type = 'product_variation' ) AND ( meta_key NOT IN ( $exclude_keys ) $exclude_key_patterns )";
455
-
456
- // sql escaped, cached
457
- $data = $wpdb->get_results( $sql ); // phpcs:ignore
458
-
459
- if ( count( $data ) ) {
460
- foreach ( $data as $value ) {
461
- //TODO Remove ACF Fields
462
- $info[ Woo_Feed_Products_v3::POST_META_PREFIX . $value->meta_key ] = $value->meta_key;
463
- }
464
- }
465
- woo_feed_set_cache_data( 'woo_feed_dropdown_meta_keys', $info );
466
- }
467
-
468
- return (array) $info;
469
- }
470
-
471
- /**
472
- * Product Attributes
473
- *
474
- * @return array
475
- */
476
- protected function get_product_attributes() {
477
- $attributes = array(
478
- '--1' => esc_html__( 'Primary Attributes', 'woo-feed' ),
479
- 'id' => esc_html__( 'Product Id', 'woo-feed' ),
480
- 'title' => esc_html__( 'Product Title', 'woo-feed' ),
481
- 'parent_title' => esc_html__( 'Parent Title', 'woo-feed' ),
482
- 'description' => esc_html__( 'Product Description', 'woo-feed' ),
483
- 'description_with_html' => esc_html__( 'Product Description (with HTML)', 'woo-feed' ),
484
- 'short_description' => esc_html__( 'Product Short Description', 'woo-feed' ),
485
- 'primary_category' => esc_html__( 'Parent Category', 'woo-feed' ),
486
- 'primary_category_id' => esc_html__( 'Parent Category ID', 'woo-feed' ),
487
- 'child_category' => esc_html__( 'Child Category', 'woo-feed' ),
488
- 'child_category_id' => esc_html__( 'Child Category ID', 'woo-feed' ),
489
- 'product_type' => esc_html__( 'Product Category [Category Path]', 'woo-feed' ),
490
- 'product_full_cat' => esc_html__( 'Product Full Category [Category Full Path]', 'woo-feed' ),
491
- 'link' => esc_html__( 'Product URL', 'woo-feed' ),
492
- 'parent_link' => esc_html__( 'Parent URL', 'woo-feed' ),
493
- 'canonical_link' => esc_html__( 'Canonical URL', 'woo-feed' ),
494
- 'ex_link' => esc_html__( 'External Product URL', 'woo-feed' ),
495
- 'add_to_cart_link' => esc_html__( 'Add to Cart URL', 'woo-feed' ),
496
- 'item_group_id' => esc_html__( 'Parent Id [Group Id]', 'woo-feed' ),
497
- 'sku' => esc_html__( 'SKU', 'woo-feed' ),
498
- 'sku_id' => esc_html__( 'SKU_ID', 'woo-feed' ),
499
- 'parent_sku' => esc_html__( 'Parent SKU', 'woo-feed' ),
500
- 'availability' => esc_html__( 'Availability', 'woo-feed' ),
501
- 'availability_date' => esc_html__( 'Availability Date', 'woo-feed' ),
502
- 'quantity' => esc_html__( 'Quantity', 'woo-feed' ),
503
- 'currency' => esc_html__( 'Currency', 'woo-feed' ),
504
- 'price' => esc_html__( 'Regular Price', 'woo-feed' ),
505
- 'current_price' => esc_html__( 'Price', 'woo-feed' ),
506
- 'sale_price' => esc_html__( 'Sale Price', 'woo-feed' ),
507
- 'price_with_tax' => esc_html__( 'Regular Price With Tax', 'woo-feed' ),
508
- 'current_price_with_tax' => esc_html__( 'Price With Tax', 'woo-feed' ),
509
- 'sale_price_with_tax' => esc_html__( 'Sale Price With Tax', 'woo-feed' ),
510
- 'sale_price_sdate' => esc_html__( 'Sale Start Date', 'woo-feed' ),
511
- 'sale_price_edate' => esc_html__( 'Sale End Date', 'woo-feed' ),
512
- 'reviewer_name' => esc_html__( 'Reviewer Name', 'woo-feed' ),
513
- 'weight' => esc_html__( 'Weight', 'woo-feed' ),
514
- 'weight_unit' => esc_html__( 'Weight Unit', 'woo-feed' ),
515
- 'width' => esc_html__( 'Width', 'woo-feed' ),
516
- 'height' => esc_html__( 'Height', 'woo-feed' ),
517
- 'length' => esc_html__( 'Length', 'woo-feed' ),
518
- 'shipping' => esc_html__( 'Shipping (Google Format)', 'woo-feed' ),
519
- 'shipping_cost' => esc_html__( 'Shipping Cost', 'woo-feed' ),
520
- 'shipping_class' => esc_html__( 'Shipping Class', 'woo-feed' ),
521
- 'type' => esc_html__( 'Product Type', 'woo-feed' ),
522
- 'variation_type' => esc_html__( 'Variation Type', 'woo-feed' ),
523
- 'visibility' => esc_html__( 'Visibility', 'woo-feed' ),
524
- 'rating_total' => esc_html__( 'Total Rating', 'woo-feed' ),
525
- 'rating_average' => esc_html__( 'Average Rating', 'woo-feed' ),
526
- 'tags' => esc_html__( 'Tags', 'woo-feed' ),
527
- 'sale_price_effective_date' => esc_html__( 'Sale Price Effective Date', 'woo-feed' ),
528
- 'is_bundle' => esc_html__( 'Is Bundle', 'woo-feed' ),
529
- 'author_name' => esc_html__( 'Author Name', 'woo-feed' ),
530
- 'author_email' => esc_html__( 'Author Email', 'woo-feed' ),
531
- 'date_created' => esc_html__( 'Date Created', 'woo-feed' ),
532
- 'date_updated' => esc_html__( 'Date Updated', 'woo-feed' ),
533
- 'tax' => esc_html__( 'Tax', 'woo-feed' ),
534
- 'tax_class' => esc_html__( 'Tax Class', 'woo-feed' ),
535
- 'tax_status' => esc_html__( 'Tax Status', 'woo-feed' ),
536
- '---1' => '',
537
- );
538
-
539
- $custom_fields = woo_feed_product_custom_fields();
540
- $custom_identifier_filter = new Woo_Feed_Custom_Identifier_Filter( $custom_fields );
541
- $custom_identifier = iterator_to_array( $custom_identifier_filter );
542
- $product_attribute_enables = [];
543
- if ( ! empty( $custom_identifier ) ) {
544
- $attributes['--2'] = esc_html__( 'Custom Fields by CTX Feed', 'woo-feed' );
545
-
546
- foreach ( $custom_identifier as $key => $value ) {
547
- $product_attribute_enables[ 'woo_feed_identifier_' . sanitize_text_field( wp_unslash( $key ) ) ] = sanitize_text_field( $value[0] );
548
- }
549
- $attributes['---2'] = '';
550
- }
551
- array_splice_preserve_keys( $attributes, count($attributes) - 1, 0, $product_attribute_enables );
552
-
553
- // Subscription & Installment Attributes
554
- if ( class_exists( 'WC_Subscriptions' ) ) {
555
- $attributes['--3'] = esc_html__( 'Subscription & Installment', 'woo-feed' );
556
- $attributes = array_merge(
557
- $attributes,
558
- array(
559
- 'subscription_period' => esc_html__( 'Subscription Period', 'woo-feed' ),
560
- 'subscription_period_interval' => esc_html__( 'Subscription Period Length', 'woo-feed' ),
561
- 'subscription_amount' => esc_html__( 'Subscription Amount', 'woo-feed' ),
562
- 'installment_months' => esc_html__( 'Installment Months', 'woo-feed' ),
563
- 'installment_amount' => esc_html__( 'Installment Amount', 'woo-feed' ),
564
- )
565
- );
566
- $attributes['---3'] = '';
567
- }
568
-
569
- // Unit Price Measure & Unit Price Base Measure Attributes
570
-
571
- $unit_price_attributes = array(
572
- 'unit_price_measure' => esc_html__( 'Unit Price Measure', 'woo-feed' ),
573
- 'unit_price_base_measure' => esc_html__( 'Unit Price Base Measure', 'woo-feed' ),
574
- );
575
-
576
- if ( class_exists( 'WooCommerce_Germanized' ) ) {
577
- $attributes['--4'] = esc_html__( 'WooCommerce Germanized', 'woo-feed' );
578
- $attributes = array_merge( $attributes,$unit_price_attributes);
579
- $attributes += array(
580
- 'wc_germanized_gtin' => 'GTIN',
581
- 'wc_germanized_mpn' => 'MPN',
582
- );
583
- $attributes['---4'] = '';
584
- }else {
585
- $identifiers = woo_feed_get_options('woo_feed_identifier');
586
- if ( 'enable' === $identifiers['unit_pricing_base_measure']
587
- && 'enable' === $identifiers['unit_pricing_measure']
588
- && 'enable' === $identifiers['unit']
589
- ) {
590
- $attributes['--4'] = esc_html__( 'Unit Price', 'woo-feed' );
591
- $attributes = array_merge( $attributes,$unit_price_attributes);
592
- $attributes['---4'] = '';
593
- }
594
- }
595
-
596
- // All In One SEO Attributes
597
- if ( class_exists( 'AIOSEO\Plugin\AIOSEO' ) ) {
598
- $attributes['--5'] = esc_html__( 'ALL IN ONE SEO', 'woo-feed' );
599
- $attributes = array_merge(
600
- $attributes,
601
- array(
602
- '_aioseop_title' => esc_html__( 'Title [All in One SEO]', 'woo-feed' ),
603
- '_aioseop_description' => esc_html__( 'Description [All in One SEO]', 'woo-feed' ),
604
- '_aioseop_canonical_url' => esc_html__( 'Canonical URL [All in One SEO]', 'woo-feed' ),
605
- )
606
- );
607
- $attributes['---5'] = '';
608
- }
609
-
610
- // Yoast Identifier Attributes.
611
- if ( class_exists( 'WPSEO_Frontend' ) || class_exists( 'WPSEO_Premium' ) ) {
612
- $attributes['--6'] = esc_html__( 'Yoast SEO', 'woo-feed' );
613
-
614
- $yoast_attributes = array(
615
- 'yoast_wpseo_title' => esc_html__( 'Title [Yoast SEO]', 'woo-feed' ),
616
- 'yoast_wpseo_metadesc' => esc_html__( 'Description [Yoast SEO]', 'woo-feed' ),
617
- 'yoast_canonical_url' => esc_html__( 'Canonical URL [Yoast SEO]', 'woo-feed' ),
618
-
619
- );
620
-
621
- if ( class_exists( 'Yoast_WooCommerce_SEO' ) ) {
622
- $yoast_attributes += array(
623
- 'yoast_gtin8' => esc_html__( 'GTIN8 [Yoast SEO]', 'woo-feed' ),
624
- 'yoast_gtin12' => esc_html__( 'GTIN12 / UPC [Yoast SEO]', 'woo-feed' ),
625
- 'yoast_gtin13' => esc_html__( 'GTIN13 / EAN [Yoast SEO]', 'woo-feed' ),
626
- 'yoast_gtin14' => esc_html__( 'GTIN14 / ITF-14 [Yoast SEO]', 'woo-feed' ),
627
- 'yoast_isbn' => esc_html__( 'ISBN [Yoast SEO]', 'woo-feed' ),
628
- 'yoast_mpn' => esc_html__( 'MPN [Yoast SEO]', 'woo-feed' ),
629
- );
630
- }
631
- $attributes = array_merge(
632
- $attributes, $yoast_attributes
633
- );
634
-
635
- $attributes['---6'] = '';
636
- }
637
-
638
- // Rank Math SEO Attributes
639
- if ( class_exists( 'RankMath' ) || class_exists( 'RankMathPro' ) ) {
640
-
641
- $attributes['--7'] = esc_html__('Rank Math SEO', 'woo-feed');
642
- $attributes = array_merge(
643
- $attributes,
644
- array(
645
- 'rank_math_title' => esc_html__('Title [RankMath SEO]', 'woo-feed'),
646
- 'rank_math_description' => esc_html__('Description [RankMath SEO]', 'woo-feed'),
647
- 'rank_math_canonical_url' => esc_html__('Canonical URL [RankMath SEO]', 'woo-feed'),
648
- 'rank_math_gtin' => esc_html__('GTIN [RankMath Pro SEO]', 'woo-feed'),
649
- )
650
- );
651
- $attributes['---7'] = '';
652
- }
653
-
654
- // Image Attributes.
655
- $attributes['--8'] = esc_html__( 'Image Attributes', 'woo-feed' );
656
- $attributes += array(
657
- 'image' => esc_html__( 'Main Image', 'woo-feed' ),
658
- 'feature_image' => esc_html__( 'Featured Image', 'woo-feed' ),
659
- 'images' => esc_html__( 'Images [Comma Separated]', 'woo-feed' ),
660
- 'image_1' => esc_html__( 'Additional Image 1', 'woo-feed' ),
661
- 'image_2' => esc_html__( 'Additional Image 2', 'woo-feed' ),
662
- 'image_3' => esc_html__( 'Additional Image 3', 'woo-feed' ),
663
- 'image_4' => esc_html__( 'Additional Image 4', 'woo-feed' ),
664
- 'image_5' => esc_html__( 'Additional Image 5', 'woo-feed' ),
665
- 'image_6' => esc_html__( 'Additional Image 6', 'woo-feed' ),
666
- 'image_7' => esc_html__( 'Additional Image 7', 'woo-feed' ),
667
- 'image_8' => esc_html__( 'Additional Image 8', 'woo-feed' ),
668
- 'image_9' => esc_html__( 'Additional Image 9', 'woo-feed' ),
669
- 'image_10' => esc_html__( 'Additional Image 10', 'woo-feed' ),
670
- );
671
- $attributes['---8'] = '';
672
-
673
- // Product Attribute.
674
- $_attributes = $this->getAttributeTaxonomies();
675
- if ( ! empty( $_attributes ) && is_array( $_attributes ) ) {
676
- $attributes['--50'] = esc_html__( 'Product Attributes', 'woo-feed' );
677
- $attributes += $this->getAttributeTaxonomies();
678
- $attributes['---50'] = '';
679
- }
680
-
681
-
682
- $_custom_attributes = $this->getCustomAttributes();
683
- if ( ! empty( $_custom_attributes ) && is_array( $_custom_attributes ) ) {
684
- $attributes['--51'] = esc_html__( 'Product Custom Attributes', 'woo-feed' );
685
- $attributes += $_custom_attributes;
686
- $attributes['---51'] = '';
687
- }
688
-
689
- $_taxonomies = $this->getAllTaxonomy();
690
- if ( ! empty( $_taxonomies ) && is_array( $_taxonomies ) ) {
691
- $attributes['--52'] = esc_html__( 'Product Taxonomies', 'woo-feed' );
692
- $attributes += $_taxonomies;
693
- $attributes['---52'] = '';
694
- }
695
-
696
- $_wp_options = $this->getAllOptions();
697
- if ( ! empty( $_wp_options ) && is_array( $_wp_options ) ) {
698
- $attributes['--53'] = esc_html__( 'WP Options', 'woo-feed' );
699
- $attributes += $_wp_options;
700
- $attributes['---53'] = '';
701
- }
702
-
703
- // Category Mapping
704
- $_category_mappings = $this->getCustomCategoryMappedAttributes();
705
- if ( ! empty( $_category_mappings ) && is_array( $_category_mappings ) ) {
706
- $attributes['--54'] = esc_html__( 'Category Mappings', 'woo-feed' );
707
- $attributes += $_category_mappings;
708
- $attributes['---54'] = '';
709
- }
710
-
711
- // ACF Plugin custom fields
712
- $_acf_fields = woo_feed_get_acf_field_list();
713
- if ( ! empty( $_acf_fields ) && is_array( $_acf_fields ) ) {
714
- $attributes['--98'] = esc_html__( 'Advance Custom Fields (ACF)', 'woo-feed' );
715
- $attributes += $_acf_fields;
716
- $attributes['---98'] = '';
717
- }
718
-
719
- // Custom Fields & Post Metas
720
- $_meta_keys = $this->getProductMetaKeys();
721
- if ( ! empty( $_meta_keys ) && is_array( $_meta_keys ) ) {
722
- $attributes['--55'] = esc_html__( 'Custom Fields & Post Metas', 'woo-feed' );
723
- $attributes += $_meta_keys;
724
- $attributes['---55'] = '';
725
- }
726
-
727
-
728
- return apply_filters('woo_feed_product_attribute_dropdown',$attributes);
729
- }
730
-
731
- /**
732
- * Get Category Mappings
733
- * @return array
734
- */
735
- protected function getCustomCategoryMappedAttributes() {
736
- global $wpdb;
737
- // Load Custom Category Mapped Attributes
738
- $info = array();
739
- // query cached and escaped
740
- $data = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->options WHERE option_name LIKE %s;", Woo_Feed_Products_v3::PRODUCT_CATEGORY_MAPPING_PREFIX . '%' ) ); // phpcs:ignore
741
- if ( count( $data ) ) {
742
- foreach ( $data as $key => $value ) {
743
- $opts = maybe_unserialize( $value->option_value );
744
- $opts = maybe_unserialize( $opts );
745
- $info[ $value->option_name ] = is_array( $opts ) && isset( $opts['mappingname'] ) ? $opts['mappingname'] : str_replace( 'wf_cmapping_',
746
- '',
747
- $value->option_name );
748
- }
749
- }
750
- return (array) $info;
751
- }
752
-
753
- /**
754
- * Local Attribute List to map product value with merchant attributes
755
- *
756
- * @param string $selected
757
- *
758
- * @return string
759
- */
760
- public function product_attributes_dropdown( $selected = '' ) {
761
-
762
- $attributeDropdown = $this->get_cached_dropdown( 'woo_feed_dropdown_product_attributes', $selected );
763
-
764
- if ( false === $attributeDropdown ) {
765
- return $this->cache_dropdown( 'woo_feed_dropdown_product_attributes', $this->get_product_attributes(), $selected, __( 'Select Attributes', 'woo-feed' ) );
766
- }
767
-
768
- return $attributeDropdown;
769
- }
770
-
771
- // Helper functions.
772
-
773
- /**
774
- * Get Cached Dropdown Entries
775
- *
776
- * @param string $key cache key
777
- * @param string $selected selected option
778
- *
779
- * @return string|false
780
- */
781
- protected function get_cached_dropdown( $key, $selected = '' ) {
782
- $options = woo_feed_get_cached_data( $key );
783
- if ( strlen( $selected ) ) {
784
- $selected = esc_attr( $selected );
785
- $options = str_replace( "value=\"{$selected}\"", "value=\"{$selected}\" selected", $options );
786
- }
787
- return empty( $options ) ? false : $options;
788
- }
789
-
790
- /**
791
- * create dropdown options and cache for next use
792
- *
793
- * @param string $cache_key cache key
794
- * @param array $items dropdown items
795
- * @param string $selected selected option
796
- * @param string $default default option
797
- *
798
- * @return string
799
- */
800
- protected function cache_dropdown( $cache_key, $items, $selected = '', $default = '' ) {
801
-
802
- if ( empty( $items ) || ! is_array( $items ) ) {
803
- return '';
804
- }
805
-
806
- if ( ! empty( $default ) ) {
807
- $options = '<option value="" class="disabled" selected>' . esc_html( $default ) . '</option>';
808
- } else {
809
- $options = '<option></option>';
810
- }
811
-
812
- foreach ( $items as $key => $value ) {
813
- if ( substr( $key, 0, 2 ) == '--' ) {
814
- $options .= "<optgroup label=\"{$value}\">";
815
- } elseif ( substr( $key, 0, 2 ) == '---' ) {
816
- $options .= '</optgroup>';
817
- } else {
818
- $options .= sprintf( '<option value="%s">%s</option>', $key, $value );
819
- }
820
- }
821
-
822
- woo_feed_set_cache_data( $cache_key, $options );
823
-
824
- if ( strlen( $selected ) ) {
825
- $selected = esc_attr( $selected );
826
- $options = str_replace( "value=\"{$selected}\"", "value=\"{$selected}\" selected", $options );
827
- }
828
-
829
- return $options;
830
- }
831
-
832
-
833
- /**
834
- * Get WP Option Table Item List
835
- *
836
- * @param string $selected
837
- */
838
- public function woo_feed_get_wp_options( $selected = '' ) {
839
- $options = $this->get_cached_dropdown( 'woo_feed_dropdown_wp_options', $selected );
840
- if ( false === $options ) {
841
- global $wpdb;
842
- $default_exclude_keys = array(
843
- 'db_version',
844
- 'cron',
845
- 'wpfp_option',
846
- 'recovery_keys',
847
- 'wf_schedule',
848
- 'woo_feed_output_type_options',
849
- 'ftp_credentials',
850
- );
851
-
852
- /**
853
- * Exclude Option Names from dropdown
854
- *
855
- * @param array $exclude Option Names to exclude.
856
- * @param array $default_exclude_keys Option Names by default.
857
- */
858
- $user_exclude = apply_filters( 'woo_feed_dropdown_exclude_option_names', null, $default_exclude_keys );
859
-
860
- if ( is_array( $user_exclude ) && ! empty( $user_exclude ) ) {
861
- $user_exclude = esc_sql( $user_exclude );
862
- $default_exclude_keys = array_merge( $default_exclude_keys, $user_exclude );
863
- }
864
-
865
- $default_exclude_keys = array_map( 'esc_sql', $default_exclude_keys );
866
- $exclude_keys = '\'' . implode( '\', \'', $default_exclude_keys ) . '\'';
867
-
868
- $default_exclude_key_patterns = array(
869
- 'mailserver_%',
870
- '_transient%',
871
- '_site_transient%',
872
- 'wf_config%',
873
- 'wf_feed_%',
874
- 'wpfw_%',
875
- 'wf_dattribute_%',
876
- 'wf_cmapping_%',
877
- 'webappick-woo%',
878
- 'widget_%',
879
- );
880
-
881
- /**
882
- * Exclude Option Name patterns from dropdown
883
- *
884
- * @param array $exclude Option Name Patter to exclude.
885
- * @param array $default_exclude_key_patterns Option Name Patters by default.
886
- */
887
- $user_exclude_patterns = apply_filters(
888
- 'woo_feed_dropdown_exclude_option_name_pattern',
889
- null,
890
- $default_exclude_key_patterns
891
- );
892
- if ( is_array( $user_exclude_patterns ) && ! empty( $user_exclude_patterns ) ) {
893
- $default_exclude_key_patterns = array_merge( $default_exclude_key_patterns, $user_exclude_patterns );
894
- }
895
- $exclude_key_patterns = '';
896
- foreach ( $default_exclude_key_patterns as $pattern ) {
897
- $exclude_key_patterns .= $wpdb->prepare( ' AND option_name NOT LIKE %s', $pattern );
898
- }
899
-
900
- /** @noinspection SqlConstantCondition */
901
- $query = "SELECT * FROM $wpdb->options
902
- WHERE 1=1 AND
903
- ( option_name NOT IN ( $exclude_keys ) $exclude_key_patterns )";
904
- // sql escaped, cached
905
- $options = $wpdb->get_results( $query ); // phpcs:ignore
906
- $item = array();
907
- if ( is_array( $options ) && ! empty( $options ) ) {
908
- foreach ( $options as $key => $value ) {
909
- $item[ esc_attr( $value->option_name ) . '-' . esc_attr( $value->option_name ) ] = esc_html( $value->option_name );
910
- }
911
- }
912
- $options = $this->cache_dropdown( 'woo_feed_dropdown_wp_options', $item, $selected );
913
- }
914
- // HTML option element with escaped label and value
915
- echo $options; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
916
- }
917
 
918
  // Merchant Attribute DropDown.
919
 
54
 
55
  return apply_filters('woo_feed_output_types', $output_types);
56
  }
57
+
58
+ /**
59
+ * Get Cached Dropdown Entries
60
+ *
61
+ * @param string $key cache key
62
+ * @param string $selected selected option
63
+ *
64
+ * @return string|false
65
+ */
66
+ protected function get_cached_dropdown( $key, $selected = '' ) {
67
+ $options = woo_feed_get_cached_data( $key );
68
+ if ( strlen( $selected ) ) {
69
+ $selected = esc_attr( $selected );
70
+ $options = str_replace( "value=\"{$selected}\"", "value=\"{$selected}\" selected", $options );
71
+ }
72
+ return empty( $options ) ? false : $options;
73
+ }
74
+
75
+ /**
76
+ * create dropdown options and cache for next use
77
+ *
78
+ * @param string $cache_key cache key
79
+ * @param array $items dropdown items
80
+ * @param string $selected selected option
81
+ * @param string $default default option
82
+ *
83
+ * @return string
84
+ */
85
+ protected function cache_dropdown( $cache_key, $items, $selected = '', $default = '' ) {
86
+
87
+ if ( empty( $items ) || ! is_array( $items ) ) {
88
+ return '';
89
+ }
90
+
91
+ if ( ! empty( $default ) ) {
92
+ $options = '<option value="" class="disabled" selected>' . esc_html( $default ) . '</option>';
93
+ } else {
94
+ $options = '<option></option>';
95
+ }
96
+
97
+ foreach ( $items as $key => $value ) {
98
+ if ( substr( $key, 0, 2 ) == '--' ) {
99
+ $options .= "<optgroup label=\"{$value}\">";
100
+ } elseif ( substr( $key, 0, 2 ) == '---' ) {
101
+ $options .= '</optgroup>';
102
+ } else {
103
+ $options .= sprintf( '<option value="%s">%s</option>', $key, $value );
104
+ }
105
+ }
106
+
107
+ woo_feed_set_cache_data( $cache_key, $options );
108
+
109
+ if ( strlen( $selected ) ) {
110
+ $selected = esc_attr( $selected );
111
+ $options = str_replace( "value=\"{$selected}\"", "value=\"{$selected}\" selected", $options );
112
+ }
113
+
114
+ return $options;
115
+ }
116
 
117
  /**
118
  * Dropdown of Merchant List
291
  return $taxonomy;
292
  }
293
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
294
 
295
  // Merchant Attribute DropDown.
296
 
includes/classes/class-woo-feed-product-attributes.php ADDED
@@ -0,0 +1,818 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * The file that defines the merchants attributes
5
+ *
6
+ * A class definition that includes attributes and functions used across the
7
+ * admin area.
8
+ *
9
+ * @link https://webappick.com/
10
+ * @since 1.0.0
11
+ *
12
+ * @package Woo_Feed
13
+ * @subpackage Woo_Feed/includes
14
+ * @author Ohidul Islam <wahid@webappick.com>
15
+ */
16
+ class Woo_Feed_Product_Attributes {
17
+ /**
18
+ * Hold Product Attributes.
19
+ *
20
+ * @var $attributes
21
+ */
22
+ public $attributes;
23
+
24
+ /**
25
+ * Get Product Attributes
26
+ * @return string
27
+ */
28
+ public function getAttributes( $selected = '' ) {
29
+ $attributeDropdown = $this->get_cached_dropdown( 'woo_feed_product_attribute_dropdown', $selected );
30
+ if ( false === $attributeDropdown ) {
31
+ return $this->cache_dropdown( 'woo_feed_product_attribute_dropdown', $this->setAttributes(), $selected, __( 'Select Attributes', 'woo-feed' ) );
32
+ }
33
+
34
+ return $attributeDropdown;
35
+ }
36
+
37
+ /**
38
+ * Get Cached Dropdown Entries
39
+ *
40
+ * @param string $key cache key
41
+ * @param string $selected selected option
42
+ *
43
+ * @return string|false
44
+ */
45
+ protected function get_cached_dropdown( $key, $selected = '' ) {
46
+ $options = woo_feed_get_cached_data( $key );
47
+ if ( $selected !== '' ) {
48
+ $selected = esc_attr( $selected );
49
+ $options = str_replace( "value=\"{$selected}\"", "value=\"{$selected}\" selected", $options );
50
+ }
51
+
52
+ return empty( $options ) ? false : $options;
53
+ }
54
+
55
+ /**
56
+ * Create dropdown options and cache for next use
57
+ *
58
+ * @param string $cache_key cache key
59
+ * @param array $items dropdown items
60
+ * @param string $selected selected option
61
+ * @param string $default default option
62
+ *
63
+ * @return string
64
+ */
65
+ protected function cache_dropdown( $cache_key, $items, $selected = '', $default = '' ) {
66
+
67
+ if ( empty( $items ) || ! is_array( $items ) ) {
68
+ return '';
69
+ }
70
+
71
+ if ( ! empty( $default ) ) {
72
+ $options = '<option value="" class="disabled" selected>' . esc_html( $default ) . '</option>';
73
+ } else {
74
+ $options = '<option></option>';
75
+ }
76
+
77
+ foreach ( $items as $item ) {
78
+ if ( ! empty( $item['options'] ) ) {
79
+ $options .= "<optgroup label=\"{$item['optionGroup']}\">";
80
+ foreach ( $item['options'] as $option_key => $option ) {
81
+ $options .= sprintf( '<option value="%s">%s</option>', $option_key, $option );
82
+ }
83
+ }
84
+ $options .= '</optgroup>';
85
+ }
86
+
87
+ woo_feed_set_cache_data( $cache_key, $options );
88
+
89
+ if ( $selected !== '' ) {
90
+ $selected = esc_attr( $selected );
91
+ $options = str_replace( "value=\"{$selected}\"", "value=\"{$selected}\" selected", $options );
92
+ }
93
+
94
+ return $options;
95
+ }
96
+
97
+ protected function setAttributes() {
98
+ $attributes = [];
99
+ $primaryAttributes = [
100
+ 'optionGroup' => esc_html__( 'Primary Attributes', 'woo-feed' ),
101
+ 'options' => [
102
+ 'id' => esc_html__( 'Product Id', 'woo-feed' ),
103
+ 'title' => esc_html__( 'Product Title', 'woo-feed' ),
104
+ 'parent_title' => esc_html__( 'Parent Title', 'woo-feed' ),
105
+ 'description' => esc_html__( 'Product Description', 'woo-feed' ),
106
+ 'description_with_html' => esc_html__( 'Product Description (with HTML)', 'woo-feed' ),
107
+ 'short_description' => esc_html__( 'Product Short Description', 'woo-feed' ),
108
+ 'primary_category' => esc_html__( 'Parent Category', 'woo-feed' ),
109
+ 'primary_category_id' => esc_html__( 'Parent Category ID', 'woo-feed' ),
110
+ 'child_category' => esc_html__( 'Child Category', 'woo-feed' ),
111
+ 'child_category_id' => esc_html__( 'Child Category ID', 'woo-feed' ),
112
+ 'product_type' => esc_html__( 'Product Category [Category Path]', 'woo-feed' ),
113
+ 'product_full_cat' => esc_html__( 'Product Full Category [Category Full Path]', 'woo-feed' ),
114
+ 'link' => esc_html__( 'Product URL', 'woo-feed' ),
115
+ 'parent_link' => esc_html__( 'Parent URL', 'woo-feed' ),
116
+ 'canonical_link' => esc_html__( 'Canonical URL', 'woo-feed' ),
117
+ 'ex_link' => esc_html__( 'External Product URL', 'woo-feed' ),
118
+ 'add_to_cart_link' => esc_html__( 'Add to Cart URL', 'woo-feed' ),
119
+ 'item_group_id' => esc_html__( 'Parent Id [Group Id]', 'woo-feed' ),
120
+ 'sku' => esc_html__( 'SKU', 'woo-feed' ),
121
+ 'sku_id' => esc_html__( 'SKU_ID', 'woo-feed' ),
122
+ 'parent_sku' => esc_html__( 'Parent SKU', 'woo-feed' ),
123
+ 'availability' => esc_html__( 'Availability', 'woo-feed' ),
124
+ 'availability_date' => esc_html__( 'Availability Date', 'woo-feed' ),
125
+ 'quantity' => esc_html__( 'Quantity', 'woo-feed' ),
126
+ 'reviewer_name' => esc_html__( 'Reviewer Name', 'woo-feed' ),
127
+ 'weight' => esc_html__( 'Weight', 'woo-feed' ),
128
+ 'weight_unit' => esc_html__( 'Weight Unit', 'woo-feed' ),
129
+ 'width' => esc_html__( 'Width', 'woo-feed' ),
130
+ 'height' => esc_html__( 'Height', 'woo-feed' ),
131
+ 'length' => esc_html__( 'Length', 'woo-feed' ),
132
+ 'type' => esc_html__( 'Product Type', 'woo-feed' ),
133
+ 'visibility' => esc_html__( 'Visibility', 'woo-feed' ),
134
+ 'rating_total' => esc_html__( 'Total Rating', 'woo-feed' ),
135
+ 'rating_average' => esc_html__( 'Average Rating', 'woo-feed' ),
136
+ 'tags' => esc_html__( 'Tags', 'woo-feed' ),
137
+ 'is_bundle' => esc_html__( 'Is Bundle', 'woo-feed' ),
138
+ 'author_name' => esc_html__( 'Author Name', 'woo-feed' ),
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
+
145
+ $attributes [] = $primaryAttributes;
146
+
147
+
148
+ $imageAttributes = [
149
+ 'optionGroup' => esc_html__( 'Images', 'woo-feed' ),
150
+ 'options' => [
151
+ 'image' => esc_html__( 'Main Image', 'woo-feed' ),
152
+ 'feature_image' => esc_html__( 'Featured Image', 'woo-feed' ),
153
+ 'images' => esc_html__( 'Images [Comma Separated]', 'woo-feed' ),
154
+ 'image_1' => esc_html__( 'Additional Image 1', 'woo-feed' ),
155
+ 'image_2' => esc_html__( 'Additional Image 2', 'woo-feed' ),
156
+ 'image_3' => esc_html__( 'Additional Image 3', 'woo-feed' ),
157
+ 'image_4' => esc_html__( 'Additional Image 4', 'woo-feed' ),
158
+ 'image_5' => esc_html__( 'Additional Image 5', 'woo-feed' ),
159
+ 'image_6' => esc_html__( 'Additional Image 6', 'woo-feed' ),
160
+ 'image_7' => esc_html__( 'Additional Image 7', 'woo-feed' ),
161
+ 'image_8' => esc_html__( 'Additional Image 8', 'woo-feed' ),
162
+ 'image_9' => esc_html__( 'Additional Image 9', 'woo-feed' ),
163
+ 'image_10' => esc_html__( 'Additional Image 10', 'woo-feed' ),
164
+ ],
165
+ ];
166
+
167
+ $attributes [] = $imageAttributes;
168
+
169
+ $priceAttributes = [
170
+ 'optionGroup' => esc_html__( 'Price', 'woo-feed' ),
171
+ 'options' => [
172
+ 'currency' => esc_html__( 'Currency', 'woo-feed' ),
173
+ 'price' => esc_html__( 'Regular Price', 'woo-feed' ),
174
+ 'current_price' => esc_html__( 'Price', 'woo-feed' ),
175
+ 'sale_price' => esc_html__( 'Sale Price', 'woo-feed' ),
176
+ 'price_with_tax' => esc_html__( 'Regular Price With Tax', 'woo-feed' ),
177
+ 'current_price_with_tax' => esc_html__( 'Price With Tax', 'woo-feed' ),
178
+ 'sale_price_with_tax' => esc_html__( 'Sale Price With Tax', 'woo-feed' ),
179
+ 'sale_price_sdate' => esc_html__( 'Sale Start Date', 'woo-feed' ),
180
+ 'sale_price_edate' => esc_html__( 'Sale End Date', 'woo-feed' ),
181
+ 'sale_price_effective_date' => esc_html__( 'Sale Price Effective Date', 'woo-feed' ),
182
+ ],
183
+ ];
184
+
185
+ $attributes [] = $priceAttributes;
186
+
187
+ $shippingAttributes = [
188
+ 'optionGroup' => esc_html__( 'Shipping', 'woo-feed' ),
189
+ 'options' => [
190
+ 'shipping' => esc_html__( 'Shipping (Google Format)', 'woo-feed' ),
191
+ 'shipping_class' => esc_html__( 'Shipping Class', 'woo-feed' ),
192
+ 'shipping_zone_name' => esc_html__( 'Shipping Zone Name', 'woo-feed' ),
193
+ 'shipping_country' => esc_html__( 'Shipping Country', 'woo-feed' ),
194
+ 'shipping_region' => esc_html__( 'Shipping Regions', 'woo-feed' ),
195
+ 'shipping_postcode' => esc_html__( 'Shipping Postcodes', 'woo-feed' ),
196
+ 'shipping_service' => esc_html__( 'Shipping Method Name', 'woo-feed' ),
197
+ 'shipping_price' => esc_html__( 'Shipping Cost', 'woo-feed' ),
198
+ ],
199
+ ];
200
+
201
+ $attributes [] = $shippingAttributes;
202
+
203
+ $taxAttributes = [
204
+ 'optionGroup' => esc_html__( 'Tax', 'woo-feed' ),
205
+ 'options' => [
206
+ 'tax' => esc_html__( 'Tax (Google Format)', 'woo-feed' ),
207
+ 'tax_class' => esc_html__( 'Tax Class', 'woo-feed' ),
208
+ 'tax_status' => esc_html__( 'Tax Status', 'woo-feed' ),
209
+ 'tax_country' => esc_html__( 'Tax Country', 'woo-feed' ),
210
+ 'tax_state' => esc_html__( 'Tax State', 'woo-feed' ),
211
+ 'tax_postcode' => esc_html__( 'Tax Postcodes', 'woo-feed' ),
212
+ 'tax_city' => esc_html__( 'Tax City', 'woo-feed' ),
213
+ 'tax_rate' => esc_html__( 'Tax Rate', 'woo-feed' ),
214
+ 'tax_label' => esc_html__( 'Tax Name', 'woo-feed' ),
215
+ ],
216
+ ];
217
+
218
+ $attributes [] = $taxAttributes;
219
+
220
+ $subscriptionAttributes = [
221
+ 'optionGroup' => esc_html__( 'Subscription & Installment', 'woo-feed' ),
222
+ 'options' => [
223
+ 'subscription_period' => esc_html__( 'Subscription Period', 'woo-feed' ),
224
+ 'subscription_period_interval' => esc_html__( 'Subscription Period Length', 'woo-feed' ),
225
+ 'subscription_amount' => esc_html__( 'Subscription Amount', 'woo-feed' ),
226
+ 'installment_months' => esc_html__( 'Installment Months', 'woo-feed' ),
227
+ 'installment_amount' => esc_html__( 'Installment Amount', 'woo-feed' ),
228
+ ],
229
+ ];
230
+
231
+ $customXMLAttributes = [
232
+ 'optionGroup' => esc_html__( 'Custom Template 2 (XML)', 'woo-feed' ),
233
+ 'options' => [
234
+ 'custom_xml_variations' => esc_html__( 'Product Variations', 'woo-feed' ),
235
+ 'custom_xml_images' => esc_html__( 'Product Gallery Images', 'woo-feed' ),
236
+ 'custom_xml_categories' => esc_html__( 'Product Categories', 'woo-feed' ),
237
+ ]
238
+ ];
239
+
240
+ /**
241
+ * Add subscription attributes if WooCommerce Subscription plugin installed.
242
+ * @link https://woocommerce.com/products/woocommerce-subscriptions/
243
+ */
244
+ if ( class_exists( 'WC_Subscriptions' ) ) {
245
+ $attributes[] = $subscriptionAttributes;
246
+ }
247
+
248
+ $attributes[] = $this->getPluginsCustomFields();
249
+ $attributes[] = $this->getUnitPriceAttributes();
250
+ $attributes[] = $this->getSeoPluginAttributes();
251
+ $attributes[] = $this->getGlobalAttributes();
252
+ $attributes[] = $this->getCustomAttributes();
253
+ $attributes[] = $this->getAllTaxonomy();
254
+ $attributes[] = $this->getAllOptions();
255
+ // Category Mapping
256
+ $attributes[] = $this->getCategoryMappedAttributes();
257
+ // ACF Plugin custom fields getACFAttributes
258
+ $attributes[] = $this->getACFAttributes();
259
+ // Custom Fields & Post Metas
260
+ $attributes[] = $this->getProductMetaKeyAttributes();
261
+
262
+ if(class_exists('Woo_Feed_Products_v3_Pro')){
263
+ $attributes [] = $this->getMultiLanguageAttributes();
264
+ $attributes [] = $this->getMultiVendorAttributes();
265
+ // Dynamic Attributes
266
+ $attributes[] = $this->getDynamicAttributes();
267
+ // Attribute Mappings
268
+ $attributes[] = $this->getCustomMappedAttributes();
269
+ // Custom Template 2 Attributes
270
+ $attributes [] = $customXMLAttributes;
271
+ }
272
+
273
+ return apply_filters( 'woo_feed_product_attribute_dropdown', $attributes );
274
+ }
275
+
276
+ /**
277
+ * Get CTX Feed plugins Custom Fields.
278
+ *
279
+ * @return array
280
+ */
281
+ protected function getPluginsCustomFields() {
282
+
283
+ $custom_fields = woo_feed_product_custom_fields();
284
+ $custom_identifier_filter = new Woo_Feed_Custom_Identifier_Filter( $custom_fields );
285
+ $custom_identifier = iterator_to_array( $custom_identifier_filter );
286
+ $activeAttributes = [ 'optionGroup' => esc_html__( 'Custom Fields by CTX Feed', 'woo-feed' ), ];
287
+ if ( ! empty( $custom_identifier ) ) {
288
+ foreach ( $custom_identifier as $key => $value ) {
289
+ $activeAttributes['options'][ 'woo_feed_identifier_' . sanitize_text_field( wp_unslash( $key ) ) ] = sanitize_text_field( $value[0] );
290
+ }
291
+ }
292
+
293
+ return ! empty( $activeAttributes['options'] ) ? $activeAttributes : [];
294
+ }
295
+
296
+ /**
297
+ * Get Unit Price Attributes.
298
+ *
299
+ * @return array
300
+ */
301
+ protected function getUnitPriceAttributes() {
302
+
303
+ $unitPriceAttributes = [
304
+ 'optionGroup' => esc_html__( 'Unit Price (CTX Feed)', 'woo-feed' ),
305
+ 'options' => [
306
+ 'unit_price_unit' => esc_html__( 'Unit', 'woo-feed' ),
307
+ 'unit_price_measure' => esc_html__( 'Unit Price Measure', 'woo-feed' ),
308
+ 'unit_price_base_measure' => esc_html__( 'Unit Price Base Measure', 'woo-feed' ),
309
+ ],
310
+ ];
311
+
312
+ /**
313
+ * Get Germanized for WooCommerce plugins unit attributes.
314
+ * @link https://wordpress.org/plugins/woocommerce-germanized/
315
+ */
316
+ if ( class_exists( 'WooCommerce_Germanized' ) ) {
317
+ $wcUnitPriceAttributes = [
318
+ 'optionGroup' => esc_html__( 'Unit Price (WooCommerce Germanized)', 'woo-feed' ),
319
+ 'options' => [
320
+ 'wc_germanized_unit_price_measure' => esc_html__( 'Unit Price Measure', 'woo-feed' ),
321
+ 'wc_germanized_unit_price_base_measure' => esc_html__( 'Unit Price Base Measure', 'woo-feed' ),
322
+ 'wc_germanized_gtin' => esc_html__( 'GTIN', 'woo-feed' ),
323
+ 'wc_germanized_mpn' => esc_html__( 'MPN', 'woo-feed' ),
324
+ ],
325
+ ];
326
+ $unitPriceAttributes += $wcUnitPriceAttributes;
327
+ }
328
+
329
+ return $unitPriceAttributes;
330
+ }
331
+
332
+ /**
333
+ * Get installed SEO plugin attributes.
334
+ *
335
+ * @return array
336
+ */
337
+ protected function getSeoPluginAttributes() {
338
+
339
+ $seoAttributes = [];
340
+ /**
341
+ * Get Yoast SEO Plugin Attributes.
342
+ * @link https://wordpress.org/plugins/wordpress-seo/
343
+ */
344
+ if ( class_exists( 'WPSEO_Frontend' ) || class_exists( 'WPSEO_Premium' ) ) {
345
+
346
+ $seoAttributes = [
347
+ 'optionGroup' => esc_html__( 'Yoast SEO', 'woo-feed' ),
348
+ 'options' => [
349
+ 'yoast_wpseo_title' => esc_html__( 'Title [Yoast SEO]', 'woo-feed' ),
350
+ 'yoast_wpseo_metadesc' => esc_html__( 'Description [Yoast SEO]', 'woo-feed' ),
351
+ 'yoast_canonical_url' => esc_html__( 'Canonical URL [Yoast SEO]', 'woo-feed' ),
352
+ ],
353
+ ];
354
+
355
+ /**
356
+ * Get Yoast WooCommerce SEO plugins Identifier Attributes.
357
+ * @link https://yoast.com/wordpress/plugins/yoast-woocommerce-seo/
358
+ */
359
+ if ( class_exists( 'Yoast_WooCommerce_SEO' ) ) {
360
+ $seoAttributes['options'] += [
361
+ 'yoast_gtin8' => esc_html__( 'GTIN8 [Yoast SEO]', 'woo-feed' ),
362
+ 'yoast_gtin12' => esc_html__( 'GTIN12 / UPC [Yoast SEO]', 'woo-feed' ),
363
+ 'yoast_gtin13' => esc_html__( 'GTIN13 / EAN [Yoast SEO]', 'woo-feed' ),
364
+ 'yoast_gtin14' => esc_html__( 'GTIN14 / ITF-14 [Yoast SEO]', 'woo-feed' ),
365
+ 'yoast_isbn' => esc_html__( 'ISBN [Yoast SEO]', 'woo-feed' ),
366
+ 'yoast_mpn' => esc_html__( 'MPN [Yoast SEO]', 'woo-feed' ),
367
+ ];
368
+ }
369
+ }
370
+
371
+ if ( class_exists( 'RankMath' ) || class_exists( 'RankMathPro' ) ) {
372
+ $seoAttributes = [
373
+ 'optionGroup' => esc_html__( 'RANK MATH SEO', 'woo-feed' ),
374
+ 'options' => [
375
+ 'rank_math_title' => esc_html__( 'Title [RankMath SEO]', 'woo-feed' ),
376
+ 'rank_math_description' => esc_html__( 'Description [RankMath SEO]', 'woo-feed' ),
377
+ 'rank_math_canonical_url' => esc_html__( 'Canonical URL [RankMath SEO]', 'woo-feed' )
378
+ ],
379
+ ];
380
+
381
+ if ( class_exists( 'RankMathPro' ) ) {
382
+ $seoAttributes['options'] += [ 'rank_math_gtin' => esc_html__( 'GTIN [RankMath Pro SEO]', 'woo-feed' ) ];
383
+ }
384
+ }
385
+
386
+ if ( class_exists( 'AIOSEO\Plugin\AIOSEO' ) ) {
387
+ $seoAttributes = [
388
+ 'optionGroup' => esc_html__( 'ALL IN ONE SEO', 'woo-feed' ),
389
+ 'options' => [
390
+ '_aioseop_title' => esc_html__( 'Title [All in One SEO]', 'woo-feed' ),
391
+ '_aioseop_description' => esc_html__( 'Description [All in One SEO]', 'woo-feed' ),
392
+ '_aioseop_canonical_url' => esc_html__( 'Canonical URL [All in One SEO]', 'woo-feed' ),
393
+ ],
394
+ ];
395
+ }
396
+
397
+ return $seoAttributes;
398
+ }
399
+
400
+ /**
401
+ * Get Product Global Attributes.
402
+ * @retun array
403
+ */
404
+ protected function getGlobalAttributes() {
405
+ $taxonomies = woo_feed_get_cached_data( 'getAttributeTaxonomies' );
406
+ if ( false === $taxonomies ) {
407
+ // Load the main attributes
408
+ $globalAttributes = wc_get_attribute_taxonomy_labels();
409
+ if ( count( $globalAttributes ) ) {
410
+ foreach ( $globalAttributes as $key => $value ) {
411
+ $taxonomies[ Woo_Feed_Products_v3::PRODUCT_ATTRIBUTE_PREFIX . 'pa_' . $key ] = $value;
412
+ }
413
+ }
414
+ woo_feed_set_cache_data( 'getAttributeTaxonomies', $taxonomies );
415
+ }
416
+
417
+ return [
418
+ 'optionGroup' => esc_html__( 'Product Attributes', 'woo-feed' ),
419
+ 'options' => $taxonomies,
420
+ ];
421
+ }
422
+
423
+ /**
424
+ * Get Product Custom Attributes.
425
+ * @retun array
426
+ */
427
+ protected function getCustomAttributes() {
428
+ $attributes = woo_feed_get_cached_data( 'woo_feed_dropdown_product_custom_attributes' );
429
+ if ( false === $attributes ) {
430
+ // Get Variation Attributes
431
+ $attributes = $this->queryVariationsAttributes();
432
+ // Get Product Custom Attributes
433
+ $attributes += $this->queryCustomAttributes();
434
+
435
+ woo_feed_set_cache_data( 'woo_feed_dropdown_product_custom_attributes', $attributes );
436
+ }
437
+
438
+ return [
439
+ 'optionGroup' => esc_html__( 'Product Custom Attributes', 'woo-feed' ),
440
+ 'options' => $attributes,
441
+ ];
442
+ }
443
+
444
+ /**
445
+ * Get Variation Attributes
446
+ * Local attributes will be found on variation product meta only with attribute_ suffix
447
+ */
448
+ protected function queryVariationsAttributes() {
449
+ // Get Variation Attributes
450
+ global $wpdb;
451
+ $attributes = array();
452
+ $sql = "SELECT DISTINCT( meta_key ) FROM $wpdb->postmeta
453
+ WHERE post_id IN (
454
+ SELECT ID FROM $wpdb->posts WHERE post_type = 'product_variation' -- local attributes will be found on variation product meta only with attribute_ suffix
455
+ ) AND (
456
+ meta_key LIKE 'attribute_%' -- include only product attributes from meta list
457
+ AND meta_key NOT LIKE 'attribute_pa_%'
458
+ )";
459
+ // sanitization ok
460
+ $localAttributes = $wpdb->get_col( $sql ); // phpcs:ignore
461
+ foreach ( $localAttributes as $localAttribute ) {
462
+ $localAttribute = str_replace( 'attribute_', '', $localAttribute );
463
+ $attributes[ Woo_Feed_Products_v3::PRODUCT_ATTRIBUTE_PREFIX . $localAttribute ] = ucwords( str_replace( '-', ' ', $localAttribute ) );
464
+ }
465
+
466
+ return $attributes;
467
+ }
468
+
469
+ /**
470
+ * Get Product Custom Attributes
471
+ */
472
+ protected function queryCustomAttributes() {
473
+ global $wpdb;
474
+ $attributes = array();
475
+ $sql = 'SELECT meta.meta_id, meta.meta_key as name, meta.meta_value as type FROM ' . $wpdb->postmeta . ' AS meta, ' . $wpdb->posts . " AS posts WHERE meta.post_id = posts.id AND posts.post_type LIKE '%product%' AND meta.meta_key='_product_attributes';";
476
+ $customAttributes = $wpdb->get_results( $sql ); // phpcs:ignore
477
+ if ( ! empty( $customAttributes ) ) {
478
+ foreach ( $customAttributes as $value ) {
479
+ $product_attr = maybe_unserialize( $value->type );
480
+ if ( is_array( $product_attr ) ) {
481
+ foreach ( $product_attr as $key => $arr_value ) {
482
+ if ( strpos( $key, 'pa_' ) === false ) {
483
+ $attributes[ Woo_Feed_Products_v3::PRODUCT_ATTRIBUTE_PREFIX . $key ] = ucwords( str_replace( '-', ' ', $arr_value['name'] ) );
484
+ }
485
+ }
486
+ }
487
+ }
488
+ }
489
+
490
+ return $attributes;
491
+ }
492
+
493
+ /**
494
+ * Get All Taxonomy
495
+ *
496
+ * @return array
497
+ */
498
+ protected function getAllTaxonomy() {
499
+ $info = woo_feed_get_cached_data( 'woo_feed_dropdown_product_taxonomy' );
500
+ if ( false === $info ) {
501
+ $info = array();
502
+ global $wp_taxonomies;
503
+ $default_excludes = array(
504
+ 'product_type',
505
+ 'product_visibility',
506
+ 'product_cat',
507
+ 'product_tag',
508
+ 'product_shipping_class',
509
+ 'translation_priority',
510
+ );
511
+
512
+ /**
513
+ * Exclude Taxonomy from dropdown
514
+ *
515
+ * @param array $user_excludes
516
+ * @param array $default_excludes
517
+ */
518
+
519
+ $user_excludes = apply_filters( 'woo_feed_dropdown_exclude_taxonomy', null, $default_excludes );
520
+ $default_excludes = ! empty( $user_excludes ) ? array_merge( $default_excludes, $user_excludes ) : $default_excludes;
521
+
522
+ foreach ( get_object_taxonomies( 'product' ) as $value ) {
523
+ $value = ! empty( $value ) ? trim( $value ) : $value;
524
+ if ( in_array( $value, $default_excludes, true ) || strpos( $value, 'pa_' ) !== false ) {
525
+ continue;
526
+ }
527
+ $label = isset( $wp_taxonomies[ $value ] ) ? $wp_taxonomies[ $value ]->label . " [$value]" : $value;
528
+ $info[ Woo_Feed_Products_v3::PRODUCT_TAXONOMY_PREFIX . $value ] = $label;
529
+ }
530
+
531
+ woo_feed_set_cache_data( 'woo_feed_dropdown_product_taxonomy', $info );
532
+ }
533
+
534
+ return [
535
+ 'optionGroup' => esc_html__( 'Product Taxonomies', 'woo-feed' ),
536
+ 'options' => $info,
537
+ ];
538
+ }
539
+
540
+ /**
541
+ * Get All Options
542
+ *
543
+ * @return array
544
+ */
545
+ protected function getAllOptions() {
546
+ $_wp_options = wp_list_pluck( get_option( 'wpfp_option', array() ), 'option_name' );
547
+ $_wp_options_val = str_replace( 'wf_option_', '', $_wp_options );
548
+ $_wp_options = array_combine( $_wp_options, $_wp_options_val );
549
+
550
+ return [
551
+ 'optionGroup' => esc_html__( 'Options', 'woo-feed' ),
552
+ 'options' => $_wp_options,
553
+ ];
554
+ }
555
+
556
+ /**
557
+ * Get Category Mappings
558
+ * @return array
559
+ */
560
+ protected function getCategoryMappedAttributes() {
561
+ global $wpdb;
562
+ // Load Custom Category Mapped Attributes
563
+ $info = array();
564
+ // query cached and escaped
565
+ $data = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->options WHERE option_name LIKE %s;", Woo_Feed_Products_v3::PRODUCT_CATEGORY_MAPPING_PREFIX . '%' ) ); // phpcs:ignore
566
+ if ( count( $data ) ) {
567
+ foreach ( $data as $value ) {
568
+ $opts = maybe_unserialize( $value->option_value );
569
+ $opts = maybe_unserialize( $opts );
570
+ $info[ $value->option_name ] = is_array( $opts ) && isset( $opts['mappingname'] ) ? $opts['mappingname'] : str_replace( 'wf_cmapping_',
571
+ '',
572
+ $value->option_name );
573
+ }
574
+ }
575
+
576
+ return [
577
+ 'optionGroup' => esc_html__( 'Category Mapping', 'woo-feed' ),
578
+ 'options' => $info,
579
+ ];
580
+ }
581
+
582
+ /**
583
+ * Get Advance Custom Field (ACF) field list
584
+ *
585
+ *
586
+ * @return Array
587
+ */
588
+ protected function getACFAttributes() {
589
+ $options = [];
590
+ if ( class_exists( 'ACF' ) ) {
591
+ $acf_fields = woo_feed_get_cached_data( 'acf_field_list' );
592
+ if ( false === $acf_fields && function_exists( 'acf_get_field_groups' ) ) {
593
+ $field_groups = acf_get_field_groups();
594
+ foreach ( $field_groups as $group ) {
595
+ // DO NOT USE here: $fields = acf_get_fields($group['key']);
596
+ // because it causes repeater field bugs and returns "trashed" fields
597
+ $fields = get_posts( array(
598
+ 'posts_per_page' => - 1,
599
+ 'post_type' => 'acf-field',
600
+ 'orderby' => 'menu_order',
601
+ 'order' => 'ASC',
602
+ 'suppress_filters' => true, // DO NOT allow WPML to modify the query
603
+ 'post_parent' => $group['ID'],
604
+ 'post_status' => 'any',
605
+ 'update_post_meta_cache' => false,
606
+ ) );
607
+ foreach ( $fields as $field ) {
608
+ $options[ 'acf_fields_' . $field->post_name ] = $field->post_title;
609
+ }
610
+ }
611
+
612
+ woo_feed_set_cache_data( 'acf_field_list', $options );
613
+ }
614
+ }
615
+
616
+ return [
617
+ 'optionGroup' => esc_html__( 'Advance Custom Fields (ACF)', 'woo-feed' ),
618
+ 'options' => $options,
619
+ ];
620
+ }
621
+
622
+ /**
623
+ * Get All Custom Attributes
624
+ *
625
+ * @return array
626
+ */
627
+ protected function getProductMetaKeyAttributes() {
628
+ $info = woo_feed_get_cached_data( 'woo_feed_dropdown_meta_keys' );
629
+ if ( false === $info ) {
630
+ global $wpdb;
631
+ $info = [];
632
+ // Load the main attributes.
633
+
634
+ $default_exclude_keys = [
635
+ // WP internals.
636
+ '_edit_lock',
637
+ '_wp_old_slug',
638
+ '_edit_last',
639
+ '_wp_old_date',
640
+ // WC internals.
641
+ '_downloadable_files',
642
+ '_sku',
643
+ '_weight',
644
+ '_width',
645
+ '_height',
646
+ '_length',
647
+ '_file_path',
648
+ '_file_paths',
649
+ '_default_attributes',
650
+ '_product_attributes',
651
+ '_children',
652
+ '_variation_description',
653
+ // ignore variation description, engine will get child product description from WC CRUD WC_Product::get_description().
654
+ // Plugin Data.
655
+ '_wpcom_is_markdown',
656
+ // JetPack Meta.
657
+ '_yith_wcpb_bundle_data',
658
+ // Yith product bundle data.
659
+ '_et_builder_version',
660
+ // Divi builder data.
661
+ '_vc_post_settings',
662
+ // Visual Composer (WP Bakery) data.
663
+ '_enable_sidebar',
664
+ 'frs_woo_product_tabs',
665
+ // WooCommerce Custom Product Tabs http://www.skyverge.com/.
666
+ ];
667
+
668
+ /**
669
+ * Exclude meta keys from dropdown
670
+ *
671
+ * @param array $exclude meta keys to exclude.
672
+ * @param array $default_exclude_keys Exclude keys by default.
673
+ */
674
+ $user_exclude = apply_filters( 'woo_feed_dropdown_exclude_meta_keys', null, $default_exclude_keys );
675
+
676
+ if ( is_array( $user_exclude ) && ! empty( $user_exclude ) ) {
677
+ $user_exclude = esc_sql( $user_exclude );
678
+ $default_exclude_keys = array_merge( $default_exclude_keys, $user_exclude );
679
+ }
680
+
681
+ $default_exclude_keys = array_map( 'esc_sql', $default_exclude_keys );
682
+ $exclude_keys = '\'' . implode( '\', \'', $default_exclude_keys ) . '\'';
683
+
684
+ $default_exclude_key_patterns = [
685
+ '%_et_pb_%', // Divi builder data
686
+ 'attribute_%', // Exclude product attributes from meta list
687
+ '_yoast_wpseo_%', // Yoast SEO Data
688
+ '_acf-%', // ACF duplicate fields
689
+ '_aioseop_%', // All In One SEO Pack Data
690
+ '_oembed%', // exclude oEmbed cache meta
691
+ '_wpml_%', // wpml metas
692
+ '_oh_add_script_%', // SOGO Add Script to Individual Pages Header Footer.
693
+ ];
694
+
695
+ /**
696
+ * Exclude meta key patterns from dropdown
697
+ *
698
+ * @param array $exclude meta keys to exclude.
699
+ * @param array $default_exclude_key_patterns Exclude keys by default.
700
+ */
701
+ $user_exclude_patterns = apply_filters( 'woo_feed_dropdown_exclude_meta_keys_pattern', null, $default_exclude_key_patterns );
702
+ if ( is_array( $user_exclude_patterns ) && ! empty( $user_exclude_patterns ) ) {
703
+ $default_exclude_key_patterns = array_merge( $default_exclude_key_patterns, $user_exclude_patterns );
704
+ }
705
+ $exclude_key_patterns = '';
706
+ foreach ( $default_exclude_key_patterns as $pattern ) {
707
+ $exclude_key_patterns .= $wpdb->prepare( ' AND meta_key NOT LIKE %s', $pattern );
708
+ }
709
+
710
+ $sql = "SELECT DISTINCT( meta_key ) FROM $wpdb->postmeta WHERE 1=1 AND post_id IN ( SELECT ID FROM $wpdb->posts WHERE post_type = 'product' OR post_type = 'product_variation' ) AND ( meta_key NOT IN ( $exclude_keys ) $exclude_key_patterns )";
711
+
712
+ // sql escaped, cached
713
+ $data = $wpdb->get_results( $sql ); // phpcs:ignore
714
+
715
+ if ( count( $data ) ) {
716
+ foreach ( $data as $value ) {
717
+ //TODO Remove ACF Fields
718
+ $info[ Woo_Feed_Products_v3::POST_META_PREFIX . $value->meta_key ] = $value->meta_key;
719
+ }
720
+ }
721
+ woo_feed_set_cache_data( 'woo_feed_dropdown_meta_keys', $info );
722
+ }
723
+
724
+ return [
725
+ 'optionGroup' => esc_html__( 'Custom Fields & Post Metas', 'woo-feed' ),
726
+ 'options' => $info,
727
+ ];
728
+ }
729
+
730
+ /**
731
+ * Get Dynamic Attribute List
732
+ *
733
+ * @return array
734
+ */
735
+ protected function getDynamicAttributes() {
736
+ global $wpdb;
737
+
738
+ // Load Custom Category Mapped Attributes
739
+ $info = array();
740
+ // query escaped and cached
741
+ $data = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->options WHERE option_name LIKE %s;", Woo_Feed_Products_v3_Pro::PRODUCT_DYNAMIC_ATTRIBUTE_PREFIX . '%' ) ); // phpcs:ignore
742
+ if ( count( $data ) ) {
743
+ foreach ( $data as $key => $value ) {
744
+ $opts = maybe_unserialize( $value->option_value );
745
+ $opts = maybe_unserialize( $opts );
746
+ $info[ $value->option_name ] = is_array( $opts ) && isset( $opts['wfDAttributeName'] ) ? $opts['wfDAttributeName'] : str_replace(
747
+ 'wf_dattribute_',
748
+ '',
749
+ $value->option_name
750
+ );
751
+ }
752
+ }
753
+
754
+ return [
755
+ 'optionGroup' => esc_html__( 'Dynamic Attributes', 'woo-feed' ),
756
+ 'options' => $info,
757
+ ];
758
+ }
759
+
760
+ /**
761
+ * Get Attribute Mappings
762
+ *
763
+ * @return array
764
+ */
765
+ protected function getCustomMappedAttributes() {
766
+ global $wpdb;
767
+ // Load Custom Category Mapped Attributes
768
+ $info = [];
769
+ // query cached and escaped
770
+ $data = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->options WHERE option_name LIKE %s;", Woo_Feed_Products_v3_Pro::PRODUCT_ATTRIBUTE_MAPPING_PREFIX . '%' ) ); // phpcs:ignore
771
+ if ( count( $data ) ) {
772
+ foreach ( $data as $value ) {
773
+ $opts = maybe_unserialize( $value->option_value );
774
+ $info[ $value->option_name ] = is_array( $opts ) && isset( $opts['name'] ) ? $opts['name'] : str_replace( Woo_Feed_Products_v3_Pro::PRODUCT_ATTRIBUTE_MAPPING_PREFIX, '', $value->option_name );
775
+ }
776
+ }
777
+
778
+ return [
779
+ 'optionGroup' => esc_html__( 'Attribute Mappings', 'woo-feed' ),
780
+ 'options' => $info,
781
+ ];
782
+ }
783
+
784
+ /**
785
+ * @return array
786
+ */
787
+ protected function getMultiLanguageAttributes() {
788
+ $attributes = [];
789
+ if ( class_exists( 'SitePress' ) ) {
790
+ $attributes = [
791
+ 'optionGroup' => esc_html__( 'WPML Attributes', 'woo-feed' ),
792
+ 'options' => [
793
+ 'parent_id' => esc_html__( 'Parent Product ID', 'woo-feed' )
794
+ ]
795
+ ];
796
+ }
797
+
798
+ return $attributes;
799
+ }
800
+
801
+ /**
802
+ * @return array
803
+ */
804
+ protected function getMultiVendorAttributes() {
805
+ $attributes = [];
806
+ if ( function_exists('woo_feed_is_multi_vendor') && woo_feed_is_multi_vendor() ) {
807
+ $attributes = [
808
+ 'optionGroup' => esc_html__( 'Multi Vendor Attributes', 'woo-feed' ),
809
+ 'options' => [
810
+ 'vendor_store_name' => esc_html__( 'Vendor Store Name', 'woo-feed' )
811
+ ]
812
+ ];
813
+ }
814
+
815
+ return $attributes;
816
+ }
817
+ }
818
+
includes/classes/class-woo-feed-products-v3.php CHANGED
@@ -9,312 +9,311 @@
9
 
10
  use RankMath\Helper;
11
 
12
- if (!defined('ABSPATH')) {
13
- die();
14
  }
15
 
16
  /**
17
  * Class Woo_Feed_Products_v3
18
  */
19
- class Woo_Feed_Products_v3
20
- {
21
- /**
22
- * The Increment
23
- * @var int
24
- */
25
- protected $pi = 0;
26
- /**
27
- * Feed file headers
28
- *
29
- * @var string|array
30
- */
31
- public $feedHeader;
32
- /**
33
- * Feed File Body
34
- *
35
- * @var string|array
36
- */
37
- public $feedBody;
38
- /**
39
- * Feed file footer
40
- *
41
- * @var string|array
42
- */
43
- public $feedFooter;
44
- /**
45
- * CSV|TXT column (text|word) enclosure
46
- *
47
- * @var string
48
- */
49
- protected $enclosure;
50
- /**
51
- * CSV|TXT column delimiter
52
- *
53
- * @var string
54
- */
55
- protected $delimiter;
56
- /**
57
- * Feed Rules
58
- *
59
- * @var array
60
- */
61
- protected $config;
62
- /**
63
- * Post status to query
64
- *
65
- * @var string
66
- */
67
- protected $post_status = 'publish';
68
- /**
69
- * Processed Products
70
- *
71
- * @var array
72
- */
73
- public $products = [];
74
 
75
 
76
- /**
77
- * Products IDs
78
- *
79
- * @var array
80
- */
81
- public $product_ids = [];
82
 
83
- /**
84
- * Feed Big Data
85
- *
86
- * @var array
87
- */
88
- public $data = [];
89
 
90
- /**
91
- * Processed Products
92
- *
93
- * @var array
94
- */
95
- public $product_types = [
96
- 'simple',
97
- 'variable',
98
- 'variation',
99
- 'grouped',
100
- 'external',
101
- 'composite',
102
- 'bundle',
103
- 'bundled',
104
- 'yith_bundle',
105
- 'yith-composite',
106
- 'subscription',
107
- 'variable-subscription',
108
- 'woosb',
109
- ];
110
- /**
111
- * Query Method Selector
112
- *
113
- * @var string
114
- */
115
- protected $queryType = 'wp';
116
- /**
117
- * To replace google product highlight attribute for CSV & TXT feed
118
- * @var array
119
- */
120
- protected $google_product_highlights = array(
121
- 'product highlight 1',
122
- 'product highlight 2',
123
- 'product highlight 3',
124
- 'product highlight 4',
125
- 'product highlight 5',
126
- 'product highlight 6',
127
- 'product highlight 7',
128
- 'product highlight 8',
129
- 'product highlight 9',
130
- 'product highlight 10',
131
- );
132
-
133
- /**
134
- * To replace google additional image link attribute for CSV & TXT feed
135
- * @var array
136
- */
137
- protected $google_additional_image = array(
138
- 'additional image link 1',
139
- 'additional image link 2',
140
- 'additional image link 3',
141
- 'additional image link 4',
142
- 'additional image link 5',
143
- 'additional image link 6',
144
- 'additional image link 7',
145
- 'additional image link 8',
146
- 'additional image link 9',
147
- 'additional image link 10',
148
- );
149
- /**
150
- * Google shipping tax attributes
151
- * @var array
152
- */
153
- /**
154
- * Google shipping tax attributes
155
- *
156
- * @var array
157
- */
158
- protected $google_shipping_tax = array(
159
- 'shipping_country',
160
- 'shipping_region',
161
- 'shipping_postal_code',
162
- 'shipping_service',
163
- 'shipping_price',
164
- 'min_handling_time',
165
- 'max_handling_time',
166
- 'min_transit_time',
167
- 'max_transit_time',
168
- 'tax',
169
- 'tax_country',
170
- 'tax_region',
171
- 'tax_rate',
172
- 'tax_ship',
173
- 'installment_months',
174
- 'installment_amount',
175
- 'subscription_period',
176
- 'subscription_period_length',
177
- 'subscription_amount',
178
- 'section_name',
179
- 'attribute_name',
180
- 'attribute_value',
181
- 'unit_price_value',
182
- 'unit_price_currency',
183
- 'unit_price_unit',
184
- 'additional_variant_label',
185
- 'additional_variant_value',
186
- );
187
- /**
188
- * XML Wrapper Array
189
- * Contains 'header' and 'footer' for template.
190
- * @var array
191
- */
192
- protected $xml_wrapper = [];
193
-
194
-
195
- /**
196
- * Attribute to skip in attribute loop for processing separately
197
- *
198
- * @var array
199
- */
200
- protected $skipped_merchant_attributes = array(
201
- 'google' => array(
202
- 'shipping_country',
203
- 'shipping_region',
204
- 'shipping_postal_code',
205
- 'shipping_service',
206
- 'shipping_price',
207
- 'min_handling_time',
208
- 'max_handling_time',
209
- 'min_transit_time',
210
- 'max_transit_time',
211
- 'tax_country',
212
- 'tax_region',
213
- 'tax_rate',
214
- 'tax_ship',
215
- 'installment_months',
216
- 'installment_amount',
217
- 'subscription_period',
218
- 'subscription_period_length',
219
- 'subscription_amount',
220
- 'section_name',
221
- 'attribute_name',
222
- 'attribute_value',
223
- ),
224
- 'facebook' => array(
225
- 'shipping_country',
226
- 'shipping_region',
227
- 'shipping_service',
228
- 'shipping_price',
229
- 'tax_country',
230
- 'tax_region',
231
- 'tax_rate',
232
- 'tax_ship',
233
- 'installment_months',
234
- 'installment_amount',
235
- 'subscription_period',
236
- 'subscription_period_length',
237
- 'subscription_amount',
238
- 'section_name',
239
- 'attribute_name',
240
- 'attribute_value',
241
- 'unit_price_value',
242
- 'unit_price_currency',
243
- 'unit_price_unit',
244
- 'additional_variant_label',
245
- 'additional_variant_value',
246
- ),
247
- 'bing' => array(
248
- 'shipping_country',
249
- 'shipping_service',
250
- 'shipping_price',
251
- ),
252
- 'pinterest' => array(
253
- 'shipping_country',
254
- 'shipping_service',
255
- 'shipping_price',
256
- 'shipping_region',
257
- 'shipping_postal_code',
258
- 'tax_country',
259
- 'tax_region',
260
- 'tax_rate',
261
- 'tax_ship',
262
- ),
263
- );
264
-
265
- /**
266
- * Already Processed merchant attributes by the attribute loop
267
- * this will ensure unique merchant attribute.
268
- * @see Woo_Feed_Products_v::exclude_current_attribute()
269
- * @var array
270
- */
271
- protected $processed_merchant_attributes = array();
272
-
273
-
274
- /**
275
- * Post meta prefix for dropdown item
276
- * @since 3.1.18
277
- * @var string
278
- */
279
- const POST_META_PREFIX = 'wf_cattr_';
280
-
281
- /**
282
- * Product Attribute (taxonomy & local) Prefix
283
- * @since 3.1.18
284
- * @var string
285
- */
286
- const PRODUCT_ATTRIBUTE_PREFIX = 'wf_attr_';
287
-
288
- /**
289
- * Product Taxonomy Prefix
290
- * @since 3.1.18
291
- * @var string
292
- */
293
- const PRODUCT_TAXONOMY_PREFIX = 'wf_taxo_';
294
-
295
- /**
296
- * Product Custom Field Prefix
297
- *
298
- * @since 3.1.18
299
- * @var string
300
- */
301
- const PRODUCT_CUSTOM_IDENTIFIER = 'woo_feed_';
302
-
303
- /**
304
- * Product Category Mapping Prefix
305
- * @since 3.1.18
306
- * @var string
307
- */
308
- const PRODUCT_CATEGORY_MAPPING_PREFIX = 'wf_cmapping_';
309
-
310
- /**
311
- * WordPress Option Prefix
312
- *
313
- * @since 4.3.33
314
- * @var string
315
- * @author Nazrul Islam Nayan
316
- */
317
- const WP_OPTION_PREFIX = 'wf_option_';
318
 
319
  /**
320
  * Advance Custom Field (ACF) Prefix
@@ -324,4149 +323,4054 @@ class Woo_Feed_Products_v3
324
  */
325
  const PRODUCT_ACF_FIELDS = 'acf_fields_';
326
 
327
- /**
328
- * Woo_Feed_Products_v3 constructor.
329
- *
330
- * @param $config
331
- * @return void
332
- */
333
- public function __construct($config)
334
- {
335
- $this->config = woo_feed_parse_feed_rules($config);
336
- $this->queryType = woo_feed_get_options('product_query_type');
337
- $this->process_xml_wrapper();
338
- woo_feed_log_feed_process($this->config['filename'], sprintf('Current Query Type is %s', $this->queryType));
339
- }
340
-
341
- /**
342
- * Generate Query Args For WP/WC query class
343
- * @param string $type
344
- * @return array
345
- */
346
- protected function get_query_args($type = 'wc')
347
- {
348
- $args = [];
349
-
350
- // Include Product Variations with db query if configured
351
- $variation_query = woo_feed_get_options('variation_query_type');
352
-
353
- if ('wc' === $type) {
354
- $product_types = $this->product_types;
355
- if ('variable' === $variation_query) {
356
- $variation = array_search('variation', $product_types, true);
357
- if ($variation) {
358
- unset($product_types[$variation]);
359
- }
360
- }
361
-
362
- $args = array(
363
- 'limit' => -1, // phpcs:ignore
364
- 'status' => $this->post_status,
365
- 'type' => $product_types,
366
- 'orderby' => 'date',
367
- 'order' => 'DESC',
368
- 'return' => 'ids',
369
- 'suppress_filters' => false,
370
- );
371
- }
372
-
373
- if ('wp' === $type) {
374
-
375
- $post_type = 'product';
376
- // Include Product Variations with db query if configured
377
- $variation_query = woo_feed_get_options('variation_query_type');
378
- if ('individual' === $variation_query) {
379
- $post_type = ['product', 'product_variation'];
380
- }
381
-
382
- $args = array(
383
- 'posts_per_page' => -1, // phpcs:ignore
384
- 'post_type' => $post_type,
385
- 'post_status' => 'publish',
386
- 'order' => 'DESC',
387
- 'fields' => 'ids',
388
- 'cache_results' => false,
389
- 'update_post_meta_cache' => false,
390
- 'update_post_term_cache' => false,
391
- 'suppress_filters' => false,
392
- );
393
- }
394
- return $args;
395
- }
396
-
397
- /**
398
- * Get Products using WC_Product_Query
399
- *
400
- * @return array
401
- */
402
- public function get_wc_query_products()
403
- {
404
- $args = $this->get_query_args('wc');
405
- if (woo_feed_is_debugging_enabled()) {
406
- woo_feed_log_feed_process($this->config['filename'], 'WC_Product_Query Args::' . PHP_EOL . print_r($args, true)); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
407
- woo_feed_log($this->config['filename'], 'WC_Product_Query Args::' . PHP_EOL . print_r($args, true), 'info'); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
408
- }
409
- $query = new WC_Product_Query($args);
410
- if (woo_feed_is_debugging_enabled()) {
411
- woo_feed_log_feed_process($this->config['filename'], sprintf('WC_Product_Query Args ::' . PHP_EOL . '%s', print_r($args, true))); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
412
- }
413
- return $query->get_products();
414
- }
415
-
416
- /**
417
- * Get Products using WP_Query
418
- *
419
- * return array
420
- */
421
- public function get_wp_query_products()
422
- {
423
- $args = $this->get_query_args('wp');
424
- $query = new WP_Query($args);
425
- if (!is_wp_error($query) && woo_feed_is_debugging_enabled()) {
426
- woo_feed_log_feed_process($this->config['filename'], 'WC_Product_Query Args::' . PHP_EOL . print_r($args, true)); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
427
- woo_feed_log_feed_process($this->config['filename'], sprintf('WP_Query Request ::' . PHP_EOL . '%s', $query->request));
428
- woo_feed_log($this->config['filename'], 'WC_Product_Query Args::' . PHP_EOL . print_r($args, true), 'info'); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
429
- woo_feed_log($this->config['filename'], sprintf('WP_Query Request ::' . PHP_EOL . '%s', $query->request), 'info');
430
- }
431
- return $query->get_posts();
432
- }
433
-
434
- /**
435
- * Get products
436
- *
437
- * @return array
438
- */
439
- public function query_products()
440
- {
441
- $products = [];
442
- if ('wc' == $this->queryType) {
443
- $products = $this->get_wc_query_products();
444
- } elseif ('wp' == $this->queryType) {
445
- $products = $this->get_wp_query_products();
446
- } elseif ('both' == $this->queryType) {
447
- $wc = $this->get_wc_query_products();
448
- $wp = $this->get_wp_query_products();
449
- $products = array_unique(array_merge($wc, $wp));
450
- }
451
-
452
- //set product ids
453
- $this->product_ids = $products;
454
-
455
- return $products;
456
- }
457
-
458
- /**
459
- * Organize Feed Attribute config
460
- * @return array|bool
461
- */
462
- public function get_attribute_config()
463
- {
464
- if (empty($this->config)) {
465
- return false;
466
- }
467
-
468
- $attributeConfig = array();
469
- $merchantAttributes = $this->config['mattributes'];
470
- if (!empty($merchantAttributes)) {
471
- $i = 0;
472
- foreach ($merchantAttributes as $key => $value) {
473
- $attributeConfig[$i]['mattributes'] = $value;
474
- $attributeConfig[$i]['prefix'] = $this->config['prefix'][$key];
475
- $attributeConfig[$i]['type'] = $this->config['type'][$key];
476
- $attributeConfig[$i]['attributes'] = $this->config['attributes'][$key];
477
- $attributeConfig[$i]['default'] = $this->config['default'][$key];
478
- $attributeConfig[$i]['suffix'] = $this->config['suffix'][$key];
479
- $attributeConfig[$i]['output_type'] = $this->config['output_type'][$key];
480
- $attributeConfig[$i]['limit'] = $this->config['limit'][$key];
481
- $i++;
482
- }
483
- }
484
-
485
- return $attributeConfig;
486
- }
487
-
488
- /**
489
- * Get Product Information according to feed config
490
- *
491
- * @param int[] $productIds
492
- *
493
- * @return array
494
- * @since 3.2.0
495
- *
496
- */
497
- public function get_products($productIds)
498
- {
499
-
500
- if (empty($productIds)) {
501
- return [];
502
- }
503
-
504
- //filter big data
505
- $this->data = apply_filters("woo_feed_feed_big_data", $this->data, $productIds, $this->config);
506
-
507
- /**
508
- * Fires before looping through request product for getting product data
509
- *
510
- * @param int[] $productIds
511
- * @param array $feedConfig
512
- *
513
- * @since 3.2.10
514
- */
515
- do_action('woo_feed_before_product_loop', $productIds, $this->config);
516
-
517
- foreach ($productIds as $key => $pid) {
518
- woo_feed_log_feed_process($this->config['filename'], sprintf('Loading Product Data For %d.', $pid));
519
- $product = wc_get_product($pid);
520
-
521
- if ($this->exclude_from_loop($product)) {
522
- continue;
523
- }
524
-
525
- if ($this->process_variation($product)) {
526
- continue;
527
- }
528
-
529
- if (!$this->filter_product($product)) {
530
- woo_feed_log_feed_process($this->config['filename'], 'Skipping Product :: Matched with filter conditions');
531
- continue;
532
- }
533
-
534
- woo_feed_log_feed_process($this->config['filename'], 'Formatting Feed Data...');
535
-
536
- // Add Single item wrapper before product info loop start
537
- if ('xml' == $this->config['feedType']) {
538
- $this->feedBody .= "\n";
539
- $this->feedBody .= '<' . $this->config['itemWrapper'] . '>';
540
- $this->feedBody .= "\n";
541
- }
542
-
543
- // reset processed attribute list before loop
544
- $this->processed_merchant_attributes = [];
545
-
546
- // Process attribute values
547
- $this->process_attributes($product);
548
-
549
- try {
550
- woo_feed_log_feed_process($this->config['filename'], 'Processing Merchant Specific Fields');
551
- // Process feed data for uncommon merchant feed like Google,Facebook,Pinterest
552
- $this->process_for_merchant($product, $this->pi);
553
- } catch (Exception $e) {
554
- $message = 'Error Processing Merchant Specific Fields.' . PHP_EOL . 'Caught Exception :: ' . $e->getMessage();
555
- woo_feed_log($this->config['filename'], $message, 'critical', $e, true);
556
- woo_feed_log_fatal_error($message, $e);
557
- }
558
-
559
- if ('xml' == $this->config['feedType']) {
560
- if (empty($this->feedHeader)) {
561
- $this->feedHeader = $this->process_xml_feed_header();
562
- $this->feedFooter = $this->process_xml_feed_footer();
563
-
564
- }
565
-
566
- $this->feedBody .= '</' . $this->config['itemWrapper'] . '>';
567
-
568
-
569
- } elseif ('txt' == $this->config['feedType']) {
570
- if (empty($this->feedHeader)) {
571
- $this->process_txt_feed_header();
572
- }
573
- $this->process_txt_feed_body();
574
- } elseif ('csv' == $this->config['feedType'] || 'xls' == $this->config['feedType']) {
575
- if (empty($this->feedHeader)) {
576
- $this->process_csv_feed_header();
577
- }
578
- $this->process_csv_feed_body();
579
- } elseif ('json' == $this->config['feedType']) {
580
- $this->process_json_feed_body();
581
- }
582
- woo_feed_log_feed_process($this->config['filename'], 'Done Formatting...');
583
- $this->pi++;
584
- }
585
-
586
- /**
587
- * Fires after looping through request product for getting product data
588
- *
589
- * @param int[] $productIds
590
- * @param array $feedConfig
591
- *
592
- * @since 3.2.10
593
- */
594
- do_action('woo_feed_after_product_loop', $productIds, $this->config);
595
-
596
- return $this->products;
597
- }
598
-
599
- /**
600
- * Process product variations
601
- * @param WC_Abstract_Legacy_Product $product
602
- *
603
- * @return bool
604
- * @since 3.3.9
605
- */
606
- protected function process_variation($product)
607
- {
608
- // Apply variable and variation settings
609
- if ($product->is_type('variable') && $product->has_child()) {
610
- $this->pi++;
611
-
612
- $variation_query = woo_feed_get_options('variation_query_type');
613
- if ('variable' === $variation_query) {
614
- $variations = $product->get_visible_children();
615
- if (is_array($variations) && (sizeof($variations) > 0)) {
616
- if (woo_feed_is_debugging_enabled()) {
617
- woo_feed_log_feed_process($this->config['filename'], sprintf('Getting Variation Product(s) :: %s', implode(', ', $variations)));
618
- }
619
- $this->get_products($variations);
620
- return true;
621
- }
622
- }
623
- }
624
-
625
- return false;
626
- }
627
-
628
- /**
629
- * Process The Attributes and assign value to merchant attribute
630
- *
631
- * @param WC_Abstract_Legacy_Product $product
632
- *
633
- * @return void
634
- * @since 3.3.9
635
- */
636
- protected function process_attributes($product)
637
- {
638
- // print_r($this->config['attributes']);
639
- // Get Product Attribute values by type and assign to product array
640
- foreach ($this->config['attributes'] as $attr_key => $attribute) {
641
-
642
- $merchant_attribute = isset($this->config['mattributes'][$attr_key]) ? $this->config['mattributes'][$attr_key] : '';
643
-
644
- if ($this->exclude_current_attribute($product, $merchant_attribute, $attribute)) {
645
- continue;
646
- }
647
-
648
- // Add Prefix and Suffix into Output
649
- $prefix = $this->config['prefix'][$attr_key];
650
- $suffix = $this->config['suffix'][$attr_key];
651
- $merchant = $this->config['provider'];
652
- $feedType = $this->config['feedType'];
653
-
654
- if ('pattern' == $this->config['type'][$attr_key]) {
655
- $attributeValue = $this->config['default'][$attr_key];
656
- } else { // Get Pattern value
657
- $attributeValue = $this->getAttributeValueByType($product, $attribute, $merchant_attribute);
658
- }
659
-
660
- // Format Output according to Output Type config.
661
- if (isset($this->config['output_type'][$attr_key])) {
662
- $outputType = $this->config['output_type'][$attr_key];
663
- $attributeValue = $this->format_output($attributeValue, $this->config['output_type'][$attr_key], $product, $attribute, $merchant_attribute);
664
- }
665
-
666
- // Limit Output.
667
- if (isset($this->config['limit'][$attr_key])) {
668
- $attributeValue = $this->crop_string($attributeValue, 0, $this->config['limit'][$attr_key]);
669
- }
670
-
671
- // Process prefix and suffix.
672
- $attributeValue = $this->process_prefix_suffix($attributeValue, $prefix, $suffix, $attribute);
673
-
674
- if ('xml' == $feedType) {
675
-
676
- // Replace XML Nodes according to merchant requirement.
677
- $getReplacedAttribute = woo_feed_replace_to_merchant_attribute($merchant_attribute, $merchant, $feedType);
678
-
679
- // XML does not support space in node. So replace Space with Underscore.
680
- $getReplacedAttribute = str_replace(' ', '_', $getReplacedAttribute);
681
-
682
- // Trim XML Element text & Encode for UTF-8.
683
- if (!empty($attributeValue)) {
684
- $attributeValue = trim($attributeValue);
685
-
686
- if ('custom' === $this->config['provider'] && strpos($attributeValue, '<![CDATA[') === false) {
687
- $attributeValue = htmlentities($attributeValue, ENT_XML1 | ENT_QUOTES, 'UTF-8');
688
- }
689
- }
690
-
691
- // Add closing XML node if value is empty
692
- if ('' !== $attributeValue) {
693
- // Add CDATA wrapper for XML feed to prevent XML error.
694
- $attributeValue = woo_feed_add_cdata($merchant_attribute, $attributeValue, $merchant, $this->config['feedType']);
695
- // print_r($attributeValue);echo"<br/>";
696
- // Strip slash from output.
697
- $attributeValue = stripslashes($attributeValue);
698
- $this->feedBody .= '<' . $getReplacedAttribute . '>' . "$attributeValue" . '</' . $getReplacedAttribute . '>';
699
- $this->feedBody .= "\n";
700
- } else {
701
- $this->feedBody .= '<' . $getReplacedAttribute . '/>';
702
- $this->feedBody .= "\n";
703
- }
704
-
705
- } elseif (in_array($feedType, ['csv', 'tsv', 'xls'], true)) {
706
- $merchant_attribute = woo_feed_replace_to_merchant_attribute($merchant_attribute, $merchant, $feedType);
707
- $merchant_attribute = $this->processStringForCSV($merchant_attribute);
708
-
709
- if ("shipping" === $merchant_attribute && 'bing' == $this->config['provider']) {
710
- $merchant_attribute = 'shipping(country:service:price)';
711
- } elseif ("shipping" === $merchant_attribute) {
712
- $merchant_attribute = 'shipping(country:region:service:price)';
713
- }
714
-
715
- if ("tax" === $merchant_attribute) {
716
- $merchant_attribute = 'tax(country:region:rate:tax_ship)';
717
- }
718
-
719
- $attributeValue = $this->processStringForCSV($attributeValue);
720
-
721
- } elseif ('txt' == $feedType) {
722
- $merchant_attribute = woo_feed_replace_to_merchant_attribute($merchant_attribute, $merchant, $feedType);
723
- $merchant_attribute = $this->processStringForTXT($merchant_attribute);
724
-
725
- if ("shipping" === $merchant_attribute && 'bing' == $this->config['provider']) {
726
- $merchant_attribute = 'shipping(country:service:price)';
727
- } elseif ("shipping" === $merchant_attribute) {
728
- $merchant_attribute = 'shipping(country:region:service:price)';
729
- }
730
-
731
- if ("tax" === $merchant_attribute) {
732
- $merchant_attribute = 'tax(country:region:rate:tax_ship)';
733
- }
734
-
735
- $attributeValue = $this->processStringForTXT($attributeValue);
736
- }
737
-
738
- $this->products[$this->pi][$merchant_attribute] = $attributeValue;
739
- }
740
- }
741
-
742
- /**
743
- * Process Nested Attributes
744
- *
745
- * @return array
746
- * @since 4.0.5
747
- *
748
- */
749
- protected function feed_nested_attributes()
750
- {
751
- return [
752
- 'reviewer' => ['reviewer', 'name'],
753
- 'ratings' => ['ratings', 'overall'],
754
- 'product_url' => ['products', 'product', 'product_url'],
755
- ];
756
- }
757
-
758
- /**
759
- * Process Nested Attributes
760
- *
761
- * @param string $attribute //product feed tag
762
- * @param string $content //product feed content
763
- *
764
- * @return string
765
- * @since 4.0.5
766
- *
767
- */
768
-
769
- protected function nested_attributes_element($attribute, $content)
770
- {
771
- $starter = '';
772
- $finisher = '';
773
- $element = '';
774
-
775
- if (empty($attribute)) {
776
- return $attribute;
777
- }
778
-
779
- $attr_names = $this->feed_nested_attributes();
780
-
781
- foreach ($attr_names as $key => $value) {
782
- if ($key === $attribute) {
783
- //starter tags element
784
- foreach ($value as $item_value) {
785
- $starter .= '<' . strval($item_value) . '>';
786
- }
787
-
788
- //finishing tags element
789
- $rev_value = array_reverse($value);
790
- foreach ($rev_value as $item_value) {
791
- $finisher .= '</' . strval($item_value) . '>';
792
- }
793
- }
794
- }
795
-
796
- $element = $starter . $content . $finisher;
797
-
798
- return $element;
799
- }
800
-
801
- /**
802
- * Check if current product should be processed for feed
803
- * This should be using by Woo_Feed_Products_v3::get_products()
804
- *
805
- * @param WC_Product $product
806
- *
807
- * @return bool
808
- * @since 3.3.9
809
- *
810
- */
811
- protected function exclude_from_loop($product)
812
- {
813
- // Skip for invalid products
814
- if (!is_object($product)) {
815
- woo_feed_log_feed_process($this->config['filename'], 'Skipping Product :: Product data is not a valid WC_Product object.');
816
- return true;
817
- }
818
-
819
- // For WP_Query check available product types
820
- if ('wp' == $this->queryType && !in_array($product->get_type(), $this->product_types, true)) {
821
- woo_feed_log_feed_process($this->config['filename'], sprintf('Skipping Product :: Invalid Post/Product Type : %s.', $product->get_type()));
822
- return true;
823
- }
824
-
825
- // Skip orphaned variation
826
- if ($product->is_type('variation') && !$product->get_parent_id()) {
827
- woo_feed_log_feed_process($this->config['filename'], sprintf('Skipping Product :: Orphaned variation product [id: %s] skipped.', $product->get_id()));
828
- return true;
829
- }
830
-
831
- // Skip for invisible products
832
- if (!$product->is_visible()) {
833
- woo_feed_log_feed_process($this->config['filename'], 'Skipping Product :: Product is not visible.');
834
- return true;
835
- }
836
- return false;
837
- }
838
-
839
- /**
840
- * Check if current attribute/merchant attribute should be processed for feed
841
- * This should be using by Woo_Feed_Products_v3::get_products()
842
- *
843
- * @param WC_Product $product
844
- * @param string $merchant_attribute
845
- * @param string $product_attribute
846
- * @param string $feedType
847
- *
848
- * @return bool
849
- *
850
- * @since 3.3.9
851
- *
852
- */
853
- protected function exclude_current_attribute($product, $merchant_attribute, $product_attribute, $feedType = 'xml')
854
- {
855
 
856
- if (empty($merchant_attribute)) {
857
- return true;
858
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
859
 
860
- if (
861
- in_array($this->config['provider'], array_keys($this->skipped_merchant_attributes)) &&
862
- in_array($merchant_attribute, $this->skipped_merchant_attributes[$this->config['provider']])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
863
 
864
- ) {
865
- return true;
866
- }
867
 
868
- if ('shopping_ads_excluded_country' !== $merchant_attribute && in_array($merchant_attribute, $this->processed_merchant_attributes)) {
869
- return true;
870
- }
 
 
 
 
 
 
 
 
 
 
 
 
871
 
872
- $this->processed_merchant_attributes[] = $merchant_attribute;
 
873
 
874
- return false;
875
- }
 
 
 
 
 
 
 
 
 
 
 
 
876
 
877
- /**
878
- * Wrapper for substr with <![CDATA[string]]> support
879
- *
880
- * @param string $string
881
- * @param int $start
882
- * @param int $limit
883
- *
884
- * @return string
885
- * @see substr
886
- *
887
- */
888
- protected function crop_string($string, $start = 0, $limit = null)
889
- {
890
- $limit = absint($limit);
891
- if ($limit > 0) {
892
- $start = absint($start);
893
- if (strpos($string, '<![CDATA[') !== false) {
894
- $string = str_replace(array('<![CDATA[', ']]>'), array('', ''), $string);
895
- $string = substr($string, $start, $limit);
896
- $string = '<![CDATA[' . $string . ']]>';
897
- } else {
898
- $string = substr($string, $start, $limit);
899
- }
900
- }
901
- return $string;
902
- }
903
-
904
- /**
905
- * Process feed data according to merchant uncommon requirements like Google
906
- *
907
- * @param object $productObj WC_Product
908
- * @param int $index Product Index
909
- *
910
- * @since 3.2.0
911
- */
912
- protected function process_for_merchant($productObj, $index)
913
- {
914
- $product = $this->products[$index];
915
- $merchantAttributes = $this->config['mattributes'];
916
- $s = 0; // Shipping Index
917
- $i = 0; // Installment Index
918
- $t = 0; // Tax Index
919
- $tax = '';
920
- $shipping = '';
921
- $sub = 0;
922
- $subscription = '';
923
- $ins = 0; // Installment Index
924
- $installment = "";
925
- $product_detail = '';
926
- $unit_price = '';
927
- $additional_variant_attribute = '';
928
- $pd = 0;
929
- $up = 0; //Unit Price for facebook
930
- $av = 0; //Additional Variant Attribute for facebook
931
-
932
-
933
- // Format Shipping and Tax data for CSV and TXT feed only for google and facebook
934
-
935
- if ('xml' != $this->config['feedType'] && in_array($this->config['provider'], array('google', 'facebook', 'bing', 'snapchat', 'pinterest'))) {
936
- foreach ($merchantAttributes as $key => $value) {
937
-
938
- if (!in_array($value, $this->google_shipping_tax, true)) {
939
- continue;
940
- }
941
-
942
- # Get value by attribute type with prefix & suffix
943
- $output = $this->process_for_merchant_get_value($productObj, $key);
944
-
945
- if ('shipping_country' == $value) {
946
- $s++;
947
- $shipping .= $output;
948
- }
949
- if ('shipping_region' == $value) {
950
- $shipping .= ':' . $output;
951
- } elseif ('shipping_postal_code' == $value) {
952
- $shipping .= ':' . $output;
953
- }
954
- if ('shipping_service' == $value) {
955
- $shipping .= ':' . $output;
956
- }
957
- if ('shipping_price' == $value) {
958
- $shipping .= ':' . $output;
959
- }
960
-
961
- if ('section_name' == $value) {
962
- $pd++;
963
- $product_detail .= $output;
964
- }
965
- if ('attribute_name' == $value) {
966
- $product_detail .= ':' . $output;
967
- }
968
- if ('attribute_value' == $value) {
969
- $product_detail .= ':' . $output;
970
- }
971
-
972
- //facebook nested attributes
973
- if (isset($this->config['provider']) && "facebook" === $this->config['provider']) {
974
- if ('unit_price_value' == $value) {
975
- $up++;
976
- $unit_price .= $output;
977
- }
978
- if ('unit_price_currency' == $value) {
979
- $unit_price .= ':' . $output;
980
- }
981
- if ('unit_price_unit' == $value) {
982
- $unit_price .= ':' . $output;
983
- }
984
-
985
- if ('additional_variant_label' == $value) {
986
- $av++;
987
- $additional_variant_attribute .= $output;
988
- }
989
- if ('additional_variant_value' == $value) {
990
- $additional_variant_attribute .= ':' . $output;
991
- }
992
-
993
- if (0 < $up) {
994
- $this->products[$this->pi]["unit_price"] = $unit_price;
995
- }
996
-
997
- if (0 < $av) {
998
- $this->products[$this->pi]["additional_variant_attribute"] = $additional_variant_attribute;
999
- }
1000
- }
1001
-
1002
-
1003
- if ('installment_months' == $value) {
1004
- $ins++;
1005
- $installment .= $output;
1006
- }
1007
- if ('installment_amount' == $value) {
1008
- $installment .= ':' . $output;
1009
- }
1010
-
1011
- if ('subscription_period' == $value) {
1012
- $sub++;
1013
- $subscription .= $output;
1014
- }
1015
- if ('subscription_period_length' == $value) {
1016
- $subscription .= ':' . $output;
1017
- }
1018
- if ('subscription_amount' == $value) {
1019
- $subscription .= ':' . $output;
1020
- }
1021
- }
1022
-
1023
- if (0 < $pd) {
1024
- $this->products[$this->pi]["product detail"] = $product_detail;
1025
- }
1026
-
1027
- if (0 < $sub) {
1028
- $this->products[$this->pi]["subscription cost"] = $subscription;
1029
-
1030
- }
1031
-
1032
- if (0 < $ins) {
1033
- $this->products[$this->pi]["installment"] = $installment;
1034
- }
1035
- }
1036
-
1037
-
1038
- if (in_array($this->config['provider'], array('google', 'facebook', 'snapchat', 'bing', 'pinterest'))) {
1039
-
1040
-
1041
- // Reformat Shipping attributes for google, facebook
1042
- if ('xml' == $this->config['feedType']) {
1043
- foreach ($merchantAttributes as $key => $value) {
1044
-
1045
- if (!in_array($value, $this->google_shipping_tax)) {
1046
- continue;
1047
- }
1048
-
1049
-
1050
- # Get value by attribute type with prefix & suffix
1051
- $output = $this->process_for_merchant_get_value($productObj, $key);
1052
-
1053
-
1054
- if ('shipping_country' == $value) {
1055
- if (0 == $s) {
1056
- $shipping .= '<g:shipping>';
1057
- $s = 1;
1058
- } else {
1059
- $shipping .= '</g:shipping>' . "\n";
1060
- $shipping .= '<g:shipping>';
1061
- }
1062
- } elseif (!in_array('shipping_country', $merchantAttributes) && 'shipping_price' == $value) {
1063
- if (0 == $s) {
1064
- $shipping .= '<g:shipping>';
1065
- $s = 1;
1066
- } else {
1067
- $shipping .= '</g:shipping>' . "\n";
1068
- $shipping .= '<g:shipping>';
1069
- }
1070
- }
1071
-
1072
- if ('shipping_country' == $value) {
1073
- $shipping .= '<g:country>' . $output . '</g:country>' . "\n";
1074
- } elseif ('shipping_region' == $value) {
1075
- $shipping .= '<g:region>' . $output . '</g:region>' . "\n";
1076
- } elseif ('shipping_region' == $value) {
1077
- $shipping .= '<g:region>' . $output . '</g:region>' . "\n";
1078
- } elseif ('shipping_service' == $value) {
1079
- $shipping .= '<g:service>' . $output . '</g:service>' . "\n";
1080
- } elseif ('shipping_postal_code' == $value) {
1081
- $shipping .= '<g:postal_code>' . $output . '</g:postal_code>' . "\n";
1082
- } elseif ('shipping_price' == $value) {
1083
- $shipping .= '<g:price>' . $output . '</g:price>' . "\n";
1084
- } elseif ('tax_country' == $value) {
1085
- if (0 == $t) {
1086
- $tax .= '<g:tax>';
1087
- $t = 1;
1088
- } else {
1089
- $tax .= '</g:tax>' . "\n";
1090
- $tax .= '<g:tax>';
1091
- }
1092
- $tax .= '<g:country>' . $output . '</g:country>' . "\n";
1093
- } elseif ('tax_region' == $value) {
1094
- $tax .= '<g:region>' . $output . '</g:region>' . "\n";
1095
- } elseif ('tax_rate' == $value) {
1096
- $tax .= '<g:rate>' . $output . '</g:rate>' . "\n";
1097
- } elseif ('tax_ship' == $value) {
1098
- $tax .= '<g:tax_ship>' . $output . '</g:tax_ship>' . "\n";
1099
- } elseif ('subscription_period' == $value) {
1100
- if (0 == $sub) {
1101
- $subscription .= '<g:subscription_cost>';
1102
- $sub = 1;
1103
- } else {
1104
- $subscription .= '</g:subscription_cost>' . "\n";
1105
- $subscription .= '<g:subscription_cost>';
1106
- }
1107
- $subscription .= '<g:period>' . $output . '</g:period>' . "\n";
1108
- } elseif ('subscription_period_length' == $value) {
1109
- $subscription .= '<g:period_length>' . $output . '</g:period_length>' . "\n";
1110
- } elseif ('subscription_amount' == $value) {
1111
- $subscription .= '<g:amount>' . $output . '</g:amount>' . "\n";
1112
- }
1113
-
1114
- if ('section_name' == $value) {
1115
- if (0 == $pd) {
1116
- $product_detail .= '<g:product_detail>';
1117
- $pd = 1;
1118
- } else {
1119
- $product_detail .= '</g:product_detail>' . "\n";
1120
- $product_detail .= '<g:product_detail>';
1121
- }
1122
- } elseif (!in_array('section_name', $merchantAttributes) && 'attribute_name' == $value) {
1123
- if (0 == $pd) {
1124
- $product_detail .= '<g:product_detail>';
1125
- $pd = 1;
1126
- } else {
1127
- $product_detail .= '</g:product_detail>' . "\n";
1128
- $product_detail .= '<g:product_detail>';
1129
- }
1130
- }
1131
-
1132
- if ('section_name' == $value) {
1133
- $product_detail .= '<g:section_name>' . $output . '</g:section_name>' . "\n";
1134
- } elseif ('attribute_name' == $value) {
1135
- $product_detail .= '<g:attribute_name>' . $output . '</g:attribute_name>' . "\n";
1136
- } elseif ('attribute_value' == $value) {
1137
- $product_detail .= '<g:attribute_value>' . $output . '</g:attribute_value>' . "\n";
1138
- }
1139
-
1140
- if (isset($this->config['provider']) && "facebook" === $this->config['provider']) {
1141
-
1142
- // unit_price configure
1143
- if ('unit_price_value' == $value) {
1144
- if (0 == $up) {
1145
- $unit_price .= '<unit_price>';
1146
- $up = 1;
1147
- } else {
1148
- $unit_price .= '</unit_price>' . "\n";
1149
- $unit_price .= '<unit_price>';
1150
- }
1151
- } elseif (!in_array('unit_price_value', $merchantAttributes) && 'unit_price_currency' == $value) {
1152
- if (0 == $up) {
1153
- $unit_price .= '<unit_price>';
1154
- $up = 1;
1155
- } else {
1156
- $unit_price .= '</unit_price>' . "\n";
1157
- $unit_price .= '<unit_price>';
1158
- }
1159
- }
1160
-
1161
- if ('unit_price_value' == $value) {
1162
- $unit_price .= '<value>' . $output . '</value>' . "\n";
1163
- } elseif ('unit_price_currency' == $value) {
1164
- $unit_price .= '<currency>' . $output . '</currency>' . "\n";
1165
- } elseif ('unit_price_unit' == $value) {
1166
- $unit_price .= '<unit>' . $output . '</unit>' . "\n";
1167
- }
1168
-
1169
- // additional_variant_attribute configure
1170
- if ('additional_variant_label' == $value) {
1171
- if (0 == $av) {
1172
- $additional_variant_attribute .= '<additional_variant_attribute>';
1173
- $av = 1;
1174
- } else {
1175
- $additional_variant_attribute .= '</additional_variant_attribute>' . "\n";
1176
- $additional_variant_attribute .= '<additional_variant_attribute>';
1177
- }
1178
- } elseif (!in_array('additional_variant_label', $merchantAttributes) && 'additional_variant_value' == $value) {
1179
- if (0 == $av) {
1180
- $additional_variant_attribute .= '<additional_variant_attribute>';
1181
- $av = 1;
1182
- } else {
1183
- $additional_variant_attribute .= '</additional_variant_attribute>' . "\n";
1184
- $additional_variant_attribute .= '<additional_variant_attribute>';
1185
- }
1186
- }
1187
-
1188
- if ('additional_variant_label' == $value) {
1189
- $additional_variant_attribute .= '<label>' . $output . '</label>' . "\n";
1190
- } elseif ('additional_variant_value' == $value) {
1191
- $additional_variant_attribute .= '<value>' . $output . '</value>' . "\n";
1192
- }
1193
- }
1194
-
1195
-
1196
- if ('installment_months' === $value) {
1197
- if (0 == $ins) {
1198
- $installment .= '<g:installment>';
1199
- $ins = 1;
1200
- } else {
1201
- $installment .= '</g:installment>' . "\n";
1202
- $installment .= '<g:installment>';
1203
- }
1204
- $installment .= '<g:months>' . $output . '</g:months>' . "\n";
1205
- } elseif ('installment_amount' == $value) {
1206
- $installment .= '<g:amount>' . $output . '</g:amount>' . "\n";
1207
- }
1208
- }
1209
-
1210
- if (1 == $pd) {
1211
- $product_detail .= '</g:product_detail>';
1212
- }
1213
-
1214
- if (isset($this->config['provider']) && "facebook" === $this->config['provider']) {
1215
- if (1 == $up) {
1216
- $unit_price .= '</unit_price>';
1217
- }
1218
-
1219
- if (1 == $av) {
1220
- $additional_variant_attribute .= '</additional_variant_attribute>';
1221
- }
1222
-
1223
- $this->feedBody .= $unit_price;
1224
- $this->feedBody .= $additional_variant_attribute;
1225
- }
1226
-
1227
- if (1 == $s) {
1228
- $shipping .= '</g:shipping>';
1229
- }
1230
- if (1 == $t) {
1231
- $tax .= '</g:tax>';
1232
- }
1233
-
1234
- if (1 == $sub) {
1235
- $subscription .= '</g:subscription_cost>';
1236
- }
1237
-
1238
- if (1 == $ins) {
1239
- $installment .= '</g:installment>';
1240
- }
1241
-
1242
- //$this->feedBody .= $shipping;
1243
- //$this->feedBody .= $tax;
1244
- $this->feedBody .= $product_detail;
1245
- $this->feedBody .= $installment;
1246
-
1247
- if ($productObj->is_type('subscription') ||
1248
- $productObj->is_type('variable-subscription') ||
1249
- $productObj->is_type('subscription_variation')) {
1250
- $this->feedBody .= $subscription;
1251
- }
1252
- }
1253
- // ADD g:identifier_exists
1254
- $identifier = array('brand', 'upc', 'sku', 'mpn', 'gtin');
1255
- $countIdentifier = 0;
1256
- if (!in_array('identifier_exists', $merchantAttributes)) {
1257
- if (count(array_intersect_key(array_flip($identifier), $product)) >= 2) {
1258
- // Any 2 required keys exist!
1259
- // @TODO Refactor with OR
1260
- if (array_key_exists('brand', $product) && !empty($product['brand'])) {
1261
- $countIdentifier++;
1262
- }
1263
- if (array_key_exists('upc', $product) && !empty($product['upc'])) {
1264
- $countIdentifier++;
1265
- }
1266
- if (array_key_exists('sku', $product) && !empty($product['sku'])) {
1267
- $countIdentifier++;
1268
- }
1269
- if (array_key_exists('mpn', $product) && !empty($product['mpn'])) {
1270
- $countIdentifier++;
1271
- }
1272
- if (array_key_exists('gtin', $product) && !empty($product['gtin'])) {
1273
- $countIdentifier++;
1274
- }
1275
- }
1276
-
1277
- if ('xml' == $this->config['feedType']) {
1278
- if ($countIdentifier >= 2) {
1279
- $this->feedBody .= '<g:identifier_exists>yes</g:identifier_exists>';
1280
- } else {
1281
- $this->feedBody .= '<g:identifier_exists>no</g:identifier_exists>';
1282
- }
1283
- } else {
1284
- $identifier_exists = 'identifier exists';
1285
- if (in_array($this->config['provider'], array('bing', 'pinterest'))) {
1286
- $identifier_exists = 'identifier_exists';
1287
- }
1288
-
1289
- if ($countIdentifier >= 2) {
1290
- $this->products[$this->pi][$identifier_exists] = 'yes';
1291
- } else {
1292
- $this->products[$this->pi][$identifier_exists] = 'no';
1293
- }
1294
- }
1295
- }
1296
- }
1297
- }
1298
-
1299
- private function process_for_merchant_get_value($productObj, $key)
1300
- {
1301
- $prefix = $this->config['prefix'][$key];
1302
- $suffix = $this->config['suffix'][$key];
1303
- $attribute = $this->config['attributes'][$key];
1304
- $merchant_attribute = $this->config['mattributes'][$key];
1305
-
1306
- if ('pattern' == $this->config['type'][$key]) {// Get Pattern value.
1307
- $output = $this->config['default'][$key];
1308
- $output = $this->apply_filters_to_attribute_value($output, $productObj, $attribute, $merchant_attribute);
1309
- } else {
1310
- $output = $this->getAttributeValueByType($productObj, $attribute, $merchant_attribute);
1311
- }
1312
-
1313
- $output = $this->format_output($output, $this->config['output_type'], $productObj, $attribute, $merchant_attribute);
1314
-
1315
- $output = $this->process_prefix_suffix($output, $prefix, $suffix, $attribute = '');
1316
-
1317
- return $output;
1318
- }
1319
-
1320
- /**
1321
- * Get Query Type Settings
1322
- * @return string
1323
- */
1324
- public function get_query_type()
1325
- {
1326
- return $this->queryType;
1327
- }
1328
-
1329
- public function get_product_types()
1330
- {
1331
- return $this->product_types;
1332
- }
1333
-
1334
- /**
1335
- * Generate TXT Feed Header
1336
- *
1337
- * @return string
1338
- * @since 3.2.0
1339
- *
1340
- */
1341
- protected function process_txt_feed_header()
1342
- {
1343
- // Set Delimiter
1344
- if ('tab' == $this->config['delimiter']) {
1345
- $this->delimiter = "\t";
1346
- } else {
1347
- $this->delimiter = $this->config['delimiter'];
1348
- }
1349
-
1350
- // Set Enclosure
1351
- if (!empty($this->config['enclosure'])) {
1352
- $this->enclosure = $this->config['enclosure'];
1353
- if ('double' == $this->enclosure) {
1354
- $this->enclosure = '"';
1355
- } elseif ('single' == $this->enclosure) {
1356
- $this->enclosure = "'";
1357
- } else {
1358
- $this->enclosure = '';
1359
- }
1360
- } else {
1361
- $this->enclosure = '';
1362
- }
1363
-
1364
- $eol = PHP_EOL;
1365
- if ('trovaprezzi' === $this->config['provider']) {
1366
- $eol = '<endrecord>' . PHP_EOL;
1367
- }
1368
-
1369
- $product = $this->products[$this->pi];
1370
-
1371
- $headers = array_keys($product);
1372
-
1373
- $this->feedHeader .= $this->enclosure . implode("$this->enclosure$this->delimiter$this->enclosure", $headers) . $this->enclosure . $eol;
1374
-
1375
- if ('google' === $this->config['provider']) {
1376
- $this->feedHeader = str_replace($this->google_product_highlights, 'product highlight', $this->feedHeader);
1377
- $this->feedHeader = str_replace($this->google_additional_image, 'additional image link', $this->feedHeader);
1378
- }
1379
-
1380
- return $this->feedHeader;
1381
- }
1382
-
1383
- /**
1384
- * Generate TXT Feed Body
1385
- *
1386
- * @return string
1387
- * @since 3.2.0
1388
- *
1389
- */
1390
- protected function process_txt_feed_body()
1391
- {
1392
- $productInfo = array_values($this->products[$this->pi]);
1393
- $eol = PHP_EOL;
1394
- if ('trovaprezzi' === $this->config['provider']) {
1395
- $eol = '<endrecord>' . PHP_EOL;
1396
- }
1397
- $this->feedBody .= $this->enclosure . implode("$this->enclosure$this->delimiter$this->enclosure", $productInfo) . $this->enclosure . $eol;
1398
-
1399
- return $this->feedBody;
1400
- }
1401
-
1402
- /**
1403
- * Generate CSV Feed Header
1404
- *
1405
- * @return array
1406
- * @since 3.2.0
1407
- *
1408
- */
1409
- protected function process_csv_feed_header()
1410
- {
1411
- // Set Delimiter
1412
- if ('tab' == $this->config['delimiter']) {
1413
- $this->delimiter = "\t";
1414
- } else {
1415
- $this->delimiter = $this->config['delimiter'];
1416
- }
1417
-
1418
- // Set Enclosure
1419
- if (!empty($this->config['enclosure'])) {
1420
- $this->enclosure = $this->config['enclosure'];
1421
- if ('double' == $this->enclosure) {
1422
- $this->enclosure = '"';
1423
- } elseif ('single' == $this->enclosure) {
1424
- $this->enclosure = "'";
1425
- } else {
1426
- $this->enclosure = '';
1427
- }
1428
- } else {
1429
- $this->enclosure = '';
1430
- }
1431
-
1432
- $product = $this->products[$this->pi];
1433
-
1434
- $this->feedHeader = array_keys($product);
1435
-
1436
- if ('google' === $this->config['provider']) {
1437
- $this->feedHeader = str_replace($this->google_product_highlights, 'product highlight', $this->feedHeader);
1438
- $this->feedHeader = str_replace($this->google_additional_image, 'additional image link', $this->feedHeader);
1439
- }
1440
-
1441
- return $this->feedHeader;
1442
- }
1443
-
1444
- /**
1445
- * Generate CSV Feed Body
1446
- * @return array
1447
- * @since 3.2.0
1448
- */
1449
- protected function process_csv_feed_body()
1450
- {
1451
- $product = $this->products[$this->pi];
1452
- $this->feedBody[] = array_values($product);
1453
-
1454
- return $this->feedBody;
1455
- }
1456
-
1457
- protected function process_json_feed_body()
1458
- {
1459
- $product = $this->products[$this->pi];
1460
- $this->feedBody[] = $product;
1461
-
1462
- return $this->feedBody;
1463
- }
1464
-
1465
- protected function process_xml_wrapper()
1466
- {
1467
- $itemsWrapperClose = explode(' ', $this->config['itemsWrapper']);
1468
- $itemsWrapperClose = $itemsWrapperClose[0];
1469
- $this->xml_wrapper = [
1470
- 'header' => '<?xml version="1.0" encoding="UTF-8" ?>' . PHP_EOL . '<' . wp_unslash($this->config['itemsWrapper']) . '>',
1471
- 'footer' => PHP_EOL . '</' . $itemsWrapperClose . '>',
1472
- ];
1473
- $this->config['itemWrapper'] = str_replace(' ', '_', $this->config['itemWrapper']);
1474
- $this->config['itemsWrapper'] = str_replace(' ', '_', $this->config['itemsWrapper']);
1475
-
1476
- if (file_exists(WOO_FEED_FREE_ADMIN_PATH . 'partials/templates/' . $this->config['provider'] . '.txt')) {
1477
- $txt = file_get_contents(WOO_FEED_FREE_ADMIN_PATH . 'partials/templates/' . $this->config['provider'] . '.txt');
1478
- $txt = trim($txt);
1479
- $txt = explode('{separator}', $txt);
1480
- if (2 === count($txt)) {
1481
- $this->xml_wrapper['header'] = trim($txt[0]);
1482
- $this->xml_wrapper['footer'] = "\n" . trim($txt[1]);
1483
- }
1484
- }
1485
-
1486
- if (!empty($this->config['extraHeader'])) {
1487
- $this->xml_wrapper['header'] .= PHP_EOL . $this->config['extraHeader'];
1488
- }
1489
-
1490
- // replace template variables.
1491
- $datetime_now = date('Y-m-d H:i:s', strtotime(current_time('mysql'))); // {DateTimeNow}
1492
- if ('pinterest_rss' === $this->config['provider']) { // DATE_RFC822 date format for pinterest rss feed
1493
- $datetime_now = date('r', strtotime(current_time('mysql'))); // {DateTimeNow}
1494
- }
1495
- $blog_name = get_bloginfo('name'); // {BlogName}
1496
- $blog_url = get_bloginfo('url'); // {BlogURL}
1497
- //$blog_desc = get_bloginfo('description'); // {BlogDescription}
1498
- $blog_desc = "CTX Feed - This product feed is generated with the CTX Feed - WooCommerce Product Feed Manager plugin by WebAppick.com. For all your support questions check out our plugin Docs on https://webappick.com/docs or e-mail to: support@webappick.com"; // {BlogDescription}
1499
- $blog_email = get_bloginfo('admin_email'); // {BlogEmail}
1500
-
1501
- $this->xml_wrapper['header'] = str_replace(
1502
- ['{DateTimeNow}', '{BlogName}', '{BlogURL}', '{BlogDescription}', '{BlogEmail}'],
1503
- [$datetime_now, $blog_name, $blog_url, $blog_desc, $blog_email],
1504
- $this->xml_wrapper['header']
1505
- );
1506
- }
1507
-
1508
- /**
1509
- * Make XML feed header
1510
- * @return string
1511
- * @since 3.2.0
1512
- */
1513
- protected function process_xml_feed_header()
1514
- {
1515
- return $this->xml_wrapper['header'];
1516
- }
1517
-
1518
- /**
1519
- * Make XML feed header
1520
- * @return string
1521
- * @since 3.2.0
1522
- */
1523
- protected function process_xml_feed_footer()
1524
- {
1525
- return $this->xml_wrapper['footer'];
1526
- }
1527
-
1528
- /**
1529
- * Process string for TXT CSV Feed
1530
- *
1531
- * @param $string
1532
- *
1533
- * @return mixed|string
1534
- * @since 3.2.0
1535
- *
1536
- */
1537
- protected function processStringForTXT($string)
1538
- {
1539
- if (!empty($string)) {
1540
- $string = html_entity_decode($string, ENT_HTML401 | ENT_QUOTES); // Convert any HTML entities
1541
-
1542
- if (stristr($string, '"')) {
1543
- $string = str_replace('"', '""', $string);
1544
- }
1545
- $string = str_replace("\n", ' ', $string);
1546
- $string = str_replace("\r", ' ', $string);
1547
- $string = str_replace("\t", ' ', $string);
1548
- $string = trim($string);
1549
- $string = stripslashes($string);
1550
-
1551
- return $string;
1552
- } elseif ('0' == $string) {
1553
- return '0';
1554
- } else {
1555
- return '';
1556
- }
1557
- }
1558
-
1559
- /**
1560
- * Process string for CSV
1561
- *
1562
- * @param $string
1563
- *
1564
- * @return mixed|string
1565
- * @since 3.2.0
1566
- *
1567
- */
1568
- protected function processStringForCSV($string)
1569
- {
1570
- if (!empty($string)) {
1571
- $string = str_replace("\n", ' ', $string);
1572
- $string = str_replace("\r", ' ', $string);
1573
- $string = trim($string);
1574
- $string = stripslashes($string);
1575
-
1576
- return $string;
1577
- } elseif ('0' == $string) {
1578
- return '0';
1579
- } else {
1580
- return '';
1581
- }
1582
- }
1583
-
1584
- /**
1585
- * Get Product Attribute Value by Type
1586
- *
1587
- * @param $product WC_Product
1588
- * @param $attribute
1589
- *
1590
- * @return mixed|string
1591
- * @since 3.2.0
1592
- *
1593
- */
1594
- public function getAttributeValueByType($product, $attribute, $merchant_attribute = '')
1595
- {
1596
 
1597
- if (method_exists($this, $attribute)) {
1598
- $output = $this->$attribute($product);
1599
- } elseif ( false !== strpos( $attribute, self::PRODUCT_ACF_FIELDS ) ) {
1600
- $output = $this->getACFField( $product, $attribute );
1601
- } elseif (false !== strpos($attribute, self::PRODUCT_CUSTOM_IDENTIFIER) || woo_feed_strpos_array(array('_identifier_gtin', '_identifier_ean', '_identifier_mpn'), $attribute)) {
1602
- $output = $this->getCustomField($product, $attribute);
1603
- } elseif (false !== strpos($attribute, self::PRODUCT_ATTRIBUTE_PREFIX)) {
1604
- $attribute = str_replace(self::PRODUCT_ATTRIBUTE_PREFIX, '', $attribute);
1605
- $output = $this->getProductAttribute($product, $attribute);
1606
- } elseif (false !== strpos($attribute, self::POST_META_PREFIX)) {
1607
- $attribute = str_replace(self::POST_META_PREFIX, '', $attribute);
1608
- $output = $this->getProductMeta($product, $attribute);
1609
- } elseif (false !== strpos($attribute, self::PRODUCT_TAXONOMY_PREFIX)) {
1610
- $attribute = str_replace(self::PRODUCT_TAXONOMY_PREFIX, '', $attribute);
1611
- $output = $this->getProductTaxonomy($product, $attribute);
1612
- } elseif (false !== strpos($attribute, self::PRODUCT_CATEGORY_MAPPING_PREFIX)) {
1613
- $id = $product->is_type('variation') ? $product->get_parent_id() : $product->get_id();
1614
- $output = woo_feed_get_category_mapping_value($attribute, $id);
1615
- } elseif (false !== strpos($attribute, self::WP_OPTION_PREFIX)) {
1616
- $optionName = str_replace(self::WP_OPTION_PREFIX, '', $attribute);
1617
- $output = get_option($optionName);
1618
- } elseif ('image_' == substr($attribute, 0, 6)) {
1619
- // For additional image method images() will be used with extra parameter - image number
1620
- $imageKey = explode('_', $attribute);
1621
- if (!isset($imageKey[1]) || (isset($imageKey[1]) && (empty($imageKey[1]) || !is_numeric($imageKey[1])))) {
1622
- $imageKey[1] = '';
1623
- }
1624
- $output = call_user_func_array(array($this, 'images'), array($product, $imageKey[1]));
1625
- } else {
1626
- // return the attribute so multiple attribute can be join with separator to make custom attribute.
1627
- $output = $attribute;
1628
- }
1629
-
1630
- // Json encode if value is an array
1631
- if (is_array($output)) {
1632
- $output = wp_json_encode($output);
1633
- }
1634
-
1635
- $output = $this->apply_filters_to_attribute_value($output, $product, $attribute, $merchant_attribute);
1636
-
1637
- return $output;
1638
- }
1639
-
1640
- /**
1641
- * Apply Filter to Attribute value
1642
- *
1643
- * @param $output
1644
- * @param $product
1645
- * @param $attribute
1646
- * @param $merchant_attribute
1647
- *
1648
- * @return mixed|void
1649
- */
1650
- protected function apply_filters_to_attribute_value($output, $product, $attribute, $merchant_attribute)
1651
- {
1652
- /**
1653
- * Filter attribute value
1654
- *
1655
- * @param string $output the output
1656
- * @param WC_Abstract_Legacy_Product $product Product Object.
1657
- * @param array feed config/rule
1658
- *
1659
- * @since 3.4.3
1660
- *
1661
- */
1662
- $output = apply_filters('woo_feed_get_attribute', $output, $product, $this->config, $merchant_attribute);
1663
-
1664
- /**
1665
- * Filter attribute value before return based on attribute name
1666
- *
1667
- * @param string $output the output
1668
- * @param WC_Abstract_Legacy_Product $product Product Object.
1669
- * @param array feed config/rule
1670
- *
1671
- * @since 3.3.5
1672
- *
1673
- */
1674
- $output = apply_filters("woo_feed_get_{$attribute}_attribute", $output, $product, $this->config);
1675
-
1676
- /**
1677
- * Filter attribute value before return based on merchant and attribute name
1678
- *
1679
- * @param string $output the output
1680
- * @param WC_Abstract_Legacy_Product $product Product Object.
1681
- * @param array feed config/rule
1682
- *
1683
- * @since 3.3.7
1684
- *
1685
- */
1686
- $output = apply_filters("woo_feed_get_{$this->config['provider']}_{$attribute}_attribute", $output, $product, $this->config);
1687
-
1688
- return $output;
1689
- }
1690
-
1691
-
1692
- /**
1693
- * Get Product Id
1694
- *
1695
- * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product Product Object.
1696
- *
1697
- * @return mixed
1698
- * @since 3.2.0
1699
- */
1700
- protected function id($product)
1701
- {
1702
- $id = $product->get_id();
1703
-
1704
- return apply_filters('woo_feed_filter_product_id', $id, $product, $this->config);
1705
- }
1706
-
1707
- /**
1708
- * Get Product Title
1709
- *
1710
- * @param WC_Product $product
1711
- *
1712
- * @return mixed
1713
- * @since 3.2.0
1714
- *
1715
- */
1716
- protected function title($product)
1717
- {
1718
- $title = woo_feed_strip_all_tags($this->remove_short_codes($product->get_name()));
1719
-
1720
- // Add all available variation attributes to variation title.
1721
- if ($product->is_type('variation') && !empty($product->get_attributes())) {
1722
- $title = $this->parent_title($product);
1723
- $attributes = [];
1724
- foreach ($product->get_attributes() as $slug => $value) {
1725
- $attribute = $product->get_attribute($slug);
1726
- if (empty($attribute)) {
1727
- continue;
1728
- }
1729
- $attributes[$slug] = $attribute;
1730
- }
1731
-
1732
- // set variation attributes with separator
1733
- if (isset($this->config['provider']) && 'google' === $this->config['provider']) {
1734
- $variation_attributes = implode(' - ', $attributes);
1735
- } else {
1736
- $variation_attributes = implode(', ', $attributes);
1737
- }
1738
-
1739
- //get product title with variation attribute
1740
- $get_with_var_attributes = apply_filters("woo_feed_get_product_title_with_variation_attribute", true, $product, $this->config);
1741
-
1742
- if ($get_with_var_attributes) {
1743
- $title .= " - " . $variation_attributes;
1744
- }
1745
- }
1746
-
1747
- return apply_filters('woo_feed_filter_product_title', $title, $product, $this->config);
1748
- }
1749
-
1750
- /**
1751
- * Get Parent Product Title
1752
- *
1753
- * @param WC_Product $product Product Object.
1754
- *
1755
- * @return mixed
1756
- * @author Nazrul Islam Nayan
1757
- * @since 5.1.8
1758
- */
1759
- protected function parent_title($product)
1760
- {
1761
- if ($product->is_type('variation')) {
1762
- $product = wc_get_product($product->get_parent_id());
1763
- $title = woo_feed_strip_all_tags($this->remove_short_codes($product->get_name()));
1764
- } else {
1765
- $title = $this->title($product);
1766
- }
1767
-
1768
- return apply_filters('woo_feed_filter_product_parent_title', $title, $product, $this->config);
1769
- }
1770
-
1771
- /**
1772
- * Get All in One SEO Canonical URL
1773
- *
1774
- * @param WC_Product $product
1775
- *
1776
- * @return mixed
1777
- * @since 4.4.12
1778
- */
1779
- protected function _aioseop_canonical_url($product)
1780
- {
1781
- $aioseop_canonical_url = '';
1782
- if (is_plugin_active('all-in-one-seo-pack/all_in_one_seo_pack.php') && class_exists('AIOSEO\Plugin\Common\Models\Post')) {
1783
- $post = AIOSEO\Plugin\Common\Models\Post::getPost($product->get_id());
1784
- $aioseop_canonical_url = $post->canonical_url;
1785
- }
1786
-
1787
- return apply_filters('woo_feed_filter_product_aioseop_canonical_url', $aioseop_canonical_url, $product, $this->config);
1788
- }
1789
-
1790
- /**
1791
- * Get Yoast Product Title
1792
- *
1793
- * @param WC_Product $product
1794
- *
1795
- * @return mixed
1796
- * @since 3.2.0
1797
- *
1798
- */
1799
- protected function yoast_wpseo_title($product)
1800
- {
1801
- $product_id = woo_feed_parent_product_id($product);
1802
- $yoast_title = get_post_meta($product_id, '_yoast_wpseo_title', true);
1803
- if (strpos($yoast_title, '%%') !== false) {
1804
- $title = strstr($yoast_title, '%%', true);
1805
- if (empty($title)) {
1806
- $title = get_the_title($product_id);
1807
- }
1808
- $wpseo_titles = get_option('wpseo_titles');
1809
-
1810
- $sep_options = WPSEO_Option_Titles::get_instance()->get_separator_options();
1811
- if (isset($wpseo_titles['separator']) && isset($sep_options[$wpseo_titles['separator']])) {
1812
- $sep = $sep_options[$wpseo_titles['separator']];
1813
- } else {
1814
- $sep = '-'; //setting default separator if Admin didn't set it from backed
1815
- }
1816
-
1817
- $site_title = get_bloginfo('name');
1818
-
1819
- $meta_title = $title . ' ' . $sep . ' ' . $site_title;
1820
-
1821
- if (!empty($meta_title)) {
1822
- $title = $meta_title;
1823
- }
1824
- } elseif (!empty($yoast_title)) {
1825
- $title = $yoast_title;
1826
- } else {
1827
- $title = $this->title($product);
1828
- }
1829
-
1830
- return apply_filters('woo_feed_filter_product_yoast_wpseo_title', $title, $product, $this->config);
1831
- }
1832
-
1833
- /**
1834
- * Get Yoast Canonical URL
1835
- *
1836
- * @param WC_Product $product
1837
- *
1838
- * @return mixed
1839
- * @since 4.3.77
1840
- */
1841
- protected function yoast_canonical_url($product)
1842
- {
1843
- $product_id = woo_feed_parent_product_id($product);
1844
- $yoast_canonical_url = get_post_meta($product_id, '_yoast_wpseo_canonical', true);
1845
-
1846
- return apply_filters('woo_feed_filter_product_yoast_canonical_url', $yoast_canonical_url, $product, $this->config);
1847
- }
1848
-
1849
- /**
1850
- * Get Rank Math Product Title
1851
- *
1852
- * @param WC_Product $product
1853
- *
1854
- * @return mixed
1855
- * @since 5.1.3
1856
- */
1857
- protected function rank_math_title($product)
1858
- {
1859
- $rank_title = '';
1860
- $post_title = '';
1861
- $page = '';
1862
- $sep = '';
1863
- $sitemap = '';
1864
- if (class_exists('RankMath')) {
1865
- $title = get_post_meta($product->get_id(), 'rank_math_title', true);
1866
- if (empty($title)) {
1867
- $title_format = Helper::get_settings("titles.pt_product_title");
1868
- $title_format = $title_format ? $title_format : '%title%';
1869
- $sep = Helper::get_settings('titles.title_separator');
1870
-
1871
- $rank_title = str_replace('%title%', $product->get_title(), $title_format);
1872
- $rank_title = str_replace('%sep%', $sep, $rank_title);
1873
- $rank_title = str_replace('%page%', '', $rank_title);
1874
- $rank_title = str_replace('%sitename%', get_bloginfo('name'), $rank_title);
1875
- } else {
1876
- $rank_title = $title;
1877
- }
1878
- }
1879
-
1880
- return apply_filters('woo_feed_filter_product_rank_math_title', $rank_title, $product, $this->config);
1881
- }
1882
-
1883
- /**
1884
- * Get Rank Math Product Description
1885
- *
1886
- * @param WC_Product $product
1887
- *
1888
- * @return mixed
1889
- * @since 5.1.3
1890
- */
1891
- protected function rank_math_description($product)
1892
- {
1893
- $description = '';
1894
- if (class_exists('RankMath')) {
1895
- $description = get_post_meta($product->get_id(), 'rank_math_description');
1896
- $desc_format = Helper::get_settings("titles.pt_post_description");
1897
-
1898
- if (empty($description)) {
1899
- if (!empty($desc_format) && strpos((string)$desc_format, 'excerpt') !== false) {
1900
- $description = str_replace('%excerpt%', get_the_excerpt($product->get_id()), $desc_format);
1901
- }
1902
-
1903
- // Get Variation Description
1904
- if ($product->is_type('variation') && empty($description)) {
1905
- $parent = wc_get_product($product->get_parent_id());
1906
- $description = $parent->get_description();
1907
- }
1908
- }
1909
-
1910
- if (is_array($description)) {
1911
- $description = reset($description);
1912
- }
1913
-
1914
- $description = $this->remove_short_codes($description);
1915
-
1916
- //strip tags and spacial characters
1917
- $strip_description = woo_feed_strip_all_tags(wp_specialchars_decode($description));
1918
-
1919
- $description = !empty(strlen($strip_description)) && 0 < strlen($strip_description) ? $strip_description : $description;
1920
- }
1921
-
1922
- return apply_filters('woo_feed_filter_product_rank_math_description', $description, $product, $this->config);
1923
- }
1924
-
1925
- /**
1926
- * Get Rank Math Canonical URL
1927
- *
1928
- * @param WC_Product $product
1929
- *
1930
- * @return mixed
1931
- * @since 5.1.6
1932
- */
1933
- protected function rank_math_canonical_url($product)
1934
- {
1935
- $canonical_url = '';
1936
 
1937
- if (class_exists('RankMath')) {
1938
- $post_canonical_url = get_post_meta($product->get_id(), 'rank_math_canonical_url');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1939
 
1940
- if (empty($post_canonical_url)) {
1941
- $canonical_url = get_the_permalink($product->get_id());
1942
- } else {
1943
- $canonical_url = $post_canonical_url;
1944
- }
1945
 
1946
- if (is_array($canonical_url)) {
1947
- $canonical_url = reset($canonical_url);
1948
- }
1949
- }
 
 
 
 
 
 
1950
 
1951
- return apply_filters('woo_feed_filter_product_rank_math_canonical_url', $canonical_url, $product, $this->config);
1952
- }
 
1953
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1954
 
1955
- /**
1956
- * Get All In One Product Title
1957
- *
1958
- * @param WC_Product $product
1959
- *
1960
- * @return mixed
1961
- * @since 3.2.0
1962
- *
1963
- */
1964
- protected function _aioseop_title($product)
1965
- {
1966
- $title = '';
1967
- if (is_plugin_active('all-in-one-seo-pack/all_in_one_seo_pack.php') && class_exists('AIOSEO\Plugin\Common\Models\Post')) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1968
 
1969
- $post = AIOSEO\Plugin\Common\Models\Post::getPost($product->get_id());
1970
- $title = !empty($post->title) ? $post->title : aioseo()->meta->title->getPostTypeTitle('product');
1971
- }
1972
 
1973
- $title = !empty($title) ? $title : $this->title($product);
 
 
 
 
1974
 
1975
- return apply_filters('woo_feed_filter_product_aioseop_title', $title, $product, $this->config);
1976
- }
1977
 
1978
- /**
1979
- * Get Product Description
1980
- *
1981
- * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product Product Object.
1982
- *
1983
- * @return mixed|string
1984
- * @since 3.2.0
1985
- *
1986
- */
1987
- protected function description($product)
1988
- {
1989
- $description = $product->get_description();
1990
-
1991
- // Get Variation Description
1992
- if ($product->is_type('variation') && empty($description)) {
1993
- $parent = wc_get_product($product->get_parent_id());
1994
-
1995
- if (is_object($parent)) {
1996
- $description = $parent->get_description();
1997
- } else {
1998
- $description = '';
1999
- }
2000
- }
2001
- $description = $this->remove_short_codes($description);
2002
-
2003
- // Add variations attributes after description to prevent Facebook error
2004
- if ('facebook' == $this->config['provider'] && $product->is_type('variation')) {
2005
- $variationInfo = explode('-', $product->get_name());
2006
- if (isset($variationInfo[1])) {
2007
- $extension = $variationInfo[1];
2008
- } else {
2009
- $extension = $product->get_id();
2010
- }
2011
- $description .= ' ' . $extension;
2012
- }
2013
-
2014
- //strip tags and spacial characters
2015
- $strip_description = woo_feed_strip_all_tags(wp_specialchars_decode($description));
2016
-
2017
- $description = !empty(strlen($strip_description)) && 0 < strlen($strip_description) ? $strip_description : $description;
2018
-
2019
- return apply_filters('woo_feed_filter_product_description', $description, $product, $this->config);
2020
- }
2021
-
2022
- /**
2023
- * Get Product Description (with HTML)
2024
- *
2025
- * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product Product Object.
2026
- *
2027
- * @return mixed|string
2028
- * @since 5.2.41
2029
- */
2030
- protected function description_with_html($product)
2031
- {
2032
- $description = $product->get_description();
2033
-
2034
- // Get Variation Description
2035
- if ($product->is_type('variation') && empty($description)) {
2036
- $parent = wc_get_product($product->get_parent_id());
2037
- $description = $parent->get_description();
2038
- }
2039
- $description = $this->remove_short_codes($description);
2040
-
2041
- // Add variations attributes after description to prevent Facebook error
2042
- if ('facebook' === $this->config['provider'] && $product->is_type('variation')) {
2043
- $variationInfo = explode('-', $product->get_name());
2044
- if (isset($variationInfo[1])) {
2045
- $extension = $variationInfo[1];
2046
- } else {
2047
- $extension = $product->get_id();
2048
- }
2049
- $description .= ' ' . $extension;
2050
- }
2051
-
2052
- //remove spacial characters
2053
- $strip_description = wp_check_invalid_utf8(wp_specialchars_decode($description), true);
2054
-
2055
- return apply_filters('woo_feed_filter_product_description_with_html', $description, $product, $this->config);
2056
- }
2057
-
2058
- /**
2059
- * Get Yoast Product Description
2060
- *
2061
- * @param WC_Product $product
2062
- *
2063
- * @return mixed
2064
- * @since 3.2.0
2065
- *
2066
- */
2067
- protected function yoast_wpseo_metadesc($product)
2068
- {
2069
- $product_id = woo_feed_parent_product_id($product);
2070
- $description = '';
2071
- if (class_exists('WPSEO_Frontend')) {
2072
- $description = wpseo_replace_vars(WPSEO_Meta::get_value('metadesc', $product_id),
2073
- get_post($product->get_id()));
2074
- } else {
2075
- $description = YoastSEO()->meta->for_post($product_id)->description;
2076
- }
2077
-
2078
- if (empty($description)) {
2079
- $description = $this->description($product);
2080
- }
2081
-
2082
- return apply_filters('woo_feed_filter_product_yoast_wpseo_metadesc', $description, $product, $this->config);
2083
- }
2084
-
2085
- /**
2086
- * Get All In One Product Description
2087
- *
2088
- * @param WC_Product $product
2089
- *
2090
- * @return mixed
2091
- * @since 3.2.0
2092
- *
2093
- */
2094
- protected function _aioseop_description($product)
2095
- {
2096
- $description = '';
2097
 
2098
- if (is_plugin_active('all-in-one-seo-pack/all_in_one_seo_pack.php') && class_exists('AIOSEO\Plugin\Common\Models\Post')) {
 
 
 
 
 
 
 
 
 
 
 
2099
 
2100
- $post = AIOSEO\Plugin\Common\Models\Post::getPost($product->get_id());
2101
- $description = !empty($post->description) ? $post->description : aioseo()->meta->description->getPostTypeDescription('product');
2102
- }
2103
 
2104
- if (empty($description)) {
2105
- $description = $this->description($product);
2106
- }
 
 
 
 
 
 
 
 
 
2107
 
2108
- return apply_filters('woo_feed_filter_product_aioseop_description', $description, $product, $this->config);
2109
- }
 
 
 
 
 
 
 
 
 
2110
 
2111
- /**
2112
- * Get Product Short Description
2113
- *
2114
- * @param WC_Product $product
2115
- *
2116
- * @return mixed|string
2117
- * @since 3.2.0
2118
- *
2119
- */
2120
- protected function short_description($product)
2121
- {
2122
- $short_description = $product->get_short_description();
2123
 
2124
- // Get Variation Short Description
2125
- if ($product->is_type('variation') && empty($short_description)) {
2126
- $parent = wc_get_product($product->get_parent_id());
2127
- $short_description = $parent->get_short_description();
2128
- }
 
 
 
 
 
 
2129
 
 
 
2130
 
2131
- $short_description = $this->remove_short_codes($short_description);
 
 
 
 
 
 
 
 
 
 
2132
 
2133
- //strip tags and spacial characters
2134
- $short_description = woo_feed_strip_all_tags(wp_specialchars_decode($short_description));
2135
 
2136
- return apply_filters('woo_feed_filter_product_short_description', $short_description, $product, $this->config);
2137
- }
 
 
 
 
 
 
 
 
 
2138
 
 
 
2139
 
2140
- /**
2141
- * At First convert Short Codes and then Remove failed Short Codes from String
2142
- *
2143
- * @param $content
2144
- *
2145
- * @return mixed|string
2146
- * @since 3.2.0
2147
- *
2148
- */
2149
- protected function remove_short_codes($content)
2150
- {
2151
- if ($content == '') {
2152
- return '';
2153
- }
 
 
2154
 
2155
- $content = do_shortcode($content);
 
2156
 
2157
- $content = woo_feed_stripInvalidXml($content);
 
 
 
 
 
 
 
 
 
2158
 
2159
- // Covers all kinds of shortcodes
2160
- $expression = '/\[\/*[a-zA-Z1-90_| -=\'"\{\}]*\/*\]/m';
 
 
 
 
 
 
 
 
2161
 
2162
- $content = preg_replace($expression, '', $content);
 
 
 
 
 
 
 
 
 
 
 
 
 
2163
 
2164
- return strip_shortcodes($content);
2165
- }
2166
 
2167
- /*
2168
- * Retrieves product's parent category
2169
- *
2170
- * @param $product A Post/Product object
2171
- *
2172
- * @return WP_Term
2173
- * @since 4.4.19
2174
- * */
2175
- protected function product_parent_category_object($product)
2176
- {
2177
- global $parent_category_memo;
2178
- if (empty($parent_category_memo)) {
2179
- $parent_category_memo = [];
2180
- }
2181
-
2182
- $id = $product->get_id();
2183
- if ($product->is_type('variation')) {
2184
- $id = $product->get_parent_id();
2185
- }
2186
-
2187
- $taxonomy = 'product_cat';
2188
- $categories = wp_get_post_terms($id, $taxonomy);
2189
- $child_category = $categories[count($categories) - 1]; // Last selected category
2190
-
2191
- $parent_category = '';
2192
-
2193
- // Memoization for faster parent retrieval
2194
- if (
2195
- isset($parent_category_memo[$child_category->term_id])
2196
- && !empty($parent_category_memo[$child_category->term_id])
2197
- ) {
2198
- $parent_category = get_term_by('term_id', $parent_category_memo[$child_category->term_id], $taxonomy);
2199
- } else {
2200
- $parent_category = woo_feed_parent_category($child_category, $taxonomy);
2201
- $parent_category_memo[$child_category->term_id] = $parent_category->term_id;
2202
- }
2203
-
2204
- // Yoast SEO primary term fetching
2205
- if (class_exists('WPSEO_Primary_Term')) {
2206
- $wpseo_primary_term = new WPSEO_Primary_Term($taxonomy, $id);
2207
- $parent_category_id = $wpseo_primary_term->get_primary_term();
2208
- if (!empty($parent_category_id)) {
2209
- $parent_category = get_term_by('term_id', $parent_category_id, $taxonomy);
2210
- }
2211
- }
2212
-
2213
- return $parent_category;
2214
- }
2215
-
2216
- /**
2217
- * Get Product Parent/Main Category
2218
- *
2219
- * @param WC_Product $product
2220
- *
2221
- * @return string
2222
- *
2223
- */
2224
- protected function primary_category($product)
2225
- {
2226
- $parent_category = "";
2227
- $separator = apply_filters('woo_feed_product_type_separator', ' > ', $this->config, $product);
2228
- $full_category = $this->product_type($product);
2229
- if (!empty($full_category)) {
2230
- $full_category_array = explode($separator, $full_category);
2231
- $parent_category = $full_category_array[0];
2232
- }
2233
-
2234
- return apply_filters('woo_feed_filter_product_primary_category', $parent_category, $product, $this->config);
2235
- }
2236
-
2237
- /**
2238
- * Get Product Parent/Main Category ID
2239
- *
2240
- * @param WC_Product $product
2241
- *
2242
- * @return string
2243
- *
2244
- */
2245
- protected function primary_category_id($product)
2246
- {
2247
- $parent_category_id = "";
2248
- $separator = apply_filters('woo_feed_product_type_separator', ' > ', $this->config, $product);
2249
- $full_category = $this->product_type($product);
2250
- if (!empty($full_category)) {
2251
- $full_category_array = explode($separator, $full_category);
2252
- $parent_category_obj = get_term_by('name', $full_category_array[0], 'product_cat');
2253
- $parent_category_id = isset($parent_category_obj->term_id) ? $parent_category_obj->term_id : "";
2254
- }
2255
-
2256
- return apply_filters('woo_feed_filter_product_primary_category_id', $parent_category_id, $product, $this->config);
2257
- }
2258
-
2259
- /**
2260
- * Get Product Child Category
2261
- *
2262
- * @param WC_Product $product
2263
- *
2264
- * @return string
2265
- */
2266
- protected function child_category($product)
2267
- {
2268
- $child_category = "";
2269
- $separator = apply_filters('woo_feed_product_type_separator', ' > ', $this->config, $product);
2270
- $full_category = $this->product_type($product);
2271
- if (!empty($full_category)) {
2272
- $full_category_array = explode($separator, $full_category);
2273
- $child_category = end($full_category_array);
2274
- }
2275
-
2276
- return apply_filters('woo_feed_filter_product_child_category', $child_category, $product, $this->config);
2277
- }
2278
-
2279
- /**
2280
- * Get Product Child Category ID
2281
- *
2282
- * @param WC_Product $product
2283
- *
2284
- * @return string
2285
- */
2286
- protected function child_category_id($product)
2287
- {
2288
- $child_category_id = "";
2289
- $separator = apply_filters('woo_feed_product_type_separator', ' > ', $this->config, $product);
2290
- $full_category = $this->product_type($product);
2291
- if (!empty($full_category)) {
2292
- $full_category_array = explode($separator, $full_category);
2293
- $child_category_obj = get_term_by('name', end($full_category_array), 'product_cat');
2294
- $child_category_id = isset($child_category_obj->term_id) ? $child_category_obj->term_id : "";
2295
- }
2296
-
2297
- return apply_filters('woo_feed_filter_product_child_category_id', $child_category_id, $product, $this->config);
2298
- }
2299
-
2300
- /**
2301
- * Get Product Categories
2302
- *
2303
- * @param WC_Product $product
2304
- *
2305
- * @return string
2306
- * @since 3.2.0
2307
- *
2308
- */
2309
- protected function product_type($product)
2310
- {
2311
- $id = $product->get_id();
2312
- if ($product->is_type('variation')) {
2313
- $id = $product->get_parent_id();
2314
- }
2315
 
2316
- $separator = apply_filters('woo_feed_product_type_separator', ' > ', $this->config, $product);
 
 
 
 
 
 
2317
 
2318
- $product_type = woo_feed_strip_all_tags(wc_get_product_category_list($id, $separator));
 
2319
 
2320
- $product_categories = '';
2321
- $term_list = get_the_terms($id, 'product_cat');
 
2322
 
2323
- if (is_array($term_list)) {
2324
- $col = array_column($term_list, "term_id");
2325
- array_multisort($col, SORT_ASC, $term_list);
2326
- $term_list = array_column($term_list, "name");
2327
- $product_categories = implode($separator, $term_list);
2328
- }
2329
 
 
2330
 
2331
- return apply_filters('woo_feed_filter_product_local_category', $product_categories, $product, $this->config);
2332
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2333
 
2334
- /**
2335
- * Get Product Full Categories with unselected category parent
2336
- *
2337
- * @param WC_Product $product
2338
- *
2339
- * @return string
2340
- * @since 4.3.47
2341
- */
2342
- protected function product_full_cat($product)
2343
- {
2344
- // $id = $product->get_id();
2345
- // if ($product->is_type('variation')) {
2346
- // $id = $product->get_parent_id();
2347
- // }
2348
- //
2349
- // $separator = apply_filters('woo_feed_product_type_separator', '>', $this->config, $product);
2350
- //
2351
- // $product_type = woo_feed_get_terms_list_hierarchical_order($id);
2352
 
2353
- $product_type = $this->product_type($product);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2354
 
2355
- return apply_filters('woo_feed_filter_product_local_category', $product_type, $product, $this->config);
2356
- }
2357
 
2358
- /**
2359
- * Get Product URL
2360
- *
2361
- * @param WC_Product|WC_Product_Variation $product
2362
- *
2363
- * @return string
2364
- * @since 3.2.0
2365
- *
2366
- */
2367
- protected function link($product)
2368
- {
 
 
 
 
 
2369
 
2370
- $link = $product->get_permalink();
 
2371
 
2372
- $link = $this->add_utm_tracker($link);
2373
- return apply_filters('woo_feed_filter_product_link', $link, $product, $this->config);
2374
- }
 
 
 
 
 
 
 
 
 
2375
 
2376
- /**
2377
- * Adding UTM Tracker Query Arguments to URL
2378
- * @param string $url
2379
- *
2380
- * @return string $url
2381
- * @since 4.4.26
2382
- */
2383
- protected function add_utm_tracker($url)
2384
- {
 
 
 
 
 
 
2385
 
2386
- $utm = $this->config['campaign_parameters'];
2387
 
2388
- if (!empty($utm['utm_source']) && !empty($utm['utm_medium']) && !empty($utm['utm_campaign'])) {
2389
 
2390
- $utm = [
2391
- 'utm_source' => str_replace(' ', '+', $utm['utm_source']),
2392
- 'utm_medium' => str_replace(' ', '+', $utm['utm_medium']),
2393
- 'utm_campaign' => str_replace(' ', '+', $utm['utm_campaign']),
2394
- 'utm_term' => str_replace(' ', '+', $utm['utm_term']),
2395
- 'utm_content' => str_replace(' ', '+', $utm['utm_content']),
2396
- ];
2397
 
2398
- $url = add_query_arg(array_filter($utm), $url);
2399
 
2400
- }
 
2401
 
2402
- return $url;
2403
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2404
 
2405
- /**
2406
- * Get Parent Product URL
2407
- *
2408
- * @param WC_Product $product
2409
- *
2410
- * @return string
2411
- * @author Nazrul Islam Nayan
2412
- * @since 5.1.8
2413
- */
2414
- protected function parent_link($product)
2415
- {
2416
- if ($product->is_type('variation')) {
2417
- $product = wc_get_product($product->get_parent_id());
2418
- $link = $this->link($product);
2419
- } else {
2420
- $link = $this->link($product);
2421
- }
2422
-
2423
- return apply_filters('woo_feed_filter_product_parent_link', $link, $product, $this->config);
2424
- }
2425
-
2426
- /**
2427
- * Get Canonical Link
2428
- * @param WC_Product $product
2429
- * @return mixed
2430
- */
2431
- protected function canonical_link($product)
2432
- {
2433
- if ($product->is_type('variation')) {
2434
- $product = wc_get_product($product->get_parent_id());
2435
- $canonical_link = $product->get_permalink();
2436
- } else {
2437
- $canonical_link = $product->get_permalink();
2438
- }
2439
-
2440
- return apply_filters('woo_feed_filter_product_canonical_link', $canonical_link, $product, $this->config);
2441
- }
2442
-
2443
- /**
2444
- * Get External Product URL
2445
- *
2446
- * @param WC_Product $product
2447
- *
2448
- * @return string
2449
- * @since 3.2.0
2450
- *
2451
- */
2452
- protected function ex_link($product)
2453
- {
2454
- if ($product->is_type('external')) {
2455
- $utm = $this->config['campaign_parameters'];
2456
- if (!empty($utm['utm_source']) && !empty($utm['utm_medium']) && !empty($utm['utm_campaign'])) {
2457
- $utm = [
2458
- 'utm_source' => str_replace(' ', '+', $utm['utm_source']),
2459
- 'utm_medium' => str_replace(' ', '+', $utm['utm_medium']),
2460
- 'utm_campaign' => str_replace(' ', '+', $utm['utm_campaign']),
2461
- 'utm_term' => str_replace(' ', '+', $utm['utm_term']),
2462
- 'utm_content' => str_replace(' ', '+', $utm['utm_content']),
2463
- ];
2464
-
2465
- return add_query_arg(array_filter($utm), $product->get_product_url());
2466
- } else {
2467
- $ex_link = $product->get_product_url();
2468
- }
2469
- } else {
2470
- $ex_link = '';
2471
- }
2472
-
2473
- return apply_filters('woo_feed_filter_product_ex_link', $ex_link, $product, $this->config);
2474
- }
2475
-
2476
- /**
2477
- * Get Product Image
2478
- *
2479
- * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product Product Object.
2480
- *
2481
- * @return mixed
2482
- * @since 3.2.0
2483
- *
2484
- */
2485
- protected function image($product)
2486
- {
2487
- $image = '';
2488
- if ($product->is_type('variation')) {
2489
- // Variation product type
2490
- if (has_post_thumbnail($product->get_id())) {
2491
- $getImage = wp_get_attachment_image_src(get_post_thumbnail_id($product->get_id()), 'single-post-thumbnail');
2492
- $image = woo_feed_get_formatted_url($getImage[0]);
2493
- } elseif (has_post_thumbnail($product->get_parent_id())) {
2494
- $getImage = wp_get_attachment_image_src(get_post_thumbnail_id($product->get_parent_id()), 'single-post-thumbnail');
2495
- $image = woo_feed_get_formatted_url($getImage[0]);
2496
- }
2497
- } elseif (has_post_thumbnail($product->get_id())) { // All product type except variation
2498
- $getImage = wp_get_attachment_image_src(get_post_thumbnail_id($product->get_id()), 'single-post-thumbnail');
2499
- $image = isset($getImage[0]) ? woo_feed_get_formatted_url($getImage[0]) : '';
2500
- }
2501
-
2502
- return apply_filters('woo_feed_filter_product_image', $image, $product, $this->config);
2503
- }
2504
-
2505
- /**
2506
- * Get Product Featured Image. For product variations it will return the variable product image.
2507
- *
2508
- * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product Product Object.
2509
- *
2510
- * @return mixed
2511
- * @since 3.2.0
2512
- *
2513
- */
2514
- protected function feature_image($product)
2515
- {
2516
- if ($product->is_type('variation')) {
2517
- $id = $product->get_parent_id();
2518
- } else {
2519
- $id = $product->get_id();
2520
- }
2521
-
2522
- $getImage = wp_get_attachment_image_src(get_post_thumbnail_id($id), 'single-post-thumbnail');
2523
- $image = isset($getImage[0]) ? woo_feed_get_formatted_url($getImage[0]) : '';
2524
-
2525
- return apply_filters('woo_feed_filter_product_feature_image', $image, $product, $this->config);
2526
- }
2527
-
2528
- /**
2529
- * Get Comma Separated Product Images
2530
- *
2531
- * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product Product Object.
2532
- * @param string $additionalImg Specific Additional Image.
2533
- *
2534
- * @return mixed
2535
- * @since 3.2.0
2536
- *
2537
- */
2538
- protected function images($product, $additionalImg = '')
2539
- {
2540
- $imgUrls = $this->get_product_gallery($product);
2541
- $separator = ',';
2542
-
2543
- // Return Specific Additional Image URL
2544
- if ('' !== $additionalImg) {
2545
- if (array_key_exists($additionalImg, $imgUrls)) {
2546
- $images = $imgUrls[$additionalImg];
2547
- } else {
2548
- $images = '';
2549
- }
2550
- } else {
2551
- if (isset($this->config['provider']) && "idealo" === $this->config['provider']) {
2552
- $separator = ';';
2553
- }
2554
-
2555
- $images = implode($separator, array_filter($imgUrls));
2556
- }
2557
-
2558
- return apply_filters('woo_feed_filter_product_images', $images, $product, $this->config);
2559
- }
2560
-
2561
- /**
2562
- * Get Product Gallery Items (URL) array.
2563
- * This can contains empty array values
2564
- *
2565
- * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product
2566
- *
2567
- * @return string[]
2568
- * @since 3.2.6
2569
- */
2570
- protected function get_product_gallery($product)
2571
- {
2572
- $imgUrls = [];
2573
- $attachmentIds = [];
2574
-
2575
- if ($product->is_type('variation')) {
2576
- if (class_exists('Woo_Variation_Gallery')) {
2577
- /**
2578
- * Get Variation Additional Images for "Additional Variation Images Gallery for WooCommerce"
2579
- * @plugin Additional Variation Images Gallery for WooCommerce
2580
- * @link https://wordpress.org/plugins/woo-variation-gallery/
2581
- */
2582
- $attachmentIds = get_post_meta($product->get_id(), 'woo_variation_gallery_images', true);
2583
- } elseif (class_exists('WooProductVariationGallery')) {
2584
- /**
2585
- * Get Variation Additional Images for "Variation Images Gallery for WooCommerce"
2586
- * @plugin Variation Images Gallery for WooCommerce
2587
- * @link https://wordpress.org/plugins/woo-product-variation-gallery/
2588
- */
2589
- $attachmentIds = get_post_meta($product->get_id(), 'rtwpvg_images', true);
2590
- } elseif (class_exists('WC_Additional_Variation_Images')) {
2591
- /**
2592
- * Get Variation Additional Images for "WooCommerce Additional Variation Images"
2593
- * @plugin WooCommerce Additional Variation Images
2594
- * @link https://woocommerce.com/products/woocommerce-additional-variation-images/
2595
- */
2596
- $attachmentIds = explode(',', get_post_meta($product->get_id(), '_wc_additional_variation_images', true));
2597
- } elseif (class_exists('WOODMART_Theme')) {
2598
- /**
2599
- * Get Variation Additional Images for "WOODMART Theme -> Variation Gallery Images Feature"
2600
- * @theme WOODMART
2601
- * @link https://themeforest.net/item/woodmart-woocommerce-wordpress-theme/20264492
2602
- */
2603
- $var_id = $product->get_id();
2604
- $parent_id = $product->get_parent_id();
2605
-
2606
- $variation_obj = get_post_meta($parent_id, 'woodmart_variation_gallery_data', true);
2607
- if (isset($variation_obj) && isset($variation_obj[$var_id])) {
2608
- $attachmentIds = explode(',', $variation_obj[$var_id]);
2609
- } else {
2610
- $attachmentIds = explode(',', get_post_meta($var_id, 'wd_additional_variation_images_data', true));
2611
- }
2612
- } else {
2613
- /**
2614
- * If any Variation Gallery Image plugin not installed then get Variable Product Additional Image Ids .
2615
- */
2616
- $attachmentIds = wc_get_product($product->get_parent_id())->get_gallery_image_ids();
2617
- }
2618
- }
2619
-
2620
- /**
2621
- * Get Variable Product Gallery Image ids if Product is not a variation
2622
- * or variation does not have any gallery images
2623
- */
2624
- if (empty($attachmentIds)) {
2625
- $attachmentIds = $product->get_gallery_image_ids();
2626
- }
2627
-
2628
- if ($attachmentIds && is_array($attachmentIds)) {
2629
- $mKey = 1;
2630
- foreach ($attachmentIds as $attachmentId) {
2631
- $imgUrls[$mKey] = woo_feed_get_formatted_url(wp_get_attachment_url($attachmentId));
2632
- $mKey++;
2633
- }
2634
- }
2635
-
2636
- return $imgUrls;
2637
- }
2638
-
2639
- /**
2640
- * Get Product Condition
2641
- *
2642
- * @param WC_Product $product
2643
- *
2644
- * @return mixed
2645
- * @since 3.2.0
2646
- *
2647
- */
2648
- protected function condition($product)
2649
- {
2650
- return apply_filters('woo_feed_product_condition', 'new', $product);
2651
- }
2652
-
2653
- /**
2654
- * Get Product Type
2655
- *
2656
- * @param WC_Product $product
2657
- *
2658
- * @return mixed
2659
- * @since 3.2.0
2660
- *
2661
- */
2662
- protected function type($product)
2663
- {
2664
- return apply_filters('woo_feed_filter_product_type', $product->get_type(), $product, $this->config);
2665
- }
2666
-
2667
- /**
2668
- * Get Product is a bundle product or not
2669
- *
2670
- * @param WC_Product $product
2671
- *
2672
- * @return mixed
2673
- * @since 3.2.0
2674
- *
2675
- */
2676
- protected function is_bundle($product)
2677
- {
2678
- if ($product->is_type('bundle') || $product->is_type('yith_bundle')) {
2679
- $is_bundle = 'yes';
2680
- } else {
2681
- $is_bundle = 'no';
2682
- }
2683
-
2684
- return apply_filters('woo_feed_filter_product_is_bundle', $is_bundle, $product, $this->config);
2685
- }
2686
-
2687
- /**
2688
- * Get Product is a multi-pack product or not
2689
- *
2690
- * @param WC_Product $product
2691
- *
2692
- * @return mixed
2693
- * @since 3.2.0
2694
- *
2695
- */
2696
- protected function multipack($product)
2697
- {
2698
- $multi_pack = '';
2699
- if ($product->is_type('grouped')) {
2700
- $multi_pack = (!empty($product->get_children())) ? count($product->get_children()) : '';
2701
- }
2702
-
2703
- return $multi_pack;
2704
- }
2705
-
2706
- /**
2707
- * Get Product visibility status
2708
- *
2709
- * @param WC_Product $product
2710
- *
2711
- * @return mixed
2712
- * @since 3.2.0
2713
- *
2714
- */
2715
- protected function visibility($product)
2716
- {
2717
- return apply_filters('woo_feed_filter_product_visibility', $product->get_catalog_visibility(), $product, $this->config);
2718
- }
2719
-
2720
- /**
2721
- * Get Product Total Rating
2722
- *
2723
- * @param WC_Product $product
2724
- *
2725
- * @return mixed
2726
- * @since 3.2.0
2727
- *
2728
- */
2729
- protected function rating_total($product)
2730
- {
2731
- return apply_filters('woo_feed_filter_product_rating_total', $product->get_rating_count(), $product, $this->config);
2732
- }
2733
-
2734
- /**
2735
- * Get Product average rating
2736
- *
2737
- * @param WC_Product $product
2738
- *
2739
- * @return mixed
2740
- * @since 3.2.0
2741
- *
2742
- */
2743
- protected function rating_average($product)
2744
- {
2745
- return apply_filters('woo_feed_filter_product_rating_average', $product->get_average_rating(), $product, $this->config);
2746
- }
2747
-
2748
- /**
2749
- * Get Product tags
2750
- *
2751
- * @param WC_Product $product
2752
- *
2753
- * @return string
2754
- * @since 3.2.0
2755
- *
2756
- */
2757
- protected function tags($product)
2758
- {
2759
- $id = $product->get_id();
2760
- if ($product->is_type('variation')) {
2761
- $id = $product->get_parent_id();
2762
- }
2763
-
2764
- /**
2765
- * Separator for multiple tags
2766
- * @param string $separator
2767
- * @param array $config
2768
- * @param WC_Abstract_Legacy_Product $product
2769
- * @since 3.4.3
2770
- */
2771
- $separator = apply_filters('woo_feed_tags_separator', ',', $this->config, $product);
2772
-
2773
- $tags = woo_feed_strip_all_tags(get_the_term_list($id, 'product_tag', '', $separator, ''));
2774
-
2775
- return apply_filters('woo_feed_filter_product_tags', $tags, $product, $this->config);
2776
- }
2777
-
2778
- /**
2779
- * Get Product Parent Id
2780
- *
2781
- * @param WC_Product $product
2782
- *
2783
- * @return mixed
2784
- * @since 3.2.0
2785
- *
2786
- */
2787
- protected function item_group_id($product)
2788
- {
2789
- $id = $product->get_id();
2790
- if ($product->is_type('variation')) {
2791
- $id = $product->get_parent_id();
2792
- }
2793
-
2794
- return apply_filters('woo_feed_filter_product_item_group_id', $id, $product, $this->config);
2795
- }
2796
-
2797
- /**
2798
- * Get Product SKU
2799
- *
2800
- * @param WC_Product $product
2801
- *
2802
- * @return mixed
2803
- * @since 3.2.0
2804
- *
2805
- */
2806
- protected function sku($product)
2807
- {
2808
- return apply_filters('woo_feed_filter_product_sku', $product->get_sku(), $product, $this->config);
2809
- }
2810
-
2811
- /**
2812
- * Get Product SKU ID. It should come with after merging of sku and product id with '_' sign.
2813
- *
2814
- * @param WC_Product $product
2815
- *
2816
- * @return string
2817
- * @author Nazrul Islam Nayan
2818
- * @since 4.3.13
2819
- */
2820
- protected function sku_id($product)
2821
- {
2822
- $sku = !empty($product->get_sku()) ? $product->get_sku() . '_' : '';
2823
- $sku_id = $sku . $product->get_id();
2824
-
2825
- return apply_filters('woo_feed_filter_product_sku_id', $sku_id, $product, $this->config);
2826
- }
2827
-
2828
- /**
2829
- * Get Product Parent SKU
2830
- *
2831
- * @param WC_Product $product
2832
- *
2833
- * @return mixed
2834
- * @since 3.2.0
2835
- *
2836
- */
2837
- protected function parent_sku($product)
2838
- {
2839
- if ($product->is_type('variation')) {
2840
- $id = $product->get_parent_id();
2841
- $parent = wc_get_product($id);
2842
-
2843
- $parent_sku = $parent->get_sku();
2844
- } else {
2845
- $parent_sku = $product->get_sku();
2846
- }
2847
-
2848
- return apply_filters('woo_feed_filter_product_parent_sku', $parent_sku, $product, $this->config);
2849
- }
2850
-
2851
- /**
2852
- * Get Product Availability Status
2853
- *
2854
- * @param WC_Product $product
2855
- *
2856
- * @return mixed
2857
- * @since 3.2.0
2858
- *
2859
- */
2860
- protected function availability($product)
2861
- {
2862
- $status = $product->get_stock_status();
2863
- if ('instock' == $status) {
2864
- $status = 'in stock';
2865
- } elseif ('outofstock' == $status) {
2866
- $status = 'out of stock';
2867
- } elseif ('onbackorder' == $status) {
2868
- $status = 'on backorder';
2869
- }
2870
-
2871
- // set (_) as separator for google merchant
2872
- if (isset($this->config['provider']) && 'google' === $this->config['provider']) {
2873
- $status = explode(' ', $status);
2874
- $status = implode('_', $status);
2875
- }
2876
-
2877
- return apply_filters('woo_feed_filter_product_availability', $status, $product, $this->config);
2878
- }
2879
-
2880
- /**
2881
- * Get Product Availability Date
2882
- *
2883
- * @param WC_Product $product
2884
- *
2885
- * @return mixed
2886
- * @author Ohidul Islam
2887
- * @since 3.2.0
2888
- *
2889
- */
2890
- protected function availability_date($product)
2891
- {
2892
 
2893
- $feed_settings = get_option('woo_feed_settings');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2894
 
2895
- $availability_date_settings = isset($feed_settings['woo_feed_identifier']['availability_date'])
2896
- ? $feed_settings['woo_feed_identifier']['availability_date']
2897
- : 'enable';
2898
 
2899
- if ($product->get_stock_status() !== 'onbackorder' || $availability_date_settings === 'disable') {
2900
- return '';
2901
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2902
 
2903
- $meta_field_name = 'woo_feed_availability_date';
 
 
 
2904
 
2905
- if ($product->is_type('variation')) {
2906
- $meta_field_name .= '_var';
2907
- }
 
2908
 
2909
- $availability_date = get_post_meta($product->get_id(), $meta_field_name, true);
 
 
 
 
 
 
 
 
 
 
2910
 
2911
- if ('' !== $availability_date && in_array($this->config['provider'], [
2912
- 'google',
2913
- 'facebook',
2914
- 'pinterest',
2915
- 'bing',
2916
- 'snapchat',
2917
- ], true)) {
2918
- $availability_date = gmdate('c', strtotime($availability_date));
2919
- }
2920
 
2921
- return apply_filters('woo_feed_filter_product_availability_date', $availability_date, $product, $this->config);
2922
- }
2923
 
2924
- /**
2925
- * Get Product Add to Cart Link
2926
- *
2927
- * @param WC_Product $product
2928
- *
2929
- * @return string
2930
- * @author Nazrul Islam Nayan
2931
- * @since 5.1.8
2932
- */
2933
- protected function add_to_cart_link($product)
2934
- {
2935
- $url = $this->link($product);
2936
- $suffix = 'add-to-cart=' . $product->get_id();
2937
-
2938
- $add_to_cart_link = woo_feed_make_url_with_parameter($url, $suffix);
2939
-
2940
- return apply_filters('woo_feed_filter_product_add_to_cart_link', $add_to_cart_link, $product, $this->config);
2941
- }
2942
-
2943
- /**
2944
- * Get Product Quantity
2945
- *
2946
- * @param WC_Product $product
2947
- *
2948
- * @return mixed
2949
- * @since 3.2.0
2950
- *
2951
- */
2952
- protected function quantity($product)
2953
- {
2954
- $quantity = $product->get_stock_quantity();
2955
- $status = $product->get_stock_status();
2956
-
2957
- //when product is outofstock and it's quantity is empty, set quantity to 0
2958
- if ('outofstock' == $status && empty($quantity)) {
2959
- $quantity = 0;
2960
- }
2961
-
2962
- if ($product->is_type('variable') && $product->has_child()) {
2963
- $visible_children = $product->get_visible_children();
2964
- $qty = array();
2965
- foreach ($visible_children as $key => $child) {
2966
- $childQty = get_post_meta($child, '_stock', true);
2967
- $qty[] = (int)$childQty + 0;
2968
- }
2969
-
2970
- if (isset($this->config['variable_quantity'])) {
2971
- $vaQty = $this->config['variable_quantity'];
2972
- if ('max' == $vaQty) {
2973
- $quantity = max($qty);
2974
- } elseif ('min' == $vaQty) {
2975
- $quantity = min($qty);
2976
- } elseif ('sum' == $vaQty) {
2977
- $quantity = array_sum($qty);
2978
- } elseif ('first' == $vaQty) {
2979
- $quantity = ((int)$qty[0]);
2980
- }
2981
-
2982
- $quantity = array_sum($qty);
2983
- }
2984
- }
2985
-
2986
- return apply_filters('woo_feed_filter_product_quantity', $quantity, $product, $this->config);
2987
- }
2988
-
2989
- /**
2990
- * Get Product Currency
2991
- *
2992
- * @param WC_Product $product
2993
- *
2994
- * @return mixed
2995
- * @since 4.4.39
2996
- *
2997
- */
2998
- protected function currency($product)
2999
- {
3000
- $quantity = get_option('woocommerce_currency');
3001
 
3002
- return apply_filters('woo_feed_filter_product_currency', $quantity, $product, $this->config);
3003
- }
3004
 
3005
- /**
3006
- * Get Store currency code.
3007
- *
3008
- * @param WC_Product $product Product Object
3009
- * @return mixed|string
3010
- * @since 3.2.0
3011
- *
3012
- */
3013
- protected function store_currency($product)
3014
- {
3015
- return get_woocommerce_currency();
3016
- }
3017
-
3018
- /**
3019
- * Get Product Sale Price Start Date
3020
- *
3021
- * @param WC_Product $product
3022
- *
3023
- * @return mixed
3024
- * @since 3.2.0
3025
- *
3026
- */
3027
- protected function sale_price_sdate($product)
3028
- {
3029
- $startDate = $product->get_date_on_sale_from();
3030
- if (is_object($startDate)) {
3031
- $sale_price_sdate = $startDate->date_i18n();
3032
- } else {
3033
- $sale_price_sdate = '';
3034
- }
3035
-
3036
- return apply_filters('woo_feed_filter_product_sale_price_sdate', $sale_price_sdate, $product, $this->config);
3037
- }
3038
-
3039
- /**
3040
- * Get Product Sale Price End Date
3041
- *
3042
- * @param WC_Product $product
3043
- *
3044
- * @return mixed
3045
- * @since 3.2.0
3046
- *
3047
- */
3048
- protected function sale_price_edate($product)
3049
- {
3050
- $endDate = $product->get_date_on_sale_to();
3051
- if (is_object($endDate)) {
3052
- $sale_price_edate = $endDate->date_i18n();
3053
- } else {
3054
- $sale_price_edate = "";
3055
- }
3056
-
3057
- return apply_filters('woo_feed_filter_product_sale_price_edate', $sale_price_edate, $product, $this->config);
3058
- }
3059
-
3060
- /**
3061
- * Get feed currency
3062
- *
3063
- * @return mixed|string
3064
- */
3065
- protected function get_feed_currency()
3066
- {
3067
- $currency = get_woocommerce_currency();
3068
- if (isset($this->config['feedCurrency'])) {
3069
- $currency = $this->config['feedCurrency'];
3070
- }
3071
-
3072
- return $currency;
3073
- }
3074
-
3075
- /**
3076
- * Get Product Price by default WooCommerce Price Type (regular_price|price|sale_price).
3077
- *
3078
- * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product Object
3079
- * @param string $price_type Price Type (regular_price|price|sale_price)
3080
- * @param bool $tax Add tax with price (true|false)
3081
- *
3082
- * @return float|mixed|string|void
3083
- * @since 4.4.14
3084
- *
3085
- * @author Ohidul Islam
3086
- */
3087
- protected function get_price_by_price_type($product, $price_type, $tax)
3088
- {
3089
-
3090
- if ('regular_price' === $price_type) {
3091
- $price = $product->get_regular_price();
3092
- } elseif ('price' === $price_type) {
3093
- $price = $product->get_price();
3094
- } else {
3095
- $price = $product->get_sale_price();
3096
- }
3097
-
3098
- // Get WooCommerce Multi language Price by Currency.
3099
- $price = apply_filters('woo_feed_wcml_price',
3100
- $price, $product->get_id(), $this->get_feed_currency(), '_' . $price_type
3101
- );
3102
-
3103
- // Get Price with tax
3104
- if (true === $tax) {
3105
- $price = woo_feed_get_price_with_tax($price, $product);
3106
- }
3107
-
3108
- return $price;
3109
- }
3110
-
3111
- /**
3112
- * Get Product Price by Product Type.
3113
- *
3114
- * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product Object
3115
- * @param string $price_type Price Type (regular_price|price|sale_price)
3116
- * @param bool $tax Add tax with price (true|false)
3117
- *
3118
- * @return float|int|mixed|string
3119
- * @since 4.4.14
3120
- *
3121
- * @author Ohidul Islam
3122
- */
3123
- protected function get_price_by_product_type($product, $price_type, $tax = false)
3124
- {
3125
- if ($product->is_type('variable')) {
3126
- $price = $this->getVariableProductPrice($product, $price_type, $tax);
3127
- } elseif ($product->is_type('grouped')) {
3128
- $price = $this->getGroupProductPrice($product, $price_type, $tax);
3129
- } elseif ($product->is_type('bundle')) {
3130
- //TODO Diff taxation
3131
- $price = $this->getBundleProductPrice($product, $price_type, $tax);
3132
- } elseif ($product->is_type('composite')) {
3133
- //TODO Diff taxation
3134
- $price = $this->getCompositeProductPrice($product, $price_type, $tax);
3135
- } elseif ($product->is_type('bundled')) {
3136
- // iconic woocommerce product bundled plugin
3137
- $price = $this->iconic_bundle_product_price($product, $price_type, $tax);
3138
- } else {
3139
- $price = $this->get_price_by_price_type($product, $price_type, $tax);
3140
- }
3141
-
3142
- return $price > 0 ? $price : '';
3143
- }
3144
-
3145
- /**
3146
- * Get Product Regular Price
3147
- *
3148
- * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product Object.
3149
- *
3150
- * @return mixed
3151
- * @since 3.2.0
3152
- *
3153
- */
3154
- protected function price($product)
3155
- {
3156
 
3157
- $regular_price = $this->get_price_by_product_type($product, 'regular_price');
 
3158
 
3159
- return apply_filters('woo_feed_filter_product_price', $regular_price, $product, $this->config, false);
3160
- }
 
 
 
 
 
 
 
 
 
 
3161
 
3162
- /**
3163
- * Get Product Price
3164
- *
3165
- * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product object.
3166
- *
3167
- * @return int|float|mixed
3168
- * @since 3.2.0
3169
- *
3170
- */
3171
- protected function current_price($product)
3172
- {
3173
 
3174
- $price = $this->get_price_by_product_type($product, 'price');
 
 
 
 
 
 
 
 
 
 
 
3175
 
3176
- return apply_filters('woo_feed_filter_product_regular_price', $price, $product, $this->config, false);
3177
- }
3178
 
3179
- /**
3180
- * Get Product Sale Price
3181
- *
3182
- * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product object.
3183
- *
3184
- * @return mixed
3185
- * @since 3.2.0
3186
- *
3187
- */
3188
- protected function sale_price($product)
3189
- {
3190
 
3191
- $sale_price = $this->get_price_by_product_type($product, 'sale_price');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3192
 
3193
- return apply_filters('woo_feed_filter_product_sale_price', $sale_price, $product, $this->config, false);
3194
- }
 
3195
 
3196
- /**
3197
- * Get Product Regular Price with Tax
3198
- *
3199
- * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product Object.
3200
- *
3201
- * @return mixed
3202
- * @since 3.2.0
3203
- *
3204
- */
3205
- protected function price_with_tax($product)
3206
- {
3207
 
3208
- $regular_price_with_tax = $this->get_price_by_product_type($product, 'regular_price', true);
 
3209
 
3210
- return apply_filters('woo_feed_filter_product_price_with_tax', $regular_price_with_tax, $product, $this->config, true);
3211
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3212
 
3213
- /**
3214
- * Get Product Regular Price with Tax
3215
- *
3216
- * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product object.
3217
- *
3218
- * @return mixed
3219
- * @since 3.2.0
3220
- *
3221
- */
3222
- protected function current_price_with_tax($product)
3223
- {
3224
 
3225
- $price_with_tax = $this->get_price_by_product_type($product, 'price', true);
 
3226
 
3227
- return apply_filters('woo_feed_filter_product_regular_price_with_tax', $price_with_tax, $product, $this->config, true);
3228
- }
3229
 
3230
- /**
3231
- * Get Product Regular Price with Tax
3232
- *
3233
- * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product object.
3234
- *
3235
- * @return mixed
3236
- * @since 3.2.0
3237
- *
3238
- */
3239
- protected function sale_price_with_tax($product)
3240
- {
 
 
3241
 
3242
- $sale_price_with_tax = $this->get_price_by_product_type($product, 'sale_price', true);
 
3243
 
3244
- return apply_filters('woo_feed_filter_product_sale_price_with_tax', $sale_price_with_tax, $product, $this->config, true);
3245
- }
 
 
 
 
 
 
 
 
 
 
 
3246
 
3247
- /**
3248
- * Get Composite Product Price
3249
- *
3250
- * @param WC_Product|WC_Product_Composite|WC_Composite_Products $product Composite Product object.
3251
- * @param string $type Price Type (regular_price|price|sale_price)
3252
- * @param bool $tax Add tax with price (true|false)
3253
- *
3254
- * @return int|float|double
3255
- * @since 3.2.6
3256
- */
3257
- protected function getCompositeProductPrice($product, $type, $tax = false)
3258
- {
3259
- if (class_exists('WC_Product_Composite') && class_exists('WPCleverWooco')) {
3260
- // WPC Composite Product
3261
- return $this->get_wpc_composite_price($product, $type, $tax);
3262
- } elseif (class_exists('WC_Composite_Products')) {
3263
- // WooCommerce Composite Product
3264
- return $this->get_wc_composite_product_price($product, $type, $tax);
3265
- } else {
3266
- // Get Base Price for Others Composite Products.
3267
- // Note*: YITH does not auto select components. So no need to calculate component price.
3268
- return $this->get_price_by_price_type($product, $type, $tax);
3269
- }
3270
- }
3271
-
3272
- /**
3273
- * Get WooCommerce Composite Product Price
3274
- * Plugin URL: https://wordpress.org/plugins/wpc-composite-products/
3275
- * Product Type: composite
3276
- *
3277
- * @param WC_Product|WC_Product_Composite $product
3278
- * @param string $type Price Type (regular_price|price|sale_price)
3279
- * @param bool $tax Add tax with price (true|false)
3280
- * @return float|int|mixed|string|void
3281
- */
3282
- protected function get_wc_composite_product_price($product, $type, $tax)
3283
- {
3284
- $price = 0;
3285
- // Parent Component Price
3286
- $base_price = $this->get_price_by_price_type($product, $type, $tax);
3287
- if (isset($this->config['composite_price']) && 'all_product_price' == $this->config['composite_price']) {
3288
- $composite = new WC_Product_Composite($product);
3289
-
3290
- if ('price' === $type || 'sale_price' === $type) {
3291
- $price = $composite->get_composite_price();
3292
- } else {
3293
- $price = $composite->get_composite_regular_price();
3294
- }
3295
-
3296
- // Get WooCommerce Multi language Price by Currency.
3297
- $price = apply_filters('woo_feed_wcml_price',
3298
- $price, $product->get_id(), $this->get_feed_currency(), '_' . $type
3299
- );
3300
-
3301
- // Get Price with tax
3302
- if (true === $tax) {
3303
- $price = woo_feed_get_price_with_tax($price, $composite);
3304
- }
3305
- } else {
3306
- $price = $base_price;
3307
- }
3308
-
3309
- return $price > 0 ? $price : '';
3310
- }
3311
-
3312
- /**
3313
- * Get WPC Composite Product Price.
3314
- * Plugin URL: https://wordpress.org/plugins/wpc-composite-products/
3315
- * Product Type: composite
3316
- *
3317
- * @param WC_Product|WC_Product_Composite $product
3318
- * @param string $type Price Type (regular_price|price|sale_price)
3319
- * @param bool $tax Add tax with price (true|false)
3320
- * @return float|int|mixed|string|void
3321
- */
3322
- protected function get_wpc_composite_price($product, $type, $tax)
3323
- {
3324
- $price = 0;
3325
- // Parent Component Price
3326
- $base_price = $this->get_price_by_price_type($product, $type, $tax);
3327
- if (isset($this->config['composite_price']) && 'all_product_price' == $this->config['composite_price']) {
3328
- $components_price = 0;
3329
- $components = $product->get_components();
3330
- if (!empty($components) && is_array($components)) {
3331
- foreach ($components as $component) {
3332
- $products = explode(',', $component['products']);
3333
- foreach ($products as $key => $product_id) {
3334
- $default_product = wc_get_product($product_id);
3335
- if (is_object($default_product) && $default_product->is_in_stock()) {
3336
- $quantity = (isset($component['qty']) && $component['qty'] > 0) ? $component['qty'] : 1;
3337
- if ('products' == $component['type'] && empty($component['price'])) {
3338
- $components_price += $this->get_price_by_price_type($default_product, 'price', $tax);
3339
- $components_price *= $quantity;
3340
- } elseif ('products' == $component['type'] && !empty($component['price'])) {
3341
- $clever = new WPCleverWooco();
3342
- $old_price = $this->get_price_by_price_type($default_product, 'price', $tax);
3343
- $new_price = $component['price'];
3344
- $components_price += $clever::wooco_new_price($old_price, $new_price);
3345
- $components_price *= $quantity;
3346
- }
3347
- break; // Get first in stock product from component options.
3348
- }
3349
- }
3350
- }
3351
-
3352
- // Apply discount to components price.
3353
- $discount = $product->get_discount();
3354
- if ($discount > 0) {
3355
- $components_price -= (($discount / 100) * $components_price);
3356
- }
3357
- }
3358
-
3359
- if ('exclude' === $product->get_pricing()) {
3360
- $price = $components_price;
3361
- } elseif ('include' === $product->get_pricing()) {
3362
- $price = $components_price + $base_price;
3363
- } elseif ('only' === $product->get_pricing()) {
3364
- $price = $base_price;
3365
- }
3366
- } else {
3367
- $price = $base_price;
3368
- }
3369
-
3370
- return $price > 0 ? $price : '';
3371
- }
3372
-
3373
- /**
3374
- * Get total price of grouped product
3375
- *
3376
- * @param WC_Product_Grouped $grouped Grouped Product Object
3377
- * @param string $type Price Type (regular_price|price|sale_price)
3378
- * @param bool $tax Add tax with price (true|false)
3379
- *
3380
- * @return int|string
3381
- * @since 3.2.0
3382
- *
3383
- */
3384
- protected function getGroupProductPrice($grouped, $type, $tax = false)
3385
- {
3386
- $groupProductIds = $grouped->get_children();
3387
- $price = 0;
3388
- if (!empty($groupProductIds)) {
3389
- foreach ($groupProductIds as $id) {
3390
- $product = wc_get_product($id);
3391
- if (!is_object($product)) {
3392
- continue; // make sure that the product exists..
3393
- }
3394
-
3395
- $get_price = $this->get_price_by_product_type($product, $type, $tax);
3396
- if (!empty($get_price)) {
3397
- $price += $get_price;
3398
- }
3399
- }
3400
- }
3401
-
3402
- return $price > 0 ? $price : '';
3403
- }
3404
-
3405
- /**
3406
- * Get Variable Product Price
3407
- *
3408
- * @param WC_Product_Variable $variable Variable Product Object
3409
- * @param string $type Price Type (regular_price|price|sale_price)
3410
- * @param bool $tax Add tax with price (true|false)
3411
- *
3412
- * @return int|string
3413
- * @since 3.2.0
3414
- *
3415
- */
3416
- protected function getVariableProductPrice($variable, $type, $tax = false)
3417
- {
3418
- $min_max_first_default = apply_filters('woo_feed_variable_product_price_range', 'min');
3419
- if (isset($this->config['variable_price'])) {
3420
- $min_max_first_default = $this->config['variable_price'];
3421
- }
3422
-
3423
- $price = 0;
3424
- if ('first' == $min_max_first_default) {
3425
- $children = $variable->get_visible_children();
3426
- if (isset($children[0]) && !empty($children[0])) {
3427
- $variation = wc_get_product($children[0]);
3428
- $price = $this->get_price_by_product_type($variation, $type, $tax);
3429
- }
3430
- } else {
3431
- if ('regular_price' == $type) {
3432
- $price = $variable->get_variation_regular_price($min_max_first_default);
3433
- } elseif ('sale_price' == $type) {
3434
- $price = $variable->get_variation_sale_price($min_max_first_default);
3435
- } else {
3436
- $price = $variable->get_variation_price($min_max_first_default);
3437
- }
3438
-
3439
- // Get WooCommerce Multi language Price by Currency.
3440
- $price = apply_filters('woo_feed_wcml_price',
3441
- $price, $variable->get_id(), $this->get_feed_currency(), '_' . $type
3442
- );
3443
-
3444
- // Get Price with tax
3445
- if (true === $tax) {
3446
- $price = woo_feed_get_price_with_tax($price, $variable);
3447
- }
3448
- }
3449
-
3450
- return $price > 0 ? $price : '';
3451
- }
3452
-
3453
- /**
3454
- * Get Bundle Product Price
3455
- *
3456
- * @param WC_Product $product Product object.
3457
- * @param string $type Price Type (regular_price|price|sale_price)
3458
- * @param bool $tax Add tax with price (true|false)
3459
- *
3460
- * @return int|float|string
3461
- * @since 4.3.24
3462
- */
3463
- protected function getBundleProductPrice($product, $type, $tax = false)
3464
- {
3465
- if (class_exists('WC_Product_Bundle')) {//WC_Product_Bundle
3466
- $bundle = new WC_Product_Bundle($product);
3467
- if ('price' === $type || 'sale_price' === $type) {
3468
- $price = $bundle->get_bundle_price();
3469
- } else {
3470
- $price = $bundle->get_bundle_regular_price();
3471
- }
3472
-
3473
- // Get WooCommerce Multi language Price by Currency.
3474
- $price = apply_filters('woo_feed_wcml_price',
3475
- $price, $product->get_id(), $this->get_feed_currency(), '_' . $type
3476
- );
3477
-
3478
- // Get Price with tax
3479
- if (true === $tax) {
3480
- $price = woo_feed_get_price_with_tax($price, $bundle);
3481
- }
3482
- } else {
3483
- // Get Default price for others bundle products.
3484
- $price = $this->get_price_by_price_type($product, $type, $tax);
3485
- }
3486
-
3487
- return $price > 0 ? $price : '';
3488
- }
3489
-
3490
- /**
3491
- * Get price for Iconic woocommerce-bundled-products
3492
- *
3493
- * @param WC_Product $product Product object
3494
- * @param string $type Price Type (regular_price|price|sale_price)
3495
- * @param bool $tax Add tax with price (true|false)
3496
- *
3497
- * @return mixed $bundle_price
3498
- */
3499
- protected function iconic_bundle_product_price($product, $type, $tax = false)
3500
- {
3501
- if (!class_exists('WC_Product_Bundled')) {
3502
- return $product->get_price();
3503
- }
3504
-
3505
- $is_discounted = false;
3506
- $price = $product->get_price();
3507
- $bundle = new WC_Product_Bundled($product->get_id());
3508
- $iconic_bundle_product_type = (!is_null($bundle->options['price_display'])) ? $bundle->options['price_display'] : '';
3509
- $product_ids = $bundle->options['product_ids'];
3510
-
3511
- //set discount
3512
- if (!empty($bundle->options['fixed_discount'])) {
3513
- $is_discounted = true;
3514
- $discount = $bundle->options['fixed_discount'];
3515
- } else {
3516
- $is_discounted = false;
3517
- $discount = 0;
3518
- }
3519
-
3520
- // Get price
3521
- if (is_array($product_ids)) {
3522
- $product_prices = array_map(function ($id) use ($tax, $type, $is_discounted, $discount) {
3523
- $product = wc_get_product($id);
3524
-
3525
- return $this->get_price_by_price_type($product, $type, $tax);
3526
-
3527
- }, $product_ids);
3528
-
3529
- if ('range' === $iconic_bundle_product_type) {
3530
- $price = min($product_prices);
3531
- } else {
3532
- $price = array_sum($product_prices);
3533
- }
3534
- }
3535
-
3536
- // Get sale price if discount enabled
3537
- if ($is_discounted && ('sale_price' === $type || 'price' === $type)) {
3538
- $price -= $discount;
3539
- }
3540
-
3541
- // Get WooCommerce Multi language Price by Currency.
3542
- $price = apply_filters('woo_feed_wcml_price',
3543
- $price, $product->get_id(), $this->get_feed_currency(), '_' . $type
3544
- );
3545
-
3546
- // Get Price with tax
3547
- if (true === $tax) {
3548
- $price = woo_feed_get_price_with_tax($price, $bundle);
3549
- }
3550
-
3551
- return $price > 0 ? $price : '';
3552
- }
3553
-
3554
- /**
3555
- * Get Product Weight
3556
- *
3557
- * @param WC_Product $product
3558
- *
3559
- * @return mixed
3560
- * @since 3.2.0
3561
- *
3562
- */
3563
- protected function weight($product)
3564
- {
3565
- return apply_filters('woo_feed_filter_product_weight', $product->get_weight(), $product, $this->config);
3566
- }
3567
-
3568
- /**
3569
- * Get Product Weight Unit
3570
- *
3571
- * @param WC_Product $product
3572
- *
3573
- * @return mixed
3574
- * @since 5.2.7
3575
- *
3576
- */
3577
- protected function weight_unit($product)
3578
- {
3579
- return apply_filters('woo_feed_filter_product_weight_unit', get_option('woocommerce_weight_unit'), $product, $this->config);
3580
- }
3581
-
3582
- /**
3583
- * Get Product Width
3584
- *
3585
- * @param WC_Product $product
3586
- *
3587
- * @return mixed
3588
- * @since 3.2.0
3589
- *
3590
- */
3591
- protected function width($product)
3592
- {
3593
- return apply_filters('woo_feed_filter_product_width', $product->get_width(), $product, $this->config);
3594
- }
3595
-
3596
- /**
3597
- * Get Product Height
3598
- *
3599
- * @param WC_Product $product
3600
- *
3601
- * @return mixed
3602
- * @since 3.2.0
3603
- *
3604
- */
3605
- protected function height($product)
3606
- {
3607
- return apply_filters('woo_feed_filter_product_height', $product->get_height(), $product, $this->config);
3608
- }
3609
-
3610
- /**
3611
- * Get Product Length
3612
- *
3613
- * @param WC_Product $product
3614
- *
3615
- * @return mixed
3616
- * @since 3.2.0
3617
- *
3618
- */
3619
- protected function length($product)
3620
- {
3621
- return apply_filters('woo_feed_filter_product_length', $product->get_length(), $product, $this->config);
3622
- }
3623
-
3624
- /**
3625
- * Get Product Shipping
3626
- *
3627
- * @param WC_Product $product
3628
- *
3629
- * @return mixed
3630
- * @since 4.3.16
3631
- * @author Nazrul Islam Nayan
3632
- */
3633
- protected function shipping($product)
3634
- {
3635
- $feedBody = '';
3636
- $data = $this->data;
3637
-
3638
- if (isset($data['shipping_zones']) && !empty($data['shipping_zones'])) {
3639
- $zones = $data['shipping_zones'];
3640
-
3641
- if (in_array($this->config['provider'], ['google', 'facebook', 'pinterest', 'bing', 'snapchat'])) {
3642
- $get_shipping = new Woo_Feed_Shipping($this->config);
3643
- $feedBody .= $get_shipping->set_product($product)->set_shipping_zone($zones)->get_google_shipping();
3644
- }
3645
- }
3646
-
3647
- return apply_filters('woo_feed_filter_product_shipping', $feedBody, $product, $this->config);
3648
-
3649
- }
3650
-
3651
- /**
3652
- * Get Product Shipping Cost
3653
- *
3654
- * @param WC_Product $product
3655
- *
3656
- * @return mixed
3657
- * @since 5.1.20
3658
- * @author Nazrul Islam Nayan
3659
- */
3660
- protected function shipping_cost($product)
3661
- {
3662
- $shipping_obj = new Woo_Feed_Shipping($this->config);
3663
- $shipping_obj = $shipping_obj->set_product($product);
3664
-
3665
- return apply_filters('woo_feed_filter_product_shipping_cost', $shipping_obj->get_lowest_shipping_price(), $product, $this->config);
3666
- }
3667
-
3668
- /**
3669
- * Get Product Shipping Class
3670
- *
3671
- * @param WC_Product $product
3672
- *
3673
- * @return mixed
3674
- * @since 3.2.0
3675
- *
3676
- */
3677
- protected function shipping_class($product)
3678
- {
3679
- return apply_filters('woo_feed_filter_product_shipping_class', $product->get_shipping_class(), $product, $this->config);
3680
- }
3681
-
3682
- /**
3683
- * Get Product Author Name
3684
- *
3685
- * @param WC_Product $product
3686
- *
3687
- * @return mixed
3688
- * @since 3.2.0
3689
- *
3690
- */
3691
- protected function author_name($product)
3692
- {
3693
- $post = get_post($product->get_id());
3694
 
3695
- return get_the_author_meta('user_login', $post->post_author);
3696
- }
3697
 
3698
- /**
3699
- * Get Product Author Email
3700
- *
3701
- * @param WC_Product $product
3702
- *
3703
- * @return mixed
3704
- * @since 3.2.0
3705
- *
3706
- */
3707
- protected function author_email($product)
3708
- {
3709
- $post = get_post($product->get_id());
3710
 
3711
- return get_the_author_meta('user_email', $post->post_author);
3712
- }
3713
 
3714
- /**
3715
- * Get Product Created Date
3716
- *
3717
- * @param WC_Product $product
3718
- *
3719
- * @return mixed
3720
- * @since 3.2.0
3721
- *
3722
- */
3723
- protected function date_created($product)
3724
- {
3725
- $date_created = gmdate('Y-m-d', strtotime($product->get_date_created()));
3726
 
3727
- return apply_filters('woo_feed_filter_product_date_created', $date_created, $product, $this->config);
3728
- }
3729
 
3730
- /**
3731
- * Get Product Last Updated Date
3732
- *
3733
- * @param WC_Product $product
3734
- *
3735
- * @return mixed
3736
- * @since 3.2.0
3737
- *
3738
- */
3739
- protected function date_updated($product)
3740
- {
3741
- $date_updated = gmdate('Y-m-d', strtotime($product->get_date_modified()));
3742
 
3743
- return apply_filters('woo_feed_filter_product_date_updated', $date_updated, $product, $this->config);
3744
- }
3745
 
3746
- /**
3747
- * Get Product Tax
3748
- *
3749
- * @param WC_Product $product Product object.
3750
- * @return mixed
3751
- * @since 5.1.20
3752
- * @author Nazrul Islam Nayan
3753
- */
3754
- protected function tax($product)
3755
- {
3756
- $feedBody = '';
3757
- if (in_array($this->config['provider'], ['google', 'facebook', 'pinterest', 'bing', 'snapchat'])) {
3758
- $shipping_obj = new Woo_Feed_Shipping($this->config);
3759
- $shipping_obj = $shipping_obj->set_product($product);
3760
- $feedBody .= $shipping_obj->get_google_tax();
3761
- }
3762
-
3763
- return apply_filters('woo_feed_filter_product_tax', $feedBody, $product, $this->config);
3764
- }
3765
-
3766
- /**
3767
- * Get Product Tax class
3768
- * @param WC_Product $product Product object.
3769
- * @return string
3770
- */
3771
- protected function tax_class($product)
3772
- {
3773
- return apply_filters('woo_feed_filter_product_tax_class', $product->get_tax_class(), $product, $this->config);
3774
- }
3775
-
3776
- /**
3777
- * Get Product Tax Status
3778
- * @param WC_Product $product Product object.
3779
- * @return string
3780
- */
3781
- protected function tax_status($product)
3782
- {
3783
- return apply_filters('woo_feed_filter_product_tax_status', $product->get_tax_status(), $product, $this->config);
3784
- }
3785
-
3786
- /**
3787
- * Get CTX Feed Custom Field value
3788
- *
3789
- * @param WC_Product $product Product object.
3790
- * @param string $field custom field name.
3791
- * @return string
3792
- */
3793
- protected function getCustomField($product, $field)
3794
- {
3795
- $id = $product->get_id();
3796
- $meta = $field;
3797
- if ($product->is_type('variation')) {
3798
- $meta = $field . '_var';
3799
- }
3800
-
3801
- $meta = apply_filters('woo_feed_custom_field_meta', $meta, $product, $field);
3802
-
3803
- $new_meta_key = '';
3804
- $old_meta_key = '';
3805
-
3806
- if (strpos($meta, '_identifier') !== false) {
3807
- $old_meta_key = $meta;
3808
- $new_meta_key = str_replace('_identifier', '', $meta);
3809
- } else {
3810
- $new_meta_key = $meta;
3811
- $old_meta_key = str_replace('woo_feed_', 'woo_feed_identifier_', $meta);
3812
- }
3813
-
3814
- $new_meta_value = $this->getProductMeta($product, $new_meta_key);
3815
- $old_meta_value = $this->getProductMeta($product, $old_meta_key);
3816
-
3817
- if (empty($new_meta_value)) {
3818
- return $old_meta_value;
3819
- } else {
3820
- return $new_meta_value;
3821
- }
3822
-
3823
- }
3824
-
3825
- /**
3826
- * Get Product Sale Price Effected Date for Google Shopping
3827
- *
3828
- * @param WC_Product $product
3829
- *
3830
- * @return string
3831
- * @since 3.2.0
3832
- *
3833
- */
3834
- protected function sale_price_effective_date($product)
3835
- {
3836
- $effective_date = '';
3837
- $from = $this->sale_price_sdate($product);
3838
- $to = $this->sale_price_edate($product);
3839
- if (!empty($from) && !empty($to)) {
3840
- $from = gmdate('c', strtotime($from));
3841
- $to = gmdate('c', strtotime($to));
3842
-
3843
- $effective_date = $from . '/' . $to;
3844
- }
3845
-
3846
- return $effective_date;
3847
- }
3848
-
3849
- /**
3850
- * Ger Product Attribute
3851
- *
3852
- * @param WC_Product $product
3853
- * @param $attr
3854
- *
3855
- * @return string
3856
- * @since 2.2.3
3857
- *
3858
- */
3859
- protected function getProductAttribute($product, $attr)
3860
- {
3861
- $id = $product->get_id();
3862
-
3863
- if (woo_feed_wc_version_check(3.2)) {
3864
- if (woo_feed_wc_version_check(3.6)) {
3865
- $attr = str_replace('pa_', '', $attr);
3866
- }
3867
- $value = $product->get_attribute($attr);
3868
-
3869
- // if empty get attribute of parent post
3870
- if ('' === $value && $product->is_type('variation')) {
3871
- $product = wc_get_product($product->get_parent_id());
3872
- $value = $product->get_attribute($attr);
3873
- }
3874
-
3875
- $getproductattribute = $value;
3876
- } else {
3877
- $getproductattribute = implode(',', wc_get_product_terms($id, $attr, array('fields' => 'names')));
3878
- }
3879
-
3880
- return apply_filters('woo_feed_filter_product_attribute', $getproductattribute, $product, $attr, $this->config);
3881
- }
3882
-
3883
- /**
3884
- * Get Meta
3885
- *
3886
- * @param WC_Product $product
3887
- * @param string $meta post meta key
3888
- *
3889
- * @return mixed|string
3890
- * @since 2.2.3
3891
- *
3892
- */
3893
- protected function getProductMeta($product, $meta)
3894
- {
3895
- $value = get_post_meta($product->get_id(), $meta, true);
3896
- // if empty get meta value of parent post
3897
- if ('' === $value && $product->is_type('variation')) {
3898
- $value = get_post_meta($product->get_parent_id(), $meta, true);
3899
- }
3900
-
3901
- return apply_filters('woo_feed_filter_product_meta', $value, $product, $this->config);
3902
- }
3903
-
3904
- /**
3905
- * Filter Products by Conditions
3906
- *
3907
- * @param WC_Product $product
3908
- *
3909
- * @return bool|array
3910
- * @since 3.2.0
3911
- *
3912
- */
3913
- public function filter_product($product)
3914
- {
3915
- return true;
3916
- }
3917
-
3918
- /**
3919
- * Get Taxonomy
3920
- *
3921
- * @param WC_Product $product
3922
- * @param $taxonomy
3923
- *
3924
- * @return string
3925
- * @since 2.2.3
3926
- *
3927
- */
3928
- protected function getProductTaxonomy($product, $taxonomy)
3929
- {
3930
- $id = $product->get_id();
3931
- if ($product->is_type('variation')) {
3932
- $id = $product->get_parent_id();
3933
- }
3934
 
3935
- $separator = apply_filters('woo_feed_product_taxonomy_term_list_separator', ',', $this->config, $product);
 
3936
 
3937
- $term_list = get_the_term_list($id, $taxonomy, '', $separator, '');
 
 
 
 
 
 
 
 
 
3938
 
3939
- if (is_object($term_list) && get_class($term_list) === 'WP_Error') {
3940
- $term_list = '';
3941
- }
3942
 
3943
- $getproducttaxonomy = woo_feed_strip_all_tags($term_list);
 
 
 
 
 
 
 
 
 
3944
 
3945
- return apply_filters('woo_feed_filter_product_taxonomy', $getproducttaxonomy, $product, $this->config);
3946
- }
3947
 
3948
- /**
3949
- * Format price value
3950
- *
3951
- * @param string $name Attribute Name
3952
- * @param int $conditionName condition
3953
- * @param int $result price
3954
- *
3955
- * @return mixed
3956
- * @since 3.2.0
3957
- *
3958
- */
3959
- protected function price_format($name, $conditionName, $result)
3960
- {
3961
- $plus = '+';
3962
- $minus = '-';
3963
- $percent = '%';
3964
-
3965
- if (strpos($name, 'price') !== false) {
3966
- if (strpos($result, $plus) !== false && strpos($result, $percent) !== false) {
3967
- $result = str_replace('+', '', $result);
3968
- $result = str_replace('%', '', $result);
3969
- if (is_numeric($result)) {
3970
- $result = $conditionName + (($conditionName * $result) / 100);
3971
- }
3972
- } elseif (strpos($result, $minus) !== false && strpos($result, $percent) !== false) {
3973
- $result = str_replace('-', '', $result);
3974
- $result = str_replace('%', '', $result);
3975
- if (is_numeric($result)) {
3976
- $result = $conditionName - (($conditionName * $result) / 100);
3977
- }
3978
- } elseif (strpos($result, $plus) !== false) {
3979
- $result = str_replace('+', '', $result);
3980
- if (is_numeric($result)) {
3981
- $result = ($conditionName + $result);
3982
- }
3983
- } elseif (strpos($result, $minus) !== false) {
3984
- $result = str_replace('-', '', $result);
3985
- if (is_numeric($result)) {
3986
- $result = $conditionName - $result;
3987
- }
3988
- }
3989
- }
3990
-
3991
- return $result;
3992
- }
3993
-
3994
- /**
3995
- * Format output According to Output Type config
3996
- *
3997
- * @param string $output
3998
- * @param array $outputTypes
3999
- * @param WC_Product $product
4000
- * @param string $productAttribute
4001
- *
4002
- * @return float|int|string
4003
- * @since 3.2.0
4004
- *
4005
- */
4006
- protected function format_output($output, $outputTypes, $product, $productAttribute, $merchant_attribute)
4007
- {
4008
- if (!empty($outputTypes) && is_array($outputTypes)) {
4009
-
4010
- // Format Output According to output type
4011
- if (in_array(2, $outputTypes)) { // Strip Tags
4012
- $output = woo_feed_strip_all_tags(html_entity_decode($output));
4013
- }
4014
-
4015
- if (in_array(3, $outputTypes)) { // UTF-8 Encode
4016
- $output = utf8_encode($output);
4017
- }
4018
-
4019
- if (in_array(4, $outputTypes)) { // htmlentities
4020
- $output = htmlentities($output, ENT_QUOTES, 'UTF-8');
4021
- }
4022
-
4023
- if (in_array(5, $outputTypes)) { // Integer
4024
- $output = intval($output);
4025
- }
4026
-
4027
- if (in_array(6, $outputTypes)) { // Format Price
4028
- if (!empty($output) && $output > 0) {
4029
- $decimals = wc_get_price_decimals();
4030
- $decimal_separator = wc_get_price_decimal_separator();
4031
- $thousand_separator = wc_get_price_thousand_separator();
4032
- $output = (float)$output;
4033
-
4034
- if ("idealo" === $this->config['provider']) {
4035
- $output = number_format($output, $decimals, wp_specialchars_decode(stripslashes($decimal_separator)), wp_specialchars_decode(stripslashes($thousand_separator)));
4036
- } else {
4037
- $output = number_format($output, 2, '.', '');
4038
- }
4039
-
4040
- }
4041
- }
4042
-
4043
- if (in_array(7, $outputTypes)) { // Rounded Price
4044
- if (!empty($output) && $output > 0) {
4045
- $output = round($output);
4046
- $output = number_format($output, 2, '.', '');
4047
- }
4048
- }
4049
-
4050
- if (in_array(8, $outputTypes)) { // Delete Space
4051
- $output = htmlentities($output, null, 'utf-8');
4052
- $output = str_replace("&nbsp;", " ", $output);
4053
- $output = html_entity_decode($output);
4054
- $output = preg_replace("/\\s+/", ' ', $output);
4055
- }
4056
-
4057
- if (in_array(10, $outputTypes)) { // Remove Invalid Character
4058
- $output = woo_feed_stripInvalidXml($output);
4059
- }
4060
-
4061
- if (in_array(11, $outputTypes)) { // Remove ShortCodes
4062
- $output = $this->remove_short_codes($output);
4063
- }
4064
-
4065
- if (in_array(12, $outputTypes)) {
4066
- $output = ucwords(strtolower($output));
4067
- }
4068
-
4069
- if (in_array(13, $outputTypes)) {
4070
- $output = ucfirst(strtolower($output));
4071
- }
4072
-
4073
- if (in_array(14, $outputTypes)) {
4074
- $output = strtoupper(strtolower($output));
4075
- }
4076
-
4077
- if (in_array(15, $outputTypes)) {
4078
- $output = strtolower($output);
4079
- }
4080
-
4081
- if (in_array(16, $outputTypes)) {
4082
- if ('http' == substr($output, 0, 4)) {
4083
- $output = str_replace('http://', 'https://', $output);
4084
- }
4085
- }
4086
-
4087
- if (in_array(17, $outputTypes)) {
4088
- if ('http' == substr($output, 0, 4)) {
4089
- $output = str_replace('https://', 'http://', $output);
4090
- }
4091
- }
4092
-
4093
- if (in_array(18, $outputTypes)) { // only parent
4094
- if ($product->is_type('variation')) {
4095
- $id = $product->get_parent_id();
4096
- $parentProduct = wc_get_product($id);
4097
- $output = $this->getAttributeValueByType($parentProduct, $productAttribute, $merchant_attribute);
4098
- }
4099
- }
4100
-
4101
- if (in_array(19, $outputTypes)) { // child if parent empty
4102
- if ($product->is_type('variation')) {
4103
- $id = $product->get_parent_id();
4104
- $parentProduct = wc_get_product($id);
4105
- $output = $this->getAttributeValueByType($parentProduct, $productAttribute, $merchant_attribute);
4106
- if (empty($output)) {
4107
- $output = $this->getAttributeValueByType($product, $productAttribute, $merchant_attribute);
4108
- }
4109
- }
4110
- }
4111
-
4112
- if (in_array(20, $outputTypes)) { // parent if child empty
4113
- if ($product->is_type('variation')) {
4114
- $output = $this->getAttributeValueByType($product, $productAttribute, $merchant_attribute);
4115
- if (empty($output)) {
4116
- $id = $product->get_parent_id();
4117
- $parentProduct = wc_get_product($id);
4118
- $output = $this->getAttributeValueByType($parentProduct, $productAttribute, $merchant_attribute);
4119
- }
4120
- }
4121
- }
4122
-
4123
- if (in_array(9, $outputTypes) && !empty($output) && 'xml' === $this->config['feedType']) { // Add CDATA
4124
- $output = '<![CDATA[' . $output . ']]>';
4125
- }
4126
- }
4127
-
4128
- return $output;
4129
- }
4130
-
4131
- /**
4132
- * Add Prefix and Suffix with attribute value
4133
- *
4134
- * @param $output
4135
- * @param $prefix
4136
- * @param $suffix
4137
- * @param $attribute
4138
- *
4139
- * @return string
4140
- * @since 3.2.0
4141
- *
4142
- */
4143
- public function process_prefix_suffix($output, $prefix, $suffix, $attribute = '')
4144
- {
4145
- $cdata = false;
4146
- if ('' === $output) {
4147
- return $output;
4148
- }
4149
-
4150
- if (strpos($output, '<![CDATA[') !== false) {
4151
- $cdata = true;
4152
- $output = str_replace(array('<![CDATA[', ']]>'), array('', ''), $output);
4153
- }
4154
-
4155
- // Add Prefix before Output
4156
- if ('' !== $prefix) {
4157
- $output = "$prefix" . $output;
4158
- }
4159
-
4160
- // Add Suffix after Output
4161
- if ('' !== $suffix) {
4162
- if (array_key_exists(trim($suffix), get_woocommerce_currencies())) { // Add space before suffix if attribute contain price.
4163
- $output .= ' ' . $suffix;
4164
- } elseif (substr($output, 0, 4) === 'http') {
4165
- // Parse URL Parameters if available into suffix field
4166
- $output = woo_feed_make_url_with_parameter($output, $suffix);
4167
- } else {
4168
- $output .= (string)$suffix;
4169
- }
4170
- }
4171
-
4172
- if ($cdata) {
4173
- $output = '<![CDATA[' . $output . ']]>';
4174
- }
4175
-
4176
- return "$output";
4177
- }
4178
-
4179
- /**
4180
- * Get Subscription period
4181
- *
4182
- * @param WC_Product $product
4183
- *
4184
- * @return mixed
4185
- * @since 3.6.3
4186
- *
4187
- */
4188
- protected function subscription_period($product)
4189
- {
4190
- if (class_exists('WC_Subscriptions')) {
4191
- return $this->getProductMeta($product, '_subscription_period');
4192
- }
4193
- return '';
4194
- }
4195
-
4196
- /**
4197
- * Get Subscription period interval
4198
- *
4199
- * @param WC_Product $product
4200
- *
4201
- * @return mixed
4202
- * @since 3.6.3
4203
- *
4204
- */
4205
- protected function subscription_period_interval($product)
4206
- {
4207
- if (class_exists('WC_Subscriptions')) {
4208
- return $this->getProductMeta($product, '_subscription_period_interval');
4209
- }
4210
- return '';
4211
- }
4212
-
4213
- /**
4214
- * Get Subscription period interval
4215
- *
4216
- * @param WC_Product $product
4217
- *
4218
- * @return mixed
4219
- * @since 3.6.3
4220
- *
4221
- */
4222
- protected function subscription_amount($product)
4223
- {
4224
- return $this->price($product);
4225
- }
4226
-
4227
- /**
4228
- * Get Installment Amount
4229
- *
4230
- * @param WC_Product $product
4231
- *
4232
- * @return mixed
4233
- * @since 4.3.101
4234
- */
4235
- protected function installment_amount($product)
4236
- {
4237
- return $this->price($product);
4238
- }
4239
-
4240
- /**
4241
- * Get Installment Months
4242
- *
4243
- * @param WC_Product $product
4244
- *
4245
- * @return mixed
4246
- * @since 4.3.101
4247
- */
4248
- protected function installment_months($product)
4249
- {
4250
- if (class_exists('WC_Subscriptions')) {
4251
- return $this->getProductMeta($product, '_subscription_length');
4252
- }
4253
- return '';
4254
- }
4255
-
4256
-
4257
- /**
4258
- * Calculate unit_price_measure. If Unit custom fields by CTX feed are enabled then it will take value
4259
- * from custom fields or it will take values for WooCommerce Germanized Plugin if enabled.
4260
- *
4261
- * If variation values are empty then it will take value from variable product.
4262
- *
4263
- * @param WC_Product $product
4264
- *
4265
- * @return mixed
4266
- * @since 3.6.3
4267
- */
4268
- protected function unit_price_measure($product)
4269
- {
4270
- $unit_price_measure = '';
4271
- $identifiers = woo_feed_get_options('woo_feed_identifier');
4272
- if ('enable' === $identifiers['unit_pricing_base_measure']
4273
- && 'enable' === $identifiers['unit_pricing_measure']
4274
- && 'enable' === $identifiers['unit']
4275
- ) {
4276
- $unit = $this->getCustomField($product, 'woo_feed_unit');
4277
- $unit_price_measure = $this->getCustomField($product, 'woo_feed_unit_pricing_measure');
4278
-
4279
- $unit_price_measure .= " " . $unit;
4280
- }
4281
-
4282
- if (empty($unit_price_measure) && class_exists('WooCommerce_Germanized')) { // For WooCommerce Germanized Plugin
4283
- $unit = $this->getProductMeta($product, '_unit');
4284
- $unit_price_measure = $this->getProductMeta($product, '_unit_product');
4285
-
4286
- $unit_price_measure .= " " . $unit;
4287
- }
4288
-
4289
- return apply_filters('woo_feed_filter_unit_price_measure', $unit_price_measure, $product, $this->config);
4290
- }
4291
-
4292
- /**
4293
- * Calculate unit_price_base_measure. If Unit custom fields by CTX feed are enabled then it will take value
4294
- * from custom fields or it will take values for WooCommerce Germanized Plugin if enabled.
4295
- *
4296
- * If variation values are empty then it will take value from variable product.
4297
- *
4298
- * @param WC_Product $product
4299
- *
4300
- * @return mixed
4301
- * @since 3.6.3
4302
- */
4303
- protected function unit_price_base_measure($product)
4304
- {
4305
- $unit_price_base_measure = '';
4306
- $identifiers = woo_feed_get_options('woo_feed_identifier');
4307
- if ('enable' === $identifiers['unit_pricing_base_measure']
4308
- && 'enable' === $identifiers['unit_pricing_measure']
4309
- && 'enable' === $identifiers['unit']
4310
- ) {
4311
- $unit = $this->getCustomField($product, 'woo_feed_unit');
4312
- $unit_price_base_measure = $this->getCustomField($product, 'woo_feed_unit_pricing_base_measure');
4313
-
4314
- $unit_price_base_measure .= " " . $unit;
4315
- }
4316
-
4317
- if (empty($unit_price_base_measure) && class_exists('WooCommerce_Germanized')) { // For WooCommerce Germanized Plugin
4318
- $unit = $this->getProductMeta($product, '_unit');
4319
- $unit_price_base_measure = $this->getProductMeta($product, '_unit_base');
4320
-
4321
- $unit_price_base_measure .= " " . $unit;
4322
- }
4323
-
4324
- return apply_filters('woo_feed_filter_unit_price_base_measure', $unit_price_base_measure, $product, $this->config);
4325
- }
4326
-
4327
- /**
4328
- * Get GTIN value of WooCommerce Germanized Plugin
4329
- *
4330
- * @param WC_Product $product
4331
- *
4332
- * @return mixed
4333
- * @since 3.6.3
4334
- */
4335
- protected function wc_germanized_gtin($product)
4336
- {
4337
- $wc_germanized_gtin = '';
4338
- if (class_exists('WooCommerce_Germanized')) { // For WooCommerce Germanized Plugin
4339
- $wc_germanized_gtin = $this->getProductMeta($product, '_ts_gtin');
4340
- }
4341
-
4342
- return apply_filters('woo_feed_filter_wc_germanized_gtin', $wc_germanized_gtin, $product, $this->config);
4343
- }
4344
-
4345
- /**
4346
- * Get MPN value of WooCommerce Germanized Plugin
4347
- *
4348
- * @param WC_Product $product
4349
- *
4350
- * @return mixed
4351
- * @since 3.6.3
4352
- */
4353
- protected function wc_germanized_mpn($product)
4354
- {
4355
- $wc_germanized_mpn = '';
4356
- if (class_exists('WooCommerce_Germanized')) { // For WooCommerce Germanized Plugin
4357
- $wc_germanized_mpn = $this->getProductMeta($product, '_ts_mpn');
4358
- }
4359
-
4360
- return apply_filters('woo_feed_filter_wc_germanized_mpn', $wc_germanized_mpn, $product, $this->config);
4361
- }
4362
-
4363
-
4364
- /**
4365
- * Yoast Identifier attribute for gtin8
4366
- *
4367
- * @param WC_Product $product
4368
- *
4369
- * @return mixed
4370
- * @since 4.4.4
4371
- */
4372
- protected function yoast_gtin8($product)
4373
- {
4374
- $yoast_gtin8_value = woo_feed_get_yoast_identifiers_value('gtin8', $product);
4375
-
4376
- return apply_filters('yoast_gtin8_attribute_value', $yoast_gtin8_value, $product);
4377
- }
4378
-
4379
- /**
4380
- * Yoast Identifier attribute for gtin12
4381
- *
4382
- * @param WC_Product $product
4383
- *
4384
- * @return mixed
4385
- * @since 4.4.4
4386
- */
4387
- protected function yoast_gtin12($product)
4388
- {
4389
- $yoast_gtin12_value = woo_feed_get_yoast_identifiers_value('gtin12', $product);
4390
-
4391
- return apply_filters('yoast_gtin12_attribute_value', $yoast_gtin12_value, $product);
4392
- }
4393
-
4394
- /**
4395
- * Yoast Identifier attribute for gtin13
4396
- *
4397
- * @param WC_Product $product
4398
- *
4399
- * @return mixed
4400
- * @since 4.4.4
4401
- */
4402
- protected function yoast_gtin13($product)
4403
- {
4404
- $yoast_gtin13_value = woo_feed_get_yoast_identifiers_value('gtin13', $product);
4405
-
4406
- return apply_filters('yoast_gtin13_attribute_value', $yoast_gtin13_value, $product);
4407
- }
4408
-
4409
- /**
4410
- * Yoast Identifier attribute for gtin12
4411
- *
4412
- * @param WC_Product $product
4413
- *
4414
- * @return mixed
4415
- * @since 4.4.4
4416
- */
4417
- protected function yoast_gtin14($product)
4418
- {
4419
- $yoast_gtin14_value = woo_feed_get_yoast_identifiers_value('gtin14', $product);
4420
-
4421
- return apply_filters('yoast_gtin14_attribute_value', $yoast_gtin14_value, $product);
4422
- }
4423
-
4424
- /**
4425
- * Yoast Identifier attribute for isbn
4426
- *
4427
- * @param WC_Product $product
4428
- *
4429
- * @return mixed
4430
- * @since 4.4.4
4431
- */
4432
- protected function yoast_isbn($product)
4433
- {
4434
- $yoast_isbn_value = woo_feed_get_yoast_identifiers_value('isbn', $product);
4435
-
4436
- return apply_filters('yoast_isbn_attribute_value', $yoast_isbn_value, $product);
4437
- }
4438
-
4439
- /**
4440
- * Yoast Identifier attribute for mpn
4441
- *
4442
- * @param WC_Product $product
4443
- *
4444
- * @return mixed
4445
- * @since 4.4.4
4446
- */
4447
- protected function yoast_mpn($product)
4448
- {
4449
- $yoast_mpn_value = woo_feed_get_yoast_identifiers_value('mpn', $product);
4450
-
4451
- return apply_filters('yoast_mpn_attribute_value', $yoast_mpn_value, $product);
4452
- }
4453
-
4454
- /**
4455
- * Rank Math GTIN Identifier attribute
4456
- *
4457
- * @param WC_Product $product
4458
- *
4459
- * @return mixed
4460
- * @since 5.2.66
4461
- */
4462
- protected function rank_math_gtin($product)
4463
- {
4464
- $product_id = woo_feed_parent_product_id($product);
4465
- $rankmath_gtin_value = get_post_meta($product_id, '_rank_math_gtin_code');
4466
- $rankmath_gtin_value = !empty($rankmath_gtin_value) && is_array($rankmath_gtin_value) ? $rankmath_gtin_value[0] : '';
4467
 
4468
- return apply_filters('rankmath_gtin_attribute_value', $rankmath_gtin_value, $product);
4469
- }
4470
 
4471
  /**
4472
  * Get ACF Field values
@@ -4484,5 +4388,4 @@ class Woo_Feed_Products_v3
4484
 
4485
  return '';
4486
  }
4487
-
4488
  }
9
 
10
  use RankMath\Helper;
11
 
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ die();
14
  }
15
 
16
  /**
17
  * Class Woo_Feed_Products_v3
18
  */
19
+ class Woo_Feed_Products_v3 {
20
+ /**
21
+ * The Increment
22
+ * @var int
23
+ */
24
+ protected $pi = 0;
25
+ /**
26
+ * Feed file headers
27
+ *
28
+ * @var string|array
29
+ */
30
+ public $feedHeader;
31
+ /**
32
+ * Feed File Body
33
+ *
34
+ * @var string|array
35
+ */
36
+ public $feedBody;
37
+ /**
38
+ * Feed file footer
39
+ *
40
+ * @var string|array
41
+ */
42
+ public $feedFooter;
43
+ /**
44
+ * CSV|TXT column (text|word) enclosure
45
+ *
46
+ * @var string
47
+ */
48
+ protected $enclosure;
49
+ /**
50
+ * CSV|TXT column delimiter
51
+ *
52
+ * @var string
53
+ */
54
+ protected $delimiter;
55
+ /**
56
+ * Feed Rules
57
+ *
58
+ * @var array
59
+ */
60
+ protected $config;
61
+ /**
62
+ * Post status to query
63
+ *
64
+ * @var string
65
+ */
66
+ protected $post_status = 'publish';
67
+ /**
68
+ * Processed Products
69
+ *
70
+ * @var array
71
+ */
72
+ public $products = [];
 
73
 
74
 
75
+ /**
76
+ * Products IDs
77
+ *
78
+ * @var array
79
+ */
80
+ public $product_ids = [];
81
 
82
+ /**
83
+ * Feed Big Data
84
+ *
85
+ * @var array
86
+ */
87
+ public $data = [];
88
 
89
+ /**
90
+ * Processed Products
91
+ *
92
+ * @var array
93
+ */
94
+ public $product_types = [
95
+ 'simple',
96
+ 'variable',
97
+ 'variation',
98
+ 'grouped',
99
+ 'external',
100
+ 'composite',
101
+ 'bundle',
102
+ 'bundled',
103
+ 'yith_bundle',
104
+ 'yith-composite',
105
+ 'subscription',
106
+ 'variable-subscription',
107
+ 'woosb',
108
+ ];
109
+ /**
110
+ * Query Method Selector
111
+ *
112
+ * @var string
113
+ */
114
+ protected $queryType = 'wp';
115
+ /**
116
+ * To replace google product highlight attribute for CSV & TXT feed
117
+ * @var array
118
+ */
119
+ protected $google_product_highlights = array(
120
+ 'product highlight 1',
121
+ 'product highlight 2',
122
+ 'product highlight 3',
123
+ 'product highlight 4',
124
+ 'product highlight 5',
125
+ 'product highlight 6',
126
+ 'product highlight 7',
127
+ 'product highlight 8',
128
+ 'product highlight 9',
129
+ 'product highlight 10',
130
+ );
131
+
132
+ /**
133
+ * To replace google additional image link attribute for CSV & TXT feed
134
+ * @var array
135
+ */
136
+ protected $google_additional_image = array(
137
+ 'additional image link 1',
138
+ 'additional image link 2',
139
+ 'additional image link 3',
140
+ 'additional image link 4',
141
+ 'additional image link 5',
142
+ 'additional image link 6',
143
+ 'additional image link 7',
144
+ 'additional image link 8',
145
+ 'additional image link 9',
146
+ 'additional image link 10',
147
+ );
148
+ /**
149
+ * Google shipping tax attributes
150
+ * @var array
151
+ */
152
+ /**
153
+ * Google shipping tax attributes
154
+ *
155
+ * @var array
156
+ */
157
+ protected $google_shipping_tax = array(
158
+ 'shipping_country',
159
+ 'shipping_region',
160
+ 'shipping_postal_code',
161
+ 'shipping_service',
162
+ 'shipping_price',
163
+ 'min_handling_time',
164
+ 'max_handling_time',
165
+ 'min_transit_time',
166
+ 'max_transit_time',
167
+ 'tax',
168
+ 'tax_country',
169
+ 'tax_region',
170
+ 'tax_rate',
171
+ 'tax_ship',
172
+ 'installment_months',
173
+ 'installment_amount',
174
+ 'subscription_period',
175
+ 'subscription_period_length',
176
+ 'subscription_amount',
177
+ 'section_name',
178
+ 'attribute_name',
179
+ 'attribute_value',
180
+ 'unit_price_value',
181
+ 'unit_price_currency',
182
+ 'unit_price_unit',
183
+ 'additional_variant_label',
184
+ 'additional_variant_value',
185
+ );
186
+ /**
187
+ * XML Wrapper Array
188
+ * Contains 'header' and 'footer' for template.
189
+ * @var array
190
+ */
191
+ protected $xml_wrapper = [];
192
+
193
+
194
+ /**
195
+ * Attribute to skip in attribute loop for processing separately
196
+ *
197
+ * @var array
198
+ */
199
+ protected $skipped_merchant_attributes = array(
200
+ 'google' => array(
201
+ 'shipping_country',
202
+ 'shipping_region',
203
+ 'shipping_postal_code',
204
+ 'shipping_service',
205
+ 'shipping_price',
206
+ 'min_handling_time',
207
+ 'max_handling_time',
208
+ 'min_transit_time',
209
+ 'max_transit_time',
210
+ 'tax_country',
211
+ 'tax_region',
212
+ 'tax_rate',
213
+ 'tax_ship',
214
+ 'installment_months',
215
+ 'installment_amount',
216
+ 'subscription_period',
217
+ 'subscription_period_length',
218
+ 'subscription_amount',
219
+ 'section_name',
220
+ 'attribute_name',
221
+ 'attribute_value',
222
+ ),
223
+ 'facebook' => array(
224
+ 'shipping_country',
225
+ 'shipping_region',
226
+ 'shipping_service',
227
+ 'shipping_price',
228
+ 'tax_country',
229
+ 'tax_region',
230
+ 'tax_rate',
231
+ 'tax_ship',
232
+ 'installment_months',
233
+ 'installment_amount',
234
+ 'subscription_period',
235
+ 'subscription_period_length',
236
+ 'subscription_amount',
237
+ 'section_name',
238
+ 'attribute_name',
239
+ 'attribute_value',
240
+ 'unit_price_value',
241
+ 'unit_price_currency',
242
+ 'unit_price_unit',
243
+ 'additional_variant_label',
244
+ 'additional_variant_value',
245
+ ),
246
+ 'bing' => array(
247
+ 'shipping_country',
248
+ 'shipping_service',
249
+ 'shipping_price',
250
+ ),
251
+ 'pinterest' => array(
252
+ 'shipping_country',
253
+ 'shipping_service',
254
+ 'shipping_price',
255
+ 'shipping_region',
256
+ 'shipping_postal_code',
257
+ 'tax_country',
258
+ 'tax_region',
259
+ 'tax_rate',
260
+ 'tax_ship',
261
+ ),
262
+ );
263
+
264
+ /**
265
+ * Already Processed merchant attributes by the attribute loop
266
+ * this will ensure unique merchant attribute.
267
+ * @see Woo_Feed_Products_v::exclude_current_attribute()
268
+ * @var array
269
+ */
270
+ protected $processed_merchant_attributes = array();
271
+
272
+
273
+ /**
274
+ * Post meta prefix for dropdown item
275
+ * @since 3.1.18
276
+ * @var string
277
+ */
278
+ const POST_META_PREFIX = 'wf_cattr_';
279
+
280
+ /**
281
+ * Product Attribute (taxonomy & local) Prefix
282
+ * @since 3.1.18
283
+ * @var string
284
+ */
285
+ const PRODUCT_ATTRIBUTE_PREFIX = 'wf_attr_';
286
+
287
+ /**
288
+ * Product Taxonomy Prefix
289
+ * @since 3.1.18
290
+ * @var string
291
+ */
292
+ const PRODUCT_TAXONOMY_PREFIX = 'wf_taxo_';
293
+
294
+ /**
295
+ * Product Custom Field Prefix
296
+ *
297
+ * @since 3.1.18
298
+ * @var string
299
+ */
300
+ const PRODUCT_CUSTOM_IDENTIFIER = 'woo_feed_';
301
+
302
+ /**
303
+ * Product Category Mapping Prefix
304
+ * @since 3.1.18
305
+ * @var string
306
+ */
307
+ const PRODUCT_CATEGORY_MAPPING_PREFIX = 'wf_cmapping_';
308
+
309
+ /**
310
+ * WordPress Option Prefix
311
+ *
312
+ * @since 4.3.33
313
+ * @var string
314
+ * @author Nazrul Islam Nayan
315
+ */
316
+ const WP_OPTION_PREFIX = 'wf_option_';
317
 
318
  /**
319
  * Advance Custom Field (ACF) Prefix
323
  */
324
  const PRODUCT_ACF_FIELDS = 'acf_fields_';
325
 
326
+ /**
327
+ * Woo_Feed_Products_v3 constructor.
328
+ *
329
+ * @param $config
330
+ *
331
+ * @return void
332
+ */
333
+ public function __construct( $config ) {
334
+ $this->config = woo_feed_parse_feed_rules( $config );
335
+ $this->queryType = woo_feed_get_options( 'product_query_type' );
336
+ $this->process_xml_wrapper();
337
+ woo_feed_log_feed_process( $this->config['filename'], sprintf( 'Current Query Type is %s', $this->queryType ) );
338
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
339
 
340
+ /**
341
+ * Generate Query Args For WP/WC query class
342
+ *
343
+ * @param string $type
344
+ *
345
+ * @return array
346
+ */
347
+ protected function get_query_args( $type = 'wc' ) {
348
+ $args = [];
349
+
350
+ // Include Product Variations with db query if configured
351
+ $variation_query = woo_feed_get_options( 'variation_query_type' );
352
+
353
+ if ( 'wc' === $type ) {
354
+ $product_types = $this->product_types;
355
+ if ( 'variable' === $variation_query ) {
356
+ $variation = array_search( 'variation', $product_types, true );
357
+ if ( $variation ) {
358
+ unset( $product_types[ $variation ] );
359
+ }
360
+ }
361
+
362
+ $args = array(
363
+ 'limit' => - 1, // phpcs:ignore
364
+ 'status' => $this->post_status,
365
+ 'type' => $product_types,
366
+ 'orderby' => 'date',
367
+ 'order' => 'DESC',
368
+ 'return' => 'ids',
369
+ 'suppress_filters' => false,
370
+ );
371
+ }
372
 
373
+ if ( 'wp' === $type ) {
374
+
375
+ $post_type = 'product';
376
+ // Include Product Variations with db query if configured
377
+ $variation_query = woo_feed_get_options( 'variation_query_type' );
378
+ if ( 'individual' === $variation_query ) {
379
+ $post_type = [ 'product', 'product_variation' ];
380
+ }
381
+
382
+ $args = array(
383
+ 'posts_per_page' => - 1, // phpcs:ignore
384
+ 'post_type' => $post_type,
385
+ 'post_status' => 'publish',
386
+ 'order' => 'DESC',
387
+ 'fields' => 'ids',
388
+ 'cache_results' => false,
389
+ 'update_post_meta_cache' => false,
390
+ 'update_post_term_cache' => false,
391
+ 'suppress_filters' => false,
392
+ );
393
+ }
394
 
395
+ return $args;
396
+ }
 
397
 
398
+ /**
399
+ * Get Products using WC_Product_Query
400
+ *
401
+ * @return array
402
+ */
403
+ public function get_wc_query_products() {
404
+ $args = $this->get_query_args( 'wc' );
405
+ if ( woo_feed_is_debugging_enabled() ) {
406
+ woo_feed_log_feed_process( $this->config['filename'], 'WC_Product_Query Args::' . PHP_EOL . print_r( $args, true ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
407
+ woo_feed_log( $this->config['filename'], 'WC_Product_Query Args::' . PHP_EOL . print_r( $args, true ), 'info' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
408
+ }
409
+ $query = new WC_Product_Query( $args );
410
+ if ( woo_feed_is_debugging_enabled() ) {
411
+ woo_feed_log_feed_process( $this->config['filename'], sprintf( 'WC_Product_Query Args ::' . PHP_EOL . '%s', print_r( $args, true ) ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
412
+ }
413
 
414
+ return $query->get_products();
415
+ }
416
 
417
+ /**
418
+ * Get Products using WP_Query
419
+ *
420
+ * return array
421
+ */
422
+ public function get_wp_query_products() {
423
+ $args = $this->get_query_args( 'wp' );
424
+ $query = new WP_Query( $args );
425
+ if ( ! is_wp_error( $query ) && woo_feed_is_debugging_enabled() ) {
426
+ woo_feed_log_feed_process( $this->config['filename'], 'WC_Product_Query Args::' . PHP_EOL . print_r( $args, true ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
427
+ woo_feed_log_feed_process( $this->config['filename'], sprintf( 'WP_Query Request ::' . PHP_EOL . '%s', $query->request ) );
428
+ woo_feed_log( $this->config['filename'], 'WC_Product_Query Args::' . PHP_EOL . print_r( $args, true ), 'info' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
429
+ woo_feed_log( $this->config['filename'], sprintf( 'WP_Query Request ::' . PHP_EOL . '%s', $query->request ), 'info' );
430
+ }
431
 
432
+ return $query->get_posts();
433
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
434
 
435
+ /**
436
+ * Get products
437
+ *
438
+ * @return array
439
+ */
440
+ public function query_products() {
441
+ $products = [];
442
+ if ( 'wc' == $this->queryType ) {
443
+ $products = $this->get_wc_query_products();
444
+ } elseif ( 'wp' == $this->queryType ) {
445
+ $products = $this->get_wp_query_products();
446
+ } elseif ( 'both' == $this->queryType ) {
447
+ $wc = $this->get_wc_query_products();
448
+ $wp = $this->get_wp_query_products();
449
+ $products = array_unique( array_merge( $wc, $wp ) );
450
+ }
451
+
452
+ //set product ids
453
+ $this->product_ids = $products;
454
+
455
+ return $products;
456
+ }
457
+
458
+ /**
459
+ * Organize Feed Attribute config
460
+ * @return array|bool
461
+ */
462
+ public function get_attribute_config() {
463
+ if ( empty( $this->config ) ) {
464
+ return false;
465
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
466
 
467
+ $attributeConfig = array();
468
+ $merchantAttributes = $this->config['mattributes'];
469
+ if ( ! empty( $merchantAttributes ) ) {
470
+ $i = 0;
471
+ foreach ( $merchantAttributes as $key => $value ) {
472
+ $attributeConfig[ $i ]['mattributes'] = $value;
473
+ $attributeConfig[ $i ]['prefix'] = $this->config['prefix'][ $key ];
474
+ $attributeConfig[ $i ]['type'] = $this->config['type'][ $key ];
475
+ $attributeConfig[ $i ]['attributes'] = $this->config['attributes'][ $key ];
476
+ $attributeConfig[ $i ]['default'] = $this->config['default'][ $key ];
477
+ $attributeConfig[ $i ]['suffix'] = $this->config['suffix'][ $key ];
478
+ $attributeConfig[ $i ]['output_type'] = $this->config['output_type'][ $key ];
479
+ $attributeConfig[ $i ]['limit'] = $this->config['limit'][ $key ];
480
+ $i ++;
481
+ }
482
+ }
483
 
484
+ return $attributeConfig;
485
+ }
 
 
 
486
 
487
+ /**
488
+ * Get Product Information according to feed config
489
+ *
490
+ * @param int[] $productIds
491
+ *
492
+ * @return array
493
+ * @since 3.2.0
494
+ *
495
+ */
496
+ public function get_products( $productIds ) {
497
 
498
+ if ( empty( $productIds ) ) {
499
+ return [];
500
+ }
501
 
502
+ //filter big data
503
+ $this->data = apply_filters( "woo_feed_feed_big_data", $this->data, $productIds, $this->config );
504
+
505
+ /**
506
+ * Fires before looping through request product for getting product data
507
+ *
508
+ * @param int[] $productIds
509
+ * @param array $feedConfig
510
+ *
511
+ * @since 3.2.10
512
+ */
513
+ do_action( 'woo_feed_before_product_loop', $productIds, $this->config );
514
+
515
+ foreach ( $productIds as $key => $pid ) {
516
+ woo_feed_log_feed_process( $this->config['filename'], sprintf( 'Loading Product Data For %d.', $pid ) );
517
+ $product = wc_get_product( $pid );
518
+
519
+ if ( $this->exclude_from_loop( $product ) ) {
520
+ continue;
521
+ }
522
+
523
+ if ( $this->process_variation( $product ) ) {
524
+ continue;
525
+ }
526
+
527
+ if ( ! $this->filter_product( $product ) ) {
528
+ woo_feed_log_feed_process( $this->config['filename'], 'Skipping Product :: Matched with filter conditions' );
529
+ continue;
530
+ }
531
+
532
+ woo_feed_log_feed_process( $this->config['filename'], 'Formatting Feed Data...' );
533
+
534
+ // Add Single item wrapper before product info loop start
535
+ if ( 'xml' == $this->config['feedType'] ) {
536
+ $this->feedBody .= "\n";
537
+ $this->feedBody .= '<' . $this->config['itemWrapper'] . '>';
538
+ $this->feedBody .= "\n";
539
+ }
540
+
541
+ // reset processed attribute list before loop
542
+ $this->processed_merchant_attributes = [];
543
+
544
+ // Process attribute values
545
+ $this->process_attributes( $product );
546
+
547
+ try {
548
+ woo_feed_log_feed_process( $this->config['filename'], 'Processing Merchant Specific Fields' );
549
+ // Process feed data for uncommon merchant feed like Google,Facebook,Pinterest
550
+ $this->process_for_merchant( $product, $this->pi );
551
+ } catch ( Exception $e ) {
552
+ $message = 'Error Processing Merchant Specific Fields.' . PHP_EOL . 'Caught Exception :: ' . $e->getMessage();
553
+ woo_feed_log( $this->config['filename'], $message, 'critical', $e, true );
554
+ woo_feed_log_fatal_error( $message, $e );
555
+ }
556
+
557
+ if ( 'xml' == $this->config['feedType'] ) {
558
+ if ( empty( $this->feedHeader ) ) {
559
+ $this->feedHeader = $this->process_xml_feed_header();
560
+ $this->feedFooter = $this->process_xml_feed_footer();
561
+
562
+ }
563
+
564
+ $this->feedBody .= '</' . $this->config['itemWrapper'] . '>';
565
+
566
+
567
+ } elseif ( 'txt' == $this->config['feedType'] ) {
568
+ if ( empty( $this->feedHeader ) ) {
569
+ $this->process_txt_feed_header();
570
+ }
571
+ $this->process_txt_feed_body();
572
+ } elseif ( 'csv' == $this->config['feedType'] || 'xls' == $this->config['feedType'] ) {
573
+ if ( empty( $this->feedHeader ) ) {
574
+ $this->process_csv_feed_header();
575
+ }
576
+ $this->process_csv_feed_body();
577
+ } elseif ( 'json' == $this->config['feedType'] ) {
578
+ $this->process_json_feed_body();
579
+ }
580
+ woo_feed_log_feed_process( $this->config['filename'], 'Done Formatting...' );
581
+ $this->pi ++;
582
+ }
583
 
584
+ /**
585
+ * Fires after looping through request product for getting product data
586
+ *
587
+ * @param int[] $productIds
588
+ * @param array $feedConfig
589
+ *
590
+ * @since 3.2.10
591
+ */
592
+ do_action( 'woo_feed_after_product_loop', $productIds, $this->config );
593
+
594
+ return $this->products;
595
+ }
596
+
597
+ /**
598
+ * Process product variations
599
+ *
600
+ * @param WC_Abstract_Legacy_Product $product
601
+ *
602
+ * @return bool
603
+ * @since 3.3.9
604
+ */
605
+ protected function process_variation( $product ) {
606
+ // Apply variable and variation settings
607
+ if ( $product->is_type( 'variable' ) && $product->has_child() ) {
608
+ $this->pi ++;
609
+
610
+ $variation_query = woo_feed_get_options( 'variation_query_type' );
611
+ if ( 'variable' === $variation_query ) {
612
+ $variations = $product->get_visible_children();
613
+ if ( is_array( $variations ) && ( sizeof( $variations ) > 0 ) ) {
614
+ if ( woo_feed_is_debugging_enabled() ) {
615
+ woo_feed_log_feed_process( $this->config['filename'], sprintf( 'Getting Variation Product(s) :: %s', implode( ', ', $variations ) ) );
616
+ }
617
+ $this->get_products( $variations );
618
+ }
619
+ }
620
+ return true;
621
+ }
622
+
623
+ return false;
624
+ }
625
+
626
+ /**
627
+ * Process The Attributes and assign value to merchant attribute
628
+ *
629
+ * @param WC_Abstract_Legacy_Product $product
630
+ *
631
+ * @return void
632
+ * @since 3.3.9
633
+ */
634
+ protected function process_attributes( $product ) {
635
+ // print_r($this->config['attributes']);
636
+ // Get Product Attribute values by type and assign to product array
637
+ foreach ( $this->config['attributes'] as $attr_key => $attribute ) {
638
+
639
+ $merchant_attribute = isset( $this->config['mattributes'][ $attr_key ] ) ? $this->config['mattributes'][ $attr_key ] : '';
640
+
641
+ if ( $this->exclude_current_attribute( $product, $merchant_attribute, $attribute ) ) {
642
+ continue;
643
+ }
644
+
645
+ // Add Prefix and Suffix into Output
646
+ $prefix = $this->config['prefix'][ $attr_key ];
647
+ $suffix = $this->config['suffix'][ $attr_key ];
648
+ $merchant = $this->config['provider'];
649
+ $feedType = $this->config['feedType'];
650
+
651
+ if ( 'pattern' == $this->config['type'][ $attr_key ] ) {
652
+ $attributeValue = $this->config['default'][ $attr_key ];
653
+ } else { // Get Pattern value
654
+ $attributeValue = $this->getAttributeValueByType( $product, $attribute, $merchant_attribute );
655
+ }
656
+
657
+ // Format Output according to Output Type config.
658
+ if ( isset( $this->config['output_type'][ $attr_key ] ) ) {
659
+ $outputType = $this->config['output_type'][ $attr_key ];
660
+ $attributeValue = $this->format_output( $attributeValue, $this->config['output_type'][ $attr_key ], $product, $attribute, $merchant_attribute );
661
+ }
662
+
663
+ // Limit Output.
664
+ if ( isset( $this->config['limit'][ $attr_key ] ) ) {
665
+ $attributeValue = $this->crop_string( $attributeValue, 0, $this->config['limit'][ $attr_key ] );
666
+ }
667
+
668
+ // Process prefix and suffix.
669
+ $attributeValue = $this->process_prefix_suffix( $attributeValue, $prefix, $suffix, $attribute );
670
+
671
+ if ( 'xml' == $feedType ) {
672
+
673
+ // Replace XML Nodes according to merchant requirement.
674
+ $getReplacedAttribute = woo_feed_replace_to_merchant_attribute( $merchant_attribute, $merchant, $feedType );
675
+
676
+ // XML does not support space in node. So replace Space with Underscore.
677
+ $getReplacedAttribute = str_replace( ' ', '_', $getReplacedAttribute );
678
+
679
+ // Trim XML Element text & Encode for UTF-8.
680
+ if ( ! empty( $attributeValue ) ) {
681
+ $attributeValue = trim( $attributeValue );
682
+
683
+ if ( 'custom' === $this->config['provider'] && strpos( $attributeValue, '<![CDATA[' ) === false ) {
684
+ $attributeValue = htmlentities( $attributeValue, ENT_XML1 | ENT_QUOTES, 'UTF-8' );
685
+ }
686
+ }
687
+
688
+ // Add closing XML node if value is empty
689
+ if ( '' !== $attributeValue ) {
690
+ // Add CDATA wrapper for XML feed to prevent XML error.
691
+ $attributeValue = woo_feed_add_cdata( $merchant_attribute, $attributeValue, $merchant, $this->config['feedType'] );
692
+ // print_r($attributeValue);echo"<br/>";
693
+ // Strip slash from output.
694
+ $attributeValue = stripslashes( $attributeValue );
695
+ $this->feedBody .= '<' . $getReplacedAttribute . '>' . "$attributeValue" . '</' . $getReplacedAttribute . '>';
696
+ $this->feedBody .= "\n";
697
+ } else {
698
+ $this->feedBody .= '<' . $getReplacedAttribute . '/>';
699
+ $this->feedBody .= "\n";
700
+ }
701
+
702
+ } elseif ( in_array( $feedType, [ 'csv', 'tsv', 'xls' ], true ) ) {
703
+ $merchant_attribute = woo_feed_replace_to_merchant_attribute( $merchant_attribute, $merchant, $feedType );
704
+ $merchant_attribute = $this->processStringForCSV( $merchant_attribute );
705
+
706
+ if ( "shipping" === $merchant_attribute && 'bing' == $this->config['provider'] ) {
707
+ $merchant_attribute = 'shipping(country:service:price)';
708
+ } elseif ( "shipping" === $merchant_attribute ) {
709
+ $merchant_attribute = 'shipping(country:region:service:price)';
710
+ }
711
+
712
+ if ( "tax" === $merchant_attribute ) {
713
+ $merchant_attribute = 'tax(country:region:rate:tax_ship)';
714
+ }
715
+
716
+ $attributeValue = $this->processStringForCSV( $attributeValue );
717
+
718
+ } elseif ( 'txt' == $feedType ) {
719
+ $merchant_attribute = woo_feed_replace_to_merchant_attribute( $merchant_attribute, $merchant, $feedType );
720
+ $merchant_attribute = $this->processStringForTXT( $merchant_attribute );
721
+
722
+ if ( "shipping" === $merchant_attribute && 'bing' == $this->config['provider'] ) {
723
+ $merchant_attribute = 'shipping(country:service:price)';
724
+ } elseif ( "shipping" === $merchant_attribute ) {
725
+ $merchant_attribute = 'shipping(country:region:service:price)';
726
+ }
727
+
728
+ if ( "tax" === $merchant_attribute ) {
729
+ $merchant_attribute = 'tax(country:region:rate:tax_ship)';
730
+ }
731
+
732
+ $attributeValue = $this->processStringForTXT( $attributeValue );
733
+ }
734
+
735
+ $this->products[ $this->pi ][ $merchant_attribute ] = $attributeValue;
736
+ }
737
+ }
738
+
739
+ /**
740
+ * Process Nested Attributes
741
+ *
742
+ * @return array
743
+ * @since 4.0.5
744
+ *
745
+ */
746
+ protected function feed_nested_attributes() {
747
+ return [
748
+ 'reviewer' => [ 'reviewer', 'name' ],
749
+ 'ratings' => [ 'ratings', 'overall' ],
750
+ 'product_url' => [ 'products', 'product', 'product_url' ],
751
+ ];
752
+ }
753
+
754
+ /**
755
+ * Process Nested Attributes
756
+ *
757
+ * @param string $attribute //product feed tag
758
+ * @param string $content //product feed content
759
+ *
760
+ * @return string
761
+ * @since 4.0.5
762
+ *
763
+ */
764
+
765
+ protected function nested_attributes_element( $attribute, $content ) {
766
+ $starter = '';
767
+ $finisher = '';
768
+ $element = '';
769
+
770
+ if ( empty( $attribute ) ) {
771
+ return $attribute;
772
+ }
773
+
774
+ $attr_names = $this->feed_nested_attributes();
775
+
776
+ foreach ( $attr_names as $key => $value ) {
777
+ if ( $key === $attribute ) {
778
+ //starter tags element
779
+ foreach ( $value as $item_value ) {
780
+ $starter .= '<' . strval( $item_value ) . '>';
781
+ }
782
+
783
+ //finishing tags element
784
+ $rev_value = array_reverse( $value );
785
+ foreach ( $rev_value as $item_value ) {
786
+ $finisher .= '</' . strval( $item_value ) . '>';
787
+ }
788
+ }
789
+ }
790
+
791
+ $element = $starter . $content . $finisher;
792
+
793
+ return $element;
794
+ }
795
+
796
+ /**
797
+ * Check if current product should be processed for feed
798
+ * This should be using by Woo_Feed_Products_v3::get_products()
799
+ *
800
+ * @param WC_Product $product
801
+ *
802
+ * @return bool
803
+ * @since 3.3.9
804
+ *
805
+ */
806
+ protected function exclude_from_loop( $product ) {
807
+ // Skip for invalid products
808
+ if ( ! is_object( $product ) ) {
809
+ woo_feed_log_feed_process( $this->config['filename'], 'Skipping Product :: Product data is not a valid WC_Product object.' );
810
+
811
+ return true;
812
+ }
813
+
814
+ // For WP_Query check available product types
815
+ if ( 'wp' == $this->queryType && ! in_array( $product->get_type(), $this->product_types, true ) ) {
816
+ woo_feed_log_feed_process( $this->config['filename'], sprintf( 'Skipping Product :: Invalid Post/Product Type : %s.', $product->get_type() ) );
817
+
818
+ return true;
819
+ }
820
+
821
+ // Skip orphaned variation
822
+ if ( $product->is_type( 'variation' ) && ! $product->get_parent_id() ) {
823
+ woo_feed_log_feed_process( $this->config['filename'], sprintf( 'Skipping Product :: Orphaned variation product [id: %s] skipped.', $product->get_id() ) );
824
+
825
+ return true;
826
+ }
827
+
828
+ // Skip for invisible products
829
+ if ( ! $product->is_visible() ) {
830
+ woo_feed_log_feed_process( $this->config['filename'], 'Skipping Product :: Product is not visible.' );
831
+
832
+ return true;
833
+ }
834
+
835
+ return false;
836
+ }
837
+
838
+ /**
839
+ * Check if current attribute/merchant attribute should be processed for feed
840
+ * This should be using by Woo_Feed_Products_v3::get_products()
841
+ *
842
+ * @param WC_Product $product
843
+ * @param string $merchant_attribute
844
+ * @param string $product_attribute
845
+ * @param string $feedType
846
+ *
847
+ * @return bool
848
+ *
849
+ * @since 3.3.9
850
+ *
851
+ */
852
+ protected function exclude_current_attribute( $product, $merchant_attribute, $product_attribute, $feedType = 'xml' ) {
853
+
854
+ if ( empty( $merchant_attribute ) ) {
855
+ return true;
856
+ }
857
+
858
+ if (
859
+ in_array( $this->config['provider'], array_keys( $this->skipped_merchant_attributes ) ) &&
860
+ in_array( $merchant_attribute, $this->skipped_merchant_attributes[ $this->config['provider'] ] )
861
+
862
+ ) {
863
+ return true;
864
+ }
865
+
866
+ if ( 'shopping_ads_excluded_country' !== $merchant_attribute && in_array( $merchant_attribute, $this->processed_merchant_attributes ) ) {
867
+ return true;
868
+ }
869
+
870
+ $this->processed_merchant_attributes[] = $merchant_attribute;
871
+
872
+ return false;
873
+ }
874
+
875
+ /**
876
+ * Wrapper for substr with <![CDATA[string]]> support
877
+ *
878
+ * @param string $string
879
+ * @param int $start
880
+ * @param int $limit
881
+ *
882
+ * @return string
883
+ * @see substr
884
+ *
885
+ */
886
+ protected function crop_string( $string, $start = 0, $limit = null ) {
887
+ $limit = absint( $limit );
888
+ if ( $limit > 0 ) {
889
+ $start = absint( $start );
890
+ if ( strpos( $string, '<![CDATA[' ) !== false ) {
891
+ $string = str_replace( array( '<![CDATA[', ']]>' ), array( '', '' ), $string );
892
+ $string = substr( $string, $start, $limit );
893
+ $string = '<![CDATA[' . $string . ']]>';
894
+ } else {
895
+ $string = substr( $string, $start, $limit );
896
+ }
897
+ }
898
+
899
+ return $string;
900
+ }
901
+
902
+ /**
903
+ * Process feed data according to merchant uncommon requirements like Google
904
+ *
905
+ * @param object $productObj WC_Product
906
+ * @param int $index Product Index
907
+ *
908
+ * @since 3.2.0
909
+ */
910
+ protected function process_for_merchant( $productObj, $index ) {
911
+ $product = $this->products[ $index ];
912
+ $merchantAttributes = $this->config['mattributes'];
913
+ $s = 0; // Shipping Index
914
+ $i = 0; // Installment Index
915
+ $t = 0; // Tax Index
916
+ $tax = '';
917
+ $shipping = '';
918
+ $sub = 0;
919
+ $subscription = '';
920
+ $ins = 0; // Installment Index
921
+ $installment = "";
922
+ $product_detail = '';
923
+ $unit_price = '';
924
+ $additional_variant_attribute = '';
925
+ $pd = 0;
926
+ $up = 0; //Unit Price for facebook
927
+ $av = 0; //Additional Variant Attribute for facebook
928
+
929
+
930
+ // Format Shipping and Tax data for CSV and TXT feed only for google and facebook
931
+
932
+ if ( 'xml' != $this->config['feedType'] && in_array( $this->config['provider'], array(
933
+ 'google',
934
+ 'facebook',
935
+ 'bing',
936
+ 'snapchat',
937
+ 'pinterest'
938
+ ) ) ) {
939
+ foreach ( $merchantAttributes as $key => $value ) {
940
+
941
+ if ( ! in_array( $value, $this->google_shipping_tax, true ) ) {
942
+ continue;
943
+ }
944
+
945
+ # Get value by attribute type with prefix & suffix
946
+ $output = $this->process_for_merchant_get_value( $productObj, $key );
947
+
948
+ if ( 'shipping_country' == $value ) {
949
+ $s ++;
950
+ $shipping .= $output;
951
+ }
952
+ if ( 'shipping_region' == $value ) {
953
+ $shipping .= ':' . $output;
954
+ } elseif ( 'shipping_postal_code' == $value ) {
955
+ $shipping .= ':' . $output;
956
+ }
957
+ if ( 'shipping_service' == $value ) {
958
+ $shipping .= ':' . $output;
959
+ }
960
+ if ( 'shipping_price' == $value ) {
961
+ $shipping .= ':' . $output;
962
+ }
963
+
964
+ if ( 'section_name' == $value ) {
965
+ $pd ++;
966
+ $product_detail .= $output;
967
+ }
968
+ if ( 'attribute_name' == $value ) {
969
+ $product_detail .= ':' . $output;
970
+ }
971
+ if ( 'attribute_value' == $value ) {
972
+ $product_detail .= ':' . $output;
973
+ }
974
+
975
+ //facebook nested attributes
976
+ if ( isset( $this->config['provider'] ) && "facebook" === $this->config['provider'] ) {
977
+ if ( 'unit_price_value' == $value ) {
978
+ $up ++;
979
+ $unit_price .= $output;
980
+ }
981
+ if ( 'unit_price_currency' == $value ) {
982
+ $unit_price .= ':' . $output;
983
+ }
984
+ if ( 'unit_price_unit' == $value ) {
985
+ $unit_price .= ':' . $output;
986
+ }
987
+
988
+ if ( 'additional_variant_label' == $value ) {
989
+ $av ++;
990
+ $additional_variant_attribute .= $output;
991
+ }
992
+ if ( 'additional_variant_value' == $value ) {
993
+ $additional_variant_attribute .= ':' . $output;
994
+ }
995
+
996
+ if ( 0 < $up ) {
997
+ $this->products[ $this->pi ]["unit_price"] = $unit_price;
998
+ }
999
+
1000
+ if ( 0 < $av ) {
1001
+ $this->products[ $this->pi ]["additional_variant_attribute"] = $additional_variant_attribute;
1002
+ }
1003
+ }
1004
+
1005
+
1006
+ if ( 'installment_months' == $value ) {
1007
+ $ins ++;
1008
+ $installment .= $output;
1009
+ }
1010
+ if ( 'installment_amount' == $value ) {
1011
+ $installment .= ':' . $output;
1012
+ }
1013
+
1014
+ if ( 'subscription_period' == $value ) {
1015
+ $sub ++;
1016
+ $subscription .= $output;
1017
+ }
1018
+ if ( 'subscription_period_length' == $value ) {
1019
+ $subscription .= ':' . $output;
1020
+ }
1021
+ if ( 'subscription_amount' == $value ) {
1022
+ $subscription .= ':' . $output;
1023
+ }
1024
+ }
1025
+
1026
+ if ( 0 < $pd ) {
1027
+ $this->products[ $this->pi ]["product detail"] = $product_detail;
1028
+ }
1029
+
1030
+ if ( 0 < $sub ) {
1031
+ $this->products[ $this->pi ]["subscription cost"] = $subscription;
1032
+
1033
+ }
1034
+
1035
+ if ( 0 < $ins ) {
1036
+ $this->products[ $this->pi ]["installment"] = $installment;
1037
+ }
1038
+ }
1039
+
1040
+
1041
+ if ( in_array( $this->config['provider'], array( 'google', 'facebook', 'snapchat', 'bing', 'pinterest' ) ) ) {
1042
+
1043
+
1044
+ // Reformat Shipping attributes for google, facebook
1045
+ if ( 'xml' == $this->config['feedType'] ) {
1046
+ foreach ( $merchantAttributes as $key => $value ) {
1047
+
1048
+ if ( ! in_array( $value, $this->google_shipping_tax ) ) {
1049
+ continue;
1050
+ }
1051
+
1052
+
1053
+ # Get value by attribute type with prefix & suffix
1054
+ $output = $this->process_for_merchant_get_value( $productObj, $key );
1055
+
1056
+
1057
+ if ( 'shipping_country' == $value ) {
1058
+ if ( 0 == $s ) {
1059
+ $shipping .= '<g:shipping>';
1060
+ $s = 1;
1061
+ } else {
1062
+ $shipping .= '</g:shipping>' . "\n";
1063
+ $shipping .= '<g:shipping>';
1064
+ }
1065
+ } elseif ( ! in_array( 'shipping_country', $merchantAttributes ) && 'shipping_price' == $value ) {
1066
+ if ( 0 == $s ) {
1067
+ $shipping .= '<g:shipping>';
1068
+ $s = 1;
1069
+ } else {
1070
+ $shipping .= '</g:shipping>' . "\n";
1071
+ $shipping .= '<g:shipping>';
1072
+ }
1073
+ }
1074
+
1075
+ if ( 'shipping_country' == $value ) {
1076
+ $shipping .= '<g:country>' . $output . '</g:country>' . "\n";
1077
+ } elseif ( 'shipping_region' == $value ) {
1078
+ $shipping .= '<g:region>' . $output . '</g:region>' . "\n";
1079
+ } elseif ( 'shipping_region' == $value ) {
1080
+ $shipping .= '<g:region>' . $output . '</g:region>' . "\n";
1081
+ } elseif ( 'shipping_service' == $value ) {
1082
+ $shipping .= '<g:service>' . $output . '</g:service>' . "\n";
1083
+ } elseif ( 'shipping_postal_code' == $value ) {
1084
+ $shipping .= '<g:postal_code>' . $output . '</g:postal_code>' . "\n";
1085
+ } elseif ( 'shipping_price' == $value ) {
1086
+ $shipping .= '<g:price>' . $output . '</g:price>' . "\n";
1087
+ } elseif ( 'tax_country' == $value ) {
1088
+ if ( 0 == $t ) {
1089
+ $tax .= '<g:tax>';
1090
+ $t = 1;
1091
+ } else {
1092
+ $tax .= '</g:tax>' . "\n";
1093
+ $tax .= '<g:tax>';
1094
+ }
1095
+ $tax .= '<g:country>' . $output . '</g:country>' . "\n";
1096
+ } elseif ( 'tax_region' == $value ) {
1097
+ $tax .= '<g:region>' . $output . '</g:region>' . "\n";
1098
+ } elseif ( 'tax_rate' == $value ) {
1099
+ $tax .= '<g:rate>' . $output . '</g:rate>' . "\n";
1100
+ } elseif ( 'tax_ship' == $value ) {
1101
+ $tax .= '<g:tax_ship>' . $output . '</g:tax_ship>' . "\n";
1102
+ } elseif ( 'subscription_period' == $value ) {
1103
+ if ( 0 == $sub ) {
1104
+ $subscription .= '<g:subscription_cost>';
1105
+ $sub = 1;
1106
+ } else {
1107
+ $subscription .= '</g:subscription_cost>' . "\n";
1108
+ $subscription .= '<g:subscription_cost>';
1109
+ }
1110
+ $subscription .= '<g:period>' . $output . '</g:period>' . "\n";
1111
+ } elseif ( 'subscription_period_length' == $value ) {
1112
+ $subscription .= '<g:period_length>' . $output . '</g:period_length>' . "\n";
1113
+ } elseif ( 'subscription_amount' == $value ) {
1114
+ $subscription .= '<g:amount>' . $output . '</g:amount>' . "\n";
1115
+ }
1116
+
1117
+ if ( 'section_name' == $value ) {
1118
+ if ( 0 == $pd ) {
1119
+ $product_detail .= '<g:product_detail>';
1120
+ $pd = 1;
1121
+ } else {
1122
+ $product_detail .= '</g:product_detail>' . "\n";
1123
+ $product_detail .= '<g:product_detail>';
1124
+ }
1125
+ } elseif ( ! in_array( 'section_name', $merchantAttributes ) && 'attribute_name' == $value ) {
1126
+ if ( 0 == $pd ) {
1127
+ $product_detail .= '<g:product_detail>';
1128
+ $pd = 1;
1129
+ } else {
1130
+ $product_detail .= '</g:product_detail>' . "\n";
1131
+ $product_detail .= '<g:product_detail>';
1132
+ }
1133
+ }
1134
+
1135
+ if ( 'section_name' == $value ) {
1136
+ $product_detail .= '<g:section_name>' . $output . '</g:section_name>' . "\n";
1137
+ } elseif ( 'attribute_name' == $value ) {
1138
+ $product_detail .= '<g:attribute_name>' . $output . '</g:attribute_name>' . "\n";
1139
+ } elseif ( 'attribute_value' == $value ) {
1140
+ $product_detail .= '<g:attribute_value>' . $output . '</g:attribute_value>' . "\n";
1141
+ }
1142
+
1143
+ if ( isset( $this->config['provider'] ) && "facebook" === $this->config['provider'] ) {
1144
+
1145
+ // unit_price configure
1146
+ if ( 'unit_price_value' == $value ) {
1147
+ if ( 0 == $up ) {
1148
+ $unit_price .= '<unit_price>';
1149
+ $up = 1;
1150
+ } else {
1151
+ $unit_price .= '</unit_price>' . "\n";
1152
+ $unit_price .= '<unit_price>';
1153
+ }
1154
+ } elseif ( ! in_array( 'unit_price_value', $merchantAttributes ) && 'unit_price_currency' == $value ) {
1155
+ if ( 0 == $up ) {
1156
+ $unit_price .= '<unit_price>';
1157
+ $up = 1;
1158
+ } else {
1159
+ $unit_price .= '</unit_price>' . "\n";
1160
+ $unit_price .= '<unit_price>';
1161
+ }
1162
+ }
1163
+
1164
+ if ( 'unit_price_value' == $value ) {
1165
+ $unit_price .= '<value>' . $output . '</value>' . "\n";
1166
+ } elseif ( 'unit_price_currency' == $value ) {
1167
+ $unit_price .= '<currency>' . $output . '</currency>' . "\n";
1168
+ } elseif ( 'unit_price_unit' == $value ) {
1169
+ $unit_price .= '<unit>' . $output . '</unit>' . "\n";
1170
+ }
1171
+
1172
+ // additional_variant_attribute configure
1173
+ if ( 'additional_variant_label' == $value ) {
1174
+ if ( 0 == $av ) {
1175
+ $additional_variant_attribute .= '<additional_variant_attribute>';
1176
+ $av = 1;
1177
+ } else {
1178
+ $additional_variant_attribute .= '</additional_variant_attribute>' . "\n";
1179
+ $additional_variant_attribute .= '<additional_variant_attribute>';
1180
+ }
1181
+ } elseif ( ! in_array( 'additional_variant_label', $merchantAttributes ) && 'additional_variant_value' == $value ) {
1182
+ if ( 0 == $av ) {
1183
+ $additional_variant_attribute .= '<additional_variant_attribute>';
1184
+ $av = 1;
1185
+ } else {
1186
+ $additional_variant_attribute .= '</additional_variant_attribute>' . "\n";
1187
+ $additional_variant_attribute .= '<additional_variant_attribute>';
1188
+ }
1189
+ }
1190
+
1191
+ if ( 'additional_variant_label' == $value ) {
1192
+ $additional_variant_attribute .= '<label>' . $output . '</label>' . "\n";
1193
+ } elseif ( 'additional_variant_value' == $value ) {
1194
+ $additional_variant_attribute .= '<value>' . $output . '</value>' . "\n";
1195
+ }
1196
+ }
1197
+
1198
+
1199
+ if ( 'installment_months' === $value ) {
1200
+ if ( 0 == $ins ) {
1201
+ $installment .= '<g:installment>';
1202
+ $ins = 1;
1203
+ } else {
1204
+ $installment .= '</g:installment>' . "\n";
1205
+ $installment .= '<g:installment>';
1206
+ }
1207
+ $installment .= '<g:months>' . $output . '</g:months>' . "\n";
1208
+ } elseif ( 'installment_amount' == $value ) {
1209
+ $installment .= '<g:amount>' . $output . '</g:amount>' . "\n";
1210
+ }
1211
+ }
1212
+
1213
+ if ( 1 == $pd ) {
1214
+ $product_detail .= '</g:product_detail>';
1215
+ }
1216
+
1217
+ if ( isset( $this->config['provider'] ) && "facebook" === $this->config['provider'] ) {
1218
+ if ( 1 == $up ) {
1219
+ $unit_price .= '</unit_price>';
1220
+ }
1221
+
1222
+ if ( 1 == $av ) {
1223
+ $additional_variant_attribute .= '</additional_variant_attribute>';
1224
+ }
1225
+
1226
+ $this->feedBody .= $unit_price;
1227
+ $this->feedBody .= $additional_variant_attribute;
1228
+ }
1229
+
1230
+ if ( 1 == $s ) {
1231
+ $shipping .= '</g:shipping>';
1232
+ }
1233
+ if ( 1 == $t ) {
1234
+ $tax .= '</g:tax>';
1235
+ }
1236
+
1237
+ if ( 1 == $sub ) {
1238
+ $subscription .= '</g:subscription_cost>';
1239
+ }
1240
+
1241
+ if ( 1 == $ins ) {
1242
+ $installment .= '</g:installment>';
1243
+ }
1244
+
1245
+ //$this->feedBody .= $shipping;
1246
+ //$this->feedBody .= $tax;
1247
+ $this->feedBody .= $product_detail;
1248
+ $this->feedBody .= $installment;
1249
+
1250
+ if ( $productObj->is_type( 'subscription' ) ||
1251
+ $productObj->is_type( 'variable-subscription' ) ||
1252
+ $productObj->is_type( 'subscription_variation' ) ) {
1253
+ $this->feedBody .= $subscription;
1254
+ }
1255
+ }
1256
+ // ADD g:identifier_exists
1257
+ $identifier = array( 'brand', 'upc', 'sku', 'mpn', 'gtin' );
1258
+ $countIdentifier = 0;
1259
+ if ( ! in_array( 'identifier_exists', $merchantAttributes ) ) {
1260
+ if ( count( array_intersect_key( array_flip( $identifier ), $product ) ) >= 2 ) {
1261
+ // Any 2 required keys exist!
1262
+ // @TODO Refactor with OR
1263
+ if ( array_key_exists( 'brand', $product ) && ! empty( $product['brand'] ) ) {
1264
+ $countIdentifier ++;
1265
+ }
1266
+ if ( array_key_exists( 'upc', $product ) && ! empty( $product['upc'] ) ) {
1267
+ $countIdentifier ++;
1268
+ }
1269
+ if ( array_key_exists( 'sku', $product ) && ! empty( $product['sku'] ) ) {
1270
+ $countIdentifier ++;
1271
+ }
1272
+ if ( array_key_exists( 'mpn', $product ) && ! empty( $product['mpn'] ) ) {
1273
+ $countIdentifier ++;
1274
+ }
1275
+ if ( array_key_exists( 'gtin', $product ) && ! empty( $product['gtin'] ) ) {
1276
+ $countIdentifier ++;
1277
+ }
1278
+ }
1279
+
1280
+ if ( 'xml' == $this->config['feedType'] ) {
1281
+ if ( $countIdentifier >= 2 ) {
1282
+ $this->feedBody .= '<g:identifier_exists>yes</g:identifier_exists>';
1283
+ } else {
1284
+ $this->feedBody .= '<g:identifier_exists>no</g:identifier_exists>';
1285
+ }
1286
+ } else {
1287
+ $identifier_exists = 'identifier exists';
1288
+ if ( in_array( $this->config['provider'], array( 'bing', 'pinterest' ) ) ) {
1289
+ $identifier_exists = 'identifier_exists';
1290
+ }
1291
+
1292
+ if ( $countIdentifier >= 2 ) {
1293
+ $this->products[ $this->pi ][ $identifier_exists ] = 'yes';
1294
+ } else {
1295
+ $this->products[ $this->pi ][ $identifier_exists ] = 'no';
1296
+ }
1297
+ }
1298
+ }
1299
+ }
1300
+ }
1301
+
1302
+ private function process_for_merchant_get_value( $productObj, $key ) {
1303
+ $prefix = $this->config['prefix'][ $key ];
1304
+ $suffix = $this->config['suffix'][ $key ];
1305
+ $attribute = $this->config['attributes'][ $key ];
1306
+ $merchant_attribute = $this->config['mattributes'][ $key ];
1307
+
1308
+ if ( 'pattern' == $this->config['type'][ $key ] ) {// Get Pattern value.
1309
+ $output = $this->config['default'][ $key ];
1310
+ $output = $this->apply_filters_to_attribute_value( $output, $productObj, $attribute, $merchant_attribute );
1311
+ } else {
1312
+ $output = $this->getAttributeValueByType( $productObj, $attribute, $merchant_attribute );
1313
+ }
1314
+
1315
+ $output = $this->format_output( $output, $this->config['output_type'], $productObj, $attribute, $merchant_attribute );
1316
+
1317
+ $output = $this->process_prefix_suffix( $output, $prefix, $suffix, $attribute = '' );
1318
+
1319
+ return $output;
1320
+ }
1321
+
1322
+ /**
1323
+ * Get Query Type Settings
1324
+ * @return string
1325
+ */
1326
+ public function get_query_type() {
1327
+ return $this->queryType;
1328
+ }
1329
+
1330
+ public function get_product_types() {
1331
+ return $this->product_types;
1332
+ }
1333
+
1334
+ /**
1335
+ * Generate TXT Feed Header
1336
+ *
1337
+ * @return string
1338
+ * @since 3.2.0
1339
+ *
1340
+ */
1341
+ protected function process_txt_feed_header() {
1342
+ // Set Delimiter
1343
+ if ( 'tab' == $this->config['delimiter'] ) {
1344
+ $this->delimiter = "\t";
1345
+ } else {
1346
+ $this->delimiter = $this->config['delimiter'];
1347
+ }
1348
+
1349
+ // Set Enclosure
1350
+ if ( ! empty( $this->config['enclosure'] ) ) {
1351
+ $this->enclosure = $this->config['enclosure'];
1352
+ if ( 'double' == $this->enclosure ) {
1353
+ $this->enclosure = '"';
1354
+ } elseif ( 'single' == $this->enclosure ) {
1355
+ $this->enclosure = "'";
1356
+ } else {
1357
+ $this->enclosure = '';
1358
+ }
1359
+ } else {
1360
+ $this->enclosure = '';
1361
+ }
1362
+
1363
+ $eol = PHP_EOL;
1364
+ if ( 'trovaprezzi' === $this->config['provider'] ) {
1365
+ $eol = '<endrecord>' . PHP_EOL;
1366
+ }
1367
+
1368
+ $product = $this->products[ $this->pi ];
1369
+
1370
+ $headers = array_keys( $product );
1371
+
1372
+ $this->feedHeader .= $this->enclosure . implode( "$this->enclosure$this->delimiter$this->enclosure", $headers ) . $this->enclosure . $eol;
1373
+
1374
+ if ( 'google' === $this->config['provider'] ) {
1375
+ $this->feedHeader = str_replace( $this->google_product_highlights, 'product highlight', $this->feedHeader );
1376
+ $this->feedHeader = str_replace( $this->google_additional_image, 'additional image link', $this->feedHeader );
1377
+ }
1378
+
1379
+ return $this->feedHeader;
1380
+ }
1381
+
1382
+ /**
1383
+ * Generate TXT Feed Body
1384
+ *
1385
+ * @return string
1386
+ * @since 3.2.0
1387
+ *
1388
+ */
1389
+ protected function process_txt_feed_body() {
1390
+ $productInfo = array_values( $this->products[ $this->pi ] );
1391
+ $eol = PHP_EOL;
1392
+ if ( 'trovaprezzi' === $this->config['provider'] ) {
1393
+ $eol = '<endrecord>' . PHP_EOL;
1394
+ }
1395
+ $this->feedBody .= $this->enclosure . implode( "$this->enclosure$this->delimiter$this->enclosure", $productInfo ) . $this->enclosure . $eol;
1396
+
1397
+ return $this->feedBody;
1398
+ }
1399
+
1400
+ /**
1401
+ * Generate CSV Feed Header
1402
+ *
1403
+ * @return array
1404
+ * @since 3.2.0
1405
+ *
1406
+ */
1407
+ protected function process_csv_feed_header() {
1408
+ // Set Delimiter
1409
+ if ( 'tab' == $this->config['delimiter'] ) {
1410
+ $this->delimiter = "\t";
1411
+ } else {
1412
+ $this->delimiter = $this->config['delimiter'];
1413
+ }
1414
+
1415
+ // Set Enclosure
1416
+ if ( ! empty( $this->config['enclosure'] ) ) {
1417
+ $this->enclosure = $this->config['enclosure'];
1418
+ if ( 'double' == $this->enclosure ) {
1419
+ $this->enclosure = '"';
1420
+ } elseif ( 'single' == $this->enclosure ) {
1421
+ $this->enclosure = "'";
1422
+ } else {
1423
+ $this->enclosure = '';
1424
+ }
1425
+ } else {
1426
+ $this->enclosure = '';
1427
+ }
1428
+
1429
+ $product = $this->products[ $this->pi ];
1430
+
1431
+ $this->feedHeader = array_keys( $product );
1432
+
1433
+ if ( 'google' === $this->config['provider'] ) {
1434
+ $this->feedHeader = str_replace( $this->google_product_highlights, 'product highlight', $this->feedHeader );
1435
+ $this->feedHeader = str_replace( $this->google_additional_image, 'additional image link', $this->feedHeader );
1436
+ }
1437
+
1438
+ return $this->feedHeader;
1439
+ }
1440
+
1441
+ /**
1442
+ * Generate CSV Feed Body
1443
+ * @return array
1444
+ * @since 3.2.0
1445
+ */
1446
+ protected function process_csv_feed_body() {
1447
+ $product = $this->products[ $this->pi ];
1448
+ $this->feedBody[] = array_values( $product );
1449
+
1450
+ return $this->feedBody;
1451
+ }
1452
+
1453
+ protected function process_json_feed_body() {
1454
+ $product = $this->products[ $this->pi ];
1455
+ $this->feedBody[] = $product;
1456
+
1457
+ return $this->feedBody;
1458
+ }
1459
+
1460
+ protected function process_xml_wrapper() {
1461
+ $itemsWrapperClose = explode( ' ', $this->config['itemsWrapper'] );
1462
+ $itemsWrapperClose = $itemsWrapperClose[0];
1463
+ $this->xml_wrapper = [
1464
+ 'header' => '<?xml version="1.0" encoding="UTF-8" ?>' . PHP_EOL . '<' . wp_unslash( $this->config['itemsWrapper'] ) . '>',
1465
+ 'footer' => PHP_EOL . '</' . $itemsWrapperClose . '>',
1466
+ ];
1467
+ $this->config['itemWrapper'] = str_replace( ' ', '_', $this->config['itemWrapper'] );
1468
+ $this->config['itemsWrapper'] = str_replace( ' ', '_', $this->config['itemsWrapper'] );
1469
+
1470
+ if ( file_exists( WOO_FEED_FREE_ADMIN_PATH . 'partials/templates/' . $this->config['provider'] . '.txt' ) ) {
1471
+ $txt = file_get_contents( WOO_FEED_FREE_ADMIN_PATH . 'partials/templates/' . $this->config['provider'] . '.txt' );
1472
+ $txt = trim( $txt );
1473
+ $txt = explode( '{separator}', $txt );
1474
+ if ( 2 === count( $txt ) ) {
1475
+ $this->xml_wrapper['header'] = trim( $txt[0] );
1476
+ $this->xml_wrapper['footer'] = "\n" . trim( $txt[1] );
1477
+ }
1478
+ }
1479
+
1480
+ if ( ! empty( $this->config['extraHeader'] ) ) {
1481
+ $this->xml_wrapper['header'] .= PHP_EOL . $this->config['extraHeader'];
1482
+ }
1483
+
1484
+ // replace template variables.
1485
+ $datetime_now = date( 'Y-m-d H:i:s', strtotime( current_time( 'mysql' ) ) ); // {DateTimeNow}
1486
+ if ( 'pinterest_rss' === $this->config['provider'] ) { // DATE_RFC822 date format for pinterest rss feed
1487
+ $datetime_now = date( 'r', strtotime( current_time( 'mysql' ) ) ); // {DateTimeNow}
1488
+ }
1489
+ $blog_name = get_bloginfo( 'name' ); // {BlogName}
1490
+ $blog_url = get_bloginfo( 'url' ); // {BlogURL}
1491
+ //$blog_desc = get_bloginfo('description'); // {BlogDescription}
1492
+ $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}
1493
+ $blog_email = get_bloginfo( 'admin_email' ); // {BlogEmail}
1494
+
1495
+ $this->xml_wrapper['header'] = str_replace(
1496
+ [ '{DateTimeNow}', '{BlogName}', '{BlogURL}', '{BlogDescription}', '{BlogEmail}' ],
1497
+ [ $datetime_now, $blog_name, $blog_url, $blog_desc, $blog_email ],
1498
+ $this->xml_wrapper['header']
1499
+ );
1500
+ }
1501
+
1502
+ /**
1503
+ * Make XML feed header
1504
+ * @return string
1505
+ * @since 3.2.0
1506
+ */
1507
+ protected function process_xml_feed_header() {
1508
+ return $this->xml_wrapper['header'];
1509
+ }
1510
+
1511
+ /**
1512
+ * Make XML feed header
1513
+ * @return string
1514
+ * @since 3.2.0
1515
+ */
1516
+ protected function process_xml_feed_footer() {
1517
+ return $this->xml_wrapper['footer'];
1518
+ }
1519
+
1520
+ /**
1521
+ * Process string for TXT CSV Feed
1522
+ *
1523
+ * @param $string
1524
+ *
1525
+ * @return mixed|string
1526
+ * @since 3.2.0
1527
+ *
1528
+ */
1529
+ protected function processStringForTXT( $string ) {
1530
+ if ( ! empty( $string ) ) {
1531
+ $string = html_entity_decode( $string, ENT_HTML401 | ENT_QUOTES ); // Convert any HTML entities
1532
+
1533
+ if ( stristr( $string, '"' ) ) {
1534
+ $string = str_replace( '"', '""', $string );
1535
+ }
1536
+ $string = str_replace( "\n", ' ', $string );
1537
+ $string = str_replace( "\r", ' ', $string );
1538
+ $string = str_replace( "\t", ' ', $string );
1539
+ $string = trim( $string );
1540
+ $string = stripslashes( $string );
1541
+
1542
+ return $string;
1543
+ } elseif ( '0' == $string ) {
1544
+ return '0';
1545
+ } else {
1546
+ return '';
1547
+ }
1548
+ }
1549
+
1550
+ /**
1551
+ * Process string for CSV
1552
+ *
1553
+ * @param $string
1554
+ *
1555
+ * @return mixed|string
1556
+ * @since 3.2.0
1557
+ *
1558
+ */
1559
+ protected function processStringForCSV( $string ) {
1560
+ if ( ! empty( $string ) ) {
1561
+ $string = str_replace( "\n", ' ', $string );
1562
+ $string = str_replace( "\r", ' ', $string );
1563
+ $string = trim( $string );
1564
+ $string = stripslashes( $string );
1565
+
1566
+ return $string;
1567
+ } elseif ( '0' == $string ) {
1568
+ return '0';
1569
+ } else {
1570
+ return '';
1571
+ }
1572
+ }
1573
+
1574
+ /**
1575
+ * Get Product Attribute Value by Type
1576
+ *
1577
+ * @param $product WC_Product
1578
+ * @param $attribute
1579
+ *
1580
+ * @return mixed|string
1581
+ * @since 3.2.0
1582
+ *
1583
+ */
1584
+ public function getAttributeValueByType( $product, $attribute, $merchant_attribute = '' ) {
1585
+
1586
+ if ( method_exists( $this, $attribute ) ) {
1587
+ $output = $this->$attribute( $product );
1588
+ } elseif ( false !== strpos( $attribute, self::PRODUCT_ACF_FIELDS ) ) {
1589
+ $output = $this->getACFField( $product, $attribute );
1590
+ } elseif ( false !== strpos( $attribute, self::PRODUCT_CUSTOM_IDENTIFIER ) || woo_feed_strpos_array( array(
1591
+ '_identifier_gtin',
1592
+ '_identifier_ean',
1593
+ '_identifier_mpn'
1594
+ ), $attribute ) ) {
1595
+ $output = $this->getCustomField( $product, $attribute );
1596
+ } elseif ( false !== strpos( $attribute, self::PRODUCT_ATTRIBUTE_PREFIX ) ) {
1597
+ $attribute = str_replace( self::PRODUCT_ATTRIBUTE_PREFIX, '', $attribute );
1598
+ $output = $this->getProductAttribute( $product, $attribute );
1599
+ } elseif ( false !== strpos( $attribute, self::POST_META_PREFIX ) ) {
1600
+ $attribute = str_replace( self::POST_META_PREFIX, '', $attribute );
1601
+ $output = $this->getProductMeta( $product, $attribute );
1602
+ } elseif ( false !== strpos( $attribute, self::PRODUCT_TAXONOMY_PREFIX ) ) {
1603
+ $attribute = str_replace( self::PRODUCT_TAXONOMY_PREFIX, '', $attribute );
1604
+ $output = $this->getProductTaxonomy( $product, $attribute );
1605
+ } elseif ( false !== strpos( $attribute, self::PRODUCT_CATEGORY_MAPPING_PREFIX ) ) {
1606
+ $id = $product->is_type( 'variation' ) ? $product->get_parent_id() : $product->get_id();
1607
+ $output = woo_feed_get_category_mapping_value( $attribute, $id );
1608
+ } elseif ( false !== strpos( $attribute, self::WP_OPTION_PREFIX ) ) {
1609
+ $optionName = str_replace( self::WP_OPTION_PREFIX, '', $attribute );
1610
+ $output = get_option( $optionName );
1611
+ } elseif ( 'image_' == substr( $attribute, 0, 6 ) ) {
1612
+ // For additional image method images() will be used with extra parameter - image number
1613
+ $imageKey = explode( '_', $attribute );
1614
+ if ( ! isset( $imageKey[1] ) || ( isset( $imageKey[1] ) && ( empty( $imageKey[1] ) || ! is_numeric( $imageKey[1] ) ) ) ) {
1615
+ $imageKey[1] = '';
1616
+ }
1617
+ $output = call_user_func_array( array( $this, 'images' ), array( $product, $imageKey[1] ) );
1618
+ } else {
1619
+ // return the attribute so multiple attribute can be join with separator to make custom attribute.
1620
+ $output = $attribute;
1621
+ }
1622
+
1623
+ // Json encode if value is an array
1624
+ if ( is_array( $output ) ) {
1625
+ $output = wp_json_encode( $output );
1626
+ }
1627
+
1628
+ $output = $this->apply_filters_to_attribute_value( $output, $product, $attribute, $merchant_attribute );
1629
+
1630
+ return $output;
1631
+ }
1632
+
1633
+ /**
1634
+ * Apply Filter to Attribute value
1635
+ *
1636
+ * @param $output
1637
+ * @param $product
1638
+ * @param $attribute
1639
+ * @param $merchant_attribute
1640
+ *
1641
+ * @return mixed|void
1642
+ */
1643
+ protected function apply_filters_to_attribute_value( $output, $product, $attribute, $merchant_attribute ) {
1644
+ /**
1645
+ * Filter attribute value
1646
+ *
1647
+ * @param string $output the output
1648
+ * @param WC_Abstract_Legacy_Product $product Product Object.
1649
+ * @param array feed config/rule
1650
+ *
1651
+ * @since 3.4.3
1652
+ *
1653
+ */
1654
+ $output = apply_filters( 'woo_feed_get_attribute', $output, $product, $this->config, $merchant_attribute );
1655
+
1656
+ /**
1657
+ * Filter attribute value before return based on attribute name
1658
+ *
1659
+ * @param string $output the output
1660
+ * @param WC_Abstract_Legacy_Product $product Product Object.
1661
+ * @param array feed config/rule
1662
+ *
1663
+ * @since 3.3.5
1664
+ *
1665
+ */
1666
+ $output = apply_filters( "woo_feed_get_{$attribute}_attribute", $output, $product, $this->config );
1667
+
1668
+ /**
1669
+ * Filter attribute value before return based on merchant and attribute name
1670
+ *
1671
+ * @param string $output the output
1672
+ * @param WC_Abstract_Legacy_Product $product Product Object.
1673
+ * @param array feed config/rule
1674
+ *
1675
+ * @since 3.3.7
1676
+ *
1677
+ */
1678
+ $output = apply_filters( "woo_feed_get_{$this->config['provider']}_{$attribute}_attribute", $output, $product, $this->config );
1679
+
1680
+ return $output;
1681
+ }
1682
+
1683
+
1684
+ /**
1685
+ * Get Product Id
1686
+ *
1687
+ * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product Product Object.
1688
+ *
1689
+ * @return mixed
1690
+ * @since 3.2.0
1691
+ */
1692
+ protected function id( $product ) {
1693
+ $id = $product->get_id();
1694
+
1695
+ return apply_filters( 'woo_feed_filter_product_id', $id, $product, $this->config );
1696
+ }
1697
+
1698
+ /**
1699
+ * Get Product Title
1700
+ *
1701
+ * @param WC_Product $product
1702
+ *
1703
+ * @return mixed
1704
+ * @since 3.2.0
1705
+ *
1706
+ */
1707
+ protected function title( $product ) {
1708
+ $title = woo_feed_strip_all_tags( $this->remove_short_codes( $product->get_name() ) );
1709
+
1710
+ // Add all available variation attributes to variation title.
1711
+ if ( $product->is_type( 'variation' ) && ! empty( $product->get_attributes() ) ) {
1712
+ $title = $this->parent_title( $product );
1713
+ $attributes = [];
1714
+ foreach ( $product->get_attributes() as $slug => $value ) {
1715
+ $attribute = $product->get_attribute( $slug );
1716
+ if ( empty( $attribute ) ) {
1717
+ continue;
1718
+ }
1719
+ $attributes[ $slug ] = $attribute;
1720
+ }
1721
+
1722
+ // set variation attributes with separator
1723
+ if ( isset( $this->config['provider'] ) && 'google' === $this->config['provider'] ) {
1724
+ $variation_attributes = implode( ' - ', $attributes );
1725
+ } else {
1726
+ $variation_attributes = implode( ', ', $attributes );
1727
+ }
1728
+
1729
+ //get product title with variation attribute
1730
+ $get_with_var_attributes = apply_filters( "woo_feed_get_product_title_with_variation_attribute", true, $product, $this->config );
1731
+
1732
+ if ( $get_with_var_attributes ) {
1733
+ $title .= " - " . $variation_attributes;
1734
+ }
1735
+ }
1736
+
1737
+ return apply_filters( 'woo_feed_filter_product_title', $title, $product, $this->config );
1738
+ }
1739
+
1740
+ /**
1741
+ * Get Parent Product Title
1742
+ *
1743
+ * @param WC_Product $product Product Object.
1744
+ *
1745
+ * @return mixed
1746
+ * @author Nazrul Islam Nayan
1747
+ * @since 5.1.8
1748
+ */
1749
+ protected function parent_title( $product ) {
1750
+ if ( $product->is_type( 'variation' ) ) {
1751
+ $product = wc_get_product( $product->get_parent_id() );
1752
+ $title = woo_feed_strip_all_tags( $this->remove_short_codes( $product->get_name() ) );
1753
+ } else {
1754
+ $title = $this->title( $product );
1755
+ }
1756
+
1757
+ return apply_filters( 'woo_feed_filter_product_parent_title', $title, $product, $this->config );
1758
+ }
1759
+
1760
+ /**
1761
+ * Get All in One SEO Canonical URL
1762
+ *
1763
+ * @param WC_Product $product
1764
+ *
1765
+ * @return mixed
1766
+ * @since 4.4.12
1767
+ */
1768
+ protected function _aioseop_canonical_url( $product ) {
1769
+ $aioseop_canonical_url = '';
1770
+ if ( is_plugin_active( 'all-in-one-seo-pack/all_in_one_seo_pack.php' ) && class_exists( 'AIOSEO\Plugin\Common\Models\Post' ) ) {
1771
+ $post = AIOSEO\Plugin\Common\Models\Post::getPost( $product->get_id() );
1772
+ $aioseop_canonical_url = $post->canonical_url;
1773
+ }
1774
+
1775
+ return apply_filters( 'woo_feed_filter_product_aioseop_canonical_url', $aioseop_canonical_url, $product, $this->config );
1776
+ }
1777
+
1778
+ /**
1779
+ * Get Yoast Product Title
1780
+ *
1781
+ * @param WC_Product $product
1782
+ *
1783
+ * @return mixed
1784
+ * @since 3.2.0
1785
+ *
1786
+ */
1787
+ protected function yoast_wpseo_title( $product ) {
1788
+ $product_id = woo_feed_parent_product_id( $product );
1789
+ $yoast_title = get_post_meta( $product_id, '_yoast_wpseo_title', true );
1790
+ if ( strpos( $yoast_title, '%%' ) !== false ) {
1791
+ $title = strstr( $yoast_title, '%%', true );
1792
+ if ( empty( $title ) ) {
1793
+ $title = get_the_title( $product_id );
1794
+ }
1795
+ $wpseo_titles = get_option( 'wpseo_titles' );
1796
+
1797
+ $sep_options = WPSEO_Option_Titles::get_instance()->get_separator_options();
1798
+ if ( isset( $wpseo_titles['separator'] ) && isset( $sep_options[ $wpseo_titles['separator'] ] ) ) {
1799
+ $sep = $sep_options[ $wpseo_titles['separator'] ];
1800
+ } else {
1801
+ $sep = '-'; //setting default separator if Admin didn't set it from backed
1802
+ }
1803
+
1804
+ $site_title = get_bloginfo( 'name' );
1805
+
1806
+ $meta_title = $title . ' ' . $sep . ' ' . $site_title;
1807
+
1808
+ if ( ! empty( $meta_title ) ) {
1809
+ $title = $meta_title;
1810
+ }
1811
+ } elseif ( ! empty( $yoast_title ) ) {
1812
+ $title = $yoast_title;
1813
+ } else {
1814
+ $title = $this->title( $product );
1815
+ }
1816
+
1817
+ return apply_filters( 'woo_feed_filter_product_yoast_wpseo_title', $title, $product, $this->config );
1818
+ }
1819
+
1820
+ /**
1821
+ * Get Yoast Canonical URL
1822
+ *
1823
+ * @param WC_Product $product
1824
+ *
1825
+ * @return mixed
1826
+ * @since 4.3.77
1827
+ */
1828
+ protected function yoast_canonical_url( $product ) {
1829
+ $product_id = woo_feed_parent_product_id( $product );
1830
+ $yoast_canonical_url = get_post_meta( $product_id, '_yoast_wpseo_canonical', true );
1831
+
1832
+ return apply_filters( 'woo_feed_filter_product_yoast_canonical_url', $yoast_canonical_url, $product, $this->config );
1833
+ }
1834
+
1835
+ /**
1836
+ * Get Rank Math Product Title
1837
+ *
1838
+ * @param WC_Product $product
1839
+ *
1840
+ * @return mixed
1841
+ * @since 5.1.3
1842
+ */
1843
+ protected function rank_math_title( $product ) {
1844
+ $rank_title = '';
1845
+ $post_title = '';
1846
+ $page = '';
1847
+ $sep = '';
1848
+ $sitemap = '';
1849
+ if ( class_exists( 'RankMath' ) ) {
1850
+ $title = get_post_meta( $product->get_id(), 'rank_math_title', true );
1851
+ if ( empty( $title ) ) {
1852
+ $title_format = Helper::get_settings( "titles.pt_product_title" );
1853
+ $title_format = $title_format ? $title_format : '%title%';
1854
+ $sep = Helper::get_settings( 'titles.title_separator' );
1855
+
1856
+ $rank_title = str_replace( '%title%', $product->get_title(), $title_format );
1857
+ $rank_title = str_replace( '%sep%', $sep, $rank_title );
1858
+ $rank_title = str_replace( '%page%', '', $rank_title );
1859
+ $rank_title = str_replace( '%sitename%', get_bloginfo( 'name' ), $rank_title );
1860
+ } else {
1861
+ $rank_title = $title;
1862
+ }
1863
+ }
1864
+
1865
+ return apply_filters( 'woo_feed_filter_product_rank_math_title', $rank_title, $product, $this->config );
1866
+ }
1867
+
1868
+ /**
1869
+ * Get Rank Math Product Description
1870
+ *
1871
+ * @param WC_Product $product
1872
+ *
1873
+ * @return mixed
1874
+ * @since 5.1.3
1875
+ */
1876
+ protected function rank_math_description( $product ) {
1877
+ $description = '';
1878
+ if ( class_exists( 'RankMath' ) ) {
1879
+ $description = get_post_meta( $product->get_id(), 'rank_math_description' );
1880
+ $desc_format = Helper::get_settings( "titles.pt_post_description" );
1881
+
1882
+ if ( empty( $description ) ) {
1883
+ if ( ! empty( $desc_format ) && strpos( (string) $desc_format, 'excerpt' ) !== false ) {
1884
+ $description = str_replace( '%excerpt%', get_the_excerpt( $product->get_id() ), $desc_format );
1885
+ }
1886
+
1887
+ // Get Variation Description
1888
+ if ( $product->is_type( 'variation' ) && empty( $description ) ) {
1889
+ $parent = wc_get_product( $product->get_parent_id() );
1890
+ $description = $parent->get_description();
1891
+ }
1892
+ }
1893
+
1894
+ if ( is_array( $description ) ) {
1895
+ $description = reset( $description );
1896
+ }
1897
+
1898
+ $description = $this->remove_short_codes( $description );
1899
+
1900
+ //strip tags and spacial characters
1901
+ $strip_description = woo_feed_strip_all_tags( wp_specialchars_decode( $description ) );
1902
+
1903
+ $description = ! empty( strlen( $strip_description ) ) && 0 < strlen( $strip_description ) ? $strip_description : $description;
1904
+ }
1905
+
1906
+ return apply_filters( 'woo_feed_filter_product_rank_math_description', $description, $product, $this->config );
1907
+ }
1908
+
1909
+ /**
1910
+ * Get Rank Math Canonical URL
1911
+ *
1912
+ * @param WC_Product $product
1913
+ *
1914
+ * @return mixed
1915
+ * @since 5.1.6
1916
+ */
1917
+ protected function rank_math_canonical_url( $product ) {
1918
+ $canonical_url = '';
1919
+
1920
+ if ( class_exists( 'RankMath' ) ) {
1921
+ $post_canonical_url = get_post_meta( $product->get_id(), 'rank_math_canonical_url' );
1922
+
1923
+ if ( empty( $post_canonical_url ) ) {
1924
+ $canonical_url = get_the_permalink( $product->get_id() );
1925
+ } else {
1926
+ $canonical_url = $post_canonical_url;
1927
+ }
1928
+
1929
+ if ( is_array( $canonical_url ) ) {
1930
+ $canonical_url = reset( $canonical_url );
1931
+ }
1932
+ }
1933
+
1934
+ return apply_filters( 'woo_feed_filter_product_rank_math_canonical_url', $canonical_url, $product, $this->config );
1935
+ }
1936
+
1937
+
1938
+ /**
1939
+ * Get All In One Product Title
1940
+ *
1941
+ * @param WC_Product $product
1942
+ *
1943
+ * @return mixed
1944
+ * @since 3.2.0
1945
+ *
1946
+ */
1947
+ protected function _aioseop_title( $product ) {
1948
+ $title = '';
1949
+ if ( is_plugin_active( 'all-in-one-seo-pack/all_in_one_seo_pack.php' ) && class_exists( 'AIOSEO\Plugin\Common\Models\Post' ) ) {
1950
+
1951
+ $post = AIOSEO\Plugin\Common\Models\Post::getPost( $product->get_id() );
1952
+ $title = ! empty( $post->title ) ? $post->title : aioseo()->meta->title->getPostTypeTitle( 'product' );
1953
+ }
1954
+
1955
+ $title = ! empty( $title ) ? $title : $this->title( $product );
1956
+
1957
+ return apply_filters( 'woo_feed_filter_product_aioseop_title', $title, $product, $this->config );
1958
+ }
1959
+
1960
+ /**
1961
+ * Get Product Description
1962
+ *
1963
+ * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product Product Object.
1964
+ *
1965
+ * @return mixed|string
1966
+ * @since 3.2.0
1967
+ *
1968
+ */
1969
+ protected function description( $product ) {
1970
+ $description = $product->get_description();
1971
+
1972
+ // Get Variation Description
1973
+ if ( $product->is_type( 'variation' ) && empty( $description ) ) {
1974
+ $parent = wc_get_product( $product->get_parent_id() );
1975
+
1976
+ if ( is_object( $parent ) ) {
1977
+ $description = $parent->get_description();
1978
+ } else {
1979
+ $description = '';
1980
+ }
1981
+ }
1982
+ $description = $this->remove_short_codes( $description );
1983
+
1984
+ // Add variations attributes after description to prevent Facebook error
1985
+ if ( 'facebook' == $this->config['provider'] && $product->is_type( 'variation' ) ) {
1986
+ $variationInfo = explode( '-', $product->get_name() );
1987
+ if ( isset( $variationInfo[1] ) ) {
1988
+ $extension = $variationInfo[1];
1989
+ } else {
1990
+ $extension = $product->get_id();
1991
+ }
1992
+ $description .= ' ' . $extension;
1993
+ }
1994
+
1995
+ //strip tags and spacial characters
1996
+ $strip_description = woo_feed_strip_all_tags( wp_specialchars_decode( $description ) );
1997
+
1998
+ $description = ! empty( strlen( $strip_description ) ) && 0 < strlen( $strip_description ) ? $strip_description : $description;
1999
+
2000
+ return apply_filters( 'woo_feed_filter_product_description', $description, $product, $this->config );
2001
+ }
2002
+
2003
+ /**
2004
+ * Get Product Description (with HTML)
2005
+ *
2006
+ * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product Product Object.
2007
+ *
2008
+ * @return mixed|string
2009
+ * @since 5.2.41
2010
+ */
2011
+ protected function description_with_html( $product ) {
2012
+ $description = $product->get_description();
2013
+
2014
+ // Get Variation Description
2015
+ if ( $product->is_type( 'variation' ) && empty( $description ) ) {
2016
+ $parent = wc_get_product( $product->get_parent_id() );
2017
+ $description = $parent->get_description();
2018
+ }
2019
+ $description = $this->remove_short_codes( $description );
2020
+
2021
+ // Add variations attributes after description to prevent Facebook error
2022
+ if ( 'facebook' === $this->config['provider'] && $product->is_type( 'variation' ) ) {
2023
+ $variationInfo = explode( '-', $product->get_name() );
2024
+ if ( isset( $variationInfo[1] ) ) {
2025
+ $extension = $variationInfo[1];
2026
+ } else {
2027
+ $extension = $product->get_id();
2028
+ }
2029
+ $description .= ' ' . $extension;
2030
+ }
2031
+
2032
+ //remove spacial characters
2033
+ $strip_description = wp_check_invalid_utf8( wp_specialchars_decode( $description ), true );
2034
+
2035
+ return apply_filters( 'woo_feed_filter_product_description_with_html', $description, $product, $this->config );
2036
+ }
2037
+
2038
+ /**
2039
+ * Get Yoast Product Description
2040
+ *
2041
+ * @param WC_Product $product
2042
+ *
2043
+ * @return mixed
2044
+ * @since 3.2.0
2045
+ *
2046
+ */
2047
+ protected function yoast_wpseo_metadesc( $product ) {
2048
+ $product_id = woo_feed_parent_product_id( $product );
2049
+ $description = '';
2050
+ if ( class_exists( 'WPSEO_Frontend' ) ) {
2051
+ $description = wpseo_replace_vars( WPSEO_Meta::get_value( 'metadesc', $product_id ),
2052
+ get_post( $product->get_id() ) );
2053
+ } else {
2054
+ $description = YoastSEO()->meta->for_post( $product_id )->description;
2055
+ }
2056
+
2057
+ if ( empty( $description ) ) {
2058
+ $description = $this->description( $product );
2059
+ }
2060
+
2061
+ return apply_filters( 'woo_feed_filter_product_yoast_wpseo_metadesc', $description, $product, $this->config );
2062
+ }
2063
+
2064
+ /**
2065
+ * Get All In One Product Description
2066
+ *
2067
+ * @param WC_Product $product
2068
+ *
2069
+ * @return mixed
2070
+ * @since 3.2.0
2071
+ *
2072
+ */
2073
+ protected function _aioseop_description( $product ) {
2074
+ $description = '';
2075
+
2076
+ if ( is_plugin_active( 'all-in-one-seo-pack/all_in_one_seo_pack.php' ) && class_exists( 'AIOSEO\Plugin\Common\Models\Post' ) ) {
2077
+
2078
+ $post = AIOSEO\Plugin\Common\Models\Post::getPost( $product->get_id() );
2079
+ $description = ! empty( $post->description ) ? $post->description : aioseo()->meta->description->getPostTypeDescription( 'product' );
2080
+ }
2081
+
2082
+ if ( empty( $description ) ) {
2083
+ $description = $this->description( $product );
2084
+ }
2085
+
2086
+ return apply_filters( 'woo_feed_filter_product_aioseop_description', $description, $product, $this->config );
2087
+ }
2088
+
2089
+ /**
2090
+ * Get Product Short Description
2091
+ *
2092
+ * @param WC_Product $product
2093
+ *
2094
+ * @return mixed|string
2095
+ * @since 3.2.0
2096
+ *
2097
+ */
2098
+ protected function short_description( $product ) {
2099
+ $short_description = $product->get_short_description();
2100
+
2101
+ // Get Variation Short Description
2102
+ if ( $product->is_type( 'variation' ) && empty( $short_description ) ) {
2103
+ $parent = wc_get_product( $product->get_parent_id() );
2104
+ $short_description = $parent->get_short_description();
2105
+ }
2106
+
2107
+
2108
+ $short_description = $this->remove_short_codes( $short_description );
2109
+
2110
+ //strip tags and spacial characters
2111
+ $short_description = woo_feed_strip_all_tags( wp_specialchars_decode( $short_description ) );
2112
+
2113
+ return apply_filters( 'woo_feed_filter_product_short_description', $short_description, $product, $this->config );
2114
+ }
2115
+
2116
+
2117
+ /**
2118
+ * At First convert Short Codes and then Remove failed Short Codes from String
2119
+ *
2120
+ * @param $content
2121
+ *
2122
+ * @return mixed|string
2123
+ * @since 3.2.0
2124
+ *
2125
+ */
2126
+ protected function remove_short_codes( $content ) {
2127
+ if ( $content == '' ) {
2128
+ return '';
2129
+ }
2130
+
2131
+ $content = do_shortcode( $content );
2132
+
2133
+ $content = woo_feed_stripInvalidXml( $content );
2134
+
2135
+ // Covers all kinds of shortcodes
2136
+ $expression = '/\[\/*[a-zA-Z1-90_| -=\'"\{\}]*\/*\]/m';
2137
+
2138
+ $content = preg_replace( $expression, '', $content );
2139
+
2140
+ return strip_shortcodes( $content );
2141
+ }
2142
+
2143
+ /*
2144
+ * Retrieves product's parent category
2145
+ *
2146
+ * @param $product A Post/Product object
2147
+ *
2148
+ * @return WP_Term
2149
+ * @since 4.4.19
2150
+ * */
2151
+ protected function product_parent_category_object( $product ) {
2152
+ global $parent_category_memo;
2153
+ if ( empty( $parent_category_memo ) ) {
2154
+ $parent_category_memo = [];
2155
+ }
2156
+
2157
+ $id = $product->get_id();
2158
+ if ( $product->is_type( 'variation' ) ) {
2159
+ $id = $product->get_parent_id();
2160
+ }
2161
+
2162
+ $taxonomy = 'product_cat';
2163
+ $categories = wp_get_post_terms( $id, $taxonomy );
2164
+ $child_category = $categories[ count( $categories ) - 1 ]; // Last selected category
2165
+
2166
+ $parent_category = '';
2167
+
2168
+ // Memoization for faster parent retrieval
2169
+ if (
2170
+ isset( $parent_category_memo[ $child_category->term_id ] )
2171
+ && ! empty( $parent_category_memo[ $child_category->term_id ] )
2172
+ ) {
2173
+ $parent_category = get_term_by( 'term_id', $parent_category_memo[ $child_category->term_id ], $taxonomy );
2174
+ } else {
2175
+ $parent_category = woo_feed_parent_category( $child_category, $taxonomy );
2176
+ $parent_category_memo[ $child_category->term_id ] = $parent_category->term_id;
2177
+ }
2178
+
2179
+ // Yoast SEO primary term fetching
2180
+ if ( class_exists( 'WPSEO_Primary_Term' ) ) {
2181
+ $wpseo_primary_term = new WPSEO_Primary_Term( $taxonomy, $id );
2182
+ $parent_category_id = $wpseo_primary_term->get_primary_term();
2183
+ if ( ! empty( $parent_category_id ) ) {
2184
+ $parent_category = get_term_by( 'term_id', $parent_category_id, $taxonomy );
2185
+ }
2186
+ }
2187
+
2188
+ return $parent_category;
2189
+ }
2190
+
2191
+ /**
2192
+ * Get Product Parent/Main Category
2193
+ *
2194
+ * @param WC_Product $product
2195
+ *
2196
+ * @return string
2197
+ *
2198
+ */
2199
+ protected function primary_category( $product ) {
2200
+ $parent_category = "";
2201
+ $separator = apply_filters( 'woo_feed_product_type_separator', ' > ', $this->config, $product );
2202
+ $full_category = $this->product_type( $product );
2203
+ if ( ! empty( $full_category ) ) {
2204
+ $full_category_array = explode( $separator, $full_category );
2205
+ $parent_category = $full_category_array[0];
2206
+ }
2207
+
2208
+ return apply_filters( 'woo_feed_filter_product_primary_category', $parent_category, $product, $this->config );
2209
+ }
2210
+
2211
+ /**
2212
+ * Get Product Parent/Main Category ID
2213
+ *
2214
+ * @param WC_Product $product
2215
+ *
2216
+ * @return string
2217
+ *
2218
+ */
2219
+ protected function primary_category_id( $product ) {
2220
+ $parent_category_id = "";
2221
+ $separator = apply_filters( 'woo_feed_product_type_separator', ' > ', $this->config, $product );
2222
+ $full_category = $this->product_type( $product );
2223
+ if ( ! empty( $full_category ) ) {
2224
+ $full_category_array = explode( $separator, $full_category );
2225
+ $parent_category_obj = get_term_by( 'name', $full_category_array[0], 'product_cat' );
2226
+ $parent_category_id = isset( $parent_category_obj->term_id ) ? $parent_category_obj->term_id : "";
2227
+ }
2228
+
2229
+ return apply_filters( 'woo_feed_filter_product_primary_category_id', $parent_category_id, $product, $this->config );
2230
+ }
2231
+
2232
+ /**
2233
+ * Get Product Child Category
2234
+ *
2235
+ * @param WC_Product $product
2236
+ *
2237
+ * @return string
2238
+ */
2239
+ protected function child_category( $product ) {
2240
+ $child_category = "";
2241
+ $separator = apply_filters( 'woo_feed_product_type_separator', ' > ', $this->config, $product );
2242
+ $full_category = $this->product_type( $product );
2243
+ if ( ! empty( $full_category ) ) {
2244
+ $full_category_array = explode( $separator, $full_category );
2245
+ $child_category = end( $full_category_array );
2246
+ }
2247
+
2248
+ return apply_filters( 'woo_feed_filter_product_child_category', $child_category, $product, $this->config );
2249
+ }
2250
+
2251
+ /**
2252
+ * Get Product Child Category ID
2253
+ *
2254
+ * @param WC_Product $product
2255
+ *
2256
+ * @return string
2257
+ */
2258
+ protected function child_category_id( $product ) {
2259
+ $child_category_id = "";
2260
+ $separator = apply_filters( 'woo_feed_product_type_separator', ' > ', $this->config, $product );
2261
+ $full_category = $this->product_type( $product );
2262
+ if ( ! empty( $full_category ) ) {
2263
+ $full_category_array = explode( $separator, $full_category );
2264
+ $child_category_obj = get_term_by( 'name', end( $full_category_array ), 'product_cat' );
2265
+ $child_category_id = isset( $child_category_obj->term_id ) ? $child_category_obj->term_id : "";
2266
+ }
2267
+
2268
+ return apply_filters( 'woo_feed_filter_product_child_category_id', $child_category_id, $product, $this->config );
2269
+ }
2270
+
2271
+ /**
2272
+ * Get Product Categories
2273
+ *
2274
+ * @param WC_Product $product
2275
+ *
2276
+ * @return string
2277
+ * @since 3.2.0
2278
+ *
2279
+ */
2280
+ protected function product_type( $product ) {
2281
+ $id = $product->get_id();
2282
+ if ( $product->is_type( 'variation' ) ) {
2283
+ $id = $product->get_parent_id();
2284
+ }
2285
+
2286
+ $separator = apply_filters( 'woo_feed_product_type_separator', ' > ', $this->config, $product );
2287
+
2288
+ $product_type = woo_feed_strip_all_tags( wc_get_product_category_list( $id, $separator ) );
2289
+
2290
+ $product_categories = '';
2291
+ $term_list = get_the_terms( $id, 'product_cat' );
2292
+
2293
+ if ( is_array( $term_list ) ) {
2294
+ $col = array_column( $term_list, "term_id" );
2295
+ array_multisort( $col, SORT_ASC, $term_list );
2296
+ $term_list = array_column( $term_list, "name" );
2297
+ $product_categories = implode( $separator, $term_list );
2298
+ }
2299
+
2300
+
2301
+ return apply_filters( 'woo_feed_filter_product_local_category', $product_categories, $product, $this->config );
2302
+ }
2303
+
2304
+ /**
2305
+ * Get Product Full Categories with unselected category parent
2306
+ *
2307
+ * @param WC_Product $product
2308
+ *
2309
+ * @return string
2310
+ * @since 4.3.47
2311
+ */
2312
+ protected function product_full_cat( $product ) {
2313
+ // $id = $product->get_id();
2314
+ // if ($product->is_type('variation')) {
2315
+ // $id = $product->get_parent_id();
2316
+ // }
2317
+ //
2318
+ // $separator = apply_filters('woo_feed_product_type_separator', '>', $this->config, $product);
2319
+ //
2320
+ // $product_type = woo_feed_get_terms_list_hierarchical_order($id);
2321
+
2322
+ $product_type = $this->product_type( $product );
2323
+
2324
+ return apply_filters( 'woo_feed_filter_product_local_category', $product_type, $product, $this->config );
2325
+ }
2326
+
2327
+ /**
2328
+ * Get Product URL
2329
+ *
2330
+ * @param WC_Product|WC_Product_Variation $product
2331
+ *
2332
+ * @return string
2333
+ * @since 3.2.0
2334
+ *
2335
+ */
2336
+ protected function link( $product ) {
2337
+
2338
+ $link = $product->get_permalink();
2339
+
2340
+ $link = $this->add_utm_tracker( $link );
2341
+
2342
+ return apply_filters( 'woo_feed_filter_product_link', $link, $product, $this->config );
2343
+ }
2344
+
2345
+ /**
2346
+ * Adding UTM Tracker Query Arguments to URL
2347
+ *
2348
+ * @param string $url
2349
+ *
2350
+ * @return string $url
2351
+ * @since 4.4.26
2352
+ */
2353
+ protected function add_utm_tracker( $url ) {
2354
+
2355
+ $utm = $this->config['campaign_parameters'];
2356
+
2357
+ if ( ! empty( $utm['utm_source'] ) && ! empty( $utm['utm_medium'] ) && ! empty( $utm['utm_campaign'] ) ) {
2358
+
2359
+ $utm = [
2360
+ 'utm_source' => str_replace( ' ', '+', $utm['utm_source'] ),
2361
+ 'utm_medium' => str_replace( ' ', '+', $utm['utm_medium'] ),
2362
+ 'utm_campaign' => str_replace( ' ', '+', $utm['utm_campaign'] ),
2363
+ 'utm_term' => str_replace( ' ', '+', $utm['utm_term'] ),
2364
+ 'utm_content' => str_replace( ' ', '+', $utm['utm_content'] ),
2365
+ ];
2366
+
2367
+ $url = add_query_arg( array_filter( $utm ), $url );
2368
+
2369
+ }
2370
+
2371
+ return $url;
2372
+ }
2373
+
2374
+ /**
2375
+ * Get Parent Product URL
2376
+ *
2377
+ * @param WC_Product $product
2378
+ *
2379
+ * @return string
2380
+ * @author Nazrul Islam Nayan
2381
+ * @since 5.1.8
2382
+ */
2383
+ protected function parent_link( $product ) {
2384
+ if ( $product->is_type( 'variation' ) ) {
2385
+ $product = wc_get_product( $product->get_parent_id() );
2386
+ $link = $this->link( $product );
2387
+ } else {
2388
+ $link = $this->link( $product );
2389
+ }
2390
+
2391
+ return apply_filters( 'woo_feed_filter_product_parent_link', $link, $product, $this->config );
2392
+ }
2393
+
2394
+ /**
2395
+ * Get Canonical Link
2396
+ *
2397
+ * @param WC_Product $product
2398
+ *
2399
+ * @return mixed
2400
+ */
2401
+ protected function canonical_link( $product ) {
2402
+ if ( $product->is_type( 'variation' ) ) {
2403
+ $product = wc_get_product( $product->get_parent_id() );
2404
+ $canonical_link = $product->get_permalink();
2405
+ } else {
2406
+ $canonical_link = $product->get_permalink();
2407
+ }
2408
+
2409
+ return apply_filters( 'woo_feed_filter_product_canonical_link', $canonical_link, $product, $this->config );
2410
+ }
2411
+
2412
+ /**
2413
+ * Get External Product URL
2414
+ *
2415
+ * @param WC_Product $product
2416
+ *
2417
+ * @return string
2418
+ * @since 3.2.0
2419
+ *
2420
+ */
2421
+ protected function ex_link( $product ) {
2422
+ if ( $product->is_type( 'external' ) ) {
2423
+ $utm = $this->config['campaign_parameters'];
2424
+ if ( ! empty( $utm['utm_source'] ) && ! empty( $utm['utm_medium'] ) && ! empty( $utm['utm_campaign'] ) ) {
2425
+ $utm = [
2426
+ 'utm_source' => str_replace( ' ', '+', $utm['utm_source'] ),
2427
+ 'utm_medium' => str_replace( ' ', '+', $utm['utm_medium'] ),
2428
+ 'utm_campaign' => str_replace( ' ', '+', $utm['utm_campaign'] ),
2429
+ 'utm_term' => str_replace( ' ', '+', $utm['utm_term'] ),
2430
+ 'utm_content' => str_replace( ' ', '+', $utm['utm_content'] ),
2431
+ ];
2432
+
2433
+ return add_query_arg( array_filter( $utm ), $product->get_product_url() );
2434
+ } else {
2435
+ $ex_link = $product->get_product_url();
2436
+ }
2437
+ } else {
2438
+ $ex_link = '';
2439
+ }
2440
+
2441
+ return apply_filters( 'woo_feed_filter_product_ex_link', $ex_link, $product, $this->config );
2442
+ }
2443
+
2444
+ /**
2445
+ * Get Product Image
2446
+ *
2447
+ * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product Product Object.
2448
+ *
2449
+ * @return mixed
2450
+ * @since 3.2.0
2451
+ *
2452
+ */
2453
+ protected function image( $product ) {
2454
+ $image = '';
2455
+ if ( $product->is_type( 'variation' ) ) {
2456
+ // Variation product type
2457
+ if ( has_post_thumbnail( $product->get_id() ) ) {
2458
+ $getImage = wp_get_attachment_image_src( get_post_thumbnail_id( $product->get_id() ), 'single-post-thumbnail' );
2459
+ $image = woo_feed_get_formatted_url( $getImage[0] );
2460
+ } elseif ( has_post_thumbnail( $product->get_parent_id() ) ) {
2461
+ $getImage = wp_get_attachment_image_src( get_post_thumbnail_id( $product->get_parent_id() ), 'single-post-thumbnail' );
2462
+ $image = woo_feed_get_formatted_url( $getImage[0] );
2463
+ }
2464
+ } elseif ( has_post_thumbnail( $product->get_id() ) ) { // All product type except variation
2465
+ $getImage = wp_get_attachment_image_src( get_post_thumbnail_id( $product->get_id() ), 'single-post-thumbnail' );
2466
+ $image = isset( $getImage[0] ) ? woo_feed_get_formatted_url( $getImage[0] ) : '';
2467
+ }
2468
+
2469
+ return apply_filters( 'woo_feed_filter_product_image', $image, $product, $this->config );
2470
+ }
2471
+
2472
+ /**
2473
+ * Get Product Featured Image. For product variations it will return the variable product image.
2474
+ *
2475
+ * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product Product Object.
2476
+ *
2477
+ * @return mixed
2478
+ * @since 3.2.0
2479
+ *
2480
+ */
2481
+ protected function feature_image( $product ) {
2482
+ if ( $product->is_type( 'variation' ) ) {
2483
+ $id = $product->get_parent_id();
2484
+ } else {
2485
+ $id = $product->get_id();
2486
+ }
2487
+
2488
+ $getImage = wp_get_attachment_image_src( get_post_thumbnail_id( $id ), 'single-post-thumbnail' );
2489
+ $image = isset( $getImage[0] ) ? woo_feed_get_formatted_url( $getImage[0] ) : '';
2490
+
2491
+ return apply_filters( 'woo_feed_filter_product_feature_image', $image, $product, $this->config );
2492
+ }
2493
+
2494
+ /**
2495
+ * Get Comma Separated Product Images
2496
+ *
2497
+ * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product Product Object.
2498
+ * @param string $additionalImg Specific Additional Image.
2499
+ *
2500
+ * @return mixed
2501
+ * @since 3.2.0
2502
+ *
2503
+ */
2504
+ protected function images( $product, $additionalImg = '' ) {
2505
+ $imgUrls = $this->get_product_gallery( $product );
2506
+ $separator = ',';
2507
+
2508
+ // Return Specific Additional Image URL
2509
+ if ( '' !== $additionalImg ) {
2510
+ if ( array_key_exists( $additionalImg, $imgUrls ) ) {
2511
+ $images = $imgUrls[ $additionalImg ];
2512
+ } else {
2513
+ $images = '';
2514
+ }
2515
+ } else {
2516
+ if ( isset( $this->config['provider'] ) && "idealo" === $this->config['provider'] ) {
2517
+ $separator = ';';
2518
+ }
2519
+
2520
+ $images = implode( $separator, array_filter( $imgUrls ) );
2521
+ }
2522
+
2523
+ return apply_filters( 'woo_feed_filter_product_images', $images, $product, $this->config );
2524
+ }
2525
+
2526
+ /**
2527
+ * Get Product Gallery Items (URL) array.
2528
+ * This can contains empty array values
2529
+ *
2530
+ * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product
2531
+ *
2532
+ * @return string[]
2533
+ * @since 3.2.6
2534
+ */
2535
+ protected function get_product_gallery( $product ) {
2536
+ $imgUrls = [];
2537
+ $attachmentIds = [];
2538
+
2539
+ if ( $product->is_type( 'variation' ) ) {
2540
+ if ( class_exists( 'Woo_Variation_Gallery' ) ) {
2541
+ /**
2542
+ * Get Variation Additional Images for "Additional Variation Images Gallery for WooCommerce"
2543
+ * @plugin Additional Variation Images Gallery for WooCommerce
2544
+ * @link https://wordpress.org/plugins/woo-variation-gallery/
2545
+ */
2546
+ $attachmentIds = get_post_meta( $product->get_id(), 'woo_variation_gallery_images', true );
2547
+ } elseif ( class_exists( 'WooProductVariationGallery' ) ) {
2548
+ /**
2549
+ * Get Variation Additional Images for "Variation Images Gallery for WooCommerce"
2550
+ * @plugin Variation Images Gallery for WooCommerce
2551
+ * @link https://wordpress.org/plugins/woo-product-variation-gallery/
2552
+ */
2553
+ $attachmentIds = get_post_meta( $product->get_id(), 'rtwpvg_images', true );
2554
+ } elseif ( class_exists( 'WC_Additional_Variation_Images' ) ) {
2555
+ /**
2556
+ * Get Variation Additional Images for "WooCommerce Additional Variation Images"
2557
+ * @plugin WooCommerce Additional Variation Images
2558
+ * @link https://woocommerce.com/products/woocommerce-additional-variation-images/
2559
+ */
2560
+ $attachmentIds = explode( ',', get_post_meta( $product->get_id(), '_wc_additional_variation_images', true ) );
2561
+ } elseif ( class_exists( 'WOODMART_Theme' ) ) {
2562
+ /**
2563
+ * Get Variation Additional Images for "WOODMART Theme -> Variation Gallery Images Feature"
2564
+ * @theme WOODMART
2565
+ * @link https://themeforest.net/item/woodmart-woocommerce-wordpress-theme/20264492
2566
+ */
2567
+ $var_id = $product->get_id();
2568
+ $parent_id = $product->get_parent_id();
2569
+
2570
+ $variation_obj = get_post_meta( $parent_id, 'woodmart_variation_gallery_data', true );
2571
+ if ( isset( $variation_obj ) && isset( $variation_obj[ $var_id ] ) ) {
2572
+ $attachmentIds = explode( ',', $variation_obj[ $var_id ] );
2573
+ } else {
2574
+ $attachmentIds = explode( ',', get_post_meta( $var_id, 'wd_additional_variation_images_data', true ) );
2575
+ }
2576
+ } else {
2577
+ /**
2578
+ * If any Variation Gallery Image plugin not installed then get Variable Product Additional Image Ids .
2579
+ */
2580
+ $attachmentIds = wc_get_product( $product->get_parent_id() )->get_gallery_image_ids();
2581
+ }
2582
+ }
2583
+
2584
+ /**
2585
+ * Get Variable Product Gallery Image ids if Product is not a variation
2586
+ * or variation does not have any gallery images
2587
+ */
2588
+ if ( empty( $attachmentIds ) ) {
2589
+ $attachmentIds = $product->get_gallery_image_ids();
2590
+ }
2591
+
2592
+ if ( $attachmentIds && is_array( $attachmentIds ) ) {
2593
+ $mKey = 1;
2594
+ foreach ( $attachmentIds as $attachmentId ) {
2595
+ $imgUrls[ $mKey ] = woo_feed_get_formatted_url( wp_get_attachment_url( $attachmentId ) );
2596
+ $mKey ++;
2597
+ }
2598
+ }
2599
+
2600
+ return $imgUrls;
2601
+ }
2602
+
2603
+ /**
2604
+ * Get Product Condition
2605
+ *
2606
+ * @param WC_Product $product
2607
+ *
2608
+ * @return mixed
2609
+ * @since 3.2.0
2610
+ *
2611
+ */
2612
+ protected function condition( $product ) {
2613
+ return apply_filters( 'woo_feed_product_condition', 'new', $product );
2614
+ }
2615
+
2616
+ /**
2617
+ * Get Product Type
2618
+ *
2619
+ * @param WC_Product $product
2620
+ *
2621
+ * @return mixed
2622
+ * @since 3.2.0
2623
+ *
2624
+ */
2625
+ protected function type( $product ) {
2626
+ return apply_filters( 'woo_feed_filter_product_type', $product->get_type(), $product, $this->config );
2627
+ }
2628
+
2629
+ /**
2630
+ * Get Product is a bundle product or not
2631
+ *
2632
+ * @param WC_Product $product
2633
+ *
2634
+ * @return mixed
2635
+ * @since 3.2.0
2636
+ *
2637
+ */
2638
+ protected function is_bundle( $product ) {
2639
+ if ( $product->is_type( 'bundle' ) || $product->is_type( 'yith_bundle' ) ) {
2640
+ $is_bundle = 'yes';
2641
+ } else {
2642
+ $is_bundle = 'no';
2643
+ }
2644
+
2645
+ return apply_filters( 'woo_feed_filter_product_is_bundle', $is_bundle, $product, $this->config );
2646
+ }
2647
+
2648
+ /**
2649
+ * Get Product is a multi-pack product or not
2650
+ *
2651
+ * @param WC_Product $product
2652
+ *
2653
+ * @return mixed
2654
+ * @since 3.2.0
2655
+ *
2656
+ */
2657
+ protected function multipack( $product ) {
2658
+ $multi_pack = '';
2659
+ if ( $product->is_type( 'grouped' ) ) {
2660
+ $multi_pack = ( ! empty( $product->get_children() ) ) ? count( $product->get_children() ) : '';
2661
+ }
2662
+
2663
+ return $multi_pack;
2664
+ }
2665
+
2666
+ /**
2667
+ * Get Product visibility status
2668
+ *
2669
+ * @param WC_Product $product
2670
+ *
2671
+ * @return mixed
2672
+ * @since 3.2.0
2673
+ *
2674
+ */
2675
+ protected function visibility( $product ) {
2676
+ return apply_filters( 'woo_feed_filter_product_visibility', $product->get_catalog_visibility(), $product, $this->config );
2677
+ }
2678
+
2679
+ /**
2680
+ * Get Product Total Rating
2681
+ *
2682
+ * @param WC_Product $product
2683
+ *
2684
+ * @return mixed
2685
+ * @since 3.2.0
2686
+ *
2687
+ */
2688
+ protected function rating_total( $product ) {
2689
+ return apply_filters( 'woo_feed_filter_product_rating_total', $product->get_rating_count(), $product, $this->config );
2690
+ }
2691
+
2692
+ /**
2693
+ * Get Product average rating
2694
+ *
2695
+ * @param WC_Product $product
2696
+ *
2697
+ * @return mixed
2698
+ * @since 3.2.0
2699
+ *
2700
+ */
2701
+ protected function rating_average( $product ) {
2702
+ return apply_filters( 'woo_feed_filter_product_rating_average', $product->get_average_rating(), $product, $this->config );
2703
+ }
2704
+
2705
+ /**
2706
+ * Get Product tags
2707
+ *
2708
+ * @param WC_Product $product
2709
+ *
2710
+ * @return string
2711
+ * @since 3.2.0
2712
+ *
2713
+ */
2714
+ protected function tags( $product ) {
2715
+ $id = $product->get_id();
2716
+ if ( $product->is_type( 'variation' ) ) {
2717
+ $id = $product->get_parent_id();
2718
+ }
2719
+
2720
+ /**
2721
+ * Separator for multiple tags
2722
+ *
2723
+ * @param string $separator
2724
+ * @param array $config
2725
+ * @param WC_Abstract_Legacy_Product $product
2726
+ *
2727
+ * @since 3.4.3
2728
+ */
2729
+ $separator = apply_filters( 'woo_feed_tags_separator', ',', $this->config, $product );
2730
+
2731
+ $tags = woo_feed_strip_all_tags( get_the_term_list( $id, 'product_tag', '', $separator, '' ) );
2732
+
2733
+ return apply_filters( 'woo_feed_filter_product_tags', $tags, $product, $this->config );
2734
+ }
2735
+
2736
+ /**
2737
+ * Get Product Parent Id
2738
+ *
2739
+ * @param WC_Product $product
2740
+ *
2741
+ * @return mixed
2742
+ * @since 3.2.0
2743
+ *
2744
+ */
2745
+ protected function item_group_id( $product ) {
2746
+ $id = $product->get_id();
2747
+ if ( $product->is_type( 'variation' ) ) {
2748
+ $id = $product->get_parent_id();
2749
+ }
2750
+
2751
+ return apply_filters( 'woo_feed_filter_product_item_group_id', $id, $product, $this->config );
2752
+ }
2753
+
2754
+ /**
2755
+ * Get Product SKU
2756
+ *
2757
+ * @param WC_Product $product
2758
+ *
2759
+ * @return mixed
2760
+ * @since 3.2.0
2761
+ *
2762
+ */
2763
+ protected function sku( $product ) {
2764
+ return apply_filters( 'woo_feed_filter_product_sku', $product->get_sku(), $product, $this->config );
2765
+ }
2766
+
2767
+ /**
2768
+ * Get Product SKU ID. It should come with after merging of sku and product id with '_' sign.
2769
+ *
2770
+ * @param WC_Product $product
2771
+ *
2772
+ * @return string
2773
+ * @author Nazrul Islam Nayan
2774
+ * @since 4.3.13
2775
+ */
2776
+ protected function sku_id( $product ) {
2777
+ $sku = ! empty( $product->get_sku() ) ? $product->get_sku() . '_' : '';
2778
+ $sku_id = $sku . $product->get_id();
2779
+
2780
+ return apply_filters( 'woo_feed_filter_product_sku_id', $sku_id, $product, $this->config );
2781
+ }
2782
+
2783
+ /**
2784
+ * Get Product Parent SKU
2785
+ *
2786
+ * @param WC_Product $product
2787
+ *
2788
+ * @return mixed
2789
+ * @since 3.2.0
2790
+ *
2791
+ */
2792
+ protected function parent_sku( $product ) {
2793
+ if ( $product->is_type( 'variation' ) ) {
2794
+ $id = $product->get_parent_id();
2795
+ $parent = wc_get_product( $id );
2796
+
2797
+ $parent_sku = $parent->get_sku();
2798
+ } else {
2799
+ $parent_sku = $product->get_sku();
2800
+ }
2801
+
2802
+ return apply_filters( 'woo_feed_filter_product_parent_sku', $parent_sku, $product, $this->config );
2803
+ }
2804
+
2805
+ /**
2806
+ * Get Product Availability Status
2807
+ *
2808
+ * @param WC_Product $product
2809
+ *
2810
+ * @return mixed
2811
+ * @since 3.2.0
2812
+ *
2813
+ */
2814
+ protected function availability( $product ) {
2815
+ $status = $product->get_stock_status();
2816
+ if ( 'instock' == $status ) {
2817
+ $status = 'in stock';
2818
+ } elseif ( 'outofstock' == $status ) {
2819
+ $status = 'out of stock';
2820
+ } elseif ( 'onbackorder' == $status ) {
2821
+ $status = 'on backorder';
2822
+ }
2823
+
2824
+ // set (_) as separator for google merchant
2825
+ if ( isset( $this->config['provider'] ) && 'google' === $this->config['provider'] ) {
2826
+ $status = explode( ' ', $status );
2827
+ $status = implode( '_', $status );
2828
+ }
2829
+
2830
+ return apply_filters( 'woo_feed_filter_product_availability', $status, $product, $this->config );
2831
+ }
2832
+
2833
+ /**
2834
+ * Get Product Availability Date
2835
+ *
2836
+ * @param WC_Product $product
2837
+ *
2838
+ * @return mixed
2839
+ * @author Ohidul Islam
2840
+ * @since 3.2.0
2841
+ *
2842
+ */
2843
+ protected function availability_date( $product ) {
2844
+
2845
+ $feed_settings = get_option( 'woo_feed_settings' );
2846
+
2847
+ $availability_date_settings = isset( $feed_settings['woo_feed_identifier']['availability_date'] )
2848
+ ? $feed_settings['woo_feed_identifier']['availability_date']
2849
+ : 'enable';
2850
+
2851
+ if ( $product->get_stock_status() !== 'onbackorder' || $availability_date_settings === 'disable' ) {
2852
+ return '';
2853
+ }
2854
+
2855
+ $meta_field_name = 'woo_feed_availability_date';
2856
+
2857
+ if ( $product->is_type( 'variation' ) ) {
2858
+ $meta_field_name .= '_var';
2859
+ }
2860
+
2861
+ $availability_date = get_post_meta( $product->get_id(), $meta_field_name, true );
2862
+
2863
+ if ( '' !== $availability_date && in_array( $this->config['provider'], [
2864
+ 'google',
2865
+ 'facebook',
2866
+ 'pinterest',
2867
+ 'bing',
2868
+ 'snapchat',
2869
+ ], true ) ) {
2870
+ $availability_date = gmdate( 'c', strtotime( $availability_date ) );
2871
+ }
2872
+
2873
+ return apply_filters( 'woo_feed_filter_product_availability_date', $availability_date, $product, $this->config );
2874
+ }
2875
+
2876
+ /**
2877
+ * Get Product Add to Cart Link
2878
+ *
2879
+ * @param WC_Product $product
2880
+ *
2881
+ * @return string
2882
+ * @author Nazrul Islam Nayan
2883
+ * @since 5.1.8
2884
+ */
2885
+ protected function add_to_cart_link( $product ) {
2886
+ $url = $this->link( $product );
2887
+ $suffix = 'add-to-cart=' . $product->get_id();
2888
+
2889
+ $add_to_cart_link = woo_feed_make_url_with_parameter( $url, $suffix );
2890
+
2891
+ return apply_filters( 'woo_feed_filter_product_add_to_cart_link', $add_to_cart_link, $product, $this->config );
2892
+ }
2893
+
2894
+ /**
2895
+ * Get Product Quantity
2896
+ *
2897
+ * @param WC_Product $product
2898
+ *
2899
+ * @return mixed
2900
+ * @since 3.2.0
2901
+ *
2902
+ */
2903
+ protected function quantity( $product ) {
2904
+ $quantity = $product->get_stock_quantity();
2905
+ $status = $product->get_stock_status();
2906
+
2907
+ //when product is outofstock and it's quantity is empty, set quantity to 0
2908
+ if ( 'outofstock' == $status && empty( $quantity ) ) {
2909
+ $quantity = 0;
2910
+ }
2911
+
2912
+ if ( $product->is_type( 'variable' ) && $product->has_child() ) {
2913
+ $visible_children = $product->get_visible_children();
2914
+ $qty = array();
2915
+ foreach ( $visible_children as $key => $child ) {
2916
+ $childQty = get_post_meta( $child, '_stock', true );
2917
+ $qty[] = (int) $childQty + 0;
2918
+ }
2919
+
2920
+ if ( isset( $this->config['variable_quantity'] ) ) {
2921
+ $vaQty = $this->config['variable_quantity'];
2922
+ if ( 'max' == $vaQty ) {
2923
+ $quantity = max( $qty );
2924
+ } elseif ( 'min' == $vaQty ) {
2925
+ $quantity = min( $qty );
2926
+ } elseif ( 'sum' == $vaQty ) {
2927
+ $quantity = array_sum( $qty );
2928
+ } elseif ( 'first' == $vaQty ) {
2929
+ $quantity = ( (int) $qty[0] );
2930
+ }
2931
+
2932
+ $quantity = array_sum( $qty );
2933
+ }
2934
+ }
2935
+
2936
+ return apply_filters( 'woo_feed_filter_product_quantity', $quantity, $product, $this->config );
2937
+ }
2938
+
2939
+ /**
2940
+ * Get Product Currency
2941
+ *
2942
+ * @param WC_Product $product
2943
+ *
2944
+ * @return mixed
2945
+ * @since 4.4.39
2946
+ *
2947
+ */
2948
+ protected function currency( $product ) {
2949
+ $quantity = get_option( 'woocommerce_currency' );
2950
+
2951
+ return apply_filters( 'woo_feed_filter_product_currency', $quantity, $product, $this->config );
2952
+ }
2953
+
2954
+ /**
2955
+ * Get Store currency code.
2956
+ *
2957
+ * @param WC_Product $product Product Object
2958
+ *
2959
+ * @return mixed|string
2960
+ * @since 3.2.0
2961
+ *
2962
+ */
2963
+ protected function store_currency( $product ) {
2964
+ return get_woocommerce_currency();
2965
+ }
2966
+
2967
+ /**
2968
+ * Get Product Sale Price Start Date
2969
+ *
2970
+ * @param WC_Product $product
2971
+ *
2972
+ * @return mixed
2973
+ * @since 3.2.0
2974
+ *
2975
+ */
2976
+ protected function sale_price_sdate( $product ) {
2977
+ $startDate = $product->get_date_on_sale_from();
2978
+ if ( is_object( $startDate ) ) {
2979
+ $sale_price_sdate = $startDate->date_i18n();
2980
+ } else {
2981
+ $sale_price_sdate = '';
2982
+ }
2983
+
2984
+ return apply_filters( 'woo_feed_filter_product_sale_price_sdate', $sale_price_sdate, $product, $this->config );
2985
+ }
2986
+
2987
+ /**
2988
+ * Get Product Sale Price End Date
2989
+ *
2990
+ * @param WC_Product $product
2991
+ *
2992
+ * @return mixed
2993
+ * @since 3.2.0
2994
+ *
2995
+ */
2996
+ protected function sale_price_edate( $product ) {
2997
+ $endDate = $product->get_date_on_sale_to();
2998
+ if ( is_object( $endDate ) ) {
2999
+ $sale_price_edate = $endDate->date_i18n();
3000
+ } else {
3001
+ $sale_price_edate = "";
3002
+ }
3003
+
3004
+ return apply_filters( 'woo_feed_filter_product_sale_price_edate', $sale_price_edate, $product, $this->config );
3005
+ }
3006
+
3007
+ /**
3008
+ * Get feed currency
3009
+ *
3010
+ * @return mixed|string
3011
+ */
3012
+ protected function get_feed_currency() {
3013
+ $currency = get_woocommerce_currency();
3014
+ if ( isset( $this->config['feedCurrency'] ) ) {
3015
+ $currency = $this->config['feedCurrency'];
3016
+ }
3017
+
3018
+ return $currency;
3019
+ }
3020
+
3021
+ /**
3022
+ * Get Product Price by default WooCommerce Price Type (regular_price|price|sale_price).
3023
+ *
3024
+ * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product Object
3025
+ * @param string $price_type Price Type (regular_price|price|sale_price)
3026
+ * @param bool $tax Add tax with price (true|false)
3027
+ *
3028
+ * @return float|mixed|string|void
3029
+ * @since 4.4.14
3030
+ *
3031
+ * @author Ohidul Islam
3032
+ */
3033
+ protected function get_price_by_price_type( $product, $price_type, $tax ) {
3034
+
3035
+ if ( 'regular_price' === $price_type ) {
3036
+ $price = $product->get_regular_price();
3037
+ } elseif ( 'price' === $price_type ) {
3038
+ $price = $product->get_price();
3039
+ } else {
3040
+ $price = $product->get_sale_price();
3041
+ }
3042
+
3043
+ // Get WooCommerce Multi language Price by Currency.
3044
+ $price = apply_filters( 'woo_feed_wcml_price',
3045
+ $price, $product->get_id(), $this->get_feed_currency(), '_' . $price_type
3046
+ );
3047
+
3048
+ // Get Price with tax
3049
+ if ( true === $tax ) {
3050
+ $price = woo_feed_get_price_with_tax( $price, $product );
3051
+ }
3052
+
3053
+ return $price;
3054
+ }
3055
+
3056
+ /**
3057
+ * Get Product Price by Product Type.
3058
+ *
3059
+ * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product Object
3060
+ * @param string $price_type Price Type (regular_price|price|sale_price)
3061
+ * @param bool $tax Add tax with price (true|false)
3062
+ *
3063
+ * @return float|int|mixed|string
3064
+ * @since 4.4.14
3065
+ *
3066
+ * @author Ohidul Islam
3067
+ */
3068
+ protected function get_price_by_product_type( $product, $price_type, $tax = false ) {
3069
+ if ( $product->is_type( 'variable' ) ) {
3070
+ $price = $this->getVariableProductPrice( $product, $price_type, $tax );
3071
+ } elseif ( $product->is_type( 'grouped' ) ) {
3072
+ $price = $this->getGroupProductPrice( $product, $price_type, $tax );
3073
+ } elseif ( $product->is_type( 'bundle' ) ) {
3074
+ //TODO Diff taxation
3075
+ $price = $this->getBundleProductPrice( $product, $price_type, $tax );
3076
+ } elseif ( $product->is_type( 'composite' ) ) {
3077
+ //TODO Diff taxation
3078
+ $price = $this->getCompositeProductPrice( $product, $price_type, $tax );
3079
+ } elseif ( $product->is_type( 'bundled' ) ) {
3080
+ // iconic woocommerce product bundled plugin
3081
+ $price = $this->iconic_bundle_product_price( $product, $price_type, $tax );
3082
+ } else {
3083
+ $price = $this->get_price_by_price_type( $product, $price_type, $tax );
3084
+ }
3085
+
3086
+ return $price > 0 ? $price : '';
3087
+ }
3088
+
3089
+ /**
3090
+ * Get Product Regular Price
3091
+ *
3092
+ * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product Object.
3093
+ *
3094
+ * @return mixed
3095
+ * @since 3.2.0
3096
+ *
3097
+ */
3098
+ protected function price( $product ) {
3099
+
3100
+ $regular_price = $this->get_price_by_product_type( $product, 'regular_price' );
3101
+
3102
+ return apply_filters( 'woo_feed_filter_product_price', $regular_price, $product, $this->config, false );
3103
+ }
3104
+
3105
+ /**
3106
+ * Get Product Price
3107
+ *
3108
+ * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product object.
3109
+ *
3110
+ * @return int|float|mixed
3111
+ * @since 3.2.0
3112
+ *
3113
+ */
3114
+ protected function current_price( $product ) {
3115
+
3116
+ $price = $this->get_price_by_product_type( $product, 'price' );
3117
+
3118
+ return apply_filters( 'woo_feed_filter_product_regular_price', $price, $product, $this->config, false );
3119
+ }
3120
+
3121
+ /**
3122
+ * Get Product Sale Price
3123
+ *
3124
+ * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product object.
3125
+ *
3126
+ * @return mixed
3127
+ * @since 3.2.0
3128
+ *
3129
+ */
3130
+ protected function sale_price( $product ) {
3131
+
3132
+ $sale_price = $this->get_price_by_product_type( $product, 'sale_price' );
3133
+
3134
+ return apply_filters( 'woo_feed_filter_product_sale_price', $sale_price, $product, $this->config, false );
3135
+ }
3136
+
3137
+ /**
3138
+ * Get Product Regular Price with Tax
3139
+ *
3140
+ * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product Object.
3141
+ *
3142
+ * @return mixed
3143
+ * @since 3.2.0
3144
+ *
3145
+ */
3146
+ protected function price_with_tax( $product ) {
3147
+
3148
+ $regular_price_with_tax = $this->get_price_by_product_type( $product, 'regular_price', true );
3149
+
3150
+ return apply_filters( 'woo_feed_filter_product_price_with_tax', $regular_price_with_tax, $product, $this->config, true );
3151
+ }
3152
+
3153
+ /**
3154
+ * Get Product Regular Price with Tax
3155
+ *
3156
+ * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product object.
3157
+ *
3158
+ * @return mixed
3159
+ * @since 3.2.0
3160
+ *
3161
+ */
3162
+ protected function current_price_with_tax( $product ) {
3163
+
3164
+ $price_with_tax = $this->get_price_by_product_type( $product, 'price', true );
3165
+
3166
+ return apply_filters( 'woo_feed_filter_product_regular_price_with_tax', $price_with_tax, $product, $this->config, true );
3167
+ }
3168
+
3169
+ /**
3170
+ * Get Product Regular Price with Tax
3171
+ *
3172
+ * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product object.
3173
+ *
3174
+ * @return mixed
3175
+ * @since 3.2.0
3176
+ *
3177
+ */
3178
+ protected function sale_price_with_tax( $product ) {
3179
+
3180
+ $sale_price_with_tax = $this->get_price_by_product_type( $product, 'sale_price', true );
3181
+
3182
+ return apply_filters( 'woo_feed_filter_product_sale_price_with_tax', $sale_price_with_tax, $product, $this->config, true );
3183
+ }
3184
+
3185
+ /**
3186
+ * Get Composite Product Price
3187
+ *
3188
+ * @param WC_Product|WC_Product_Composite|WC_Composite_Products $product Composite Product object.
3189
+ * @param string $type Price Type (regular_price|price|sale_price)
3190
+ * @param bool $tax Add tax with price (true|false)
3191
+ *
3192
+ * @return int|float|double
3193
+ * @since 3.2.6
3194
+ */
3195
+ protected function getCompositeProductPrice( $product, $type, $tax = false ) {
3196
+ if ( class_exists( 'WC_Product_Composite' ) && class_exists( 'WPCleverWooco' ) ) {
3197
+ // WPC Composite Product
3198
+ return $this->get_wpc_composite_price( $product, $type, $tax );
3199
+ } elseif ( class_exists( 'WC_Composite_Products' ) ) {
3200
+ // WooCommerce Composite Product
3201
+ return $this->get_wc_composite_product_price( $product, $type, $tax );
3202
+ } else {
3203
+ // Get Base Price for Others Composite Products.
3204
+ // Note*: YITH does not auto select components. So no need to calculate component price.
3205
+ return $this->get_price_by_price_type( $product, $type, $tax );
3206
+ }
3207
+ }
3208
+
3209
+ /**
3210
+ * Get WooCommerce Composite Product Price
3211
+ * Plugin URL: https://wordpress.org/plugins/wpc-composite-products/
3212
+ * Product Type: composite
3213
+ *
3214
+ * @param WC_Product|WC_Product_Composite $product
3215
+ * @param string $type Price Type (regular_price|price|sale_price)
3216
+ * @param bool $tax Add tax with price (true|false)
3217
+ *
3218
+ * @return float|int|mixed|string|void
3219
+ */
3220
+ protected function get_wc_composite_product_price( $product, $type, $tax ) {
3221
+ $price = 0;
3222
+ // Parent Component Price
3223
+ $base_price = $this->get_price_by_price_type( $product, $type, $tax );
3224
+ if ( isset( $this->config['composite_price'] ) && 'all_product_price' == $this->config['composite_price'] ) {
3225
+ $composite = new WC_Product_Composite( $product );
3226
+
3227
+ if ( 'price' === $type || 'sale_price' === $type ) {
3228
+ $price = $composite->get_composite_price();
3229
+ } else {
3230
+ $price = $composite->get_composite_regular_price();
3231
+ }
3232
+
3233
+ // Get WooCommerce Multi language Price by Currency.
3234
+ $price = apply_filters( 'woo_feed_wcml_price',
3235
+ $price, $product->get_id(), $this->get_feed_currency(), '_' . $type
3236
+ );
3237
+
3238
+ // Get Price with tax
3239
+ if ( true === $tax ) {
3240
+ $price = woo_feed_get_price_with_tax( $price, $composite );
3241
+ }
3242
+ } else {
3243
+ $price = $base_price;
3244
+ }
3245
+
3246
+ return $price > 0 ? $price : '';
3247
+ }
3248
+
3249
+ /**
3250
+ * Get WPC Composite Product Price.
3251
+ * Plugin URL: https://wordpress.org/plugins/wpc-composite-products/
3252
+ * Product Type: composite
3253
+ *
3254
+ * @param WC_Product|WC_Product_Composite $product
3255
+ * @param string $type Price Type (regular_price|price|sale_price)
3256
+ * @param bool $tax Add tax with price (true|false)
3257
+ *
3258
+ * @return float|int|mixed|string|void
3259
+ */
3260
+ protected function get_wpc_composite_price( $product, $type, $tax ) {
3261
+ $price = 0;
3262
+ // Parent Component Price
3263
+ $base_price = $this->get_price_by_price_type( $product, $type, $tax );
3264
+ if ( isset( $this->config['composite_price'] ) && 'all_product_price' == $this->config['composite_price'] ) {
3265
+ $components_price = 0;
3266
+ $components = $product->get_components();
3267
+ if ( ! empty( $components ) && is_array( $components ) ) {
3268
+ foreach ( $components as $component ) {
3269
+ $products = explode( ',', $component['products'] );
3270
+ foreach ( $products as $key => $product_id ) {
3271
+ $default_product = wc_get_product( $product_id );
3272
+ if ( is_object( $default_product ) && $default_product->is_in_stock() ) {
3273
+ $quantity = ( isset( $component['qty'] ) && $component['qty'] > 0 ) ? $component['qty'] : 1;
3274
+ if ( 'products' == $component['type'] && empty( $component['price'] ) ) {
3275
+ $components_price += $this->get_price_by_price_type( $default_product, 'price', $tax );
3276
+ $components_price *= $quantity;
3277
+ } elseif ( 'products' == $component['type'] && ! empty( $component['price'] ) ) {
3278
+ $clever = new WPCleverWooco();
3279
+ $old_price = $this->get_price_by_price_type( $default_product, 'price', $tax );
3280
+ $new_price = $component['price'];
3281
+ $components_price += $clever::wooco_new_price( $old_price, $new_price );
3282
+ $components_price *= $quantity;
3283
+ }
3284
+ break; // Get first in stock product from component options.
3285
+ }
3286
+ }
3287
+ }
3288
+
3289
+ // Apply discount to components price.
3290
+ $discount = $product->get_discount();
3291
+ if ( $discount > 0 ) {
3292
+ $components_price -= ( ( $discount / 100 ) * $components_price );
3293
+ }
3294
+ }
3295
+
3296
+ if ( 'exclude' === $product->get_pricing() ) {
3297
+ $price = $components_price;
3298
+ } elseif ( 'include' === $product->get_pricing() ) {
3299
+ $price = $components_price + $base_price;
3300
+ } elseif ( 'only' === $product->get_pricing() ) {
3301
+ $price = $base_price;
3302
+ }
3303
+ } else {
3304
+ $price = $base_price;
3305
+ }
3306
+
3307
+ return $price > 0 ? $price : '';
3308
+ }
3309
+
3310
+ /**
3311
+ * Get total price of grouped product
3312
+ *
3313
+ * @param WC_Product_Grouped $grouped Grouped Product Object
3314
+ * @param string $type Price Type (regular_price|price|sale_price)
3315
+ * @param bool $tax Add tax with price (true|false)
3316
+ *
3317
+ * @return int|string
3318
+ * @since 3.2.0
3319
+ *
3320
+ */
3321
+ protected function getGroupProductPrice( $grouped, $type, $tax = false ) {
3322
+ $groupProductIds = $grouped->get_children();
3323
+ $price = 0;
3324
+ if ( ! empty( $groupProductIds ) ) {
3325
+ foreach ( $groupProductIds as $id ) {
3326
+ $product = wc_get_product( $id );
3327
+ if ( ! is_object( $product ) ) {
3328
+ continue; // make sure that the product exists..
3329
+ }
3330
+
3331
+ $get_price = $this->get_price_by_product_type( $product, $type, $tax );
3332
+ if ( ! empty( $get_price ) ) {
3333
+ $price += $get_price;
3334
+ }
3335
+ }
3336
+ }
3337
+
3338
+ return $price > 0 ? $price : '';
3339
+ }
3340
+
3341
+ /**
3342
+ * Get Variable Product Price
3343
+ *
3344
+ * @param WC_Product_Variable $variable Variable Product Object
3345
+ * @param string $type Price Type (regular_price|price|sale_price)
3346
+ * @param bool $tax Add tax with price (true|false)
3347
+ *
3348
+ * @return int|string
3349
+ * @since 3.2.0
3350
+ *
3351
+ */
3352
+ protected function getVariableProductPrice( $variable, $type, $tax = false ) {
3353
+ $min_max_first_default = apply_filters( 'woo_feed_variable_product_price_range', 'min' );
3354
+ if ( isset( $this->config['variable_price'] ) ) {
3355
+ $min_max_first_default = $this->config['variable_price'];
3356
+ }
3357
+
3358
+ $price = 0;
3359
+ if ( 'first' == $min_max_first_default ) {
3360
+ $children = $variable->get_visible_children();
3361
+ if ( isset( $children[0] ) && ! empty( $children[0] ) ) {
3362
+ $variation = wc_get_product( $children[0] );
3363
+ $price = $this->get_price_by_product_type( $variation, $type, $tax );
3364
+ }
3365
+ } else {
3366
+ if ( 'regular_price' == $type ) {
3367
+ $price = $variable->get_variation_regular_price( $min_max_first_default );
3368
+ } elseif ( 'sale_price' == $type ) {
3369
+ $price = $variable->get_variation_sale_price( $min_max_first_default );
3370
+ } else {
3371
+ $price = $variable->get_variation_price( $min_max_first_default );
3372
+ }
3373
+
3374
+ // Get WooCommerce Multi language Price by Currency.
3375
+ $price = apply_filters( 'woo_feed_wcml_price',
3376
+ $price, $variable->get_id(), $this->get_feed_currency(), '_' . $type
3377
+ );
3378
+
3379
+ // Get Price with tax
3380
+ if ( true === $tax ) {
3381
+ $price = woo_feed_get_price_with_tax( $price, $variable );
3382
+ }
3383
+ }
3384
+
3385
+ return $price > 0 ? $price : '';
3386
+ }
3387
+
3388
+ /**
3389
+ * Get Bundle Product Price
3390
+ *
3391
+ * @param WC_Product $product Product object.
3392
+ * @param string $type Price Type (regular_price|price|sale_price)
3393
+ * @param bool $tax Add tax with price (true|false)
3394
+ *
3395
+ * @return int|float|string
3396
+ * @since 4.3.24
3397
+ */
3398
+ protected function getBundleProductPrice( $product, $type, $tax = false ) {
3399
+ if ( class_exists( 'WC_Product_Bundle' ) ) {//WC_Product_Bundle
3400
+ $bundle = new WC_Product_Bundle( $product );
3401
+ if ( 'price' === $type || 'sale_price' === $type ) {
3402
+ $price = $bundle->get_bundle_price();
3403
+ } else {
3404
+ $price = $bundle->get_bundle_regular_price();
3405
+ }
3406
+
3407
+ // Get WooCommerce Multi language Price by Currency.
3408
+ $price = apply_filters( 'woo_feed_wcml_price',
3409
+ $price, $product->get_id(), $this->get_feed_currency(), '_' . $type
3410
+ );
3411
+
3412
+ // Get Price with tax
3413
+ if ( true === $tax ) {
3414
+ $price = woo_feed_get_price_with_tax( $price, $bundle );
3415
+ }
3416
+ } else {
3417
+ // Get Default price for others bundle products.
3418
+ $price = $this->get_price_by_price_type( $product, $type, $tax );
3419
+ }
3420
+
3421
+ return $price > 0 ? $price : '';
3422
+ }
3423
+
3424
+ /**
3425
+ * Get price for Iconic woocommerce-bundled-products
3426
+ *
3427
+ * @param WC_Product $product Product object
3428
+ * @param string $type Price Type (regular_price|price|sale_price)
3429
+ * @param bool $tax Add tax with price (true|false)
3430
+ *
3431
+ * @return mixed $bundle_price
3432
+ */
3433
+ protected function iconic_bundle_product_price( $product, $type, $tax = false ) {
3434
+ if ( ! class_exists( 'WC_Product_Bundled' ) ) {
3435
+ return $product->get_price();
3436
+ }
3437
+
3438
+ $is_discounted = false;
3439
+ $price = $product->get_price();
3440
+ $bundle = new WC_Product_Bundled( $product->get_id() );
3441
+ $iconic_bundle_product_type = ( ! is_null( $bundle->options['price_display'] ) ) ? $bundle->options['price_display'] : '';
3442
+ $product_ids = $bundle->options['product_ids'];
3443
+
3444
+ //set discount
3445
+ if ( ! empty( $bundle->options['fixed_discount'] ) ) {
3446
+ $is_discounted = true;
3447
+ $discount = $bundle->options['fixed_discount'];
3448
+ } else {
3449
+ $is_discounted = false;
3450
+ $discount = 0;
3451
+ }
3452
+
3453
+ // Get price
3454
+ if ( is_array( $product_ids ) ) {
3455
+ $product_prices = array_map( function ( $id ) use ( $tax, $type, $is_discounted, $discount ) {
3456
+ $product = wc_get_product( $id );
3457
+
3458
+ return $this->get_price_by_price_type( $product, $type, $tax );
3459
+
3460
+ }, $product_ids );
3461
+
3462
+ if ( 'range' === $iconic_bundle_product_type ) {
3463
+ $price = min( $product_prices );
3464
+ } else {
3465
+ $price = array_sum( $product_prices );
3466
+ }
3467
+ }
3468
+
3469
+ // Get sale price if discount enabled
3470
+ if ( $is_discounted && ( 'sale_price' === $type || 'price' === $type ) ) {
3471
+ $price -= $discount;
3472
+ }
3473
+
3474
+ // Get WooCommerce Multi language Price by Currency.
3475
+ $price = apply_filters( 'woo_feed_wcml_price',
3476
+ $price, $product->get_id(), $this->get_feed_currency(), '_' . $type
3477
+ );
3478
+
3479
+ // Get Price with tax
3480
+ if ( true === $tax ) {
3481
+ $price = woo_feed_get_price_with_tax( $price, $bundle );
3482
+ }
3483
+
3484
+ return $price > 0 ? $price : '';
3485
+ }
3486
+
3487
+ /**
3488
+ * Get Product Weight
3489
+ *
3490
+ * @param WC_Product $product
3491
+ *
3492
+ * @return mixed
3493
+ * @since 3.2.0
3494
+ *
3495
+ */
3496
+ protected function weight( $product ) {
3497
+ return apply_filters( 'woo_feed_filter_product_weight', $product->get_weight(), $product, $this->config );
3498
+ }
3499
+
3500
+ /**
3501
+ * Get Product Weight Unit
3502
+ *
3503
+ * @param WC_Product $product
3504
+ *
3505
+ * @return mixed
3506
+ * @since 5.2.7
3507
+ *
3508
+ */
3509
+ protected function weight_unit( $product ) {
3510
+ return apply_filters( 'woo_feed_filter_product_weight_unit', get_option( 'woocommerce_weight_unit' ), $product, $this->config );
3511
+ }
3512
+
3513
+ /**
3514
+ * Get Product Width
3515
+ *
3516
+ * @param WC_Product $product
3517
+ *
3518
+ * @return mixed
3519
+ * @since 3.2.0
3520
+ *
3521
+ */
3522
+ protected function width( $product ) {
3523
+ return apply_filters( 'woo_feed_filter_product_width', $product->get_width(), $product, $this->config );
3524
+ }
3525
+
3526
+ /**
3527
+ * Get Product Height
3528
+ *
3529
+ * @param WC_Product $product
3530
+ *
3531
+ * @return mixed
3532
+ * @since 3.2.0
3533
+ *
3534
+ */
3535
+ protected function height( $product ) {
3536
+ return apply_filters( 'woo_feed_filter_product_height', $product->get_height(), $product, $this->config );
3537
+ }
3538
+
3539
+ /**
3540
+ * Get Product Length
3541
+ *
3542
+ * @param WC_Product $product
3543
+ *
3544
+ * @return mixed
3545
+ * @since 3.2.0
3546
+ *
3547
+ */
3548
+ protected function length( $product ) {
3549
+ return apply_filters( 'woo_feed_filter_product_length', $product->get_length(), $product, $this->config );
3550
+ }
3551
+
3552
+ /**
3553
+ * Get Product Shipping
3554
+ *
3555
+ * @param WC_Product $product
3556
+ *
3557
+ * @return mixed
3558
+ * @since 4.3.16
3559
+ * @author Nazrul Islam Nayan
3560
+ */
3561
+ protected function shipping( $product ) {
3562
+ $feedBody = '';
3563
+ $data = $this->data;
3564
 
3565
+ if ( isset( $data['shipping_zones'] ) && ! empty( $data['shipping_zones'] ) ) {
3566
+ $zones = $data['shipping_zones'];
 
3567
 
3568
+ if ( in_array( $this->config['provider'], [ 'google', 'facebook', 'pinterest', 'bing', 'snapchat' ] ) ) {
3569
+ $get_shipping = new Woo_Feed_Shipping( $this->config );
3570
+ $feedBody .= $get_shipping->set_product( $product )->set_shipping_zone( $zones )->get_google_shipping();
3571
+ }
3572
+ }
3573
 
3574
+ return apply_filters( 'woo_feed_filter_product_shipping', $feedBody, $product, $this->config );
 
3575
 
3576
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3577
 
3578
+ /**
3579
+ * Get Product Shipping Cost
3580
+ *
3581
+ * @param WC_Product $product
3582
+ *
3583
+ * @return mixed
3584
+ * @since 5.1.20
3585
+ * @author Nazrul Islam Nayan
3586
+ */
3587
+ protected function shipping_cost( $product ) {
3588
+ $shipping_obj = new Woo_Feed_Shipping( $this->config );
3589
+ $shipping_obj = $shipping_obj->set_product( $product );
3590
 
3591
+ return apply_filters( 'woo_feed_filter_product_shipping_cost', $shipping_obj->get_lowest_shipping_price(), $product, $this->config );
3592
+ }
 
3593
 
3594
+ /**
3595
+ * Get Product Shipping Class
3596
+ *
3597
+ * @param WC_Product $product
3598
+ *
3599
+ * @return mixed
3600
+ * @since 3.2.0
3601
+ *
3602
+ */
3603
+ protected function shipping_class( $product ) {
3604
+ return apply_filters( 'woo_feed_filter_product_shipping_class', $product->get_shipping_class(), $product, $this->config );
3605
+ }
3606
 
3607
+ /**
3608
+ * Get Product Author Name
3609
+ *
3610
+ * @param WC_Product $product
3611
+ *
3612
+ * @return mixed
3613
+ * @since 3.2.0
3614
+ *
3615
+ */
3616
+ protected function author_name( $product ) {
3617
+ $post = get_post( $product->get_id() );
3618
 
3619
+ return get_the_author_meta( 'user_login', $post->post_author );
3620
+ }
 
 
 
 
 
 
 
 
 
 
3621
 
3622
+ /**
3623
+ * Get Product Author Email
3624
+ *
3625
+ * @param WC_Product $product
3626
+ *
3627
+ * @return mixed
3628
+ * @since 3.2.0
3629
+ *
3630
+ */
3631
+ protected function author_email( $product ) {
3632
+ $post = get_post( $product->get_id() );
3633
 
3634
+ return get_the_author_meta( 'user_email', $post->post_author );
3635
+ }
3636
 
3637
+ /**
3638
+ * Get Product Created Date
3639
+ *
3640
+ * @param WC_Product $product
3641
+ *
3642
+ * @return mixed
3643
+ * @since 3.2.0
3644
+ *
3645
+ */
3646
+ protected function date_created( $product ) {
3647
+ $date_created = gmdate( 'Y-m-d', strtotime( $product->get_date_created() ) );
3648
 
3649
+ return apply_filters( 'woo_feed_filter_product_date_created', $date_created, $product, $this->config );
3650
+ }
3651
 
3652
+ /**
3653
+ * Get Product Last Updated Date
3654
+ *
3655
+ * @param WC_Product $product
3656
+ *
3657
+ * @return mixed
3658
+ * @since 3.2.0
3659
+ *
3660
+ */
3661
+ protected function date_updated( $product ) {
3662
+ $date_updated = gmdate( 'Y-m-d', strtotime( $product->get_date_modified() ) );
3663
 
3664
+ return apply_filters( 'woo_feed_filter_product_date_updated', $date_updated, $product, $this->config );
3665
+ }
3666
 
3667
+ /**
3668
+ * Get Product Tax
3669
+ *
3670
+ * @param WC_Product $product Product object.
3671
+ *
3672
+ * @return mixed
3673
+ * @since 5.1.20
3674
+ * @author Nazrul Islam Nayan
3675
+ */
3676
+ protected function tax( $product ) {
3677
+ $feedBody = '';
3678
+ if ( in_array( $this->config['provider'], [ 'google', 'facebook', 'pinterest', 'bing', 'snapchat' ] ) ) {
3679
+ $shipping_obj = new Woo_Feed_Shipping( $this->config );
3680
+ $shipping_obj = $shipping_obj->set_product( $product );
3681
+ $feedBody .= $shipping_obj->get_google_tax();
3682
+ }
3683
 
3684
+ return apply_filters( 'woo_feed_filter_product_tax', $feedBody, $product, $this->config );
3685
+ }
3686
 
3687
+ /**
3688
+ * Get Product Tax class
3689
+ *
3690
+ * @param WC_Product $product Product object.
3691
+ *
3692
+ * @return string
3693
+ */
3694
+ protected function tax_class( $product ) {
3695
+ return apply_filters( 'woo_feed_filter_product_tax_class', $product->get_tax_class(), $product, $this->config );
3696
+ }
3697
 
3698
+ /**
3699
+ * Get Product Tax Status
3700
+ *
3701
+ * @param WC_Product $product Product object.
3702
+ *
3703
+ * @return string
3704
+ */
3705
+ protected function tax_status( $product ) {
3706
+ return apply_filters( 'woo_feed_filter_product_tax_status', $product->get_tax_status(), $product, $this->config );
3707
+ }
3708
 
3709
+ /**
3710
+ * Get CTX Feed Custom Field value
3711
+ *
3712
+ * @param WC_Product $product Product object.
3713
+ * @param string $field custom field name.
3714
+ *
3715
+ * @return string
3716
+ */
3717
+ protected function getCustomField( $product, $field ) {
3718
+ $id = $product->get_id();
3719
+ $meta = $field;
3720
+ if ( $product->is_type( 'variation' ) ) {
3721
+ $meta = $field . '_var';
3722
+ }
3723
 
3724
+ $meta = apply_filters( 'woo_feed_custom_field_meta', $meta, $product, $field );
 
3725
 
3726
+ $new_meta_key = '';
3727
+ $old_meta_key = '';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3728
 
3729
+ if ( strpos( $meta, '_identifier' ) !== false ) {
3730
+ $old_meta_key = $meta;
3731
+ $new_meta_key = str_replace( '_identifier', '', $meta );
3732
+ } else {
3733
+ $new_meta_key = $meta;
3734
+ $old_meta_key = str_replace( 'woo_feed_', 'woo_feed_identifier_', $meta );
3735
+ }
3736
 
3737
+ $new_meta_value = $this->getProductMeta( $product, $new_meta_key );
3738
+ $old_meta_value = $this->getProductMeta( $product, $old_meta_key );
3739
 
3740
+ if ( empty( $new_meta_value ) ) {
3741
+ return $old_meta_value;
3742
+ }
3743
 
3744
+ return $new_meta_value;
 
 
 
 
 
3745
 
3746
+ }
3747
 
3748
+ /**
3749
+ * Get Product Sale Price Effected Date for Google Shopping
3750
+ *
3751
+ * @param WC_Product $product
3752
+ *
3753
+ * @return string
3754
+ * @since 3.2.0
3755
+ *
3756
+ */
3757
+ protected function sale_price_effective_date( $product ) {
3758
+ $effective_date = '';
3759
+ $from = $this->sale_price_sdate( $product );
3760
+ $to = $this->sale_price_edate( $product );
3761
+ if ( ! empty( $from ) && ! empty( $to ) ) {
3762
+ $from = gmdate( 'c', strtotime( $from ) );
3763
+ $to = gmdate( 'c', strtotime( $to ) );
3764
+
3765
+ $effective_date = $from . '/' . $to;
3766
+ }
3767
 
3768
+ return $effective_date;
3769
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3770
 
3771
+ /**
3772
+ * Ger Product Attribute
3773
+ *
3774
+ * @param WC_Product $product
3775
+ * @param $attr
3776
+ *
3777
+ * @return string
3778
+ * @since 2.2.3
3779
+ *
3780
+ */
3781
+ protected function getProductAttribute( $product, $attr ) {
3782
+ $id = $product->get_id();
3783
+
3784
+ if ( woo_feed_wc_version_check( 3.2 ) ) {
3785
+ if ( woo_feed_wc_version_check( 3.6 ) ) {
3786
+ $attr = str_replace( 'pa_', '', $attr );
3787
+ }
3788
+ $value = $product->get_attribute( $attr );
3789
+
3790
+ // if empty get attribute of parent post
3791
+ if ( '' === $value && $product->is_type( 'variation' ) ) {
3792
+ $product = wc_get_product( $product->get_parent_id() );
3793
+ $value = $product->get_attribute( $attr );
3794
+ }
3795
+
3796
+ $getproductattribute = $value;
3797
+ } else {
3798
+ $getproductattribute = implode( ',', wc_get_product_terms( $id, $attr, array( 'fields' => 'names' ) ) );
3799
+ }
3800
 
3801
+ return apply_filters( 'woo_feed_filter_product_attribute', $getproductattribute, $product, $attr, $this->config );
3802
+ }
3803
 
3804
+ /**
3805
+ * Get Meta
3806
+ *
3807
+ * @param WC_Product $product
3808
+ * @param string $meta post meta key
3809
+ *
3810
+ * @return mixed|string
3811
+ * @since 2.2.3
3812
+ *
3813
+ */
3814
+ protected function getProductMeta( $product, $meta ) {
3815
+ $value = get_post_meta( $product->get_id(), $meta, true );
3816
+ // if empty get meta value of parent post
3817
+ if ( '' === $value && $product->is_type( 'variation' ) ) {
3818
+ $value = get_post_meta( $product->get_parent_id(), $meta, true );
3819
+ }
3820
 
3821
+ return apply_filters( 'woo_feed_filter_product_meta', $value, $product, $this->config );
3822
+ }
3823
 
3824
+ /**
3825
+ * Filter Products by Conditions
3826
+ *
3827
+ * @param WC_Product $product
3828
+ *
3829
+ * @return bool|array
3830
+ * @since 3.2.0
3831
+ *
3832
+ */
3833
+ public function filter_product( $product ) {
3834
+ return true;
3835
+ }
3836
 
3837
+ /**
3838
+ * Get Taxonomy
3839
+ *
3840
+ * @param WC_Product $product
3841
+ * @param $taxonomy
3842
+ *
3843
+ * @return string
3844
+ * @since 2.2.3
3845
+ *
3846
+ */
3847
+ protected function getProductTaxonomy( $product, $taxonomy ) {
3848
+ $id = $product->get_id();
3849
+ if ( $product->is_type( 'variation' ) ) {
3850
+ $id = $product->get_parent_id();
3851
+ }
3852
 
3853
+ $separator = apply_filters( 'woo_feed_product_taxonomy_term_list_separator', ',', $this->config, $product );
3854
 
3855
+ $term_list = get_the_term_list( $id, $taxonomy, '', $separator, '' );
3856
 
3857
+ if ( is_object( $term_list ) && get_class( $term_list ) === 'WP_Error' ) {
3858
+ $term_list = '';
3859
+ }
 
 
 
 
3860
 
3861
+ $getproducttaxonomy = woo_feed_strip_all_tags( $term_list );
3862
 
3863
+ return apply_filters( 'woo_feed_filter_product_taxonomy', $getproducttaxonomy, $product, $this->config );
3864
+ }
3865
 
3866
+ /**
3867
+ * Format price value
3868
+ *
3869
+ * @param string $name Attribute Name
3870
+ * @param int $conditionName condition
3871
+ * @param int $result price
3872
+ *
3873
+ * @return mixed
3874
+ * @since 3.2.0
3875
+ *
3876
+ */
3877
+ protected function price_format( $name, $conditionName, $result ) {
3878
+ $plus = '+';
3879
+ $minus = '-';
3880
+ $percent = '%';
3881
+
3882
+ if ( strpos( $name, 'price' ) !== false ) {
3883
+ if ( strpos( $result, $plus ) !== false && strpos( $result, $percent ) !== false ) {
3884
+ $result = str_replace( '+', '', $result );
3885
+ $result = str_replace( '%', '', $result );
3886
+ if ( is_numeric( $result ) ) {
3887
+ $result = $conditionName + ( ( $conditionName * $result ) / 100 );
3888
+ }
3889
+ } elseif ( strpos( $result, $minus ) !== false && strpos( $result, $percent ) !== false ) {
3890
+ $result = str_replace( '-', '', $result );
3891
+ $result = str_replace( '%', '', $result );
3892
+ if ( is_numeric( $result ) ) {
3893
+ $result = $conditionName - ( ( $conditionName * $result ) / 100 );
3894
+ }
3895
+ } elseif ( strpos( $result, $plus ) !== false ) {
3896
+ $result = str_replace( '+', '', $result );
3897
+ if ( is_numeric( $result ) ) {
3898
+ $result = ( $conditionName + $result );
3899
+ }
3900
+ } elseif ( strpos( $result, $minus ) !== false ) {
3901
+ $result = str_replace( '-', '', $result );
3902
+ if ( is_numeric( $result ) ) {
3903
+ $result = $conditionName - $result;
3904
+ }
3905
+ }
3906
+ }
3907
 
3908
+ return $result;
3909
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3910
 
3911
+ /**
3912
+ * Format output According to Output Type config
3913
+ *
3914
+ * @param string $output
3915
+ * @param array $outputTypes
3916
+ * @param WC_Product $product
3917
+ * @param string $productAttribute
3918
+ *
3919
+ * @return float|int|string
3920
+ * @since 3.2.0
3921
+ *
3922
+ */
3923
+ protected function format_output( $output, $outputTypes, $product, $productAttribute, $merchant_attribute ) {
3924
+ if ( ! empty( $outputTypes ) && is_array( $outputTypes ) ) {
3925
+
3926
+ // Format Output According to output type
3927
+ if ( in_array( 2, $outputTypes ) ) { // Strip Tags
3928
+ $output = woo_feed_strip_all_tags( html_entity_decode( $output ) );
3929
+ }
3930
+
3931
+ if ( in_array( 3, $outputTypes ) ) { // UTF-8 Encode
3932
+ $output = utf8_encode( $output );
3933
+ }
3934
+
3935
+ if ( in_array( 4, $outputTypes ) ) { // htmlentities
3936
+ $output = htmlentities( $output, ENT_QUOTES, 'UTF-8' );
3937
+ }
3938
+
3939
+ if ( in_array( 5, $outputTypes ) ) { // Integer
3940
+ $output = intval( $output );
3941
+ }
3942
+
3943
+ if ( in_array( 6, $outputTypes ) ) { // Format Price
3944
+ if ( ! empty( $output ) && $output > 0 ) {
3945
+ $decimals = wc_get_price_decimals();
3946
+ $decimal_separator = wc_get_price_decimal_separator();
3947
+ $thousand_separator = wc_get_price_thousand_separator();
3948
+ $output = (float) $output;
3949
+
3950
+ if ( "idealo" === $this->config['provider'] ) {
3951
+ $output = number_format( $output, $decimals, wp_specialchars_decode( stripslashes( $decimal_separator ) ), wp_specialchars_decode( stripslashes( $thousand_separator ) ) );
3952
+ } else {
3953
+ $output = number_format( $output, 2, '.', '' );
3954
+ }
3955
+
3956
+ }
3957
+ }
3958
+
3959
+ if ( in_array( 7, $outputTypes ) ) { // Rounded Price
3960
+ if ( ! empty( $output ) && $output > 0 ) {
3961
+ $output = round( $output );
3962
+ $output = number_format( $output, 2, '.', '' );
3963
+ }
3964
+ }
3965
+
3966
+ if ( in_array( 8, $outputTypes ) ) { // Delete Space
3967
+ $output = htmlentities( $output, null, 'utf-8' );
3968
+ $output = str_replace( "&nbsp;", " ", $output );
3969
+ $output = html_entity_decode( $output );
3970
+ $output = preg_replace( "/\\s+/", ' ', $output );
3971
+ }
3972
+
3973
+ if ( in_array( 10, $outputTypes ) ) { // Remove Invalid Character
3974
+ $output = woo_feed_stripInvalidXml( $output );
3975
+ }
3976
+
3977
+ if ( in_array( 11, $outputTypes ) ) { // Remove ShortCodes
3978
+ $output = $this->remove_short_codes( $output );
3979
+ }
3980
+
3981
+ if ( in_array( 12, $outputTypes ) ) {
3982
+ //$output = ucwords(mb_strtolower($output));
3983
+ $output = mb_convert_case( $output, MB_CASE_TITLE );
3984
+ }
3985
+
3986
+ if ( in_array( 13, $outputTypes ) ) {
3987
+ //$output = ucfirst(strtolower($output));
3988
+ $output = mb_strtoupper( mb_substr( $output, 0, 1 ) ) . mb_substr( $output, 1 );
3989
+ }
3990
+
3991
+ if ( in_array( 14, $outputTypes ) ) {
3992
+ $output = mb_strtoupper( mb_strtolower( $output ) );
3993
+ }
3994
+
3995
+ if ( in_array( 15, $outputTypes ) ) {
3996
+ $output = mb_strtolower( $output );
3997
+ }
3998
+
3999
+ if ( in_array( 16, $outputTypes ) ) {
4000
+ if ( 'http' == substr( $output, 0, 4 ) ) {
4001
+ $output = str_replace( 'http://', 'https://', $output );
4002
+ }
4003
+ }
4004
+
4005
+ if ( in_array( 17, $outputTypes ) ) {
4006
+ if ( 'http' == substr( $output, 0, 4 ) ) {
4007
+ $output = str_replace( 'https://', 'http://', $output );
4008
+ }
4009
+ }
4010
+
4011
+ if ( in_array( 18, $outputTypes ) ) { // only parent
4012
+ if ( $product->is_type( 'variation' ) ) {
4013
+ $id = $product->get_parent_id();
4014
+ $parentProduct = wc_get_product( $id );
4015
+ $output = $this->getAttributeValueByType( $parentProduct, $productAttribute, $merchant_attribute );
4016
+ }
4017
+ }
4018
+
4019
+ if ( in_array( 19, $outputTypes ) ) { // child if parent empty
4020
+ if ( $product->is_type( 'variation' ) ) {
4021
+ $id = $product->get_parent_id();
4022
+ $parentProduct = wc_get_product( $id );
4023
+ $output = $this->getAttributeValueByType( $parentProduct, $productAttribute, $merchant_attribute );
4024
+ if ( empty( $output ) ) {
4025
+ $output = $this->getAttributeValueByType( $product, $productAttribute, $merchant_attribute );
4026
+ }
4027
+ }
4028
+ }
4029
+
4030
+ if ( in_array( 20, $outputTypes ) ) { // parent if child empty
4031
+ if ( $product->is_type( 'variation' ) ) {
4032
+ $output = $this->getAttributeValueByType( $product, $productAttribute, $merchant_attribute );
4033
+ if ( empty( $output ) ) {
4034
+ $id = $product->get_parent_id();
4035
+ $parentProduct = wc_get_product( $id );
4036
+ $output = $this->getAttributeValueByType( $parentProduct, $productAttribute, $merchant_attribute );
4037
+ }
4038
+ }
4039
+ }
4040
+
4041
+ if ( in_array( 9, $outputTypes ) && ! empty( $output ) && 'xml' === $this->config['feedType'] ) { // Add CDATA
4042
+ $output = '<![CDATA[' . $output . ']]>';
4043
+ }
4044
+ }
4045
 
4046
+ return $output;
4047
+ }
 
4048
 
4049
+ /**
4050
+ * Add Prefix and Suffix with attribute value
4051
+ *
4052
+ * @param $output
4053
+ * @param $prefix
4054
+ * @param $suffix
4055
+ * @param $attribute
4056
+ *
4057
+ * @return string
4058
+ * @since 3.2.0
4059
+ *
4060
+ */
4061
+ public function process_prefix_suffix( $output, $prefix, $suffix, $attribute = '' ) {
4062
+ $cdata = false;
4063
+ if ( '' === $output ) {
4064
+ return $output;
4065
+ }
4066
 
4067
+ if ( strpos( $output, '<![CDATA[' ) !== false ) {
4068
+ $cdata = true;
4069
+ $output = str_replace( array( '<![CDATA[', ']]>' ), array( '', '' ), $output );
4070
+ }
4071
 
4072
+ // Add Prefix before Output
4073
+ if ( '' !== $prefix ) {
4074
+ $output = "$prefix" . $output;
4075
+ }
4076
 
4077
+ // Add Suffix after Output
4078
+ if ( '' !== $suffix ) {
4079
+ if ( array_key_exists( trim( $suffix ), get_woocommerce_currencies() ) ) { // Add space before suffix if attribute contain price.
4080
+ $output .= ' ' . $suffix;
4081
+ } elseif ( substr( $output, 0, 4 ) === 'http' ) {
4082
+ // Parse URL Parameters if available into suffix field
4083
+ $output = woo_feed_make_url_with_parameter( $output, $suffix );
4084
+ } else {
4085
+ $output .= (string) $suffix;
4086
+ }
4087
+ }
4088
 
4089
+ if ( $cdata ) {
4090
+ $output = '<![CDATA[' . $output . ']]>';
4091
+ }
 
 
 
 
 
 
4092
 
4093
+ return "$output";
4094
+ }
4095
 
4096
+ /**
4097
+ * Get Subscription period
4098
+ *
4099
+ * @param WC_Product $product
4100
+ *
4101
+ * @return mixed
4102
+ * @since 3.6.3
4103
+ *
4104
+ */
4105
+ protected function subscription_period( $product ) {
4106
+ if ( class_exists( 'WC_Subscriptions' ) ) {
4107
+ return $this->getProductMeta( $product, '_subscription_period' );
4108
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4109
 
4110
+ return '';
4111
+ }
4112
 
4113
+ /**
4114
+ * Get Subscription period interval
4115
+ *
4116
+ * @param WC_Product $product
4117
+ *
4118
+ * @return mixed
4119
+ * @since 3.6.3
4120
+ *
4121
+ */
4122
+ protected function subscription_period_interval( $product ) {
4123
+ if ( class_exists( 'WC_Subscriptions' ) ) {
4124
+ return $this->getProductMeta( $product, '_subscription_period_interval' );
4125
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4126
 
4127
+ return '';
4128
+ }
4129
 
4130
+ /**
4131
+ * Get Subscription period interval
4132
+ *
4133
+ * @param WC_Product $product
4134
+ *
4135
+ * @return mixed
4136
+ * @since 3.6.3
4137
+ *
4138
+ */
4139
+ protected function subscription_amount( $product ) {
4140
+ return $this->price( $product );
4141
+ }
4142
 
4143
+ /**
4144
+ * Get Installment Amount
4145
+ *
4146
+ * @param WC_Product $product
4147
+ *
4148
+ * @return mixed
4149
+ * @since 4.3.101
4150
+ */
4151
+ protected function installment_amount( $product ) {
4152
+ return $this->price( $product );
4153
+ }
4154
 
4155
+ /**
4156
+ * Get Installment Months
4157
+ *
4158
+ * @param WC_Product $product
4159
+ *
4160
+ * @return mixed
4161
+ * @since 4.3.101
4162
+ */
4163
+ protected function installment_months( $product ) {
4164
+ if ( class_exists( 'WC_Subscriptions' ) ) {
4165
+ return $this->getProductMeta( $product, '_subscription_length' );
4166
+ }
4167
 
4168
+ return '';
4169
+ }
4170
 
 
 
 
 
 
 
 
 
 
 
 
4171
 
4172
+ /**
4173
+ * Calculate unit_price_measure. If Unit custom fields by CTX feed are enabled then it will take value
4174
+ * from custom fields or it will take values for WooCommerce Germanized Plugin if enabled.
4175
+ *
4176
+ * If variation values are empty then it will take value from variable product.
4177
+ *
4178
+ * @param WC_Product $product
4179
+ *
4180
+ * @return mixed
4181
+ * @since 3.6.3
4182
+ */
4183
+ protected function unit_price_measure( $product ) {
4184
+ $unit_price_measure = '';
4185
+ $identifiers = woo_feed_get_options( 'woo_feed_identifier' );
4186
+ if ( 'enable' === $identifiers['unit_pricing_base_measure']
4187
+ && 'enable' === $identifiers['unit_pricing_measure']
4188
+ && 'enable' === $identifiers['unit']
4189
+ ) {
4190
+ $unit = $this->getCustomField( $product, 'woo_feed_unit' );
4191
+ $unit_price_measure = $this->getCustomField( $product, 'woo_feed_unit_pricing_measure' );
4192
+
4193
+ $unit_price_measure .= " " . $unit;
4194
+ }
4195
 
4196
+ if ( empty( $unit_price_measure ) && class_exists( 'WooCommerce_Germanized' ) ) { // For WooCommerce Germanized Plugin
4197
+ $unit = $this->getProductMeta( $product, '_unit' );
4198
+ $unit_price_measure = $this->getProductMeta( $product, '_unit_product' );
4199
 
4200
+ $unit_price_measure .= " " . $unit;
4201
+ }
 
 
 
 
 
 
 
 
 
4202
 
4203
+ return apply_filters( 'woo_feed_filter_unit_price_measure', $unit_price_measure, $product, $this->config );
4204
+ }
4205
 
4206
+ /**
4207
+ * Calculate unit_price_base_measure. If Unit custom fields by CTX feed are enabled then it will take value
4208
+ * from custom fields or it will take values for WooCommerce Germanized Plugin if enabled.
4209
+ *
4210
+ * If variation values are empty then it will take value from variable product.
4211
+ *
4212
+ * @param WC_Product $product
4213
+ *
4214
+ * @return mixed
4215
+ * @since 3.6.3
4216
+ */
4217
+ protected function unit_price_base_measure( $product ) {
4218
+ $unit_price_base_measure = '';
4219
+ $identifiers = woo_feed_get_options( 'woo_feed_identifier' );
4220
+ if ( 'enable' === $identifiers['unit_pricing_base_measure']
4221
+ && 'enable' === $identifiers['unit_pricing_measure']
4222
+ && 'enable' === $identifiers['unit']
4223
+ ) {
4224
+ $unit = $this->getCustomField( $product, 'woo_feed_unit' );
4225
+ $unit_price_base_measure = $this->getCustomField( $product, 'woo_feed_unit_pricing_base_measure' );
4226
+
4227
+ $unit_price_base_measure .= " " . $unit;
4228
+ }
4229
 
4230
+ if ( empty( $unit_price_base_measure ) && class_exists( 'WooCommerce_Germanized' ) ) { // For WooCommerce Germanized Plugin
4231
+ $unit = $this->getProductMeta( $product, '_unit' );
4232
+ $unit_price_base_measure = $this->getProductMeta( $product, '_unit_base' );
 
 
 
 
 
 
 
 
4233
 
4234
+ $unit_price_base_measure .= " " . $unit;
4235
+ }
4236
 
4237
+ return apply_filters( 'woo_feed_filter_unit_price_base_measure', $unit_price_base_measure, $product, $this->config );
4238
+ }
4239
 
4240
+ /**
4241
+ * Get GTIN value of WooCommerce Germanized Plugin
4242
+ *
4243
+ * @param WC_Product $product
4244
+ *
4245
+ * @return mixed
4246
+ * @since 3.6.3
4247
+ */
4248
+ protected function wc_germanized_gtin( $product ) {
4249
+ $wc_germanized_gtin = '';
4250
+ if ( class_exists( 'WooCommerce_Germanized' ) ) { // For WooCommerce Germanized Plugin
4251
+ $wc_germanized_gtin = $this->getProductMeta( $product, '_ts_gtin' );
4252
+ }
4253
 
4254
+ return apply_filters( 'woo_feed_filter_wc_germanized_gtin', $wc_germanized_gtin, $product, $this->config );
4255
+ }
4256
 
4257
+ /**
4258
+ * Get MPN value of WooCommerce Germanized Plugin
4259
+ *
4260
+ * @param WC_Product $product
4261
+ *
4262
+ * @return mixed
4263
+ * @since 3.6.3
4264
+ */
4265
+ protected function wc_germanized_mpn( $product ) {
4266
+ $wc_germanized_mpn = '';
4267
+ if ( class_exists( 'WooCommerce_Germanized' ) ) { // For WooCommerce Germanized Plugin
4268
+ $wc_germanized_mpn = $this->getProductMeta( $product, '_ts_mpn' );
4269
+ }
4270
 
4271
+ return apply_filters( 'woo_feed_filter_wc_germanized_mpn', $wc_germanized_mpn, $product, $this->config );
4272
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4273
 
 
 
4274
 
4275
+ /**
4276
+ * Yoast Identifier attribute for gtin8
4277
+ *
4278
+ * @param WC_Product $product
4279
+ *
4280
+ * @return mixed
4281
+ * @since 4.4.4
4282
+ */
4283
+ protected function yoast_gtin8( $product ) {
4284
+ $yoast_gtin8_value = woo_feed_get_yoast_identifiers_value( 'gtin8', $product );
 
 
4285
 
4286
+ return apply_filters( 'yoast_gtin8_attribute_value', $yoast_gtin8_value, $product );
4287
+ }
4288
 
4289
+ /**
4290
+ * Yoast Identifier attribute for gtin12
4291
+ *
4292
+ * @param WC_Product $product
4293
+ *
4294
+ * @return mixed
4295
+ * @since 4.4.4
4296
+ */
4297
+ protected function yoast_gtin12( $product ) {
4298
+ $yoast_gtin12_value = woo_feed_get_yoast_identifiers_value( 'gtin12', $product );
 
 
4299
 
4300
+ return apply_filters( 'yoast_gtin12_attribute_value', $yoast_gtin12_value, $product );
4301
+ }
4302
 
4303
+ /**
4304
+ * Yoast Identifier attribute for gtin13
4305
+ *
4306
+ * @param WC_Product $product
4307
+ *
4308
+ * @return mixed
4309
+ * @since 4.4.4
4310
+ */
4311
+ protected function yoast_gtin13( $product ) {
4312
+ $yoast_gtin13_value = woo_feed_get_yoast_identifiers_value( 'gtin13', $product );
 
 
4313
 
4314
+ return apply_filters( 'yoast_gtin13_attribute_value', $yoast_gtin13_value, $product );
4315
+ }
4316
 
4317
+ /**
4318
+ * Yoast Identifier attribute for gtin12
4319
+ *
4320
+ * @param WC_Product $product
4321
+ *
4322
+ * @return mixed
4323
+ * @since 4.4.4
4324
+ */
4325
+ protected function yoast_gtin14( $product ) {
4326
+ $yoast_gtin14_value = woo_feed_get_yoast_identifiers_value( 'gtin14', $product );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4327
 
4328
+ return apply_filters( 'yoast_gtin14_attribute_value', $yoast_gtin14_value, $product );
4329
+ }
4330
 
4331
+ /**
4332
+ * Yoast Identifier attribute for isbn
4333
+ *
4334
+ * @param WC_Product $product
4335
+ *
4336
+ * @return mixed
4337
+ * @since 4.4.4
4338
+ */
4339
+ protected function yoast_isbn( $product ) {
4340
+ $yoast_isbn_value = woo_feed_get_yoast_identifiers_value( 'isbn', $product );
4341
 
4342
+ return apply_filters( 'yoast_isbn_attribute_value', $yoast_isbn_value, $product );
4343
+ }
 
4344
 
4345
+ /**
4346
+ * Yoast Identifier attribute for mpn
4347
+ *
4348
+ * @param WC_Product $product
4349
+ *
4350
+ * @return mixed
4351
+ * @since 4.4.4
4352
+ */
4353
+ protected function yoast_mpn( $product ) {
4354
+ $yoast_mpn_value = woo_feed_get_yoast_identifiers_value( 'mpn', $product );
4355
 
4356
+ return apply_filters( 'yoast_mpn_attribute_value', $yoast_mpn_value, $product );
4357
+ }
4358
 
4359
+ /**
4360
+ * Rank Math GTIN Identifier attribute
4361
+ *
4362
+ * @param WC_Product $product
4363
+ *
4364
+ * @return mixed
4365
+ * @since 5.2.66
4366
+ */
4367
+ protected function rank_math_gtin( $product ) {
4368
+ $product_id = woo_feed_parent_product_id( $product );
4369
+ $rankmath_gtin_value = get_post_meta( $product_id, '_rank_math_gtin_code' );
4370
+ $rankmath_gtin_value = ! empty( $rankmath_gtin_value ) && is_array( $rankmath_gtin_value ) ? $rankmath_gtin_value[0] : '';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4371
 
4372
+ return apply_filters( 'rankmath_gtin_attribute_value', $rankmath_gtin_value, $product );
4373
+ }
4374
 
4375
  /**
4376
  * Get ACF Field values
4388
 
4389
  return '';
4390
  }
 
4391
  }
includes/classes/class-woo-feed-shipping.php CHANGED
@@ -38,7 +38,7 @@ class Woo_Feed_Shipping {
38
  public $obj_v3;
39
 
40
  public function __construct( $feed_config ) {
41
-
42
  $this->config = $feed_config;
43
  //$this->class_cost_id = $this->set_shipping_class_id();
44
  $this->feed_country = $this->set_country();
@@ -157,9 +157,9 @@ class Woo_Feed_Shipping {
157
  }
158
  }
159
 
160
- //when allow_all_shipping is disabled and feed country doesn't match shipping country then skip the shipping method
161
  if ( isset( $this->settings ) && is_array( $this->settings ) && array_key_exists( 'allow_all_shipping', $this->settings ) ) {
162
- $all_country_shipping = $this->settings['allow_all_shipping'];
163
  if ( 'no' === $all_country_shipping && $shipping['country'] !== $this->feed_country ) {
164
  unset($shipping);
165
  continue 2;
@@ -178,23 +178,12 @@ class Woo_Feed_Shipping {
178
  if ( 'yes' === $method->enabled ) {
179
  if ( empty( $shipping['country'] ) ) {
180
  $shipping['service'] = $zone['zone_name'] . " " . $method->title;
 
181
  } else {
182
  $shipping['service'] = $zone['zone_name'] . " " . $method->title . " " . $shipping['country'];
 
183
  }
184
 
185
- //when only_free_shipping is enabled and shipping is not free shipping then skip the shipping method
186
- // if( isset($this->settings) && is_array($this->settings) ) {
187
- // if( array_key_exists('only_free_shipping', $this->settings) ) {
188
- // $only_free_shipping = $this->settings['only_free_shipping'];
189
- // if( empty($only_free_shipping) || 'yes' === $only_free_shipping ) {
190
- // if ( "free_shipping" !== $method->id ) {
191
- // unset( $shipping );
192
- // continue;
193
- // }
194
- // }
195
- // }
196
- // }
197
-
198
  if ( "free_shipping" === $method->id ) {
199
  $minimum_fee = $method->min_amount;
200
 
@@ -204,23 +193,8 @@ class Woo_Feed_Shipping {
204
  // Only Free Shipping when product price is over or equal to minimum order fee
205
  if ( $this->product->get_price() >= $minimum_fee ) {
206
  // $shipping['free'] = "yes";
207
- $shipping['price'] = apply_filters('woo_feed_filter_shipping_attribute_price', 0, $method, $this->config);;
208
  }
209
-
210
- // else {
211
- // // There are no free shipping requirements
212
- // if ($method->requires === "") {
213
- // $shipping['free'] = "yes";
214
- // } else {
215
- // // No Free Shipping Allowed for this product
216
- // //unset($zone_details);
217
- // unset($shipping['service']);
218
- // unset($shipping['price']);
219
- // unset($shipping);
220
- // }
221
- // }
222
-
223
-
224
  }else {
225
  $shipping_method['id'] = $method->id;
226
  $shipping_method['instance_id'] = $method->instance_id;
@@ -625,7 +599,7 @@ class Woo_Feed_Shipping {
625
 
626
  if ( ! empty($all_tax_rates) ) {
627
  foreach ( $all_tax_rates as $rate_key => $rate ) {
628
- $all_country_shipping = $this->settings['allow_all_shipping'];
629
  if ( 'no' === $all_country_shipping && $rate->tax_rate_country !== $this->feed_country ) {
630
  continue;
631
  }
38
  public $obj_v3;
39
 
40
  public function __construct( $feed_config ) {
41
+
42
  $this->config = $feed_config;
43
  //$this->class_cost_id = $this->set_shipping_class_id();
44
  $this->feed_country = $this->set_country();
157
  }
158
  }
159
 
160
+ // When allow_all_shipping is disabled and feed country doesn't match shipping country then skip the shipping method
161
  if ( isset( $this->settings ) && is_array( $this->settings ) && array_key_exists( 'allow_all_shipping', $this->settings ) ) {
162
+ $all_country_shipping = apply_filters( 'woo_feed_allowed_shipping_countries', $this->settings['allow_all_shipping'],$this->config);
163
  if ( 'no' === $all_country_shipping && $shipping['country'] !== $this->feed_country ) {
164
  unset($shipping);
165
  continue 2;
178
  if ( 'yes' === $method->enabled ) {
179
  if ( empty( $shipping['country'] ) ) {
180
  $shipping['service'] = $zone['zone_name'] . " " . $method->title;
181
+ $shipping['zone_name'] = $zone['zone_name'];
182
  } else {
183
  $shipping['service'] = $zone['zone_name'] . " " . $method->title . " " . $shipping['country'];
184
+ $shipping['zone_name'] = $zone['zone_name'];
185
  }
186
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
  if ( "free_shipping" === $method->id ) {
188
  $minimum_fee = $method->min_amount;
189
 
193
  // Only Free Shipping when product price is over or equal to minimum order fee
194
  if ( $this->product->get_price() >= $minimum_fee ) {
195
  // $shipping['free'] = "yes";
196
+ $shipping['price'] = apply_filters('woo_feed_filter_shipping_attribute_price', 0, $method, $this->config);
197
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
198
  }else {
199
  $shipping_method['id'] = $method->id;
200
  $shipping_method['instance_id'] = $method->instance_id;
599
 
600
  if ( ! empty($all_tax_rates) ) {
601
  foreach ( $all_tax_rates as $rate_key => $rate ) {
602
+ $all_country_shipping = apply_filters( 'woo_feed_allowed_tax_countries', $this->settings['allow_all_shipping'],$this->config);
603
  if ( 'no' === $all_country_shipping && $rate->tax_rate_country !== $this->feed_country ) {
604
  continue;
605
  }
includes/feeds/class-woo-feed-review.php CHANGED
@@ -11,273 +11,287 @@
11
  */
12
  class Woo_Feed_Review {
13
 
14
- /**
15
- * This variable is responsible for holding all product attributes and their values
16
- *
17
- * @since 1.0.0
18
- * @var array $products Contains all the product attributes to generate feed
19
- * @access public
20
- */
21
- public $products;
22
-
23
- /**
24
- * This variable is responsible for making error number
25
- *
26
- * @since 1.0.0
27
- * @var int $errorCounter Generate error number
28
- * @access public
29
- */
30
- public $errorCounter;
31
-
32
- /**
33
- * Feed Wrapper text for enclosing each product information
34
- *
35
- * @since 1.0.0
36
- * @var string $feedWrapper Feed Wrapper text
37
- * @access public
38
- */
39
- public $feedWrapper = 'review';
40
-
41
- /**
42
- * Store product information
43
- *
44
- * @since 1.0.0
45
- * @var array $storeProducts
46
- * @access public
47
- */
48
- private $storeProducts;
49
-
50
- /**
51
- * Product Ids
52
- *
53
- * @since 1.0.0
54
- * @var array $ids
55
- * @access public
56
- */
57
- private $ids;
58
-
59
- /**
60
- * Review Data
61
- *
62
- * @since 1.0.0
63
- * @var array $data
64
- * @access public
65
- */
66
- private $data;
67
-
68
- /**
69
- * Define the core functionality to generate feed.
70
- *
71
- * Set the feed rules. Map products according to the rules and Check required attributes
72
- * and their values according to merchant specification.
73
- * @var Woo_Generate_Feed $feedRule Contain Feed Configuration
74
- * @since 1.0.0
75
- */
76
- public function __construct( $feedRule ) {
77
-
78
- $feedRule['itemWrapper'] = $this->feedWrapper;
79
-
80
- $this->products = new Woo_Feed_Products_v3( $feedRule );
81
-
82
- // When update via cron job then set productIds.
83
- if ( ! isset( $feedRule['productIds'] ) ) {
84
- $feedRule['productIds'] = $this->products->query_products();
85
- }
86
-
87
- $products = $this->products->get_products( $feedRule['productIds'] );
88
-
89
- $this->ids = $feedRule['productIds'];
90
-
91
- $this->rules = $feedRule;
92
-
93
- $this->data = $this->processReviewsData($feedRule);
94
- }
95
-
96
- /**
97
- * Process Reviews Data
98
- *
99
- * @param mixed $config feed configuration
100
- *
101
- */
102
- private function processReviewsData($config ) {
103
- $ids = $this->ids;
104
- $feed = array();
105
- $feed['version'] = '2.3';
106
- $feed['aggregator']['name'] = 'review';
107
- $feed['publisher']['name'] = 'CTX Feed – WooCommerce Product Feed Generator by Webappick';
108
- $feed['reviews'] = array();
109
-
110
- foreach ( $ids as $id ) {
111
- $product = wc_get_product($id);
112
-
113
- $reviews = get_comments(
114
- array(
115
- 'post_id' => $id,
116
- 'status' => 'approve',
117
- 'post_status' => 'publish',
118
- 'post_type' => 'product'
119
- )
120
- );
121
-
122
- $review = array();
123
- $i=0;
124
- if ( $reviews && is_array($reviews) ) {
125
- foreach ( $reviews as $single_review ) {
126
- $review_time = ! empty($single_review->comment_date_gmt)?gmdate('c', strtotime($single_review->comment_date_gmt)):"";
127
- $review_content = $single_review->comment_content;
128
- $rating = get_comment_meta( $single_review->comment_ID, 'rating', true);
129
-
130
- //Review Content
131
- //strip tags and spacial characters
132
- $strip_review_content = woo_feed_strip_all_tags(wp_specialchars_decode($review_content));
133
- $review_content = !empty(strlen($strip_review_content)) && 0 < strlen($strip_review_content) ? $strip_review_content : $review_content;
134
-
135
- $review_product_url = ! empty($product->get_permalink()) ? $product->get_permalink() : "";
136
-
137
- $review_id = ! empty($single_review->comment_ID) ? $single_review->comment_ID : "";
138
- $review_author = ! empty($single_review->comment_author) ? $single_review->comment_author : "";
139
- $review_user_id = ! empty($single_review->user_id) ? $single_review->user_id : "";
140
-
141
- $review['review']['review_id'] = $review_id;
142
- $review['review']['reviewer']['name'] = $review_author;
143
- $review['review']['reviewer']['reviewer_id'] = $review_user_id;
144
- $review['review']['content'] = $review_content;
145
- $review['review']['review_timestamp'] = $review_time;
146
- $review['review']['review_url'] = $review_product_url;
147
- $review['review']['ratings']["overall"] = $rating;
148
- $review['review']['products'] = array();
149
- $review['review']['products']['product'] = array();
150
-
151
- $review['review']['products']['product']['product_name'] = ! empty($product->get_name()) ? $product->get_name() : "";
152
- $review['review']['products']['product']['product_url'] = $review_product_url;
153
-
154
- // Get Product Attribute values by type and assign to product array
155
- foreach ( $config['attributes'] as $attr_key => $attribute ) {
156
- $merchant_attribute = isset($config['mattributes'][ $attr_key ]) ? $config['mattributes'][ $attr_key ] : '';
157
-
158
- // Add Prefix and Suffix into Output
159
- $prefix = $config['prefix'][ $attr_key ];
160
- $suffix = $config['suffix'][ $attr_key ];
161
-
162
- if ( 'pattern' === $config['type'][ $attr_key ] ) {
163
- $attributeValue = $config['default'][ $attr_key ];
164
- } else {
165
- $attributeValue = $this->products->getAttributeValueByType($product, $attribute, $merchant_attribute);
166
- }
167
-
168
- //add prefix - suffix to attribute value
169
- $attributeValue = $prefix . $attributeValue . $suffix;
170
- $attributeValue = ! empty($attributeValue) ? $attributeValue : "";
171
-
172
- if ( "review_temp_gtin" === $merchant_attribute && !empty($attributeValue)) {
173
- $review['review']['products']['product']['product_ids']['gtins'] = $this->get_product_ids($product,$config, $attr_key, $attribute,$merchant_attribute,'gtin');
174
- } elseif ( "review_temp_mpn" === $merchant_attribute && !empty($attributeValue)) {
175
- $review['review']['products']['product']['product_ids']['mpns'] = $this->get_product_ids($product,$config, $attr_key, $attribute,$merchant_attribute,'mpn');
176
- } elseif ( "review_temp_sku" === $merchant_attribute && !empty($attributeValue)) {
177
- $review['review']['products']['product']['product_ids']['skus'] = $this->get_product_ids($product,$config, $attr_key, $attribute,$merchant_attribute,'sku');
178
- } elseif ( "review_temp_brand" === $merchant_attribute && !empty($attributeValue)) {
179
- $review['review']['products']['product']['product_ids']['brands'] = $this->get_product_ids($product,$config, $attr_key, $attribute,$merchant_attribute,'brand');
180
- }
181
- }
182
-
183
- array_push($feed['reviews'], $review);
184
- $i++;
185
- }
186
- }
187
-
188
- }
189
- return $feed;
190
- }
191
-
192
- /**
193
- * Get Product Ids associated with a review (Ex: variations)
194
- *
195
- * @param $product
196
- * @param $config
197
- * @param $attr_key
198
- * @param $attribute
199
- * @param $merchant_attribute
200
- * @param $id_type
201
- * @return array
202
- */
203
- public function get_product_ids($product, $config, $attr_key, $attribute, $merchant_attribute, $id_type)
204
- {
205
- if($product->is_type('variable')){
206
- $variations = $product->get_children();
207
- if(!empty($variations)){
208
- $variation_ids = [];
209
- foreach ($variations as $key=>$variation){
210
- $product = wc_get_product($variation);
211
- if ( 'pattern' === $config['type'][ $attr_key ] ) {
212
- $variation_ids[$key][$id_type] = $config['default'][ $attr_key ];
213
- }else{
214
- $variation_ids[$key][$id_type] = $this->products->getAttributeValueByType($product, $attribute, $merchant_attribute);
215
- }
216
- }
217
- return $variation_ids;
218
- }
219
- }
220
-
221
- // For non variation products
222
- $attributeValue = "";
223
- if ( 'pattern' === $config['type'][ $attr_key ] ) {
224
- $attributeValue = $config['default'][ $attr_key ];
225
- }else{
226
- $attributeValue = $this->products->getAttributeValueByType($product, $attribute, $merchant_attribute);
227
- }
228
-
229
- return [$id_type=>$attributeValue];
230
- }
231
-
232
- /**
233
- * Convert an array to XML
234
- *
235
- * @param array $array array to convert
236
- * @param mixed $xml xml object
237
- *
238
- */
239
- function woo_feed_array_to_xml( $array, &$xml ) {
240
- foreach ( $array as $key => $value ) {
241
- if ( is_array($value) ) {
242
- if ( ! is_numeric($key) ) {
243
- $subnode = $xml->addChild("$key");
244
- $this->woo_feed_array_to_xml($value, $subnode);
245
- } else {
246
- $this->woo_feed_array_to_xml($value, $xml);
247
- }
248
- } else {
249
- if ( "overall" === $key ) {
250
- $rating = $xml->addChild($key,"$value");
251
- $rating->addAttribute('min','1');
252
- $rating->addAttribute('max','5');
253
- } elseif("review_url" === $key){
254
- $rating = $xml->addChild($key,"$value");
255
- $rating->addAttribute('type','group');
256
- }else {
257
- $value = htmlspecialchars($value);
258
- $xml->addChild("$key","$value");
259
- }
260
- }
261
- }
262
- }
263
-
264
- /**
265
- * Make XML Feed
266
- *
267
- * @return string
268
- */
269
- public function make_review_xml_feed() {
270
- // create simpleXML object
271
- $xml = new SimpleXMLElement("<?xml version=\"1.0\" encoding=\"utf-8\"?><feed xmlns:vc=\"http://www.w3.org/2007/XMLSchema-versioning\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://www.google.com/shopping/reviews/schema/product/2.3/product_reviews.xsd\"></feed>");
272
- $this->woo_feed_array_to_xml($this->data,$xml);
273
- $feedBody = $xml->asXML();
274
-
275
- $data = new DOMDocument();
276
- $data->preserveWhiteSpace = false;
277
- $data->formatOutput = true;
278
- $data->loadXML($feedBody);
279
- $feedBody = $data->saveXML();
280
-
281
- return $feedBody;
282
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
283
  }
11
  */
12
  class Woo_Feed_Review {
13
 
14
+ /**
15
+ * This variable is responsible for holding all product attributes and their values
16
+ *
17
+ * @since 1.0.0
18
+ * @var array $products Contains all the product attributes to generate feed
19
+ * @access public
20
+ */
21
+ public $products;
22
+
23
+ /**
24
+ * This variable is responsible for making error number
25
+ *
26
+ * @since 1.0.0
27
+ * @var int $errorCounter Generate error number
28
+ * @access public
29
+ */
30
+ public $errorCounter;
31
+
32
+ /**
33
+ * Feed Wrapper text for enclosing each product information
34
+ *
35
+ * @since 1.0.0
36
+ * @var string $feedWrapper Feed Wrapper text
37
+ * @access public
38
+ */
39
+ public $feedWrapper = 'review';
40
+
41
+ /**
42
+ * Store product information
43
+ *
44
+ * @since 1.0.0
45
+ * @var array $storeProducts
46
+ * @access public
47
+ */
48
+ private $storeProducts;
49
+
50
+ /**
51
+ * Product Ids
52
+ *
53
+ * @since 1.0.0
54
+ * @var array $ids
55
+ * @access public
56
+ */
57
+ private $ids;
58
+
59
+ /**
60
+ * Review Data
61
+ *
62
+ * @since 1.0.0
63
+ * @var array $data
64
+ * @access public
65
+ */
66
+ private $data;
67
+
68
+ /**
69
+ * Define the core functionality to generate feed.
70
+ *
71
+ * Set the feed rules. Map products according to the rules and Check required attributes
72
+ * and their values according to merchant specification.
73
+ * @var Woo_Generate_Feed $feedRule Contain Feed Configuration
74
+ * @since 1.0.0
75
+ */
76
+ public function __construct( $feedRule ) {
77
+
78
+ $feedRule['itemWrapper'] = $this->feedWrapper;
79
+
80
+ $this->products = new Woo_Feed_Products_v3( $feedRule );
81
+
82
+ // When update via cron job then set productIds.
83
+ if ( ! isset( $feedRule['productIds'] ) ) {
84
+ $feedRule['productIds'] = $this->products->query_products();
85
+ }
86
+
87
+ $products = $this->products->get_products( $feedRule['productIds'] );
88
+
89
+ $this->ids = $feedRule['productIds'];
90
+
91
+ $this->rules = $feedRule;
92
+
93
+ $this->data = $this->processReviewsData( $feedRule );
94
+ }
95
+
96
+ /**
97
+ * Process Reviews Data
98
+ *
99
+ * @param mixed $config feed configuration
100
+ *
101
+ */
102
+ private function processReviewsData( $config ) {
103
+ $ids = $this->ids;
104
+ $feed = array();
105
+ $feed['version'] = '2.3';
106
+ $feed['aggregator']['name'] = 'review';
107
+ $feed['publisher']['name'] = 'CTX Feed – WooCommerce Product Feed Generator by Webappick';
108
+ $feed['reviews'] = array();
109
+
110
+ foreach ( $ids as $id ) {
111
+ $product = wc_get_product( $id );
112
+
113
+ $reviews = get_comments(
114
+ array(
115
+ 'post_id' => $id,
116
+ 'status' => 'approve',
117
+ 'post_status' => 'publish',
118
+ 'post_type' => 'product',
119
+ 'parent' => 0
120
+ )
121
+ );
122
+
123
+ $review = array();
124
+ $i = 0;
125
+ if ( $reviews && is_array( $reviews ) ) {
126
+ foreach ( $reviews as $single_review ) {
127
+
128
+ $review_content = $single_review->comment_content;
129
+ if ( empty( $review_content ) ) {
130
+ continue;
131
+ }
132
+
133
+ $rating = get_comment_meta( $single_review->comment_ID, 'rating', true );
134
+ if ( empty( $rating ) ) {
135
+ continue;
136
+ }
137
+
138
+ $review_time = ! empty( $single_review->comment_date_gmt ) ? gmdate( 'c', strtotime( $single_review->comment_date_gmt ) ) : "";
139
+
140
+
141
+ //Review Content
142
+ //strip tags and spacial characters
143
+ $strip_review_content = woo_feed_strip_all_tags( wp_specialchars_decode( $review_content ) );
144
+ $review_content = ! empty( strlen( $strip_review_content ) ) && 0 < strlen( $strip_review_content ) ? $strip_review_content : $review_content;
145
+
146
+ $review_product_url = ! empty( $product->get_permalink() ) ? $product->get_permalink() : "";
147
+
148
+ $review_id = ! empty( $single_review->comment_ID ) ? $single_review->comment_ID : "";
149
+ $review_author = ! empty( $single_review->comment_author ) ? $single_review->comment_author : "";
150
+ $review_user_id = ! empty( $single_review->user_id ) ? $single_review->user_id : "";
151
+
152
+ $review['review']['review_id'] = $review_id;
153
+ $review['review']['reviewer']['name'] = $review_author;
154
+ $review['review']['reviewer']['reviewer_id'] = $review_user_id;
155
+ $review['review']['content'] = $review_content;
156
+ $review['review']['review_timestamp'] = $review_time;
157
+ $review['review']['review_url'] = $review_product_url;
158
+ $review['review']['ratings']["overall"] = $rating;
159
+ $review['review']['products'] = array();
160
+ $review['review']['products']['product'] = array();
161
+
162
+ $review['review']['products']['product']['product_name'] = ! empty( $product->get_name() ) ? $product->get_name() : "";
163
+ $review['review']['products']['product']['product_url'] = $review_product_url;
164
+
165
+ // Get Product Attribute values by type and assign to product array
166
+ foreach ( $config['attributes'] as $attr_key => $attribute ) {
167
+ $merchant_attribute = isset( $config['mattributes'][ $attr_key ] ) ? $config['mattributes'][ $attr_key ] : '';
168
+
169
+ // Add Prefix and Suffix into Output
170
+ $prefix = $config['prefix'][ $attr_key ];
171
+ $suffix = $config['suffix'][ $attr_key ];
172
+
173
+ if ( 'pattern' === $config['type'][ $attr_key ] ) {
174
+ $attributeValue = $config['default'][ $attr_key ];
175
+ } else {
176
+ $attributeValue = $this->products->getAttributeValueByType( $product, $attribute, $merchant_attribute );
177
+ }
178
+
179
+ //add prefix - suffix to attribute value
180
+ $attributeValue = $prefix . $attributeValue . $suffix;
181
+ $attributeValue = ! empty( $attributeValue ) ? $attributeValue : "";
182
+
183
+ if ( "review_temp_gtin" === $merchant_attribute) {
184
+ $review['review']['products']['product']['product_ids']['gtins'] = $this->get_product_ids( $product, $config, $attr_key, $attribute, $merchant_attribute, 'gtin' );
185
+ } elseif ( "review_temp_mpn" === $merchant_attribute) {
186
+ $review['review']['products']['product']['product_ids']['mpns'] = $this->get_product_ids( $product, $config, $attr_key, $attribute, $merchant_attribute, 'mpn' );
187
+ } elseif ( "review_temp_sku" === $merchant_attribute ) {
188
+ $review['review']['products']['product']['product_ids']['skus'] = $this->get_product_ids( $product, $config, $attr_key, $attribute, $merchant_attribute, 'sku' );
189
+ } elseif ( "review_temp_brand" === $merchant_attribute) {
190
+ $review['review']['products']['product']['product_ids']['brands'] = $this->get_product_ids( $product, $config, $attr_key, $attribute, $merchant_attribute, 'brand' );
191
+ }
192
+ }
193
+
194
+ $feed['reviews'][] = $review;
195
+ $i ++;
196
+ }
197
+ }
198
+
199
+ }
200
+
201
+ return $feed;
202
+ }
203
+
204
+ /**
205
+ * Get Product Ids associated with a review (Ex: variations)
206
+ *
207
+ * @param $product
208
+ * @param $config
209
+ * @param $attr_key
210
+ * @param $attribute
211
+ * @param $merchant_attribute
212
+ * @param $id_type
213
+ *
214
+ * @return array
215
+ */
216
+ public function get_product_ids( $product, $config, $attr_key, $attribute, $merchant_attribute, $id_type ) {
217
+ if ( $product->is_type( 'variable' ) ) {
218
+ $variations = $product->get_children();
219
+ if ( ! empty( $variations ) ) {
220
+ $variation_ids = [];
221
+ foreach ( $variations as $key => $variation ) {
222
+ $variation = wc_get_product( $variation );
223
+ if ( 'pattern' === $config['type'][ $attr_key ] ) {
224
+ $variation_ids[ $key ][ $id_type ] = $config['default'][ $attr_key ];
225
+ } else {
226
+ // echo "<pre>";echo $attribute; die();
227
+ $variation_ids[ $key ][ $id_type ] = $this->products->getAttributeValueByType( $variation, $attribute, $merchant_attribute );
228
+ }
229
+ }
230
+
231
+ return $variation_ids;
232
+ }
233
+ }
234
+
235
+ // For non variation products
236
+ $attributeValue = "";
237
+ if ( 'pattern' === $config['type'][ $attr_key ] ) {
238
+ $attributeValue = $config['default'][ $attr_key ];
239
+ } else {
240
+ $attributeValue = $this->products->getAttributeValueByType( $product, $attribute, $merchant_attribute );
241
+ }
242
+
243
+ return [ $id_type => $attributeValue ];
244
+ }
245
+
246
+ /**
247
+ * Convert an array to XML
248
+ *
249
+ * @param array $array array to convert
250
+ * @param mixed $xml xml object
251
+ *
252
+ */
253
+ function woo_feed_array_to_xml( $array, &$xml ) {
254
+ foreach ( $array as $key => $value ) {
255
+ if ( is_array( $value ) ) {
256
+ if ( ! is_numeric( $key ) ) {
257
+ $subnode = $xml->addChild( "$key" );
258
+ $this->woo_feed_array_to_xml( $value, $subnode );
259
+ } else {
260
+ $this->woo_feed_array_to_xml( $value, $xml );
261
+ }
262
+ } else {
263
+ if ( "overall" === $key ) {
264
+ $rating = $xml->addChild( $key, "$value" );
265
+ $rating->addAttribute( 'min', '1' );
266
+ $rating->addAttribute( 'max', '5' );
267
+ } elseif ( "review_url" === $key ) {
268
+ $rating = $xml->addChild( $key, "$value" );
269
+ $rating->addAttribute( 'type', 'group' );
270
+ } else {
271
+ $value = htmlspecialchars( $value );
272
+ $xml->addChild( "$key", "$value" );
273
+ }
274
+ }
275
+ }
276
+ }
277
+
278
+ /**
279
+ * Make XML Feed
280
+ *
281
+ * @return string
282
+ */
283
+ public function make_review_xml_feed() {
284
+ // create simpleXML object
285
+ $xml = new SimpleXMLElement( "<?xml version=\"1.0\" encoding=\"utf-8\"?><feed xmlns:vc=\"http://www.w3.org/2007/XMLSchema-versioning\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://www.google.com/shopping/reviews/schema/product/2.3/product_reviews.xsd\"></feed>" );
286
+ $this->woo_feed_array_to_xml( $this->data, $xml );
287
+ $feedBody = $xml->asXML();
288
+
289
+ $data = new DOMDocument();
290
+ $data->preserveWhiteSpace = false;
291
+ $data->formatOutput = true;
292
+ $data->loadXML( $feedBody );
293
+ $feedBody = $data->saveXML();
294
+
295
+ return $feedBody;
296
+ }
297
  }
includes/filters/filters.php CHANGED
@@ -37,4 +37,4 @@ function CTXFEED_filter_securing_input_cb($meth = "POST", $inpu = '', $type = "t
37
 
38
  }
39
 
40
- add_filter( 'CTXFEED_filter_securing_input', 'CTXFEED_filter_securing_input_cb', 10, 4 );
37
 
38
  }
39
 
40
+ add_filter( 'CTXFEED_filter_securing_input', 'CTXFEED_filter_securing_input_cb', 10, 4 );
includes/helper.php CHANGED
@@ -9,244 +9,244 @@
9
  * @copyright WebAppick
10
  */
11
 
12
- if ( ! defined('ABSPATH') ) {
13
- die(); // Silence...
14
- }
15
-
16
- if ( ! function_exists('woo_feed_maybe_define_constant') ) {
17
- /**
18
- * Define a constant if it is not already defined.
19
- *
20
- * @param string $name Constant name.
21
- * @param mixed $value Value.
22
- *
23
- * @return void
24
- * @since 3.2.1
25
- */
26
- function woo_feed_maybe_define_constant( $name, $value ) {
27
- // phpcs:disable
28
- if (!defined($name)) {
29
- define($name, $value);
30
- }
31
- // phpcs:enable
32
- }
33
- }
34
- if ( ! function_exists('woo_feed_doing_it_wrong') ) {
35
- /**
36
- * Wrapper for _doing_it_wrong.
37
- *
38
- * @param string $function Function used.
39
- * @param string $message Message to log.
40
- * @param string $version Version the message was added in.
41
- *
42
- * @return void
43
- * @since 3.2.1
44
- *
45
- */
46
- function woo_feed_doing_it_wrong( $function, $message, $version ) {
47
- // phpcs:disable
48
- $message .= ' Backtrace: ' . wp_debug_backtrace_summary();
49
-
50
- if (is_ajax() || WC()->is_rest_api_request()) {
51
- do_action('doing_it_wrong_run', $function, $message, $version);
52
- error_log("{$function} was called incorrectly. {$message}. This message was added in version {$version}.");
53
- } else {
54
- _doing_it_wrong($function, $message, $version);
55
- }
56
- // phpcs:enable
57
- }
58
- }
59
- if ( ! function_exists('is_ajax') ) {
60
-
61
- /**
62
- * Is_ajax - Returns true when the page is loaded via ajax.
63
- *
64
- * @return bool
65
- */
66
- function is_ajax() {
67
- return function_exists('wp_doing_ajax') ? wp_doing_ajax() : defined('DOING_AJAX');
68
- }
69
- }
70
- if ( ! function_exists('woo_feed_is_plugin_active') ) {
71
- /**
72
- * Determines whether a plugin is active.
73
- *
74
- * @param string $plugin Path to the plugin file relative to the plugins directory.
75
- *
76
- * @return bool True, if in the active plugins list. False, not in the list.
77
- * @since 3.1.41
78
- * @see is_plugin_active()
79
- *
80
- */
81
- function woo_feed_is_plugin_active( $plugin ) {
82
- if ( ! function_exists('is_plugin_active') ) {
83
- include_once ABSPATH . 'wp-admin/includes/plugin.php';
84
- }
85
-
86
- return is_plugin_active($plugin);
87
- }
88
- }
89
- if ( ! function_exists('wooFeed_is_plugin_inactive') ) {
90
- /**
91
- * Determines whether the plugin is inactive.
92
- *
93
- * @param string $plugin Path to the plugin file relative to the plugins directory.
94
- *
95
- * @return bool True if inactive. False if active.
96
- * @since 3.1.41
97
- * @see wooFeed_is_plugin_inactive()
98
- *
99
- */
100
- function wooFeed_is_plugin_inactive( $plugin ) {
101
- return ! woo_feed_is_plugin_active($plugin);
102
- }
103
- }
104
- if ( ! function_exists('wooFeed_deactivate_plugins') ) {
105
- /**
106
- * Deactivate a single plugin or multiple plugins.
107
- * Wrapper for core deactivate_plugins() function
108
- *
109
- * @param string|array $plugins Single plugin or list of plugins to deactivate.
110
- * @param bool $silent Prevent calling deactivation hooks. Default is false.
111
- * @param mixed $network_wide Whether to deactivate the plugin for all sites in the network.
112
- *
113
- * @return void
114
- * @see deactivate_plugins()
115
- *
116
- */
117
- function wooFeed_Deactivate_plugins( $plugins, $silent = false, $network_wide = null ) {
118
- if ( ! function_exists('deactivate_plugins') ) {
119
- require_once(ABSPATH . 'wp-admin/includes/plugin.php');
120
- }
121
- deactivate_plugins($plugins, $silent, $network_wide);
122
- }
123
- }
124
- if ( ! function_exists('wooFeed_is_supported_php') ) {
125
- /**
126
- * Check if server php version meet minimum requirement
127
- * @return bool
128
- * @since 3.1.41
129
- */
130
- function wooFeed_is_supported_php() {
131
- // PHP version need to be => WOO_FEED_MIN_PHP_VERSION
132
- return ! version_compare(PHP_VERSION, WOO_FEED_MIN_PHP_VERSION, '<');
133
- }
134
- }
135
- if ( ! function_exists('wooFeed_check_WC') ) {
136
- function wooFeed_check_WC() {
137
- return class_exists('WooCommerce', false);
138
- }
139
- }
140
- if ( ! function_exists('wooFeed_is_WC_supported') ) {
141
- function wooFeed_is_WC_supported() {
142
- // Ensure WC is loaded before checking version
143
- return (defined('WC_VERSION') && version_compare(WC_VERSION, WOO_FEED_MIN_WC_VERSION, '>='));
144
- }
145
- }
146
- if ( ! function_exists('woo_feed_wc_version_check') ) {
147
- /**
148
- * Check WooCommerce Version
149
- *
150
- * @param string $version
151
- *
152
- * @return bool
153
- */
154
- function woo_feed_wc_version_check( $version = '3.0' ) {
155
- if ( ! function_exists('get_plugins') ) {
156
- require_once ABSPATH . 'wp-admin/includes/plugin.php';
157
- }
158
- $plugins = get_plugins();
159
- if ( array_key_exists('woocommerce/woocommerce.php', $plugins) ) {
160
- $currentVersion = $plugins['woocommerce/woocommerce.php']['Version'];
161
- if ( version_compare($currentVersion, $version, '>=') ) {
162
- return true;
163
- }
164
- }
165
-
166
- return false;
167
- }
168
- }
169
- if ( ! function_exists('woo_feed_wpml_version_check') ) {
170
- /**
171
- * Check WooCommerce Version
172
- *
173
- * @param string $version
174
- *
175
- * @return bool
176
- */
177
- function woo_feed_wpml_version_check( $version = '3.2' ) {
178
- // calling this function too early (before wc loaded) will not give correct output
179
- if ( defined('ICL_SITEPRESS_VERSION') ) {
180
- if ( version_compare(ICL_SITEPRESS_VERSION, $version, '>=') ) {
181
- return true;
182
- }
183
- }
184
-
185
- return false;
186
- }
187
- }
188
- if ( ! function_exists('wooFeed_Admin_Notices') ) {
189
- /**
190
- * Display Admin Messages
191
- * @hooked admin_notices
192
- * @return void
193
- * @since 3.1.41
194
- */
195
- function wooFeed_Admin_Notices() {
196
- // @TODO Refactor this function with admin message class
197
- // WC Missing Notice..
198
- if ( ! wooFeed_check_WC() ) {
199
- $plugin_url = self_admin_url('plugin-install.php?s=woocommerce&tab=search&type=term');
200
- /**
201
- * @noinspection HtmlUnknownTarget
202
- */
203
- $plugin_url = sprintf('<a href="%s">%s</a>', $plugin_url, esc_html__('WooCommerce', 'woo-feed'));
204
- $plugin_name = sprintf('<code>%s</code>', esc_html__('WooCommerce Product Feed', 'woo-feed'));
205
- $wc_name = sprintf('<code>%s</code>', esc_html__('WooCommerce', 'woo-feed'));
206
- $message = sprintf(
207
- /* translators: 1: this plugin name, 2: required plugin name, 3: required plugin name and installation url */
208
- esc_html__('%1$s requires %2$s to be installed and active. You can installed/activate %3$s here.', 'woo-feed'),
209
- $plugin_name,
210
- $wc_name,
211
- $plugin_url
212
- );
213
- printf('<div class="error"><p><strong>%1$s</strong></p></div>', $message); // phpcs:ignore
214
- }
215
- if ( wooFeed_check_WC() && ! wooFeed_is_WC_supported() ) {
216
- $plugin_url = self_admin_url('plugin-install.php?s=woocommerce&tab=search&type=term');
217
- $wcVersion = defined('WC_VERSION') ? '<code>' . WC_VERSION . '</code>' : '<code>UNKNOWN</code>';
218
- $minVersion = '<code>' . WOO_FEED_MIN_WC_VERSION . '</code>';
219
- /**
220
- * @noinspection HtmlUnknownTarget
221
- */
222
- $plugin_url = sprintf('<a href="%s">%s</a>', $plugin_url, esc_html__('WooCommerce', 'woo-feed'));
223
- $plugin_name = sprintf('<code>%s</code>', esc_html__('WooCommerce Product Feed', 'woo-feed'));
224
- $wc_name = sprintf('<code>%s</code>', esc_html__('WooCommerce', 'woo-feed'));
225
- $message = sprintf(
226
- /* translators: 1: this plugin name, 2: required plugin name, 3: required plugin required version, 4: required plugin current version, 5: required plugin update url and name */
227
- esc_html__('%1$s requires %2$s version %3$s or above and %4$s found. Please upgrade %2$s to the latest version here %5$s', 'woo-feed'),
228
- $plugin_name,
229
- $wc_name,
230
- $minVersion,
231
- $wcVersion,
232
- $plugin_url
233
- );
234
- printf('<div class="error"><p><strong>%1$s</strong></p></div>', $message); // phpcs:ignore
235
- }
236
- }
237
- }
238
- if ( ! function_exists('woo_feed_black_friday_notice') ) {
239
- /**
240
- * CTX Feed Black Friday Notice
241
- *
242
- * @since 4.4.35
243
- * @author Nazrul Islam Nayan
244
- */
245
- function woo_feed_black_friday_notice() {
246
- $user_id = get_current_user_id();
247
- if ( ! get_user_meta($user_id, 'woo_feed_black_friday_notice_2021_dismissed') ) {
248
- ob_start();
249
- ?>
250
  <script type="text/javascript">
251
  (function ($) {
252
  $(document).on('click', '.woo-feed-ctx-startup-notice button.notice-dismiss', function (e) {
@@ -265,31 +265,32 @@ if ( ! function_exists('woo_feed_black_friday_notice') ) {
265
  });
266
  })(jQuery)
267
  </script>
268
- <a href="https://webappick.com/plugin/woocommerce-product-feed-pro/?utm_source=freePlugin&utm_medium=go_premium&utm_campaign=black_friday_2021&utm_term=wooFeed" class="notice woo-feed-ctx-startup-notice is-dismissible"
269
- style="background: url(<?php echo WOO_FEED_PLUGIN_URL . "admin/images/ctx-feed-black-friday-banner-2021.png"; ?>) no-repeat top center;">
 
270
  <input type="hidden" id="woo_feed_to_ctx_feed_nonce"
271
- value="<?php echo wp_create_nonce('woo-feed-to-ctx-feed-notice'); ?>">
272
  </a>
273
- <?php
274
- $image = ob_get_contents();
275
- }
276
- }
277
- }
278
- if ( ! function_exists('woo_feed_progress_bar') ) {
279
- /**
280
- * Feed Progress Bar
281
- *
282
- * @since 4.1.1
283
- */
284
- function woo_feed_progress_bar() {
285
- $progress_bar = '';
286
- ob_start();
287
- ?>
288
  <div id="feed_progress_table" style="display: none;">
289
  <table class="table widefat fixed">
290
  <thead>
291
  <tr>
292
- <th><b><?php esc_html_e('Generating Product Feed', 'woo-feed'); ?></b></th>
293
  </tr>
294
  </thead>
295
  <tbody>
@@ -315,1326 +316,1363 @@ if ( ! function_exists('woo_feed_progress_bar') ) {
315
  </table>
316
  <br>
317
  </div>
318
- <?php
319
- $progress_bar .= ob_get_clean();
320
-
321
- echo $progress_bar;
322
-
323
- }
324
- }
325
-
326
- if ( ! function_exists('checkFTP_connection') ) {
327
- /**
328
- * Verify if ftp module enabled
329
- * @TODO improve module detection
330
- * @return bool
331
- */
332
- function checkFTP_connection() {
333
- return (extension_loaded('ftp') || function_exists('ftp_connect'));
334
- }
335
- }
336
- if ( ! function_exists('checkSFTP_connection') ) {
337
- /**
338
- * Verify if ssh/sftp module enabled
339
- * @TODO improve module detection
340
- * @return bool
341
- */
342
- function checkSFTP_connection() {
343
- return (extension_loaded('ssh2') || function_exists('ssh2_connect'));
344
- }
345
- }
346
- if ( ! function_exists('array_splice_assoc') ) {
347
- /**
348
- * Array Splice Associative Array
349
- * @see https://www.php.net/manual/en/function.array-splice.php#111204
350
- *
351
- * @param array $input
352
- * @param string|int $offset
353
- * @param string|int $length
354
- * @param array $replacement
355
- *
356
- * @return array
357
- */
358
- function array_splice_assoc( $input, $offset, $length, $replacement ) {
359
- $replacement = (array)$replacement;
360
- $key_indices = array_flip(array_keys($input));
361
- if ( isset($input[ $offset ]) && is_string($offset) ) {
362
- $offset = $key_indices[ $offset ] + 1;
363
- }
364
- if ( isset($input[ $length ]) && is_string($length) ) {
365
- $length = $key_indices[ $length ] - $offset;
366
- }
367
-
368
- $input = array_slice($input, 0, $offset, true) + $replacement + array_slice($input, $offset + $length, null, true);
369
-
370
- return $input;
371
- }
372
- }
373
- if ( ! function_exists('woo_feed_get_query_type_options') ) {
374
- /**
375
- * Get Query available Types
376
- *
377
- * @param string $type
378
- * @return array
379
- * @since 3.3.11
380
- */
381
- function woo_feed_get_query_type_options( $type='' ) {
382
- if ( 'variation' === $type ) {
383
- return [
384
- 'individual' => __('Individual', 'woo-feed'),
385
- 'variable' => __('Variable Dependable', 'woo-feed'),
386
- ];
387
- }else {
388
- return [
389
- 'wc' => __('WC_Product_Query', 'woo-feed'),
390
- 'wp' => __('WP_Query', 'woo-feed'),
391
- 'both' => __('Both', 'woo-feed'),
392
- ];
393
- }
394
- }
395
- }
396
- if ( ! function_exists('woo_feed_get_cache_ttl_options') ) {
397
- /**
398
- * Cache Expiration Options
399
- * @return array
400
- */
401
- function woo_feed_get_cache_ttl_options() {
402
- return apply_filters(
403
- 'woo_feed_cache_ttl_options',
404
- [
405
- 0 => esc_html__('No Expiration ', 'woo-feed'),
406
- MONTH_IN_SECONDS => esc_html__('1 Month', 'woo-feed'),
407
- WEEK_IN_SECONDS => esc_html__('1 Week', 'woo-feed'),
408
- DAY_IN_SECONDS => esc_html__('24 Hours', 'woo-feed'),
409
- 12 * HOUR_IN_SECONDS => esc_html__('12 Hours', 'woo-feed'),
410
- 6 * HOUR_IN_SECONDS => esc_html__('6 Hours', 'woo-feed'),
411
- HOUR_IN_SECONDS => esc_html__('1 Hours', 'woo-feed'),
412
- ]
413
- );
414
- }
415
- }
416
- if ( ! function_exists('woo_feed_get_custom2_merchant') ) {
417
- /**
418
- * Get Merchant list that are allowed on Custom2 Template
419
- * @return array
420
- */
421
- function woo_feed_get_custom2_merchant() {
422
- return array( 'custom2', 'admarkt', 'yandex_xml', 'glami' );
423
- }
424
- }
425
- if ( ! function_exists('woo_feed_get_merchant_class') ) {
426
- /**
427
- * @param string $provider
428
- *
429
- * @return string
430
- */
431
- function woo_feed_get_merchant_class( $provider ) {
432
- if ( in_array($provider, [ 'google', 'google_shopping_action', 'google_local', 'google_local_inventory', 'adroll', 'smartly.io' ], true) ) {
433
- return 'Woo_Feed_Google';
434
- } elseif ( in_array($provider, array( 'pinterest', 'pinterest_rss' )) ) {
435
- return 'Woo_Feed_Pinterest';
436
- } elseif ( 'facebook' === $provider ) {
437
- return 'Woo_Feed_Facebook';
438
- } elseif ( strpos($provider, 'amazon') !== false ) {
439
- return 'Woo_Feed_Amazon';
440
- } elseif ( in_array($provider, woo_feed_get_custom2_merchant(), true) ) {
441
- return 'Woo_Feed_Custom_XML';
442
- } else {
443
- return 'Woo_Feed_Custom';
444
- }
445
- }
446
- }
447
- if ( ! function_exists('woo_feed_handle_file_transfer') ) {
448
- /**
449
- * Transfer file as per ftp config
450
- *
451
- * @param string $fileFrom
452
- * @param string $fileTo
453
- * @param array $info
454
- *
455
- * @return bool
456
- */
457
- function woo_feed_handle_file_transfer( $fileFrom, $fileTo, $info ) {
458
- if ( 1 === (int)$info['ftpenabled'] ) {
459
- if ( ! file_exists($fileFrom) ) {
460
- woo_feed_log_feed_process($info['filename'], 'Unable to process file transfer request. File does not exists.');
461
- return false;
462
- }
463
- $ftpHost = sanitize_text_field($info['ftphost']);
464
- $ftp_user = sanitize_text_field($info['ftpuser']);
465
- $ftp_password = sanitize_text_field($info['ftppassword']);
466
- $ftpPath = trailingslashit(untrailingslashit(sanitize_text_field($info['ftppath'])));
467
- $ftp_passive_mode = (isset($info['ftpmode']) && sanitize_text_field($info['ftpmode']) === 'passive') ? true : false;
468
- if ( isset($info['ftporsftp']) & 'ftp' === $info['ftporsftp'] ) {
469
- $ftporsftp = 'ftp';
470
- } else {
471
- $ftporsftp = 'sftp';
472
- }
473
- if ( isset($info['ftpport']) && ! empty($info['ftpport']) ) {
474
- $ftp_port = absint($info['ftpport']);
475
- } else {
476
- $ftp_port = false;
477
- }
478
-
479
- if ( ! $ftp_port || ! ( ( 1 <= $ftp_port ) && ( $ftp_port <= 65535 ) ) ) {
480
- $ftp_port = 'sftp' === $ftporsftp ? 22 : 21;
481
- }
482
-
483
- woo_feed_log_feed_process($info['filename'], sprintf('Uploading Feed file via %s.', $ftporsftp));
484
-
485
- try {
486
- if ( 'ftp' === $ftporsftp ) {
487
-
488
- $ftp = new WebAppick\FTP\FTPConnection();
489
- if ( $ftp->connect($ftpHost, $ftp_user, $ftp_password, $ftp_passive_mode, $ftp_port) ) {
490
- return $ftp->upload_file($fileFrom, $ftpPath . $fileTo);
491
- }
492
- } elseif ( 'sftp' === $ftporsftp ) {
493
-
494
- $sftp = new WebAppick\FTP\SFTPConnection($ftpHost, $ftp_port);
495
- $sftp->login($ftp_user, $ftp_password);
496
-
497
- return $sftp->upload_file($fileFrom, $fileTo, $ftpPath);
498
-
499
- }
500
- } catch ( Exception $e ) {
501
- $message = 'Error Uploading Feed Via ' . $ftporsftp . PHP_EOL . 'Caught Exception :: ' . $e->getMessage();
502
- woo_feed_log($info['filename'], $message, 'critical', $e, true);
503
- woo_feed_log_fatal_error($message, $e);
504
- return false;
505
- }
506
- }
507
- return false;
508
- }
509
- }
510
- if ( ! function_exists('woo_feed_get_file_types') ) {
511
- function woo_feed_get_file_types() {
512
- return array(
513
- 'xml' => 'XML',
514
- 'csv' => 'CSV',
515
- 'tsv' => 'TSV',
516
- 'xls' => 'XLS',
517
- 'txt' => 'TXT',
518
- 'json' => 'JSON',
519
- );
520
- }
521
- }
522
- if ( ! function_exists('woo_feed_get_default_brand') ) {
523
- /**
524
- * Guess Brand name from Site URL
525
- *
526
- * @return string
527
- */
528
- function woo_feed_get_default_brand() {
529
- $brand = apply_filters('woo_feed_pre_get_default_brand_name', null);
530
- if ( ! is_null($brand) ) {
531
- return $brand;
532
- }
533
- $brand = '';
534
- $url = filter_var(site_url(), FILTER_SANITIZE_URL);
535
- if ( false !== $url ) {
536
- $url = wp_parse_url($url);
537
- if ( array_key_exists('host', $url) ) {
538
- if ( strpos($url['host'], ".") !== false ) {
539
- $arr = explode('.', $url['host']);
540
- $brand = $arr[ count($arr) - 2 ];
541
- $brand = ucfirst($brand);
542
- } else {
543
- $brand = $url['host'];
544
- $brand = ucfirst($brand);
545
- }
546
- }
547
- }
548
-
549
- return apply_filters('woo_feed_get_default_brand_name', $brand);
550
- }
551
- }
552
- if ( ! function_exists('woo_feed_merchant_require_google_category') ) {
553
- /**
554
- * Check if current merchant supports google taxonomy for current attribute.
555
- * @param string $merchant
556
- * @param string $attribute
557
- *
558
- * @return array|bool
559
- */
560
- function woo_feed_merchant_require_google_category( $merchant = null, $attribute = null ) {
561
- $list = [
562
- 'current_category' => [
563
- 'google',
564
- 'google_shopping_action',
565
- 'google_local',
566
- 'google_local_inventory',
567
- 'facebook',
568
- 'tiktok',
569
- 'snapchat',
570
- 'adroll',
571
- 'smartly.io',
572
- 'pinterest',
573
- 'rakuten.de',
574
- ],
575
- 'fb_product_category' => [ 'facebook' ],
576
- 'google_product_category' => [ 'rakuten.de','tiktok','snapchat' ],
577
- 'google_category_id' => [ 'daisycon', 'daisycon_automotive', 'daisycon_books', 'daisycon_cosmetics', 'daisycon_daily_offers', 'daisycon_electronics', 'daisycon_food_drinks', 'daisycon_home_garden', 'daisycon_housing', 'daisycon_fashion', 'daisycon_studies_trainings', 'daisycon_telecom_accessories', 'daisycon_telecom_all_in_one', 'daisycon_telecom_gsm_subscription', 'daisycon_telecom_gsm', 'daisycon_telecom_sim', 'daisycon_magazines', 'daisycon_holidays_accommodations', 'daisycon_holidays_accommodations_and_transport', 'daisycon_holidays_trips', 'daisycon_work_jobs' ],
578
- ];
579
- if ( null !== $merchant && null !== $attribute ) {
580
- return (isset($list[ $attribute ]) && in_array($merchant, $list[ $attribute ], true));
581
- }
582
- return $list;
583
- }
584
- }
585
- if ( ! function_exists('woo_feed_get_item_wrapper_hidden_merchant') ) {
586
- function woo_feed_get_item_wrapper_hidden_merchant() {
587
- return apply_filters(
588
- 'woo_feed_item_wrapper_hidden_merchant',
589
- [
590
- 'google',
591
- 'google_shopping_action',
592
- 'facebook',
593
- 'pinterest',
594
- 'fruugo.au',
595
- 'stylight.com',
596
- 'nextad',
597
- 'skinflint.co.uk',
598
- 'comparer.be',
599
- 'dooyoo',
600
- 'hintaseuranta.fi',
601
- 'incurvy',
602
- 'kijiji.ca',
603
- 'marktplaats.nl',
604
- 'rakuten.de',
605
- 'shopalike.fr',
606
- 'spartoo.fi',
607
- 'webmarchand',
608
- 'skroutz',
609
- 'daisycon',
610
- 'daisycon_automotive',
611
- 'daisycon_books',
612
- 'daisycon_cosmetics',
613
- 'daisycon_daily_offers',
614
- 'daisycon_electronics',
615
- 'daisycon_food_drinks',
616
- 'daisycon_home_garden',
617
- 'daisycon_housing',
618
- 'daisycon_fashion',
619
- 'daisycon_studies_trainings',
620
- 'daisycon_telecom_accessories',
621
- 'daisycon_telecom_all_in_one',
622
- 'daisycon_telecom_gsm_subscription',
623
- 'daisycon_telecom_gsm',
624
- 'daisycon_telecom_sim',
625
- 'daisycon_magazines',
626
- 'daisycon_holidays_accommodations',
627
- 'daisycon_holidays_accommodations_and_transport',
628
- 'daisycon_holidays_trips',
629
- 'daisycon_work_jobs',
630
- ]
631
- );
632
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
633
  }
634
 
635
  // The Editor.
636
- if ( ! function_exists('woo_feed_parse_feed_rules') ) {
637
- /**
638
- * Parse Feed Config/Rules to make sure that necessary array keys are exists
639
- * this will reduce the uses of isset() checking
640
- *
641
- * @param array $rules rules to parse.
642
- * @param string $context parsing context. useful for filtering, view, save, db, create etc.
643
- *
644
- * @return array
645
- * @since 3.3.5 $context parameter added.
646
- *
647
- * @uses wp_parse_args
648
- *
649
- */
650
- function woo_feed_parse_feed_rules( $rules = [], $context = 'view' ) {
651
-
652
- if ( empty($rules) ) {
653
- $rules = [];
654
- }
655
- $defaults = [
656
- 'provider' => '',
657
- 'filename' => '',
658
- 'feedType' => '',
659
- 'feed_country' => '',
660
- 'ftpenabled' => 0,
661
- 'ftporsftp' => 'ftp',
662
- 'ftphost' => '',
663
- 'ftpport' => '21',
664
- 'ftpuser' => '',
665
- 'ftppassword' => '',
666
- 'ftppath' => '',
667
- 'ftpmode' => 'active',
668
- 'is_variations' => 'y',
669
- 'variable_price' => 'first',
670
- 'variable_quantity' => 'first',
671
- 'feedLanguage' => apply_filters('wpml_current_language', null),
672
- 'feedCurrency' => get_woocommerce_currency(),
673
- 'itemsWrapper' => 'products',
674
- 'itemWrapper' => 'product',
675
- 'delimiter' => ',',
676
- 'enclosure' => 'double',
677
- 'extraHeader' => '',
678
- 'vendors' => [],
679
- // Feed Config
680
- 'mattributes' => [], // merchant attributes
681
- 'prefix' => [], // prefixes
682
- 'type' => [], // value (attribute) types
683
- 'attributes' => [], // product attribute mappings
684
- 'default' => [], // default values (patterns) if value type set to pattern
685
- 'suffix' => [], // suffixes
686
- 'output_type' => [], // output type (output filter)
687
- 'limit' => [], // limit or command
688
- // filters tab
689
- 'composite_price' => '',
690
- 'product_ids' => '',
691
- 'categories' => [],
692
- 'post_status' => [ 'publish' ],
693
- 'filter_mode' => [],
694
- 'campaign_parameters' => [],
695
-
696
- 'ptitle_show' => '',
697
- 'decimal_separator' => wc_get_price_decimal_separator(),
698
- 'thousand_separator' => wc_get_price_thousand_separator(),
699
- 'decimals' => wc_get_price_decimals(),
700
- ];
701
- $rules = wp_parse_args($rules, $defaults);
702
- $rules['filter_mode'] = wp_parse_args($rules['filter_mode'],
703
- [
704
- 'product_ids' => 'include',
705
- 'categories' => 'include',
706
- 'post_status' => 'include',
707
- ]);
708
-
709
- $rules['campaign_parameters'] = wp_parse_args(
710
- $rules['campaign_parameters'],
711
- [
712
- 'utm_source' => '',
713
- 'utm_medium' => '',
714
- 'utm_campaign' => '',
715
- 'utm_term' => '',
716
- 'utm_content' => '',
717
- ]
718
- );
719
-
720
- if ( ! empty($rules['provider']) && is_string($rules['provider']) ) {
721
- /**
722
- * filter parsed rules for provider
723
- *
724
- * @param array $rules
725
- * @param string $context
726
- *
727
- * @since 3.3.7
728
- *
729
- */
730
- $rules = apply_filters("woo_feed_{$rules['provider']}_parsed_rules", $rules, $context);
731
- }
732
-
733
- /**
734
- * filter parsed rules
735
- *
736
- * @param array $rules
737
- * @param string $context
738
- *
739
- * @since 3.3.7 $provider parameter removed
740
- *
741
- */
742
- return apply_filters('woo_feed_parsed_rules', $rules, $context);
743
- }
744
- }
745
- if ( ! function_exists('woo_feed_register_and_do_woo_feed_meta_boxes') ) {
746
- /**
747
- * Registers the default Feed Editor MetaBoxes, and runs the `do_meta_boxes` actions.
748
- *
749
- * @param string|WP_Screen $screen Screen identifier. If you have used add_menu_page() or
750
- * add_submenu_page() to create a new screen (and hence screen_id)
751
- * make sure your menu slug conforms to the limits of sanitize_key()
752
- * otherwise the 'screen' menu may not correctly render on your page.
753
- * @param array $feedRules current feed being processed.
754
- *
755
- * @return void
756
- * @see register_and_do_post_meta_boxes()
757
- *
758
- * @since 3.2.6
759
- *
760
- */
761
- function woo_feed_register_and_do_woo_feed_meta_boxes( $screen, $feedRules = array() ) {
762
- if ( empty($screen) ) {
763
- $screen = get_current_screen();
764
- } elseif ( is_string($screen) ) {
765
- $screen = convert_to_screen($screen);
766
- }
767
- // edit page MetaBoxes
768
- if ( 'ctx-feed_page_webappick-new-feed' === $screen->id || 'toplevel_page_webappick-manage-feeds' === $screen->id ) {
769
- add_meta_box('feed_merchant_info', 'Feed Merchant Info', 'woo_feed_merchant_info_metabox', null, 'side', 'default');
770
- }
771
- /**
772
- * This action is documented in wp-admin/includes/meta-boxes.php
773
- * using screen id instead of post type
774
- */
775
- do_action('add_meta_boxes', $screen->id, $feedRules);
776
- do_action("add_meta_boxes_{$screen->id}", $feedRules);
777
- do_action('do_meta_boxes', $screen->id, 'normal', $feedRules);
778
- do_action('do_meta_boxes', $screen->id, 'advanced', $feedRules);
779
- do_action('do_meta_boxes', $screen->id, 'side', $feedRules);
780
- }
781
- }
782
- if ( ! function_exists('woo_feed_ajax_merchant_info') ) {
783
- add_action('wp_ajax_woo_feed_get_merchant_info', 'woo_feed_ajax_merchant_info');
784
- function woo_feed_ajax_merchant_info() {
785
- if ( isset($_REQUEST['nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_REQUEST['nonce'])),
786
- 'wpf_feed_nonce') ) {
787
- $provider = (isset($_REQUEST['provider']) && ! empty($_REQUEST['provider'])) ? sanitize_text_field(wp_unslash($_REQUEST['provider'])) : '';
788
- $merchantInfo = new Woo_Feed_Merchant($provider);
789
- $data = [];
790
- $na = esc_html__('N/A', 'woo-feed');
791
- foreach ( $merchantInfo->get_info() as $k => $v ) {
792
- if ( 'link' === $k ) {
793
- /** @noinspection HtmlUnknownTarget */
794
- $data[ $k ] = empty($v) ? $na : sprintf('<a href="%s" target="_blank">%s</a>',
795
- esc_url($v),
796
- esc_html__('Read Article', 'woo-feed'));
797
- } elseif ( 'video' === $k ) {
798
- /** @noinspection HtmlUnknownTarget */
799
- $data[ $k ] = empty($v) ? $na : sprintf('<a href="%s" target="_blank">%s</a>',
800
- esc_url($v),
801
- esc_html__('Watch Now', 'woo-feed'));
802
- } elseif ( 'feed_file_type' === $k ) {
803
- if ( ! empty($v) ) {
804
- $v = array_map(function ( $type ) {
805
- return strtoupper($type);
806
- },
807
- (array)$v);
808
- $data[ $k ] = esc_html(implode(', ', $v));
809
- } else {
810
- $data[ $k ] = $na;
811
- }
812
- } elseif ( 'doc' === $k ) {
813
- $links = '';
814
- foreach ( $v as $label => $link ) {
815
- /** @noinspection HtmlUnknownTarget */
816
- $links .= sprintf('<li><a href="%s" target="_blank">%s</a></li>',
817
- esc_url($link),
818
- esc_html($label));
819
- }
820
- $data[ $k ] = empty($links) ? $na : $links;
821
- }
822
- }
823
- wp_send_json_success($data);
824
- } else {
825
- wp_send_json_error(esc_html__('Invalid Request.', 'woo-feed'));
826
- }
827
- die();
828
- }
829
- }
830
- if ( ! function_exists('woo_feed_merchant_info_metabox') ) {
831
- /**
832
- * Render Merchant Info Metabox
833
- *
834
- * @param array $feedConfig
835
- *
836
- * @return void
837
- */
838
- function woo_feed_merchant_info_metabox( $feedConfig ) {
839
- $provider = (isset($feedConfig['provider']) && ! empty($feedConfig['provider'])) ? $feedConfig['provider'] : '';
840
- $merchantInfo = new Woo_Feed_Merchant($provider);
841
-
842
- //get feed options
843
- if ( isset($_GET['feed']) ) {
844
- $filename = str_replace('wf_feed_', '', wp_unslash($_GET['feed']));
845
- $feed_options = maybe_unserialize(get_option('wf_feed_' . $filename));
846
- }
847
- ?>
 
 
848
  <span class="spinner"></span>
849
  <div class="merchant-infos">
850
- <?php foreach ( $merchantInfo->get_info() as $k => $v ) { ?>
851
- <div class="merchant-info-section <?php echo esc_attr($k); ?>">
852
- <?php if ( 'link' === $k ) { ?>
853
  <span class="dashicons dashicons-media-document" style="color: #82878c;"
854
  aria-hidden="true"></span>
855
- <span><?php esc_html_e('Feed Specification:', 'woo-feed'); ?></span>
856
  <strong class="data">
857
- <?php
858
- /** @noinspection HtmlUnknownTarget */
859
- (empty($v)) ? esc_html_e('N/A',
860
- 'woo-feed') : printf('<a href="%s" target="_blank">%s</a>',
861
- esc_url($v),
862
- esc_html__('Read Article', 'woo-feed'));
863
- ?>
864
  </strong>
865
- <?php } elseif ( 'video' === $k ) { ?>
866
  <span class="dashicons dashicons-video-alt3" style="color: #82878c;" aria-hidden="true"></span>
867
- <span><?php esc_html_e('Video Documentation:', 'woo-feed'); ?></span>
868
  <strong class="data">
869
- <?php
870
- /** @noinspection HtmlUnknownTarget */
871
- (empty($v)) ? esc_html_e('N/A',
872
- 'woo-feed') : printf('<a href="%s" target="_blank">%s</a>',
873
- esc_url($v),
874
- esc_html__('Watch now', 'woo-feed'));
875
- ?>
876
  </strong>
877
- <?php } elseif ( 'feed_file_type' === $k ) { ?>
878
  <span class="dashicons dashicons-media-text" style="color: #82878c;"
879
- aria-hidden="true"></span> <?php esc_html_e('Supported File Types:', 'woo-feed'); ?>
880
  <strong class="data" style="display: block;padding-left: 24px;margin-top: 5px;">
881
- <?php
882
- if ( empty($v) ) {
883
- esc_html_e('N/A', 'woo-feed');
884
- } else {
885
- $v = implode(', ',
886
- array_map(function ( $type ) {
887
- return esc_html(strtoupper($type));
888
- },
889
- (array)$v));
890
- echo esc_html($v);
891
- }
892
- ?>
893
  </strong>
894
- <?php
895
- } elseif ( 'doc' === $k ) {
896
- ?>
897
  <span class="dashicons dashicons-editor-help" style="color: #82878c;" aria-hidden="true"></span>
898
- <span><?php esc_html_e('Support Docs:', 'woo-feed'); ?></span>
899
  <ul class="data">
900
- <?php
901
- if ( empty($v) ) {
902
- esc_html_e('N/A', 'woo-feed');
903
- } else {
904
- foreach ( $v as $label => $link ) {
905
- /** @noinspection HtmlUnknownTarget */
906
- printf('<li><a href="%s" target="_blank">%s</a></li>',
907
- esc_url($link),
908
- esc_html($label));
909
- }
910
- }
911
- ?>
912
  </ul>
913
- <?php
914
- }
915
- ?>
916
  </div>
917
- <?php } ?>
918
  <div class="merchant-info-section woo-feed-open-file">
919
- <?php
920
- if ( isset($feed_options['url']) && ! empty($feed_options['url']) ) {
921
- echo sprintf(
922
- '<a href="%1$s" title="%2$s" aria-label="%2$s" target="_blank"><span class="dashicons dashicons-external" aria-hidden="true"></span> %3$s</a>',
923
- $feed_options['url'],
924
- esc_html__('View', 'woo-feed'),
925
- esc_html__('Open Feed File', 'woo-feed')
926
- );
927
- }
928
- ?>
929
  </div>
930
  </div>
931
- <?php
932
- }
933
- }
934
- if ( ! function_exists('woo_feed_get_csv_delimiters') ) {
935
- /**
936
- * Get CSV/TXT/TSV Delimiters
937
- * @return array
938
- */
939
- function woo_feed_get_csv_delimiters() {
940
- return [
941
- ',' => 'Comma',
942
- ':' => 'Colon',
943
- ' ' => 'Space',
944
- '|' => 'Pipe',
945
- ';' => 'Semi Colon',
946
- "\t" => 'TAB',
947
- ];
948
- }
949
- }
950
- if ( ! function_exists('woo_feed_get_csv_enclosure') ) {
951
- /**
952
- * Get CSV/TXT/TSV Enclosure for multiple words
953
- * @return array
954
- */
955
- function woo_feed_get_csv_enclosure() {
956
- return [
957
- 'double' => '"',
958
- 'single' => '\'',
959
- ' ' => 'None',
960
- ];
961
- }
962
  }
963
 
964
  // Editor Tabs.
965
- if ( ! function_exists('render_feed_config') ) {
966
- /**
967
- * @param string $tabId
968
- * @param array $feedRules
969
- * @param bool $idEdit
970
- */
971
- function render_feed_config( $tabId, $feedRules, $idEdit ) {
972
- global $provider, $wooFeedDropDown, $merchant;
973
- include WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-edit-config.php';
974
- }
975
- }
976
- if ( ! function_exists('render_filter_config') ) {
977
- /**
978
- * @param string $tabId
979
- * @param array $feedRules
980
- * @param bool $idEdit
981
- */
982
- function render_filter_config( $tabId, $feedRules, $idEdit ) {
983
- global $provider, $wooFeedDropDown, $merchant;
984
- include WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-edit-filter.php';
985
- }
986
- }
987
- if ( ! function_exists('render_ftp_config') ) {
988
- /**
989
- * @param string $tabId
990
- * @param array $feedRules
991
- * @param bool $idEdit
992
- */
993
- function render_ftp_config( $tabId, $feedRules, $idEdit ) {
994
- global $provider, $wooFeedDropDown, $merchant;
995
- include WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-edit-ftp.php';
996
- }
997
  }
998
 
999
  // Sanitization.
1000
- if ( ! function_exists('woo_feed_check_google_category') ) {
1001
- /**
1002
- * @param array $feedInfo
1003
- *
1004
- * @return string
1005
- */
1006
- function woo_feed_check_google_category( $feedInfo ) {
1007
- // Check Google Product Category for Google & Facebook Template and show message.
1008
- $list = woo_feed_merchant_require_google_category();
1009
- $cat_keys = array_keys($list);
1010
- $merchants = call_user_func_array('array_merge', array_values($list));
1011
- $checkCategory = isset($feedInfo['feedrules']['mattributes']) ? $feedInfo['feedrules']['mattributes'] : [];
1012
- $checkCategoryType = isset($feedInfo['feedrules']['type']) ? $feedInfo['feedrules']['type'] : [];
1013
- $merchant = isset($feedInfo['feedrules']['provider']) ? $feedInfo['feedrules']['provider'] : [];
1014
- $cat = 'yes';
1015
- foreach ( $list as $attribute => $merchants ) {
1016
- if ( in_array($merchant, $merchants, true) && in_array($attribute, $checkCategory, true) ) {
1017
- $catKey = array_search($attribute, $checkCategory, true);
1018
- if ( 'pattern' === $checkCategoryType[ $catKey ] ) {
1019
- $checkCategoryValue = $feedInfo['feedrules']['default'];
1020
- } else {
1021
- $checkCategoryValue = $feedInfo['feedrules']['attributes'];
1022
- }
1023
-
1024
- if ( empty($checkCategoryValue[ $catKey ]) ) {
1025
- $cat = 'no';
1026
- }
1027
- break;
1028
- }
1029
- }
1030
-
1031
- return $cat;
1032
- }
1033
- }
1034
- if ( ! function_exists('woo_feed_array_sanitize') ) {
1035
- /**
1036
- * Sanitize array post
1037
- *
1038
- * @param array $array
1039
- *
1040
- * @return array
1041
- */
1042
- function woo_feed_array_sanitize( $array ) {
1043
- $newArray = array();
1044
- if ( count($array) ) {
1045
- foreach ( $array as $key => $value ) {
1046
- if ( is_array($value) ) {
1047
- foreach ( $value as $key2 => $value2 ) {
1048
- if ( is_array($value2) ) {
1049
- foreach ( $value2 as $key3 => $value3 ) {
1050
- $newArray[ $key ][ $key2 ][ $key3 ] = sanitize_text_field($value3);
1051
- }
1052
- } else {
1053
- $newArray[ $key ][ $key2 ] = sanitize_text_field($value2);
1054
- }
1055
- }
1056
- } else {
1057
- $newArray[ $key ] = sanitize_text_field($value);
1058
- }
1059
- }
1060
- }
1061
-
1062
- return $newArray;
1063
- }
1064
- }
1065
- if ( ! function_exists('woo_feed_sanitize_form_fields') ) {
1066
- /**
1067
- * Sanitize Form Fields ($_POST Array)
1068
- *
1069
- * @param array $data
1070
- *
1071
- * @return array
1072
- */
1073
- function woo_feed_sanitize_form_fields( $data ) {
1074
- foreach ( $data as $k => $v ) {
1075
- if ( true === apply_filters('woo_feed_sanitize_form_fields', true, $k, $v, $data) ) {
1076
- if ( is_array($v) ) {
1077
- $v = woo_feed_sanitize_form_fields($v);
1078
- } else {
1079
- // $v = sanitize_text_field( $v ); #TODO should not trim Prefix and Suffix field
1080
- }
1081
- }
1082
- $data[ $k ] = apply_filters('woo_feed_sanitize_form_field', $v, $k);
1083
- }
1084
-
1085
- return $data;
1086
- }
1087
- }
1088
- if ( ! function_exists('woo_feed_unique_feed_slug') ) {
1089
- /**
1090
- * Generate Unique slug for feed.
1091
- * This function only check database for existing feed for generating unique slug.
1092
- * Use generate_unique_feed_file_name() for complete unique slug name.
1093
- *
1094
- * @param string $slug slug for checking uniqueness.
1095
- * @param string $prefix prefix to check with. Optional.
1096
- * @param int $option_id option id. Optional option id to exclude specific option.
1097
- *
1098
- * @return string
1099
- * @see wp_unique_post_slug()
1100
- *
1101
- */
1102
- function woo_feed_unique_feed_slug( $slug, $prefix = '', $option_id = null ) {
1103
- global $wpdb;
1104
- /** @noinspection SpellCheckingInspection */
1105
- $disallowed = array( 'siteurl', 'home', 'blogname', 'blogdescription', 'users_can_register', 'admin_email' );
1106
- if ( $option_id && $option_id > 0 ) {
1107
- $checkSql = "SELECT option_name FROM $wpdb->options WHERE option_name = %s AND option_id != %d LIMIT 1";
1108
- $nameCheck = $wpdb->get_var($wpdb->prepare($checkSql, $prefix . $slug, $option_id)); // phpcs:ignore
1109
- } else {
1110
- $checkSql = "SELECT option_name FROM $wpdb->options WHERE option_name = %s LIMIT 1";
1111
- $nameCheck = $wpdb->get_var($wpdb->prepare($checkSql, $prefix . $slug)); // phpcs:ignore
1112
- }
1113
- // slug found or slug in disallowed list
1114
- if ( $nameCheck || in_array($slug, $disallowed, true) ) {
1115
- $suffix = 2;
1116
- do {
1117
- $altName = _truncate_post_slug($slug, 200 - (strlen($suffix) + 1)) . "-$suffix";
1118
- if ( $option_id && $option_id > 0 ) {
1119
- $nameCheck = $wpdb->get_var($wpdb->prepare($checkSql, $prefix . $altName, $option_id)); // phpcs:ignore
1120
- } else {
1121
- $nameCheck = $wpdb->get_var($wpdb->prepare($checkSql, $prefix . $altName)); // phpcs:ignore
1122
- }
1123
- $suffix++;
1124
- } while ( $nameCheck );
1125
- $slug = $altName;
1126
- }
1127
-
1128
- return $slug;
1129
- }
1130
- }
1131
- if ( ! function_exists('woo_feed_unique_option_name') ) {
1132
- /**
1133
- * Alias of woo_feed_unique_feed_slug
1134
- *
1135
- * @param string $slug
1136
- * @param string $prefix
1137
- * @param null $option_id
1138
- *
1139
- * @return string
1140
- * @see woo_feed_unique_feed_slug
1141
- *
1142
- * @since 3.3.8
1143
- *
1144
- */
1145
- function woo_feed_unique_option_name( $slug, $prefix = '', $option_id = null ) {
1146
- return woo_feed_unique_feed_slug($slug, $prefix, $option_id);
1147
- }
1148
- }
1149
- if ( ! function_exists('generate_unique_feed_file_name') ) {
1150
- /**
1151
- * Generate Unique file Name.
1152
- * This will insure unique slug and file name for a single feed.
1153
- *
1154
- * @param string $filename
1155
- * @param string $type
1156
- * @param string $provider
1157
- *
1158
- * @return string|string[]
1159
- */
1160
- function generate_unique_feed_file_name( $filename, $type, $provider ) {
1161
-
1162
- $feedDir = woo_feed_get_file_dir($provider, $type);
1163
- $raw_filename = sanitize_title($filename, '', 'save');
1164
- // check option name uniqueness ...
1165
- $raw_filename = woo_feed_unique_feed_slug($raw_filename, 'wf_feed_');
1166
- $raw_filename = sanitize_file_name($raw_filename . '.' . $type);
1167
- $raw_filename = wp_unique_filename($feedDir, $raw_filename);
1168
- $raw_filename = str_replace('.' . $type, '', $raw_filename);
1169
-
1170
- return -1 !== (int)$raw_filename ? $raw_filename : false;
1171
- }
1172
  }
1173
 
1174
  // File process.
1175
- if ( ! function_exists('woo_feed_check_valid_extension') ) {
1176
- /**
1177
- * Check Feed File Extension Validity
1178
- *
1179
- * @param string $extension Ext to check.
1180
- *
1181
- * @return bool
1182
- */
1183
- function woo_feed_check_valid_extension( $extension ) {
1184
- return in_array($extension, array_keys(woo_feed_get_file_types()), true);
1185
- }
1186
- }
1187
- if ( ! function_exists('woo_feed_save_feed_config_data') ) {
1188
- /**
1189
- * Sanitize And Save Feed config data (array) to db (option table)
1190
- *
1191
- * @param array $data data to be saved in db
1192
- * @param null $feed_option_name feed (file) name. optional, if empty or null name will be auto generated
1193
- * @param bool $configOnly save only wf_config or both wf_config and wf_feed_. default is only wf_config
1194
- *
1195
- * @return bool|string return false if failed to update. return filename if success
1196
- */
1197
- function woo_feed_save_feed_config_data( $data, $feed_option_name = null, $configOnly = true ) {
1198
- if ( ! is_array($data) ) {
1199
- return false;
1200
- }
1201
- if ( ! isset($data['filename'], $data['feedType'], $data['provider']) ) {
1202
- return false;
1203
- }
1204
- // unnecessary form fields to remove
1205
- $removables = [ 'closedpostboxesnonce', '_wpnonce', '_wp_http_referer', 'save_feed_config', 'edit-feed' ];
1206
- foreach ( $removables as $removable ) {
1207
- if ( isset($data[ $removable ]) ) {
1208
- unset($data[ $removable ]);
1209
- }
1210
- }
1211
- // parse rules
1212
- $data = woo_feed_parse_feed_rules($data);
1213
- // Sanitize Fields
1214
- $data = woo_feed_sanitize_form_fields($data);
1215
- if ( empty($feed_option_name) ) {
1216
- $feed_option_name = generate_unique_feed_file_name(
1217
- $data['filename'],
1218
- $data['feedType'],
1219
- $data['provider']);
1220
- } else {
1221
- $feed_option_name = woo_feed_extract_feed_option_name($feed_option_name);
1222
- }
1223
-
1224
- // get old config
1225
- $old_data = get_option('wf_config' . $feed_option_name, array());
1226
- $update = false;
1227
- $updated = false;
1228
- if ( is_array($old_data) && ! empty($old_data) ) {
1229
- $update = true;
1230
- }
1231
-
1232
- /**
1233
- * Filters feed data just before it is inserted into the database.
1234
- *
1235
- * @param array $data An array of sanitized config
1236
- * @param array $old_data An array of old feed data
1237
- * @param string $feed_option_name Option name
1238
- *
1239
- * @since 3.3.3
1240
- *
1241
- */
1242
- $data = apply_filters('woo_feed_insert_feed_data', $data, $old_data, 'wf_config' . $feed_option_name);
1243
-
1244
- if ( $update ) {
1245
- /**
1246
- * Before Updating Config to db
1247
- *
1248
- * @param array $data An array of sanitized config
1249
- * @param string $feed_option_name Option name
1250
- */
1251
- do_action('woo_feed_before_update_config', $data, 'wf_config' . $feed_option_name);
1252
- } else {
1253
- /**
1254
- * Before inserting Config to db
1255
- *
1256
- * @param array $data An array of sanitized config
1257
- * @param string $feed_option_name Option name
1258
- */
1259
- do_action('woo_feed_before_insert_config', $data, 'wf_config' . $feed_option_name);
1260
- }
1261
- $updated = ($data === $old_data);
1262
- if ( false === $updated ) {
1263
- // Store Config.
1264
- $updated = update_option('wf_config' . $feed_option_name, $data, false);
1265
- }
1266
- // update wf_feed if wp_config update ok...
1267
- if ( $updated && false === $configOnly ) {
1268
- $old_feed = maybe_unserialize(get_option('wf_feed_' . $feed_option_name));
1269
- $feed_data = array(
1270
- 'feedrules' => $data,
1271
- 'url' => woo_feed_get_file_url($feed_option_name, $data['provider'], $data['feedType']),
1272
- 'last_updated' => date('Y-m-d H:i:s', strtotime(current_time('mysql'))),
1273
- 'status' => isset($old_feed['status']) && 1 === (int)$old_feed['status'] ? 1 : 0,
1274
- // set old status or disable auto update.
1275
- );
1276
-
1277
- $saved2 = update_option('wf_feed_' . $feed_option_name, maybe_serialize($feed_data), false);
1278
- }
1279
-
1280
- if ( $update ) {
1281
- /**
1282
- * After Updating Config to db
1283
- *
1284
- * @param array $data An array of sanitized config
1285
- * @param string $feed_option_name Option name
1286
- */
1287
- do_action('woo_feed_after_update_config', $data, 'wf_config' . $feed_option_name);
1288
- } else {
1289
- /**
1290
- * After inserting Config to db
1291
- *
1292
- * @param array $data An array of sanitized config
1293
- * @param string $feed_option_name Option name
1294
- */
1295
- do_action('woo_feed_after_insert_config', $data, 'wf_config' . $feed_option_name);
1296
- }
1297
-
1298
- // return filename on success or update status
1299
- return $updated ? $feed_option_name : $updated;
1300
- }
1301
- }
1302
- if ( ! function_exists('woo_feed_extract_feed_option_name') ) {
1303
- /**
1304
- * Remove Feed Option Name Prefix and return the slug
1305
- *
1306
- * @param string $feed_option_name
1307
- *
1308
- * @return string
1309
- */
1310
- function woo_feed_extract_feed_option_name( $feed_option_name ) {
1311
- return str_replace([ 'wf_feed_', 'wf_config' ], '', $feed_option_name);
1312
- }
1313
- }
1314
- if ( ! function_exists('woo_feed_get_file_path') ) {
1315
- /**
1316
- * Get File Path for feed or the file upload path for the plugin to use.
1317
- *
1318
- * @param string $provider provider name.
1319
- * @param string $type feed file type.
1320
- *
1321
- * @return string
1322
- */
1323
- function woo_feed_get_file_path( $provider = '', $type = '' ) {
1324
- $upload_dir = wp_get_upload_dir();
1325
-
1326
- return sprintf('%s/woo-feed/%s/%s/', $upload_dir['basedir'], $provider, $type);
1327
- }
1328
- }
1329
- if ( ! function_exists('woo_feed_get_file') ) {
1330
- /**
1331
- * Get Feed File URL
1332
- *
1333
- * @param string $fileName
1334
- * @param string $provider
1335
- * @param string $type
1336
- *
1337
- * @return string
1338
- */
1339
- function woo_feed_get_file( $fileName, $provider, $type ) {
1340
- $fileName = woo_feed_extract_feed_option_name($fileName);
1341
- $path = woo_feed_get_file_path($provider, $type);
1342
-
1343
- return sprintf('%s/%s.%s', untrailingslashit($path), $fileName, $type);
1344
- }
1345
- }
1346
- if ( ! function_exists('woo_feed_get_file_url') ) {
1347
- /**
1348
- * Get Feed File URL
1349
- *
1350
- * @param string $fileName
1351
- * @param string $provider
1352
- * @param string $type
1353
- *
1354
- * @return string
1355
- */
1356
- function woo_feed_get_file_url( $fileName, $provider, $type ) {
1357
- $fileName = woo_feed_extract_feed_option_name($fileName);
1358
- $upload_dir = wp_get_upload_dir();
1359
-
1360
- return esc_url(sprintf('%s/woo-feed/%s/%s/%s.%s',
1361
- $upload_dir['baseurl'],
1362
- $provider,
1363
- $type,
1364
- $fileName,
1365
- $type));
1366
- }
1367
- }
1368
- if ( ! function_exists('woo_feed_check_feed_file') ) {
1369
- /**
1370
- * Check if feed file exists
1371
- *
1372
- * @param string $fileName
1373
- * @param string $provider
1374
- * @param string $type
1375
- *
1376
- * @return bool
1377
- */
1378
- function woo_feed_check_feed_file( $fileName, $provider, $type ) {
1379
- $upload_dir = wp_get_upload_dir();
1380
-
1381
- return file_exists(sprintf('%s/woo-feed/%s/%s/%s.%s',
1382
- $upload_dir['basedir'],
1383
- $provider,
1384
- $type,
1385
- $fileName,
1386
- $type));
1387
- }
1388
- }
1389
- if ( ! function_exists('woo_feed_get_file_dir') ) {
1390
- /**
1391
- * Get Feed Directory
1392
- *
1393
- * @param string $provider
1394
- * @param string $feedType
1395
- *
1396
- * @return string
1397
- */
1398
- function woo_feed_get_file_dir( $provider, $feedType ) {
1399
- $upload_dir = wp_get_upload_dir();
1400
-
1401
- return sprintf('%s/woo-feed/%s/%s', $upload_dir['basedir'], $provider, $feedType);
1402
- }
1403
- }
1404
- if ( ! function_exists('woo_feed_save_batch_feed_info') ) {
1405
- /**
1406
- * Save Feed Batch Chunk
1407
- *
1408
- * @param string $feedService merchant.
1409
- * @param string $type file type (ext).
1410
- * @param string|array $string data.
1411
- * @param string $fileName file name.
1412
- * @param array $info feed config.
1413
- *
1414
- * @return bool
1415
- */
1416
- function woo_feed_save_batch_feed_info( $feedService, $type, $string, $fileName, $info ) {
1417
- $ext = $type;
1418
- if ( 'csv' === $type || 'tsv' === $type || 'xls' === $type || 'json' === $type ) {
1419
- $string = wp_json_encode($string);
1420
- $ext = 'json';
1421
- }
1422
- // Save File.
1423
- $path = woo_feed_get_file_dir($feedService, $type);
1424
- $file = $path . '/' . $fileName . '.' . $ext;
1425
- $save = new Woo_Feed_Savefile();
1426
- $status = $save->saveFile($path, $file, $string);
1427
- if ( woo_feed_is_debugging_enabled() ) {
1428
- if ( $status ) {
1429
- $message = sprintf('Batch chunk file (%s) saved.', $fileName);
1430
- } else {
1431
- $message = sprintf('Unable to save batch chunk file %s.', $fileName);
1432
- }
1433
- woo_feed_log_feed_process($info['filename'], $message);
1434
- }
1435
-
1436
- return $status;
1437
- }
1438
- }
1439
- if ( ! function_exists('woo_feed_get_batch_feed_info') ) {
1440
- /**
1441
- * @param string $feedService
1442
- * @param string $type
1443
- * @param string $fileName
1444
- *
1445
- * @return bool|array|string
1446
- */
1447
- function woo_feed_get_batch_feed_info( $feedService, $type, $fileName ) {
1448
- $ext = $type;
1449
- if ( 'csv' === $type || 'tsv' === $type || 'xls' === $type || 'json' === $type ) {
1450
- $ext = 'json';
1451
- }
1452
- // Save File
1453
- $path = woo_feed_get_file_dir($feedService, $type);
1454
- $file = $path . '/' . $fileName . '.' . $ext;
1455
- if ( ! file_exists($file) ) {
1456
- return false;
1457
- }
1458
-
1459
- $data = file_get_contents($file); // phpcs:ignore
1460
-
1461
- if ( 'csv' === $type || 'tsv' === $type || 'xls' === $type || 'json' === $type ) {
1462
- $data = ($data) ? json_decode($data, true) : false;
1463
- }
1464
-
1465
- return $data;
1466
- }
1467
- }
1468
- if ( ! function_exists('woo_feed_unlink_tempFiles') ) {
1469
- /**
1470
- * Remove temporary feed files
1471
- *
1472
- * @param array $config Feed config
1473
- * @param string $fileName feed file name.
1474
- *
1475
- * @return void
1476
- */
1477
- function woo_feed_unlink_tempFiles( $config, $fileName ) {
1478
- $type = $config['feedType'];
1479
- $ext = $type;
1480
- $path = woo_feed_get_file_dir($config['provider'], $type);
1481
-
1482
- if ( 'csv' === $type || 'tsv' === $type || 'xls' === $type ) {
1483
- $ext = 'json';
1484
- }
1485
- $files = [
1486
- 'headerFile' => $path . '/' . 'wf_store_feed_header_info_' . $fileName . '.' . $ext,
1487
- 'bodyFile' => $path . '/' . 'wf_store_feed_body_info_' . $fileName . '.' . $ext,
1488
- 'footerFile' => $path . '/' . 'wf_store_feed_footer_info_' . $fileName . '.' . $ext,
1489
- ];
1490
-
1491
- woo_feed_log_feed_process($config['filename'], sprintf('Deleting Temporary Files (%s).', implode(', ', array_values($files))));
1492
- foreach ( $files as $key => $file ) {
1493
- if ( file_exists($file) ) {
1494
- unlink($file); // phpcs:ignore
1495
- }
1496
- }
1497
- }
1498
- }
1499
- if ( ! function_exists('woo_feed_delete_feed') ) {
1500
- /**
1501
- * Delete feed option and the file from uploads directory
1502
- *
1503
- * @param string|int $feed_id feed option name or ID.
1504
- *
1505
- * @return bool
1506
- */
1507
- function woo_feed_delete_feed( $feed_id ) {
1508
- global $wpdb;
1509
- if ( ! is_numeric($feed_id) ) {
1510
- $feed_name = woo_feed_extract_feed_option_name($feed_id);
1511
- } else {
1512
- $feed_data = $wpdb->get_row($wpdb->prepare("SELECT option_name FROM $wpdb->options WHERE option_id = %d", $feed_id)); // phpcs:ignore
1513
- $option_name = $feed_data->option_name;
1514
- $feed_name = woo_feed_extract_feed_option_name($feed_data->option_name);
1515
- }
1516
- $feedInfo = maybe_unserialize(get_option('wf_feed_' . $feed_name));
1517
- if ( false !== $feedInfo ) {
1518
- $feedInfo = $feedInfo['feedrules'];
1519
- } else {
1520
- $feedInfo = maybe_unserialize(get_option('wf_config' . $feed_name));
1521
- }
1522
- $deleted = false;
1523
- $file = woo_feed_get_file($feed_name, $feedInfo['provider'], $feedInfo['feedType']);
1524
- // delete any leftover
1525
- woo_feed_unlink_tempFiles($feedInfo, $feed_name);
1526
- if ( file_exists($file) ) {
1527
- // file exists in upload directory
1528
- if (unlink($file)) { // phpcs:ignore
1529
- delete_option('wf_feed_' . $feed_name);
1530
- delete_option('wf_config' . $feed_name);
1531
- $deleted = true;
1532
- }
1533
- } else {
1534
- delete_option('wf_feed_' . $feed_name);
1535
- delete_option('wf_config' . $feed_name);
1536
- $deleted = true;
1537
- }
1538
-
1539
- // Delete cron schedule.
1540
- $feed_cron_param = 'wf_config' . $feed_name;
1541
- wp_clear_scheduled_hook('woo_feed_update_single_feed', [ $feed_cron_param ]);
1542
-
1543
- return $deleted;
1544
- }
1545
  }
1546
 
1547
  // Mics..
1548
- if ( ! function_exists('woo_feed_remove_query_args') ) {
1549
- /**
1550
- * Add more items to the removable query args array...
1551
- *
1552
- * @param array $removable_query_args
1553
- *
1554
- * @return array
1555
- */
1556
- function woo_feed_remove_query_args( $removable_query_args ) {
1557
- global $plugin_page;
1558
- if ( strpos($plugin_page, 'webappick') !== false ) {
1559
- $removable_query_args[] = 'feed_created';
1560
- $removable_query_args[] = 'feed_updated';
1561
- $removable_query_args[] = 'feed_imported';
1562
- $removable_query_args[] = 'feed_regenerate';
1563
- $removable_query_args[] = 'feed_name';
1564
- $removable_query_args[] = 'link';
1565
- $removable_query_args[] = 'wpf_message';
1566
- $removable_query_args[] = 'cat';
1567
- $removable_query_args[] = 'schedule_updated';
1568
- $removable_query_args[] = 'settings_updated';
1569
- /** @noinspection SpellCheckingInspection */
1570
- $removable_query_args[] = 'WPFP_WPML_CURLANG';
1571
- }
1572
-
1573
- return $removable_query_args;
1574
- }
1575
-
1576
- add_filter('removable_query_args', 'woo_feed_remove_query_args', 10, 1);
1577
- }
1578
- if ( ! function_exists('woo_feed_usort_reorder') ) {
1579
- /**
1580
- * This checks for sorting input and sorts the data in our array accordingly.
1581
- *
1582
- * In a real-world situation involving a database, you would probably want
1583
- * to handle sorting by passing the 'orderby' and 'order' values directly
1584
- * to a custom query. The returned data will be pre-sorted, and this array
1585
- * sorting technique would be unnecessary.
1586
- *
1587
- * @param array $a first data.
1588
- *
1589
- * @param array $b second data.
1590
- *
1591
- * @return bool
1592
- */
1593
- function woo_feed_usort_reorder( $a, $b ) {
1594
- // If no sort, default to title
1595
- $orderby = ( ! empty($_REQUEST['orderby'])) ? sanitize_text_field(wp_unslash($_REQUEST['orderby'])) : 'option_name'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
1596
- // If no order, default to asc
1597
- $order = ( ! empty($_REQUEST['order'])) ? sanitize_text_field(wp_unslash($_REQUEST['order'])) : 'asc'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
1598
- $result = strcmp($a[ $orderby ], $b[ $orderby ]); // Determine sort order
1599
-
1600
- return ('asc' === $order) ? $result : -$result; // Send final sort direction to usort
1601
- }
1602
- }
1603
- if ( ! function_exists('str_replace_trim') ) {
1604
- /**
1605
- * str_replace() wrapper with trim()
1606
- *
1607
- * @param mixed $search The value being searched for, otherwise known as the needle.
1608
- * An array may be used to designate multiple needles.
1609
- * @param mixed $replace The replacement value that replaces found search values.
1610
- * An array may be used to designate multiple replacements.
1611
- * @param mixed $subject The string or array being searched and replaced on,
1612
- * otherwise known as the haystack.
1613
- * @param string $charlist [optional]
1614
- * Optionally, the stripped characters can also be specified using the charlist parameter.
1615
- * Simply list all characters that you want to be stripped.
1616
- * With this you can specify a range of characters.
1617
- *
1618
- * @return array|string
1619
- */
1620
- function str_replace_trim( $search, $replace, $subject, $charlist = " \t\n\r\0\x0B" ) {
1621
- $replaced = str_replace($search, $replace, $subject);
1622
- if ( is_array($replaced) ) {
1623
- return array_map(
1624
- function ( $item ) use ( $charlist ) {
1625
- return trim($item, $charlist);
1626
- },
1627
- $replaced
1628
- );
1629
- } else {
1630
- return trim($replaced, $charlist);
1631
- }
1632
- }
1633
  }
1634
 
1635
  if ( ! function_exists( 'woo_feed_strip_all_tags' ) ) {
1636
 
1637
- /*
1638
  * Extends wp_strip_all_tags to fix WP_Error object passing issue
1639
  *
1640
  * @param string | WP_Error $string
@@ -1642,2904 +1680,2957 @@ if ( ! function_exists( 'woo_feed_strip_all_tags' ) ) {
1642
  * @return string
1643
  * @since 4.4.19
1644
  * */
1645
- function woo_feed_strip_all_tags( $string ) {
1646
-
1647
- if ( $string instanceof WP_Error ) {
1648
- return '';
1649
- }
1650
-
1651
- return wp_strip_all_tags( $string );
1652
-
1653
- }
1654
- }
1655
-
1656
- if ( ! function_exists('woo_feed_export_config') ) {
1657
- /**
1658
- * Handle config export request
1659
- *
1660
- * @return void
1661
- * @since 3.3.10
1662
- */
1663
- function woo_feed_export_config() {
1664
- if ( isset($_REQUEST['feed'], $_REQUEST['_wpnonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_REQUEST['_wpnonce'])), 'wpf-export') ) {
1665
- $feed = sanitize_text_field(wp_unslash($_REQUEST['feed']));
1666
- $feed = woo_feed_extract_feed_option_name($feed);
1667
- if ( ! empty($feed) ) {
1668
- $feed = maybe_unserialize(get_option('wf_feed_' . $feed));
1669
- $feed = (isset($feed['feedrules']) && is_array($feed['feedrules'])) ? $feed['feedrules'] : [];
1670
- }
1671
- if ( ! is_array($feed) ) {
1672
- wp_die(esc_html__('Invalid Request', 'woo-feed'), esc_html__('Invalid Request', 'woo-feed'), [ 'back_link' => true ]);
1673
- }
1674
- $file_name = sprintf(
1675
- '%s-%s-%s.wpf',
1676
- sanitize_title($feed['filename']),
1677
- $feed['provider'],
1678
- time()
1679
- );
1680
- $feed = wp_json_encode($feed);
1681
- $meta = wp_json_encode([
1682
- 'version' => WOO_FEED_FREE_VERSION,
1683
- 'file_name' => $file_name,
1684
- 'hash' => md5($feed),
1685
- ]);
1686
- $bin = pack('VA*VA*', strlen($meta), $meta, strlen($feed), $feed);
1687
- $feed = gzdeflate($bin, 9);
1688
- // Let set the header...
1689
- if ( ! headers_sent() ) {
1690
- status_header(200);
1691
- header('Content-Type: application/octet-stream;');
1692
- header('Content-disposition: attachment; filename=' . $file_name);
1693
- header('Content-Length: ' . strlen($feed));
1694
- header('Pragma: no-cache');
1695
- header('Expires: 0');
1696
- }
1697
- // exporting data.
1698
- echo $feed; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1699
- } else {
1700
- wp_die(
1701
- esc_html__('Invalid Request', 'woo-feed'),
1702
- esc_html__('Invalid Request', 'woo-feed'),
1703
- [ 'back_link' => true ]
1704
- );
1705
- }
1706
- }
1707
- }
1708
- if ( ! function_exists('woo_feed_import_config') ) {
1709
- /**
1710
- * Handle config import request
1711
- *
1712
- * @return void
1713
- * @since 3.3.10
1714
- */
1715
- function woo_feed_import_config() {
1716
- check_admin_referer('wpf_import');
1717
- $wpf_import_file = isset($_FILES['wpf_import_file']) ? $_FILES['wpf_import_file'] : '';
1718
- $wpf_import_feed_name = CTXFEED_filter_securing_input_cb("POST", @$_FILES['wpf_import_feed_name'], "file_name" );
1719
- $wpf_import_file_name = CTXFEED_filter_securing_input_cb("POST", @$_FILES['wpf_import_file']['name'], "file_name" );
1720
- $wpf_import_file_tmp_name = CTXFEED_filter_securing_input_cb("POST", @$_FILES['wpf_import_file']['tmp_name'], "file_name" );
1721
-
1722
- if (
1723
- $wpf_import_file &&
1724
- $wpf_import_feed_name &&
1725
- $wpf_import_file_name &&
1726
- $wpf_import_file_tmp_name &&
1727
- 'wpf' === pathinfo(wp_unslash($wpf_import_file_name), PATHINFO_EXTENSION) // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1728
- ) {
1729
- $file_name = sanitize_file_name( sanitize_text_field(wp_unslash( $wpf_import_file_name )));
1730
- $data = file_get_contents(sanitize_text_field(wp_unslash( $wpf_import_file_tmp_name)));
1731
- if ( empty($data) ) {
1732
- wp_die(
1733
- esc_html__('Empty File Uploaded. Try again.', 'woo-feed'),
1734
- esc_html__('Empty File', 'woo-feed'),
1735
- [
1736
- 'link_url' => esc_url(admin_url('admin.php?page=webappick-manage-feeds')),
1737
- 'link_text' => esc_html__('&laquo; Back', 'woo-feed'),
1738
- ]
1739
- );
1740
- }
1741
- $feed = gzinflate($data);
1742
- if ( false === $feed ) {
1743
- wp_die(
1744
- esc_html__('Unable to read file content', 'woo-feed'),
1745
- esc_html__('Invalid File', 'woo-feed'),
1746
- [
1747
- 'link_url' => esc_url(admin_url('admin.php?page=webappick-manage-feeds')),
1748
- 'link_text' => esc_html__('&laquo; Back', 'woo-feed'),
1749
- ]
1750
- );
1751
- }
1752
- // unpack meta data.
1753
- $meta_length = unpack('V', $feed);
1754
- if ( false === $meta_length ) {
1755
- wp_die(
1756
- esc_html__('Unable to read data from file.', 'woo-feed'),
1757
- esc_html__('Invalid File', 'woo-feed'),
1758
- [
1759
- 'link_url' => esc_url(admin_url('admin.php?page=webappick-manage-feeds')),
1760
- 'link_text' => esc_html__('&laquo; Back', 'woo-feed'),
1761
- ]
1762
- );
1763
- }
1764
- $meta = unpack('A*', substr($feed, 4, $meta_length[1]))[1];
1765
- if ( false === $meta || 0 !== strpos($meta, '{') ) {
1766
- wp_die(
1767
- esc_html__('Unable to read file info.', 'woo-feed'),
1768
- esc_html__('Invalid File', 'woo-feed'),
1769
- [
1770
- 'link_url' => esc_url(admin_url('admin.php?page=webappick-manage-feeds')),
1771
- 'link_text' => esc_html__('&laquo; Back', 'woo-feed'),
1772
- ]
1773
- );
1774
- }
1775
- $meta = json_decode($meta, true);
1776
- // unpack feed data.
1777
- $feed = substr($feed, $meta_length[1] + 8); // 4 bytes for each V (length data)
1778
- $feed = unpack('A*', $feed)[1];
1779
- if ( false === $feed || 0 !== strpos($feed, '{') ) {
1780
- wp_die(
1781
- esc_html__('Unable to read feed data from file.', 'woo-feed'),
1782
- esc_html__('Invalid File', 'woo-feed'),
1783
- [
1784
- 'link_url' => esc_url(admin_url('admin.php?page=webappick-manage-feeds')),
1785
- 'link_text' => esc_html__('&laquo; Back', 'woo-feed'),
1786
- ]
1787
- );
1788
- }
1789
- if ( md5($feed) !== $meta['hash'] ) {
1790
- wp_die(
1791
- esc_html__('Unable to verify the file.', 'woo-feed'),
1792
- esc_html__('Invalid File', 'woo-feed'),
1793
- [
1794
- 'link_url' => esc_url(admin_url('admin.php?page=webappick-manage-feeds')),
1795
- 'link_text' => esc_html__('&laquo; Back', 'woo-feed'),
1796
- ]
1797
- );
1798
- }
1799
-
1800
- $feed = json_decode($feed, true);
1801
- if ( ! is_array($feed) ) {
1802
- wp_die(
1803
- esc_html__('Invalid or corrupted config file.', 'woo-feed'),
1804
- esc_html__('Invalid File', 'woo-feed'),
1805
- [
1806
- 'link_url' => esc_url(admin_url('admin.php?page=webappick-manage-feeds')),
1807
- 'link_text' => esc_html__('&laquo; Back', 'woo-feed'),
1808
- ]
1809
- );
1810
- }
1811
-
1812
- $feed = woo_feed_parse_feed_rules($feed);
1813
- $new_name = sanitize_text_field(wp_unslash($_POST['wpf_import_feed_name']));
1814
- $new_name = trim($new_name);
1815
- if ( ! empty($new_name) ) {
1816
- $opt_name = $new_name;
1817
- $feed['filename'] = $new_name;
1818
- } else {
1819
- $opt_name = $feed['filename'];
1820
- $feed['filename'] = str_replace_trim([ '-', '_' ], ' ', $feed['filename']);
1821
- $feed['filename'] = sprintf(
1822
- '%s: %s',
1823
- esc_html__(' Imported', 'woo-feed'),
1824
- ucwords($feed['filename'])
1825
- );
1826
- }
1827
- // New Slug.
1828
- $opt_name = generate_unique_feed_file_name($opt_name,
1829
- $feed['feedType'],
1830
- $feed['provider']);
1831
- // save config.
1832
- $fileName = woo_feed_save_feed_config_data($feed, $opt_name, false);
1833
- // Redirect back to the list.
1834
- wp_safe_redirect(
1835
- add_query_arg(
1836
- [
1837
- 'feed_imported' => (int)false !== $fileName,
1838
- 'feed_regenerate' => 1,
1839
- 'feed_name' => $fileName ? $fileName : '',
1840
- ],
1841
- esc_url(admin_url('admin.php?page=webappick-manage-feeds'))
1842
- )
1843
- );
1844
- die();
1845
- }
1846
- wp_die(
1847
- esc_html__('Invalid Request.', 'woo-feed'),
1848
- esc_html__('Invalid Request', 'woo-feed'),
1849
- [
1850
- 'link_url' => esc_url(admin_url('admin.php?page=webappick-manage-feeds')),
1851
- 'link_text' => esc_html__('&laquo; Back', 'woo-feed'),
1852
- ]
1853
- );
1854
- }
1855
- }
1856
-
1857
- if ( ! function_exists('woo_feed_download_feed_log') ) {
1858
-
1859
- /**
1860
- * Handle latest log download request
1861
- *
1862
- * @return void
1863
- * @since 4.4.15
1864
- */
1865
- function woo_feed_download_feed_log() {
1866
- if (
1867
- isset( $_REQUEST['feed'], $_REQUEST['_wpnonce'] )
1868
- && wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) ), 'wpf-log-download')
1869
- ) {
1870
- $feed_name = sanitize_text_field(wp_unslash($_REQUEST['feed']));
1871
- $feed_name = str_replace( 'wf_feed_', '', $feed_name );
1872
- $log_file_path = Woo_Feed_Log_Handler_File::get_log_file_path( $feed_name );
1873
-
1874
- if ( $log_file_path && file_exists( $log_file_path ) ) {
1875
- $log_data = file_get_contents( $log_file_path );
1876
- } else {
1877
- $log_data = 'No log is generated.';
1878
- }
1879
-
1880
- if ( ! empty($feed_name) ) {
1881
- $feed_details = maybe_unserialize(get_option('wf_feed_' . $feed_name));
1882
- $feed_details = (isset($feed['feedrules']) && is_array($feed['feedrules'])) ? $feed['feedrules'] : [];
1883
- }
1884
-
1885
- if ( ! is_array($feed_details) ) {
1886
- wp_die(esc_html__('Invalid Request', 'woo-feed'), esc_html__('Invalid Request', 'woo-feed'), [ 'back_link' => true ]);
1887
- }
1888
-
1889
- $file_name = sprintf(
1890
- '%s-%s-%s.log',
1891
- sanitize_title($feed_name),
1892
- gmdate( 'Y-m-d', time() ),
1893
- time()
1894
- );
1895
-
1896
- // Let set the header...
1897
- if ( ! headers_sent() ) {
1898
- status_header(200);
1899
- header('Content-Type: application/octet-stream;');
1900
- header('Content-disposition: attachment; filename=' . $file_name);
1901
- header('Content-Length: ' . strlen($log_data));
1902
- header('Pragma: no-cache');
1903
- header('Expires: 0');
1904
- }
1905
-
1906
- // exporting data.
1907
- echo $log_data; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1908
- } else {
1909
- wp_die(
1910
- esc_html__('Invalid Request', 'woo-feed'),
1911
- esc_html__('Invalid Request', 'woo-feed'),
1912
- [ 'back_link' => true ]
1913
- );
1914
- }
1915
- }
1916
  }
1917
 
1918
  // Feed Functions.
1919
- if ( ! function_exists('woo_feed_generate_feed') ) {
1920
- /**
1921
- * Update Feed Information
1922
- *
1923
- * @param array $info feed config array
1924
- * @param string $feed_option_name feed option/file name
1925
- *
1926
- * @return string|bool
1927
- */
1928
- function woo_feed_generate_feed( $info, $feed_option_name ) {
1929
- if ( false === $info || empty($info) ) {
1930
- return false;
1931
- }
1932
- // parse rules.
1933
- $info = woo_feed_parse_feed_rules(isset($info['feedrules']) ? $info['feedrules'] : $info);
1934
- $feed_option_name = woo_feed_extract_feed_option_name($feed_option_name);
1935
- if ( ! empty($info['provider']) ) {
1936
- do_action('before_woo_feed_generate_feed', $info);
1937
-
1938
- // Generate Feed Data
1939
- if ( isset( $info['provider'] ) && 'googlereview' === $info['provider'] ) {
1940
- $reviewObj = new Woo_Feed_Review($info);
1941
- $feedBody = $reviewObj->make_review_xml_feed();
1942
- $string = $feedBody;
1943
-
1944
- } else {
1945
- $products = new Woo_Generate_Feed($info['provider'], $info);
1946
- $getString = $products->getProducts();
1947
- if ( 'csv' == $info['feedType'] || 'tsv' == $info['feedType'] || 'xls' == $info['feedType'] ) {
1948
- $csvHead[0] = $getString['header'];
1949
- if ( ! empty($csvHead) && ! empty($getString['body']) ) {
1950
- $string = array_merge($csvHead, $getString['body']);
1951
- } else {
1952
- $string = array();
1953
- }
1954
- } else {
1955
- if ( 'json' == $info['feedType'] ) {
1956
- $string = array();
1957
- } else {
1958
- $string = $getString['header'] . $getString['body'] . $getString['footer'];
1959
- }
1960
- }
1961
- }
1962
-
1963
- $saveFile = false;
1964
- // Check If any products founds
1965
- if ( $string && ! empty($string) ) {
1966
- // Save File
1967
- $path = woo_feed_get_file_path($info['provider'], $info['feedType']);
1968
- $file = woo_feed_get_file($feed_option_name, $info['provider'], $info['feedType']);
1969
- $save = new Woo_Feed_Savefile();
1970
- if ( 'csv' == $info['feedType'] || 'tsv' == $info['feedType'] || 'xls' == $info['feedType'] || 'json' == $info['feedType'] ) {
1971
- $saveFile = $save->saveValueFile($path, $file, $string, $info, $info['feedType']);
1972
- } else {
1973
- $saveFile = $save->saveFile($path, $file, $string);
1974
- }
1975
-
1976
- // Upload file to ftp server
1977
- if ( 1 == (int)$info['ftpenabled'] ) {
1978
- woo_feed_handle_file_transfer($file, $feed_option_name . '.' . $info['feedType'], $info);
1979
- }
1980
- }
1981
- $feed_URL = woo_feed_get_file_url($feed_option_name, $info['provider'], $info['feedType']);
1982
- // Save Info into database
1983
- $feedInfo = array(
1984
- 'feedrules' => $info,
1985
- 'url' => $feed_URL,
1986
- 'last_updated' => date('Y-m-d H:i:s', strtotime(current_time('mysql'))),
1987
- 'status' => 1,
1988
- );
1989
- update_option('wf_feed_' . $feed_option_name, serialize($feedInfo), false); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize
1990
- do_action('after_woo_feed_generate_feed', $info);
1991
- if ( $saveFile ) {
1992
- return $feed_URL;
1993
- } else {
1994
- return false;
1995
- }
1996
- }
1997
-
1998
- return false;
1999
- }
2000
- }
2001
-
2002
- if ( ! function_exists('woo_feed_get_schedule_interval_options') ) {
2003
- /**
2004
- * Get Schedule Intervals
2005
- * @return mixed
2006
- */
2007
- function woo_feed_get_schedule_interval_options() {
2008
- return apply_filters(
2009
- 'woo_feed_schedule_interval_options',
2010
- [
2011
- WEEK_IN_SECONDS => esc_html__('1 Week', 'woo-feed'),
2012
- DAY_IN_SECONDS => esc_html__('24 Hours', 'woo-feed'),
2013
- 12 * HOUR_IN_SECONDS => esc_html__('12 Hours', 'woo-feed'),
2014
- 6 * HOUR_IN_SECONDS => esc_html__('6 Hours', 'woo-feed'),
2015
- HOUR_IN_SECONDS => esc_html__('1 Hours', 'woo-feed'),
2016
- ]
2017
- );
2018
- }
2019
- }
2020
- if ( ! function_exists('woo_feed_get_minimum_interval_option') ) {
2021
- function woo_feed_get_minimum_interval_option() {
2022
- $intervals = array_keys(woo_feed_get_schedule_interval_options());
2023
- if ( ! empty($intervals) ) {
2024
- return end($intervals);
2025
- }
2026
-
2027
- return 15 * MINUTE_IN_SECONDS;
2028
- }
2029
- }
2030
- if ( ! function_exists('woo_feed_stripInvalidXml') ) {
2031
- /**
2032
- * Remove non supported xml character
2033
- *
2034
- * @param string $value
2035
- *
2036
- * @return string
2037
- */
2038
- function woo_feed_stripInvalidXml( $value ) {
2039
- $ret = '';
2040
- if ( empty($value) ) {
2041
- return $ret;
2042
- }
2043
- $length = strlen($value);
2044
- for ( $i = 0; $i < $length; $i++ ) {
2045
- $current = ord($value[ $i ]);
2046
- if ( (0x9 == $current) || (0xA == $current) || (0xD == $current) || (($current >= 0x20) && ($current <= 0xD7FF)) || (($current >= 0xE000) && ($current <= 0xFFFD)) || (($current >= 0x10000) && ($current <= 0x10FFFF)) ) {
2047
- $ret .= chr($current);
2048
- } else {
2049
- $ret .= '';
2050
- }
2051
- }
2052
-
2053
- return $ret;
2054
- }
2055
- }
2056
- if ( ! function_exists('woo_feed_get_formatted_url') ) {
2057
- /**
2058
- * Get Formatted URL
2059
- *
2060
- * @param string $url
2061
- *
2062
- * @return string
2063
- */
2064
- function woo_feed_get_formatted_url( $url = '' ) {
2065
- if ( ! empty($url) ) {
2066
- if ( substr(trim($url), 0, 4) === 'http' || substr(trim($url),
2067
- 0,
2068
- 3) === 'ftp' || substr(trim($url), 0, 4) === 'sftp' ) {
2069
- return rtrim($url, '/');
2070
- } else {
2071
- $base = get_site_url();
2072
- $url = $base . $url;
2073
-
2074
- return rtrim($url, '/');
2075
- }
2076
- }
2077
-
2078
- return '';
2079
- }
2080
- }
2081
- if ( ! function_exists('array_value_first') ) {
2082
- /**
2083
- * Get First Value of an array
2084
- *
2085
- * @param array $arr
2086
- *
2087
- * @return mixed|null
2088
- * @since 3.0.0
2089
- */
2090
- function array_value_first( array $arr ) {
2091
- foreach ( $arr as $key => $unused ) {
2092
- return $unused;
2093
- }
2094
-
2095
- return null;
2096
- }
2097
- }
2098
- if ( ! function_exists('woo_feed_make_url_with_parameter') ) {
2099
- /**
2100
- * Make proper URL using parameters
2101
- *
2102
- * @param string $output
2103
- * @param string $suffix
2104
- *
2105
- * @return string
2106
- */
2107
- function woo_feed_make_url_with_parameter( $output = '', $suffix = '' ) {
2108
- if ( empty($output) || empty($suffix) ) {
2109
- return $output;
2110
- }
2111
-
2112
- $getParam = explode('?', $output);
2113
- $URLParam = array();
2114
- if ( isset($getParam[1]) ) {
2115
- $URLParam = woo_feed_parse_string($getParam[1]);
2116
- }
2117
-
2118
- $EXTRAParam = array();
2119
- if ( ! empty($suffix) ) {
2120
- $suffix = str_replace('?', '', $suffix);
2121
- $EXTRAParam = woo_feed_parse_string($suffix);
2122
- }
2123
-
2124
- $params = array_merge($URLParam, $EXTRAParam);
2125
- if ( ! empty($params) && '' != $output ) {
2126
- $params = http_build_query($params);
2127
- $baseURL = isset($getParam) ? $getParam[0] : $output;
2128
- $output = $baseURL . '?' . $params;
2129
- }
2130
-
2131
- return $output;
2132
- }
2133
- }
2134
- if ( ! function_exists('woo_feed_parse_string') ) {
2135
- /**
2136
- * Parse URL parameter
2137
- *
2138
- * @param string $str
2139
- *
2140
- * @return array
2141
- */
2142
- function woo_feed_parse_string( $str = '' ) {
2143
-
2144
- // result array
2145
- $arr = array();
2146
-
2147
- if ( empty($str) ) {
2148
- return $arr;
2149
- }
2150
-
2151
- // split on outer delimiter
2152
- $pairs = explode('&', $str);
2153
-
2154
- if ( ! empty($pairs) && is_array($pairs) ) {
2155
-
2156
- // loop through each pair
2157
- foreach ( $pairs as $i ) {
2158
- // split into name and value
2159
- list($name, $value) = explode('=', $i, 2);
2160
-
2161
- // if name already exists
2162
- if ( isset($arr[ $name ]) ) {
2163
- // stick multiple values into an array
2164
- if ( is_array($arr[ $name ]) ) {
2165
- $arr[ $name ][] = $value;
2166
- } else {
2167
- $arr[ $name ] = array( $arr[ $name ], $value );
2168
- }
2169
- } // otherwise, simply stick it in a scalar
2170
- else {
2171
- $arr[ $name ] = $value;
2172
- }
2173
- }
2174
- } elseif ( ! empty($str) ) {
2175
- list($name, $value) = explode('=', $str, 2);
2176
- $arr[ $name ] = $value;
2177
- }
2178
-
2179
- // return result array
2180
- return $arr;
2181
- }
2182
- }
2183
- if ( ! function_exists('woo_feed_replace_to_merchant_attribute') ) {
2184
- /**
2185
- * Parse URL parameter
2186
- *
2187
- * @param string $pluginAttribute
2188
- * @param string $merchant
2189
- * @param string feedType CSV XML TXT
2190
- *
2191
- * @return string
2192
- */
2193
- function woo_feed_replace_to_merchant_attribute( $pluginAttribute, $merchant, $feedType ) {
2194
- $attributeClass = new Woo_Feed_Default_Attributes();
2195
- $merchantAttributes = '';
2196
- if ( 'google' === $merchant
2197
- || 'google_shopping_action' === $merchant
2198
- || 'google_local' === $merchant
2199
- || 'google_local_inventory' === $merchant
2200
- || 'adroll' == $merchant
2201
- || 'smartly.io' == $merchant ) {
2202
- if ( 'xml' === $feedType ) {
2203
- $g_attributes = $attributeClass->googleXMLAttribute;
2204
- if ( 'google_local' === $merchant ) {
2205
- unset($g_attributes['description']);
2206
- }
2207
- $merchantAttributes = $g_attributes;
2208
- } elseif ( 'csv' == $feedType || 'txt' == $feedType ) {
2209
- $merchantAttributes = $attributeClass->googleCSVTXTAttribute;
2210
- }
2211
- } elseif ( 'facebook' == $merchant ) {
2212
- if ( 'xml' == $feedType ) {
2213
- $merchantAttributes = $attributeClass->facebookXMLAttribute;
2214
- } elseif ( 'csv' == $feedType || 'txt' == $feedType ) {
2215
- $merchantAttributes = $attributeClass->facebookCSVTXTAttribute;
2216
- }
2217
- } elseif ( 'pinterest' == $merchant ) {
2218
- if ( 'xml' == $feedType ) {
2219
- $merchantAttributes = $attributeClass->pinterestXMLAttribute;
2220
- } elseif ( 'csv' == $feedType || 'txt' == $feedType ) {
2221
- $merchantAttributes = $attributeClass->pinterestCSVTXTAttribute;
2222
- }
2223
- } elseif ( 'skroutz' == $merchant ) {
2224
- if ( 'xml' == $feedType ) {
2225
- $merchantAttributes = $attributeClass->skroutzXMLAttributes;
2226
- }
2227
- }
2228
-
2229
- if ( ! empty($merchantAttributes) && array_key_exists($pluginAttribute, $merchantAttributes) ) {
2230
- return $merchantAttributes[ $pluginAttribute ][0];
2231
- }
2232
-
2233
- return $pluginAttribute;
2234
- }
2235
- }
2236
- if ( ! function_exists('woo_feed_add_cdata') ) {
2237
- /**
2238
- * Parse URL parameter
2239
- *
2240
- * @param string $pluginAttribute
2241
- * @param string $attributeValue
2242
- * @param string $merchant
2243
- * @param string $feed_type
2244
- *
2245
- * @return string
2246
- */
2247
- function woo_feed_add_cdata( $pluginAttribute, $attributeValue, $merchant, $feed_type ) {
2248
- if ( "xml" !== $feed_type ) {
2249
- return "$attributeValue";
2250
- }
2251
-
2252
- if ( 'custom' === $merchant ) {
2253
- return "$attributeValue";
2254
- }
2255
-
2256
- if ( "shipping" === $pluginAttribute || "tax" === $pluginAttribute ) {
2257
- return "$attributeValue";
2258
- }
2259
-
2260
- if ( strpos($attributeValue, '<![CDATA[') !== false ) {
2261
- return "$attributeValue";
2262
- }
2263
-
2264
- $attributeClass = new Woo_Feed_Default_Attributes();
2265
- $merchantAttributes = '';
2266
- if ( 'google' == $merchant ) {
2267
- $merchantAttributes = $attributeClass->googleXMLAttribute;
2268
- } elseif ( 'facebook' == $merchant ) {
2269
- $merchantAttributes = $attributeClass->facebookXMLAttribute;
2270
- } elseif ( 'pinterest' == $merchant ) {
2271
- $merchantAttributes = $attributeClass->pinterestXMLAttribute;
2272
- } elseif ( 'skroutz' == $merchant ) {
2273
- $merchantAttributes = $attributeClass->skroutzXMLAttributes;
2274
- }
2275
-
2276
- if ( ! empty($merchantAttributes) && array_key_exists($pluginAttribute, $merchantAttributes) ) {
2277
- if ( 'true' == $merchantAttributes[ $pluginAttribute ][1] ) {
2278
- return "<![CDATA[$attributeValue]]>";
2279
- } else {
2280
- return "$attributeValue";
2281
- }
2282
- } elseif ( false !== strpos($attributeValue, '&') || 'http' == substr(trim($attributeValue), 0, 4) ) {
2283
- if ( 'catch.com.au' === $merchant ) {
2284
- if ( false !== strpos($pluginAttribute, 'image') ) {
2285
- return "$attributeValue";
2286
- }
2287
- } else {
2288
- return "<![CDATA[ $attributeValue ]]>";
2289
  // return "$attributeValue";
2290
- }
2291
- } else {
2292
- return "$attributeValue";
2293
- }
2294
- return "$attributeValue";
2295
- }
 
2296
  }
2297
 
2298
  // WooFeed Settings API
2299
- if ( ! function_exists('woo_feed_get_options') ) {
2300
- /**
2301
- * Get saved settings.
2302
- *
2303
- * @param string $key Option name.
2304
- * All default values will be returned if this set to 'defaults',
2305
- * all settings will be return if set to 'all'.
2306
- * @param bool $default value to return if no matching data found for the key (option)
2307
- *
2308
- * @return array|bool|string|mixed
2309
- * @since 3.3.11
2310
- */
2311
- function woo_feed_get_options( $key, $default = false ) {
2312
- $defaults = [
2313
- 'per_batch' => 200,
2314
- 'product_query_type' => 'wc',
2315
- 'variation_query_type' => 'individual',
2316
- 'enable_error_debugging' => 'off',
2317
- 'cache_ttl' => 6 * HOUR_IN_SECONDS,
2318
- 'overridden_structured_data' => 'off',
2319
- 'disable_mpn' => 'enable',
2320
- 'disable_brand' => 'enable',
2321
- 'disable_pixel' => 'enable',
2322
- 'pixel_id' => '',
2323
- 'disable_remarketing' => 'disable',
2324
- 'remarketing_id' => '',
2325
- 'remarketing_label' => '',
2326
- 'allow_all_shipping' => 'no',
2327
- 'only_free_shipping' => 'yes',
2328
- 'only_local_pickup_shipping' => 'no',
2329
- 'enable_ftp_upload' => 'no',
2330
- 'woo_feed_taxonomy' => array(
2331
- 'brand' => 'disable',
2332
- ),
2333
- 'woo_feed_identifier' => array(
2334
- 'gtin' => 'disable',
2335
- 'ean' => 'disable',
2336
- 'mpn' => 'disable',
2337
- 'isbn' => 'disable',
2338
- 'age_group' => 'disable',
2339
- 'material' => 'disable',
2340
- 'gender' => 'disable',
2341
- 'cost_of_good_sold' => 'disable',
2342
- 'availability_date' => 'enable',
2343
- 'unit' => 'disable',
2344
- 'unit_pricing_measure' => 'disable',
2345
- 'unit_pricing_base_measure' => 'disable',
2346
- 'custom_field_0' => 'disable',
2347
- 'custom_field_1' => 'disable',
2348
- 'custom_field_2' => 'disable',
2349
- 'custom_field_3' => 'disable',
2350
- 'custom_field_4' => 'disable',
2351
- ),
2352
- ];
2353
-
2354
- /**
2355
- * Add defaults without chainging the core values.
2356
- *
2357
- * @param array $defaults
2358
- *
2359
- * @since 3.3.11
2360
- */
2361
- $defaults = wp_parse_args(apply_filters('woo_feed_settings_extra_defaults', []), $defaults);
2362
-
2363
- if ( 'defaults' === $key ) {
2364
- return $defaults;
2365
- }
2366
-
2367
- $settings = wp_parse_args(get_option('woo_feed_settings', []), $defaults);
2368
-
2369
- if ( 'all' === $key ) {
2370
- return $settings;
2371
- }
2372
-
2373
- if ( array_key_exists($key, $settings) ) {
2374
- return $settings[ $key ];
2375
- }
2376
-
2377
- return $default;
2378
- }
2379
- }
2380
- if ( ! function_exists('woo_feed_save_options') ) {
2381
- /**
2382
- * Save Settings.
2383
- *
2384
- * @param array $args Required. option key value paired array to save.
2385
- *
2386
- * @return bool
2387
- * @since 3.3.11
2388
- */
2389
- function woo_feed_save_options( $args ) {
2390
- $data = woo_feed_get_options('all');
2391
- $defaults = woo_feed_get_options('defaults');
2392
- $_data = $data;
2393
-
2394
- if ( array_key_exists('per_batch', $args) ) {
2395
- $data['per_batch'] = absint($args['per_batch']);
2396
- if ( $data['per_batch'] <= 0 ) {
2397
- $data['per_batch'] = $_data['per_batch'] > 0 ? $_data['per_batch'] : $defaults['per_batch'];
2398
- }
2399
- unset($args['unset']);
2400
- }
2401
- if ( array_key_exists('product_query_type', $args) ) {
2402
- $data['product_query_type'] = strtolower($args['product_query_type']);
2403
- $query_types = array_keys(woo_feed_get_query_type_options());
2404
- if ( ! in_array($data['product_query_type'], $query_types) ) {
2405
- $data['product_query_type'] = in_array($_data['product_query_type'], $query_types) ? $_data['product_query_type'] : $defaults['product_query_type'];
2406
- }
2407
- unset($args['product_query_type']);
2408
- }
2409
- if ( array_key_exists('variation_query_type', $args) ) {
2410
- $data['variation_query_type'] = strtolower($args['variation_query_type']);
2411
- $query_types = array_keys(woo_feed_get_query_type_options('variation'));
2412
- if ( ! in_array($data['variation_query_type'], $query_types, true) ) {
2413
- $data['variation_query_type'] = in_array($_data['variation_query_type'], $query_types, true) ? $_data['variation_query_type'] : $defaults['variation_query_type'];
2414
- }
2415
- unset($args['variation_query_type']);
2416
- }
2417
- if ( array_key_exists('enable_error_debugging', $args) ) {
2418
- $data['enable_error_debugging'] = strtolower($args['enable_error_debugging']);
2419
- if ( ! in_array($data['enable_error_debugging'], [ 'on', 'off' ]) ) {
2420
- $data['enable_error_debugging'] = in_array($_data['enable_error_debugging'], [ 'on', 'off' ]) ? $_data['enable_error_debugging'] : $defaults['enable_error_debugging'];
2421
- }
2422
- unset($args['enable_error_debugging']);
2423
- }
2424
- if ( array_key_exists('cache_ttl', $args) ) {
2425
- $data['cache_ttl'] = absint($args['cache_ttl']); // cache ttl can be zero.
2426
- unset($args['cache_ttl']);
2427
- }
2428
- if ( array_key_exists('overridden_structured_data', $args) ) {
2429
- $data['overridden_structured_data'] = strtolower($args['overridden_structured_data']);
2430
- if ( ! in_array($data['overridden_structured_data'], array( 'on', 'off' )) ) {
2431
- $data['overridden_structured_data'] = in_array($_data['overridden_structured_data'], array( 'on', 'off' )) ? $_data['overridden_structured_data'] : $defaults['overridden_structured_data'];
2432
- }
2433
- unset($args['overridden_structured_data']);
2434
- }
2435
-
2436
- if ( array_key_exists('disable_pixel', $args) ) {
2437
- $data['disable_pixel'] = strtolower($args['disable_pixel']);
2438
- if ( ! in_array($data['disable_pixel'], array( 'enable', 'disable' )) ) {
2439
- $data['disable_pixel'] = in_array($_data['disable_pixel'], array( 'enable', 'disable' )) ? $_data['disable_pixel'] : $defaults['disable_pixel'];
2440
- }
2441
- unset($args['disable_pixel']);
2442
- }
2443
- if ( array_key_exists('pixel_id', $args) ) {
2444
- if ( isset($args['pixel_id']) && ! empty($args['pixel_id']) ) {
2445
- $data['pixel_id'] = absint($args['pixel_id']);
2446
- } else {
2447
- $data['pixel_id'] = $defaults['pixel_id'];
2448
- }
2449
- unset($args['pixel_id']);
2450
- }
2451
-
2452
- if ( array_key_exists('disable_remarketing', $args) ) {
2453
- $data['disable_remarketing'] = strtolower($args['disable_remarketing']);
2454
- if ( ! in_array($data['disable_remarketing'], array( 'enable', 'disable' )) ) {
2455
- $data['disable_remarketing'] = in_array($_data['disable_remarketing'], array( 'enable', 'disable' )) ? $_data['disable_remarketing'] : $defaults['disable_remarketing'];
2456
- }
2457
- unset($args['disable_remarketing']);
2458
- }
2459
- if ( array_key_exists('remarketing_id', $args) ) {
2460
- if ( isset($args['remarketing_id']) && ! empty($args['remarketing_id']) ) {
2461
- $data['remarketing_id'] = $args['remarketing_id'];
2462
- } else {
2463
- $data['remarketing_id'] = $defaults['remarketing_id'];
2464
- }
2465
- unset($args['remarketing_id']);
2466
- }
2467
- if ( array_key_exists('remarketing_label', $args) ) {
2468
- if ( isset($args['remarketing_label']) && ! empty($args['remarketing_label']) ) {
2469
- $data['remarketing_label'] = $args['remarketing_label'];
2470
- } else {
2471
- $data['remarketing_label'] = $defaults['remarketing_label'];
2472
- }
2473
- unset($args['remarketing_label']);
2474
- }
2475
-
2476
- if ( array_key_exists('allow_all_shipping', $args) ) {
2477
- $data['allow_all_shipping'] = strtolower($args['allow_all_shipping']);
2478
- if ( ! in_array($data['allow_all_shipping'], array( 'yes', 'no' )) ) {
2479
- $data['allow_all_shipping'] = in_array($_data['allow_all_shipping'], array( 'yes', 'no' )) ? $_data['allow_all_shipping'] : $defaults['allow_all_shipping'];
2480
- }
2481
- unset($args['allow_all_shipping']);
2482
- }
2483
-
2484
- if ( array_key_exists('only_free_shipping', $args) ) {
2485
- $data['only_free_shipping'] = strtolower($args['only_free_shipping']);
2486
- if ( ! in_array($data['only_free_shipping'], array( 'yes', 'no' )) ) {
2487
- $data['only_free_shipping'] = in_array($_data['only_free_shipping'], array( 'yes', 'no' )) ? $_data['only_free_shipping'] : $defaults['only_free_shipping'];
2488
- }
2489
- unset($args['only_free_shipping']);
2490
- }
2491
-
2492
- if ( array_key_exists('only_local_pickup_shipping', $args) ) {
2493
- $data['only_local_pickup_shipping'] = strtolower($args['only_local_pickup_shipping']);
2494
- if ( ! in_array($data['only_local_pickup_shipping'], array( 'yes', 'no' )) ) {
2495
- $data['only_local_pickup_shipping'] = in_array($_data['only_local_pickup_shipping'], array( 'yes', 'no' )) ? $_data['only_local_pickup_shipping'] : $defaults['only_local_pickup_shipping'];
2496
- }
2497
- unset($args['only_local_pickup_shipping']);
2498
- }
2499
-
2500
-
2501
- if ( array_key_exists('enable_ftp_upload', $args) ) {
2502
- $data['enable_ftp_upload'] = strtolower($args['enable_ftp_upload']);
2503
- if ( ! in_array($data['enable_ftp_upload'], array( 'yes', 'no' )) ) {
2504
- $data['enable_ftp_upload'] = in_array($_data['enable_ftp_upload'], array( 'yes', 'no' )) ? $_data['enable_ftp_upload'] : $defaults['enable_ftp_upload'];
2505
- }
2506
- unset($args['enable_ftp_upload']);
2507
- }
2508
-
2509
- if ( ! empty($args) ) {
2510
- foreach ( $args as $key => $value ) {
2511
- if ( has_filter("woo_feed_save_{$key}_option") ) {
2512
- $data[ $key ] = apply_filters("woo_feed_save_{$key}_option", sanitize_text_field($value));
2513
- }
2514
- }
2515
- }
2516
-
2517
- return update_option('woo_feed_settings', $data, false);
2518
- }
2519
- }
2520
- if ( ! function_exists('woo_feed_reset_options') ) {
2521
- /**
2522
- * Restore the default settings.
2523
- *
2524
- * @return bool
2525
- * @since 3.3.11
2526
- */
2527
- function woo_feed_reset_options() {
2528
- return update_option('woo_feed_settings', woo_feed_get_options('defaults'), false);
2529
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2530
  }
2531
 
2532
  // Caching. Wrapper for Transient API.
2533
- if ( ! function_exists('woo_feed_get_cached_data') ) {
2534
- /**
2535
- * Get Cached Data
2536
- *
2537
- * @param string $key Cache Name
2538
- *
2539
- * @return mixed|false false if cache not found.
2540
- * @since 3.3.10
2541
- */
2542
- function woo_feed_get_cached_data( $key ) {
2543
- if ( empty($key) ) {
2544
- return false;
2545
- }
2546
-
2547
- return get_transient('__woo_feed_cache_' . $key);
2548
- }
2549
- }
2550
- if ( ! function_exists('woo_feed_set_cache_data') ) {
2551
- /**
2552
- *
2553
- * @param string $key Cache name. Expected to not be SQL-escaped. Must be
2554
- * 172 characters or fewer in length.
2555
- * @param mixed $data Data to cache. Must be serializable if non-scalar.
2556
- * Expected to not be SQL-escaped.
2557
- * @param int|bool $expiration Optional. Time until expiration in seconds. Default 0 (no expiration).
2558
- *
2559
- * @return bool
2560
- */
2561
- function woo_feed_set_cache_data( $key, $data, $expiration = false ) {
2562
-
2563
- if ( empty($key) ) {
2564
- return false;
2565
- }
2566
-
2567
- if (false === $expiration) $expiration = WOO_FEED_CACHE_TTL;
2568
-
2569
- return set_transient('__woo_feed_cache_' . $key, $data, (int)$expiration);
2570
- }
2571
- }
2572
- if ( ! function_exists('woo_feed_delete_cache_data') ) {
2573
- /**
2574
- * Delete Cached Data
2575
- * @param string $key cache name.
2576
- *
2577
- * @return bool
2578
- */
2579
- function woo_feed_delete_cache_data( $key ) {
2580
- if ( empty($key) ) {
2581
- return false;
2582
- }
2583
-
2584
- return delete_transient('__woo_feed_cache_' . $key);
2585
- }
2586
- }
2587
- if ( ! function_exists('woo_feed_flush_cache_data') ) {
2588
- /**
2589
- * Delete All Cached Data
2590
- *
2591
- * @return void
2592
- */
2593
- function woo_feed_flush_cache_data() {
2594
- global $wpdb;
 
 
 
2595
  // $wpdb->query( "DELETE FROM $wpdb->options WHERE {$wpdb->options}.option_name LIKE '_transient___woo_feed_cache_%' " ); // phpcs:ignore
2596
  // $wpdb->query( "DELETE FROM $wpdb->options WHERE {$wpdb->options}.option_name LIKE '_transient_timeout___woo_feed_cache_%'" ); // phpcs:ignore
2597
- $wpdb->query("DELETE FROM $wpdb->options WHERE ({$wpdb->options}.option_name LIKE '_transient_timeout___woo_feed_cache_%') OR ({$wpdb->options}.option_name LIKE '_transient___woo_feed_cache_%')"); // phpcs:ignore
2598
- }
2599
  }
2600
 
2601
  // Price And Tax.
2602
- if ( ! function_exists('woo_feed_apply_tax_location_data') ) {
2603
- /**
2604
- * Filter and Change Location data for tax calculation
2605
- *
2606
- * @param array $location Location array.
2607
- * @param string $tax_class Tax class.
2608
- * @param WC_Customer $customer WooCommerce Customer Object.
2609
- *
2610
- * @return array
2611
- */
2612
- function woo_feed_apply_tax_location_data( $location, $tax_class, $customer ) {
2613
- // @TODO use filter. add tab in feed editor so user can set custom settings.
2614
- // @TODO tab should not list all country and cities. it only list available tax settings and user can just select one.
2615
- // @TODO then it will extract the location data from it to use here.
2616
- $wc_tax_location = [
2617
- WC()->countries->get_base_country(),
2618
- WC()->countries->get_base_state(),
2619
- WC()->countries->get_base_postcode(),
2620
- WC()->countries->get_base_city(),
2621
- ];
2622
- /**
2623
- * Filter Tax Location to apply before product loop
2624
- *
2625
- * @param array $tax_location
2626
- *
2627
- * @since 3.3.0
2628
- */
2629
- $tax_location = apply_filters('woo_feed_tax_location_data', $wc_tax_location);
2630
- if ( ! is_array($tax_location) || (is_array($tax_location) && 4 !== count($tax_location)) ) {
2631
- $tax_location = $wc_tax_location;
2632
- }
2633
-
2634
- return $tax_location;
2635
- }
2636
  }
2637
 
2638
  // Hook feed generating process...
2639
- if ( ! function_exists('woo_feed_apply_hooks_before_product_loop') ) {
2640
- /**
2641
- * Apply Hooks Before Looping through ProductIds
2642
- *
2643
- * @param int[] $productIds product id array.
2644
- * @param array $feedConfig feed config array.
2645
- */
2646
- function woo_feed_apply_hooks_before_product_loop( $productIds, $feedConfig ) {
2647
- add_filter('woocommerce_get_tax_location', 'woo_feed_apply_tax_location_data', 10, 3);
2648
-
2649
- // RightPress dynamic pricing support.
2650
- add_filter('rightpress_product_price_shop_change_prices_in_backend', '__return_true', 999);
2651
- add_filter('rightpress_product_price_shop_change_prices_before_cart_is_loaded', '__return_true', 999);
2652
-
2653
- }
2654
- }
2655
-
2656
- if ( ! function_exists('woo_feed_remove_hooks_after_product_loop') ) {
2657
- /**
2658
- * Remove Applied Hooks Looping through ProductIds
2659
- *
2660
- * @param int[] $productIds product id array.
2661
- * @param array $feedConfig feed config array.
2662
- *
2663
- * @see woo_feed_apply_hooks_before_product_loop
2664
- */
2665
- function woo_feed_remove_hooks_after_product_loop( $productIds, $feedConfig ) {
2666
- remove_filter('woocommerce_get_tax_location', 'woo_feed_apply_tax_location_data', 10);
2667
-
2668
- // RightPress dynamic pricing support.
2669
- remove_filter('rightpress_product_price_shop_change_prices_in_backend', '__return_true', 999);
2670
- remove_filter('rightpress_product_price_shop_change_prices_before_cart_is_loaded', '__return_true', 999);
2671
-
2672
- }
2673
- }
2674
- if ( ! function_exists('woo_feed_remove_hooks_before_product_loop') ) {
2675
- /**
2676
- * Remove Applied Hooks Looping through ProductIds
2677
- *
2678
- * @param int[] $productIds product id array.
2679
- * @param array $feedConfig feed config array.
2680
- *
2681
- * @see woo_feed_apply_hooks_before_product_loop
2682
- */
2683
- function woo_feed_remove_hooks_before_product_loop( $productIds, $feedConfig ) {
2684
- remove_filter('woocommerce_get_tax_location', 'woo_feed_apply_tax_location_data', 10);
2685
- }
2686
- }
2687
-
2688
- if ( ! function_exists('woo_feed_product_taxonomy_term_separator') ) {
2689
- /**
2690
- * Filter Product local category (type) separator
2691
- *
2692
- * @param string $separator
2693
- * @param array $config
2694
- *
2695
- * @return string
2696
- */
2697
- function woo_feed_product_taxonomy_term_separator( $separator, $config ) {
2698
- if ( 'trovaprezzi' === $config['provider'] ) {
2699
- $separator = ',';
2700
- }
2701
-
2702
- if ( false !== strpos($config['provider'], 'daisycon') ) {
2703
- $separator = '|';
2704
- }
2705
-
2706
- return $separator;
2707
- }
2708
- }
2709
- if ( ! function_exists('woo_feed_get_availability_attribute_filter') ) {
2710
- /**
2711
- * Filter Product Availability Attribute Output For Template
2712
- *
2713
- * @param string $output Output string.
2714
- * @param WC_Product $product Product Object
2715
- * @param array $config Feed Config
2716
- *
2717
- * @return int
2718
- */
2719
- function woo_feed_get_availability_attribute_filter( $output, $product, $config ) {
2720
- $status = $product->get_stock_status();
2721
- $provider = $config['provider'];
2722
-
2723
- if ( 'trovaprezzi' === $provider ) {
2724
- $output = 2;
2725
- if ( $status ) {
2726
- if ( 'instock' == $status ) {
2727
- $output = 2;
2728
- } elseif ( 'outofstock' == $status ) {
2729
- $output = 0;
2730
- } elseif ( 'onbackorder' == $status ) {
2731
- $output = 1;
2732
- }
2733
- }
2734
- }
2735
-
2736
- if ( false !== strpos($provider, 'daisycon') ) {
2737
- $output = 'true';
2738
- if ( $status ) {
2739
- if ( 'instock' == $status ) {
2740
- $output = 'true';
2741
- } elseif ( 'outofstock' == $status ) {
2742
- $output = 'false';
2743
- } elseif ( 'onbackorder' == $status ) {
2744
- $output = 'false';
2745
- }
2746
- }
2747
- }
2748
-
2749
- return $output;
2750
- }
2751
  }
2752
 
2753
  // Parse feed rules.
2754
- if ( ! function_exists('woo_feed_filter_parsed_rules') ) {
2755
- /**
2756
- * Filter Feed parsed rules
2757
- *
2758
- * @param array $rules Feed Config
2759
- * @param string $context Parsing context
2760
- *
2761
- * @return array
2762
- * @since 3.3.7
2763
- */
2764
- function woo_feed_filter_parsed_rules( $rules, $context ) {
2765
- $provider = $rules['provider'];
2766
-
2767
- if ( 'create' === $context ) {
2768
- if ( 'criteo' === $provider ) {
2769
- $rules['itemsWrapper'] = 'channel';
2770
- $rules['itemWrapper'] = 'item';
2771
- }
2772
-
2773
- if ( 'wine_searcher' === $provider ) {
2774
- $rules['itemsWrapper'] = 'product-list';
2775
- $rules['itemWrapper'] = 'row';
2776
- $rules['delimiter'] = '|';
2777
- $rules['enclosure'] = ' ';
2778
- }
2779
-
2780
- if ( 'trovaprezzi' === $provider ) {
2781
- $rules['decimal_separator'] = ',';
2782
- $rules['thousand_separator'] = '';
2783
- $rules['decimals'] = 2;
2784
- $rules['itemsWrapper'] = 'Products';
2785
- $rules['itemWrapper'] = 'Offer';
2786
- $rules['delimiter'] = '|';
2787
- $rules['enclosure'] = ' ';
2788
- }
2789
-
2790
- if ( false !== strpos($provider, 'daisycon') ) {
2791
- $rules['itemsWrapper'] = 'channel';
2792
- $rules['itemWrapper'] = 'item';
2793
- }
2794
-
2795
- if ( false !== strpos($provider, 'zbozi.cz') ) {
2796
- $rules['itemsWrapper'] = 'SHOP xmlns="http://www.zbozi.cz/ns/offer/1.0"';
2797
- $rules['itemWrapper'] = 'SHOPITEM';
2798
- }
2799
-
2800
- if ( false !== strpos($provider, 'heureka.sk') ) {
2801
- $rules['itemWrapper'] = 'SHOPITEM';
2802
- }
2803
- }
2804
-
2805
- return $rules;
2806
- }
2807
- }
2808
-
2809
- if ( ! function_exists('array_splice_preserve_keys') ) {
2810
- /**
2811
- * Function to splice an array keeping key
2812
- */
2813
- function array_splice_preserve_keys( &$input, $offset, $length = null, $replacement = array() ) {
2814
-
2815
- if ( empty($replacement) ) {
2816
- return array_splice($input, $offset, $length);
2817
- }
2818
-
2819
- $part_before = array_slice($input, 0, $offset, $preserve_keys = true);
2820
- $part_removed = array_slice($input, $offset, $length, $preserve_keys = true);
2821
- $part_after = array_slice($input, $offset + $length, null, $preserve_keys = true);
2822
-
2823
- $input = $part_before + $replacement + $part_after;
2824
-
2825
- return $part_removed;
2826
- }
2827
- }
2828
-
2829
- if ( ! function_exists('woo_feed_product_custom_fields') ) {
2830
- function woo_feed_product_custom_fields() {
2831
- /**
2832
- * Here array of a field contain 3 elements
2833
- * 1. Name
2834
- * 2. Is this fields enabled by default
2835
- * 3. Is this fields is a custom taxonomy
2836
- */
2837
- $custom_fields = array(
2838
- 'brand' => array( __('Brand', 'woo-feed'), true, true ),
2839
- 'gtin' => array( __('GTIN', 'woo-feed'), true ),
2840
- 'mpn' => array( __('MPN', 'woo-feed'), true ),
2841
- 'ean' => array( __('EAN', 'woo-feed'), true ),
2842
- 'isbn' => array( __('ISBN', 'woo-feed'), true ),
2843
- 'age_group' => array( __('Age group', 'woo-feed'), true ),
2844
- 'gender' => array( __('Gender', 'woo-feed'), true ),
2845
- 'material' => array( __('Material', 'woo-feed'), true ),
2846
- 'cost_of_good_sold' => array( __('Cost of good sold', 'woo-feed'), true ),
2847
- 'availability_date' => array( __('Availability Date', 'woo-feed'), true, false, false ),
2848
- 'unit' => array( __('Unit', 'woo-feed'), true ),
2849
- 'unit_pricing_measure' => array( __('Unit Price Measure', 'woo-feed'), true ),
2850
- 'unit_pricing_base_measure' => array( __('Unit Price Base Measure', 'woo-feed'), true ),
2851
- 'custom_field_0' => array( __('Custom field 0', 'woo-feed'), true ),
2852
- 'custom_field_1' => array( __('Custom field 1', 'woo-feed'), true ),
2853
- 'custom_field_2' => array( __('Custom field 2', 'woo-feed'), true ),
2854
- 'custom_field_3' => array( __('Custom field 3', 'woo-feed'), true ),
2855
- 'custom_field_4' => array( __('Custom field 4', 'woo-feed'), true ),
2856
- );
2857
- return apply_filters('woo_feed_product_custom_fields', $custom_fields);
2858
- }
2859
- }
2860
-
2861
- if ( ! function_exists('woo_feed_product_attribute_cache_remove_cb') ) {
2862
-
2863
- add_action('wp_ajax_woo_feed_product_attribute_cache_remove', 'woo_feed_product_attribute_cache_remove_cb');
2864
- /**
2865
- * This function is called when product attribute swicher click.
2866
- */
2867
- function woo_feed_product_attribute_cache_remove_cb() {
2868
- $is_nonce_valid = isset($_POST['nonce']) && wp_verify_nonce(sanitize_text_field($_POST['nonce']), 'wpf_feed_nonce');
2869
-
2870
- if ( $is_nonce_valid ) {
2871
- delete_transient('__woo_feed_cache_woo_feed_dropdown_product_attributes');
2872
- } else {
2873
- wp_send_json_error(esc_html__('Invalid Request.', 'woo-feed'));
2874
- }
2875
-
2876
- wp_die();
2877
- }
2878
- }
2879
-
2880
- if ( ! function_exists('woo_feed_custom_fields_status_change_cb') ) {
2881
- add_action('wp_ajax_woo_feed_custom_fields_status_change', 'woo_feed_custom_fields_status_change_cb');
2882
- /**
2883
- * This AJAX callback function is called when custom fields on/off switched
2884
- */
2885
- function woo_feed_custom_fields_status_change_cb() {
2886
- $is_nonce_valid = isset($_POST['nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'wpf_feed_nonce');
2887
-
2888
- if ( $is_nonce_valid && isset($_POST['field'], $_POST['status'],
2889
- $_POST['isTaxonomy']) ) {
2890
- $field = sanitize_text_field(wp_unslash($_POST['field']));
2891
- $is_taxonomy = sanitize_text_field(wp_unslash($_POST['isTaxonomy']));
2892
- $status = sanitize_text_field(wp_unslash($_POST['status']));
2893
- $data = woo_feed_get_options('all');
2894
- if ( 'true' === $is_taxonomy ) {
2895
- $data['woo_feed_taxonomy'][ $field ] = ('true' === $status) ? 'enable' : 'disable';
2896
- } else {
2897
- $data['woo_feed_identifier'][ $field ] = ('true' === $status) ? 'enable' : 'disable';
2898
- }
2899
- update_option('woo_feed_settings', $data, false);
2900
- } else {
2901
- wp_send_json_error(esc_html__('Invalid Request.', 'woo-feed'));
2902
- }
2903
-
2904
- wp_die();
2905
- }
2906
- }
2907
-
2908
- if ( ! function_exists('woo_feed_add_custom_identifier') ) {
2909
- /**
2910
- * Add Custom fields into product inventory tab for Unique Identifier (GTIN,MPN,EAN)
2911
- *
2912
- * @since 3.7.8
2913
- */
2914
- function woo_feed_add_custom_identifier() {
2915
- $custom_fields = woo_feed_product_custom_fields();
2916
- $custom_identifier_filter = new Woo_Feed_Custom_Identifier_Filter($custom_fields);
2917
- $custom_identifier = iterator_to_array($custom_identifier_filter);
2918
-
2919
- echo '<div class="options_group">';
2920
- if ( ! empty($custom_identifier) ) {
2921
- echo sprintf('<h4 class="%s" style="padding-left: 10px;color: black;">%s</h4>', esc_attr('woo-feed-option-title'), esc_html__('CUSTOM FIELDS by CTX Feed', 'woo-feed'));
2922
- foreach ( $custom_identifier as $key => $value ) {
2923
-
2924
- //identifier meta value for old and new version users
2925
- $custom_field_key_previous = sprintf('woo_feed_identifier_%s', strtolower($key));
2926
- $custom_field_value_previous = get_post_meta( get_the_ID(), $custom_field_key_previous, true );
2927
-
2928
- $custom_field_key = sprintf('woo_feed_%s', strtolower($key));
2929
- $custom_field_value = get_post_meta( get_the_ID(), $custom_field_key, true );
2930
-
2931
- if ( empty( $custom_field_value ) && ! empty( $custom_field_value_previous ) ) {
2932
- $custom_field_key = $custom_field_key_previous;
2933
- $custom_field_value = $custom_field_value_previous;
2934
- }
2935
-
2936
- $custom_field_id = esc_attr(wp_unslash("woo_feed_{$key}"));
2937
- $custom_field_label = esc_attr(wp_unslash($custom_fields[ $key ][0]));
2938
- $custom_field_description = __('Set product ', 'woo-feed') . esc_html($custom_field_label) . __(' here.', 'woo-feed');
2939
- woocommerce_wp_text_input(
2940
- array(
2941
- 'id' => $custom_field_id,
2942
- 'value' => esc_attr( wp_unslash( $custom_field_value ) ),
2943
- 'placeholder' => $custom_field_label,
2944
- 'label' => $custom_field_label,
2945
- 'desc_tip' => true,
2946
- 'description' => $custom_field_description,
2947
- )
2948
- );
2949
- }
2950
- }
2951
-
2952
- echo '</div>';
2953
-
2954
- }
2955
-
2956
- add_action('woocommerce_product_options_inventory_product_data', 'woo_feed_add_custom_identifier');
2957
- }
2958
-
2959
- if ( ! function_exists('woo_feed_save_custom_identifier') ) {
2960
-
2961
- /**
2962
- * Updating custom fields data. (Unique Identifier (GTIN,MPN,EAN))
2963
- *
2964
- * @param int $id Post Id
2965
- * @param WP_Post $post Wp Post Object.
2966
- * @since 3.7.8
2967
- */
2968
- function woo_feed_save_custom_identifier( $product_id, $product ) {
2969
- $custom_fields = woo_feed_product_custom_fields();
2970
- $custom_identifier_filter = new Woo_Feed_Custom_Identifier_Filter($custom_fields);
2971
- $custom_identifier = iterator_to_array($custom_identifier_filter);
2972
- $set_meta_val = '';
2973
-
2974
- if ( ! empty($custom_identifier) ) {
2975
- foreach ( $custom_identifier as $key => $name ) {
2976
- $product_meta_key = "woo_feed_{$key}";
2977
-
2978
- $new_meta_key = "woo_feed_identifier_{$key}";
2979
- $new_meta_val = get_post_meta($product_id, $new_meta_key, true);
2980
- $old_meta_val = get_post_meta($product_id, $product_meta_key, true);
2981
-
2982
- if(!empty($old_meta_val)){
2983
- $set_meta_val = $old_meta_val;
2984
- }else {
2985
- $set_meta_val = $new_meta_val;
2986
- }
2987
-
2988
- $product_meta_value = isset($_POST[$product_meta_key]) ? sanitize_text_field($_POST[$product_meta_key]) : (isset($_POST["woo_feed_identifier_{$key}"]) ? sanitize_text_field($_POST["woo_feed_identifier_{$key}"]) : $set_meta_val);
2989
-
2990
- if (isset($product_meta_value) && !empty($product_meta_value)) {
2991
- update_post_meta($product_id, $product_meta_key, $product_meta_value);
2992
- } else {
2993
- delete_post_meta($product_id, $product_meta_key);
2994
- }
2995
- }
2996
- }
2997
-
2998
- }
2999
-
3000
- add_action('save_post_product', 'woo_feed_save_custom_identifier', 10, 2);
3001
- }
3002
-
3003
- if ( ! function_exists('woo_feed_add_custom_identifier_for_variation') ) {
3004
-
3005
- /**
3006
- * Custom options in variation tab, here we are putting gtin, mpn, ean input fields in product variation tab
3007
- *
3008
- * @param int $loop Variation loop index.
3009
- * @param array $variation_data Variation info.
3010
- * @param WP_Post $variation Post Object.
3011
- *
3012
- * @since 3.7.8
3013
- */
3014
- function woo_feed_add_custom_identifier_for_variation( $loop, $variation_data, $variation ) {
3015
- $settings = woo_feed_get_options('all');
3016
- if ( isset($settings['disable_mpn']) && "enable" === $settings['disable_mpn'] ) {
3017
- echo '<div class="woo-feed-variation-options">';
3018
- $custom_fields = woo_feed_product_custom_fields();
3019
- $custom_identifier_filter = new Woo_Feed_Custom_Identifier_Filter($custom_fields);
3020
- $custom_identifier = iterator_to_array($custom_identifier_filter);
3021
-
3022
- if ( ! empty($custom_identifier) ) {
3023
- echo '<div class="woo-feed-variation-options">';
3024
- echo sprintf('<h4 class="%s">%s</h4>', esc_attr('woo-feed-variation-option-title'), esc_html__('CUSTOM FIELDS by CTX Feed', 'woo-feed'));
3025
- echo '<div class="woo-feed-variation-items">';
3026
-
3027
- foreach ( $custom_identifier as $key => $value ) {
3028
- $custom_field_id = sprintf('woo_feed_%s_var[%d]', strtolower($key), $variation->ID);
3029
- $custom_field_label = isset($value[0]) ? $value[0] : '';
3030
- $custom_field_description = sprintf('Set product %s here.', $custom_field_label);
3031
-
3032
- //identifier meta value for old and new version users
3033
- if ( metadata_exists('post', $variation->ID, 'woo_feed_' . strtolower($key) . '_var') ) {
3034
- $custom_field_key = sprintf('woo_feed_%s_var', strtolower($key));
3035
- } else {
3036
- $custom_field_key = sprintf('woo_feed_identifier_%s_var', strtolower($key));
3037
- }
3038
-
3039
- woocommerce_wp_text_input(
3040
- array(
3041
- 'id' => $custom_field_id,
3042
- 'value' => esc_attr(get_post_meta($variation->ID, $custom_field_key, true)),
3043
- 'placeholder' => esc_html($custom_field_label),
3044
- 'label' => esc_html($custom_field_label),
3045
- 'desc_tip' => true,
3046
- 'description' => esc_html($custom_field_description),
3047
- 'wrapper_class' => 'form-row form-row-full',
3048
- )
3049
- );
3050
- }
3051
- echo '</div></div>';
3052
- }
3053
- echo '</div>';
3054
- }
3055
- }
3056
-
3057
- add_action('woocommerce_product_after_variable_attributes', 'woo_feed_add_custom_identifier_for_variation', 10, 3);
3058
- }
3059
-
3060
- if ( ! function_exists('woo_feed_save_custom_identifier_for_variation') ) {
3061
-
3062
- /**
3063
- * Saving variation custom fields.
3064
- *
3065
- * @param int $variation_id Variation Id.
3066
- * @param int $i variations loop index.
3067
- *
3068
- * @since 3.7.8
3069
- */
3070
- function woo_feed_save_custom_identifier_for_variation( $variation_id, $i ) {
3071
- $custom_fields = woo_feed_product_custom_fields();
3072
- $custom_identifier_filter = new Woo_Feed_Custom_Identifier_Filter($custom_fields);
3073
- $custom_identifier = iterator_to_array($custom_identifier_filter);
3074
-
3075
- if ( ! empty($custom_identifier) ) {
3076
- foreach ( $custom_identifier as $key => $value ) {
3077
- $custom_field_value = isset($_POST[ "woo_feed_{$key}_var" ][ $variation_id ]) ? sanitize_text_field($_POST[ "woo_feed_{$key}_var" ][ $variation_id ]) : (isset($_POST[ "woo_feed_identifier_{$key}_var" ][ $variation_id ]) ? sanitize_text_field($_POST[ "woo_feed_identifier_{$key}_var" ]) : '');
3078
- if ( isset($custom_field_value) ) {
3079
- update_post_meta($variation_id, "woo_feed_{$key}_var", $custom_field_value);
3080
- }
3081
- }
3082
- }
3083
-
3084
- }
3085
-
3086
- add_action('woocommerce_save_product_variation', 'woo_feed_save_custom_identifier_for_variation', 10, 2);
3087
- }
3088
-
3089
- if ( ! function_exists('woo_feed_category_mapping') ) {
3090
- /**
3091
- * Category Mapping
3092
- */
3093
- function woo_feed_category_mapping() {
3094
- // Manage action for category mapping.
3095
- if ( isset($_GET['action'], $_GET['cmapping']) && 'edit-mapping' == $_GET['action'] ) {
3096
- if ( count($_POST) && isset($_POST['mappingname']) && isset($_POST['edit-mapping']) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
3097
- check_admin_referer('category-mapping');
3098
-
3099
- $mappingOption = sanitize_text_field(wp_unslash($_POST['mappingname']));
3100
- $mappingOption = 'wf_cmapping_' . sanitize_title($mappingOption);
3101
- $mappingData = woo_feed_array_sanitize($_POST);
3102
- $oldMapping = maybe_unserialize(get_option($mappingOption, array()));
3103
-
3104
- # Delete product attribute drop-down cache
3105
- delete_transient('__woo_feed_cache_woo_feed_dropdown_product_attributes');
3106
-
3107
- if ( $oldMapping === $mappingData ) {
3108
- update_option('wpf_message', esc_html__('Mapping Not Changed', 'woo-feed'), false);
3109
- wp_safe_redirect(admin_url('admin.php?page=webappick-feed-category-mapping&wpf_message=warning'));
3110
- die();
3111
- }
3112
-
3113
- if ( update_option($mappingOption, serialize($mappingData), false) ) { // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize
3114
- update_option('wpf_message', esc_html__('Mapping Updated Successfully', 'woo-feed'), false);
3115
- wp_safe_redirect(admin_url('admin.php?page=webappick-feed-category-mapping&wpf_message=success'));
3116
- die();
3117
- } else {
3118
- update_option('wpf_message', esc_html__('Failed To Updated Mapping', 'woo-feed'), false);
3119
- wp_safe_redirect(admin_url('admin.php?page=webappick-feed-category-mapping&wpf_message=error'));
3120
- die();
3121
- }
3122
- }
3123
- require WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-category-mapping.php';
3124
- } elseif ( isset($_GET['action']) && 'add-mapping' == $_GET['action'] ) {
3125
- if ( count($_POST) && isset($_POST['mappingname']) && isset($_POST['add-mapping']) ) {
3126
- check_admin_referer('category-mapping');
3127
-
3128
- $mappingOption = 'wf_cmapping_' . sanitize_text_field(wp_unslash($_POST['mappingname']));
3129
-
3130
- # Delete product attribute drop-down cache
3131
- delete_transient('__woo_feed_cache_woo_feed_dropdown_product_attributes');
3132
-
3133
- if ( false !== get_option($mappingOption, false) ) {
3134
- update_option('wpf_message', esc_html__('Another category mapping exists with the same name.', 'woo-feed'), false);
3135
- wp_safe_redirect(admin_url('admin.php?page=webappick-feed-category-mapping&wpf_message=warning'));
3136
- die();
3137
- }
3138
- if ( update_option($mappingOption, serialize(woo_feed_array_sanitize($_POST)), false) ) { // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize
3139
- update_option('wpf_message', esc_html__('Mapping Added Successfully', 'woo-feed'), false);
3140
- wp_safe_redirect(admin_url('admin.php?page=webappick-feed-category-mapping&wpf_message=success'));
3141
- die();
3142
- } else {
3143
- update_option('wpf_message', esc_html__('Failed To Add Mapping', 'woo-feed'), false);
3144
- wp_safe_redirect(admin_url('admin.php?page=webappick-feed-category-mapping&wpf_message=error'));
3145
- die();
3146
- }
3147
- }
3148
- require WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-category-mapping.php';
3149
- } else {
3150
- require WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-category-mapping-list.php';
3151
- }
3152
- }
 
 
3153
  }
3154
 
3155
  // Category mapping.
3156
- if ( ! function_exists('woo_feed_render_categories') ) {
3157
- /**
3158
- * Get Product Categories
3159
- *
3160
- * @param int $parent Parent ID.
3161
- * @param string $par separator.
3162
- * @param string $value mapped values.
3163
- *
3164
- * @return void
3165
- */
3166
- function woo_feed_render_categories( $parent = 0, $par = '', $value = '' ) {
3167
- $categoryArgs = [
3168
- 'taxonomy' => 'product_cat',
3169
- 'parent' => $parent,
3170
- 'orderby' => 'term_group',
3171
- 'show_count' => 1,
3172
- 'pad_counts' => 1,
3173
- 'hierarchical' => 1,
3174
- 'title_li' => '',
3175
- 'hide_empty' => 0,
3176
- ];
3177
- $categories = get_categories($categoryArgs);
3178
- if ( ! empty($categories) ) {
3179
- if ( ! empty($par) ) {
3180
- $par = $par . ' > ';
3181
- }
3182
- foreach ( $categories as $cat ) {
3183
- $class = $parent ? "treegrid-parent-{$parent} category-mapping" : 'treegrid-parent category-mapping';
3184
- ?>
3185
  <tr class="treegrid-1 ">
3186
  <th>
3187
- <label for="cat_mapping_<?php echo esc_attr($cat->term_id); ?>"><?php echo esc_html($par . $cat->name); ?></label>
3188
  </th>
3189
  <td colspan="3">
3190
  <!--suppress HtmlUnknownAttribute -->
3191
- <?php
3192
- $newOrGoogleFacebook = ! empty( $value )
3193
- && in_array(
3194
- $value['mappingprovider'],
3195
- array( 'google', 'facebook', 'pinterest', 'bing', 'bing_local_inventory', 'snapchat' )
3196
- );
3197
-
3198
- $previous_mapping_value = is_array($value) && isset($value['cmapping'][ $cat->term_id ]) ? esc_attr($value['cmapping'][ $cat->term_id ]) : '';
3199
- $previous_listing_mapping_value = is_array($value) && isset($value['gcl-cmapping'][ $cat->term_id ]) && ! empty( $value['gcl-cmapping'][ $cat->term_id ] )
3200
- ? esc_attr($value['gcl-cmapping'][ $cat->term_id ])
3201
- : $previous_mapping_value;
3202
-
3203
- ?>
3204
- <input <?php echo ( ! $newOrGoogleFacebook ) ? '' : 'style=" display: none;" '; ?> id="cat_mapping_<?php echo esc_attr($cat->term_id); ?>"
3205
- class="<?php echo esc_attr($class); ?> woo-feed-mapping-input"
3206
- autocomplete="off"
3207
- type="text"
3208
- name="cmapping[<?php echo esc_attr($cat->term_id); ?>]"
3209
- placeholder="<?php echo esc_attr($par . $cat->name); ?>"
3210
- data-cat_id="<?php echo esc_attr($cat->term_id); ?>"
3211
- value="<?php echo $previous_mapping_value; ?>"
 
 
 
 
 
 
 
 
3212
  >
3213
- <span <?php echo ( $newOrGoogleFacebook ) ? '' : 'style=" display: none;" '; ?>class="wf_default wf_attributes">
3214
- <select name="gcl-cmapping[<?php echo $cat->term_id ?>]" class="selectize selectize-google-category woo-feed-mapping-select" data-selected="<?php echo $previous_mapping_value; ?>" data-placeholder="<?php esc_attr_e( 'Select A Category', 'woo-feed' ); ?>">
3215
- <option value="<?php echo esc_attr( $previous_listing_mapping_value ); ?>" selected >
 
 
 
 
3216
  <?php echo esc_attr( $previous_listing_mapping_value ); ?>
3217
  </option>
3218
  </select>
3219
 
3220
  </span>
3221
  </td>
3222
- <?php
3223
- if ( ! empty( get_term_children( $cat->term_id, 'product_cat' ) ) ) {
3224
- $woo_map_term_id = 'parent-'. $cat->term_id;
3225
- } else {
3226
- $woo_map_term_id = 'child-' . $cat->parent;
3227
- }
3228
- $termchildren = ! empty( get_term_children( $cat->term_id, 'product_cat' ) ) || $cat->parent;
3229
- ?>
3230
- <td class="<?php echo $termchildren ? 'group-' . $woo_map_term_id : ''; ?>" >
3231
- <?php
3232
- $childrencat = ! empty( get_term_children( $cat->term_id, 'product_cat' ) );
3233
- if ( $childrencat ) {
3234
- $title = __( 'Copy this category to subcategories', 'woo-feed' );
3235
- echo '<span class="dashicons dashicons-arrow-down-alt" title=" ' . $title . '" id="cat-map-'.$cat->term_id.'"></span>';
3236
- }
3237
- ?>
3238
  </td>
3239
  </tr>
3240
- <?php
3241
- // call and render the child category if any.
3242
- woo_feed_render_categories($cat->term_id, $par . $cat->name, $value);
3243
- }
3244
- }
3245
- }
3246
- }
3247
-
3248
- if ( ! function_exists('woo_feed_clear_cache_button') ) {
3249
- /**
3250
- * Clear cache button.
3251
- *
3252
- * @return void
3253
- * @since 4.1.2
3254
- */
3255
- function woo_feed_clear_cache_button() {
3256
- ?>
3257
  <div class="wf_clean_cache_wrapper">
3258
  <img class="woo-feed-cache-loader"
3259
  src="data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22iso-8859-1%22%3F%3E%0D%0A%3C%21--%20Generator%3A%20Adobe%20Illustrator%2019.0.0%2C%20SVG%20Export%20Plug-In%20.%20SVG%20Version%3A%206.00%20Build%200%29%20%20--%3E%0D%0A%3Csvg%20version%3D%221.1%22%20id%3D%22Capa_1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20x%3D%220px%22%20y%3D%220px%22%0D%0A%09%20viewBox%3D%220%200%20458.186%20458.186%22%20style%3D%22enable-background%3Anew%200%200%20458.186%20458.186%3B%22%20xml%3Aspace%3D%22preserve%22%3E%0D%0A%3Cg%3E%0D%0A%09%3Cg%3E%0D%0A%09%09%3Cpath%20d%3D%22M445.651%2C201.95c-1.485-9.308-10.235-15.649-19.543-14.164c-9.308%2C1.485-15.649%2C10.235-14.164%2C19.543%0D%0A%09%09%09c0.016%2C0.102%2C0.033%2C0.203%2C0.051%2C0.304c17.38%2C102.311-51.47%2C199.339-153.781%2C216.719c-102.311%2C17.38-199.339-51.47-216.719-153.781%0D%0A%09%09%09S92.966%2C71.232%2C195.276%2C53.852c62.919-10.688%2C126.962%2C11.29%2C170.059%2C58.361l-75.605%2C25.19%0D%0A%09%09%09c-8.944%2C2.976-13.781%2C12.638-10.806%2C21.582c0.001%2C0.002%2C0.002%2C0.005%2C0.003%2C0.007c2.976%2C8.944%2C12.638%2C13.781%2C21.582%2C10.806%0D%0A%09%09%09c0.003-0.001%2C0.005-0.002%2C0.007-0.002l102.4-34.133c6.972-2.322%2C11.675-8.847%2C11.674-16.196v-102.4%0D%0A%09%09%09C414.59%2C7.641%2C406.949%2C0%2C397.523%2C0s-17.067%2C7.641-17.067%2C17.067v62.344C292.564-4.185%2C153.545-0.702%2C69.949%2C87.19%0D%0A%09%09%09s-80.114%2C226.911%2C7.779%2C310.508s226.911%2C80.114%2C310.508-7.779C435.905%2C339.799%2C457.179%2C270.152%2C445.651%2C201.95z%22%2F%3E%0D%0A%09%3C%2Fg%3E%0D%0A%3C%2Fg%3E%0D%0A%3Cg%3E%0D%0A%3C%2Fg%3E%0D%0A%3Cg%3E%0D%0A%3C%2Fg%3E%0D%0A%3Cg%3E%0D%0A%3C%2Fg%3E%0D%0A%3Cg%3E%0D%0A%3C%2Fg%3E%0D%0A%3Cg%3E%0D%0A%3C%2Fg%3E%0D%0A%3Cg%3E%0D%0A%3C%2Fg%3E%0D%0A%3Cg%3E%0D%0A%3C%2Fg%3E%0D%0A%3Cg%3E%0D%0A%3C%2Fg%3E%0D%0A%3Cg%3E%0D%0A%3C%2Fg%3E%0D%0A%3Cg%3E%0D%0A%3C%2Fg%3E%0D%0A%3Cg%3E%0D%0A%3C%2Fg%3E%0D%0A%3Cg%3E%0D%0A%3C%2Fg%3E%0D%0A%3Cg%3E%0D%0A%3C%2Fg%3E%0D%0A%3Cg%3E%0D%0A%3C%2Fg%3E%0D%0A%3Cg%3E%0D%0A%3C%2Fg%3E%0D%0A%3C%2Fsvg%3E%0D%0A"
3260
  alt="loader">
3261
  <input type="hidden" class="woo-feed-clean-cache-nonce"
3262
- value="<?php echo wp_create_nonce('clean_cache_nonce'); //phpcs:ignore
3263
- ?>">
3264
- <button type="button"><?php esc_html_e('Clear Cache', 'woo-feed'); ?></button>
3265
  </div>
3266
- <?php
3267
- }
3268
- }
3269
-
3270
- if ( ! function_exists('woo_feed_clear_cache_data') ) {
3271
- /**
3272
- * Clear cache data.
3273
- *
3274
- * @param int _ajax_clean_nonce nonce number.
3275
- *
3276
- * @since 4.1.2
3277
- */
3278
- function woo_feed_clear_cache_data() {
3279
- if ( isset($_REQUEST['_ajax_clean_nonce']) ) {
3280
-
3281
- if ( wp_verify_nonce(sanitize_text_field(wp_unslash($_REQUEST['_ajax_clean_nonce'])), 'clean_cache_nonce') ) {
3282
- $data = [];
3283
-
3284
- global $wpdb;
3285
- //TODO add wpdb prepare statement
3286
- $wpdb->query("DELETE FROM $wpdb->options WHERE ({$wpdb->options}.option_name LIKE '_transient_timeout___woo_feed_cache_%') OR ({$wpdb->options}.option_name LIKE '_transient___woo_feed_cache_%')"); // phpcs:ignore
3287
-
3288
-
3289
- $data = [ 'success' => true ];
3290
-
3291
- wp_send_json_success($data);
3292
- }
3293
- } else {
3294
- wp_send_json_error(esc_html__('Invalid Request.', 'woo-feed'));
3295
- }
3296
- wp_die();
3297
- }
3298
- }
3299
- add_action('wp_ajax_clear_cache_data', 'woo_feed_clear_cache_data');
3300
-
3301
- if ( ! function_exists('woo_feed_get_current_timestamp') ) {
3302
- /**
3303
- * Current local timestamp UTC.
3304
- *
3305
- * @since 4.2.0
3306
- */
3307
- function woo_feed_get_current_timestamp() {
3308
-
3309
- $interval = get_option('wf_schedule');
3310
-
3311
- $current_timestamp = time() + $interval;
3312
-
3313
- return $current_timestamp;
3314
- }
3315
  }
3316
 
3317
- if ( ! function_exists('woo_feed_deep_term') ) {
3318
-
3319
- /**
3320
- * Get product terms list by hierarchical order.
3321
- *
3322
- * @param object $term product term object
3323
- * @return string
3324
- * @since 4.3.88+
3325
- */
3326
- function woo_feed_deep_term( $term, $taxonomy ) {
3327
 
3328
- if ( $term->parent === 0 ) {
3329
- return $term->name;
3330
- }
3331
 
3332
- $parent_term = get_term_by('term_id', $term->parent, $taxonomy);
 
 
3333
 
3334
- return woo_feed_deep_term($parent_term, $taxonomy) . ' > ' . $term->name;
3335
- }
3336
- }
3337
 
3338
- if ( ! function_exists('woo_feed_parent_category') ) {
3339
 
3340
- /**
3341
- * Get product terms list by hierarchical order.
3342
- *
3343
- * @param WP_Term $term product term object
3344
- *
3345
- * @return WP_Term $term product parent term object
3346
- * @since 4.4.19
3347
- */
3348
- function woo_feed_parent_category( $term, $taxonomy ) {
 
 
 
 
 
 
 
 
3349
 
3350
- if ( $term->parent === 0 ) {
3351
- return $term;
3352
- }
3353
 
3354
- $parent_term = get_term_by('term_id', $term->parent, $taxonomy);
3355
 
3356
- return woo_feed_parent_category($parent_term, $taxonomy);
3357
- }
3358
  }
3359
 
3360
- if ( ! function_exists('woo_feed_get_terms_list_hierarchical_order') ) {
3361
- /**
3362
- * Get product terms list by hierarchical order.
3363
- *
3364
- * @param int $id post id
3365
- * @param bool $full_path get full category path if true
3366
- * @param string $taxonomy post taxonomy
3367
- * @return false|string
3368
- * @return string
3369
- * @since 4.2.1
3370
- *
3371
- */
3372
- function woo_feed_get_terms_list_hierarchical_order( $id, $full_path = true, $taxonomy = 'product_cat' ) {
3373
-
3374
- $terms = get_the_terms($id, $taxonomy);
3375
 
3376
- if ( count($terms) ) {
3377
-
3378
- if ( $full_path ) {
3379
- return woo_feed_deep_term($terms[ count($terms) - 1 ], $taxonomy);
3380
- } else {
3381
- return $terms[ count($terms) - 1 ]->name;
3382
- }
3383
- }
3384
-
3385
- return false;
3386
- }
3387
- }
3388
-
3389
- if ( ! function_exists('woo_feed_get_products_ids_of_reviews') ) {
3390
- /**
3391
- * Get reviews product ids .
3392
- *
3393
- * @return array $review_products_ids // review products ids
3394
- * @since 4.0.5
3395
- */
3396
- function woo_feed_get_products_ids_of_reviews() {
3397
- $args = array( 'post_type' => 'product' );
3398
- $reviews = get_comments($args);
3399
- $review_products_ids = wp_list_pluck($reviews, 'comment_post_ID');
3400
-
3401
-
3402
- return ! empty($review_products_ids) && is_array($review_products_ids) ? array_unique($review_products_ids) : array();
3403
-
3404
- }
3405
- }
3406
-
3407
- if ( ! function_exists('woo_feed_get_approved_reviews_data') ) {
3408
- /**
3409
- * Get approved review's data.
3410
- *
3411
- * @return mixed
3412
- * @since 4.3.0
3413
- */
3414
- function woo_feed_get_approved_reviews_data() {
3415
- $approved_reviews = [];
3416
- $product_ids = woo_feed_get_products_ids_of_reviews();
3417
-
3418
- if ( ! empty($product_ids) && is_array($product_ids) ) {
3419
-
3420
- foreach ( $product_ids as $product_id ) {
3421
- $reviews = get_comments(array(
3422
- 'post_id' => $product_id,
3423
- 'comment_type' => 'review',
3424
- 'comment_approved' => 1,
3425
- 'parent' => 0,
3426
- ));
3427
-
3428
- $product_name = get_the_title($product_id);
3429
- $product_link = get_the_permalink($product_id);
3430
-
3431
- if ( is_array($reviews) && sizeof($reviews) > 0 ) {
3432
- foreach ( $reviews as $item ) {
3433
- $review = array();
3434
- $review['review_ratings'] = get_comment_meta($item->comment_ID, 'rating', true);
3435
- $review['review_id'] = $item->comment_ID;
3436
- $review['reviewer']['name'] = strip_tags(trim(ucfirst($item->comment_author)));
3437
- $review['reviewer']['reviewer_id'] = $item->user_id;
3438
- $review['review_timestamp'] = $item->comment_date;
3439
- $review['review_product_name'] = $product_name;
3440
- $review['review_url'] = $product_link;
3441
- $review['review_product_url'] = $product_link;
3442
- $review['title'] = $product_name;
3443
- $review['content'] = $item->comment_content;
3444
-
3445
- //product ids
3446
- $review['products']['product']['product_ids']['gtins']['gtin'] = '';
3447
- $review['products']['product']['product_ids']['mpns']['mpn'] = '';
3448
- $review['products']['product']['product_ids']['skus']['sku'] = '';
3449
- $review['products']['product']['product_ids']['brands']['brand'] = '';
3450
- $review['products']['product']['product_name'] = $product_name;
3451
- $review['products']['product']['product_url'] = $product_link;
3452
- array_push($approved_reviews, $review);
3453
- }
3454
- }
3455
- }
3456
- }
3457
-
3458
- return $approved_reviews;
3459
-
3460
- }
3461
- }
3462
-
3463
- if ( ! function_exists('woo_feed_save_black_friday_notice_2021_notice') ) {
3464
- /**
3465
- * Update user meta to work ctx startup notice once.
3466
- *
3467
- * @param int _ajax_nonce nonce number.
3468
- *
3469
- * @since 4.3.31
3470
- * @author Nazrul Islam Nayan
3471
- */
3472
- function woo_feed_save_black_friday_notice_2021_notice() {
3473
- if (isset($_REQUEST['_wp_ajax_nonce']) && wp_verify_nonce(wp_unslash($_REQUEST['_wp_ajax_nonce']), 'woo-feed-to-ctx-feed-notice')) { //phpcs:ignore
3474
- $user_id = get_current_user_id();
3475
- if ( isset($_REQUEST['clicked']) ) {
3476
- $updated_user_meta = add_user_meta($user_id, 'woo_feed_black_friday_notice_2021_dismissed', 'true', true);
3477
-
3478
- if ( $updated_user_meta ) {
3479
- wp_send_json_success(esc_html__('User meta updated successfully.', 'woo-feed'));
3480
- } else {
3481
- wp_send_json_error(esc_html__('Something is wrong.', 'woo-feed'));
3482
- }
3483
- }
3484
- } else {
3485
- wp_send_json_error(esc_html__('Invalid Request.', 'woo-feed'));
3486
- }
3487
- wp_die();
3488
- }
3489
- }
3490
- add_action('wp_ajax_woo_feed_save_black_friday_notice_2021_notice', 'woo_feed_save_black_friday_notice_2021_notice');
3491
-
3492
- if ( ! function_exists('woo_feed_hide_promotion') ) {
3493
- /**
3494
- * Update option to hide promotion.
3495
- *
3496
- * @param int _ajax_nonce nonce number.
3497
- *
3498
- * @since 5.1.7
3499
- */
3500
- function woo_feed_hide_promotion() {
3501
- if ( isset($_REQUEST['_ajax_nonce']) ) {
3502
- $hide_promotion = update_option('woo_feed_hide_promotion', 1);
3503
- $data = array(
3504
- 'msg' => 'Hide promotion updated successfully.',
3505
- );
3506
- if ( $hide_promotion ) {
3507
- wp_send_json_success($data);
3508
- } else {
3509
- wp_send_json_error(esc_html__('Something is wrong.', 'woo-feed'));
3510
- }
3511
- } else {
3512
- wp_send_json_error(esc_html__('Invalid Request.', 'woo-feed'));
3513
- }
3514
- wp_die();
3515
- }
3516
- }
3517
- add_action('wp_ajax_woo_feed_hide_promotion', 'woo_feed_hide_promotion');
3518
-
3519
- if ( ! function_exists('array_key_first') ) {
3520
- /**
3521
- * Array first key.
3522
- *
3523
- * @param array $arr given array.
3524
- *
3525
- * @return mixed
3526
- * @since 4.3.0
3527
- */
3528
- function array_key_first( array $arr ) {
3529
- foreach ( $arr as $k => $unused ) {
3530
- return $k;
3531
- }
3532
- return NULL;
3533
- }
3534
- }
3535
-
3536
- if ( ! function_exists('woo_feed_custom_taxonomy') ) {
3537
- function woo_feed_custom_taxonomy() {
3538
- $custom_fields = woo_feed_product_custom_fields();
3539
- $custom_taxonomies_filter = new Woo_Feed_Custom_Taxonomy_Filter($custom_fields);
3540
- $custom_taxonomies = iterator_to_array($custom_taxonomies_filter);
3541
-
3542
- $settings = woo_feed_get_options( 'all' );
3543
- if ( isset( $settings['woo_feed_taxonomy'], $settings['woo_feed_identifier'] ) ) {
3544
- $custom_attributes = array_merge( $settings['woo_feed_taxonomy'], $settings['woo_feed_identifier'] );
3545
- }else {
3546
- $custom_attributes = $settings['woo_feed_taxonomy'];
3547
- }
3548
-
3549
- if ( isset($custom_attributes['brand']) && 'enable' === $custom_attributes['brand'] ) {
3550
- if ( ! empty($custom_taxonomies) ) {
3551
- foreach ( $custom_taxonomies as $key => $value ) {
3552
- $taxonomy_name = esc_html($value[0]);
3553
-
3554
- $labels = array(
3555
- 'name' => $taxonomy_name . ' ' . __('by CTX Feed', 'woo-feed'),
3556
- 'singular_name' => $taxonomy_name,
3557
- 'menu_name' => $taxonomy_name . 's ' . __('by CTX Feed', 'woo-feed'),
3558
- 'all_items' => __('All', 'woo-feed') . ' ' . $taxonomy_name . 's',
3559
- 'parent_item' => __('Parent', 'woo-feed') . $taxonomy_name,
3560
- 'parent_item_colon' => __('Parent:', 'woo-feed') . $taxonomy_name . ':',
3561
- 'new_item_name' => __('New', 'woo-feed') . ' ' . $taxonomy_name . ' ' . __('Name', 'woo-feed'),
3562
- 'add_new_item' => __('Add New', 'woo-feed') . ' ' . $taxonomy_name,
3563
- 'edit_item' => __('Edit', 'woo-feed') . ' ' . $taxonomy_name,
3564
- 'update_item' => __('Update', 'woo-feed') . ' ' . $taxonomy_name,
3565
- 'separate_items_with_commas' => __('Separate', 'woo-feed') . ' ' . $taxonomy_name . ' ' . __('with commas', 'woo-feed'),
3566
- 'search_items' => __('Search', 'woo-feed') . ' ' . $taxonomy_name,
3567
- 'add_or_remove_items' => __('Add or remove', 'woo-feed') . ' ' . $taxonomy_name,
3568
- 'choose_from_most_used' => __('Choose from the most used', 'woo-feed') . ' ' . $taxonomy_name . 's',
3569
- );
3570
- $args = array(
3571
- 'labels' => $labels,
3572
- 'hierarchical' => true,
3573
- 'public' => true,
3574
- 'show_ui' => true,
3575
- 'show_admin_column' => false,
3576
- 'show_in_rest' => true,
3577
- 'show_in_nav_menus' => true,
3578
- 'show_tagcloud' => true,
3579
- 'show_in_quick_edit' => false,
3580
- );
3581
- $taxonomy_key = sprintf('woo-feed-%s', strtolower($key));
3582
-
3583
- register_taxonomy($taxonomy_key, 'product', $args);
3584
- }
3585
- }
3586
- }
3587
-
3588
- }
3589
-
3590
- add_action('init', 'woo_feed_custom_taxonomy');
3591
- }
3592
-
3593
- if ( ! function_exists('woo_feed_brand_term_radio_checklist') ) {
3594
-
3595
- /**
3596
- * Use radio inputs product brand taxonomies
3597
- *
3598
- * @param $args
3599
- * @return mixed
3600
- */
3601
- function woo_feed_brand_term_radio_checklist( $args ) {
3602
- if ( ! empty($args['taxonomy']) && 'woo-feed-brand' === $args['taxonomy'] ) {
3603
- if ( empty($args['walker']) || is_a($args['walker'], 'Walker') ) {
3604
- if ( ! class_exists('Woo_Feed_Brand_Walker_Category_Radio_Checklist') ) {
3605
- /**
3606
- * Custom walker for switching checkbox inputs to radio.
3607
- *
3608
- * @see Walker_Category_Checklist
3609
- */
3610
- class Woo_Feed_Brand_Walker_Category_Radio_Checklist extends Walker_Category_Checklist
3611
- {
3612
- function walk( $elements, $max_depth, ...$args ) {
3613
- $output = parent::walk($elements, $max_depth, ...$args);
3614
- $output = str_replace(
3615
- array( 'type="checkbox"', "type='checkbox'" ),
3616
- array( 'type="radio"', "type='radio'" ),
3617
- $output
3618
- );
3619
-
3620
- return $output;
3621
- }
3622
- }
3623
- }
3624
- $args['walker'] = new Woo_Feed_Brand_Walker_Category_Radio_Checklist();
3625
- }
3626
- }
3627
- return $args;
3628
- }
3629
-
3630
- add_filter('wp_terms_checklist_args', 'woo_feed_brand_term_radio_checklist');
3631
- }
3632
-
3633
- if ( ! function_exists('woo_feed_filter_woocommerce_structured_data_product') ) {
3634
-
3635
- $settings = woo_feed_get_options('all');
3636
- $overridden_structured_data = $settings['overridden_structured_data'];
3637
-
3638
-
3639
- if ( "on" === $overridden_structured_data ) {
3640
-
3641
- /**
3642
- * Removed woocommerce default schema structure
3643
- *
3644
- * @param $markup
3645
- * @param $product
3646
- *
3647
- * @return array $markup
3648
- * @since 4.3.6
3649
- */
3650
- function woo_feed_filter_woocommerce_structured_data_product( $markup, $product ) {
3651
-
3652
- if( ! $product instanceof WC_Product ) {
3653
- return $markup;
3654
- }
3655
-
3656
- $settings = woo_feed_get_options('all');
3657
- $disable_mpn = $settings['disable_mpn'];
3658
- $disable_brand = $settings['disable_brand'];
3659
-
3660
- $description = apply_filters('woo_feed_schema_description', wp_strip_all_tags($product->get_short_description() ? $product->get_short_description() : $product->get_description()), $product);
3661
- $markup["description"] = $description;
3662
-
3663
- if ( 'enable' === $disable_brand ) {
3664
- $brand_term = wp_get_post_terms($product->get_id(), 'woo-feed-brand', array( 'fields' => 'names' ));
3665
-
3666
- if ( ! is_wp_error($brand_term) ) {
3667
- if ( isset($brand_term[0]) ) {
3668
- $markup['brand']["name"] = $brand_term[0];
3669
- }
3670
- }
3671
- }
3672
-
3673
- //get price and currency to work with all the compatible currency plugin
3674
- $price = $product->get_price();
3675
- $currency = get_woocommerce_currency();
3676
-
3677
- //filter schema price & currency
3678
- $price = apply_filters('woo_feed_schema_product_price', $price, $markup, $product);
3679
- $currency = apply_filters('woo_feed_schema_product_currency', $currency, $markup, $product);
3680
- $markup['offers'][0]['price'] = $price;
3681
- $markup['offers'][0]['priceSpecification']['price'] = $price;
3682
- $markup['offers'][0]['priceSpecification']['priceCurrency'] = $currency;
3683
- $markup['offers'][0]['priceCurrency'] = $currency;
3684
-
3685
- // Check if we have mpn data.
3686
- if ( 'enable' === $disable_mpn && ! empty($mpn) ) {
3687
- $mpn = $product->get_meta('woo_feed_mpn');
3688
- $markup['mpn'] = $mpn;
3689
- }
3690
-
3691
- $markup = apply_filters("woo_feed_after_wc_product_structured_data", $markup, $product);
3692
-
3693
- return $markup;
3694
- }
3695
-
3696
- add_filter('woocommerce_structured_data_product', 'woo_feed_filter_woocommerce_structured_data_product', 10, 2);
3697
-
3698
- }
3699
- }
3700
-
3701
- if ( ! function_exists('woo_feed_trim_attribute') ) {
3702
- /**
3703
- * Trim attribute by specific sign
3704
- *
3705
- * @param $attribute string feed attribute
3706
- * @return mixed
3707
- */
3708
- function woo_feed_trim_attribute( $attribute ) {
3709
- return str_replace('_', ' ', $attribute);
3710
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3711
  }
3712
 
3713
  // Facebook pixel integration
3714
  if ( ! function_exists( 'woo_feed_facebook_pixel_init' ) ) {
3715
 
3716
- function woo_feed_facebook_pixel_init() {
3717
- new WebAppick\Feed\Tracker\Facebook\Pixel();
3718
- }
3719
 
3720
- add_action( 'init', 'woo_feed_facebook_pixel_init' );
3721
 
3722
  }
3723
 
3724
  // Google Remarketing integration
3725
  if ( ! function_exists( 'woo_feed_google_remarketing_init' ) ) {
3726
 
3727
- function woo_feed_google_remarketing_init() {
3728
- new WebAppick\Feed\Tracker\Google\Remarketing();
3729
- }
3730
-
3731
- add_action( 'init', 'woo_feed_google_remarketing_init' );
3732
-
3733
- }
3734
-
3735
- if ( ! function_exists('woo_feed_filter_dropdown_attributes') ) {
3736
- /**
3737
- * Woo Feed Filter Dropdown Attributes
3738
- *
3739
- * @param array $default_attr default attributes
3740
- * @param array $merchants merchant names
3741
- *
3742
- * @return array $filtered_attributes
3743
- *
3744
- * @author Nazrul Islam Nayan
3745
- * @updated 23-12-2020
3746
- *
3747
- * @since 4.3.11
3748
- */
3749
- function woo_feed_filter_dropdown_attributes( $default_attr, $merchants ) {
3750
- $filtered_attributes = $default_attr;
3751
- $snapchat_additional_attr = array();
3752
- $snapchat_additional_attr['--18'] = 'Snapchat Additional Attributes';
3753
- $snapchat_additional_attr['icon_media_url'] = 'Icon Media Url[icon_media_url]';
3754
- $snapchat_additional_attr['ios_app_name'] = 'IOS App Name[ios_app_name]';
3755
- $snapchat_additional_attr['ios_app_store_id'] = 'IOS App Store ID[ios_app_store_id]';
3756
- $snapchat_additional_attr['ios_url'] = 'IOS Url[ios_url]';
3757
- $snapchat_additional_attr['android_app_name'] = 'Android App Name[android_app_name]';
3758
- $snapchat_additional_attr['android_package'] = 'Android Package[android_package]';
3759
- $snapchat_additional_attr['android_url'] = 'Android URL[android_url]';
3760
- $snapchat_additional_attr['mobile_link'] = 'Mobile Link[mobile_link]';
3761
- $snapchat_additional_attr['---18'] = '';
3762
-
3763
- //filtering attributes for pinterest merchant
3764
- if ( in_array('pinterest', $merchants) ) {
3765
- if ( isset($default_attr['ads_redirect']) ) {
3766
- if ( array_key_exists('ads_redirect', $default_attr) ) {
3767
- $keys = array_keys($default_attr);
3768
- $keys[ array_search('ads_redirect', $keys) ] = 'ads_link';
3769
- $filtered_attributes = array_combine($keys, $default_attr);
3770
- $filtered_attributes['ads_link'] = 'Ads Link[ads_link]';
3771
- }
3772
- }
3773
- }
3774
-
3775
- //filtering attributes for snapchat merchant
3776
- if ( in_array('snapchat', $merchants) ) {
3777
- $filtered_attributes = array_merge($filtered_attributes, $snapchat_additional_attr);
3778
- }
3779
-
3780
- //filtering attributes for facebook merchant
3781
- if ( in_array('facebook', $merchants) ) {
3782
- if ( isset($filtered_attributes['excluded_destination']) ) {
3783
- $facebook_attributes = array();
3784
- $facebook_attributes['quantity_to_sell_on_facebook'] = 'Quantity to sell on facebook [quantity_to_sell_on_facebook]';
3785
- $filtered_attributes = woo_feed_array_insert_after($filtered_attributes, 'excluded_destination', $facebook_attributes);
3786
- }
3787
- }
3788
-
3789
- return $filtered_attributes;
3790
- }
3791
-
3792
- add_filter('woo_feed_filter_dropdown_attributes', 'woo_feed_filter_dropdown_attributes', 2, 10);
3793
- }
3794
-
3795
-
3796
- if ( ! function_exists('woo_feed_countries') ) {
3797
- /**
3798
- * Woo Feed Country List
3799
- *
3800
- * @return array
3801
- * @since 4.3.16
3802
- * @author Nazrul Islam Nayan
3803
- * @updated 10-01-2021
3804
- *
3805
- */
3806
-
3807
- function woo_feed_countries() {
3808
-
3809
- return array(
3810
- 'AF' => 'Afghanistan',
3811
- 'AX' => 'Aland Islands',
3812
- 'AL' => 'Albania',
3813
- 'DZ' => 'Algeria',
3814
- 'AS' => 'American Samoa',
3815
- 'AD' => 'Andorra',
3816
- 'AO' => 'Angola',
3817
- 'AI' => 'Anguilla',
3818
- 'AQ' => 'Antarctica',
3819
- 'AG' => 'Antigua and Barbuda',
3820
- 'AR' => 'Argentina',
3821
- 'AM' => 'Armenia',
3822
- 'AW' => 'Aruba',
3823
- 'AU' => 'Australia',
3824
- 'AT' => 'Austria',
3825
- 'AZ' => 'Azerbaijan',
3826
- 'BS' => 'Bahamas the',
3827
- 'BH' => 'Bahrain',
3828
- 'BD' => 'Bangladesh',
3829
- 'BB' => 'Barbados',
3830
- 'BY' => 'Belarus',
3831
- 'BE' => 'Belgium',
3832
- 'BZ' => 'Belize',
3833
- 'BJ' => 'Benin',
3834
- 'BM' => 'Bermuda',
3835
- 'BT' => 'Bhutan',
3836
- 'BO' => 'Bolivia',
3837
- 'BA' => 'Bosnia and Herzegovina',
3838
- 'BW' => 'Botswana',
3839
- 'BV' => 'Bouvet Island (Bouvetoya)',
3840
- 'BR' => 'Brazil',
3841
- 'IO' => 'British Indian Ocean Territory (Chagos Archipelago)',
3842
- 'VG' => 'British Virgin Islands',
3843
- 'BN' => 'Brunei Darussalam',
3844
- 'BG' => 'Bulgaria',
3845
- 'BF' => 'Burkina Faso',
3846
- 'BI' => 'Burundi',
3847
- 'KH' => 'Cambodia',
3848
- 'CM' => 'Cameroon',
3849
- 'CA' => 'Canada',
3850
- 'CV' => 'Cape Verde',
3851
- 'KY' => 'Cayman Islands',
3852
- 'CF' => 'Central African Republic',
3853
- 'TD' => 'Chad',
3854
- 'CL' => 'Chile',
3855
- 'CN' => 'China',
3856
- 'CX' => 'Christmas Island',
3857
- 'CC' => 'Cocos (Keeling) Islands',
3858
- 'CO' => 'Colombia',
3859
- 'KM' => 'Comoros the',
3860
- 'CD' => 'Congo',
3861
- 'CG' => 'Congo the',
3862
- 'CK' => 'Cook Islands',
3863
- 'CR' => 'Costa Rica',
3864
- 'CI' => 'Cote d\'Ivoire',
3865
- 'HR' => 'Croatia',
3866
- 'CU' => 'Cuba',
3867
- 'CY' => 'Cyprus',
3868
- 'CZ' => 'Czech Republic',
3869
- 'DK' => 'Denmark',
3870
- 'DJ' => 'Djibouti',
3871
- 'DM' => 'Dominica',
3872
- 'DO' => 'Dominican Republic',
3873
- 'EC' => 'Ecuador',
3874
- 'EG' => 'Egypt',
3875
- 'SV' => 'El Salvador',
3876
- 'GQ' => 'Equatorial Guinea',
3877
- 'ER' => 'Eritrea',
3878
- 'EE' => 'Estonia',
3879
- 'ET' => 'Ethiopia',
3880
- 'FO' => 'Faroe Islands',
3881
- 'FK' => 'Falkland Islands (Malvinas)',
3882
- 'FJ' => 'Fiji the Fiji Islands',
3883
- 'FI' => 'Finland',
3884
- 'FR' => 'France',
3885
- 'GF' => 'French Guiana',
3886
- 'PF' => 'French Polynesia',
3887
- 'TF' => 'French Southern Territories',
3888
- 'GA' => 'Gabon',
3889
- 'GM' => 'Gambia the',
3890
- 'GE' => 'Georgia',
3891
- 'DE' => 'Germany',
3892
- 'GH' => 'Ghana',
3893
- 'GI' => 'Gibraltar',
3894
- 'GR' => 'Greece',
3895
- 'GL' => 'Greenland',
3896
- 'GD' => 'Grenada',
3897
- 'GP' => 'Guadeloupe',
3898
- 'GU' => 'Guam',
3899
- 'GT' => 'Guatemala',
3900
- 'GG' => 'Guernsey',
3901
- 'GN' => 'Guinea',
3902
- 'GW' => 'Guinea-Bissau',
3903
- 'GY' => 'Guyana',
3904
- 'HT' => 'Haiti',
3905
- 'HM' => 'Heard Island and McDonald Islands',
3906
- 'VA' => 'Holy See (Vatican City State)',
3907
- 'HN' => 'Honduras',
3908
- 'HK' => 'Hong Kong',
3909
- 'HU' => 'Hungary',
3910
- 'IS' => 'Iceland',
3911
- 'IN' => 'India',
3912
- 'ID' => 'Indonesia',
3913
- 'IR' => 'Iran',
3914
- 'IQ' => 'Iraq',
3915
- 'IE' => 'Ireland',
3916
- 'IM' => 'Isle of Man',
3917
- 'IL' => 'Israel',
3918
- 'IT' => 'Italy',
3919
- 'JM' => 'Jamaica',
3920
- 'JP' => 'Japan',
3921
- 'JE' => 'Jersey',
3922
- 'JO' => 'Jordan',
3923
- 'KZ' => 'Kazakhstan',
3924
- 'KE' => 'Kenya',
3925
- 'KI' => 'Kiribati',
3926
- 'KP' => 'Korea',
3927
- 'KR' => 'Korea',
3928
- 'KW' => 'Kuwait',
3929
- 'KG' => 'Kyrgyz Republic',
3930
- 'LA' => 'Lao',
3931
- 'LV' => 'Latvia',
3932
- 'LB' => 'Lebanon',
3933
- 'LS' => 'Lesotho',
3934
- 'LR' => 'Liberia',
3935
- 'LY' => 'Libyan Arab Jamahiriya',
3936
- 'LI' => 'Liechtenstein',
3937
- 'LT' => 'Lithuania',
3938
- 'LU' => 'Luxembourg',
3939
- 'MO' => 'Macao',
3940
- 'MK' => 'Macedonia',
3941
- 'MG' => 'Madagascar',
3942
- 'MW' => 'Malawi',
3943
- 'MY' => 'Malaysia',
3944
- 'MV' => 'Maldives',
3945
- 'ML' => 'Mali',
3946
- 'MT' => 'Malta',
3947
- 'MH' => 'Marshall Islands',
3948
- 'MQ' => 'Martinique',
3949
- 'MR' => 'Mauritania',
3950
- 'MU' => 'Mauritius',
3951
- 'YT' => 'Mayotte',
3952
- 'MX' => 'Mexico',
3953
- 'FM' => 'Micronesia',
3954
- 'MD' => 'Moldova',
3955
- 'MC' => 'Monaco',
3956
- 'MN' => 'Mongolia',
3957
- 'ME' => 'Montenegro',
3958
- 'MS' => 'Montserrat',
3959
- 'MA' => 'Morocco',
3960
- 'MZ' => 'Mozambique',
3961
- 'MM' => 'Myanmar',
3962
- 'NA' => 'Namibia',
3963
- 'NR' => 'Nauru',
3964
- 'NP' => 'Nepal',
3965
- 'AN' => 'Netherlands Antilles',
3966
- 'NL' => 'Netherlands',
3967
- 'NC' => 'New Caledonia',
3968
- 'NZ' => 'New Zealand',
3969
- 'NI' => 'Nicaragua',
3970
- 'NE' => 'Niger',
3971
- 'NG' => 'Nigeria',
3972
- 'NU' => 'Niue',
3973
- 'NF' => 'Norfolk Island',
3974
- 'MP' => 'Northern Mariana Islands',
3975
- 'NO' => 'Norway',
3976
- 'OM' => 'Oman',
3977
- 'PK' => 'Pakistan',
3978
- 'PW' => 'Palau',
3979
- 'PS' => 'Palestinian Territory',
3980
- 'PA' => 'Panama',
3981
- 'PG' => 'Papua New Guinea',
3982
- 'PY' => 'Paraguay',
3983
- 'PE' => 'Peru',
3984
- 'PH' => 'Philippines',
3985
- 'PN' => 'Pitcairn Islands',
3986
- 'PL' => 'Poland',
3987
- 'PT' => 'Portugal, Portuguese Republic',
3988
- 'PR' => 'Puerto Rico',
3989
- 'QA' => 'Qatar',
3990
- 'RE' => 'Reunion',
3991
- 'RO' => 'Romania',
3992
- 'RU' => 'Russian Federation',
3993
- 'RW' => 'Rwanda',
3994
- 'BL' => 'Saint Barthelemy',
3995
- 'SH' => 'Saint Helena',
3996
- 'KN' => 'Saint Kitts and Nevis',
3997
- 'LC' => 'Saint Lucia',
3998
- 'MF' => 'Saint Martin',
3999
- 'PM' => 'Saint Pierre and Miquelon',
4000
- 'VC' => 'Saint Vincent and the Grenadines',
4001
- 'WS' => 'Samoa',
4002
- 'SM' => 'San Marino',
4003
- 'ST' => 'Sao Tome and Principe',
4004
- 'SA' => 'Saudi Arabia',
4005
- 'SN' => 'Senegal',
4006
- 'RS' => 'Serbia',
4007
- 'SC' => 'Seychelles',
4008
- 'SL' => 'Sierra Leone',
4009
- 'SG' => 'Singapore',
4010
- 'SK' => 'Slovakia (Slovak Republic)',
4011
- 'SI' => 'Slovenia',
4012
- 'SB' => 'Solomon Islands',
4013
- 'SO' => 'Somalia, Somali Republic',
4014
- 'ZA' => 'South Africa',
4015
- 'GS' => 'South Georgia and the South Sandwich Islands',
4016
- 'ES' => 'Spain',
4017
- 'LK' => 'Sri Lanka',
4018
- 'SD' => 'Sudan',
4019
- 'SR' => 'Suriname',
4020
- 'SJ' => 'Svalbard & Jan Mayen Islands',
4021
- 'SZ' => 'Swaziland',
4022
- 'SE' => 'Sweden',
4023
- 'CH' => 'Switzerland',
4024
- 'SY' => 'Syrian Arab Republic',
4025
- 'TW' => 'Taiwan',
4026
- 'TJ' => 'Tajikistan',
4027
- 'TZ' => 'Tanzania',
4028
- 'TH' => 'Thailand',
4029
- 'TL' => 'Timor-Leste',
4030
- 'TG' => 'Togo',
4031
- 'TK' => 'Tokelau',
4032
- 'TO' => 'Tonga',
4033
- 'TT' => 'Trinidad and Tobago',
4034
- 'TN' => 'Tunisia',
4035
- 'TR' => 'Turkey',
4036
- 'TM' => 'Turkmenistan',
4037
- 'TC' => 'Turks and Caicos Islands',
4038
- 'TV' => 'Tuvalu',
4039
- 'UG' => 'Uganda',
4040
- 'UA' => 'Ukraine',
4041
- 'AE' => 'United Arab Emirates',
4042
- 'GB' => 'United Kingdom',
4043
- 'US' => 'United States',
4044
- 'UM' => 'United States Minor Outlying Islands',
4045
- 'VI' => 'United States Virgin Islands',
4046
- 'UY' => 'Uruguay, Eastern Republic of',
4047
- 'UZ' => 'Uzbekistan',
4048
- 'VU' => 'Vanuatu',
4049
- 'VE' => 'Venezuela',
4050
- 'VN' => 'Vietnam',
4051
- 'WF' => 'Wallis and Futuna',
4052
- 'EH' => 'Western Sahara',
4053
- 'YE' => 'Yemen',
4054
- 'ZM' => 'Zambia',
4055
- 'ZW' => 'Zimbabwe',
4056
- );
4057
-
4058
- }
4059
- }
4060
-
4061
-
4062
- if ( ! function_exists('woo_feed_positioning_attribute_value') ) {
4063
- /**
4064
- * Positioning new associative array in attribute's dropdown list
4065
- *
4066
- * @param $array array Main attribute array.
4067
- * @param $key string Targeted main array key, after that key index the given associative array should come.
4068
- * @param $input_array array Given associative array.
4069
- *
4070
- * @return array $array
4071
- * @since 4.3.18
4072
- * @author Nazrul Islam Nayan
4073
- * @updated 12-01-2021
4074
- *
4075
- */
4076
- function woo_feed_positioning_attribute_value( $array, $key, $input_array ) {
4077
- $keys = array_keys($array);
4078
- $index = array_search($key, $keys, true);
4079
- $pos = false === $index ? count($array) : $index + 1;
4080
-
4081
- $array = array_slice($array, 0, $pos, true) + $input_array + array_slice($array, $pos, count($array) - 1, true);
4082
- return $array;
4083
- }
4084
- }
4085
-
4086
- if ( ! function_exists('woo_feed_get_feed_file_list') ) {
4087
- function woo_feed_get_feed_file_list() {
4088
- global $wpdb;
4089
- $feed_data = $wpdb->get_results($wpdb->prepare("SELECT option_name FROM $wpdb->options WHERE option_name like %s", 'wf_feed_%'), ARRAY_A); // phpcs:ignore
4090
- $feed_urls = [];
4091
- if ( ! empty($feed_data) and is_array($feed_data) ) {
4092
- foreach ( $feed_data as $key => $data ) {
4093
- $feed_info = maybe_unserialize(get_option($data['option_name']));
4094
- $feed_urls[] = $feed_info['url'];
4095
- }
4096
- }
4097
-
4098
- return $feed_urls;
4099
- }
4100
- }
4101
-
4102
- if ( ! function_exists('woo_feed_exclude_feed_from_wp_rocket_cache') ) {
4103
- /**
4104
- * Exclude Feed file URL form WP Rocket caching
4105
- *
4106
- * @param $files
4107
- *
4108
- * @return array
4109
- */
4110
- function woo_feed_exclude_feed_from_wp_rocket_cache( $files ) {
4111
- return array_merge(
4112
- $files,
4113
- [
4114
- '/wp-content/uploads/woo-feed/(.*)',
4115
- ]
4116
- );
4117
- }
4118
- }
4119
-
4120
- if ( ! function_exists('woo_feed_exclude_feed_from_litespeed_cache') ) {
4121
- /**
4122
- * Exclude Feed file URL form LiteSpeed caching
4123
- *
4124
- * @return array|false
4125
- */
4126
- function woo_feed_exclude_feed_from_litespeed_cache() {
4127
- if ( ! class_exists('LiteSpeed\Core') || ! defined('LSCWP_DIR') ) {
4128
- return false;
4129
- }
4130
-
4131
- $litespeed_ex_paths = maybe_unserialize(get_option('litespeed.conf.cdn-exc'));
4132
- if ( $litespeed_ex_paths && is_array($litespeed_ex_paths) && ! in_array('/wp-content/uploads/woo-feed', $litespeed_ex_paths) ) {
4133
- $litespeed_ex_paths = array_merge(
4134
- $litespeed_ex_paths,
4135
- [ '/wp-content/uploads/woo-feed' ]
4136
- );
4137
- update_option('litespeed.conf.cdn-exc', $litespeed_ex_paths);
4138
- }
4139
- return false;
4140
- }
4141
- }
4142
-
4143
- if ( ! function_exists('woo_feed_exclude_feed_from_wp_fastest_cache') ) {
4144
- /**
4145
- * Exclude Feed file URL form WP Fastest caching
4146
- *
4147
- * @return array|false
4148
- */
4149
- function woo_feed_exclude_feed_from_wp_fastest_cache() {
4150
-
4151
- if ( ! class_exists('WpFastestCache') ) {
4152
- return false;
4153
- }
4154
-
4155
- $wp_fastest_cache_ex_paths = json_decode(get_option('WpFastestCacheExclude'));
4156
- if ( $wp_fastest_cache_ex_paths && is_array($wp_fastest_cache_ex_paths) ) {
4157
-
4158
- $feed_path_exist = false;
4159
- foreach ( $wp_fastest_cache_ex_paths as $key => $path ) {
4160
- if ( 'woo-feed' === $path->content ) {
4161
- $feed_path_exist = true;
4162
- break;
4163
- }
4164
- }
4165
-
4166
- if ( ! $feed_path_exist ) {
4167
- $new_rule = new stdClass();
4168
- $new_rule->prefix = "contain";
4169
- $new_rule->content = 'woo-feed';
4170
- $new_rule->type = "page";
4171
-
4172
- $wp_fastest_cache_ex_paths = array_merge(
4173
- $wp_fastest_cache_ex_paths,
4174
- [ $new_rule ]
4175
- );
4176
-
4177
- update_option('WpFastestCacheExclude', wp_json_encode($wp_fastest_cache_ex_paths));
4178
- }
4179
- } elseif ( empty($wp_fastest_cache_ex_paths) ) {
4180
- $wp_fastest_cache_ex_paths = [];
4181
- $new_rule = new stdClass();
4182
- $new_rule->prefix = "contain";
4183
- $new_rule->content = 'woo-feed';
4184
- $new_rule->type = "page";
4185
-
4186
- $wp_fastest_cache_ex_paths = array_merge(
4187
- $wp_fastest_cache_ex_paths,
4188
- [ $new_rule ]
4189
- );
4190
-
4191
- update_option('WpFastestCacheExclude', wp_json_encode($wp_fastest_cache_ex_paths));
4192
- }
4193
- return false;
4194
- }
4195
- }
4196
-
4197
- if ( ! function_exists('woo_feed_exclude_feed_from_wp_super_cache') ) {
4198
- /**
4199
- * Exclude Feed file URL form WP Super caching
4200
- *
4201
- * @return array|false
4202
- */
4203
- function woo_feed_exclude_feed_from_wp_super_cache() {
4204
-
4205
- if ( ! function_exists('wpsc_init') ) {
4206
- return false;
4207
- }
4208
-
4209
- $wp_super_ex_paths = get_option('ossdl_off_exclude');
4210
- if ( $wp_super_ex_paths && strpos($wp_super_ex_paths, 'woo-feed') === false ) {
4211
- $wp_super_ex_paths = explode(',', $wp_super_ex_paths);
4212
- $wp_super_ex_paths = array_merge($wp_super_ex_paths, [ 'woo-feed' ]);
4213
- update_option('ossdl_off_exclude', implode(',', $wp_super_ex_paths));
4214
- }
4215
-
4216
- return false;
4217
- }
4218
- }
4219
-
4220
- if ( ! function_exists('woo_feed_exclude_feed_from_breeze_cache') ) {
4221
- /**
4222
- * Exclude Feed file URL form BREEZE caching
4223
- *
4224
- * @return array|false
4225
- */
4226
- function woo_feed_exclude_feed_from_breeze_cache() {
4227
-
4228
- if ( ! class_exists('Breeze_Admin') ) {
4229
- return false;
4230
- }
4231
-
4232
- $breeze_settings = maybe_unserialize(get_option('breeze_cdn_integration'));
4233
- if ( is_array($breeze_settings) ) {
4234
- $woo_feed_files = [ '.xml', '.csv', '.tsv', '.txt', '.xls' ];
4235
- $woo_feed_files = array_unique(array_merge($woo_feed_files, $breeze_settings['cdn-exclude-content']));
4236
- $breeze_settings['cdn-exclude-content'] = $woo_feed_files;
4237
- update_option('breeze_cdn_integration', $breeze_settings);
4238
- }
4239
- return false;
4240
- }
4241
- }
4242
-
4243
- if ( ! function_exists('woo_feed_exclude_feed_from_wp_optimize_cache') ) {
4244
- /**
4245
- * Exclude Feed file URL form WP Optimize caching
4246
- *
4247
- * @return array|false
4248
- */
4249
- function woo_feed_exclude_feed_from_wp_optimize_cache() {
4250
-
4251
- if ( ! class_exists('WP_Optimize') ) {
4252
- return false;
4253
- }
4254
-
4255
- $wp_optimize_ex_paths = maybe_unserialize(get_option('wpo_cache_config'));
4256
- if ( isset($wp_optimize_ex_paths['enable_page_caching']) && $wp_optimize_ex_paths['enable_page_caching'] ) { // If page Caching enabled
4257
- if ( is_array($wp_optimize_ex_paths) && ! in_array('/wp-content/uploads/woo-feed', $wp_optimize_ex_paths['cache_exception_urls']) ) {
4258
- $woo_feed_ex_path['cache_exception_urls'] = [ '/wp-content/uploads/woo-feed' ];
4259
- $wp_optimize_ex_paths = array_merge_recursive(
4260
- $wp_optimize_ex_paths,
4261
- $woo_feed_ex_path
4262
- );
4263
- update_option('wpo_cache_config', $wp_optimize_ex_paths);
4264
- }
4265
- }
4266
-
4267
- return false;
4268
- }
4269
- }
4270
-
4271
- if ( ! function_exists('woo_feed_exclude_feed_from_cache_enabler_cache') ) {
4272
- /**
4273
- * Exclude Feed file URL form Cache Enabler caching
4274
- *
4275
- * @return array|false
4276
- */
4277
- function woo_feed_exclude_feed_from_cache_enabler_cache() {
4278
-
4279
- if ( ! class_exists('Cache_Enabler') ) {
4280
- return false;
4281
- }
4282
-
4283
- $cache_enabler_ex_paths = maybe_unserialize(get_option('cache_enabler'));
4284
- if ( isset($cache_enabler_ex_paths['excluded_page_paths']) && empty($cache_enabler_ex_paths['excluded_page_paths']) ) {
4285
- $cache_enabler_ex_paths['excluded_page_paths'] = '/wp-content/uploads/woo-feed/';
4286
- update_option('cache_enabler', $cache_enabler_ex_paths);
4287
- }
4288
-
4289
- return false;
4290
- }
4291
- }
4292
-
4293
- if ( ! function_exists('woo_feed_exclude_feed_from_swift_performance_cache') ) {
4294
- /**
4295
- * Exclude Feed file URL form Swift Performance caching
4296
- *
4297
- * @return array|false
4298
- */
4299
- function woo_feed_exclude_feed_from_swift_performance_cache() {
4300
-
4301
- if ( ! class_exists('Swift_Performance_Lite') ) {
4302
- return false;
4303
- }
4304
-
4305
- $swift_perform_ex_paths = maybe_unserialize(get_option('swift_performance_options'));
4306
-
4307
- if ( $swift_perform_ex_paths && isset($swift_perform_ex_paths['exclude-strings']) ) {
4308
- $exclude_strings = $swift_perform_ex_paths['exclude-strings'];
4309
- if ( is_array($exclude_strings) && ! in_array('/wp-content/uploads/woo-feed', $exclude_strings) ) {
4310
- $woo_feed_ex_path['exclude-strings'] = [ '/wp-content/uploads/woo-feed' ];
4311
- $swift_perform_ex_paths = array_merge_recursive(
4312
- $swift_perform_ex_paths,
4313
- $woo_feed_ex_path
4314
- );
4315
- } else {
4316
- $swift_perform_ex_paths['exclude-strings'] = [ '/wp-content/uploads/woo-feed' ];
4317
- }
4318
- update_option('swift_performance_options', $swift_perform_ex_paths);
4319
- } elseif ( empty($swift_perform_ex_paths) ) {
4320
- $swift_perform_ex_paths['exclude-strings'] = [ '/wp-content/uploads/woo-feed' ];
4321
- update_option('swift_performance_options', $swift_perform_ex_paths);
4322
- }
4323
-
4324
- return false;
4325
- }
4326
- }
4327
-
4328
- if ( ! function_exists('woo_feed_exclude_feed_from_speed_booster_cache') ) {
4329
- /**
4330
- * Exclude Feed file URL form Speed Booster Pack caching
4331
- *
4332
- * @return array|false
4333
- */
4334
- function woo_feed_exclude_feed_from_speed_booster_cache() {
4335
-
4336
- if ( ! class_exists('Speed_Booster_Pack') ) {
4337
- return false;
4338
- }
4339
-
4340
- $feed_files = [];
4341
- $speed_booster_settings = maybe_unserialize(get_option('sbp_options'));
4342
- if ( isset($speed_booster_settings['caching_exclude_urls']) ) {
4343
- $feed_files = woo_feed_get_feed_file_list();
4344
- $caching_exclude_urls = $speed_booster_settings['caching_exclude_urls'];
4345
- if ( ! empty($caching_exclude_urls) ) {
4346
- if ( ! empty($feed_files) ) {
4347
- foreach ( $feed_files as $key => $file ) {
4348
- $file = str_replace(array( 'http://', 'https://' ), '', $file);
4349
- if ( ! in_array($file, explode("\n", $caching_exclude_urls)) ) {
4350
- $caching_exclude_urls .= "\n" . $file;
4351
- }
4352
- }
4353
- }
4354
- } else {
4355
- $caching_exclude_urls = str_replace(array( 'http://', 'https://' ), '', implode("\n", $feed_files));
4356
- }
4357
- $speed_booster_settings['caching_exclude_urls'] = $caching_exclude_urls;
4358
- update_option('sbp_options', $speed_booster_settings);
4359
- }
4360
- //TODO CDN extension exclude
4361
- return false;
4362
- }
4363
- }
4364
-
4365
- if ( ! function_exists('woo_feed_exclude_feed_from_comet_cache') ) {
4366
- /**
4367
- * Exclude Feed file URL form Comet Cache caching
4368
- *
4369
- * @return array|false
4370
- */
4371
- function woo_feed_exclude_feed_from_comet_cache() {
4372
- if ( ! is_plugin_active('comet-cache/comet-cache.php') ) {
4373
- return false;
4374
- }
4375
-
4376
- $comet_cache_settings = maybe_unserialize(get_option('comet_cache_options'));
4377
-
4378
- if ( $comet_cache_settings && isset($comet_cache_settings['exclude_uris']) ) {
4379
- $exclude_uris = $comet_cache_settings['exclude_uris'];
4380
- if ( strpos($exclude_uris, '/wp-content/uploads/woo-feed') === false ) {
4381
- $exclude_uris .= "\n/wp-content/uploads/woo-feed";
4382
- $comet_cache_settings['exclude_uris'] = $exclude_uris;
4383
- update_option('comet_cache_options', $comet_cache_settings);
4384
- }
4385
- }
4386
-
4387
- return false;
4388
- }
4389
- }
4390
-
4391
- if ( ! function_exists('woo_feed_exclude_feed_from_hyper_cache') ) {
4392
- /**
4393
- * Exclude Feed file URL form Swift Performance caching
4394
- *
4395
- * @return array|false
4396
- */
4397
- function woo_feed_exclude_feed_from_hyper_cache() {
4398
-
4399
- if ( ! class_exists('HyperCache') ) {
4400
- return false;
4401
- }
4402
-
4403
- $hyper_cache_settings = maybe_unserialize(get_option('hyper-cache'));
4404
- if ( $hyper_cache_settings && isset($hyper_cache_settings['reject_uris']) ) {
4405
- $exclude_strings = $hyper_cache_settings['reject_uris'];
4406
- if ( is_array($exclude_strings) && ! in_array('/wp-content/uploads/woo-feed', $exclude_strings) ) {
4407
- $woo_feed_ex_path['reject_uris'] = [ '/wp-content/uploads/woo-feed' ];
4408
- $woo_feed_ex_path['reject_uris_enabled'] = 1;
4409
- $hyper_cache_settings = array_merge_recursive(
4410
- $hyper_cache_settings,
4411
- $woo_feed_ex_path
4412
- );
4413
- }
4414
- update_option('hyper-cache', $hyper_cache_settings);
4415
- }
4416
-
4417
- return false;
4418
- }
4419
- }
4420
-
4421
- if ( ! function_exists('woo_feed_wp_options') ) {
4422
- function woo_feed_wp_options() {
4423
- if ( isset($_GET['action']) && 'add-option' == $_GET['action'] ) {
4424
- if ( count($_POST) && isset($_POST['wpfp_option']) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
4425
- check_admin_referer('woo-feed-add-option');
4426
-
4427
- $options = get_option('wpfp_option', array());
4428
- $newOption = sanitize_text_field($_POST['wpfp_option']);
4429
- $id = explode('-', $newOption);
4430
- if ( false !== array_search($id[0], array_column($options, 'option_id')) ) { // found
4431
- update_option('wpf_message', esc_html__('Option Already Added.', 'woo-feed'), false);
4432
- wp_safe_redirect(admin_url('admin.php?page=webappick-wp-options&wpf_message=error'));
4433
- die();
4434
- } else {
4435
- $options[ $id[0] ] = array(
4436
- 'option_id' => $id[0],
4437
- 'option_name' => 'wf_option_' . str_replace($id[0] . '-', '', $newOption),
4438
- );
4439
- update_option('wpfp_option', $options, false);
4440
- update_option('wpf_message', esc_html__('Option Successfully Added.', 'woo-feed'), false);
4441
- wp_safe_redirect(admin_url('admin.php?page=webappick-wp-options&wpf_message=success'));
4442
- die();
4443
- }
4444
- }
4445
- require WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-add-option.php';
4446
- } else {
4447
- require WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-option-list.php';
4448
- }
4449
- }
4450
- }
4451
-
4452
- if ( ! function_exists('woo_feed_get_price_with_tax') ) {
4453
-
4454
-
4455
- /**
4456
- * Get price with tax
4457
- *
4458
- * @param $price
4459
- * @param WC_Product $product product object
4460
- *
4461
- * @return float|mixed|string|void
4462
- */
4463
- function woo_feed_get_price_with_tax( $price, $product ) {
4464
-
4465
- if ( woo_feed_wc_version_check(3.0) ) {
4466
- return wc_get_price_including_tax($product, array( 'price' => $price ));
4467
- } else {
4468
- return $product->get_price_including_tax(1, $price);
4469
- }
4470
-
4471
- return apply_filters('woo_feed_price_with_tax', $price, $product);
4472
- }
4473
- }
4474
-
4475
- if ( ! function_exists('woo_feed_get_dynamic_discounted_product_price') ) {
4476
-
4477
- /**
4478
- * Get price with dynamic discount
4479
- *
4480
- * @param WC_Product|WC_Product_Variable $product product object
4481
- * @param $price
4482
- * @param $config
4483
- * @param bool $tax product taxable or not
4484
- * @return mixed $price
4485
- */
4486
- function woo_feed_get_dynamic_discounted_product_price( $price, $product, $config, $tax ) {
4487
- $base_price = $price;
4488
- $discount_plugin_activate = false;
4489
-
4490
-
4491
- /**
4492
- * PLUGIN: Discount Rules for WooCommerce
4493
- * URL: https://wordpress.org/plugins/woo-discount-rules/
4494
- */
4495
- if ( is_plugin_active('woo-discount-rules/woo-discount-rules.php') ) {
4496
- $discount_plugin_activate = true;
4497
- if ( class_exists('Wdr\App\Controllers\Configuration') ) {
4498
- $config = Wdr\App\Controllers\Configuration::getInstance()->getConfig('calculate_discount_from', 'sale_price');
4499
-
4500
- if ( isset($config) && ! empty($config) ) {
4501
- if ( 'regular_price' === $config ) {
4502
- $price = $product->get_regular_price();
4503
- } else {
4504
- $price = $product->get_price();
4505
- }
4506
- } else {
4507
- $price = $product->get_price();
4508
- }
4509
-
4510
- if ( $product->is_type('variable') ) {
4511
- $min = $product->get_variation_price('min', false);
4512
- $max = $product->get_variation_price('max', false);
4513
-
4514
- $price = $min;
4515
- if ( $max === $base_price ) {
4516
- $price = $max;
4517
- }
4518
- }
4519
-
4520
- $price = apply_filters('advanced_woo_discount_rules_get_product_discount_price_from_custom_price', false, $product, 1, $price, 'discounted_price', true, true);
4521
-
4522
- if ( empty($price) ) {
4523
- $price = $base_price;
4524
- }
4525
-
4526
- if ( ! isset( $feedConfig['feedCurrency'] ) ) {
4527
- $feedConfig['feedCurrency'] = get_woocommerce_currency();
4528
- }
4529
-
4530
- $price = apply_filters('wcml_raw_price_amount', $price, $feedConfig['feedCurrency'] );
4531
-
4532
- }
4533
- }
4534
-
4535
- /**
4536
- * PLUGIN: Dynamic Pricing With Discount Rules for WooCommerce
4537
- * URL: https://wordpress.org/plugins/aco-woo-dynamic-pricing/
4538
- *
4539
- * This plugin does not apply discount on product page.
4540
- *
4541
- * Don't apply discount manually.
4542
- */
 
 
 
 
 
 
4543
  // if (is_plugin_active('aco-woo-dynamic-pricing/start.php')) {
4544
  // $discount_plugin_activate = true;
4545
  // if (class_exists('AWDP_Discount')) {
@@ -4547,12 +4638,12 @@ if ( ! function_exists('woo_feed_get_dynamic_discounted_product_price') ) {
4547
  // }
4548
  // }
4549
 
4550
- /**
4551
- * PLUGIN: Conditional Discounts for WooCommerce
4552
- * URL: https://wordpress.org/plugins/woo-advanced-discounts/
4553
- *
4554
- * NOTE:* Automatically apply discount to $product->get_sale_price() method.
4555
- */
4556
  // if (is_plugin_active('woo-advanced-discounts/wad.php')) {
4557
  // $discount_plugin_activate = true;
4558
  // $discount_amount = 0;
@@ -4577,66 +4668,65 @@ if ( ! function_exists('woo_feed_get_dynamic_discounted_product_price') ) {
4577
  // }
4578
  // }
4579
 
4580
- /**
4581
- * PLUGIN: Pricing Deals for WooCommerce
4582
- * URL: https://wordpress.org/plugins/pricing-deals-for-woocommerce/
4583
- */
4584
- if ( is_plugin_active('pricing-deals-for-woocommerce/vt-pricing-deals.php') ) {
4585
- $discount_plugin_activate = true;
4586
- if ( class_exists('VTPRD_Controller') ) {
4587
- global $vtprd_rules_set;
4588
- $vtprd_rules_set = get_option('vtprd_rules_set');
4589
- if ( ! empty($vtprd_rules_set) && is_array($vtprd_rules_set) ) {
4590
- foreach ( $vtprd_rules_set as $vtprd_rule_set ) {
4591
- $status = $vtprd_rule_set->rule_on_off_sw_select;
4592
- if ( 'on' === $status || 'onForever' === $status ) {
4593
- $discount_type = $vtprd_rule_set->rule_deal_info[0]['discount_amt_type'];
4594
- $discount = $vtprd_rule_set->rule_deal_info[0]['discount_amt_count'];
4595
- if ( 'currency' === $discount_type || 'fixedPrice' === $discount_type ) {
4596
- $price = $product->get_price() - $discount;
4597
- } elseif ( 'percent' === $discount_type ) {
4598
- $price = $product->get_price() - (($product->get_price() * $discount) / 100);
4599
- }
4600
- }
4601
- }
4602
- }
4603
- }
4604
- }
4605
-
4606
- //######################### YITH #########################################################
4607
- /**
4608
- * PLUGIN: YITH WOOCOMMERCE DYNAMIC PRICING AND DISCOUNTS
4609
- * URL: hhttps://yithemes.com/themes/plugins/yith-woocommerce-dynamic-pricing-and-discounts/
4610
- *
4611
- * NOTE:* YITH Automatically apply discount to $product->get_sale_price() method.
4612
- */
4613
- //######################### RightPress ###################################################
4614
- /**
4615
- * PLUGIN: WooCommerce Dynamic Pricing & Discounts
4616
- * URL: https://codecanyon.net/item/woocommerce-dynamic-pricing-discounts/7119279
4617
- *
4618
- * RightPress dynamic pricing supported. Filter Hooks applied to "woo_feed_apply_hooks_before_product_loop"
4619
- * to get the dynamic discounted price via $product->ger_sale_price(); method.
4620
- */
4621
- //###################### Dynamic Pricing ##################################################
4622
- /**
4623
- * PLUGIN: Dynamic Pricing
4624
- * URL: https://woocommerce.com/products/dynamic-pricing/
4625
- *
4626
- * Dynamic Pricing plugin doesn't show the options or any price change on your frontend.
4627
- * So a user will not even notice the discounts until he reaches the checkout.
4628
- * No need to add the compatibility.
4629
- */
4630
-
4631
-
4632
-
4633
- // Get Price with tax
4634
- if ( $discount_plugin_activate && $tax ) {
4635
- $price = woo_feed_get_price_with_tax($price, $product);
4636
- }
4637
-
4638
- return ( isset($base_price) || ($price > 0) && ($price < $base_price) ) ? $price : $base_price;
4639
- }
4640
  }
4641
 
4642
  /**
@@ -4644,19 +4734,18 @@ if ( ! function_exists('woo_feed_get_dynamic_discounted_product_price') ) {
4644
  *
4645
  * @since 4.3.93
4646
  */
4647
- if ( ! class_exists('Woo_Feed_Custom_Taxonomy_Filter') ) {
4648
- class Woo_Feed_Custom_Taxonomy_Filter extends FilterIterator
4649
- {
4650
 
4651
- public function __construct( array $items ) {
4652
- $object = new ArrayObject($items);
4653
- parent::__construct($object->getIterator());
4654
- }
4655
 
4656
- public function accept() {
4657
- return array_key_exists(2, parent::current()) ? parent::current()[2] : false;
4658
- }
4659
- }
4660
  }
4661
 
4662
  /**
@@ -4664,951 +4753,986 @@ if ( ! class_exists('Woo_Feed_Custom_Taxonomy_Filter') ) {
4664
  *
4665
  * @since 4.3.93
4666
  */
4667
- if ( ! class_exists('Woo_Feed_Custom_Identifier_Filter') ) {
4668
- class Woo_Feed_Custom_Identifier_Filter extends FilterIterator
4669
- {
4670
-
4671
- public function __construct( array $items ) {
4672
- $object = new ArrayObject($items);
4673
- parent::__construct($object->getIterator());
4674
- }
4675
-
4676
- public function accept() {
4677
- if ( ! isset( parent::current()[3] ) || (isset(parent::current()[3]) && parent::current()[3] ) ) {
4678
- $is_identifier = ! array_key_exists( 2, parent::current() ) ? true : ! parent::current()[2];
4679
- if ( $is_identifier ) {
4680
- $get_settings = woo_feed_get_options( 'all' );
4681
- $get_identifiers = isset( $get_settings['woo_feed_identifier'] ) ? $get_settings['woo_feed_identifier'] : array();
4682
-
4683
- if ( in_array( parent::key(), array_keys( $get_identifiers ), true ) ) {
4684
- if ( 'enable' === $get_identifiers[ parent::key() ] ) {
4685
- return parent::current();
4686
- }
4687
- } else {
4688
- if ( parent::current()[1] ) {
4689
- return parent::current();
4690
- }
4691
- }
4692
- }
4693
- }
4694
- }
4695
- }
4696
- }
4697
-
4698
- if ( ! function_exists('woo_feed_array_splice_preserve_keys') ) {
4699
- function woo_feed_array_splice_preserve_keys( &$input, $offset, $length = null, $replacement = array() ) {
4700
- if ( empty($replacement) ) {
4701
- return array_splice($input, $offset, $length);
4702
- }
4703
-
4704
- $part_before = array_slice($input, 0, $offset, $preserve_keys = true);
4705
- $part_removed = array_slice($input, $offset, $length, $preserve_keys = true);
4706
- $part_after = array_slice($input, $offset + $length, null, $preserve_keys = true);
4707
-
4708
- $input = $part_before + $replacement + $part_after;
4709
-
4710
- return $part_removed;
4711
- }
4712
- }
4713
-
4714
- if ( ! function_exists('woo_feed_filter_count_cb') ) {
4715
- /**
4716
- * Add AJAX action when client click filter tab.
4717
- */
4718
- add_action('wp_ajax_woo_feed_filter_count', 'woo_feed_filter_count_cb');
4719
- /**
4720
- * This function return object with product counter based on status
4721
- * - Is product out of stock?
4722
- * - Is product is hidden?
4723
- * - Product has description or short description?
4724
- * - Product has image?
4725
- * - Product has price? Regulart price or sell price
4726
- *
4727
- * @return mixed array | error
4728
- */
4729
- function woo_feed_filter_count_cb() {
4730
- $is_nonce_valid = isset($_GET['nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_GET['nonce'])), 'wpf_feed_nonce');
4731
-
4732
- if ( $is_nonce_valid ) {
4733
- $results = array(
4734
- 'hidden' => woo_feed_hidden_products_count(),
4735
- 'noPrice' => woo_feed_no_price_products_count(),
4736
- 'noImg' => woo_feed_no_image_products_count(),
4737
- 'noDesc' => woo_feed_no_description_products_count(),
4738
- 'outOfStock' => woo_feed_out_of_stock_products_count(),
4739
- 'backorder' => woo_feed_backorder_products_count(),
4740
- );
4741
- wp_send_json_success($results);
4742
- } else {
4743
- wp_send_json_error(esc_html__('Invalid Request.', 'woo-feed'));
4744
- }
4745
- wp_die();
4746
- }
4747
- }
4748
- if ( ! function_exists('woo_feed_hidden_products_count') ) {
4749
- /**
4750
- * This function give the hidden products count.
4751
- *
4752
- * @return integer
4753
- */
4754
- function woo_feed_hidden_products_count() {
4755
- $args = array(
4756
- 'post_type' => 'product',
4757
- 'posts_per_page' => -1,
4758
- 'fields' => 'ids',
4759
- 'tax_query' => array(
4760
- array(
4761
- 'taxonomy' => 'product_visibility',
4762
- 'field' => 'name',
4763
- 'terms' => 'exclude-from-catalog',
4764
- 'operator' => 'IN',
4765
- ),
4766
- ),
4767
- );
4768
- $products = new WP_Query($args);
4769
- return count($products->posts);
4770
- }
4771
- }
4772
- if ( ! function_exists('woo_feed_no_image_products_count') ) {
4773
- /**
4774
- * This function give the products count which have no thumbnail image or gallery image
4775
- *
4776
- * @return integer
4777
- */
4778
- function woo_feed_no_image_products_count() {
4779
- $args = array(
4780
- 'post_type' => 'product',
4781
- 'posts_per_page' => -1,
4782
- 'fields' => 'ids',
4783
- 'meta_query' => array(
4784
- 'relation' => 'AND',
4785
- array(
4786
- 'key' => '_thumbnail_id',
4787
- 'compare' => 'NOT EXISTS',
4788
- ),
4789
- array(
4790
- 'key' => '_product_image_gallery',
4791
- 'compare' => 'NOT EXISTS',
4792
- ),
4793
- ),
4794
- );
4795
- $products = new WP_Query($args);
4796
- return count($products->posts);
4797
- }
4798
- }
4799
- if ( ! function_exists('woo_feed_no_description_products_count') ) {
4800
- /**
4801
- * This function give the products count which have no description/short description.
4802
- *
4803
- * @return integer
4804
- */
4805
- function woo_feed_no_description_products_count() {
4806
- add_filter('posts_where', 'woo_feed_filter_where_product_with_no_description');
4807
- $args = array(
4808
- 'post_type' => 'product',
4809
- 'posts_per_page' => -1,
4810
- 'fields' => 'ids',
4811
- );
4812
- $products = new WP_Query($args);
4813
- remove_filter('posts_where', 'woo_feed_filter_where_product_with_no_description');
4814
- return count($products->posts);
4815
- }
4816
- }
4817
- if ( ! function_exists('woo_feed_filter_where_product_with_no_description') ) {
4818
- /**
4819
- * This function changes the wp query to get out of products without description.
4820
- *
4821
- * @param string $where
4822
- */
4823
- function woo_feed_filter_where_product_with_no_description( $where = '' ) {
4824
- $where .= "
 
 
4825
  AND trim( coalesce( post_content, '' ) ) = ''
4826
  ";
4827
- return $where;
4828
- }
4829
- }
4830
- if ( ! function_exists('woo_feed_out_of_stock_products_count') ) {
4831
- /**
4832
- * This function gives the `out of stock products` count.
4833
- *
4834
- * @return integer
4835
- */
4836
- function woo_feed_out_of_stock_products_count() {
4837
- $args = array(
4838
- 'post_type' => 'product',
4839
- 'posts_per_page' => -1,
4840
- 'fields' => 'ids',
4841
- 'meta_query' => array(
4842
- array(
4843
- 'key' => '_stock_status',
4844
- 'value' => 'outofstock',
4845
- 'compare' => '==',
4846
- ),
4847
- ),
4848
- );
4849
- $products = new WP_Query($args);
4850
- return count($products->posts);
4851
- }
4852
- }
4853
- if ( ! function_exists('woo_feed_backorder_products_count') ) {
4854
- /**
4855
- * This function gives the `backorder` products count.
4856
- *
4857
- * @return integer
4858
- */
4859
- function woo_feed_backorder_products_count() {
4860
- $args = array(
4861
- 'post_type' => 'product',
4862
- 'posts_per_page' => -1,
4863
- 'fields' => 'ids',
4864
- 'meta_query' => array(
4865
- array(
4866
- 'key' => '_stock_status',
4867
- 'value' => 'onbackorder',
4868
- 'compare' => '==',
4869
- ),
4870
- ),
4871
- );
4872
- $products = new WP_Query($args);
4873
- return count($products->posts);
4874
- }
4875
- }
4876
- if ( ! function_exists('woo_feed_no_price_products_count') ) {
4877
- /**
4878
- * This function give the products count which have no prices.
4879
- *
4880
- * @return integer
4881
- */
4882
- function woo_feed_no_price_products_count() {
4883
- $args = array(
4884
- 'post_type' => 'product',
4885
- 'posts_per_page' => -1,
4886
- 'fields' => 'ids',
4887
- 'meta_query' => array(
4888
- array(
4889
- 'key' => '_price',
4890
- 'value' => '',
4891
- 'compare' => '==',
4892
- ),
4893
- ),
4894
- );
4895
- $products = new WP_Query($args);
4896
- return count($products->posts);
4897
- }
4898
- }
4899
-
4900
- if ( ! function_exists('woo_feed_custom_field_meta_filter') ) {
4901
- /**
4902
- * Identifier meta value filter for old and new version users
4903
- *
4904
- * @param $meta string Default Meta
4905
- * @param WC_Product $product
4906
- * @param $field string Meta field
4907
- * @return string Custom Field Meta.
4908
- * @since 4.3.99
4909
- *
4910
- */
4911
- function woo_feed_custom_field_meta_filter( $meta, $product, $field ) {
4912
- $id = $product->get_id();
4913
-
4914
- //identifier meta value for old and new version users
4915
- if ( false !== strpos($meta, 'woo_feed_identifier_') ) {
4916
-
4917
- $identifier = str_replace('woo_feed_identifier_', '', $meta);
4918
- if ( metadata_exists('post', $id, 'woo_feed_' . $identifier) ) {
4919
- $meta = 'woo_feed_' . $identifier;
4920
- } else {
4921
- $meta = 'woo_feed_identifier_' . $identifier;
4922
- }
4923
- }
4924
-
4925
- return $meta;
4926
- }
4927
-
4928
- add_filter('woo_feed_custom_field_meta', 'woo_feed_custom_field_meta_filter', 3, 10);
4929
- }
4930
-
4931
- if ( ! function_exists('woo_feed_strpos_array') ) {
4932
-
4933
- /**
4934
- * Extension of php `strpos` function
4935
- *
4936
- * @param $niddles array
4937
- * @param $haystack string
4938
- *
4939
- * @return boolean If any string exists.
4940
- * @since 4.3.100
4941
- *
4942
- */
4943
- function woo_feed_strpos_array( $niddles, $haystack ) {
4944
-
4945
- if ( empty($haystack) ) {
4946
- return;
4947
- }
4948
-
4949
- foreach ( $niddles as $niddle ) {
4950
- if ( strpos($haystack, $niddle) !== false ) {
4951
- return true;
4952
- }
4953
- }
4954
-
4955
- return false;
4956
 
4957
- }
4958
- }
4959
-
4960
- if ( ! function_exists('woo_feed_schema_description_filter') ) {
4961
- /**
4962
- * Filter schema description
4963
- *
4964
- * @param $description mixed default product description
4965
- * @param $product mixed product object
4966
- *
4967
- * @return mixed
4968
- * @since 4.3.101
4969
- *
4970
- */
4971
- function woo_feed_schema_description_filter( $description, $product ) {
4972
-
4973
- $description = do_shortcode($description);
4974
- $description = woo_feed_stripInvalidXml($description);
4975
- $description = preg_replace('/\[\/?vc_.*?\]/', '', $description);
4976
- $description = strip_shortcodes($description);
4977
- $description = preg_replace('~[\r\n]+~', '', $description);
4978
-
4979
- //strip tags and spacial characters
4980
- $strip_description = wp_strip_all_tags(wp_specialchars_decode($description));
4981
-
4982
- $description = ! empty(strlen($strip_description)) && 0 < strlen($strip_description) ? $strip_description : $description;
4983
-
4984
- return $description;
4985
- }
4986
-
4987
- add_filter('woo_feed_schema_description', 'woo_feed_schema_description_filter', 10, 2);
4988
- }
4989
-
4990
-
4991
- if ( ! function_exists('woo_feed_get_yoast_identifiers_value') ) {
4992
- /**
4993
- * Get Yoast identifiers value
4994
- *
4995
- * @param $attribute_key string attribute key
4996
- * @param $product WC_Product product object
4997
- * @return mixed identifier value.
4998
- * @since 4.4.4
4999
- *
5000
- * @author Nazrul Islam Nayan
5001
- */
5002
- function woo_feed_get_yoast_identifiers_value( $attribute_key, $product ) {
5003
- $identifier = '';
5004
- if ( class_exists('Yoast_WooCommerce_SEO') ) {
5005
- $wpseo_identifier = get_post_meta($product->get_id(), 'wpseo_global_identifier_values');
5006
- $wpseo_identifier = reset($wpseo_identifier);
5007
-
5008
- if ( isset($wpseo_identifier[ $attribute_key ]) ) {
5009
- $identifier = $wpseo_identifier[ $attribute_key ];
5010
- }
5011
-
5012
- if ( empty($identifier) && $product->is_type('variation') ) {
5013
- $parent = wc_get_product($product->get_parent_id());
5014
- $identifier = woo_feed_get_yoast_identifiers_value($attribute_key, $parent);
5015
- }
5016
- }
5017
-
5018
- return $identifier;
5019
- }
5020
-
5021
- if ( ! function_exists('woo_feed_parent_product_id') ) {
5022
- /**
5023
- * Return variable product id for variation else main product id.
5024
- *
5025
- * @param WC_Product $product
5026
- *
5027
- * @return int
5028
- */
5029
- function woo_feed_parent_product_id( $product ) {
5030
- if ( $product->is_type('variation') ) {
5031
- return $product->get_parent_id();
5032
- }
5033
- return $product->get_id();
5034
- }
5035
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5036
  }
5037
 
5038
  #==== MERCHANT TEMPLATE OVERRIDE START ==============#
5039
- if ( ! function_exists('woo_feed_modify_google_color_attribute_value') ) {
5040
- /**
5041
- * Replace comma (,) with slash (/) for Google Shopping template color attribute value
5042
- *
5043
- * @param $attribute_value
5044
- * @param $product
5045
- * @param $feed_config
5046
- *
5047
- * @return string
5048
- */
5049
- function woo_feed_modify_google_color_attribute_value( $attribute_value, $product, $feed_config, $merchant_attribute ) {
5050
- // Replace Google Color attribute value according to requirements
5051
- if ( ('g:color' === $merchant_attribute || 'color' === $merchant_attribute)
5052
- && in_array($feed_config['provider'], [
5053
- 'google',
5054
- 'facebook',
5055
- 'pinterest',
5056
- 'bing',
5057
- 'snapchat',
5058
- ], true) ) {
5059
- return str_replace(', ', '/', $attribute_value);
5060
- }
5061
- return $attribute_value;
5062
- }
5063
- }
5064
-
5065
- if ( ! function_exists('woo_feed_modify_weight_attribute_value') ) {
5066
- /**
5067
- * Add wight unit as suffix for Google Shopping template shipping_weight attribute.
5068
- *
5069
- * @param $attribute_value
5070
- * @param WC_Product $product
5071
- * @param $feed_config
5072
- *
5073
- * @return string
5074
- */
5075
- function woo_feed_modify_weight_attribute_value( $attribute_value, $product, $feed_config ) {
5076
- if ( isset($feed_config['attributes'])
5077
- && in_array($feed_config['provider'], [
5078
- 'google',
5079
- 'facebook',
5080
- 'pinterest',
5081
- 'bing',
5082
- 'snapchat',
5083
- ]) ) {
5084
- $attributes = $feed_config['attributes'];
5085
- $key = array_search('weight', $attributes, true);
5086
- if ( isset($feed_config['suffix']) && ! empty($key) && array_key_exists($key, $feed_config['suffix']) ) {
5087
- $weight_suffix_unit = $feed_config['suffix'][ $key ];
5088
-
5089
- if ( empty($weight_suffix_unit) && ! empty($attribute_value) ) {
5090
- $attribute_value .= ' ' . get_option('woocommerce_weight_unit');
5091
- }
5092
- }
5093
- }
5094
-
5095
- return $attribute_value;
5096
- }
5097
- }
5098
-
5099
- if ( ! function_exists('woo_feed_get_bestprice_categoryPath_attribute_value_modify') ) {
5100
- /**
5101
- * Replace BestPrice categoryPath value from > to ,
5102
- *
5103
- * @param $attribute_value
5104
- * @param $product
5105
- * @param $feed_config
5106
- *
5107
- * @return string
5108
- */
5109
- function woo_feed_get_bestprice_categoryPath_attribute_value_modify( $attribute_value, $product, $feed_config ) {
5110
- $attribute_value = str_replace('>', ', ', $attribute_value);
5111
-
5112
- return $attribute_value;
5113
- }
5114
- }
5115
-
5116
- if ( ! function_exists('woo_feed_availability_attribute_value_modify') ) {
5117
- /**
5118
- * Modify Availability attribute value based on channel.
5119
- *
5120
- * @param $attribute_value
5121
- * @param $product
5122
- * @param $feed_config
5123
- *
5124
- * @return string
5125
- */
5126
- function woo_feed_availability_attribute_value_modify( $attribute_value, $product, $feed_config ) {
5127
- if ( 'bestprice' === $feed_config['provider'] ) {
5128
- if ( 'in stock' === $attribute_value ) {
5129
- return "Y";
5130
- }
5131
-
5132
- return "N";
5133
- }
5134
-
5135
- if ( 'skroutz' === $feed_config['provider'] ) {
5136
-
5137
- if ( 'in stock' === $attribute_value ) {
5138
- $in_stock_string = __('Delivery 1 to 3 days', 'woo-feed' );
5139
- } else {
5140
- $in_stock_string = __('Delivery up to 30 days', 'woo-feed' );
5141
- }
5142
-
5143
- return $in_stock_string;
5144
- }
5145
-
5146
- if ( 'pricerunner' === $feed_config['provider'] ) {
5147
- if ( 'in stock' === $attribute_value ) {
5148
- return "Yes";
5149
- }
5150
-
5151
- return "No";
5152
- }
5153
-
5154
- if ( 'google' === $feed_config['provider'] || 'pinterest' === $feed_config['provider'] ) {
5155
- if ( 'on backorder' === $attribute_value || 'on_backorder' === $attribute_value ) {
5156
- return 'preorder';
5157
- }
5158
-
5159
- if ( 'google' === $feed_config['provider'] ) {
5160
- if ( ! in_array( $attribute_value, [ 'in_stock', 'out_of_stock', 'on_backorder' ] ) ) {
5161
- return 'in_stock';
5162
- }
5163
- } elseif ( ! in_array( $attribute_value, [ 'in stock', 'out of stock', 'on backorder' ] ) ) {
5164
- return 'in stock';
5165
- }
5166
- }
5167
-
5168
- if ( 'facebook' === $feed_config['provider'] ) {
5169
- if ( 'on backorder' === $attribute_value ) {
5170
- return 'available for order';
5171
- }elseif ( ! in_array( $attribute_value, [ 'in stock', 'out of stock', 'on backorder' ] ) ) {
5172
- return 'in stock';
5173
- }
5174
- }
5175
-
5176
- return $attribute_value;
5177
- }
5178
- }
5179
-
5180
- if ( ! function_exists('woo_feed_spartoo_attribute_value_modify') ) {
5181
- /**
5182
- * Modify Spartoo feed Parent/Child attribute value.
5183
- *
5184
- * @param $attribute_value
5185
- * @param $product
5186
- * @param $feed_config
5187
- *
5188
- * @return string
5189
- */
5190
- function woo_feed_spartoo_attribute_value_modify( $attribute_value, $product, $feed_config ) {
5191
- if ( 'spartoo.fi' === $feed_config['provider'] ) {
5192
- if ( 'variation' === $attribute_value ) {
5193
- return "child";
5194
- }
5195
-
5196
- return "parent";
5197
- }
5198
-
5199
- return $attribute_value;
5200
- }
5201
- }
5202
-
5203
- if ( ! function_exists('woo_feed_get_pinterest_rss_date_attribute_callback') ) {
5204
- /**
5205
- * Convert date format to DATERFC822 for pinterest RSS Feed.
5206
- *
5207
- * @param $attribute_value
5208
- * @param $product
5209
- * @param $feed_config
5210
- *
5211
- * @return string
5212
- */
5213
- function woo_feed_get_pinterest_rss_date_attribute_callback( $attribute_value, $product, $feed_config ) {
5214
- if ( ! empty($attribute_value) ) {
5215
- return date('r', strtotime($attribute_value));
5216
- }
5217
- return $attribute_value;
5218
- }
 
 
5219
  }
5220
 
5221
  if ( ! function_exists( 'woo_feed_duplicate_feed' ) ) {
5222
- /**
5223
- * @param string $feed_from Required. Feed name to duplicate from
5224
- * @param string $new_name Optional. New name for duplicate feed.
5225
- * Default to auto generated slug from the old name prefixed with number.
5226
- * @param bool $copy_file Optional. Copy the file. Default is true.
5227
- *
5228
- * @return bool|WP_Error WP_Error object on error, true on success.
5229
- */
5230
- function woo_feed_duplicate_feed( $feed_from, $new_name = '', $copy_file = true ) {
5231
-
5232
- if ( empty( $feed_from ) ) {
5233
- return new WP_Error( 'invalid_feed_name_top_copy_from', esc_html__( 'Invalid Request.', 'woo-feed' ) );
5234
- }
5235
- // normalize the option name.
5236
- $feed_from = woo_feed_extract_feed_option_name( $feed_from );
5237
- // get the feed data for duplicating.
5238
- $base_feed = maybe_unserialize( get_option( 'wf_feed_' . $feed_from, array() ) );
5239
- // validate the feed data.
5240
- if ( empty( $base_feed ) || ! is_array( $base_feed ) || ! isset( $base_feed['feedrules'] ) || ( isset( $base_feed['feedrules'] ) && empty( $base_feed['feedrules'] ) ) ) {
5241
- return new WP_Error( 'empty_base_feed', esc_html__( 'Feed data is empty. Can\'t duplicate feed.', 'woo-feed' ) );
5242
- }
5243
- $part = '';
5244
- if ( empty( $new_name ) ) {
5245
- // generate a unique slug for duplicate the feed.
5246
- $new_name = generate_unique_feed_file_name( $feed_from, $base_feed['feedrules']['feedType'], $base_feed['feedrules']['provider'] );
5247
- // example-2 or example-2-2-3
5248
- $part = ' ' . str_replace_trim( $feed_from . '-', '', $new_name ); // -2-2-3
5249
- } else {
5250
- $new_name = generate_unique_feed_file_name( $new_name, $base_feed['feedrules']['feedType'], $base_feed['feedrules']['provider'] );
5251
- }
5252
- // new name for the feed with numeric parts from the unique slug.
5253
- $base_feed['feedrules']['filename'] = $base_feed['feedrules']['filename'] . $part;
5254
- // copy feed config data.
5255
- $saved_feed = woo_feed_save_feed_config_data( $base_feed['feedrules'], $new_name, false );
5256
- if ( false === $saved_feed ) {
5257
- return new WP_Error( 'unable_to_save_the_duplicate', esc_html__( 'Unable to save the duplicate feed data.', 'woo-feed' ) );
5258
- }
5259
-
5260
- if ( true === $copy_file ) {
5261
- // copy the data file.
5262
- $original_file = woo_feed_get_file( $feed_from, $base_feed['feedrules']['provider'], $base_feed['feedrules']['feedType'] );
5263
- $new_file = woo_feed_get_file( $new_name, $base_feed['feedrules']['provider'], $base_feed['feedrules']['feedType'] );
5264
- if ( copy( $original_file, $new_file ) ) {
5265
- return true;
5266
- } else {
5267
- return new WP_Error( 'unable_to_copy_file', esc_html__( 'Feed Successfully Duplicated, but unable to generate the data file. Please click the "Regenerate Button"', 'woo-feed' ) );
5268
- }
5269
- }
5270
- return true;
5271
- }
5272
- }
5273
-
5274
- if ( ! function_exists('woo_feed_is_google_group_merchant') ) {
5275
- /**
5276
- * Check if the given merchant is a google group merchant (google, facebook, pinterest, bing)
5277
- *
5278
- * @param string $provider Feed Merchant
5279
- *
5280
- * @author Nazrul Islam Nayan
5281
- * @since 4.4.22
5282
- * @return boolean
5283
- */
5284
- function woo_feed_is_google_group_merchant( $provider ) {
5285
- return in_array($provider, [ 'google', 'facebook', 'pinterest', 'bing' ]);
5286
- }
5287
- }
5288
-
5289
- if ( ! function_exists('woo_feed_filter_product_description_callback') ) {
5290
- /**
5291
- * @param string $description Product Description
5292
- * @param WC_Product $product Product Object
5293
- * @param array $configFeed Feed Config
5294
- *
5295
- * @return mixed
5296
- */
5297
- function woo_feed_filter_product_description_callback( $description, $product, $config ) {
5298
- if ( empty($description) ) {
5299
- return $description;
5300
- }
5301
-
5302
- if ( isset($config['provider']) && woo_feed_is_google_group_merchant($config['provider']) ) {
5303
- if ( strlen($description) > 5000 ) {
5304
- for ( $I = 4999; $description[ $I ] != ' ' ; $I-- );
5305
- $description = substr($description, 0, $I);
5306
- }
5307
- }
5308
-
5309
- return $description;
5310
- }
 
 
 
5311
  }
5312
 
5313
  if ( ! function_exists( 'woo_feed_filter_product_title' ) ) {
5314
- /**
5315
- * @param string $title Product Title
5316
- * @param WC_Product $product
5317
- * @param array $config Feed config
5318
- *
5319
- * @return string
5320
- */
5321
- function woo_feed_filter_product_title( $title, $product, $config ) {
5322
-
5323
- if ( ! is_string( $title ) ) {
5324
- return '';
5325
- }
5326
-
5327
- if ( isset($config['provider']) && in_array($config['provider'], [ 'google', 'facebook', 'pinterest', 'bing' ]) ) {
5328
- if ( strlen($title) > 150 ) {
5329
- for ( $I = 149; $title[ $I ] != ' ' ; $I-- );
5330
- $title = substr($title, 0, $I);
5331
- }
5332
- }
5333
-
5334
- return $title;
5335
- }
 
 
 
 
 
 
 
5336
  }
5337
 
5338
  if ( ! function_exists( 'woo_feed_array_insert_after' ) ) {
5339
- /**
5340
- * Insert a value or key/value pair after a specific key in an array. If key doesn't exist, value is appended
5341
- * to the end of the array.
5342
- *
5343
- * @param array $array
5344
- * @param string $key
5345
- * @param array $new
5346
- *
5347
- * @return array
5348
- */
5349
- function woo_feed_array_insert_after( array $array, $key, array $new ) {
5350
- $keys = array_keys( $array );
5351
- $index = array_search( $key, $keys, true );
5352
- $pos = false === $index ? count( $array ) : $index + 1;
5353
-
5354
- return array_merge( array_slice( $array, 0, $pos ), $new, array_slice( $array, $pos ) );
5355
- }
5356
  }
5357
 
5358
  if ( ! function_exists( 'woo_feed_get_js_dequeue_handles_list' ) ) {
5359
- /**
5360
- * JS files handles list to dequeue from loading
5361
- *
5362
- * @since 4.4.43
5363
- * @author Nazrul Islam Nayan
5364
- * @return array
5365
- */
5366
- function woo_feed_get_js_dequeue_handles_list() {
5367
- $js_files_handles = [ 'common_aramex', 'jquery_chained', 'validate_aramex' ]; //aramex shipping plugin handles
5368
 
5369
- return apply_filters("woo_feed_filter_js_dequeue_handles", $js_files_handles);
5370
- }
5371
  }
5372
 
5373
  if ( ! function_exists( 'woo_feed_get_plugin_pages_slugs' ) ) {
5374
- /**
5375
- * Get Woo Feed Plugin Pages Slugs
5376
- *
5377
- * @since 4.4.44
5378
- * @author Nazrul Islam Nayan
5379
- * @return array
5380
- */
5381
- function woo_feed_get_plugin_pages_slugs() {
5382
- $woo_feed_plugin_pages = [
5383
- 'webappick-manage-feeds',
5384
- 'webappick-new-feed',
5385
- 'webappick-wp-options',
5386
- 'webappick-feed-settings',
5387
- 'webappick-feed-docs',
5388
- 'webappick-feed-pro-vs-free',
5389
- 'webappick-wp-status',
5390
- 'webappick-feed-category-mapping',
5391
- 'webappick-wp-options',
5392
- ];
5393
 
5394
- return apply_filters('woo_feed_plugin_pages_slugs', $woo_feed_plugin_pages);
5395
- }
5396
  }
5397
 
5398
- if ( ! function_exists('woo_feed_make_feed_big_data') ) {
5399
- function woo_feed_make_feed_big_data( $data, $ids, $config ) {
 
 
 
 
 
 
 
5400
 
5401
- //setup feed shipping data @TODO: need to make a class when another data setup will be added
5402
- if ( isset($config['attributes']) && in_array("shipping", $config["attributes"]) ) {
5403
- if ( class_exists( 'WC_Shipping_Zones' ) ) {
5404
- $data['shipping_zones'] = WC_Shipping_Zones::get_zones();
5405
- }
5406
- }
5407
 
5408
- return $data;
5409
 
5410
- }
5411
- add_filter('woo_feed_feed_big_data', 'woo_feed_make_feed_big_data', 10, 3);
5412
  }
5413
 
5414
 
5415
- if( ! function_exists('woo_feed_after_wc_product_structured_data') ) {
5416
- function woo_feed_after_wc_product_structured_data($markup, $product) {
5417
 
5418
- if( ! $product instanceof WC_Product ) {
5419
- return $markup;
5420
- }
5421
 
5422
- if( isset($_SERVER['REQUEST_URI']) && strpos($_SERVER['REQUEST_URI'], 'attribute_') ) {
5423
- $url = $_SERVER['REQUEST_URI'];
5424
- $url_components = parse_url($url);
5425
- $currency = get_option('woocommerce_currency');
5426
 
5427
- if( isset($url_components['query']) && !empty($url_components['query']) ) {
5428
- parse_str($url_components['query'], $params);
5429
 
5430
- $attributes = $product->get_attributes();
5431
- $attribute_names = array_keys($attributes);
5432
 
5433
- if( isset($attribute_names) && is_array($attribute_names) ) {
5434
- $meta_query_items = [];
5435
- $meta_query_items['relation'] = 'AND';
5436
 
5437
- foreach($attribute_names as $attr_name) {
5438
- $attribute_name = 'attribute_'. $attr_name;
5439
 
5440
- if( isset($params[$attribute_name]) ) {
5441
- $new_query_item = [];
5442
- $new_query_item['key'] = $attribute_name;
5443
- $new_query_item['value'] = $params[$attribute_name];
5444
- $new_query_item['compare'] = 'LIKE';
5445
-
5446
- array_push($meta_query_items, $new_query_item);
5447
- }
5448
- }
5449
-
5450
- $variation_id = get_posts(
5451
- array(
5452
- 'post_type' => 'product_variation',
5453
- 'numberposts' => 1,
5454
- 'post_status' => 'publish',
5455
- 'fields' => 'ids',
5456
- 'post_parent' => $product->get_id(),
5457
- 'meta_query' => $meta_query_items,
5458
- )
5459
- );
5460
 
5461
- if( isset($variation_id[0]) ) {
5462
- $variation_product = wc_get_product($variation_id[0]);
 
5463
 
5464
- if( $variation_product instanceof WC_Product_Variation ) {
5465
- $variation_price = $variation_product->get_price();
 
 
 
 
 
 
 
 
5466
 
5467
- $markup['offers'][0]['@type'] = "Offer";
5468
- $markup['offers'][0]['price'] = $variation_price;
5469
- $markup['offers'][0]['priceSpecification']['price'] = $variation_price;
5470
- $markup['offers'][0]['priceSpecification']['priceCurrency'] = $currency;
5471
- $markup['offers'][0]['priceCurrency'] = $currency;
5472
- }
5473
 
5474
- }
 
5475
 
5476
- }
5477
- }
 
 
 
 
5478
 
5479
- }
5480
 
5481
- return $markup;
 
5482
 
5483
- }
5484
- add_filter('woo_feed_after_wc_product_structured_data', 'woo_feed_after_wc_product_structured_data', 10, 2);
 
 
 
 
 
5485
  }
5486
 
5487
- if ( ! function_exists('woo_feed_filter_shipping_info_callback') ) {
5488
- function woo_feed_filter_shipping_info_callback( $shipping_info, $shipping_zones, $product, $config ) {
5489
 
5490
- //when WooCommerce Advanced Shipping by sormano is activated
5491
- if( is_plugin_active('woocommerce-advanced-shipping/woocommerce-advanced-shipping.php') ) {
5492
- $product_id = $product->get_id();
5493
 
5494
- //get advanced shipping post ids for post type `was`
5495
- $args = array(
5496
- 'post_type' => 'was',
5497
- 'fields' => 'ids',
5498
- );
5499
 
5500
- $ids = get_posts($args);
5501
 
5502
- // Set shipping cost
5503
- $shipping_cost = 0;
5504
- $tax = 0;
5505
- defined('WC_ABSPATH') || exit;
5506
 
5507
- // Load cart functions which are loaded only on the front-end.
5508
- include_once WC_ABSPATH . 'includes/wc-cart-functions.php';
5509
- include_once WC_ABSPATH . 'includes/class-wc-cart.php';
5510
 
5511
- wc_load_cart();
5512
- global $woocommerce;
5513
 
5514
- // Make sure to empty the cart again
5515
- $woocommerce->cart->empty_cart();
5516
 
5517
- // add product to cart
5518
- $woocommerce->cart->add_to_cart($product_id, 1);
5519
 
5520
- if (isset(WC()->session->get('shipping_for_package_0')['rates'])) {
5521
- $cart_shippings = WC()->session->get('shipping_for_package_0')['rates'];
5522
- $exist_shipping_keys = array_keys($cart_shippings);
5523
 
5524
- if (isset($cart_shippings) && is_array($cart_shippings)) {
5525
- $adv_shipping = [];
5526
- foreach ($cart_shippings as $key => $cart_shipping) {
5527
- $new_adv_shipping = [];
5528
 
5529
- if (in_array($key, $ids)) {
5530
- $new_adv_shipping['country'] = $config['feed_country'];
5531
- $new_adv_shipping['service'] = '';
5532
- $label = $cart_shipping->get_label();
5533
 
5534
- //advanced shipping service
5535
- if (isset($label) && !empty($label)) {
5536
- $new_adv_shipping['service'] = $label;
5537
- } else {
5538
- $new_adv_shipping['service'] = get_the_title($key);
5539
- }
5540
 
5541
- //advanced shipping cost
5542
- if (!empty($cart_shipping->get_cost())) {
5543
- $new_adv_shipping['price'] = $cart_shipping->get_cost();
5544
- } else {
5545
- $new_adv_shipping['price'] = 0;
5546
- }
5547
 
5548
- array_push($adv_shipping, $new_adv_shipping);
5549
- }
5550
 
5551
- }
5552
- }
5553
 
5554
- }
5555
 
5556
- // Make sure to empty the cart again
5557
- $woocommerce->cart->empty_cart();
5558
 
5559
 
5560
- if (!empty($adv_shipping)) {
5561
- $shipping_info = array_merge($shipping_info, $adv_shipping);
5562
- }
5563
 
5564
- }
5565
 
5566
 
5567
- return $shipping_info;
5568
 
5569
- }
5570
 
5571
- add_filter('woo_feed_filter_shipping_info', 'woo_feed_filter_shipping_info_callback', 10, 4);
5572
  }
5573
 
5574
  #=============== ACF ===============================================
5575
  if ( ! function_exists( 'woo_feed_get_acf_field_list' ) ) {
5576
- /**
5577
- * Get Advance Custom Field (ACF) field list
5578
- *
5579
- *
5580
- * @return Array
5581
- */
5582
- function woo_feed_get_acf_field_list() {
5583
- $options = [];
5584
- if ( class_exists( 'ACF' ) ) {
5585
- $acf_fields = woo_feed_get_cached_data( 'acf_field_list' );
5586
- if ( false === $acf_fields ) {
5587
- $field_groups = acf_get_field_groups();
5588
- foreach ( $field_groups as $group ) {
5589
- // DO NOT USE here: $fields = acf_get_fields($group['key']);
5590
- // because it causes repeater field bugs and returns "trashed" fields
5591
- $fields = get_posts( array(
5592
- 'posts_per_page' => - 1,
5593
- 'post_type' => 'acf-field',
5594
- 'orderby' => 'menu_order',
5595
- 'order' => 'ASC',
5596
- 'suppress_filters' => true, // DO NOT allow WPML to modify the query
5597
- 'post_parent' => $group['ID'],
5598
- 'post_status' => 'any',
5599
- 'update_post_meta_cache' => false,
5600
- ) );
5601
- foreach ( $fields as $field ) {
5602
- $options[ 'acf_fields_'.$field->post_name ] = $field->post_title;
5603
- }
5604
- }
5605
-
5606
- woo_feed_set_cache_data( 'acf_field_list', $options );
5607
- }
5608
- }
5609
-
5610
- return $options;
5611
- }
 
 
 
 
 
 
 
 
 
 
 
 
5612
  }
5613
 
5614
  #==== MERCHANT TEMPLATE OVERRIDE END ================#
9
  * @copyright WebAppick
10
  */
11
 
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ die(); // Silence...
14
+ }
15
+
16
+ if ( ! function_exists( 'woo_feed_maybe_define_constant' ) ) {
17
+ /**
18
+ * Define a constant if it is not already defined.
19
+ *
20
+ * @param string $name Constant name.
21
+ * @param mixed $value Value.
22
+ *
23
+ * @return void
24
+ * @since 3.2.1
25
+ */
26
+ function woo_feed_maybe_define_constant( $name, $value ) {
27
+ // phpcs:disable
28
+ if ( ! defined( $name ) ) {
29
+ define( $name, $value );
30
+ }
31
+ // phpcs:enable
32
+ }
33
+ }
34
+ if ( ! function_exists( 'woo_feed_doing_it_wrong' ) ) {
35
+ /**
36
+ * Wrapper for _doing_it_wrong.
37
+ *
38
+ * @param string $function Function used.
39
+ * @param string $message Message to log.
40
+ * @param string $version Version the message was added in.
41
+ *
42
+ * @return void
43
+ * @since 3.2.1
44
+ *
45
+ */
46
+ function woo_feed_doing_it_wrong( $function, $message, $version ) {
47
+ // phpcs:disable
48
+ $message .= ' Backtrace: ' . wp_debug_backtrace_summary();
49
+
50
+ if ( is_ajax() || WC()->is_rest_api_request() ) {
51
+ do_action( 'doing_it_wrong_run', $function, $message, $version );
52
+ error_log( "{$function} was called incorrectly. {$message}. This message was added in version {$version}." );
53
+ } else {
54
+ _doing_it_wrong( $function, $message, $version );
55
+ }
56
+ // phpcs:enable
57
+ }
58
+ }
59
+ if ( ! function_exists( 'is_ajax' ) ) {
60
+
61
+ /**
62
+ * Is_ajax - Returns true when the page is loaded via ajax.
63
+ *
64
+ * @return bool
65
+ */
66
+ function is_ajax() {
67
+ return function_exists( 'wp_doing_ajax' ) ? wp_doing_ajax() : defined( 'DOING_AJAX' );
68
+ }
69
+ }
70
+ if ( ! function_exists( 'woo_feed_is_plugin_active' ) ) {
71
+ /**
72
+ * Determines whether a plugin is active.
73
+ *
74
+ * @param string $plugin Path to the plugin file relative to the plugins directory.
75
+ *
76
+ * @return bool True, if in the active plugins list. False, not in the list.
77
+ * @since 3.1.41
78
+ * @see is_plugin_active()
79
+ *
80
+ */
81
+ function woo_feed_is_plugin_active( $plugin ) {
82
+ if ( ! function_exists( 'is_plugin_active' ) ) {
83
+ include_once ABSPATH . 'wp-admin/includes/plugin.php';
84
+ }
85
+
86
+ return is_plugin_active( $plugin );
87
+ }
88
+ }
89
+ if ( ! function_exists( 'wooFeed_is_plugin_inactive' ) ) {
90
+ /**
91
+ * Determines whether the plugin is inactive.
92
+ *
93
+ * @param string $plugin Path to the plugin file relative to the plugins directory.
94
+ *
95
+ * @return bool True if inactive. False if active.
96
+ * @since 3.1.41
97
+ * @see wooFeed_is_plugin_inactive()
98
+ *
99
+ */
100
+ function wooFeed_is_plugin_inactive( $plugin ) {
101
+ return ! woo_feed_is_plugin_active( $plugin );
102
+ }
103
+ }
104
+ if ( ! function_exists( 'wooFeed_deactivate_plugins' ) ) {
105
+ /**
106
+ * Deactivate a single plugin or multiple plugins.
107
+ * Wrapper for core deactivate_plugins() function
108
+ *
109
+ * @param string|array $plugins Single plugin or list of plugins to deactivate.
110
+ * @param bool $silent Prevent calling deactivation hooks. Default is false.
111
+ * @param mixed $network_wide Whether to deactivate the plugin for all sites in the network.
112
+ *
113
+ * @return void
114
+ * @see deactivate_plugins()
115
+ *
116
+ */
117
+ function wooFeed_Deactivate_plugins( $plugins, $silent = false, $network_wide = null ) {
118
+ if ( ! function_exists( 'deactivate_plugins' ) ) {
119
+ require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
120
+ }
121
+ deactivate_plugins( $plugins, $silent, $network_wide );
122
+ }
123
+ }
124
+ if ( ! function_exists( 'wooFeed_is_supported_php' ) ) {
125
+ /**
126
+ * Check if server php version meet minimum requirement
127
+ * @return bool
128
+ * @since 3.1.41
129
+ */
130
+ function wooFeed_is_supported_php() {
131
+ // PHP version need to be => WOO_FEED_MIN_PHP_VERSION
132
+ return ! version_compare( PHP_VERSION, WOO_FEED_MIN_PHP_VERSION, '<' );
133
+ }
134
+ }
135
+ if ( ! function_exists( 'wooFeed_check_WC' ) ) {
136
+ function wooFeed_check_WC() {
137
+ return class_exists( 'WooCommerce', false );
138
+ }
139
+ }
140
+ if ( ! function_exists( 'wooFeed_is_WC_supported' ) ) {
141
+ function wooFeed_is_WC_supported() {
142
+ // Ensure WC is loaded before checking version
143
+ return ( defined( 'WC_VERSION' ) && version_compare( WC_VERSION, WOO_FEED_MIN_WC_VERSION, '>=' ) );
144
+ }
145
+ }
146
+ if ( ! function_exists( 'woo_feed_wc_version_check' ) ) {
147
+ /**
148
+ * Check WooCommerce Version
149
+ *
150
+ * @param string $version
151
+ *
152
+ * @return bool
153
+ */
154
+ function woo_feed_wc_version_check( $version = '3.0' ) {
155
+ if ( ! function_exists( 'get_plugins' ) ) {
156
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
157
+ }
158
+ $plugins = get_plugins();
159
+ if ( array_key_exists( 'woocommerce/woocommerce.php', $plugins ) ) {
160
+ $currentVersion = $plugins['woocommerce/woocommerce.php']['Version'];
161
+ if ( version_compare( $currentVersion, $version, '>=' ) ) {
162
+ return true;
163
+ }
164
+ }
165
+
166
+ return false;
167
+ }
168
+ }
169
+ if ( ! function_exists( 'woo_feed_wpml_version_check' ) ) {
170
+ /**
171
+ * Check WooCommerce Version
172
+ *
173
+ * @param string $version
174
+ *
175
+ * @return bool
176
+ */
177
+ function woo_feed_wpml_version_check( $version = '3.2' ) {
178
+ // calling this function too early (before wc loaded) will not give correct output
179
+ if ( defined( 'ICL_SITEPRESS_VERSION' ) ) {
180
+ if ( version_compare( ICL_SITEPRESS_VERSION, $version, '>=' ) ) {
181
+ return true;
182
+ }
183
+ }
184
+
185
+ return false;
186
+ }
187
+ }
188
+ if ( ! function_exists( 'wooFeed_Admin_Notices' ) ) {
189
+ /**
190
+ * Display Admin Messages
191
+ * @hooked admin_notices
192
+ * @return void
193
+ * @since 3.1.41
194
+ */
195
+ function wooFeed_Admin_Notices() {
196
+ // @TODO Refactor this function with admin message class
197
+ // WC Missing Notice..
198
+ if ( ! wooFeed_check_WC() ) {
199
+ $plugin_url = self_admin_url( 'plugin-install.php?s=woocommerce&tab=search&type=term' );
200
+ /**
201
+ * @noinspection HtmlUnknownTarget
202
+ */
203
+ $plugin_url = sprintf( '<a href="%s">%s</a>', $plugin_url, esc_html__( 'WooCommerce', 'woo-feed' ) );
204
+ $plugin_name = sprintf( '<code>%s</code>', esc_html__( 'WooCommerce Product Feed', 'woo-feed' ) );
205
+ $wc_name = sprintf( '<code>%s</code>', esc_html__( 'WooCommerce', 'woo-feed' ) );
206
+ $message = sprintf(
207
+ /* translators: 1: this plugin name, 2: required plugin name, 3: required plugin name and installation url */
208
+ esc_html__( '%1$s requires %2$s to be installed and active. You can installed/activate %3$s here.', 'woo-feed' ),
209
+ $plugin_name,
210
+ $wc_name,
211
+ $plugin_url
212
+ );
213
+ printf( '<div class="error"><p><strong>%1$s</strong></p></div>', $message ); // phpcs:ignore
214
+ }
215
+ if ( wooFeed_check_WC() && ! wooFeed_is_WC_supported() ) {
216
+ $plugin_url = self_admin_url( 'plugin-install.php?s=woocommerce&tab=search&type=term' );
217
+ $wcVersion = defined( 'WC_VERSION' ) ? '<code>' . WC_VERSION . '</code>' : '<code>UNKNOWN</code>';
218
+ $minVersion = '<code>' . WOO_FEED_MIN_WC_VERSION . '</code>';
219
+ /**
220
+ * @noinspection HtmlUnknownTarget
221
+ */
222
+ $plugin_url = sprintf( '<a href="%s">%s</a>', $plugin_url, esc_html__( 'WooCommerce', 'woo-feed' ) );
223
+ $plugin_name = sprintf( '<code>%s</code>', esc_html__( 'WooCommerce Product Feed', 'woo-feed' ) );
224
+ $wc_name = sprintf( '<code>%s</code>', esc_html__( 'WooCommerce', 'woo-feed' ) );
225
+ $message = sprintf(
226
+ /* translators: 1: this plugin name, 2: required plugin name, 3: required plugin required version, 4: required plugin current version, 5: required plugin update url and name */
227
+ esc_html__( '%1$s requires %2$s version %3$s or above and %4$s found. Please upgrade %2$s to the latest version here %5$s', 'woo-feed' ),
228
+ $plugin_name,
229
+ $wc_name,
230
+ $minVersion,
231
+ $wcVersion,
232
+ $plugin_url
233
+ );
234
+ printf( '<div class="error"><p><strong>%1$s</strong></p></div>', $message ); // phpcs:ignore
235
+ }
236
+ }
237
+ }
238
+ if ( ! function_exists( 'woo_feed_black_friday_notice' ) ) {
239
+ /**
240
+ * CTX Feed Black Friday Notice
241
+ *
242
+ * @since 4.4.35
243
+ * @author Nazrul Islam Nayan
244
+ */
245
+ function woo_feed_black_friday_notice() {
246
+ $user_id = get_current_user_id();
247
+ if ( ! get_user_meta( $user_id, 'woo_feed_black_friday_notice_2021_dismissed' ) ) {
248
+ ob_start();
249
+ ?>
250
  <script type="text/javascript">
251
  (function ($) {
252
  $(document).on('click', '.woo-feed-ctx-startup-notice button.notice-dismiss', function (e) {
265
  });
266
  })(jQuery)
267
  </script>
268
+ <a href="https://webappick.com/plugin/woocommerce-product-feed-pro/?utm_source=freePlugin&utm_medium=go_premium&utm_campaign=black_friday_2021&utm_term=wooFeed"
269
+ class="notice woo-feed-ctx-startup-notice is-dismissible"
270
+ style="background: url(<?php echo WOO_FEED_PLUGIN_URL . "admin/images/ctx-feed-black-friday-banner-2021.png"; ?>) no-repeat top center;">
271
  <input type="hidden" id="woo_feed_to_ctx_feed_nonce"
272
+ value="<?php echo wp_create_nonce( 'woo-feed-to-ctx-feed-notice' ); ?>">
273
  </a>
274
+ <?php
275
+ $image = ob_get_contents();
276
+ }
277
+ }
278
+ }
279
+ if ( ! function_exists( 'woo_feed_progress_bar' ) ) {
280
+ /**
281
+ * Feed Progress Bar
282
+ *
283
+ * @since 4.1.1
284
+ */
285
+ function woo_feed_progress_bar() {
286
+ $progress_bar = '';
287
+ ob_start();
288
+ ?>
289
  <div id="feed_progress_table" style="display: none;">
290
  <table class="table widefat fixed">
291
  <thead>
292
  <tr>
293
+ <th><b><?php esc_html_e( 'Generating Product Feed', 'woo-feed' ); ?></b></th>
294
  </tr>
295
  </thead>
296
  <tbody>
316
  </table>
317
  <br>
318
  </div>
319
+ <?php
320
+ $progress_bar .= ob_get_clean();
321
+
322
+ echo $progress_bar;
323
+
324
+ }
325
+ }
326
+
327
+ if ( ! function_exists( 'checkFTP_connection' ) ) {
328
+ /**
329
+ * Verify if ftp module enabled
330
+ * @TODO improve module detection
331
+ * @return bool
332
+ */
333
+ function checkFTP_connection() {
334
+ return ( extension_loaded( 'ftp' ) || function_exists( 'ftp_connect' ) );
335
+ }
336
+ }
337
+ if ( ! function_exists( 'checkSFTP_connection' ) ) {
338
+ /**
339
+ * Verify if ssh/sftp module enabled
340
+ * @TODO improve module detection
341
+ * @return bool
342
+ */
343
+ function checkSFTP_connection() {
344
+ return ( extension_loaded( 'ssh2' ) || function_exists( 'ssh2_connect' ) );
345
+ }
346
+ }
347
+ if ( ! function_exists( 'array_splice_assoc' ) ) {
348
+ /**
349
+ * Array Splice Associative Array
350
+ * @see https://www.php.net/manual/en/function.array-splice.php#111204
351
+ *
352
+ * @param array $input
353
+ * @param string|int $offset
354
+ * @param string|int $length
355
+ * @param array $replacement
356
+ *
357
+ * @return array
358
+ */
359
+ function array_splice_assoc( $input, $offset, $length, $replacement ) {
360
+ $replacement = (array) $replacement;
361
+ $key_indices = array_flip( array_keys( $input ) );
362
+ if ( isset( $input[ $offset ] ) && is_string( $offset ) ) {
363
+ $offset = $key_indices[ $offset ] + 1;
364
+ }
365
+ if ( isset( $input[ $length ] ) && is_string( $length ) ) {
366
+ $length = $key_indices[ $length ] - $offset;
367
+ }
368
+
369
+ $input = array_slice( $input, 0, $offset, true ) + $replacement + array_slice( $input, $offset + $length, null, true );
370
+
371
+ return $input;
372
+ }
373
+ }
374
+ if ( ! function_exists( 'woo_feed_get_query_type_options' ) ) {
375
+ /**
376
+ * Get Query available Types
377
+ *
378
+ * @param string $type
379
+ *
380
+ * @return array
381
+ * @since 3.3.11
382
+ */
383
+ function woo_feed_get_query_type_options( $type = '' ) {
384
+ if ( 'variation' === $type ) {
385
+ return [
386
+ 'individual' => __( 'Individual', 'woo-feed' ),
387
+ 'variable' => __( 'Variable Dependable', 'woo-feed' ),
388
+ ];
389
+ } else {
390
+ return [
391
+ 'wc' => __( 'WC_Product_Query', 'woo-feed' ),
392
+ 'wp' => __( 'WP_Query', 'woo-feed' ),
393
+ 'both' => __( 'Both', 'woo-feed' ),
394
+ ];
395
+ }
396
+ }
397
+ }
398
+ if ( ! function_exists( 'woo_feed_get_cache_ttl_options' ) ) {
399
+ /**
400
+ * Cache Expiration Options
401
+ * @return array
402
+ */
403
+ function woo_feed_get_cache_ttl_options() {
404
+ return apply_filters(
405
+ 'woo_feed_cache_ttl_options',
406
+ [
407
+ 0 => esc_html__( 'No Expiration ', 'woo-feed' ),
408
+ MONTH_IN_SECONDS => esc_html__( '1 Month', 'woo-feed' ),
409
+ WEEK_IN_SECONDS => esc_html__( '1 Week', 'woo-feed' ),
410
+ DAY_IN_SECONDS => esc_html__( '24 Hours', 'woo-feed' ),
411
+ 12 * HOUR_IN_SECONDS => esc_html__( '12 Hours', 'woo-feed' ),
412
+ 6 * HOUR_IN_SECONDS => esc_html__( '6 Hours', 'woo-feed' ),
413
+ HOUR_IN_SECONDS => esc_html__( '1 Hours', 'woo-feed' ),
414
+ ]
415
+ );
416
+ }
417
+ }
418
+ if ( ! function_exists( 'woo_feed_get_custom2_merchant' ) ) {
419
+ /**
420
+ * Get Merchant list that are allowed on Custom2 Template
421
+ * @return array
422
+ */
423
+ function woo_feed_get_custom2_merchant() {
424
+ return array( 'custom2', 'admarkt', 'yandex_xml', 'glami' );
425
+ }
426
+ }
427
+ if ( ! function_exists( 'woo_feed_get_merchant_class' ) ) {
428
+ /**
429
+ * @param string $provider
430
+ *
431
+ * @return string
432
+ */
433
+ function woo_feed_get_merchant_class( $provider ) {
434
+ if ( in_array( $provider, [
435
+ 'google',
436
+ 'google_shopping_action',
437
+ 'google_local',
438
+ 'google_local_inventory',
439
+ 'adroll',
440
+ 'smartly.io'
441
+ ], true ) ) {
442
+ return 'Woo_Feed_Google';
443
+ } elseif ( in_array( $provider, array( 'pinterest', 'pinterest_rss' ) ) ) {
444
+ return 'Woo_Feed_Pinterest';
445
+ } elseif ( 'facebook' === $provider ) {
446
+ return 'Woo_Feed_Facebook';
447
+ } elseif ( strpos( $provider, 'amazon' ) !== false ) {
448
+ return 'Woo_Feed_Amazon';
449
+ } elseif ( in_array( $provider, woo_feed_get_custom2_merchant(), true ) ) {
450
+ return 'Woo_Feed_Custom_XML';
451
+ } else {
452
+ return 'Woo_Feed_Custom';
453
+ }
454
+ }
455
+ }
456
+ if ( ! function_exists( 'woo_feed_handle_file_transfer' ) ) {
457
+ /**
458
+ * Transfer file as per ftp config
459
+ *
460
+ * @param string $fileFrom
461
+ * @param string $fileTo
462
+ * @param array $info
463
+ *
464
+ * @return bool
465
+ */
466
+ function woo_feed_handle_file_transfer( $fileFrom, $fileTo, $info ) {
467
+ if ( 1 === (int) $info['ftpenabled'] ) {
468
+ if ( ! file_exists( $fileFrom ) ) {
469
+ woo_feed_log_feed_process( $info['filename'], 'Unable to process file transfer request. File does not exists.' );
470
+
471
+ return false;
472
+ }
473
+ $ftpHost = sanitize_text_field( $info['ftphost'] );
474
+ $ftp_user = sanitize_text_field( $info['ftpuser'] );
475
+ $ftp_password = sanitize_text_field( $info['ftppassword'] );
476
+ $ftpPath = trailingslashit( untrailingslashit( sanitize_text_field( $info['ftppath'] ) ) );
477
+ $ftp_passive_mode = ( isset( $info['ftpmode'] ) && sanitize_text_field( $info['ftpmode'] ) === 'passive' ) ? true : false;
478
+ if ( isset( $info['ftporsftp'] ) & 'ftp' === $info['ftporsftp'] ) {
479
+ $ftporsftp = 'ftp';
480
+ } else {
481
+ $ftporsftp = 'sftp';
482
+ }
483
+ if ( isset( $info['ftpport'] ) && ! empty( $info['ftpport'] ) ) {
484
+ $ftp_port = absint( $info['ftpport'] );
485
+ } else {
486
+ $ftp_port = false;
487
+ }
488
+
489
+ if ( ! $ftp_port || ! ( ( 1 <= $ftp_port ) && ( $ftp_port <= 65535 ) ) ) {
490
+ $ftp_port = 'sftp' === $ftporsftp ? 22 : 21;
491
+ }
492
+
493
+ woo_feed_log_feed_process( $info['filename'], sprintf( 'Uploading Feed file via %s.', $ftporsftp ) );
494
+
495
+ try {
496
+ if ( 'ftp' === $ftporsftp ) {
497
+
498
+ $ftp = new WebAppick\FTP\FTPConnection();
499
+ if ( $ftp->connect( $ftpHost, $ftp_user, $ftp_password, $ftp_passive_mode, $ftp_port ) ) {
500
+ return $ftp->upload_file( $fileFrom, $ftpPath . $fileTo );
501
+ }
502
+ } elseif ( 'sftp' === $ftporsftp ) {
503
+
504
+ $sftp = new WebAppick\FTP\SFTPConnection( $ftpHost, $ftp_port );
505
+ $sftp->login( $ftp_user, $ftp_password );
506
+
507
+ return $sftp->upload_file( $fileFrom, $fileTo, $ftpPath );
508
+
509
+ }
510
+ } catch ( Exception $e ) {
511
+ $message = 'Error Uploading Feed Via ' . $ftporsftp . PHP_EOL . 'Caught Exception :: ' . $e->getMessage();
512
+ woo_feed_log( $info['filename'], $message, 'critical', $e, true );
513
+ woo_feed_log_fatal_error( $message, $e );
514
+
515
+ return false;
516
+ }
517
+ }
518
+
519
+ return false;
520
+ }
521
+ }
522
+ if ( ! function_exists( 'woo_feed_get_file_types' ) ) {
523
+ function woo_feed_get_file_types() {
524
+ return array(
525
+ 'xml' => 'XML',
526
+ 'csv' => 'CSV',
527
+ 'tsv' => 'TSV',
528
+ 'xls' => 'XLS',
529
+ 'txt' => 'TXT',
530
+ 'json' => 'JSON',
531
+ );
532
+ }
533
+ }
534
+ if ( ! function_exists( 'woo_feed_get_default_brand' ) ) {
535
+ /**
536
+ * Guess Brand name from Site URL
537
+ *
538
+ * @return string
539
+ */
540
+ function woo_feed_get_default_brand() {
541
+ $brand = apply_filters( 'woo_feed_pre_get_default_brand_name', null );
542
+ if ( ! is_null( $brand ) ) {
543
+ return $brand;
544
+ }
545
+ $brand = '';
546
+ $url = filter_var( site_url(), FILTER_SANITIZE_URL );
547
+ if ( false !== $url ) {
548
+ $url = wp_parse_url( $url );
549
+ if ( array_key_exists( 'host', $url ) ) {
550
+ if ( strpos( $url['host'], "." ) !== false ) {
551
+ $arr = explode( '.', $url['host'] );
552
+ $brand = $arr[ count( $arr ) - 2 ];
553
+ $brand = ucfirst( $brand );
554
+ } else {
555
+ $brand = $url['host'];
556
+ $brand = ucfirst( $brand );
557
+ }
558
+ }
559
+ }
560
+
561
+ return apply_filters( 'woo_feed_get_default_brand_name', $brand );
562
+ }
563
+ }
564
+ if ( ! function_exists( 'woo_feed_merchant_require_google_category' ) ) {
565
+ /**
566
+ * Check if current merchant supports google taxonomy for current attribute.
567
+ *
568
+ * @param string $merchant
569
+ * @param string $attribute
570
+ *
571
+ * @return array|bool
572
+ */
573
+ function woo_feed_merchant_require_google_category( $merchant = null, $attribute = null ) {
574
+ $list = [
575
+ 'current_category' => [
576
+ 'google',
577
+ 'google_shopping_action',
578
+ 'google_local',
579
+ 'google_local_inventory',
580
+ 'facebook',
581
+ 'tiktok',
582
+ 'snapchat',
583
+ 'adroll',
584
+ 'smartly.io',
585
+ 'pinterest',
586
+ 'rakuten.de',
587
+ ],
588
+ 'fb_product_category' => [ 'facebook' ],
589
+ 'google_product_category' => [ 'rakuten.de', 'tiktok', 'snapchat' ],
590
+ 'google_category_id' => [
591
+ 'daisycon',
592
+ 'daisycon_automotive',
593
+ 'daisycon_books',
594
+ 'daisycon_cosmetics',
595
+ 'daisycon_daily_offers',
596
+ 'daisycon_electronics',
597
+ 'daisycon_food_drinks',
598
+ 'daisycon_home_garden',
599
+ 'daisycon_housing',
600
+ 'daisycon_fashion',
601
+ 'daisycon_studies_trainings',
602
+ 'daisycon_telecom_accessories',
603
+ 'daisycon_telecom_all_in_one',
604
+ 'daisycon_telecom_gsm_subscription',
605
+ 'daisycon_telecom_gsm',
606
+ 'daisycon_telecom_sim',
607
+ 'daisycon_magazines',
608
+ 'daisycon_holidays_accommodations',
609
+ 'daisycon_holidays_accommodations_and_transport',
610
+ 'daisycon_holidays_trips',
611
+ 'daisycon_work_jobs'
612
+ ],
613
+ ];
614
+ if ( null !== $merchant && null !== $attribute ) {
615
+ return ( isset( $list[ $attribute ] ) && in_array( $merchant, $list[ $attribute ], true ) );
616
+ }
617
+
618
+ return $list;
619
+ }
620
+ }
621
+ if ( ! function_exists( 'woo_feed_get_item_wrapper_hidden_merchant' ) ) {
622
+ function woo_feed_get_item_wrapper_hidden_merchant() {
623
+ return apply_filters(
624
+ 'woo_feed_item_wrapper_hidden_merchant',
625
+ [
626
+ 'google',
627
+ 'google_shopping_action',
628
+ 'facebook',
629
+ 'pinterest',
630
+ 'fruugo.au',
631
+ 'stylight.com',
632
+ 'nextad',
633
+ 'skinflint.co.uk',
634
+ 'comparer.be',
635
+ 'dooyoo',
636
+ 'hintaseuranta.fi',
637
+ 'incurvy',
638
+ 'kijiji.ca',
639
+ 'marktplaats.nl',
640
+ 'rakuten.de',
641
+ 'shopalike.fr',
642
+ 'spartoo.fi',
643
+ 'webmarchand',
644
+ 'skroutz',
645
+ 'daisycon',
646
+ 'daisycon_automotive',
647
+ 'daisycon_books',
648
+ 'daisycon_cosmetics',
649
+ 'daisycon_daily_offers',
650
+ 'daisycon_electronics',
651
+ 'daisycon_food_drinks',
652
+ 'daisycon_home_garden',
653
+ 'daisycon_housing',
654
+ 'daisycon_fashion',
655
+ 'daisycon_studies_trainings',
656
+ 'daisycon_telecom_accessories',
657
+ 'daisycon_telecom_all_in_one',
658
+ 'daisycon_telecom_gsm_subscription',
659
+ 'daisycon_telecom_gsm',
660
+ 'daisycon_telecom_sim',
661
+ 'daisycon_magazines',
662
+ 'daisycon_holidays_accommodations',
663
+ 'daisycon_holidays_accommodations_and_transport',
664
+ 'daisycon_holidays_trips',
665
+ 'daisycon_work_jobs',
666
+ ]
667
+ );
668
+ }
669
  }
670
 
671
  // The Editor.
672
+ if ( ! function_exists( 'woo_feed_parse_feed_rules' ) ) {
673
+ /**
674
+ * Parse Feed Config/Rules to make sure that necessary array keys are exists
675
+ * this will reduce the uses of isset() checking
676
+ *
677
+ * @param array $rules rules to parse.
678
+ * @param string $context parsing context. useful for filtering, view, save, db, create etc.
679
+ *
680
+ * @return array
681
+ * @since 3.3.5 $context parameter added.
682
+ *
683
+ * @uses wp_parse_args
684
+ *
685
+ */
686
+ function woo_feed_parse_feed_rules( $rules = [], $context = 'view' ) {
687
+
688
+ if ( empty( $rules ) ) {
689
+ $rules = [];
690
+ }
691
+ $defaults = [
692
+ 'provider' => '',
693
+ 'filename' => '',
694
+ 'feedType' => '',
695
+ 'feed_country' => '',
696
+ 'ftpenabled' => 0,
697
+ 'ftporsftp' => 'ftp',
698
+ 'ftphost' => '',
699
+ 'ftpport' => '21',
700
+ 'ftpuser' => '',
701
+ 'ftppassword' => '',
702
+ 'ftppath' => '',
703
+ 'ftpmode' => 'active',
704
+ 'is_variations' => 'y',
705
+ 'variable_price' => 'first',
706
+ 'variable_quantity' => 'first',
707
+ 'feedLanguage' => apply_filters( 'wpml_current_language', null ),
708
+ 'feedCurrency' => get_woocommerce_currency(),
709
+ 'itemsWrapper' => 'products',
710
+ 'itemWrapper' => 'product',
711
+ 'delimiter' => ',',
712
+ 'enclosure' => 'double',
713
+ 'extraHeader' => '',
714
+ 'vendors' => [],
715
+ // Feed Config
716
+ 'mattributes' => [], // merchant attributes
717
+ 'prefix' => [], // prefixes
718
+ 'type' => [], // value (attribute) types
719
+ 'attributes' => [], // product attribute mappings
720
+ 'default' => [], // default values (patterns) if value type set to pattern
721
+ 'suffix' => [], // suffixes
722
+ 'output_type' => [], // output type (output filter)
723
+ 'limit' => [], // limit or command
724
+ // filters tab
725
+ 'composite_price' => '',
726
+ 'shipping_country' => '',
727
+ 'tax_country' => '',
728
+ 'product_ids' => '',
729
+ 'categories' => [],
730
+ 'post_status' => [ 'publish' ],
731
+ 'filter_mode' => [],
732
+ 'campaign_parameters' => [],
733
+
734
+ 'ptitle_show' => '',
735
+ 'decimal_separator' => wc_get_price_decimal_separator(),
736
+ 'thousand_separator' => wc_get_price_thousand_separator(),
737
+ 'decimals' => wc_get_price_decimals(),
738
+ ];
739
+ $rules = wp_parse_args( $rules, $defaults );
740
+ $rules['filter_mode'] = wp_parse_args( $rules['filter_mode'],
741
+ [
742
+ 'product_ids' => 'include',
743
+ 'categories' => 'include',
744
+ 'post_status' => 'include',
745
+ ] );
746
+
747
+ $rules['campaign_parameters'] = wp_parse_args(
748
+ $rules['campaign_parameters'],
749
+ [
750
+ 'utm_source' => '',
751
+ 'utm_medium' => '',
752
+ 'utm_campaign' => '',
753
+ 'utm_term' => '',
754
+ 'utm_content' => '',
755
+ ]
756
+ );
757
+
758
+ if ( ! empty( $rules['provider'] ) && is_string( $rules['provider'] ) ) {
759
+ /**
760
+ * filter parsed rules for provider
761
+ *
762
+ * @param array $rules
763
+ * @param string $context
764
+ *
765
+ * @since 3.3.7
766
+ *
767
+ */
768
+ $rules = apply_filters( "woo_feed_{$rules['provider']}_parsed_rules", $rules, $context );
769
+ }
770
+
771
+ /**
772
+ * filter parsed rules
773
+ *
774
+ * @param array $rules
775
+ * @param string $context
776
+ *
777
+ * @since 3.3.7 $provider parameter removed
778
+ *
779
+ */
780
+ return apply_filters( 'woo_feed_parsed_rules', $rules, $context );
781
+ }
782
+ }
783
+ if ( ! function_exists( 'woo_feed_register_and_do_woo_feed_meta_boxes' ) ) {
784
+ /**
785
+ * Registers the default Feed Editor MetaBoxes, and runs the `do_meta_boxes` actions.
786
+ *
787
+ * @param string|WP_Screen $screen Screen identifier. If you have used add_menu_page() or
788
+ * add_submenu_page() to create a new screen (and hence screen_id)
789
+ * make sure your menu slug conforms to the limits of sanitize_key()
790
+ * otherwise the 'screen' menu may not correctly render on your page.
791
+ * @param array $feedRules current feed being processed.
792
+ *
793
+ * @return void
794
+ * @see register_and_do_post_meta_boxes()
795
+ *
796
+ * @since 3.2.6
797
+ *
798
+ */
799
+ function woo_feed_register_and_do_woo_feed_meta_boxes( $screen, $feedRules = array() ) {
800
+ if ( empty( $screen ) ) {
801
+ $screen = get_current_screen();
802
+ } elseif ( is_string( $screen ) ) {
803
+ $screen = convert_to_screen( $screen );
804
+ }
805
+ // edit page MetaBoxes
806
+ if ( 'ctx-feed_page_webappick-new-feed' === $screen->id || 'toplevel_page_webappick-manage-feeds' === $screen->id ) {
807
+ add_meta_box( 'feed_merchant_info', 'Feed Merchant Info', 'woo_feed_merchant_info_metabox', null, 'side', 'default' );
808
+ }
809
+ /**
810
+ * This action is documented in wp-admin/includes/meta-boxes.php
811
+ * using screen id instead of post type
812
+ */
813
+ do_action( 'add_meta_boxes', $screen->id, $feedRules );
814
+ do_action( "add_meta_boxes_{$screen->id}", $feedRules );
815
+ do_action( 'do_meta_boxes', $screen->id, 'normal', $feedRules );
816
+ do_action( 'do_meta_boxes', $screen->id, 'advanced', $feedRules );
817
+ do_action( 'do_meta_boxes', $screen->id, 'side', $feedRules );
818
+ }
819
+ }
820
+ if ( ! function_exists( 'woo_feed_ajax_merchant_info' ) ) {
821
+ add_action( 'wp_ajax_woo_feed_get_merchant_info', 'woo_feed_ajax_merchant_info' );
822
+ function woo_feed_ajax_merchant_info() {
823
+ if ( isset( $_REQUEST['nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) ),
824
+ 'wpf_feed_nonce' ) ) {
825
+ $provider = ( isset( $_REQUEST['provider'] ) && ! empty( $_REQUEST['provider'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST['provider'] ) ) : '';
826
+ $merchantInfo = new Woo_Feed_Merchant( $provider );
827
+ $data = [];
828
+ $na = esc_html__( 'N/A', 'woo-feed' );
829
+ foreach ( $merchantInfo->get_info() as $k => $v ) {
830
+ if ( 'link' === $k ) {
831
+ /** @noinspection HtmlUnknownTarget */
832
+ $data[ $k ] = empty( $v ) ? $na : sprintf( '<a href="%s" target="_blank">%s</a>',
833
+ esc_url( $v ),
834
+ esc_html__( 'Read Article', 'woo-feed' ) );
835
+ } elseif ( 'video' === $k ) {
836
+ /** @noinspection HtmlUnknownTarget */
837
+ $data[ $k ] = empty( $v ) ? $na : sprintf( '<a href="%s" target="_blank">%s</a>',
838
+ esc_url( $v ),
839
+ esc_html__( 'Watch Now', 'woo-feed' ) );
840
+ } elseif ( 'feed_file_type' === $k ) {
841
+ if ( ! empty( $v ) ) {
842
+ $v = array_map( function ( $type ) {
843
+ return strtoupper( $type );
844
+ },
845
+ (array) $v );
846
+ $data[ $k ] = esc_html( implode( ', ', $v ) );
847
+ } else {
848
+ $data[ $k ] = $na;
849
+ }
850
+ } elseif ( 'doc' === $k ) {
851
+ $links = '';
852
+ foreach ( $v as $label => $link ) {
853
+ /** @noinspection HtmlUnknownTarget */
854
+ $links .= sprintf( '<li><a href="%s" target="_blank">%s</a></li>',
855
+ esc_url( $link ),
856
+ esc_html( $label ) );
857
+ }
858
+ $data[ $k ] = empty( $links ) ? $na : $links;
859
+ }
860
+ }
861
+ wp_send_json_success( $data );
862
+ } else {
863
+ wp_send_json_error( esc_html__( 'Invalid Request.', 'woo-feed' ) );
864
+ }
865
+ die();
866
+ }
867
+ }
868
+ if ( ! function_exists( 'woo_feed_merchant_info_metabox' ) ) {
869
+ /**
870
+ * Render Merchant Info Metabox
871
+ *
872
+ * @param array $feedConfig
873
+ *
874
+ * @return void
875
+ */
876
+ function woo_feed_merchant_info_metabox( $feedConfig ) {
877
+ $provider = ( isset( $feedConfig['provider'] ) && ! empty( $feedConfig['provider'] ) ) ? $feedConfig['provider'] : '';
878
+ $merchantInfo = new Woo_Feed_Merchant( $provider );
879
+
880
+ //get feed options
881
+ if ( isset( $_GET['feed'] ) ) {
882
+ $filename = str_replace( 'wf_feed_', '', wp_unslash( $_GET['feed'] ) );
883
+ $feed_options = maybe_unserialize( get_option( 'wf_feed_' . $filename ) );
884
+ }
885
+ ?>
886
  <span class="spinner"></span>
887
  <div class="merchant-infos">
888
+ <?php foreach ( $merchantInfo->get_info() as $k => $v ) { ?>
889
+ <div class="merchant-info-section <?php echo esc_attr( $k ); ?>">
890
+ <?php if ( 'link' === $k ) { ?>
891
  <span class="dashicons dashicons-media-document" style="color: #82878c;"
892
  aria-hidden="true"></span>
893
+ <span><?php esc_html_e( 'Feed Specification:', 'woo-feed' ); ?></span>
894
  <strong class="data">
895
+ <?php
896
+ /** @noinspection HtmlUnknownTarget */
897
+ ( empty( $v ) ) ? esc_html_e( 'N/A',
898
+ 'woo-feed' ) : printf( '<a href="%s" target="_blank">%s</a>',
899
+ esc_url( $v ),
900
+ esc_html__( 'Read Article', 'woo-feed' ) );
901
+ ?>
902
  </strong>
903
+ <?php } elseif ( 'video' === $k ) { ?>
904
  <span class="dashicons dashicons-video-alt3" style="color: #82878c;" aria-hidden="true"></span>
905
+ <span><?php esc_html_e( 'Video Documentation:', 'woo-feed' ); ?></span>
906
  <strong class="data">
907
+ <?php
908
+ /** @noinspection HtmlUnknownTarget */
909
+ ( empty( $v ) ) ? esc_html_e( 'N/A',
910
+ 'woo-feed' ) : printf( '<a href="%s" target="_blank">%s</a>',
911
+ esc_url( $v ),
912
+ esc_html__( 'Watch now', 'woo-feed' ) );
913
+ ?>
914
  </strong>
915
+ <?php } elseif ( 'feed_file_type' === $k ) { ?>
916
  <span class="dashicons dashicons-media-text" style="color: #82878c;"
917
+ aria-hidden="true"></span> <?php esc_html_e( 'Supported File Types:', 'woo-feed' ); ?>
918
  <strong class="data" style="display: block;padding-left: 24px;margin-top: 5px;">
919
+ <?php
920
+ if ( empty( $v ) ) {
921
+ esc_html_e( 'N/A', 'woo-feed' );
922
+ } else {
923
+ $v = implode( ', ',
924
+ array_map( function ( $type ) {
925
+ return esc_html( strtoupper( $type ) );
926
+ },
927
+ (array) $v ) );
928
+ echo esc_html( $v );
929
+ }
930
+ ?>
931
  </strong>
932
+ <?php
933
+ } elseif ( 'doc' === $k ) {
934
+ ?>
935
  <span class="dashicons dashicons-editor-help" style="color: #82878c;" aria-hidden="true"></span>
936
+ <span><?php esc_html_e( 'Support Docs:', 'woo-feed' ); ?></span>
937
  <ul class="data">
938
+ <?php
939
+ if ( empty( $v ) ) {
940
+ esc_html_e( 'N/A', 'woo-feed' );
941
+ } else {
942
+ foreach ( $v as $label => $link ) {
943
+ /** @noinspection HtmlUnknownTarget */
944
+ printf( '<li><a href="%s" target="_blank">%s</a></li>',
945
+ esc_url( $link ),
946
+ esc_html( $label ) );
947
+ }
948
+ }
949
+ ?>
950
  </ul>
951
+ <?php
952
+ }
953
+ ?>
954
  </div>
955
+ <?php } ?>
956
  <div class="merchant-info-section woo-feed-open-file">
957
+ <?php
958
+ if ( isset( $feed_options['url'] ) && ! empty( $feed_options['url'] ) ) {
959
+ echo sprintf(
960
+ '<a href="%1$s" title="%2$s" aria-label="%2$s" target="_blank"><span class="dashicons dashicons-external" aria-hidden="true"></span> %3$s</a>',
961
+ $feed_options['url'],
962
+ esc_html__( 'View', 'woo-feed' ),
963
+ esc_html__( 'Open Feed File', 'woo-feed' )
964
+ );
965
+ }
966
+ ?>
967
  </div>
968
  </div>
969
+ <?php
970
+ }
971
+ }
972
+ if ( ! function_exists( 'woo_feed_get_csv_delimiters' ) ) {
973
+ /**
974
+ * Get CSV/TXT/TSV Delimiters
975
+ * @return array
976
+ */
977
+ function woo_feed_get_csv_delimiters() {
978
+ return [
979
+ ',' => 'Comma',
980
+ ':' => 'Colon',
981
+ ' ' => 'Space',
982
+ '|' => 'Pipe',
983
+ ';' => 'Semi Colon',
984
+ "\t" => 'TAB',
985
+ ];
986
+ }
987
+ }
988
+ if ( ! function_exists( 'woo_feed_get_csv_enclosure' ) ) {
989
+ /**
990
+ * Get CSV/TXT/TSV Enclosure for multiple words
991
+ * @return array
992
+ */
993
+ function woo_feed_get_csv_enclosure() {
994
+ return [
995
+ 'double' => '"',
996
+ 'single' => '\'',
997
+ ' ' => 'None',
998
+ ];
999
+ }
1000
  }
1001
 
1002
  // Editor Tabs.
1003
+ if ( ! function_exists( 'render_feed_config' ) ) {
1004
+ /**
1005
+ * @param string $tabId
1006
+ * @param array $feedRules
1007
+ * @param bool $idEdit
1008
+ */
1009
+ function render_feed_config( $tabId, $feedRules, $idEdit ) {
1010
+ global $provider, $wooFeedDropDown, $merchant;
1011
+ include WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-edit-config.php';
1012
+ }
1013
+ }
1014
+ if ( ! function_exists( 'render_filter_config' ) ) {
1015
+ /**
1016
+ * @param string $tabId
1017
+ * @param array $feedRules
1018
+ * @param bool $idEdit
1019
+ */
1020
+ function render_filter_config( $tabId, $feedRules, $idEdit ) {
1021
+ global $provider, $wooFeedDropDown, $merchant;
1022
+ include WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-edit-filter.php';
1023
+ }
1024
+ }
1025
+ if ( ! function_exists( 'render_ftp_config' ) ) {
1026
+ /**
1027
+ * @param string $tabId
1028
+ * @param array $feedRules
1029
+ * @param bool $idEdit
1030
+ */
1031
+ function render_ftp_config( $tabId, $feedRules, $idEdit ) {
1032
+ global $provider, $wooFeedDropDown, $merchant;
1033
+ include WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-edit-ftp.php';
1034
+ }
1035
  }
1036
 
1037
  // Sanitization.
1038
+ if ( ! function_exists( 'woo_feed_check_google_category' ) ) {
1039
+ /**
1040
+ * @param array $feedInfo
1041
+ *
1042
+ * @return string
1043
+ */
1044
+ function woo_feed_check_google_category( $feedInfo ) {
1045
+ // Check Google Product Category for Google & Facebook Template and show message.
1046
+ $list = woo_feed_merchant_require_google_category();
1047
+ $cat_keys = array_keys( $list );
1048
+ $merchants = call_user_func_array( 'array_merge', array_values( $list ) );
1049
+ $checkCategory = isset( $feedInfo['feedrules']['mattributes'] ) ? $feedInfo['feedrules']['mattributes'] : [];
1050
+ $checkCategoryType = isset( $feedInfo['feedrules']['type'] ) ? $feedInfo['feedrules']['type'] : [];
1051
+ $merchant = isset( $feedInfo['feedrules']['provider'] ) ? $feedInfo['feedrules']['provider'] : [];
1052
+ $cat = 'yes';
1053
+ foreach ( $list as $attribute => $merchants ) {
1054
+ if ( in_array( $merchant, $merchants, true ) && in_array( $attribute, $checkCategory, true ) ) {
1055
+ $catKey = array_search( $attribute, $checkCategory, true );
1056
+ if ( 'pattern' === $checkCategoryType[ $catKey ] ) {
1057
+ $checkCategoryValue = $feedInfo['feedrules']['default'];
1058
+ } else {
1059
+ $checkCategoryValue = $feedInfo['feedrules']['attributes'];
1060
+ }
1061
+
1062
+ if ( empty( $checkCategoryValue[ $catKey ] ) ) {
1063
+ $cat = 'no';
1064
+ }
1065
+ break;
1066
+ }
1067
+ }
1068
+
1069
+ return $cat;
1070
+ }
1071
+ }
1072
+ if ( ! function_exists( 'woo_feed_array_sanitize' ) ) {
1073
+ /**
1074
+ * Sanitize array post
1075
+ *
1076
+ * @param array $array
1077
+ *
1078
+ * @return array
1079
+ */
1080
+ function woo_feed_array_sanitize( $array ) {
1081
+ $newArray = array();
1082
+ if ( count( $array ) ) {
1083
+ foreach ( $array as $key => $value ) {
1084
+ if ( is_array( $value ) ) {
1085
+ foreach ( $value as $key2 => $value2 ) {
1086
+ if ( is_array( $value2 ) ) {
1087
+ foreach ( $value2 as $key3 => $value3 ) {
1088
+ $newArray[ $key ][ $key2 ][ $key3 ] = sanitize_text_field( $value3 );
1089
+ }
1090
+ } else {
1091
+ $newArray[ $key ][ $key2 ] = sanitize_text_field( $value2 );
1092
+ }
1093
+ }
1094
+ } else {
1095
+ $newArray[ $key ] = sanitize_text_field( $value );
1096
+ }
1097
+ }
1098
+ }
1099
+
1100
+ return $newArray;
1101
+ }
1102
+ }
1103
+ if ( ! function_exists( 'woo_feed_sanitize_form_fields' ) ) {
1104
+ /**
1105
+ * Sanitize Form Fields ($_POST Array)
1106
+ *
1107
+ * @param array $data
1108
+ *
1109
+ * @return array
1110
+ */
1111
+ function woo_feed_sanitize_form_fields( $data ) {
1112
+ foreach ( $data as $k => $v ) {
1113
+ if ( true === apply_filters( 'woo_feed_sanitize_form_fields', true, $k, $v, $data ) ) {
1114
+ if ( is_array( $v ) ) {
1115
+ $v = woo_feed_sanitize_form_fields( $v );
1116
+ } else {
1117
+ // $v = sanitize_text_field( $v ); #TODO should not trim Prefix and Suffix field
1118
+ }
1119
+ }
1120
+ $data[ $k ] = apply_filters( 'woo_feed_sanitize_form_field', $v, $k );
1121
+ }
1122
+
1123
+ return $data;
1124
+ }
1125
+ }
1126
+ if ( ! function_exists( 'woo_feed_unique_feed_slug' ) ) {
1127
+ /**
1128
+ * Generate Unique slug for feed.
1129
+ * This function only check database for existing feed for generating unique slug.
1130
+ * Use generate_unique_feed_file_name() for complete unique slug name.
1131
+ *
1132
+ * @param string $slug slug for checking uniqueness.
1133
+ * @param string $prefix prefix to check with. Optional.
1134
+ * @param int $option_id option id. Optional option id to exclude specific option.
1135
+ *
1136
+ * @return string
1137
+ * @see wp_unique_post_slug()
1138
+ *
1139
+ */
1140
+ function woo_feed_unique_feed_slug( $slug, $prefix = '', $option_id = null ) {
1141
+ global $wpdb;
1142
+ /** @noinspection SpellCheckingInspection */
1143
+ $disallowed = array( 'siteurl', 'home', 'blogname', 'blogdescription', 'users_can_register', 'admin_email' );
1144
+ if ( $option_id && $option_id > 0 ) {
1145
+ $checkSql = "SELECT option_name FROM $wpdb->options WHERE option_name = %s AND option_id != %d LIMIT 1";
1146
+ $nameCheck = $wpdb->get_var( $wpdb->prepare( $checkSql, $prefix . $slug, $option_id ) ); // phpcs:ignore
1147
+ } else {
1148
+ $checkSql = "SELECT option_name FROM $wpdb->options WHERE option_name = %s LIMIT 1";
1149
+ $nameCheck = $wpdb->get_var( $wpdb->prepare( $checkSql, $prefix . $slug ) ); // phpcs:ignore
1150
+ }
1151
+ // slug found or slug in disallowed list
1152
+ if ( $nameCheck || in_array( $slug, $disallowed, true ) ) {
1153
+ $suffix = 2;
1154
+ do {
1155
+ $altName = _truncate_post_slug( $slug, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
1156
+ if ( $option_id && $option_id > 0 ) {
1157
+ $nameCheck = $wpdb->get_var( $wpdb->prepare( $checkSql, $prefix . $altName, $option_id ) ); // phpcs:ignore
1158
+ } else {
1159
+ $nameCheck = $wpdb->get_var( $wpdb->prepare( $checkSql, $prefix . $altName ) ); // phpcs:ignore
1160
+ }
1161
+ $suffix ++;
1162
+ } while ( $nameCheck );
1163
+ $slug = $altName;
1164
+ }
1165
+
1166
+ return $slug;
1167
+ }
1168
+ }
1169
+ if ( ! function_exists( 'woo_feed_unique_option_name' ) ) {
1170
+ /**
1171
+ * Alias of woo_feed_unique_feed_slug
1172
+ *
1173
+ * @param string $slug
1174
+ * @param string $prefix
1175
+ * @param null $option_id
1176
+ *
1177
+ * @return string
1178
+ * @see woo_feed_unique_feed_slug
1179
+ *
1180
+ * @since 3.3.8
1181
+ *
1182
+ */
1183
+ function woo_feed_unique_option_name( $slug, $prefix = '', $option_id = null ) {
1184
+ return woo_feed_unique_feed_slug( $slug, $prefix, $option_id );
1185
+ }
1186
+ }
1187
+ if ( ! function_exists( 'generate_unique_feed_file_name' ) ) {
1188
+ /**
1189
+ * Generate Unique file Name.
1190
+ * This will insure unique slug and file name for a single feed.
1191
+ *
1192
+ * @param string $filename
1193
+ * @param string $type
1194
+ * @param string $provider
1195
+ *
1196
+ * @return string|string[]
1197
+ */
1198
+ function generate_unique_feed_file_name( $filename, $type, $provider ) {
1199
+
1200
+ $feedDir = woo_feed_get_file_dir( $provider, $type );
1201
+ $raw_filename = sanitize_title( $filename, '', 'save' );
1202
+ // check option name uniqueness ...
1203
+ $raw_filename = woo_feed_unique_feed_slug( $raw_filename, 'wf_feed_' );
1204
+ $raw_filename = sanitize_file_name( $raw_filename . '.' . $type );
1205
+ $raw_filename = wp_unique_filename( $feedDir, $raw_filename );
1206
+ $raw_filename = str_replace( '.' . $type, '', $raw_filename );
1207
+
1208
+ return - 1 !== (int) $raw_filename ? $raw_filename : false;
1209
+ }
1210
  }
1211
 
1212
  // File process.
1213
+ if ( ! function_exists( 'woo_feed_check_valid_extension' ) ) {
1214
+ /**
1215
+ * Check Feed File Extension Validity
1216
+ *
1217
+ * @param string $extension Ext to check.
1218
+ *
1219
+ * @return bool
1220
+ */
1221
+ function woo_feed_check_valid_extension( $extension ) {
1222
+ return in_array( $extension, array_keys( woo_feed_get_file_types() ), true );
1223
+ }
1224
+ }
1225
+ if ( ! function_exists( 'woo_feed_save_feed_config_data' ) ) {
1226
+ /**
1227
+ * Sanitize And Save Feed config data (array) to db (option table)
1228
+ *
1229
+ * @param array $data data to be saved in db
1230
+ * @param null $feed_option_name feed (file) name. optional, if empty or null name will be auto generated
1231
+ * @param bool $configOnly save only wf_config or both wf_config and wf_feed_. default is only wf_config
1232
+ *
1233
+ * @return bool|string return false if failed to update. return filename if success
1234
+ */
1235
+ function woo_feed_save_feed_config_data( $data, $feed_option_name = null, $configOnly = true ) {
1236
+ if ( ! is_array( $data ) ) {
1237
+ return false;
1238
+ }
1239
+ if ( ! isset( $data['filename'], $data['feedType'], $data['provider'] ) ) {
1240
+ return false;
1241
+ }
1242
+ // unnecessary form fields to remove
1243
+ $removables = [ 'closedpostboxesnonce', '_wpnonce', '_wp_http_referer', 'save_feed_config', 'edit-feed' ];
1244
+ foreach ( $removables as $removable ) {
1245
+ if ( isset( $data[ $removable ] ) ) {
1246
+ unset( $data[ $removable ] );
1247
+ }
1248
+ }
1249
+ // parse rules
1250
+ $data = woo_feed_parse_feed_rules( $data );
1251
+ // Sanitize Fields
1252
+ $data = woo_feed_sanitize_form_fields( $data );
1253
+ if ( empty( $feed_option_name ) ) {
1254
+ $feed_option_name = generate_unique_feed_file_name(
1255
+ $data['filename'],
1256
+ $data['feedType'],
1257
+ $data['provider'] );
1258
+ } else {
1259
+ $feed_option_name = woo_feed_extract_feed_option_name( $feed_option_name );
1260
+ }
1261
+
1262
+ // get old config
1263
+ $old_data = get_option( 'wf_config' . $feed_option_name, array() );
1264
+ $update = false;
1265
+ $updated = false;
1266
+ if ( is_array( $old_data ) && ! empty( $old_data ) ) {
1267
+ $update = true;
1268
+ }
1269
+
1270
+ /**
1271
+ * Filters feed data just before it is inserted into the database.
1272
+ *
1273
+ * @param array $data An array of sanitized config
1274
+ * @param array $old_data An array of old feed data
1275
+ * @param string $feed_option_name Option name
1276
+ *
1277
+ * @since 3.3.3
1278
+ *
1279
+ */
1280
+ $data = apply_filters( 'woo_feed_insert_feed_data', $data, $old_data, 'wf_config' . $feed_option_name );
1281
+
1282
+ if ( $update ) {
1283
+ /**
1284
+ * Before Updating Config to db
1285
+ *
1286
+ * @param array $data An array of sanitized config
1287
+ * @param string $feed_option_name Option name
1288
+ */
1289
+ do_action( 'woo_feed_before_update_config', $data, 'wf_config' . $feed_option_name );
1290
+ } else {
1291
+ /**
1292
+ * Before inserting Config to db
1293
+ *
1294
+ * @param array $data An array of sanitized config
1295
+ * @param string $feed_option_name Option name
1296
+ */
1297
+ do_action( 'woo_feed_before_insert_config', $data, 'wf_config' . $feed_option_name );
1298
+ }
1299
+ $updated = ( $data === $old_data );
1300
+ if ( false === $updated ) {
1301
+ // Store Config.
1302
+ $updated = update_option( 'wf_config' . $feed_option_name, $data, false );
1303
+ }
1304
+ // update wf_feed if wp_config update ok...
1305
+ if ( $updated && false === $configOnly ) {
1306
+ $old_feed = maybe_unserialize( get_option( 'wf_feed_' . $feed_option_name ) );
1307
+ $feed_data = array(
1308
+ 'feedrules' => $data,
1309
+ 'url' => woo_feed_get_file_url( $feed_option_name, $data['provider'], $data['feedType'] ),
1310
+ 'last_updated' => date( 'Y-m-d H:i:s', strtotime( current_time( 'mysql' ) ) ),
1311
+ 'status' => isset( $old_feed['status'] ) && 1 === (int) $old_feed['status'] ? 1 : 0,
1312
+ // set old status or disable auto update.
1313
+ );
1314
+
1315
+ $saved2 = update_option( 'wf_feed_' . $feed_option_name, maybe_serialize( $feed_data ), false );
1316
+ }
1317
+
1318
+ if ( $update ) {
1319
+ /**
1320
+ * After Updating Config to db
1321
+ *
1322
+ * @param array $data An array of sanitized config
1323
+ * @param string $feed_option_name Option name
1324
+ */
1325
+ do_action( 'woo_feed_after_update_config', $data, 'wf_config' . $feed_option_name );
1326
+ } else {
1327
+ /**
1328
+ * After inserting Config to db
1329
+ *
1330
+ * @param array $data An array of sanitized config
1331
+ * @param string $feed_option_name Option name
1332
+ */
1333
+ do_action( 'woo_feed_after_insert_config', $data, 'wf_config' . $feed_option_name );
1334
+ }
1335
+
1336
+ // return filename on success or update status
1337
+ return $updated ? $feed_option_name : $updated;
1338
+ }
1339
+ }
1340
+ if ( ! function_exists( 'woo_feed_extract_feed_option_name' ) ) {
1341
+ /**
1342
+ * Remove Feed Option Name Prefix and return the slug
1343
+ *
1344
+ * @param string $feed_option_name
1345
+ *
1346
+ * @return string
1347
+ */
1348
+ function woo_feed_extract_feed_option_name( $feed_option_name ) {
1349
+ return str_replace( [ 'wf_feed_', 'wf_config' ], '', $feed_option_name );
1350
+ }
1351
+ }
1352
+ if ( ! function_exists( 'woo_feed_get_file_path' ) ) {
1353
+ /**
1354
+ * Get File Path for feed or the file upload path for the plugin to use.
1355
+ *
1356
+ * @param string $provider provider name.
1357
+ * @param string $type feed file type.
1358
+ *
1359
+ * @return string
1360
+ */
1361
+ function woo_feed_get_file_path( $provider = '', $type = '' ) {
1362
+ $upload_dir = wp_get_upload_dir();
1363
+
1364
+ return sprintf( '%s/woo-feed/%s/%s/', $upload_dir['basedir'], $provider, $type );
1365
+ }
1366
+ }
1367
+ if ( ! function_exists( 'woo_feed_get_file' ) ) {
1368
+ /**
1369
+ * Get Feed File URL
1370
+ *
1371
+ * @param string $fileName
1372
+ * @param string $provider
1373
+ * @param string $type
1374
+ *
1375
+ * @return string
1376
+ */
1377
+ function woo_feed_get_file( $fileName, $provider, $type ) {
1378
+ $fileName = woo_feed_extract_feed_option_name( $fileName );
1379
+ $path = woo_feed_get_file_path( $provider, $type );
1380
+
1381
+ return sprintf( '%s/%s.%s', untrailingslashit( $path ), $fileName, $type );
1382
+ }
1383
+ }
1384
+ if ( ! function_exists( 'woo_feed_get_file_url' ) ) {
1385
+ /**
1386
+ * Get Feed File URL
1387
+ *
1388
+ * @param string $fileName
1389
+ * @param string $provider
1390
+ * @param string $type
1391
+ *
1392
+ * @return string
1393
+ */
1394
+ function woo_feed_get_file_url( $fileName, $provider, $type ) {
1395
+ $fileName = woo_feed_extract_feed_option_name( $fileName );
1396
+ $upload_dir = wp_get_upload_dir();
1397
+
1398
+ return esc_url( sprintf( '%s/woo-feed/%s/%s/%s.%s',
1399
+ $upload_dir['baseurl'],
1400
+ $provider,
1401
+ $type,
1402
+ $fileName,
1403
+ $type ) );
1404
+ }
1405
+ }
1406
+ if ( ! function_exists( 'woo_feed_check_feed_file' ) ) {
1407
+ /**
1408
+ * Check if feed file exists
1409
+ *
1410
+ * @param string $fileName
1411
+ * @param string $provider
1412
+ * @param string $type
1413
+ *
1414
+ * @return bool
1415
+ */
1416
+ function woo_feed_check_feed_file( $fileName, $provider, $type ) {
1417
+ $upload_dir = wp_get_upload_dir();
1418
+
1419
+ return file_exists( sprintf( '%s/woo-feed/%s/%s/%s.%s',
1420
+ $upload_dir['basedir'],
1421
+ $provider,
1422
+ $type,
1423
+ $fileName,
1424
+ $type ) );
1425
+ }
1426
+ }
1427
+ if ( ! function_exists( 'woo_feed_get_file_dir' ) ) {
1428
+ /**
1429
+ * Get Feed Directory
1430
+ *
1431
+ * @param string $provider
1432
+ * @param string $feedType
1433
+ *
1434
+ * @return string
1435
+ */
1436
+ function woo_feed_get_file_dir( $provider, $feedType ) {
1437
+ $upload_dir = wp_get_upload_dir();
1438
+
1439
+ return sprintf( '%s/woo-feed/%s/%s', $upload_dir['basedir'], $provider, $feedType );
1440
+ }
1441
+ }
1442
+ if ( ! function_exists( 'woo_feed_save_batch_feed_info' ) ) {
1443
+ /**
1444
+ * Save Feed Batch Chunk
1445
+ *
1446
+ * @param string $feedService merchant.
1447
+ * @param string $type file type (ext).
1448
+ * @param string|array $string data.
1449
+ * @param string $fileName file name.
1450
+ * @param array $info feed config.
1451
+ *
1452
+ * @return bool
1453
+ */
1454
+ function woo_feed_save_batch_feed_info( $feedService, $type, $string, $fileName, $info ) {
1455
+ $ext = $type;
1456
+ if ( 'csv' === $type || 'tsv' === $type || 'xls' === $type || 'json' === $type ) {
1457
+ $string = wp_json_encode( $string );
1458
+ $ext = 'json';
1459
+ }
1460
+ // Save File.
1461
+ $path = woo_feed_get_file_dir( $feedService, $type );
1462
+ $file = $path . '/' . $fileName . '.' . $ext;
1463
+ $save = new Woo_Feed_Savefile();
1464
+ $status = $save->saveFile( $path, $file, $string );
1465
+ if ( woo_feed_is_debugging_enabled() ) {
1466
+ if ( $status ) {
1467
+ $message = sprintf( 'Batch chunk file (%s) saved.', $fileName );
1468
+ } else {
1469
+ $message = sprintf( 'Unable to save batch chunk file %s.', $fileName );
1470
+ }
1471
+ woo_feed_log_feed_process( $info['filename'], $message );
1472
+ }
1473
+
1474
+ return $status;
1475
+ }
1476
+ }
1477
+ if ( ! function_exists( 'woo_feed_get_batch_feed_info' ) ) {
1478
+ /**
1479
+ * @param string $feedService
1480
+ * @param string $type
1481
+ * @param string $fileName
1482
+ *
1483
+ * @return bool|array|string
1484
+ */
1485
+ function woo_feed_get_batch_feed_info( $feedService, $type, $fileName ) {
1486
+ $ext = $type;
1487
+ if ( 'csv' === $type || 'tsv' === $type || 'xls' === $type || 'json' === $type ) {
1488
+ $ext = 'json';
1489
+ }
1490
+ // Save File
1491
+ $path = woo_feed_get_file_dir( $feedService, $type );
1492
+ $file = $path . '/' . $fileName . '.' . $ext;
1493
+ if ( ! file_exists( $file ) ) {
1494
+ return false;
1495
+ }
1496
+
1497
+ $data = file_get_contents( $file ); // phpcs:ignore
1498
+
1499
+ if ( 'csv' === $type || 'tsv' === $type || 'xls' === $type || 'json' === $type ) {
1500
+ $data = ( $data ) ? json_decode( $data, true ) : false;
1501
+ }
1502
+
1503
+ return $data;
1504
+ }
1505
+ }
1506
+ if ( ! function_exists( 'woo_feed_unlink_tempFiles' ) ) {
1507
+ /**
1508
+ * Remove temporary feed files
1509
+ *
1510
+ * @param array $config Feed config
1511
+ * @param string $fileName feed file name.
1512
+ *
1513
+ * @return void
1514
+ */
1515
+ function woo_feed_unlink_tempFiles( $config, $fileName ) {
1516
+ $type = $config['feedType'];
1517
+ $ext = $type;
1518
+ $path = woo_feed_get_file_dir( $config['provider'], $type );
1519
+
1520
+ if ( 'csv' === $type || 'tsv' === $type || 'xls' === $type ) {
1521
+ $ext = 'json';
1522
+ }
1523
+ $files = [
1524
+ 'headerFile' => $path . '/' . 'wf_store_feed_header_info_' . $fileName . '.' . $ext,
1525
+ 'bodyFile' => $path . '/' . 'wf_store_feed_body_info_' . $fileName . '.' . $ext,
1526
+ 'footerFile' => $path . '/' . 'wf_store_feed_footer_info_' . $fileName . '.' . $ext,
1527
+ ];
1528
+
1529
+ woo_feed_log_feed_process( $config['filename'], sprintf( 'Deleting Temporary Files (%s).', implode( ', ', array_values( $files ) ) ) );
1530
+ foreach ( $files as $key => $file ) {
1531
+ if ( file_exists( $file ) ) {
1532
+ unlink( $file ); // phpcs:ignore
1533
+ }
1534
+ }
1535
+ }
1536
+ }
1537
+ if ( ! function_exists( 'woo_feed_delete_feed' ) ) {
1538
+ /**
1539
+ * Delete feed option and the file from uploads directory
1540
+ *
1541
+ * @param string|int $feed_id feed option name or ID.
1542
+ *
1543
+ * @return bool
1544
+ */
1545
+ function woo_feed_delete_feed( $feed_id ) {
1546
+ global $wpdb;
1547
+ if ( ! is_numeric( $feed_id ) ) {
1548
+ $feed_name = woo_feed_extract_feed_option_name( $feed_id );
1549
+ } else {
1550
+ $feed_data = $wpdb->get_row( $wpdb->prepare( "SELECT option_name FROM $wpdb->options WHERE option_id = %d", $feed_id ) ); // phpcs:ignore
1551
+ $option_name = $feed_data->option_name;
1552
+ $feed_name = woo_feed_extract_feed_option_name( $feed_data->option_name );
1553
+ }
1554
+ $feedInfo = maybe_unserialize( get_option( 'wf_feed_' . $feed_name ) );
1555
+ if ( false !== $feedInfo ) {
1556
+ $feedInfo = $feedInfo['feedrules'];
1557
+ } else {
1558
+ $feedInfo = maybe_unserialize( get_option( 'wf_config' . $feed_name ) );
1559
+ }
1560
+ $deleted = false;
1561
+ $file = woo_feed_get_file( $feed_name, $feedInfo['provider'], $feedInfo['feedType'] );
1562
+ // delete any leftover
1563
+ woo_feed_unlink_tempFiles( $feedInfo, $feed_name );
1564
+ if ( file_exists( $file ) ) {
1565
+ // file exists in upload directory
1566
+ if ( unlink( $file ) ) { // phpcs:ignore
1567
+ delete_option( 'wf_feed_' . $feed_name );
1568
+ delete_option( 'wf_config' . $feed_name );
1569
+ $deleted = true;
1570
+ }
1571
+ } else {
1572
+ delete_option( 'wf_feed_' . $feed_name );
1573
+ delete_option( 'wf_config' . $feed_name );
1574
+ $deleted = true;
1575
+ }
1576
+
1577
+ // Delete cron schedule.
1578
+ $feed_cron_param = 'wf_config' . $feed_name;
1579
+ wp_clear_scheduled_hook( 'woo_feed_update_single_feed', [ $feed_cron_param ] );
1580
+
1581
+ return $deleted;
1582
+ }
1583
  }
1584
 
1585
  // Mics..
1586
+ if ( ! function_exists( 'woo_feed_remove_query_args' ) ) {
1587
+ /**
1588
+ * Add more items to the removable query args array...
1589
+ *
1590
+ * @param array $removable_query_args
1591
+ *
1592
+ * @return array
1593
+ */
1594
+ function woo_feed_remove_query_args( $removable_query_args ) {
1595
+ global $plugin_page;
1596
+ if ( strpos( $plugin_page, 'webappick' ) !== false ) {
1597
+ $removable_query_args[] = 'feed_created';
1598
+ $removable_query_args[] = 'feed_updated';
1599
+ $removable_query_args[] = 'feed_imported';
1600
+ $removable_query_args[] = 'feed_regenerate';
1601
+ $removable_query_args[] = 'feed_name';
1602
+ $removable_query_args[] = 'link';
1603
+ $removable_query_args[] = 'wpf_message';
1604
+ $removable_query_args[] = 'cat';
1605
+ $removable_query_args[] = 'schedule_updated';
1606
+ $removable_query_args[] = 'settings_updated';
1607
+ /** @noinspection SpellCheckingInspection */
1608
+ $removable_query_args[] = 'WPFP_WPML_CURLANG';
1609
+ }
1610
+
1611
+ return $removable_query_args;
1612
+ }
1613
+
1614
+ add_filter( 'removable_query_args', 'woo_feed_remove_query_args', 10, 1 );
1615
+ }
1616
+ if ( ! function_exists( 'woo_feed_usort_reorder' ) ) {
1617
+ /**
1618
+ * This checks for sorting input and sorts the data in our array accordingly.
1619
+ *
1620
+ * In a real-world situation involving a database, you would probably want
1621
+ * to handle sorting by passing the 'orderby' and 'order' values directly
1622
+ * to a custom query. The returned data will be pre-sorted, and this array
1623
+ * sorting technique would be unnecessary.
1624
+ *
1625
+ * @param array $a first data.
1626
+ *
1627
+ * @param array $b second data.
1628
+ *
1629
+ * @return bool
1630
+ */
1631
+ function woo_feed_usort_reorder( $a, $b ) {
1632
+ // If no sort, default to title
1633
+ $orderby = ( ! empty( $_REQUEST['orderby'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST['orderby'] ) ) : 'option_name'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
1634
+ // If no order, default to asc
1635
+ $order = ( ! empty( $_REQUEST['order'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST['order'] ) ) : 'asc'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
1636
+ $result = strcmp( $a[ $orderby ], $b[ $orderby ] ); // Determine sort order
1637
+
1638
+ return ( 'asc' === $order ) ? $result : - $result; // Send final sort direction to usort
1639
+ }
1640
+ }
1641
+ if ( ! function_exists( 'str_replace_trim' ) ) {
1642
+ /**
1643
+ * str_replace() wrapper with trim()
1644
+ *
1645
+ * @param mixed $search The value being searched for, otherwise known as the needle.
1646
+ * An array may be used to designate multiple needles.
1647
+ * @param mixed $replace The replacement value that replaces found search values.
1648
+ * An array may be used to designate multiple replacements.
1649
+ * @param mixed $subject The string or array being searched and replaced on,
1650
+ * otherwise known as the haystack.
1651
+ * @param string $charlist [optional]
1652
+ * Optionally, the stripped characters can also be specified using the charlist parameter.
1653
+ * Simply list all characters that you want to be stripped.
1654
+ * With this you can specify a range of characters.
1655
+ *
1656
+ * @return array|string
1657
+ */
1658
+ function str_replace_trim( $search, $replace, $subject, $charlist = " \t\n\r\0\x0B" ) {
1659
+ $replaced = str_replace( $search, $replace, $subject );
1660
+ if ( is_array( $replaced ) ) {
1661
+ return array_map(
1662
+ function ( $item ) use ( $charlist ) {
1663
+ return trim( $item, $charlist );
1664
+ },
1665
+ $replaced
1666
+ );
1667
+ } else {
1668
+ return trim( $replaced, $charlist );
1669
+ }
1670
+ }
1671
  }
1672
 
1673
  if ( ! function_exists( 'woo_feed_strip_all_tags' ) ) {
1674
 
1675
+ /*
1676
  * Extends wp_strip_all_tags to fix WP_Error object passing issue
1677
  *
1678
  * @param string | WP_Error $string
1680
  * @return string
1681
  * @since 4.4.19
1682
  * */
1683
+ function woo_feed_strip_all_tags( $string ) {
1684
+
1685
+ if ( $string instanceof WP_Error ) {
1686
+ return '';
1687
+ }
1688
+
1689
+ return wp_strip_all_tags( $string );
1690
+
1691
+ }
1692
+ }
1693
+
1694
+ if ( ! function_exists( 'woo_feed_export_config' ) ) {
1695
+ /**
1696
+ * Handle config export request
1697
+ *
1698
+ * @return void
1699
+ * @since 3.3.10
1700
+ */
1701
+ function woo_feed_export_config() {
1702
+ if ( isset( $_REQUEST['feed'], $_REQUEST['_wpnonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) ), 'wpf-export' ) ) {
1703
+ $feed = sanitize_text_field( wp_unslash( $_REQUEST['feed'] ) );
1704
+ $feed = woo_feed_extract_feed_option_name( $feed );
1705
+ if ( ! empty( $feed ) ) {
1706
+ $feed = maybe_unserialize( get_option( 'wf_feed_' . $feed ) );
1707
+ $feed = ( isset( $feed['feedrules'] ) && is_array( $feed['feedrules'] ) ) ? $feed['feedrules'] : [];
1708
+ }
1709
+ if ( ! is_array( $feed ) ) {
1710
+ wp_die( esc_html__( 'Invalid Request', 'woo-feed' ), esc_html__( 'Invalid Request', 'woo-feed' ), [ 'back_link' => true ] );
1711
+ }
1712
+ $file_name = sprintf(
1713
+ '%s-%s-%s.wpf',
1714
+ sanitize_title( $feed['filename'] ),
1715
+ $feed['provider'],
1716
+ time()
1717
+ );
1718
+ $feed = wp_json_encode( $feed );
1719
+ $meta = wp_json_encode( [
1720
+ 'version' => WOO_FEED_FREE_VERSION,
1721
+ 'file_name' => $file_name,
1722
+ 'hash' => md5( $feed ),
1723
+ ] );
1724
+ $bin = pack( 'VA*VA*', strlen( $meta ), $meta, strlen( $feed ), $feed );
1725
+ $feed = gzdeflate( $bin, 9 );
1726
+ // Let set the header...
1727
+ if ( ! headers_sent() ) {
1728
+ status_header( 200 );
1729
+ header( 'Content-Type: application/octet-stream;' );
1730
+ header( 'Content-disposition: attachment; filename=' . $file_name );
1731
+ header( 'Content-Length: ' . strlen( $feed ) );
1732
+ header( 'Pragma: no-cache' );
1733
+ header( 'Expires: 0' );
1734
+ }
1735
+ // exporting data.
1736
+ echo $feed; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1737
+ } else {
1738
+ wp_die(
1739
+ esc_html__( 'Invalid Request', 'woo-feed' ),
1740
+ esc_html__( 'Invalid Request', 'woo-feed' ),
1741
+ [ 'back_link' => true ]
1742
+ );
1743
+ }
1744
+ }
1745
+ }
1746
+ if ( ! function_exists( 'woo_feed_import_config' ) ) {
1747
+ /**
1748
+ * Handle config import request
1749
+ *
1750
+ * @return void
1751
+ * @since 3.3.10
1752
+ */
1753
+ function woo_feed_import_config() {
1754
+ check_admin_referer( 'wpf_import' );
1755
+ $wpf_import_file = isset( $_FILES['wpf_import_file'] ) ? $_FILES['wpf_import_file'] : '';
1756
+ $wpf_import_feed_name = isset( $_POST['wpf_import_feed_name'] ) ? $_POST['wpf_import_feed_name'] : '';
1757
+ $wpf_import_file_name = isset( $_FILES['wpf_import_file']['name'] ) ? $_FILES['wpf_import_file']['name'] : '';
1758
+ $wpf_import_file_tmp_name = isset( $_FILES['wpf_import_file']['tmp_name'] ) ? $_FILES['wpf_import_file']['tmp_name'] : '';
1759
+
1760
+ if (
1761
+ $wpf_import_file &&
1762
+ $wpf_import_feed_name &&
1763
+ $wpf_import_file_name &&
1764
+ $wpf_import_file_tmp_name &&
1765
+ 'wpf' === pathinfo( wp_unslash( $wpf_import_file_name ), PATHINFO_EXTENSION ) // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1766
+ ) {
1767
+ $file_name = sanitize_file_name( sanitize_text_field( wp_unslash( $wpf_import_file_name ) ) );
1768
+ $data = file_get_contents( sanitize_text_field( wp_unslash( $wpf_import_file_tmp_name ) ) );
1769
+ if ( empty( $data ) ) {
1770
+ wp_die(
1771
+ esc_html__( 'Empty File Uploaded. Try again.', 'woo-feed' ),
1772
+ esc_html__( 'Empty File', 'woo-feed' ),
1773
+ [
1774
+ 'link_url' => esc_url( admin_url( 'admin.php?page=webappick-manage-feeds' ) ),
1775
+ 'link_text' => esc_html__( '&laquo; Back', 'woo-feed' ),
1776
+ ]
1777
+ );
1778
+ }
1779
+ $feed = gzinflate( $data );
1780
+ if ( false === $feed ) {
1781
+ wp_die(
1782
+ esc_html__( 'Unable to read file content', 'woo-feed' ),
1783
+ esc_html__( 'Invalid File', 'woo-feed' ),
1784
+ [
1785
+ 'link_url' => esc_url( admin_url( 'admin.php?page=webappick-manage-feeds' ) ),
1786
+ 'link_text' => esc_html__( '&laquo; Back', 'woo-feed' ),
1787
+ ]
1788
+ );
1789
+ }
1790
+ // unpack meta data.
1791
+ $meta_length = unpack( 'V', $feed );
1792
+ if ( false === $meta_length ) {
1793
+ wp_die(
1794
+ esc_html__( 'Unable to read data from file.', 'woo-feed' ),
1795
+ esc_html__( 'Invalid File', 'woo-feed' ),
1796
+ [
1797
+ 'link_url' => esc_url( admin_url( 'admin.php?page=webappick-manage-feeds' ) ),
1798
+ 'link_text' => esc_html__( '&laquo; Back', 'woo-feed' ),
1799
+ ]
1800
+ );
1801
+ }
1802
+ $meta = unpack( 'A*', substr( $feed, 4, $meta_length[1] ) )[1];
1803
+ if ( false === $meta || 0 !== strpos( $meta, '{' ) ) {
1804
+ wp_die(
1805
+ esc_html__( 'Unable to read file info.', 'woo-feed' ),
1806
+ esc_html__( 'Invalid File', 'woo-feed' ),
1807
+ [
1808
+ 'link_url' => esc_url( admin_url( 'admin.php?page=webappick-manage-feeds' ) ),
1809
+ 'link_text' => esc_html__( '&laquo; Back', 'woo-feed' ),
1810
+ ]
1811
+ );
1812
+ }
1813
+ $meta = json_decode( $meta, true );
1814
+ // unpack feed data.
1815
+ $feed = substr( $feed, $meta_length[1] + 8 ); // 4 bytes for each V (length data)
1816
+ $feed = unpack( 'A*', $feed )[1];
1817
+ if ( false === $feed || 0 !== strpos( $feed, '{' ) ) {
1818
+ wp_die(
1819
+ esc_html__( 'Unable to read feed data from file.', 'woo-feed' ),
1820
+ esc_html__( 'Invalid File', 'woo-feed' ),
1821
+ [
1822
+ 'link_url' => esc_url( admin_url( 'admin.php?page=webappick-manage-feeds' ) ),
1823
+ 'link_text' => esc_html__( '&laquo; Back', 'woo-feed' ),
1824
+ ]
1825
+ );
1826
+ }
1827
+ if ( md5( $feed ) !== $meta['hash'] ) {
1828
+ wp_die(
1829
+ esc_html__( 'Unable to verify the file.', 'woo-feed' ),
1830
+ esc_html__( 'Invalid File', 'woo-feed' ),
1831
+ [
1832
+ 'link_url' => esc_url( admin_url( 'admin.php?page=webappick-manage-feeds' ) ),
1833
+ 'link_text' => esc_html__( '&laquo; Back', 'woo-feed' ),
1834
+ ]
1835
+ );
1836
+ }
1837
+
1838
+ $feed = json_decode( $feed, true );
1839
+ if ( ! is_array( $feed ) ) {
1840
+ wp_die(
1841
+ esc_html__( 'Invalid or corrupted config file.', 'woo-feed' ),
1842
+ esc_html__( 'Invalid File', 'woo-feed' ),
1843
+ [
1844
+ 'link_url' => esc_url( admin_url( 'admin.php?page=webappick-manage-feeds' ) ),
1845
+ 'link_text' => esc_html__( '&laquo; Back', 'woo-feed' ),
1846
+ ]
1847
+ );
1848
+ }
1849
+
1850
+ $feed = woo_feed_parse_feed_rules( $feed );
1851
+ $new_name = sanitize_text_field( wp_unslash( $_POST['wpf_import_feed_name'] ) );
1852
+ $new_name = trim( $new_name );
1853
+ if ( ! empty( $new_name ) ) {
1854
+ $opt_name = $new_name;
1855
+ $feed['filename'] = $new_name;
1856
+ } else {
1857
+ $opt_name = $feed['filename'];
1858
+ $feed['filename'] = str_replace_trim( [ '-', '_' ], ' ', $feed['filename'] );
1859
+ $feed['filename'] = sprintf(
1860
+ '%s: %s',
1861
+ esc_html__( ' Imported', 'woo-feed' ),
1862
+ ucwords( $feed['filename'] )
1863
+ );
1864
+ }
1865
+ // New Slug.
1866
+ $opt_name = generate_unique_feed_file_name( $opt_name,
1867
+ $feed['feedType'],
1868
+ $feed['provider'] );
1869
+ // save config.
1870
+ $fileName = woo_feed_save_feed_config_data( $feed, $opt_name, false );
1871
+ // Redirect back to the list.
1872
+ wp_safe_redirect(
1873
+ add_query_arg(
1874
+ [
1875
+ 'feed_imported' => (int) false !== $fileName,
1876
+ 'feed_regenerate' => 1,
1877
+ 'feed_name' => $fileName ? $fileName : '',
1878
+ ],
1879
+ esc_url( admin_url( 'admin.php?page=webappick-manage-feeds' ) )
1880
+ )
1881
+ );
1882
+ die();
1883
+ }
1884
+ wp_die(
1885
+ esc_html__( 'Invalid Request.', 'woo-feed' ),
1886
+ esc_html__( 'Invalid Request', 'woo-feed' ),
1887
+ [
1888
+ 'link_url' => esc_url( admin_url( 'admin.php?page=webappick-manage-feeds' ) ),
1889
+ 'link_text' => esc_html__( '&laquo; Back', 'woo-feed' ),
1890
+ ]
1891
+ );
1892
+ }
1893
+ }
1894
+
1895
+ if ( ! function_exists( 'woo_feed_download_feed_log' ) ) {
1896
+
1897
+ /**
1898
+ * Handle latest log download request
1899
+ *
1900
+ * @return void
1901
+ * @since 4.4.15
1902
+ */
1903
+ function woo_feed_download_feed_log() {
1904
+ if (
1905
+ isset( $_REQUEST['feed'], $_REQUEST['_wpnonce'] )
1906
+ && wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) ), 'wpf-log-download' )
1907
+ ) {
1908
+ $feed_name = sanitize_text_field( wp_unslash( $_REQUEST['feed'] ) );
1909
+ $feed_name = str_replace( 'wf_feed_', '', $feed_name );
1910
+ $log_file_path = Woo_Feed_Log_Handler_File::get_log_file_path( $feed_name );
1911
+
1912
+ if ( $log_file_path && file_exists( $log_file_path ) ) {
1913
+ $log_data = file_get_contents( $log_file_path );
1914
+ } else {
1915
+ $log_data = 'No log is generated.';
1916
+ }
1917
+
1918
+ if ( ! empty( $feed_name ) ) {
1919
+ $feed_details = maybe_unserialize( get_option( 'wf_feed_' . $feed_name ) );
1920
+ $feed_details = ( isset( $feed['feedrules'] ) && is_array( $feed['feedrules'] ) ) ? $feed['feedrules'] : [];
1921
+ }
1922
+
1923
+ if ( ! is_array( $feed_details ) ) {
1924
+ wp_die( esc_html__( 'Invalid Request', 'woo-feed' ), esc_html__( 'Invalid Request', 'woo-feed' ), [ 'back_link' => true ] );
1925
+ }
1926
+
1927
+ $file_name = sprintf(
1928
+ '%s-%s-%s.log',
1929
+ sanitize_title( $feed_name ),
1930
+ gmdate( 'Y-m-d', time() ),
1931
+ time()
1932
+ );
1933
+
1934
+ // Let set the header...
1935
+ if ( ! headers_sent() ) {
1936
+ status_header( 200 );
1937
+ header( 'Content-Type: application/octet-stream;' );
1938
+ header( 'Content-disposition: attachment; filename=' . $file_name );
1939
+ header( 'Content-Length: ' . strlen( $log_data ) );
1940
+ header( 'Pragma: no-cache' );
1941
+ header( 'Expires: 0' );
1942
+ }
1943
+
1944
+ // exporting data.
1945
+ echo $log_data; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1946
+ } else {
1947
+ wp_die(
1948
+ esc_html__( 'Invalid Request', 'woo-feed' ),
1949
+ esc_html__( 'Invalid Request', 'woo-feed' ),
1950
+ [ 'back_link' => true ]
1951
+ );
1952
+ }
1953
+ }
1954
  }
1955
 
1956
  // Feed Functions.
1957
+ if ( ! function_exists( 'woo_feed_generate_feed' ) ) {
1958
+ /**
1959
+ * Update Feed Information
1960
+ *
1961
+ * @param array $info feed config array
1962
+ * @param string $feed_option_name feed option/file name
1963
+ *
1964
+ * @return string|bool
1965
+ */
1966
+ function woo_feed_generate_feed( $info, $feed_option_name ) {
1967
+ if ( false === $info || empty( $info ) ) {
1968
+ return false;
1969
+ }
1970
+ // parse rules.
1971
+ $info = woo_feed_parse_feed_rules( isset( $info['feedrules'] ) ? $info['feedrules'] : $info );
1972
+ $feed_option_name = woo_feed_extract_feed_option_name( $feed_option_name );
1973
+ if ( ! empty( $info['provider'] ) ) {
1974
+ do_action( 'before_woo_feed_generate_feed', $info );
1975
+
1976
+ // Generate Feed Data
1977
+ if ( isset( $info['provider'] ) && 'googlereview' === $info['provider'] ) {
1978
+ $reviewObj = new Woo_Feed_Review( $info );
1979
+ $feedBody = $reviewObj->make_review_xml_feed();
1980
+ $string = $feedBody;
1981
+
1982
+ } else {
1983
+ $products = new Woo_Generate_Feed( $info['provider'], $info );
1984
+ $getString = $products->getProducts();
1985
+ if ( 'csv' == $info['feedType'] || 'tsv' == $info['feedType'] || 'xls' == $info['feedType'] ) {
1986
+ $csvHead[0] = $getString['header'];
1987
+ if ( ! empty( $csvHead ) && ! empty( $getString['body'] ) ) {
1988
+ $string = array_merge( $csvHead, $getString['body'] );
1989
+ } else {
1990
+ $string = array();
1991
+ }
1992
+ } else {
1993
+ if ( 'json' == $info['feedType'] ) {
1994
+ $string = array();
1995
+ } else {
1996
+ $string = $getString['header'] . $getString['body'] . $getString['footer'];
1997
+ }
1998
+ }
1999
+ }
2000
+
2001
+ $saveFile = false;
2002
+ // Check If any products founds
2003
+ if ( $string && ! empty( $string ) ) {
2004
+ // Save File
2005
+ $path = woo_feed_get_file_path( $info['provider'], $info['feedType'] );
2006
+ $file = woo_feed_get_file( $feed_option_name, $info['provider'], $info['feedType'] );
2007
+ $save = new Woo_Feed_Savefile();
2008
+ if ( 'csv' == $info['feedType'] || 'tsv' == $info['feedType'] || 'xls' == $info['feedType'] || 'json' == $info['feedType'] ) {
2009
+ $saveFile = $save->saveValueFile( $path, $file, $string, $info, $info['feedType'] );
2010
+ } else {
2011
+ $saveFile = $save->saveFile( $path, $file, $string );
2012
+ }
2013
+
2014
+ // Upload file to ftp server
2015
+ if ( 1 == (int) $info['ftpenabled'] ) {
2016
+ woo_feed_handle_file_transfer( $file, $feed_option_name . '.' . $info['feedType'], $info );
2017
+ }
2018
+ }
2019
+ $feed_URL = woo_feed_get_file_url( $feed_option_name, $info['provider'], $info['feedType'] );
2020
+ // Save Info into database
2021
+ $feedInfo = array(
2022
+ 'feedrules' => $info,
2023
+ 'url' => $feed_URL,
2024
+ 'last_updated' => date( 'Y-m-d H:i:s', strtotime( current_time( 'mysql' ) ) ),
2025
+ 'status' => 1,
2026
+ );
2027
+ update_option( 'wf_feed_' . $feed_option_name, serialize( $feedInfo ), false ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize
2028
+ do_action( 'after_woo_feed_generate_feed', $info );
2029
+ if ( $saveFile ) {
2030
+ return $feed_URL;
2031
+ } else {
2032
+ return false;
2033
+ }
2034
+ }
2035
+
2036
+ return false;
2037
+ }
2038
+ }
2039
+
2040
+ if ( ! function_exists( 'woo_feed_get_schedule_interval_options' ) ) {
2041
+ /**
2042
+ * Get Schedule Intervals
2043
+ * @return mixed
2044
+ */
2045
+ function woo_feed_get_schedule_interval_options() {
2046
+ return apply_filters(
2047
+ 'woo_feed_schedule_interval_options',
2048
+ [
2049
+ WEEK_IN_SECONDS => esc_html__( '1 Week', 'woo-feed' ),
2050
+ DAY_IN_SECONDS => esc_html__( '24 Hours', 'woo-feed' ),
2051
+ 12 * HOUR_IN_SECONDS => esc_html__( '12 Hours', 'woo-feed' ),
2052
+ 6 * HOUR_IN_SECONDS => esc_html__( '6 Hours', 'woo-feed' ),
2053
+ HOUR_IN_SECONDS => esc_html__( '1 Hours', 'woo-feed' ),
2054
+ ]
2055
+ );
2056
+ }
2057
+ }
2058
+ if ( ! function_exists( 'woo_feed_get_minimum_interval_option' ) ) {
2059
+ function woo_feed_get_minimum_interval_option() {
2060
+ $intervals = array_keys( woo_feed_get_schedule_interval_options() );
2061
+ if ( ! empty( $intervals ) ) {
2062
+ return end( $intervals );
2063
+ }
2064
+
2065
+ return 15 * MINUTE_IN_SECONDS;
2066
+ }
2067
+ }
2068
+ if ( ! function_exists( 'woo_feed_stripInvalidXml' ) ) {
2069
+ /**
2070
+ * Remove non supported xml character
2071
+ *
2072
+ * @param string $value
2073
+ *
2074
+ * @return string
2075
+ */
2076
+ function woo_feed_stripInvalidXml( $value ) {
2077
+ $ret = '';
2078
+ if ( empty( $value ) ) {
2079
+ return $ret;
2080
+ }
2081
+ $length = strlen( $value );
2082
+ for ( $i = 0; $i < $length; $i ++ ) {
2083
+ $current = ord( $value[ $i ] );
2084
+ if ( ( 0x9 == $current ) || ( 0xA == $current ) || ( 0xD == $current ) || ( ( $current >= 0x20 ) && ( $current <= 0xD7FF ) ) || ( ( $current >= 0xE000 ) && ( $current <= 0xFFFD ) ) || ( ( $current >= 0x10000 ) && ( $current <= 0x10FFFF ) ) ) {
2085
+ $ret .= chr( $current );
2086
+ } else {
2087
+ $ret .= '';
2088
+ }
2089
+ }
2090
+
2091
+ return $ret;
2092
+ }
2093
+ }
2094
+ if ( ! function_exists( 'woo_feed_get_formatted_url' ) ) {
2095
+ /**
2096
+ * Get Formatted URL
2097
+ *
2098
+ * @param string $url
2099
+ *
2100
+ * @return string
2101
+ */
2102
+ function woo_feed_get_formatted_url( $url = '' ) {
2103
+ if ( ! empty( $url ) ) {
2104
+ if ( substr( trim( $url ), 0, 4 ) === 'http' || substr( trim( $url ),
2105
+ 0,
2106
+ 3 ) === 'ftp' || substr( trim( $url ), 0, 4 ) === 'sftp' ) {
2107
+ return rtrim( $url, '/' );
2108
+ } else {
2109
+ $base = get_site_url();
2110
+ $url = $base . $url;
2111
+
2112
+ return rtrim( $url, '/' );
2113
+ }
2114
+ }
2115
+
2116
+ return '';
2117
+ }
2118
+ }
2119
+ if ( ! function_exists( 'array_value_first' ) ) {
2120
+ /**
2121
+ * Get First Value of an array
2122
+ *
2123
+ * @param array $arr
2124
+ *
2125
+ * @return mixed|null
2126
+ * @since 3.0.0
2127
+ */
2128
+ function array_value_first( array $arr ) {
2129
+ foreach ( $arr as $key => $unused ) {
2130
+ return $unused;
2131
+ }
2132
+
2133
+ return null;
2134
+ }
2135
+ }
2136
+ if ( ! function_exists( 'woo_feed_make_url_with_parameter' ) ) {
2137
+ /**
2138
+ * Make proper URL using parameters
2139
+ *
2140
+ * @param string $output
2141
+ * @param string $suffix
2142
+ *
2143
+ * @return string
2144
+ */
2145
+ function woo_feed_make_url_with_parameter( $output = '', $suffix = '' ) {
2146
+ if ( empty( $output ) || empty( $suffix ) ) {
2147
+ return $output;
2148
+ }
2149
+
2150
+ $getParam = explode( '?', $output );
2151
+ $URLParam = array();
2152
+ if ( isset( $getParam[1] ) ) {
2153
+ $URLParam = woo_feed_parse_string( $getParam[1] );
2154
+ }
2155
+
2156
+ $EXTRAParam = array();
2157
+ if ( ! empty( $suffix ) ) {
2158
+ $suffix = str_replace( '?', '', $suffix );
2159
+ $EXTRAParam = woo_feed_parse_string( $suffix );
2160
+ }
2161
+
2162
+ $params = array_merge( $URLParam, $EXTRAParam );
2163
+ if ( ! empty( $params ) && '' != $output ) {
2164
+ $params = http_build_query( $params );
2165
+ $baseURL = isset( $getParam ) ? $getParam[0] : $output;
2166
+ $output = $baseURL . '?' . $params;
2167
+ }
2168
+
2169
+ return $output;
2170
+ }
2171
+ }
2172
+ if ( ! function_exists( 'woo_feed_parse_string' ) ) {
2173
+ /**
2174
+ * Parse URL parameter
2175
+ *
2176
+ * @param string $str
2177
+ *
2178
+ * @return array
2179
+ */
2180
+ function woo_feed_parse_string( $str = '' ) {
2181
+
2182
+ // result array
2183
+ $arr = array();
2184
+
2185
+ if ( empty( $str ) ) {
2186
+ return $arr;
2187
+ }
2188
+
2189
+ // split on outer delimiter
2190
+ $pairs = explode( '&', $str );
2191
+
2192
+ if ( ! empty( $pairs ) && is_array( $pairs ) ) {
2193
+
2194
+ // loop through each pair
2195
+ foreach ( $pairs as $i ) {
2196
+ // split into name and value
2197
+ list( $name, $value ) = explode( '=', $i, 2 );
2198
+
2199
+ // if name already exists
2200
+ if ( isset( $arr[ $name ] ) ) {
2201
+ // stick multiple values into an array
2202
+ if ( is_array( $arr[ $name ] ) ) {
2203
+ $arr[ $name ][] = $value;
2204
+ } else {
2205
+ $arr[ $name ] = array( $arr[ $name ], $value );
2206
+ }
2207
+ } // otherwise, simply stick it in a scalar
2208
+ else {
2209
+ $arr[ $name ] = $value;
2210
+ }
2211
+ }
2212
+ } elseif ( ! empty( $str ) ) {
2213
+ list( $name, $value ) = explode( '=', $str, 2 );
2214
+ $arr[ $name ] = $value;
2215
+ }
2216
+
2217
+ // return result array
2218
+ return $arr;
2219
+ }
2220
+ }
2221
+ if ( ! function_exists( 'woo_feed_replace_to_merchant_attribute' ) ) {
2222
+ /**
2223
+ * Parse URL parameter
2224
+ *
2225
+ * @param string $pluginAttribute
2226
+ * @param string $merchant
2227
+ * @param string feedType CSV XML TXT
2228
+ *
2229
+ * @return string
2230
+ */
2231
+ function woo_feed_replace_to_merchant_attribute( $pluginAttribute, $merchant, $feedType ) {
2232
+ $attributeClass = new Woo_Feed_Default_Attributes();
2233
+ $merchantAttributes = '';
2234
+ if ( 'google' === $merchant
2235
+ || 'google_shopping_action' === $merchant
2236
+ || 'google_local' === $merchant
2237
+ || 'google_local_inventory' === $merchant
2238
+ || 'adroll' == $merchant
2239
+ || 'smartly.io' == $merchant ) {
2240
+ if ( 'xml' === $feedType ) {
2241
+ $g_attributes = $attributeClass->googleXMLAttribute;
2242
+ if ( 'google_local' === $merchant ) {
2243
+ unset( $g_attributes['description'] );
2244
+ }
2245
+ $merchantAttributes = $g_attributes;
2246
+ } elseif ( 'csv' == $feedType || 'txt' == $feedType ) {
2247
+ $merchantAttributes = $attributeClass->googleCSVTXTAttribute;
2248
+ }
2249
+ } elseif ( 'facebook' == $merchant ) {
2250
+ if ( 'xml' == $feedType ) {
2251
+ $merchantAttributes = $attributeClass->facebookXMLAttribute;
2252
+ } elseif ( 'csv' == $feedType || 'txt' == $feedType ) {
2253
+ $merchantAttributes = $attributeClass->facebookCSVTXTAttribute;
2254
+ }
2255
+ } elseif ( 'pinterest' == $merchant ) {
2256
+ if ( 'xml' == $feedType ) {
2257
+ $merchantAttributes = $attributeClass->pinterestXMLAttribute;
2258
+ } elseif ( 'csv' == $feedType || 'txt' == $feedType ) {
2259
+ $merchantAttributes = $attributeClass->pinterestCSVTXTAttribute;
2260
+ }
2261
+ } elseif ( 'skroutz' == $merchant ) {
2262
+ if ( 'xml' == $feedType ) {
2263
+ $merchantAttributes = $attributeClass->skroutzXMLAttributes;
2264
+ }
2265
+ }
2266
+
2267
+ if ( ! empty( $merchantAttributes ) && array_key_exists( $pluginAttribute, $merchantAttributes ) ) {
2268
+ return $merchantAttributes[ $pluginAttribute ][0];
2269
+ }
2270
+
2271
+ return $pluginAttribute;
2272
+ }
2273
+ }
2274
+ if ( ! function_exists( 'woo_feed_add_cdata' ) ) {
2275
+ /**
2276
+ * Parse URL parameter
2277
+ *
2278
+ * @param string $pluginAttribute
2279
+ * @param string $attributeValue
2280
+ * @param string $merchant
2281
+ * @param string $feed_type
2282
+ *
2283
+ * @return string
2284
+ */
2285
+ function woo_feed_add_cdata( $pluginAttribute, $attributeValue, $merchant, $feed_type ) {
2286
+ if ( "xml" !== $feed_type ) {
2287
+ return "$attributeValue";
2288
+ }
2289
+
2290
+ if ( 'custom' === $merchant ) {
2291
+ return "$attributeValue";
2292
+ }
2293
+
2294
+ if ( "shipping" === $pluginAttribute || "tax" === $pluginAttribute ) {
2295
+ return "$attributeValue";
2296
+ }
2297
+
2298
+ if ( strpos( $attributeValue, '<![CDATA[' ) !== false ) {
2299
+ return "$attributeValue";
2300
+ }
2301
+
2302
+ $attributeClass = new Woo_Feed_Default_Attributes();
2303
+ $merchantAttributes = '';
2304
+ if ( 'google' == $merchant ) {
2305
+ $merchantAttributes = $attributeClass->googleXMLAttribute;
2306
+ } elseif ( 'facebook' == $merchant ) {
2307
+ $merchantAttributes = $attributeClass->facebookXMLAttribute;
2308
+ } elseif ( 'pinterest' == $merchant ) {
2309
+ $merchantAttributes = $attributeClass->pinterestXMLAttribute;
2310
+ } elseif ( 'skroutz' == $merchant ) {
2311
+ $merchantAttributes = $attributeClass->skroutzXMLAttributes;
2312
+ }
2313
+
2314
+ if ( ! empty( $merchantAttributes ) && array_key_exists( $pluginAttribute, $merchantAttributes ) ) {
2315
+ if ( 'true' == $merchantAttributes[ $pluginAttribute ][1] ) {
2316
+ return "<![CDATA[$attributeValue]]>";
2317
+ } else {
2318
+ return "$attributeValue";
2319
+ }
2320
+ } elseif ( false !== strpos( $attributeValue, '&' ) || 'http' == substr( trim( $attributeValue ), 0, 4 ) ) {
2321
+ if ( 'catch.com.au' === $merchant ) {
2322
+ if ( false !== strpos( $pluginAttribute, 'image' ) ) {
2323
+ return "$attributeValue";
2324
+ }
2325
+ } else {
2326
+ return "<![CDATA[ $attributeValue ]]>";
2327
  // return "$attributeValue";
2328
+ }
2329
+ } else {
2330
+ return "$attributeValue";
2331
+ }
2332
+
2333
+ return "$attributeValue";
2334
+ }
2335
  }
2336
 
2337
  // WooFeed Settings API
2338
+ if ( ! function_exists( 'woo_feed_get_options' ) ) {
2339
+ /**
2340
+ * Get saved settings.
2341
+ *
2342
+ * @param string $key Option name.
2343
+ * All default values will be returned if this set to 'defaults',
2344
+ * all settings will be return if set to 'all'.
2345
+ * @param bool $default value to return if no matching data found for the key (option)
2346
+ *
2347
+ * @return array|bool|string|mixed
2348
+ * @since 3.3.11
2349
+ */
2350
+ function woo_feed_get_options( $key, $default = false ) {
2351
+ $defaults = [
2352
+ 'per_batch' => 200,
2353
+ 'product_query_type' => 'wc',
2354
+ 'variation_query_type' => 'individual',
2355
+ 'enable_error_debugging' => 'off',
2356
+ 'cache_ttl' => 6 * HOUR_IN_SECONDS,
2357
+ 'overridden_structured_data' => 'off',
2358
+ 'disable_mpn' => 'enable',
2359
+ 'disable_brand' => 'enable',
2360
+ 'disable_pixel' => 'enable',
2361
+ 'pixel_id' => '',
2362
+ 'disable_remarketing' => 'disable',
2363
+ 'remarketing_id' => '',
2364
+ 'remarketing_label' => '',
2365
+ 'allow_all_shipping' => 'no',
2366
+ 'only_free_shipping' => 'yes',
2367
+ 'only_local_pickup_shipping' => 'no',
2368
+ 'enable_ftp_upload' => 'no',
2369
+ 'woo_feed_taxonomy' => array(
2370
+ 'brand' => 'disable',
2371
+ ),
2372
+ 'woo_feed_identifier' => array(
2373
+ 'gtin' => 'disable',
2374
+ 'ean' => 'disable',
2375
+ 'mpn' => 'disable',
2376
+ 'isbn' => 'disable',
2377
+ 'age_group' => 'disable',
2378
+ 'material' => 'disable',
2379
+ 'gender' => 'disable',
2380
+ 'cost_of_good_sold' => 'disable',
2381
+ 'availability_date' => 'enable',
2382
+ 'unit' => 'disable',
2383
+ 'unit_pricing_measure' => 'disable',
2384
+ 'unit_pricing_base_measure' => 'disable',
2385
+ 'custom_field_0' => 'disable',
2386
+ 'custom_field_1' => 'disable',
2387
+ 'custom_field_2' => 'disable',
2388
+ 'custom_field_3' => 'disable',
2389
+ 'custom_field_4' => 'disable',
2390
+ ),
2391
+ ];
2392
+
2393
+ /**
2394
+ * Add defaults without chainging the core values.
2395
+ *
2396
+ * @param array $defaults
2397
+ *
2398
+ * @since 3.3.11
2399
+ */
2400
+ $defaults = wp_parse_args( apply_filters( 'woo_feed_settings_extra_defaults', [] ), $defaults );
2401
+
2402
+ if ( 'defaults' === $key ) {
2403
+ return $defaults;
2404
+ }
2405
+
2406
+ $settings = wp_parse_args( get_option( 'woo_feed_settings', [] ), $defaults );
2407
+
2408
+ if ( 'all' === $key ) {
2409
+ return $settings;
2410
+ }
2411
+
2412
+ if ( array_key_exists( $key, $settings ) ) {
2413
+ return $settings[ $key ];
2414
+ }
2415
+
2416
+ return $default;
2417
+ }
2418
+ }
2419
+ if ( ! function_exists( 'woo_feed_save_options' ) ) {
2420
+ /**
2421
+ * Save Settings.
2422
+ *
2423
+ * @param array $args Required. option key value paired array to save.
2424
+ *
2425
+ * @return bool
2426
+ * @since 3.3.11
2427
+ */
2428
+ function woo_feed_save_options( $args ) {
2429
+ $data = woo_feed_get_options( 'all' );
2430
+ $defaults = woo_feed_get_options( 'defaults' );
2431
+ $_data = $data;
2432
+
2433
+ if ( array_key_exists( 'per_batch', $args ) ) {
2434
+ $data['per_batch'] = absint( $args['per_batch'] );
2435
+ if ( $data['per_batch'] <= 0 ) {
2436
+ $data['per_batch'] = $_data['per_batch'] > 0 ? $_data['per_batch'] : $defaults['per_batch'];
2437
+ }
2438
+ unset( $args['unset'] );
2439
+ }
2440
+ if ( array_key_exists( 'product_query_type', $args ) ) {
2441
+ $data['product_query_type'] = strtolower( $args['product_query_type'] );
2442
+ $query_types = array_keys( woo_feed_get_query_type_options() );
2443
+ if ( ! in_array( $data['product_query_type'], $query_types ) ) {
2444
+ $data['product_query_type'] = in_array( $_data['product_query_type'], $query_types ) ? $_data['product_query_type'] : $defaults['product_query_type'];
2445
+ }
2446
+ unset( $args['product_query_type'] );
2447
+ }
2448
+ if ( array_key_exists( 'variation_query_type', $args ) ) {
2449
+ $data['variation_query_type'] = strtolower( $args['variation_query_type'] );
2450
+ $query_types = array_keys( woo_feed_get_query_type_options( 'variation' ) );
2451
+ if ( ! in_array( $data['variation_query_type'], $query_types, true ) ) {
2452
+ $data['variation_query_type'] = in_array( $_data['variation_query_type'], $query_types, true ) ? $_data['variation_query_type'] : $defaults['variation_query_type'];
2453
+ }
2454
+ unset( $args['variation_query_type'] );
2455
+ }
2456
+ if ( array_key_exists( 'enable_error_debugging', $args ) ) {
2457
+ $data['enable_error_debugging'] = strtolower( $args['enable_error_debugging'] );
2458
+ if ( ! in_array( $data['enable_error_debugging'], [ 'on', 'off' ] ) ) {
2459
+ $data['enable_error_debugging'] = in_array( $_data['enable_error_debugging'], [
2460
+ 'on',
2461
+ 'off'
2462
+ ] ) ? $_data['enable_error_debugging'] : $defaults['enable_error_debugging'];
2463
+ }
2464
+ unset( $args['enable_error_debugging'] );
2465
+ }
2466
+ if ( array_key_exists( 'cache_ttl', $args ) ) {
2467
+ $data['cache_ttl'] = absint( $args['cache_ttl'] ); // cache ttl can be zero.
2468
+ unset( $args['cache_ttl'] );
2469
+ }
2470
+ if ( array_key_exists( 'overridden_structured_data', $args ) ) {
2471
+ $data['overridden_structured_data'] = strtolower( $args['overridden_structured_data'] );
2472
+ if ( ! in_array( $data['overridden_structured_data'], array( 'on', 'off' ) ) ) {
2473
+ $data['overridden_structured_data'] = in_array( $_data['overridden_structured_data'], array(
2474
+ 'on',
2475
+ 'off'
2476
+ ) ) ? $_data['overridden_structured_data'] : $defaults['overridden_structured_data'];
2477
+ }
2478
+ unset( $args['overridden_structured_data'] );
2479
+ }
2480
+
2481
+ if ( array_key_exists( 'disable_pixel', $args ) ) {
2482
+ $data['disable_pixel'] = strtolower( $args['disable_pixel'] );
2483
+ if ( ! in_array( $data['disable_pixel'], array( 'enable', 'disable' ) ) ) {
2484
+ $data['disable_pixel'] = in_array( $_data['disable_pixel'], array(
2485
+ 'enable',
2486
+ 'disable'
2487
+ ) ) ? $_data['disable_pixel'] : $defaults['disable_pixel'];
2488
+ }
2489
+ unset( $args['disable_pixel'] );
2490
+ }
2491
+ if ( array_key_exists( 'pixel_id', $args ) ) {
2492
+ if ( isset( $args['pixel_id'] ) && ! empty( $args['pixel_id'] ) ) {
2493
+ $data['pixel_id'] = absint( $args['pixel_id'] );
2494
+ } else {
2495
+ $data['pixel_id'] = $defaults['pixel_id'];
2496
+ }
2497
+ unset( $args['pixel_id'] );
2498
+ }
2499
+
2500
+ if ( array_key_exists( 'disable_remarketing', $args ) ) {
2501
+ $data['disable_remarketing'] = strtolower( $args['disable_remarketing'] );
2502
+ if ( ! in_array( $data['disable_remarketing'], array( 'enable', 'disable' ) ) ) {
2503
+ $data['disable_remarketing'] = in_array( $_data['disable_remarketing'], array(
2504
+ 'enable',
2505
+ 'disable'
2506
+ ) ) ? $_data['disable_remarketing'] : $defaults['disable_remarketing'];
2507
+ }
2508
+ unset( $args['disable_remarketing'] );
2509
+ }
2510
+ if ( array_key_exists( 'remarketing_id', $args ) ) {
2511
+ if ( isset( $args['remarketing_id'] ) && ! empty( $args['remarketing_id'] ) ) {
2512
+ $data['remarketing_id'] = $args['remarketing_id'];
2513
+ } else {
2514
+ $data['remarketing_id'] = $defaults['remarketing_id'];
2515
+ }
2516
+ unset( $args['remarketing_id'] );
2517
+ }
2518
+ if ( array_key_exists( 'remarketing_label', $args ) ) {
2519
+ if ( isset( $args['remarketing_label'] ) && ! empty( $args['remarketing_label'] ) ) {
2520
+ $data['remarketing_label'] = $args['remarketing_label'];
2521
+ } else {
2522
+ $data['remarketing_label'] = $defaults['remarketing_label'];
2523
+ }
2524
+ unset( $args['remarketing_label'] );
2525
+ }
2526
+
2527
+ if ( array_key_exists( 'allow_all_shipping', $args ) ) {
2528
+ $data['allow_all_shipping'] = strtolower( $args['allow_all_shipping'] );
2529
+ if ( ! in_array( $data['allow_all_shipping'], array( 'yes', 'no' ) ) ) {
2530
+ $data['allow_all_shipping'] = in_array( $_data['allow_all_shipping'], array(
2531
+ 'yes',
2532
+ 'no'
2533
+ ) ) ? $_data['allow_all_shipping'] : $defaults['allow_all_shipping'];
2534
+ }
2535
+ unset( $args['allow_all_shipping'] );
2536
+ }
2537
+
2538
+ if ( array_key_exists( 'only_free_shipping', $args ) ) {
2539
+ $data['only_free_shipping'] = strtolower( $args['only_free_shipping'] );
2540
+ if ( ! in_array( $data['only_free_shipping'], array( 'yes', 'no' ) ) ) {
2541
+ $data['only_free_shipping'] = in_array( $_data['only_free_shipping'], array(
2542
+ 'yes',
2543
+ 'no'
2544
+ ) ) ? $_data['only_free_shipping'] : $defaults['only_free_shipping'];
2545
+ }
2546
+ unset( $args['only_free_shipping'] );
2547
+ }
2548
+
2549
+ if ( array_key_exists( 'only_local_pickup_shipping', $args ) ) {
2550
+ $data['only_local_pickup_shipping'] = strtolower( $args['only_local_pickup_shipping'] );
2551
+ if ( ! in_array( $data['only_local_pickup_shipping'], array( 'yes', 'no' ) ) ) {
2552
+ $data['only_local_pickup_shipping'] = in_array( $_data['only_local_pickup_shipping'], array(
2553
+ 'yes',
2554
+ 'no'
2555
+ ) ) ? $_data['only_local_pickup_shipping'] : $defaults['only_local_pickup_shipping'];
2556
+ }
2557
+ unset( $args['only_local_pickup_shipping'] );
2558
+ }
2559
+
2560
+
2561
+ if ( array_key_exists( 'enable_ftp_upload', $args ) ) {
2562
+ $data['enable_ftp_upload'] = strtolower( $args['enable_ftp_upload'] );
2563
+ if ( ! in_array( $data['enable_ftp_upload'], array( 'yes', 'no' ) ) ) {
2564
+ $data['enable_ftp_upload'] = in_array( $_data['enable_ftp_upload'], array(
2565
+ 'yes',
2566
+ 'no'
2567
+ ) ) ? $_data['enable_ftp_upload'] : $defaults['enable_ftp_upload'];
2568
+ }
2569
+ unset( $args['enable_ftp_upload'] );
2570
+ }
2571
+
2572
+ if ( ! empty( $args ) ) {
2573
+ foreach ( $args as $key => $value ) {
2574
+ if ( has_filter( "woo_feed_save_{$key}_option" ) ) {
2575
+ $data[ $key ] = apply_filters( "woo_feed_save_{$key}_option", sanitize_text_field( $value ) );
2576
+ }
2577
+ }
2578
+ }
2579
+
2580
+ return update_option( 'woo_feed_settings', $data, false );
2581
+ }
2582
+ }
2583
+ if ( ! function_exists( 'woo_feed_reset_options' ) ) {
2584
+ /**
2585
+ * Restore the default settings.
2586
+ *
2587
+ * @return bool
2588
+ * @since 3.3.11
2589
+ */
2590
+ function woo_feed_reset_options() {
2591
+ return update_option( 'woo_feed_settings', woo_feed_get_options( 'defaults' ), false );
2592
+ }
2593
  }
2594
 
2595
  // Caching. Wrapper for Transient API.
2596
+ if ( ! function_exists( 'woo_feed_get_cached_data' ) ) {
2597
+ /**
2598
+ * Get Cached Data
2599
+ *
2600
+ * @param string $key Cache Name
2601
+ *
2602
+ * @return mixed|false false if cache not found.
2603
+ * @since 3.3.10
2604
+ */
2605
+ function woo_feed_get_cached_data( $key ) {
2606
+ if ( empty( $key ) ) {
2607
+ return false;
2608
+ }
2609
+
2610
+ return get_transient( '__woo_feed_cache_' . $key );
2611
+ }
2612
+ }
2613
+ if ( ! function_exists( 'woo_feed_set_cache_data' ) ) {
2614
+ /**
2615
+ *
2616
+ * @param string $key Cache name. Expected to not be SQL-escaped. Must be
2617
+ * 172 characters or fewer in length.
2618
+ * @param mixed $data Data to cache. Must be serializable if non-scalar.
2619
+ * Expected to not be SQL-escaped.
2620
+ * @param int|bool $expiration Optional. Time until expiration in seconds. Default 0 (no expiration).
2621
+ *
2622
+ * @return bool
2623
+ */
2624
+ function woo_feed_set_cache_data( $key, $data, $expiration = false ) {
2625
+
2626
+ if ( empty( $key ) ) {
2627
+ return false;
2628
+ }
2629
+
2630
+ if ( false === $expiration ) {
2631
+ $expiration = WOO_FEED_CACHE_TTL;
2632
+ }
2633
+
2634
+ return set_transient( '__woo_feed_cache_' . $key, $data, (int) $expiration );
2635
+ }
2636
+ }
2637
+ if ( ! function_exists( 'woo_feed_delete_cache_data' ) ) {
2638
+ /**
2639
+ * Delete Cached Data
2640
+ *
2641
+ * @param string $key cache name.
2642
+ *
2643
+ * @return bool
2644
+ */
2645
+ function woo_feed_delete_cache_data( $key ) {
2646
+ if ( empty( $key ) ) {
2647
+ return false;
2648
+ }
2649
+
2650
+ return delete_transient( '__woo_feed_cache_' . $key );
2651
+ }
2652
+ }
2653
+ if ( ! function_exists( 'woo_feed_flush_cache_data' ) ) {
2654
+ /**
2655
+ * Delete All Cached Data
2656
+ *
2657
+ * @return void
2658
+ */
2659
+ function woo_feed_flush_cache_data() {
2660
+ global $wpdb;
2661
  // $wpdb->query( "DELETE FROM $wpdb->options WHERE {$wpdb->options}.option_name LIKE '_transient___woo_feed_cache_%' " ); // phpcs:ignore
2662
  // $wpdb->query( "DELETE FROM $wpdb->options WHERE {$wpdb->options}.option_name LIKE '_transient_timeout___woo_feed_cache_%'" ); // phpcs:ignore
2663
+ $wpdb->query( "DELETE FROM $wpdb->options WHERE ({$wpdb->options}.option_name LIKE '_transient_timeout___woo_feed_cache_%') OR ({$wpdb->options}.option_name LIKE '_transient___woo_feed_cache_%')" ); // phpcs:ignore
2664
+ }
2665
  }
2666
 
2667
  // Price And Tax.
2668
+ if ( ! function_exists( 'woo_feed_apply_tax_location_data' ) ) {
2669
+ /**
2670
+ * Filter and Change Location data for tax calculation
2671
+ *
2672
+ * @param array $location Location array.
2673
+ * @param string $tax_class Tax class.
2674
+ * @param WC_Customer $customer WooCommerce Customer Object.
2675
+ *
2676
+ * @return array
2677
+ */
2678
+ function woo_feed_apply_tax_location_data( $location, $tax_class, $customer ) {
2679
+ // @TODO use filter. add tab in feed editor so user can set custom settings.
2680
+ // @TODO tab should not list all country and cities. it only list available tax settings and user can just select one.
2681
+ // @TODO then it will extract the location data from it to use here.
2682
+ $wc_tax_location = [
2683
+ WC()->countries->get_base_country(),
2684
+ WC()->countries->get_base_state(),
2685
+ WC()->countries->get_base_postcode(),
2686
+ WC()->countries->get_base_city(),
2687
+ ];
2688
+ /**
2689
+ * Filter Tax Location to apply before product loop
2690
+ *
2691
+ * @param array $tax_location
2692
+ *
2693
+ * @since 3.3.0
2694
+ */
2695
+ $tax_location = apply_filters( 'woo_feed_tax_location_data', $wc_tax_location );
2696
+ if ( ! is_array( $tax_location ) || ( is_array( $tax_location ) && 4 !== count( $tax_location ) ) ) {
2697
+ $tax_location = $wc_tax_location;
2698
+ }
2699
+
2700
+ return $tax_location;
2701
+ }
2702
  }
2703
 
2704
  // Hook feed generating process...
2705
+ if ( ! function_exists( 'woo_feed_apply_hooks_before_product_loop' ) ) {
2706
+ /**
2707
+ * Apply Hooks Before Looping through ProductIds
2708
+ *
2709
+ * @param int[] $productIds product id array.
2710
+ * @param array $feedConfig feed config array.
2711
+ */
2712
+ function woo_feed_apply_hooks_before_product_loop( $productIds, $feedConfig ) {
2713
+ add_filter( 'woocommerce_get_tax_location', 'woo_feed_apply_tax_location_data', 10, 3 );
2714
+
2715
+ // RightPress dynamic pricing support.
2716
+ add_filter( 'rightpress_product_price_shop_change_prices_in_backend', '__return_true', 999 );
2717
+ add_filter( 'rightpress_product_price_shop_change_prices_before_cart_is_loaded', '__return_true', 999 );
2718
+
2719
+ }
2720
+ }
2721
+
2722
+ if ( ! function_exists( 'woo_feed_remove_hooks_after_product_loop' ) ) {
2723
+ /**
2724
+ * Remove Applied Hooks Looping through ProductIds
2725
+ *
2726
+ * @param int[] $productIds product id array.
2727
+ * @param array $feedConfig feed config array.
2728
+ *
2729
+ * @see woo_feed_apply_hooks_before_product_loop
2730
+ */
2731
+ function woo_feed_remove_hooks_after_product_loop( $productIds, $feedConfig ) {
2732
+ remove_filter( 'woocommerce_get_tax_location', 'woo_feed_apply_tax_location_data', 10 );
2733
+
2734
+ // RightPress dynamic pricing support.
2735
+ remove_filter( 'rightpress_product_price_shop_change_prices_in_backend', '__return_true', 999 );
2736
+ remove_filter( 'rightpress_product_price_shop_change_prices_before_cart_is_loaded', '__return_true', 999 );
2737
+
2738
+ }
2739
+ }
2740
+ if ( ! function_exists( 'woo_feed_remove_hooks_before_product_loop' ) ) {
2741
+ /**
2742
+ * Remove Applied Hooks Looping through ProductIds
2743
+ *
2744
+ * @param int[] $productIds product id array.
2745
+ * @param array $feedConfig feed config array.
2746
+ *
2747
+ * @see woo_feed_apply_hooks_before_product_loop
2748
+ */
2749
+ function woo_feed_remove_hooks_before_product_loop( $productIds, $feedConfig ) {
2750
+ remove_filter( 'woocommerce_get_tax_location', 'woo_feed_apply_tax_location_data', 10 );
2751
+ }
2752
+ }
2753
+
2754
+ if ( ! function_exists( 'woo_feed_product_taxonomy_term_separator' ) ) {
2755
+ /**
2756
+ * Filter Product local category (type) separator
2757
+ *
2758
+ * @param string $separator
2759
+ * @param array $config
2760
+ *
2761
+ * @return string
2762
+ */
2763
+ function woo_feed_product_taxonomy_term_separator( $separator, $config ) {
2764
+ if ( 'trovaprezzi' === $config['provider'] ) {
2765
+ $separator = ',';
2766
+ }
2767
+
2768
+ if ( false !== strpos( $config['provider'], 'daisycon' ) ) {
2769
+ $separator = '|';
2770
+ }
2771
+
2772
+ return $separator;
2773
+ }
2774
+ }
2775
+ if ( ! function_exists( 'woo_feed_get_availability_attribute_filter' ) ) {
2776
+ /**
2777
+ * Filter Product Availability Attribute Output For Template
2778
+ *
2779
+ * @param string $output Output string.
2780
+ * @param WC_Product $product Product Object
2781
+ * @param array $config Feed Config
2782
+ *
2783
+ * @return int
2784
+ */
2785
+ function woo_feed_get_availability_attribute_filter( $output, $product, $config ) {
2786
+ $status = $product->get_stock_status();
2787
+ $provider = $config['provider'];
2788
+
2789
+ if ( 'trovaprezzi' === $provider ) {
2790
+ $output = 2;
2791
+ if ( $status ) {
2792
+ if ( 'instock' == $status ) {
2793
+ $output = 2;
2794
+ } elseif ( 'outofstock' == $status ) {
2795
+ $output = 0;
2796
+ } elseif ( 'onbackorder' == $status ) {
2797
+ $output = 1;
2798
+ }
2799
+ }
2800
+ }
2801
+
2802
+ if ( false !== strpos( $provider, 'daisycon' ) ) {
2803
+ $output = 'true';
2804
+ if ( $status ) {
2805
+ if ( 'instock' == $status ) {
2806
+ $output = 'true';
2807
+ } elseif ( 'outofstock' == $status ) {
2808
+ $output = 'false';
2809
+ } elseif ( 'onbackorder' == $status ) {
2810
+ $output = 'false';
2811
+ }
2812
+ }
2813
+ }
2814
+
2815
+ return $output;
2816
+ }
2817
  }
2818
 
2819
  // Parse feed rules.
2820
+ if ( ! function_exists( 'woo_feed_filter_parsed_rules' ) ) {
2821
+ /**
2822
+ * Filter Feed parsed rules
2823
+ *
2824
+ * @param array $rules Feed Config
2825
+ * @param string $context Parsing context
2826
+ *
2827
+ * @return array
2828
+ * @since 3.3.7
2829
+ */
2830
+ function woo_feed_filter_parsed_rules( $rules, $context ) {
2831
+ $provider = $rules['provider'];
2832
+
2833
+ if ( 'create' === $context ) {
2834
+ if ( 'criteo' === $provider ) {
2835
+ $rules['itemsWrapper'] = 'channel';
2836
+ $rules['itemWrapper'] = 'item';
2837
+ }
2838
+
2839
+ if ( 'wine_searcher' === $provider ) {
2840
+ $rules['itemsWrapper'] = 'product-list';
2841
+ $rules['itemWrapper'] = 'row';
2842
+ $rules['delimiter'] = '|';
2843
+ $rules['enclosure'] = ' ';
2844
+ }
2845
+
2846
+ if ( 'trovaprezzi' === $provider ) {
2847
+ $rules['decimal_separator'] = ',';
2848
+ $rules['thousand_separator'] = '';
2849
+ $rules['decimals'] = 2;
2850
+ $rules['itemsWrapper'] = 'Products';
2851
+ $rules['itemWrapper'] = 'Offer';
2852
+ $rules['delimiter'] = '|';
2853
+ $rules['enclosure'] = ' ';
2854
+ }
2855
+
2856
+ if ( false !== strpos( $provider, 'daisycon' ) ) {
2857
+ $rules['itemsWrapper'] = 'channel';
2858
+ $rules['itemWrapper'] = 'item';
2859
+ }
2860
+
2861
+ if ( false !== strpos( $provider, 'zbozi.cz' ) ) {
2862
+ $rules['itemsWrapper'] = 'SHOP xmlns="http://www.zbozi.cz/ns/offer/1.0"';
2863
+ $rules['itemWrapper'] = 'SHOPITEM';
2864
+ }
2865
+
2866
+ if ( false !== strpos( $provider, 'heureka.sk' ) ) {
2867
+ $rules['itemWrapper'] = 'SHOPITEM';
2868
+ }
2869
+ }
2870
+
2871
+ return $rules;
2872
+ }
2873
+ }
2874
+
2875
+ if ( ! function_exists( 'array_splice_preserve_keys' ) ) {
2876
+ /**
2877
+ * Function to splice an array keeping key
2878
+ */
2879
+ function array_splice_preserve_keys( &$input, $offset, $length = null, $replacement = array() ) {
2880
+
2881
+ if ( empty( $replacement ) ) {
2882
+ return array_splice( $input, $offset, $length );
2883
+ }
2884
+
2885
+ $part_before = array_slice( $input, 0, $offset, $preserve_keys = true );
2886
+ $part_removed = array_slice( $input, $offset, $length, $preserve_keys = true );
2887
+ $part_after = array_slice( $input, $offset + $length, null, $preserve_keys = true );
2888
+
2889
+ $input = $part_before + $replacement + $part_after;
2890
+
2891
+ return $part_removed;
2892
+ }
2893
+ }
2894
+
2895
+ if ( ! function_exists( 'woo_feed_product_custom_fields' ) ) {
2896
+ function woo_feed_product_custom_fields() {
2897
+ /**
2898
+ * Here array of a field contain 3 elements
2899
+ * 1. Name
2900
+ * 2. Is this fields enabled by default
2901
+ * 3. Is this fields is a custom taxonomy
2902
+ */
2903
+ $custom_fields = array(
2904
+ 'brand' => array( __( 'Brand', 'woo-feed' ), true, true ),
2905
+ 'gtin' => array( __( 'GTIN', 'woo-feed' ), true ),
2906
+ 'mpn' => array( __( 'MPN', 'woo-feed' ), true ),
2907
+ 'ean' => array( __( 'EAN', 'woo-feed' ), true ),
2908
+ 'isbn' => array( __( 'ISBN', 'woo-feed' ), true ),
2909
+ 'age_group' => array( __( 'Age group', 'woo-feed' ), true ),
2910
+ 'gender' => array( __( 'Gender', 'woo-feed' ), true ),
2911
+ 'material' => array( __( 'Material', 'woo-feed' ), true ),
2912
+ 'cost_of_good_sold' => array( __( 'Cost of good sold', 'woo-feed' ), true ),
2913
+ 'availability_date' => array( __( 'Availability Date', 'woo-feed' ), true, false, false ),
2914
+ 'unit' => array( __( 'Unit', 'woo-feed' ), true ),
2915
+ 'unit_pricing_measure' => array( __( 'Unit Price Measure', 'woo-feed' ), true ),
2916
+ 'unit_pricing_base_measure' => array( __( 'Unit Price Base Measure', 'woo-feed' ), true ),
2917
+ 'custom_field_0' => array( __( 'Custom field 0', 'woo-feed' ), true ),
2918
+ 'custom_field_1' => array( __( 'Custom field 1', 'woo-feed' ), true ),
2919
+ 'custom_field_2' => array( __( 'Custom field 2', 'woo-feed' ), true ),
2920
+ 'custom_field_3' => array( __( 'Custom field 3', 'woo-feed' ), true ),
2921
+ 'custom_field_4' => array( __( 'Custom field 4', 'woo-feed' ), true ),
2922
+ );
2923
+
2924
+ return apply_filters( 'woo_feed_product_custom_fields', $custom_fields );
2925
+ }
2926
+ }
2927
+
2928
+ if ( ! function_exists( 'woo_feed_product_attribute_cache_remove_cb' ) ) {
2929
+
2930
+ add_action( 'wp_ajax_woo_feed_product_attribute_cache_remove', 'woo_feed_product_attribute_cache_remove_cb' );
2931
+ /**
2932
+ * This function is called when product attribute swicher click.
2933
+ */
2934
+ function woo_feed_product_attribute_cache_remove_cb() {
2935
+ $is_nonce_valid = isset( $_POST['nonce'] ) && wp_verify_nonce( sanitize_text_field( $_POST['nonce'] ), 'wpf_feed_nonce' );
2936
+
2937
+ if ( $is_nonce_valid ) {
2938
+ delete_transient( '__woo_feed_cache_woo_feed_dropdown_product_attributes' );
2939
+ } else {
2940
+ wp_send_json_error( esc_html__( 'Invalid Request.', 'woo-feed' ) );
2941
+ }
2942
+
2943
+ wp_die();
2944
+ }
2945
+ }
2946
+
2947
+ if ( ! function_exists( 'woo_feed_custom_fields_status_change_cb' ) ) {
2948
+ add_action( 'wp_ajax_woo_feed_custom_fields_status_change', 'woo_feed_custom_fields_status_change_cb' );
2949
+ /**
2950
+ * This AJAX callback function is called when custom fields on/off switched
2951
+ */
2952
+ function woo_feed_custom_fields_status_change_cb() {
2953
+ $is_nonce_valid = isset( $_POST['nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'wpf_feed_nonce' );
2954
+
2955
+ if ( $is_nonce_valid && isset( $_POST['field'], $_POST['status'],
2956
+ $_POST['isTaxonomy'] ) ) {
2957
+ $field = sanitize_text_field( wp_unslash( $_POST['field'] ) );
2958
+ $is_taxonomy = sanitize_text_field( wp_unslash( $_POST['isTaxonomy'] ) );
2959
+ $status = sanitize_text_field( wp_unslash( $_POST['status'] ) );
2960
+ $data = woo_feed_get_options( 'all' );
2961
+ if ( 'true' === $is_taxonomy ) {
2962
+ $data['woo_feed_taxonomy'][ $field ] = ( 'true' === $status ) ? 'enable' : 'disable';
2963
+ } else {
2964
+ $data['woo_feed_identifier'][ $field ] = ( 'true' === $status ) ? 'enable' : 'disable';
2965
+ }
2966
+ update_option( 'woo_feed_settings', $data, false );
2967
+ } else {
2968
+ wp_send_json_error( esc_html__( 'Invalid Request.', 'woo-feed' ) );
2969
+ }
2970
+
2971
+ wp_die();
2972
+ }
2973
+ }
2974
+
2975
+ if ( ! function_exists( 'woo_feed_add_custom_identifier' ) ) {
2976
+ /**
2977
+ * Add Custom fields into product inventory tab for Unique Identifier (GTIN,MPN,EAN)
2978
+ *
2979
+ * @since 3.7.8
2980
+ */
2981
+ function woo_feed_add_custom_identifier() {
2982
+ $custom_fields = woo_feed_product_custom_fields();
2983
+ $custom_identifier_filter = new Woo_Feed_Custom_Identifier_Filter( $custom_fields );
2984
+ $custom_identifier = iterator_to_array( $custom_identifier_filter );
2985
+
2986
+ echo '<div class="options_group">';
2987
+ if ( ! empty( $custom_identifier ) ) {
2988
+ echo sprintf( '<h4 class="%s" style="padding-left: 10px;color: black;">%s</h4>', esc_attr( 'woo-feed-option-title' ), esc_html__( 'CUSTOM FIELDS by CTX Feed', 'woo-feed' ) );
2989
+ foreach ( $custom_identifier as $key => $value ) {
2990
+
2991
+ //identifier meta value for old and new version users
2992
+ $custom_field_key_previous = sprintf( 'woo_feed_identifier_%s', strtolower( $key ) );
2993
+ $custom_field_value_previous = get_post_meta( get_the_ID(), $custom_field_key_previous, true );
2994
+
2995
+ $custom_field_key = sprintf( 'woo_feed_%s', strtolower( $key ) );
2996
+ $custom_field_value = get_post_meta( get_the_ID(), $custom_field_key, true );
2997
+
2998
+ if ( empty( $custom_field_value ) && ! empty( $custom_field_value_previous ) ) {
2999
+ $custom_field_key = $custom_field_key_previous;
3000
+ $custom_field_value = $custom_field_value_previous;
3001
+ }
3002
+
3003
+ $custom_field_id = esc_attr( wp_unslash( "woo_feed_{$key}" ) );
3004
+ $custom_field_label = esc_attr( wp_unslash( $custom_fields[ $key ][0] ) );
3005
+ $custom_field_description = __( 'Set product ', 'woo-feed' ) . esc_html( $custom_field_label ) . __( ' here.', 'woo-feed' );
3006
+ woocommerce_wp_text_input(
3007
+ array(
3008
+ 'id' => $custom_field_id,
3009
+ 'value' => esc_attr( wp_unslash( $custom_field_value ) ),
3010
+ 'placeholder' => $custom_field_label,
3011
+ 'label' => $custom_field_label,
3012
+ 'desc_tip' => true,
3013
+ 'description' => $custom_field_description,
3014
+ )
3015
+ );
3016
+ }
3017
+ }
3018
+
3019
+ echo '</div>';
3020
+
3021
+ }
3022
+
3023
+ add_action( 'woocommerce_product_options_inventory_product_data', 'woo_feed_add_custom_identifier' );
3024
+ }
3025
+
3026
+ if ( ! function_exists( 'woo_feed_save_custom_identifier' ) ) {
3027
+
3028
+ /**
3029
+ * Updating custom fields data. (Unique Identifier (GTIN,MPN,EAN))
3030
+ *
3031
+ * @param int $id Post Id
3032
+ * @param WP_Post $post Wp Post Object.
3033
+ *
3034
+ * @since 3.7.8
3035
+ */
3036
+ function woo_feed_save_custom_identifier( $product_id, $product ) {
3037
+ $custom_fields = woo_feed_product_custom_fields();
3038
+ $custom_identifier_filter = new Woo_Feed_Custom_Identifier_Filter( $custom_fields );
3039
+ $custom_identifier = iterator_to_array( $custom_identifier_filter );
3040
+ $set_meta_val = '';
3041
+
3042
+ if ( ! empty( $custom_identifier ) ) {
3043
+ foreach ( $custom_identifier as $key => $name ) {
3044
+ $product_meta_key = "woo_feed_{$key}";
3045
+
3046
+ $new_meta_key = "woo_feed_identifier_{$key}";
3047
+ $new_meta_val = get_post_meta( $product_id, $new_meta_key, true );
3048
+ $old_meta_val = get_post_meta( $product_id, $product_meta_key, true );
3049
+
3050
+ if ( ! empty( $old_meta_val ) ) {
3051
+ $set_meta_val = $old_meta_val;
3052
+ } else {
3053
+ $set_meta_val = $new_meta_val;
3054
+ }
3055
+
3056
+ $product_meta_value = isset( $_POST[ $product_meta_key ] ) ? sanitize_text_field( $_POST[ $product_meta_key ] ) : ( isset( $_POST["woo_feed_identifier_{$key}"] ) ? sanitize_text_field( $_POST["woo_feed_identifier_{$key}"] ) : $set_meta_val );
3057
+
3058
+ if ( isset( $product_meta_value ) && ! empty( $product_meta_value ) ) {
3059
+ update_post_meta( $product_id, $product_meta_key, $product_meta_value );
3060
+ } else {
3061
+ delete_post_meta( $product_id, $product_meta_key );
3062
+ }
3063
+ }
3064
+ }
3065
+
3066
+ }
3067
+
3068
+ add_action( 'save_post_product', 'woo_feed_save_custom_identifier', 10, 2 );
3069
+ }
3070
+
3071
+ if ( ! function_exists( 'woo_feed_add_custom_identifier_for_variation' ) ) {
3072
+
3073
+ /**
3074
+ * Custom options in variation tab, here we are putting gtin, mpn, ean input fields in product variation tab
3075
+ *
3076
+ * @param int $loop Variation loop index.
3077
+ * @param array $variation_data Variation info.
3078
+ * @param WP_Post $variation Post Object.
3079
+ *
3080
+ * @since 3.7.8
3081
+ */
3082
+ function woo_feed_add_custom_identifier_for_variation( $loop, $variation_data, $variation ) {
3083
+ $settings = woo_feed_get_options( 'all' );
3084
+ if ( isset( $settings['disable_mpn'] ) && "enable" === $settings['disable_mpn'] ) {
3085
+ echo '<div class="woo-feed-variation-options">';
3086
+ $custom_fields = woo_feed_product_custom_fields();
3087
+ $custom_identifier_filter = new Woo_Feed_Custom_Identifier_Filter( $custom_fields );
3088
+ $custom_identifier = iterator_to_array( $custom_identifier_filter );
3089
+
3090
+ if ( ! empty( $custom_identifier ) ) {
3091
+ echo '<div class="woo-feed-variation-options">';
3092
+ echo sprintf( '<h4 class="%s">%s</h4>', esc_attr( 'woo-feed-variation-option-title' ), esc_html__( 'CUSTOM FIELDS by CTX Feed', 'woo-feed' ) );
3093
+ echo '<div class="woo-feed-variation-items">';
3094
+
3095
+ foreach ( $custom_identifier as $key => $value ) {
3096
+ $custom_field_id = sprintf( 'woo_feed_%s_var[%d]', strtolower( $key ), $variation->ID );
3097
+ $custom_field_label = isset( $value[0] ) ? $value[0] : '';
3098
+ $custom_field_description = sprintf( 'Set product %s here.', $custom_field_label );
3099
+
3100
+ //identifier meta value for old and new version users
3101
+ if ( metadata_exists( 'post', $variation->ID, 'woo_feed_' . strtolower( $key ) . '_var' ) ) {
3102
+ $custom_field_key = sprintf( 'woo_feed_%s_var', strtolower( $key ) );
3103
+ } else {
3104
+ $custom_field_key = sprintf( 'woo_feed_identifier_%s_var', strtolower( $key ) );
3105
+ }
3106
+
3107
+ woocommerce_wp_text_input(
3108
+ array(
3109
+ 'id' => $custom_field_id,
3110
+ 'value' => esc_attr( get_post_meta( $variation->ID, $custom_field_key, true ) ),
3111
+ 'placeholder' => esc_html( $custom_field_label ),
3112
+ 'label' => esc_html( $custom_field_label ),
3113
+ 'desc_tip' => true,
3114
+ 'description' => esc_html( $custom_field_description ),
3115
+ 'wrapper_class' => 'form-row form-row-full',
3116
+ )
3117
+ );
3118
+ }
3119
+ echo '</div></div>';
3120
+ }
3121
+ echo '</div>';
3122
+ }
3123
+ }
3124
+
3125
+ add_action( 'woocommerce_product_after_variable_attributes', 'woo_feed_add_custom_identifier_for_variation', 10, 3 );
3126
+ }
3127
+
3128
+ if ( ! function_exists( 'woo_feed_save_custom_identifier_for_variation' ) ) {
3129
+
3130
+ /**
3131
+ * Saving variation custom fields.
3132
+ *
3133
+ * @param int $variation_id Variation Id.
3134
+ * @param int $i variations loop index.
3135
+ *
3136
+ * @since 3.7.8
3137
+ */
3138
+ function woo_feed_save_custom_identifier_for_variation( $variation_id, $i ) {
3139
+ $custom_fields = woo_feed_product_custom_fields();
3140
+ $custom_identifier_filter = new Woo_Feed_Custom_Identifier_Filter( $custom_fields );
3141
+ $custom_identifier = iterator_to_array( $custom_identifier_filter );
3142
+
3143
+ if ( ! empty( $custom_identifier ) ) {
3144
+ foreach ( $custom_identifier as $key => $value ) {
3145
+ $custom_field_value = isset( $_POST["woo_feed_{$key}_var"][ $variation_id ] ) ? sanitize_text_field( $_POST["woo_feed_{$key}_var"][ $variation_id ] ) : ( isset( $_POST["woo_feed_identifier_{$key}_var"][ $variation_id ] ) ? sanitize_text_field( $_POST["woo_feed_identifier_{$key}_var"] ) : '' );
3146
+ if ( isset( $custom_field_value ) ) {
3147
+ update_post_meta( $variation_id, "woo_feed_{$key}_var", $custom_field_value );
3148
+ }
3149
+ }
3150
+ }
3151
+
3152
+ }
3153
+
3154
+ add_action( 'woocommerce_save_product_variation', 'woo_feed_save_custom_identifier_for_variation', 10, 2 );
3155
+ }
3156
+
3157
+ if ( ! function_exists( 'woo_feed_category_mapping' ) ) {
3158
+ /**
3159
+ * Category Mapping
3160
+ */
3161
+ function woo_feed_category_mapping() {
3162
+ // Manage action for category mapping.
3163
+ if ( isset( $_GET['action'], $_GET['cmapping'] ) && 'edit-mapping' == $_GET['action'] ) {
3164
+ if ( count( $_POST ) && isset( $_POST['mappingname'] ) && isset( $_POST['edit-mapping'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
3165
+ check_admin_referer( 'category-mapping' );
3166
+
3167
+ $mappingOption = sanitize_text_field( wp_unslash( $_POST['mappingname'] ) );
3168
+ $mappingOption = 'wf_cmapping_' . sanitize_title( $mappingOption );
3169
+ $mappingData = woo_feed_array_sanitize( $_POST );
3170
+ $oldMapping = maybe_unserialize( get_option( $mappingOption, array() ) );
3171
+
3172
+ # Delete product attribute drop-down cache
3173
+ delete_transient( '__woo_feed_cache_woo_feed_dropdown_product_attributes' );
3174
+
3175
+ if ( $oldMapping === $mappingData ) {
3176
+ update_option( 'wpf_message', esc_html__( 'Mapping Not Changed', 'woo-feed' ), false );
3177
+ wp_safe_redirect( admin_url( 'admin.php?page=webappick-feed-category-mapping&wpf_message=warning' ) );
3178
+ die();
3179
+ }
3180
+
3181
+ if ( update_option( $mappingOption, serialize( $mappingData ), false ) ) { // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize
3182
+ update_option( 'wpf_message', esc_html__( 'Mapping Updated Successfully', 'woo-feed' ), false );
3183
+ wp_safe_redirect( admin_url( 'admin.php?page=webappick-feed-category-mapping&wpf_message=success' ) );
3184
+ die();
3185
+ } else {
3186
+ update_option( 'wpf_message', esc_html__( 'Failed To Updated Mapping', 'woo-feed' ), false );
3187
+ wp_safe_redirect( admin_url( 'admin.php?page=webappick-feed-category-mapping&wpf_message=error' ) );
3188
+ die();
3189
+ }
3190
+ }
3191
+ require WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-category-mapping.php';
3192
+ } elseif ( isset( $_GET['action'] ) && 'add-mapping' == $_GET['action'] ) {
3193
+ if ( count( $_POST ) && isset( $_POST['mappingname'] ) && isset( $_POST['add-mapping'] ) ) {
3194
+ check_admin_referer( 'category-mapping' );
3195
+
3196
+ $mappingOption = 'wf_cmapping_' . sanitize_text_field( wp_unslash( $_POST['mappingname'] ) );
3197
+
3198
+ # Delete product attribute drop-down cache
3199
+ delete_transient( '__woo_feed_cache_woo_feed_dropdown_product_attributes' );
3200
+
3201
+ if ( false !== get_option( $mappingOption, false ) ) {
3202
+ update_option( 'wpf_message', esc_html__( 'Another category mapping exists with the same name.', 'woo-feed' ), false );
3203
+ wp_safe_redirect( admin_url( 'admin.php?page=webappick-feed-category-mapping&wpf_message=warning' ) );
3204
+ die();
3205
+ }
3206
+ if ( update_option( $mappingOption, serialize( woo_feed_array_sanitize( $_POST ) ), false ) ) { // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize
3207
+ update_option( 'wpf_message', esc_html__( 'Mapping Added Successfully', 'woo-feed' ), false );
3208
+ wp_safe_redirect( admin_url( 'admin.php?page=webappick-feed-category-mapping&wpf_message=success' ) );
3209
+ die();
3210
+ } else {
3211
+ update_option( 'wpf_message', esc_html__( 'Failed To Add Mapping', 'woo-feed' ), false );
3212
+ wp_safe_redirect( admin_url( 'admin.php?page=webappick-feed-category-mapping&wpf_message=error' ) );
3213
+ die();
3214
+ }
3215
+ }
3216
+ require WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-category-mapping.php';
3217
+ } else {
3218
+ require WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-category-mapping-list.php';
3219
+ }
3220
+ }
3221
  }
3222
 
3223
  // Category mapping.
3224
+ if ( ! function_exists( 'woo_feed_render_categories' ) ) {
3225
+ /**
3226
+ * Get Product Categories
3227
+ *
3228
+ * @param int $parent Parent ID.
3229
+ * @param string $par separator.
3230
+ * @param string $value mapped values.
3231
+ *
3232
+ * @return void
3233
+ */
3234
+ function woo_feed_render_categories( $parent = 0, $par = '', $value = '' ) {
3235
+ $categoryArgs = [
3236
+ 'taxonomy' => 'product_cat',
3237
+ 'parent' => $parent,
3238
+ 'orderby' => 'term_group',
3239
+ 'show_count' => 1,
3240
+ 'pad_counts' => 1,
3241
+ 'hierarchical' => 1,
3242
+ 'title_li' => '',
3243
+ 'hide_empty' => 0,
3244
+ ];
3245
+ $categories = get_categories( $categoryArgs );
3246
+ if ( ! empty( $categories ) ) {
3247
+ if ( ! empty( $par ) ) {
3248
+ $par = $par . ' > ';
3249
+ }
3250
+ foreach ( $categories as $cat ) {
3251
+ $class = $parent ? "treegrid-parent-{$parent} category-mapping" : 'treegrid-parent category-mapping';
3252
+ ?>
3253
  <tr class="treegrid-1 ">
3254
  <th>
3255
+ <label for="cat_mapping_<?php echo esc_attr( $cat->term_id ); ?>"><?php echo esc_html( $par . $cat->name ); ?></label>
3256
  </th>
3257
  <td colspan="3">
3258
  <!--suppress HtmlUnknownAttribute -->
3259
+ <?php
3260
+ $newOrGoogleFacebook = ! empty( $value )
3261
+ && in_array(
3262
+ $value['mappingprovider'],
3263
+ array(
3264
+ 'google',
3265
+ 'facebook',
3266
+ 'pinterest',
3267
+ 'bing',
3268
+ 'bing_local_inventory',
3269
+ 'snapchat'
3270
+ )
3271
+ );
3272
+
3273
+ $previous_mapping_value = is_array( $value ) && isset( $value['cmapping'][ $cat->term_id ] ) ? esc_attr( $value['cmapping'][ $cat->term_id ] ) : '';
3274
+ $previous_listing_mapping_value = is_array( $value ) && isset( $value['gcl-cmapping'][ $cat->term_id ] ) && ! empty( $value['gcl-cmapping'][ $cat->term_id ] )
3275
+ ? esc_attr( $value['gcl-cmapping'][ $cat->term_id ] )
3276
+ : $previous_mapping_value;
3277
+
3278
+ ?>
3279
+ <input <?php echo ( ! $newOrGoogleFacebook ) ? '' : 'style=" display: none;" '; ?>
3280
+ id="cat_mapping_<?php echo esc_attr( $cat->term_id ); ?>"
3281
+ class="<?php echo esc_attr( $class ); ?> woo-feed-mapping-input"
3282
+ autocomplete="off"
3283
+ type="text"
3284
+ name="cmapping[<?php echo esc_attr( $cat->term_id ); ?>]"
3285
+ placeholder="<?php echo esc_attr( $par . $cat->name ); ?>"
3286
+ data-cat_id="<?php echo esc_attr( $cat->term_id ); ?>"
3287
+ value="<?php echo $previous_mapping_value; ?>"
3288
  >
3289
+ <span
3290
+ <?php echo ( $newOrGoogleFacebook ) ? '' : 'style=" display: none;" '; ?>class="wf_default wf_attributes">
3291
+ <select name="gcl-cmapping[<?php echo $cat->term_id ?>]"
3292
+ class="selectize selectize-google-category woo-feed-mapping-select"
3293
+ data-selected="<?php echo $previous_mapping_value; ?>"
3294
+ data-placeholder="<?php esc_attr_e( 'Select A Category', 'woo-feed' ); ?>">
3295
+ <option value="<?php echo esc_attr( $previous_listing_mapping_value ); ?>" selected>
3296
  <?php echo esc_attr( $previous_listing_mapping_value ); ?>
3297
  </option>
3298
  </select>
3299
 
3300
  </span>
3301
  </td>
3302
+ <?php
3303
+ if ( ! empty( get_term_children( $cat->term_id, 'product_cat' ) ) ) {
3304
+ $woo_map_term_id = 'parent-' . $cat->term_id;
3305
+ } else {
3306
+ $woo_map_term_id = 'child-' . $cat->parent;
3307
+ }
3308
+ $termchildren = ! empty( get_term_children( $cat->term_id, 'product_cat' ) ) || $cat->parent;
3309
+ ?>
3310
+ <td class="<?php echo $termchildren ? 'group-' . $woo_map_term_id : ''; ?>">
3311
+ <?php
3312
+ $childrencat = ! empty( get_term_children( $cat->term_id, 'product_cat' ) );
3313
+ if ( $childrencat ) {
3314
+ $title = __( 'Copy this category to subcategories', 'woo-feed' );
3315
+ echo '<span class="dashicons dashicons-arrow-down-alt" title=" ' . $title . '" id="cat-map-' . $cat->term_id . '"></span>';
3316
+ }
3317
+ ?>
3318
  </td>
3319
  </tr>
3320
+ <?php
3321
+ // call and render the child category if any.
3322
+ woo_feed_render_categories( $cat->term_id, $par . $cat->name, $value );
3323
+ }
3324
+ }
3325
+ }
3326
+ }
3327
+
3328
+ if ( ! function_exists( 'woo_feed_clear_cache_button' ) ) {
3329
+ /**
3330
+ * Clear cache button.
3331
+ *
3332
+ * @return void
3333
+ * @since 4.1.2
3334
+ */
3335
+ function woo_feed_clear_cache_button() {
3336
+ ?>
3337
  <div class="wf_clean_cache_wrapper">
3338
  <img class="woo-feed-cache-loader"
3339
  src="data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22iso-8859-1%22%3F%3E%0D%0A%3C%21--%20Generator%3A%20Adobe%20Illustrator%2019.0.0%2C%20SVG%20Export%20Plug-In%20.%20SVG%20Version%3A%206.00%20Build%200%29%20%20--%3E%0D%0A%3Csvg%20version%3D%221.1%22%20id%3D%22Capa_1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20x%3D%220px%22%20y%3D%220px%22%0D%0A%09%20viewBox%3D%220%200%20458.186%20458.186%22%20style%3D%22enable-background%3Anew%200%200%20458.186%20458.186%3B%22%20xml%3Aspace%3D%22preserve%22%3E%0D%0A%3Cg%3E%0D%0A%09%3Cg%3E%0D%0A%09%09%3Cpath%20d%3D%22M445.651%2C201.95c-1.485-9.308-10.235-15.649-19.543-14.164c-9.308%2C1.485-15.649%2C10.235-14.164%2C19.543%0D%0A%09%09%09c0.016%2C0.102%2C0.033%2C0.203%2C0.051%2C0.304c17.38%2C102.311-51.47%2C199.339-153.781%2C216.719c-102.311%2C17.38-199.339-51.47-216.719-153.781%0D%0A%09%09%09S92.966%2C71.232%2C195.276%2C53.852c62.919-10.688%2C126.962%2C11.29%2C170.059%2C58.361l-75.605%2C25.19%0D%0A%09%09%09c-8.944%2C2.976-13.781%2C12.638-10.806%2C21.582c0.001%2C0.002%2C0.002%2C0.005%2C0.003%2C0.007c2.976%2C8.944%2C12.638%2C13.781%2C21.582%2C10.806%0D%0A%09%09%09c0.003-0.001%2C0.005-0.002%2C0.007-0.002l102.4-34.133c6.972-2.322%2C11.675-8.847%2C11.674-16.196v-102.4%0D%0A%09%09%09C414.59%2C7.641%2C406.949%2C0%2C397.523%2C0s-17.067%2C7.641-17.067%2C17.067v62.344C292.564-4.185%2C153.545-0.702%2C69.949%2C87.19%0D%0A%09%09%09s-80.114%2C226.911%2C7.779%2C310.508s226.911%2C80.114%2C310.508-7.779C435.905%2C339.799%2C457.179%2C270.152%2C445.651%2C201.95z%22%2F%3E%0D%0A%09%3C%2Fg%3E%0D%0A%3C%2Fg%3E%0D%0A%3Cg%3E%0D%0A%3C%2Fg%3E%0D%0A%3Cg%3E%0D%0A%3C%2Fg%3E%0D%0A%3Cg%3E%0D%0A%3C%2Fg%3E%0D%0A%3Cg%3E%0D%0A%3C%2Fg%3E%0D%0A%3Cg%3E%0D%0A%3C%2Fg%3E%0D%0A%3Cg%3E%0D%0A%3C%2Fg%3E%0D%0A%3Cg%3E%0D%0A%3C%2Fg%3E%0D%0A%3Cg%3E%0D%0A%3C%2Fg%3E%0D%0A%3Cg%3E%0D%0A%3C%2Fg%3E%0D%0A%3Cg%3E%0D%0A%3C%2Fg%3E%0D%0A%3Cg%3E%0D%0A%3C%2Fg%3E%0D%0A%3Cg%3E%0D%0A%3C%2Fg%3E%0D%0A%3Cg%3E%0D%0A%3C%2Fg%3E%0D%0A%3Cg%3E%0D%0A%3C%2Fg%3E%0D%0A%3Cg%3E%0D%0A%3C%2Fg%3E%0D%0A%3C%2Fsvg%3E%0D%0A"
3340
  alt="loader">
3341
  <input type="hidden" class="woo-feed-clean-cache-nonce"
3342
+ value="<?php echo wp_create_nonce( 'clean_cache_nonce' ); //phpcs:ignore
3343
+ ?>">
3344
+ <button type="button"><?php esc_html_e( 'Clear Cache', 'woo-feed' ); ?></button>
3345
  </div>
3346
+ <?php
3347
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3348
  }
3349
 
3350
+ if ( ! function_exists( 'woo_feed_clear_cache_data' ) ) {
3351
+ /**
3352
+ * Clear cache data.
3353
+ *
3354
+ * @param int _ajax_clean_nonce nonce number.
3355
+ *
3356
+ * @since 4.1.2
3357
+ */
3358
+ function woo_feed_clear_cache_data() {
3359
+ if ( isset( $_REQUEST['_ajax_clean_nonce'] ) ) {
3360
 
3361
+ if ( wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['_ajax_clean_nonce'] ) ), 'clean_cache_nonce' ) ) {
3362
+ $data = [];
 
3363
 
3364
+ global $wpdb;
3365
+ //TODO add wpdb prepare statement
3366
+ $wpdb->query( "DELETE FROM $wpdb->options WHERE ({$wpdb->options}.option_name LIKE '_transient_timeout___woo_feed_cache_%') OR ({$wpdb->options}.option_name LIKE '_transient___woo_feed_cache_%')" ); // phpcs:ignore
3367
 
 
 
 
3368
 
3369
+ $data = [ 'success' => true ];
3370
 
3371
+ wp_send_json_success( $data );
3372
+ }
3373
+ } else {
3374
+ wp_send_json_error( esc_html__( 'Invalid Request.', 'woo-feed' ) );
3375
+ }
3376
+ wp_die();
3377
+ }
3378
+ }
3379
+ add_action( 'wp_ajax_clear_cache_data', 'woo_feed_clear_cache_data' );
3380
+
3381
+ if ( ! function_exists( 'woo_feed_get_current_timestamp' ) ) {
3382
+ /**
3383
+ * Current local timestamp UTC.
3384
+ *
3385
+ * @since 4.2.0
3386
+ */
3387
+ function woo_feed_get_current_timestamp() {
3388
 
3389
+ $interval = get_option( 'wf_schedule' );
 
 
3390
 
3391
+ $current_timestamp = time() + $interval;
3392
 
3393
+ return $current_timestamp;
3394
+ }
3395
  }
3396
 
3397
+ if ( ! function_exists( 'woo_feed_deep_term' ) ) {
3398
+
3399
+ /**
3400
+ * Get product terms list by hierarchical order.
3401
+ *
3402
+ * @param object $term product term object
3403
+ *
3404
+ * @return string
3405
+ * @since 4.3.88+
3406
+ */
3407
+ function woo_feed_deep_term( $term, $taxonomy ) {
3408
+
3409
+ if ( $term->parent === 0 ) {
3410
+ return $term->name;
3411
+ }
3412
 
3413
+ $parent_term = get_term_by( 'term_id', $term->parent, $taxonomy );
3414
+
3415
+ return woo_feed_deep_term( $parent_term, $taxonomy ) . ' > ' . $term->name;
3416
+ }
3417
+ }
3418
+
3419
+ if ( ! function_exists( 'woo_feed_parent_category' ) ) {
3420
+
3421
+ /**
3422
+ * Get product terms list by hierarchical order.
3423
+ *
3424
+ * @param WP_Term $term product term object
3425
+ *
3426
+ * @return WP_Term $term product parent term object
3427
+ * @since 4.4.19
3428
+ */
3429
+ function woo_feed_parent_category( $term, $taxonomy ) {
3430
+
3431
+ if ( $term->parent === 0 ) {
3432
+ return $term;
3433
+ }
3434
+
3435
+ $parent_term = get_term_by( 'term_id', $term->parent, $taxonomy );
3436
+
3437
+ return woo_feed_parent_category( $parent_term, $taxonomy );
3438
+ }
3439
+ }
3440
+
3441
+ if ( ! function_exists( 'woo_feed_get_terms_list_hierarchical_order' ) ) {
3442
+ /**
3443
+ * Get product terms list by hierarchical order.
3444
+ *
3445
+ * @param int $id post id
3446
+ * @param bool $full_path get full category path if true
3447
+ * @param string $taxonomy post taxonomy
3448
+ *
3449
+ * @return false|string
3450
+ * @return string
3451
+ * @since 4.2.1
3452
+ *
3453
+ */
3454
+ function woo_feed_get_terms_list_hierarchical_order( $id, $full_path = true, $taxonomy = 'product_cat' ) {
3455
+
3456
+ $terms = get_the_terms( $id, $taxonomy );
3457
+
3458
+ if ( count( $terms ) ) {
3459
+
3460
+ if ( $full_path ) {
3461
+ return woo_feed_deep_term( $terms[ count( $terms ) - 1 ], $taxonomy );
3462
+ } else {
3463
+ return $terms[ count( $terms ) - 1 ]->name;
3464
+ }
3465
+ }
3466
+
3467
+ return false;
3468
+ }
3469
+ }
3470
+
3471
+ if ( ! function_exists( 'woo_feed_get_products_ids_of_reviews' ) ) {
3472
+ /**
3473
+ * Get reviews product ids .
3474
+ *
3475
+ * @return array $review_products_ids // review products ids
3476
+ * @since 4.0.5
3477
+ */
3478
+ function woo_feed_get_products_ids_of_reviews() {
3479
+ $args = array( 'post_type' => 'product' );
3480
+ $reviews = get_comments( $args );
3481
+ $review_products_ids = wp_list_pluck( $reviews, 'comment_post_ID' );
3482
+
3483
+
3484
+ return ! empty( $review_products_ids ) && is_array( $review_products_ids ) ? array_unique( $review_products_ids ) : array();
3485
+
3486
+ }
3487
+ }
3488
+
3489
+ if ( ! function_exists( 'woo_feed_get_approved_reviews_data' ) ) {
3490
+ /**
3491
+ * Get approved review's data.
3492
+ *
3493
+ * @return mixed
3494
+ * @since 4.3.0
3495
+ */
3496
+ function woo_feed_get_approved_reviews_data() {
3497
+ $approved_reviews = [];
3498
+ $product_ids = woo_feed_get_products_ids_of_reviews();
3499
+
3500
+ if ( ! empty( $product_ids ) && is_array( $product_ids ) ) {
3501
+
3502
+ foreach ( $product_ids as $product_id ) {
3503
+ $reviews = get_comments( array(
3504
+ 'post_id' => $product_id,
3505
+ 'comment_type' => 'review',
3506
+ 'comment_approved' => 1,
3507
+ 'parent' => 0,
3508
+ ) );
3509
+
3510
+ $product_name = get_the_title( $product_id );
3511
+ $product_link = get_the_permalink( $product_id );
3512
+
3513
+ if ( is_array( $reviews ) && sizeof( $reviews ) > 0 ) {
3514
+ foreach ( $reviews as $item ) {
3515
+ $review = array();
3516
+ $review['review_ratings'] = get_comment_meta( $item->comment_ID, 'rating', true );
3517
+ $review['review_id'] = $item->comment_ID;
3518
+ $review['reviewer']['name'] = strip_tags( trim( ucfirst( $item->comment_author ) ) );
3519
+ $review['reviewer']['reviewer_id'] = $item->user_id;
3520
+ $review['review_timestamp'] = $item->comment_date;
3521
+ $review['review_product_name'] = $product_name;
3522
+ $review['review_url'] = $product_link;
3523
+ $review['review_product_url'] = $product_link;
3524
+ $review['title'] = $product_name;
3525
+ $review['content'] = $item->comment_content;
3526
+
3527
+ //product ids
3528
+ $review['products']['product']['product_ids']['gtins']['gtin'] = '';
3529
+ $review['products']['product']['product_ids']['mpns']['mpn'] = '';
3530
+ $review['products']['product']['product_ids']['skus']['sku'] = '';
3531
+ $review['products']['product']['product_ids']['brands']['brand'] = '';
3532
+ $review['products']['product']['product_name'] = $product_name;
3533
+ $review['products']['product']['product_url'] = $product_link;
3534
+ array_push( $approved_reviews, $review );
3535
+ }
3536
+ }
3537
+ }
3538
+ }
3539
+
3540
+ return $approved_reviews;
3541
+
3542
+ }
3543
+ }
3544
+
3545
+ if ( ! function_exists( 'woo_feed_save_black_friday_notice_2021_notice' ) ) {
3546
+ /**
3547
+ * Update user meta to work ctx startup notice once.
3548
+ *
3549
+ * @param int _ajax_nonce nonce number.
3550
+ *
3551
+ * @since 4.3.31
3552
+ * @author Nazrul Islam Nayan
3553
+ */
3554
+ function woo_feed_save_black_friday_notice_2021_notice() {
3555
+ if ( isset( $_REQUEST['_wp_ajax_nonce'] ) && wp_verify_nonce( wp_unslash( $_REQUEST['_wp_ajax_nonce'] ), 'woo-feed-to-ctx-feed-notice' ) ) { //phpcs:ignore
3556
+ $user_id = get_current_user_id();
3557
+ if ( isset( $_REQUEST['clicked'] ) ) {
3558
+ $updated_user_meta = add_user_meta( $user_id, 'woo_feed_black_friday_notice_2021_dismissed', 'true', true );
3559
+
3560
+ if ( $updated_user_meta ) {
3561
+ wp_send_json_success( esc_html__( 'User meta updated successfully.', 'woo-feed' ) );
3562
+ } else {
3563
+ wp_send_json_error( esc_html__( 'Something is wrong.', 'woo-feed' ) );
3564
+ }
3565
+ }
3566
+ } else {
3567
+ wp_send_json_error( esc_html__( 'Invalid Request.', 'woo-feed' ) );
3568
+ }
3569
+ wp_die();
3570
+ }
3571
+ }
3572
+ add_action( 'wp_ajax_woo_feed_save_black_friday_notice_2021_notice', 'woo_feed_save_black_friday_notice_2021_notice' );
3573
+
3574
+ if ( ! function_exists( 'woo_feed_hide_promotion' ) ) {
3575
+ /**
3576
+ * Update option to hide promotion.
3577
+ *
3578
+ * @param int _ajax_nonce nonce number.
3579
+ *
3580
+ * @since 5.1.7
3581
+ */
3582
+ function woo_feed_hide_promotion() {
3583
+ if ( isset( $_REQUEST['_ajax_nonce'] ) ) {
3584
+ $hide_promotion = update_option( 'woo_feed_hide_promotion', 1 );
3585
+ $data = array(
3586
+ 'msg' => 'Hide promotion updated successfully.',
3587
+ );
3588
+ if ( $hide_promotion ) {
3589
+ wp_send_json_success( $data );
3590
+ } else {
3591
+ wp_send_json_error( esc_html__( 'Something is wrong.', 'woo-feed' ) );
3592
+ }
3593
+ } else {
3594
+ wp_send_json_error( esc_html__( 'Invalid Request.', 'woo-feed' ) );
3595
+ }
3596
+ wp_die();
3597
+ }
3598
+ }
3599
+ add_action( 'wp_ajax_woo_feed_hide_promotion', 'woo_feed_hide_promotion' );
3600
+
3601
+ if ( ! function_exists( 'array_key_first' ) ) {
3602
+ /**
3603
+ * Array first key.
3604
+ *
3605
+ * @param array $arr given array.
3606
+ *
3607
+ * @return mixed
3608
+ * @since 4.3.0
3609
+ */
3610
+ function array_key_first( array $arr ) {
3611
+ foreach ( $arr as $k => $unused ) {
3612
+ return $k;
3613
+ }
3614
+
3615
+ return null;
3616
+ }
3617
+ }
3618
+
3619
+ if ( ! function_exists( 'woo_feed_custom_taxonomy' ) ) {
3620
+ function woo_feed_custom_taxonomy() {
3621
+ $custom_fields = woo_feed_product_custom_fields();
3622
+ $custom_taxonomies_filter = new Woo_Feed_Custom_Taxonomy_Filter( $custom_fields );
3623
+ $custom_taxonomies = iterator_to_array( $custom_taxonomies_filter );
3624
+
3625
+ $settings = woo_feed_get_options( 'all' );
3626
+ if ( isset( $settings['woo_feed_taxonomy'], $settings['woo_feed_identifier'] ) ) {
3627
+ $custom_attributes = array_merge( $settings['woo_feed_taxonomy'], $settings['woo_feed_identifier'] );
3628
+ } else {
3629
+ $custom_attributes = $settings['woo_feed_taxonomy'];
3630
+ }
3631
+
3632
+ if ( isset( $custom_attributes['brand'] ) && 'enable' === $custom_attributes['brand'] ) {
3633
+ if ( ! empty( $custom_taxonomies ) ) {
3634
+ foreach ( $custom_taxonomies as $key => $value ) {
3635
+ $taxonomy_name = esc_html( $value[0] );
3636
+
3637
+ $labels = array(
3638
+ 'name' => $taxonomy_name . ' ' . __( 'by CTX Feed', 'woo-feed' ),
3639
+ 'singular_name' => $taxonomy_name,
3640
+ 'menu_name' => $taxonomy_name . 's ' . __( 'by CTX Feed', 'woo-feed' ),
3641
+ 'all_items' => __( 'All', 'woo-feed' ) . ' ' . $taxonomy_name . 's',
3642
+ 'parent_item' => __( 'Parent', 'woo-feed' ) . $taxonomy_name,
3643
+ 'parent_item_colon' => __( 'Parent:', 'woo-feed' ) . $taxonomy_name . ':',
3644
+ 'new_item_name' => __( 'New', 'woo-feed' ) . ' ' . $taxonomy_name . ' ' . __( 'Name', 'woo-feed' ),
3645
+ 'add_new_item' => __( 'Add New', 'woo-feed' ) . ' ' . $taxonomy_name,
3646
+ 'edit_item' => __( 'Edit', 'woo-feed' ) . ' ' . $taxonomy_name,
3647
+ 'update_item' => __( 'Update', 'woo-feed' ) . ' ' . $taxonomy_name,
3648
+ 'separate_items_with_commas' => __( 'Separate', 'woo-feed' ) . ' ' . $taxonomy_name . ' ' . __( 'with commas', 'woo-feed' ),
3649
+ 'search_items' => __( 'Search', 'woo-feed' ) . ' ' . $taxonomy_name,
3650
+ 'add_or_remove_items' => __( 'Add or remove', 'woo-feed' ) . ' ' . $taxonomy_name,
3651
+ 'choose_from_most_used' => __( 'Choose from the most used', 'woo-feed' ) . ' ' . $taxonomy_name . 's',
3652
+ );
3653
+ $args = array(
3654
+ 'labels' => $labels,
3655
+ 'hierarchical' => true,
3656
+ 'public' => true,
3657
+ 'show_ui' => true,
3658
+ 'show_admin_column' => false,
3659
+ 'show_in_rest' => true,
3660
+ 'show_in_nav_menus' => true,
3661
+ 'show_tagcloud' => true,
3662
+ 'show_in_quick_edit' => false,
3663
+ );
3664
+ $taxonomy_key = sprintf( 'woo-feed-%s', strtolower( $key ) );
3665
+
3666
+ register_taxonomy( $taxonomy_key, 'product', $args );
3667
+ }
3668
+ }
3669
+ }
3670
+
3671
+ }
3672
+
3673
+ add_action( 'init', 'woo_feed_custom_taxonomy' );
3674
+ }
3675
+
3676
+ if ( ! function_exists( 'woo_feed_brand_term_radio_checklist' ) ) {
3677
+
3678
+ /**
3679
+ * Use radio inputs product brand taxonomies
3680
+ *
3681
+ * @param $args
3682
+ *
3683
+ * @return mixed
3684
+ */
3685
+ function woo_feed_brand_term_radio_checklist( $args ) {
3686
+ if ( ! empty( $args['taxonomy'] ) && 'woo-feed-brand' === $args['taxonomy'] ) {
3687
+ if ( empty( $args['walker'] ) || is_a( $args['walker'], 'Walker' ) ) {
3688
+ if ( ! class_exists( 'Woo_Feed_Brand_Walker_Category_Radio_Checklist' ) ) {
3689
+ /**
3690
+ * Custom walker for switching checkbox inputs to radio.
3691
+ *
3692
+ * @see Walker_Category_Checklist
3693
+ */
3694
+ class Woo_Feed_Brand_Walker_Category_Radio_Checklist extends Walker_Category_Checklist {
3695
+ function walk( $elements, $max_depth, ...$args ) {
3696
+ $output = parent::walk( $elements, $max_depth, ...$args );
3697
+ $output = str_replace(
3698
+ array( 'type="checkbox"', "type='checkbox'" ),
3699
+ array( 'type="radio"', "type='radio'" ),
3700
+ $output
3701
+ );
3702
+
3703
+ return $output;
3704
+ }
3705
+ }
3706
+ }
3707
+ $args['walker'] = new Woo_Feed_Brand_Walker_Category_Radio_Checklist();
3708
+ }
3709
+ }
3710
+
3711
+ return $args;
3712
+ }
3713
+
3714
+ add_filter( 'wp_terms_checklist_args', 'woo_feed_brand_term_radio_checklist' );
3715
+ }
3716
+
3717
+ if ( ! function_exists( 'woo_feed_filter_woocommerce_structured_data_product' ) ) {
3718
+
3719
+ $settings = woo_feed_get_options( 'all' );
3720
+ $overridden_structured_data = $settings['overridden_structured_data'];
3721
+
3722
+
3723
+ if ( "on" === $overridden_structured_data ) {
3724
+
3725
+ /**
3726
+ * Removed woocommerce default schema structure
3727
+ *
3728
+ * @param $markup
3729
+ * @param $product
3730
+ *
3731
+ * @return array $markup
3732
+ * @since 4.3.6
3733
+ */
3734
+ function woo_feed_filter_woocommerce_structured_data_product( $markup, $product ) {
3735
+
3736
+ if ( ! $product instanceof WC_Product ) {
3737
+ return $markup;
3738
+ }
3739
+
3740
+ $settings = woo_feed_get_options( 'all' );
3741
+ $disable_mpn = $settings['disable_mpn'];
3742
+ $disable_brand = $settings['disable_brand'];
3743
+
3744
+ $description = apply_filters( 'woo_feed_schema_description', wp_strip_all_tags( $product->get_short_description() ? $product->get_short_description() : $product->get_description() ), $product );
3745
+ $markup["description"] = $description;
3746
+
3747
+ if ( 'enable' === $disable_brand ) {
3748
+ $brand_term = wp_get_post_terms( $product->get_id(), 'woo-feed-brand', array( 'fields' => 'names' ) );
3749
+
3750
+ if ( ! is_wp_error( $brand_term ) ) {
3751
+ if ( isset( $brand_term[0] ) ) {
3752
+ $markup['brand']["name"] = $brand_term[0];
3753
+ }
3754
+ }
3755
+ }
3756
+
3757
+ //get price and currency to work with all the compatible currency plugin
3758
+ $price = $product->get_price();
3759
+ $currency = get_woocommerce_currency();
3760
+
3761
+ //filter schema price & currency
3762
+ $price = apply_filters( 'woo_feed_schema_product_price', $price, $markup, $product );
3763
+ $currency = apply_filters( 'woo_feed_schema_product_currency', $currency, $markup, $product );
3764
+ $markup['offers'][0]['price'] = $price;
3765
+ $markup['offers'][0]['priceSpecification']['price'] = $price;
3766
+ $markup['offers'][0]['priceSpecification']['priceCurrency'] = $currency;
3767
+ $markup['offers'][0]['priceCurrency'] = $currency;
3768
+
3769
+ // Check if we have mpn data.
3770
+ if ( 'enable' === $disable_mpn && ! empty( $mpn ) ) {
3771
+ $mpn = $product->get_meta( 'woo_feed_mpn' );
3772
+ $markup['mpn'] = $mpn;
3773
+ }
3774
+
3775
+ $markup = apply_filters( "woo_feed_after_wc_product_structured_data", $markup, $product );
3776
+
3777
+ return $markup;
3778
+ }
3779
+
3780
+ add_filter( 'woocommerce_structured_data_product', 'woo_feed_filter_woocommerce_structured_data_product', 10, 2 );
3781
+
3782
+ }
3783
+ }
3784
+
3785
+ if ( ! function_exists( 'woo_feed_trim_attribute' ) ) {
3786
+ /**
3787
+ * Trim attribute by specific sign
3788
+ *
3789
+ * @param $attribute string feed attribute
3790
+ *
3791
+ * @return mixed
3792
+ */
3793
+ function woo_feed_trim_attribute( $attribute ) {
3794
+ return str_replace( '_', ' ', $attribute );
3795
+ }
3796
  }
3797
 
3798
  // Facebook pixel integration
3799
  if ( ! function_exists( 'woo_feed_facebook_pixel_init' ) ) {
3800
 
3801
+ function woo_feed_facebook_pixel_init() {
3802
+ new WebAppick\Feed\Tracker\Facebook\Pixel();
3803
+ }
3804
 
3805
+ add_action( 'init', 'woo_feed_facebook_pixel_init' );
3806
 
3807
  }
3808
 
3809
  // Google Remarketing integration
3810
  if ( ! function_exists( 'woo_feed_google_remarketing_init' ) ) {
3811
 
3812
+ function woo_feed_google_remarketing_init() {
3813
+ new WebAppick\Feed\Tracker\Google\Remarketing();
3814
+ }
3815
+
3816
+ add_action( 'init', 'woo_feed_google_remarketing_init' );
3817
+
3818
+ }
3819
+
3820
+ if ( ! function_exists( 'woo_feed_filter_dropdown_attributes' ) ) {
3821
+ /**
3822
+ * Woo Feed Filter Dropdown Attributes
3823
+ *
3824
+ * @param array $default_attr default attributes
3825
+ * @param array $merchants merchant names
3826
+ *
3827
+ * @return array $filtered_attributes
3828
+ *
3829
+ * @author Nazrul Islam Nayan
3830
+ * @updated 23-12-2020
3831
+ *
3832
+ * @since 4.3.11
3833
+ */
3834
+ function woo_feed_filter_dropdown_attributes( $default_attr, $merchants ) {
3835
+ $filtered_attributes = $default_attr;
3836
+ $snapchat_additional_attr = array();
3837
+ $snapchat_additional_attr['--18'] = 'Snapchat Additional Attributes';
3838
+ $snapchat_additional_attr['icon_media_url'] = 'Icon Media Url[icon_media_url]';
3839
+ $snapchat_additional_attr['ios_app_name'] = 'IOS App Name[ios_app_name]';
3840
+ $snapchat_additional_attr['ios_app_store_id'] = 'IOS App Store ID[ios_app_store_id]';
3841
+ $snapchat_additional_attr['ios_url'] = 'IOS Url[ios_url]';
3842
+ $snapchat_additional_attr['android_app_name'] = 'Android App Name[android_app_name]';
3843
+ $snapchat_additional_attr['android_package'] = 'Android Package[android_package]';
3844
+ $snapchat_additional_attr['android_url'] = 'Android URL[android_url]';
3845
+ $snapchat_additional_attr['mobile_link'] = 'Mobile Link[mobile_link]';
3846
+ $snapchat_additional_attr['---18'] = '';
3847
+
3848
+ //filtering attributes for pinterest merchant
3849
+ if ( in_array( 'pinterest', $merchants ) ) {
3850
+ if ( isset( $default_attr['ads_redirect'] ) ) {
3851
+ if ( array_key_exists( 'ads_redirect', $default_attr ) ) {
3852
+ $keys = array_keys( $default_attr );
3853
+ $keys[ array_search( 'ads_redirect', $keys ) ] = 'ads_link';
3854
+ $filtered_attributes = array_combine( $keys, $default_attr );
3855
+ $filtered_attributes['ads_link'] = 'Ads Link[ads_link]';
3856
+ }
3857
+ }
3858
+ }
3859
+
3860
+ //filtering attributes for snapchat merchant
3861
+ if ( in_array( 'snapchat', $merchants ) ) {
3862
+ $filtered_attributes = array_merge( $filtered_attributes, $snapchat_additional_attr );
3863
+ }
3864
+
3865
+ //filtering attributes for facebook merchant
3866
+ if ( in_array( 'facebook', $merchants ) ) {
3867
+ if ( isset( $filtered_attributes['excluded_destination'] ) ) {
3868
+ $facebook_attributes = array();
3869
+ $facebook_attributes['quantity_to_sell_on_facebook'] = 'Quantity to sell on facebook [quantity_to_sell_on_facebook]';
3870
+ $filtered_attributes = woo_feed_array_insert_after( $filtered_attributes, 'excluded_destination', $facebook_attributes );
3871
+ }
3872
+ }
3873
+
3874
+ return $filtered_attributes;
3875
+ }
3876
+
3877
+ add_filter( 'woo_feed_filter_dropdown_attributes', 'woo_feed_filter_dropdown_attributes', 2, 10 );
3878
+ }
3879
+
3880
+
3881
+ if ( ! function_exists( 'woo_feed_countries' ) ) {
3882
+ /**
3883
+ * Woo Feed Country List
3884
+ *
3885
+ * @return array
3886
+ * @since 4.3.16
3887
+ * @author Nazrul Islam Nayan
3888
+ * @updated 10-01-2021
3889
+ *
3890
+ */
3891
+
3892
+ function woo_feed_countries() {
3893
+
3894
+ return array(
3895
+ 'AF' => 'Afghanistan',
3896
+ 'AX' => 'Aland Islands',
3897
+ 'AL' => 'Albania',
3898
+ 'DZ' => 'Algeria',
3899
+ 'AS' => 'American Samoa',
3900
+ 'AD' => 'Andorra',
3901
+ 'AO' => 'Angola',
3902
+ 'AI' => 'Anguilla',
3903
+ 'AQ' => 'Antarctica',
3904
+ 'AG' => 'Antigua and Barbuda',
3905
+ 'AR' => 'Argentina',
3906
+ 'AM' => 'Armenia',
3907
+ 'AW' => 'Aruba',
3908
+ 'AU' => 'Australia',
3909
+ 'AT' => 'Austria',
3910
+ 'AZ' => 'Azerbaijan',
3911
+ 'BS' => 'Bahamas the',
3912
+ 'BH' => 'Bahrain',
3913
+ 'BD' => 'Bangladesh',
3914
+ 'BB' => 'Barbados',
3915
+ 'BY' => 'Belarus',
3916
+ 'BE' => 'Belgium',
3917
+ 'BZ' => 'Belize',
3918
+ 'BJ' => 'Benin',
3919
+ 'BM' => 'Bermuda',
3920
+ 'BT' => 'Bhutan',
3921
+ 'BO' => 'Bolivia',
3922
+ 'BA' => 'Bosnia and Herzegovina',
3923
+ 'BW' => 'Botswana',
3924
+ 'BV' => 'Bouvet Island (Bouvetoya)',
3925
+ 'BR' => 'Brazil',
3926
+ 'IO' => 'British Indian Ocean Territory (Chagos Archipelago)',
3927
+ 'VG' => 'British Virgin Islands',
3928
+ 'BN' => 'Brunei Darussalam',
3929
+ 'BG' => 'Bulgaria',
3930
+ 'BF' => 'Burkina Faso',
3931
+ 'BI' => 'Burundi',
3932
+ 'KH' => 'Cambodia',
3933
+ 'CM' => 'Cameroon',
3934
+ 'CA' => 'Canada',
3935
+ 'CV' => 'Cape Verde',
3936
+ 'KY' => 'Cayman Islands',
3937
+ 'CF' => 'Central African Republic',
3938
+ 'TD' => 'Chad',
3939
+ 'CL' => 'Chile',
3940
+ 'CN' => 'China',
3941
+ 'CX' => 'Christmas Island',
3942
+ 'CC' => 'Cocos (Keeling) Islands',
3943
+ 'CO' => 'Colombia',
3944
+ 'KM' => 'Comoros the',
3945
+ 'CD' => 'Congo',
3946
+ 'CG' => 'Congo the',
3947
+ 'CK' => 'Cook Islands',
3948
+ 'CR' => 'Costa Rica',
3949
+ 'CI' => 'Cote d\'Ivoire',
3950
+ 'HR' => 'Croatia',
3951
+ 'CU' => 'Cuba',
3952
+ 'CY' => 'Cyprus',
3953
+ 'CZ' => 'Czech Republic',
3954
+ 'DK' => 'Denmark',
3955
+ 'DJ' => 'Djibouti',
3956
+ 'DM' => 'Dominica',
3957
+ 'DO' => 'Dominican Republic',
3958
+ 'EC' => 'Ecuador',
3959
+ 'EG' => 'Egypt',
3960
+ 'SV' => 'El Salvador',
3961
+ 'GQ' => 'Equatorial Guinea',
3962
+ 'ER' => 'Eritrea',
3963
+ 'EE' => 'Estonia',
3964
+ 'ET' => 'Ethiopia',
3965
+ 'FO' => 'Faroe Islands',
3966
+ 'FK' => 'Falkland Islands (Malvinas)',
3967
+ 'FJ' => 'Fiji the Fiji Islands',
3968
+ 'FI' => 'Finland',
3969
+ 'FR' => 'France',
3970
+ 'GF' => 'French Guiana',
3971
+ 'PF' => 'French Polynesia',
3972
+ 'TF' => 'French Southern Territories',
3973
+ 'GA' => 'Gabon',
3974
+ 'GM' => 'Gambia the',
3975
+ 'GE' => 'Georgia',
3976
+ 'DE' => 'Germany',
3977
+ 'GH' => 'Ghana',
3978
+ 'GI' => 'Gibraltar',
3979
+ 'GR' => 'Greece',
3980
+ 'GL' => 'Greenland',
3981
+ 'GD' => 'Grenada',
3982
+ 'GP' => 'Guadeloupe',
3983
+ 'GU' => 'Guam',
3984
+ 'GT' => 'Guatemala',
3985
+ 'GG' => 'Guernsey',
3986
+ 'GN' => 'Guinea',
3987
+ 'GW' => 'Guinea-Bissau',
3988
+ 'GY' => 'Guyana',
3989
+ 'HT' => 'Haiti',
3990
+ 'HM' => 'Heard Island and McDonald Islands',
3991
+ 'VA' => 'Holy See (Vatican City State)',
3992
+ 'HN' => 'Honduras',
3993
+ 'HK' => 'Hong Kong',
3994
+ 'HU' => 'Hungary',
3995
+ 'IS' => 'Iceland',
3996
+ 'IN' => 'India',
3997
+ 'ID' => 'Indonesia',
3998
+ 'IR' => 'Iran',
3999
+ 'IQ' => 'Iraq',
4000
+ 'IE' => 'Ireland',
4001
+ 'IM' => 'Isle of Man',
4002
+ 'IL' => 'Israel',
4003
+ 'IT' => 'Italy',
4004
+ 'JM' => 'Jamaica',
4005
+ 'JP' => 'Japan',
4006
+ 'JE' => 'Jersey',
4007
+ 'JO' => 'Jordan',
4008
+ 'KZ' => 'Kazakhstan',
4009
+ 'KE' => 'Kenya',
4010
+ 'KI' => 'Kiribati',
4011
+ 'KP' => 'Korea',
4012
+ 'KR' => 'Korea',
4013
+ 'KW' => 'Kuwait',
4014
+ 'KG' => 'Kyrgyz Republic',
4015
+ 'LA' => 'Lao',
4016
+ 'LV' => 'Latvia',
4017
+ 'LB' => 'Lebanon',
4018
+ 'LS' => 'Lesotho',
4019
+ 'LR' => 'Liberia',
4020
+ 'LY' => 'Libyan Arab Jamahiriya',
4021
+ 'LI' => 'Liechtenstein',
4022
+ 'LT' => 'Lithuania',
4023
+ 'LU' => 'Luxembourg',
4024
+ 'MO' => 'Macao',
4025
+ 'MK' => 'Macedonia',
4026
+ 'MG' => 'Madagascar',
4027
+ 'MW' => 'Malawi',
4028
+ 'MY' => 'Malaysia',
4029
+ 'MV' => 'Maldives',
4030
+ 'ML' => 'Mali',
4031
+ 'MT' => 'Malta',
4032
+ 'MH' => 'Marshall Islands',
4033
+ 'MQ' => 'Martinique',
4034
+ 'MR' => 'Mauritania',
4035
+ 'MU' => 'Mauritius',
4036
+ 'YT' => 'Mayotte',
4037
+ 'MX' => 'Mexico',
4038
+ 'FM' => 'Micronesia',
4039
+ 'MD' => 'Moldova',
4040
+ 'MC' => 'Monaco',
4041
+ 'MN' => 'Mongolia',
4042
+ 'ME' => 'Montenegro',
4043
+ 'MS' => 'Montserrat',
4044
+ 'MA' => 'Morocco',
4045
+ 'MZ' => 'Mozambique',
4046
+ 'MM' => 'Myanmar',
4047
+ 'NA' => 'Namibia',
4048
+ 'NR' => 'Nauru',
4049
+ 'NP' => 'Nepal',
4050
+ 'AN' => 'Netherlands Antilles',
4051
+ 'NL' => 'Netherlands',
4052
+ 'NC' => 'New Caledonia',
4053
+ 'NZ' => 'New Zealand',
4054
+ 'NI' => 'Nicaragua',
4055
+ 'NE' => 'Niger',
4056
+ 'NG' => 'Nigeria',
4057
+ 'NU' => 'Niue',
4058
+ 'NF' => 'Norfolk Island',
4059
+ 'MP' => 'Northern Mariana Islands',
4060
+ 'NO' => 'Norway',
4061
+ 'OM' => 'Oman',
4062
+ 'PK' => 'Pakistan',
4063
+ 'PW' => 'Palau',
4064
+ 'PS' => 'Palestinian Territory',
4065
+ 'PA' => 'Panama',
4066
+ 'PG' => 'Papua New Guinea',
4067
+ 'PY' => 'Paraguay',
4068
+ 'PE' => 'Peru',
4069
+ 'PH' => 'Philippines',
4070
+ 'PN' => 'Pitcairn Islands',
4071
+ 'PL' => 'Poland',
4072
+ 'PT' => 'Portugal, Portuguese Republic',
4073
+ 'PR' => 'Puerto Rico',
4074
+ 'QA' => 'Qatar',
4075
+ 'RE' => 'Reunion',
4076
+ 'RO' => 'Romania',
4077
+ 'RU' => 'Russian Federation',
4078
+ 'RW' => 'Rwanda',
4079
+ 'BL' => 'Saint Barthelemy',
4080
+ 'SH' => 'Saint Helena',
4081
+ 'KN' => 'Saint Kitts and Nevis',
4082
+ 'LC' => 'Saint Lucia',
4083
+ 'MF' => 'Saint Martin',
4084
+ 'PM' => 'Saint Pierre and Miquelon',
4085
+ 'VC' => 'Saint Vincent and the Grenadines',
4086
+ 'WS' => 'Samoa',
4087
+ 'SM' => 'San Marino',
4088
+ 'ST' => 'Sao Tome and Principe',
4089
+ 'SA' => 'Saudi Arabia',
4090
+ 'SN' => 'Senegal',
4091
+ 'RS' => 'Serbia',
4092
+ 'SC' => 'Seychelles',
4093
+ 'SL' => 'Sierra Leone',
4094
+ 'SG' => 'Singapore',
4095
+ 'SK' => 'Slovakia (Slovak Republic)',
4096
+ 'SI' => 'Slovenia',
4097
+ 'SB' => 'Solomon Islands',
4098
+ 'SO' => 'Somalia, Somali Republic',
4099
+ 'ZA' => 'South Africa',
4100
+ 'GS' => 'South Georgia and the South Sandwich Islands',
4101
+ 'ES' => 'Spain',
4102
+ 'LK' => 'Sri Lanka',
4103
+ 'SD' => 'Sudan',
4104
+ 'SR' => 'Suriname',
4105
+ 'SJ' => 'Svalbard & Jan Mayen Islands',
4106
+ 'SZ' => 'Swaziland',
4107
+ 'SE' => 'Sweden',
4108
+ 'CH' => 'Switzerland',
4109
+ 'SY' => 'Syrian Arab Republic',
4110
+ 'TW' => 'Taiwan',
4111
+ 'TJ' => 'Tajikistan',
4112
+ 'TZ' => 'Tanzania',
4113
+ 'TH' => 'Thailand',
4114
+ 'TL' => 'Timor-Leste',
4115
+ 'TG' => 'Togo',
4116
+ 'TK' => 'Tokelau',
4117
+ 'TO' => 'Tonga',
4118
+ 'TT' => 'Trinidad and Tobago',
4119
+ 'TN' => 'Tunisia',
4120
+ 'TR' => 'Turkey',
4121
+ 'TM' => 'Turkmenistan',
4122
+ 'TC' => 'Turks and Caicos Islands',
4123
+ 'TV' => 'Tuvalu',
4124
+ 'UG' => 'Uganda',
4125
+ 'UA' => 'Ukraine',
4126
+ 'AE' => 'United Arab Emirates',
4127
+ 'GB' => 'United Kingdom',
4128
+ 'US' => 'United States',
4129
+ 'UM' => 'United States Minor Outlying Islands',
4130
+ 'VI' => 'United States Virgin Islands',
4131
+ 'UY' => 'Uruguay, Eastern Republic of',
4132
+ 'UZ' => 'Uzbekistan',
4133
+ 'VU' => 'Vanuatu',
4134
+ 'VE' => 'Venezuela',
4135
+ 'VN' => 'Vietnam',
4136
+ 'WF' => 'Wallis and Futuna',
4137
+ 'EH' => 'Western Sahara',
4138
+ 'YE' => 'Yemen',
4139
+ 'ZM' => 'Zambia',
4140
+ 'ZW' => 'Zimbabwe',
4141
+ );
4142
+
4143
+ }
4144
+ }
4145
+
4146
+
4147
+ if ( ! function_exists( 'woo_feed_positioning_attribute_value' ) ) {
4148
+ /**
4149
+ * Positioning new associative array in attribute's dropdown list
4150
+ *
4151
+ * @param $array array Main attribute array.
4152
+ * @param $key string Targeted main array key, after that key index the given associative array should come.
4153
+ * @param $input_array array Given associative array.
4154
+ *
4155
+ * @return array $array
4156
+ * @since 4.3.18
4157
+ * @author Nazrul Islam Nayan
4158
+ * @updated 12-01-2021
4159
+ *
4160
+ */
4161
+ function woo_feed_positioning_attribute_value( $array, $key, $input_array ) {
4162
+ $keys = array_keys( $array );
4163
+ $index = array_search( $key, $keys, true );
4164
+ $pos = false === $index ? count( $array ) : $index + 1;
4165
+
4166
+ $array = array_slice( $array, 0, $pos, true ) + $input_array + array_slice( $array, $pos, count( $array ) - 1, true );
4167
+
4168
+ return $array;
4169
+ }
4170
+ }
4171
+
4172
+ if ( ! function_exists( 'woo_feed_get_feed_file_list' ) ) {
4173
+ function woo_feed_get_feed_file_list() {
4174
+ global $wpdb;
4175
+ $feed_data = $wpdb->get_results( $wpdb->prepare( "SELECT option_name FROM $wpdb->options WHERE option_name like %s", 'wf_feed_%' ), ARRAY_A ); // phpcs:ignore
4176
+ $feed_urls = [];
4177
+ if ( ! empty( $feed_data ) and is_array( $feed_data ) ) {
4178
+ foreach ( $feed_data as $key => $data ) {
4179
+ $feed_info = maybe_unserialize( get_option( $data['option_name'] ) );
4180
+ $feed_urls[] = $feed_info['url'];
4181
+ }
4182
+ }
4183
+
4184
+ return $feed_urls;
4185
+ }
4186
+ }
4187
+
4188
+ if ( ! function_exists( 'woo_feed_exclude_feed_from_wp_rocket_cache' ) ) {
4189
+ /**
4190
+ * Exclude Feed file URL form WP Rocket caching
4191
+ *
4192
+ * @param $files
4193
+ *
4194
+ * @return array
4195
+ */
4196
+ function woo_feed_exclude_feed_from_wp_rocket_cache( $files ) {
4197
+ return array_merge(
4198
+ $files,
4199
+ [
4200
+ '/wp-content/uploads/woo-feed/(.*)',
4201
+ ]
4202
+ );
4203
+ }
4204
+ }
4205
+
4206
+ if ( ! function_exists( 'woo_feed_exclude_feed_from_litespeed_cache' ) ) {
4207
+ /**
4208
+ * Exclude Feed file URL form LiteSpeed caching
4209
+ *
4210
+ * @return array|false
4211
+ */
4212
+ function woo_feed_exclude_feed_from_litespeed_cache() {
4213
+ if ( ! class_exists( 'LiteSpeed\Core' ) || ! defined( 'LSCWP_DIR' ) ) {
4214
+ return false;
4215
+ }
4216
+
4217
+ $litespeed_ex_paths = maybe_unserialize( get_option( 'litespeed.conf.cdn-exc' ) );
4218
+ if ( $litespeed_ex_paths && is_array( $litespeed_ex_paths ) && ! in_array( '/wp-content/uploads/woo-feed', $litespeed_ex_paths ) ) {
4219
+ $litespeed_ex_paths = array_merge(
4220
+ $litespeed_ex_paths,
4221
+ [ '/wp-content/uploads/woo-feed' ]
4222
+ );
4223
+ update_option( 'litespeed.conf.cdn-exc', $litespeed_ex_paths );
4224
+ }
4225
+
4226
+ return false;
4227
+ }
4228
+ }
4229
+
4230
+ if ( ! function_exists( 'woo_feed_exclude_feed_from_wp_fastest_cache' ) ) {
4231
+ /**
4232
+ * Exclude Feed file URL form WP Fastest caching
4233
+ *
4234
+ * @return array|false
4235
+ */
4236
+ function woo_feed_exclude_feed_from_wp_fastest_cache() {
4237
+
4238
+ if ( ! class_exists( 'WpFastestCache' ) ) {
4239
+ return false;
4240
+ }
4241
+
4242
+ $wp_fastest_cache_ex_paths = json_decode( get_option( 'WpFastestCacheExclude' ) );
4243
+ if ( $wp_fastest_cache_ex_paths && is_array( $wp_fastest_cache_ex_paths ) ) {
4244
+
4245
+ $feed_path_exist = false;
4246
+ foreach ( $wp_fastest_cache_ex_paths as $key => $path ) {
4247
+ if ( 'woo-feed' === $path->content ) {
4248
+ $feed_path_exist = true;
4249
+ break;
4250
+ }
4251
+ }
4252
+
4253
+ if ( ! $feed_path_exist ) {
4254
+ $new_rule = new stdClass();
4255
+ $new_rule->prefix = "contain";
4256
+ $new_rule->content = 'woo-feed';
4257
+ $new_rule->type = "page";
4258
+
4259
+ $wp_fastest_cache_ex_paths = array_merge(
4260
+ $wp_fastest_cache_ex_paths,
4261
+ [ $new_rule ]
4262
+ );
4263
+
4264
+ update_option( 'WpFastestCacheExclude', wp_json_encode( $wp_fastest_cache_ex_paths ) );
4265
+ }
4266
+ } elseif ( empty( $wp_fastest_cache_ex_paths ) ) {
4267
+ $wp_fastest_cache_ex_paths = [];
4268
+ $new_rule = new stdClass();
4269
+ $new_rule->prefix = "contain";
4270
+ $new_rule->content = 'woo-feed';
4271
+ $new_rule->type = "page";
4272
+
4273
+ $wp_fastest_cache_ex_paths = array_merge(
4274
+ $wp_fastest_cache_ex_paths,
4275
+ [ $new_rule ]
4276
+ );
4277
+
4278
+ update_option( 'WpFastestCacheExclude', wp_json_encode( $wp_fastest_cache_ex_paths ) );
4279
+ }
4280
+
4281
+ return false;
4282
+ }
4283
+ }
4284
+
4285
+ if ( ! function_exists( 'woo_feed_exclude_feed_from_wp_super_cache' ) ) {
4286
+ /**
4287
+ * Exclude Feed file URL form WP Super caching
4288
+ *
4289
+ * @return array|false
4290
+ */
4291
+ function woo_feed_exclude_feed_from_wp_super_cache() {
4292
+
4293
+ if ( ! function_exists( 'wpsc_init' ) ) {
4294
+ return false;
4295
+ }
4296
+
4297
+ $wp_super_ex_paths = get_option( 'ossdl_off_exclude' );
4298
+ if ( $wp_super_ex_paths && strpos( $wp_super_ex_paths, 'woo-feed' ) === false ) {
4299
+ $wp_super_ex_paths = explode( ',', $wp_super_ex_paths );
4300
+ $wp_super_ex_paths = array_merge( $wp_super_ex_paths, [ 'woo-feed' ] );
4301
+ update_option( 'ossdl_off_exclude', implode( ',', $wp_super_ex_paths ) );
4302
+ }
4303
+
4304
+ return false;
4305
+ }
4306
+ }
4307
+
4308
+ if ( ! function_exists( 'woo_feed_exclude_feed_from_breeze_cache' ) ) {
4309
+ /**
4310
+ * Exclude Feed file URL form BREEZE caching
4311
+ *
4312
+ * @return array|false
4313
+ */
4314
+ function woo_feed_exclude_feed_from_breeze_cache() {
4315
+
4316
+ if ( ! class_exists( 'Breeze_Admin' ) ) {
4317
+ return false;
4318
+ }
4319
+
4320
+ $breeze_settings = maybe_unserialize( get_option( 'breeze_cdn_integration' ) );
4321
+ if ( is_array( $breeze_settings ) ) {
4322
+ $woo_feed_files = [ '.xml', '.csv', '.tsv', '.txt', '.xls' ];
4323
+ $woo_feed_files = array_unique( array_merge( $woo_feed_files, $breeze_settings['cdn-exclude-content'] ) );
4324
+ $breeze_settings['cdn-exclude-content'] = $woo_feed_files;
4325
+ update_option( 'breeze_cdn_integration', $breeze_settings );
4326
+ }
4327
+
4328
+ return false;
4329
+ }
4330
+ }
4331
+
4332
+ if ( ! function_exists( 'woo_feed_exclude_feed_from_wp_optimize_cache' ) ) {
4333
+ /**
4334
+ * Exclude Feed file URL form WP Optimize caching
4335
+ *
4336
+ * @return array|false
4337
+ */
4338
+ function woo_feed_exclude_feed_from_wp_optimize_cache() {
4339
+
4340
+ if ( ! class_exists( 'WP_Optimize' ) ) {
4341
+ return false;
4342
+ }
4343
+
4344
+ $wp_optimize_ex_paths = maybe_unserialize( get_option( 'wpo_cache_config' ) );
4345
+ if ( isset( $wp_optimize_ex_paths['enable_page_caching'] ) && $wp_optimize_ex_paths['enable_page_caching'] ) { // If page Caching enabled
4346
+ if ( is_array( $wp_optimize_ex_paths ) && ! in_array( '/wp-content/uploads/woo-feed', $wp_optimize_ex_paths['cache_exception_urls'] ) ) {
4347
+ $woo_feed_ex_path['cache_exception_urls'] = [ '/wp-content/uploads/woo-feed' ];
4348
+ $wp_optimize_ex_paths = array_merge_recursive(
4349
+ $wp_optimize_ex_paths,
4350
+ $woo_feed_ex_path
4351
+ );
4352
+ update_option( 'wpo_cache_config', $wp_optimize_ex_paths );
4353
+ }
4354
+ }
4355
+
4356
+ return false;
4357
+ }
4358
+ }
4359
+
4360
+ if ( ! function_exists( 'woo_feed_exclude_feed_from_cache_enabler_cache' ) ) {
4361
+ /**
4362
+ * Exclude Feed file URL form Cache Enabler caching
4363
+ *
4364
+ * @return array|false
4365
+ */
4366
+ function woo_feed_exclude_feed_from_cache_enabler_cache() {
4367
+
4368
+ if ( ! class_exists( 'Cache_Enabler' ) ) {
4369
+ return false;
4370
+ }
4371
+
4372
+ $cache_enabler_ex_paths = maybe_unserialize( get_option( 'cache_enabler' ) );
4373
+ if ( isset( $cache_enabler_ex_paths['excluded_page_paths'] ) && empty( $cache_enabler_ex_paths['excluded_page_paths'] ) ) {
4374
+ $cache_enabler_ex_paths['excluded_page_paths'] = '/wp-content/uploads/woo-feed/';
4375
+ update_option( 'cache_enabler', $cache_enabler_ex_paths );
4376
+ }
4377
+
4378
+ return false;
4379
+ }
4380
+ }
4381
+
4382
+ if ( ! function_exists( 'woo_feed_exclude_feed_from_swift_performance_cache' ) ) {
4383
+ /**
4384
+ * Exclude Feed file URL form Swift Performance caching
4385
+ *
4386
+ * @return array|false
4387
+ */
4388
+ function woo_feed_exclude_feed_from_swift_performance_cache() {
4389
+
4390
+ if ( ! class_exists( 'Swift_Performance_Lite' ) ) {
4391
+ return false;
4392
+ }
4393
+
4394
+ $swift_perform_ex_paths = maybe_unserialize( get_option( 'swift_performance_options' ) );
4395
+
4396
+ if ( $swift_perform_ex_paths && isset( $swift_perform_ex_paths['exclude-strings'] ) ) {
4397
+ $exclude_strings = $swift_perform_ex_paths['exclude-strings'];
4398
+ if ( is_array( $exclude_strings ) && ! in_array( '/wp-content/uploads/woo-feed', $exclude_strings ) ) {
4399
+ $woo_feed_ex_path['exclude-strings'] = [ '/wp-content/uploads/woo-feed' ];
4400
+ $swift_perform_ex_paths = array_merge_recursive(
4401
+ $swift_perform_ex_paths,
4402
+ $woo_feed_ex_path
4403
+ );
4404
+ } else {
4405
+ $swift_perform_ex_paths['exclude-strings'] = [ '/wp-content/uploads/woo-feed' ];
4406
+ }
4407
+ update_option( 'swift_performance_options', $swift_perform_ex_paths );
4408
+ } elseif ( empty( $swift_perform_ex_paths ) ) {
4409
+ $swift_perform_ex_paths['exclude-strings'] = [ '/wp-content/uploads/woo-feed' ];
4410
+ update_option( 'swift_performance_options', $swift_perform_ex_paths );
4411
+ }
4412
+
4413
+ return false;
4414
+ }
4415
+ }
4416
+
4417
+ if ( ! function_exists( 'woo_feed_exclude_feed_from_speed_booster_cache' ) ) {
4418
+ /**
4419
+ * Exclude Feed file URL form Speed Booster Pack caching
4420
+ *
4421
+ * @return array|false
4422
+ */
4423
+ function woo_feed_exclude_feed_from_speed_booster_cache() {
4424
+
4425
+ if ( ! class_exists( 'Speed_Booster_Pack' ) ) {
4426
+ return false;
4427
+ }
4428
+
4429
+ $feed_files = [];
4430
+ $speed_booster_settings = maybe_unserialize( get_option( 'sbp_options' ) );
4431
+ if ( isset( $speed_booster_settings['caching_exclude_urls'] ) ) {
4432
+ $feed_files = woo_feed_get_feed_file_list();
4433
+ $caching_exclude_urls = $speed_booster_settings['caching_exclude_urls'];
4434
+ if ( ! empty( $caching_exclude_urls ) ) {
4435
+ if ( ! empty( $feed_files ) ) {
4436
+ foreach ( $feed_files as $key => $file ) {
4437
+ $file = str_replace( array( 'http://', 'https://' ), '', $file );
4438
+ if ( ! in_array( $file, explode( "\n", $caching_exclude_urls ) ) ) {
4439
+ $caching_exclude_urls .= "\n" . $file;
4440
+ }
4441
+ }
4442
+ }
4443
+ } else {
4444
+ $caching_exclude_urls = str_replace( array( 'http://', 'https://' ), '', implode( "\n", $feed_files ) );
4445
+ }
4446
+ $speed_booster_settings['caching_exclude_urls'] = $caching_exclude_urls;
4447
+ update_option( 'sbp_options', $speed_booster_settings );
4448
+ }
4449
+
4450
+ //TODO CDN extension exclude
4451
+ return false;
4452
+ }
4453
+ }
4454
+
4455
+ if ( ! function_exists( 'woo_feed_exclude_feed_from_comet_cache' ) ) {
4456
+ /**
4457
+ * Exclude Feed file URL form Comet Cache caching
4458
+ *
4459
+ * @return array|false
4460
+ */
4461
+ function woo_feed_exclude_feed_from_comet_cache() {
4462
+ if ( ! is_plugin_active( 'comet-cache/comet-cache.php' ) ) {
4463
+ return false;
4464
+ }
4465
+
4466
+ $comet_cache_settings = maybe_unserialize( get_option( 'comet_cache_options' ) );
4467
+
4468
+ if ( $comet_cache_settings && isset( $comet_cache_settings['exclude_uris'] ) ) {
4469
+ $exclude_uris = $comet_cache_settings['exclude_uris'];
4470
+ if ( strpos( $exclude_uris, '/wp-content/uploads/woo-feed' ) === false ) {
4471
+ $exclude_uris .= "\n/wp-content/uploads/woo-feed";
4472
+ $comet_cache_settings['exclude_uris'] = $exclude_uris;
4473
+ update_option( 'comet_cache_options', $comet_cache_settings );
4474
+ }
4475
+ }
4476
+
4477
+ return false;
4478
+ }
4479
+ }
4480
+
4481
+ if ( ! function_exists( 'woo_feed_exclude_feed_from_hyper_cache' ) ) {
4482
+ /**
4483
+ * Exclude Feed file URL form Swift Performance caching
4484
+ *
4485
+ * @return array|false
4486
+ */
4487
+ function woo_feed_exclude_feed_from_hyper_cache() {
4488
+
4489
+ if ( ! class_exists( 'HyperCache' ) ) {
4490
+ return false;
4491
+ }
4492
+
4493
+ $hyper_cache_settings = maybe_unserialize( get_option( 'hyper-cache' ) );
4494
+ if ( $hyper_cache_settings && isset( $hyper_cache_settings['reject_uris'] ) ) {
4495
+ $exclude_strings = $hyper_cache_settings['reject_uris'];
4496
+ if ( is_array( $exclude_strings ) && ! in_array( '/wp-content/uploads/woo-feed', $exclude_strings ) ) {
4497
+ $woo_feed_ex_path['reject_uris'] = [ '/wp-content/uploads/woo-feed' ];
4498
+ $woo_feed_ex_path['reject_uris_enabled'] = 1;
4499
+ $hyper_cache_settings = array_merge_recursive(
4500
+ $hyper_cache_settings,
4501
+ $woo_feed_ex_path
4502
+ );
4503
+ }
4504
+ update_option( 'hyper-cache', $hyper_cache_settings );
4505
+ }
4506
+
4507
+ return false;
4508
+ }
4509
+ }
4510
+
4511
+ if ( ! function_exists( 'woo_feed_wp_options' ) ) {
4512
+ function woo_feed_wp_options() {
4513
+ if ( isset( $_GET['action'] ) && 'add-option' == $_GET['action'] ) {
4514
+ if ( count( $_POST ) && isset( $_POST['wpfp_option'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
4515
+ check_admin_referer( 'woo-feed-add-option' );
4516
+
4517
+ $options = get_option( 'wpfp_option', array() );
4518
+ $newOption = sanitize_text_field( $_POST['wpfp_option'] );
4519
+ $id = explode( '-', $newOption );
4520
+ if ( false !== array_search( $id[0], array_column( $options, 'option_id' ) ) ) { // found
4521
+ update_option( 'wpf_message', esc_html__( 'Option Already Added.', 'woo-feed' ), false );
4522
+ wp_safe_redirect( admin_url( 'admin.php?page=webappick-wp-options&wpf_message=error' ) );
4523
+ die();
4524
+ } else {
4525
+ $options[ $id[0] ] = array(
4526
+ 'option_id' => $id[0],
4527
+ 'option_name' => 'wf_option_' . str_replace( $id[0] . '-', '', $newOption ),
4528
+ );
4529
+ update_option( 'wpfp_option', $options, false );
4530
+ update_option( 'wpf_message', esc_html__( 'Option Successfully Added.', 'woo-feed' ), false );
4531
+ wp_safe_redirect( admin_url( 'admin.php?page=webappick-wp-options&wpf_message=success' ) );
4532
+ die();
4533
+ }
4534
+ }
4535
+ require WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-add-option.php';
4536
+ } else {
4537
+ require WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-option-list.php';
4538
+ }
4539
+ }
4540
+ }
4541
+
4542
+ if ( ! function_exists( 'woo_feed_get_price_with_tax' ) ) {
4543
+
4544
+
4545
+ /**
4546
+ * Get price with tax
4547
+ *
4548
+ * @param $price
4549
+ * @param WC_Product $product product object
4550
+ *
4551
+ * @return float|mixed|string|void
4552
+ */
4553
+ function woo_feed_get_price_with_tax( $price, $product ) {
4554
+
4555
+ if ( woo_feed_wc_version_check( 3.0 ) ) {
4556
+ return wc_get_price_including_tax( $product, array( 'price' => $price ) );
4557
+ } else {
4558
+ return $product->get_price_including_tax( 1, $price );
4559
+ }
4560
+
4561
+ return apply_filters( 'woo_feed_price_with_tax', $price, $product );
4562
+ }
4563
+ }
4564
+
4565
+ if ( ! function_exists( 'woo_feed_get_dynamic_discounted_product_price' ) ) {
4566
+
4567
+ /**
4568
+ * Get price with dynamic discount
4569
+ *
4570
+ * @param WC_Product|WC_Product_Variable $product product object
4571
+ * @param $price
4572
+ * @param $config
4573
+ * @param bool $tax product taxable or not
4574
+ *
4575
+ * @return mixed $price
4576
+ */
4577
+ function woo_feed_get_dynamic_discounted_product_price( $price, $product, $config, $tax ) {
4578
+ $base_price = $price;
4579
+ $discount_plugin_activate = false;
4580
+
4581
+
4582
+ /**
4583
+ * PLUGIN: Discount Rules for WooCommerce
4584
+ * URL: https://wordpress.org/plugins/woo-discount-rules/
4585
+ */
4586
+ if ( is_plugin_active( 'woo-discount-rules/woo-discount-rules.php' ) ) {
4587
+ $discount_plugin_activate = true;
4588
+ if ( class_exists( 'Wdr\App\Controllers\Configuration' ) ) {
4589
+ $config = Wdr\App\Controllers\Configuration::getInstance()->getConfig( 'calculate_discount_from', 'sale_price' );
4590
+
4591
+ if ( isset( $config ) && ! empty( $config ) ) {
4592
+ if ( 'regular_price' === $config ) {
4593
+ $price = $product->get_regular_price();
4594
+ } else {
4595
+ $price = $product->get_price();
4596
+ }
4597
+ } else {
4598
+ $price = $product->get_price();
4599
+ }
4600
+
4601
+ if ( $product->is_type( 'variable' ) ) {
4602
+ $min = $product->get_variation_price( 'min', false );
4603
+ $max = $product->get_variation_price( 'max', false );
4604
+
4605
+ $price = $min;
4606
+ if ( $max === $base_price ) {
4607
+ $price = $max;
4608
+ }
4609
+ }
4610
+
4611
+ $price = apply_filters( 'advanced_woo_discount_rules_get_product_discount_price_from_custom_price', false, $product, 1, $price, 'discounted_price', true, true );
4612
+
4613
+ if ( empty( $price ) ) {
4614
+ $price = $base_price;
4615
+ }
4616
+
4617
+ if ( ! isset( $feedConfig['feedCurrency'] ) ) {
4618
+ $feedConfig['feedCurrency'] = get_woocommerce_currency();
4619
+ }
4620
+
4621
+ $price = apply_filters( 'wcml_raw_price_amount', $price, $feedConfig['feedCurrency'] );
4622
+
4623
+ }
4624
+ }
4625
+
4626
+ /**
4627
+ * PLUGIN: Dynamic Pricing With Discount Rules for WooCommerce
4628
+ * URL: https://wordpress.org/plugins/aco-woo-dynamic-pricing/
4629
+ *
4630
+ * This plugin does not apply discount on product page.
4631
+ *
4632
+ * Don't apply discount manually.
4633
+ */
4634
  // if (is_plugin_active('aco-woo-dynamic-pricing/start.php')) {
4635
  // $discount_plugin_activate = true;
4636
  // if (class_exists('AWDP_Discount')) {
4638
  // }
4639
  // }
4640
 
4641
+ /**
4642
+ * PLUGIN: Conditional Discounts for WooCommerce
4643
+ * URL: https://wordpress.org/plugins/woo-advanced-discounts/
4644
+ *
4645
+ * NOTE:* Automatically apply discount to $product->get_sale_price() method.
4646
+ */
4647
  // if (is_plugin_active('woo-advanced-discounts/wad.php')) {
4648
  // $discount_plugin_activate = true;
4649
  // $discount_amount = 0;
4668
  // }
4669
  // }
4670
 
4671
+ /**
4672
+ * PLUGIN: Pricing Deals for WooCommerce
4673
+ * URL: https://wordpress.org/plugins/pricing-deals-for-woocommerce/
4674
+ */
4675
+ if ( is_plugin_active( 'pricing-deals-for-woocommerce/vt-pricing-deals.php' ) ) {
4676
+ $discount_plugin_activate = true;
4677
+ if ( class_exists( 'VTPRD_Controller' ) ) {
4678
+ global $vtprd_rules_set;
4679
+ $vtprd_rules_set = get_option( 'vtprd_rules_set' );
4680
+ if ( ! empty( $vtprd_rules_set ) && is_array( $vtprd_rules_set ) ) {
4681
+ foreach ( $vtprd_rules_set as $vtprd_rule_set ) {
4682
+ $status = $vtprd_rule_set->rule_on_off_sw_select;
4683
+ if ( 'on' === $status || 'onForever' === $status ) {
4684
+ $discount_type = $vtprd_rule_set->rule_deal_info[0]['discount_amt_type'];
4685
+ $discount = $vtprd_rule_set->rule_deal_info[0]['discount_amt_count'];
4686
+ if ( 'currency' === $discount_type || 'fixedPrice' === $discount_type ) {
4687
+ $price = $product->get_price() - $discount;
4688
+ } elseif ( 'percent' === $discount_type ) {
4689
+ $price = $product->get_price() - ( ( $product->get_price() * $discount ) / 100 );
4690
+ }
4691
+ }
4692
+ }
4693
+ }
4694
+ }
4695
+ }
4696
+
4697
+ //######################### YITH #########################################################
4698
+ /**
4699
+ * PLUGIN: YITH WOOCOMMERCE DYNAMIC PRICING AND DISCOUNTS
4700
+ * URL: hhttps://yithemes.com/themes/plugins/yith-woocommerce-dynamic-pricing-and-discounts/
4701
+ *
4702
+ * NOTE:* YITH Automatically apply discount to $product->get_sale_price() method.
4703
+ */
4704
+ //######################### RightPress ###################################################
4705
+ /**
4706
+ * PLUGIN: WooCommerce Dynamic Pricing & Discounts
4707
+ * URL: https://codecanyon.net/item/woocommerce-dynamic-pricing-discounts/7119279
4708
+ *
4709
+ * RightPress dynamic pricing supported. Filter Hooks applied to "woo_feed_apply_hooks_before_product_loop"
4710
+ * to get the dynamic discounted price via $product->ger_sale_price(); method.
4711
+ */
4712
+ //###################### Dynamic Pricing ##################################################
4713
+ /**
4714
+ * PLUGIN: Dynamic Pricing
4715
+ * URL: https://woocommerce.com/products/dynamic-pricing/
4716
+ *
4717
+ * Dynamic Pricing plugin doesn't show the options or any price change on your frontend.
4718
+ * So a user will not even notice the discounts until he reaches the checkout.
4719
+ * No need to add the compatibility.
4720
+ */
4721
+
4722
+
4723
+ // Get Price with tax
4724
+ if ( $discount_plugin_activate && $tax ) {
4725
+ $price = woo_feed_get_price_with_tax( $price, $product );
4726
+ }
4727
+
4728
+ return ( isset( $base_price ) || ( $price > 0 ) && ( $price < $base_price ) ) ? $price : $base_price;
4729
+ }
 
4730
  }
4731
 
4732
  /**
4734
  *
4735
  * @since 4.3.93
4736
  */
4737
+ if ( ! class_exists( 'Woo_Feed_Custom_Taxonomy_Filter' ) ) {
4738
+ class Woo_Feed_Custom_Taxonomy_Filter extends FilterIterator {
 
4739
 
4740
+ public function __construct( array $items ) {
4741
+ $object = new ArrayObject( $items );
4742
+ parent::__construct( $object->getIterator() );
4743
+ }
4744
 
4745
+ public function accept() {
4746
+ return array_key_exists( 2, parent::current() ) ? parent::current()[2] : false;
4747
+ }
4748
+ }
4749
  }
4750
 
4751
  /**
4753
  *
4754
  * @since 4.3.93
4755
  */
4756
+ if ( ! class_exists( 'Woo_Feed_Custom_Identifier_Filter' ) ) {
4757
+ class Woo_Feed_Custom_Identifier_Filter extends FilterIterator {
4758
+
4759
+ public function __construct( array $items ) {
4760
+ $object = new ArrayObject( $items );
4761
+ parent::__construct( $object->getIterator() );
4762
+ }
4763
+
4764
+ public function accept() {
4765
+ if ( ! isset( parent::current()[3] ) || ( isset( parent::current()[3] ) && parent::current()[3] ) ) {
4766
+ $is_identifier = ! array_key_exists( 2, parent::current() ) ? true : ! parent::current()[2];
4767
+ if ( $is_identifier ) {
4768
+ $get_settings = woo_feed_get_options( 'all' );
4769
+ $get_identifiers = isset( $get_settings['woo_feed_identifier'] ) ? $get_settings['woo_feed_identifier'] : array();
4770
+
4771
+ if ( in_array( parent::key(), array_keys( $get_identifiers ), true ) ) {
4772
+ if ( 'enable' === $get_identifiers[ parent::key() ] ) {
4773
+ return parent::current();
4774
+ }
4775
+ } else {
4776
+ if ( parent::current()[1] ) {
4777
+ return parent::current();
4778
+ }
4779
+ }
4780
+ }
4781
+ }
4782
+ }
4783
+ }
4784
+ }
4785
+
4786
+ if ( ! function_exists( 'woo_feed_array_splice_preserve_keys' ) ) {
4787
+ function woo_feed_array_splice_preserve_keys( &$input, $offset, $length = null, $replacement = array() ) {
4788
+ if ( empty( $replacement ) ) {
4789
+ return array_splice( $input, $offset, $length );
4790
+ }
4791
+
4792
+ $part_before = array_slice( $input, 0, $offset, $preserve_keys = true );
4793
+ $part_removed = array_slice( $input, $offset, $length, $preserve_keys = true );
4794
+ $part_after = array_slice( $input, $offset + $length, null, $preserve_keys = true );
4795
+
4796
+ $input = $part_before + $replacement + $part_after;
4797
+
4798
+ return $part_removed;
4799
+ }
4800
+ }
4801
+
4802
+ if ( ! function_exists( 'woo_feed_filter_count_cb' ) ) {
4803
+ /**
4804
+ * Add AJAX action when client click filter tab.
4805
+ */
4806
+ add_action( 'wp_ajax_woo_feed_filter_count', 'woo_feed_filter_count_cb' );
4807
+ /**
4808
+ * This function return object with product counter based on status
4809
+ * - Is product out of stock?
4810
+ * - Is product is hidden?
4811
+ * - Product has description or short description?
4812
+ * - Product has image?
4813
+ * - Product has price? Regulart price or sell price
4814
+ *
4815
+ * @return mixed array | error
4816
+ */
4817
+ function woo_feed_filter_count_cb() {
4818
+ $is_nonce_valid = isset( $_GET['nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['nonce'] ) ), 'wpf_feed_nonce' );
4819
+
4820
+ if ( $is_nonce_valid ) {
4821
+ $results = array(
4822
+ 'hidden' => woo_feed_hidden_products_count(),
4823
+ 'noPrice' => woo_feed_no_price_products_count(),
4824
+ 'noImg' => woo_feed_no_image_products_count(),
4825
+ 'noDesc' => woo_feed_no_description_products_count(),
4826
+ 'outOfStock' => woo_feed_out_of_stock_products_count(),
4827
+ 'backorder' => woo_feed_backorder_products_count(),
4828
+ );
4829
+ wp_send_json_success( $results );
4830
+ } else {
4831
+ wp_send_json_error( esc_html__( 'Invalid Request.', 'woo-feed' ) );
4832
+ }
4833
+ wp_die();
4834
+ }
4835
+ }
4836
+ if ( ! function_exists( 'woo_feed_hidden_products_count' ) ) {
4837
+ /**
4838
+ * This function give the hidden products count.
4839
+ *
4840
+ * @return integer
4841
+ */
4842
+ function woo_feed_hidden_products_count() {
4843
+ $args = array(
4844
+ 'post_type' => 'product',
4845
+ 'posts_per_page' => - 1,
4846
+ 'fields' => 'ids',
4847
+ 'tax_query' => array(
4848
+ array(
4849
+ 'taxonomy' => 'product_visibility',
4850
+ 'field' => 'name',
4851
+ 'terms' => 'exclude-from-catalog',
4852
+ 'operator' => 'IN',
4853
+ ),
4854
+ ),
4855
+ );
4856
+ $products = new WP_Query( $args );
4857
+
4858
+ return count( $products->posts );
4859
+ }
4860
+ }
4861
+ if ( ! function_exists( 'woo_feed_no_image_products_count' ) ) {
4862
+ /**
4863
+ * This function give the products count which have no thumbnail image or gallery image
4864
+ *
4865
+ * @return integer
4866
+ */
4867
+ function woo_feed_no_image_products_count() {
4868
+ $args = array(
4869
+ 'post_type' => 'product',
4870
+ 'posts_per_page' => - 1,
4871
+ 'fields' => 'ids',
4872
+ 'meta_query' => array(
4873
+ 'relation' => 'AND',
4874
+ array(
4875
+ 'key' => '_thumbnail_id',
4876
+ 'compare' => 'NOT EXISTS',
4877
+ ),
4878
+ array(
4879
+ 'key' => '_product_image_gallery',
4880
+ 'compare' => 'NOT EXISTS',
4881
+ ),
4882
+ ),
4883
+ );
4884
+ $products = new WP_Query( $args );
4885
+
4886
+ return count( $products->posts );
4887
+ }
4888
+ }
4889
+ if ( ! function_exists( 'woo_feed_no_description_products_count' ) ) {
4890
+ /**
4891
+ * This function give the products count which have no description/short description.
4892
+ *
4893
+ * @return integer
4894
+ */
4895
+ function woo_feed_no_description_products_count() {
4896
+ add_filter( 'posts_where', 'woo_feed_filter_where_product_with_no_description' );
4897
+ $args = array(
4898
+ 'post_type' => 'product',
4899
+ 'posts_per_page' => - 1,
4900
+ 'fields' => 'ids',
4901
+ );
4902
+ $products = new WP_Query( $args );
4903
+ remove_filter( 'posts_where', 'woo_feed_filter_where_product_with_no_description' );
4904
+
4905
+ return count( $products->posts );
4906
+ }
4907
+ }
4908
+ if ( ! function_exists( 'woo_feed_filter_where_product_with_no_description' ) ) {
4909
+ /**
4910
+ * This function changes the wp query to get out of products without description.
4911
+ *
4912
+ * @param string $where
4913
+ */
4914
+ function woo_feed_filter_where_product_with_no_description( $where = '' ) {
4915
+ $where .= "
4916
  AND trim( coalesce( post_content, '' ) ) = ''
4917
  ";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4918
 
4919
+ return $where;
4920
+ }
4921
+ }
4922
+ if ( ! function_exists( 'woo_feed_out_of_stock_products_count' ) ) {
4923
+ /**
4924
+ * This function gives the `out of stock products` count.
4925
+ *
4926
+ * @return integer
4927
+ */
4928
+ function woo_feed_out_of_stock_products_count() {
4929
+ $args = array(
4930
+ 'post_type' => 'product',
4931
+ 'posts_per_page' => - 1,
4932
+ 'fields' => 'ids',
4933
+ 'meta_query' => array(
4934
+ array(
4935
+ 'key' => '_stock_status',
4936
+ 'value' => 'outofstock',
4937
+ 'compare' => '==',
4938
+ ),
4939
+ ),
4940
+ );
4941
+ $products = new WP_Query( $args );
4942
+
4943
+ return count( $products->posts );
4944
+ }
4945
+ }
4946
+ if ( ! function_exists( 'woo_feed_backorder_products_count' ) ) {
4947
+ /**
4948
+ * This function gives the `backorder` products count.
4949
+ *
4950
+ * @return integer
4951
+ */
4952
+ function woo_feed_backorder_products_count() {
4953
+ $args = array(
4954
+ 'post_type' => 'product',
4955
+ 'posts_per_page' => - 1,
4956
+ 'fields' => 'ids',
4957
+ 'meta_query' => array(
4958
+ array(
4959
+ 'key' => '_stock_status',
4960
+ 'value' => 'onbackorder',
4961
+ 'compare' => '==',
4962
+ ),
4963
+ ),
4964
+ );
4965
+ $products = new WP_Query( $args );
4966
+
4967
+ return count( $products->posts );
4968
+ }
4969
+ }
4970
+ if ( ! function_exists( 'woo_feed_no_price_products_count' ) ) {
4971
+ /**
4972
+ * This function give the products count which have no prices.
4973
+ *
4974
+ * @return integer
4975
+ */
4976
+ function woo_feed_no_price_products_count() {
4977
+ $args = array(
4978
+ 'post_type' => 'product',
4979
+ 'posts_per_page' => - 1,
4980
+ 'fields' => 'ids',
4981
+ 'meta_query' => array(
4982
+ array(
4983
+ 'key' => '_price',
4984
+ 'value' => '',
4985
+ 'compare' => '==',
4986
+ ),
4987
+ ),
4988
+ );
4989
+ $products = new WP_Query( $args );
4990
+
4991
+ return count( $products->posts );
4992
+ }
4993
+ }
4994
+
4995
+ if ( ! function_exists( 'woo_feed_custom_field_meta_filter' ) ) {
4996
+ /**
4997
+ * Identifier meta value filter for old and new version users
4998
+ *
4999
+ * @param $meta string Default Meta
5000
+ * @param WC_Product $product
5001
+ * @param $field string Meta field
5002
+ *
5003
+ * @return string Custom Field Meta.
5004
+ * @since 4.3.99
5005
+ *
5006
+ */
5007
+ function woo_feed_custom_field_meta_filter( $meta, $product, $field ) {
5008
+ $id = $product->get_id();
5009
+
5010
+ //identifier meta value for old and new version users
5011
+ if ( false !== strpos( $meta, 'woo_feed_identifier_' ) ) {
5012
+
5013
+ $identifier = str_replace( 'woo_feed_identifier_', '', $meta );
5014
+ if ( metadata_exists( 'post', $id, 'woo_feed_' . $identifier ) ) {
5015
+ $meta = 'woo_feed_' . $identifier;
5016
+ } else {
5017
+ $meta = 'woo_feed_identifier_' . $identifier;
5018
+ }
5019
+ }
5020
+
5021
+ return $meta;
5022
+ }
5023
+
5024
+ add_filter( 'woo_feed_custom_field_meta', 'woo_feed_custom_field_meta_filter', 3, 10 );
5025
+ }
5026
+
5027
+ if ( ! function_exists( 'woo_feed_strpos_array' ) ) {
5028
+
5029
+ /**
5030
+ * Extension of php `strpos` function
5031
+ *
5032
+ * @param $niddles array
5033
+ * @param $haystack string
5034
+ *
5035
+ * @return boolean If any string exists.
5036
+ * @since 4.3.100
5037
+ *
5038
+ */
5039
+ function woo_feed_strpos_array( $niddles, $haystack ) {
5040
+
5041
+ if ( empty( $haystack ) ) {
5042
+ return;
5043
+ }
5044
+
5045
+ foreach ( $niddles as $niddle ) {
5046
+ if ( strpos( $haystack, $niddle ) !== false ) {
5047
+ return true;
5048
+ }
5049
+ }
5050
+
5051
+ return false;
5052
+
5053
+ }
5054
+ }
5055
+
5056
+ if ( ! function_exists( 'woo_feed_schema_description_filter' ) ) {
5057
+ /**
5058
+ * Filter schema description
5059
+ *
5060
+ * @param $description mixed default product description
5061
+ * @param $product mixed product object
5062
+ *
5063
+ * @return mixed
5064
+ * @since 4.3.101
5065
+ *
5066
+ */
5067
+ function woo_feed_schema_description_filter( $description, $product ) {
5068
+
5069
+ $description = do_shortcode( $description );
5070
+ $description = woo_feed_stripInvalidXml( $description );
5071
+ $description = preg_replace( '/\[\/?vc_.*?\]/', '', $description );
5072
+ $description = strip_shortcodes( $description );
5073
+ $description = preg_replace( '~[\r\n]+~', '', $description );
5074
+
5075
+ //strip tags and spacial characters
5076
+ $strip_description = wp_strip_all_tags( wp_specialchars_decode( $description ) );
5077
+
5078
+ $description = ! empty( strlen( $strip_description ) ) && 0 < strlen( $strip_description ) ? $strip_description : $description;
5079
+
5080
+ return $description;
5081
+ }
5082
+
5083
+ add_filter( 'woo_feed_schema_description', 'woo_feed_schema_description_filter', 10, 2 );
5084
+ }
5085
+
5086
+
5087
+ if ( ! function_exists( 'woo_feed_get_yoast_identifiers_value' ) ) {
5088
+ /**
5089
+ * Get Yoast identifiers value
5090
+ *
5091
+ * @param $attribute_key string attribute key
5092
+ * @param $product WC_Product product object
5093
+ *
5094
+ * @return mixed identifier value.
5095
+ * @since 4.4.4
5096
+ *
5097
+ * @author Nazrul Islam Nayan
5098
+ */
5099
+ function woo_feed_get_yoast_identifiers_value( $attribute_key, $product ) {
5100
+ $identifier = '';
5101
+ if ( class_exists( 'Yoast_WooCommerce_SEO' ) ) {
5102
+ $wpseo_identifier = get_post_meta( $product->get_id(), 'wpseo_global_identifier_values' );
5103
+ $wpseo_identifier = reset( $wpseo_identifier );
5104
+
5105
+ if ( isset( $wpseo_identifier[ $attribute_key ] ) ) {
5106
+ $identifier = $wpseo_identifier[ $attribute_key ];
5107
+ }
5108
+
5109
+ if ( empty( $identifier ) && $product->is_type( 'variation' ) ) {
5110
+ $parent = wc_get_product( $product->get_parent_id() );
5111
+ $identifier = woo_feed_get_yoast_identifiers_value( $attribute_key, $parent );
5112
+ }
5113
+ }
5114
+
5115
+ return $identifier;
5116
+ }
5117
+
5118
+ if ( ! function_exists( 'woo_feed_parent_product_id' ) ) {
5119
+ /**
5120
+ * Return variable product id for variation else main product id.
5121
+ *
5122
+ * @param WC_Product $product
5123
+ *
5124
+ * @return int
5125
+ */
5126
+ function woo_feed_parent_product_id( $product ) {
5127
+ if ( $product->is_type( 'variation' ) ) {
5128
+ return $product->get_parent_id();
5129
+ }
5130
+
5131
+ return $product->get_id();
5132
+ }
5133
+ }
5134
  }
5135
 
5136
  #==== MERCHANT TEMPLATE OVERRIDE START ==============#
5137
+ if ( ! function_exists( 'woo_feed_modify_google_color_attribute_value' ) ) {
5138
+ /**
5139
+ * Replace comma (,) with slash (/) for Google Shopping template color attribute value
5140
+ *
5141
+ * @param $attribute_value
5142
+ * @param $product
5143
+ * @param $feed_config
5144
+ *
5145
+ * @return string
5146
+ */
5147
+ function woo_feed_modify_google_color_attribute_value( $attribute_value, $product, $feed_config, $merchant_attribute ) {
5148
+ // Replace Google Color attribute value according to requirements
5149
+ if ( ( 'g:color' === $merchant_attribute || 'color' === $merchant_attribute )
5150
+ && in_array( $feed_config['provider'], [
5151
+ 'google',
5152
+ 'facebook',
5153
+ 'pinterest',
5154
+ 'bing',
5155
+ 'snapchat',
5156
+ ], true ) ) {
5157
+ return str_replace( ', ', '/', $attribute_value );
5158
+ }
5159
+
5160
+ return $attribute_value;
5161
+ }
5162
+ }
5163
+
5164
+ if ( ! function_exists( 'woo_feed_modify_weight_attribute_value' ) ) {
5165
+ /**
5166
+ * Add wight unit as suffix for Google Shopping template shipping_weight attribute.
5167
+ *
5168
+ * @param $attribute_value
5169
+ * @param WC_Product $product
5170
+ * @param $feed_config
5171
+ *
5172
+ * @return string
5173
+ */
5174
+ function woo_feed_modify_weight_attribute_value( $attribute_value, $product, $feed_config ) {
5175
+ if ( isset( $feed_config['attributes'] )
5176
+ && in_array( $feed_config['provider'], [
5177
+ 'google',
5178
+ 'facebook',
5179
+ 'pinterest',
5180
+ 'bing',
5181
+ 'snapchat',
5182
+ ] ) ) {
5183
+ $attributes = $feed_config['attributes'];
5184
+ $key = array_search( 'weight', $attributes, true );
5185
+ if ( isset( $feed_config['suffix'] ) && ! empty( $key ) && array_key_exists( $key, $feed_config['suffix'] ) ) {
5186
+ $weight_suffix_unit = $feed_config['suffix'][ $key ];
5187
+
5188
+ if ( empty( $weight_suffix_unit ) && ! empty( $attribute_value ) ) {
5189
+ $attribute_value .= ' ' . get_option( 'woocommerce_weight_unit' );
5190
+ }
5191
+ }
5192
+ }
5193
+
5194
+ return $attribute_value;
5195
+ }
5196
+ }
5197
+
5198
+ if ( ! function_exists( 'woo_feed_get_bestprice_categoryPath_attribute_value_modify' ) ) {
5199
+ /**
5200
+ * Replace BestPrice categoryPath value from > to ,
5201
+ *
5202
+ * @param $attribute_value
5203
+ * @param $product
5204
+ * @param $feed_config
5205
+ *
5206
+ * @return string
5207
+ */
5208
+ function woo_feed_get_bestprice_categoryPath_attribute_value_modify( $attribute_value, $product, $feed_config ) {
5209
+ $attribute_value = str_replace( '>', ', ', $attribute_value );
5210
+
5211
+ return $attribute_value;
5212
+ }
5213
+ }
5214
+
5215
+ if ( ! function_exists( 'woo_feed_availability_attribute_value_modify' ) ) {
5216
+ /**
5217
+ * Modify Availability attribute value based on channel.
5218
+ *
5219
+ * @param $attribute_value
5220
+ * @param $product
5221
+ * @param $feed_config
5222
+ *
5223
+ * @return string
5224
+ */
5225
+ function woo_feed_availability_attribute_value_modify( $attribute_value, $product, $feed_config ) {
5226
+ if ( 'bestprice' === $feed_config['provider'] ) {
5227
+ if ( 'in stock' === $attribute_value ) {
5228
+ return "Y";
5229
+ }
5230
+
5231
+ return "N";
5232
+ }
5233
+
5234
+ if ( 'skroutz' === $feed_config['provider'] ) {
5235
+
5236
+ if ( 'in stock' === $attribute_value ) {
5237
+ $in_stock_string = __( 'Delivery 1 to 3 days', 'woo-feed' );
5238
+ } else {
5239
+ $in_stock_string = __( 'Delivery up to 30 days', 'woo-feed' );
5240
+ }
5241
+
5242
+ return $in_stock_string;
5243
+ }
5244
+
5245
+ if ( 'pricerunner' === $feed_config['provider'] ) {
5246
+ if ( 'in stock' === $attribute_value ) {
5247
+ return "Yes";
5248
+ }
5249
+
5250
+ return "No";
5251
+ }
5252
+
5253
+ if ( 'google' === $feed_config['provider'] || 'pinterest' === $feed_config['provider'] ) {
5254
+ if ( 'on backorder' === $attribute_value || 'on_backorder' === $attribute_value ) {
5255
+ return 'preorder';
5256
+ }
5257
+
5258
+ if ( 'google' === $feed_config['provider'] ) {
5259
+ if ( ! in_array( $attribute_value, [ 'in_stock', 'out_of_stock', 'on_backorder' ] ) ) {
5260
+ return 'in_stock';
5261
+ }
5262
+ } elseif ( ! in_array( $attribute_value, [ 'in stock', 'out of stock', 'on backorder' ] ) ) {
5263
+ return 'in stock';
5264
+ }
5265
+ }
5266
+
5267
+ if ( 'facebook' === $feed_config['provider'] ) {
5268
+ if ( 'on backorder' === $attribute_value ) {
5269
+ return 'available for order';
5270
+ } elseif ( ! in_array( $attribute_value, [ 'in stock', 'out of stock', 'on backorder' ] ) ) {
5271
+ return 'in stock';
5272
+ }
5273
+ }
5274
+
5275
+ return $attribute_value;
5276
+ }
5277
+ }
5278
+
5279
+ if ( ! function_exists( 'woo_feed_spartoo_attribute_value_modify' ) ) {
5280
+ /**
5281
+ * Modify Spartoo feed Parent/Child attribute value.
5282
+ *
5283
+ * @param $attribute_value
5284
+ * @param $product
5285
+ * @param $feed_config
5286
+ *
5287
+ * @return string
5288
+ */
5289
+ function woo_feed_spartoo_attribute_value_modify( $attribute_value, $product, $feed_config ) {
5290
+ if ( 'spartoo.fi' === $feed_config['provider'] ) {
5291
+ if ( 'variation' === $attribute_value ) {
5292
+ return "child";
5293
+ }
5294
+
5295
+ return "parent";
5296
+ }
5297
+
5298
+ return $attribute_value;
5299
+ }
5300
+ }
5301
+
5302
+ if ( ! function_exists( 'woo_feed_get_pinterest_rss_date_attribute_callback' ) ) {
5303
+ /**
5304
+ * Convert date format to DATERFC822 for pinterest RSS Feed.
5305
+ *
5306
+ * @param $attribute_value
5307
+ * @param $product
5308
+ * @param $feed_config
5309
+ *
5310
+ * @return string
5311
+ */
5312
+ function woo_feed_get_pinterest_rss_date_attribute_callback( $attribute_value, $product, $feed_config ) {
5313
+ if ( ! empty( $attribute_value ) ) {
5314
+ return date( 'r', strtotime( $attribute_value ) );
5315
+ }
5316
+
5317
+ return $attribute_value;
5318
+ }
5319
  }
5320
 
5321
  if ( ! function_exists( 'woo_feed_duplicate_feed' ) ) {
5322
+ /**
5323
+ * @param string $feed_from Required. Feed name to duplicate from
5324
+ * @param string $new_name Optional. New name for duplicate feed.
5325
+ * Default to auto generated slug from the old name prefixed with number.
5326
+ * @param bool $copy_file Optional. Copy the file. Default is true.
5327
+ *
5328
+ * @return bool|WP_Error WP_Error object on error, true on success.
5329
+ */
5330
+ function woo_feed_duplicate_feed( $feed_from, $new_name = '', $copy_file = true ) {
5331
+
5332
+ if ( empty( $feed_from ) ) {
5333
+ return new WP_Error( 'invalid_feed_name_top_copy_from', esc_html__( 'Invalid Request.', 'woo-feed' ) );
5334
+ }
5335
+ // normalize the option name.
5336
+ $feed_from = woo_feed_extract_feed_option_name( $feed_from );
5337
+ // get the feed data for duplicating.
5338
+ $base_feed = maybe_unserialize( get_option( 'wf_feed_' . $feed_from, array() ) );
5339
+ // validate the feed data.
5340
+ if ( empty( $base_feed ) || ! is_array( $base_feed ) || ! isset( $base_feed['feedrules'] ) || ( isset( $base_feed['feedrules'] ) && empty( $base_feed['feedrules'] ) ) ) {
5341
+ return new WP_Error( 'empty_base_feed', esc_html__( 'Feed data is empty. Can\'t duplicate feed.', 'woo-feed' ) );
5342
+ }
5343
+ $part = '';
5344
+ if ( empty( $new_name ) ) {
5345
+ // generate a unique slug for duplicate the feed.
5346
+ $new_name = generate_unique_feed_file_name( $feed_from, $base_feed['feedrules']['feedType'], $base_feed['feedrules']['provider'] );
5347
+ // example-2 or example-2-2-3
5348
+ $part = ' ' . str_replace_trim( $feed_from . '-', '', $new_name ); // -2-2-3
5349
+ } else {
5350
+ $new_name = generate_unique_feed_file_name( $new_name, $base_feed['feedrules']['feedType'], $base_feed['feedrules']['provider'] );
5351
+ }
5352
+ // new name for the feed with numeric parts from the unique slug.
5353
+ $base_feed['feedrules']['filename'] = $base_feed['feedrules']['filename'] . $part;
5354
+ // copy feed config data.
5355
+ $saved_feed = woo_feed_save_feed_config_data( $base_feed['feedrules'], $new_name, false );
5356
+ if ( false === $saved_feed ) {
5357
+ return new WP_Error( 'unable_to_save_the_duplicate', esc_html__( 'Unable to save the duplicate feed data.', 'woo-feed' ) );
5358
+ }
5359
+
5360
+ if ( true === $copy_file ) {
5361
+ // copy the data file.
5362
+ $original_file = woo_feed_get_file( $feed_from, $base_feed['feedrules']['provider'], $base_feed['feedrules']['feedType'] );
5363
+ $new_file = woo_feed_get_file( $new_name, $base_feed['feedrules']['provider'], $base_feed['feedrules']['feedType'] );
5364
+ if ( copy( $original_file, $new_file ) ) {
5365
+ return true;
5366
+ } else {
5367
+ return new WP_Error( 'unable_to_copy_file', esc_html__( 'Feed Successfully Duplicated, but unable to generate the data file. Please click the "Regenerate Button"', 'woo-feed' ) );
5368
+ }
5369
+ }
5370
+
5371
+ return true;
5372
+ }
5373
+ }
5374
+
5375
+ if ( ! function_exists( 'woo_feed_is_google_group_merchant' ) ) {
5376
+ /**
5377
+ * Check if the given merchant is a google group merchant (google, facebook, pinterest, bing)
5378
+ *
5379
+ * @param string $provider Feed Merchant
5380
+ *
5381
+ * @return boolean
5382
+ * @since 4.4.22
5383
+ * @author Nazrul Islam Nayan
5384
+ */
5385
+ function woo_feed_is_google_group_merchant( $provider ) {
5386
+ return in_array( $provider, [ 'google', 'facebook', 'pinterest', 'bing' ] );
5387
+ }
5388
+ }
5389
+
5390
+ if ( ! function_exists( 'woo_feed_filter_product_description_callback' ) ) {
5391
+ /**
5392
+ * @param string $description Product Description
5393
+ * @param WC_Product $product Product Object
5394
+ * @param array $configFeed Feed Config
5395
+ *
5396
+ * @return mixed
5397
+ */
5398
+ function woo_feed_filter_product_description_callback( $description, $product, $config ) {
5399
+ if ( empty( $description ) ) {
5400
+ return $description;
5401
+ }
5402
+
5403
+ if ( isset( $config['provider'] ) && woo_feed_is_google_group_merchant( $config['provider'] ) ) {
5404
+ if ( strlen( $description ) > 5000 ) {
5405
+ for ( $I = 4999; $description[ $I ] != ' '; $I -- ) {
5406
+ ;
5407
+ }
5408
+ $description = substr( $description, 0, $I );
5409
+ }
5410
+ }
5411
+
5412
+ return $description;
5413
+ }
5414
  }
5415
 
5416
  if ( ! function_exists( 'woo_feed_filter_product_title' ) ) {
5417
+ /**
5418
+ * @param string $title Product Title
5419
+ * @param WC_Product $product
5420
+ * @param array $config Feed config
5421
+ *
5422
+ * @return string
5423
+ */
5424
+ function woo_feed_filter_product_title( $title, $product, $config ) {
5425
+
5426
+ if ( ! is_string( $title ) ) {
5427
+ return '';
5428
+ }
5429
+
5430
+ if ( isset( $config['provider'] ) && in_array( $config['provider'], [
5431
+ 'google',
5432
+ 'facebook',
5433
+ 'pinterest',
5434
+ 'bing'
5435
+ ] ) ) {
5436
+ if ( strlen( $title ) > 150 ) {
5437
+ for ( $I = 149; $title[ $I ] != ' '; $I -- ) {
5438
+ ;
5439
+ }
5440
+ $title = substr( $title, 0, $I );
5441
+ }
5442
+ }
5443
+
5444
+ return $title;
5445
+ }
5446
  }
5447
 
5448
  if ( ! function_exists( 'woo_feed_array_insert_after' ) ) {
5449
+ /**
5450
+ * Insert a value or key/value pair after a specific key in an array. If key doesn't exist, value is appended
5451
+ * to the end of the array.
5452
+ *
5453
+ * @param array $array
5454
+ * @param string $key
5455
+ * @param array $new
5456
+ *
5457
+ * @return array
5458
+ */
5459
+ function woo_feed_array_insert_after( array $array, $key, array $new ) {
5460
+ $keys = array_keys( $array );
5461
+ $index = array_search( $key, $keys, true );
5462
+ $pos = false === $index ? count( $array ) : $index + 1;
5463
+
5464
+ return array_merge( array_slice( $array, 0, $pos ), $new, array_slice( $array, $pos ) );
5465
+ }
5466
  }
5467
 
5468
  if ( ! function_exists( 'woo_feed_get_js_dequeue_handles_list' ) ) {
5469
+ /**
5470
+ * JS files handles list to dequeue from loading
5471
+ *
5472
+ * @return array
5473
+ * @author Nazrul Islam Nayan
5474
+ * @since 4.4.43
5475
+ */
5476
+ function woo_feed_get_js_dequeue_handles_list() {
5477
+ $js_files_handles = [ 'common_aramex', 'jquery_chained', 'validate_aramex' ]; //aramex shipping plugin handles
5478
 
5479
+ return apply_filters( "woo_feed_filter_js_dequeue_handles", $js_files_handles );
5480
+ }
5481
  }
5482
 
5483
  if ( ! function_exists( 'woo_feed_get_plugin_pages_slugs' ) ) {
5484
+ /**
5485
+ * Get Woo Feed Plugin Pages Slugs
5486
+ *
5487
+ * @return array
5488
+ * @author Nazrul Islam Nayan
5489
+ * @since 4.4.44
5490
+ */
5491
+ function woo_feed_get_plugin_pages_slugs() {
5492
+ $woo_feed_plugin_pages = [
5493
+ 'webappick-manage-feeds',
5494
+ 'webappick-new-feed',
5495
+ 'webappick-wp-options',
5496
+ 'webappick-feed-settings',
5497
+ 'webappick-feed-docs',
5498
+ 'webappick-feed-pro-vs-free',
5499
+ 'webappick-wp-status',
5500
+ 'webappick-feed-category-mapping',
5501
+ 'webappick-wp-options',
5502
+ ];
5503
 
5504
+ return apply_filters( 'woo_feed_plugin_pages_slugs', $woo_feed_plugin_pages );
5505
+ }
5506
  }
5507
 
5508
+ if ( ! function_exists( 'woo_feed_make_feed_big_data' ) ) {
5509
+ function woo_feed_make_feed_big_data( $data, $ids, $config ) {
5510
+
5511
+ //setup feed shipping data @TODO: need to make a class when another data setup will be added
5512
+ if ( isset( $config['attributes'] ) && in_array( "shipping", $config["attributes"] ) ) {
5513
+ if ( class_exists( 'WC_Shipping_Zones' ) ) {
5514
+ $data['shipping_zones'] = WC_Shipping_Zones::get_zones();
5515
+ }
5516
+ }
5517
 
5518
+ return $data;
 
 
 
 
 
5519
 
5520
+ }
5521
 
5522
+ add_filter( 'woo_feed_feed_big_data', 'woo_feed_make_feed_big_data', 10, 3 );
 
5523
  }
5524
 
5525
 
5526
+ if ( ! function_exists( 'woo_feed_after_wc_product_structured_data' ) ) {
5527
+ function woo_feed_after_wc_product_structured_data( $markup, $product ) {
5528
 
5529
+ if ( ! $product instanceof WC_Product ) {
5530
+ return $markup;
5531
+ }
5532
 
5533
+ if ( isset( $_SERVER['REQUEST_URI'] ) && strpos( $_SERVER['REQUEST_URI'], 'attribute_' ) ) {
5534
+ $url = $_SERVER['REQUEST_URI'];
5535
+ $url_components = parse_url( $url );
5536
+ $currency = get_option( 'woocommerce_currency' );
5537
 
5538
+ if ( isset( $url_components['query'] ) && ! empty( $url_components['query'] ) ) {
5539
+ parse_str( $url_components['query'], $params );
5540
 
5541
+ $attributes = $product->get_attributes();
5542
+ $attribute_names = array_keys( $attributes );
5543
 
5544
+ if ( isset( $attribute_names ) && is_array( $attribute_names ) ) {
5545
+ $meta_query_items = [];
5546
+ $meta_query_items['relation'] = 'AND';
5547
 
5548
+ foreach ( $attribute_names as $attr_name ) {
5549
+ $attribute_name = 'attribute_' . $attr_name;
5550
 
5551
+ if ( isset( $params[ $attribute_name ] ) ) {
5552
+ $new_query_item = [];
5553
+ $new_query_item['key'] = $attribute_name;
5554
+ $new_query_item['value'] = $params[ $attribute_name ];
5555
+ $new_query_item['compare'] = 'LIKE';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5556
 
5557
+ array_push( $meta_query_items, $new_query_item );
5558
+ }
5559
+ }
5560
 
5561
+ $variation_id = get_posts(
5562
+ array(
5563
+ 'post_type' => 'product_variation',
5564
+ 'numberposts' => 1,
5565
+ 'post_status' => 'publish',
5566
+ 'fields' => 'ids',
5567
+ 'post_parent' => $product->get_id(),
5568
+ 'meta_query' => $meta_query_items,
5569
+ )
5570
+ );
5571
 
5572
+ if ( isset( $variation_id[0] ) ) {
5573
+ $variation_product = wc_get_product( $variation_id[0] );
 
 
 
 
5574
 
5575
+ if ( $variation_product instanceof WC_Product_Variation ) {
5576
+ $variation_price = $variation_product->get_price();
5577
 
5578
+ $markup['offers'][0]['@type'] = "Offer";
5579
+ $markup['offers'][0]['price'] = $variation_price;
5580
+ $markup['offers'][0]['priceSpecification']['price'] = $variation_price;
5581
+ $markup['offers'][0]['priceSpecification']['priceCurrency'] = $currency;
5582
+ $markup['offers'][0]['priceCurrency'] = $currency;
5583
+ }
5584
 
5585
+ }
5586
 
5587
+ }
5588
+ }
5589
 
5590
+ }
5591
+
5592
+ return $markup;
5593
+
5594
+ }
5595
+
5596
+ add_filter( 'woo_feed_after_wc_product_structured_data', 'woo_feed_after_wc_product_structured_data', 10, 2 );
5597
  }
5598
 
5599
+ if ( ! function_exists( 'woo_feed_filter_shipping_info_callback' ) ) {
5600
+ function woo_feed_filter_shipping_info_callback( $shipping_info, $shipping_zones, $product, $config ) {
5601
 
5602
+ //when WooCommerce Advanced Shipping by sormano is activated
5603
+ if ( is_plugin_active( 'woocommerce-advanced-shipping/woocommerce-advanced-shipping.php' ) ) {
5604
+ $product_id = $product->get_id();
5605
 
5606
+ //get advanced shipping post ids for post type `was`
5607
+ $args = array(
5608
+ 'post_type' => 'was',
5609
+ 'fields' => 'ids',
5610
+ );
5611
 
5612
+ $ids = get_posts( $args );
5613
 
5614
+ // Set shipping cost
5615
+ $shipping_cost = 0;
5616
+ $tax = 0;
5617
+ defined( 'WC_ABSPATH' ) || exit;
5618
 
5619
+ // Load cart functions which are loaded only on the front-end.
5620
+ include_once WC_ABSPATH . 'includes/wc-cart-functions.php';
5621
+ include_once WC_ABSPATH . 'includes/class-wc-cart.php';
5622
 
5623
+ wc_load_cart();
5624
+ global $woocommerce;
5625
 
5626
+ // Make sure to empty the cart again
5627
+ $woocommerce->cart->empty_cart();
5628
 
5629
+ // add product to cart
5630
+ $woocommerce->cart->add_to_cart( $product_id, 1 );
5631
 
5632
+ if ( isset( WC()->session->get( 'shipping_for_package_0' )['rates'] ) ) {
5633
+ $cart_shippings = WC()->session->get( 'shipping_for_package_0' )['rates'];
5634
+ $exist_shipping_keys = array_keys( $cart_shippings );
5635
 
5636
+ if ( isset( $cart_shippings ) && is_array( $cart_shippings ) ) {
5637
+ $adv_shipping = [];
5638
+ foreach ( $cart_shippings as $key => $cart_shipping ) {
5639
+ $new_adv_shipping = [];
5640
 
5641
+ if ( in_array( $key, $ids ) ) {
5642
+ $new_adv_shipping['country'] = $config['feed_country'];
5643
+ $new_adv_shipping['service'] = '';
5644
+ $label = $cart_shipping->get_label();
5645
 
5646
+ //advanced shipping service
5647
+ if ( isset( $label ) && ! empty( $label ) ) {
5648
+ $new_adv_shipping['service'] = $label;
5649
+ } else {
5650
+ $new_adv_shipping['service'] = get_the_title( $key );
5651
+ }
5652
 
5653
+ //advanced shipping cost
5654
+ if ( ! empty( $cart_shipping->get_cost() ) ) {
5655
+ $new_adv_shipping['price'] = $cart_shipping->get_cost();
5656
+ } else {
5657
+ $new_adv_shipping['price'] = 0;
5658
+ }
5659
 
5660
+ array_push( $adv_shipping, $new_adv_shipping );
5661
+ }
5662
 
5663
+ }
5664
+ }
5665
 
5666
+ }
5667
 
5668
+ // Make sure to empty the cart again
5669
+ $woocommerce->cart->empty_cart();
5670
 
5671
 
5672
+ if ( ! empty( $adv_shipping ) ) {
5673
+ $shipping_info = array_merge( $shipping_info, $adv_shipping );
5674
+ }
5675
 
5676
+ }
5677
 
5678
 
5679
+ return $shipping_info;
5680
 
5681
+ }
5682
 
5683
+ add_filter( 'woo_feed_filter_shipping_info', 'woo_feed_filter_shipping_info_callback', 10, 4 );
5684
  }
5685
 
5686
  #=============== ACF ===============================================
5687
  if ( ! function_exists( 'woo_feed_get_acf_field_list' ) ) {
5688
+ /**
5689
+ * Get Advance Custom Field (ACF) field list
5690
+ *
5691
+ *
5692
+ * @return Array
5693
+ */
5694
+ function woo_feed_get_acf_field_list() {
5695
+ $options = [];
5696
+ if ( class_exists( 'ACF' ) ) {
5697
+ $acf_fields = woo_feed_get_cached_data( 'acf_field_list' );
5698
+ if ( false === $acf_fields ) {
5699
+ $field_groups = acf_get_field_groups();
5700
+ foreach ( $field_groups as $group ) {
5701
+ // DO NOT USE here: $fields = acf_get_fields($group['key']);
5702
+ // because it causes repeater field bugs and returns "trashed" fields
5703
+ $fields = get_posts( array(
5704
+ 'posts_per_page' => - 1,
5705
+ 'post_type' => 'acf-field',
5706
+ 'orderby' => 'menu_order',
5707
+ 'order' => 'ASC',
5708
+ 'suppress_filters' => true, // DO NOT allow WPML to modify the query
5709
+ 'post_parent' => $group['ID'],
5710
+ 'post_status' => 'any',
5711
+ 'update_post_meta_cache' => false,
5712
+ ) );
5713
+ foreach ( $fields as $field ) {
5714
+ $options[ 'acf_fields_' . $field->post_name ] = $field->post_title;
5715
+ }
5716
+ }
5717
+
5718
+ woo_feed_set_cache_data( 'acf_field_list', $options );
5719
+ }
5720
+ }
5721
+
5722
+ return $options;
5723
+ }
5724
+ }
5725
+
5726
+ if ( ! function_exists( 'woo_feed_get_product_attributes' ) ) {
5727
+ /**
5728
+ * Get Advance Custom Field (ACF) field list
5729
+ *
5730
+ *
5731
+ * @return string
5732
+ */
5733
+ function woo_feed_get_product_attributes( $selected = '' ) {
5734
+ return ( new Woo_Feed_Product_Attributes() )->getAttributes( $selected );
5735
+ }
5736
  }
5737
 
5738
  #==== MERCHANT TEMPLATE OVERRIDE END ================#
languages/woo-feed.pot CHANGED
@@ -12,151 +12,151 @@ msgstr ""
12
  "X-Poedit-KeywordsList: __;_e;_ex:1,2c;_n:1,2;_n_noop:1,2;_nx:1,2,4c;_nx_noop:1,2,3c;_x:1,2c;esc_attr__;esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c\n"
13
  "Plural-Forms: nplurals=2; plural=(n != 1);\n"
14
 
15
- #: woo-feed.php:136, woo-feed.php:256, woo-feed.php:331, woo-feed.php:687, woo-feed.php:727, woo-feed.php:747, woo-feed.php:767, woo-feed.php:793
16
  msgid "Unauthorized Action."
17
  msgstr ""
18
 
19
- #: woo-feed.php:141, woo-feed.php:260, includes/helper.php:823, includes/helper.php:1843, includes/helper.php:2867, includes/helper.php:2895, includes/helper.php:3288, includes/helper.php:3479, includes/helper.php:3506, includes/helper.php:4737, includes/helper.php:5227
20
  msgid "Invalid Request."
21
  msgstr ""
22
 
23
- #: woo-feed.php:236, woo-feed.php:200
24
  msgid "No products found. Add product or change feed config before generate the feed."
25
  msgstr ""
26
 
27
- #: woo-feed.php:214
28
  msgid "Failed to fetch products."
29
  msgstr ""
30
 
31
- #: woo-feed.php:335
32
  msgid "Invalid Feed."
33
  msgstr ""
34
 
35
- #: woo-feed.php:419
36
  msgid "No Product Found with your feed configuration. Please Update And Generate the feed again."
37
  msgstr ""
38
 
39
- #: woo-feed.php:414
40
  msgid "Products not found with your filtering condition."
41
  msgstr ""
42
 
43
- #: woo-feed.php:467
44
  msgid "Failed to save feed file. Please confirm that your WordPress directory have read and write permission."
45
  msgstr ""
46
 
47
- #: woo-feed.php:459
48
  msgid "Feed Making Complete"
49
  msgstr ""
50
 
51
- #: woo-feed.php:543, woo-feed.php:583
52
  msgid "Failed security check"
53
  msgstr ""
54
 
55
- #: woo-feed.php:547, woo-feed.php:587
56
  msgid "Invalid Feed Type!"
57
  msgstr ""
58
 
59
- #: woo-feed.php:641
60
  msgid "Feed Does not Exists."
61
  msgstr ""
62
 
63
- #: woo-feed.php:693
64
  msgid "Invalid Merchant"
65
  msgstr ""
66
 
67
- #: admin/class-woo-feed-admin.php:174, includes/helper.php:788, includes/helper.php:900, includes/helper.php:881, includes/helper.php:869, includes/helper.php:857
68
  msgid "N/A"
69
  msgstr ""
70
 
71
- #: admin/class-woo-feed-admin.php:175
72
  msgid "Generating..."
73
  msgstr ""
74
 
75
- #: admin/class-woo-feed-admin.php:176
76
  msgid "Learn More.."
77
  msgstr ""
78
 
79
- #: admin/class-woo-feed-admin.php:178, includes/helper.php:3208, admin/partials/woo-feed-edit-config.php:66
80
  msgid "Select A Category"
81
  msgstr ""
82
 
83
- #: admin/class-woo-feed-admin.php:179
84
  msgid "Loading Template..."
85
  msgstr ""
86
 
87
- #: admin/class-woo-feed-admin.php:180
88
  msgid "Delivering Configuration..."
89
  msgstr ""
90
 
91
- #: admin/class-woo-feed-admin.php:181
92
  msgid "Saving Configuration..."
93
  msgstr ""
94
 
95
- #: admin/class-woo-feed-admin.php:182
96
  msgid "Wait! Checking Extensions ..."
97
  msgstr ""
98
 
99
- #: admin/class-woo-feed-admin.php:183
100
  msgid "Warning! Enable PHP ssh2 extension to use SFTP. Contact your server administrator."
101
  msgstr ""
102
 
103
- #: admin/class-woo-feed-admin.php:184
104
  msgid "SFTP Available!"
105
  msgstr ""
106
 
107
- #: admin/class-woo-feed-admin.php:185
108
  msgid "Please add one or more items to continue."
109
  msgstr ""
110
 
111
- #: admin/class-woo-feed-admin.php:187
112
  msgid "Are you sure you want to delete this item?"
113
  msgstr ""
114
 
115
- #: admin/class-woo-feed-admin.php:188
116
  msgid "Are you sure you want to delete selected items?"
117
  msgstr ""
118
 
119
- #: admin/class-woo-feed-admin.php:199
120
  msgid "There was an error processing ajax request."
121
  msgstr ""
122
 
123
- #: admin/class-woo-feed-admin.php:235
124
  msgid "Get Pro"
125
  msgstr ""
126
 
127
- #: admin/class-woo-feed-admin.php:237, admin/class-woo-feed-admin.php:268
128
  msgid "Docs"
129
  msgstr ""
130
 
131
- #: admin/class-woo-feed-admin.php:239, admin/class-woo-feed-admin.php:266, admin/class-woo-feed-admin.php:266, admin/partials/woo-feed-settings.php:17
132
  msgid "Settings"
133
  msgstr ""
134
 
135
- #: admin/class-woo-feed-admin.php:261, admin/class-woo-feed-admin.php:261, includes/classes/class-woo-feed-admin-message.php:121, includes/classes/class-woo-feed-webappick-api.php:300
136
  msgid "CTX Feed"
137
  msgstr ""
138
 
139
- #: admin/class-woo-feed-admin.php:262, admin/class-woo-feed-admin.php:262
140
  msgid "Manage Feeds"
141
  msgstr ""
142
 
143
- #: admin/class-woo-feed-admin.php:263, admin/class-woo-feed-admin.php:263
144
  msgid "Make Feed"
145
  msgstr ""
146
 
147
- #: admin/class-woo-feed-admin.php:264, admin/class-woo-feed-admin.php:264, admin/partials/woo-feed-category-mapping.php:25
148
  msgid "Category Mapping"
149
  msgstr ""
150
 
151
- #: admin/class-woo-feed-admin.php:265, admin/class-woo-feed-admin.php:265, includes/classes/class-woo-feed-dropdown.php:698
152
  msgid "WP Options"
153
  msgstr ""
154
 
155
- #: admin/class-woo-feed-admin.php:267, admin/class-woo-feed-admin.php:267
156
  msgid "Status"
157
  msgstr ""
158
 
159
- #: admin/class-woo-feed-admin.php:268, includes/classes/class-woo-feed-admin-message.php:129, includes/classes/class-woo-feed-webappick-api.php:186
160
  msgid "Documentation"
161
  msgstr ""
162
 
@@ -168,7 +168,7 @@ msgstr ""
168
  msgid "mappings"
169
  msgstr ""
170
 
171
- #: admin/class-woo-feed-category-list.php:81, admin/class-woo-feed-category-list.php:122, admin/class-woo-feed-category-list.php:217, admin/class-woo-feed-manage-list.php:162, admin/class-woo-feed-manage-list.php:270, includes/helper.php:3557
172
  msgid "Edit"
173
  msgstr ""
174
 
@@ -192,24 +192,24 @@ msgstr ""
192
  msgid "Action"
193
  msgstr ""
194
 
195
- #: admin/class-woo-feed-category-list.php:325
196
  msgid "Failed To Delete Mapping"
197
  msgstr ""
198
 
199
- #: admin/class-woo-feed-category-list.php:321
200
  msgid "Mapping Deleted Successfully"
201
  msgstr ""
202
 
203
- #: admin/class-woo-feed-category-list.php:316, admin/class-woo-feed-category-list.php:343
204
  msgid "Failed To Delete Mapping. You do not have sufficient permission to delete."
205
  msgstr ""
206
 
207
- #: admin/class-woo-feed-category-list.php:335, admin/class-woo-feed-manage-list.php:424, admin/class-woo-feed-manage-list.php:433, admin/class-woo-feed-option-list.php:336
208
  msgid "You do not have sufficient permission to delete!"
209
  msgstr ""
210
 
211
  #. translators: 1: number of item deleted.
212
- #: admin/class-woo-feed-category-list.php:357
213
  msgid "%d Mapping Successfully Deleted."
214
  msgid_plural "%d Mappings Successfully Deleted."
215
  msgstr[0] ""
@@ -227,7 +227,7 @@ msgstr ""
227
  msgid "Copy To Clipboard"
228
  msgstr ""
229
 
230
- #: admin/class-woo-feed-manage-list.php:116, includes/helper.php:922
231
  msgid "View"
232
  msgstr ""
233
 
@@ -279,11 +279,11 @@ msgstr ""
279
  msgid "Last Updated"
280
  msgstr ""
281
 
282
- #: admin/class-woo-feed-manage-list.php:392
283
  msgid "Failed To Delete Feed"
284
  msgstr ""
285
 
286
- #: admin/class-woo-feed-manage-list.php:388
287
  msgid "Feed Deleted Successfully"
288
  msgstr ""
289
 
@@ -291,16 +291,16 @@ msgstr ""
291
  msgid "Failed To Delete Feed. You do not have sufficient permission to delete."
292
  msgstr ""
293
 
294
- #: admin/class-woo-feed-manage-list.php:412
295
  msgid "Feed Successfully Duplicated."
296
  msgstr ""
297
 
298
- #: admin/class-woo-feed-manage-list.php:402
299
  msgid "Failed To Duplicate Feed. You do not have sufficient permission to duplicate."
300
  msgstr ""
301
 
302
  #. translators: %d: number of item deleted.
303
- #: admin/class-woo-feed-manage-list.php:446
304
  msgid "%d Feed Successfully Deleted."
305
  msgid_plural "%d Feeds Successfully Deleted."
306
  msgstr[0] ""
@@ -326,20 +326,20 @@ msgstr ""
326
  msgid "Option Value"
327
  msgstr ""
328
 
329
- #: admin/class-woo-feed-option-list.php:325
330
  msgid "Failed To Delete Option."
331
  msgstr ""
332
 
333
- #: admin/class-woo-feed-option-list.php:321
334
  msgid "Option Deleted Successfully."
335
  msgstr ""
336
 
337
- #: admin/class-woo-feed-option-list.php:316, admin/class-woo-feed-option-list.php:356
338
  msgid "Failed To Delete Option. You do not have sufficient permission to delete."
339
  msgstr ""
340
 
341
  #. translators: 1: number of item deleted.
342
- #: admin/class-woo-feed-option-list.php:371
343
  msgid "%d Option Successfully Deleted."
344
  msgid_plural "%d Options Successfully Deleted."
345
  msgstr[0] ""
@@ -401,339 +401,339 @@ msgstr ""
401
  msgid "%1$s requires %2$s version %3$s or above and %4$s found. Please upgrade %2$s to the latest version here %5$s"
402
  msgstr ""
403
 
404
- #: includes/helper.php:292
405
  msgid "Generating Product Feed"
406
  msgstr ""
407
 
408
- #: includes/helper.php:389
409
  msgid "WC_Product_Query"
410
  msgstr ""
411
 
412
- #: includes/helper.php:390
413
  msgid "WP_Query"
414
  msgstr ""
415
 
416
- #: includes/helper.php:391
417
  msgid "Both"
418
  msgstr ""
419
 
420
- #: includes/helper.php:384
421
  msgid "Individual"
422
  msgstr ""
423
 
424
- #: includes/helper.php:385
425
  msgid "Variable Dependable"
426
  msgstr ""
427
 
428
- #: includes/helper.php:405
429
  msgid "No Expiration "
430
  msgstr ""
431
 
432
- #: includes/helper.php:406
433
  msgid "1 Month"
434
  msgstr ""
435
 
436
- #: includes/helper.php:407, includes/helper.php:2007
437
  msgid "1 Week"
438
  msgstr ""
439
 
440
- #: includes/helper.php:408, includes/helper.php:2008
441
  msgid "24 Hours"
442
  msgstr ""
443
 
444
- #: includes/helper.php:409, includes/helper.php:2009
445
  msgid "12 Hours"
446
  msgstr ""
447
 
448
- #: includes/helper.php:410, includes/helper.php:2010
449
  msgid "6 Hours"
450
  msgstr ""
451
 
452
- #: includes/helper.php:411, includes/helper.php:2011
453
  msgid "1 Hours"
454
  msgstr ""
455
 
456
- #: includes/helper.php:799
457
  msgid "Watch Now"
458
  msgstr ""
459
 
460
- #: includes/helper.php:794, includes/helper.php:860
461
  msgid "Read Article"
462
  msgstr ""
463
 
464
- #: includes/helper.php:896
465
  msgid "Support Docs:"
466
  msgstr ""
467
 
468
- #: includes/helper.php:877
469
  msgid "Supported File Types:"
470
  msgstr ""
471
 
472
- #: includes/helper.php:865
473
  msgid "Video Documentation:"
474
  msgstr ""
475
 
476
- #: includes/helper.php:872
477
  msgid "Watch now"
478
  msgstr ""
479
 
480
- #: includes/helper.php:853
481
  msgid "Feed Specification:"
482
  msgstr ""
483
 
484
- #: includes/helper.php:923
485
  msgid "Open Feed File"
486
  msgstr ""
487
 
488
- #: includes/helper.php:1699, includes/helper.php:1700, includes/helper.php:1670, includes/helper.php:1670, includes/helper.php:1844, includes/helper.php:1906, includes/helper.php:1907, includes/helper.php:1882, includes/helper.php:1882, libs/WebAppick/AppServices/Insights.php:813, libs/WebAppick/AppServices/Promotions.php:362
489
  msgid "Invalid Request"
490
  msgstr ""
491
 
492
- #: includes/helper.php:1729
493
  msgid "Empty File Uploaded. Try again."
494
  msgstr ""
495
 
496
- #: includes/helper.php:1730
497
  msgid "Empty File"
498
  msgstr ""
499
 
500
- #: includes/helper.php:1733, includes/helper.php:1744, includes/helper.php:1756, includes/helper.php:1767, includes/helper.php:1781, includes/helper.php:1791, includes/helper.php:1803, includes/helper.php:1847
501
  msgid "&laquo; Back"
502
  msgstr ""
503
 
504
- #: includes/helper.php:1740
505
  msgid "Unable to read file content"
506
  msgstr ""
507
 
508
- #: includes/helper.php:1741, includes/helper.php:1753, includes/helper.php:1764, includes/helper.php:1778, includes/helper.php:1788, includes/helper.php:1800
509
  msgid "Invalid File"
510
  msgstr ""
511
 
512
- #: includes/helper.php:1752
513
  msgid "Unable to read data from file."
514
  msgstr ""
515
 
516
- #: includes/helper.php:1763
517
  msgid "Unable to read file info."
518
  msgstr ""
519
 
520
- #: includes/helper.php:1777
521
  msgid "Unable to read feed data from file."
522
  msgstr ""
523
 
524
- #: includes/helper.php:1787
525
  msgid "Unable to verify the file."
526
  msgstr ""
527
 
528
- #: includes/helper.php:1799
529
  msgid "Invalid or corrupted config file."
530
  msgstr ""
531
 
532
- #: includes/helper.php:1819
533
  msgid " Imported"
534
  msgstr ""
535
 
536
- #: includes/helper.php:2832
537
  msgid "Brand"
538
  msgstr ""
539
 
540
- #: includes/helper.php:2833
541
  msgid "GTIN"
542
  msgstr ""
543
 
544
- #: includes/helper.php:2834
545
  msgid "MPN"
546
  msgstr ""
547
 
548
- #: includes/helper.php:2835
549
  msgid "EAN"
550
  msgstr ""
551
 
552
- #: includes/helper.php:2836
553
  msgid "ISBN"
554
  msgstr ""
555
 
556
- #: includes/helper.php:2837
557
  msgid "Age group"
558
  msgstr ""
559
 
560
- #: includes/helper.php:2838
561
  msgid "Gender"
562
  msgstr ""
563
 
564
- #: includes/helper.php:2839
565
  msgid "Material"
566
  msgstr ""
567
 
568
- #: includes/helper.php:2840
569
  msgid "Cost of good sold"
570
  msgstr ""
571
 
572
- #: includes/helper.php:2841, includes/classes/class-woo-feed-dropdown.php:501, libs/WebAppick/Attributes/AvailabilityDate.php:47, libs/WebAppick/Attributes/AvailabilityDate.php:77
573
  msgid "Availability Date"
574
  msgstr ""
575
 
576
- #: includes/helper.php:2842
577
  msgid "Unit"
578
  msgstr ""
579
 
580
- #: includes/helper.php:2843, includes/classes/class-woo-feed-dropdown.php:572
581
  msgid "Unit Price Measure"
582
  msgstr ""
583
 
584
- #: includes/helper.php:2844, includes/classes/class-woo-feed-dropdown.php:573
585
  msgid "Unit Price Base Measure"
586
  msgstr ""
587
 
588
- #: includes/helper.php:2845
589
  msgid "Custom field 0"
590
  msgstr ""
591
 
592
- #: includes/helper.php:2846
593
  msgid "Custom field 1"
594
  msgstr ""
595
 
596
- #: includes/helper.php:2847
597
  msgid "Custom field 2"
598
  msgstr ""
599
 
600
- #: includes/helper.php:2848
601
  msgid "Custom field 3"
602
  msgstr ""
603
 
604
- #: includes/helper.php:2849
605
  msgid "Custom field 4"
606
  msgstr ""
607
 
608
- #: includes/helper.php:2915, includes/helper.php:3018
609
  msgid "CUSTOM FIELDS by CTX Feed"
610
  msgstr ""
611
 
612
- #: includes/helper.php:2932
613
  msgid "Set product "
614
  msgstr ""
615
 
616
- #: includes/helper.php:2932
617
  msgid " here."
618
  msgstr ""
619
 
620
- #: includes/helper.php:3128
621
  msgid "Another category mapping exists with the same name."
622
  msgstr ""
623
 
624
- #: includes/helper.php:3137
625
  msgid "Failed To Add Mapping"
626
  msgstr ""
627
 
628
- #: includes/helper.php:3133
629
  msgid "Mapping Added Successfully"
630
  msgstr ""
631
 
632
- #: includes/helper.php:3102
633
  msgid "Mapping Not Changed"
634
  msgstr ""
635
 
636
- #: includes/helper.php:3112
637
  msgid "Failed To Updated Mapping"
638
  msgstr ""
639
 
640
- #: includes/helper.php:3108
641
  msgid "Mapping Updated Successfully"
642
  msgstr ""
643
 
644
- #: includes/helper.php:3228
645
  msgid "Copy this category to subcategories"
646
  msgstr ""
647
 
648
- #: includes/helper.php:3258
649
  msgid "Clear Cache"
650
  msgstr ""
651
 
652
- #: includes/helper.php:3475, includes/helper.php:3503
653
  msgid "Something is wrong."
654
  msgstr ""
655
 
656
- #: includes/helper.php:3473
657
  msgid "User meta updated successfully."
658
  msgstr ""
659
 
660
- #: includes/helper.php:3549, includes/helper.php:3551
661
  msgid "by CTX Feed"
662
  msgstr ""
663
 
664
- #: includes/helper.php:3552
665
  msgid "All"
666
  msgstr ""
667
 
668
- #: includes/helper.php:3553
669
  msgid "Parent"
670
  msgstr ""
671
 
672
- #: includes/helper.php:3554
673
  msgid "Parent:"
674
  msgstr ""
675
 
676
- #: includes/helper.php:3555
677
  msgid "New"
678
  msgstr ""
679
 
680
- #: includes/helper.php:3555, libs/WebAppick/AppServices/Insights.php:977
681
  msgid "Name"
682
  msgstr ""
683
 
684
- #: includes/helper.php:3556
685
  msgid "Add New"
686
  msgstr ""
687
 
688
- #: includes/helper.php:3558
689
  msgid "Update"
690
  msgstr ""
691
 
692
- #: includes/helper.php:3559
693
  msgid "Separate"
694
  msgstr ""
695
 
696
- #: includes/helper.php:3559
697
  msgid "with commas"
698
  msgstr ""
699
 
700
- #: includes/helper.php:3560
701
  msgid "Search"
702
  msgstr ""
703
 
704
- #: includes/helper.php:3561
705
  msgid "Add or remove"
706
  msgstr ""
707
 
708
- #: includes/helper.php:3562
709
  msgid "Choose from the most used"
710
  msgstr ""
711
 
712
- #: includes/helper.php:4434
713
  msgid "Option Successfully Added."
714
  msgstr ""
715
 
716
- #: includes/helper.php:4425
717
  msgid "Option Already Added."
718
  msgstr ""
719
 
720
- #: includes/helper.php:5134
721
  msgid "Delivery up to 30 days"
722
  msgstr ""
723
 
724
- #: includes/helper.php:5132
725
  msgid "Delivery 1 to 3 days"
726
  msgstr ""
727
 
728
- #: includes/helper.php:5235
729
  msgid "Feed data is empty. Can't duplicate feed."
730
  msgstr ""
731
 
732
- #: includes/helper.php:5251
733
  msgid "Unable to save the duplicate feed data."
734
  msgstr ""
735
 
736
- #: includes/helper.php:5261
737
  msgid "Feed Successfully Duplicated, but unable to generate the data file. Please click the \"Regenerate Button\""
738
  msgstr ""
739
 
@@ -814,27 +814,27 @@ msgstr ""
814
  msgid "Are You Sure to Delete?"
815
  msgstr ""
816
 
817
- #: admin/partials/woo-feed-category-mapping.php:33
818
  msgid "Merchant"
819
  msgstr ""
820
 
821
- #: admin/partials/woo-feed-category-mapping.php:45
822
  msgid "Mapping Name"
823
  msgstr ""
824
 
825
- #: admin/partials/woo-feed-category-mapping.php:47
826
  msgid "Mapping Name should be unique and don't use space. Otherwise it will override the existing Category Mapping. Example: myMappingName or my_mapping_name"
827
  msgstr ""
828
 
829
- #: admin/partials/woo-feed-category-mapping.php:56
830
  msgid "Local Category"
831
  msgstr ""
832
 
833
- #: admin/partials/woo-feed-category-mapping.php:57
834
  msgid "Merchant Category"
835
  msgstr ""
836
 
837
- #: admin/partials/woo-feed-category-mapping.php:67
838
  msgid "Save Mapping"
839
  msgstr ""
840
 
@@ -1062,39 +1062,39 @@ msgstr ""
1062
  msgid "Edit WooCommerce Product Feed"
1063
  msgstr ""
1064
 
1065
- #: admin/partials/woo-feed-manage-list.php:34
1066
  msgid "Manage Feed"
1067
  msgstr ""
1068
 
1069
- #: admin/partials/woo-feed-manage-list.php:35
1070
  msgid "New Feed"
1071
  msgstr ""
1072
 
1073
- #: admin/partials/woo-feed-manage-list.php:36
1074
  msgid "Import Feed"
1075
  msgstr ""
1076
 
1077
- #: admin/partials/woo-feed-manage-list.php:44
1078
  msgid "Import Feed File"
1079
  msgstr ""
1080
 
1081
- #: admin/partials/woo-feed-manage-list.php:50, admin/partials/woo-feed-manage-list.php:51
1082
  msgid "Feed File Name"
1083
  msgstr ""
1084
 
1085
- #: admin/partials/woo-feed-manage-list.php:56
1086
  msgid "Import Now"
1087
  msgstr ""
1088
 
1089
- #: admin/partials/woo-feed-manage-list.php:69
1090
  msgid "Auto Update Feed Interval"
1091
  msgstr ""
1092
 
1093
- #: admin/partials/woo-feed-manage-list.php:79
1094
  msgid "Interval"
1095
  msgstr ""
1096
 
1097
- #: admin/partials/woo-feed-manage-list.php:88
1098
  msgid "Update Interval"
1099
  msgstr ""
1100
 
@@ -1376,1010 +1376,1106 @@ msgstr ""
1376
  msgid "Settings Updated."
1377
  msgstr ""
1378
 
1379
- #: includes/classes/class-woo-feed-dropdown.php:478, includes/classes/class-woo-feed-products.php:1784
1380
- msgid "Primary Attributes"
1381
  msgstr ""
1382
 
1383
- #: includes/classes/class-woo-feed-dropdown.php:479, includes/classes/class-woo-feed-products.php:1711
1384
- msgid "Product Id"
1385
  msgstr ""
1386
 
1387
- #: includes/classes/class-woo-feed-dropdown.php:480, includes/classes/class-woo-feed-products.php:1712
1388
- msgid "Product Title"
1389
  msgstr ""
1390
 
1391
- #: includes/classes/class-woo-feed-dropdown.php:481
1392
- msgid "Parent Title"
1393
  msgstr ""
1394
 
1395
- #: includes/classes/class-woo-feed-dropdown.php:482, includes/classes/class-woo-feed-products.php:1713
1396
- msgid "Product Description"
1397
  msgstr ""
1398
 
1399
- #: includes/classes/class-woo-feed-dropdown.php:483
1400
- msgid "Product Description (with HTML)"
1401
  msgstr ""
1402
 
1403
- #: includes/classes/class-woo-feed-dropdown.php:484, includes/classes/class-woo-feed-products.php:1714
1404
- msgid "Product Short Description"
1405
  msgstr ""
1406
 
1407
- #: includes/classes/class-woo-feed-dropdown.php:485
1408
- msgid "Parent Category"
1409
  msgstr ""
1410
 
1411
- #: includes/classes/class-woo-feed-dropdown.php:486
1412
- msgid "Parent Category ID"
1413
  msgstr ""
1414
 
1415
- #: includes/classes/class-woo-feed-dropdown.php:487
1416
- msgid "Child Category"
 
1417
  msgstr ""
1418
 
1419
- #: includes/classes/class-woo-feed-dropdown.php:488
1420
- msgid "Child Category ID"
1421
- msgstr ""
 
 
1422
 
1423
- #: includes/classes/class-woo-feed-dropdown.php:489
1424
- msgid "Product Category [Category Path]"
1425
- msgstr ""
 
 
1426
 
1427
- #: includes/classes/class-woo-feed-dropdown.php:490
1428
- msgid "Product Full Category [Category Full Path]"
1429
- msgstr ""
 
 
1430
 
1431
- #: includes/classes/class-woo-feed-dropdown.php:491, includes/classes/class-woo-feed-products.php:1716
1432
- msgid "Product URL"
1433
  msgstr ""
1434
 
1435
- #: includes/classes/class-woo-feed-dropdown.php:492
1436
- msgid "Parent URL"
1437
  msgstr ""
1438
 
1439
- #: includes/classes/class-woo-feed-dropdown.php:493
1440
- msgid "Canonical URL"
1441
  msgstr ""
1442
 
1443
- #: includes/classes/class-woo-feed-dropdown.php:494, includes/classes/class-woo-feed-products.php:1717
1444
- msgid "External Product URL"
 
 
 
 
 
 
1445
  msgstr ""
1446
 
1447
- #: includes/classes/class-woo-feed-dropdown.php:495
1448
- msgid "Add to Cart URL"
1449
  msgstr ""
1450
 
1451
- #: includes/classes/class-woo-feed-dropdown.php:496, includes/classes/class-woo-feed-products.php:1719
1452
- msgid "Parent Id [Group Id]"
1453
  msgstr ""
1454
 
1455
- #: includes/classes/class-woo-feed-dropdown.php:497, includes/classes/class-woo-feed-products.php:1720
1456
- msgid "SKU"
 
1457
  msgstr ""
1458
 
1459
- #: includes/classes/class-woo-feed-dropdown.php:498
1460
- msgid "SKU_ID"
1461
  msgstr ""
1462
 
1463
- #: includes/classes/class-woo-feed-dropdown.php:499, includes/classes/class-woo-feed-products.php:1721
1464
- msgid "Parent SKU"
1465
  msgstr ""
1466
 
1467
- #: includes/classes/class-woo-feed-dropdown.php:500, includes/classes/class-woo-feed-products.php:1722
1468
- msgid "Availability"
1469
  msgstr ""
1470
 
1471
- #: includes/classes/class-woo-feed-dropdown.php:502, includes/classes/class-woo-feed-products.php:1723
1472
- msgid "Quantity"
1473
  msgstr ""
1474
 
1475
- #: includes/classes/class-woo-feed-dropdown.php:503
1476
- msgid "Currency"
1477
  msgstr ""
1478
 
1479
- #: includes/classes/class-woo-feed-dropdown.php:504, includes/classes/class-woo-feed-products.php:1724
1480
- msgid "Regular Price"
1481
  msgstr ""
1482
 
1483
- #: includes/classes/class-woo-feed-dropdown.php:505, includes/classes/class-woo-feed-products.php:1725
1484
- msgid "Price"
1485
  msgstr ""
1486
 
1487
- #: includes/classes/class-woo-feed-dropdown.php:506, includes/classes/class-woo-feed-products.php:1726
1488
- msgid "Sale Price"
1489
  msgstr ""
1490
 
1491
- #: includes/classes/class-woo-feed-dropdown.php:507, includes/classes/class-woo-feed-products.php:1727
1492
- msgid "Regular Price With Tax"
1493
  msgstr ""
1494
 
1495
- #: includes/classes/class-woo-feed-dropdown.php:508, includes/classes/class-woo-feed-products.php:1728
1496
- msgid "Price With Tax"
1497
  msgstr ""
1498
 
1499
- #: includes/classes/class-woo-feed-dropdown.php:509, includes/classes/class-woo-feed-products.php:1729
1500
- msgid "Sale Price With Tax"
1501
  msgstr ""
1502
 
1503
- #: includes/classes/class-woo-feed-dropdown.php:510, includes/classes/class-woo-feed-products.php:1730
1504
- msgid "Sale Start Date"
1505
  msgstr ""
1506
 
1507
- #: includes/classes/class-woo-feed-dropdown.php:511, includes/classes/class-woo-feed-products.php:1731
1508
- msgid "Sale End Date"
1509
  msgstr ""
1510
 
1511
- #: includes/classes/class-woo-feed-dropdown.php:512
1512
- msgid "Reviewer Name"
1513
  msgstr ""
1514
 
1515
- #: includes/classes/class-woo-feed-dropdown.php:513, includes/classes/class-woo-feed-products.php:1732
1516
- msgid "Weight"
1517
  msgstr ""
1518
 
1519
- #: includes/classes/class-woo-feed-dropdown.php:514
1520
- msgid "Weight Unit"
1521
  msgstr ""
1522
 
1523
- #: includes/classes/class-woo-feed-dropdown.php:515, includes/classes/class-woo-feed-products.php:1733
1524
- msgid "Width"
1525
  msgstr ""
1526
 
1527
- #: includes/classes/class-woo-feed-dropdown.php:516, includes/classes/class-woo-feed-products.php:1734
1528
- msgid "Height"
1529
  msgstr ""
1530
 
1531
- #: includes/classes/class-woo-feed-dropdown.php:517, includes/classes/class-woo-feed-products.php:1735
1532
- msgid "Length"
1533
  msgstr ""
1534
 
1535
- #: includes/classes/class-woo-feed-dropdown.php:518
1536
- msgid "Shipping (Google Format)"
1537
  msgstr ""
1538
 
1539
- #: includes/classes/class-woo-feed-dropdown.php:519
1540
- msgid "Shipping Cost"
1541
  msgstr ""
1542
 
1543
- #: includes/classes/class-woo-feed-dropdown.php:520, includes/classes/class-woo-feed-products.php:1736
1544
- msgid "Shipping Class"
1545
  msgstr ""
1546
 
1547
- #: includes/classes/class-woo-feed-dropdown.php:521, includes/classes/class-woo-feed-products.php:1737
1548
- msgid "Product Type"
1549
  msgstr ""
1550
 
1551
- #: includes/classes/class-woo-feed-dropdown.php:522, includes/classes/class-woo-feed-products.php:1738
1552
- msgid "Variation Type"
1553
  msgstr ""
1554
 
1555
- #: includes/classes/class-woo-feed-dropdown.php:523, includes/classes/class-woo-feed-products.php:1739
1556
- msgid "Visibility"
1557
  msgstr ""
1558
 
1559
- #: includes/classes/class-woo-feed-dropdown.php:524, includes/classes/class-woo-feed-products.php:1740
1560
- msgid "Total Rating"
1561
  msgstr ""
1562
 
1563
- #: includes/classes/class-woo-feed-dropdown.php:525, includes/classes/class-woo-feed-products.php:1741
1564
- msgid "Average Rating"
1565
  msgstr ""
1566
 
1567
- #: includes/classes/class-woo-feed-dropdown.php:526, includes/classes/class-woo-feed-products.php:1742
1568
- msgid "Tags"
1569
  msgstr ""
1570
 
1571
- #: includes/classes/class-woo-feed-dropdown.php:527, includes/classes/class-woo-feed-products.php:1743
1572
- msgid "Sale Price Effective Date"
1573
  msgstr ""
1574
 
1575
- #: includes/classes/class-woo-feed-dropdown.php:528, includes/classes/class-woo-feed-products.php:1744
1576
- msgid "Is Bundle"
1577
  msgstr ""
1578
 
1579
- #: includes/classes/class-woo-feed-dropdown.php:529, includes/classes/class-woo-feed-products.php:1745
1580
- msgid "Author Name"
1581
  msgstr ""
1582
 
1583
- #: includes/classes/class-woo-feed-dropdown.php:530, includes/classes/class-woo-feed-products.php:1746
1584
- msgid "Author Email"
1585
  msgstr ""
1586
 
1587
- #: includes/classes/class-woo-feed-dropdown.php:531, includes/classes/class-woo-feed-products.php:1747
1588
- msgid "Date Created"
1589
  msgstr ""
1590
 
1591
- #: includes/classes/class-woo-feed-dropdown.php:532, includes/classes/class-woo-feed-products.php:1748
1592
- msgid "Date Updated"
1593
  msgstr ""
1594
 
1595
- #: includes/classes/class-woo-feed-dropdown.php:533
1596
- msgid "Tax"
1597
  msgstr ""
1598
 
1599
- #: includes/classes/class-woo-feed-dropdown.php:534
1600
- msgid "Tax Class"
1601
  msgstr ""
1602
 
1603
- #: includes/classes/class-woo-feed-dropdown.php:535
1604
- msgid "Tax Status"
1605
  msgstr ""
1606
 
1607
- #: includes/classes/class-woo-feed-dropdown.php:544
1608
- msgid "Custom Fields by CTX Feed"
1609
  msgstr ""
1610
 
1611
- #: includes/classes/class-woo-feed-dropdown.php:555
1612
- msgid "Subscription & Installment"
1613
  msgstr ""
1614
 
1615
- #: includes/classes/class-woo-feed-dropdown.php:559
1616
- msgid "Subscription Period"
1617
  msgstr ""
1618
 
1619
- #: includes/classes/class-woo-feed-dropdown.php:560
1620
- msgid "Subscription Period Length"
1621
  msgstr ""
1622
 
1623
- #: includes/classes/class-woo-feed-dropdown.php:561
1624
- msgid "Subscription Amount"
1625
  msgstr ""
1626
 
1627
- #: includes/classes/class-woo-feed-dropdown.php:562
1628
- msgid "Installment Months"
1629
  msgstr ""
1630
 
1631
- #: includes/classes/class-woo-feed-dropdown.php:563
1632
- msgid "Installment Amount"
1633
  msgstr ""
1634
 
1635
- #: includes/classes/class-woo-feed-dropdown.php:590
1636
- msgid "Unit Price"
1637
  msgstr ""
1638
 
1639
- #: includes/classes/class-woo-feed-dropdown.php:577
1640
- msgid "WooCommerce Germanized"
1641
  msgstr ""
1642
 
1643
- #: includes/classes/class-woo-feed-dropdown.php:598
1644
- msgid "ALL IN ONE SEO"
1645
  msgstr ""
1646
 
1647
- #: includes/classes/class-woo-feed-dropdown.php:602, includes/classes/class-woo-feed-products.php:1769
1648
- msgid "Title [All in One SEO]"
1649
  msgstr ""
1650
 
1651
- #: includes/classes/class-woo-feed-dropdown.php:603, includes/classes/class-woo-feed-products.php:1770
1652
- msgid "Description [All in One SEO]"
1653
  msgstr ""
1654
 
1655
- #: includes/classes/class-woo-feed-dropdown.php:604
1656
- msgid "Canonical URL [All in One SEO]"
1657
  msgstr ""
1658
 
1659
- #: includes/classes/class-woo-feed-dropdown.php:612
1660
- msgid "Yoast SEO"
1661
  msgstr ""
1662
 
1663
- #: includes/classes/class-woo-feed-dropdown.php:615, includes/classes/class-woo-feed-products.php:1776
1664
- msgid "Title [Yoast SEO]"
1665
  msgstr ""
1666
 
1667
- #: includes/classes/class-woo-feed-dropdown.php:616, includes/classes/class-woo-feed-products.php:1777
1668
- msgid "Description [Yoast SEO]"
1669
  msgstr ""
1670
 
1671
- #: includes/classes/class-woo-feed-dropdown.php:617
1672
- msgid "Canonical URL [Yoast SEO]"
1673
  msgstr ""
1674
 
1675
- #: includes/classes/class-woo-feed-dropdown.php:623
1676
- msgid "GTIN8 [Yoast SEO]"
1677
  msgstr ""
1678
 
1679
- #: includes/classes/class-woo-feed-dropdown.php:624
1680
- msgid "GTIN12 / UPC [Yoast SEO]"
1681
  msgstr ""
1682
 
1683
- #: includes/classes/class-woo-feed-dropdown.php:625
1684
- msgid "GTIN13 / EAN [Yoast SEO]"
1685
  msgstr ""
1686
 
1687
- #: includes/classes/class-woo-feed-dropdown.php:626
1688
- msgid "GTIN14 / ITF-14 [Yoast SEO]"
1689
  msgstr ""
1690
 
1691
- #: includes/classes/class-woo-feed-dropdown.php:627
1692
- msgid "ISBN [Yoast SEO]"
1693
  msgstr ""
1694
 
1695
- #: includes/classes/class-woo-feed-dropdown.php:628
1696
- msgid "MPN [Yoast SEO]"
1697
  msgstr ""
1698
 
1699
- #: includes/classes/class-woo-feed-dropdown.php:641
1700
- msgid "Rank Math SEO"
1701
  msgstr ""
1702
 
1703
- #: includes/classes/class-woo-feed-dropdown.php:645
1704
- msgid "Title [RankMath SEO]"
1705
  msgstr ""
1706
 
1707
- #: includes/classes/class-woo-feed-dropdown.php:646
1708
- msgid "Description [RankMath SEO]"
1709
  msgstr ""
1710
 
1711
- #: includes/classes/class-woo-feed-dropdown.php:647
1712
- msgid "Canonical URL [RankMath SEO]"
1713
  msgstr ""
1714
 
1715
- #: includes/classes/class-woo-feed-dropdown.php:648
1716
- msgid "GTIN [RankMath Pro SEO]"
1717
  msgstr ""
1718
 
1719
- #: includes/classes/class-woo-feed-dropdown.php:655, includes/classes/class-woo-feed-products.php:1793
1720
- msgid "Image Attributes"
1721
  msgstr ""
1722
 
1723
- #: includes/classes/class-woo-feed-dropdown.php:657, includes/classes/class-woo-feed-products.php:1751
1724
- msgid "Main Image"
1725
  msgstr ""
1726
 
1727
- #: includes/classes/class-woo-feed-dropdown.php:658, includes/classes/class-woo-feed-products.php:1752
1728
- msgid "Featured Image"
1729
  msgstr ""
1730
 
1731
- #: includes/classes/class-woo-feed-dropdown.php:659, includes/classes/class-woo-feed-products.php:1753
1732
- msgid "Images [Comma Separated]"
1733
  msgstr ""
1734
 
1735
- #: includes/classes/class-woo-feed-dropdown.php:660, includes/classes/class-woo-feed-products.php:1754
1736
- msgid "Additional Image 1"
1737
  msgstr ""
1738
 
1739
- #: includes/classes/class-woo-feed-dropdown.php:661, includes/classes/class-woo-feed-products.php:1755
1740
- msgid "Additional Image 2"
1741
  msgstr ""
1742
 
1743
- #: includes/classes/class-woo-feed-dropdown.php:662, includes/classes/class-woo-feed-products.php:1756
1744
- msgid "Additional Image 3"
1745
  msgstr ""
1746
 
1747
- #: includes/classes/class-woo-feed-dropdown.php:663, includes/classes/class-woo-feed-products.php:1757
1748
- msgid "Additional Image 4"
1749
  msgstr ""
1750
 
1751
- #: includes/classes/class-woo-feed-dropdown.php:664, includes/classes/class-woo-feed-products.php:1758
1752
- msgid "Additional Image 5"
1753
  msgstr ""
1754
 
1755
- #: includes/classes/class-woo-feed-dropdown.php:665, includes/classes/class-woo-feed-products.php:1759
1756
- msgid "Additional Image 6"
1757
  msgstr ""
1758
 
1759
- #: includes/classes/class-woo-feed-dropdown.php:666, includes/classes/class-woo-feed-products.php:1760
1760
- msgid "Additional Image 7"
1761
  msgstr ""
1762
 
1763
- #: includes/classes/class-woo-feed-dropdown.php:667, includes/classes/class-woo-feed-products.php:1761
1764
- msgid "Additional Image 8"
1765
  msgstr ""
1766
 
1767
- #: includes/classes/class-woo-feed-dropdown.php:668, includes/classes/class-woo-feed-products.php:1762
1768
- msgid "Additional Image 9"
1769
  msgstr ""
1770
 
1771
- #: includes/classes/class-woo-feed-dropdown.php:669, includes/classes/class-woo-feed-products.php:1763
1772
- msgid "Additional Image 10"
1773
  msgstr ""
1774
 
1775
- #: includes/classes/class-woo-feed-dropdown.php:676
1776
- msgid "Product Attributes"
1777
  msgstr ""
1778
 
1779
- #: includes/classes/class-woo-feed-dropdown.php:684, includes/classes/class-woo-feed-products.php:1813
1780
- msgid "Product Custom Attributes"
1781
  msgstr ""
1782
 
1783
- #: includes/classes/class-woo-feed-dropdown.php:691
1784
- msgid "Product Taxonomies"
1785
  msgstr ""
1786
 
1787
- #: includes/classes/class-woo-feed-dropdown.php:706
1788
- msgid "Category Mappings"
1789
  msgstr ""
1790
 
1791
- #: includes/classes/class-woo-feed-dropdown.php:714
1792
- msgid "Custom Fields & Post Metas"
1793
  msgstr ""
1794
 
1795
- #: includes/classes/class-woo-feed-dropdown.php:757, includes/classes/class-woo-feed-products.php:1803
1796
- msgid "Select Attributes"
1797
  msgstr ""
1798
 
1799
- #: includes/classes/class-woo-feed-list-table.php:182
1800
- msgid "List View"
1801
  msgstr ""
1802
 
1803
- #: includes/classes/class-woo-feed-list-table.php:183
1804
- msgid "Excerpt View"
1805
  msgstr ""
1806
 
1807
- #: includes/classes/class-woo-feed-list-table.php:360
1808
- msgid "No items found."
1809
  msgstr ""
1810
 
1811
- #: includes/classes/class-woo-feed-list-table.php:495
1812
- msgid "Select bulk action"
1813
  msgstr ""
1814
 
1815
- #: includes/classes/class-woo-feed-list-table.php:497
1816
- msgid "Bulk Actions"
1817
  msgstr ""
1818
 
1819
- #: includes/classes/class-woo-feed-list-table.php:506
1820
- msgid "Apply"
1821
  msgstr ""
1822
 
1823
- #: includes/classes/class-woo-feed-list-table.php:560, includes/classes/class-woo-feed-list-table.php:1408
1824
- msgid "Show more details"
1825
  msgstr ""
1826
 
1827
- #: includes/classes/class-woo-feed-list-table.php:629
1828
- msgid "Filter by date"
1829
  msgstr ""
1830
 
1831
- #: includes/classes/class-woo-feed-list-table.php:631
1832
- msgid "All dates"
1833
  msgstr ""
1834
 
1835
- #. translators: 1: month name, 2: 4-digit year
1836
- #: includes/classes/class-woo-feed-list-table.php:646
1837
- msgid "%1$s %2$d"
1838
  msgstr ""
1839
 
1840
- #: includes/classes/class-woo-feed-list-table.php:699
1841
- msgid "%s comment"
1842
- msgid_plural "%s comments"
1843
- msgstr[0] ""
1844
- msgstr[1] ""
1845
 
1846
- #: includes/classes/class-woo-feed-list-table.php:700
1847
- msgid "%s approved comment"
1848
- msgid_plural "%s approved comments"
1849
- msgstr[0] ""
1850
- msgstr[1] ""
1851
 
1852
- #: includes/classes/class-woo-feed-list-table.php:701
1853
- msgid "%s pending comment"
1854
- msgid_plural "%s pending comments"
1855
- msgstr[0] ""
1856
- msgstr[1] ""
1857
 
1858
- #: includes/classes/class-woo-feed-list-table.php:729
1859
- msgid "No approved comments"
1860
  msgstr ""
1861
 
1862
- #: includes/classes/class-woo-feed-list-table.php:729, includes/classes/class-woo-feed-list-table.php:707, includes/classes/class-woo-feed-list-table.php:752
1863
- msgid "No comments"
1864
  msgstr ""
1865
 
1866
- #: includes/classes/class-woo-feed-list-table.php:752
1867
- msgid "No pending comments"
1868
  msgstr ""
1869
 
1870
- #: includes/classes/class-woo-feed-list-table.php:831, includes/classes/class-woo-feed-list-table.php:1433
1871
- msgid "%s item"
1872
- msgid_plural "%s items"
1873
- msgstr[0] ""
1874
- msgstr[1] ""
1875
 
1876
- #: includes/classes/class-woo-feed-list-table.php:867
1877
- msgid "First page"
1878
  msgstr ""
1879
 
1880
- #: includes/classes/class-woo-feed-list-table.php:878
1881
- msgid "Previous page"
1882
  msgstr ""
1883
 
1884
- #: includes/classes/class-woo-feed-list-table.php:889, includes/classes/class-woo-feed-list-table.php:885
1885
- msgid "Current Page"
1886
  msgstr ""
1887
 
1888
- #: includes/classes/class-woo-feed-list-table.php:895
1889
- msgctxt "paging"
1890
- msgid "%1$s of %2$s"
1891
  msgstr ""
1892
 
1893
- #: includes/classes/class-woo-feed-list-table.php:903
1894
- msgid "Next page"
1895
  msgstr ""
1896
 
1897
- #: includes/classes/class-woo-feed-list-table.php:914
1898
- msgid "Last page"
1899
  msgstr ""
1900
 
1901
- #: includes/classes/class-woo-feed-list-table.php:1144
1902
- msgid "Select All"
1903
  msgstr ""
1904
 
1905
- #: includes/classes/class-woo-feed-log-handler-file.php:347, includes/classes/class-woo-feed-log-handler-file.php:367
1906
- msgid "This method should not be called before plugins_loaded."
1907
  msgstr ""
1908
 
1909
- #: includes/classes/class-woo-feed-merchant.php:311
1910
- msgid "Custom Template"
1911
  msgstr ""
1912
 
1913
- #: includes/classes/class-woo-feed-merchant.php:312
1914
- msgid "Custom Template 1"
1915
  msgstr ""
1916
 
1917
- #: includes/classes/class-woo-feed-merchant.php:323
1918
- msgid "Popular Templates"
1919
  msgstr ""
1920
 
1921
- #: includes/classes/class-woo-feed-merchant.php:324
1922
- msgid "Google Shopping"
1923
  msgstr ""
1924
 
1925
- #: includes/classes/class-woo-feed-merchant.php:325
1926
- msgid "Google Local Inventory Ads"
1927
  msgstr ""
1928
 
1929
- #: includes/classes/class-woo-feed-merchant.php:326
1930
- msgid "Google Local Product Inventory"
1931
  msgstr ""
1932
 
1933
- #: includes/classes/class-woo-feed-merchant.php:327
1934
- msgid "Google Product Review"
1935
  msgstr ""
1936
 
1937
- #: includes/classes/class-woo-feed-merchant.php:328
1938
- msgid "Google Shopping Action"
1939
  msgstr ""
1940
 
1941
- #: includes/classes/class-woo-feed-merchant.php:329
1942
- msgid "Google Promotions"
1943
  msgstr ""
1944
 
1945
- #: includes/classes/class-woo-feed-merchant.php:330
1946
- msgid "Google Dynamic Search Ads"
1947
  msgstr ""
1948
 
1949
- #: includes/classes/class-woo-feed-merchant.php:331
1950
- msgid "Google Ads"
1951
  msgstr ""
1952
 
1953
- #: includes/classes/class-woo-feed-merchant.php:332
1954
- msgid "Google Ads Local Product"
1955
  msgstr ""
1956
 
1957
- #: includes/classes/class-woo-feed-merchant.php:333
1958
- msgid "Facebook Catalog / Instagram"
1959
  msgstr ""
1960
 
1961
- #: includes/classes/class-woo-feed-merchant.php:334
1962
- msgid "Pinterest Catalog"
1963
  msgstr ""
1964
 
1965
- #: includes/classes/class-woo-feed-merchant.php:335
1966
- msgid "Pinterest RSS Board"
1967
  msgstr ""
1968
 
1969
- #: includes/classes/class-woo-feed-merchant.php:336
1970
- msgid "Bing Shopping"
1971
  msgstr ""
1972
 
1973
- #: includes/classes/class-woo-feed-merchant.php:337
1974
- msgid "Bing Local Inventory"
1975
  msgstr ""
1976
 
1977
- #: includes/classes/class-woo-feed-merchant.php:338
1978
- msgid "Snapchat"
1979
  msgstr ""
1980
 
1981
- #: includes/classes/class-woo-feed-merchant.php:339
1982
- msgid "TikTok"
1983
  msgstr ""
1984
 
1985
- #: includes/classes/class-woo-feed-merchant.php:340
1986
- msgid "Idealo"
1987
  msgstr ""
1988
 
1989
- #: includes/classes/class-woo-feed-merchant.php:341
1990
- msgid "PriceSpy"
1991
  msgstr ""
1992
 
1993
- #: includes/classes/class-woo-feed-merchant.php:342
1994
- msgid "Price Runner"
1995
  msgstr ""
1996
 
1997
- #: includes/classes/class-woo-feed-merchant.php:343
1998
- msgid "Yandex (CSV)"
1999
  msgstr ""
2000
 
2001
- #: includes/classes/class-woo-feed-merchant.php:344
2002
- msgid "Yandex (XML)"
2003
  msgstr ""
2004
 
2005
- #: includes/classes/class-woo-feed-merchant.php:355
2006
- msgid "Templates"
2007
  msgstr ""
2008
 
2009
- #: includes/classes/class-woo-feed-merchant.php:356
2010
- msgid "AdForm"
2011
  msgstr ""
2012
 
2013
- #: includes/classes/class-woo-feed-merchant.php:357
2014
- msgid "AdRoll"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2015
  msgstr ""
2016
 
2017
- #: includes/classes/class-woo-feed-merchant.php:358
2018
- msgid "Avantlink"
2019
  msgstr ""
2020
 
2021
- #: includes/classes/class-woo-feed-merchant.php:359
2022
- msgid "Become"
2023
  msgstr ""
2024
 
2025
- #: includes/classes/class-woo-feed-merchant.php:360
2026
- msgid "Beslist.nl"
2027
  msgstr ""
2028
 
2029
- #: includes/classes/class-woo-feed-merchant.php:361
2030
- msgid "Bestprice"
2031
  msgstr ""
2032
 
2033
- #: includes/classes/class-woo-feed-merchant.php:362
2034
- msgid "Billiger.de"
2035
  msgstr ""
2036
 
2037
- #: includes/classes/class-woo-feed-merchant.php:363
2038
- msgid "Bol.com"
2039
  msgstr ""
2040
 
2041
- #: includes/classes/class-woo-feed-merchant.php:364
2042
- msgid "Bonanza"
2043
  msgstr ""
2044
 
2045
- #: includes/classes/class-woo-feed-merchant.php:365
2046
- msgid "Catch.com.au"
2047
  msgstr ""
2048
 
2049
- #: includes/classes/class-woo-feed-merchant.php:366
2050
- msgid "CDiscount.fr"
2051
  msgstr ""
2052
 
2053
- #: includes/classes/class-woo-feed-merchant.php:367
2054
- msgid "Comparer.be"
2055
  msgstr ""
2056
 
2057
- #: includes/classes/class-woo-feed-merchant.php:368
2058
- msgid "Connexity"
2059
  msgstr ""
2060
 
2061
- #: includes/classes/class-woo-feed-merchant.php:369
2062
- msgid "Criteo"
2063
  msgstr ""
2064
 
2065
- #: includes/classes/class-woo-feed-merchant.php:370
2066
- msgid "Crowdfox"
2067
  msgstr ""
2068
 
2069
- #: includes/classes/class-woo-feed-merchant.php:371
2070
- msgid "Daisycon Advertiser (General)"
2071
  msgstr ""
2072
 
2073
- #: includes/classes/class-woo-feed-merchant.php:372
2074
- msgid "Daisycon Advertiser (Automotive)"
2075
  msgstr ""
2076
 
2077
- #: includes/classes/class-woo-feed-merchant.php:373
2078
- msgid "Daisycon Advertiser (Books)"
2079
  msgstr ""
2080
 
2081
- #: includes/classes/class-woo-feed-merchant.php:374
2082
- msgid "Daisycon Advertiser (Cosmetics)"
2083
  msgstr ""
2084
 
2085
- #: includes/classes/class-woo-feed-merchant.php:375
2086
- msgid "Daisycon Advertiser (Daily Offers)"
2087
  msgstr ""
2088
 
2089
- #: includes/classes/class-woo-feed-merchant.php:376
2090
- msgid "Daisycon Advertiser (Electronics)"
2091
  msgstr ""
2092
 
2093
- #: includes/classes/class-woo-feed-merchant.php:377
2094
- msgid "Daisycon Advertiser (Fashion)"
2095
  msgstr ""
2096
 
2097
- #: includes/classes/class-woo-feed-merchant.php:378
2098
- msgid "Daisycon Advertiser (Food & Drinks)"
2099
  msgstr ""
2100
 
2101
- #: includes/classes/class-woo-feed-merchant.php:379
2102
- msgid "Daisycon Advertiser (Holidays: Accommodations and transport)"
2103
  msgstr ""
2104
 
2105
- #: includes/classes/class-woo-feed-merchant.php:380
2106
- msgid "Daisycon Advertiser (Holidays: Accommodations)"
2107
  msgstr ""
2108
 
2109
- #: includes/classes/class-woo-feed-merchant.php:381
2110
- msgid "Daisycon Advertiser (Holidays: Trips)"
2111
  msgstr ""
2112
 
2113
- #: includes/classes/class-woo-feed-merchant.php:382
2114
- msgid "Daisycon Advertiser (Home & Garden)"
2115
  msgstr ""
2116
 
2117
- #: includes/classes/class-woo-feed-merchant.php:383
2118
- msgid "Daisycon Advertiser (Housing)"
2119
  msgstr ""
2120
 
2121
- #: includes/classes/class-woo-feed-merchant.php:384
2122
- msgid "Daisycon Advertiser (Magazines)"
2123
  msgstr ""
2124
 
2125
- #: includes/classes/class-woo-feed-merchant.php:385
2126
- msgid "Daisycon Advertiser (Studies & Trainings)"
2127
  msgstr ""
2128
 
2129
- #: includes/classes/class-woo-feed-merchant.php:386
2130
- msgid "Daisycon Advertiser (Telecom: Accessories)"
2131
  msgstr ""
2132
 
2133
- #: includes/classes/class-woo-feed-merchant.php:387
2134
- msgid "Daisycon Advertiser (Telecom: All-in-one)"
2135
  msgstr ""
2136
 
2137
- #: includes/classes/class-woo-feed-merchant.php:388
2138
- msgid "Daisycon Advertiser (Telecom: GSM + Subscription)"
2139
  msgstr ""
2140
 
2141
- #: includes/classes/class-woo-feed-merchant.php:389
2142
- msgid "Daisycon Advertiser (Telecom: GSM only)"
2143
  msgstr ""
2144
 
2145
- #: includes/classes/class-woo-feed-merchant.php:390
2146
- msgid "Daisycon Advertiser (Telecom: Sim only)"
2147
  msgstr ""
2148
 
2149
- #: includes/classes/class-woo-feed-merchant.php:391
2150
- msgid "Daisycon Advertiser (Work & Jobs)"
2151
  msgstr ""
2152
 
2153
- #: includes/classes/class-woo-feed-merchant.php:392
2154
- msgid "Dooyoo"
2155
  msgstr ""
2156
 
2157
- #: includes/classes/class-woo-feed-merchant.php:393
2158
- msgid "Ecommerce.it"
2159
  msgstr ""
2160
 
2161
- #: includes/classes/class-woo-feed-merchant.php:394
2162
- msgid "Etsy"
2163
  msgstr ""
2164
 
2165
- #: includes/classes/class-woo-feed-merchant.php:395
2166
- msgid "Fruugo"
2167
  msgstr ""
2168
 
2169
- #: includes/classes/class-woo-feed-merchant.php:396
2170
- msgid "Fashionchick.nl"
2171
  msgstr ""
2172
 
2173
- #: includes/classes/class-woo-feed-merchant.php:397
2174
- msgid "Fruugoaustralia.com"
2175
  msgstr ""
2176
 
2177
- #: includes/classes/class-woo-feed-merchant.php:398
2178
- msgid "Fyndiq.se"
2179
  msgstr ""
2180
 
2181
- #: includes/classes/class-woo-feed-merchant.php:399
2182
- msgid "GoedGeplaatst.nl"
2183
  msgstr ""
2184
 
2185
- #: includes/classes/class-woo-feed-merchant.php:400
2186
- msgid "Heureka.sk"
2187
  msgstr ""
2188
 
2189
- #: includes/classes/class-woo-feed-merchant.php:401
2190
- msgid "Hintaseuranta.fi"
2191
  msgstr ""
2192
 
2193
- #: includes/classes/class-woo-feed-merchant.php:402
2194
- msgid "Incurvy"
2195
  msgstr ""
2196
 
2197
- #: includes/classes/class-woo-feed-merchant.php:403
2198
- msgid "Jet.com"
2199
  msgstr ""
2200
 
2201
- #: includes/classes/class-woo-feed-merchant.php:404
2202
- msgid "Kelkoo"
2203
  msgstr ""
2204
 
2205
- #: includes/classes/class-woo-feed-merchant.php:405
2206
- msgid "Kieskeurig.nl"
2207
  msgstr ""
2208
 
2209
- #: includes/classes/class-woo-feed-merchant.php:406
2210
- msgid "Kijiji.ca"
2211
  msgstr ""
2212
 
2213
- #: includes/classes/class-woo-feed-merchant.php:407
2214
- msgid "LeGuide"
2215
  msgstr ""
2216
 
2217
- #: includes/classes/class-woo-feed-merchant.php:408
2218
- msgid "Marktplaats.nl"
2219
  msgstr ""
2220
 
2221
- #: includes/classes/class-woo-feed-merchant.php:409
2222
- msgid "Miinto.de"
2223
  msgstr ""
2224
 
2225
- #: includes/classes/class-woo-feed-merchant.php:410
2226
- msgid "Miinto.nl"
2227
  msgstr ""
2228
 
2229
- #: includes/classes/class-woo-feed-merchant.php:411
2230
- msgid "Modalova"
2231
  msgstr ""
2232
 
2233
- #: includes/classes/class-woo-feed-merchant.php:412
2234
- msgid "Modina.de"
2235
  msgstr ""
2236
 
2237
- #: includes/classes/class-woo-feed-merchant.php:413
2238
- msgid "Moebel.de"
2239
  msgstr ""
2240
 
2241
- #: includes/classes/class-woo-feed-merchant.php:414
2242
- msgid "Myshopping.com.au"
2243
  msgstr ""
2244
 
2245
- #: includes/classes/class-woo-feed-merchant.php:415
2246
- msgid "TheNextAd"
2247
  msgstr ""
2248
 
2249
- #: includes/classes/class-woo-feed-merchant.php:416
2250
- msgid "Nextag"
2251
  msgstr ""
2252
 
2253
- #: includes/classes/class-woo-feed-merchant.php:417
2254
- msgid "Polyvore"
2255
  msgstr ""
2256
 
2257
- #: includes/classes/class-woo-feed-merchant.php:418
2258
- msgid "Price Grabber"
2259
  msgstr ""
2260
 
2261
- #: includes/classes/class-woo-feed-merchant.php:419
2262
- msgid "Prisjakt"
2263
  msgstr ""
2264
 
2265
- #: includes/classes/class-woo-feed-merchant.php:420
2266
- msgid "Profit Share"
2267
  msgstr ""
2268
 
2269
- #: includes/classes/class-woo-feed-merchant.php:421
2270
- msgid "Rakuten.de"
2271
  msgstr ""
2272
 
2273
- #: includes/classes/class-woo-feed-merchant.php:422
2274
- msgid "Real"
2275
  msgstr ""
2276
 
2277
- #: includes/classes/class-woo-feed-merchant.php:423
2278
- msgid "ShareASale"
2279
  msgstr ""
2280
 
2281
- #: includes/classes/class-woo-feed-merchant.php:424
2282
- msgid "Shopalike.fr"
2283
  msgstr ""
2284
 
2285
- #: includes/classes/class-woo-feed-merchant.php:425
2286
- msgid "Shopbot"
2287
  msgstr ""
2288
 
2289
- #: includes/classes/class-woo-feed-merchant.php:426
2290
- msgid "Shopmania"
2291
  msgstr ""
2292
 
2293
- #: includes/classes/class-woo-feed-merchant.php:427
2294
- msgid "Shopping.com"
2295
  msgstr ""
2296
 
2297
- #: includes/classes/class-woo-feed-merchant.php:428
2298
- msgid "Shopzilla"
2299
  msgstr ""
2300
 
2301
- #: includes/classes/class-woo-feed-merchant.php:429
2302
- msgid "SkinFlint.co.uk"
2303
  msgstr ""
2304
 
2305
- #: includes/classes/class-woo-feed-merchant.php:430
2306
- msgid "Skroutz.gr"
2307
  msgstr ""
2308
 
2309
- #: includes/classes/class-woo-feed-merchant.php:431
2310
- msgid "Smartly.io"
2311
  msgstr ""
2312
 
2313
- #: includes/classes/class-woo-feed-merchant.php:432
2314
- msgid "Spartoo.fi"
2315
  msgstr ""
2316
 
2317
- #: includes/classes/class-woo-feed-merchant.php:433
2318
- msgid "Shopee"
2319
  msgstr ""
2320
 
2321
- #: includes/classes/class-woo-feed-merchant.php:434
2322
- msgid "Stylight.com"
2323
  msgstr ""
2324
 
2325
- #: includes/classes/class-woo-feed-merchant.php:435
2326
- msgid "Trovaprezzi.it"
2327
  msgstr ""
2328
 
2329
- #: includes/classes/class-woo-feed-merchant.php:436
2330
- msgid "Twenga"
2331
  msgstr ""
2332
 
2333
- #: includes/classes/class-woo-feed-merchant.php:437
2334
- msgid "Tweakers (XML)"
2335
  msgstr ""
2336
 
2337
- #: includes/classes/class-woo-feed-merchant.php:438
2338
- msgid "Tweakers (CSV)"
2339
  msgstr ""
2340
 
2341
- #: includes/classes/class-woo-feed-merchant.php:439
2342
- msgid "Vertaa.fi"
2343
  msgstr ""
2344
 
2345
- #: includes/classes/class-woo-feed-merchant.php:440
2346
- msgid "Walmart"
2347
  msgstr ""
2348
 
2349
- #: includes/classes/class-woo-feed-merchant.php:441
2350
- msgid "Webmarchand"
2351
  msgstr ""
2352
 
2353
- #: includes/classes/class-woo-feed-merchant.php:442
2354
- msgid "Wine Searcher"
2355
  msgstr ""
2356
 
2357
- #: includes/classes/class-woo-feed-merchant.php:443
2358
- msgid "Wish.com"
2359
  msgstr ""
2360
 
2361
- #: includes/classes/class-woo-feed-merchant.php:444
2362
- msgid "Yahoo NFA"
2363
  msgstr ""
2364
 
2365
- #: includes/classes/class-woo-feed-merchant.php:445
2366
- msgid "Zap.co.il"
2367
  msgstr ""
2368
 
2369
- #: includes/classes/class-woo-feed-merchant.php:446
2370
- msgid "Zbozi.cz"
2371
  msgstr ""
2372
 
2373
- #: includes/classes/class-woo-feed-merchant.php:447
2374
- msgid "Zalando"
2375
  msgstr ""
2376
 
2377
- #: includes/classes/class-woo-feed-merchant.php:448
2378
- msgid "Admarkt(marktplaats)"
2379
  msgstr ""
2380
 
2381
- #: includes/classes/class-woo-feed-merchant.php:449
2382
- msgid "GLAMI"
2383
  msgstr ""
2384
 
2385
  #: includes/classes/class-woo-feed-products.php:1715
@@ -2390,6 +2486,14 @@ msgstr ""
2390
  msgid "Condition"
2391
  msgstr ""
2392
 
 
 
 
 
 
 
 
 
2393
  #: includes/classes/class-woo-feed-products.php:1821
2394
  msgid "Custom Fields/Post Meta"
2395
  msgstr ""
@@ -2511,6 +2615,10 @@ msgstr ""
2511
  msgid "WooCommerce Dynamic Pricing & Discounts"
2512
  msgstr ""
2513
 
 
 
 
 
2514
  #: libs/WebAppick/AppServices/Insights.php:332
2515
  msgid "Server environment details (php, mysql, server, WordPress versions)."
2516
  msgstr ""
12
  "X-Poedit-KeywordsList: __;_e;_ex:1,2c;_n:1,2;_n_noop:1,2;_nx:1,2,4c;_nx_noop:1,2,3c;_x:1,2c;esc_attr__;esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c\n"
13
  "Plural-Forms: nplurals=2; plural=(n != 1);\n"
14
 
15
+ #: woo-feed.php:141, woo-feed.php:262, woo-feed.php:337, woo-feed.php:706, woo-feed.php:746, woo-feed.php:766, woo-feed.php:786, woo-feed.php:812
16
  msgid "Unauthorized Action."
17
  msgstr ""
18
 
19
+ #: woo-feed.php:146, woo-feed.php:266, includes/helper.php:863, includes/helper.php:1885, includes/helper.php:2940, includes/helper.php:2968, includes/helper.php:3374, includes/helper.php:3567, includes/helper.php:3594, includes/helper.php:4831, includes/helper.php:5333, includes/classes/class-woo-feed-webappick-api.php:468
20
  msgid "Invalid Request."
21
  msgstr ""
22
 
23
+ #: woo-feed.php:242, woo-feed.php:206
24
  msgid "No products found. Add product or change feed config before generate the feed."
25
  msgstr ""
26
 
27
+ #: woo-feed.php:220
28
  msgid "Failed to fetch products."
29
  msgstr ""
30
 
31
+ #: woo-feed.php:341
32
  msgid "Invalid Feed."
33
  msgstr ""
34
 
35
+ #: woo-feed.php:425
36
  msgid "No Product Found with your feed configuration. Please Update And Generate the feed again."
37
  msgstr ""
38
 
39
+ #: woo-feed.php:420
40
  msgid "Products not found with your filtering condition."
41
  msgstr ""
42
 
43
+ #: woo-feed.php:473
44
  msgid "Failed to save feed file. Please confirm that your WordPress directory have read and write permission."
45
  msgstr ""
46
 
47
+ #: woo-feed.php:465
48
  msgid "Feed Making Complete"
49
  msgstr ""
50
 
51
+ #: woo-feed.php:550, woo-feed.php:600
52
  msgid "Failed security check"
53
  msgstr ""
54
 
55
+ #: woo-feed.php:554, woo-feed.php:604
56
  msgid "Invalid Feed Type!"
57
  msgstr ""
58
 
59
+ #: woo-feed.php:659
60
  msgid "Feed Does not Exists."
61
  msgstr ""
62
 
63
+ #: woo-feed.php:712
64
  msgid "Invalid Merchant"
65
  msgstr ""
66
 
67
+ #: admin/class-woo-feed-admin.php:181, includes/helper.php:828, includes/helper.php:940, includes/helper.php:921, includes/helper.php:909, includes/helper.php:897
68
  msgid "N/A"
69
  msgstr ""
70
 
71
+ #: admin/class-woo-feed-admin.php:182
72
  msgid "Generating..."
73
  msgstr ""
74
 
75
+ #: admin/class-woo-feed-admin.php:183
76
  msgid "Learn More.."
77
  msgstr ""
78
 
79
+ #: admin/class-woo-feed-admin.php:185, includes/helper.php:3294, admin/partials/woo-feed-edit-config.php:66
80
  msgid "Select A Category"
81
  msgstr ""
82
 
83
+ #: admin/class-woo-feed-admin.php:186
84
  msgid "Loading Template..."
85
  msgstr ""
86
 
87
+ #: admin/class-woo-feed-admin.php:187
88
  msgid "Delivering Configuration..."
89
  msgstr ""
90
 
91
+ #: admin/class-woo-feed-admin.php:188
92
  msgid "Saving Configuration..."
93
  msgstr ""
94
 
95
+ #: admin/class-woo-feed-admin.php:189
96
  msgid "Wait! Checking Extensions ..."
97
  msgstr ""
98
 
99
+ #: admin/class-woo-feed-admin.php:190
100
  msgid "Warning! Enable PHP ssh2 extension to use SFTP. Contact your server administrator."
101
  msgstr ""
102
 
103
+ #: admin/class-woo-feed-admin.php:191
104
  msgid "SFTP Available!"
105
  msgstr ""
106
 
107
+ #: admin/class-woo-feed-admin.php:192
108
  msgid "Please add one or more items to continue."
109
  msgstr ""
110
 
111
+ #: admin/class-woo-feed-admin.php:194
112
  msgid "Are you sure you want to delete this item?"
113
  msgstr ""
114
 
115
+ #: admin/class-woo-feed-admin.php:195
116
  msgid "Are you sure you want to delete selected items?"
117
  msgstr ""
118
 
119
+ #: admin/class-woo-feed-admin.php:206
120
  msgid "There was an error processing ajax request."
121
  msgstr ""
122
 
123
+ #: admin/class-woo-feed-admin.php:249
124
  msgid "Get Pro"
125
  msgstr ""
126
 
127
+ #: admin/class-woo-feed-admin.php:251, admin/class-woo-feed-admin.php:282
128
  msgid "Docs"
129
  msgstr ""
130
 
131
+ #: admin/class-woo-feed-admin.php:253, admin/class-woo-feed-admin.php:280, admin/class-woo-feed-admin.php:280, admin/partials/woo-feed-settings.php:17
132
  msgid "Settings"
133
  msgstr ""
134
 
135
+ #: admin/class-woo-feed-admin.php:275, admin/class-woo-feed-admin.php:275, includes/classes/class-woo-feed-admin-message.php:121, includes/classes/class-woo-feed-webappick-api.php:300
136
  msgid "CTX Feed"
137
  msgstr ""
138
 
139
+ #: admin/class-woo-feed-admin.php:276, admin/class-woo-feed-admin.php:276
140
  msgid "Manage Feeds"
141
  msgstr ""
142
 
143
+ #: admin/class-woo-feed-admin.php:277, admin/class-woo-feed-admin.php:277
144
  msgid "Make Feed"
145
  msgstr ""
146
 
147
+ #: admin/class-woo-feed-admin.php:278, admin/class-woo-feed-admin.php:278, admin/partials/woo-feed-category-mapping.php:27, includes/classes/class-woo-feed-product-attributes.php:576
148
  msgid "Category Mapping"
149
  msgstr ""
150
 
151
+ #: admin/class-woo-feed-admin.php:279, admin/class-woo-feed-admin.php:279
152
  msgid "WP Options"
153
  msgstr ""
154
 
155
+ #: admin/class-woo-feed-admin.php:281, admin/class-woo-feed-admin.php:281
156
  msgid "Status"
157
  msgstr ""
158
 
159
+ #: admin/class-woo-feed-admin.php:282, includes/classes/class-woo-feed-admin-message.php:129, includes/classes/class-woo-feed-webappick-api.php:186
160
  msgid "Documentation"
161
  msgstr ""
162
 
168
  msgid "mappings"
169
  msgstr ""
170
 
171
+ #: admin/class-woo-feed-category-list.php:81, admin/class-woo-feed-category-list.php:122, admin/class-woo-feed-category-list.php:217, admin/class-woo-feed-manage-list.php:162, admin/class-woo-feed-manage-list.php:270, includes/helper.php:3646
172
  msgid "Edit"
173
  msgstr ""
174
 
192
  msgid "Action"
193
  msgstr ""
194
 
195
+ #: admin/class-woo-feed-category-list.php:326
196
  msgid "Failed To Delete Mapping"
197
  msgstr ""
198
 
199
+ #: admin/class-woo-feed-category-list.php:322
200
  msgid "Mapping Deleted Successfully"
201
  msgstr ""
202
 
203
+ #: admin/class-woo-feed-category-list.php:316, admin/class-woo-feed-category-list.php:350
204
  msgid "Failed To Delete Mapping. You do not have sufficient permission to delete."
205
  msgstr ""
206
 
207
+ #: admin/class-woo-feed-category-list.php:336, admin/class-woo-feed-manage-list.php:426, admin/class-woo-feed-manage-list.php:441, admin/class-woo-feed-option-list.php:337
208
  msgid "You do not have sufficient permission to delete!"
209
  msgstr ""
210
 
211
  #. translators: 1: number of item deleted.
212
+ #: admin/class-woo-feed-category-list.php:364
213
  msgid "%d Mapping Successfully Deleted."
214
  msgid_plural "%d Mappings Successfully Deleted."
215
  msgstr[0] ""
227
  msgid "Copy To Clipboard"
228
  msgstr ""
229
 
230
+ #: admin/class-woo-feed-manage-list.php:116, includes/helper.php:962
231
  msgid "View"
232
  msgstr ""
233
 
279
  msgid "Last Updated"
280
  msgstr ""
281
 
282
+ #: admin/class-woo-feed-manage-list.php:394
283
  msgid "Failed To Delete Feed"
284
  msgstr ""
285
 
286
+ #: admin/class-woo-feed-manage-list.php:390
287
  msgid "Feed Deleted Successfully"
288
  msgstr ""
289
 
291
  msgid "Failed To Delete Feed. You do not have sufficient permission to delete."
292
  msgstr ""
293
 
294
+ #: admin/class-woo-feed-manage-list.php:414
295
  msgid "Feed Successfully Duplicated."
296
  msgstr ""
297
 
298
+ #: admin/class-woo-feed-manage-list.php:404
299
  msgid "Failed To Duplicate Feed. You do not have sufficient permission to duplicate."
300
  msgstr ""
301
 
302
  #. translators: %d: number of item deleted.
303
+ #: admin/class-woo-feed-manage-list.php:454
304
  msgid "%d Feed Successfully Deleted."
305
  msgid_plural "%d Feeds Successfully Deleted."
306
  msgstr[0] ""
326
  msgid "Option Value"
327
  msgstr ""
328
 
329
+ #: admin/class-woo-feed-option-list.php:326
330
  msgid "Failed To Delete Option."
331
  msgstr ""
332
 
333
+ #: admin/class-woo-feed-option-list.php:322
334
  msgid "Option Deleted Successfully."
335
  msgstr ""
336
 
337
+ #: admin/class-woo-feed-option-list.php:316, admin/class-woo-feed-option-list.php:355
338
  msgid "Failed To Delete Option. You do not have sufficient permission to delete."
339
  msgstr ""
340
 
341
  #. translators: 1: number of item deleted.
342
+ #: admin/class-woo-feed-option-list.php:370
343
  msgid "%d Option Successfully Deleted."
344
  msgid_plural "%d Options Successfully Deleted."
345
  msgstr[0] ""
401
  msgid "%1$s requires %2$s version %3$s or above and %4$s found. Please upgrade %2$s to the latest version here %5$s"
402
  msgstr ""
403
 
404
+ #: includes/helper.php:293
405
  msgid "Generating Product Feed"
406
  msgstr ""
407
 
408
+ #: includes/helper.php:391
409
  msgid "WC_Product_Query"
410
  msgstr ""
411
 
412
+ #: includes/helper.php:392
413
  msgid "WP_Query"
414
  msgstr ""
415
 
416
+ #: includes/helper.php:393
417
  msgid "Both"
418
  msgstr ""
419
 
420
+ #: includes/helper.php:386
421
  msgid "Individual"
422
  msgstr ""
423
 
424
+ #: includes/helper.php:387
425
  msgid "Variable Dependable"
426
  msgstr ""
427
 
428
+ #: includes/helper.php:407
429
  msgid "No Expiration "
430
  msgstr ""
431
 
432
+ #: includes/helper.php:408
433
  msgid "1 Month"
434
  msgstr ""
435
 
436
+ #: includes/helper.php:409, includes/helper.php:2049
437
  msgid "1 Week"
438
  msgstr ""
439
 
440
+ #: includes/helper.php:410, includes/helper.php:2050
441
  msgid "24 Hours"
442
  msgstr ""
443
 
444
+ #: includes/helper.php:411, includes/helper.php:2051
445
  msgid "12 Hours"
446
  msgstr ""
447
 
448
+ #: includes/helper.php:412, includes/helper.php:2052
449
  msgid "6 Hours"
450
  msgstr ""
451
 
452
+ #: includes/helper.php:413, includes/helper.php:2053
453
  msgid "1 Hours"
454
  msgstr ""
455
 
456
+ #: includes/helper.php:839
457
  msgid "Watch Now"
458
  msgstr ""
459
 
460
+ #: includes/helper.php:834, includes/helper.php:900
461
  msgid "Read Article"
462
  msgstr ""
463
 
464
+ #: includes/helper.php:936
465
  msgid "Support Docs:"
466
  msgstr ""
467
 
468
+ #: includes/helper.php:917
469
  msgid "Supported File Types:"
470
  msgstr ""
471
 
472
+ #: includes/helper.php:905
473
  msgid "Video Documentation:"
474
  msgstr ""
475
 
476
+ #: includes/helper.php:912
477
  msgid "Watch now"
478
  msgstr ""
479
 
480
+ #: includes/helper.php:893
481
  msgid "Feed Specification:"
482
  msgstr ""
483
 
484
+ #: includes/helper.php:963
485
  msgid "Open Feed File"
486
  msgstr ""
487
 
488
+ #: includes/helper.php:1739, includes/helper.php:1740, includes/helper.php:1710, includes/helper.php:1710, includes/helper.php:1886, includes/helper.php:1948, includes/helper.php:1949, includes/helper.php:1924, includes/helper.php:1924, libs/WebAppick/AppServices/Insights.php:813, libs/WebAppick/AppServices/Promotions.php:362
489
  msgid "Invalid Request"
490
  msgstr ""
491
 
492
+ #: includes/helper.php:1771
493
  msgid "Empty File Uploaded. Try again."
494
  msgstr ""
495
 
496
+ #: includes/helper.php:1772
497
  msgid "Empty File"
498
  msgstr ""
499
 
500
+ #: includes/helper.php:1775, includes/helper.php:1786, includes/helper.php:1798, includes/helper.php:1809, includes/helper.php:1823, includes/helper.php:1833, includes/helper.php:1845, includes/helper.php:1889
501
  msgid "&laquo; Back"
502
  msgstr ""
503
 
504
+ #: includes/helper.php:1782
505
  msgid "Unable to read file content"
506
  msgstr ""
507
 
508
+ #: includes/helper.php:1783, includes/helper.php:1795, includes/helper.php:1806, includes/helper.php:1820, includes/helper.php:1830, includes/helper.php:1842
509
  msgid "Invalid File"
510
  msgstr ""
511
 
512
+ #: includes/helper.php:1794
513
  msgid "Unable to read data from file."
514
  msgstr ""
515
 
516
+ #: includes/helper.php:1805
517
  msgid "Unable to read file info."
518
  msgstr ""
519
 
520
+ #: includes/helper.php:1819
521
  msgid "Unable to read feed data from file."
522
  msgstr ""
523
 
524
+ #: includes/helper.php:1829
525
  msgid "Unable to verify the file."
526
  msgstr ""
527
 
528
+ #: includes/helper.php:1841
529
  msgid "Invalid or corrupted config file."
530
  msgstr ""
531
 
532
+ #: includes/helper.php:1861
533
  msgid " Imported"
534
  msgstr ""
535
 
536
+ #: includes/helper.php:2904
537
  msgid "Brand"
538
  msgstr ""
539
 
540
+ #: includes/helper.php:2905, includes/classes/class-woo-feed-product-attributes.php:321
541
  msgid "GTIN"
542
  msgstr ""
543
 
544
+ #: includes/helper.php:2906, includes/classes/class-woo-feed-product-attributes.php:322
545
  msgid "MPN"
546
  msgstr ""
547
 
548
+ #: includes/helper.php:2907
549
  msgid "EAN"
550
  msgstr ""
551
 
552
+ #: includes/helper.php:2908
553
  msgid "ISBN"
554
  msgstr ""
555
 
556
+ #: includes/helper.php:2909
557
  msgid "Age group"
558
  msgstr ""
559
 
560
+ #: includes/helper.php:2910
561
  msgid "Gender"
562
  msgstr ""
563
 
564
+ #: includes/helper.php:2911
565
  msgid "Material"
566
  msgstr ""
567
 
568
+ #: includes/helper.php:2912
569
  msgid "Cost of good sold"
570
  msgstr ""
571
 
572
+ #: includes/helper.php:2913, includes/classes/class-woo-feed-product-attributes.php:124, libs/WebAppick/Attributes/AvailabilityDate.php:47, libs/WebAppick/Attributes/AvailabilityDate.php:77
573
  msgid "Availability Date"
574
  msgstr ""
575
 
576
+ #: includes/helper.php:2914, includes/classes/class-woo-feed-product-attributes.php:305
577
  msgid "Unit"
578
  msgstr ""
579
 
580
+ #: includes/helper.php:2915, includes/classes/class-woo-feed-product-attributes.php:306, includes/classes/class-woo-feed-product-attributes.php:319
581
  msgid "Unit Price Measure"
582
  msgstr ""
583
 
584
+ #: includes/helper.php:2916, includes/classes/class-woo-feed-product-attributes.php:307, includes/classes/class-woo-feed-product-attributes.php:320
585
  msgid "Unit Price Base Measure"
586
  msgstr ""
587
 
588
+ #: includes/helper.php:2917
589
  msgid "Custom field 0"
590
  msgstr ""
591
 
592
+ #: includes/helper.php:2918
593
  msgid "Custom field 1"
594
  msgstr ""
595
 
596
+ #: includes/helper.php:2919
597
  msgid "Custom field 2"
598
  msgstr ""
599
 
600
+ #: includes/helper.php:2920
601
  msgid "Custom field 3"
602
  msgstr ""
603
 
604
+ #: includes/helper.php:2921
605
  msgid "Custom field 4"
606
  msgstr ""
607
 
608
+ #: includes/helper.php:2988, includes/helper.php:3092
609
  msgid "CUSTOM FIELDS by CTX Feed"
610
  msgstr ""
611
 
612
+ #: includes/helper.php:3005
613
  msgid "Set product "
614
  msgstr ""
615
 
616
+ #: includes/helper.php:3005
617
  msgid " here."
618
  msgstr ""
619
 
620
+ #: includes/helper.php:3202
621
  msgid "Another category mapping exists with the same name."
622
  msgstr ""
623
 
624
+ #: includes/helper.php:3211
625
  msgid "Failed To Add Mapping"
626
  msgstr ""
627
 
628
+ #: includes/helper.php:3207
629
  msgid "Mapping Added Successfully"
630
  msgstr ""
631
 
632
+ #: includes/helper.php:3176
633
  msgid "Mapping Not Changed"
634
  msgstr ""
635
 
636
+ #: includes/helper.php:3186
637
  msgid "Failed To Updated Mapping"
638
  msgstr ""
639
 
640
+ #: includes/helper.php:3182
641
  msgid "Mapping Updated Successfully"
642
  msgstr ""
643
 
644
+ #: includes/helper.php:3314
645
  msgid "Copy this category to subcategories"
646
  msgstr ""
647
 
648
+ #: includes/helper.php:3344
649
  msgid "Clear Cache"
650
  msgstr ""
651
 
652
+ #: includes/helper.php:3563, includes/helper.php:3591
653
  msgid "Something is wrong."
654
  msgstr ""
655
 
656
+ #: includes/helper.php:3561
657
  msgid "User meta updated successfully."
658
  msgstr ""
659
 
660
+ #: includes/helper.php:3638, includes/helper.php:3640
661
  msgid "by CTX Feed"
662
  msgstr ""
663
 
664
+ #: includes/helper.php:3641
665
  msgid "All"
666
  msgstr ""
667
 
668
+ #: includes/helper.php:3642
669
  msgid "Parent"
670
  msgstr ""
671
 
672
+ #: includes/helper.php:3643
673
  msgid "Parent:"
674
  msgstr ""
675
 
676
+ #: includes/helper.php:3644
677
  msgid "New"
678
  msgstr ""
679
 
680
+ #: includes/helper.php:3644, libs/WebAppick/AppServices/Insights.php:977
681
  msgid "Name"
682
  msgstr ""
683
 
684
+ #: includes/helper.php:3645
685
  msgid "Add New"
686
  msgstr ""
687
 
688
+ #: includes/helper.php:3647
689
  msgid "Update"
690
  msgstr ""
691
 
692
+ #: includes/helper.php:3648
693
  msgid "Separate"
694
  msgstr ""
695
 
696
+ #: includes/helper.php:3648
697
  msgid "with commas"
698
  msgstr ""
699
 
700
+ #: includes/helper.php:3649
701
  msgid "Search"
702
  msgstr ""
703
 
704
+ #: includes/helper.php:3650
705
  msgid "Add or remove"
706
  msgstr ""
707
 
708
+ #: includes/helper.php:3651
709
  msgid "Choose from the most used"
710
  msgstr ""
711
 
712
+ #: includes/helper.php:4530
713
  msgid "Option Successfully Added."
714
  msgstr ""
715
 
716
+ #: includes/helper.php:4521
717
  msgid "Option Already Added."
718
  msgstr ""
719
 
720
+ #: includes/helper.php:5239
721
  msgid "Delivery up to 30 days"
722
  msgstr ""
723
 
724
+ #: includes/helper.php:5237
725
  msgid "Delivery 1 to 3 days"
726
  msgstr ""
727
 
728
+ #: includes/helper.php:5341
729
  msgid "Feed data is empty. Can't duplicate feed."
730
  msgstr ""
731
 
732
+ #: includes/helper.php:5357
733
  msgid "Unable to save the duplicate feed data."
734
  msgstr ""
735
 
736
+ #: includes/helper.php:5367
737
  msgid "Feed Successfully Duplicated, but unable to generate the data file. Please click the \"Regenerate Button\""
738
  msgstr ""
739
 
814
  msgid "Are You Sure to Delete?"
815
  msgstr ""
816
 
817
+ #: admin/partials/woo-feed-category-mapping.php:35
818
  msgid "Merchant"
819
  msgstr ""
820
 
821
+ #: admin/partials/woo-feed-category-mapping.php:47
822
  msgid "Mapping Name"
823
  msgstr ""
824
 
825
+ #: admin/partials/woo-feed-category-mapping.php:49
826
  msgid "Mapping Name should be unique and don't use space. Otherwise it will override the existing Category Mapping. Example: myMappingName or my_mapping_name"
827
  msgstr ""
828
 
829
+ #: admin/partials/woo-feed-category-mapping.php:58
830
  msgid "Local Category"
831
  msgstr ""
832
 
833
+ #: admin/partials/woo-feed-category-mapping.php:59
834
  msgid "Merchant Category"
835
  msgstr ""
836
 
837
+ #: admin/partials/woo-feed-category-mapping.php:69
838
  msgid "Save Mapping"
839
  msgstr ""
840
 
1062
  msgid "Edit WooCommerce Product Feed"
1063
  msgstr ""
1064
 
1065
+ #: admin/partials/woo-feed-manage-list.php:41
1066
  msgid "Manage Feed"
1067
  msgstr ""
1068
 
1069
+ #: admin/partials/woo-feed-manage-list.php:42
1070
  msgid "New Feed"
1071
  msgstr ""
1072
 
1073
+ #: admin/partials/woo-feed-manage-list.php:43
1074
  msgid "Import Feed"
1075
  msgstr ""
1076
 
1077
+ #: admin/partials/woo-feed-manage-list.php:51
1078
  msgid "Import Feed File"
1079
  msgstr ""
1080
 
1081
+ #: admin/partials/woo-feed-manage-list.php:57, admin/partials/woo-feed-manage-list.php:58
1082
  msgid "Feed File Name"
1083
  msgstr ""
1084
 
1085
+ #: admin/partials/woo-feed-manage-list.php:63
1086
  msgid "Import Now"
1087
  msgstr ""
1088
 
1089
+ #: admin/partials/woo-feed-manage-list.php:76
1090
  msgid "Auto Update Feed Interval"
1091
  msgstr ""
1092
 
1093
+ #: admin/partials/woo-feed-manage-list.php:86
1094
  msgid "Interval"
1095
  msgstr ""
1096
 
1097
+ #: admin/partials/woo-feed-manage-list.php:95
1098
  msgid "Update Interval"
1099
  msgstr ""
1100
 
1376
  msgid "Settings Updated."
1377
  msgstr ""
1378
 
1379
+ #: includes/classes/class-woo-feed-list-table.php:182
1380
+ msgid "List View"
1381
  msgstr ""
1382
 
1383
+ #: includes/classes/class-woo-feed-list-table.php:183
1384
+ msgid "Excerpt View"
1385
  msgstr ""
1386
 
1387
+ #: includes/classes/class-woo-feed-list-table.php:360
1388
+ msgid "No items found."
1389
  msgstr ""
1390
 
1391
+ #: includes/classes/class-woo-feed-list-table.php:495
1392
+ msgid "Select bulk action"
1393
  msgstr ""
1394
 
1395
+ #: includes/classes/class-woo-feed-list-table.php:497
1396
+ msgid "Bulk Actions"
1397
  msgstr ""
1398
 
1399
+ #: includes/classes/class-woo-feed-list-table.php:506
1400
+ msgid "Apply"
1401
  msgstr ""
1402
 
1403
+ #: includes/classes/class-woo-feed-list-table.php:560, includes/classes/class-woo-feed-list-table.php:1408
1404
+ msgid "Show more details"
1405
  msgstr ""
1406
 
1407
+ #: includes/classes/class-woo-feed-list-table.php:629
1408
+ msgid "Filter by date"
1409
  msgstr ""
1410
 
1411
+ #: includes/classes/class-woo-feed-list-table.php:631
1412
+ msgid "All dates"
1413
  msgstr ""
1414
 
1415
+ #. translators: 1: month name, 2: 4-digit year
1416
+ #: includes/classes/class-woo-feed-list-table.php:646
1417
+ msgid "%1$s %2$d"
1418
  msgstr ""
1419
 
1420
+ #: includes/classes/class-woo-feed-list-table.php:699
1421
+ msgid "%s comment"
1422
+ msgid_plural "%s comments"
1423
+ msgstr[0] ""
1424
+ msgstr[1] ""
1425
 
1426
+ #: includes/classes/class-woo-feed-list-table.php:700
1427
+ msgid "%s approved comment"
1428
+ msgid_plural "%s approved comments"
1429
+ msgstr[0] ""
1430
+ msgstr[1] ""
1431
 
1432
+ #: includes/classes/class-woo-feed-list-table.php:701
1433
+ msgid "%s pending comment"
1434
+ msgid_plural "%s pending comments"
1435
+ msgstr[0] ""
1436
+ msgstr[1] ""
1437
 
1438
+ #: includes/classes/class-woo-feed-list-table.php:729
1439
+ msgid "No approved comments"
1440
  msgstr ""
1441
 
1442
+ #: includes/classes/class-woo-feed-list-table.php:729, includes/classes/class-woo-feed-list-table.php:707, includes/classes/class-woo-feed-list-table.php:752
1443
+ msgid "No comments"
1444
  msgstr ""
1445
 
1446
+ #: includes/classes/class-woo-feed-list-table.php:752
1447
+ msgid "No pending comments"
1448
  msgstr ""
1449
 
1450
+ #: includes/classes/class-woo-feed-list-table.php:831, includes/classes/class-woo-feed-list-table.php:1433
1451
+ msgid "%s item"
1452
+ msgid_plural "%s items"
1453
+ msgstr[0] ""
1454
+ msgstr[1] ""
1455
+
1456
+ #: includes/classes/class-woo-feed-list-table.php:867
1457
+ msgid "First page"
1458
  msgstr ""
1459
 
1460
+ #: includes/classes/class-woo-feed-list-table.php:878
1461
+ msgid "Previous page"
1462
  msgstr ""
1463
 
1464
+ #: includes/classes/class-woo-feed-list-table.php:889, includes/classes/class-woo-feed-list-table.php:885
1465
+ msgid "Current Page"
1466
  msgstr ""
1467
 
1468
+ #: includes/classes/class-woo-feed-list-table.php:895
1469
+ msgctxt "paging"
1470
+ msgid "%1$s of %2$s"
1471
  msgstr ""
1472
 
1473
+ #: includes/classes/class-woo-feed-list-table.php:903
1474
+ msgid "Next page"
1475
  msgstr ""
1476
 
1477
+ #: includes/classes/class-woo-feed-list-table.php:914
1478
+ msgid "Last page"
1479
  msgstr ""
1480
 
1481
+ #: includes/classes/class-woo-feed-list-table.php:1144
1482
+ msgid "Select All"
1483
  msgstr ""
1484
 
1485
+ #: includes/classes/class-woo-feed-log-handler-file.php:347, includes/classes/class-woo-feed-log-handler-file.php:367
1486
+ msgid "This method should not be called before plugins_loaded."
1487
  msgstr ""
1488
 
1489
+ #: includes/classes/class-woo-feed-merchant.php:311
1490
+ msgid "Custom Template"
1491
  msgstr ""
1492
 
1493
+ #: includes/classes/class-woo-feed-merchant.php:312
1494
+ msgid "Custom Template 1"
1495
  msgstr ""
1496
 
1497
+ #: includes/classes/class-woo-feed-merchant.php:323
1498
+ msgid "Popular Templates"
1499
  msgstr ""
1500
 
1501
+ #: includes/classes/class-woo-feed-merchant.php:324
1502
+ msgid "Google Shopping"
1503
  msgstr ""
1504
 
1505
+ #: includes/classes/class-woo-feed-merchant.php:325
1506
+ msgid "Google Local Inventory Ads"
1507
  msgstr ""
1508
 
1509
+ #: includes/classes/class-woo-feed-merchant.php:326
1510
+ msgid "Google Local Product Inventory"
1511
  msgstr ""
1512
 
1513
+ #: includes/classes/class-woo-feed-merchant.php:327
1514
+ msgid "Google Product Review"
1515
  msgstr ""
1516
 
1517
+ #: includes/classes/class-woo-feed-merchant.php:328
1518
+ msgid "Google Shopping Action"
1519
  msgstr ""
1520
 
1521
+ #: includes/classes/class-woo-feed-merchant.php:329
1522
+ msgid "Google Promotions"
1523
  msgstr ""
1524
 
1525
+ #: includes/classes/class-woo-feed-merchant.php:330
1526
+ msgid "Google Dynamic Search Ads"
1527
  msgstr ""
1528
 
1529
+ #: includes/classes/class-woo-feed-merchant.php:331
1530
+ msgid "Google Ads"
1531
  msgstr ""
1532
 
1533
+ #: includes/classes/class-woo-feed-merchant.php:332
1534
+ msgid "Google Ads Local Product"
1535
  msgstr ""
1536
 
1537
+ #: includes/classes/class-woo-feed-merchant.php:333
1538
+ msgid "Facebook Catalog / Instagram"
1539
  msgstr ""
1540
 
1541
+ #: includes/classes/class-woo-feed-merchant.php:334
1542
+ msgid "Pinterest Catalog"
1543
  msgstr ""
1544
 
1545
+ #: includes/classes/class-woo-feed-merchant.php:335
1546
+ msgid "Pinterest RSS Board"
1547
  msgstr ""
1548
 
1549
+ #: includes/classes/class-woo-feed-merchant.php:336
1550
+ msgid "Bing Shopping"
1551
  msgstr ""
1552
 
1553
+ #: includes/classes/class-woo-feed-merchant.php:337
1554
+ msgid "Bing Local Inventory"
1555
  msgstr ""
1556
 
1557
+ #: includes/classes/class-woo-feed-merchant.php:338
1558
+ msgid "Snapchat"
1559
  msgstr ""
1560
 
1561
+ #: includes/classes/class-woo-feed-merchant.php:339
1562
+ msgid "TikTok"
1563
  msgstr ""
1564
 
1565
+ #: includes/classes/class-woo-feed-merchant.php:340
1566
+ msgid "Idealo"
1567
  msgstr ""
1568
 
1569
+ #: includes/classes/class-woo-feed-merchant.php:341
1570
+ msgid "PriceSpy"
1571
  msgstr ""
1572
 
1573
+ #: includes/classes/class-woo-feed-merchant.php:342
1574
+ msgid "Price Runner"
1575
  msgstr ""
1576
 
1577
+ #: includes/classes/class-woo-feed-merchant.php:343
1578
+ msgid "Yandex (CSV)"
1579
  msgstr ""
1580
 
1581
+ #: includes/classes/class-woo-feed-merchant.php:344
1582
+ msgid "Yandex (XML)"
1583
  msgstr ""
1584
 
1585
+ #: includes/classes/class-woo-feed-merchant.php:355
1586
+ msgid "Templates"
1587
  msgstr ""
1588
 
1589
+ #: includes/classes/class-woo-feed-merchant.php:356
1590
+ msgid "AdForm"
1591
  msgstr ""
1592
 
1593
+ #: includes/classes/class-woo-feed-merchant.php:357
1594
+ msgid "AdRoll"
1595
  msgstr ""
1596
 
1597
+ #: includes/classes/class-woo-feed-merchant.php:358
1598
+ msgid "Avantlink"
1599
  msgstr ""
1600
 
1601
+ #: includes/classes/class-woo-feed-merchant.php:359
1602
+ msgid "Become"
1603
  msgstr ""
1604
 
1605
+ #: includes/classes/class-woo-feed-merchant.php:360
1606
+ msgid "Beslist.nl"
1607
  msgstr ""
1608
 
1609
+ #: includes/classes/class-woo-feed-merchant.php:361
1610
+ msgid "Bestprice"
1611
  msgstr ""
1612
 
1613
+ #: includes/classes/class-woo-feed-merchant.php:362
1614
+ msgid "Billiger.de"
1615
  msgstr ""
1616
 
1617
+ #: includes/classes/class-woo-feed-merchant.php:363
1618
+ msgid "Bol.com"
1619
  msgstr ""
1620
 
1621
+ #: includes/classes/class-woo-feed-merchant.php:364
1622
+ msgid "Bonanza"
1623
  msgstr ""
1624
 
1625
+ #: includes/classes/class-woo-feed-merchant.php:365
1626
+ msgid "Catch.com.au"
1627
  msgstr ""
1628
 
1629
+ #: includes/classes/class-woo-feed-merchant.php:366
1630
+ msgid "CDiscount.fr"
1631
  msgstr ""
1632
 
1633
+ #: includes/classes/class-woo-feed-merchant.php:367
1634
+ msgid "Comparer.be"
1635
  msgstr ""
1636
 
1637
+ #: includes/classes/class-woo-feed-merchant.php:368
1638
+ msgid "Connexity"
1639
  msgstr ""
1640
 
1641
+ #: includes/classes/class-woo-feed-merchant.php:369
1642
+ msgid "Criteo"
1643
  msgstr ""
1644
 
1645
+ #: includes/classes/class-woo-feed-merchant.php:370
1646
+ msgid "Crowdfox"
1647
  msgstr ""
1648
 
1649
+ #: includes/classes/class-woo-feed-merchant.php:371
1650
+ msgid "Daisycon Advertiser (General)"
1651
  msgstr ""
1652
 
1653
+ #: includes/classes/class-woo-feed-merchant.php:372
1654
+ msgid "Daisycon Advertiser (Automotive)"
1655
  msgstr ""
1656
 
1657
+ #: includes/classes/class-woo-feed-merchant.php:373
1658
+ msgid "Daisycon Advertiser (Books)"
1659
  msgstr ""
1660
 
1661
+ #: includes/classes/class-woo-feed-merchant.php:374
1662
+ msgid "Daisycon Advertiser (Cosmetics)"
1663
  msgstr ""
1664
 
1665
+ #: includes/classes/class-woo-feed-merchant.php:375
1666
+ msgid "Daisycon Advertiser (Daily Offers)"
1667
  msgstr ""
1668
 
1669
+ #: includes/classes/class-woo-feed-merchant.php:376
1670
+ msgid "Daisycon Advertiser (Electronics)"
1671
  msgstr ""
1672
 
1673
+ #: includes/classes/class-woo-feed-merchant.php:377
1674
+ msgid "Daisycon Advertiser (Fashion)"
1675
  msgstr ""
1676
 
1677
+ #: includes/classes/class-woo-feed-merchant.php:378
1678
+ msgid "Daisycon Advertiser (Food & Drinks)"
1679
  msgstr ""
1680
 
1681
+ #: includes/classes/class-woo-feed-merchant.php:379
1682
+ msgid "Daisycon Advertiser (Holidays: Accommodations and transport)"
1683
  msgstr ""
1684
 
1685
+ #: includes/classes/class-woo-feed-merchant.php:380
1686
+ msgid "Daisycon Advertiser (Holidays: Accommodations)"
1687
  msgstr ""
1688
 
1689
+ #: includes/classes/class-woo-feed-merchant.php:381
1690
+ msgid "Daisycon Advertiser (Holidays: Trips)"
1691
  msgstr ""
1692
 
1693
+ #: includes/classes/class-woo-feed-merchant.php:382
1694
+ msgid "Daisycon Advertiser (Home & Garden)"
1695
  msgstr ""
1696
 
1697
+ #: includes/classes/class-woo-feed-merchant.php:383
1698
+ msgid "Daisycon Advertiser (Housing)"
1699
  msgstr ""
1700
 
1701
+ #: includes/classes/class-woo-feed-merchant.php:384
1702
+ msgid "Daisycon Advertiser (Magazines)"
1703
  msgstr ""
1704
 
1705
+ #: includes/classes/class-woo-feed-merchant.php:385
1706
+ msgid "Daisycon Advertiser (Studies & Trainings)"
1707
  msgstr ""
1708
 
1709
+ #: includes/classes/class-woo-feed-merchant.php:386
1710
+ msgid "Daisycon Advertiser (Telecom: Accessories)"
1711
  msgstr ""
1712
 
1713
+ #: includes/classes/class-woo-feed-merchant.php:387
1714
+ msgid "Daisycon Advertiser (Telecom: All-in-one)"
1715
  msgstr ""
1716
 
1717
+ #: includes/classes/class-woo-feed-merchant.php:388
1718
+ msgid "Daisycon Advertiser (Telecom: GSM + Subscription)"
1719
  msgstr ""
1720
 
1721
+ #: includes/classes/class-woo-feed-merchant.php:389
1722
+ msgid "Daisycon Advertiser (Telecom: GSM only)"
1723
  msgstr ""
1724
 
1725
+ #: includes/classes/class-woo-feed-merchant.php:390
1726
+ msgid "Daisycon Advertiser (Telecom: Sim only)"
1727
  msgstr ""
1728
 
1729
+ #: includes/classes/class-woo-feed-merchant.php:391
1730
+ msgid "Daisycon Advertiser (Work & Jobs)"
1731
  msgstr ""
1732
 
1733
+ #: includes/classes/class-woo-feed-merchant.php:392
1734
+ msgid "Dooyoo"
1735
  msgstr ""
1736
 
1737
+ #: includes/classes/class-woo-feed-merchant.php:393
1738
+ msgid "Ecommerce.it"
1739
  msgstr ""
1740
 
1741
+ #: includes/classes/class-woo-feed-merchant.php:394
1742
+ msgid "Etsy"
1743
  msgstr ""
1744
 
1745
+ #: includes/classes/class-woo-feed-merchant.php:395
1746
+ msgid "Fruugo"
1747
  msgstr ""
1748
 
1749
+ #: includes/classes/class-woo-feed-merchant.php:396
1750
+ msgid "Fashionchick.nl"
1751
  msgstr ""
1752
 
1753
+ #: includes/classes/class-woo-feed-merchant.php:397
1754
+ msgid "Fruugoaustralia.com"
1755
  msgstr ""
1756
 
1757
+ #: includes/classes/class-woo-feed-merchant.php:398
1758
+ msgid "Fyndiq.se"
1759
  msgstr ""
1760
 
1761
+ #: includes/classes/class-woo-feed-merchant.php:399
1762
+ msgid "GoedGeplaatst.nl"
1763
  msgstr ""
1764
 
1765
+ #: includes/classes/class-woo-feed-merchant.php:400
1766
+ msgid "Heureka.sk"
1767
  msgstr ""
1768
 
1769
+ #: includes/classes/class-woo-feed-merchant.php:401
1770
+ msgid "Hintaseuranta.fi"
1771
  msgstr ""
1772
 
1773
+ #: includes/classes/class-woo-feed-merchant.php:402
1774
+ msgid "Incurvy"
1775
  msgstr ""
1776
 
1777
+ #: includes/classes/class-woo-feed-merchant.php:403
1778
+ msgid "Jet.com"
1779
  msgstr ""
1780
 
1781
+ #: includes/classes/class-woo-feed-merchant.php:404
1782
+ msgid "Kelkoo"
1783
  msgstr ""
1784
 
1785
+ #: includes/classes/class-woo-feed-merchant.php:405
1786
+ msgid "Kieskeurig.nl"
1787
  msgstr ""
1788
 
1789
+ #: includes/classes/class-woo-feed-merchant.php:406
1790
+ msgid "Kijiji.ca"
1791
  msgstr ""
1792
 
1793
+ #: includes/classes/class-woo-feed-merchant.php:407
1794
+ msgid "LeGuide"
1795
  msgstr ""
1796
 
1797
+ #: includes/classes/class-woo-feed-merchant.php:408
1798
+ msgid "Marktplaats.nl"
1799
  msgstr ""
1800
 
1801
+ #: includes/classes/class-woo-feed-merchant.php:409
1802
+ msgid "Miinto.de"
1803
  msgstr ""
1804
 
1805
+ #: includes/classes/class-woo-feed-merchant.php:410
1806
+ msgid "Miinto.nl"
1807
  msgstr ""
1808
 
1809
+ #: includes/classes/class-woo-feed-merchant.php:411
1810
+ msgid "Modalova"
1811
  msgstr ""
1812
 
1813
+ #: includes/classes/class-woo-feed-merchant.php:412
1814
+ msgid "Modina.de"
1815
  msgstr ""
1816
 
1817
+ #: includes/classes/class-woo-feed-merchant.php:413
1818
+ msgid "Moebel.de"
1819
  msgstr ""
1820
 
1821
+ #: includes/classes/class-woo-feed-merchant.php:414
1822
+ msgid "Myshopping.com.au"
1823
  msgstr ""
1824
 
1825
+ #: includes/classes/class-woo-feed-merchant.php:415
1826
+ msgid "TheNextAd"
1827
  msgstr ""
1828
 
1829
+ #: includes/classes/class-woo-feed-merchant.php:416
1830
+ msgid "Nextag"
1831
  msgstr ""
1832
 
1833
+ #: includes/classes/class-woo-feed-merchant.php:417
1834
+ msgid "Polyvore"
1835
  msgstr ""
1836
 
1837
+ #: includes/classes/class-woo-feed-merchant.php:418
1838
+ msgid "Price Grabber"
1839
  msgstr ""
1840
 
1841
+ #: includes/classes/class-woo-feed-merchant.php:419
1842
+ msgid "Prisjakt"
1843
  msgstr ""
1844
 
1845
+ #: includes/classes/class-woo-feed-merchant.php:420
1846
+ msgid "Profit Share"
1847
  msgstr ""
1848
 
1849
+ #: includes/classes/class-woo-feed-merchant.php:421
1850
+ msgid "Rakuten.de"
 
1851
  msgstr ""
1852
 
1853
+ #: includes/classes/class-woo-feed-merchant.php:422
1854
+ msgid "Real"
1855
+ msgstr ""
 
 
1856
 
1857
+ #: includes/classes/class-woo-feed-merchant.php:423
1858
+ msgid "ShareASale"
1859
+ msgstr ""
 
 
1860
 
1861
+ #: includes/classes/class-woo-feed-merchant.php:424
1862
+ msgid "Shopalike.fr"
1863
+ msgstr ""
 
 
1864
 
1865
+ #: includes/classes/class-woo-feed-merchant.php:425
1866
+ msgid "Shopbot"
1867
  msgstr ""
1868
 
1869
+ #: includes/classes/class-woo-feed-merchant.php:426
1870
+ msgid "Shopmania"
1871
  msgstr ""
1872
 
1873
+ #: includes/classes/class-woo-feed-merchant.php:427
1874
+ msgid "Shopping.com"
1875
  msgstr ""
1876
 
1877
+ #: includes/classes/class-woo-feed-merchant.php:428
1878
+ msgid "Shopflix (WellComm)"
1879
+ msgstr ""
 
 
1880
 
1881
+ #: includes/classes/class-woo-feed-merchant.php:429
1882
+ msgid "Shopzilla"
1883
  msgstr ""
1884
 
1885
+ #: includes/classes/class-woo-feed-merchant.php:430
1886
+ msgid "SkinFlint.co.uk"
1887
  msgstr ""
1888
 
1889
+ #: includes/classes/class-woo-feed-merchant.php:431
1890
+ msgid "Skroutz.gr"
1891
  msgstr ""
1892
 
1893
+ #: includes/classes/class-woo-feed-merchant.php:432
1894
+ msgid "Smartly.io"
 
1895
  msgstr ""
1896
 
1897
+ #: includes/classes/class-woo-feed-merchant.php:433
1898
+ msgid "Spartoo.fi"
1899
  msgstr ""
1900
 
1901
+ #: includes/classes/class-woo-feed-merchant.php:434
1902
+ msgid "Shopee"
1903
  msgstr ""
1904
 
1905
+ #: includes/classes/class-woo-feed-merchant.php:435
1906
+ msgid "Stylight.com"
1907
  msgstr ""
1908
 
1909
+ #: includes/classes/class-woo-feed-merchant.php:436
1910
+ msgid "Trovaprezzi.it"
1911
  msgstr ""
1912
 
1913
+ #: includes/classes/class-woo-feed-merchant.php:437
1914
+ msgid "Twenga"
1915
  msgstr ""
1916
 
1917
+ #: includes/classes/class-woo-feed-merchant.php:438
1918
+ msgid "Tweakers (XML)"
1919
  msgstr ""
1920
 
1921
+ #: includes/classes/class-woo-feed-merchant.php:439
1922
+ msgid "Tweakers (CSV)"
1923
  msgstr ""
1924
 
1925
+ #: includes/classes/class-woo-feed-merchant.php:440
1926
+ msgid "Vertaa.fi"
1927
  msgstr ""
1928
 
1929
+ #: includes/classes/class-woo-feed-merchant.php:441
1930
+ msgid "Walmart"
1931
  msgstr ""
1932
 
1933
+ #: includes/classes/class-woo-feed-merchant.php:442
1934
+ msgid "Webmarchand"
1935
  msgstr ""
1936
 
1937
+ #: includes/classes/class-woo-feed-merchant.php:443
1938
+ msgid "Wine Searcher"
1939
  msgstr ""
1940
 
1941
+ #: includes/classes/class-woo-feed-merchant.php:444
1942
+ msgid "Wish.com"
1943
  msgstr ""
1944
 
1945
+ #: includes/classes/class-woo-feed-merchant.php:445
1946
+ msgid "Yahoo NFA"
1947
  msgstr ""
1948
 
1949
+ #: includes/classes/class-woo-feed-merchant.php:446
1950
+ msgid "Zap.co.il"
1951
  msgstr ""
1952
 
1953
+ #: includes/classes/class-woo-feed-merchant.php:447
1954
+ msgid "Zbozi.cz"
1955
  msgstr ""
1956
 
1957
+ #: includes/classes/class-woo-feed-merchant.php:448
1958
+ msgid "Zalando"
1959
  msgstr ""
1960
 
1961
+ #: includes/classes/class-woo-feed-merchant.php:449
1962
+ msgid "Admarkt(marktplaats)"
1963
  msgstr ""
1964
 
1965
+ #: includes/classes/class-woo-feed-merchant.php:450
1966
+ msgid "GLAMI"
1967
  msgstr ""
1968
 
1969
+ #: includes/classes/class-woo-feed-product-attributes.php:31, includes/classes/class-woo-feed-products.php:1803
1970
+ msgid "Select Attributes"
1971
  msgstr ""
1972
 
1973
+ #: includes/classes/class-woo-feed-product-attributes.php:100, includes/classes/class-woo-feed-products.php:1784
1974
+ msgid "Primary Attributes"
1975
  msgstr ""
1976
 
1977
+ #: includes/classes/class-woo-feed-product-attributes.php:102, includes/classes/class-woo-feed-products.php:1711
1978
+ msgid "Product Id"
1979
  msgstr ""
1980
 
1981
+ #: includes/classes/class-woo-feed-product-attributes.php:103, includes/classes/class-woo-feed-products.php:1712
1982
+ msgid "Product Title"
1983
  msgstr ""
1984
 
1985
+ #: includes/classes/class-woo-feed-product-attributes.php:104
1986
+ msgid "Parent Title"
1987
  msgstr ""
1988
 
1989
+ #: includes/classes/class-woo-feed-product-attributes.php:105, includes/classes/class-woo-feed-products.php:1713
1990
+ msgid "Product Description"
1991
  msgstr ""
1992
 
1993
+ #: includes/classes/class-woo-feed-product-attributes.php:106
1994
+ msgid "Product Description (with HTML)"
1995
  msgstr ""
1996
 
1997
+ #: includes/classes/class-woo-feed-product-attributes.php:107, includes/classes/class-woo-feed-products.php:1714
1998
+ msgid "Product Short Description"
1999
  msgstr ""
2000
 
2001
+ #: includes/classes/class-woo-feed-product-attributes.php:108
2002
+ msgid "Parent Category"
2003
  msgstr ""
2004
 
2005
+ #: includes/classes/class-woo-feed-product-attributes.php:109
2006
+ msgid "Parent Category ID"
2007
  msgstr ""
2008
 
2009
+ #: includes/classes/class-woo-feed-product-attributes.php:110
2010
+ msgid "Child Category"
2011
  msgstr ""
2012
 
2013
+ #: includes/classes/class-woo-feed-product-attributes.php:111
2014
+ msgid "Child Category ID"
2015
  msgstr ""
2016
 
2017
+ #: includes/classes/class-woo-feed-product-attributes.php:112
2018
+ msgid "Product Category [Category Path]"
2019
+ msgstr ""
2020
+
2021
+ #: includes/classes/class-woo-feed-product-attributes.php:113
2022
+ msgid "Product Full Category [Category Full Path]"
2023
+ msgstr ""
2024
+
2025
+ #: includes/classes/class-woo-feed-product-attributes.php:114, includes/classes/class-woo-feed-products.php:1716
2026
+ msgid "Product URL"
2027
+ msgstr ""
2028
+
2029
+ #: includes/classes/class-woo-feed-product-attributes.php:115
2030
+ msgid "Parent URL"
2031
+ msgstr ""
2032
+
2033
+ #: includes/classes/class-woo-feed-product-attributes.php:116
2034
+ msgid "Canonical URL"
2035
+ msgstr ""
2036
+
2037
+ #: includes/classes/class-woo-feed-product-attributes.php:117, includes/classes/class-woo-feed-products.php:1717
2038
+ msgid "External Product URL"
2039
+ msgstr ""
2040
+
2041
+ #: includes/classes/class-woo-feed-product-attributes.php:118
2042
+ msgid "Add to Cart URL"
2043
+ msgstr ""
2044
+
2045
+ #: includes/classes/class-woo-feed-product-attributes.php:119, includes/classes/class-woo-feed-products.php:1719
2046
+ msgid "Parent Id [Group Id]"
2047
+ msgstr ""
2048
+
2049
+ #: includes/classes/class-woo-feed-product-attributes.php:120, includes/classes/class-woo-feed-products.php:1720
2050
+ msgid "SKU"
2051
+ msgstr ""
2052
+
2053
+ #: includes/classes/class-woo-feed-product-attributes.php:121
2054
+ msgid "SKU_ID"
2055
+ msgstr ""
2056
+
2057
+ #: includes/classes/class-woo-feed-product-attributes.php:122, includes/classes/class-woo-feed-products.php:1721
2058
+ msgid "Parent SKU"
2059
+ msgstr ""
2060
+
2061
+ #: includes/classes/class-woo-feed-product-attributes.php:123, includes/classes/class-woo-feed-products.php:1722
2062
+ msgid "Availability"
2063
+ msgstr ""
2064
+
2065
+ #: includes/classes/class-woo-feed-product-attributes.php:125, includes/classes/class-woo-feed-products.php:1723
2066
+ msgid "Quantity"
2067
+ msgstr ""
2068
+
2069
+ #: includes/classes/class-woo-feed-product-attributes.php:126
2070
+ msgid "Reviewer Name"
2071
+ msgstr ""
2072
+
2073
+ #: includes/classes/class-woo-feed-product-attributes.php:127, includes/classes/class-woo-feed-products.php:1732
2074
+ msgid "Weight"
2075
+ msgstr ""
2076
+
2077
+ #: includes/classes/class-woo-feed-product-attributes.php:128
2078
+ msgid "Weight Unit"
2079
+ msgstr ""
2080
+
2081
+ #: includes/classes/class-woo-feed-product-attributes.php:129, includes/classes/class-woo-feed-products.php:1733
2082
+ msgid "Width"
2083
+ msgstr ""
2084
+
2085
+ #: includes/classes/class-woo-feed-product-attributes.php:130, includes/classes/class-woo-feed-products.php:1734
2086
+ msgid "Height"
2087
+ msgstr ""
2088
+
2089
+ #: includes/classes/class-woo-feed-product-attributes.php:131, includes/classes/class-woo-feed-products.php:1735
2090
+ msgid "Length"
2091
+ msgstr ""
2092
+
2093
+ #: includes/classes/class-woo-feed-product-attributes.php:132, includes/classes/class-woo-feed-products.php:1737
2094
+ msgid "Product Type"
2095
+ msgstr ""
2096
+
2097
+ #: includes/classes/class-woo-feed-product-attributes.php:133, includes/classes/class-woo-feed-products.php:1739
2098
+ msgid "Visibility"
2099
+ msgstr ""
2100
+
2101
+ #: includes/classes/class-woo-feed-product-attributes.php:134, includes/classes/class-woo-feed-products.php:1740
2102
+ msgid "Total Rating"
2103
+ msgstr ""
2104
+
2105
+ #: includes/classes/class-woo-feed-product-attributes.php:135, includes/classes/class-woo-feed-products.php:1741
2106
+ msgid "Average Rating"
2107
+ msgstr ""
2108
+
2109
+ #: includes/classes/class-woo-feed-product-attributes.php:136, includes/classes/class-woo-feed-products.php:1742
2110
+ msgid "Tags"
2111
  msgstr ""
2112
 
2113
+ #: includes/classes/class-woo-feed-product-attributes.php:137, includes/classes/class-woo-feed-products.php:1744
2114
+ msgid "Is Bundle"
2115
  msgstr ""
2116
 
2117
+ #: includes/classes/class-woo-feed-product-attributes.php:138, includes/classes/class-woo-feed-products.php:1745
2118
+ msgid "Author Name"
2119
  msgstr ""
2120
 
2121
+ #: includes/classes/class-woo-feed-product-attributes.php:139, includes/classes/class-woo-feed-products.php:1746
2122
+ msgid "Author Email"
2123
  msgstr ""
2124
 
2125
+ #: includes/classes/class-woo-feed-product-attributes.php:140, includes/classes/class-woo-feed-products.php:1747
2126
+ msgid "Date Created"
2127
  msgstr ""
2128
 
2129
+ #: includes/classes/class-woo-feed-product-attributes.php:141, includes/classes/class-woo-feed-products.php:1748
2130
+ msgid "Date Updated"
2131
  msgstr ""
2132
 
2133
+ #: includes/classes/class-woo-feed-product-attributes.php:150
2134
+ msgid "Images"
2135
  msgstr ""
2136
 
2137
+ #: includes/classes/class-woo-feed-product-attributes.php:152, includes/classes/class-woo-feed-products.php:1751
2138
+ msgid "Main Image"
2139
  msgstr ""
2140
 
2141
+ #: includes/classes/class-woo-feed-product-attributes.php:153, includes/classes/class-woo-feed-products.php:1752
2142
+ msgid "Featured Image"
2143
  msgstr ""
2144
 
2145
+ #: includes/classes/class-woo-feed-product-attributes.php:154, includes/classes/class-woo-feed-products.php:1753
2146
+ msgid "Images [Comma Separated]"
2147
  msgstr ""
2148
 
2149
+ #: includes/classes/class-woo-feed-product-attributes.php:155, includes/classes/class-woo-feed-products.php:1754
2150
+ msgid "Additional Image 1"
2151
  msgstr ""
2152
 
2153
+ #: includes/classes/class-woo-feed-product-attributes.php:156, includes/classes/class-woo-feed-products.php:1755
2154
+ msgid "Additional Image 2"
2155
  msgstr ""
2156
 
2157
+ #: includes/classes/class-woo-feed-product-attributes.php:157, includes/classes/class-woo-feed-products.php:1756
2158
+ msgid "Additional Image 3"
2159
  msgstr ""
2160
 
2161
+ #: includes/classes/class-woo-feed-product-attributes.php:158, includes/classes/class-woo-feed-products.php:1757
2162
+ msgid "Additional Image 4"
2163
  msgstr ""
2164
 
2165
+ #: includes/classes/class-woo-feed-product-attributes.php:159, includes/classes/class-woo-feed-products.php:1758
2166
+ msgid "Additional Image 5"
2167
  msgstr ""
2168
 
2169
+ #: includes/classes/class-woo-feed-product-attributes.php:160, includes/classes/class-woo-feed-products.php:1759
2170
+ msgid "Additional Image 6"
2171
  msgstr ""
2172
 
2173
+ #: includes/classes/class-woo-feed-product-attributes.php:161, includes/classes/class-woo-feed-products.php:1760
2174
+ msgid "Additional Image 7"
2175
  msgstr ""
2176
 
2177
+ #: includes/classes/class-woo-feed-product-attributes.php:162, includes/classes/class-woo-feed-products.php:1761
2178
+ msgid "Additional Image 8"
2179
  msgstr ""
2180
 
2181
+ #: includes/classes/class-woo-feed-product-attributes.php:163, includes/classes/class-woo-feed-products.php:1762
2182
+ msgid "Additional Image 9"
2183
  msgstr ""
2184
 
2185
+ #: includes/classes/class-woo-feed-product-attributes.php:164, includes/classes/class-woo-feed-products.php:1763
2186
+ msgid "Additional Image 10"
2187
  msgstr ""
2188
 
2189
+ #: includes/classes/class-woo-feed-product-attributes.php:171, includes/classes/class-woo-feed-product-attributes.php:175, includes/classes/class-woo-feed-products.php:1725
2190
+ msgid "Price"
2191
  msgstr ""
2192
 
2193
+ #: includes/classes/class-woo-feed-product-attributes.php:173
2194
+ msgid "Currency"
2195
  msgstr ""
2196
 
2197
+ #: includes/classes/class-woo-feed-product-attributes.php:174, includes/classes/class-woo-feed-products.php:1724
2198
+ msgid "Regular Price"
2199
  msgstr ""
2200
 
2201
+ #: includes/classes/class-woo-feed-product-attributes.php:176, includes/classes/class-woo-feed-products.php:1726
2202
+ msgid "Sale Price"
2203
  msgstr ""
2204
 
2205
+ #: includes/classes/class-woo-feed-product-attributes.php:177, includes/classes/class-woo-feed-products.php:1727
2206
+ msgid "Regular Price With Tax"
2207
  msgstr ""
2208
 
2209
+ #: includes/classes/class-woo-feed-product-attributes.php:178, includes/classes/class-woo-feed-products.php:1728
2210
+ msgid "Price With Tax"
2211
  msgstr ""
2212
 
2213
+ #: includes/classes/class-woo-feed-product-attributes.php:179, includes/classes/class-woo-feed-products.php:1729
2214
+ msgid "Sale Price With Tax"
2215
  msgstr ""
2216
 
2217
+ #: includes/classes/class-woo-feed-product-attributes.php:180, includes/classes/class-woo-feed-products.php:1730
2218
+ msgid "Sale Start Date"
2219
  msgstr ""
2220
 
2221
+ #: includes/classes/class-woo-feed-product-attributes.php:181, includes/classes/class-woo-feed-products.php:1731
2222
+ msgid "Sale End Date"
2223
  msgstr ""
2224
 
2225
+ #: includes/classes/class-woo-feed-product-attributes.php:182, includes/classes/class-woo-feed-products.php:1743
2226
+ msgid "Sale Price Effective Date"
2227
  msgstr ""
2228
 
2229
+ #: includes/classes/class-woo-feed-product-attributes.php:189
2230
+ msgid "Shipping"
2231
  msgstr ""
2232
 
2233
+ #: includes/classes/class-woo-feed-product-attributes.php:191
2234
+ msgid "Shipping (Google Format)"
2235
  msgstr ""
2236
 
2237
+ #: includes/classes/class-woo-feed-product-attributes.php:192, includes/classes/class-woo-feed-products.php:1736
2238
+ msgid "Shipping Class"
2239
  msgstr ""
2240
 
2241
+ #: includes/classes/class-woo-feed-product-attributes.php:193
2242
+ msgid "Shipping Zone Name"
2243
  msgstr ""
2244
 
2245
+ #: includes/classes/class-woo-feed-product-attributes.php:194
2246
+ msgid "Shipping Country"
2247
  msgstr ""
2248
 
2249
+ #: includes/classes/class-woo-feed-product-attributes.php:195
2250
+ msgid "Shipping Regions"
2251
  msgstr ""
2252
 
2253
+ #: includes/classes/class-woo-feed-product-attributes.php:196
2254
+ msgid "Shipping Postcodes"
2255
  msgstr ""
2256
 
2257
+ #: includes/classes/class-woo-feed-product-attributes.php:197
2258
+ msgid "Shipping Method Name"
2259
  msgstr ""
2260
 
2261
+ #: includes/classes/class-woo-feed-product-attributes.php:198
2262
+ msgid "Shipping Cost"
2263
  msgstr ""
2264
 
2265
+ #: includes/classes/class-woo-feed-product-attributes.php:205
2266
+ msgid "Tax"
2267
  msgstr ""
2268
 
2269
+ #: includes/classes/class-woo-feed-product-attributes.php:207
2270
+ msgid "Tax (Google Format)"
2271
  msgstr ""
2272
 
2273
+ #: includes/classes/class-woo-feed-product-attributes.php:208
2274
+ msgid "Tax Class"
2275
  msgstr ""
2276
 
2277
+ #: includes/classes/class-woo-feed-product-attributes.php:209
2278
+ msgid "Tax Status"
2279
  msgstr ""
2280
 
2281
+ #: includes/classes/class-woo-feed-product-attributes.php:210
2282
+ msgid "Tax Country"
2283
  msgstr ""
2284
 
2285
+ #: includes/classes/class-woo-feed-product-attributes.php:211
2286
+ msgid "Tax State"
2287
  msgstr ""
2288
 
2289
+ #: includes/classes/class-woo-feed-product-attributes.php:212
2290
+ msgid "Tax Postcodes"
2291
  msgstr ""
2292
 
2293
+ #: includes/classes/class-woo-feed-product-attributes.php:213
2294
+ msgid "Tax City"
2295
  msgstr ""
2296
 
2297
+ #: includes/classes/class-woo-feed-product-attributes.php:214
2298
+ msgid "Tax Rate"
2299
  msgstr ""
2300
 
2301
+ #: includes/classes/class-woo-feed-product-attributes.php:215
2302
+ msgid "Tax Name"
2303
  msgstr ""
2304
 
2305
+ #: includes/classes/class-woo-feed-product-attributes.php:222
2306
+ msgid "Subscription & Installment"
2307
  msgstr ""
2308
 
2309
+ #: includes/classes/class-woo-feed-product-attributes.php:224
2310
+ msgid "Subscription Period"
2311
  msgstr ""
2312
 
2313
+ #: includes/classes/class-woo-feed-product-attributes.php:225
2314
+ msgid "Subscription Period Length"
2315
  msgstr ""
2316
 
2317
+ #: includes/classes/class-woo-feed-product-attributes.php:226
2318
+ msgid "Subscription Amount"
2319
  msgstr ""
2320
 
2321
+ #: includes/classes/class-woo-feed-product-attributes.php:227
2322
+ msgid "Installment Months"
2323
  msgstr ""
2324
 
2325
+ #: includes/classes/class-woo-feed-product-attributes.php:228
2326
+ msgid "Installment Amount"
2327
  msgstr ""
2328
 
2329
+ #: includes/classes/class-woo-feed-product-attributes.php:233
2330
+ msgid "Custom Template 2 (XML)"
2331
  msgstr ""
2332
 
2333
+ #: includes/classes/class-woo-feed-product-attributes.php:235
2334
+ msgid "Product Variations"
2335
  msgstr ""
2336
 
2337
+ #: includes/classes/class-woo-feed-product-attributes.php:236
2338
+ msgid "Product Gallery Images"
2339
  msgstr ""
2340
 
2341
+ #: includes/classes/class-woo-feed-product-attributes.php:237
2342
+ msgid "Product Categories"
2343
  msgstr ""
2344
 
2345
+ #: includes/classes/class-woo-feed-product-attributes.php:285
2346
+ msgid "Custom Fields by CTX Feed"
2347
  msgstr ""
2348
 
2349
+ #: includes/classes/class-woo-feed-product-attributes.php:303
2350
+ msgid "Unit Price (CTX Feed)"
2351
  msgstr ""
2352
 
2353
+ #: includes/classes/class-woo-feed-product-attributes.php:317
2354
+ msgid "Unit Price (WooCommerce Germanized)"
2355
  msgstr ""
2356
 
2357
+ #: includes/classes/class-woo-feed-product-attributes.php:346
2358
+ msgid "Yoast SEO"
2359
  msgstr ""
2360
 
2361
+ #: includes/classes/class-woo-feed-product-attributes.php:348, includes/classes/class-woo-feed-products.php:1776
2362
+ msgid "Title [Yoast SEO]"
2363
  msgstr ""
2364
 
2365
+ #: includes/classes/class-woo-feed-product-attributes.php:349, includes/classes/class-woo-feed-products.php:1777
2366
+ msgid "Description [Yoast SEO]"
2367
  msgstr ""
2368
 
2369
+ #: includes/classes/class-woo-feed-product-attributes.php:350
2370
+ msgid "Canonical URL [Yoast SEO]"
2371
  msgstr ""
2372
 
2373
+ #: includes/classes/class-woo-feed-product-attributes.php:360
2374
+ msgid "GTIN8 [Yoast SEO]"
2375
  msgstr ""
2376
 
2377
+ #: includes/classes/class-woo-feed-product-attributes.php:361
2378
+ msgid "GTIN12 / UPC [Yoast SEO]"
2379
  msgstr ""
2380
 
2381
+ #: includes/classes/class-woo-feed-product-attributes.php:362
2382
+ msgid "GTIN13 / EAN [Yoast SEO]"
2383
  msgstr ""
2384
 
2385
+ #: includes/classes/class-woo-feed-product-attributes.php:363
2386
+ msgid "GTIN14 / ITF-14 [Yoast SEO]"
2387
  msgstr ""
2388
 
2389
+ #: includes/classes/class-woo-feed-product-attributes.php:364
2390
+ msgid "ISBN [Yoast SEO]"
2391
  msgstr ""
2392
 
2393
+ #: includes/classes/class-woo-feed-product-attributes.php:365
2394
+ msgid "MPN [Yoast SEO]"
2395
  msgstr ""
2396
 
2397
+ #: includes/classes/class-woo-feed-product-attributes.php:372
2398
+ msgid "RANK MATH SEO"
2399
  msgstr ""
2400
 
2401
+ #: includes/classes/class-woo-feed-product-attributes.php:374
2402
+ msgid "Title [RankMath SEO]"
2403
  msgstr ""
2404
 
2405
+ #: includes/classes/class-woo-feed-product-attributes.php:375
2406
+ msgid "Description [RankMath SEO]"
2407
  msgstr ""
2408
 
2409
+ #: includes/classes/class-woo-feed-product-attributes.php:376
2410
+ msgid "Canonical URL [RankMath SEO]"
2411
  msgstr ""
2412
 
2413
+ #: includes/classes/class-woo-feed-product-attributes.php:381
2414
+ msgid "GTIN [RankMath Pro SEO]"
2415
  msgstr ""
2416
 
2417
+ #: includes/classes/class-woo-feed-product-attributes.php:387
2418
+ msgid "ALL IN ONE SEO"
2419
  msgstr ""
2420
 
2421
+ #: includes/classes/class-woo-feed-product-attributes.php:389, includes/classes/class-woo-feed-products.php:1769
2422
+ msgid "Title [All in One SEO]"
2423
  msgstr ""
2424
 
2425
+ #: includes/classes/class-woo-feed-product-attributes.php:390, includes/classes/class-woo-feed-products.php:1770
2426
+ msgid "Description [All in One SEO]"
2427
  msgstr ""
2428
 
2429
+ #: includes/classes/class-woo-feed-product-attributes.php:391
2430
+ msgid "Canonical URL [All in One SEO]"
2431
  msgstr ""
2432
 
2433
+ #: includes/classes/class-woo-feed-product-attributes.php:417
2434
+ msgid "Product Attributes"
2435
  msgstr ""
2436
 
2437
+ #: includes/classes/class-woo-feed-product-attributes.php:438, includes/classes/class-woo-feed-products.php:1813
2438
+ msgid "Product Custom Attributes"
2439
  msgstr ""
2440
 
2441
+ #: includes/classes/class-woo-feed-product-attributes.php:534
2442
+ msgid "Product Taxonomies"
2443
  msgstr ""
2444
 
2445
+ #: includes/classes/class-woo-feed-product-attributes.php:550
2446
+ msgid "Options"
2447
  msgstr ""
2448
 
2449
+ #: includes/classes/class-woo-feed-product-attributes.php:616
2450
+ msgid "Advance Custom Fields (ACF)"
2451
  msgstr ""
2452
 
2453
+ #: includes/classes/class-woo-feed-product-attributes.php:724
2454
+ msgid "Custom Fields & Post Metas"
2455
  msgstr ""
2456
 
2457
+ #: includes/classes/class-woo-feed-product-attributes.php:754
2458
+ msgid "Dynamic Attributes"
2459
  msgstr ""
2460
 
2461
+ #: includes/classes/class-woo-feed-product-attributes.php:778
2462
+ msgid "Attribute Mappings"
2463
  msgstr ""
2464
 
2465
+ #: includes/classes/class-woo-feed-product-attributes.php:790
2466
+ msgid "WPML Attributes"
2467
  msgstr ""
2468
 
2469
+ #: includes/classes/class-woo-feed-product-attributes.php:792
2470
+ msgid "Parent Product ID"
2471
  msgstr ""
2472
 
2473
+ #: includes/classes/class-woo-feed-product-attributes.php:807
2474
+ msgid "Multi Vendor Attributes"
2475
  msgstr ""
2476
 
2477
+ #: includes/classes/class-woo-feed-product-attributes.php:809
2478
+ msgid "Vendor Store Name"
2479
  msgstr ""
2480
 
2481
  #: includes/classes/class-woo-feed-products.php:1715
2486
  msgid "Condition"
2487
  msgstr ""
2488
 
2489
+ #: includes/classes/class-woo-feed-products.php:1738
2490
+ msgid "Variation Type"
2491
+ msgstr ""
2492
+
2493
+ #: includes/classes/class-woo-feed-products.php:1793
2494
+ msgid "Image Attributes"
2495
+ msgstr ""
2496
+
2497
  #: includes/classes/class-woo-feed-products.php:1821
2498
  msgid "Custom Fields/Post Meta"
2499
  msgstr ""
2615
  msgid "WooCommerce Dynamic Pricing & Discounts"
2616
  msgstr ""
2617
 
2618
+ #: includes/classes/class-woo-feed-webappick-api.php:465
2619
+ msgid "Request Successful."
2620
+ msgstr ""
2621
+
2622
  #: libs/WebAppick/AppServices/Insights.php:332
2623
  msgid "Server environment details (php, mysql, server, WordPress versions)."
2624
  msgstr ""
woo-feed.php CHANGED
@@ -10,7 +10,7 @@
10
  * Plugin Name: CTX Feed
11
  * Plugin URI: https://webappick.com/
12
  * Description: Easily generate woocommerce product feed for any marketing channel like Google Shopping(Merchant), Facebook Remarketing, Bing, eBay & more. Support 100+ Merchants.
13
- * Version: 4.4.67
14
  * Author: WebAppick
15
  * Author URI: https://webappick.com/
16
  * License: GPL v2
10
  * Plugin Name: CTX Feed
11
  * Plugin URI: https://webappick.com/
12
  * Description: Easily generate woocommerce product feed for any marketing channel like Google Shopping(Merchant), Facebook Remarketing, Bing, eBay & more. Support 100+ Merchants.
13
+ * Version: 4.4.68
14
  * Author: WebAppick
15
  * Author URI: https://webappick.com/
16
  * License: GPL v2