Version Description
(2019-11-03) = * Loading ClipboardJS directly from plugin for older WordPress * Added WooCommerce minimum version checking before loading other dependencies * Fix support for WooCommerce older than 3.6.0
Download this release
Release Info
Developer | wahid0003 |
Plugin | CTX Feed – WooCommerce Product Feed Manager Plugin |
Version | 3.1.45 |
Comparing to | |
See all releases |
Code changes from version 3.1.44 to 3.1.45
- README.txt +6 -1
- admin/class-woo-feed-admin.php +5 -3
- admin/js/clipboard.min.js +7 -0
- includes/class-woo-feed.php +45 -42
- includes/feeds/class-woo-feed-become.php +667 -667
- includes/feeds/class-woo-feed-bing.php +650 -650
- includes/feeds/class-woo-feed-connexity.php +667 -667
- includes/feeds/class-woo-feed-facebook.php +523 -523
- includes/feeds/class-woo-feed-google.php +629 -629
- includes/feeds/class-woo-feed-kelkoo.php +437 -437
- includes/feeds/class-woo-feed-nextag.php +113 -113
- includes/feeds/class-woo-feed-pricegrabber.php +479 -479
- includes/feeds/class-woo-feed-shopmania.php +467 -467
- includes/feeds/class-woo-feed-shopping.php +703 -703
- includes/feeds/class-woo-feed-shopzilla.php +667 -667
- includes/helper.php +127 -24
- includes/wc-legacy-support.php +26 -0
- woo-feed.php +17 -19
README.txt
CHANGED
@@ -4,7 +4,7 @@ Donate link: https://webappick.com
|
|
4 |
Tags:woocommerce,google product feed,facebook product feed,woocommerce product feed,woocommerce,
|
5 |
Requires at least: 3.6
|
6 |
Tested Up To: 5.3
|
7 |
-
Stable tag: 3.1.
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
@@ -304,6 +304,11 @@ Using pro version:
|
|
304 |
|
305 |
== Changelog ==
|
306 |
|
|
|
|
|
|
|
|
|
|
|
307 |
= 3.1.44 (2019-10-31) =
|
308 |
* Remove Duplicate Css
|
309 |
* Fix success message not showing
|
4 |
Tags:woocommerce,google product feed,facebook product feed,woocommerce product feed,woocommerce,
|
5 |
Requires at least: 3.6
|
6 |
Tested Up To: 5.3
|
7 |
+
Stable tag: 3.1.45
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
304 |
|
305 |
== Changelog ==
|
306 |
|
307 |
+
= 3.1.45 (2019-11-03) =
|
308 |
+
* Loading ClipboardJS directly from plugin for older WordPress
|
309 |
+
* Added WooCommerce minimum version checking before loading other dependencies
|
310 |
+
* Fix support for WooCommerce older than 3.6.0
|
311 |
+
|
312 |
= 3.1.44 (2019-10-31) =
|
313 |
* Remove Duplicate Css
|
314 |
* Fix success message not showing
|
admin/class-woo-feed-admin.php
CHANGED
@@ -96,14 +96,16 @@ class Woo_Feed_Admin
|
|
96 |
* between the defined hooks and the functions defined in this
|
97 |
* class.
|
98 |
*/
|
99 |
-
|
100 |
-
|
101 |
wp_register_script( "jquery-selectize", plugin_dir_url(__FILE__) . 'js/selectize.min.js', array( 'jquery' ), $this->version, false );
|
102 |
wp_register_script( "jquery-validate", plugin_dir_url(__FILE__) . 'js/jquery.validate.min.js', array( 'jquery' ), $this->version, false );
|
103 |
wp_register_script( "jquery-validate-additional-methods", plugin_dir_url(__FILE__) . 'js/additional-methods.min.js', array( 'jquery', 'jquery-validate' ), $this->version, false );
|
104 |
wp_register_script( "jquery-sortable", plugin_dir_url(__FILE__) . 'js/jquery-sortable.js', array( 'jquery' ), $this->version, false );
|
105 |
wp_register_script( "jquery-slick", plugin_dir_url(__FILE__) . 'js/slick.js', array( 'jquery' ), $this->version, false );
|
106 |
-
|
|
|
|
|
|
|
107 |
$mainDeps = array( 'jquery', 'clipboard', 'jquery-selectize', 'jquery-sortable', 'jquery-validate', 'jquery-validate-additional-methods' );
|
108 |
if( $hook == 'woo-feed_page_webappick-feed-pro-vs-free' ) {
|
109 |
$mainDeps[] = 'jquery-slick';
|
96 |
* between the defined hooks and the functions defined in this
|
97 |
* class.
|
98 |
*/
|
99 |
+
|
|
|
100 |
wp_register_script( "jquery-selectize", plugin_dir_url(__FILE__) . 'js/selectize.min.js', array( 'jquery' ), $this->version, false );
|
101 |
wp_register_script( "jquery-validate", plugin_dir_url(__FILE__) . 'js/jquery.validate.min.js', array( 'jquery' ), $this->version, false );
|
102 |
wp_register_script( "jquery-validate-additional-methods", plugin_dir_url(__FILE__) . 'js/additional-methods.min.js', array( 'jquery', 'jquery-validate' ), $this->version, false );
|
103 |
wp_register_script( "jquery-sortable", plugin_dir_url(__FILE__) . 'js/jquery-sortable.js', array( 'jquery' ), $this->version, false );
|
104 |
wp_register_script( "jquery-slick", plugin_dir_url(__FILE__) . 'js/slick.js', array( 'jquery' ), $this->version, false );
|
105 |
+
if( ! wp_script_is( 'clipboard', 'registered' ) ) {
|
106 |
+
wp_register_script( 'clipboard', plugin_dir_url(__FILE__) . 'js/clipboard.min.js', [], '2.0.4', false);
|
107 |
+
}
|
108 |
+
|
109 |
$mainDeps = array( 'jquery', 'clipboard', 'jquery-selectize', 'jquery-sortable', 'jquery-validate', 'jquery-validate-additional-methods' );
|
110 |
if( $hook == 'woo-feed_page_webappick-feed-pro-vs-free' ) {
|
111 |
$mainDeps[] = 'jquery-slick';
|
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}}}])});
|
includes/class-woo-feed.php
CHANGED
@@ -12,7 +12,7 @@
|
|
12 |
* @package Woo_Feed
|
13 |
* @subpackage Woo_Feed/includes
|
14 |
*/
|
15 |
-
|
16 |
/**
|
17 |
* The core plugin class.
|
18 |
*
|
@@ -67,14 +67,9 @@ class Woo_Feed
|
|
67 |
*
|
68 |
* @since 1.0.0
|
69 |
*/
|
70 |
-
public function __construct()
|
71 |
-
{
|
72 |
$this->woo_feed = 'woo-feed';
|
73 |
$this->version = WOO_FEED_VERSION;
|
74 |
-
$this->load_dependencies();
|
75 |
-
$this->set_locale();
|
76 |
-
$this->define_admin_hooks();
|
77 |
-
$this->define_public_hooks();
|
78 |
}
|
79 |
|
80 |
|
@@ -95,107 +90,109 @@ class Woo_Feed
|
|
95 |
* @since 1.0.0
|
96 |
* @access private
|
97 |
*/
|
98 |
-
private function load_dependencies()
|
99 |
-
|
100 |
-
|
|
|
|
|
101 |
/**
|
102 |
* The class responsible for orchestrating the actions and filters of the
|
103 |
* core plugin.
|
104 |
*/
|
105 |
-
require_once
|
106 |
|
107 |
/**
|
108 |
* The class responsible for defining internationalization functionality
|
109 |
* of the plugin.
|
110 |
*/
|
111 |
-
require_once
|
112 |
|
113 |
/**
|
114 |
* The class responsible for getting all product information
|
115 |
* of the plugin.
|
116 |
*/
|
117 |
-
require_once
|
118 |
|
119 |
/**
|
120 |
* The class responsible for processing feed
|
121 |
*/
|
122 |
-
require_once
|
123 |
|
124 |
/**
|
125 |
* The class contain all merchants attribute dropdown
|
126 |
*/
|
127 |
-
require_once
|
128 |
|
129 |
/**
|
130 |
* The class contain merchant attributes
|
131 |
*/
|
132 |
-
require_once
|
133 |
|
134 |
/**
|
135 |
* The class responsible for generating feed
|
136 |
*/
|
137 |
-
require_once
|
138 |
|
139 |
/**
|
140 |
* The class is a FTP library
|
141 |
*/
|
142 |
-
require_once
|
143 |
|
144 |
/**
|
145 |
* The class
|
146 |
*/
|
147 |
-
require_once
|
148 |
|
149 |
|
150 |
/**
|
151 |
* The class responsible for save feed
|
152 |
*/
|
153 |
-
require_once
|
154 |
-
require_once
|
155 |
/**
|
156 |
* Merchant classes
|
157 |
*/
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
require_once
|
169 |
-
require_once
|
170 |
-
require_once
|
171 |
-
require_once
|
172 |
/**
|
173 |
* Docs Page Class
|
174 |
*/
|
175 |
-
require_once
|
176 |
/**
|
177 |
* The class responsible for defining all actions that occur in the admin area.
|
178 |
*/
|
179 |
-
require_once
|
180 |
|
181 |
/**
|
182 |
* The class responsible for defining all actions that occur in the public area.
|
183 |
*/
|
184 |
-
require_once
|
185 |
|
186 |
/**
|
187 |
* The class responsible for making list table
|
188 |
*/
|
189 |
|
190 |
-
require_once
|
191 |
|
192 |
|
193 |
/**
|
194 |
* The class responsible for making feed list
|
195 |
*/
|
196 |
-
require_once
|
197 |
|
198 |
-
require_once
|
199 |
|
200 |
$this->loader = new Woo_Feed_Loader();
|
201 |
|
@@ -261,7 +258,13 @@ class Woo_Feed
|
|
261 |
*/
|
262 |
public function run()
|
263 |
{
|
264 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
265 |
}
|
266 |
|
267 |
/**
|
12 |
* @package Woo_Feed
|
13 |
* @subpackage Woo_Feed/includes
|
14 |
*/
|
15 |
+
/** @define "WOO_FEED_PATH" "./../" */
|
16 |
/**
|
17 |
* The core plugin class.
|
18 |
*
|
67 |
*
|
68 |
* @since 1.0.0
|
69 |
*/
|
70 |
+
public function __construct() {
|
|
|
71 |
$this->woo_feed = 'woo-feed';
|
72 |
$this->version = WOO_FEED_VERSION;
|
|
|
|
|
|
|
|
|
73 |
}
|
74 |
|
75 |
|
90 |
* @since 1.0.0
|
91 |
* @access private
|
92 |
*/
|
93 |
+
private function load_dependencies() {
|
94 |
+
/**
|
95 |
+
* Support for older version of WooCommerce
|
96 |
+
*/
|
97 |
+
require_once WOO_FEED_PATH . 'includes/wc-legacy-support.php';
|
98 |
/**
|
99 |
* The class responsible for orchestrating the actions and filters of the
|
100 |
* core plugin.
|
101 |
*/
|
102 |
+
require_once WOO_FEED_PATH . 'includes/class-woo-feed-loader.php';
|
103 |
|
104 |
/**
|
105 |
* The class responsible for defining internationalization functionality
|
106 |
* of the plugin.
|
107 |
*/
|
108 |
+
require_once WOO_FEED_PATH . 'includes/class-woo-feed-i18n.php';
|
109 |
|
110 |
/**
|
111 |
* The class responsible for getting all product information
|
112 |
* of the plugin.
|
113 |
*/
|
114 |
+
require_once WOO_FEED_PATH . 'includes/classes/class-woo-feed-products.php';
|
115 |
|
116 |
/**
|
117 |
* The class responsible for processing feed
|
118 |
*/
|
119 |
+
require_once WOO_FEED_PATH . 'includes/classes/class-woo-feed-engine.php';
|
120 |
|
121 |
/**
|
122 |
* The class contain all merchants attribute dropdown
|
123 |
*/
|
124 |
+
require_once WOO_FEED_PATH . 'includes/classes/class-woo-feed-dropdown.php';
|
125 |
|
126 |
/**
|
127 |
* The class contain merchant attributes
|
128 |
*/
|
129 |
+
require_once WOO_FEED_PATH . 'includes/classes/class-woo-feed-default-attributes.php';
|
130 |
|
131 |
/**
|
132 |
* The class responsible for generating feed
|
133 |
*/
|
134 |
+
require_once WOO_FEED_PATH . 'includes/feeds/class-woo-feed-generate.php';
|
135 |
|
136 |
/**
|
137 |
* The class is a FTP library
|
138 |
*/
|
139 |
+
require_once WOO_FEED_PATH . 'includes/classes/class-woo-feed-ftp.php';
|
140 |
|
141 |
/**
|
142 |
* The class
|
143 |
*/
|
144 |
+
require_once WOO_FEED_PATH . 'includes/classes/class-woo-feed-auto-update.php';
|
145 |
|
146 |
|
147 |
/**
|
148 |
* The class responsible for save feed
|
149 |
*/
|
150 |
+
require_once WOO_FEED_PATH . 'includes/classes/class-woo-feed-savefile.php';
|
151 |
+
require_once WOO_FEED_PATH . 'includes/classes/class-woo-feed-admin-message.php';
|
152 |
/**
|
153 |
* Merchant classes
|
154 |
*/
|
155 |
+
require_once WOO_FEED_PATH . 'includes/feeds/class-woo-feed-google.php';
|
156 |
+
require_once WOO_FEED_PATH . 'includes/feeds/class-woo-feed-amazon.php';
|
157 |
+
require_once WOO_FEED_PATH . 'includes/feeds/class-woo-feed-facebook.php';
|
158 |
+
require_once WOO_FEED_PATH . 'includes/feeds/class-woo-feed-nextag.php';
|
159 |
+
require_once WOO_FEED_PATH . 'includes/feeds/class-woo-feed-pinterest.php';
|
160 |
+
require_once WOO_FEED_PATH . 'includes/feeds/class-woo-feed-kelkoo.php';
|
161 |
+
require_once WOO_FEED_PATH . 'includes/feeds/class-woo-feed-pricegrabber.php';
|
162 |
+
require_once WOO_FEED_PATH . 'includes/feeds/class-woo-feed-shopzilla.php';
|
163 |
+
require_once WOO_FEED_PATH . 'includes/feeds/class-woo-feed-shopmania.php';
|
164 |
+
require_once WOO_FEED_PATH . 'includes/feeds/class-woo-feed-shopping.php';
|
165 |
+
require_once WOO_FEED_PATH . 'includes/feeds/class-woo-feed-bing.php';
|
166 |
+
require_once WOO_FEED_PATH . 'includes/feeds/class-woo-feed-become.php';
|
167 |
+
require_once WOO_FEED_PATH . 'includes/feeds/class-woo-feed-connexity.php';
|
168 |
+
require_once WOO_FEED_PATH . 'includes/feeds/class-woo-feed-custom.php';
|
169 |
/**
|
170 |
* Docs Page Class
|
171 |
*/
|
172 |
+
require_once WOO_FEED_PATH . 'includes/class-woo-feed-docs.php';
|
173 |
/**
|
174 |
* The class responsible for defining all actions that occur in the admin area.
|
175 |
*/
|
176 |
+
require_once WOO_FEED_PATH . 'admin/class-woo-feed-admin.php';
|
177 |
|
178 |
/**
|
179 |
* The class responsible for defining all actions that occur in the public area.
|
180 |
*/
|
181 |
+
require_once WOO_FEED_PATH . 'public/class-woo-feed-public.php';
|
182 |
|
183 |
/**
|
184 |
* The class responsible for making list table
|
185 |
*/
|
186 |
|
187 |
+
require_once WOO_FEED_PATH . 'includes/classes/class-woo-feed-list-table.php';
|
188 |
|
189 |
|
190 |
/**
|
191 |
* The class responsible for making feed list
|
192 |
*/
|
193 |
+
require_once WOO_FEED_PATH . 'admin/class-woo-feed-manage-list.php';
|
194 |
|
195 |
+
require_once WOO_FEED_PATH . 'includes/classes/class-woo-feed-sftp.php';
|
196 |
|
197 |
$this->loader = new Woo_Feed_Loader();
|
198 |
|
258 |
*/
|
259 |
public function run()
|
260 |
{
|
261 |
+
if( wooFeed_check_WC() && wooFeed_is_WC_supported() ) {
|
262 |
+
$this->load_dependencies();
|
263 |
+
$this->set_locale();
|
264 |
+
$this->define_admin_hooks();
|
265 |
+
$this->define_public_hooks();
|
266 |
+
$this->loader->run();
|
267 |
+
}
|
268 |
}
|
269 |
|
270 |
/**
|
includes/feeds/class-woo-feed-become.php
CHANGED
@@ -1,668 +1,668 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Class Become
|
5 |
-
*
|
6 |
-
* Responsible for processing and generating feed for Become.com
|
7 |
-
*
|
8 |
-
* @since 1.0.0
|
9 |
-
* @package Become
|
10 |
-
*
|
11 |
-
*/
|
12 |
-
class Become
|
13 |
-
{
|
14 |
-
|
15 |
-
/**
|
16 |
-
* This variable is responsible for holding all product attributes and their values
|
17 |
-
*
|
18 |
-
* @since 1.0.0
|
19 |
-
* @var array $products Contains all the product attributes to generate feed
|
20 |
-
* @access public
|
21 |
-
*/
|
22 |
-
public $products;
|
23 |
-
|
24 |
-
/**
|
25 |
-
* This variable is responsible for holding feed configuration form values
|
26 |
-
*
|
27 |
-
* @since 1.0.0
|
28 |
-
* @var Become $rules Contains feed configuration form values
|
29 |
-
* @access public
|
30 |
-
*/
|
31 |
-
public $rules;
|
32 |
-
|
33 |
-
/**
|
34 |
-
* This variable is responsible for mapping store attributes to merchant attribute
|
35 |
-
*
|
36 |
-
* @since 1.0.0
|
37 |
-
* @var Become $mapping Map store attributes to merchant attribute
|
38 |
-
* @access public
|
39 |
-
*/
|
40 |
-
public $mapping;
|
41 |
-
|
42 |
-
/**
|
43 |
-
* This variable is responsible for generate error logs
|
44 |
-
*
|
45 |
-
* @since 1.0.0
|
46 |
-
* @var Become $errorLog Generate error logs
|
47 |
-
* @access public
|
48 |
-
*/
|
49 |
-
public $errorLog;
|
50 |
-
|
51 |
-
/**
|
52 |
-
* This variable is responsible for making error number
|
53 |
-
*
|
54 |
-
* @since 1.0.0
|
55 |
-
* @var Become $errorCounter Generate error number
|
56 |
-
* @access public
|
57 |
-
*/
|
58 |
-
public $errorCounter;
|
59 |
-
|
60 |
-
/**
|
61 |
-
* Feed Wrapper text for enclosing each product information
|
62 |
-
*
|
63 |
-
* @since 1.0.0
|
64 |
-
* @var Become $feedWrapper Feed Wrapper text
|
65 |
-
* @access public
|
66 |
-
*/
|
67 |
-
private $feedWrapper;
|
68 |
-
|
69 |
-
/**
|
70 |
-
* Define the core functionality to generate feed.
|
71 |
-
*
|
72 |
-
* Set the feed rules. Map products according to the rules and Check required attributes
|
73 |
-
* and their values according to merchant specification.
|
74 |
-
* @var Woo_Generate_Feed $feedRule Contain Feed Configuration
|
75 |
-
* @since 1.0.0
|
76 |
-
*/
|
77 |
-
public function __construct($feedRule)
|
78 |
-
{
|
79 |
-
$this->feedWrapper = 'product';
|
80 |
-
$this->errorCounter = 0;
|
81 |
-
$this->rules = $feedRule;
|
82 |
-
$this->mapProductsByRules();
|
83 |
-
$this->formatRequiredField();
|
84 |
-
$this->filterProductValues();
|
85 |
-
if ($this->rules['feedType'] == 'xml') {
|
86 |
-
$this->mapAttributeForXML();
|
87 |
-
} else {
|
88 |
-
$this->mapAttributeForCSVTEXT();
|
89 |
-
}
|
90 |
-
}
|
91 |
-
|
92 |
-
/**
|
93 |
-
* Configure merchant attributes for XML feed
|
94 |
-
*/
|
95 |
-
public function mapAttributeForXML()
|
96 |
-
{
|
97 |
-
//Basic product information
|
98 |
-
|
99 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
100 |
-
foreach ($this->products as $key => $values) {
|
101 |
-
foreach ($values as $attr => $value) {
|
102 |
-
$this->products[$key][$attr] = $this->formatXMLLine($attr, $value, true, true, true);
|
103 |
-
}
|
104 |
-
}
|
105 |
-
}
|
106 |
-
}
|
107 |
-
|
108 |
-
/**
|
109 |
-
* Configure merchant attributes for CSV and TXT feed
|
110 |
-
*/
|
111 |
-
public function mapAttributeForCSVTEXT()
|
112 |
-
{
|
113 |
-
//Basic product information
|
114 |
-
|
115 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
116 |
-
foreach ($this->products as $key => $values) {
|
117 |
-
foreach ($values as $attr => $value) {
|
118 |
-
//Allow force strip HTML
|
119 |
-
$value = strip_tags(html_entity_decode($value));
|
120 |
-
if ($attr != 'Category') {
|
121 |
-
$value = utf8_encode($value);
|
122 |
-
$attr = utf8_encode($attr);
|
123 |
-
|
124 |
-
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
|
125 |
-
|
126 |
-
if (gettype($value) == 'array')
|
127 |
-
$value = json_encode($value);
|
128 |
-
}
|
129 |
-
|
130 |
-
$this->products[$key][$attr] = $value;
|
131 |
-
}
|
132 |
-
}
|
133 |
-
}
|
134 |
-
}
|
135 |
-
|
136 |
-
/**
|
137 |
-
* Check all the required attributes and make error message
|
138 |
-
*/
|
139 |
-
public function formatRequiredField()
|
140 |
-
{
|
141 |
-
foreach ($this->products as $no => $product) {
|
142 |
-
$upn = 0;
|
143 |
-
if (array_key_exists('Unique ID', $product)) {
|
144 |
-
$id = $product['Unique ID'];
|
145 |
-
} else {
|
146 |
-
$id = $product['Title'];
|
147 |
-
}
|
148 |
-
|
149 |
-
if (!array_key_exists('Unique ID', $product)) {
|
150 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Unique ID</b>] Missing for <b>$id</b>.";
|
151 |
-
$this->errorCounter++;
|
152 |
-
}
|
153 |
-
|
154 |
-
|
155 |
-
if (!array_key_exists('Title', $product)) {
|
156 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Title</b>] Missing for <b>$id</b>.";
|
157 |
-
$this->errorCounter++;
|
158 |
-
}
|
159 |
-
|
160 |
-
if (!array_key_exists('Description', $product)) {
|
161 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Description</b>] Missing for <b>$id</b>.";
|
162 |
-
$this->errorCounter++;
|
163 |
-
}
|
164 |
-
|
165 |
-
if (!array_key_exists('Category', $product)) {
|
166 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Category</b>] Missing for <b>$id</b>.";
|
167 |
-
$this->errorCounter++;
|
168 |
-
}
|
169 |
-
|
170 |
-
if (!array_key_exists('Product URL', $product)) {
|
171 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Product URL</b>] Missing for <b>$id</b>.";
|
172 |
-
$this->errorCounter++;
|
173 |
-
}
|
174 |
-
|
175 |
-
if (!array_key_exists('Image URL', $product)) {
|
176 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Image URL</b>] Missing for <b>$id</b>.";
|
177 |
-
$this->errorCounter++;
|
178 |
-
}
|
179 |
-
|
180 |
-
if (!array_key_exists('Condition', $product)) {
|
181 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Condition</b>] Missing for <b>$id</b>.";
|
182 |
-
$this->errorCounter++;
|
183 |
-
}
|
184 |
-
|
185 |
-
if (!array_key_exists('Availability', $product)) {
|
186 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Availability</b>] Missing for <b>$id</b>.";
|
187 |
-
$this->errorCounter++;
|
188 |
-
}
|
189 |
-
|
190 |
-
if (!array_key_exists('Current price', $product)) {
|
191 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Current price</b>] Missing for <b>$id</b>.";
|
192 |
-
$this->errorCounter++;
|
193 |
-
}
|
194 |
-
}
|
195 |
-
}
|
196 |
-
|
197 |
-
/**
|
198 |
-
* Return Feed
|
199 |
-
*
|
200 |
-
* @return array|bool|string
|
201 |
-
*/
|
202 |
-
public function returnFinalProduct()
|
203 |
-
{
|
204 |
-
if ($this->rules['feedType'] == 'xml') {
|
205 |
-
return $this->get_feed($this->products);
|
206 |
-
} elseif ($this->rules['feedType'] == 'txt') {
|
207 |
-
return $this->get_txt_feed();
|
208 |
-
} elseif ($this->rules['feedType'] == 'csv') {
|
209 |
-
return $this->get_csv_feed();
|
210 |
-
}
|
211 |
-
return false;
|
212 |
-
}
|
213 |
-
|
214 |
-
/**
|
215 |
-
* Check product's attribute value according to merchant specifications
|
216 |
-
*/
|
217 |
-
public function filterProductValues()
|
218 |
-
{
|
219 |
-
$getProduct = new Woo_Feed_Products();
|
220 |
-
$products = $this->products;
|
221 |
-
|
222 |
-
foreach ($products as $no => $product) {
|
223 |
-
if (array_key_exists('Unique ID', $product)) {
|
224 |
-
$id = $product['Unique ID'];
|
225 |
-
} else {
|
226 |
-
$id = $product['Title'];
|
227 |
-
}
|
228 |
-
// echo "<pre>";
|
229 |
-
// print_r($product);
|
230 |
-
foreach ($product as $key => $value) {
|
231 |
-
switch ($key) {
|
232 |
-
case "Unique ID":
|
233 |
-
if (strlen($value) > 100) {
|
234 |
-
$this->errorLog[$this->errorCounter] = "[<b>Unique ID</b>] is more that 100 character for $id.";
|
235 |
-
$this->errorCounter++;
|
236 |
-
}
|
237 |
-
break;
|
238 |
-
case "Title":
|
239 |
-
if (strlen($value) > 1000) {
|
240 |
-
$this->errorLog[$this->errorCounter] = "[<b>Title</b>] is more that 1000 character for $id.";
|
241 |
-
$this->errorCounter++;
|
242 |
-
}
|
243 |
-
break;
|
244 |
-
case "Description":
|
245 |
-
if (strlen($value) > 3000) {
|
246 |
-
$this->errorLog[$this->errorCounter] = "[<b>Description</b>] is more that 3000 character for $id.";
|
247 |
-
$this->errorCounter++;
|
248 |
-
}
|
249 |
-
break;
|
250 |
-
case "Category":
|
251 |
-
if (strlen($value) > 1000) {
|
252 |
-
$this->errorLog[$this->errorCounter] = "[<b>Category</b>] is more that 1000 character for $id.";
|
253 |
-
$this->errorCounter++;
|
254 |
-
}
|
255 |
-
break;
|
256 |
-
case "Product URL":
|
257 |
-
if (strpos($value, 'http://') == false || strpos($value, 'https://') == false) {
|
258 |
-
$this->errorLog[$this->errorCounter] = "[<b>Product URL</b>] must start with http:// or https:// for $id.";
|
259 |
-
$this->errorCounter++;
|
260 |
-
}
|
261 |
-
|
262 |
-
if (strlen($value) > 2000) {
|
263 |
-
$this->errorLog[$this->errorCounter] = "[<b>Product URL</b>] is more that 2000 character for $id.";
|
264 |
-
$this->errorCounter++;
|
265 |
-
}
|
266 |
-
|
267 |
-
break;
|
268 |
-
case "Image URL":
|
269 |
-
if (strpos($value, 'http://') == false || strpos($value, 'https://') == false) {
|
270 |
-
$this->errorLog[$this->errorCounter] = "[<b>Image URL</b>] must start with http:// or https:// for $id.";
|
271 |
-
$this->errorCounter++;
|
272 |
-
}
|
273 |
-
|
274 |
-
if (strlen($value) > 2000) {
|
275 |
-
$this->errorLog[$this->errorCounter] = "[<b>Image URL</b>] is more that 2000 character for $id.";
|
276 |
-
$this->errorCounter++;
|
277 |
-
}
|
278 |
-
|
279 |
-
list($width, $height) = getimagesize($value);
|
280 |
-
if ($width < 450 || $height < 450) {
|
281 |
-
$this->errorLog[$this->errorCounter] = "<b>Image Width and Height</b> should be more that 450px for $id.";
|
282 |
-
$this->errorCounter++;
|
283 |
-
}
|
284 |
-
|
285 |
-
break;
|
286 |
-
case "Condition":
|
287 |
-
$condition = array("New", "Used", "Refurbished", "Open Box", "OEM");
|
288 |
-
if (!array_key_exists($value, $condition)) {
|
289 |
-
$this->errorLog[$this->errorCounter] = "[<b>Condition</b>] = $value is acceptable for $id.";
|
290 |
-
$this->errorCounter++;
|
291 |
-
}
|
292 |
-
break;
|
293 |
-
case "Availability":
|
294 |
-
$availability = array("In Stock", "Out of Stock", "Available for Order", "PreOrder");
|
295 |
-
if ($value == 'in stock') {
|
296 |
-
$this->products[$no][$key] = "In Stock";
|
297 |
-
} else {
|
298 |
-
$this->products[$no][$key] = "Out of Stock";
|
299 |
-
}
|
300 |
-
|
301 |
-
if (!array_key_exists($this->products[$no][$key], $availability)) {
|
302 |
-
$this->errorLog[$this->errorCounter] = "[<b>Availability</b>] = $value is acceptable for $id.";
|
303 |
-
$this->errorCounter++;
|
304 |
-
}
|
305 |
-
break;
|
306 |
-
case "Current price":
|
307 |
-
if (!is_numeric($value)) {
|
308 |
-
$this->errorLog[$this->errorCounter] = "[<b>Current price</b>] should be numeric for $id.";
|
309 |
-
$this->errorCounter++;
|
310 |
-
}
|
311 |
-
break;
|
312 |
-
case "Original Price":
|
313 |
-
if (!is_numeric($value)) {
|
314 |
-
$this->errorLog[$this->errorCounter] = "[<b>Original price</b>] should be numeric for $id.";
|
315 |
-
$this->errorCounter++;
|
316 |
-
}
|
317 |
-
break;
|
318 |
-
default:
|
319 |
-
break;
|
320 |
-
}
|
321 |
-
}
|
322 |
-
}
|
323 |
-
}
|
324 |
-
|
325 |
-
/**
|
326 |
-
* Return Dynamic Category Mapping Values by Parent Product Id
|
327 |
-
*
|
328 |
-
* @param string $mappingName Category Mapping Name
|
329 |
-
* @param int $parent Parent id of the product
|
330 |
-
* @return mixed
|
331 |
-
*/
|
332 |
-
public function get_category_mapping_value($mappingName, $parent)
|
333 |
-
{
|
334 |
-
$getValue = unserialize(get_option($mappingName));
|
335 |
-
$mapp = array_reverse($getValue['cmapping'], true);
|
336 |
-
$categories = get_the_terms($parent, 'product_cat');
|
337 |
-
|
338 |
-
foreach ($categories as $key => $category) {
|
339 |
-
if (!empty($mapp[$category->term_id]))
|
340 |
-
return $mapp[$category->term_id];
|
341 |
-
}
|
342 |
-
return false;
|
343 |
-
}
|
344 |
-
|
345 |
-
/**
|
346 |
-
* Configure the feed according to the rules
|
347 |
-
* @return Shopping
|
348 |
-
*/
|
349 |
-
public function mapProductsByRules()
|
350 |
-
{
|
351 |
-
/**
|
352 |
-
* Get WooCommerce Products
|
353 |
-
* @package Woo_Feed_Products
|
354 |
-
*/
|
355 |
-
$products = new Woo_Feed_Products();
|
356 |
-
|
357 |
-
/**
|
358 |
-
* This variable contain selected Woo attributes from feed making form
|
359 |
-
*
|
360 |
-
* @since 1.0.0
|
361 |
-
* @var array $attributes contain selected Woo attributes from feed making form
|
362 |
-
*/
|
363 |
-
$attributes = $this->rules['attributes'];
|
364 |
-
/**
|
365 |
-
* This variable contain selected Prefix Values from feed making form
|
366 |
-
*
|
367 |
-
* @since 1.0.0
|
368 |
-
* @var array $prefix Prefix Values from feed making form
|
369 |
-
*/
|
370 |
-
$prefix = $this->rules['prefix'];
|
371 |
-
/**
|
372 |
-
* This variable contain selected Prefix Values from feed making form
|
373 |
-
*
|
374 |
-
* @since 1.0.0
|
375 |
-
* @var array $suffix Suffix Values from feed making form
|
376 |
-
*/
|
377 |
-
$suffix = $this->rules['suffix'];
|
378 |
-
/**
|
379 |
-
* This variable contain selected Output Types from feed making form
|
380 |
-
*
|
381 |
-
* @since 1.0.0
|
382 |
-
* @var array $outputType Output Types from feed making form
|
383 |
-
*/
|
384 |
-
$outputType = $this->rules['output_type'];
|
385 |
-
|
386 |
-
/**
|
387 |
-
* This variable contain selected Output Limit from feed making form
|
388 |
-
*
|
389 |
-
* @since 1.0.0
|
390 |
-
* @var array $limit Output Limit from feed making form
|
391 |
-
*/
|
392 |
-
$limit = $this->rules['limit'];
|
393 |
-
/**
|
394 |
-
* This variable contain selected Merchant attributes from feed making form
|
395 |
-
*
|
396 |
-
* @since 1.0.0
|
397 |
-
* @var array $merchantAttributes contain selected Woo attributes from feed making form
|
398 |
-
*/
|
399 |
-
$merchantAttributes = $this->rules['mattributes'];
|
400 |
-
/**
|
401 |
-
* This variable contain attribute types from feed making form
|
402 |
-
*
|
403 |
-
* @since 1.0.0
|
404 |
-
* @var array $type contain attribute types from feed making form
|
405 |
-
*/
|
406 |
-
$type = $this->rules['type'];
|
407 |
-
/**
|
408 |
-
* This variable contain manual output of attribute from feed making form
|
409 |
-
*
|
410 |
-
* @since 1.0.0
|
411 |
-
* @var array $default contain manual output of attribute
|
412 |
-
*/
|
413 |
-
$default = $this->rules['default'];
|
414 |
-
|
415 |
-
/**
|
416 |
-
* This variable contain feed type
|
417 |
-
*
|
418 |
-
* @since 1.0.0
|
419 |
-
* @var array $feedType contain feed type
|
420 |
-
*/
|
421 |
-
$feedType = $this->rules['feedType'];
|
422 |
-
|
423 |
-
// Map Merchant Attributes and Woo Attributes
|
424 |
-
if (count($merchantAttributes)) {
|
425 |
-
foreach ($merchantAttributes as $key => $attr) {
|
426 |
-
if (!empty($attr) && !empty($attributes[$key])) {
|
427 |
-
if ($type[$key] == 'attribute') {
|
428 |
-
$this->mapping[$attr]['value'] = $attributes[$key];
|
429 |
-
$this->mapping[$attr]['suffix'] = $suffix[$key];
|
430 |
-
$this->mapping[$attr]['prefix'] = $prefix[$key];
|
431 |
-
$this->mapping[$attr]['type'] = $outputType[$key];
|
432 |
-
$this->mapping[$attr]['limit'] = $limit[$key];
|
433 |
-
}
|
434 |
-
} else if (empty($attributes[$key])) {
|
435 |
-
if ($type[$key] == 'pattern') {
|
436 |
-
$this->mapping[$attr]['value'] = "wf_pattern_$default[$key]";
|
437 |
-
$this->mapping[$attr]['suffix'] = $suffix[$key];
|
438 |
-
$this->mapping[$attr]['prefix'] = $prefix[$key];
|
439 |
-
$this->mapping[$attr]['type'] = $outputType[$key];
|
440 |
-
$this->mapping[$attr]['limit'] = $limit[$key];
|
441 |
-
}
|
442 |
-
}
|
443 |
-
}
|
444 |
-
}
|
445 |
-
|
446 |
-
// Make Product feed array according to mapping
|
447 |
-
foreach ($products->woo_feed_get_visible_product() as $key => $value) {
|
448 |
-
$i = 0;
|
449 |
-
foreach ($this->mapping as $attr => $rules) {
|
450 |
-
if (array_key_exists($rules['value'], $value)) {
|
451 |
-
|
452 |
-
$output = $rules['prefix'] . $value[$rules['value']] . " " . $rules['suffix'];
|
453 |
-
// Format According to output type
|
454 |
-
if ($rules['type'] == 2) {
|
455 |
-
$output = strip_tags($output);
|
456 |
-
} elseif ($rules['type'] == 3) {
|
457 |
-
$output = absint($output);
|
458 |
-
}
|
459 |
-
// Format According to output limit
|
460 |
-
if (!empty($rules['limit']) && is_numeric($rules['limit'])) {
|
461 |
-
$output = substr($output, 0, $rules['limit']);
|
462 |
-
}
|
463 |
-
$attr = trim($attr);
|
464 |
-
$this->products[$key][$attr] = trim($output);
|
465 |
-
} else {
|
466 |
-
if (!empty($default[$i])) {
|
467 |
-
$output = $rules['prefix'] . str_replace("wf_pattern_", "", $rules['value']) . " " . $rules['suffix'];
|
468 |
-
if ($rules['type'] == 2) {
|
469 |
-
$output = strip_tags($output);
|
470 |
-
} elseif ($rules['type'] == 3) {
|
471 |
-
$output = absint($output);
|
472 |
-
}
|
473 |
-
// Format According to output limit
|
474 |
-
if (!empty($rules['limit']) && is_numeric($rules['limit'])) {
|
475 |
-
$output = substr($output, 0, $rules['limit']);
|
476 |
-
}
|
477 |
-
$attr = trim($attr);
|
478 |
-
$this->products[$key][$attr] = trim($output);
|
479 |
-
}
|
480 |
-
}
|
481 |
-
$i++;
|
482 |
-
}
|
483 |
-
}
|
484 |
-
|
485 |
-
|
486 |
-
return $this->products;
|
487 |
-
}
|
488 |
-
|
489 |
-
/**
|
490 |
-
* Change the products old array key and set new
|
491 |
-
*
|
492 |
-
* @param string $from Attribute Before
|
493 |
-
* @param string $to Attribute After
|
494 |
-
* @param bool $cdata Enclose Feed value
|
495 |
-
*/
|
496 |
-
public function mapAttribute($from, $to, $cdata = false)
|
497 |
-
{
|
498 |
-
$i = 0;
|
499 |
-
foreach ($this->products as $no => $product) {
|
500 |
-
foreach ($product as $key => $value) {
|
501 |
-
if ($key == $from) {
|
502 |
-
unset($this->products[$no][$from]);
|
503 |
-
if ($from == 'images') {
|
504 |
-
$this->products[$no][$to] = $value;
|
505 |
-
} else {
|
506 |
-
$this->products[$no][$to] = $this->formatXMLLine($to, $value, $cdata, true, true);
|
507 |
-
}
|
508 |
-
|
509 |
-
}
|
510 |
-
}
|
511 |
-
$i++;
|
512 |
-
}
|
513 |
-
}
|
514 |
-
|
515 |
-
/**
|
516 |
-
* Format and Make the XML node for the Feed
|
517 |
-
*
|
518 |
-
* @param $attribute
|
519 |
-
* @param $value
|
520 |
-
* @param bool $cdata
|
521 |
-
* @param bool $stripHTML
|
522 |
-
* @param bool $utf8encode
|
523 |
-
* @param string $space
|
524 |
-
* @return string
|
525 |
-
*/
|
526 |
-
function formatXMLLine($attribute, $value, $cdata = false, $stripHTML = true, $utf8encode = true, $space = ' ')
|
527 |
-
{
|
528 |
-
//Make single line for XML
|
529 |
-
$c_leader = '';
|
530 |
-
$c_footer = '';
|
531 |
-
if ($cdata) {
|
532 |
-
$c_leader = '<![CDATA[';
|
533 |
-
$c_footer = ']]>';
|
534 |
-
}
|
535 |
-
//Allow force strip HTML
|
536 |
-
if ($stripHTML)
|
537 |
-
$value = strip_tags(html_entity_decode($value));
|
538 |
-
|
539 |
-
|
540 |
-
if ($utf8encode || $utf8encode == 1) {
|
541 |
-
$value = utf8_encode($value);
|
542 |
-
$attribute = utf8_encode($attribute);
|
543 |
-
}
|
544 |
-
|
545 |
-
|
546 |
-
if (!$cdata)
|
547 |
-
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
|
548 |
-
|
549 |
-
if (gettype($value) == 'array')
|
550 |
-
$value = json_encode($value);
|
551 |
-
|
552 |
-
|
553 |
-
return '
|
554 |
-
' . $space . '<' . $attribute . '>' . $c_leader . $value . $c_footer . '</' . $attribute . '>';
|
555 |
-
}
|
556 |
-
|
557 |
-
/**
|
558 |
-
* Responsible to change product array key
|
559 |
-
*
|
560 |
-
* @param $array
|
561 |
-
* @param $old_key
|
562 |
-
* @param $new_key
|
563 |
-
* @return array
|
564 |
-
*/
|
565 |
-
function change_key($array, $old_key, $new_key)
|
566 |
-
{
|
567 |
-
foreach ($this->products as $no => $product) {
|
568 |
-
if (!array_key_exists($old_key, $product))
|
569 |
-
return $array;
|
570 |
-
|
571 |
-
$keys = array_keys($array);
|
572 |
-
$keys[array_search($old_key, $keys)] = $new_key;
|
573 |
-
}
|
574 |
-
return array_combine($keys, $array);
|
575 |
-
}
|
576 |
-
|
577 |
-
/**
|
578 |
-
* Responsible to make XML feed header
|
579 |
-
* @return string
|
580 |
-
*/
|
581 |
-
public function get_feed_header()
|
582 |
-
{
|
583 |
-
$output = '<?xml version="1.0" encoding="UTF-8" ?>
|
584 |
-
<products>';
|
585 |
-
$output .= "\n";
|
586 |
-
return $output;
|
587 |
-
}
|
588 |
-
|
589 |
-
/**
|
590 |
-
* Responsible to make XML feed body
|
591 |
-
* @var array $item Product array
|
592 |
-
* @return string
|
593 |
-
*/
|
594 |
-
public function get_feed($items)
|
595 |
-
{
|
596 |
-
$feed = "";
|
597 |
-
$feed .= $this->get_feed_header();
|
598 |
-
$feed .= "\n";
|
599 |
-
foreach ($items as $item => $products) {
|
600 |
-
$feed .= " <" . $this->feedWrapper . ">";
|
601 |
-
foreach ($products as $key => $value) {
|
602 |
-
if (!empty($value))
|
603 |
-
$feed .= $value;
|
604 |
-
}
|
605 |
-
$feed .= "\n </" . $this->feedWrapper . ">\n";
|
606 |
-
}
|
607 |
-
$feed .= $this->get_feed_footer();
|
608 |
-
|
609 |
-
return $feed;
|
610 |
-
}
|
611 |
-
|
612 |
-
/**
|
613 |
-
* Responsible to make XML feed footer
|
614 |
-
* @return string
|
615 |
-
*/
|
616 |
-
public function get_feed_footer()
|
617 |
-
{
|
618 |
-
$footer = " </products>";
|
619 |
-
return $footer;
|
620 |
-
}
|
621 |
-
|
622 |
-
/**
|
623 |
-
* Responsible to make TXT feed
|
624 |
-
* @return string
|
625 |
-
*/
|
626 |
-
public function get_txt_feed()
|
627 |
-
{
|
628 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
629 |
-
$headers = array_keys($this->products[0]);
|
630 |
-
$feed[] = $headers;
|
631 |
-
foreach ($this->products as $no => $product) {
|
632 |
-
$row = array();
|
633 |
-
foreach ($headers as $key => $header) {
|
634 |
-
$row[] = $product[$header];
|
635 |
-
}
|
636 |
-
$feed[] = $row;
|
637 |
-
}
|
638 |
-
$str = "";
|
639 |
-
foreach ($feed as $fields) {
|
640 |
-
$str .= implode("\t", $fields) . "\n";
|
641 |
-
}
|
642 |
-
return $str;
|
643 |
-
}
|
644 |
-
return false;
|
645 |
-
}
|
646 |
-
|
647 |
-
/**
|
648 |
-
* Responsible to make CSV feed
|
649 |
-
* @return string
|
650 |
-
*/
|
651 |
-
public function get_csv_feed()
|
652 |
-
{
|
653 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
654 |
-
$headers = array_keys($this->products[0]);
|
655 |
-
$feed[] = $headers;
|
656 |
-
foreach ($this->products as $no => $product) {
|
657 |
-
$row = array();
|
658 |
-
foreach ($headers as $key => $header) {
|
659 |
-
$row[] = $product[$header];
|
660 |
-
}
|
661 |
-
$feed[] = $row;
|
662 |
-
}
|
663 |
-
|
664 |
-
return $feed;
|
665 |
-
}
|
666 |
-
return false;
|
667 |
-
}
|
668 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Become
|
5 |
+
*
|
6 |
+
* Responsible for processing and generating feed for Become.com
|
7 |
+
*
|
8 |
+
* @since 1.0.0
|
9 |
+
* @package Become
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Become
|
13 |
+
{
|
14 |
+
|
15 |
+
/**
|
16 |
+
* This variable is responsible for holding all product attributes and their values
|
17 |
+
*
|
18 |
+
* @since 1.0.0
|
19 |
+
* @var array $products Contains all the product attributes to generate feed
|
20 |
+
* @access public
|
21 |
+
*/
|
22 |
+
public $products;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* This variable is responsible for holding feed configuration form values
|
26 |
+
*
|
27 |
+
* @since 1.0.0
|
28 |
+
* @var Become $rules Contains feed configuration form values
|
29 |
+
* @access public
|
30 |
+
*/
|
31 |
+
public $rules;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* This variable is responsible for mapping store attributes to merchant attribute
|
35 |
+
*
|
36 |
+
* @since 1.0.0
|
37 |
+
* @var Become $mapping Map store attributes to merchant attribute
|
38 |
+
* @access public
|
39 |
+
*/
|
40 |
+
public $mapping;
|
41 |
+
|
42 |
+
/**
|
43 |
+
* This variable is responsible for generate error logs
|
44 |
+
*
|
45 |
+
* @since 1.0.0
|
46 |
+
* @var Become $errorLog Generate error logs
|
47 |
+
* @access public
|
48 |
+
*/
|
49 |
+
public $errorLog;
|
50 |
+
|
51 |
+
/**
|
52 |
+
* This variable is responsible for making error number
|
53 |
+
*
|
54 |
+
* @since 1.0.0
|
55 |
+
* @var Become $errorCounter Generate error number
|
56 |
+
* @access public
|
57 |
+
*/
|
58 |
+
public $errorCounter;
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Feed Wrapper text for enclosing each product information
|
62 |
+
*
|
63 |
+
* @since 1.0.0
|
64 |
+
* @var Become $feedWrapper Feed Wrapper text
|
65 |
+
* @access public
|
66 |
+
*/
|
67 |
+
private $feedWrapper;
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Define the core functionality to generate feed.
|
71 |
+
*
|
72 |
+
* Set the feed rules. Map products according to the rules and Check required attributes
|
73 |
+
* and their values according to merchant specification.
|
74 |
+
* @var Woo_Generate_Feed $feedRule Contain Feed Configuration
|
75 |
+
* @since 1.0.0
|
76 |
+
*/
|
77 |
+
public function __construct($feedRule)
|
78 |
+
{
|
79 |
+
$this->feedWrapper = 'product';
|
80 |
+
$this->errorCounter = 0;
|
81 |
+
$this->rules = $feedRule;
|
82 |
+
$this->mapProductsByRules();
|
83 |
+
$this->formatRequiredField();
|
84 |
+
$this->filterProductValues();
|
85 |
+
if ($this->rules['feedType'] == 'xml') {
|
86 |
+
$this->mapAttributeForXML();
|
87 |
+
} else {
|
88 |
+
$this->mapAttributeForCSVTEXT();
|
89 |
+
}
|
90 |
+
}
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Configure merchant attributes for XML feed
|
94 |
+
*/
|
95 |
+
public function mapAttributeForXML()
|
96 |
+
{
|
97 |
+
//Basic product information
|
98 |
+
|
99 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
100 |
+
foreach ($this->products as $key => $values) {
|
101 |
+
foreach ($values as $attr => $value) {
|
102 |
+
$this->products[$key][$attr] = $this->formatXMLLine($attr, $value, true, true, true);
|
103 |
+
}
|
104 |
+
}
|
105 |
+
}
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* Configure merchant attributes for CSV and TXT feed
|
110 |
+
*/
|
111 |
+
public function mapAttributeForCSVTEXT()
|
112 |
+
{
|
113 |
+
//Basic product information
|
114 |
+
|
115 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
116 |
+
foreach ($this->products as $key => $values) {
|
117 |
+
foreach ($values as $attr => $value) {
|
118 |
+
//Allow force strip HTML
|
119 |
+
$value = strip_tags(html_entity_decode($value));
|
120 |
+
if ($attr != 'Category') {
|
121 |
+
$value = utf8_encode($value);
|
122 |
+
$attr = utf8_encode($attr);
|
123 |
+
|
124 |
+
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
|
125 |
+
|
126 |
+
if (gettype($value) == 'array')
|
127 |
+
$value = json_encode($value);
|
128 |
+
}
|
129 |
+
|
130 |
+
$this->products[$key][$attr] = $value;
|
131 |
+
}
|
132 |
+
}
|
133 |
+
}
|
134 |
+
}
|
135 |
+
|
136 |
+
/**
|
137 |
+
* Check all the required attributes and make error message
|
138 |
+
*/
|
139 |
+
public function formatRequiredField()
|
140 |
+
{
|
141 |
+
foreach ($this->products as $no => $product) {
|
142 |
+
$upn = 0;
|
143 |
+
if (array_key_exists('Unique ID', $product)) {
|
144 |
+
$id = $product['Unique ID'];
|
145 |
+
} else {
|
146 |
+
$id = $product['Title'];
|
147 |
+
}
|
148 |
+
|
149 |
+
if (!array_key_exists('Unique ID', $product)) {
|
150 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Unique ID</b>] Missing for <b>$id</b>.";
|
151 |
+
$this->errorCounter++;
|
152 |
+
}
|
153 |
+
|
154 |
+
|
155 |
+
if (!array_key_exists('Title', $product)) {
|
156 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Title</b>] Missing for <b>$id</b>.";
|
157 |
+
$this->errorCounter++;
|
158 |
+
}
|
159 |
+
|
160 |
+
if (!array_key_exists('Description', $product)) {
|
161 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Description</b>] Missing for <b>$id</b>.";
|
162 |
+
$this->errorCounter++;
|
163 |
+
}
|
164 |
+
|
165 |
+
if (!array_key_exists('Category', $product)) {
|
166 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Category</b>] Missing for <b>$id</b>.";
|
167 |
+
$this->errorCounter++;
|
168 |
+
}
|
169 |
+
|
170 |
+
if (!array_key_exists('Product URL', $product)) {
|
171 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Product URL</b>] Missing for <b>$id</b>.";
|
172 |
+
$this->errorCounter++;
|
173 |
+
}
|
174 |
+
|
175 |
+
if (!array_key_exists('Image URL', $product)) {
|
176 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Image URL</b>] Missing for <b>$id</b>.";
|
177 |
+
$this->errorCounter++;
|
178 |
+
}
|
179 |
+
|
180 |
+
if (!array_key_exists('Condition', $product)) {
|
181 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Condition</b>] Missing for <b>$id</b>.";
|
182 |
+
$this->errorCounter++;
|
183 |
+
}
|
184 |
+
|
185 |
+
if (!array_key_exists('Availability', $product)) {
|
186 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Availability</b>] Missing for <b>$id</b>.";
|
187 |
+
$this->errorCounter++;
|
188 |
+
}
|
189 |
+
|
190 |
+
if (!array_key_exists('Current price', $product)) {
|
191 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Current price</b>] Missing for <b>$id</b>.";
|
192 |
+
$this->errorCounter++;
|
193 |
+
}
|
194 |
+
}
|
195 |
+
}
|
196 |
+
|
197 |
+
/**
|
198 |
+
* Return Feed
|
199 |
+
*
|
200 |
+
* @return array|bool|string
|
201 |
+
*/
|
202 |
+
public function returnFinalProduct()
|
203 |
+
{
|
204 |
+
if ($this->rules['feedType'] == 'xml') {
|
205 |
+
return $this->get_feed($this->products);
|
206 |
+
} elseif ($this->rules['feedType'] == 'txt') {
|
207 |
+
return $this->get_txt_feed();
|
208 |
+
} elseif ($this->rules['feedType'] == 'csv') {
|
209 |
+
return $this->get_csv_feed();
|
210 |
+
}
|
211 |
+
return false;
|
212 |
+
}
|
213 |
+
|
214 |
+
/**
|
215 |
+
* Check product's attribute value according to merchant specifications
|
216 |
+
*/
|
217 |
+
public function filterProductValues()
|
218 |
+
{
|
219 |
+
$getProduct = new Woo_Feed_Products();
|
220 |
+
$products = $this->products;
|
221 |
+
|
222 |
+
foreach ($products as $no => $product) {
|
223 |
+
if (array_key_exists('Unique ID', $product)) {
|
224 |
+
$id = $product['Unique ID'];
|
225 |
+
} else {
|
226 |
+
$id = $product['Title'];
|
227 |
+
}
|
228 |
+
// echo "<pre>";
|
229 |
+
// print_r($product);
|
230 |
+
foreach ($product as $key => $value) {
|
231 |
+
switch ($key) {
|
232 |
+
case "Unique ID":
|
233 |
+
if (strlen($value) > 100) {
|
234 |
+
$this->errorLog[$this->errorCounter] = "[<b>Unique ID</b>] is more that 100 character for $id.";
|
235 |
+
$this->errorCounter++;
|
236 |
+
}
|
237 |
+
break;
|
238 |
+
case "Title":
|
239 |
+
if (strlen($value) > 1000) {
|
240 |
+
$this->errorLog[$this->errorCounter] = "[<b>Title</b>] is more that 1000 character for $id.";
|
241 |
+
$this->errorCounter++;
|
242 |
+
}
|
243 |
+
break;
|
244 |
+
case "Description":
|
245 |
+
if (strlen($value) > 3000) {
|
246 |
+
$this->errorLog[$this->errorCounter] = "[<b>Description</b>] is more that 3000 character for $id.";
|
247 |
+
$this->errorCounter++;
|
248 |
+
}
|
249 |
+
break;
|
250 |
+
case "Category":
|
251 |
+
if (strlen($value) > 1000) {
|
252 |
+
$this->errorLog[$this->errorCounter] = "[<b>Category</b>] is more that 1000 character for $id.";
|
253 |
+
$this->errorCounter++;
|
254 |
+
}
|
255 |
+
break;
|
256 |
+
case "Product URL":
|
257 |
+
if (strpos($value, 'http://') == false || strpos($value, 'https://') == false) {
|
258 |
+
$this->errorLog[$this->errorCounter] = "[<b>Product URL</b>] must start with http:// or https:// for $id.";
|
259 |
+
$this->errorCounter++;
|
260 |
+
}
|
261 |
+
|
262 |
+
if (strlen($value) > 2000) {
|
263 |
+
$this->errorLog[$this->errorCounter] = "[<b>Product URL</b>] is more that 2000 character for $id.";
|
264 |
+
$this->errorCounter++;
|
265 |
+
}
|
266 |
+
|
267 |
+
break;
|
268 |
+
case "Image URL":
|
269 |
+
if (strpos($value, 'http://') == false || strpos($value, 'https://') == false) {
|
270 |
+
$this->errorLog[$this->errorCounter] = "[<b>Image URL</b>] must start with http:// or https:// for $id.";
|
271 |
+
$this->errorCounter++;
|
272 |
+
}
|
273 |
+
|
274 |
+
if (strlen($value) > 2000) {
|
275 |
+
$this->errorLog[$this->errorCounter] = "[<b>Image URL</b>] is more that 2000 character for $id.";
|
276 |
+
$this->errorCounter++;
|
277 |
+
}
|
278 |
+
|
279 |
+
list($width, $height) = getimagesize($value);
|
280 |
+
if ($width < 450 || $height < 450) {
|
281 |
+
$this->errorLog[$this->errorCounter] = "<b>Image Width and Height</b> should be more that 450px for $id.";
|
282 |
+
$this->errorCounter++;
|
283 |
+
}
|
284 |
+
|
285 |
+
break;
|
286 |
+
case "Condition":
|
287 |
+
$condition = array("New", "Used", "Refurbished", "Open Box", "OEM");
|
288 |
+
if (!array_key_exists($value, $condition)) {
|
289 |
+
$this->errorLog[$this->errorCounter] = "[<b>Condition</b>] = $value is acceptable for $id.";
|
290 |
+
$this->errorCounter++;
|
291 |
+
}
|
292 |
+
break;
|
293 |
+
case "Availability":
|
294 |
+
$availability = array("In Stock", "Out of Stock", "Available for Order", "PreOrder");
|
295 |
+
if ($value == 'in stock') {
|
296 |
+
$this->products[$no][$key] = "In Stock";
|
297 |
+
} else {
|
298 |
+
$this->products[$no][$key] = "Out of Stock";
|
299 |
+
}
|
300 |
+
|
301 |
+
if (!array_key_exists($this->products[$no][$key], $availability)) {
|
302 |
+
$this->errorLog[$this->errorCounter] = "[<b>Availability</b>] = $value is acceptable for $id.";
|
303 |
+
$this->errorCounter++;
|
304 |
+
}
|
305 |
+
break;
|
306 |
+
case "Current price":
|
307 |
+
if (!is_numeric($value)) {
|
308 |
+
$this->errorLog[$this->errorCounter] = "[<b>Current price</b>] should be numeric for $id.";
|
309 |
+
$this->errorCounter++;
|
310 |
+
}
|
311 |
+
break;
|
312 |
+
case "Original Price":
|
313 |
+
if (!is_numeric($value)) {
|
314 |
+
$this->errorLog[$this->errorCounter] = "[<b>Original price</b>] should be numeric for $id.";
|
315 |
+
$this->errorCounter++;
|
316 |
+
}
|
317 |
+
break;
|
318 |
+
default:
|
319 |
+
break;
|
320 |
+
}
|
321 |
+
}
|
322 |
+
}
|
323 |
+
}
|
324 |
+
|
325 |
+
/**
|
326 |
+
* Return Dynamic Category Mapping Values by Parent Product Id
|
327 |
+
*
|
328 |
+
* @param string $mappingName Category Mapping Name
|
329 |
+
* @param int $parent Parent id of the product
|
330 |
+
* @return mixed
|
331 |
+
*/
|
332 |
+
public function get_category_mapping_value($mappingName, $parent)
|
333 |
+
{
|
334 |
+
$getValue = unserialize(get_option($mappingName));
|
335 |
+
$mapp = array_reverse($getValue['cmapping'], true);
|
336 |
+
$categories = get_the_terms($parent, 'product_cat');
|
337 |
+
|
338 |
+
foreach ($categories as $key => $category) {
|
339 |
+
if (!empty($mapp[$category->term_id]))
|
340 |
+
return $mapp[$category->term_id];
|
341 |
+
}
|
342 |
+
return false;
|
343 |
+
}
|
344 |
+
|
345 |
+
/**
|
346 |
+
* Configure the feed according to the rules
|
347 |
+
* @return Shopping
|
348 |
+
*/
|
349 |
+
public function mapProductsByRules()
|
350 |
+
{
|
351 |
+
/**
|
352 |
+
* Get WooCommerce Products
|
353 |
+
* @package Woo_Feed_Products
|
354 |
+
*/
|
355 |
+
$products = new Woo_Feed_Products();
|
356 |
+
|
357 |
+
/**
|
358 |
+
* This variable contain selected Woo attributes from feed making form
|
359 |
+
*
|
360 |
+
* @since 1.0.0
|
361 |
+
* @var array $attributes contain selected Woo attributes from feed making form
|
362 |
+
*/
|
363 |
+
$attributes = $this->rules['attributes'];
|
364 |
+
/**
|
365 |
+
* This variable contain selected Prefix Values from feed making form
|
366 |
+
*
|
367 |
+
* @since 1.0.0
|
368 |
+
* @var array $prefix Prefix Values from feed making form
|
369 |
+
*/
|
370 |
+
$prefix = $this->rules['prefix'];
|
371 |
+
/**
|
372 |
+
* This variable contain selected Prefix Values from feed making form
|
373 |
+
*
|
374 |
+
* @since 1.0.0
|
375 |
+
* @var array $suffix Suffix Values from feed making form
|
376 |
+
*/
|
377 |
+
$suffix = $this->rules['suffix'];
|
378 |
+
/**
|
379 |
+
* This variable contain selected Output Types from feed making form
|
380 |
+
*
|
381 |
+
* @since 1.0.0
|
382 |
+
* @var array $outputType Output Types from feed making form
|
383 |
+
*/
|
384 |
+
$outputType = $this->rules['output_type'];
|
385 |
+
|
386 |
+
/**
|
387 |
+
* This variable contain selected Output Limit from feed making form
|
388 |
+
*
|
389 |
+
* @since 1.0.0
|
390 |
+
* @var array $limit Output Limit from feed making form
|
391 |
+
*/
|
392 |
+
$limit = $this->rules['limit'];
|
393 |
+
/**
|
394 |
+
* This variable contain selected Merchant attributes from feed making form
|
395 |
+
*
|
396 |
+
* @since 1.0.0
|
397 |
+
* @var array $merchantAttributes contain selected Woo attributes from feed making form
|
398 |
+
*/
|
399 |
+
$merchantAttributes = $this->rules['mattributes'];
|
400 |
+
/**
|
401 |
+
* This variable contain attribute types from feed making form
|
402 |
+
*
|
403 |
+
* @since 1.0.0
|
404 |
+
* @var array $type contain attribute types from feed making form
|
405 |
+
*/
|
406 |
+
$type = $this->rules['type'];
|
407 |
+
/**
|
408 |
+
* This variable contain manual output of attribute from feed making form
|
409 |
+
*
|
410 |
+
* @since 1.0.0
|
411 |
+
* @var array $default contain manual output of attribute
|
412 |
+
*/
|
413 |
+
$default = $this->rules['default'];
|
414 |
+
|
415 |
+
/**
|
416 |
+
* This variable contain feed type
|
417 |
+
*
|
418 |
+
* @since 1.0.0
|
419 |
+
* @var array $feedType contain feed type
|
420 |
+
*/
|
421 |
+
$feedType = $this->rules['feedType'];
|
422 |
+
|
423 |
+
// Map Merchant Attributes and Woo Attributes
|
424 |
+
if (count($merchantAttributes)) {
|
425 |
+
foreach ($merchantAttributes as $key => $attr) {
|
426 |
+
if (!empty($attr) && !empty($attributes[$key])) {
|
427 |
+
if ($type[$key] == 'attribute') {
|
428 |
+
$this->mapping[$attr]['value'] = $attributes[$key];
|
429 |
+
$this->mapping[$attr]['suffix'] = $suffix[$key];
|
430 |
+
$this->mapping[$attr]['prefix'] = $prefix[$key];
|
431 |
+
$this->mapping[$attr]['type'] = $outputType[$key];
|
432 |
+
$this->mapping[$attr]['limit'] = $limit[$key];
|
433 |
+
}
|
434 |
+
} else if (empty($attributes[$key])) {
|
435 |
+
if ($type[$key] == 'pattern') {
|
436 |
+
$this->mapping[$attr]['value'] = "wf_pattern_$default[$key]";
|
437 |
+
$this->mapping[$attr]['suffix'] = $suffix[$key];
|
438 |
+
$this->mapping[$attr]['prefix'] = $prefix[$key];
|
439 |
+
$this->mapping[$attr]['type'] = $outputType[$key];
|
440 |
+
$this->mapping[$attr]['limit'] = $limit[$key];
|
441 |
+
}
|
442 |
+
}
|
443 |
+
}
|
444 |
+
}
|
445 |
+
|
446 |
+
// Make Product feed array according to mapping
|
447 |
+
foreach ($products->woo_feed_get_visible_product() as $key => $value) {
|
448 |
+
$i = 0;
|
449 |
+
foreach ($this->mapping as $attr => $rules) {
|
450 |
+
if (array_key_exists($rules['value'], $value)) {
|
451 |
+
|
452 |
+
$output = $rules['prefix'] . $value[$rules['value']] . " " . $rules['suffix'];
|
453 |
+
// Format According to output type
|
454 |
+
if ($rules['type'] == 2) {
|
455 |
+
$output = strip_tags($output);
|
456 |
+
} elseif ($rules['type'] == 3) {
|
457 |
+
$output = absint($output);
|
458 |
+
}
|
459 |
+
// Format According to output limit
|
460 |
+
if (!empty($rules['limit']) && is_numeric($rules['limit'])) {
|
461 |
+
$output = substr($output, 0, $rules['limit']);
|
462 |
+
}
|
463 |
+
$attr = trim($attr);
|
464 |
+
$this->products[$key][$attr] = trim($output);
|
465 |
+
} else {
|
466 |
+
if (!empty($default[$i])) {
|
467 |
+
$output = $rules['prefix'] . str_replace("wf_pattern_", "", $rules['value']) . " " . $rules['suffix'];
|
468 |
+
if ($rules['type'] == 2) {
|
469 |
+
$output = strip_tags($output);
|
470 |
+
} elseif ($rules['type'] == 3) {
|
471 |
+
$output = absint($output);
|
472 |
+
}
|
473 |
+
// Format According to output limit
|
474 |
+
if (!empty($rules['limit']) && is_numeric($rules['limit'])) {
|
475 |
+
$output = substr($output, 0, $rules['limit']);
|
476 |
+
}
|
477 |
+
$attr = trim($attr);
|
478 |
+
$this->products[$key][$attr] = trim($output);
|
479 |
+
}
|
480 |
+
}
|
481 |
+
$i++;
|
482 |
+
}
|
483 |
+
}
|
484 |
+
|
485 |
+
|
486 |
+
return $this->products;
|
487 |
+
}
|
488 |
+
|
489 |
+
/**
|
490 |
+
* Change the products old array key and set new
|
491 |
+
*
|
492 |
+
* @param string $from Attribute Before
|
493 |
+
* @param string $to Attribute After
|
494 |
+
* @param bool $cdata Enclose Feed value
|
495 |
+
*/
|
496 |
+
public function mapAttribute($from, $to, $cdata = false)
|
497 |
+
{
|
498 |
+
$i = 0;
|
499 |
+
foreach ($this->products as $no => $product) {
|
500 |
+
foreach ($product as $key => $value) {
|
501 |
+
if ($key == $from) {
|
502 |
+
unset($this->products[$no][$from]);
|
503 |
+
if ($from == 'images') {
|
504 |
+
$this->products[$no][$to] = $value;
|
505 |
+
} else {
|
506 |
+
$this->products[$no][$to] = $this->formatXMLLine($to, $value, $cdata, true, true);
|
507 |
+
}
|
508 |
+
|
509 |
+
}
|
510 |
+
}
|
511 |
+
$i++;
|
512 |
+
}
|
513 |
+
}
|
514 |
+
|
515 |
+
/**
|
516 |
+
* Format and Make the XML node for the Feed
|
517 |
+
*
|
518 |
+
* @param $attribute
|
519 |
+
* @param $value
|
520 |
+
* @param bool $cdata
|
521 |
+
* @param bool $stripHTML
|
522 |
+
* @param bool $utf8encode
|
523 |
+
* @param string $space
|
524 |
+
* @return string
|
525 |
+
*/
|
526 |
+
function formatXMLLine($attribute, $value, $cdata = false, $stripHTML = true, $utf8encode = true, $space = ' ')
|
527 |
+
{
|
528 |
+
//Make single line for XML
|
529 |
+
$c_leader = '';
|
530 |
+
$c_footer = '';
|
531 |
+
if ($cdata) {
|
532 |
+
$c_leader = '<![CDATA[';
|
533 |
+
$c_footer = ']]>';
|
534 |
+
}
|
535 |
+
//Allow force strip HTML
|
536 |
+
if ($stripHTML)
|
537 |
+
$value = strip_tags(html_entity_decode($value));
|
538 |
+
|
539 |
+
|
540 |
+
if ($utf8encode || $utf8encode == 1) {
|
541 |
+
$value = utf8_encode($value);
|
542 |
+
$attribute = utf8_encode($attribute);
|
543 |
+
}
|
544 |
+
|
545 |
+
|
546 |
+
if (!$cdata)
|
547 |
+
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
|
548 |
+
|
549 |
+
if (gettype($value) == 'array')
|
550 |
+
$value = json_encode($value);
|
551 |
+
|
552 |
+
|
553 |
+
return '
|
554 |
+
' . $space . '<' . $attribute . '>' . $c_leader . $value . $c_footer . '</' . $attribute . '>';
|
555 |
+
}
|
556 |
+
|
557 |
+
/**
|
558 |
+
* Responsible to change product array key
|
559 |
+
*
|
560 |
+
* @param $array
|
561 |
+
* @param $old_key
|
562 |
+
* @param $new_key
|
563 |
+
* @return array
|
564 |
+
*/
|
565 |
+
function change_key($array, $old_key, $new_key)
|
566 |
+
{
|
567 |
+
foreach ($this->products as $no => $product) {
|
568 |
+
if (!array_key_exists($old_key, $product))
|
569 |
+
return $array;
|
570 |
+
|
571 |
+
$keys = array_keys($array);
|
572 |
+
$keys[array_search($old_key, $keys)] = $new_key;
|
573 |
+
}
|
574 |
+
return array_combine($keys, $array);
|
575 |
+
}
|
576 |
+
|
577 |
+
/**
|
578 |
+
* Responsible to make XML feed header
|
579 |
+
* @return string
|
580 |
+
*/
|
581 |
+
public function get_feed_header()
|
582 |
+
{
|
583 |
+
$output = '<?xml version="1.0" encoding="UTF-8" ?>
|
584 |
+
<products>';
|
585 |
+
$output .= "\n";
|
586 |
+
return $output;
|
587 |
+
}
|
588 |
+
|
589 |
+
/**
|
590 |
+
* Responsible to make XML feed body
|
591 |
+
* @var array $item Product array
|
592 |
+
* @return string
|
593 |
+
*/
|
594 |
+
public function get_feed($items)
|
595 |
+
{
|
596 |
+
$feed = "";
|
597 |
+
$feed .= $this->get_feed_header();
|
598 |
+
$feed .= "\n";
|
599 |
+
foreach ($items as $item => $products) {
|
600 |
+
$feed .= " <" . $this->feedWrapper . ">";
|
601 |
+
foreach ($products as $key => $value) {
|
602 |
+
if (!empty($value))
|
603 |
+
$feed .= $value;
|
604 |
+
}
|
605 |
+
$feed .= "\n </" . $this->feedWrapper . ">\n";
|
606 |
+
}
|
607 |
+
$feed .= $this->get_feed_footer();
|
608 |
+
|
609 |
+
return $feed;
|
610 |
+
}
|
611 |
+
|
612 |
+
/**
|
613 |
+
* Responsible to make XML feed footer
|
614 |
+
* @return string
|
615 |
+
*/
|
616 |
+
public function get_feed_footer()
|
617 |
+
{
|
618 |
+
$footer = " </products>";
|
619 |
+
return $footer;
|
620 |
+
}
|
621 |
+
|
622 |
+
/**
|
623 |
+
* Responsible to make TXT feed
|
624 |
+
* @return string
|
625 |
+
*/
|
626 |
+
public function get_txt_feed()
|
627 |
+
{
|
628 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
629 |
+
$headers = array_keys($this->products[0]);
|
630 |
+
$feed[] = $headers;
|
631 |
+
foreach ($this->products as $no => $product) {
|
632 |
+
$row = array();
|
633 |
+
foreach ($headers as $key => $header) {
|
634 |
+
$row[] = $product[$header];
|
635 |
+
}
|
636 |
+
$feed[] = $row;
|
637 |
+
}
|
638 |
+
$str = "";
|
639 |
+
foreach ($feed as $fields) {
|
640 |
+
$str .= implode("\t", $fields) . "\n";
|
641 |
+
}
|
642 |
+
return $str;
|
643 |
+
}
|
644 |
+
return false;
|
645 |
+
}
|
646 |
+
|
647 |
+
/**
|
648 |
+
* Responsible to make CSV feed
|
649 |
+
* @return string
|
650 |
+
*/
|
651 |
+
public function get_csv_feed()
|
652 |
+
{
|
653 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
654 |
+
$headers = array_keys($this->products[0]);
|
655 |
+
$feed[] = $headers;
|
656 |
+
foreach ($this->products as $no => $product) {
|
657 |
+
$row = array();
|
658 |
+
foreach ($headers as $key => $header) {
|
659 |
+
$row[] = $product[$header];
|
660 |
+
}
|
661 |
+
$feed[] = $row;
|
662 |
+
}
|
663 |
+
|
664 |
+
return $feed;
|
665 |
+
}
|
666 |
+
return false;
|
667 |
+
}
|
668 |
}
|
includes/feeds/class-woo-feed-bing.php
CHANGED
@@ -1,651 +1,651 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Class Bing
|
5 |
-
*
|
6 |
-
* Responsible for processing and generating feed for Bing.com
|
7 |
-
*
|
8 |
-
* @since 1.0.0
|
9 |
-
* @package Bing
|
10 |
-
*
|
11 |
-
*/
|
12 |
-
class Bing
|
13 |
-
{
|
14 |
-
|
15 |
-
/**
|
16 |
-
* This variable is responsible for holding all product attributes and their values
|
17 |
-
*
|
18 |
-
* @since 1.0.0
|
19 |
-
* @var array $products Contains all the product attributes to generate feed
|
20 |
-
* @access public
|
21 |
-
*/
|
22 |
-
public $products;
|
23 |
-
|
24 |
-
/**
|
25 |
-
* This variable is responsible for holding feed configuration form values
|
26 |
-
*
|
27 |
-
* @since 1.0.0
|
28 |
-
* @var Bing $rules Contains feed configuration form values
|
29 |
-
* @access public
|
30 |
-
*/
|
31 |
-
public $rules;
|
32 |
-
|
33 |
-
/**
|
34 |
-
* This variable is responsible for mapping store attributes to merchant attribute
|
35 |
-
*
|
36 |
-
* @since 1.0.0
|
37 |
-
* @var Bing $mapping Map store attributes to merchant attribute
|
38 |
-
* @access public
|
39 |
-
*/
|
40 |
-
public $mapping;
|
41 |
-
|
42 |
-
/**
|
43 |
-
* This variable is responsible for generate error logs
|
44 |
-
*
|
45 |
-
* @since 1.0.0
|
46 |
-
* @var Bing $errorLog Generate error logs
|
47 |
-
* @access public
|
48 |
-
*/
|
49 |
-
public $errorLog;
|
50 |
-
|
51 |
-
/**
|
52 |
-
* This variable is responsible for making error number
|
53 |
-
*
|
54 |
-
* @since 1.0.0
|
55 |
-
* @var Bing $errorCounter Generate error number
|
56 |
-
* @access public
|
57 |
-
*/
|
58 |
-
public $errorCounter;
|
59 |
-
|
60 |
-
/**
|
61 |
-
* Feed Wrapper text for enclosing each product information
|
62 |
-
*
|
63 |
-
* @since 1.0.0
|
64 |
-
* @var Bing $feedWrapper Feed Wrapper text
|
65 |
-
* @access public
|
66 |
-
*/
|
67 |
-
private $feedWrapper = 'product';
|
68 |
-
|
69 |
-
/**
|
70 |
-
* Define the core functionality to generate feed.
|
71 |
-
*
|
72 |
-
* Set the feed rules. Map products according to the rules and Check required attributes
|
73 |
-
* and their values according to merchant specification.
|
74 |
-
* @var Woo_Generate_Feed $feedRule Contain Feed Configuration
|
75 |
-
* @since 1.0.0
|
76 |
-
*/
|
77 |
-
public function __construct($feedRule)
|
78 |
-
{
|
79 |
-
$this->errorCounter = 0;
|
80 |
-
$this->rules = $feedRule;
|
81 |
-
$this->mapProductsByRules();
|
82 |
-
//$this->formatRequiredField();
|
83 |
-
//$this->filterProductValues();
|
84 |
-
if ($this->rules['feedType'] == 'xml') {
|
85 |
-
$this->mapAttributeForXML();
|
86 |
-
} else {
|
87 |
-
$this->mapAttributeForCSVTEXT();
|
88 |
-
}
|
89 |
-
}
|
90 |
-
|
91 |
-
/**
|
92 |
-
* Configure merchant attributes for XML feed
|
93 |
-
*/
|
94 |
-
public function mapAttributeForXML()
|
95 |
-
{
|
96 |
-
//Basic product information
|
97 |
-
|
98 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
99 |
-
foreach ($this->products as $key => $values) {
|
100 |
-
foreach ($values as $attr => $value) {
|
101 |
-
$this->products[$key][$attr] = $this->formatXMLLine($attr, $value, true, true, true);
|
102 |
-
}
|
103 |
-
}
|
104 |
-
}
|
105 |
-
}
|
106 |
-
|
107 |
-
/**
|
108 |
-
* Configure merchant attributes for CSV and TXT feed
|
109 |
-
*/
|
110 |
-
public function mapAttributeForCSVTEXT()
|
111 |
-
{
|
112 |
-
//Basic product information
|
113 |
-
|
114 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
115 |
-
foreach ($this->products as $key => $values) {
|
116 |
-
foreach ($values as $attr => $value) {
|
117 |
-
//Allow force strip HTML
|
118 |
-
|
119 |
-
$value = strip_tags(html_entity_decode($value));
|
120 |
-
|
121 |
-
$value = utf8_encode($value);
|
122 |
-
$attr = utf8_encode($attr);
|
123 |
-
|
124 |
-
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
|
125 |
-
|
126 |
-
if (gettype($value) == 'array')
|
127 |
-
$value = json_encode($value);
|
128 |
-
|
129 |
-
$this->products[$key][$attr] = $value;
|
130 |
-
}
|
131 |
-
}
|
132 |
-
}
|
133 |
-
}
|
134 |
-
|
135 |
-
/**
|
136 |
-
* Check all the required attributes and make error message
|
137 |
-
*/
|
138 |
-
public function formatRequiredField()
|
139 |
-
{
|
140 |
-
foreach ($this->products as $no => $product) {
|
141 |
-
$upn = 0;
|
142 |
-
if (array_key_exists('MerchantProductID', $product)) {
|
143 |
-
$id = $product['MerchantProductID'];
|
144 |
-
} else {
|
145 |
-
$id = $product['Title'];
|
146 |
-
}
|
147 |
-
|
148 |
-
if (!array_key_exists('MerchantProductID', $product)) {
|
149 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>MerchantProductID</b>] Missing for <b>$id</b>.";
|
150 |
-
$this->errorCounter++;
|
151 |
-
}
|
152 |
-
|
153 |
-
|
154 |
-
if (!array_key_exists('Title', $product)) {
|
155 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Title</b>] Missing for <b>$id</b>.";
|
156 |
-
$this->errorCounter++;
|
157 |
-
}
|
158 |
-
|
159 |
-
if (!array_key_exists('ProductURL', $product)) {
|
160 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>ProductURL</b>] Missing for <b>$id</b>.";
|
161 |
-
$this->errorCounter++;
|
162 |
-
}
|
163 |
-
|
164 |
-
if (!array_key_exists('Price', $product)) {
|
165 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Price</b>] Missing for <b>$id</b>.";
|
166 |
-
$this->errorCounter++;
|
167 |
-
}
|
168 |
-
|
169 |
-
if (!array_key_exists('Description', $product)) {
|
170 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Description</b>] Missing for <b>$id</b>.";
|
171 |
-
$this->errorCounter++;
|
172 |
-
}
|
173 |
-
|
174 |
-
if (!array_key_exists('ImageURL', $product)) {
|
175 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>ImageURL</b>] Missing for <b>$id</b>.";
|
176 |
-
$this->errorCounter++;
|
177 |
-
}
|
178 |
-
|
179 |
-
}
|
180 |
-
}
|
181 |
-
|
182 |
-
/**
|
183 |
-
* Return Feed
|
184 |
-
*
|
185 |
-
* @return array|bool|string
|
186 |
-
*/
|
187 |
-
public function returnFinalProduct()
|
188 |
-
{
|
189 |
-
if ($this->rules['feedType'] == 'xml') {
|
190 |
-
return $this->get_feed($this->products);
|
191 |
-
} elseif ($this->rules['feedType'] == 'txt') {
|
192 |
-
return $this->get_txt_feed();
|
193 |
-
} elseif ($this->rules['feedType'] == 'csv') {
|
194 |
-
return $this->get_csv_feed();
|
195 |
-
}
|
196 |
-
return false;
|
197 |
-
}
|
198 |
-
|
199 |
-
/**
|
200 |
-
* Check product's attribute value according to merchant specifications
|
201 |
-
*/
|
202 |
-
public function filterProductValues()
|
203 |
-
{
|
204 |
-
$getProduct = new Woo_Feed_Products();
|
205 |
-
$products = $this->products;
|
206 |
-
|
207 |
-
foreach ($products as $no => $product) {
|
208 |
-
if (array_key_exists('MerchantProductID', $product)) {
|
209 |
-
$id = $product['MerchantProductID'];
|
210 |
-
} else {
|
211 |
-
$id = $product['Title'];
|
212 |
-
}
|
213 |
-
// echo "<pre>";
|
214 |
-
// print_r($product);
|
215 |
-
foreach ($product as $key => $value) {
|
216 |
-
|
217 |
-
|
218 |
-
switch ($key) {
|
219 |
-
case "MerchantProductID":
|
220 |
-
if (strlen($value) > 100) {
|
221 |
-
$this->errorLog[$this->errorCounter] = "[<b>MerchantProductID</b>] is more that 100 character for $id.";
|
222 |
-
$this->errorCounter++;
|
223 |
-
}
|
224 |
-
break;
|
225 |
-
case "Title":
|
226 |
-
if (strlen($value) > 255) {
|
227 |
-
$this->errorLog[$this->errorCounter] = "[<b>Title</b>] is more that 255 character for $id.";
|
228 |
-
$this->errorCounter++;
|
229 |
-
}
|
230 |
-
break;
|
231 |
-
case "Brand":
|
232 |
-
if (strlen($value) > 1500) {
|
233 |
-
$this->errorLog[$this->errorCounter] = "[<b>Brand</b>] is more that 1500 character for $id.";
|
234 |
-
$this->errorCounter++;
|
235 |
-
}
|
236 |
-
break;
|
237 |
-
case "MPN":
|
238 |
-
if (strlen($value) > 255) {
|
239 |
-
$this->errorLog[$this->errorCounter] = "[<b>MPN</b>] is more that 255 character for $id.";
|
240 |
-
$this->errorCounter++;
|
241 |
-
}
|
242 |
-
break;
|
243 |
-
case "UPC":
|
244 |
-
if (strlen($value) > 12) {
|
245 |
-
$this->errorLog[$this->errorCounter] = "[<b>UPC</b>] is more that 12 character for $id.";
|
246 |
-
$this->errorCounter++;
|
247 |
-
}
|
248 |
-
break;
|
249 |
-
case "ISBN":
|
250 |
-
if (strlen($value) > 13) {
|
251 |
-
$this->errorLog[$this->errorCounter] = "[<b>ISBN</b>] is more that 13 character for $id.";
|
252 |
-
$this->errorCounter++;
|
253 |
-
}
|
254 |
-
break;
|
255 |
-
case "ProductURL":
|
256 |
-
if (strlen($value) > 2000) {
|
257 |
-
$this->errorLog[$this->errorCounter] = "[<b>ProductURL</b>] is more that 2000 character for $id.";
|
258 |
-
$this->errorCounter++;
|
259 |
-
}
|
260 |
-
break;
|
261 |
-
case "Price":
|
262 |
-
if (!is_numeric($value)) {
|
263 |
-
$this->errorLog[$this->errorCounter] = "[<b>Price</b>] should be numeric for $id.";
|
264 |
-
$this->errorCounter++;
|
265 |
-
}
|
266 |
-
break;
|
267 |
-
case "Availability":
|
268 |
-
if ($value == 'in stock') {
|
269 |
-
$this->products[$no][$key] = "In Stock";
|
270 |
-
} else if ($value == 'out of stock') {
|
271 |
-
$this->products[$no][$key] = "Out of Stock";
|
272 |
-
}
|
273 |
-
if (strlen($this->products[$no][$key]) > 15) {
|
274 |
-
$this->errorLog[$this->errorCounter] = "[<b>Availability</b>] is more that 15 character for $id.";
|
275 |
-
$this->errorCounter++;
|
276 |
-
}
|
277 |
-
break;
|
278 |
-
case "Description":
|
279 |
-
if (strlen($value) > 5000) {
|
280 |
-
$this->errorLog[$this->errorCounter] = "[<b>Description</b>] is more that 5000 character for $id.";
|
281 |
-
$this->errorCounter++;
|
282 |
-
}
|
283 |
-
break;
|
284 |
-
case "ImageURL":
|
285 |
-
if (strlen($value) > 1000) {
|
286 |
-
$this->errorLog[$this->errorCounter] = "[<b>ImageURL</b>] is more that 1000 character for $id.";
|
287 |
-
$this->errorCounter++;
|
288 |
-
}
|
289 |
-
break;
|
290 |
-
case "Shipping":
|
291 |
-
if (strlen($value) > 255) {
|
292 |
-
$this->errorLog[$this->errorCounter] = "[<b>Shipping</b>] is more that 255 character for $id.";
|
293 |
-
$this->errorCounter++;
|
294 |
-
}
|
295 |
-
break;
|
296 |
-
case "MerchantCategory":
|
297 |
-
if (strlen($value) > 255) {
|
298 |
-
$this->errorLog[$this->errorCounter] = "[<b>Shipping</b>] is more that 255 character for $id.";
|
299 |
-
$this->errorCounter++;
|
300 |
-
}
|
301 |
-
break;
|
302 |
-
case "Condition":
|
303 |
-
if (strlen($this->products[$no][$key]) > 15) {
|
304 |
-
$this->errorLog[$this->errorCounter] = "[<b>Condition</b>] is more that 15 character for $id.";
|
305 |
-
$this->errorCounter++;
|
306 |
-
}
|
307 |
-
break;
|
308 |
-
default:
|
309 |
-
break;
|
310 |
-
}
|
311 |
-
}
|
312 |
-
}
|
313 |
-
}
|
314 |
-
|
315 |
-
/**
|
316 |
-
* Return Dynamic Category Mapping Values by Parent Product Id
|
317 |
-
*
|
318 |
-
* @param string $mappingName Category Mapping Name
|
319 |
-
* @param int $parent Parent id of the product
|
320 |
-
* @return mixed
|
321 |
-
*/
|
322 |
-
public function get_category_mapping_value($mappingName, $parent)
|
323 |
-
{
|
324 |
-
$getValue = unserialize(get_option($mappingName));
|
325 |
-
$mapp = array_reverse($getValue['cmapping'], true);
|
326 |
-
$categories = get_the_terms($parent, 'product_cat');
|
327 |
-
|
328 |
-
foreach ($categories as $key => $category) {
|
329 |
-
if (!empty($mapp[$category->term_id]))
|
330 |
-
return $mapp[$category->term_id];
|
331 |
-
}
|
332 |
-
return false;
|
333 |
-
}
|
334 |
-
|
335 |
-
/**
|
336 |
-
* Configure the feed according to the rules
|
337 |
-
* @return Shopping
|
338 |
-
*/
|
339 |
-
public function mapProductsByRules()
|
340 |
-
{
|
341 |
-
/**
|
342 |
-
* Get WooCommerce Products
|
343 |
-
* @package Woo_Feed_Products
|
344 |
-
*/
|
345 |
-
$products = new Woo_Feed_Products();
|
346 |
-
|
347 |
-
/**
|
348 |
-
* This variable contain selected Woo attributes from feed making form
|
349 |
-
*
|
350 |
-
* @since 1.0.0
|
351 |
-
* @var array $attributes contain selected Woo attributes from feed making form
|
352 |
-
*/
|
353 |
-
$attributes = $this->rules['attributes'];
|
354 |
-
/**
|
355 |
-
* This variable contain selected Prefix Values from feed making form
|
356 |
-
*
|
357 |
-
* @since 1.0.0
|
358 |
-
* @var array $prefix Prefix Values from feed making form
|
359 |
-
*/
|
360 |
-
$prefix = $this->rules['prefix'];
|
361 |
-
/**
|
362 |
-
* This variable contain selected Prefix Values from feed making form
|
363 |
-
*
|
364 |
-
* @since 1.0.0
|
365 |
-
* @var array $suffix Suffix Values from feed making form
|
366 |
-
*/
|
367 |
-
$suffix = $this->rules['suffix'];
|
368 |
-
/**
|
369 |
-
* This variable contain selected Output Types from feed making form
|
370 |
-
*
|
371 |
-
* @since 1.0.0
|
372 |
-
* @var array $outputType Output Types from feed making form
|
373 |
-
*/
|
374 |
-
$outputType = $this->rules['output_type'];
|
375 |
-
|
376 |
-
/**
|
377 |
-
* This variable contain selected Output Limit from feed making form
|
378 |
-
*
|
379 |
-
* @since 1.0.0
|
380 |
-
* @var array $limit Output Limit from feed making form
|
381 |
-
*/
|
382 |
-
$limit = $this->rules['limit'];
|
383 |
-
/**
|
384 |
-
* This variable contain selected Merchant attributes from feed making form
|
385 |
-
*
|
386 |
-
* @since 1.0.0
|
387 |
-
* @var array $merchantAttributes contain selected Woo attributes from feed making form
|
388 |
-
*/
|
389 |
-
$merchantAttributes = $this->rules['mattributes'];
|
390 |
-
/**
|
391 |
-
* This variable contain attribute types from feed making form
|
392 |
-
*
|
393 |
-
* @since 1.0.0
|
394 |
-
* @var array $type contain attribute types from feed making form
|
395 |
-
*/
|
396 |
-
$type = $this->rules['type'];
|
397 |
-
/**
|
398 |
-
* This variable contain manual output of attribute from feed making form
|
399 |
-
*
|
400 |
-
* @since 1.0.0
|
401 |
-
* @var array $default contain manual output of attribute
|
402 |
-
*/
|
403 |
-
$default = $this->rules['default'];
|
404 |
-
|
405 |
-
/**
|
406 |
-
* This variable contain feed type
|
407 |
-
*
|
408 |
-
* @since 1.0.0
|
409 |
-
* @var array $feedType contain feed type
|
410 |
-
*/
|
411 |
-
$feedType = $this->rules['feedType'];
|
412 |
-
|
413 |
-
// Map Merchant Attributes and Woo Attributes
|
414 |
-
if (count($merchantAttributes)) {
|
415 |
-
foreach ($merchantAttributes as $key => $attr) {
|
416 |
-
if (!empty($attr) && !empty($attributes[$key])) {
|
417 |
-
if ($type[$key] == 'attribute') {
|
418 |
-
$this->mapping[$attr]['value'] = $attributes[$key];
|
419 |
-
$this->mapping[$attr]['suffix'] = $suffix[$key];
|
420 |
-
$this->mapping[$attr]['prefix'] = $prefix[$key];
|
421 |
-
$this->mapping[$attr]['type'] = $outputType[$key];
|
422 |
-
$this->mapping[$attr]['limit'] = $limit[$key];
|
423 |
-
}
|
424 |
-
} else if (empty($attributes[$key])) {
|
425 |
-
if ($type[$key] == 'pattern') {
|
426 |
-
$this->mapping[$attr]['value'] = "wf_pattern_$default[$key]";
|
427 |
-
$this->mapping[$attr]['suffix'] = $suffix[$key];
|
428 |
-
$this->mapping[$attr]['prefix'] = $prefix[$key];
|
429 |
-
$this->mapping[$attr]['type'] = $outputType[$key];
|
430 |
-
$this->mapping[$attr]['limit'] = $limit[$key];
|
431 |
-
}
|
432 |
-
}
|
433 |
-
}
|
434 |
-
}
|
435 |
-
|
436 |
-
// Make Product feed array according to mapping
|
437 |
-
foreach ($products->woo_feed_get_visible_product() as $key => $value) {
|
438 |
-
$i = 0;
|
439 |
-
foreach ($this->mapping as $attr => $rules) {
|
440 |
-
if (array_key_exists($rules['value'], $value)) {
|
441 |
-
|
442 |
-
$output = $rules['prefix'] . $value[$rules['value']] . " " . $rules['suffix'];
|
443 |
-
// Format According to output type
|
444 |
-
if ($rules['type'] == 2) {
|
445 |
-
$output = strip_tags($output);
|
446 |
-
} elseif ($rules['type'] == 3) {
|
447 |
-
$output = absint($output);
|
448 |
-
}
|
449 |
-
// Format According to output limit
|
450 |
-
if (!empty($rules['limit']) && is_numeric($rules['limit'])) {
|
451 |
-
$output = substr($output, 0, $rules['limit']);
|
452 |
-
}
|
453 |
-
$attr = trim($attr);
|
454 |
-
$this->products[$key][$attr] = trim($output);
|
455 |
-
} else {
|
456 |
-
if (!empty($default[$i])) {
|
457 |
-
$output = $rules['prefix'] . str_replace("wf_pattern_", "", $rules['value']) . " " . $rules['suffix'];
|
458 |
-
if ($rules['type'] == 2) {
|
459 |
-
$output = strip_tags($output);
|
460 |
-
} elseif ($rules['type'] == 3) {
|
461 |
-
$output = absint($output);
|
462 |
-
}
|
463 |
-
// Format According to output limit
|
464 |
-
if (!empty($rules['limit']) && is_numeric($rules['limit'])) {
|
465 |
-
$output = substr($output, 0, $rules['limit']);
|
466 |
-
}
|
467 |
-
$attr = trim($attr);
|
468 |
-
$this->products[$key][$attr] = trim($output);
|
469 |
-
}
|
470 |
-
}
|
471 |
-
$i++;
|
472 |
-
}
|
473 |
-
}
|
474 |
-
|
475 |
-
return $this->products;
|
476 |
-
}
|
477 |
-
|
478 |
-
/**
|
479 |
-
* Change the products old array key and set new
|
480 |
-
*
|
481 |
-
* @param string $from Attribute Before
|
482 |
-
* @param string $to Attribute After
|
483 |
-
* @param bool $cdata Enclose Feed value
|
484 |
-
*/
|
485 |
-
public function mapAttribute($from, $to, $cdata = false)
|
486 |
-
{
|
487 |
-
$i = 0;
|
488 |
-
foreach ($this->products as $no => $product) {
|
489 |
-
foreach ($product as $key => $value) {
|
490 |
-
if ($key == $from) {
|
491 |
-
unset($this->products[$no][$from]);
|
492 |
-
if ($from == 'images') {
|
493 |
-
$this->products[$no][$to] = $value;
|
494 |
-
} else {
|
495 |
-
$this->products[$no][$to] = $this->formatXMLLine($to, $value, $cdata, true, true);
|
496 |
-
}
|
497 |
-
|
498 |
-
}
|
499 |
-
}
|
500 |
-
$i++;
|
501 |
-
}
|
502 |
-
}
|
503 |
-
|
504 |
-
/**
|
505 |
-
* Format and Make the XML node for the Feed
|
506 |
-
*
|
507 |
-
* @param $attribute
|
508 |
-
* @param $value
|
509 |
-
* @param bool $cdata
|
510 |
-
* @param bool $stripHTML
|
511 |
-
* @param bool $utf8encode
|
512 |
-
* @param string $space
|
513 |
-
* @return string
|
514 |
-
*/
|
515 |
-
function formatXMLLine($attribute, $value, $cdata = false, $stripHTML = true, $utf8encode = true, $space = ' ')
|
516 |
-
{
|
517 |
-
//Make single line for XML
|
518 |
-
$c_leader = '';
|
519 |
-
$c_footer = '';
|
520 |
-
if ($cdata) {
|
521 |
-
$c_leader = '<![CDATA[';
|
522 |
-
$c_footer = ']]>';
|
523 |
-
}
|
524 |
-
//Allow force strip HTML
|
525 |
-
if ($stripHTML)
|
526 |
-
$value = strip_tags(html_entity_decode($value));
|
527 |
-
|
528 |
-
if ($utf8encode || $utf8encode == 1) {
|
529 |
-
$value = utf8_encode($value);
|
530 |
-
$attribute = utf8_encode($attribute);
|
531 |
-
}
|
532 |
-
|
533 |
-
if (!$cdata)
|
534 |
-
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
|
535 |
-
|
536 |
-
if (gettype($value) == 'array')
|
537 |
-
$value = json_encode($value);
|
538 |
-
|
539 |
-
return '
|
540 |
-
' . $space . '<' . $attribute . '>' . $c_leader . $value . $c_footer . '</' . $attribute . '>';
|
541 |
-
}
|
542 |
-
|
543 |
-
/**
|
544 |
-
* Responsible to change product array key
|
545 |
-
*
|
546 |
-
* @param $array
|
547 |
-
* @param $old_key
|
548 |
-
* @param $new_key
|
549 |
-
* @return array
|
550 |
-
*/
|
551 |
-
public function change_key($array, $old_key, $new_key)
|
552 |
-
{
|
553 |
-
foreach ($this->products as $no => $product) {
|
554 |
-
if (!array_key_exists($old_key, $product))
|
555 |
-
return $array;
|
556 |
-
|
557 |
-
$keys = array_keys($array);
|
558 |
-
$keys[array_search($old_key, $keys)] = $new_key;
|
559 |
-
}
|
560 |
-
return array_combine($keys, $array);
|
561 |
-
}
|
562 |
-
|
563 |
-
/**
|
564 |
-
* Responsible to make XML feed header
|
565 |
-
* @return string
|
566 |
-
*/
|
567 |
-
public function get_feed_header()
|
568 |
-
{
|
569 |
-
$output = '<?xml version="1.0" encoding="UTF-8" ?>
|
570 |
-
<products>';
|
571 |
-
$output .= "\n";
|
572 |
-
return $output;
|
573 |
-
}
|
574 |
-
|
575 |
-
/**
|
576 |
-
* Responsible to make XML feed body
|
577 |
-
* @var array $items Product array
|
578 |
-
* @return string
|
579 |
-
*/
|
580 |
-
public function get_feed($items)
|
581 |
-
{
|
582 |
-
$feed = "";
|
583 |
-
$feed .= $this->get_feed_header();
|
584 |
-
$feed .= "\n";
|
585 |
-
foreach ($items as $item => $products) {
|
586 |
-
$feed .= " <" . $this->feedWrapper . ">";
|
587 |
-
foreach ($products as $key => $value) {
|
588 |
-
if (!empty($value))
|
589 |
-
$feed .= $value;
|
590 |
-
}
|
591 |
-
$feed .= "\n </" . $this->feedWrapper . ">\n";
|
592 |
-
}
|
593 |
-
$feed .= $this->get_feed_footer();
|
594 |
-
|
595 |
-
return $feed;
|
596 |
-
}
|
597 |
-
|
598 |
-
|
599 |
-
/**
|
600 |
-
* Responsible to make XML feed footer
|
601 |
-
* @return string
|
602 |
-
*/
|
603 |
-
public function get_feed_footer()
|
604 |
-
{
|
605 |
-
$footer = " </products>";
|
606 |
-
return $footer;
|
607 |
-
}
|
608 |
-
|
609 |
-
/**
|
610 |
-
* Responsible to make TXT feed
|
611 |
-
* @return string
|
612 |
-
*/
|
613 |
-
public function get_txt_feed()
|
614 |
-
{
|
615 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
616 |
-
$headers = array_keys($this->products[0]);
|
617 |
-
$feed[] = $headers;
|
618 |
-
foreach ($this->products as $no => $product) {
|
619 |
-
$row = array();
|
620 |
-
foreach ($headers as $key => $header) {
|
621 |
-
$row[] = $product[$header];
|
622 |
-
}
|
623 |
-
$feed[] = $row;
|
624 |
-
}
|
625 |
-
$str = "";
|
626 |
-
foreach ($feed as $fields) {
|
627 |
-
$str .= implode("\t", $fields) . "\n";
|
628 |
-
}
|
629 |
-
return $str;
|
630 |
-
}
|
631 |
-
return false;
|
632 |
-
}
|
633 |
-
|
634 |
-
public function get_csv_feed()
|
635 |
-
{
|
636 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
637 |
-
$headers = array_keys($this->products[0]);
|
638 |
-
$feed[] = $headers;
|
639 |
-
foreach ($this->products as $no => $product) {
|
640 |
-
$row = array();
|
641 |
-
foreach ($headers as $key => $header) {
|
642 |
-
$row[] = $product[$header];
|
643 |
-
}
|
644 |
-
$feed[] = $row;
|
645 |
-
}
|
646 |
-
|
647 |
-
return $feed;
|
648 |
-
}
|
649 |
-
return false;
|
650 |
-
}
|
651 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Bing
|
5 |
+
*
|
6 |
+
* Responsible for processing and generating feed for Bing.com
|
7 |
+
*
|
8 |
+
* @since 1.0.0
|
9 |
+
* @package Bing
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Bing
|
13 |
+
{
|
14 |
+
|
15 |
+
/**
|
16 |
+
* This variable is responsible for holding all product attributes and their values
|
17 |
+
*
|
18 |
+
* @since 1.0.0
|
19 |
+
* @var array $products Contains all the product attributes to generate feed
|
20 |
+
* @access public
|
21 |
+
*/
|
22 |
+
public $products;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* This variable is responsible for holding feed configuration form values
|
26 |
+
*
|
27 |
+
* @since 1.0.0
|
28 |
+
* @var Bing $rules Contains feed configuration form values
|
29 |
+
* @access public
|
30 |
+
*/
|
31 |
+
public $rules;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* This variable is responsible for mapping store attributes to merchant attribute
|
35 |
+
*
|
36 |
+
* @since 1.0.0
|
37 |
+
* @var Bing $mapping Map store attributes to merchant attribute
|
38 |
+
* @access public
|
39 |
+
*/
|
40 |
+
public $mapping;
|
41 |
+
|
42 |
+
/**
|
43 |
+
* This variable is responsible for generate error logs
|
44 |
+
*
|
45 |
+
* @since 1.0.0
|
46 |
+
* @var Bing $errorLog Generate error logs
|
47 |
+
* @access public
|
48 |
+
*/
|
49 |
+
public $errorLog;
|
50 |
+
|
51 |
+
/**
|
52 |
+
* This variable is responsible for making error number
|
53 |
+
*
|
54 |
+
* @since 1.0.0
|
55 |
+
* @var Bing $errorCounter Generate error number
|
56 |
+
* @access public
|
57 |
+
*/
|
58 |
+
public $errorCounter;
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Feed Wrapper text for enclosing each product information
|
62 |
+
*
|
63 |
+
* @since 1.0.0
|
64 |
+
* @var Bing $feedWrapper Feed Wrapper text
|
65 |
+
* @access public
|
66 |
+
*/
|
67 |
+
private $feedWrapper = 'product';
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Define the core functionality to generate feed.
|
71 |
+
*
|
72 |
+
* Set the feed rules. Map products according to the rules and Check required attributes
|
73 |
+
* and their values according to merchant specification.
|
74 |
+
* @var Woo_Generate_Feed $feedRule Contain Feed Configuration
|
75 |
+
* @since 1.0.0
|
76 |
+
*/
|
77 |
+
public function __construct($feedRule)
|
78 |
+
{
|
79 |
+
$this->errorCounter = 0;
|
80 |
+
$this->rules = $feedRule;
|
81 |
+
$this->mapProductsByRules();
|
82 |
+
//$this->formatRequiredField();
|
83 |
+
//$this->filterProductValues();
|
84 |
+
if ($this->rules['feedType'] == 'xml') {
|
85 |
+
$this->mapAttributeForXML();
|
86 |
+
} else {
|
87 |
+
$this->mapAttributeForCSVTEXT();
|
88 |
+
}
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Configure merchant attributes for XML feed
|
93 |
+
*/
|
94 |
+
public function mapAttributeForXML()
|
95 |
+
{
|
96 |
+
//Basic product information
|
97 |
+
|
98 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
99 |
+
foreach ($this->products as $key => $values) {
|
100 |
+
foreach ($values as $attr => $value) {
|
101 |
+
$this->products[$key][$attr] = $this->formatXMLLine($attr, $value, true, true, true);
|
102 |
+
}
|
103 |
+
}
|
104 |
+
}
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Configure merchant attributes for CSV and TXT feed
|
109 |
+
*/
|
110 |
+
public function mapAttributeForCSVTEXT()
|
111 |
+
{
|
112 |
+
//Basic product information
|
113 |
+
|
114 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
115 |
+
foreach ($this->products as $key => $values) {
|
116 |
+
foreach ($values as $attr => $value) {
|
117 |
+
//Allow force strip HTML
|
118 |
+
|
119 |
+
$value = strip_tags(html_entity_decode($value));
|
120 |
+
|
121 |
+
$value = utf8_encode($value);
|
122 |
+
$attr = utf8_encode($attr);
|
123 |
+
|
124 |
+
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
|
125 |
+
|
126 |
+
if (gettype($value) == 'array')
|
127 |
+
$value = json_encode($value);
|
128 |
+
|
129 |
+
$this->products[$key][$attr] = $value;
|
130 |
+
}
|
131 |
+
}
|
132 |
+
}
|
133 |
+
}
|
134 |
+
|
135 |
+
/**
|
136 |
+
* Check all the required attributes and make error message
|
137 |
+
*/
|
138 |
+
public function formatRequiredField()
|
139 |
+
{
|
140 |
+
foreach ($this->products as $no => $product) {
|
141 |
+
$upn = 0;
|
142 |
+
if (array_key_exists('MerchantProductID', $product)) {
|
143 |
+
$id = $product['MerchantProductID'];
|
144 |
+
} else {
|
145 |
+
$id = $product['Title'];
|
146 |
+
}
|
147 |
+
|
148 |
+
if (!array_key_exists('MerchantProductID', $product)) {
|
149 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>MerchantProductID</b>] Missing for <b>$id</b>.";
|
150 |
+
$this->errorCounter++;
|
151 |
+
}
|
152 |
+
|
153 |
+
|
154 |
+
if (!array_key_exists('Title', $product)) {
|
155 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Title</b>] Missing for <b>$id</b>.";
|
156 |
+
$this->errorCounter++;
|
157 |
+
}
|
158 |
+
|
159 |
+
if (!array_key_exists('ProductURL', $product)) {
|
160 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>ProductURL</b>] Missing for <b>$id</b>.";
|
161 |
+
$this->errorCounter++;
|
162 |
+
}
|
163 |
+
|
164 |
+
if (!array_key_exists('Price', $product)) {
|
165 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Price</b>] Missing for <b>$id</b>.";
|
166 |
+
$this->errorCounter++;
|
167 |
+
}
|
168 |
+
|
169 |
+
if (!array_key_exists('Description', $product)) {
|
170 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Description</b>] Missing for <b>$id</b>.";
|
171 |
+
$this->errorCounter++;
|
172 |
+
}
|
173 |
+
|
174 |
+
if (!array_key_exists('ImageURL', $product)) {
|
175 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>ImageURL</b>] Missing for <b>$id</b>.";
|
176 |
+
$this->errorCounter++;
|
177 |
+
}
|
178 |
+
|
179 |
+
}
|
180 |
+
}
|
181 |
+
|
182 |
+
/**
|
183 |
+
* Return Feed
|
184 |
+
*
|
185 |
+
* @return array|bool|string
|
186 |
+
*/
|
187 |
+
public function returnFinalProduct()
|
188 |
+
{
|
189 |
+
if ($this->rules['feedType'] == 'xml') {
|
190 |
+
return $this->get_feed($this->products);
|
191 |
+
} elseif ($this->rules['feedType'] == 'txt') {
|
192 |
+
return $this->get_txt_feed();
|
193 |
+
} elseif ($this->rules['feedType'] == 'csv') {
|
194 |
+
return $this->get_csv_feed();
|
195 |
+
}
|
196 |
+
return false;
|
197 |
+
}
|
198 |
+
|
199 |
+
/**
|
200 |
+
* Check product's attribute value according to merchant specifications
|
201 |
+
*/
|
202 |
+
public function filterProductValues()
|
203 |
+
{
|
204 |
+
$getProduct = new Woo_Feed_Products();
|
205 |
+
$products = $this->products;
|
206 |
+
|
207 |
+
foreach ($products as $no => $product) {
|
208 |
+
if (array_key_exists('MerchantProductID', $product)) {
|
209 |
+
$id = $product['MerchantProductID'];
|
210 |
+
} else {
|
211 |
+
$id = $product['Title'];
|
212 |
+
}
|
213 |
+
// echo "<pre>";
|
214 |
+
// print_r($product);
|
215 |
+
foreach ($product as $key => $value) {
|
216 |
+
|
217 |
+
|
218 |
+
switch ($key) {
|
219 |
+
case "MerchantProductID":
|
220 |
+
if (strlen($value) > 100) {
|
221 |
+
$this->errorLog[$this->errorCounter] = "[<b>MerchantProductID</b>] is more that 100 character for $id.";
|
222 |
+
$this->errorCounter++;
|
223 |
+
}
|
224 |
+
break;
|
225 |
+
case "Title":
|
226 |
+
if (strlen($value) > 255) {
|
227 |
+
$this->errorLog[$this->errorCounter] = "[<b>Title</b>] is more that 255 character for $id.";
|
228 |
+
$this->errorCounter++;
|
229 |
+
}
|
230 |
+
break;
|
231 |
+
case "Brand":
|
232 |
+
if (strlen($value) > 1500) {
|
233 |
+
$this->errorLog[$this->errorCounter] = "[<b>Brand</b>] is more that 1500 character for $id.";
|
234 |
+
$this->errorCounter++;
|
235 |
+
}
|
236 |
+
break;
|
237 |
+
case "MPN":
|
238 |
+
if (strlen($value) > 255) {
|
239 |
+
$this->errorLog[$this->errorCounter] = "[<b>MPN</b>] is more that 255 character for $id.";
|
240 |
+
$this->errorCounter++;
|
241 |
+
}
|
242 |
+
break;
|
243 |
+
case "UPC":
|
244 |
+
if (strlen($value) > 12) {
|
245 |
+
$this->errorLog[$this->errorCounter] = "[<b>UPC</b>] is more that 12 character for $id.";
|
246 |
+
$this->errorCounter++;
|
247 |
+
}
|
248 |
+
break;
|
249 |
+
case "ISBN":
|
250 |
+
if (strlen($value) > 13) {
|
251 |
+
$this->errorLog[$this->errorCounter] = "[<b>ISBN</b>] is more that 13 character for $id.";
|
252 |
+
$this->errorCounter++;
|
253 |
+
}
|
254 |
+
break;
|
255 |
+
case "ProductURL":
|
256 |
+
if (strlen($value) > 2000) {
|
257 |
+
$this->errorLog[$this->errorCounter] = "[<b>ProductURL</b>] is more that 2000 character for $id.";
|
258 |
+
$this->errorCounter++;
|
259 |
+
}
|
260 |
+
break;
|
261 |
+
case "Price":
|
262 |
+
if (!is_numeric($value)) {
|
263 |
+
$this->errorLog[$this->errorCounter] = "[<b>Price</b>] should be numeric for $id.";
|
264 |
+
$this->errorCounter++;
|
265 |
+
}
|
266 |
+
break;
|
267 |
+
case "Availability":
|
268 |
+
if ($value == 'in stock') {
|
269 |
+
$this->products[$no][$key] = "In Stock";
|
270 |
+
} else if ($value == 'out of stock') {
|
271 |
+
$this->products[$no][$key] = "Out of Stock";
|
272 |
+
}
|
273 |
+
if (strlen($this->products[$no][$key]) > 15) {
|
274 |
+
$this->errorLog[$this->errorCounter] = "[<b>Availability</b>] is more that 15 character for $id.";
|
275 |
+
$this->errorCounter++;
|
276 |
+
}
|
277 |
+
break;
|
278 |
+
case "Description":
|
279 |
+
if (strlen($value) > 5000) {
|
280 |
+
$this->errorLog[$this->errorCounter] = "[<b>Description</b>] is more that 5000 character for $id.";
|
281 |
+
$this->errorCounter++;
|
282 |
+
}
|
283 |
+
break;
|
284 |
+
case "ImageURL":
|
285 |
+
if (strlen($value) > 1000) {
|
286 |
+
$this->errorLog[$this->errorCounter] = "[<b>ImageURL</b>] is more that 1000 character for $id.";
|
287 |
+
$this->errorCounter++;
|
288 |
+
}
|
289 |
+
break;
|
290 |
+
case "Shipping":
|
291 |
+
if (strlen($value) > 255) {
|
292 |
+
$this->errorLog[$this->errorCounter] = "[<b>Shipping</b>] is more that 255 character for $id.";
|
293 |
+
$this->errorCounter++;
|
294 |
+
}
|
295 |
+
break;
|
296 |
+
case "MerchantCategory":
|
297 |
+
if (strlen($value) > 255) {
|
298 |
+
$this->errorLog[$this->errorCounter] = "[<b>Shipping</b>] is more that 255 character for $id.";
|
299 |
+
$this->errorCounter++;
|
300 |
+
}
|
301 |
+
break;
|
302 |
+
case "Condition":
|
303 |
+
if (strlen($this->products[$no][$key]) > 15) {
|
304 |
+
$this->errorLog[$this->errorCounter] = "[<b>Condition</b>] is more that 15 character for $id.";
|
305 |
+
$this->errorCounter++;
|
306 |
+
}
|
307 |
+
break;
|
308 |
+
default:
|
309 |
+
break;
|
310 |
+
}
|
311 |
+
}
|
312 |
+
}
|
313 |
+
}
|
314 |
+
|
315 |
+
/**
|
316 |
+
* Return Dynamic Category Mapping Values by Parent Product Id
|
317 |
+
*
|
318 |
+
* @param string $mappingName Category Mapping Name
|
319 |
+
* @param int $parent Parent id of the product
|
320 |
+
* @return mixed
|
321 |
+
*/
|
322 |
+
public function get_category_mapping_value($mappingName, $parent)
|
323 |
+
{
|
324 |
+
$getValue = unserialize(get_option($mappingName));
|
325 |
+
$mapp = array_reverse($getValue['cmapping'], true);
|
326 |
+
$categories = get_the_terms($parent, 'product_cat');
|
327 |
+
|
328 |
+
foreach ($categories as $key => $category) {
|
329 |
+
if (!empty($mapp[$category->term_id]))
|
330 |
+
return $mapp[$category->term_id];
|
331 |
+
}
|
332 |
+
return false;
|
333 |
+
}
|
334 |
+
|
335 |
+
/**
|
336 |
+
* Configure the feed according to the rules
|
337 |
+
* @return Shopping
|
338 |
+
*/
|
339 |
+
public function mapProductsByRules()
|
340 |
+
{
|
341 |
+
/**
|
342 |
+
* Get WooCommerce Products
|
343 |
+
* @package Woo_Feed_Products
|
344 |
+
*/
|
345 |
+
$products = new Woo_Feed_Products();
|
346 |
+
|
347 |
+
/**
|
348 |
+
* This variable contain selected Woo attributes from feed making form
|
349 |
+
*
|
350 |
+
* @since 1.0.0
|
351 |
+
* @var array $attributes contain selected Woo attributes from feed making form
|
352 |
+
*/
|
353 |
+
$attributes = $this->rules['attributes'];
|
354 |
+
/**
|
355 |
+
* This variable contain selected Prefix Values from feed making form
|
356 |
+
*
|
357 |
+
* @since 1.0.0
|
358 |
+
* @var array $prefix Prefix Values from feed making form
|
359 |
+
*/
|
360 |
+
$prefix = $this->rules['prefix'];
|
361 |
+
/**
|
362 |
+
* This variable contain selected Prefix Values from feed making form
|
363 |
+
*
|
364 |
+
* @since 1.0.0
|
365 |
+
* @var array $suffix Suffix Values from feed making form
|
366 |
+
*/
|
367 |
+
$suffix = $this->rules['suffix'];
|
368 |
+
/**
|
369 |
+
* This variable contain selected Output Types from feed making form
|
370 |
+
*
|
371 |
+
* @since 1.0.0
|
372 |
+
* @var array $outputType Output Types from feed making form
|
373 |
+
*/
|
374 |
+
$outputType = $this->rules['output_type'];
|
375 |
+
|
376 |
+
/**
|
377 |
+
* This variable contain selected Output Limit from feed making form
|
378 |
+
*
|
379 |
+
* @since 1.0.0
|
380 |
+
* @var array $limit Output Limit from feed making form
|
381 |
+
*/
|
382 |
+
$limit = $this->rules['limit'];
|
383 |
+
/**
|
384 |
+
* This variable contain selected Merchant attributes from feed making form
|
385 |
+
*
|
386 |
+
* @since 1.0.0
|
387 |
+
* @var array $merchantAttributes contain selected Woo attributes from feed making form
|
388 |
+
*/
|
389 |
+
$merchantAttributes = $this->rules['mattributes'];
|
390 |
+
/**
|
391 |
+
* This variable contain attribute types from feed making form
|
392 |
+
*
|
393 |
+
* @since 1.0.0
|
394 |
+
* @var array $type contain attribute types from feed making form
|
395 |
+
*/
|
396 |
+
$type = $this->rules['type'];
|
397 |
+
/**
|
398 |
+
* This variable contain manual output of attribute from feed making form
|
399 |
+
*
|
400 |
+
* @since 1.0.0
|
401 |
+
* @var array $default contain manual output of attribute
|
402 |
+
*/
|
403 |
+
$default = $this->rules['default'];
|
404 |
+
|
405 |
+
/**
|
406 |
+
* This variable contain feed type
|
407 |
+
*
|
408 |
+
* @since 1.0.0
|
409 |
+
* @var array $feedType contain feed type
|
410 |
+
*/
|
411 |
+
$feedType = $this->rules['feedType'];
|
412 |
+
|
413 |
+
// Map Merchant Attributes and Woo Attributes
|
414 |
+
if (count($merchantAttributes)) {
|
415 |
+
foreach ($merchantAttributes as $key => $attr) {
|
416 |
+
if (!empty($attr) && !empty($attributes[$key])) {
|
417 |
+
if ($type[$key] == 'attribute') {
|
418 |
+
$this->mapping[$attr]['value'] = $attributes[$key];
|
419 |
+
$this->mapping[$attr]['suffix'] = $suffix[$key];
|
420 |
+
$this->mapping[$attr]['prefix'] = $prefix[$key];
|
421 |
+
$this->mapping[$attr]['type'] = $outputType[$key];
|
422 |
+
$this->mapping[$attr]['limit'] = $limit[$key];
|
423 |
+
}
|
424 |
+
} else if (empty($attributes[$key])) {
|
425 |
+
if ($type[$key] == 'pattern') {
|
426 |
+
$this->mapping[$attr]['value'] = "wf_pattern_$default[$key]";
|
427 |
+
$this->mapping[$attr]['suffix'] = $suffix[$key];
|
428 |
+
$this->mapping[$attr]['prefix'] = $prefix[$key];
|
429 |
+
$this->mapping[$attr]['type'] = $outputType[$key];
|
430 |
+
$this->mapping[$attr]['limit'] = $limit[$key];
|
431 |
+
}
|
432 |
+
}
|
433 |
+
}
|
434 |
+
}
|
435 |
+
|
436 |
+
// Make Product feed array according to mapping
|
437 |
+
foreach ($products->woo_feed_get_visible_product() as $key => $value) {
|
438 |
+
$i = 0;
|
439 |
+
foreach ($this->mapping as $attr => $rules) {
|
440 |
+
if (array_key_exists($rules['value'], $value)) {
|
441 |
+
|
442 |
+
$output = $rules['prefix'] . $value[$rules['value']] . " " . $rules['suffix'];
|
443 |
+
// Format According to output type
|
444 |
+
if ($rules['type'] == 2) {
|
445 |
+
$output = strip_tags($output);
|
446 |
+
} elseif ($rules['type'] == 3) {
|
447 |
+
$output = absint($output);
|
448 |
+
}
|
449 |
+
// Format According to output limit
|
450 |
+
if (!empty($rules['limit']) && is_numeric($rules['limit'])) {
|
451 |
+
$output = substr($output, 0, $rules['limit']);
|
452 |
+
}
|
453 |
+
$attr = trim($attr);
|
454 |
+
$this->products[$key][$attr] = trim($output);
|
455 |
+
} else {
|
456 |
+
if (!empty($default[$i])) {
|
457 |
+
$output = $rules['prefix'] . str_replace("wf_pattern_", "", $rules['value']) . " " . $rules['suffix'];
|
458 |
+
if ($rules['type'] == 2) {
|
459 |
+
$output = strip_tags($output);
|
460 |
+
} elseif ($rules['type'] == 3) {
|
461 |
+
$output = absint($output);
|
462 |
+
}
|
463 |
+
// Format According to output limit
|
464 |
+
if (!empty($rules['limit']) && is_numeric($rules['limit'])) {
|
465 |
+
$output = substr($output, 0, $rules['limit']);
|
466 |
+
}
|
467 |
+
$attr = trim($attr);
|
468 |
+
$this->products[$key][$attr] = trim($output);
|
469 |
+
}
|
470 |
+
}
|
471 |
+
$i++;
|
472 |
+
}
|
473 |
+
}
|
474 |
+
|
475 |
+
return $this->products;
|
476 |
+
}
|
477 |
+
|
478 |
+
/**
|
479 |
+
* Change the products old array key and set new
|
480 |
+
*
|
481 |
+
* @param string $from Attribute Before
|
482 |
+
* @param string $to Attribute After
|
483 |
+
* @param bool $cdata Enclose Feed value
|
484 |
+
*/
|
485 |
+
public function mapAttribute($from, $to, $cdata = false)
|
486 |
+
{
|
487 |
+
$i = 0;
|
488 |
+
foreach ($this->products as $no => $product) {
|
489 |
+
foreach ($product as $key => $value) {
|
490 |
+
if ($key == $from) {
|
491 |
+
unset($this->products[$no][$from]);
|
492 |
+
if ($from == 'images') {
|
493 |
+
$this->products[$no][$to] = $value;
|
494 |
+
} else {
|
495 |
+
$this->products[$no][$to] = $this->formatXMLLine($to, $value, $cdata, true, true);
|
496 |
+
}
|
497 |
+
|
498 |
+
}
|
499 |
+
}
|
500 |
+
$i++;
|
501 |
+
}
|
502 |
+
}
|
503 |
+
|
504 |
+
/**
|
505 |
+
* Format and Make the XML node for the Feed
|
506 |
+
*
|
507 |
+
* @param $attribute
|
508 |
+
* @param $value
|
509 |
+
* @param bool $cdata
|
510 |
+
* @param bool $stripHTML
|
511 |
+
* @param bool $utf8encode
|
512 |
+
* @param string $space
|
513 |
+
* @return string
|
514 |
+
*/
|
515 |
+
function formatXMLLine($attribute, $value, $cdata = false, $stripHTML = true, $utf8encode = true, $space = ' ')
|
516 |
+
{
|
517 |
+
//Make single line for XML
|
518 |
+
$c_leader = '';
|
519 |
+
$c_footer = '';
|
520 |
+
if ($cdata) {
|
521 |
+
$c_leader = '<![CDATA[';
|
522 |
+
$c_footer = ']]>';
|
523 |
+
}
|
524 |
+
//Allow force strip HTML
|
525 |
+
if ($stripHTML)
|
526 |
+
$value = strip_tags(html_entity_decode($value));
|
527 |
+
|
528 |
+
if ($utf8encode || $utf8encode == 1) {
|
529 |
+
$value = utf8_encode($value);
|
530 |
+
$attribute = utf8_encode($attribute);
|
531 |
+
}
|
532 |
+
|
533 |
+
if (!$cdata)
|
534 |
+
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
|
535 |
+
|
536 |
+
if (gettype($value) == 'array')
|
537 |
+
$value = json_encode($value);
|
538 |
+
|
539 |
+
return '
|
540 |
+
' . $space . '<' . $attribute . '>' . $c_leader . $value . $c_footer . '</' . $attribute . '>';
|
541 |
+
}
|
542 |
+
|
543 |
+
/**
|
544 |
+
* Responsible to change product array key
|
545 |
+
*
|
546 |
+
* @param $array
|
547 |
+
* @param $old_key
|
548 |
+
* @param $new_key
|
549 |
+
* @return array
|
550 |
+
*/
|
551 |
+
public function change_key($array, $old_key, $new_key)
|
552 |
+
{
|
553 |
+
foreach ($this->products as $no => $product) {
|
554 |
+
if (!array_key_exists($old_key, $product))
|
555 |
+
return $array;
|
556 |
+
|
557 |
+
$keys = array_keys($array);
|
558 |
+
$keys[array_search($old_key, $keys)] = $new_key;
|
559 |
+
}
|
560 |
+
return array_combine($keys, $array);
|
561 |
+
}
|
562 |
+
|
563 |
+
/**
|
564 |
+
* Responsible to make XML feed header
|
565 |
+
* @return string
|
566 |
+
*/
|
567 |
+
public function get_feed_header()
|
568 |
+
{
|
569 |
+
$output = '<?xml version="1.0" encoding="UTF-8" ?>
|
570 |
+
<products>';
|
571 |
+
$output .= "\n";
|
572 |
+
return $output;
|
573 |
+
}
|
574 |
+
|
575 |
+
/**
|
576 |
+
* Responsible to make XML feed body
|
577 |
+
* @var array $items Product array
|
578 |
+
* @return string
|
579 |
+
*/
|
580 |
+
public function get_feed($items)
|
581 |
+
{
|
582 |
+
$feed = "";
|
583 |
+
$feed .= $this->get_feed_header();
|
584 |
+
$feed .= "\n";
|
585 |
+
foreach ($items as $item => $products) {
|
586 |
+
$feed .= " <" . $this->feedWrapper . ">";
|
587 |
+
foreach ($products as $key => $value) {
|
588 |
+
if (!empty($value))
|
589 |
+
$feed .= $value;
|
590 |
+
}
|
591 |
+
$feed .= "\n </" . $this->feedWrapper . ">\n";
|
592 |
+
}
|
593 |
+
$feed .= $this->get_feed_footer();
|
594 |
+
|
595 |
+
return $feed;
|
596 |
+
}
|
597 |
+
|
598 |
+
|
599 |
+
/**
|
600 |
+
* Responsible to make XML feed footer
|
601 |
+
* @return string
|
602 |
+
*/
|
603 |
+
public function get_feed_footer()
|
604 |
+
{
|
605 |
+
$footer = " </products>";
|
606 |
+
return $footer;
|
607 |
+
}
|
608 |
+
|
609 |
+
/**
|
610 |
+
* Responsible to make TXT feed
|
611 |
+
* @return string
|
612 |
+
*/
|
613 |
+
public function get_txt_feed()
|
614 |
+
{
|
615 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
616 |
+
$headers = array_keys($this->products[0]);
|
617 |
+
$feed[] = $headers;
|
618 |
+
foreach ($this->products as $no => $product) {
|
619 |
+
$row = array();
|
620 |
+
foreach ($headers as $key => $header) {
|
621 |
+
$row[] = $product[$header];
|
622 |
+
}
|
623 |
+
$feed[] = $row;
|
624 |
+
}
|
625 |
+
$str = "";
|
626 |
+
foreach ($feed as $fields) {
|
627 |
+
$str .= implode("\t", $fields) . "\n";
|
628 |
+
}
|
629 |
+
return $str;
|
630 |
+
}
|
631 |
+
return false;
|
632 |
+
}
|
633 |
+
|
634 |
+
public function get_csv_feed()
|
635 |
+
{
|
636 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
637 |
+
$headers = array_keys($this->products[0]);
|
638 |
+
$feed[] = $headers;
|
639 |
+
foreach ($this->products as $no => $product) {
|
640 |
+
$row = array();
|
641 |
+
foreach ($headers as $key => $header) {
|
642 |
+
$row[] = $product[$header];
|
643 |
+
}
|
644 |
+
$feed[] = $row;
|
645 |
+
}
|
646 |
+
|
647 |
+
return $feed;
|
648 |
+
}
|
649 |
+
return false;
|
650 |
+
}
|
651 |
}
|
includes/feeds/class-woo-feed-connexity.php
CHANGED
@@ -1,668 +1,668 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Class Connexity
|
5 |
-
*
|
6 |
-
* Responsible for processing and generating feed for Connexity.com
|
7 |
-
*
|
8 |
-
* @since 1.0.0
|
9 |
-
* @package Connexity
|
10 |
-
*
|
11 |
-
*/
|
12 |
-
class Connexity
|
13 |
-
{
|
14 |
-
|
15 |
-
/**
|
16 |
-
* This variable is responsible for holding all product attributes and their values
|
17 |
-
*
|
18 |
-
* @since 1.0.0
|
19 |
-
* @var array $products Contains all the product attributes to generate feed
|
20 |
-
* @access public
|
21 |
-
*/
|
22 |
-
public $products;
|
23 |
-
|
24 |
-
/**
|
25 |
-
* This variable is responsible for holding feed configuration form values
|
26 |
-
*
|
27 |
-
* @since 1.0.0
|
28 |
-
* @var Connexity $rules Contains feed configuration form values
|
29 |
-
* @access public
|
30 |
-
*/
|
31 |
-
public $rules;
|
32 |
-
|
33 |
-
/**
|
34 |
-
* This variable is responsible for mapping store attributes to merchant attribute
|
35 |
-
*
|
36 |
-
* @since 1.0.0
|
37 |
-
* @var Connexity $mapping Map store attributes to merchant attribute
|
38 |
-
* @access public
|
39 |
-
*/
|
40 |
-
public $mapping;
|
41 |
-
|
42 |
-
/**
|
43 |
-
* This variable is responsible for generate error logs
|
44 |
-
*
|
45 |
-
* @since 1.0.0
|
46 |
-
* @var Connexity $errorLog Generate error logs
|
47 |
-
* @access public
|
48 |
-
*/
|
49 |
-
public $errorLog;
|
50 |
-
|
51 |
-
/**
|
52 |
-
* This variable is responsible for making error number
|
53 |
-
*
|
54 |
-
* @since 1.0.0
|
55 |
-
* @var Connexity $errorCounter Generate error number
|
56 |
-
* @access public
|
57 |
-
*/
|
58 |
-
public $errorCounter;
|
59 |
-
|
60 |
-
/**
|
61 |
-
* Feed Wrapper text for enclosing each product information
|
62 |
-
*
|
63 |
-
* @since 1.0.0
|
64 |
-
* @var Connexity $feedWrapper Feed Wrapper text
|
65 |
-
* @access public
|
66 |
-
*/
|
67 |
-
private $feedWrapper;
|
68 |
-
|
69 |
-
/**
|
70 |
-
* Define the core functionality to generate feed.
|
71 |
-
*
|
72 |
-
* Set the feed rules. Map products according to the rules and Check required attributes
|
73 |
-
* and their values according to merchant specification.
|
74 |
-
* @var Woo_Generate_Feed $feedRule Contain Feed Configuration
|
75 |
-
* @since 1.0.0
|
76 |
-
*/
|
77 |
-
public function __construct($feedRule)
|
78 |
-
{
|
79 |
-
$this->feedWrapper = 'product';
|
80 |
-
$this->errorCounter = 0;
|
81 |
-
$this->rules = $feedRule;
|
82 |
-
$this->mapProductsByRules();
|
83 |
-
$this->formatRequiredField();
|
84 |
-
$this->filterProductValues();
|
85 |
-
if ($this->rules['feedType'] == 'xml') {
|
86 |
-
$this->mapAttributeForXML();
|
87 |
-
} else {
|
88 |
-
$this->mapAttributeForCSVTEXT();
|
89 |
-
}
|
90 |
-
}
|
91 |
-
|
92 |
-
/**
|
93 |
-
* Configure merchant attributes for XML feed
|
94 |
-
*/
|
95 |
-
public function mapAttributeForXML()
|
96 |
-
{
|
97 |
-
//Basic product information
|
98 |
-
|
99 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
100 |
-
foreach ($this->products as $key => $values) {
|
101 |
-
foreach ($values as $attr => $value) {
|
102 |
-
$this->products[$key][$attr] = $this->formatXMLLine($attr, $value, true, true, true);
|
103 |
-
}
|
104 |
-
}
|
105 |
-
}
|
106 |
-
}
|
107 |
-
|
108 |
-
/**
|
109 |
-
* Configure merchant attributes for CSV and TXT feed
|
110 |
-
*/
|
111 |
-
public function mapAttributeForCSVTEXT()
|
112 |
-
{
|
113 |
-
//Basic product information
|
114 |
-
|
115 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
116 |
-
foreach ($this->products as $key => $values) {
|
117 |
-
foreach ($values as $attr => $value) {
|
118 |
-
//Allow force strip HTML
|
119 |
-
$value = strip_tags(html_entity_decode($value));
|
120 |
-
if ($attr != 'Category') {
|
121 |
-
$value = utf8_encode($value);
|
122 |
-
$attr = utf8_encode($attr);
|
123 |
-
|
124 |
-
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
|
125 |
-
|
126 |
-
if (gettype($value) == 'array')
|
127 |
-
$value = json_encode($value);
|
128 |
-
}
|
129 |
-
|
130 |
-
$this->products[$key][$attr] = $value;
|
131 |
-
}
|
132 |
-
}
|
133 |
-
}
|
134 |
-
}
|
135 |
-
|
136 |
-
/**
|
137 |
-
* Check all the required attributes and make error message
|
138 |
-
*/
|
139 |
-
public function formatRequiredField()
|
140 |
-
{
|
141 |
-
foreach ($this->products as $no => $product) {
|
142 |
-
$upn = 0;
|
143 |
-
if (array_key_exists('Unique ID', $product)) {
|
144 |
-
$id = $product['Unique ID'];
|
145 |
-
} else {
|
146 |
-
$id = $product['Title'];
|
147 |
-
}
|
148 |
-
|
149 |
-
if (!array_key_exists('Unique ID', $product)) {
|
150 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Unique ID</b>] Missing for <b>$id</b>.";
|
151 |
-
$this->errorCounter++;
|
152 |
-
}
|
153 |
-
|
154 |
-
|
155 |
-
if (!array_key_exists('Title', $product)) {
|
156 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Title</b>] Missing for <b>$id</b>.";
|
157 |
-
$this->errorCounter++;
|
158 |
-
}
|
159 |
-
|
160 |
-
if (!array_key_exists('Description', $product)) {
|
161 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Description</b>] Missing for <b>$id</b>.";
|
162 |
-
$this->errorCounter++;
|
163 |
-
}
|
164 |
-
|
165 |
-
if (!array_key_exists('Category', $product)) {
|
166 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Category</b>] Missing for <b>$id</b>.";
|
167 |
-
$this->errorCounter++;
|
168 |
-
}
|
169 |
-
|
170 |
-
if (!array_key_exists('Product URL', $product)) {
|
171 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Product URL</b>] Missing for <b>$id</b>.";
|
172 |
-
$this->errorCounter++;
|
173 |
-
}
|
174 |
-
|
175 |
-
if (!array_key_exists('Image URL', $product)) {
|
176 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Image URL</b>] Missing for <b>$id</b>.";
|
177 |
-
$this->errorCounter++;
|
178 |
-
}
|
179 |
-
|
180 |
-
if (!array_key_exists('Condition', $product)) {
|
181 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Condition</b>] Missing for <b>$id</b>.";
|
182 |
-
$this->errorCounter++;
|
183 |
-
}
|
184 |
-
|
185 |
-
if (!array_key_exists('Availability', $product)) {
|
186 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Availability</b>] Missing for <b>$id</b>.";
|
187 |
-
$this->errorCounter++;
|
188 |
-
}
|
189 |
-
|
190 |
-
if (!array_key_exists('Current price', $product)) {
|
191 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Current price</b>] Missing for <b>$id</b>.";
|
192 |
-
$this->errorCounter++;
|
193 |
-
}
|
194 |
-
}
|
195 |
-
}
|
196 |
-
|
197 |
-
/**
|
198 |
-
* Return Feed
|
199 |
-
*
|
200 |
-
* @return array|bool|string
|
201 |
-
*/
|
202 |
-
public function returnFinalProduct()
|
203 |
-
{
|
204 |
-
if ($this->rules['feedType'] == 'xml') {
|
205 |
-
return $this->get_feed($this->products);
|
206 |
-
} elseif ($this->rules['feedType'] == 'txt') {
|
207 |
-
return $this->get_txt_feed();
|
208 |
-
} elseif ($this->rules['feedType'] == 'csv') {
|
209 |
-
return $this->get_csv_feed();
|
210 |
-
}
|
211 |
-
return false;
|
212 |
-
}
|
213 |
-
|
214 |
-
/**
|
215 |
-
* Check product's attribute value according to merchant specifications
|
216 |
-
*/
|
217 |
-
public function filterProductValues()
|
218 |
-
{
|
219 |
-
$getProduct = new Woo_Feed_Products();
|
220 |
-
$products = $this->products;
|
221 |
-
|
222 |
-
foreach ($products as $no => $product) {
|
223 |
-
if (array_key_exists('Unique ID', $product)) {
|
224 |
-
$id = $product['Unique ID'];
|
225 |
-
} else {
|
226 |
-
$id = $product['Title'];
|
227 |
-
}
|
228 |
-
// echo "<pre>";
|
229 |
-
// print_r($product);
|
230 |
-
foreach ($product as $key => $value) {
|
231 |
-
switch ($key) {
|
232 |
-
case "Unique ID":
|
233 |
-
if (strlen($value) > 100) {
|
234 |
-
$this->errorLog[$this->errorCounter] = "[<b>Unique ID</b>] is more that 100 character for $id.";
|
235 |
-
$this->errorCounter++;
|
236 |
-
}
|
237 |
-
break;
|
238 |
-
case "Title":
|
239 |
-
if (strlen($value) > 1000) {
|
240 |
-
$this->errorLog[$this->errorCounter] = "[<b>Title</b>] is more that 1000 character for $id.";
|
241 |
-
$this->errorCounter++;
|
242 |
-
}
|
243 |
-
break;
|
244 |
-
case "Description":
|
245 |
-
if (strlen($value) > 3000) {
|
246 |
-
$this->errorLog[$this->errorCounter] = "[<b>Description</b>] is more that 3000 character for $id.";
|
247 |
-
$this->errorCounter++;
|
248 |
-
}
|
249 |
-
break;
|
250 |
-
case "Category":
|
251 |
-
if (strlen($value) > 1000) {
|
252 |
-
$this->errorLog[$this->errorCounter] = "[<b>Category</b>] is more that 1000 character for $id.";
|
253 |
-
$this->errorCounter++;
|
254 |
-
}
|
255 |
-
break;
|
256 |
-
case "Product URL":
|
257 |
-
if (strpos($value, 'http://') == false || strpos($value, 'https://') == false) {
|
258 |
-
$this->errorLog[$this->errorCounter] = "[<b>Product URL</b>] must start with http:// or https:// for $id.";
|
259 |
-
$this->errorCounter++;
|
260 |
-
}
|
261 |
-
|
262 |
-
if (strlen($value) > 2000) {
|
263 |
-
$this->errorLog[$this->errorCounter] = "[<b>Product URL</b>] is more that 2000 character for $id.";
|
264 |
-
$this->errorCounter++;
|
265 |
-
}
|
266 |
-
|
267 |
-
break;
|
268 |
-
case "Image URL":
|
269 |
-
if (strpos($value, 'http://') == false || strpos($value, 'https://') == false) {
|
270 |
-
$this->errorLog[$this->errorCounter] = "[<b>Image URL</b>] must start with http:// or https:// for $id.";
|
271 |
-
$this->errorCounter++;
|
272 |
-
}
|
273 |
-
|
274 |
-
if (strlen($value) > 2000) {
|
275 |
-
$this->errorLog[$this->errorCounter] = "[<b>Image URL</b>] is more that 2000 character for $id.";
|
276 |
-
$this->errorCounter++;
|
277 |
-
}
|
278 |
-
|
279 |
-
list($width, $height) = getimagesize($value);
|
280 |
-
if ($width < 450 || $height < 450) {
|
281 |
-
$this->errorLog[$this->errorCounter] = "<b>Image Width and Height</b> should be more that 450px for $id.";
|
282 |
-
$this->errorCounter++;
|
283 |
-
}
|
284 |
-
|
285 |
-
break;
|
286 |
-
case "Condition":
|
287 |
-
$condition = array("New", "Used", "Refurbished", "Open Box", "OEM");
|
288 |
-
if (!array_key_exists($value, $condition)) {
|
289 |
-
$this->errorLog[$this->errorCounter] = "[<b>Condition</b>] = $value is acceptable for $id.";
|
290 |
-
$this->errorCounter++;
|
291 |
-
}
|
292 |
-
break;
|
293 |
-
case "Availability":
|
294 |
-
$availability = array("In Stock", "Out of Stock", "Available for Order", "PreOrder");
|
295 |
-
if ($value == 'in stock') {
|
296 |
-
$this->products[$no][$key] = "In Stock";
|
297 |
-
} else {
|
298 |
-
$this->products[$no][$key] = "Out of Stock";
|
299 |
-
}
|
300 |
-
|
301 |
-
if (!array_key_exists($this->products[$no][$key], $availability)) {
|
302 |
-
$this->errorLog[$this->errorCounter] = "[<b>Availability</b>] = $value is acceptable for $id.";
|
303 |
-
$this->errorCounter++;
|
304 |
-
}
|
305 |
-
break;
|
306 |
-
case "Current price":
|
307 |
-
if (!is_numeric($value)) {
|
308 |
-
$this->errorLog[$this->errorCounter] = "[<b>Current price</b>] should be numeric for $id.";
|
309 |
-
$this->errorCounter++;
|
310 |
-
}
|
311 |
-
break;
|
312 |
-
case "Original Price":
|
313 |
-
if (!is_numeric($value)) {
|
314 |
-
$this->errorLog[$this->errorCounter] = "[<b>Original price</b>] should be numeric for $id.";
|
315 |
-
$this->errorCounter++;
|
316 |
-
}
|
317 |
-
break;
|
318 |
-
default:
|
319 |
-
break;
|
320 |
-
}
|
321 |
-
}
|
322 |
-
}
|
323 |
-
}
|
324 |
-
|
325 |
-
/**
|
326 |
-
* Return Dynamic Category Mapping Values by Parent Product Id
|
327 |
-
*
|
328 |
-
* @param string $mappingName Category Mapping Name
|
329 |
-
* @param int $parent Parent id of the product
|
330 |
-
* @return mixed
|
331 |
-
*/
|
332 |
-
public function get_category_mapping_value($mappingName, $parent)
|
333 |
-
{
|
334 |
-
$getValue = unserialize(get_option($mappingName));
|
335 |
-
$mapp = array_reverse($getValue['cmapping'], true);
|
336 |
-
$categories = get_the_terms($parent, 'product_cat');
|
337 |
-
|
338 |
-
foreach ($categories as $key => $category) {
|
339 |
-
if (!empty($mapp[$category->term_id]))
|
340 |
-
return $mapp[$category->term_id];
|
341 |
-
}
|
342 |
-
return false;
|
343 |
-
}
|
344 |
-
|
345 |
-
/**
|
346 |
-
* Configure the feed according to the rules
|
347 |
-
* @return Shopping
|
348 |
-
*/
|
349 |
-
public function mapProductsByRules()
|
350 |
-
{
|
351 |
-
/**
|
352 |
-
* Get WooCommerce Products
|
353 |
-
* @package Woo_Feed_Products
|
354 |
-
*/
|
355 |
-
$products = new Woo_Feed_Products();
|
356 |
-
|
357 |
-
/**
|
358 |
-
* This variable contain selected Woo attributes from feed making form
|
359 |
-
*
|
360 |
-
* @since 1.0.0
|
361 |
-
* @var array $attributes contain selected Woo attributes from feed making form
|
362 |
-
*/
|
363 |
-
$attributes = $this->rules['attributes'];
|
364 |
-
/**
|
365 |
-
* This variable contain selected Prefix Values from feed making form
|
366 |
-
*
|
367 |
-
* @since 1.0.0
|
368 |
-
* @var array $prefix Prefix Values from feed making form
|
369 |
-
*/
|
370 |
-
$prefix = $this->rules['prefix'];
|
371 |
-
/**
|
372 |
-
* This variable contain selected Prefix Values from feed making form
|
373 |
-
*
|
374 |
-
* @since 1.0.0
|
375 |
-
* @var array $suffix Suffix Values from feed making form
|
376 |
-
*/
|
377 |
-
$suffix = $this->rules['suffix'];
|
378 |
-
/**
|
379 |
-
* This variable contain selected Output Types from feed making form
|
380 |
-
*
|
381 |
-
* @since 1.0.0
|
382 |
-
* @var array $outputType Output Types from feed making form
|
383 |
-
*/
|
384 |
-
$outputType = $this->rules['output_type'];
|
385 |
-
|
386 |
-
/**
|
387 |
-
* This variable contain selected Output Limit from feed making form
|
388 |
-
*
|
389 |
-
* @since 1.0.0
|
390 |
-
* @var array $limit Output Limit from feed making form
|
391 |
-
*/
|
392 |
-
$limit = $this->rules['limit'];
|
393 |
-
/**
|
394 |
-
* This variable contain selected Merchant attributes from feed making form
|
395 |
-
*
|
396 |
-
* @since 1.0.0
|
397 |
-
* @var array $merchantAttributes contain selected Woo attributes from feed making form
|
398 |
-
*/
|
399 |
-
$merchantAttributes = $this->rules['mattributes'];
|
400 |
-
/**
|
401 |
-
* This variable contain attribute types from feed making form
|
402 |
-
*
|
403 |
-
* @since 1.0.0
|
404 |
-
* @var array $type contain attribute types from feed making form
|
405 |
-
*/
|
406 |
-
$type = $this->rules['type'];
|
407 |
-
/**
|
408 |
-
* This variable contain manual output of attribute from feed making form
|
409 |
-
*
|
410 |
-
* @since 1.0.0
|
411 |
-
* @var array $default contain manual output of attribute
|
412 |
-
*/
|
413 |
-
$default = $this->rules['default'];
|
414 |
-
|
415 |
-
/**
|
416 |
-
* This variable contain feed type
|
417 |
-
*
|
418 |
-
* @since 1.0.0
|
419 |
-
* @var array $feedType contain feed type
|
420 |
-
*/
|
421 |
-
$feedType = $this->rules['feedType'];
|
422 |
-
|
423 |
-
// Map Merchant Attributes and Woo Attributes
|
424 |
-
if (count($merchantAttributes)) {
|
425 |
-
foreach ($merchantAttributes as $key => $attr) {
|
426 |
-
if (!empty($attr) && !empty($attributes[$key])) {
|
427 |
-
if ($type[$key] == 'attribute') {
|
428 |
-
$this->mapping[$attr]['value'] = $attributes[$key];
|
429 |
-
$this->mapping[$attr]['suffix'] = $suffix[$key];
|
430 |
-
$this->mapping[$attr]['prefix'] = $prefix[$key];
|
431 |
-
$this->mapping[$attr]['type'] = $outputType[$key];
|
432 |
-
$this->mapping[$attr]['limit'] = $limit[$key];
|
433 |
-
}
|
434 |
-
} else if (empty($attributes[$key])) {
|
435 |
-
if ($type[$key] == 'pattern') {
|
436 |
-
$this->mapping[$attr]['value'] = "wf_pattern_$default[$key]";
|
437 |
-
$this->mapping[$attr]['suffix'] = $suffix[$key];
|
438 |
-
$this->mapping[$attr]['prefix'] = $prefix[$key];
|
439 |
-
$this->mapping[$attr]['type'] = $outputType[$key];
|
440 |
-
$this->mapping[$attr]['limit'] = $limit[$key];
|
441 |
-
}
|
442 |
-
}
|
443 |
-
}
|
444 |
-
}
|
445 |
-
|
446 |
-
// Make Product feed array according to mapping
|
447 |
-
foreach ($products->woo_feed_get_visible_product() as $key => $value) {
|
448 |
-
$i = 0;
|
449 |
-
foreach ($this->mapping as $attr => $rules) {
|
450 |
-
if (array_key_exists($rules['value'], $value)) {
|
451 |
-
|
452 |
-
$output = $rules['prefix'] . $value[$rules['value']] . " " . $rules['suffix'];
|
453 |
-
// Format According to output type
|
454 |
-
if ($rules['type'] == 2) {
|
455 |
-
$output = strip_tags($output);
|
456 |
-
} elseif ($rules['type'] == 3) {
|
457 |
-
$output = absint($output);
|
458 |
-
}
|
459 |
-
// Format According to output limit
|
460 |
-
if (!empty($rules['limit']) && is_numeric($rules['limit'])) {
|
461 |
-
$output = substr($output, 0, $rules['limit']);
|
462 |
-
}
|
463 |
-
$attr = trim($attr);
|
464 |
-
$this->products[$key][$attr] = trim($output);
|
465 |
-
} else {
|
466 |
-
if (!empty($default[$i])) {
|
467 |
-
$output = $rules['prefix'] . str_replace("wf_pattern_", "", $rules['value']) . " " . $rules['suffix'];
|
468 |
-
if ($rules['type'] == 2) {
|
469 |
-
$output = strip_tags($output);
|
470 |
-
} elseif ($rules['type'] == 3) {
|
471 |
-
$output = absint($output);
|
472 |
-
}
|
473 |
-
// Format According to output limit
|
474 |
-
if (!empty($rules['limit']) && is_numeric($rules['limit'])) {
|
475 |
-
$output = substr($output, 0, $rules['limit']);
|
476 |
-
}
|
477 |
-
$attr = trim($attr);
|
478 |
-
$this->products[$key][$attr] = trim($output);
|
479 |
-
}
|
480 |
-
}
|
481 |
-
$i++;
|
482 |
-
}
|
483 |
-
}
|
484 |
-
|
485 |
-
|
486 |
-
return $this->products;
|
487 |
-
}
|
488 |
-
|
489 |
-
/**
|
490 |
-
* Change the products old array key and set new
|
491 |
-
*
|
492 |
-
* @param string $from Attribute Before
|
493 |
-
* @param string $to Attribute After
|
494 |
-
* @param bool $cdata Enclose Feed value
|
495 |
-
*/
|
496 |
-
public function mapAttribute($from, $to, $cdata = false)
|
497 |
-
{
|
498 |
-
$i = 0;
|
499 |
-
foreach ($this->products as $no => $product) {
|
500 |
-
foreach ($product as $key => $value) {
|
501 |
-
if ($key == $from) {
|
502 |
-
unset($this->products[$no][$from]);
|
503 |
-
if ($from == 'images') {
|
504 |
-
$this->products[$no][$to] = $value;
|
505 |
-
} else {
|
506 |
-
$this->products[$no][$to] = $this->formatXMLLine($to, $value, $cdata, true, true);
|
507 |
-
}
|
508 |
-
|
509 |
-
}
|
510 |
-
}
|
511 |
-
$i++;
|
512 |
-
}
|
513 |
-
}
|
514 |
-
|
515 |
-
/**
|
516 |
-
* Format and Make the XML node for the Feed
|
517 |
-
*
|
518 |
-
* @param $attribute
|
519 |
-
* @param $value
|
520 |
-
* @param bool $cdata
|
521 |
-
* @param bool $stripHTML
|
522 |
-
* @param bool $utf8encode
|
523 |
-
* @param string $space
|
524 |
-
* @return string
|
525 |
-
*/
|
526 |
-
function formatXMLLine($attribute, $value, $cdata = false, $stripHTML = true, $utf8encode = true, $space = ' ')
|
527 |
-
{
|
528 |
-
//Make single line for XML
|
529 |
-
$c_leader = '';
|
530 |
-
$c_footer = '';
|
531 |
-
if ($cdata) {
|
532 |
-
$c_leader = '<![CDATA[';
|
533 |
-
$c_footer = ']]>';
|
534 |
-
}
|
535 |
-
//Allow force strip HTML
|
536 |
-
if ($stripHTML)
|
537 |
-
$value = strip_tags(html_entity_decode($value));
|
538 |
-
|
539 |
-
|
540 |
-
if ($utf8encode || $utf8encode == 1) {
|
541 |
-
$value = utf8_encode($value);
|
542 |
-
$attribute = utf8_encode($attribute);
|
543 |
-
}
|
544 |
-
|
545 |
-
|
546 |
-
if (!$cdata)
|
547 |
-
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
|
548 |
-
|
549 |
-
if (gettype($value) == 'array')
|
550 |
-
$value = json_encode($value);
|
551 |
-
|
552 |
-
|
553 |
-
return '
|
554 |
-
' . $space . '<' . $attribute . '>' . $c_leader . $value . $c_footer . '</' . $attribute . '>';
|
555 |
-
}
|
556 |
-
|
557 |
-
/**
|
558 |
-
* Responsible to change product array key
|
559 |
-
*
|
560 |
-
* @param $array
|
561 |
-
* @param $old_key
|
562 |
-
* @param $new_key
|
563 |
-
* @return array
|
564 |
-
*/
|
565 |
-
function change_key($array, $old_key, $new_key)
|
566 |
-
{
|
567 |
-
foreach ($this->products as $no => $product) {
|
568 |
-
if (!array_key_exists($old_key, $product))
|
569 |
-
return $array;
|
570 |
-
|
571 |
-
$keys = array_keys($array);
|
572 |
-
$keys[array_search($old_key, $keys)] = $new_key;
|
573 |
-
}
|
574 |
-
return array_combine($keys, $array);
|
575 |
-
}
|
576 |
-
|
577 |
-
/**
|
578 |
-
* Responsible to make XML feed header
|
579 |
-
* @return string
|
580 |
-
*/
|
581 |
-
public function get_feed_header()
|
582 |
-
{
|
583 |
-
$output = '<?xml version="1.0" encoding="UTF-8" ?>
|
584 |
-
<products>';
|
585 |
-
$output .= "\n";
|
586 |
-
return $output;
|
587 |
-
}
|
588 |
-
|
589 |
-
/**
|
590 |
-
* Responsible to make XML feed body
|
591 |
-
* @var array $item Product array
|
592 |
-
* @return string
|
593 |
-
*/
|
594 |
-
public function get_feed($items)
|
595 |
-
{
|
596 |
-
$feed = "";
|
597 |
-
$feed .= $this->get_feed_header();
|
598 |
-
$feed .= "\n";
|
599 |
-
foreach ($items as $item => $products) {
|
600 |
-
$feed .= " <" . $this->feedWrapper . ">";
|
601 |
-
foreach ($products as $key => $value) {
|
602 |
-
if (!empty($value))
|
603 |
-
$feed .= $value;
|
604 |
-
}
|
605 |
-
$feed .= "\n </" . $this->feedWrapper . ">\n";
|
606 |
-
}
|
607 |
-
$feed .= $this->get_feed_footer();
|
608 |
-
|
609 |
-
return $feed;
|
610 |
-
}
|
611 |
-
|
612 |
-
/**
|
613 |
-
* Responsible to make XML feed footer
|
614 |
-
* @return string
|
615 |
-
*/
|
616 |
-
public function get_feed_footer()
|
617 |
-
{
|
618 |
-
$footer = " </products>";
|
619 |
-
return $footer;
|
620 |
-
}
|
621 |
-
|
622 |
-
/**
|
623 |
-
* Responsible to make TXT feed
|
624 |
-
* @return string
|
625 |
-
*/
|
626 |
-
public function get_txt_feed()
|
627 |
-
{
|
628 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
629 |
-
$headers = array_keys($this->products[0]);
|
630 |
-
$feed[] = $headers;
|
631 |
-
foreach ($this->products as $no => $product) {
|
632 |
-
$row = array();
|
633 |
-
foreach ($headers as $key => $header) {
|
634 |
-
$row[] = $product[$header];
|
635 |
-
}
|
636 |
-
$feed[] = $row;
|
637 |
-
}
|
638 |
-
$str = "";
|
639 |
-
foreach ($feed as $fields) {
|
640 |
-
$str .= implode("\t", $fields) . "\n";
|
641 |
-
}
|
642 |
-
return $str;
|
643 |
-
}
|
644 |
-
return false;
|
645 |
-
}
|
646 |
-
|
647 |
-
/**
|
648 |
-
* Responsible to make CSV feed
|
649 |
-
* @return string
|
650 |
-
*/
|
651 |
-
public function get_csv_feed()
|
652 |
-
{
|
653 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
654 |
-
$headers = array_keys($this->products[0]);
|
655 |
-
$feed[] = $headers;
|
656 |
-
foreach ($this->products as $no => $product) {
|
657 |
-
$row = array();
|
658 |
-
foreach ($headers as $key => $header) {
|
659 |
-
$row[] = $product[$header];
|
660 |
-
}
|
661 |
-
$feed[] = $row;
|
662 |
-
}
|
663 |
-
|
664 |
-
return $feed;
|
665 |
-
}
|
666 |
-
return false;
|
667 |
-
}
|
668 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Connexity
|
5 |
+
*
|
6 |
+
* Responsible for processing and generating feed for Connexity.com
|
7 |
+
*
|
8 |
+
* @since 1.0.0
|
9 |
+
* @package Connexity
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Connexity
|
13 |
+
{
|
14 |
+
|
15 |
+
/**
|
16 |
+
* This variable is responsible for holding all product attributes and their values
|
17 |
+
*
|
18 |
+
* @since 1.0.0
|
19 |
+
* @var array $products Contains all the product attributes to generate feed
|
20 |
+
* @access public
|
21 |
+
*/
|
22 |
+
public $products;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* This variable is responsible for holding feed configuration form values
|
26 |
+
*
|
27 |
+
* @since 1.0.0
|
28 |
+
* @var Connexity $rules Contains feed configuration form values
|
29 |
+
* @access public
|
30 |
+
*/
|
31 |
+
public $rules;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* This variable is responsible for mapping store attributes to merchant attribute
|
35 |
+
*
|
36 |
+
* @since 1.0.0
|
37 |
+
* @var Connexity $mapping Map store attributes to merchant attribute
|
38 |
+
* @access public
|
39 |
+
*/
|
40 |
+
public $mapping;
|
41 |
+
|
42 |
+
/**
|
43 |
+
* This variable is responsible for generate error logs
|
44 |
+
*
|
45 |
+
* @since 1.0.0
|
46 |
+
* @var Connexity $errorLog Generate error logs
|
47 |
+
* @access public
|
48 |
+
*/
|
49 |
+
public $errorLog;
|
50 |
+
|
51 |
+
/**
|
52 |
+
* This variable is responsible for making error number
|
53 |
+
*
|
54 |
+
* @since 1.0.0
|
55 |
+
* @var Connexity $errorCounter Generate error number
|
56 |
+
* @access public
|
57 |
+
*/
|
58 |
+
public $errorCounter;
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Feed Wrapper text for enclosing each product information
|
62 |
+
*
|
63 |
+
* @since 1.0.0
|
64 |
+
* @var Connexity $feedWrapper Feed Wrapper text
|
65 |
+
* @access public
|
66 |
+
*/
|
67 |
+
private $feedWrapper;
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Define the core functionality to generate feed.
|
71 |
+
*
|
72 |
+
* Set the feed rules. Map products according to the rules and Check required attributes
|
73 |
+
* and their values according to merchant specification.
|
74 |
+
* @var Woo_Generate_Feed $feedRule Contain Feed Configuration
|
75 |
+
* @since 1.0.0
|
76 |
+
*/
|
77 |
+
public function __construct($feedRule)
|
78 |
+
{
|
79 |
+
$this->feedWrapper = 'product';
|
80 |
+
$this->errorCounter = 0;
|
81 |
+
$this->rules = $feedRule;
|
82 |
+
$this->mapProductsByRules();
|
83 |
+
$this->formatRequiredField();
|
84 |
+
$this->filterProductValues();
|
85 |
+
if ($this->rules['feedType'] == 'xml') {
|
86 |
+
$this->mapAttributeForXML();
|
87 |
+
} else {
|
88 |
+
$this->mapAttributeForCSVTEXT();
|
89 |
+
}
|
90 |
+
}
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Configure merchant attributes for XML feed
|
94 |
+
*/
|
95 |
+
public function mapAttributeForXML()
|
96 |
+
{
|
97 |
+
//Basic product information
|
98 |
+
|
99 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
100 |
+
foreach ($this->products as $key => $values) {
|
101 |
+
foreach ($values as $attr => $value) {
|
102 |
+
$this->products[$key][$attr] = $this->formatXMLLine($attr, $value, true, true, true);
|
103 |
+
}
|
104 |
+
}
|
105 |
+
}
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* Configure merchant attributes for CSV and TXT feed
|
110 |
+
*/
|
111 |
+
public function mapAttributeForCSVTEXT()
|
112 |
+
{
|
113 |
+
//Basic product information
|
114 |
+
|
115 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
116 |
+
foreach ($this->products as $key => $values) {
|
117 |
+
foreach ($values as $attr => $value) {
|
118 |
+
//Allow force strip HTML
|
119 |
+
$value = strip_tags(html_entity_decode($value));
|
120 |
+
if ($attr != 'Category') {
|
121 |
+
$value = utf8_encode($value);
|
122 |
+
$attr = utf8_encode($attr);
|
123 |
+
|
124 |
+
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
|
125 |
+
|
126 |
+
if (gettype($value) == 'array')
|
127 |
+
$value = json_encode($value);
|
128 |
+
}
|
129 |
+
|
130 |
+
$this->products[$key][$attr] = $value;
|
131 |
+
}
|
132 |
+
}
|
133 |
+
}
|
134 |
+
}
|
135 |
+
|
136 |
+
/**
|
137 |
+
* Check all the required attributes and make error message
|
138 |
+
*/
|
139 |
+
public function formatRequiredField()
|
140 |
+
{
|
141 |
+
foreach ($this->products as $no => $product) {
|
142 |
+
$upn = 0;
|
143 |
+
if (array_key_exists('Unique ID', $product)) {
|
144 |
+
$id = $product['Unique ID'];
|
145 |
+
} else {
|
146 |
+
$id = $product['Title'];
|
147 |
+
}
|
148 |
+
|
149 |
+
if (!array_key_exists('Unique ID', $product)) {
|
150 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Unique ID</b>] Missing for <b>$id</b>.";
|
151 |
+
$this->errorCounter++;
|
152 |
+
}
|
153 |
+
|
154 |
+
|
155 |
+
if (!array_key_exists('Title', $product)) {
|
156 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Title</b>] Missing for <b>$id</b>.";
|
157 |
+
$this->errorCounter++;
|
158 |
+
}
|
159 |
+
|
160 |
+
if (!array_key_exists('Description', $product)) {
|
161 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Description</b>] Missing for <b>$id</b>.";
|
162 |
+
$this->errorCounter++;
|
163 |
+
}
|
164 |
+
|
165 |
+
if (!array_key_exists('Category', $product)) {
|
166 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Category</b>] Missing for <b>$id</b>.";
|
167 |
+
$this->errorCounter++;
|
168 |
+
}
|
169 |
+
|
170 |
+
if (!array_key_exists('Product URL', $product)) {
|
171 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Product URL</b>] Missing for <b>$id</b>.";
|
172 |
+
$this->errorCounter++;
|
173 |
+
}
|
174 |
+
|
175 |
+
if (!array_key_exists('Image URL', $product)) {
|
176 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Image URL</b>] Missing for <b>$id</b>.";
|
177 |
+
$this->errorCounter++;
|
178 |
+
}
|
179 |
+
|
180 |
+
if (!array_key_exists('Condition', $product)) {
|
181 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Condition</b>] Missing for <b>$id</b>.";
|
182 |
+
$this->errorCounter++;
|
183 |
+
}
|
184 |
+
|
185 |
+
if (!array_key_exists('Availability', $product)) {
|
186 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Availability</b>] Missing for <b>$id</b>.";
|
187 |
+
$this->errorCounter++;
|
188 |
+
}
|
189 |
+
|
190 |
+
if (!array_key_exists('Current price', $product)) {
|
191 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Current price</b>] Missing for <b>$id</b>.";
|
192 |
+
$this->errorCounter++;
|
193 |
+
}
|
194 |
+
}
|
195 |
+
}
|
196 |
+
|
197 |
+
/**
|
198 |
+
* Return Feed
|
199 |
+
*
|
200 |
+
* @return array|bool|string
|
201 |
+
*/
|
202 |
+
public function returnFinalProduct()
|
203 |
+
{
|
204 |
+
if ($this->rules['feedType'] == 'xml') {
|
205 |
+
return $this->get_feed($this->products);
|
206 |
+
} elseif ($this->rules['feedType'] == 'txt') {
|
207 |
+
return $this->get_txt_feed();
|
208 |
+
} elseif ($this->rules['feedType'] == 'csv') {
|
209 |
+
return $this->get_csv_feed();
|
210 |
+
}
|
211 |
+
return false;
|
212 |
+
}
|
213 |
+
|
214 |
+
/**
|
215 |
+
* Check product's attribute value according to merchant specifications
|
216 |
+
*/
|
217 |
+
public function filterProductValues()
|
218 |
+
{
|
219 |
+
$getProduct = new Woo_Feed_Products();
|
220 |
+
$products = $this->products;
|
221 |
+
|
222 |
+
foreach ($products as $no => $product) {
|
223 |
+
if (array_key_exists('Unique ID', $product)) {
|
224 |
+
$id = $product['Unique ID'];
|
225 |
+
} else {
|
226 |
+
$id = $product['Title'];
|
227 |
+
}
|
228 |
+
// echo "<pre>";
|
229 |
+
// print_r($product);
|
230 |
+
foreach ($product as $key => $value) {
|
231 |
+
switch ($key) {
|
232 |
+
case "Unique ID":
|
233 |
+
if (strlen($value) > 100) {
|
234 |
+
$this->errorLog[$this->errorCounter] = "[<b>Unique ID</b>] is more that 100 character for $id.";
|
235 |
+
$this->errorCounter++;
|
236 |
+
}
|
237 |
+
break;
|
238 |
+
case "Title":
|
239 |
+
if (strlen($value) > 1000) {
|
240 |
+
$this->errorLog[$this->errorCounter] = "[<b>Title</b>] is more that 1000 character for $id.";
|
241 |
+
$this->errorCounter++;
|
242 |
+
}
|
243 |
+
break;
|
244 |
+
case "Description":
|
245 |
+
if (strlen($value) > 3000) {
|
246 |
+
$this->errorLog[$this->errorCounter] = "[<b>Description</b>] is more that 3000 character for $id.";
|
247 |
+
$this->errorCounter++;
|
248 |
+
}
|
249 |
+
break;
|
250 |
+
case "Category":
|
251 |
+
if (strlen($value) > 1000) {
|
252 |
+
$this->errorLog[$this->errorCounter] = "[<b>Category</b>] is more that 1000 character for $id.";
|
253 |
+
$this->errorCounter++;
|
254 |
+
}
|
255 |
+
break;
|
256 |
+
case "Product URL":
|
257 |
+
if (strpos($value, 'http://') == false || strpos($value, 'https://') == false) {
|
258 |
+
$this->errorLog[$this->errorCounter] = "[<b>Product URL</b>] must start with http:// or https:// for $id.";
|
259 |
+
$this->errorCounter++;
|
260 |
+
}
|
261 |
+
|
262 |
+
if (strlen($value) > 2000) {
|
263 |
+
$this->errorLog[$this->errorCounter] = "[<b>Product URL</b>] is more that 2000 character for $id.";
|
264 |
+
$this->errorCounter++;
|
265 |
+
}
|
266 |
+
|
267 |
+
break;
|
268 |
+
case "Image URL":
|
269 |
+
if (strpos($value, 'http://') == false || strpos($value, 'https://') == false) {
|
270 |
+
$this->errorLog[$this->errorCounter] = "[<b>Image URL</b>] must start with http:// or https:// for $id.";
|
271 |
+
$this->errorCounter++;
|
272 |
+
}
|
273 |
+
|
274 |
+
if (strlen($value) > 2000) {
|
275 |
+
$this->errorLog[$this->errorCounter] = "[<b>Image URL</b>] is more that 2000 character for $id.";
|
276 |
+
$this->errorCounter++;
|
277 |
+
}
|
278 |
+
|
279 |
+
list($width, $height) = getimagesize($value);
|
280 |
+
if ($width < 450 || $height < 450) {
|
281 |
+
$this->errorLog[$this->errorCounter] = "<b>Image Width and Height</b> should be more that 450px for $id.";
|
282 |
+
$this->errorCounter++;
|
283 |
+
}
|
284 |
+
|
285 |
+
break;
|
286 |
+
case "Condition":
|
287 |
+
$condition = array("New", "Used", "Refurbished", "Open Box", "OEM");
|
288 |
+
if (!array_key_exists($value, $condition)) {
|
289 |
+
$this->errorLog[$this->errorCounter] = "[<b>Condition</b>] = $value is acceptable for $id.";
|
290 |
+
$this->errorCounter++;
|
291 |
+
}
|
292 |
+
break;
|
293 |
+
case "Availability":
|
294 |
+
$availability = array("In Stock", "Out of Stock", "Available for Order", "PreOrder");
|
295 |
+
if ($value == 'in stock') {
|
296 |
+
$this->products[$no][$key] = "In Stock";
|
297 |
+
} else {
|
298 |
+
$this->products[$no][$key] = "Out of Stock";
|
299 |
+
}
|
300 |
+
|
301 |
+
if (!array_key_exists($this->products[$no][$key], $availability)) {
|
302 |
+
$this->errorLog[$this->errorCounter] = "[<b>Availability</b>] = $value is acceptable for $id.";
|
303 |
+
$this->errorCounter++;
|
304 |
+
}
|
305 |
+
break;
|
306 |
+
case "Current price":
|
307 |
+
if (!is_numeric($value)) {
|
308 |
+
$this->errorLog[$this->errorCounter] = "[<b>Current price</b>] should be numeric for $id.";
|
309 |
+
$this->errorCounter++;
|
310 |
+
}
|
311 |
+
break;
|
312 |
+
case "Original Price":
|
313 |
+
if (!is_numeric($value)) {
|
314 |
+
$this->errorLog[$this->errorCounter] = "[<b>Original price</b>] should be numeric for $id.";
|
315 |
+
$this->errorCounter++;
|
316 |
+
}
|
317 |
+
break;
|
318 |
+
default:
|
319 |
+
break;
|
320 |
+
}
|
321 |
+
}
|
322 |
+
}
|
323 |
+
}
|
324 |
+
|
325 |
+
/**
|
326 |
+
* Return Dynamic Category Mapping Values by Parent Product Id
|
327 |
+
*
|
328 |
+
* @param string $mappingName Category Mapping Name
|
329 |
+
* @param int $parent Parent id of the product
|
330 |
+
* @return mixed
|
331 |
+
*/
|
332 |
+
public function get_category_mapping_value($mappingName, $parent)
|
333 |
+
{
|
334 |
+
$getValue = unserialize(get_option($mappingName));
|
335 |
+
$mapp = array_reverse($getValue['cmapping'], true);
|
336 |
+
$categories = get_the_terms($parent, 'product_cat');
|
337 |
+
|
338 |
+
foreach ($categories as $key => $category) {
|
339 |
+
if (!empty($mapp[$category->term_id]))
|
340 |
+
return $mapp[$category->term_id];
|
341 |
+
}
|
342 |
+
return false;
|
343 |
+
}
|
344 |
+
|
345 |
+
/**
|
346 |
+
* Configure the feed according to the rules
|
347 |
+
* @return Shopping
|
348 |
+
*/
|
349 |
+
public function mapProductsByRules()
|
350 |
+
{
|
351 |
+
/**
|
352 |
+
* Get WooCommerce Products
|
353 |
+
* @package Woo_Feed_Products
|
354 |
+
*/
|
355 |
+
$products = new Woo_Feed_Products();
|
356 |
+
|
357 |
+
/**
|
358 |
+
* This variable contain selected Woo attributes from feed making form
|
359 |
+
*
|
360 |
+
* @since 1.0.0
|
361 |
+
* @var array $attributes contain selected Woo attributes from feed making form
|
362 |
+
*/
|
363 |
+
$attributes = $this->rules['attributes'];
|
364 |
+
/**
|
365 |
+
* This variable contain selected Prefix Values from feed making form
|
366 |
+
*
|
367 |
+
* @since 1.0.0
|
368 |
+
* @var array $prefix Prefix Values from feed making form
|
369 |
+
*/
|
370 |
+
$prefix = $this->rules['prefix'];
|
371 |
+
/**
|
372 |
+
* This variable contain selected Prefix Values from feed making form
|
373 |
+
*
|
374 |
+
* @since 1.0.0
|
375 |
+
* @var array $suffix Suffix Values from feed making form
|
376 |
+
*/
|
377 |
+
$suffix = $this->rules['suffix'];
|
378 |
+
/**
|
379 |
+
* This variable contain selected Output Types from feed making form
|
380 |
+
*
|
381 |
+
* @since 1.0.0
|
382 |
+
* @var array $outputType Output Types from feed making form
|
383 |
+
*/
|
384 |
+
$outputType = $this->rules['output_type'];
|
385 |
+
|
386 |
+
/**
|
387 |
+
* This variable contain selected Output Limit from feed making form
|
388 |
+
*
|
389 |
+
* @since 1.0.0
|
390 |
+
* @var array $limit Output Limit from feed making form
|
391 |
+
*/
|
392 |
+
$limit = $this->rules['limit'];
|
393 |
+
/**
|
394 |
+
* This variable contain selected Merchant attributes from feed making form
|
395 |
+
*
|
396 |
+
* @since 1.0.0
|
397 |
+
* @var array $merchantAttributes contain selected Woo attributes from feed making form
|
398 |
+
*/
|
399 |
+
$merchantAttributes = $this->rules['mattributes'];
|
400 |
+
/**
|
401 |
+
* This variable contain attribute types from feed making form
|
402 |
+
*
|
403 |
+
* @since 1.0.0
|
404 |
+
* @var array $type contain attribute types from feed making form
|
405 |
+
*/
|
406 |
+
$type = $this->rules['type'];
|
407 |
+
/**
|
408 |
+
* This variable contain manual output of attribute from feed making form
|
409 |
+
*
|
410 |
+
* @since 1.0.0
|
411 |
+
* @var array $default contain manual output of attribute
|
412 |
+
*/
|
413 |
+
$default = $this->rules['default'];
|
414 |
+
|
415 |
+
/**
|
416 |
+
* This variable contain feed type
|
417 |
+
*
|
418 |
+
* @since 1.0.0
|
419 |
+
* @var array $feedType contain feed type
|
420 |
+
*/
|
421 |
+
$feedType = $this->rules['feedType'];
|
422 |
+
|
423 |
+
// Map Merchant Attributes and Woo Attributes
|
424 |
+
if (count($merchantAttributes)) {
|
425 |
+
foreach ($merchantAttributes as $key => $attr) {
|
426 |
+
if (!empty($attr) && !empty($attributes[$key])) {
|
427 |
+
if ($type[$key] == 'attribute') {
|
428 |
+
$this->mapping[$attr]['value'] = $attributes[$key];
|
429 |
+
$this->mapping[$attr]['suffix'] = $suffix[$key];
|
430 |
+
$this->mapping[$attr]['prefix'] = $prefix[$key];
|
431 |
+
$this->mapping[$attr]['type'] = $outputType[$key];
|
432 |
+
$this->mapping[$attr]['limit'] = $limit[$key];
|
433 |
+
}
|
434 |
+
} else if (empty($attributes[$key])) {
|
435 |
+
if ($type[$key] == 'pattern') {
|
436 |
+
$this->mapping[$attr]['value'] = "wf_pattern_$default[$key]";
|
437 |
+
$this->mapping[$attr]['suffix'] = $suffix[$key];
|
438 |
+
$this->mapping[$attr]['prefix'] = $prefix[$key];
|
439 |
+
$this->mapping[$attr]['type'] = $outputType[$key];
|
440 |
+
$this->mapping[$attr]['limit'] = $limit[$key];
|
441 |
+
}
|
442 |
+
}
|
443 |
+
}
|
444 |
+
}
|
445 |
+
|
446 |
+
// Make Product feed array according to mapping
|
447 |
+
foreach ($products->woo_feed_get_visible_product() as $key => $value) {
|
448 |
+
$i = 0;
|
449 |
+
foreach ($this->mapping as $attr => $rules) {
|
450 |
+
if (array_key_exists($rules['value'], $value)) {
|
451 |
+
|
452 |
+
$output = $rules['prefix'] . $value[$rules['value']] . " " . $rules['suffix'];
|
453 |
+
// Format According to output type
|
454 |
+
if ($rules['type'] == 2) {
|
455 |
+
$output = strip_tags($output);
|
456 |
+
} elseif ($rules['type'] == 3) {
|
457 |
+
$output = absint($output);
|
458 |
+
}
|
459 |
+
// Format According to output limit
|
460 |
+
if (!empty($rules['limit']) && is_numeric($rules['limit'])) {
|
461 |
+
$output = substr($output, 0, $rules['limit']);
|
462 |
+
}
|
463 |
+
$attr = trim($attr);
|
464 |
+
$this->products[$key][$attr] = trim($output);
|
465 |
+
} else {
|
466 |
+
if (!empty($default[$i])) {
|
467 |
+
$output = $rules['prefix'] . str_replace("wf_pattern_", "", $rules['value']) . " " . $rules['suffix'];
|
468 |
+
if ($rules['type'] == 2) {
|
469 |
+
$output = strip_tags($output);
|
470 |
+
} elseif ($rules['type'] == 3) {
|
471 |
+
$output = absint($output);
|
472 |
+
}
|
473 |
+
// Format According to output limit
|
474 |
+
if (!empty($rules['limit']) && is_numeric($rules['limit'])) {
|
475 |
+
$output = substr($output, 0, $rules['limit']);
|
476 |
+
}
|
477 |
+
$attr = trim($attr);
|
478 |
+
$this->products[$key][$attr] = trim($output);
|
479 |
+
}
|
480 |
+
}
|
481 |
+
$i++;
|
482 |
+
}
|
483 |
+
}
|
484 |
+
|
485 |
+
|
486 |
+
return $this->products;
|
487 |
+
}
|
488 |
+
|
489 |
+
/**
|
490 |
+
* Change the products old array key and set new
|
491 |
+
*
|
492 |
+
* @param string $from Attribute Before
|
493 |
+
* @param string $to Attribute After
|
494 |
+
* @param bool $cdata Enclose Feed value
|
495 |
+
*/
|
496 |
+
public function mapAttribute($from, $to, $cdata = false)
|
497 |
+
{
|
498 |
+
$i = 0;
|
499 |
+
foreach ($this->products as $no => $product) {
|
500 |
+
foreach ($product as $key => $value) {
|
501 |
+
if ($key == $from) {
|
502 |
+
unset($this->products[$no][$from]);
|
503 |
+
if ($from == 'images') {
|
504 |
+
$this->products[$no][$to] = $value;
|
505 |
+
} else {
|
506 |
+
$this->products[$no][$to] = $this->formatXMLLine($to, $value, $cdata, true, true);
|
507 |
+
}
|
508 |
+
|
509 |
+
}
|
510 |
+
}
|
511 |
+
$i++;
|
512 |
+
}
|
513 |
+
}
|
514 |
+
|
515 |
+
/**
|
516 |
+
* Format and Make the XML node for the Feed
|
517 |
+
*
|
518 |
+
* @param $attribute
|
519 |
+
* @param $value
|
520 |
+
* @param bool $cdata
|
521 |
+
* @param bool $stripHTML
|
522 |
+
* @param bool $utf8encode
|
523 |
+
* @param string $space
|
524 |
+
* @return string
|
525 |
+
*/
|
526 |
+
function formatXMLLine($attribute, $value, $cdata = false, $stripHTML = true, $utf8encode = true, $space = ' ')
|
527 |
+
{
|
528 |
+
//Make single line for XML
|
529 |
+
$c_leader = '';
|
530 |
+
$c_footer = '';
|
531 |
+
if ($cdata) {
|
532 |
+
$c_leader = '<![CDATA[';
|
533 |
+
$c_footer = ']]>';
|
534 |
+
}
|
535 |
+
//Allow force strip HTML
|
536 |
+
if ($stripHTML)
|
537 |
+
$value = strip_tags(html_entity_decode($value));
|
538 |
+
|
539 |
+
|
540 |
+
if ($utf8encode || $utf8encode == 1) {
|
541 |
+
$value = utf8_encode($value);
|
542 |
+
$attribute = utf8_encode($attribute);
|
543 |
+
}
|
544 |
+
|
545 |
+
|
546 |
+
if (!$cdata)
|
547 |
+
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
|
548 |
+
|
549 |
+
if (gettype($value) == 'array')
|
550 |
+
$value = json_encode($value);
|
551 |
+
|
552 |
+
|
553 |
+
return '
|
554 |
+
' . $space . '<' . $attribute . '>' . $c_leader . $value . $c_footer . '</' . $attribute . '>';
|
555 |
+
}
|
556 |
+
|
557 |
+
/**
|
558 |
+
* Responsible to change product array key
|
559 |
+
*
|
560 |
+
* @param $array
|
561 |
+
* @param $old_key
|
562 |
+
* @param $new_key
|
563 |
+
* @return array
|
564 |
+
*/
|
565 |
+
function change_key($array, $old_key, $new_key)
|
566 |
+
{
|
567 |
+
foreach ($this->products as $no => $product) {
|
568 |
+
if (!array_key_exists($old_key, $product))
|
569 |
+
return $array;
|
570 |
+
|
571 |
+
$keys = array_keys($array);
|
572 |
+
$keys[array_search($old_key, $keys)] = $new_key;
|
573 |
+
}
|
574 |
+
return array_combine($keys, $array);
|
575 |
+
}
|
576 |
+
|
577 |
+
/**
|
578 |
+
* Responsible to make XML feed header
|
579 |
+
* @return string
|
580 |
+
*/
|
581 |
+
public function get_feed_header()
|
582 |
+
{
|
583 |
+
$output = '<?xml version="1.0" encoding="UTF-8" ?>
|
584 |
+
<products>';
|
585 |
+
$output .= "\n";
|
586 |
+
return $output;
|
587 |
+
}
|
588 |
+
|
589 |
+
/**
|
590 |
+
* Responsible to make XML feed body
|
591 |
+
* @var array $item Product array
|
592 |
+
* @return string
|
593 |
+
*/
|
594 |
+
public function get_feed($items)
|
595 |
+
{
|
596 |
+
$feed = "";
|
597 |
+
$feed .= $this->get_feed_header();
|
598 |
+
$feed .= "\n";
|
599 |
+
foreach ($items as $item => $products) {
|
600 |
+
$feed .= " <" . $this->feedWrapper . ">";
|
601 |
+
foreach ($products as $key => $value) {
|
602 |
+
if (!empty($value))
|
603 |
+
$feed .= $value;
|
604 |
+
}
|
605 |
+
$feed .= "\n </" . $this->feedWrapper . ">\n";
|
606 |
+
}
|
607 |
+
$feed .= $this->get_feed_footer();
|
608 |
+
|
609 |
+
return $feed;
|
610 |
+
}
|
611 |
+
|
612 |
+
/**
|
613 |
+
* Responsible to make XML feed footer
|
614 |
+
* @return string
|
615 |
+
*/
|
616 |
+
public function get_feed_footer()
|
617 |
+
{
|
618 |
+
$footer = " </products>";
|
619 |
+
return $footer;
|
620 |
+
}
|
621 |
+
|
622 |
+
/**
|
623 |
+
* Responsible to make TXT feed
|
624 |
+
* @return string
|
625 |
+
*/
|
626 |
+
public function get_txt_feed()
|
627 |
+
{
|
628 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
629 |
+
$headers = array_keys($this->products[0]);
|
630 |
+
$feed[] = $headers;
|
631 |
+
foreach ($this->products as $no => $product) {
|
632 |
+
$row = array();
|
633 |
+
foreach ($headers as $key => $header) {
|
634 |
+
$row[] = $product[$header];
|
635 |
+
}
|
636 |
+
$feed[] = $row;
|
637 |
+
}
|
638 |
+
$str = "";
|
639 |
+
foreach ($feed as $fields) {
|
640 |
+
$str .= implode("\t", $fields) . "\n";
|
641 |
+
}
|
642 |
+
return $str;
|
643 |
+
}
|
644 |
+
return false;
|
645 |
+
}
|
646 |
+
|
647 |
+
/**
|
648 |
+
* Responsible to make CSV feed
|
649 |
+
* @return string
|
650 |
+
*/
|
651 |
+
public function get_csv_feed()
|
652 |
+
{
|
653 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
654 |
+
$headers = array_keys($this->products[0]);
|
655 |
+
$feed[] = $headers;
|
656 |
+
foreach ($this->products as $no => $product) {
|
657 |
+
$row = array();
|
658 |
+
foreach ($headers as $key => $header) {
|
659 |
+
$row[] = $product[$header];
|
660 |
+
}
|
661 |
+
$feed[] = $row;
|
662 |
+
}
|
663 |
+
|
664 |
+
return $feed;
|
665 |
+
}
|
666 |
+
return false;
|
667 |
+
}
|
668 |
}
|
includes/feeds/class-woo-feed-facebook.php
CHANGED
@@ -1,524 +1,524 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Class Google
|
5 |
-
*
|
6 |
-
* Responsible for processing and generating feed for Google.com
|
7 |
-
*
|
8 |
-
* @since 1.0.0
|
9 |
-
* @package Google
|
10 |
-
*
|
11 |
-
*/
|
12 |
-
class Woo_Feed_Facebook
|
13 |
-
{
|
14 |
-
|
15 |
-
/**
|
16 |
-
* This variable is responsible for holding all product attributes and their values
|
17 |
-
*
|
18 |
-
* @since 1.0.0
|
19 |
-
* @var array $products Contains all the product attributes to generate feed
|
20 |
-
* @access public
|
21 |
-
*/
|
22 |
-
public $products;
|
23 |
-
|
24 |
-
/**
|
25 |
-
* This variable is responsible for holding feed configuration form values
|
26 |
-
*
|
27 |
-
* @since 1.0.0
|
28 |
-
* @var array $rules Contains feed configuration form values
|
29 |
-
* @access public
|
30 |
-
*/
|
31 |
-
public $rules;
|
32 |
-
|
33 |
-
/**
|
34 |
-
* This variable is responsible for mapping store attributes to merchant attribute
|
35 |
-
*
|
36 |
-
* @since 1.0.0
|
37 |
-
* @var array $mapping Map store attributes to merchant attribute
|
38 |
-
* @access public
|
39 |
-
*/
|
40 |
-
public $mapping;
|
41 |
-
|
42 |
-
/**
|
43 |
-
* This variable is responsible for generate error logs
|
44 |
-
*
|
45 |
-
* @since 1.0.0
|
46 |
-
* @var array $errorLog Generate error logs
|
47 |
-
* @access public
|
48 |
-
*/
|
49 |
-
public $errorLog;
|
50 |
-
|
51 |
-
/**
|
52 |
-
* This variable is responsible for making error number
|
53 |
-
*
|
54 |
-
* @since 1.0.0
|
55 |
-
* @var int $errorCounter Generate error number
|
56 |
-
* @access public
|
57 |
-
*/
|
58 |
-
public $errorCounter;
|
59 |
-
|
60 |
-
/**
|
61 |
-
* Feed Wrapper text for enclosing each product information
|
62 |
-
*
|
63 |
-
* @since 1.0.0
|
64 |
-
* @var string $feedWrapper Feed Wrapper text
|
65 |
-
* @access public
|
66 |
-
*/
|
67 |
-
public $feedWrapper = 'item';
|
68 |
-
|
69 |
-
/**
|
70 |
-
* Store product information
|
71 |
-
*
|
72 |
-
* @since 1.0.0
|
73 |
-
* @var array $storeProducts
|
74 |
-
* @access public
|
75 |
-
*/
|
76 |
-
private $storeProducts;
|
77 |
-
|
78 |
-
/**
|
79 |
-
* Define the core functionality to generate feed.
|
80 |
-
*
|
81 |
-
* Set the feed rules. Map products according to the rules and Check required attributes
|
82 |
-
* and their values according to merchant specification.
|
83 |
-
* @var Woo_Generate_Feed $feedRule Contain Feed Configuration
|
84 |
-
* @since 1.0.0
|
85 |
-
*/
|
86 |
-
public function __construct($feedRule)
|
87 |
-
{
|
88 |
-
$products = new Woo_Feed_Products();
|
89 |
-
$storeProducts = $products->woo_feed_get_visible_product($feedRule);
|
90 |
-
$engine = new WF_Engine($storeProducts, $feedRule);
|
91 |
-
$this->products = $engine->mapProductsByRules();
|
92 |
-
$this->rules = $feedRule;
|
93 |
-
if ($feedRule['feedType'] == 'xml') {
|
94 |
-
$this->mapAttributeForXML();
|
95 |
-
} else {
|
96 |
-
$this->mapAttributeForCSVTXT();
|
97 |
-
}
|
98 |
-
|
99 |
-
}
|
100 |
-
|
101 |
-
|
102 |
-
/**
|
103 |
-
* Return Feed
|
104 |
-
*
|
105 |
-
* @return array|bool|string
|
106 |
-
*/
|
107 |
-
public function returnFinalProduct()
|
108 |
-
{
|
109 |
-
if(!empty($this->products)) {
|
110 |
-
$engine = new WF_Engine($this->products, $this->rules);
|
111 |
-
if ($this->rules['feedType'] == 'xml') {
|
112 |
-
//return $this->get_feed($this->products);
|
113 |
-
$feed = array(
|
114 |
-
"header" => $this->get_xml_feed_header(),
|
115 |
-
"body" => $this->get_xml_feed_body($this->products),
|
116 |
-
"footer" => $this->get_xml_feed_footer(),
|
117 |
-
);
|
118 |
-
return $feed;
|
119 |
-
} elseif ($this->rules['feedType'] == 'txt') {
|
120 |
-
//return $engine->get_txt_feed();
|
121 |
-
$feed = array(
|
122 |
-
"body" => $engine->get_txt_feed(),
|
123 |
-
"header" => $engine->txtFeedHeader,
|
124 |
-
"footer" => "",
|
125 |
-
);
|
126 |
-
return $feed;
|
127 |
-
} elseif ($this->rules['feedType'] == 'csv') {
|
128 |
-
$feed = array(
|
129 |
-
"body" => $engine->get_csv_feed(),
|
130 |
-
"header" => $engine->csvFeedHeader,
|
131 |
-
"footer" => "",
|
132 |
-
);
|
133 |
-
return $feed;
|
134 |
-
}
|
135 |
-
}
|
136 |
-
$feed=array(
|
137 |
-
"body"=>"",
|
138 |
-
"header"=>"",
|
139 |
-
"footer"=>"",
|
140 |
-
);
|
141 |
-
return $feed;
|
142 |
-
}
|
143 |
-
|
144 |
-
/**
|
145 |
-
* Configure merchant attributes for XML feed
|
146 |
-
*/
|
147 |
-
public function mapAttributeForXML()
|
148 |
-
{
|
149 |
-
|
150 |
-
$googleXMLAttribute = array(
|
151 |
-
"id" => array("g:id", false),
|
152 |
-
"title" => array("g:title", true),
|
153 |
-
"description" => array("g:description", true),
|
154 |
-
"link" => array("g:link", true),
|
155 |
-
"mobile_link" => array("g:mobile_link", true),
|
156 |
-
"product_type" => array("g:product_type", true),
|
157 |
-
"current_category" => array("g:google_product_category", true),
|
158 |
-
"image" => array("g:image_link", true),
|
159 |
-
"images" => array("g:additional_image_link", false),
|
160 |
-
"images_1" => array("g:additional_image_link_1", true),
|
161 |
-
"images_2" => array("g:additional_image_link_2", true),
|
162 |
-
"images_3" => array("g:additional_image_link_3", true),
|
163 |
-
"images_4" => array("g:additional_image_link_4", true),
|
164 |
-
"images_5" => array("g:additional_image_link_5", true),
|
165 |
-
"images_6" => array("g:additional_image_link_6", true),
|
166 |
-
"images_7" => array("g:additional_image_link_7", true),
|
167 |
-
"images_8" => array("g:additional_image_link_8", true),
|
168 |
-
"images_9" => array("g:additional_image_link_9", true),
|
169 |
-
"images_10" => array("g:additional_image_link_10", true),
|
170 |
-
"condition" => array("g:condition", false),
|
171 |
-
"availability" => array("g:availability", false),
|
172 |
-
"inventory" => array("g:inventory", false),
|
173 |
-
"override" => array("g:override", false),
|
174 |
-
"price" => array("g:price", true),
|
175 |
-
"sale_price" => array("g:sale_price", true),
|
176 |
-
"sale_price_effective_date" => array("g:sale_price_effective_date", true),
|
177 |
-
"brand" => array("g:brand", true),
|
178 |
-
"sku" => array("g:mpn", true),
|
179 |
-
"upc" => array("g:gtin", true),
|
180 |
-
"identifier_exists" => array("g:identifier_exists", true),
|
181 |
-
"item_group_id" => array("g:item_group_id", false),
|
182 |
-
"color" => array("g:color", true),
|
183 |
-
"gender" => array("g:gender", true),
|
184 |
-
"age_group" => array("g:age_group", true),
|
185 |
-
"material" => array("g:material", true),
|
186 |
-
"pattern" => array("g:pattern", true),
|
187 |
-
"size" => array("g:size", true),
|
188 |
-
"size_type" => array("g:size_type", true),
|
189 |
-
"size_system" => array("g:size_system", true),
|
190 |
-
"tax" => array("tax", true),
|
191 |
-
"weight" => array("g:shipping_weight", false),
|
192 |
-
"length" => array("g:shipping_length", false),
|
193 |
-
"width" => array("g:shipping_width", false),
|
194 |
-
"height" => array("g:shipping_height", false),
|
195 |
-
"shipping_label" => array("g:shipping_label", false),
|
196 |
-
"shipping_country" => array("g:shipping_country", false),
|
197 |
-
"shipping_service" => array("g:shipping_service", false),
|
198 |
-
"shipping_price" => array("g:shipping_price", false),
|
199 |
-
"shipping_region" => array("g:shipping_region", false),
|
200 |
-
"multipack" => array("g:multipack", true),
|
201 |
-
"is_bundle" => array("g:is_bundle", true),
|
202 |
-
"adult" => array("g:adult", true),
|
203 |
-
"adwords_redirect" => array("g:adwords_redirect", true),
|
204 |
-
"custom_label_0" => array("g:custom_label_0", true),
|
205 |
-
"custom_label_1" => array("g:custom_label_1", true),
|
206 |
-
"custom_label_2" => array("g:custom_label_2", true),
|
207 |
-
"custom_label_3" => array("g:custom_label_3", true),
|
208 |
-
"custom_label_4" => array("g:custom_label_4", true),
|
209 |
-
"excluded_destination" => array("g:excluded_destination", true),
|
210 |
-
"expiration_date" => array("g:expiration_date", true),
|
211 |
-
"unit_pricing_measure" => array("g:unit_pricing_measure", true),
|
212 |
-
"unit_pricing_base_measure" => array("g:unit_pricing_base_measure", true),
|
213 |
-
"energy_efficiency_class" => array("g:energy_efficiency_class", true),
|
214 |
-
"loyalty_points" => array("g:loyalty_points", true),
|
215 |
-
"installment" => array("g:installment", true),
|
216 |
-
"promotion_id" => array("g:promotion_id", true),
|
217 |
-
"cost_of_goods_sold" => array("g:cost_of_goods_sold", true),
|
218 |
-
"availability_date" => array("g:availability_date", true),
|
219 |
-
"tax_category" => array("g:tax_category", true),
|
220 |
-
"included_destination" => array("g:included_destination", true),
|
221 |
-
);
|
222 |
-
|
223 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
224 |
-
foreach ($this->products as $no => $product) {
|
225 |
-
foreach ($product as $key => $value) {
|
226 |
-
$this->mapAttribute($no, $key, $googleXMLAttribute[$key][0], $value, $googleXMLAttribute[$key][0]);
|
227 |
-
}
|
228 |
-
$this->process_google_shipping_attribute_for_xml($no);
|
229 |
-
}
|
230 |
-
}
|
231 |
-
}
|
232 |
-
|
233 |
-
/**
|
234 |
-
* Configure merchant attributes for XML feed
|
235 |
-
*/
|
236 |
-
public function mapAttributeForCSVTXT()
|
237 |
-
{
|
238 |
-
//Basic product information
|
239 |
-
$googleCSVTXTAttribute = array(
|
240 |
-
"id" => array("id", false),
|
241 |
-
"title" => array("title", true),
|
242 |
-
"description" => array("description", true),
|
243 |
-
"link" => array("link", true),
|
244 |
-
"mobile_link" => array("mobile_link", true),
|
245 |
-
"product_type" => array("product type", true),
|
246 |
-
"current_category" => array("google product category", true),
|
247 |
-
"image" => array("image link", true),
|
248 |
-
"images" => array("additional image link", true),
|
249 |
-
"images_1" => array("additional image link 1", true),
|
250 |
-
"images_2" => array("additional image link 2", true),
|
251 |
-
"images_3" => array("additional image link 3", true),
|
252 |
-
"images_4" => array("additional image link 4", true),
|
253 |
-
"images_5" => array("additional image link 5", true),
|
254 |
-
"images_6" => array("additional image link 6", true),
|
255 |
-
"images_7" => array("additional image link 7", true),
|
256 |
-
"images_8" => array("additional image link 8", true),
|
257 |
-
"images_9" => array("additional image link 9", true),
|
258 |
-
"images_10" => array("additional image link 10", true),
|
259 |
-
"condition" => array("condition", false),
|
260 |
-
"availability" => array("availability", false),
|
261 |
-
"inventory" => array("inventory", false),
|
262 |
-
"override" => array("override", false),
|
263 |
-
"price" => array("price", true),
|
264 |
-
"sale_price" => array("sale price", true),
|
265 |
-
"sale_price_effective_date" => array("sale price effective date", true),
|
266 |
-
"brand" => array("brand", true),
|
267 |
-
"sku" => array("mpn", true),
|
268 |
-
"upc" => array("gtin", true),
|
269 |
-
"identifier_exists" => array("identifier exists", true),
|
270 |
-
"item_group_id" => array("item group id", false),
|
271 |
-
"color" => array("color", true),
|
272 |
-
"gender" => array("gender", true),
|
273 |
-
"age_group" => array("age group", true),
|
274 |
-
"material" => array("material", true),
|
275 |
-
"pattern" => array("pattern", true),
|
276 |
-
"size" => array("size", true),
|
277 |
-
"size_type" => array("size type", true),
|
278 |
-
"size_system" => array("size system", true),
|
279 |
-
"tax" => array("tax", true),
|
280 |
-
"weight" => array("shipping weight", false),
|
281 |
-
"length" => array("shipping length", false),
|
282 |
-
"width" => array("shipping width", false),
|
283 |
-
"height" => array("shipping height", false),
|
284 |
-
"shipping_label" => array("shipping label", false),
|
285 |
-
"shipping_country" => array("shipping country", false),
|
286 |
-
"shipping_service" => array("shipping service", false),
|
287 |
-
"shipping_price" => array("shipping price", false),
|
288 |
-
"shipping_region" => array("shipping region", false),
|
289 |
-
"multipack" => array("multipack", true),
|
290 |
-
"is_bundle" => array("is bundle", true),
|
291 |
-
"adult" => array("adult", true),
|
292 |
-
"adwords_redirect" => array("adwords redirect", true),
|
293 |
-
"custom_label_0" => array("custom label 0", true),
|
294 |
-
"custom_label_1" => array("custom label 1", true),
|
295 |
-
"custom_label_2" => array("custom label 2", true),
|
296 |
-
"custom_label_3" => array("custom label 3", true),
|
297 |
-
"custom_label_4" => array("custom label 4", true),
|
298 |
-
"excluded_destination" => array("excluded destination", true),
|
299 |
-
"expiration_date" => array("expiration date", true),
|
300 |
-
"unit_pricing_measure" => array("unit pricing measure", true),
|
301 |
-
"unit_pricing_base_measure" => array("unit pricing base measure", true),
|
302 |
-
"energy_efficiency_class" => array("energy efficiency class", true),
|
303 |
-
"loyalty_points" => array("loyalty points", true),
|
304 |
-
"installment" => array("installment", true),
|
305 |
-
"promotion_id" => array("promotion id", true),
|
306 |
-
"cost_of_goods_sold" => array("cost of goods sold", true),
|
307 |
-
"availability_date" => array("availability date", true),
|
308 |
-
"tax_category" => array("tax category", true),
|
309 |
-
"included_destination" => array("included destination", true),
|
310 |
-
);
|
311 |
-
|
312 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
313 |
-
foreach ($this->products as $no => $product) {
|
314 |
-
foreach ($product as $key => $value) {
|
315 |
-
$this->mapAttribute($no, $key, str_replace(" ", "_", $googleCSVTXTAttribute[$key][0]), $value, $googleCSVTXTAttribute[$key][0]);
|
316 |
-
}
|
317 |
-
$this->process_google_shipping_attribute_for_CSVTXT($no);
|
318 |
-
}
|
319 |
-
}
|
320 |
-
}
|
321 |
-
|
322 |
-
/**
|
323 |
-
* Map to google attribute
|
324 |
-
* @param $no
|
325 |
-
* @param $from
|
326 |
-
* @param $to
|
327 |
-
* @param $value
|
328 |
-
* @param bool $cdata
|
329 |
-
* @return array
|
330 |
-
*/
|
331 |
-
public function mapAttribute($no, $from, $to, $value, $cdata = false)
|
332 |
-
{
|
333 |
-
unset($this->products[$no][$from]);
|
334 |
-
if ($this->rules['feedType'] == 'xml') {
|
335 |
-
return $this->products[$no][$to] = $this->formatXMLLine($to, $value, $cdata);
|
336 |
-
} else {
|
337 |
-
return $this->products[$no][$to] = $value;
|
338 |
-
}
|
339 |
-
}
|
340 |
-
|
341 |
-
|
342 |
-
public
|
343 |
-
function process_google_shipping_attribute_for_xml($no)
|
344 |
-
{
|
345 |
-
$shipping = array('g:shipping_country', 'g:shipping_service', 'g:shipping_price', 'g:shipping_region');
|
346 |
-
$shippingAttr = array();
|
347 |
-
$products = $this->products[$no];
|
348 |
-
foreach ($products as $keyAttr => $valueAttr) {
|
349 |
-
if (in_array($keyAttr, $shipping)) {
|
350 |
-
array_push($shippingAttr, array($keyAttr => $valueAttr));
|
351 |
-
unset($this->products[$no][$keyAttr]);
|
352 |
-
}
|
353 |
-
}
|
354 |
-
if (count($shippingAttr)) {
|
355 |
-
$str = "";
|
356 |
-
foreach ($shippingAttr as $key => $attributes) {
|
357 |
-
foreach ($attributes as $keyAttr => $valueAttr) {
|
358 |
-
$str .= str_replace("shipping_", "", $valueAttr);
|
359 |
-
}
|
360 |
-
}
|
361 |
-
return $this->products[$no]['g:shipping'] = $this->formatXMLLine("g:shipping", $str, false);
|
362 |
-
}
|
363 |
-
return false;
|
364 |
-
}
|
365 |
-
|
366 |
-
public
|
367 |
-
function process_google_shipping_attribute_for_CSVTXT($no)
|
368 |
-
{
|
369 |
-
$shipping = array('shipping_country', 'shipping_service', 'shipping_price', 'shipping_region');
|
370 |
-
$shippingAttr = array();
|
371 |
-
$products = $this->products[$no];
|
372 |
-
foreach ($products as $keyAttr => $valueAttr) {
|
373 |
-
if (in_array($keyAttr, $shipping)) {
|
374 |
-
array_push($shippingAttr, array($keyAttr => $valueAttr));
|
375 |
-
unset($this->products[$no][$keyAttr]);
|
376 |
-
}
|
377 |
-
}
|
378 |
-
if (count($shippingAttr)) {
|
379 |
-
$str = "";
|
380 |
-
foreach ($shippingAttr as $key => $attributes) {
|
381 |
-
foreach ($attributes as $keyAttr => $valueAttr) {
|
382 |
-
$country = ($keyAttr == "shipping_country") ? $str .= $valueAttr . ":" : "";
|
383 |
-
$service = ($keyAttr == "shipping_service") ? $str .= $valueAttr . ":" : "";
|
384 |
-
$price = ($keyAttr == "shipping_price") ? $str .= $valueAttr : "";
|
385 |
-
$region = ($keyAttr == "shipping_region") ? $str .= $valueAttr . ":" : "";
|
386 |
-
}
|
387 |
-
}
|
388 |
-
return $this->products[$no]['shipping(country:region:service:price)'] = str_replace(" : ", ":", $str);
|
389 |
-
}
|
390 |
-
return false;
|
391 |
-
}
|
392 |
-
|
393 |
-
/**
|
394 |
-
* Make xml node
|
395 |
-
*
|
396 |
-
* @param string $attribute Attribute Name
|
397 |
-
* @param string $value Attribute Value
|
398 |
-
* @param bool $cdata
|
399 |
-
* @param string $space
|
400 |
-
* @return string
|
401 |
-
*/
|
402 |
-
function formatXMLLine($attribute, $value, $cdata, $space = "")
|
403 |
-
{
|
404 |
-
//Make single XML node
|
405 |
-
if (!empty($value))
|
406 |
-
$value = trim($value);
|
407 |
-
if (gettype($value) == 'array')
|
408 |
-
$value = json_encode($value);
|
409 |
-
if (strpos($value, "<![CDATA[") === false && substr(trim($value), 0, 4) == "http") {
|
410 |
-
$value = "<![CDATA[$value]]>";
|
411 |
-
} elseif (strpos($value, "<![CDATA[") === false && $cdata === true && !empty($value)) {
|
412 |
-
$value = "<![CDATA[$value]]>";
|
413 |
-
} elseif ($cdata) {
|
414 |
-
if(!empty($value)){
|
415 |
-
$value = "<![CDATA[$value]]>";
|
416 |
-
}
|
417 |
-
}
|
418 |
-
|
419 |
-
if (substr($attribute, 0, 23) == 'g:additional_image_link') {
|
420 |
-
$attribute = "g:additional_image_link";
|
421 |
-
}
|
422 |
-
|
423 |
-
return "
|
424 |
-
$space<$attribute>$value</$attribute>";
|
425 |
-
}
|
426 |
-
|
427 |
-
|
428 |
-
/**
|
429 |
-
* Make XML Feed Header
|
430 |
-
* @return string
|
431 |
-
*/
|
432 |
-
public function get_xml_feed_header()
|
433 |
-
{
|
434 |
-
$output = '<?xml version="1.0" encoding="UTF-8" ?>
|
435 |
-
<rss xmlns:g="http://base.google.com/ns/1.0" version="2.0">
|
436 |
-
<channel>
|
437 |
-
<title><![CDATA[' . html_entity_decode(get_option('blogname')) . ']]></title>
|
438 |
-
<link><![CDATA[' . site_url() . ']]></link>
|
439 |
-
<description><![CDATA[' . html_entity_decode( get_option('blogdescription')) . ']]></description>';
|
440 |
-
return $output;
|
441 |
-
}
|
442 |
-
|
443 |
-
/** Make XML Feed
|
444 |
-
* @param $items
|
445 |
-
* @return bool|string
|
446 |
-
*/
|
447 |
-
public function get_xml_feed_body($items)
|
448 |
-
{
|
449 |
-
$feed = "";
|
450 |
-
//$feed .= $this->get_feed_header();
|
451 |
-
$feed .= "\n";
|
452 |
-
if ($items) {
|
453 |
-
foreach ($items as $item => $products) {
|
454 |
-
$feed .= " <".$this->feedWrapper.">";
|
455 |
-
foreach ($products as $key => $value) {
|
456 |
-
if (!empty($value)){
|
457 |
-
$feed .= $value;
|
458 |
-
}
|
459 |
-
}
|
460 |
-
$feed .= "\n </" . $this->feedWrapper . ">\n";
|
461 |
-
}
|
462 |
-
// $feed .= $this->get_feed_footer();
|
463 |
-
|
464 |
-
return $feed;
|
465 |
-
}
|
466 |
-
return false;
|
467 |
-
}
|
468 |
-
|
469 |
-
/**
|
470 |
-
* Make XML Feed Footer
|
471 |
-
* @return string
|
472 |
-
*/
|
473 |
-
public function get_xml_feed_footer()
|
474 |
-
{
|
475 |
-
$footer = " </channel>
|
476 |
-
</rss>";
|
477 |
-
return $footer;
|
478 |
-
}
|
479 |
-
|
480 |
-
/**
|
481 |
-
* Short Products
|
482 |
-
* @return array
|
483 |
-
*/
|
484 |
-
public function short_products()
|
485 |
-
{
|
486 |
-
if ($this->products) {
|
487 |
-
update_option('wpf_progress', "Shorting Products");
|
488 |
-
sleep(1);
|
489 |
-
$array = array();
|
490 |
-
$ij = 0;
|
491 |
-
foreach ($this->products as $key => $item) {
|
492 |
-
$array[$ij] = $item;
|
493 |
-
unset($this->products[$key]);
|
494 |
-
$ij++;
|
495 |
-
}
|
496 |
-
return $this->products = $array;
|
497 |
-
}
|
498 |
-
return $this->products;
|
499 |
-
}
|
500 |
-
|
501 |
-
/**
|
502 |
-
* Responsible to make CSV feed
|
503 |
-
* @return string
|
504 |
-
*/
|
505 |
-
public function get_csv_feed()
|
506 |
-
{
|
507 |
-
if ($this->products) {
|
508 |
-
$headers = array_keys($this->products[0]);
|
509 |
-
$feed[] = $headers;
|
510 |
-
foreach ($this->products as $no => $product) {
|
511 |
-
$row = array();
|
512 |
-
foreach ($headers as $key => $header) {
|
513 |
-
if (strpos($header, "additional image link") !== false) {
|
514 |
-
$header = "additional image link";
|
515 |
-
}
|
516 |
-
$row[] = isset($product[$header]) ? $product[$header] : "";;
|
517 |
-
}
|
518 |
-
$feed[] = $row;
|
519 |
-
}
|
520 |
-
return $feed;
|
521 |
-
}
|
522 |
-
return false;
|
523 |
-
}
|
524 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Google
|
5 |
+
*
|
6 |
+
* Responsible for processing and generating feed for Google.com
|
7 |
+
*
|
8 |
+
* @since 1.0.0
|
9 |
+
* @package Google
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Woo_Feed_Facebook
|
13 |
+
{
|
14 |
+
|
15 |
+
/**
|
16 |
+
* This variable is responsible for holding all product attributes and their values
|
17 |
+
*
|
18 |
+
* @since 1.0.0
|
19 |
+
* @var array $products Contains all the product attributes to generate feed
|
20 |
+
* @access public
|
21 |
+
*/
|
22 |
+
public $products;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* This variable is responsible for holding feed configuration form values
|
26 |
+
*
|
27 |
+
* @since 1.0.0
|
28 |
+
* @var array $rules Contains feed configuration form values
|
29 |
+
* @access public
|
30 |
+
*/
|
31 |
+
public $rules;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* This variable is responsible for mapping store attributes to merchant attribute
|
35 |
+
*
|
36 |
+
* @since 1.0.0
|
37 |
+
* @var array $mapping Map store attributes to merchant attribute
|
38 |
+
* @access public
|
39 |
+
*/
|
40 |
+
public $mapping;
|
41 |
+
|
42 |
+
/**
|
43 |
+
* This variable is responsible for generate error logs
|
44 |
+
*
|
45 |
+
* @since 1.0.0
|
46 |
+
* @var array $errorLog Generate error logs
|
47 |
+
* @access public
|
48 |
+
*/
|
49 |
+
public $errorLog;
|
50 |
+
|
51 |
+
/**
|
52 |
+
* This variable is responsible for making error number
|
53 |
+
*
|
54 |
+
* @since 1.0.0
|
55 |
+
* @var int $errorCounter Generate error number
|
56 |
+
* @access public
|
57 |
+
*/
|
58 |
+
public $errorCounter;
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Feed Wrapper text for enclosing each product information
|
62 |
+
*
|
63 |
+
* @since 1.0.0
|
64 |
+
* @var string $feedWrapper Feed Wrapper text
|
65 |
+
* @access public
|
66 |
+
*/
|
67 |
+
public $feedWrapper = 'item';
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Store product information
|
71 |
+
*
|
72 |
+
* @since 1.0.0
|
73 |
+
* @var array $storeProducts
|
74 |
+
* @access public
|
75 |
+
*/
|
76 |
+
private $storeProducts;
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Define the core functionality to generate feed.
|
80 |
+
*
|
81 |
+
* Set the feed rules. Map products according to the rules and Check required attributes
|
82 |
+
* and their values according to merchant specification.
|
83 |
+
* @var Woo_Generate_Feed $feedRule Contain Feed Configuration
|
84 |
+
* @since 1.0.0
|
85 |
+
*/
|
86 |
+
public function __construct($feedRule)
|
87 |
+
{
|
88 |
+
$products = new Woo_Feed_Products();
|
89 |
+
$storeProducts = $products->woo_feed_get_visible_product($feedRule);
|
90 |
+
$engine = new WF_Engine($storeProducts, $feedRule);
|
91 |
+
$this->products = $engine->mapProductsByRules();
|
92 |
+
$this->rules = $feedRule;
|
93 |
+
if ($feedRule['feedType'] == 'xml') {
|
94 |
+
$this->mapAttributeForXML();
|
95 |
+
} else {
|
96 |
+
$this->mapAttributeForCSVTXT();
|
97 |
+
}
|
98 |
+
|
99 |
+
}
|
100 |
+
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Return Feed
|
104 |
+
*
|
105 |
+
* @return array|bool|string
|
106 |
+
*/
|
107 |
+
public function returnFinalProduct()
|
108 |
+
{
|
109 |
+
if(!empty($this->products)) {
|
110 |
+
$engine = new WF_Engine($this->products, $this->rules);
|
111 |
+
if ($this->rules['feedType'] == 'xml') {
|
112 |
+
//return $this->get_feed($this->products);
|
113 |
+
$feed = array(
|
114 |
+
"header" => $this->get_xml_feed_header(),
|
115 |
+
"body" => $this->get_xml_feed_body($this->products),
|
116 |
+
"footer" => $this->get_xml_feed_footer(),
|
117 |
+
);
|
118 |
+
return $feed;
|
119 |
+
} elseif ($this->rules['feedType'] == 'txt') {
|
120 |
+
//return $engine->get_txt_feed();
|
121 |
+
$feed = array(
|
122 |
+
"body" => $engine->get_txt_feed(),
|
123 |
+
"header" => $engine->txtFeedHeader,
|
124 |
+
"footer" => "",
|
125 |
+
);
|
126 |
+
return $feed;
|
127 |
+
} elseif ($this->rules['feedType'] == 'csv') {
|
128 |
+
$feed = array(
|
129 |
+
"body" => $engine->get_csv_feed(),
|
130 |
+
"header" => $engine->csvFeedHeader,
|
131 |
+
"footer" => "",
|
132 |
+
);
|
133 |
+
return $feed;
|
134 |
+
}
|
135 |
+
}
|
136 |
+
$feed=array(
|
137 |
+
"body"=>"",
|
138 |
+
"header"=>"",
|
139 |
+
"footer"=>"",
|
140 |
+
);
|
141 |
+
return $feed;
|
142 |
+
}
|
143 |
+
|
144 |
+
/**
|
145 |
+
* Configure merchant attributes for XML feed
|
146 |
+
*/
|
147 |
+
public function mapAttributeForXML()
|
148 |
+
{
|
149 |
+
|
150 |
+
$googleXMLAttribute = array(
|
151 |
+
"id" => array("g:id", false),
|
152 |
+
"title" => array("g:title", true),
|
153 |
+
"description" => array("g:description", true),
|
154 |
+
"link" => array("g:link", true),
|
155 |
+
"mobile_link" => array("g:mobile_link", true),
|
156 |
+
"product_type" => array("g:product_type", true),
|
157 |
+
"current_category" => array("g:google_product_category", true),
|
158 |
+
"image" => array("g:image_link", true),
|
159 |
+
"images" => array("g:additional_image_link", false),
|
160 |
+
"images_1" => array("g:additional_image_link_1", true),
|
161 |
+
"images_2" => array("g:additional_image_link_2", true),
|
162 |
+
"images_3" => array("g:additional_image_link_3", true),
|
163 |
+
"images_4" => array("g:additional_image_link_4", true),
|
164 |
+
"images_5" => array("g:additional_image_link_5", true),
|
165 |
+
"images_6" => array("g:additional_image_link_6", true),
|
166 |
+
"images_7" => array("g:additional_image_link_7", true),
|
167 |
+
"images_8" => array("g:additional_image_link_8", true),
|
168 |
+
"images_9" => array("g:additional_image_link_9", true),
|
169 |
+
"images_10" => array("g:additional_image_link_10", true),
|
170 |
+
"condition" => array("g:condition", false),
|
171 |
+
"availability" => array("g:availability", false),
|
172 |
+
"inventory" => array("g:inventory", false),
|
173 |
+
"override" => array("g:override", false),
|
174 |
+
"price" => array("g:price", true),
|
175 |
+
"sale_price" => array("g:sale_price", true),
|
176 |
+
"sale_price_effective_date" => array("g:sale_price_effective_date", true),
|
177 |
+
"brand" => array("g:brand", true),
|
178 |
+
"sku" => array("g:mpn", true),
|
179 |
+
"upc" => array("g:gtin", true),
|
180 |
+
"identifier_exists" => array("g:identifier_exists", true),
|
181 |
+
"item_group_id" => array("g:item_group_id", false),
|
182 |
+
"color" => array("g:color", true),
|
183 |
+
"gender" => array("g:gender", true),
|
184 |
+
"age_group" => array("g:age_group", true),
|
185 |
+
"material" => array("g:material", true),
|
186 |
+
"pattern" => array("g:pattern", true),
|
187 |
+
"size" => array("g:size", true),
|
188 |
+
"size_type" => array("g:size_type", true),
|
189 |
+
"size_system" => array("g:size_system", true),
|
190 |
+
"tax" => array("tax", true),
|
191 |
+
"weight" => array("g:shipping_weight", false),
|
192 |
+
"length" => array("g:shipping_length", false),
|
193 |
+
"width" => array("g:shipping_width", false),
|
194 |
+
"height" => array("g:shipping_height", false),
|
195 |
+
"shipping_label" => array("g:shipping_label", false),
|
196 |
+
"shipping_country" => array("g:shipping_country", false),
|
197 |
+
"shipping_service" => array("g:shipping_service", false),
|
198 |
+
"shipping_price" => array("g:shipping_price", false),
|
199 |
+
"shipping_region" => array("g:shipping_region", false),
|
200 |
+
"multipack" => array("g:multipack", true),
|
201 |
+
"is_bundle" => array("g:is_bundle", true),
|
202 |
+
"adult" => array("g:adult", true),
|
203 |
+
"adwords_redirect" => array("g:adwords_redirect", true),
|
204 |
+
"custom_label_0" => array("g:custom_label_0", true),
|
205 |
+
"custom_label_1" => array("g:custom_label_1", true),
|
206 |
+
"custom_label_2" => array("g:custom_label_2", true),
|
207 |
+
"custom_label_3" => array("g:custom_label_3", true),
|
208 |
+
"custom_label_4" => array("g:custom_label_4", true),
|
209 |
+
"excluded_destination" => array("g:excluded_destination", true),
|
210 |
+
"expiration_date" => array("g:expiration_date", true),
|
211 |
+
"unit_pricing_measure" => array("g:unit_pricing_measure", true),
|
212 |
+
"unit_pricing_base_measure" => array("g:unit_pricing_base_measure", true),
|
213 |
+
"energy_efficiency_class" => array("g:energy_efficiency_class", true),
|
214 |
+
"loyalty_points" => array("g:loyalty_points", true),
|
215 |
+
"installment" => array("g:installment", true),
|
216 |
+
"promotion_id" => array("g:promotion_id", true),
|
217 |
+
"cost_of_goods_sold" => array("g:cost_of_goods_sold", true),
|
218 |
+
"availability_date" => array("g:availability_date", true),
|
219 |
+
"tax_category" => array("g:tax_category", true),
|
220 |
+
"included_destination" => array("g:included_destination", true),
|
221 |
+
);
|
222 |
+
|
223 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
224 |
+
foreach ($this->products as $no => $product) {
|
225 |
+
foreach ($product as $key => $value) {
|
226 |
+
$this->mapAttribute($no, $key, $googleXMLAttribute[$key][0], $value, $googleXMLAttribute[$key][0]);
|
227 |
+
}
|
228 |
+
$this->process_google_shipping_attribute_for_xml($no);
|
229 |
+
}
|
230 |
+
}
|
231 |
+
}
|
232 |
+
|
233 |
+
/**
|
234 |
+
* Configure merchant attributes for XML feed
|
235 |
+
*/
|
236 |
+
public function mapAttributeForCSVTXT()
|
237 |
+
{
|
238 |
+
//Basic product information
|
239 |
+
$googleCSVTXTAttribute = array(
|
240 |
+
"id" => array("id", false),
|
241 |
+
"title" => array("title", true),
|
242 |
+
"description" => array("description", true),
|
243 |
+
"link" => array("link", true),
|
244 |
+
"mobile_link" => array("mobile_link", true),
|
245 |
+
"product_type" => array("product type", true),
|
246 |
+
"current_category" => array("google product category", true),
|
247 |
+
"image" => array("image link", true),
|
248 |
+
"images" => array("additional image link", true),
|
249 |
+
"images_1" => array("additional image link 1", true),
|
250 |
+
"images_2" => array("additional image link 2", true),
|
251 |
+
"images_3" => array("additional image link 3", true),
|
252 |
+
"images_4" => array("additional image link 4", true),
|
253 |
+
"images_5" => array("additional image link 5", true),
|
254 |
+
"images_6" => array("additional image link 6", true),
|
255 |
+
"images_7" => array("additional image link 7", true),
|
256 |
+
"images_8" => array("additional image link 8", true),
|
257 |
+
"images_9" => array("additional image link 9", true),
|
258 |
+
"images_10" => array("additional image link 10", true),
|
259 |
+
"condition" => array("condition", false),
|
260 |
+
"availability" => array("availability", false),
|
261 |
+
"inventory" => array("inventory", false),
|
262 |
+
"override" => array("override", false),
|
263 |
+
"price" => array("price", true),
|
264 |
+
"sale_price" => array("sale price", true),
|
265 |
+
"sale_price_effective_date" => array("sale price effective date", true),
|
266 |
+
"brand" => array("brand", true),
|
267 |
+
"sku" => array("mpn", true),
|
268 |
+
"upc" => array("gtin", true),
|
269 |
+
"identifier_exists" => array("identifier exists", true),
|
270 |
+
"item_group_id" => array("item group id", false),
|
271 |
+
"color" => array("color", true),
|
272 |
+
"gender" => array("gender", true),
|
273 |
+
"age_group" => array("age group", true),
|
274 |
+
"material" => array("material", true),
|
275 |
+
"pattern" => array("pattern", true),
|
276 |
+
"size" => array("size", true),
|
277 |
+
"size_type" => array("size type", true),
|
278 |
+
"size_system" => array("size system", true),
|
279 |
+
"tax" => array("tax", true),
|
280 |
+
"weight" => array("shipping weight", false),
|
281 |
+
"length" => array("shipping length", false),
|
282 |
+
"width" => array("shipping width", false),
|
283 |
+
"height" => array("shipping height", false),
|
284 |
+
"shipping_label" => array("shipping label", false),
|
285 |
+
"shipping_country" => array("shipping country", false),
|
286 |
+
"shipping_service" => array("shipping service", false),
|
287 |
+
"shipping_price" => array("shipping price", false),
|
288 |
+
"shipping_region" => array("shipping region", false),
|
289 |
+
"multipack" => array("multipack", true),
|
290 |
+
"is_bundle" => array("is bundle", true),
|
291 |
+
"adult" => array("adult", true),
|
292 |
+
"adwords_redirect" => array("adwords redirect", true),
|
293 |
+
"custom_label_0" => array("custom label 0", true),
|
294 |
+
"custom_label_1" => array("custom label 1", true),
|
295 |
+
"custom_label_2" => array("custom label 2", true),
|
296 |
+
"custom_label_3" => array("custom label 3", true),
|
297 |
+
"custom_label_4" => array("custom label 4", true),
|
298 |
+
"excluded_destination" => array("excluded destination", true),
|
299 |
+
"expiration_date" => array("expiration date", true),
|
300 |
+
"unit_pricing_measure" => array("unit pricing measure", true),
|
301 |
+
"unit_pricing_base_measure" => array("unit pricing base measure", true),
|
302 |
+
"energy_efficiency_class" => array("energy efficiency class", true),
|
303 |
+
"loyalty_points" => array("loyalty points", true),
|
304 |
+
"installment" => array("installment", true),
|
305 |
+
"promotion_id" => array("promotion id", true),
|
306 |
+
"cost_of_goods_sold" => array("cost of goods sold", true),
|
307 |
+
"availability_date" => array("availability date", true),
|
308 |
+
"tax_category" => array("tax category", true),
|
309 |
+
"included_destination" => array("included destination", true),
|
310 |
+
);
|
311 |
+
|
312 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
313 |
+
foreach ($this->products as $no => $product) {
|
314 |
+
foreach ($product as $key => $value) {
|
315 |
+
$this->mapAttribute($no, $key, str_replace(" ", "_", $googleCSVTXTAttribute[$key][0]), $value, $googleCSVTXTAttribute[$key][0]);
|
316 |
+
}
|
317 |
+
$this->process_google_shipping_attribute_for_CSVTXT($no);
|
318 |
+
}
|
319 |
+
}
|
320 |
+
}
|
321 |
+
|
322 |
+
/**
|
323 |
+
* Map to google attribute
|
324 |
+
* @param $no
|
325 |
+
* @param $from
|
326 |
+
* @param $to
|
327 |
+
* @param $value
|
328 |
+
* @param bool $cdata
|
329 |
+
* @return array
|
330 |
+
*/
|
331 |
+
public function mapAttribute($no, $from, $to, $value, $cdata = false)
|
332 |
+
{
|
333 |
+
unset($this->products[$no][$from]);
|
334 |
+
if ($this->rules['feedType'] == 'xml') {
|
335 |
+
return $this->products[$no][$to] = $this->formatXMLLine($to, $value, $cdata);
|
336 |
+
} else {
|
337 |
+
return $this->products[$no][$to] = $value;
|
338 |
+
}
|
339 |
+
}
|
340 |
+
|
341 |
+
|
342 |
+
public
|
343 |
+
function process_google_shipping_attribute_for_xml($no)
|
344 |
+
{
|
345 |
+
$shipping = array('g:shipping_country', 'g:shipping_service', 'g:shipping_price', 'g:shipping_region');
|
346 |
+
$shippingAttr = array();
|
347 |
+
$products = $this->products[$no];
|
348 |
+
foreach ($products as $keyAttr => $valueAttr) {
|
349 |
+
if (in_array($keyAttr, $shipping)) {
|
350 |
+
array_push($shippingAttr, array($keyAttr => $valueAttr));
|
351 |
+
unset($this->products[$no][$keyAttr]);
|
352 |
+
}
|
353 |
+
}
|
354 |
+
if (count($shippingAttr)) {
|
355 |
+
$str = "";
|
356 |
+
foreach ($shippingAttr as $key => $attributes) {
|
357 |
+
foreach ($attributes as $keyAttr => $valueAttr) {
|
358 |
+
$str .= str_replace("shipping_", "", $valueAttr);
|
359 |
+
}
|
360 |
+
}
|
361 |
+
return $this->products[$no]['g:shipping'] = $this->formatXMLLine("g:shipping", $str, false);
|
362 |
+
}
|
363 |
+
return false;
|
364 |
+
}
|
365 |
+
|
366 |
+
public
|
367 |
+
function process_google_shipping_attribute_for_CSVTXT($no)
|
368 |
+
{
|
369 |
+
$shipping = array('shipping_country', 'shipping_service', 'shipping_price', 'shipping_region');
|
370 |
+
$shippingAttr = array();
|
371 |
+
$products = $this->products[$no];
|
372 |
+
foreach ($products as $keyAttr => $valueAttr) {
|
373 |
+
if (in_array($keyAttr, $shipping)) {
|
374 |
+
array_push($shippingAttr, array($keyAttr => $valueAttr));
|
375 |
+
unset($this->products[$no][$keyAttr]);
|
376 |
+
}
|
377 |
+
}
|
378 |
+
if (count($shippingAttr)) {
|
379 |
+
$str = "";
|
380 |
+
foreach ($shippingAttr as $key => $attributes) {
|
381 |
+
foreach ($attributes as $keyAttr => $valueAttr) {
|
382 |
+
$country = ($keyAttr == "shipping_country") ? $str .= $valueAttr . ":" : "";
|
383 |
+
$service = ($keyAttr == "shipping_service") ? $str .= $valueAttr . ":" : "";
|
384 |
+
$price = ($keyAttr == "shipping_price") ? $str .= $valueAttr : "";
|
385 |
+
$region = ($keyAttr == "shipping_region") ? $str .= $valueAttr . ":" : "";
|
386 |
+
}
|
387 |
+
}
|
388 |
+
return $this->products[$no]['shipping(country:region:service:price)'] = str_replace(" : ", ":", $str);
|
389 |
+
}
|
390 |
+
return false;
|
391 |
+
}
|
392 |
+
|
393 |
+
/**
|
394 |
+
* Make xml node
|
395 |
+
*
|
396 |
+
* @param string $attribute Attribute Name
|
397 |
+
* @param string $value Attribute Value
|
398 |
+
* @param bool $cdata
|
399 |
+
* @param string $space
|
400 |
+
* @return string
|
401 |
+
*/
|
402 |
+
function formatXMLLine($attribute, $value, $cdata, $space = "")
|
403 |
+
{
|
404 |
+
//Make single XML node
|
405 |
+
if (!empty($value))
|
406 |
+
$value = trim($value);
|
407 |
+
if (gettype($value) == 'array')
|
408 |
+
$value = json_encode($value);
|
409 |
+
if (strpos($value, "<![CDATA[") === false && substr(trim($value), 0, 4) == "http") {
|
410 |
+
$value = "<![CDATA[$value]]>";
|
411 |
+
} elseif (strpos($value, "<![CDATA[") === false && $cdata === true && !empty($value)) {
|
412 |
+
$value = "<![CDATA[$value]]>";
|
413 |
+
} elseif ($cdata) {
|
414 |
+
if(!empty($value)){
|
415 |
+
$value = "<![CDATA[$value]]>";
|
416 |
+
}
|
417 |
+
}
|
418 |
+
|
419 |
+
if (substr($attribute, 0, 23) == 'g:additional_image_link') {
|
420 |
+
$attribute = "g:additional_image_link";
|
421 |
+
}
|
422 |
+
|
423 |
+
return "
|
424 |
+
$space<$attribute>$value</$attribute>";
|
425 |
+
}
|
426 |
+
|
427 |
+
|
428 |
+
/**
|
429 |
+
* Make XML Feed Header
|
430 |
+
* @return string
|
431 |
+
*/
|
432 |
+
public function get_xml_feed_header()
|
433 |
+
{
|
434 |
+
$output = '<?xml version="1.0" encoding="UTF-8" ?>
|
435 |
+
<rss xmlns:g="http://base.google.com/ns/1.0" version="2.0">
|
436 |
+
<channel>
|
437 |
+
<title><![CDATA[' . html_entity_decode(get_option('blogname')) . ']]></title>
|
438 |
+
<link><![CDATA[' . site_url() . ']]></link>
|
439 |
+
<description><![CDATA[' . html_entity_decode( get_option('blogdescription')) . ']]></description>';
|
440 |
+
return $output;
|
441 |
+
}
|
442 |
+
|
443 |
+
/** Make XML Feed
|
444 |
+
* @param $items
|
445 |
+
* @return bool|string
|
446 |
+
*/
|
447 |
+
public function get_xml_feed_body($items)
|
448 |
+
{
|
449 |
+
$feed = "";
|
450 |
+
//$feed .= $this->get_feed_header();
|
451 |
+
$feed .= "\n";
|
452 |
+
if ($items) {
|
453 |
+
foreach ($items as $item => $products) {
|
454 |
+
$feed .= " <".$this->feedWrapper.">";
|
455 |
+
foreach ($products as $key => $value) {
|
456 |
+
if (!empty($value)){
|
457 |
+
$feed .= $value;
|
458 |
+
}
|
459 |
+
}
|
460 |
+
$feed .= "\n </" . $this->feedWrapper . ">\n";
|
461 |
+
}
|
462 |
+
// $feed .= $this->get_feed_footer();
|
463 |
+
|
464 |
+
return $feed;
|
465 |
+
}
|
466 |
+
return false;
|
467 |
+
}
|
468 |
+
|
469 |
+
/**
|
470 |
+
* Make XML Feed Footer
|
471 |
+
* @return string
|
472 |
+
*/
|
473 |
+
public function get_xml_feed_footer()
|
474 |
+
{
|
475 |
+
$footer = " </channel>
|
476 |
+
</rss>";
|
477 |
+
return $footer;
|
478 |
+
}
|
479 |
+
|
480 |
+
/**
|
481 |
+
* Short Products
|
482 |
+
* @return array
|
483 |
+
*/
|
484 |
+
public function short_products()
|
485 |
+
{
|
486 |
+
if ($this->products) {
|
487 |
+
update_option('wpf_progress', "Shorting Products");
|
488 |
+
sleep(1);
|
489 |
+
$array = array();
|
490 |
+
$ij = 0;
|
491 |
+
foreach ($this->products as $key => $item) {
|
492 |
+
$array[$ij] = $item;
|
493 |
+
unset($this->products[$key]);
|
494 |
+
$ij++;
|
495 |
+
}
|
496 |
+
return $this->products = $array;
|
497 |
+
}
|
498 |
+
return $this->products;
|
499 |
+
}
|
500 |
+
|
501 |
+
/**
|
502 |
+
* Responsible to make CSV feed
|
503 |
+
* @return string
|
504 |
+
*/
|
505 |
+
public function get_csv_feed()
|
506 |
+
{
|
507 |
+
if ($this->products) {
|
508 |
+
$headers = array_keys($this->products[0]);
|
509 |
+
$feed[] = $headers;
|
510 |
+
foreach ($this->products as $no => $product) {
|
511 |
+
$row = array();
|
512 |
+
foreach ($headers as $key => $header) {
|
513 |
+
if (strpos($header, "additional image link") !== false) {
|
514 |
+
$header = "additional image link";
|
515 |
+
}
|
516 |
+
$row[] = isset($product[$header]) ? $product[$header] : "";;
|
517 |
+
}
|
518 |
+
$feed[] = $row;
|
519 |
+
}
|
520 |
+
return $feed;
|
521 |
+
}
|
522 |
+
return false;
|
523 |
+
}
|
524 |
}
|
includes/feeds/class-woo-feed-google.php
CHANGED
@@ -1,630 +1,630 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Class Google
|
5 |
-
*
|
6 |
-
* Responsible for processing and generating feed for Google.com
|
7 |
-
*
|
8 |
-
* @since 1.0.0
|
9 |
-
* @package Google
|
10 |
-
*
|
11 |
-
*/
|
12 |
-
class Woo_Feed_Google
|
13 |
-
{
|
14 |
-
|
15 |
-
/**
|
16 |
-
* This variable is responsible for holding all product attributes and their values
|
17 |
-
*
|
18 |
-
* @since 1.0.0
|
19 |
-
* @var array $products Contains all the product attributes to generate feed
|
20 |
-
* @access public
|
21 |
-
*/
|
22 |
-
public $products;
|
23 |
-
|
24 |
-
/**
|
25 |
-
* This variable is responsible for holding feed configuration form values
|
26 |
-
*
|
27 |
-
* @since 1.0.0
|
28 |
-
* @var array $rules Contains feed configuration form values
|
29 |
-
* @access public
|
30 |
-
*/
|
31 |
-
public $rules;
|
32 |
-
|
33 |
-
/**
|
34 |
-
* This variable is responsible for mapping store attributes to merchant attribute
|
35 |
-
*
|
36 |
-
* @since 1.0.0
|
37 |
-
* @var array $mapping Map store attributes to merchant attribute
|
38 |
-
* @access public
|
39 |
-
*/
|
40 |
-
public $mapping;
|
41 |
-
|
42 |
-
/**
|
43 |
-
* This variable is responsible for generate error logs
|
44 |
-
*
|
45 |
-
* @since 1.0.0
|
46 |
-
* @var array $errors hold error logs
|
47 |
-
* @access public
|
48 |
-
*/
|
49 |
-
public $errors;
|
50 |
-
|
51 |
-
/**
|
52 |
-
* This variable is responsible for generate error logs
|
53 |
-
*
|
54 |
-
* @since 1.0.0
|
55 |
-
* @var array $warnings hold warnings logs
|
56 |
-
* @access public
|
57 |
-
*/
|
58 |
-
public $warnings;
|
59 |
-
|
60 |
-
/**
|
61 |
-
* This variable is responsible for making error number
|
62 |
-
*
|
63 |
-
* @since 1.0.0
|
64 |
-
* @var int $errorCounter Generate error number
|
65 |
-
* @access public
|
66 |
-
*/
|
67 |
-
public $errorCounter;
|
68 |
-
|
69 |
-
/**
|
70 |
-
* Feed Wrapper text for enclosing each product information
|
71 |
-
*
|
72 |
-
* @since 1.0.0
|
73 |
-
* @var string $feedWrapper Feed Wrapper text
|
74 |
-
* @access public
|
75 |
-
*/
|
76 |
-
public $feedWrapper = 'item';
|
77 |
-
|
78 |
-
/**
|
79 |
-
* Store product information
|
80 |
-
*
|
81 |
-
* @since 1.0.0
|
82 |
-
* @var array $storeProducts
|
83 |
-
* @access public
|
84 |
-
*/
|
85 |
-
private $storeProducts;
|
86 |
-
|
87 |
-
/**
|
88 |
-
* Define the core functionality to generate feed.
|
89 |
-
*
|
90 |
-
* Set the feed rules. Map products according to the rules and Check required attributes
|
91 |
-
* and their values according to merchant specification.
|
92 |
-
* @var Woo_Generate_Feed $feedRule Contain Feed Configuration
|
93 |
-
* @since 1.0.0
|
94 |
-
*/
|
95 |
-
public function __construct($feedRule)
|
96 |
-
{
|
97 |
-
$products = new Woo_Feed_Products();
|
98 |
-
$storeProducts = $products->woo_feed_get_visible_product($feedRule);
|
99 |
-
if(!empty($storeProducts)){
|
100 |
-
$engine = new WF_Engine($storeProducts, $feedRule);
|
101 |
-
$this->products = $engine->mapProductsByRules();
|
102 |
-
$this->rules = $feedRule;
|
103 |
-
if ($feedRule['feedType'] == 'xml') {
|
104 |
-
$this->mapAttributeForXML();
|
105 |
-
} else {
|
106 |
-
$this->mapAttributeForCSVTXT();
|
107 |
-
}
|
108 |
-
}else{
|
109 |
-
$this->products=array();
|
110 |
-
}
|
111 |
-
|
112 |
-
}
|
113 |
-
|
114 |
-
|
115 |
-
/**
|
116 |
-
* Return Feed
|
117 |
-
* @return array
|
118 |
-
*/
|
119 |
-
public function returnFinalProduct()
|
120 |
-
{
|
121 |
-
if(!empty($this->products)){
|
122 |
-
$engine = new WF_Engine($this->products, $this->rules);
|
123 |
-
if ($this->rules['feedType'] == 'xml') {
|
124 |
-
//return $this->get_feed($this->products);
|
125 |
-
$feed=array(
|
126 |
-
"header"=>$this->get_xml_feed_header(),
|
127 |
-
"body"=>$this->get_xml_feed($this->products),
|
128 |
-
"footer"=>$this->get_xml_feed_footer(),
|
129 |
-
);
|
130 |
-
return $feed;
|
131 |
-
} elseif ($this->rules['feedType'] == 'txt') {
|
132 |
-
//return $engine->get_txt_feed();
|
133 |
-
$feed=array(
|
134 |
-
"body"=>$engine->get_txt_feed(),
|
135 |
-
"header"=>$engine->txtFeedHeader,
|
136 |
-
"footer"=>"",
|
137 |
-
);
|
138 |
-
return $feed;
|
139 |
-
} elseif ($this->rules['feedType'] == 'csv') {
|
140 |
-
//return $engine->get_csv_feed();
|
141 |
-
$feed=array(
|
142 |
-
"body"=>$engine->get_csv_feed(),
|
143 |
-
"header"=>$engine->csvFeedHeader,
|
144 |
-
"footer"=>"",
|
145 |
-
);
|
146 |
-
return $feed;
|
147 |
-
}
|
148 |
-
}
|
149 |
-
|
150 |
-
$feed=array(
|
151 |
-
"body"=>"",
|
152 |
-
"header"=>"",
|
153 |
-
"footer"=>"",
|
154 |
-
);
|
155 |
-
return $feed;
|
156 |
-
}
|
157 |
-
|
158 |
-
/**
|
159 |
-
* Configure merchant attributes for XML feed
|
160 |
-
*/
|
161 |
-
public function mapAttributeForXML()
|
162 |
-
{
|
163 |
-
|
164 |
-
$googleXMLAttribute = array(
|
165 |
-
"id" => array("g:id", false),
|
166 |
-
"title" => array("title", true),
|
167 |
-
"description" => array("description", true),
|
168 |
-
"link" => array("link", true),
|
169 |
-
"mobile_link" => array("mobile_link", true),
|
170 |
-
"product_type" => array("g:product_type", true),
|
171 |
-
"current_category" => array("g:google_product_category", true),
|
172 |
-
"image" => array("g:image_link", true),
|
173 |
-
"images" => array("g:additional_image_link", false),
|
174 |
-
"images_1" => array("g:additional_image_link_1", true),
|
175 |
-
"images_2" => array("g:additional_image_link_2", true),
|
176 |
-
"images_3" => array("g:additional_image_link_3", true),
|
177 |
-
"images_4" => array("g:additional_image_link_4", true),
|
178 |
-
"images_5" => array("g:additional_image_link_5", true),
|
179 |
-
"images_6" => array("g:additional_image_link_6", true),
|
180 |
-
"images_7" => array("g:additional_image_link_7", true),
|
181 |
-
"images_8" => array("g:additional_image_link_8", true),
|
182 |
-
"images_9" => array("g:additional_image_link_9", true),
|
183 |
-
"images_10" => array("g:additional_image_link_10", true),
|
184 |
-
"condition" => array("g:condition", false),
|
185 |
-
"availability" => array("g:availability", false),
|
186 |
-
"availability_date" => array("g:availability_date", false),
|
187 |
-
"inventory" => array("g:inventory", false),
|
188 |
-
"price" => array("g:price", true),
|
189 |
-
"sale_price" => array("g:sale_price", true),
|
190 |
-
"sale_price_effective_date" => array("g:sale_price_effective_date", true),
|
191 |
-
"brand" => array("g:brand", true),
|
192 |
-
"sku" => array("g:mpn", true),
|
193 |
-
"upc" => array("g:gtin", true),
|
194 |
-
"identifier_exists" => array("g:identifier_exists", true),
|
195 |
-
"item_group_id" => array("g:item_group_id", false),
|
196 |
-
"color" => array("g:color", true),
|
197 |
-
"gender" => array("g:gender", true),
|
198 |
-
"age_group" => array("g:age_group", true),
|
199 |
-
"material" => array("g:material", true),
|
200 |
-
"pattern" => array("g:pattern", true),
|
201 |
-
"size" => array("g:size", true),
|
202 |
-
"size_type" => array("g:size_type", true),
|
203 |
-
"size_system" => array("g:size_system", true),
|
204 |
-
"tax" => array("tax", true),
|
205 |
-
"tax_country" => array("g:tax_country", true),
|
206 |
-
"tax_region" => array("g:tax_region", true),
|
207 |
-
"tax_rate" => array("g:tax_rate", true),
|
208 |
-
"tax_ship" => array("g:tax_ship", true),
|
209 |
-
"tax_category" => array("g:tax_category", true),
|
210 |
-
"weight" => array("g:shipping_weight", false),
|
211 |
-
"length" => array("g:shipping_length", false),
|
212 |
-
"width" => array("g:shipping_width", false),
|
213 |
-
"height" => array("g:shipping_height", false),
|
214 |
-
"shipping_label" => array("g:shipping_label", false),
|
215 |
-
"shipping_country" => array("g:shipping_country", false),
|
216 |
-
"shipping_service" => array("g:shipping_service", false),
|
217 |
-
"shipping_price" => array("g:shipping_price", false),
|
218 |
-
"shipping_region" => array("g:shipping_region", false),
|
219 |
-
"multipack" => array("g:multipack", true),
|
220 |
-
"is_bundle" => array("g:is_bundle", true),
|
221 |
-
"adult" => array("g:adult", true),
|
222 |
-
"adwords_redirect" => array("g:adwords_redirect", true),
|
223 |
-
"custom_label_0" => array("g:custom_label_0", true),
|
224 |
-
"custom_label_1" => array("g:custom_label_1", true),
|
225 |
-
"custom_label_2" => array("g:custom_label_2", true),
|
226 |
-
"custom_label_3" => array("g:custom_label_3", true),
|
227 |
-
"custom_label_4" => array("g:custom_label_4", true),
|
228 |
-
"excluded_destination" => array("g:excluded_destination", true),
|
229 |
-
"included_destination" => array("g:included_destination", true),
|
230 |
-
"expiration_date" => array("g:expiration_date", true),
|
231 |
-
"unit_pricing_measure" => array("g:unit_pricing_measure", true),
|
232 |
-
"unit_pricing_base_measure" => array("g:unit_pricing_base_measure", true),
|
233 |
-
"energy_efficiency_class" => array("g:energy_efficiency_class", true),
|
234 |
-
"loyalty_points" => array("g:loyalty_points", true),
|
235 |
-
"installment" => array("g:installment", true),
|
236 |
-
"promotion_id" => array("g:promotion_id", true),
|
237 |
-
"cost_of_goods_sold" => array("g:cost_of_goods_sold", true),
|
238 |
-
);
|
239 |
-
|
240 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
241 |
-
foreach ($this->products as $no => $product) {
|
242 |
-
$this->identifier_status_add($no);
|
243 |
-
foreach ($product as $key => $value) {
|
244 |
-
$this->mapAttribute($no, $key, $googleXMLAttribute[$key][0], $value, $googleXMLAttribute[$key][0]);
|
245 |
-
}
|
246 |
-
|
247 |
-
$this->process_google_shipping_attribute_for_xml($no);
|
248 |
-
$this->process_google_tax_attribute_for_xml($no);
|
249 |
-
}
|
250 |
-
}
|
251 |
-
}
|
252 |
-
|
253 |
-
/**
|
254 |
-
* Configure merchant attributes for XML feed
|
255 |
-
*/
|
256 |
-
public function mapAttributeForCSVTXT()
|
257 |
-
{
|
258 |
-
//Basic product information
|
259 |
-
$googleCSVTXTAttribute = array(
|
260 |
-
"id" => array("id", false),
|
261 |
-
"title" => array("title", true),
|
262 |
-
"description" => array("description", true),
|
263 |
-
"link" => array("link", true),
|
264 |
-
"mobile_link" => array("mobile_link", true),
|
265 |
-
"product_type" => array("product type", true),
|
266 |
-
"current_category" => array("google product category", true),
|
267 |
-
"image" => array("image link", true),
|
268 |
-
"images" => array("additional image link", true),
|
269 |
-
"images_1" => array("additional image link 1", true),
|
270 |
-
"images_2" => array("additional image link 2", true),
|
271 |
-
"images_3" => array("additional image link 3", true),
|
272 |
-
"images_4" => array("additional image link 4", true),
|
273 |
-
"images_5" => array("additional image link 5", true),
|
274 |
-
"images_6" => array("additional image link 6", true),
|
275 |
-
"images_7" => array("additional image link 7", true),
|
276 |
-
"images_8" => array("additional image link 8", true),
|
277 |
-
"images_9" => array("additional image link 9", true),
|
278 |
-
"images_10" => array("additional image link 10", true),
|
279 |
-
"condition" => array("condition", false),
|
280 |
-
"availability" => array("availability", false),
|
281 |
-
"availability_date" => array("availability date", false),
|
282 |
-
"inventory" => array("inventory", false),
|
283 |
-
"price" => array("price", true),
|
284 |
-
"sale_price" => array("sale price", true),
|
285 |
-
"sale_price_effective_date" => array("sale price effective date", true),
|
286 |
-
"brand" => array("brand", true),
|
287 |
-
"sku" => array("mpn", true),
|
288 |
-
"upc" => array("gtin", true),
|
289 |
-
"identifier_exists" => array("identifier exists", true),
|
290 |
-
"item_group_id" => array("item group id", false),
|
291 |
-
"color" => array("color", true),
|
292 |
-
"gender" => array("gender", true),
|
293 |
-
"age_group" => array("age group", true),
|
294 |
-
"material" => array("material", true),
|
295 |
-
"pattern" => array("pattern", true),
|
296 |
-
"size" => array("size", true),
|
297 |
-
"size_type" => array("size type", true),
|
298 |
-
"size_system" => array("size system", true),
|
299 |
-
"tax" => array("tax", true),
|
300 |
-
"tax_country" => array("tax country", true),
|
301 |
-
"tax_region" => array("tax region", true),
|
302 |
-
"tax_rate" => array("tax rate", true),
|
303 |
-
"tax_ship" => array("tax ship", true),
|
304 |
-
"tax_category" => array("tax category", true),
|
305 |
-
"weight" => array("shipping weight", false),
|
306 |
-
"length" => array("shipping length", false),
|
307 |
-
"width" => array("shipping width", false),
|
308 |
-
"height" => array("shipping height", false),
|
309 |
-
"shipping_label" => array("shipping label", false),
|
310 |
-
"shipping_country" => array("shipping country", false),
|
311 |
-
"shipping_service" => array("shipping service", false),
|
312 |
-
"shipping_price" => array("shipping price", false),
|
313 |
-
"shipping_region" => array("shipping region", false),
|
314 |
-
"multipack" => array("multipack", true),
|
315 |
-
"is_bundle" => array("is bundle", true),
|
316 |
-
"adult" => array("adult", true),
|
317 |
-
"adwords_redirect" => array("adwords redirect", true),
|
318 |
-
"custom_label_0" => array("custom label 0", true),
|
319 |
-
"custom_label_1" => array("custom label 1", true),
|
320 |
-
"custom_label_2" => array("custom label 2", true),
|
321 |
-
"custom_label_3" => array("custom label 3", true),
|
322 |
-
"custom_label_4" => array("custom label 4", true),
|
323 |
-
"excluded_destination" => array("excluded destination", true),
|
324 |
-
"included_destination" => array("included destination", true),
|
325 |
-
"expiration_date" => array("expiration date", true),
|
326 |
-
"unit_pricing_measure" => array("unit pricing measure", true),
|
327 |
-
"unit_pricing_base_measure" => array("unit pricing base measure", true),
|
328 |
-
"energy_efficiency_class" => array("energy efficiency class", true),
|
329 |
-
"loyalty_points" => array("loyalty points", true),
|
330 |
-
"installment" => array("installment", true),
|
331 |
-
"promotion_id" => array("promotion id", true),
|
332 |
-
"cost_of_goods_sold" => array("cost of goods sold", true),
|
333 |
-
);
|
334 |
-
|
335 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
336 |
-
foreach ($this->products as $no => $product) {
|
337 |
-
foreach ($product as $key => $value) {
|
338 |
-
$this->mapAttribute($no, $key, $googleCSVTXTAttribute[$key][0], $value, $googleCSVTXTAttribute[$key][0]);
|
339 |
-
}
|
340 |
-
$this->process_google_shipping_attribute_for_CSVTXT($no);
|
341 |
-
}
|
342 |
-
}
|
343 |
-
}
|
344 |
-
|
345 |
-
/**
|
346 |
-
* Map to google attribute
|
347 |
-
* @param $no
|
348 |
-
* @param $from
|
349 |
-
* @param $to
|
350 |
-
* @param $value
|
351 |
-
* @param bool $cdata
|
352 |
-
* @return array
|
353 |
-
*/
|
354 |
-
public function mapAttribute($no, $from, $to, $value, $cdata = false)
|
355 |
-
{
|
356 |
-
unset($this->products[$no][$from]);
|
357 |
-
if($to=='g:color'){
|
358 |
-
$value=str_replace(",","/",$value);
|
359 |
-
}
|
360 |
-
if ($this->rules['feedType'] == 'xml') {
|
361 |
-
return $this->products[$no][$to] = $this->formatXMLLine($to, $value, $cdata);
|
362 |
-
} else {
|
363 |
-
return $this->products[$no][$to] = $value;
|
364 |
-
}
|
365 |
-
}
|
366 |
-
|
367 |
-
public function identifier_status_add($no)
|
368 |
-
{
|
369 |
-
$identifier = array('brand', 'upc', 'sku', 'mpn', 'gtin');
|
370 |
-
$product = $this->products[$no];
|
371 |
-
|
372 |
-
if(!array_key_exists('g:identifier_exists',$product)) {
|
373 |
-
if (count(array_intersect_key(array_flip($identifier), $product)) >= 2) {
|
374 |
-
# Any 2 required keys exist!
|
375 |
-
$countIdentifier=0;
|
376 |
-
if(array_key_exists('brand',$product) && !empty($product['brand'])){
|
377 |
-
$countIdentifier++;
|
378 |
-
}
|
379 |
-
if(array_key_exists('upc',$product) && !empty($product['upc'])){
|
380 |
-
$countIdentifier++;
|
381 |
-
}
|
382 |
-
if(array_key_exists('sku',$product) && !empty($product['sku'])){
|
383 |
-
$countIdentifier++;
|
384 |
-
}
|
385 |
-
if(array_key_exists('mpn',$product) && !empty($product['mpn'])){
|
386 |
-
$countIdentifier++;
|
387 |
-
}
|
388 |
-
if(array_key_exists('gtin',$product) && !empty($product['gtin'])){
|
389 |
-
$countIdentifier++;
|
390 |
-
}
|
391 |
-
if($countIdentifier>=2){
|
392 |
-
$this->products[$no]["g:identifier_exists"] = $this->formatXMLLine("g:identifier_exists", "yes", $cdata = true);
|
393 |
-
}else{
|
394 |
-
$this->products[$no]["g:identifier_exists"] = $this->formatXMLLine("g:identifier_exists", "no", $cdata = true);
|
395 |
-
}
|
396 |
-
} else {
|
397 |
-
$this->products[$no]["g:identifier_exists"] = $this->formatXMLLine("g:identifier_exists", "no", $cdata = true);
|
398 |
-
}
|
399 |
-
}
|
400 |
-
}
|
401 |
-
|
402 |
-
|
403 |
-
/**
|
404 |
-
* @param $no
|
405 |
-
* @return bool|string
|
406 |
-
*/
|
407 |
-
public
|
408 |
-
function process_google_shipping_attribute_for_xml($no)
|
409 |
-
{
|
410 |
-
$shipping = array('g:shipping_country', 'g:shipping_service', 'g:shipping_price', 'g:shipping_region');
|
411 |
-
$shippingAttr = array();
|
412 |
-
$products = $this->products[$no];
|
413 |
-
foreach ($products as $keyAttr => $valueAttr) {
|
414 |
-
if (in_array($keyAttr, $shipping)) {
|
415 |
-
array_push($shippingAttr, array($keyAttr => $valueAttr));
|
416 |
-
unset($this->products[$no][$keyAttr]);
|
417 |
-
}
|
418 |
-
}
|
419 |
-
if (count($shippingAttr)) {
|
420 |
-
$str = "";
|
421 |
-
foreach ($shippingAttr as $key => $attributes) {
|
422 |
-
foreach ($attributes as $keyAttr => $valueAttr) {
|
423 |
-
$str .= str_replace("shipping_", "", $valueAttr);
|
424 |
-
}
|
425 |
-
}
|
426 |
-
return $this->products[$no]['g:shipping'] = $this->formatXMLLine("g:shipping", $str, false);
|
427 |
-
}
|
428 |
-
return false;
|
429 |
-
}
|
430 |
-
|
431 |
-
public
|
432 |
-
function process_google_tax_attribute_for_xml($no)
|
433 |
-
{
|
434 |
-
$tax = array('g:tax_country', 'g:tax_region', 'g:tax_rate', 'g:tax_ship');
|
435 |
-
$taxAttr = array();
|
436 |
-
$products = $this->products[$no];
|
437 |
-
foreach ($products as $keyAttr => $valueAttr) {
|
438 |
-
if (in_array($keyAttr, $tax)) {
|
439 |
-
array_push($taxAttr, array($keyAttr => $valueAttr));
|
440 |
-
unset($this->products[$no][$keyAttr]);
|
441 |
-
}
|
442 |
-
}
|
443 |
-
if (count($taxAttr)) {
|
444 |
-
$str = "";
|
445 |
-
foreach ($taxAttr as $key => $attributes) {
|
446 |
-
foreach ($attributes as $keyAttr => $valueAttr) {
|
447 |
-
// if($keyAttr != "g:tax_ship")
|
448 |
-
// {
|
449 |
-
$str .= str_replace("tax_", "", $valueAttr);
|
450 |
-
$str = str_replace("ship", "tax_ship", $str);
|
451 |
-
// }
|
452 |
-
// else
|
453 |
-
// {
|
454 |
-
// $str .= $valueAttr;
|
455 |
-
// }
|
456 |
-
}
|
457 |
-
}
|
458 |
-
return $this->products[$no]['g:tax'] = $this->formatXMLLine("g:tax", $str, false);
|
459 |
-
}
|
460 |
-
return false;
|
461 |
-
}
|
462 |
-
|
463 |
-
/**
|
464 |
-
* @param $no
|
465 |
-
* @return bool|mixed
|
466 |
-
*/
|
467 |
-
public
|
468 |
-
function process_google_shipping_attribute_for_CSVTXT($no)
|
469 |
-
{
|
470 |
-
$shipping = array('shipping country', 'shipping service', 'shipping price', 'shipping region');
|
471 |
-
$shippingAttr = array();
|
472 |
-
$products = $this->products[$no];
|
473 |
-
foreach ($products as $keyAttr => $valueAttr) {
|
474 |
-
if (in_array($keyAttr, $shipping)) {
|
475 |
-
array_push($shippingAttr, array($keyAttr => $valueAttr));
|
476 |
-
unset($this->products[$no][$keyAttr]);
|
477 |
-
}
|
478 |
-
}
|
479 |
-
if (count($shippingAttr)) {
|
480 |
-
$str = "";
|
481 |
-
foreach ($shippingAttr as $key => $attributes) {
|
482 |
-
foreach ($attributes as $keyAttr => $valueAttr) {
|
483 |
-
$country = ($keyAttr == "shipping country") ? $str .= $valueAttr . ":" : "";
|
484 |
-
$service = ($keyAttr == "shipping service") ? $str .= $valueAttr . ":" : "";
|
485 |
-
$price = ($keyAttr == "shipping price") ? $str .= $valueAttr : "";
|
486 |
-
$region = ($keyAttr == "shipping region") ? $str .= $valueAttr . ":" : "";
|
487 |
-
}
|
488 |
-
}
|
489 |
-
return $this->products[$no]['shipping(country:region:service:price)'] = str_replace(" : ",":", $str);
|
490 |
-
}
|
491 |
-
return false;
|
492 |
-
}
|
493 |
-
|
494 |
-
public
|
495 |
-
function process_google_tax_attribute_for_CSVTXT($no)
|
496 |
-
{
|
497 |
-
$tax = array('tax country', 'tax region', 'tax rate', 'tax ship');
|
498 |
-
$taxAttr = array();
|
499 |
-
$products = $this->products[$no];
|
500 |
-
foreach ($products as $keyAttr => $valueAttr) {
|
501 |
-
if (in_array($keyAttr, $tax)) {
|
502 |
-
array_push($taxAttr, array($keyAttr => $valueAttr));
|
503 |
-
unset($this->products[$no][$keyAttr]);
|
504 |
-
}
|
505 |
-
}
|
506 |
-
if (count($taxAttr)) {
|
507 |
-
$str = "";
|
508 |
-
foreach ($taxAttr as $key => $attributes) {
|
509 |
-
foreach ($attributes as $keyAttr => $valueAttr) {
|
510 |
-
$country = ($keyAttr == "tax country") ? $str .= $valueAttr . ":" : "";
|
511 |
-
$region = ($keyAttr == "tax region") ? $str .= $valueAttr . ":" : "";
|
512 |
-
$rate = ($keyAttr == "tax rate") ? $str .= $valueAttr . ":": "";
|
513 |
-
$ship = ($keyAttr == "tax ship") ? $str .= $valueAttr . ":" : "";
|
514 |
-
}
|
515 |
-
}
|
516 |
-
return $this->products[$no]['tax(country:region:rate:tax_ship)'] = str_replace(" : ",":", $str);
|
517 |
-
}
|
518 |
-
return false;
|
519 |
-
}
|
520 |
-
|
521 |
-
function formatXMLLine($attribute, $value, $cdata, $space = "")
|
522 |
-
{
|
523 |
-
//Make single XML node
|
524 |
-
if (!empty($value))
|
525 |
-
$value = trim($value);
|
526 |
-
if (gettype($value) == 'array')
|
527 |
-
$value = json_encode($value);
|
528 |
-
if (strpos($value, "<![CDATA[") === false && substr(trim($value), 0, 4) == "http") {
|
529 |
-
$value = "<![CDATA[$value]]>";
|
530 |
-
} elseif (strpos($value, "<![CDATA[") === false && $cdata === true && !empty($value)) {
|
531 |
-
$value = "<![CDATA[$value]]>";
|
532 |
-
} else if ($cdata) {
|
533 |
-
if(!empty($value)){
|
534 |
-
$value = "<![CDATA[$value]]>";
|
535 |
-
}
|
536 |
-
}
|
537 |
-
|
538 |
-
if (substr($attribute, 0, 23) == 'g:additional_image_link') {
|
539 |
-
$attribute = "g:additional_image_link";
|
540 |
-
}
|
541 |
-
|
542 |
-
return "
|
543 |
-
$space<$attribute>$value</$attribute>";
|
544 |
-
}
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
public function get_xml_feed_header()
|
549 |
-
{
|
550 |
-
$output = '<?xml version="1.0" encoding="UTF-8" ?>
|
551 |
-
<rss version="2.0" xmlns:g="http://base.google.com/ns/1.0" xmlns:c="http://base.google.com/cns/1.0">
|
552 |
-
<channel>
|
553 |
-
<title><![CDATA[' . html_entity_decode(get_option('blogname')) . ']]></title>
|
554 |
-
<link><![CDATA['.home_url().']]></link>
|
555 |
-
<description><![CDATA['.html_entity_decode(get_option('blogdescription')).']]></description>';
|
556 |
-
return $output;
|
557 |
-
}
|
558 |
-
|
559 |
-
public function get_xml_feed($items)
|
560 |
-
{
|
561 |
-
$feed = "";
|
562 |
-
//$feed .= $this->get_feed_header();
|
563 |
-
$feed .= "\n";
|
564 |
-
if ($items) {
|
565 |
-
foreach ($items as $item => $products) {
|
566 |
-
$feed .= " <" . $this->feedWrapper . ">";
|
567 |
-
|
568 |
-
foreach ($products as $key => $value) {
|
569 |
-
if (!empty($value)){
|
570 |
-
$feed .= $value;
|
571 |
-
}
|
572 |
-
}
|
573 |
-
$feed .= "\n </" . $this->feedWrapper . ">\n";
|
574 |
-
}
|
575 |
-
//$feed .= $this->get_feed_footer();
|
576 |
-
|
577 |
-
return $feed;
|
578 |
-
}
|
579 |
-
return false;
|
580 |
-
}
|
581 |
-
|
582 |
-
public function get_xml_feed_footer()
|
583 |
-
{
|
584 |
-
$footer = " </channel>
|
585 |
-
</rss>";
|
586 |
-
return $footer;
|
587 |
-
}
|
588 |
-
|
589 |
-
public function short_products()
|
590 |
-
{
|
591 |
-
if ($this->products) {
|
592 |
-
update_option('wpf_progress', "Shorting Products");
|
593 |
-
sleep(1);
|
594 |
-
$array = array();
|
595 |
-
$ij = 0;
|
596 |
-
foreach ($this->products as $key => $item) {
|
597 |
-
$array[$ij] = $item;
|
598 |
-
unset($this->products[$key]);
|
599 |
-
$ij++;
|
600 |
-
}
|
601 |
-
return $this->products = $array;
|
602 |
-
}
|
603 |
-
return $this->products;
|
604 |
-
}
|
605 |
-
|
606 |
-
/**
|
607 |
-
* Responsible to make CSV feed
|
608 |
-
* @return string
|
609 |
-
*/
|
610 |
-
public function get_csv_feed()
|
611 |
-
{
|
612 |
-
if ($this->products) {
|
613 |
-
$headers = array_keys($this->products[0]);
|
614 |
-
$feed[] = $headers;
|
615 |
-
foreach ($this->products as $no => $product) {
|
616 |
-
$row = array();
|
617 |
-
foreach ($headers as $key => $header) {
|
618 |
-
if (strpos($header, "additional image link") !== false) {
|
619 |
-
$header = "additional image link";
|
620 |
-
}
|
621 |
-
$row[] = isset($product[$header]) ? $product[$header] : "";;
|
622 |
-
}
|
623 |
-
$feed[] = $row;
|
624 |
-
}
|
625 |
-
return $feed;
|
626 |
-
}
|
627 |
-
return false;
|
628 |
-
}
|
629 |
-
|
630 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Google
|
5 |
+
*
|
6 |
+
* Responsible for processing and generating feed for Google.com
|
7 |
+
*
|
8 |
+
* @since 1.0.0
|
9 |
+
* @package Google
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Woo_Feed_Google
|
13 |
+
{
|
14 |
+
|
15 |
+
/**
|
16 |
+
* This variable is responsible for holding all product attributes and their values
|
17 |
+
*
|
18 |
+
* @since 1.0.0
|
19 |
+
* @var array $products Contains all the product attributes to generate feed
|
20 |
+
* @access public
|
21 |
+
*/
|
22 |
+
public $products;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* This variable is responsible for holding feed configuration form values
|
26 |
+
*
|
27 |
+
* @since 1.0.0
|
28 |
+
* @var array $rules Contains feed configuration form values
|
29 |
+
* @access public
|
30 |
+
*/
|
31 |
+
public $rules;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* This variable is responsible for mapping store attributes to merchant attribute
|
35 |
+
*
|
36 |
+
* @since 1.0.0
|
37 |
+
* @var array $mapping Map store attributes to merchant attribute
|
38 |
+
* @access public
|
39 |
+
*/
|
40 |
+
public $mapping;
|
41 |
+
|
42 |
+
/**
|
43 |
+
* This variable is responsible for generate error logs
|
44 |
+
*
|
45 |
+
* @since 1.0.0
|
46 |
+
* @var array $errors hold error logs
|
47 |
+
* @access public
|
48 |
+
*/
|
49 |
+
public $errors;
|
50 |
+
|
51 |
+
/**
|
52 |
+
* This variable is responsible for generate error logs
|
53 |
+
*
|
54 |
+
* @since 1.0.0
|
55 |
+
* @var array $warnings hold warnings logs
|
56 |
+
* @access public
|
57 |
+
*/
|
58 |
+
public $warnings;
|
59 |
+
|
60 |
+
/**
|
61 |
+
* This variable is responsible for making error number
|
62 |
+
*
|
63 |
+
* @since 1.0.0
|
64 |
+
* @var int $errorCounter Generate error number
|
65 |
+
* @access public
|
66 |
+
*/
|
67 |
+
public $errorCounter;
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Feed Wrapper text for enclosing each product information
|
71 |
+
*
|
72 |
+
* @since 1.0.0
|
73 |
+
* @var string $feedWrapper Feed Wrapper text
|
74 |
+
* @access public
|
75 |
+
*/
|
76 |
+
public $feedWrapper = 'item';
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Store product information
|
80 |
+
*
|
81 |
+
* @since 1.0.0
|
82 |
+
* @var array $storeProducts
|
83 |
+
* @access public
|
84 |
+
*/
|
85 |
+
private $storeProducts;
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Define the core functionality to generate feed.
|
89 |
+
*
|
90 |
+
* Set the feed rules. Map products according to the rules and Check required attributes
|
91 |
+
* and their values according to merchant specification.
|
92 |
+
* @var Woo_Generate_Feed $feedRule Contain Feed Configuration
|
93 |
+
* @since 1.0.0
|
94 |
+
*/
|
95 |
+
public function __construct($feedRule)
|
96 |
+
{
|
97 |
+
$products = new Woo_Feed_Products();
|
98 |
+
$storeProducts = $products->woo_feed_get_visible_product($feedRule);
|
99 |
+
if(!empty($storeProducts)){
|
100 |
+
$engine = new WF_Engine($storeProducts, $feedRule);
|
101 |
+
$this->products = $engine->mapProductsByRules();
|
102 |
+
$this->rules = $feedRule;
|
103 |
+
if ($feedRule['feedType'] == 'xml') {
|
104 |
+
$this->mapAttributeForXML();
|
105 |
+
} else {
|
106 |
+
$this->mapAttributeForCSVTXT();
|
107 |
+
}
|
108 |
+
}else{
|
109 |
+
$this->products=array();
|
110 |
+
}
|
111 |
+
|
112 |
+
}
|
113 |
+
|
114 |
+
|
115 |
+
/**
|
116 |
+
* Return Feed
|
117 |
+
* @return array
|
118 |
+
*/
|
119 |
+
public function returnFinalProduct()
|
120 |
+
{
|
121 |
+
if(!empty($this->products)){
|
122 |
+
$engine = new WF_Engine($this->products, $this->rules);
|
123 |
+
if ($this->rules['feedType'] == 'xml') {
|
124 |
+
//return $this->get_feed($this->products);
|
125 |
+
$feed=array(
|
126 |
+
"header"=>$this->get_xml_feed_header(),
|
127 |
+
"body"=>$this->get_xml_feed($this->products),
|
128 |
+
"footer"=>$this->get_xml_feed_footer(),
|
129 |
+
);
|
130 |
+
return $feed;
|
131 |
+
} elseif ($this->rules['feedType'] == 'txt') {
|
132 |
+
//return $engine->get_txt_feed();
|
133 |
+
$feed=array(
|
134 |
+
"body"=>$engine->get_txt_feed(),
|
135 |
+
"header"=>$engine->txtFeedHeader,
|
136 |
+
"footer"=>"",
|
137 |
+
);
|
138 |
+
return $feed;
|
139 |
+
} elseif ($this->rules['feedType'] == 'csv') {
|
140 |
+
//return $engine->get_csv_feed();
|
141 |
+
$feed=array(
|
142 |
+
"body"=>$engine->get_csv_feed(),
|
143 |
+
"header"=>$engine->csvFeedHeader,
|
144 |
+
"footer"=>"",
|
145 |
+
);
|
146 |
+
return $feed;
|
147 |
+
}
|
148 |
+
}
|
149 |
+
|
150 |
+
$feed=array(
|
151 |
+
"body"=>"",
|
152 |
+
"header"=>"",
|
153 |
+
"footer"=>"",
|
154 |
+
);
|
155 |
+
return $feed;
|
156 |
+
}
|
157 |
+
|
158 |
+
/**
|
159 |
+
* Configure merchant attributes for XML feed
|
160 |
+
*/
|
161 |
+
public function mapAttributeForXML()
|
162 |
+
{
|
163 |
+
|
164 |
+
$googleXMLAttribute = array(
|
165 |
+
"id" => array("g:id", false),
|
166 |
+
"title" => array("title", true),
|
167 |
+
"description" => array("description", true),
|
168 |
+
"link" => array("link", true),
|
169 |
+
"mobile_link" => array("mobile_link", true),
|
170 |
+
"product_type" => array("g:product_type", true),
|
171 |
+
"current_category" => array("g:google_product_category", true),
|
172 |
+
"image" => array("g:image_link", true),
|
173 |
+
"images" => array("g:additional_image_link", false),
|
174 |
+
"images_1" => array("g:additional_image_link_1", true),
|
175 |
+
"images_2" => array("g:additional_image_link_2", true),
|
176 |
+
"images_3" => array("g:additional_image_link_3", true),
|
177 |
+
"images_4" => array("g:additional_image_link_4", true),
|
178 |
+
"images_5" => array("g:additional_image_link_5", true),
|
179 |
+
"images_6" => array("g:additional_image_link_6", true),
|
180 |
+
"images_7" => array("g:additional_image_link_7", true),
|
181 |
+
"images_8" => array("g:additional_image_link_8", true),
|
182 |
+
"images_9" => array("g:additional_image_link_9", true),
|
183 |
+
"images_10" => array("g:additional_image_link_10", true),
|
184 |
+
"condition" => array("g:condition", false),
|
185 |
+
"availability" => array("g:availability", false),
|
186 |
+
"availability_date" => array("g:availability_date", false),
|
187 |
+
"inventory" => array("g:inventory", false),
|
188 |
+
"price" => array("g:price", true),
|
189 |
+
"sale_price" => array("g:sale_price", true),
|
190 |
+
"sale_price_effective_date" => array("g:sale_price_effective_date", true),
|
191 |
+
"brand" => array("g:brand", true),
|
192 |
+
"sku" => array("g:mpn", true),
|
193 |
+
"upc" => array("g:gtin", true),
|
194 |
+
"identifier_exists" => array("g:identifier_exists", true),
|
195 |
+
"item_group_id" => array("g:item_group_id", false),
|
196 |
+
"color" => array("g:color", true),
|
197 |
+
"gender" => array("g:gender", true),
|
198 |
+
"age_group" => array("g:age_group", true),
|
199 |
+
"material" => array("g:material", true),
|
200 |
+
"pattern" => array("g:pattern", true),
|
201 |
+
"size" => array("g:size", true),
|
202 |
+
"size_type" => array("g:size_type", true),
|
203 |
+
"size_system" => array("g:size_system", true),
|
204 |
+
"tax" => array("tax", true),
|
205 |
+
"tax_country" => array("g:tax_country", true),
|
206 |
+
"tax_region" => array("g:tax_region", true),
|
207 |
+
"tax_rate" => array("g:tax_rate", true),
|
208 |
+
"tax_ship" => array("g:tax_ship", true),
|
209 |
+
"tax_category" => array("g:tax_category", true),
|
210 |
+
"weight" => array("g:shipping_weight", false),
|
211 |
+
"length" => array("g:shipping_length", false),
|
212 |
+
"width" => array("g:shipping_width", false),
|
213 |
+
"height" => array("g:shipping_height", false),
|
214 |
+
"shipping_label" => array("g:shipping_label", false),
|
215 |
+
"shipping_country" => array("g:shipping_country", false),
|
216 |
+
"shipping_service" => array("g:shipping_service", false),
|
217 |
+
"shipping_price" => array("g:shipping_price", false),
|
218 |
+
"shipping_region" => array("g:shipping_region", false),
|
219 |
+
"multipack" => array("g:multipack", true),
|
220 |
+
"is_bundle" => array("g:is_bundle", true),
|
221 |
+
"adult" => array("g:adult", true),
|
222 |
+
"adwords_redirect" => array("g:adwords_redirect", true),
|
223 |
+
"custom_label_0" => array("g:custom_label_0", true),
|
224 |
+
"custom_label_1" => array("g:custom_label_1", true),
|
225 |
+
"custom_label_2" => array("g:custom_label_2", true),
|
226 |
+
"custom_label_3" => array("g:custom_label_3", true),
|
227 |
+
"custom_label_4" => array("g:custom_label_4", true),
|
228 |
+
"excluded_destination" => array("g:excluded_destination", true),
|
229 |
+
"included_destination" => array("g:included_destination", true),
|
230 |
+
"expiration_date" => array("g:expiration_date", true),
|
231 |
+
"unit_pricing_measure" => array("g:unit_pricing_measure", true),
|
232 |
+
"unit_pricing_base_measure" => array("g:unit_pricing_base_measure", true),
|
233 |
+
"energy_efficiency_class" => array("g:energy_efficiency_class", true),
|
234 |
+
"loyalty_points" => array("g:loyalty_points", true),
|
235 |
+
"installment" => array("g:installment", true),
|
236 |
+
"promotion_id" => array("g:promotion_id", true),
|
237 |
+
"cost_of_goods_sold" => array("g:cost_of_goods_sold", true),
|
238 |
+
);
|
239 |
+
|
240 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
241 |
+
foreach ($this->products as $no => $product) {
|
242 |
+
$this->identifier_status_add($no);
|
243 |
+
foreach ($product as $key => $value) {
|
244 |
+
$this->mapAttribute($no, $key, $googleXMLAttribute[$key][0], $value, $googleXMLAttribute[$key][0]);
|
245 |
+
}
|
246 |
+
|
247 |
+
$this->process_google_shipping_attribute_for_xml($no);
|
248 |
+
$this->process_google_tax_attribute_for_xml($no);
|
249 |
+
}
|
250 |
+
}
|
251 |
+
}
|
252 |
+
|
253 |
+
/**
|
254 |
+
* Configure merchant attributes for XML feed
|
255 |
+
*/
|
256 |
+
public function mapAttributeForCSVTXT()
|
257 |
+
{
|
258 |
+
//Basic product information
|
259 |
+
$googleCSVTXTAttribute = array(
|
260 |
+
"id" => array("id", false),
|
261 |
+
"title" => array("title", true),
|
262 |
+
"description" => array("description", true),
|
263 |
+
"link" => array("link", true),
|
264 |
+
"mobile_link" => array("mobile_link", true),
|
265 |
+
"product_type" => array("product type", true),
|
266 |
+
"current_category" => array("google product category", true),
|
267 |
+
"image" => array("image link", true),
|
268 |
+
"images" => array("additional image link", true),
|
269 |
+
"images_1" => array("additional image link 1", true),
|
270 |
+
"images_2" => array("additional image link 2", true),
|
271 |
+
"images_3" => array("additional image link 3", true),
|
272 |
+
"images_4" => array("additional image link 4", true),
|
273 |
+
"images_5" => array("additional image link 5", true),
|
274 |
+
"images_6" => array("additional image link 6", true),
|
275 |
+
"images_7" => array("additional image link 7", true),
|
276 |
+
"images_8" => array("additional image link 8", true),
|
277 |
+
"images_9" => array("additional image link 9", true),
|
278 |
+
"images_10" => array("additional image link 10", true),
|
279 |
+
"condition" => array("condition", false),
|
280 |
+
"availability" => array("availability", false),
|
281 |
+
"availability_date" => array("availability date", false),
|
282 |
+
"inventory" => array("inventory", false),
|
283 |
+
"price" => array("price", true),
|
284 |
+
"sale_price" => array("sale price", true),
|
285 |
+
"sale_price_effective_date" => array("sale price effective date", true),
|
286 |
+
"brand" => array("brand", true),
|
287 |
+
"sku" => array("mpn", true),
|
288 |
+
"upc" => array("gtin", true),
|
289 |
+
"identifier_exists" => array("identifier exists", true),
|
290 |
+
"item_group_id" => array("item group id", false),
|
291 |
+
"color" => array("color", true),
|
292 |
+
"gender" => array("gender", true),
|
293 |
+
"age_group" => array("age group", true),
|
294 |
+
"material" => array("material", true),
|
295 |
+
"pattern" => array("pattern", true),
|
296 |
+
"size" => array("size", true),
|
297 |
+
"size_type" => array("size type", true),
|
298 |
+
"size_system" => array("size system", true),
|
299 |
+
"tax" => array("tax", true),
|
300 |
+
"tax_country" => array("tax country", true),
|
301 |
+
"tax_region" => array("tax region", true),
|
302 |
+
"tax_rate" => array("tax rate", true),
|
303 |
+
"tax_ship" => array("tax ship", true),
|
304 |
+
"tax_category" => array("tax category", true),
|
305 |
+
"weight" => array("shipping weight", false),
|
306 |
+
"length" => array("shipping length", false),
|
307 |
+
"width" => array("shipping width", false),
|
308 |
+
"height" => array("shipping height", false),
|
309 |
+
"shipping_label" => array("shipping label", false),
|
310 |
+
"shipping_country" => array("shipping country", false),
|
311 |
+
"shipping_service" => array("shipping service", false),
|
312 |
+
"shipping_price" => array("shipping price", false),
|
313 |
+
"shipping_region" => array("shipping region", false),
|
314 |
+
"multipack" => array("multipack", true),
|
315 |
+
"is_bundle" => array("is bundle", true),
|
316 |
+
"adult" => array("adult", true),
|
317 |
+
"adwords_redirect" => array("adwords redirect", true),
|
318 |
+
"custom_label_0" => array("custom label 0", true),
|
319 |
+
"custom_label_1" => array("custom label 1", true),
|
320 |
+
"custom_label_2" => array("custom label 2", true),
|
321 |
+
"custom_label_3" => array("custom label 3", true),
|
322 |
+
"custom_label_4" => array("custom label 4", true),
|
323 |
+
"excluded_destination" => array("excluded destination", true),
|
324 |
+
"included_destination" => array("included destination", true),
|
325 |
+
"expiration_date" => array("expiration date", true),
|
326 |
+
"unit_pricing_measure" => array("unit pricing measure", true),
|
327 |
+
"unit_pricing_base_measure" => array("unit pricing base measure", true),
|
328 |
+
"energy_efficiency_class" => array("energy efficiency class", true),
|
329 |
+
"loyalty_points" => array("loyalty points", true),
|
330 |
+
"installment" => array("installment", true),
|
331 |
+
"promotion_id" => array("promotion id", true),
|
332 |
+
"cost_of_goods_sold" => array("cost of goods sold", true),
|
333 |
+
);
|
334 |
+
|
335 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
336 |
+
foreach ($this->products as $no => $product) {
|
337 |
+
foreach ($product as $key => $value) {
|
338 |
+
$this->mapAttribute($no, $key, $googleCSVTXTAttribute[$key][0], $value, $googleCSVTXTAttribute[$key][0]);
|
339 |
+
}
|
340 |
+
$this->process_google_shipping_attribute_for_CSVTXT($no);
|
341 |
+
}
|
342 |
+
}
|
343 |
+
}
|
344 |
+
|
345 |
+
/**
|
346 |
+
* Map to google attribute
|
347 |
+
* @param $no
|
348 |
+
* @param $from
|
349 |
+
* @param $to
|
350 |
+
* @param $value
|
351 |
+
* @param bool $cdata
|
352 |
+
* @return array
|
353 |
+
*/
|
354 |
+
public function mapAttribute($no, $from, $to, $value, $cdata = false)
|
355 |
+
{
|
356 |
+
unset($this->products[$no][$from]);
|
357 |
+
if($to=='g:color'){
|
358 |
+
$value=str_replace(",","/",$value);
|
359 |
+
}
|
360 |
+
if ($this->rules['feedType'] == 'xml') {
|
361 |
+
return $this->products[$no][$to] = $this->formatXMLLine($to, $value, $cdata);
|
362 |
+
} else {
|
363 |
+
return $this->products[$no][$to] = $value;
|
364 |
+
}
|
365 |
+
}
|
366 |
+
|
367 |
+
public function identifier_status_add($no)
|
368 |
+
{
|
369 |
+
$identifier = array('brand', 'upc', 'sku', 'mpn', 'gtin');
|
370 |
+
$product = $this->products[$no];
|
371 |
+
|
372 |
+
if(!array_key_exists('g:identifier_exists',$product)) {
|
373 |
+
if (count(array_intersect_key(array_flip($identifier), $product)) >= 2) {
|
374 |
+
# Any 2 required keys exist!
|
375 |
+
$countIdentifier=0;
|
376 |
+
if(array_key_exists('brand',$product) && !empty($product['brand'])){
|
377 |
+
$countIdentifier++;
|
378 |
+
}
|
379 |
+
if(array_key_exists('upc',$product) && !empty($product['upc'])){
|
380 |
+
$countIdentifier++;
|
381 |
+
}
|
382 |
+
if(array_key_exists('sku',$product) && !empty($product['sku'])){
|
383 |
+
$countIdentifier++;
|
384 |
+
}
|
385 |
+
if(array_key_exists('mpn',$product) && !empty($product['mpn'])){
|
386 |
+
$countIdentifier++;
|
387 |
+
}
|
388 |
+
if(array_key_exists('gtin',$product) && !empty($product['gtin'])){
|
389 |
+
$countIdentifier++;
|
390 |
+
}
|
391 |
+
if($countIdentifier>=2){
|
392 |
+
$this->products[$no]["g:identifier_exists"] = $this->formatXMLLine("g:identifier_exists", "yes", $cdata = true);
|
393 |
+
}else{
|
394 |
+
$this->products[$no]["g:identifier_exists"] = $this->formatXMLLine("g:identifier_exists", "no", $cdata = true);
|
395 |
+
}
|
396 |
+
} else {
|
397 |
+
$this->products[$no]["g:identifier_exists"] = $this->formatXMLLine("g:identifier_exists", "no", $cdata = true);
|
398 |
+
}
|
399 |
+
}
|
400 |
+
}
|
401 |
+
|
402 |
+
|
403 |
+
/**
|
404 |
+
* @param $no
|
405 |
+
* @return bool|string
|
406 |
+
*/
|
407 |
+
public
|
408 |
+
function process_google_shipping_attribute_for_xml($no)
|
409 |
+
{
|
410 |
+
$shipping = array('g:shipping_country', 'g:shipping_service', 'g:shipping_price', 'g:shipping_region');
|
411 |
+
$shippingAttr = array();
|
412 |
+
$products = $this->products[$no];
|
413 |
+
foreach ($products as $keyAttr => $valueAttr) {
|
414 |
+
if (in_array($keyAttr, $shipping)) {
|
415 |
+
array_push($shippingAttr, array($keyAttr => $valueAttr));
|
416 |
+
unset($this->products[$no][$keyAttr]);
|
417 |
+
}
|
418 |
+
}
|
419 |
+
if (count($shippingAttr)) {
|
420 |
+
$str = "";
|
421 |
+
foreach ($shippingAttr as $key => $attributes) {
|
422 |
+
foreach ($attributes as $keyAttr => $valueAttr) {
|
423 |
+
$str .= str_replace("shipping_", "", $valueAttr);
|
424 |
+
}
|
425 |
+
}
|
426 |
+
return $this->products[$no]['g:shipping'] = $this->formatXMLLine("g:shipping", $str, false);
|
427 |
+
}
|
428 |
+
return false;
|
429 |
+
}
|
430 |
+
|
431 |
+
public
|
432 |
+
function process_google_tax_attribute_for_xml($no)
|
433 |
+
{
|
434 |
+
$tax = array('g:tax_country', 'g:tax_region', 'g:tax_rate', 'g:tax_ship');
|
435 |
+
$taxAttr = array();
|
436 |
+
$products = $this->products[$no];
|
437 |
+
foreach ($products as $keyAttr => $valueAttr) {
|
438 |
+
if (in_array($keyAttr, $tax)) {
|
439 |
+
array_push($taxAttr, array($keyAttr => $valueAttr));
|
440 |
+
unset($this->products[$no][$keyAttr]);
|
441 |
+
}
|
442 |
+
}
|
443 |
+
if (count($taxAttr)) {
|
444 |
+
$str = "";
|
445 |
+
foreach ($taxAttr as $key => $attributes) {
|
446 |
+
foreach ($attributes as $keyAttr => $valueAttr) {
|
447 |
+
// if($keyAttr != "g:tax_ship")
|
448 |
+
// {
|
449 |
+
$str .= str_replace("tax_", "", $valueAttr);
|
450 |
+
$str = str_replace("ship", "tax_ship", $str);
|
451 |
+
// }
|
452 |
+
// else
|
453 |
+
// {
|
454 |
+
// $str .= $valueAttr;
|
455 |
+
// }
|
456 |
+
}
|
457 |
+
}
|
458 |
+
return $this->products[$no]['g:tax'] = $this->formatXMLLine("g:tax", $str, false);
|
459 |
+
}
|
460 |
+
return false;
|
461 |
+
}
|
462 |
+
|
463 |
+
/**
|
464 |
+
* @param $no
|
465 |
+
* @return bool|mixed
|
466 |
+
*/
|
467 |
+
public
|
468 |
+
function process_google_shipping_attribute_for_CSVTXT($no)
|
469 |
+
{
|
470 |
+
$shipping = array('shipping country', 'shipping service', 'shipping price', 'shipping region');
|
471 |
+
$shippingAttr = array();
|
472 |
+
$products = $this->products[$no];
|
473 |
+
foreach ($products as $keyAttr => $valueAttr) {
|
474 |
+
if (in_array($keyAttr, $shipping)) {
|
475 |
+
array_push($shippingAttr, array($keyAttr => $valueAttr));
|
476 |
+
unset($this->products[$no][$keyAttr]);
|
477 |
+
}
|
478 |
+
}
|
479 |
+
if (count($shippingAttr)) {
|
480 |
+
$str = "";
|
481 |
+
foreach ($shippingAttr as $key => $attributes) {
|
482 |
+
foreach ($attributes as $keyAttr => $valueAttr) {
|
483 |
+
$country = ($keyAttr == "shipping country") ? $str .= $valueAttr . ":" : "";
|
484 |
+
$service = ($keyAttr == "shipping service") ? $str .= $valueAttr . ":" : "";
|
485 |
+
$price = ($keyAttr == "shipping price") ? $str .= $valueAttr : "";
|
486 |
+
$region = ($keyAttr == "shipping region") ? $str .= $valueAttr . ":" : "";
|
487 |
+
}
|
488 |
+
}
|
489 |
+
return $this->products[$no]['shipping(country:region:service:price)'] = str_replace(" : ",":", $str);
|
490 |
+
}
|
491 |
+
return false;
|
492 |
+
}
|
493 |
+
|
494 |
+
public
|
495 |
+
function process_google_tax_attribute_for_CSVTXT($no)
|
496 |
+
{
|
497 |
+
$tax = array('tax country', 'tax region', 'tax rate', 'tax ship');
|
498 |
+
$taxAttr = array();
|
499 |
+
$products = $this->products[$no];
|
500 |
+
foreach ($products as $keyAttr => $valueAttr) {
|
501 |
+
if (in_array($keyAttr, $tax)) {
|
502 |
+
array_push($taxAttr, array($keyAttr => $valueAttr));
|
503 |
+
unset($this->products[$no][$keyAttr]);
|
504 |
+
}
|
505 |
+
}
|
506 |
+
if (count($taxAttr)) {
|
507 |
+
$str = "";
|
508 |
+
foreach ($taxAttr as $key => $attributes) {
|
509 |
+
foreach ($attributes as $keyAttr => $valueAttr) {
|
510 |
+
$country = ($keyAttr == "tax country") ? $str .= $valueAttr . ":" : "";
|
511 |
+
$region = ($keyAttr == "tax region") ? $str .= $valueAttr . ":" : "";
|
512 |
+
$rate = ($keyAttr == "tax rate") ? $str .= $valueAttr . ":": "";
|
513 |
+
$ship = ($keyAttr == "tax ship") ? $str .= $valueAttr . ":" : "";
|
514 |
+
}
|
515 |
+
}
|
516 |
+
return $this->products[$no]['tax(country:region:rate:tax_ship)'] = str_replace(" : ",":", $str);
|
517 |
+
}
|
518 |
+
return false;
|
519 |
+
}
|
520 |
+
|
521 |
+
function formatXMLLine($attribute, $value, $cdata, $space = "")
|
522 |
+
{
|
523 |
+
//Make single XML node
|
524 |
+
if (!empty($value))
|
525 |
+
$value = trim($value);
|
526 |
+
if (gettype($value) == 'array')
|
527 |
+
$value = json_encode($value);
|
528 |
+
if (strpos($value, "<![CDATA[") === false && substr(trim($value), 0, 4) == "http") {
|
529 |
+
$value = "<![CDATA[$value]]>";
|
530 |
+
} elseif (strpos($value, "<![CDATA[") === false && $cdata === true && !empty($value)) {
|
531 |
+
$value = "<![CDATA[$value]]>";
|
532 |
+
} else if ($cdata) {
|
533 |
+
if(!empty($value)){
|
534 |
+
$value = "<![CDATA[$value]]>";
|
535 |
+
}
|
536 |
+
}
|
537 |
+
|
538 |
+
if (substr($attribute, 0, 23) == 'g:additional_image_link') {
|
539 |
+
$attribute = "g:additional_image_link";
|
540 |
+
}
|
541 |
+
|
542 |
+
return "
|
543 |
+
$space<$attribute>$value</$attribute>";
|
544 |
+
}
|
545 |
+
|
546 |
+
|
547 |
+
|
548 |
+
public function get_xml_feed_header()
|
549 |
+
{
|
550 |
+
$output = '<?xml version="1.0" encoding="UTF-8" ?>
|
551 |
+
<rss version="2.0" xmlns:g="http://base.google.com/ns/1.0" xmlns:c="http://base.google.com/cns/1.0">
|
552 |
+
<channel>
|
553 |
+
<title><![CDATA[' . html_entity_decode(get_option('blogname')) . ']]></title>
|
554 |
+
<link><![CDATA['.home_url().']]></link>
|
555 |
+
<description><![CDATA['.html_entity_decode(get_option('blogdescription')).']]></description>';
|
556 |
+
return $output;
|
557 |
+
}
|
558 |
+
|
559 |
+
public function get_xml_feed($items)
|
560 |
+
{
|
561 |
+
$feed = "";
|
562 |
+
//$feed .= $this->get_feed_header();
|
563 |
+
$feed .= "\n";
|
564 |
+
if ($items) {
|
565 |
+
foreach ($items as $item => $products) {
|
566 |
+
$feed .= " <" . $this->feedWrapper . ">";
|
567 |
+
|
568 |
+
foreach ($products as $key => $value) {
|
569 |
+
if (!empty($value)){
|
570 |
+
$feed .= $value;
|
571 |
+
}
|
572 |
+
}
|
573 |
+
$feed .= "\n </" . $this->feedWrapper . ">\n";
|
574 |
+
}
|
575 |
+
//$feed .= $this->get_feed_footer();
|
576 |
+
|
577 |
+
return $feed;
|
578 |
+
}
|
579 |
+
return false;
|
580 |
+
}
|
581 |
+
|
582 |
+
public function get_xml_feed_footer()
|
583 |
+
{
|
584 |
+
$footer = " </channel>
|
585 |
+
</rss>";
|
586 |
+
return $footer;
|
587 |
+
}
|
588 |
+
|
589 |
+
public function short_products()
|
590 |
+
{
|
591 |
+
if ($this->products) {
|
592 |
+
update_option('wpf_progress', "Shorting Products");
|
593 |
+
sleep(1);
|
594 |
+
$array = array();
|
595 |
+
$ij = 0;
|
596 |
+
foreach ($this->products as $key => $item) {
|
597 |
+
$array[$ij] = $item;
|
598 |
+
unset($this->products[$key]);
|
599 |
+
$ij++;
|
600 |
+
}
|
601 |
+
return $this->products = $array;
|
602 |
+
}
|
603 |
+
return $this->products;
|
604 |
+
}
|
605 |
+
|
606 |
+
/**
|
607 |
+
* Responsible to make CSV feed
|
608 |
+
* @return string
|
609 |
+
*/
|
610 |
+
public function get_csv_feed()
|
611 |
+
{
|
612 |
+
if ($this->products) {
|
613 |
+
$headers = array_keys($this->products[0]);
|
614 |
+
$feed[] = $headers;
|
615 |
+
foreach ($this->products as $no => $product) {
|
616 |
+
$row = array();
|
617 |
+
foreach ($headers as $key => $header) {
|
618 |
+
if (strpos($header, "additional image link") !== false) {
|
619 |
+
$header = "additional image link";
|
620 |
+
}
|
621 |
+
$row[] = isset($product[$header]) ? $product[$header] : "";;
|
622 |
+
}
|
623 |
+
$feed[] = $row;
|
624 |
+
}
|
625 |
+
return $feed;
|
626 |
+
}
|
627 |
+
return false;
|
628 |
+
}
|
629 |
+
|
630 |
}
|
includes/feeds/class-woo-feed-kelkoo.php
CHANGED
@@ -1,438 +1,438 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
|
4 |
-
class Kelkoo
|
5 |
-
{
|
6 |
-
|
7 |
-
public $products;
|
8 |
-
|
9 |
-
public $rules;
|
10 |
-
|
11 |
-
public $mapping;
|
12 |
-
|
13 |
-
public $errorLog;
|
14 |
-
public $errorCounter = 0;
|
15 |
-
|
16 |
-
private $filteredProduct;
|
17 |
-
private $feedWrapper = 'product';
|
18 |
-
|
19 |
-
public function __construct($feedRule)
|
20 |
-
{
|
21 |
-
$this->rules = $feedRule;
|
22 |
-
$this->mapProductsByRules();
|
23 |
-
$this->formatRequiredField();
|
24 |
-
$this->filterProductValues();
|
25 |
-
if ($this->rules['feedType'] == 'xml') {
|
26 |
-
$this->mapAttributeForXML();
|
27 |
-
} else {
|
28 |
-
$this->mapAttributeForCSVTEXT();
|
29 |
-
}
|
30 |
-
}
|
31 |
-
|
32 |
-
public function mapAttributeForXML()
|
33 |
-
{
|
34 |
-
//Basic product information
|
35 |
-
|
36 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
37 |
-
foreach ($this->products as $key => $values) {
|
38 |
-
foreach ($values as $attr => $value) {
|
39 |
-
$this->products[$key][$attr] = $this->formatXMLLine($attr, $value, true, true, true);
|
40 |
-
}
|
41 |
-
}
|
42 |
-
}
|
43 |
-
}
|
44 |
-
|
45 |
-
|
46 |
-
public function mapAttributeForCSVTEXT()
|
47 |
-
{
|
48 |
-
//Basic product information
|
49 |
-
|
50 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
51 |
-
foreach ($this->products as $key => $values) {
|
52 |
-
foreach ($values as $attr => $value) {
|
53 |
-
//Allow force strip HTML
|
54 |
-
|
55 |
-
$value = strip_tags(html_entity_decode($value));
|
56 |
-
|
57 |
-
$value = utf8_encode($value);
|
58 |
-
$attr = utf8_encode($attr);
|
59 |
-
|
60 |
-
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
|
61 |
-
|
62 |
-
if (gettype($value) == 'array')
|
63 |
-
$value = json_encode($value);
|
64 |
-
|
65 |
-
$this->products[$key][$attr] = $value;
|
66 |
-
}
|
67 |
-
}
|
68 |
-
}
|
69 |
-
}
|
70 |
-
|
71 |
-
public function formatRequiredField()
|
72 |
-
{
|
73 |
-
foreach ($this->products as $no => $product) {
|
74 |
-
$upn = 0;
|
75 |
-
if (array_key_exists('title', $product)) {
|
76 |
-
$id = $product['title'];
|
77 |
-
} else {
|
78 |
-
$id = "";
|
79 |
-
}
|
80 |
-
|
81 |
-
if (!array_key_exists('title', $product)) {
|
82 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>title</b>] Missing for <b>$id</b>.";
|
83 |
-
$this->errorCounter++;
|
84 |
-
}
|
85 |
-
|
86 |
-
|
87 |
-
if (!array_key_exists('product-url', $product)) {
|
88 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>product-url</b>] Missing for <b>$id</b>.";
|
89 |
-
$this->errorCounter++;
|
90 |
-
}
|
91 |
-
|
92 |
-
if (!array_key_exists('price', $product)) {
|
93 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>price</b>] Missing for <b>$id</b>.";
|
94 |
-
$this->errorCounter++;
|
95 |
-
}
|
96 |
-
|
97 |
-
if (!array_key_exists('merchant-category', $product)) {
|
98 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>merchant-category</b>] Missing for <b>$id</b>.";
|
99 |
-
$this->errorCounter++;
|
100 |
-
}
|
101 |
-
}
|
102 |
-
}
|
103 |
-
|
104 |
-
public function returnFinalProduct()
|
105 |
-
{
|
106 |
-
if ($this->rules['feedType'] == 'xml') {
|
107 |
-
return $this->get_feed($this->products);
|
108 |
-
} elseif ($this->rules['feedType'] == 'txt') {
|
109 |
-
return $this->get_txt_feed();
|
110 |
-
} elseif ($this->rules['feedType'] == 'csv') {
|
111 |
-
return $this->get_csv_feed();
|
112 |
-
}
|
113 |
-
return false;
|
114 |
-
}
|
115 |
-
|
116 |
-
public function filterProductValues()
|
117 |
-
{
|
118 |
-
$getProduct = new Woo_Feed_Products();
|
119 |
-
$products = $this->products;
|
120 |
-
|
121 |
-
foreach ($products as $no => $product) {
|
122 |
-
if (array_key_exists('title', $product)) {
|
123 |
-
$id = $product['title'];
|
124 |
-
} else {
|
125 |
-
$id = "";
|
126 |
-
}
|
127 |
-
|
128 |
-
foreach ($product as $key => $value) {
|
129 |
-
|
130 |
-
switch ($key) {
|
131 |
-
case "title":
|
132 |
-
if (strlen($value) > 80) {
|
133 |
-
$this->errorLog[$this->errorCounter] = "[<b>title</b>] is more that 80 character for $id.";
|
134 |
-
$this->errorCounter++;
|
135 |
-
}
|
136 |
-
break;
|
137 |
-
case "product-url":
|
138 |
-
if (strpos($value, 'http://') == false || strpos($value, 'https://') == false) {
|
139 |
-
$this->errorLog[$this->errorCounter] = "[<b>product-url</b>] must start with http:// or https:// for $id.";
|
140 |
-
$this->errorCounter++;
|
141 |
-
}
|
142 |
-
break;
|
143 |
-
case "description":
|
144 |
-
if (strlen($value) > 300) {
|
145 |
-
$this->errorLog[$this->errorCounter] = "[<b>description</b>] is more that 300 character for $id.";
|
146 |
-
$this->errorCounter++;
|
147 |
-
}
|
148 |
-
break;
|
149 |
-
case "image-url":
|
150 |
-
if (strpos($value, 'http://') == false) {
|
151 |
-
$this->errorLog[$this->errorCounter] = "[<b>image-url</b>] must start with http:// for $id.";
|
152 |
-
$this->errorCounter++;
|
153 |
-
}
|
154 |
-
|
155 |
-
list($width, $height) = getimagesize($value);
|
156 |
-
if (($width * $height) < 1920000) {
|
157 |
-
$this->errorLog[$this->errorCounter] = "<b>Image Pixel</b> should be less than 1920000px for $id.";
|
158 |
-
$this->errorCounter++;
|
159 |
-
}
|
160 |
-
|
161 |
-
break;
|
162 |
-
case "condition":
|
163 |
-
if ($value == 'new') {
|
164 |
-
$this->products[$no][$key] = "0";
|
165 |
-
} else if ($value == 'used') {
|
166 |
-
$this->products[$no][$key] = "1";
|
167 |
-
} else if ($value == 'refurbished') {
|
168 |
-
$this->products[$no][$key] = "2";
|
169 |
-
} else if ($value == 'open box') {
|
170 |
-
$this->products[$no][$key] = "3";
|
171 |
-
} else if ($value == 'returned') {
|
172 |
-
$this->products[$no][$key] = "4";
|
173 |
-
} else if ($value == 'damaged') {
|
174 |
-
$this->products[$no][$key] = "5";
|
175 |
-
} else if ($value == 'overstock') {
|
176 |
-
$this->products[$no][$key] = "6";
|
177 |
-
} else if ($value == 'liquidation') {
|
178 |
-
$this->products[$no][$key] = "7";
|
179 |
-
} else if ($value == 'unknown') {
|
180 |
-
$this->products[$no][$key] = "8";
|
181 |
-
} else if ($value == 'download') {
|
182 |
-
$this->products[$no][$key] = "9";
|
183 |
-
} else if ($value == 'offers for professional') {
|
184 |
-
$this->products[$no][$key] = "10";
|
185 |
-
}
|
186 |
-
break;
|
187 |
-
case "availability":
|
188 |
-
$conditions = array('In Stock', 'Yes', 'Any Number', 'Out of Stock');
|
189 |
-
if ($value == 'In Stock') {
|
190 |
-
$this->products[$no][$key] = "1";
|
191 |
-
} else if ($value == 'in stock') {
|
192 |
-
$this->products[$no][$key] = "1";
|
193 |
-
} else if ($value == 'Stock On Order') {
|
194 |
-
$this->products[$no][$key] = "2";
|
195 |
-
} else if ($value == 'Unknown, check site') {
|
196 |
-
$this->products[$no][$key] = "3";
|
197 |
-
} else if ($value == 'Preorder') {
|
198 |
-
$this->products[$no][$key] = "4";
|
199 |
-
} else if ($value == 'Available on Order') {
|
200 |
-
$this->products[$no][$key] = "5";
|
201 |
-
} else if ($value == 'Out of Stock') {
|
202 |
-
$this->products[$no][$key] = "6";
|
203 |
-
} else if ($value == 'out of stock') {
|
204 |
-
$this->products[$no][$key] = "6";
|
205 |
-
}
|
206 |
-
break;
|
207 |
-
default:
|
208 |
-
break;
|
209 |
-
}
|
210 |
-
}
|
211 |
-
}
|
212 |
-
}
|
213 |
-
|
214 |
-
public function get_category_mapping_value($mappingName, $parent)
|
215 |
-
{
|
216 |
-
$getValue = unserialize(get_option($mappingName));
|
217 |
-
$mapp = array_reverse($getValue['cmapping'], true);
|
218 |
-
$categories = get_the_terms($parent, 'product_cat');
|
219 |
-
|
220 |
-
foreach ($categories as $key => $category) {
|
221 |
-
if (!empty($mapp[$category->term_id]))
|
222 |
-
return $mapp[$category->term_id];
|
223 |
-
}
|
224 |
-
}
|
225 |
-
|
226 |
-
|
227 |
-
public function mapProductsByRules()
|
228 |
-
{
|
229 |
-
$products = new Woo_Feed_Products(); //$this->woo_feed_get_visible_product();
|
230 |
-
$attributes = $this->rules['attributes'];
|
231 |
-
$prefix = $this->rules['prefix'];
|
232 |
-
$suffix = $this->rules['suffix'];
|
233 |
-
$outputType = $this->rules['output_type'];
|
234 |
-
$limit = $this->rules['limit'];
|
235 |
-
$merchantAttributes = $this->rules['mattributes'];
|
236 |
-
$type = $this->rules['type'];
|
237 |
-
$default = $this->rules['default'];
|
238 |
-
$feedType = $this->rules['feedType'];
|
239 |
-
|
240 |
-
// Map Merchant Attributes and Woo Attributes
|
241 |
-
if (count($merchantAttributes)) {
|
242 |
-
foreach ($merchantAttributes as $key => $attr) {
|
243 |
-
if (!empty($attr) && !empty($attributes[$key])) {
|
244 |
-
if ($type[$key] == 'attribute') {
|
245 |
-
$this->mapping[$attr]['value'] = $attributes[$key];
|
246 |
-
$this->mapping[$attr]['suffix'] = $suffix[$key];
|
247 |
-
$this->mapping[$attr]['prefix'] = $prefix[$key];
|
248 |
-
$this->mapping[$attr]['type'] = $outputType[$key];
|
249 |
-
$this->mapping[$attr]['limit'] = $limit[$key];
|
250 |
-
}
|
251 |
-
} else if (empty($attributes[$key])) {
|
252 |
-
if ($type[$key] == 'pattern') {
|
253 |
-
$this->mapping[$attr]['value'] = "wf_pattern_$default[$key]";
|
254 |
-
$this->mapping[$attr]['suffix'] = $suffix[$key];
|
255 |
-
$this->mapping[$attr]['prefix'] = $prefix[$key];
|
256 |
-
$this->mapping[$attr]['type'] = $outputType[$key];
|
257 |
-
$this->mapping[$attr]['limit'] = $limit[$key];
|
258 |
-
}
|
259 |
-
}
|
260 |
-
}
|
261 |
-
}
|
262 |
-
|
263 |
-
// Make Product feed array according to mapping
|
264 |
-
foreach ($products->woo_feed_get_visible_product() as $key => $value) {
|
265 |
-
$i = 0;
|
266 |
-
foreach ($this->mapping as $attr => $rules) {
|
267 |
-
if (array_key_exists($rules['value'], $value)) {
|
268 |
-
|
269 |
-
$output = $rules['prefix'] . $value[$rules['value']] . " " . $rules['suffix'];
|
270 |
-
// Format According to output type
|
271 |
-
if ($rules['type'] == 2) {
|
272 |
-
$output = strip_tags($output);
|
273 |
-
} elseif ($rules['type'] == 3) {
|
274 |
-
$output = absint($output);
|
275 |
-
}
|
276 |
-
// Format According to output limit
|
277 |
-
if (!empty($rules['limit']) && is_numeric($rules['limit'])) {
|
278 |
-
$output = substr($output, 0, $rules['limit']);
|
279 |
-
}
|
280 |
-
$attr = trim($attr);
|
281 |
-
$this->products[$key][$attr] = trim($output);
|
282 |
-
} else {
|
283 |
-
if (!empty($default[$i])) {
|
284 |
-
$output = $rules['prefix'] . str_replace("wf_pattern_", "", $rules['value']) . " " . $rules['suffix'];
|
285 |
-
if ($rules['type'] == 2) {
|
286 |
-
$output = strip_tags($output);
|
287 |
-
} elseif ($rules['type'] == 3) {
|
288 |
-
$output = absint($output);
|
289 |
-
}
|
290 |
-
// Format According to output limit
|
291 |
-
if (!empty($rules['limit']) && is_numeric($rules['limit'])) {
|
292 |
-
$output = substr($output, 0, $rules['limit']);
|
293 |
-
}
|
294 |
-
$attr = trim($attr);
|
295 |
-
$this->products[$key][$attr] = trim($output);
|
296 |
-
}
|
297 |
-
}
|
298 |
-
$i++;
|
299 |
-
}
|
300 |
-
}
|
301 |
-
|
302 |
-
|
303 |
-
return $this->products;
|
304 |
-
}
|
305 |
-
|
306 |
-
public function mapAttribute($from, $to, $cdata = false)
|
307 |
-
{
|
308 |
-
$i = 0;
|
309 |
-
foreach ($this->products as $no => $product) {
|
310 |
-
foreach ($product as $key => $value) {
|
311 |
-
if ($key == $from) {
|
312 |
-
unset($this->products[$no][$from]);
|
313 |
-
if ($from == 'images') {
|
314 |
-
$this->products[$no][$to] = $value;
|
315 |
-
} else {
|
316 |
-
$this->products[$no][$to] = $this->formatXMLLine($to, $value, $cdata, true, true);
|
317 |
-
}
|
318 |
-
|
319 |
-
}
|
320 |
-
}
|
321 |
-
$i++;
|
322 |
-
}
|
323 |
-
}
|
324 |
-
|
325 |
-
function formatXMLLine($attribute, $value, $cdata = false, $stripHTML = true, $utf8encode = true, $space = ' ')
|
326 |
-
{
|
327 |
-
//Make single line for XML
|
328 |
-
$c_leader = '';
|
329 |
-
$c_footer = '';
|
330 |
-
if ($cdata) {
|
331 |
-
$c_leader = '<![CDATA[';
|
332 |
-
$c_footer = ']]>';
|
333 |
-
}
|
334 |
-
//Allow force strip HTML
|
335 |
-
if ($stripHTML)
|
336 |
-
$value = strip_tags(html_entity_decode($value));
|
337 |
-
|
338 |
-
|
339 |
-
if ($utf8encode || $utf8encode == 1) {
|
340 |
-
$value = utf8_encode($value);
|
341 |
-
$attribute = utf8_encode($attribute);
|
342 |
-
}
|
343 |
-
|
344 |
-
|
345 |
-
if (!$cdata)
|
346 |
-
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
|
347 |
-
|
348 |
-
if (gettype($value) == 'array')
|
349 |
-
$value = json_encode($value);
|
350 |
-
|
351 |
-
|
352 |
-
return '
|
353 |
-
' . $space . '<' . $attribute . '>' . $c_leader . $value . $c_footer . '</' . $attribute . '>';
|
354 |
-
}
|
355 |
-
|
356 |
-
function change_key($array, $old_key, $new_key)
|
357 |
-
{
|
358 |
-
foreach ($this->products as $no => $product) {
|
359 |
-
if (!array_key_exists($old_key, $product))
|
360 |
-
return $array;
|
361 |
-
|
362 |
-
$keys = array_keys($array);
|
363 |
-
$keys[array_search($old_key, $keys)] = $new_key;
|
364 |
-
}
|
365 |
-
return array_combine($keys, $array);
|
366 |
-
}
|
367 |
-
|
368 |
-
public function get_feed_header()
|
369 |
-
{
|
370 |
-
$output = '<?xml version="1.0" encoding="UTF-8" ?>
|
371 |
-
<products>';
|
372 |
-
$output .= "\n";
|
373 |
-
return $output;
|
374 |
-
}
|
375 |
-
|
376 |
-
public function get_feed($items)
|
377 |
-
{
|
378 |
-
$feed = "";
|
379 |
-
$feed .= $this->get_feed_header();
|
380 |
-
$feed .= "\n";
|
381 |
-
foreach ($items as $item => $products) {
|
382 |
-
$feed .= " <" . $this->feedWrapper . ">";
|
383 |
-
foreach ($products as $key => $value) {
|
384 |
-
if (!empty($value))
|
385 |
-
$feed .= $value;
|
386 |
-
}
|
387 |
-
$feed .= "\n </" . $this->feedWrapper . ">\n";
|
388 |
-
}
|
389 |
-
$feed .= $this->get_feed_footer();
|
390 |
-
|
391 |
-
return $feed;
|
392 |
-
}
|
393 |
-
|
394 |
-
public function get_feed_footer()
|
395 |
-
{
|
396 |
-
$footer = " </products>";
|
397 |
-
return $footer;
|
398 |
-
}
|
399 |
-
|
400 |
-
public function get_txt_feed()
|
401 |
-
{
|
402 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
403 |
-
$headers = array_keys($this->products[0]);
|
404 |
-
$feed[] = $headers;
|
405 |
-
foreach ($this->products as $no => $product) {
|
406 |
-
$row = array();
|
407 |
-
foreach ($headers as $key => $header) {
|
408 |
-
$row[] = $product[$header];
|
409 |
-
}
|
410 |
-
$feed[] = $row;
|
411 |
-
}
|
412 |
-
$str = "";
|
413 |
-
foreach ($feed as $fields) {
|
414 |
-
$str .= implode("\t", $fields) . "\n";
|
415 |
-
}
|
416 |
-
return $str;
|
417 |
-
}
|
418 |
-
return false;
|
419 |
-
}
|
420 |
-
|
421 |
-
public function get_csv_feed()
|
422 |
-
{
|
423 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
424 |
-
$headers = array_keys($this->products[0]);
|
425 |
-
$feed[] = $headers;
|
426 |
-
foreach ($this->products as $no => $product) {
|
427 |
-
$row = array();
|
428 |
-
foreach ($headers as $key => $header) {
|
429 |
-
$row[] = $product[$header];
|
430 |
-
}
|
431 |
-
$feed[] = $row;
|
432 |
-
}
|
433 |
-
|
434 |
-
return $feed;
|
435 |
-
}
|
436 |
-
return false;
|
437 |
-
}
|
438 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
|
4 |
+
class Kelkoo
|
5 |
+
{
|
6 |
+
|
7 |
+
public $products;
|
8 |
+
|
9 |
+
public $rules;
|
10 |
+
|
11 |
+
public $mapping;
|
12 |
+
|
13 |
+
public $errorLog;
|
14 |
+
public $errorCounter = 0;
|
15 |
+
|
16 |
+
private $filteredProduct;
|
17 |
+
private $feedWrapper = 'product';
|
18 |
+
|
19 |
+
public function __construct($feedRule)
|
20 |
+
{
|
21 |
+
$this->rules = $feedRule;
|
22 |
+
$this->mapProductsByRules();
|
23 |
+
$this->formatRequiredField();
|
24 |
+
$this->filterProductValues();
|
25 |
+
if ($this->rules['feedType'] == 'xml') {
|
26 |
+
$this->mapAttributeForXML();
|
27 |
+
} else {
|
28 |
+
$this->mapAttributeForCSVTEXT();
|
29 |
+
}
|
30 |
+
}
|
31 |
+
|
32 |
+
public function mapAttributeForXML()
|
33 |
+
{
|
34 |
+
//Basic product information
|
35 |
+
|
36 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
37 |
+
foreach ($this->products as $key => $values) {
|
38 |
+
foreach ($values as $attr => $value) {
|
39 |
+
$this->products[$key][$attr] = $this->formatXMLLine($attr, $value, true, true, true);
|
40 |
+
}
|
41 |
+
}
|
42 |
+
}
|
43 |
+
}
|
44 |
+
|
45 |
+
|
46 |
+
public function mapAttributeForCSVTEXT()
|
47 |
+
{
|
48 |
+
//Basic product information
|
49 |
+
|
50 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
51 |
+
foreach ($this->products as $key => $values) {
|
52 |
+
foreach ($values as $attr => $value) {
|
53 |
+
//Allow force strip HTML
|
54 |
+
|
55 |
+
$value = strip_tags(html_entity_decode($value));
|
56 |
+
|
57 |
+
$value = utf8_encode($value);
|
58 |
+
$attr = utf8_encode($attr);
|
59 |
+
|
60 |
+
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
|
61 |
+
|
62 |
+
if (gettype($value) == 'array')
|
63 |
+
$value = json_encode($value);
|
64 |
+
|
65 |
+
$this->products[$key][$attr] = $value;
|
66 |
+
}
|
67 |
+
}
|
68 |
+
}
|
69 |
+
}
|
70 |
+
|
71 |
+
public function formatRequiredField()
|
72 |
+
{
|
73 |
+
foreach ($this->products as $no => $product) {
|
74 |
+
$upn = 0;
|
75 |
+
if (array_key_exists('title', $product)) {
|
76 |
+
$id = $product['title'];
|
77 |
+
} else {
|
78 |
+
$id = "";
|
79 |
+
}
|
80 |
+
|
81 |
+
if (!array_key_exists('title', $product)) {
|
82 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>title</b>] Missing for <b>$id</b>.";
|
83 |
+
$this->errorCounter++;
|
84 |
+
}
|
85 |
+
|
86 |
+
|
87 |
+
if (!array_key_exists('product-url', $product)) {
|
88 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>product-url</b>] Missing for <b>$id</b>.";
|
89 |
+
$this->errorCounter++;
|
90 |
+
}
|
91 |
+
|
92 |
+
if (!array_key_exists('price', $product)) {
|
93 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>price</b>] Missing for <b>$id</b>.";
|
94 |
+
$this->errorCounter++;
|
95 |
+
}
|
96 |
+
|
97 |
+
if (!array_key_exists('merchant-category', $product)) {
|
98 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>merchant-category</b>] Missing for <b>$id</b>.";
|
99 |
+
$this->errorCounter++;
|
100 |
+
}
|
101 |
+
}
|
102 |
+
}
|
103 |
+
|
104 |
+
public function returnFinalProduct()
|
105 |
+
{
|
106 |
+
if ($this->rules['feedType'] == 'xml') {
|
107 |
+
return $this->get_feed($this->products);
|
108 |
+
} elseif ($this->rules['feedType'] == 'txt') {
|
109 |
+
return $this->get_txt_feed();
|
110 |
+
} elseif ($this->rules['feedType'] == 'csv') {
|
111 |
+
return $this->get_csv_feed();
|
112 |
+
}
|
113 |
+
return false;
|
114 |
+
}
|
115 |
+
|
116 |
+
public function filterProductValues()
|
117 |
+
{
|
118 |
+
$getProduct = new Woo_Feed_Products();
|
119 |
+
$products = $this->products;
|
120 |
+
|
121 |
+
foreach ($products as $no => $product) {
|
122 |
+
if (array_key_exists('title', $product)) {
|
123 |
+
$id = $product['title'];
|
124 |
+
} else {
|
125 |
+
$id = "";
|
126 |
+
}
|
127 |
+
|
128 |
+
foreach ($product as $key => $value) {
|
129 |
+
|
130 |
+
switch ($key) {
|
131 |
+
case "title":
|
132 |
+
if (strlen($value) > 80) {
|
133 |
+
$this->errorLog[$this->errorCounter] = "[<b>title</b>] is more that 80 character for $id.";
|
134 |
+
$this->errorCounter++;
|
135 |
+
}
|
136 |
+
break;
|
137 |
+
case "product-url":
|
138 |
+
if (strpos($value, 'http://') == false || strpos($value, 'https://') == false) {
|
139 |
+
$this->errorLog[$this->errorCounter] = "[<b>product-url</b>] must start with http:// or https:// for $id.";
|
140 |
+
$this->errorCounter++;
|
141 |
+
}
|
142 |
+
break;
|
143 |
+
case "description":
|
144 |
+
if (strlen($value) > 300) {
|
145 |
+
$this->errorLog[$this->errorCounter] = "[<b>description</b>] is more that 300 character for $id.";
|
146 |
+
$this->errorCounter++;
|
147 |
+
}
|
148 |
+
break;
|
149 |
+
case "image-url":
|
150 |
+
if (strpos($value, 'http://') == false) {
|
151 |
+
$this->errorLog[$this->errorCounter] = "[<b>image-url</b>] must start with http:// for $id.";
|
152 |
+
$this->errorCounter++;
|
153 |
+
}
|
154 |
+
|
155 |
+
list($width, $height) = getimagesize($value);
|
156 |
+
if (($width * $height) < 1920000) {
|
157 |
+
$this->errorLog[$this->errorCounter] = "<b>Image Pixel</b> should be less than 1920000px for $id.";
|
158 |
+
$this->errorCounter++;
|
159 |
+
}
|
160 |
+
|
161 |
+
break;
|
162 |
+
case "condition":
|
163 |
+
if ($value == 'new') {
|
164 |
+
$this->products[$no][$key] = "0";
|
165 |
+
} else if ($value == 'used') {
|
166 |
+
$this->products[$no][$key] = "1";
|
167 |
+
} else if ($value == 'refurbished') {
|
168 |
+
$this->products[$no][$key] = "2";
|
169 |
+
} else if ($value == 'open box') {
|
170 |
+
$this->products[$no][$key] = "3";
|
171 |
+
} else if ($value == 'returned') {
|
172 |
+
$this->products[$no][$key] = "4";
|
173 |
+
} else if ($value == 'damaged') {
|
174 |
+
$this->products[$no][$key] = "5";
|
175 |
+
} else if ($value == 'overstock') {
|
176 |
+
$this->products[$no][$key] = "6";
|
177 |
+
} else if ($value == 'liquidation') {
|
178 |
+
$this->products[$no][$key] = "7";
|
179 |
+
} else if ($value == 'unknown') {
|
180 |
+
$this->products[$no][$key] = "8";
|
181 |
+
} else if ($value == 'download') {
|
182 |
+
$this->products[$no][$key] = "9";
|
183 |
+
} else if ($value == 'offers for professional') {
|
184 |
+
$this->products[$no][$key] = "10";
|
185 |
+
}
|
186 |
+
break;
|
187 |
+
case "availability":
|
188 |
+
$conditions = array('In Stock', 'Yes', 'Any Number', 'Out of Stock');
|
189 |
+
if ($value == 'In Stock') {
|
190 |
+
$this->products[$no][$key] = "1";
|
191 |
+
} else if ($value == 'in stock') {
|
192 |
+
$this->products[$no][$key] = "1";
|
193 |
+
} else if ($value == 'Stock On Order') {
|
194 |
+
$this->products[$no][$key] = "2";
|
195 |
+
} else if ($value == 'Unknown, check site') {
|
196 |
+
$this->products[$no][$key] = "3";
|
197 |
+
} else if ($value == 'Preorder') {
|
198 |
+
$this->products[$no][$key] = "4";
|
199 |
+
} else if ($value == 'Available on Order') {
|
200 |
+
$this->products[$no][$key] = "5";
|
201 |
+
} else if ($value == 'Out of Stock') {
|
202 |
+
$this->products[$no][$key] = "6";
|
203 |
+
} else if ($value == 'out of stock') {
|
204 |
+
$this->products[$no][$key] = "6";
|
205 |
+
}
|
206 |
+
break;
|
207 |
+
default:
|
208 |
+
break;
|
209 |
+
}
|
210 |
+
}
|
211 |
+
}
|
212 |
+
}
|
213 |
+
|
214 |
+
public function get_category_mapping_value($mappingName, $parent)
|
215 |
+
{
|
216 |
+
$getValue = unserialize(get_option($mappingName));
|
217 |
+
$mapp = array_reverse($getValue['cmapping'], true);
|
218 |
+
$categories = get_the_terms($parent, 'product_cat');
|
219 |
+
|
220 |
+
foreach ($categories as $key => $category) {
|
221 |
+
if (!empty($mapp[$category->term_id]))
|
222 |
+
return $mapp[$category->term_id];
|
223 |
+
}
|
224 |
+
}
|
225 |
+
|
226 |
+
|
227 |
+
public function mapProductsByRules()
|
228 |
+
{
|
229 |
+
$products = new Woo_Feed_Products(); //$this->woo_feed_get_visible_product();
|
230 |
+
$attributes = $this->rules['attributes'];
|
231 |
+
$prefix = $this->rules['prefix'];
|
232 |
+
$suffix = $this->rules['suffix'];
|
233 |
+
$outputType = $this->rules['output_type'];
|
234 |
+
$limit = $this->rules['limit'];
|
235 |
+
$merchantAttributes = $this->rules['mattributes'];
|
236 |
+
$type = $this->rules['type'];
|
237 |
+
$default = $this->rules['default'];
|
238 |
+
$feedType = $this->rules['feedType'];
|
239 |
+
|
240 |
+
// Map Merchant Attributes and Woo Attributes
|
241 |
+
if (count($merchantAttributes)) {
|
242 |
+
foreach ($merchantAttributes as $key => $attr) {
|
243 |
+
if (!empty($attr) && !empty($attributes[$key])) {
|
244 |
+
if ($type[$key] == 'attribute') {
|
245 |
+
$this->mapping[$attr]['value'] = $attributes[$key];
|
246 |
+
$this->mapping[$attr]['suffix'] = $suffix[$key];
|
247 |
+
$this->mapping[$attr]['prefix'] = $prefix[$key];
|
248 |
+
$this->mapping[$attr]['type'] = $outputType[$key];
|
249 |
+
$this->mapping[$attr]['limit'] = $limit[$key];
|
250 |
+
}
|
251 |
+
} else if (empty($attributes[$key])) {
|
252 |
+
if ($type[$key] == 'pattern') {
|
253 |
+
$this->mapping[$attr]['value'] = "wf_pattern_$default[$key]";
|
254 |
+
$this->mapping[$attr]['suffix'] = $suffix[$key];
|
255 |
+
$this->mapping[$attr]['prefix'] = $prefix[$key];
|
256 |
+
$this->mapping[$attr]['type'] = $outputType[$key];
|
257 |
+
$this->mapping[$attr]['limit'] = $limit[$key];
|
258 |
+
}
|
259 |
+
}
|
260 |
+
}
|
261 |
+
}
|
262 |
+
|
263 |
+
// Make Product feed array according to mapping
|
264 |
+
foreach ($products->woo_feed_get_visible_product() as $key => $value) {
|
265 |
+
$i = 0;
|
266 |
+
foreach ($this->mapping as $attr => $rules) {
|
267 |
+
if (array_key_exists($rules['value'], $value)) {
|
268 |
+
|
269 |
+
$output = $rules['prefix'] . $value[$rules['value']] . " " . $rules['suffix'];
|
270 |
+
// Format According to output type
|
271 |
+
if ($rules['type'] == 2) {
|
272 |
+
$output = strip_tags($output);
|
273 |
+
} elseif ($rules['type'] == 3) {
|
274 |
+
$output = absint($output);
|
275 |
+
}
|
276 |
+
// Format According to output limit
|
277 |
+
if (!empty($rules['limit']) && is_numeric($rules['limit'])) {
|
278 |
+
$output = substr($output, 0, $rules['limit']);
|
279 |
+
}
|
280 |
+
$attr = trim($attr);
|
281 |
+
$this->products[$key][$attr] = trim($output);
|
282 |
+
} else {
|
283 |
+
if (!empty($default[$i])) {
|
284 |
+
$output = $rules['prefix'] . str_replace("wf_pattern_", "", $rules['value']) . " " . $rules['suffix'];
|
285 |
+
if ($rules['type'] == 2) {
|
286 |
+
$output = strip_tags($output);
|
287 |
+
} elseif ($rules['type'] == 3) {
|
288 |
+
$output = absint($output);
|
289 |
+
}
|
290 |
+
// Format According to output limit
|
291 |
+
if (!empty($rules['limit']) && is_numeric($rules['limit'])) {
|
292 |
+
$output = substr($output, 0, $rules['limit']);
|
293 |
+
}
|
294 |
+
$attr = trim($attr);
|
295 |
+
$this->products[$key][$attr] = trim($output);
|
296 |
+
}
|
297 |
+
}
|
298 |
+
$i++;
|
299 |
+
}
|
300 |
+
}
|
301 |
+
|
302 |
+
|
303 |
+
return $this->products;
|
304 |
+
}
|
305 |
+
|
306 |
+
public function mapAttribute($from, $to, $cdata = false)
|
307 |
+
{
|
308 |
+
$i = 0;
|
309 |
+
foreach ($this->products as $no => $product) {
|
310 |
+
foreach ($product as $key => $value) {
|
311 |
+
if ($key == $from) {
|
312 |
+
unset($this->products[$no][$from]);
|
313 |
+
if ($from == 'images') {
|
314 |
+
$this->products[$no][$to] = $value;
|
315 |
+
} else {
|
316 |
+
$this->products[$no][$to] = $this->formatXMLLine($to, $value, $cdata, true, true);
|
317 |
+
}
|
318 |
+
|
319 |
+
}
|
320 |
+
}
|
321 |
+
$i++;
|
322 |
+
}
|
323 |
+
}
|
324 |
+
|
325 |
+
function formatXMLLine($attribute, $value, $cdata = false, $stripHTML = true, $utf8encode = true, $space = ' ')
|
326 |
+
{
|
327 |
+
//Make single line for XML
|
328 |
+
$c_leader = '';
|
329 |
+
$c_footer = '';
|
330 |
+
if ($cdata) {
|
331 |
+
$c_leader = '<![CDATA[';
|
332 |
+
$c_footer = ']]>';
|
333 |
+
}
|
334 |
+
//Allow force strip HTML
|
335 |
+
if ($stripHTML)
|
336 |
+
$value = strip_tags(html_entity_decode($value));
|
337 |
+
|
338 |
+
|
339 |
+
if ($utf8encode || $utf8encode == 1) {
|
340 |
+
$value = utf8_encode($value);
|
341 |
+
$attribute = utf8_encode($attribute);
|
342 |
+
}
|
343 |
+
|
344 |
+
|
345 |
+
if (!$cdata)
|
346 |
+
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
|
347 |
+
|
348 |
+
if (gettype($value) == 'array')
|
349 |
+
$value = json_encode($value);
|
350 |
+
|
351 |
+
|
352 |
+
return '
|
353 |
+
' . $space . '<' . $attribute . '>' . $c_leader . $value . $c_footer . '</' . $attribute . '>';
|
354 |
+
}
|
355 |
+
|
356 |
+
function change_key($array, $old_key, $new_key)
|
357 |
+
{
|
358 |
+
foreach ($this->products as $no => $product) {
|
359 |
+
if (!array_key_exists($old_key, $product))
|
360 |
+
return $array;
|
361 |
+
|
362 |
+
$keys = array_keys($array);
|
363 |
+
$keys[array_search($old_key, $keys)] = $new_key;
|
364 |
+
}
|
365 |
+
return array_combine($keys, $array);
|
366 |
+
}
|
367 |
+
|
368 |
+
public function get_feed_header()
|
369 |
+
{
|
370 |
+
$output = '<?xml version="1.0" encoding="UTF-8" ?>
|
371 |
+
<products>';
|
372 |
+
$output .= "\n";
|
373 |
+
return $output;
|
374 |
+
}
|
375 |
+
|
376 |
+
public function get_feed($items)
|
377 |
+
{
|
378 |
+
$feed = "";
|
379 |
+
$feed .= $this->get_feed_header();
|
380 |
+
$feed .= "\n";
|
381 |
+
foreach ($items as $item => $products) {
|
382 |
+
$feed .= " <" . $this->feedWrapper . ">";
|
383 |
+
foreach ($products as $key => $value) {
|
384 |
+
if (!empty($value))
|
385 |
+
$feed .= $value;
|
386 |
+
}
|
387 |
+
$feed .= "\n </" . $this->feedWrapper . ">\n";
|
388 |
+
}
|
389 |
+
$feed .= $this->get_feed_footer();
|
390 |
+
|
391 |
+
return $feed;
|
392 |
+
}
|
393 |
+
|
394 |
+
public function get_feed_footer()
|
395 |
+
{
|
396 |
+
$footer = " </products>";
|
397 |
+
return $footer;
|
398 |
+
}
|
399 |
+
|
400 |
+
public function get_txt_feed()
|
401 |
+
{
|
402 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
403 |
+
$headers = array_keys($this->products[0]);
|
404 |
+
$feed[] = $headers;
|
405 |
+
foreach ($this->products as $no => $product) {
|
406 |
+
$row = array();
|
407 |
+
foreach ($headers as $key => $header) {
|
408 |
+
$row[] = $product[$header];
|
409 |
+
}
|
410 |
+
$feed[] = $row;
|
411 |
+
}
|
412 |
+
$str = "";
|
413 |
+
foreach ($feed as $fields) {
|
414 |
+
$str .= implode("\t", $fields) . "\n";
|
415 |
+
}
|
416 |
+
return $str;
|
417 |
+
}
|
418 |
+
return false;
|
419 |
+
}
|
420 |
+
|
421 |
+
public function get_csv_feed()
|
422 |
+
{
|
423 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
424 |
+
$headers = array_keys($this->products[0]);
|
425 |
+
$feed[] = $headers;
|
426 |
+
foreach ($this->products as $no => $product) {
|
427 |
+
$row = array();
|
428 |
+
foreach ($headers as $key => $header) {
|
429 |
+
$row[] = $product[$header];
|
430 |
+
}
|
431 |
+
$feed[] = $row;
|
432 |
+
}
|
433 |
+
|
434 |
+
return $feed;
|
435 |
+
}
|
436 |
+
return false;
|
437 |
+
}
|
438 |
}
|
includes/feeds/class-woo-feed-nextag.php
CHANGED
@@ -1,114 +1,114 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
|
4 |
-
class Nextag
|
5 |
-
{
|
6 |
-
|
7 |
-
/**
|
8 |
-
* This variable is responsible for holding all product attributes and their values
|
9 |
-
*
|
10 |
-
* @since 1.0.0
|
11 |
-
* @var array $products Contains all the product attributes to generate feed
|
12 |
-
* @access public
|
13 |
-
*/
|
14 |
-
public $products;
|
15 |
-
|
16 |
-
/**
|
17 |
-
* This variable is responsible for holding feed configuration form values
|
18 |
-
*
|
19 |
-
* @since 1.0.0
|
20 |
-
* @var Custom $rules Contains feed configuration form values
|
21 |
-
* @access public
|
22 |
-
*/
|
23 |
-
public $rules;
|
24 |
-
|
25 |
-
|
26 |
-
/**
|
27 |
-
* Store product information
|
28 |
-
*
|
29 |
-
* @since 1.0.0
|
30 |
-
* @var array $storeProducts
|
31 |
-
* @access public
|
32 |
-
*/
|
33 |
-
private $storeProducts;
|
34 |
-
|
35 |
-
/**
|
36 |
-
* Define the core functionality to generate feed.
|
37 |
-
*
|
38 |
-
* Set the feed rules. Map products according to the rules and Check required attributes
|
39 |
-
* and their values according to merchant specification.
|
40 |
-
* @var Woo_Generate_Feed $feedRule Contain Feed Configuration
|
41 |
-
* @since 1.0.0
|
42 |
-
*/
|
43 |
-
public function __construct($feedRule)
|
44 |
-
{
|
45 |
-
$products = new Woo_Feed_Products();
|
46 |
-
$storeProducts = $products->woo_feed_get_visible_product();
|
47 |
-
$engine = new WF_Engine($storeProducts, $feedRule);
|
48 |
-
$this->products = $engine->mapProductsByRules();
|
49 |
-
$this->rules = $feedRule;
|
50 |
-
if ($feedRule['feedType'] == 'xml') {
|
51 |
-
$this->mapAttributeForXML();
|
52 |
-
}
|
53 |
-
}
|
54 |
-
|
55 |
-
/**
|
56 |
-
* Return Feed
|
57 |
-
*
|
58 |
-
* @return array|bool|string
|
59 |
-
*/
|
60 |
-
public function returnFinalProduct()
|
61 |
-
{
|
62 |
-
$engine = new WF_Engine($this->products, $this->rules);
|
63 |
-
if ($this->rules['feedType'] == 'xml') {
|
64 |
-
return $engine->get_feed($this->products);
|
65 |
-
} elseif ($this->rules['feedType'] == 'txt') {
|
66 |
-
return $engine->get_txt_feed();
|
67 |
-
} elseif ($this->rules['feedType'] == 'csv') {
|
68 |
-
return $engine->get_csv_feed();
|
69 |
-
}
|
70 |
-
return false;
|
71 |
-
}
|
72 |
-
|
73 |
-
public function mapAttributeForXML()
|
74 |
-
{
|
75 |
-
//Basic product information
|
76 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
77 |
-
foreach ($this->products as $key => $values) {
|
78 |
-
foreach ($values as $attr => $value) {
|
79 |
-
$this->products[$key][$attr] = $this->formatXMLLine($attr, $value, true, true, true);
|
80 |
-
}
|
81 |
-
}
|
82 |
-
}
|
83 |
-
}
|
84 |
-
|
85 |
-
public function mapAttribute($from, $to, $cdata = false)
|
86 |
-
{
|
87 |
-
$i = 0;
|
88 |
-
foreach ($this->products as $no => $product) {
|
89 |
-
foreach ($product as $key => $value) {
|
90 |
-
if ($key == $from) {
|
91 |
-
unset($this->products[$no][$from]);
|
92 |
-
if ($from == 'images') {
|
93 |
-
$this->products[$no][$to] = $value;
|
94 |
-
} else {
|
95 |
-
$this->products[$no][$to] = $this->formatXMLLine($to, $value);
|
96 |
-
}
|
97 |
-
}
|
98 |
-
}
|
99 |
-
$i++;
|
100 |
-
}
|
101 |
-
}
|
102 |
-
|
103 |
-
function formatXMLLine($attribute, $value, $space = ' ')
|
104 |
-
{
|
105 |
-
|
106 |
-
if (gettype($value) == 'array')
|
107 |
-
$value = json_encode($value);
|
108 |
-
|
109 |
-
|
110 |
-
return '
|
111 |
-
' . $space . '<' . $attribute . '>' . $value . '</' . $attribute . '>';
|
112 |
-
}
|
113 |
-
|
114 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
|
4 |
+
class Nextag
|
5 |
+
{
|
6 |
+
|
7 |
+
/**
|
8 |
+
* This variable is responsible for holding all product attributes and their values
|
9 |
+
*
|
10 |
+
* @since 1.0.0
|
11 |
+
* @var array $products Contains all the product attributes to generate feed
|
12 |
+
* @access public
|
13 |
+
*/
|
14 |
+
public $products;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* This variable is responsible for holding feed configuration form values
|
18 |
+
*
|
19 |
+
* @since 1.0.0
|
20 |
+
* @var Custom $rules Contains feed configuration form values
|
21 |
+
* @access public
|
22 |
+
*/
|
23 |
+
public $rules;
|
24 |
+
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Store product information
|
28 |
+
*
|
29 |
+
* @since 1.0.0
|
30 |
+
* @var array $storeProducts
|
31 |
+
* @access public
|
32 |
+
*/
|
33 |
+
private $storeProducts;
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Define the core functionality to generate feed.
|
37 |
+
*
|
38 |
+
* Set the feed rules. Map products according to the rules and Check required attributes
|
39 |
+
* and their values according to merchant specification.
|
40 |
+
* @var Woo_Generate_Feed $feedRule Contain Feed Configuration
|
41 |
+
* @since 1.0.0
|
42 |
+
*/
|
43 |
+
public function __construct($feedRule)
|
44 |
+
{
|
45 |
+
$products = new Woo_Feed_Products();
|
46 |
+
$storeProducts = $products->woo_feed_get_visible_product();
|
47 |
+
$engine = new WF_Engine($storeProducts, $feedRule);
|
48 |
+
$this->products = $engine->mapProductsByRules();
|
49 |
+
$this->rules = $feedRule;
|
50 |
+
if ($feedRule['feedType'] == 'xml') {
|
51 |
+
$this->mapAttributeForXML();
|
52 |
+
}
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Return Feed
|
57 |
+
*
|
58 |
+
* @return array|bool|string
|
59 |
+
*/
|
60 |
+
public function returnFinalProduct()
|
61 |
+
{
|
62 |
+
$engine = new WF_Engine($this->products, $this->rules);
|
63 |
+
if ($this->rules['feedType'] == 'xml') {
|
64 |
+
return $engine->get_feed($this->products);
|
65 |
+
} elseif ($this->rules['feedType'] == 'txt') {
|
66 |
+
return $engine->get_txt_feed();
|
67 |
+
} elseif ($this->rules['feedType'] == 'csv') {
|
68 |
+
return $engine->get_csv_feed();
|
69 |
+
}
|
70 |
+
return false;
|
71 |
+
}
|
72 |
+
|
73 |
+
public function mapAttributeForXML()
|
74 |
+
{
|
75 |
+
//Basic product information
|
76 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
77 |
+
foreach ($this->products as $key => $values) {
|
78 |
+
foreach ($values as $attr => $value) {
|
79 |
+
$this->products[$key][$attr] = $this->formatXMLLine($attr, $value, true, true, true);
|
80 |
+
}
|
81 |
+
}
|
82 |
+
}
|
83 |
+
}
|
84 |
+
|
85 |
+
public function mapAttribute($from, $to, $cdata = false)
|
86 |
+
{
|
87 |
+
$i = 0;
|
88 |
+
foreach ($this->products as $no => $product) {
|
89 |
+
foreach ($product as $key => $value) {
|
90 |
+
if ($key == $from) {
|
91 |
+
unset($this->products[$no][$from]);
|
92 |
+
if ($from == 'images') {
|
93 |
+
$this->products[$no][$to] = $value;
|
94 |
+
} else {
|
95 |
+
$this->products[$no][$to] = $this->formatXMLLine($to, $value);
|
96 |
+
}
|
97 |
+
}
|
98 |
+
}
|
99 |
+
$i++;
|
100 |
+
}
|
101 |
+
}
|
102 |
+
|
103 |
+
function formatXMLLine($attribute, $value, $space = ' ')
|
104 |
+
{
|
105 |
+
|
106 |
+
if (gettype($value) == 'array')
|
107 |
+
$value = json_encode($value);
|
108 |
+
|
109 |
+
|
110 |
+
return '
|
111 |
+
' . $space . '<' . $attribute . '>' . $value . '</' . $attribute . '>';
|
112 |
+
}
|
113 |
+
|
114 |
}
|
includes/feeds/class-woo-feed-pricegrabber.php
CHANGED
@@ -1,480 +1,480 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
|
4 |
-
class Pricegrabber
|
5 |
-
{
|
6 |
-
|
7 |
-
public $products;
|
8 |
-
|
9 |
-
public $rules;
|
10 |
-
|
11 |
-
public $mapping;
|
12 |
-
|
13 |
-
public $errorLog;
|
14 |
-
public $errorCounter = 0;
|
15 |
-
|
16 |
-
private $filteredProduct;
|
17 |
-
private $feedWrapper = 'item';
|
18 |
-
|
19 |
-
public function __construct($feedRule)
|
20 |
-
{
|
21 |
-
$this->rules = $feedRule;
|
22 |
-
$this->mapProductsByRules();
|
23 |
-
$this->formatRequiredField();
|
24 |
-
$this->filterProductValues();
|
25 |
-
if ($this->rules['feedType'] == 'xml') {
|
26 |
-
$this->mapAttributeForXML();
|
27 |
-
} else {
|
28 |
-
$this->mapAttributeForCSVTEXT();
|
29 |
-
}
|
30 |
-
}
|
31 |
-
|
32 |
-
public function mapAttributeForXML()
|
33 |
-
{
|
34 |
-
//Basic product information
|
35 |
-
|
36 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
37 |
-
foreach ($this->products as $key => $values) {
|
38 |
-
foreach ($values as $attr => $value) {
|
39 |
-
$this->products[$key][$attr] = $this->formatXMLLine($attr, $value, true, true, true);
|
40 |
-
}
|
41 |
-
}
|
42 |
-
}
|
43 |
-
}
|
44 |
-
|
45 |
-
|
46 |
-
public function mapAttributeForCSVTEXT()
|
47 |
-
{
|
48 |
-
//Basic product information
|
49 |
-
|
50 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
51 |
-
foreach ($this->products as $key => $values) {
|
52 |
-
foreach ($values as $attr => $value) {
|
53 |
-
//Allow force strip HTML
|
54 |
-
|
55 |
-
$value = strip_tags(html_entity_decode($value));
|
56 |
-
|
57 |
-
$value = utf8_encode($value);
|
58 |
-
$attr = utf8_encode($attr);
|
59 |
-
|
60 |
-
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
|
61 |
-
|
62 |
-
if (gettype($value) == 'array')
|
63 |
-
$value = json_encode($value);
|
64 |
-
|
65 |
-
$this->products[$key][$attr] = $value;
|
66 |
-
}
|
67 |
-
}
|
68 |
-
}
|
69 |
-
}
|
70 |
-
|
71 |
-
public function formatRequiredField()
|
72 |
-
{
|
73 |
-
foreach ($this->products as $no => $product) {
|
74 |
-
$upn = 0;
|
75 |
-
if (array_key_exists('title', $product)) {
|
76 |
-
$id = $product['title'];
|
77 |
-
} else {
|
78 |
-
$id = $product['id'];
|
79 |
-
}
|
80 |
-
foreach ($product as $key => $value) {
|
81 |
-
if ($key == 'mpn' || $key == 'gtin') {
|
82 |
-
$upn++;
|
83 |
-
}
|
84 |
-
}
|
85 |
-
|
86 |
-
if (!array_key_exists('title', $product)) {
|
87 |
-
$this->errorLog[$this->errorCounter] = "Product Title Missing for <b>$id</b>.";
|
88 |
-
$this->errorCounter++;
|
89 |
-
}
|
90 |
-
|
91 |
-
if (!array_key_exists('id', $product)) {
|
92 |
-
$this->errorLog[$this->errorCounter] = "Product Id Missing for <b>$id</b>.";
|
93 |
-
$this->errorCounter++;
|
94 |
-
}
|
95 |
-
|
96 |
-
if (!array_key_exists('brand', $product)) {
|
97 |
-
$this->errorLog[$this->errorCounter] = "Product Brand Missing for <b>$id</b>.";
|
98 |
-
$this->errorCounter++;
|
99 |
-
}
|
100 |
-
|
101 |
-
if (!array_key_exists('description', $product)) {
|
102 |
-
$this->errorLog[$this->errorCounter] = "Product Description Missing for <b>$id</b>.";
|
103 |
-
$this->errorCounter++;
|
104 |
-
}
|
105 |
-
|
106 |
-
if (!array_key_exists('link', $product)) {
|
107 |
-
$this->errorLog[$this->errorCounter] = "Product Link Missing for <b>$id</b>.";
|
108 |
-
$this->errorCounter++;
|
109 |
-
}
|
110 |
-
|
111 |
-
if (!array_key_exists('image', $product)) {
|
112 |
-
$this->errorLog[$this->errorCounter] = "Product Image Link Missing for <b>$id</b>.";
|
113 |
-
$this->errorCounter++;
|
114 |
-
}
|
115 |
-
|
116 |
-
if (!array_key_exists('condition', $product)) {
|
117 |
-
$this->errorLog[$this->errorCounter] = "Product Condition Missing for <b>$id</b>.";
|
118 |
-
$this->errorCounter++;
|
119 |
-
}
|
120 |
-
|
121 |
-
}
|
122 |
-
}
|
123 |
-
|
124 |
-
public function returnFinalProduct()
|
125 |
-
{
|
126 |
-
if ($this->rules['feedType'] == 'xml') {
|
127 |
-
return $this->get_feed($this->products);
|
128 |
-
} elseif ($this->rules['feedType'] == 'txt') {
|
129 |
-
return $this->get_txt_feed();
|
130 |
-
} elseif ($this->rules['feedType'] == 'csv') {
|
131 |
-
return $this->get_csv_feed();
|
132 |
-
}
|
133 |
-
return false;
|
134 |
-
}
|
135 |
-
|
136 |
-
public function filterProductValues()
|
137 |
-
{
|
138 |
-
$getProduct = new Woo_Feed_Products();
|
139 |
-
$products = $this->products;
|
140 |
-
|
141 |
-
foreach ($products as $no => $product) {
|
142 |
-
if (array_key_exists('title', $product)) {
|
143 |
-
$id = $product['title'];
|
144 |
-
} else {
|
145 |
-
$id = $product['id'];
|
146 |
-
}
|
147 |
-
|
148 |
-
foreach ($product as $key => $value) {
|
149 |
-
|
150 |
-
switch ($key) {
|
151 |
-
case "id":
|
152 |
-
if (strlen($value) > 50) {
|
153 |
-
$this->errorLog[$this->errorCounter] = "Product id is more that 50 character for $id.";
|
154 |
-
$this->errorCounter++;
|
155 |
-
}
|
156 |
-
break;
|
157 |
-
case "title":
|
158 |
-
if (strlen($value) > 100) {
|
159 |
-
$this->errorLog[$this->errorCounter] = "Product Title is more that 100 character for $id.";
|
160 |
-
$this->errorCounter++;
|
161 |
-
}
|
162 |
-
$this->products[$no][$key] = ucwords($value);
|
163 |
-
break;
|
164 |
-
case "description":
|
165 |
-
if (strlen($value) > 1500) {
|
166 |
-
$this->errorLog[$this->errorCounter] = "Product Description is more that 1500 character for $id.";
|
167 |
-
$this->errorCounter++;
|
168 |
-
}
|
169 |
-
|
170 |
-
$this->products[$no][$key] = strip_tags($value);
|
171 |
-
break;
|
172 |
-
case "short_description":
|
173 |
-
if (strlen($value) > 1500) {
|
174 |
-
$this->errorLog[$this->errorCounter] = "Product Short Description is more that 1500 character for $id.";
|
175 |
-
$this->errorCounter++;
|
176 |
-
}
|
177 |
-
$this->products[$no][$key] = strip_tags($value);
|
178 |
-
break;
|
179 |
-
case "product_type":
|
180 |
-
break;
|
181 |
-
case "link":
|
182 |
-
break;
|
183 |
-
case "image":
|
184 |
-
$this->products[$no][$key] = urlencode($value);
|
185 |
-
break;
|
186 |
-
case "images":
|
187 |
-
break;
|
188 |
-
case "condition":
|
189 |
-
$conditions = array('New', 'Refurbished', 'Used', 'Like New', '3rd Party', 'Open Box', 'OEM', 'Downloadable', 'Import / Grey Market', 'Price w/Plan New', 'Price w/Plan Refurb');
|
190 |
-
if (!in_array($value, $conditions)) {
|
191 |
-
$this->errorLog[$this->errorCounter] = "Product Condition do not containing accepted value for <b>$id</b>.";
|
192 |
-
$this->errorCounter++;
|
193 |
-
}
|
194 |
-
break;
|
195 |
-
case "item_group_id":
|
196 |
-
break;
|
197 |
-
case "sku":
|
198 |
-
break;
|
199 |
-
case "availability":
|
200 |
-
if ($value == 'in stock') {
|
201 |
-
$this->products[$no][$key] = "In Stock";
|
202 |
-
} else if ($value == 'out of stock') {
|
203 |
-
$this->products[$no][$key] = "Out of Stock";
|
204 |
-
}
|
205 |
-
break;
|
206 |
-
case "quantity":
|
207 |
-
break;
|
208 |
-
case "price":
|
209 |
-
break;
|
210 |
-
case "sale_price":
|
211 |
-
break;
|
212 |
-
case "weight":
|
213 |
-
break;
|
214 |
-
case "width":
|
215 |
-
break;
|
216 |
-
case "height":
|
217 |
-
break;
|
218 |
-
case "length":
|
219 |
-
break;
|
220 |
-
case "sale_price_effective_date":
|
221 |
-
$from = $getProduct->sale_price_effective_date($id, '_sale_price_dates_from');
|
222 |
-
$to = $getProduct->sale_price_effective_date($id, '_sale_price_dates_to');
|
223 |
-
if (!empty($from) && !empty($to)) {
|
224 |
-
$from = date('Y-m-d\TH:iO', $from);
|
225 |
-
$to = date('Y-m-d\TH:iO', $to);
|
226 |
-
$this->products[$no]['sale_price_effective_date'] = "$from" . "/" . "$to";
|
227 |
-
} else {
|
228 |
-
$this->errorLog[$this->errorCounter] = "Sale Price Effective Date Missing for <b>$id</b>.";
|
229 |
-
$this->errorCounter++;
|
230 |
-
}
|
231 |
-
break;
|
232 |
-
case "mpn":
|
233 |
-
break;
|
234 |
-
case "gtin":
|
235 |
-
break;
|
236 |
-
case "brand":
|
237 |
-
break;
|
238 |
-
case "color":
|
239 |
-
break;
|
240 |
-
case "size":
|
241 |
-
break;
|
242 |
-
case "current_category":
|
243 |
-
if (substr($value, 0, 12) == "wf_cmapping_") {
|
244 |
-
$parent = $product['item_group_id'];
|
245 |
-
$category = $this->get_category_mapping_value($value, $parent);
|
246 |
-
//unset($this->products[$no][$key]);
|
247 |
-
$this->products[$no][$key] = $category;
|
248 |
-
}
|
249 |
-
break;
|
250 |
-
default:
|
251 |
-
break;
|
252 |
-
}
|
253 |
-
}
|
254 |
-
}
|
255 |
-
}
|
256 |
-
|
257 |
-
public function get_category_mapping_value($mappingName, $parent)
|
258 |
-
{
|
259 |
-
$getValue = unserialize(get_option($mappingName));
|
260 |
-
$mapp = array_reverse($getValue['cmapping'], true);
|
261 |
-
$categories = get_the_terms($parent, 'product_cat');
|
262 |
-
|
263 |
-
foreach ($categories as $key => $category) {
|
264 |
-
if (!empty($mapp[$category->term_id]))
|
265 |
-
return $mapp[$category->term_id];
|
266 |
-
}
|
267 |
-
}
|
268 |
-
|
269 |
-
|
270 |
-
public function mapProductsByRules()
|
271 |
-
{
|
272 |
-
$products = new Woo_Feed_Products(); //$this->woo_feed_get_visible_product();
|
273 |
-
$attributes = $this->rules['attributes'];
|
274 |
-
$prefix = $this->rules['prefix'];
|
275 |
-
$suffix = $this->rules['suffix'];
|
276 |
-
$outputType = $this->rules['output_type'];
|
277 |
-
$limit = $this->rules['limit'];
|
278 |
-
$merchantAttributes = $this->rules['mattributes'];
|
279 |
-
$type = $this->rules['type'];
|
280 |
-
$default = $this->rules['default'];
|
281 |
-
$feedType = $this->rules['feedType'];
|
282 |
-
|
283 |
-
// Map Merchant Attributes and Woo Attributes
|
284 |
-
if (count($merchantAttributes)) {
|
285 |
-
foreach ($merchantAttributes as $key => $attr) {
|
286 |
-
if (!empty($attr) && !empty($attributes[$key])) {
|
287 |
-
if ($type[$key] == 'attribute') {
|
288 |
-
$this->mapping[$attr]['value'] = $attributes[$key];
|
289 |
-
$this->mapping[$attr]['suffix'] = $suffix[$key];
|
290 |
-
$this->mapping[$attr]['prefix'] = $prefix[$key];
|
291 |
-
$this->mapping[$attr]['type'] = $outputType[$key];
|
292 |
-
$this->mapping[$attr]['limit'] = $limit[$key];
|
293 |
-
}
|
294 |
-
} else if (empty($attributes[$key])) {
|
295 |
-
if ($type[$key] == 'pattern') {
|
296 |
-
$this->mapping[$attr]['value'] = "wf_pattern_$default[$key]";
|
297 |
-
$this->mapping[$attr]['suffix'] = $suffix[$key];
|
298 |
-
$this->mapping[$attr]['prefix'] = $prefix[$key];
|
299 |
-
$this->mapping[$attr]['type'] = $outputType[$key];
|
300 |
-
$this->mapping[$attr]['limit'] = $limit[$key];
|
301 |
-
}
|
302 |
-
}
|
303 |
-
}
|
304 |
-
}
|
305 |
-
|
306 |
-
// Make Product feed array according to mapping
|
307 |
-
foreach ($products->woo_feed_get_visible_product() as $key => $value) {
|
308 |
-
$i = 0;
|
309 |
-
foreach ($this->mapping as $attr => $rules) {
|
310 |
-
if (array_key_exists($rules['value'], $value)) {
|
311 |
-
|
312 |
-
$output = $rules['prefix'] . $value[$rules['value']] . " " . $rules['suffix'];
|
313 |
-
// Format According to output type
|
314 |
-
if ($rules['type'] == 2) {
|
315 |
-
$output = strip_tags($output);
|
316 |
-
} elseif ($rules['type'] == 3) {
|
317 |
-
$output = absint($output);
|
318 |
-
}
|
319 |
-
// Format According to output limit
|
320 |
-
if (!empty($rules['limit']) && is_numeric($rules['limit'])) {
|
321 |
-
$output = substr($output, 0, $rules['limit']);
|
322 |
-
}
|
323 |
-
|
324 |
-
$attr = trim($attr);
|
325 |
-
$this->products[$key][$attr] = trim($output);
|
326 |
-
} else {
|
327 |
-
if (!empty($default[$i])) {
|
328 |
-
$output = $rules['prefix'] . str_replace("wf_pattern_", "", $rules['value']) . " " . $rules['suffix'];
|
329 |
-
if ($rules['type'] == 2) {
|
330 |
-
$output = strip_tags($output);
|
331 |
-
} elseif ($rules['type'] == 3) {
|
332 |
-
$output = absint($output);
|
333 |
-
}
|
334 |
-
// Format According to output limit
|
335 |
-
if (!empty($rules['limit']) && is_numeric($rules['limit'])) {
|
336 |
-
$output = substr($output, 0, $rules['limit']);
|
337 |
-
}
|
338 |
-
|
339 |
-
$attr = trim($attr);
|
340 |
-
$this->products[$key][$attr] = trim($output);
|
341 |
-
}
|
342 |
-
}
|
343 |
-
$i++;
|
344 |
-
}
|
345 |
-
}
|
346 |
-
return $this->products;
|
347 |
-
}
|
348 |
-
|
349 |
-
public function mapAttribute($from, $to, $cdata = false)
|
350 |
-
{
|
351 |
-
$i = 0;
|
352 |
-
foreach ($this->products as $no => $product) {
|
353 |
-
foreach ($product as $key => $value) {
|
354 |
-
if ($key == $from) {
|
355 |
-
unset($this->products[$no][$from]);
|
356 |
-
if ($from == 'images') {
|
357 |
-
$this->products[$no][$to] = $value;
|
358 |
-
} else {
|
359 |
-
$this->products[$no][$to] = $this->formatXMLLine($to, $value, $cdata, true, true);
|
360 |
-
}
|
361 |
-
}
|
362 |
-
}
|
363 |
-
$i++;
|
364 |
-
}
|
365 |
-
}
|
366 |
-
|
367 |
-
function formatXMLLine($attribute, $value, $cdata = false, $stripHTML = true, $utf8encode = true, $space = ' ')
|
368 |
-
{
|
369 |
-
//Make single line for XML
|
370 |
-
$c_leader = '';
|
371 |
-
$c_footer = '';
|
372 |
-
if ($cdata) {
|
373 |
-
$c_leader = '<![CDATA[';
|
374 |
-
$c_footer = ']]>';
|
375 |
-
}
|
376 |
-
//Allow force strip HTML
|
377 |
-
if ($stripHTML)
|
378 |
-
$value = strip_tags(html_entity_decode($value));
|
379 |
-
|
380 |
-
|
381 |
-
if ($utf8encode || $utf8encode == 1) {
|
382 |
-
$value = utf8_encode($value);
|
383 |
-
$attribute = utf8_encode($attribute);
|
384 |
-
}
|
385 |
-
|
386 |
-
|
387 |
-
if (!$cdata)
|
388 |
-
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
|
389 |
-
|
390 |
-
if (gettype($value) == 'array')
|
391 |
-
$value = json_encode($value);
|
392 |
-
|
393 |
-
|
394 |
-
return '
|
395 |
-
' . $space . '<' . $attribute . '>' . $c_leader . $value . $c_footer . '</' . $attribute . '>';
|
396 |
-
}
|
397 |
-
|
398 |
-
function change_key($array, $old_key, $new_key)
|
399 |
-
{
|
400 |
-
foreach ($this->products as $no => $product) {
|
401 |
-
if (!array_key_exists($old_key, $product))
|
402 |
-
return $array;
|
403 |
-
|
404 |
-
$keys = array_keys($array);
|
405 |
-
$keys[array_search($old_key, $keys)] = $new_key;
|
406 |
-
}
|
407 |
-
return array_combine($keys, $array);
|
408 |
-
}
|
409 |
-
|
410 |
-
public function get_feed_header()
|
411 |
-
{
|
412 |
-
$output = '<?xml version="1.0" encoding="UTF-8" ?>
|
413 |
-
<products>';
|
414 |
-
$output .= "\n";
|
415 |
-
return $output;
|
416 |
-
}
|
417 |
-
|
418 |
-
public function get_feed($items)
|
419 |
-
{
|
420 |
-
$feed = "";
|
421 |
-
$feed .= $this->get_feed_header();
|
422 |
-
$feed .= "\n";
|
423 |
-
foreach ($items as $item => $products) {
|
424 |
-
$feed .= " <" . $this->feedWrapper . ">";
|
425 |
-
foreach ($products as $key => $value) {
|
426 |
-
if (!empty($value))
|
427 |
-
$feed .= $value;
|
428 |
-
}
|
429 |
-
$feed .= "\n </" . $this->feedWrapper . ">\n";
|
430 |
-
}
|
431 |
-
$feed .= $this->get_feed_footer();
|
432 |
-
|
433 |
-
return $feed;
|
434 |
-
}
|
435 |
-
|
436 |
-
public function get_feed_footer()
|
437 |
-
{
|
438 |
-
$footer = " </products>";
|
439 |
-
return $footer;
|
440 |
-
}
|
441 |
-
|
442 |
-
public function get_txt_feed()
|
443 |
-
{
|
444 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
445 |
-
$headers = array_keys($this->products[0]);
|
446 |
-
$feed[] = $headers;
|
447 |
-
foreach ($this->products as $no => $product) {
|
448 |
-
$row = array();
|
449 |
-
foreach ($headers as $key => $header) {
|
450 |
-
$row[] = $product[$header];
|
451 |
-
}
|
452 |
-
$feed[] = $row;
|
453 |
-
}
|
454 |
-
$str = "";
|
455 |
-
foreach ($feed as $fields) {
|
456 |
-
$str .= implode("\t", $fields) . "\n";
|
457 |
-
}
|
458 |
-
return $str;
|
459 |
-
}
|
460 |
-
return false;
|
461 |
-
}
|
462 |
-
|
463 |
-
public function get_csv_feed()
|
464 |
-
{
|
465 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
466 |
-
$headers = array_keys($this->products[0]);
|
467 |
-
$feed[] = $headers;
|
468 |
-
foreach ($this->products as $no => $product) {
|
469 |
-
$row = array();
|
470 |
-
foreach ($headers as $key => $header) {
|
471 |
-
$row[] = $product[$header];
|
472 |
-
}
|
473 |
-
$feed[] = $row;
|
474 |
-
}
|
475 |
-
|
476 |
-
return $feed;
|
477 |
-
}
|
478 |
-
return false;
|
479 |
-
}
|
480 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
|
4 |
+
class Pricegrabber
|
5 |
+
{
|
6 |
+
|
7 |
+
public $products;
|
8 |
+
|
9 |
+
public $rules;
|
10 |
+
|
11 |
+
public $mapping;
|
12 |
+
|
13 |
+
public $errorLog;
|
14 |
+
public $errorCounter = 0;
|
15 |
+
|
16 |
+
private $filteredProduct;
|
17 |
+
private $feedWrapper = 'item';
|
18 |
+
|
19 |
+
public function __construct($feedRule)
|
20 |
+
{
|
21 |
+
$this->rules = $feedRule;
|
22 |
+
$this->mapProductsByRules();
|
23 |
+
$this->formatRequiredField();
|
24 |
+
$this->filterProductValues();
|
25 |
+
if ($this->rules['feedType'] == 'xml') {
|
26 |
+
$this->mapAttributeForXML();
|
27 |
+
} else {
|
28 |
+
$this->mapAttributeForCSVTEXT();
|
29 |
+
}
|
30 |
+
}
|
31 |
+
|
32 |
+
public function mapAttributeForXML()
|
33 |
+
{
|
34 |
+
//Basic product information
|
35 |
+
|
36 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
37 |
+
foreach ($this->products as $key => $values) {
|
38 |
+
foreach ($values as $attr => $value) {
|
39 |
+
$this->products[$key][$attr] = $this->formatXMLLine($attr, $value, true, true, true);
|
40 |
+
}
|
41 |
+
}
|
42 |
+
}
|
43 |
+
}
|
44 |
+
|
45 |
+
|
46 |
+
public function mapAttributeForCSVTEXT()
|
47 |
+
{
|
48 |
+
//Basic product information
|
49 |
+
|
50 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
51 |
+
foreach ($this->products as $key => $values) {
|
52 |
+
foreach ($values as $attr => $value) {
|
53 |
+
//Allow force strip HTML
|
54 |
+
|
55 |
+
$value = strip_tags(html_entity_decode($value));
|
56 |
+
|
57 |
+
$value = utf8_encode($value);
|
58 |
+
$attr = utf8_encode($attr);
|
59 |
+
|
60 |
+
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
|
61 |
+
|
62 |
+
if (gettype($value) == 'array')
|
63 |
+
$value = json_encode($value);
|
64 |
+
|
65 |
+
$this->products[$key][$attr] = $value;
|
66 |
+
}
|
67 |
+
}
|
68 |
+
}
|
69 |
+
}
|
70 |
+
|
71 |
+
public function formatRequiredField()
|
72 |
+
{
|
73 |
+
foreach ($this->products as $no => $product) {
|
74 |
+
$upn = 0;
|
75 |
+
if (array_key_exists('title', $product)) {
|
76 |
+
$id = $product['title'];
|
77 |
+
} else {
|
78 |
+
$id = $product['id'];
|
79 |
+
}
|
80 |
+
foreach ($product as $key => $value) {
|
81 |
+
if ($key == 'mpn' || $key == 'gtin') {
|
82 |
+
$upn++;
|
83 |
+
}
|
84 |
+
}
|
85 |
+
|
86 |
+
if (!array_key_exists('title', $product)) {
|
87 |
+
$this->errorLog[$this->errorCounter] = "Product Title Missing for <b>$id</b>.";
|
88 |
+
$this->errorCounter++;
|
89 |
+
}
|
90 |
+
|
91 |
+
if (!array_key_exists('id', $product)) {
|
92 |
+
$this->errorLog[$this->errorCounter] = "Product Id Missing for <b>$id</b>.";
|
93 |
+
$this->errorCounter++;
|
94 |
+
}
|
95 |
+
|
96 |
+
if (!array_key_exists('brand', $product)) {
|
97 |
+
$this->errorLog[$this->errorCounter] = "Product Brand Missing for <b>$id</b>.";
|
98 |
+
$this->errorCounter++;
|
99 |
+
}
|
100 |
+
|
101 |
+
if (!array_key_exists('description', $product)) {
|
102 |
+
$this->errorLog[$this->errorCounter] = "Product Description Missing for <b>$id</b>.";
|
103 |
+
$this->errorCounter++;
|
104 |
+
}
|
105 |
+
|
106 |
+
if (!array_key_exists('link', $product)) {
|
107 |
+
$this->errorLog[$this->errorCounter] = "Product Link Missing for <b>$id</b>.";
|
108 |
+
$this->errorCounter++;
|
109 |
+
}
|
110 |
+
|
111 |
+
if (!array_key_exists('image', $product)) {
|
112 |
+
$this->errorLog[$this->errorCounter] = "Product Image Link Missing for <b>$id</b>.";
|
113 |
+
$this->errorCounter++;
|
114 |
+
}
|
115 |
+
|
116 |
+
if (!array_key_exists('condition', $product)) {
|
117 |
+
$this->errorLog[$this->errorCounter] = "Product Condition Missing for <b>$id</b>.";
|
118 |
+
$this->errorCounter++;
|
119 |
+
}
|
120 |
+
|
121 |
+
}
|
122 |
+
}
|
123 |
+
|
124 |
+
public function returnFinalProduct()
|
125 |
+
{
|
126 |
+
if ($this->rules['feedType'] == 'xml') {
|
127 |
+
return $this->get_feed($this->products);
|
128 |
+
} elseif ($this->rules['feedType'] == 'txt') {
|
129 |
+
return $this->get_txt_feed();
|
130 |
+
} elseif ($this->rules['feedType'] == 'csv') {
|
131 |
+
return $this->get_csv_feed();
|
132 |
+
}
|
133 |
+
return false;
|
134 |
+
}
|
135 |
+
|
136 |
+
public function filterProductValues()
|
137 |
+
{
|
138 |
+
$getProduct = new Woo_Feed_Products();
|
139 |
+
$products = $this->products;
|
140 |
+
|
141 |
+
foreach ($products as $no => $product) {
|
142 |
+
if (array_key_exists('title', $product)) {
|
143 |
+
$id = $product['title'];
|
144 |
+
} else {
|
145 |
+
$id = $product['id'];
|
146 |
+
}
|
147 |
+
|
148 |
+
foreach ($product as $key => $value) {
|
149 |
+
|
150 |
+
switch ($key) {
|
151 |
+
case "id":
|
152 |
+
if (strlen($value) > 50) {
|
153 |
+
$this->errorLog[$this->errorCounter] = "Product id is more that 50 character for $id.";
|
154 |
+
$this->errorCounter++;
|
155 |
+
}
|
156 |
+
break;
|
157 |
+
case "title":
|
158 |
+
if (strlen($value) > 100) {
|
159 |
+
$this->errorLog[$this->errorCounter] = "Product Title is more that 100 character for $id.";
|
160 |
+
$this->errorCounter++;
|
161 |
+
}
|
162 |
+
$this->products[$no][$key] = ucwords($value);
|
163 |
+
break;
|
164 |
+
case "description":
|
165 |
+
if (strlen($value) > 1500) {
|
166 |
+
$this->errorLog[$this->errorCounter] = "Product Description is more that 1500 character for $id.";
|
167 |
+
$this->errorCounter++;
|
168 |
+
}
|
169 |
+
|
170 |
+
$this->products[$no][$key] = strip_tags($value);
|
171 |
+
break;
|
172 |
+
case "short_description":
|
173 |
+
if (strlen($value) > 1500) {
|
174 |
+
$this->errorLog[$this->errorCounter] = "Product Short Description is more that 1500 character for $id.";
|
175 |
+
$this->errorCounter++;
|
176 |
+
}
|
177 |
+
$this->products[$no][$key] = strip_tags($value);
|
178 |
+
break;
|
179 |
+
case "product_type":
|
180 |
+
break;
|
181 |
+
case "link":
|
182 |
+
break;
|
183 |
+
case "image":
|
184 |
+
$this->products[$no][$key] = urlencode($value);
|
185 |
+
break;
|
186 |
+
case "images":
|
187 |
+
break;
|
188 |
+
case "condition":
|
189 |
+
$conditions = array('New', 'Refurbished', 'Used', 'Like New', '3rd Party', 'Open Box', 'OEM', 'Downloadable', 'Import / Grey Market', 'Price w/Plan New', 'Price w/Plan Refurb');
|
190 |
+
if (!in_array($value, $conditions)) {
|
191 |
+
$this->errorLog[$this->errorCounter] = "Product Condition do not containing accepted value for <b>$id</b>.";
|
192 |
+
$this->errorCounter++;
|
193 |
+
}
|
194 |
+
break;
|
195 |
+
case "item_group_id":
|
196 |
+
break;
|
197 |
+
case "sku":
|
198 |
+
break;
|
199 |
+
case "availability":
|
200 |
+
if ($value == 'in stock') {
|
201 |
+
$this->products[$no][$key] = "In Stock";
|
202 |
+
} else if ($value == 'out of stock') {
|
203 |
+
$this->products[$no][$key] = "Out of Stock";
|
204 |
+
}
|
205 |
+
break;
|
206 |
+
case "quantity":
|
207 |
+
break;
|
208 |
+
case "price":
|
209 |
+
break;
|
210 |
+
case "sale_price":
|
211 |
+
break;
|
212 |
+
case "weight":
|
213 |
+
break;
|
214 |
+
case "width":
|
215 |
+
break;
|
216 |
+
case "height":
|
217 |
+
break;
|
218 |
+
case "length":
|
219 |
+
break;
|
220 |
+
case "sale_price_effective_date":
|
221 |
+
$from = $getProduct->sale_price_effective_date($id, '_sale_price_dates_from');
|
222 |
+
$to = $getProduct->sale_price_effective_date($id, '_sale_price_dates_to');
|
223 |
+
if (!empty($from) && !empty($to)) {
|
224 |
+
$from = date('Y-m-d\TH:iO', $from);
|
225 |
+
$to = date('Y-m-d\TH:iO', $to);
|
226 |
+
$this->products[$no]['sale_price_effective_date'] = "$from" . "/" . "$to";
|
227 |
+
} else {
|
228 |
+
$this->errorLog[$this->errorCounter] = "Sale Price Effective Date Missing for <b>$id</b>.";
|
229 |
+
$this->errorCounter++;
|
230 |
+
}
|
231 |
+
break;
|
232 |
+
case "mpn":
|
233 |
+
break;
|
234 |
+
case "gtin":
|
235 |
+
break;
|
236 |
+
case "brand":
|
237 |
+
break;
|
238 |
+
case "color":
|
239 |
+
break;
|
240 |
+
case "size":
|
241 |
+
break;
|
242 |
+
case "current_category":
|
243 |
+
if (substr($value, 0, 12) == "wf_cmapping_") {
|
244 |
+
$parent = $product['item_group_id'];
|
245 |
+
$category = $this->get_category_mapping_value($value, $parent);
|
246 |
+
//unset($this->products[$no][$key]);
|
247 |
+
$this->products[$no][$key] = $category;
|
248 |
+
}
|
249 |
+
break;
|
250 |
+
default:
|
251 |
+
break;
|
252 |
+
}
|
253 |
+
}
|
254 |
+
}
|
255 |
+
}
|
256 |
+
|
257 |
+
public function get_category_mapping_value($mappingName, $parent)
|
258 |
+
{
|
259 |
+
$getValue = unserialize(get_option($mappingName));
|
260 |
+
$mapp = array_reverse($getValue['cmapping'], true);
|
261 |
+
$categories = get_the_terms($parent, 'product_cat');
|
262 |
+
|
263 |
+
foreach ($categories as $key => $category) {
|
264 |
+
if (!empty($mapp[$category->term_id]))
|
265 |
+
return $mapp[$category->term_id];
|
266 |
+
}
|
267 |
+
}
|
268 |
+
|
269 |
+
|
270 |
+
public function mapProductsByRules()
|
271 |
+
{
|
272 |
+
$products = new Woo_Feed_Products(); //$this->woo_feed_get_visible_product();
|
273 |
+
$attributes = $this->rules['attributes'];
|
274 |
+
$prefix = $this->rules['prefix'];
|
275 |
+
$suffix = $this->rules['suffix'];
|
276 |
+
$outputType = $this->rules['output_type'];
|
277 |
+
$limit = $this->rules['limit'];
|
278 |
+
$merchantAttributes = $this->rules['mattributes'];
|
279 |
+
$type = $this->rules['type'];
|
280 |
+
$default = $this->rules['default'];
|
281 |
+
$feedType = $this->rules['feedType'];
|
282 |
+
|
283 |
+
// Map Merchant Attributes and Woo Attributes
|
284 |
+
if (count($merchantAttributes)) {
|
285 |
+
foreach ($merchantAttributes as $key => $attr) {
|
286 |
+
if (!empty($attr) && !empty($attributes[$key])) {
|
287 |
+
if ($type[$key] == 'attribute') {
|
288 |
+
$this->mapping[$attr]['value'] = $attributes[$key];
|
289 |
+
$this->mapping[$attr]['suffix'] = $suffix[$key];
|
290 |
+
$this->mapping[$attr]['prefix'] = $prefix[$key];
|
291 |
+
$this->mapping[$attr]['type'] = $outputType[$key];
|
292 |
+
$this->mapping[$attr]['limit'] = $limit[$key];
|
293 |
+
}
|
294 |
+
} else if (empty($attributes[$key])) {
|
295 |
+
if ($type[$key] == 'pattern') {
|
296 |
+
$this->mapping[$attr]['value'] = "wf_pattern_$default[$key]";
|
297 |
+
$this->mapping[$attr]['suffix'] = $suffix[$key];
|
298 |
+
$this->mapping[$attr]['prefix'] = $prefix[$key];
|
299 |
+
$this->mapping[$attr]['type'] = $outputType[$key];
|
300 |
+
$this->mapping[$attr]['limit'] = $limit[$key];
|
301 |
+
}
|
302 |
+
}
|
303 |
+
}
|
304 |
+
}
|
305 |
+
|
306 |
+
// Make Product feed array according to mapping
|
307 |
+
foreach ($products->woo_feed_get_visible_product() as $key => $value) {
|
308 |
+
$i = 0;
|
309 |
+
foreach ($this->mapping as $attr => $rules) {
|
310 |
+
if (array_key_exists($rules['value'], $value)) {
|
311 |
+
|
312 |
+
$output = $rules['prefix'] . $value[$rules['value']] . " " . $rules['suffix'];
|
313 |
+
// Format According to output type
|
314 |
+
if ($rules['type'] == 2) {
|
315 |
+
$output = strip_tags($output);
|
316 |
+
} elseif ($rules['type'] == 3) {
|
317 |
+
$output = absint($output);
|
318 |
+
}
|
319 |
+
// Format According to output limit
|
320 |
+
if (!empty($rules['limit']) && is_numeric($rules['limit'])) {
|
321 |
+
$output = substr($output, 0, $rules['limit']);
|
322 |
+
}
|
323 |
+
|
324 |
+
$attr = trim($attr);
|
325 |
+
$this->products[$key][$attr] = trim($output);
|
326 |
+
} else {
|
327 |
+
if (!empty($default[$i])) {
|
328 |
+
$output = $rules['prefix'] . str_replace("wf_pattern_", "", $rules['value']) . " " . $rules['suffix'];
|
329 |
+
if ($rules['type'] == 2) {
|
330 |
+
$output = strip_tags($output);
|
331 |
+
} elseif ($rules['type'] == 3) {
|
332 |
+
$output = absint($output);
|
333 |
+
}
|
334 |
+
// Format According to output limit
|
335 |
+
if (!empty($rules['limit']) && is_numeric($rules['limit'])) {
|
336 |
+
$output = substr($output, 0, $rules['limit']);
|
337 |
+
}
|
338 |
+
|
339 |
+
$attr = trim($attr);
|
340 |
+
$this->products[$key][$attr] = trim($output);
|
341 |
+
}
|
342 |
+
}
|
343 |
+
$i++;
|
344 |
+
}
|
345 |
+
}
|
346 |
+
return $this->products;
|
347 |
+
}
|
348 |
+
|
349 |
+
public function mapAttribute($from, $to, $cdata = false)
|
350 |
+
{
|
351 |
+
$i = 0;
|
352 |
+
foreach ($this->products as $no => $product) {
|
353 |
+
foreach ($product as $key => $value) {
|
354 |
+
if ($key == $from) {
|
355 |
+
unset($this->products[$no][$from]);
|
356 |
+
if ($from == 'images') {
|
357 |
+
$this->products[$no][$to] = $value;
|
358 |
+
} else {
|
359 |
+
$this->products[$no][$to] = $this->formatXMLLine($to, $value, $cdata, true, true);
|
360 |
+
}
|
361 |
+
}
|
362 |
+
}
|
363 |
+
$i++;
|
364 |
+
}
|
365 |
+
}
|
366 |
+
|
367 |
+
function formatXMLLine($attribute, $value, $cdata = false, $stripHTML = true, $utf8encode = true, $space = ' ')
|
368 |
+
{
|
369 |
+
//Make single line for XML
|
370 |
+
$c_leader = '';
|
371 |
+
$c_footer = '';
|
372 |
+
if ($cdata) {
|
373 |
+
$c_leader = '<![CDATA[';
|
374 |
+
$c_footer = ']]>';
|
375 |
+
}
|
376 |
+
//Allow force strip HTML
|
377 |
+
if ($stripHTML)
|
378 |
+
$value = strip_tags(html_entity_decode($value));
|
379 |
+
|
380 |
+
|
381 |
+
if ($utf8encode || $utf8encode == 1) {
|
382 |
+
$value = utf8_encode($value);
|
383 |
+
$attribute = utf8_encode($attribute);
|
384 |
+
}
|
385 |
+
|
386 |
+
|
387 |
+
if (!$cdata)
|
388 |
+
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
|
389 |
+
|
390 |
+
if (gettype($value) == 'array')
|
391 |
+
$value = json_encode($value);
|
392 |
+
|
393 |
+
|
394 |
+
return '
|
395 |
+
' . $space . '<' . $attribute . '>' . $c_leader . $value . $c_footer . '</' . $attribute . '>';
|
396 |
+
}
|
397 |
+
|
398 |
+
function change_key($array, $old_key, $new_key)
|
399 |
+
{
|
400 |
+
foreach ($this->products as $no => $product) {
|
401 |
+
if (!array_key_exists($old_key, $product))
|
402 |
+
return $array;
|
403 |
+
|
404 |
+
$keys = array_keys($array);
|
405 |
+
$keys[array_search($old_key, $keys)] = $new_key;
|
406 |
+
}
|
407 |
+
return array_combine($keys, $array);
|
408 |
+
}
|
409 |
+
|
410 |
+
public function get_feed_header()
|
411 |
+
{
|
412 |
+
$output = '<?xml version="1.0" encoding="UTF-8" ?>
|
413 |
+
<products>';
|
414 |
+
$output .= "\n";
|
415 |
+
return $output;
|
416 |
+
}
|
417 |
+
|
418 |
+
public function get_feed($items)
|
419 |
+
{
|
420 |
+
$feed = "";
|
421 |
+
$feed .= $this->get_feed_header();
|
422 |
+
$feed .= "\n";
|
423 |
+
foreach ($items as $item => $products) {
|
424 |
+
$feed .= " <" . $this->feedWrapper . ">";
|
425 |
+
foreach ($products as $key => $value) {
|
426 |
+
if (!empty($value))
|
427 |
+
$feed .= $value;
|
428 |
+
}
|
429 |
+
$feed .= "\n </" . $this->feedWrapper . ">\n";
|
430 |
+
}
|
431 |
+
$feed .= $this->get_feed_footer();
|
432 |
+
|
433 |
+
return $feed;
|
434 |
+
}
|
435 |
+
|
436 |
+
public function get_feed_footer()
|
437 |
+
{
|
438 |
+
$footer = " </products>";
|
439 |
+
return $footer;
|
440 |
+
}
|
441 |
+
|
442 |
+
public function get_txt_feed()
|
443 |
+
{
|
444 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
445 |
+
$headers = array_keys($this->products[0]);
|
446 |
+
$feed[] = $headers;
|
447 |
+
foreach ($this->products as $no => $product) {
|
448 |
+
$row = array();
|
449 |
+
foreach ($headers as $key => $header) {
|
450 |
+
$row[] = $product[$header];
|
451 |
+
}
|
452 |
+
$feed[] = $row;
|
453 |
+
}
|
454 |
+
$str = "";
|
455 |
+
foreach ($feed as $fields) {
|
456 |
+
$str .= implode("\t", $fields) . "\n";
|
457 |
+
}
|
458 |
+
return $str;
|
459 |
+
}
|
460 |
+
return false;
|
461 |
+
}
|
462 |
+
|
463 |
+
public function get_csv_feed()
|
464 |
+
{
|
465 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
466 |
+
$headers = array_keys($this->products[0]);
|
467 |
+
$feed[] = $headers;
|
468 |
+
foreach ($this->products as $no => $product) {
|
469 |
+
$row = array();
|
470 |
+
foreach ($headers as $key => $header) {
|
471 |
+
$row[] = $product[$header];
|
472 |
+
}
|
473 |
+
$feed[] = $row;
|
474 |
+
}
|
475 |
+
|
476 |
+
return $feed;
|
477 |
+
}
|
478 |
+
return false;
|
479 |
+
}
|
480 |
}
|
includes/feeds/class-woo-feed-shopmania.php
CHANGED
@@ -1,468 +1,468 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
|
4 |
-
class Shopmania
|
5 |
-
{
|
6 |
-
|
7 |
-
public $products;
|
8 |
-
|
9 |
-
public $rules;
|
10 |
-
|
11 |
-
public $mapping;
|
12 |
-
|
13 |
-
public $errorLog;
|
14 |
-
public $errorCounter = 0;
|
15 |
-
|
16 |
-
private $filteredProduct;
|
17 |
-
private $feedWrapper = 'product';
|
18 |
-
|
19 |
-
public function __construct($feedRule)
|
20 |
-
{
|
21 |
-
$this->rules = $feedRule;
|
22 |
-
$this->mapProductsByRules();
|
23 |
-
$this->formatRequiredField();
|
24 |
-
$this->filterProductValues();
|
25 |
-
if ($this->rules['feedType'] == 'xml') {
|
26 |
-
$this->mapAttributeForXML();
|
27 |
-
} else {
|
28 |
-
$this->mapAttributeForCSVTEXT();
|
29 |
-
}
|
30 |
-
}
|
31 |
-
|
32 |
-
public function mapAttributeForXML()
|
33 |
-
{
|
34 |
-
//Basic product information
|
35 |
-
|
36 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
37 |
-
foreach ($this->products as $key => $values) {
|
38 |
-
foreach ($values as $attr => $value) {
|
39 |
-
$this->products[$key][$attr] = $this->formatXMLLine($attr, $value, true, true, true);
|
40 |
-
}
|
41 |
-
}
|
42 |
-
}
|
43 |
-
}
|
44 |
-
|
45 |
-
|
46 |
-
public function mapAttributeForCSVTEXT()
|
47 |
-
{
|
48 |
-
//Basic product information
|
49 |
-
|
50 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
51 |
-
foreach ($this->products as $key => $values) {
|
52 |
-
foreach ($values as $attr => $value) {
|
53 |
-
//Allow force strip HTML
|
54 |
-
|
55 |
-
$value = strip_tags(html_entity_decode($value));
|
56 |
-
|
57 |
-
$value = utf8_encode($value);
|
58 |
-
$attr = utf8_encode($attr);
|
59 |
-
|
60 |
-
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
|
61 |
-
|
62 |
-
if (gettype($value) == 'array')
|
63 |
-
$value = json_encode($value);
|
64 |
-
|
65 |
-
$this->products[$key][$attr] = $value;
|
66 |
-
}
|
67 |
-
}
|
68 |
-
}
|
69 |
-
}
|
70 |
-
|
71 |
-
public function formatRequiredField()
|
72 |
-
{
|
73 |
-
foreach ($this->products as $no => $product) {
|
74 |
-
$upn = 0;
|
75 |
-
if (array_key_exists('title', $product)) {
|
76 |
-
$id = $product['title'];
|
77 |
-
} else {
|
78 |
-
$id = $product['id'];
|
79 |
-
}
|
80 |
-
|
81 |
-
if (!array_key_exists('title', $product)) {
|
82 |
-
$this->errorLog[$this->errorCounter] = "Product Title Missing for <b>$id</b>.";
|
83 |
-
$this->errorCounter++;
|
84 |
-
}
|
85 |
-
|
86 |
-
|
87 |
-
if (!array_key_exists('brand', $product)) {
|
88 |
-
$this->errorLog[$this->errorCounter] = "Product Manufacturer Missing for <b>$id</b>.";
|
89 |
-
$this->errorCounter++;
|
90 |
-
}
|
91 |
-
|
92 |
-
if (!array_key_exists('description', $product)) {
|
93 |
-
$this->errorLog[$this->errorCounter] = "Product Description Missing for <b>$id</b>.";
|
94 |
-
$this->errorCounter++;
|
95 |
-
}
|
96 |
-
|
97 |
-
if (!array_key_exists('link', $product)) {
|
98 |
-
$this->errorLog[$this->errorCounter] = "Product Link Missing for <b>$id</b>.";
|
99 |
-
$this->errorCounter++;
|
100 |
-
}
|
101 |
-
|
102 |
-
if (!array_key_exists('image', $product)) {
|
103 |
-
$this->errorLog[$this->errorCounter] = "Product Image Link Missing for <b>$id</b>.";
|
104 |
-
$this->errorCounter++;
|
105 |
-
}
|
106 |
-
|
107 |
-
if (!array_key_exists('condition', $product)) {
|
108 |
-
$this->errorLog[$this->errorCounter] = "Product Condition Missing for <b>$id</b>.";
|
109 |
-
$this->errorCounter++;
|
110 |
-
}
|
111 |
-
|
112 |
-
}
|
113 |
-
}
|
114 |
-
|
115 |
-
public function returnFinalProduct()
|
116 |
-
{
|
117 |
-
if ($this->rules['feedType'] == 'xml') {
|
118 |
-
return $this->get_feed($this->products);
|
119 |
-
} elseif ($this->rules['feedType'] == 'txt') {
|
120 |
-
return $this->get_txt_feed();
|
121 |
-
} elseif ($this->rules['feedType'] == 'csv') {
|
122 |
-
return $this->get_csv_feed();
|
123 |
-
}
|
124 |
-
return false;
|
125 |
-
}
|
126 |
-
|
127 |
-
public function filterProductValues()
|
128 |
-
{
|
129 |
-
$getProduct = new Woo_Feed_Products();
|
130 |
-
$products = $this->products;
|
131 |
-
|
132 |
-
foreach ($products as $no => $product) {
|
133 |
-
if (array_key_exists('title', $product)) {
|
134 |
-
$id = $product['title'];
|
135 |
-
} else {
|
136 |
-
$id = $product['id'];
|
137 |
-
}
|
138 |
-
// echo "<pre>";
|
139 |
-
// print_r($product);
|
140 |
-
foreach ($product as $key => $value) {
|
141 |
-
|
142 |
-
|
143 |
-
switch ($key) {
|
144 |
-
case "id":
|
145 |
-
if (strlen($value) > 50) {
|
146 |
-
$this->errorLog[$this->errorCounter] = "Product id is more that 50 character for $id.";
|
147 |
-
$this->errorCounter++;
|
148 |
-
}
|
149 |
-
break;
|
150 |
-
case "title":
|
151 |
-
if (strlen($value) > 100) {
|
152 |
-
$this->errorLog[$this->errorCounter] = "Product Title is more that 100 character for $id.";
|
153 |
-
$this->errorCounter++;
|
154 |
-
}
|
155 |
-
$this->products[$no][$key] = ucwords($value);
|
156 |
-
break;
|
157 |
-
case "description":
|
158 |
-
if (strlen($value) > 1500) {
|
159 |
-
$this->errorLog[$this->errorCounter] = "Product Description is more that 1500 character for $id.";
|
160 |
-
$this->errorCounter++;
|
161 |
-
}
|
162 |
-
|
163 |
-
$this->products[$no][$key] = strip_tags($value);
|
164 |
-
break;
|
165 |
-
case "short_description":
|
166 |
-
if (strlen($value) > 1500) {
|
167 |
-
$this->errorLog[$this->errorCounter] = "Product Short Description is more that 1500 character for $id.";
|
168 |
-
$this->errorCounter++;
|
169 |
-
}
|
170 |
-
$this->products[$no][$key] = strip_tags($value);
|
171 |
-
break;
|
172 |
-
case "product_type":
|
173 |
-
break;
|
174 |
-
case "link":
|
175 |
-
break;
|
176 |
-
case "image":
|
177 |
-
break;
|
178 |
-
case "images":
|
179 |
-
break;
|
180 |
-
case "condition":
|
181 |
-
break;
|
182 |
-
case "item_group_id":
|
183 |
-
break;
|
184 |
-
case "sku":
|
185 |
-
break;
|
186 |
-
case "Availability":
|
187 |
-
if ($value == 'in stock') {
|
188 |
-
$this->products[$no][$key] = "In Stock";
|
189 |
-
} else {
|
190 |
-
$this->products[$no][$key] = "Out of Stock";
|
191 |
-
}
|
192 |
-
break;
|
193 |
-
case "quantity":
|
194 |
-
break;
|
195 |
-
case "price":
|
196 |
-
break;
|
197 |
-
case "sale_price":
|
198 |
-
break;
|
199 |
-
case "weight":
|
200 |
-
break;
|
201 |
-
case "width":
|
202 |
-
break;
|
203 |
-
case "height":
|
204 |
-
break;
|
205 |
-
case "length":
|
206 |
-
break;
|
207 |
-
case "sale_price_effective_date":
|
208 |
-
$from = $getProduct->sale_price_effective_date($id, '_sale_price_dates_from');
|
209 |
-
$to = $getProduct->sale_price_effective_date($id, '_sale_price_dates_to');
|
210 |
-
if (!empty($from) && !empty($to)) {
|
211 |
-
$from = date('Y-m-d', $from);
|
212 |
-
$to = date('Y-m-d', $to);
|
213 |
-
$this->products[$no]['sale_price_effective_date'] = "$from" . "/" . "$to";
|
214 |
-
} else {
|
215 |
-
$this->errorLog[$this->errorCounter] = "Sale Price Effective Date Missing for <b>$id</b>.";
|
216 |
-
$this->errorCounter++;
|
217 |
-
}
|
218 |
-
break;
|
219 |
-
case "mpn":
|
220 |
-
break;
|
221 |
-
case "gtin":
|
222 |
-
break;
|
223 |
-
case "brand":
|
224 |
-
break;
|
225 |
-
case "color":
|
226 |
-
break;
|
227 |
-
case "size":
|
228 |
-
break;
|
229 |
-
case "current_category":
|
230 |
-
if (substr($value, 0, 12) == "wf_cmapping_") {
|
231 |
-
$parent = $product['item_group_id'];
|
232 |
-
$category = $this->get_category_mapping_value($value, $parent);
|
233 |
-
//unset($this->products[$no][$key]);
|
234 |
-
$this->products[$no][$key] = $category;
|
235 |
-
}
|
236 |
-
break;
|
237 |
-
default:
|
238 |
-
break;
|
239 |
-
}
|
240 |
-
}
|
241 |
-
}
|
242 |
-
}
|
243 |
-
|
244 |
-
public function get_category_mapping_value($mappingName, $parent)
|
245 |
-
{
|
246 |
-
$getValue = unserialize(get_option($mappingName));
|
247 |
-
$mapp = array_reverse($getValue['cmapping'], true);
|
248 |
-
$categories = get_the_terms($parent, 'product_cat');
|
249 |
-
|
250 |
-
foreach ($categories as $key => $category) {
|
251 |
-
if (!empty($mapp[$category->term_id]))
|
252 |
-
return $mapp[$category->term_id];
|
253 |
-
}
|
254 |
-
}
|
255 |
-
|
256 |
-
|
257 |
-
public function mapProductsByRules()
|
258 |
-
{
|
259 |
-
$products = new Woo_Feed_Products(); //$this->woo_feed_get_visible_product();
|
260 |
-
$attributes = $this->rules['attributes'];
|
261 |
-
$prefix = $this->rules['prefix'];
|
262 |
-
$suffix = $this->rules['suffix'];
|
263 |
-
$outputType = $this->rules['output_type'];
|
264 |
-
$limit = $this->rules['limit'];
|
265 |
-
$merchantAttributes = $this->rules['mattributes'];
|
266 |
-
$type = $this->rules['type'];
|
267 |
-
$default = $this->rules['default'];
|
268 |
-
$feedType = $this->rules['feedType'];
|
269 |
-
|
270 |
-
// Map Merchant Attributes and Woo Attributes
|
271 |
-
if (count($merchantAttributes)) {
|
272 |
-
foreach ($merchantAttributes as $key => $attr) {
|
273 |
-
if (!empty($attr) && !empty($attributes[$key])) {
|
274 |
-
if ($type[$key] == 'attribute') {
|
275 |
-
$this->mapping[$attr]['value'] = $attributes[$key];
|
276 |
-
$this->mapping[$attr]['suffix'] = $suffix[$key];
|
277 |
-
$this->mapping[$attr]['prefix'] = $prefix[$key];
|
278 |
-
$this->mapping[$attr]['type'] = $outputType[$key];
|
279 |
-
$this->mapping[$attr]['limit'] = $limit[$key];
|
280 |
-
}
|
281 |
-
} else if (empty($attributes[$key])) {
|
282 |
-
if ($type[$key] == 'pattern') {
|
283 |
-
$this->mapping[$attr]['value'] = "wf_pattern_$default[$key]";
|
284 |
-
$this->mapping[$attr]['suffix'] = $suffix[$key];
|
285 |
-
$this->mapping[$attr]['prefix'] = $prefix[$key];
|
286 |
-
$this->mapping[$attr]['type'] = $outputType[$key];
|
287 |
-
$this->mapping[$attr]['limit'] = $limit[$key];
|
288 |
-
}
|
289 |
-
}
|
290 |
-
}
|
291 |
-
}
|
292 |
-
|
293 |
-
// Make Product feed array according to mapping
|
294 |
-
foreach ($products->woo_feed_get_visible_product() as $key => $value) {
|
295 |
-
$i = 0;
|
296 |
-
foreach ($this->mapping as $attr => $rules) {
|
297 |
-
if (array_key_exists($rules['value'], $value)) {
|
298 |
-
|
299 |
-
$output = $rules['prefix'] . $value[$rules['value']] . " " . $rules['suffix'];
|
300 |
-
// Format According to output type
|
301 |
-
if ($rules['type'] == 2) {
|
302 |
-
$output = strip_tags($output);
|
303 |
-
} elseif ($rules['type'] == 3) {
|
304 |
-
$output = absint($output);
|
305 |
-
}
|
306 |
-
// Format According to output limit
|
307 |
-
if (!empty($rules['limit']) && is_numeric($rules['limit'])) {
|
308 |
-
$output = substr($output, 0, $rules['limit']);
|
309 |
-
}
|
310 |
-
$attr = trim($attr);
|
311 |
-
$this->products[$key][$attr] = trim($output);
|
312 |
-
} else {
|
313 |
-
if (!empty($default[$i])) {
|
314 |
-
$output = $rules['prefix'] . str_replace("wf_pattern_", "", $rules['value']) . " " . $rules['suffix'];
|
315 |
-
if ($rules['type'] == 2) {
|
316 |
-
$output = strip_tags($output);
|
317 |
-
} elseif ($rules['type'] == 3) {
|
318 |
-
$output = absint($output);
|
319 |
-
}
|
320 |
-
// Format According to output limit
|
321 |
-
if (!empty($rules['limit']) && is_numeric($rules['limit'])) {
|
322 |
-
$output = substr($output, 0, $rules['limit']);
|
323 |
-
}
|
324 |
-
$attr = trim($attr);
|
325 |
-
$this->products[$key][$attr] = trim($output);
|
326 |
-
}
|
327 |
-
}
|
328 |
-
$i++;
|
329 |
-
}
|
330 |
-
}
|
331 |
-
|
332 |
-
|
333 |
-
return $this->products;
|
334 |
-
}
|
335 |
-
|
336 |
-
public function mapAttribute($from, $to, $cdata = false)
|
337 |
-
{
|
338 |
-
$i = 0;
|
339 |
-
foreach ($this->products as $no => $product) {
|
340 |
-
foreach ($product as $key => $value) {
|
341 |
-
if ($key == $from) {
|
342 |
-
unset($this->products[$no][$from]);
|
343 |
-
if ($from == 'images') {
|
344 |
-
$this->products[$no][$to] = $value;
|
345 |
-
} else {
|
346 |
-
$this->products[$no][$to] = $this->formatXMLLine($to, $value, $cdata, true, true);
|
347 |
-
}
|
348 |
-
|
349 |
-
}
|
350 |
-
}
|
351 |
-
$i++;
|
352 |
-
}
|
353 |
-
}
|
354 |
-
|
355 |
-
function formatXMLLine($attribute, $value, $cdata = false, $stripHTML = true, $utf8encode = true, $space = ' ')
|
356 |
-
{
|
357 |
-
//Make single line for XML
|
358 |
-
$c_leader = '';
|
359 |
-
$c_footer = '';
|
360 |
-
if ($cdata) {
|
361 |
-
$c_leader = '<![CDATA[';
|
362 |
-
$c_footer = ']]>';
|
363 |
-
}
|
364 |
-
//Allow force strip HTML
|
365 |
-
if ($stripHTML)
|
366 |
-
$value = strip_tags(html_entity_decode($value));
|
367 |
-
|
368 |
-
|
369 |
-
if ($utf8encode || $utf8encode == 1) {
|
370 |
-
$value = utf8_encode($value);
|
371 |
-
$attribute = utf8_encode($attribute);
|
372 |
-
}
|
373 |
-
|
374 |
-
|
375 |
-
if (!$cdata)
|
376 |
-
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
|
377 |
-
|
378 |
-
if (gettype($value) == 'array')
|
379 |
-
$value = json_encode($value);
|
380 |
-
|
381 |
-
|
382 |
-
return '
|
383 |
-
' . $space . '<' . $attribute . '>' . $c_leader . $value . $c_footer . '</' . $attribute . '>';
|
384 |
-
}
|
385 |
-
|
386 |
-
function change_key($array, $old_key, $new_key)
|
387 |
-
{
|
388 |
-
foreach ($this->products as $no => $product) {
|
389 |
-
if (!array_key_exists($old_key, $product))
|
390 |
-
return $array;
|
391 |
-
|
392 |
-
$keys = array_keys($array);
|
393 |
-
$keys[array_search($old_key, $keys)] = $new_key;
|
394 |
-
}
|
395 |
-
return array_combine($keys, $array);
|
396 |
-
}
|
397 |
-
|
398 |
-
public function get_feed_header()
|
399 |
-
{
|
400 |
-
$output = '<?xml version="1.0" encoding="UTF-8" ?>
|
401 |
-
<products>';
|
402 |
-
$output .= "\n";
|
403 |
-
return $output;
|
404 |
-
}
|
405 |
-
|
406 |
-
public function get_feed($items)
|
407 |
-
{
|
408 |
-
$feed = "";
|
409 |
-
$feed .= $this->get_feed_header();
|
410 |
-
$feed .= "\n";
|
411 |
-
foreach ($items as $item => $products) {
|
412 |
-
$feed .= " <" . $this->feedWrapper . ">";
|
413 |
-
foreach ($products as $key => $value) {
|
414 |
-
if (!empty($value))
|
415 |
-
$feed .= $value;
|
416 |
-
}
|
417 |
-
$feed .= "\n </" . $this->feedWrapper . ">\n";
|
418 |
-
}
|
419 |
-
$feed .= $this->get_feed_footer();
|
420 |
-
|
421 |
-
return $feed;
|
422 |
-
}
|
423 |
-
|
424 |
-
public function get_feed_footer()
|
425 |
-
{
|
426 |
-
$footer = " </products>";
|
427 |
-
return $footer;
|
428 |
-
}
|
429 |
-
|
430 |
-
public function get_txt_feed()
|
431 |
-
{
|
432 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
433 |
-
$headers = array_keys($this->products[0]);
|
434 |
-
$feed[] = $headers;
|
435 |
-
foreach ($this->products as $no => $product) {
|
436 |
-
$row = array();
|
437 |
-
foreach ($headers as $key => $header) {
|
438 |
-
$row[] = $product[$header];
|
439 |
-
}
|
440 |
-
$feed[] = $row;
|
441 |
-
}
|
442 |
-
$str = "";
|
443 |
-
foreach ($feed as $fields) {
|
444 |
-
$str .= implode("\t", $fields) . "\n";
|
445 |
-
}
|
446 |
-
return $str;
|
447 |
-
}
|
448 |
-
return false;
|
449 |
-
}
|
450 |
-
|
451 |
-
public function get_csv_feed()
|
452 |
-
{
|
453 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
454 |
-
$headers = array_keys($this->products[0]);
|
455 |
-
$feed[] = $headers;
|
456 |
-
foreach ($this->products as $no => $product) {
|
457 |
-
$row = array();
|
458 |
-
foreach ($headers as $key => $header) {
|
459 |
-
$row[] = $product[$header];
|
460 |
-
}
|
461 |
-
$feed[] = $row;
|
462 |
-
}
|
463 |
-
|
464 |
-
return $feed;
|
465 |
-
}
|
466 |
-
return false;
|
467 |
-
}
|
468 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
|
4 |
+
class Shopmania
|
5 |
+
{
|
6 |
+
|
7 |
+
public $products;
|
8 |
+
|
9 |
+
public $rules;
|
10 |
+
|
11 |
+
public $mapping;
|
12 |
+
|
13 |
+
public $errorLog;
|
14 |
+
public $errorCounter = 0;
|
15 |
+
|
16 |
+
private $filteredProduct;
|
17 |
+
private $feedWrapper = 'product';
|
18 |
+
|
19 |
+
public function __construct($feedRule)
|
20 |
+
{
|
21 |
+
$this->rules = $feedRule;
|
22 |
+
$this->mapProductsByRules();
|
23 |
+
$this->formatRequiredField();
|
24 |
+
$this->filterProductValues();
|
25 |
+
if ($this->rules['feedType'] == 'xml') {
|
26 |
+
$this->mapAttributeForXML();
|
27 |
+
} else {
|
28 |
+
$this->mapAttributeForCSVTEXT();
|
29 |
+
}
|
30 |
+
}
|
31 |
+
|
32 |
+
public function mapAttributeForXML()
|
33 |
+
{
|
34 |
+
//Basic product information
|
35 |
+
|
36 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
37 |
+
foreach ($this->products as $key => $values) {
|
38 |
+
foreach ($values as $attr => $value) {
|
39 |
+
$this->products[$key][$attr] = $this->formatXMLLine($attr, $value, true, true, true);
|
40 |
+
}
|
41 |
+
}
|
42 |
+
}
|
43 |
+
}
|
44 |
+
|
45 |
+
|
46 |
+
public function mapAttributeForCSVTEXT()
|
47 |
+
{
|
48 |
+
//Basic product information
|
49 |
+
|
50 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
51 |
+
foreach ($this->products as $key => $values) {
|
52 |
+
foreach ($values as $attr => $value) {
|
53 |
+
//Allow force strip HTML
|
54 |
+
|
55 |
+
$value = strip_tags(html_entity_decode($value));
|
56 |
+
|
57 |
+
$value = utf8_encode($value);
|
58 |
+
$attr = utf8_encode($attr);
|
59 |
+
|
60 |
+
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
|
61 |
+
|
62 |
+
if (gettype($value) == 'array')
|
63 |
+
$value = json_encode($value);
|
64 |
+
|
65 |
+
$this->products[$key][$attr] = $value;
|
66 |
+
}
|
67 |
+
}
|
68 |
+
}
|
69 |
+
}
|
70 |
+
|
71 |
+
public function formatRequiredField()
|
72 |
+
{
|
73 |
+
foreach ($this->products as $no => $product) {
|
74 |
+
$upn = 0;
|
75 |
+
if (array_key_exists('title', $product)) {
|
76 |
+
$id = $product['title'];
|
77 |
+
} else {
|
78 |
+
$id = $product['id'];
|
79 |
+
}
|
80 |
+
|
81 |
+
if (!array_key_exists('title', $product)) {
|
82 |
+
$this->errorLog[$this->errorCounter] = "Product Title Missing for <b>$id</b>.";
|
83 |
+
$this->errorCounter++;
|
84 |
+
}
|
85 |
+
|
86 |
+
|
87 |
+
if (!array_key_exists('brand', $product)) {
|
88 |
+
$this->errorLog[$this->errorCounter] = "Product Manufacturer Missing for <b>$id</b>.";
|
89 |
+
$this->errorCounter++;
|
90 |
+
}
|
91 |
+
|
92 |
+
if (!array_key_exists('description', $product)) {
|
93 |
+
$this->errorLog[$this->errorCounter] = "Product Description Missing for <b>$id</b>.";
|
94 |
+
$this->errorCounter++;
|
95 |
+
}
|
96 |
+
|
97 |
+
if (!array_key_exists('link', $product)) {
|
98 |
+
$this->errorLog[$this->errorCounter] = "Product Link Missing for <b>$id</b>.";
|
99 |
+
$this->errorCounter++;
|
100 |
+
}
|
101 |
+
|
102 |
+
if (!array_key_exists('image', $product)) {
|
103 |
+
$this->errorLog[$this->errorCounter] = "Product Image Link Missing for <b>$id</b>.";
|
104 |
+
$this->errorCounter++;
|
105 |
+
}
|
106 |
+
|
107 |
+
if (!array_key_exists('condition', $product)) {
|
108 |
+
$this->errorLog[$this->errorCounter] = "Product Condition Missing for <b>$id</b>.";
|
109 |
+
$this->errorCounter++;
|
110 |
+
}
|
111 |
+
|
112 |
+
}
|
113 |
+
}
|
114 |
+
|
115 |
+
public function returnFinalProduct()
|
116 |
+
{
|
117 |
+
if ($this->rules['feedType'] == 'xml') {
|
118 |
+
return $this->get_feed($this->products);
|
119 |
+
} elseif ($this->rules['feedType'] == 'txt') {
|
120 |
+
return $this->get_txt_feed();
|
121 |
+
} elseif ($this->rules['feedType'] == 'csv') {
|
122 |
+
return $this->get_csv_feed();
|
123 |
+
}
|
124 |
+
return false;
|
125 |
+
}
|
126 |
+
|
127 |
+
public function filterProductValues()
|
128 |
+
{
|
129 |
+
$getProduct = new Woo_Feed_Products();
|
130 |
+
$products = $this->products;
|
131 |
+
|
132 |
+
foreach ($products as $no => $product) {
|
133 |
+
if (array_key_exists('title', $product)) {
|
134 |
+
$id = $product['title'];
|
135 |
+
} else {
|
136 |
+
$id = $product['id'];
|
137 |
+
}
|
138 |
+
// echo "<pre>";
|
139 |
+
// print_r($product);
|
140 |
+
foreach ($product as $key => $value) {
|
141 |
+
|
142 |
+
|
143 |
+
switch ($key) {
|
144 |
+
case "id":
|
145 |
+
if (strlen($value) > 50) {
|
146 |
+
$this->errorLog[$this->errorCounter] = "Product id is more that 50 character for $id.";
|
147 |
+
$this->errorCounter++;
|
148 |
+
}
|
149 |
+
break;
|
150 |
+
case "title":
|
151 |
+
if (strlen($value) > 100) {
|
152 |
+
$this->errorLog[$this->errorCounter] = "Product Title is more that 100 character for $id.";
|
153 |
+
$this->errorCounter++;
|
154 |
+
}
|
155 |
+
$this->products[$no][$key] = ucwords($value);
|
156 |
+
break;
|
157 |
+
case "description":
|
158 |
+
if (strlen($value) > 1500) {
|
159 |
+
$this->errorLog[$this->errorCounter] = "Product Description is more that 1500 character for $id.";
|
160 |
+
$this->errorCounter++;
|
161 |
+
}
|
162 |
+
|
163 |
+
$this->products[$no][$key] = strip_tags($value);
|
164 |
+
break;
|
165 |
+
case "short_description":
|
166 |
+
if (strlen($value) > 1500) {
|
167 |
+
$this->errorLog[$this->errorCounter] = "Product Short Description is more that 1500 character for $id.";
|
168 |
+
$this->errorCounter++;
|
169 |
+
}
|
170 |
+
$this->products[$no][$key] = strip_tags($value);
|
171 |
+
break;
|
172 |
+
case "product_type":
|
173 |
+
break;
|
174 |
+
case "link":
|
175 |
+
break;
|
176 |
+
case "image":
|
177 |
+
break;
|
178 |
+
case "images":
|
179 |
+
break;
|
180 |
+
case "condition":
|
181 |
+
break;
|
182 |
+
case "item_group_id":
|
183 |
+
break;
|
184 |
+
case "sku":
|
185 |
+
break;
|
186 |
+
case "Availability":
|
187 |
+
if ($value == 'in stock') {
|
188 |
+
$this->products[$no][$key] = "In Stock";
|
189 |
+
} else {
|
190 |
+
$this->products[$no][$key] = "Out of Stock";
|
191 |
+
}
|
192 |
+
break;
|
193 |
+
case "quantity":
|
194 |
+
break;
|
195 |
+
case "price":
|
196 |
+
break;
|
197 |
+
case "sale_price":
|
198 |
+
break;
|
199 |
+
case "weight":
|
200 |
+
break;
|
201 |
+
case "width":
|
202 |
+
break;
|
203 |
+
case "height":
|
204 |
+
break;
|
205 |
+
case "length":
|
206 |
+
break;
|
207 |
+
case "sale_price_effective_date":
|
208 |
+
$from = $getProduct->sale_price_effective_date($id, '_sale_price_dates_from');
|
209 |
+
$to = $getProduct->sale_price_effective_date($id, '_sale_price_dates_to');
|
210 |
+
if (!empty($from) && !empty($to)) {
|
211 |
+
$from = date('Y-m-d', $from);
|
212 |
+
$to = date('Y-m-d', $to);
|
213 |
+
$this->products[$no]['sale_price_effective_date'] = "$from" . "/" . "$to";
|
214 |
+
} else {
|
215 |
+
$this->errorLog[$this->errorCounter] = "Sale Price Effective Date Missing for <b>$id</b>.";
|
216 |
+
$this->errorCounter++;
|
217 |
+
}
|
218 |
+
break;
|
219 |
+
case "mpn":
|
220 |
+
break;
|
221 |
+
case "gtin":
|
222 |
+
break;
|
223 |
+
case "brand":
|
224 |
+
break;
|
225 |
+
case "color":
|
226 |
+
break;
|
227 |
+
case "size":
|
228 |
+
break;
|
229 |
+
case "current_category":
|
230 |
+
if (substr($value, 0, 12) == "wf_cmapping_") {
|
231 |
+
$parent = $product['item_group_id'];
|
232 |
+
$category = $this->get_category_mapping_value($value, $parent);
|
233 |
+
//unset($this->products[$no][$key]);
|
234 |
+
$this->products[$no][$key] = $category;
|
235 |
+
}
|
236 |
+
break;
|
237 |
+
default:
|
238 |
+
break;
|
239 |
+
}
|
240 |
+
}
|
241 |
+
}
|
242 |
+
}
|
243 |
+
|
244 |
+
public function get_category_mapping_value($mappingName, $parent)
|
245 |
+
{
|
246 |
+
$getValue = unserialize(get_option($mappingName));
|
247 |
+
$mapp = array_reverse($getValue['cmapping'], true);
|
248 |
+
$categories = get_the_terms($parent, 'product_cat');
|
249 |
+
|
250 |
+
foreach ($categories as $key => $category) {
|
251 |
+
if (!empty($mapp[$category->term_id]))
|
252 |
+
return $mapp[$category->term_id];
|
253 |
+
}
|
254 |
+
}
|
255 |
+
|
256 |
+
|
257 |
+
public function mapProductsByRules()
|
258 |
+
{
|
259 |
+
$products = new Woo_Feed_Products(); //$this->woo_feed_get_visible_product();
|
260 |
+
$attributes = $this->rules['attributes'];
|
261 |
+
$prefix = $this->rules['prefix'];
|
262 |
+
$suffix = $this->rules['suffix'];
|
263 |
+
$outputType = $this->rules['output_type'];
|
264 |
+
$limit = $this->rules['limit'];
|
265 |
+
$merchantAttributes = $this->rules['mattributes'];
|
266 |
+
$type = $this->rules['type'];
|
267 |
+
$default = $this->rules['default'];
|
268 |
+
$feedType = $this->rules['feedType'];
|
269 |
+
|
270 |
+
// Map Merchant Attributes and Woo Attributes
|
271 |
+
if (count($merchantAttributes)) {
|
272 |
+
foreach ($merchantAttributes as $key => $attr) {
|
273 |
+
if (!empty($attr) && !empty($attributes[$key])) {
|
274 |
+
if ($type[$key] == 'attribute') {
|
275 |
+
$this->mapping[$attr]['value'] = $attributes[$key];
|
276 |
+
$this->mapping[$attr]['suffix'] = $suffix[$key];
|
277 |
+
$this->mapping[$attr]['prefix'] = $prefix[$key];
|
278 |
+
$this->mapping[$attr]['type'] = $outputType[$key];
|
279 |
+
$this->mapping[$attr]['limit'] = $limit[$key];
|
280 |
+
}
|
281 |
+
} else if (empty($attributes[$key])) {
|
282 |
+
if ($type[$key] == 'pattern') {
|
283 |
+
$this->mapping[$attr]['value'] = "wf_pattern_$default[$key]";
|
284 |
+
$this->mapping[$attr]['suffix'] = $suffix[$key];
|
285 |
+
$this->mapping[$attr]['prefix'] = $prefix[$key];
|
286 |
+
$this->mapping[$attr]['type'] = $outputType[$key];
|
287 |
+
$this->mapping[$attr]['limit'] = $limit[$key];
|
288 |
+
}
|
289 |
+
}
|
290 |
+
}
|
291 |
+
}
|
292 |
+
|
293 |
+
// Make Product feed array according to mapping
|
294 |
+
foreach ($products->woo_feed_get_visible_product() as $key => $value) {
|
295 |
+
$i = 0;
|
296 |
+
foreach ($this->mapping as $attr => $rules) {
|
297 |
+
if (array_key_exists($rules['value'], $value)) {
|
298 |
+
|
299 |
+
$output = $rules['prefix'] . $value[$rules['value']] . " " . $rules['suffix'];
|
300 |
+
// Format According to output type
|
301 |
+
if ($rules['type'] == 2) {
|
302 |
+
$output = strip_tags($output);
|
303 |
+
} elseif ($rules['type'] == 3) {
|
304 |
+
$output = absint($output);
|
305 |
+
}
|
306 |
+
// Format According to output limit
|
307 |
+
if (!empty($rules['limit']) && is_numeric($rules['limit'])) {
|
308 |
+
$output = substr($output, 0, $rules['limit']);
|
309 |
+
}
|
310 |
+
$attr = trim($attr);
|
311 |
+
$this->products[$key][$attr] = trim($output);
|
312 |
+
} else {
|
313 |
+
if (!empty($default[$i])) {
|
314 |
+
$output = $rules['prefix'] . str_replace("wf_pattern_", "", $rules['value']) . " " . $rules['suffix'];
|
315 |
+
if ($rules['type'] == 2) {
|
316 |
+
$output = strip_tags($output);
|
317 |
+
} elseif ($rules['type'] == 3) {
|
318 |
+
$output = absint($output);
|
319 |
+
}
|
320 |
+
// Format According to output limit
|
321 |
+
if (!empty($rules['limit']) && is_numeric($rules['limit'])) {
|
322 |
+
$output = substr($output, 0, $rules['limit']);
|
323 |
+
}
|
324 |
+
$attr = trim($attr);
|
325 |
+
$this->products[$key][$attr] = trim($output);
|
326 |
+
}
|
327 |
+
}
|
328 |
+
$i++;
|
329 |
+
}
|
330 |
+
}
|
331 |
+
|
332 |
+
|
333 |
+
return $this->products;
|
334 |
+
}
|
335 |
+
|
336 |
+
public function mapAttribute($from, $to, $cdata = false)
|
337 |
+
{
|
338 |
+
$i = 0;
|
339 |
+
foreach ($this->products as $no => $product) {
|
340 |
+
foreach ($product as $key => $value) {
|
341 |
+
if ($key == $from) {
|
342 |
+
unset($this->products[$no][$from]);
|
343 |
+
if ($from == 'images') {
|
344 |
+
$this->products[$no][$to] = $value;
|
345 |
+
} else {
|
346 |
+
$this->products[$no][$to] = $this->formatXMLLine($to, $value, $cdata, true, true);
|
347 |
+
}
|
348 |
+
|
349 |
+
}
|
350 |
+
}
|
351 |
+
$i++;
|
352 |
+
}
|
353 |
+
}
|
354 |
+
|
355 |
+
function formatXMLLine($attribute, $value, $cdata = false, $stripHTML = true, $utf8encode = true, $space = ' ')
|
356 |
+
{
|
357 |
+
//Make single line for XML
|
358 |
+
$c_leader = '';
|
359 |
+
$c_footer = '';
|
360 |
+
if ($cdata) {
|
361 |
+
$c_leader = '<![CDATA[';
|
362 |
+
$c_footer = ']]>';
|
363 |
+
}
|
364 |
+
//Allow force strip HTML
|
365 |
+
if ($stripHTML)
|
366 |
+
$value = strip_tags(html_entity_decode($value));
|
367 |
+
|
368 |
+
|
369 |
+
if ($utf8encode || $utf8encode == 1) {
|
370 |
+
$value = utf8_encode($value);
|
371 |
+
$attribute = utf8_encode($attribute);
|
372 |
+
}
|
373 |
+
|
374 |
+
|
375 |
+
if (!$cdata)
|
376 |
+
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
|
377 |
+
|
378 |
+
if (gettype($value) == 'array')
|
379 |
+
$value = json_encode($value);
|
380 |
+
|
381 |
+
|
382 |
+
return '
|
383 |
+
' . $space . '<' . $attribute . '>' . $c_leader . $value . $c_footer . '</' . $attribute . '>';
|
384 |
+
}
|
385 |
+
|
386 |
+
function change_key($array, $old_key, $new_key)
|
387 |
+
{
|
388 |
+
foreach ($this->products as $no => $product) {
|
389 |
+
if (!array_key_exists($old_key, $product))
|
390 |
+
return $array;
|
391 |
+
|
392 |
+
$keys = array_keys($array);
|
393 |
+
$keys[array_search($old_key, $keys)] = $new_key;
|
394 |
+
}
|
395 |
+
return array_combine($keys, $array);
|
396 |
+
}
|
397 |
+
|
398 |
+
public function get_feed_header()
|
399 |
+
{
|
400 |
+
$output = '<?xml version="1.0" encoding="UTF-8" ?>
|
401 |
+
<products>';
|
402 |
+
$output .= "\n";
|
403 |
+
return $output;
|
404 |
+
}
|
405 |
+
|
406 |
+
public function get_feed($items)
|
407 |
+
{
|
408 |
+
$feed = "";
|
409 |
+
$feed .= $this->get_feed_header();
|
410 |
+
$feed .= "\n";
|
411 |
+
foreach ($items as $item => $products) {
|
412 |
+
$feed .= " <" . $this->feedWrapper . ">";
|
413 |
+
foreach ($products as $key => $value) {
|
414 |
+
if (!empty($value))
|
415 |
+
$feed .= $value;
|
416 |
+
}
|
417 |
+
$feed .= "\n </" . $this->feedWrapper . ">\n";
|
418 |
+
}
|
419 |
+
$feed .= $this->get_feed_footer();
|
420 |
+
|
421 |
+
return $feed;
|
422 |
+
}
|
423 |
+
|
424 |
+
public function get_feed_footer()
|
425 |
+
{
|
426 |
+
$footer = " </products>";
|
427 |
+
return $footer;
|
428 |
+
}
|
429 |
+
|
430 |
+
public function get_txt_feed()
|
431 |
+
{
|
432 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
433 |
+
$headers = array_keys($this->products[0]);
|
434 |
+
$feed[] = $headers;
|
435 |
+
foreach ($this->products as $no => $product) {
|
436 |
+
$row = array();
|
437 |
+
foreach ($headers as $key => $header) {
|
438 |
+
$row[] = $product[$header];
|
439 |
+
}
|
440 |
+
$feed[] = $row;
|
441 |
+
}
|
442 |
+
$str = "";
|
443 |
+
foreach ($feed as $fields) {
|
444 |
+
$str .= implode("\t", $fields) . "\n";
|
445 |
+
}
|
446 |
+
return $str;
|
447 |
+
}
|
448 |
+
return false;
|
449 |
+
}
|
450 |
+
|
451 |
+
public function get_csv_feed()
|
452 |
+
{
|
453 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
454 |
+
$headers = array_keys($this->products[0]);
|
455 |
+
$feed[] = $headers;
|
456 |
+
foreach ($this->products as $no => $product) {
|
457 |
+
$row = array();
|
458 |
+
foreach ($headers as $key => $header) {
|
459 |
+
$row[] = $product[$header];
|
460 |
+
}
|
461 |
+
$feed[] = $row;
|
462 |
+
}
|
463 |
+
|
464 |
+
return $feed;
|
465 |
+
}
|
466 |
+
return false;
|
467 |
+
}
|
468 |
}
|
includes/feeds/class-woo-feed-shopping.php
CHANGED
@@ -1,704 +1,704 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Class Shopping
|
5 |
-
*
|
6 |
-
* Responsible for processing and generating feed for Shopping.com
|
7 |
-
*
|
8 |
-
* @since 1.0.0
|
9 |
-
* @package Shopping
|
10 |
-
*
|
11 |
-
*/
|
12 |
-
class Shopping
|
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 holding feed configuration form values
|
25 |
-
*
|
26 |
-
* @since 1.0.0
|
27 |
-
* @var Shopping $rules Contains feed configuration form values
|
28 |
-
* @access public
|
29 |
-
*/
|
30 |
-
public $rules;
|
31 |
-
|
32 |
-
/**
|
33 |
-
* This variable is responsible for mapping store attributes to merchant attribute
|
34 |
-
*
|
35 |
-
* @since 1.0.0
|
36 |
-
* @var Shopping $mapping Map store attributes to merchant attribute
|
37 |
-
* @access public
|
38 |
-
*/
|
39 |
-
public $mapping;
|
40 |
-
|
41 |
-
/**
|
42 |
-
* This variable is responsible for generate error logs
|
43 |
-
*
|
44 |
-
* @since 1.0.0
|
45 |
-
* @var Shopping $errorLog Generate error logs
|
46 |
-
* @access public
|
47 |
-
*/
|
48 |
-
public $errorLog;
|
49 |
-
|
50 |
-
/**
|
51 |
-
* This variable is responsible for making error number
|
52 |
-
*
|
53 |
-
* @since 1.0.0
|
54 |
-
* @var Shopping $errorCounter Generate error number
|
55 |
-
* @access public
|
56 |
-
*/
|
57 |
-
public $errorCounter;
|
58 |
-
|
59 |
-
/**
|
60 |
-
* Feed Wrapper text for enclosing each product information
|
61 |
-
*
|
62 |
-
* @since 1.0.0
|
63 |
-
* @var Shopping $feedWrapper Feed Wrapper text
|
64 |
-
* @access public
|
65 |
-
*/
|
66 |
-
private $feedWrapper = 'product';
|
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 |
-
$this->errorCounter = 0;
|
79 |
-
$this->rules = $feedRule;
|
80 |
-
$this->mapProductsByRules();
|
81 |
-
$this->formatRequiredField();
|
82 |
-
$this->filterProductValues();
|
83 |
-
if ($this->rules['feedType'] == 'xml') {
|
84 |
-
$this->mapAttributeForXML();
|
85 |
-
} else {
|
86 |
-
$this->mapAttributeForCSVTEXT();
|
87 |
-
}
|
88 |
-
}
|
89 |
-
|
90 |
-
/**
|
91 |
-
* Configure merchant attributes for XML feed
|
92 |
-
*/
|
93 |
-
public function mapAttributeForXML()
|
94 |
-
{
|
95 |
-
//Required Attributes
|
96 |
-
$this->mapAttribute('Unique Merchant SKU', 'Merchant_SKU', true);
|
97 |
-
$this->mapAttribute('Product Name', 'Product_Name', true);
|
98 |
-
$this->mapAttribute('Product URL', 'Product_URL', true);
|
99 |
-
$this->mapAttribute('Image URL', 'Image_URL', true);
|
100 |
-
$this->mapAttribute('Current Price', 'Current_Price', true);
|
101 |
-
$this->mapAttribute('Stock Availability', 'Stock_Availability', true);
|
102 |
-
$this->mapAttribute('Condition', 'Condition', true);
|
103 |
-
$this->mapAttribute('MPN', 'MPN', false);
|
104 |
-
$this->mapAttribute('ISBN', 'ISBN', false);
|
105 |
-
$this->mapAttribute('UPC', 'UPC', false);
|
106 |
-
$this->mapAttribute('EAN', 'EAN', false);
|
107 |
-
|
108 |
-
//Additional Attributes
|
109 |
-
$this->mapAttribute('Shipping Rate', 'Shipping_Rate', false);
|
110 |
-
$this->mapAttribute('Original Price', 'Original_Price', false);
|
111 |
-
$this->mapAttribute('Coupon Code', 'Coupon_Code', false);
|
112 |
-
$this->mapAttribute('Coupon Code Description', 'Coupon_Code_Description', true);
|
113 |
-
$this->mapAttribute('Manufacturer', 'Manufacturer', true);
|
114 |
-
$this->mapAttribute('Product Description', 'Product_Description', true);
|
115 |
-
$this->mapAttribute('Product Type', 'Product_Type', true);
|
116 |
-
$this->mapAttribute('Category', 'Category', true);
|
117 |
-
$this->mapAttribute('Category ID', 'Category_ID', false);
|
118 |
-
$this->mapAttribute('Parent SKU', 'Parent_SKU', true);
|
119 |
-
$this->mapAttribute('Parent Name', 'Parent_Name', true);
|
120 |
-
$this->mapAttribute('Top Seller Rank', 'Top_Seller_Rank', false);
|
121 |
-
$this->mapAttribute('Estimated Ship Date', 'Estimated_Ship_Date', true);
|
122 |
-
$this->mapAttribute('Gender', 'Gender', true);
|
123 |
-
$this->mapAttribute('Color', 'Color', true);
|
124 |
-
$this->mapAttribute('Material', 'Material', true);
|
125 |
-
$this->mapAttribute('Size', 'Size', true);
|
126 |
-
$this->mapAttribute('Size Unit of Measure', 'Size_Unit_of_Measure', true);
|
127 |
-
$this->mapAttribute('Age Range', 'Age_Range', true);
|
128 |
-
$this->mapAttribute('Stock Description', 'Stock_Description', true);
|
129 |
-
$this->mapAttribute('Product Launch Date', 'Product_Launch_Date', false);
|
130 |
-
$this->mapAttribute('Product Bullet Point 1', 'Product_Bullet_Point_1', false);
|
131 |
-
$this->mapAttribute('Product Bullet Point 2', 'Product_Bullet_Point_2', false);
|
132 |
-
$this->mapAttribute('Product Bullet Point 3', 'Product_Bullet_Point_3', false);
|
133 |
-
$this->mapAttribute('Product Bullet Point 4', 'Product_Bullet_Point_4', false);
|
134 |
-
$this->mapAttribute('Product Bullet Point 5', 'Product_Bullet_Point_5', false);
|
135 |
-
$this->mapAttribute('Alternative Image URL 1', 'Alternative_Image_URL_1', false);
|
136 |
-
$this->mapAttribute('Alternative Image URL 2', 'Alternative_Image_URL_2', false);
|
137 |
-
$this->mapAttribute('Alternative Image URL 3', 'Alternative_Image_URL_3', false);
|
138 |
-
$this->mapAttribute('Alternative Image URL 4', 'Alternative_Image_URL_4', false);
|
139 |
-
$this->mapAttribute('Alternative Image URL 5', 'Alternative_Image_URL_5', false);
|
140 |
-
$this->mapAttribute('Mobile URL', 'Mobile_URL', false);
|
141 |
-
$this->mapAttribute('Related Products', 'Related_Products', false);
|
142 |
-
$this->mapAttribute('Merchandising Type', 'Merchandising_Type', false);
|
143 |
-
$this->mapAttribute('Zip Code', 'Zip_Code', false);
|
144 |
-
$this->mapAttribute('Shipping Weight', 'Shipping_Weight', false);
|
145 |
-
$this->mapAttribute('Format', 'Format', false);
|
146 |
-
$this->mapAttribute('Unit Price', 'Unit_Price', false);
|
147 |
-
$this->mapAttribute('Bundle', 'Bundle', false);
|
148 |
-
$this->mapAttribute('Software Platform', 'Software_Platform', false);
|
149 |
-
$this->mapAttribute('Watch Display Type', 'Watch_Display_Type', false);
|
150 |
-
$this->mapAttribute('Custom', 'Custom', false);
|
151 |
-
|
152 |
-
}
|
153 |
-
|
154 |
-
/**
|
155 |
-
* Configure merchant attributes for CSV and TXT feed
|
156 |
-
*/
|
157 |
-
public function mapAttributeForCSVTEXT()
|
158 |
-
{
|
159 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
160 |
-
foreach ($this->products as $key => $values) {
|
161 |
-
foreach ($values as $attr => $value) {
|
162 |
-
// Allow force strip HTML
|
163 |
-
$value = strip_tags(html_entity_decode($value));
|
164 |
-
// Encode value and attribute
|
165 |
-
$value = utf8_encode($value);
|
166 |
-
$attr = utf8_encode($attr);
|
167 |
-
|
168 |
-
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
|
169 |
-
|
170 |
-
if (gettype($value) == 'array')
|
171 |
-
$value = json_encode($value);
|
172 |
-
|
173 |
-
$this->products[$key][$attr] = $value;
|
174 |
-
}
|
175 |
-
}
|
176 |
-
}
|
177 |
-
}
|
178 |
-
|
179 |
-
/**
|
180 |
-
* Check all the required attributes and make error message
|
181 |
-
*/
|
182 |
-
public function formatRequiredField()
|
183 |
-
{
|
184 |
-
foreach ($this->products as $no => $product) {
|
185 |
-
$upn = 0;
|
186 |
-
if (array_key_exists('Unique Merchant SKU', $product)) {
|
187 |
-
$id = $product['Unique Merchant SKU'];
|
188 |
-
} else {
|
189 |
-
$id = $product['Product Name'];
|
190 |
-
}
|
191 |
-
|
192 |
-
if (!array_key_exists('Product Name', $product)) {
|
193 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Product Name</b>] Missing for <b>$id</b>.";
|
194 |
-
$this->errorCounter++;
|
195 |
-
}
|
196 |
-
|
197 |
-
|
198 |
-
if (!array_key_exists('Unique Merchant SKU', $product)) {
|
199 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Unique Merchant SKU</b>] Missing for <b>$id</b>.";
|
200 |
-
$this->errorCounter++;
|
201 |
-
}
|
202 |
-
|
203 |
-
if (!array_key_exists('Product URL', $product)) {
|
204 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Product URL</b>] Missing for <b>$id</b>.";
|
205 |
-
$this->errorCounter++;
|
206 |
-
}
|
207 |
-
|
208 |
-
if (!array_key_exists('Image URL', $product)) {
|
209 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Image URL</b>] Missing for <b>$id</b>.";
|
210 |
-
$this->errorCounter++;
|
211 |
-
}
|
212 |
-
|
213 |
-
if (!array_key_exists('Current Price', $product)) {
|
214 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Current Price</b>] Missing for <b>$id</b>.";
|
215 |
-
$this->errorCounter++;
|
216 |
-
}
|
217 |
-
|
218 |
-
if (!array_key_exists('Stock Availability', $product)) {
|
219 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Stock Availability</b>] Missing for <b>$id</b>.";
|
220 |
-
$this->errorCounter++;
|
221 |
-
}
|
222 |
-
|
223 |
-
if (!array_key_exists('Condition', $product)) {
|
224 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Condition</b>] Missing for <b>$id</b>.";
|
225 |
-
$this->errorCounter++;
|
226 |
-
}
|
227 |
-
|
228 |
-
if (!array_key_exists('MPN', $product) && !array_key_exists('ISBN', $product)) {
|
229 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>MPN / ISBN</b>] Missing for <b>$id</b>.";
|
230 |
-
$this->errorCounter++;
|
231 |
-
}
|
232 |
-
if (!array_key_exists('UPC', $product) && !array_key_exists('EAN', $product)) {
|
233 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>UPC / EAN</b>] Missing for <b>$id</b>.";
|
234 |
-
$this->errorCounter++;
|
235 |
-
}
|
236 |
-
}
|
237 |
-
}
|
238 |
-
|
239 |
-
/**
|
240 |
-
* Return Feed
|
241 |
-
*
|
242 |
-
* @return array|bool|string
|
243 |
-
*/
|
244 |
-
public function returnFinalProduct()
|
245 |
-
{
|
246 |
-
if ($this->rules['feedType'] == 'xml') {
|
247 |
-
return $this->get_feed($this->products);
|
248 |
-
} elseif ($this->rules['feedType'] == 'txt') {
|
249 |
-
return $this->get_txt_feed();
|
250 |
-
} elseif ($this->rules['feedType'] == 'csv') {
|
251 |
-
return $this->get_csv_feed();
|
252 |
-
}
|
253 |
-
return false;
|
254 |
-
}
|
255 |
-
|
256 |
-
|
257 |
-
/**
|
258 |
-
* Check product's attribute value according to merchant specifications
|
259 |
-
*/
|
260 |
-
public function filterProductValues()
|
261 |
-
{
|
262 |
-
$getProduct = new Woo_Feed_Products();
|
263 |
-
$products = $this->products;
|
264 |
-
|
265 |
-
foreach ($products as $no => $product) {
|
266 |
-
if (array_key_exists('Unique Merchant SKU', $product)) {
|
267 |
-
$id = $product['Unique Merchant SKU'];
|
268 |
-
} else {
|
269 |
-
$id = $product['Product Name'];
|
270 |
-
}
|
271 |
-
// echo "<pre>";
|
272 |
-
// print_r($product);
|
273 |
-
foreach ($product as $key => $value) {
|
274 |
-
switch ($key) {
|
275 |
-
case "Product Name":
|
276 |
-
if (strlen($value) > 90) {
|
277 |
-
$this->errorLog[$this->errorCounter] = "<b>Product Name</b> is more that 90 character for $id.";
|
278 |
-
$this->errorCounter++;
|
279 |
-
}
|
280 |
-
break;
|
281 |
-
case "Image URL":
|
282 |
-
list($width, $height) = getimagesize($value);
|
283 |
-
if ($width < 150 || $height < 150) {
|
284 |
-
$this->errorLog[$this->errorCounter] = "<b>Image Width and Height</b> should be more that 150px for $id.";
|
285 |
-
$this->errorCounter++;
|
286 |
-
}
|
287 |
-
break;
|
288 |
-
case "Stock Availability":
|
289 |
-
if ($value == 'in stock') {
|
290 |
-
$this->products[$no][$key] = "YES";
|
291 |
-
} else if ($value == 'out of stock') {
|
292 |
-
$this->products[$no][$key] = "NO";
|
293 |
-
}
|
294 |
-
break;
|
295 |
-
case "Condition":
|
296 |
-
if ($value != "New") {
|
297 |
-
$this->errorLog[$this->errorCounter] = "<b>Condition</b> should be <b>New</b> for $id.";
|
298 |
-
$this->errorCounter++;
|
299 |
-
}
|
300 |
-
break;
|
301 |
-
case "MPN":
|
302 |
-
if (strlen($value) != 13 || strlen($value) != 10) {
|
303 |
-
$this->errorLog[$this->errorCounter] = "Product [<b>MPN</b>] should be 10 and 13 digit for $id.";
|
304 |
-
$this->errorCounter++;
|
305 |
-
}
|
306 |
-
break;
|
307 |
-
case "ISBN":
|
308 |
-
if (strlen($value) != 13 || strlen($value) != 10) {
|
309 |
-
$this->errorLog[$this->errorCounter] = "Product [<b>ISBN</b>] should be 10 and 13 digit for $id.";
|
310 |
-
$this->errorCounter++;
|
311 |
-
}
|
312 |
-
break;
|
313 |
-
case "UPC":
|
314 |
-
if (strlen($value) != 12) {
|
315 |
-
$this->errorLog[$this->errorCounter] = "Product [<b>UPC</b>] should be 12-digit Universal Product Codes for $id.";
|
316 |
-
$this->errorCounter++;
|
317 |
-
}
|
318 |
-
if (!is_numeric($value)) {
|
319 |
-
$this->errorLog[$this->errorCounter] = "Product [<b>UPC</b>] should be Numeric for $id.";
|
320 |
-
$this->errorCounter++;
|
321 |
-
}
|
322 |
-
break;
|
323 |
-
case "EAN":
|
324 |
-
if (strlen($value) != 13) {
|
325 |
-
$this->errorLog[$this->errorCounter] = "Product [<b>EAN</b>] should be 13-digit EAN for $id.";
|
326 |
-
$this->errorCounter++;
|
327 |
-
}
|
328 |
-
if (!is_numeric($value)) {
|
329 |
-
$this->errorLog[$this->errorCounter] = "Product [<b>EAN</b>] should be Numeric for $id.";
|
330 |
-
$this->errorCounter++;
|
331 |
-
}
|
332 |
-
break;
|
333 |
-
case "Coupon Code":
|
334 |
-
if (strlen($value) > 20) {
|
335 |
-
$this->errorLog[$this->errorCounter] = "[<b>Coupon Code</b>] is more that 20 character for $id.";
|
336 |
-
$this->errorCounter++;
|
337 |
-
}
|
338 |
-
break;
|
339 |
-
case "Coupon Code Description":
|
340 |
-
if (strlen($value) > 150) {
|
341 |
-
$this->errorLog[$this->errorCounter] = "[<b>Coupon Code Description</b>] is more that 150 character for $id.";
|
342 |
-
$this->errorCounter++;
|
343 |
-
}
|
344 |
-
break;
|
345 |
-
case "Product Description":
|
346 |
-
if (strlen($value) > 4000) {
|
347 |
-
$this->errorLog[$this->errorCounter] = "[<b>Product Description</b>] is more that 150 character for $id.";
|
348 |
-
$this->errorCounter++;
|
349 |
-
}
|
350 |
-
break;
|
351 |
-
case "Product Type":
|
352 |
-
$this->products[$no][$key] = str_replace(">", ",", $value);
|
353 |
-
break;
|
354 |
-
default:
|
355 |
-
break;
|
356 |
-
}
|
357 |
-
}
|
358 |
-
}
|
359 |
-
}
|
360 |
-
|
361 |
-
/**
|
362 |
-
* Return Dynamic Category Mapping Values by Parent Product Id
|
363 |
-
*
|
364 |
-
* @param string $mappingName Category Mapping Name
|
365 |
-
* @param int $parent Parent id of the product
|
366 |
-
* @return mixed
|
367 |
-
*/
|
368 |
-
public function get_category_mapping_value($mappingName, $parent)
|
369 |
-
{
|
370 |
-
$getValue = unserialize(get_option($mappingName));
|
371 |
-
$mapp = array_reverse($getValue['cmapping'], true);
|
372 |
-
$categories = get_the_terms($parent, 'product_cat');
|
373 |
-
|
374 |
-
foreach ($categories as $key => $category) {
|
375 |
-
if (!empty($mapp[$category->term_id]))
|
376 |
-
return $mapp[$category->term_id];
|
377 |
-
}
|
378 |
-
return false;
|
379 |
-
}
|
380 |
-
|
381 |
-
/**
|
382 |
-
* Configure the feed according to the rules
|
383 |
-
* @return Shopping
|
384 |
-
*/
|
385 |
-
public function mapProductsByRules()
|
386 |
-
{
|
387 |
-
/**
|
388 |
-
* Get WooCommerce Products
|
389 |
-
* @package Woo_Feed_Products
|
390 |
-
*/
|
391 |
-
$products = new Woo_Feed_Products();
|
392 |
-
|
393 |
-
/**
|
394 |
-
* This variable contain selected Woo attributes from feed making form
|
395 |
-
*
|
396 |
-
* @since 1.0.0
|
397 |
-
* @var array $attributes contain selected Woo attributes from feed making form
|
398 |
-
*/
|
399 |
-
$attributes = $this->rules['attributes'];
|
400 |
-
/**
|
401 |
-
* This variable contain selected Prefix Values from feed making form
|
402 |
-
*
|
403 |
-
* @since 1.0.0
|
404 |
-
* @var array $prefix Prefix Values from feed making form
|
405 |
-
*/
|
406 |
-
$prefix = $this->rules['prefix'];
|
407 |
-
/**
|
408 |
-
* This variable contain selected Prefix Values from feed making form
|
409 |
-
*
|
410 |
-
* @since 1.0.0
|
411 |
-
* @var array $suffix Suffix Values from feed making form
|
412 |
-
*/
|
413 |
-
$suffix = $this->rules['suffix'];
|
414 |
-
/**
|
415 |
-
* This variable contain selected Output Types from feed making form
|
416 |
-
*
|
417 |
-
* @since 1.0.0
|
418 |
-
* @var array $outputType Output Types from feed making form
|
419 |
-
*/
|
420 |
-
$outputType = $this->rules['output_type'];
|
421 |
-
|
422 |
-
/**
|
423 |
-
* This variable contain selected Output Limit from feed making form
|
424 |
-
*
|
425 |
-
* @since 1.0.0
|
426 |
-
* @var array $limit Output Limit from feed making form
|
427 |
-
*/
|
428 |
-
$limit = $this->rules['limit'];
|
429 |
-
/**
|
430 |
-
* This variable contain selected Merchant attributes from feed making form
|
431 |
-
*
|
432 |
-
* @since 1.0.0
|
433 |
-
* @var array $merchantAttributes contain selected Woo attributes from feed making form
|
434 |
-
*/
|
435 |
-
$merchantAttributes = $this->rules['mattributes'];
|
436 |
-
/**
|
437 |
-
* This variable contain attribute types from feed making form
|
438 |
-
*
|
439 |
-
* @since 1.0.0
|
440 |
-
* @var array $type contain attribute types from feed making form
|
441 |
-
*/
|
442 |
-
$type = $this->rules['type'];
|
443 |
-
/**
|
444 |
-
* This variable contain manual output of attribute from feed making form
|
445 |
-
*
|
446 |
-
* @since 1.0.0
|
447 |
-
* @var array $default contain manual output of attribute
|
448 |
-
*/
|
449 |
-
$default = $this->rules['default'];
|
450 |
-
|
451 |
-
/**
|
452 |
-
* This variable contain feed type
|
453 |
-
*
|
454 |
-
* @since 1.0.0
|
455 |
-
* @var array $feedType contain feed type
|
456 |
-
*/
|
457 |
-
$feedType = $this->rules['feedType'];
|
458 |
-
|
459 |
-
// Map Merchant Attributes and Woo Attributes
|
460 |
-
if (count($merchantAttributes)) {
|
461 |
-
foreach ($merchantAttributes as $key => $attr) {
|
462 |
-
if (!empty($attr) && !empty($attributes[$key])) {
|
463 |
-
if ($type[$key] == 'attribute') {
|
464 |
-
$this->mapping[$attr]['value'] = $attributes[$key];
|
465 |
-
$this->mapping[$attr]['suffix'] = $suffix[$key];
|
466 |
-
$this->mapping[$attr]['prefix'] = $prefix[$key];
|
467 |
-
$this->mapping[$attr]['type'] = $outputType[$key];
|
468 |
-
$this->mapping[$attr]['limit'] = $limit[$key];
|
469 |
-
}
|
470 |
-
} else if (empty($attributes[$key])) {
|
471 |
-
if ($type[$key] == 'pattern') {
|
472 |
-
$this->mapping[$attr]['value'] = "wf_pattern_$default[$key]";
|
473 |
-
$this->mapping[$attr]['suffix'] = $suffix[$key];
|
474 |
-
$this->mapping[$attr]['prefix'] = $prefix[$key];
|
475 |
-
$this->mapping[$attr]['type'] = $outputType[$key];
|
476 |
-
$this->mapping[$attr]['limit'] = $limit[$key];
|
477 |
-
}
|
478 |
-
}
|
479 |
-
}
|
480 |
-
}
|
481 |
-
|
482 |
-
// Make Product feed array according to mapping
|
483 |
-
foreach ($products->woo_feed_get_visible_product() as $key => $value) {
|
484 |
-
$i = 0;
|
485 |
-
foreach ($this->mapping as $attr => $rules) {
|
486 |
-
if (array_key_exists($rules['value'], $value)) {
|
487 |
-
|
488 |
-
$output = $rules['prefix'] . $value[$rules['value']] . " " . $rules['suffix'];
|
489 |
-
// Format According to output type
|
490 |
-
if ($rules['type'] == 2) {
|
491 |
-
$output = strip_tags($output);
|
492 |
-
} elseif ($rules['type'] == 3) {
|
493 |
-
$output = absint($output);
|
494 |
-
}
|
495 |
-
// Format According to output limit
|
496 |
-
if (!empty($rules['limit']) && is_numeric($rules['limit'])) {
|
497 |
-
$output = substr($output, 0, $rules['limit']);
|
498 |
-
}
|
499 |
-
$attr = trim($attr);
|
500 |
-
$this->products[$key][$attr] = trim($output);
|
501 |
-
} else {
|
502 |
-
if (!empty($default[$i])) {
|
503 |
-
$output = $rules['prefix'] . str_replace("wf_pattern_", "", $rules['value']) . " " . $rules['suffix'];
|
504 |
-
|
505 |
-
// Format output type
|
506 |
-
if ($rules['type'] == 2) {
|
507 |
-
$output = strip_tags($output);
|
508 |
-
} elseif ($rules['type'] == 3) {
|
509 |
-
$output = absint($output);
|
510 |
-
}
|
511 |
-
// Format According to output limit
|
512 |
-
if (!empty($rules['limit']) && is_numeric($rules['limit'])) {
|
513 |
-
$output = substr($output, 0, $rules['limit']);
|
514 |
-
}
|
515 |
-
$attr = trim($attr);
|
516 |
-
$this->products[$key][$attr] = trim($output);
|
517 |
-
}
|
518 |
-
}
|
519 |
-
$i++;
|
520 |
-
}
|
521 |
-
}
|
522 |
-
return $this->products;
|
523 |
-
}
|
524 |
-
|
525 |
-
/**
|
526 |
-
* Change the products old array key and set new
|
527 |
-
*
|
528 |
-
* @param string $from Attribute Before
|
529 |
-
* @param string $to Attribute After
|
530 |
-
* @param bool $cdata Enclose Feed value
|
531 |
-
*/
|
532 |
-
public function mapAttribute($from, $to, $cdata = false)
|
533 |
-
{
|
534 |
-
$i = 0;
|
535 |
-
foreach ($this->products as $no => $product) {
|
536 |
-
foreach ($product as $key => $value) {
|
537 |
-
if ($key == $from) {
|
538 |
-
unset($this->products[$no][$from]);
|
539 |
-
if ($from == 'images') {
|
540 |
-
$this->products[$no][$to] = $value;
|
541 |
-
} else {
|
542 |
-
$this->products[$no][$to] = $this->formatXMLLine($to, $value, $cdata, true, true);
|
543 |
-
}
|
544 |
-
|
545 |
-
}
|
546 |
-
}
|
547 |
-
$i++;
|
548 |
-
}
|
549 |
-
}
|
550 |
-
|
551 |
-
/**
|
552 |
-
* Format and Make the XML node for the Feed
|
553 |
-
*
|
554 |
-
* @param $attribute
|
555 |
-
* @param $value
|
556 |
-
* @param bool $cdata
|
557 |
-
* @param bool $stripHTML
|
558 |
-
* @param bool $utf8encode
|
559 |
-
* @param string $space
|
560 |
-
* @return string
|
561 |
-
*/
|
562 |
-
function formatXMLLine($attribute, $value, $cdata = false, $stripHTML = true, $utf8encode = true, $space = ' ')
|
563 |
-
{
|
564 |
-
//Make single line for XML
|
565 |
-
$c_leader = '';
|
566 |
-
$c_footer = '';
|
567 |
-
if ($cdata) {
|
568 |
-
$c_leader = '<![CDATA[';
|
569 |
-
$c_footer = ']]>';
|
570 |
-
}
|
571 |
-
//Allow force strip HTML
|
572 |
-
if ($stripHTML)
|
573 |
-
$value = strip_tags(html_entity_decode($value));
|
574 |
-
|
575 |
-
|
576 |
-
if ($utf8encode || $utf8encode == 1) {
|
577 |
-
$value = utf8_encode($value);
|
578 |
-
$attribute = utf8_encode($attribute);
|
579 |
-
}
|
580 |
-
|
581 |
-
if (!$cdata)
|
582 |
-
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
|
583 |
-
|
584 |
-
if (gettype($value) == 'array')
|
585 |
-
$value = json_encode($value);
|
586 |
-
|
587 |
-
return '
|
588 |
-
' . $space . '<' . $attribute . '>' . $c_leader . $value . $c_footer . '</' . $attribute . '>';
|
589 |
-
}
|
590 |
-
|
591 |
-
/**
|
592 |
-
* Responsible to change product array key
|
593 |
-
*
|
594 |
-
* @param $array
|
595 |
-
* @param $old_key
|
596 |
-
* @param $new_key
|
597 |
-
* @return array
|
598 |
-
*/
|
599 |
-
function change_key($array, $old_key, $new_key)
|
600 |
-
{
|
601 |
-
foreach ($this->products as $no => $product) {
|
602 |
-
if (!array_key_exists($old_key, $product))
|
603 |
-
return $array;
|
604 |
-
|
605 |
-
$keys = array_keys($array);
|
606 |
-
$keys[array_search($old_key, $keys)] = $new_key;
|
607 |
-
}
|
608 |
-
return array_combine($keys, $array);
|
609 |
-
}
|
610 |
-
|
611 |
-
/**
|
612 |
-
* Responsible to make XML feed header
|
613 |
-
* @return string
|
614 |
-
*/
|
615 |
-
public function get_feed_header()
|
616 |
-
{
|
617 |
-
$output = '<?xml version="1.0" encoding="UTF-8" ?>
|
618 |
-
<products>';
|
619 |
-
$output .= "\n";
|
620 |
-
return $output;
|
621 |
-
}
|
622 |
-
|
623 |
-
/**
|
624 |
-
* Responsible to make XML feed body
|
625 |
-
* @var array $items Product array
|
626 |
-
* @return string
|
627 |
-
*/
|
628 |
-
public function get_feed($items)
|
629 |
-
{
|
630 |
-
$feed = "";
|
631 |
-
$feed .= $this->get_feed_header();
|
632 |
-
$feed .= "\n";
|
633 |
-
foreach ($items as $item => $products) {
|
634 |
-
$feed .= " <" . $this->feedWrapper . ">";
|
635 |
-
foreach ($products as $key => $value) {
|
636 |
-
if (!empty($value))
|
637 |
-
$feed .= $value;
|
638 |
-
}
|
639 |
-
$feed .= "\n </" . $this->feedWrapper . ">\n";
|
640 |
-
}
|
641 |
-
$feed .= $this->get_feed_footer();
|
642 |
-
|
643 |
-
return $feed;
|
644 |
-
}
|
645 |
-
|
646 |
-
/**
|
647 |
-
* Responsible to make XML feed footer
|
648 |
-
* @return string
|
649 |
-
*/
|
650 |
-
public function get_feed_footer()
|
651 |
-
{
|
652 |
-
$footer = " </products>";
|
653 |
-
return $footer;
|
654 |
-
}
|
655 |
-
|
656 |
-
|
657 |
-
/**
|
658 |
-
* Responsible to make TXT feed
|
659 |
-
* @return string
|
660 |
-
*/
|
661 |
-
public function get_txt_feed()
|
662 |
-
{
|
663 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
664 |
-
$headers = array_keys($this->products[0]);
|
665 |
-
$feed[] = $headers;
|
666 |
-
foreach ($this->products as $no => $product) {
|
667 |
-
$row = array();
|
668 |
-
foreach ($headers as $key => $header) {
|
669 |
-
$row[] = $product[$header];
|
670 |
-
}
|
671 |
-
$feed[] = $row;
|
672 |
-
}
|
673 |
-
$str = "";
|
674 |
-
foreach ($feed as $fields) {
|
675 |
-
$str .= implode("\t", $fields) . "\n";
|
676 |
-
}
|
677 |
-
return $str;
|
678 |
-
}
|
679 |
-
return false;
|
680 |
-
}
|
681 |
-
|
682 |
-
/**
|
683 |
-
* Responsible to make CSV feed
|
684 |
-
* @var $products
|
685 |
-
* @return string
|
686 |
-
*/
|
687 |
-
public function get_csv_feed()
|
688 |
-
{
|
689 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
690 |
-
$headers = array_keys($this->products[0]);
|
691 |
-
$feed[] = $headers;
|
692 |
-
foreach ($this->products as $no => $product) {
|
693 |
-
$row = array();
|
694 |
-
foreach ($headers as $key => $header) {
|
695 |
-
$row[] = $product[$header];
|
696 |
-
}
|
697 |
-
$feed[] = $row;
|
698 |
-
}
|
699 |
-
|
700 |
-
return $feed;
|
701 |
-
}
|
702 |
-
return false;
|
703 |
-
}
|
704 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Shopping
|
5 |
+
*
|
6 |
+
* Responsible for processing and generating feed for Shopping.com
|
7 |
+
*
|
8 |
+
* @since 1.0.0
|
9 |
+
* @package Shopping
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Shopping
|
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 holding feed configuration form values
|
25 |
+
*
|
26 |
+
* @since 1.0.0
|
27 |
+
* @var Shopping $rules Contains feed configuration form values
|
28 |
+
* @access public
|
29 |
+
*/
|
30 |
+
public $rules;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* This variable is responsible for mapping store attributes to merchant attribute
|
34 |
+
*
|
35 |
+
* @since 1.0.0
|
36 |
+
* @var Shopping $mapping Map store attributes to merchant attribute
|
37 |
+
* @access public
|
38 |
+
*/
|
39 |
+
public $mapping;
|
40 |
+
|
41 |
+
/**
|
42 |
+
* This variable is responsible for generate error logs
|
43 |
+
*
|
44 |
+
* @since 1.0.0
|
45 |
+
* @var Shopping $errorLog Generate error logs
|
46 |
+
* @access public
|
47 |
+
*/
|
48 |
+
public $errorLog;
|
49 |
+
|
50 |
+
/**
|
51 |
+
* This variable is responsible for making error number
|
52 |
+
*
|
53 |
+
* @since 1.0.0
|
54 |
+
* @var Shopping $errorCounter Generate error number
|
55 |
+
* @access public
|
56 |
+
*/
|
57 |
+
public $errorCounter;
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Feed Wrapper text for enclosing each product information
|
61 |
+
*
|
62 |
+
* @since 1.0.0
|
63 |
+
* @var Shopping $feedWrapper Feed Wrapper text
|
64 |
+
* @access public
|
65 |
+
*/
|
66 |
+
private $feedWrapper = 'product';
|
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 |
+
$this->errorCounter = 0;
|
79 |
+
$this->rules = $feedRule;
|
80 |
+
$this->mapProductsByRules();
|
81 |
+
$this->formatRequiredField();
|
82 |
+
$this->filterProductValues();
|
83 |
+
if ($this->rules['feedType'] == 'xml') {
|
84 |
+
$this->mapAttributeForXML();
|
85 |
+
} else {
|
86 |
+
$this->mapAttributeForCSVTEXT();
|
87 |
+
}
|
88 |
+
}
|
89 |
+
|
90 |
+
/**
|
91 |
+
* Configure merchant attributes for XML feed
|
92 |
+
*/
|
93 |
+
public function mapAttributeForXML()
|
94 |
+
{
|
95 |
+
//Required Attributes
|
96 |
+
$this->mapAttribute('Unique Merchant SKU', 'Merchant_SKU', true);
|
97 |
+
$this->mapAttribute('Product Name', 'Product_Name', true);
|
98 |
+
$this->mapAttribute('Product URL', 'Product_URL', true);
|
99 |
+
$this->mapAttribute('Image URL', 'Image_URL', true);
|
100 |
+
$this->mapAttribute('Current Price', 'Current_Price', true);
|
101 |
+
$this->mapAttribute('Stock Availability', 'Stock_Availability', true);
|
102 |
+
$this->mapAttribute('Condition', 'Condition', true);
|
103 |
+
$this->mapAttribute('MPN', 'MPN', false);
|
104 |
+
$this->mapAttribute('ISBN', 'ISBN', false);
|
105 |
+
$this->mapAttribute('UPC', 'UPC', false);
|
106 |
+
$this->mapAttribute('EAN', 'EAN', false);
|
107 |
+
|
108 |
+
//Additional Attributes
|
109 |
+
$this->mapAttribute('Shipping Rate', 'Shipping_Rate', false);
|
110 |
+
$this->mapAttribute('Original Price', 'Original_Price', false);
|
111 |
+
$this->mapAttribute('Coupon Code', 'Coupon_Code', false);
|
112 |
+
$this->mapAttribute('Coupon Code Description', 'Coupon_Code_Description', true);
|
113 |
+
$this->mapAttribute('Manufacturer', 'Manufacturer', true);
|
114 |
+
$this->mapAttribute('Product Description', 'Product_Description', true);
|
115 |
+
$this->mapAttribute('Product Type', 'Product_Type', true);
|
116 |
+
$this->mapAttribute('Category', 'Category', true);
|
117 |
+
$this->mapAttribute('Category ID', 'Category_ID', false);
|
118 |
+
$this->mapAttribute('Parent SKU', 'Parent_SKU', true);
|
119 |
+
$this->mapAttribute('Parent Name', 'Parent_Name', true);
|
120 |
+
$this->mapAttribute('Top Seller Rank', 'Top_Seller_Rank', false);
|
121 |
+
$this->mapAttribute('Estimated Ship Date', 'Estimated_Ship_Date', true);
|
122 |
+
$this->mapAttribute('Gender', 'Gender', true);
|
123 |
+
$this->mapAttribute('Color', 'Color', true);
|
124 |
+
$this->mapAttribute('Material', 'Material', true);
|
125 |
+
$this->mapAttribute('Size', 'Size', true);
|
126 |
+
$this->mapAttribute('Size Unit of Measure', 'Size_Unit_of_Measure', true);
|
127 |
+
$this->mapAttribute('Age Range', 'Age_Range', true);
|
128 |
+
$this->mapAttribute('Stock Description', 'Stock_Description', true);
|
129 |
+
$this->mapAttribute('Product Launch Date', 'Product_Launch_Date', false);
|
130 |
+
$this->mapAttribute('Product Bullet Point 1', 'Product_Bullet_Point_1', false);
|
131 |
+
$this->mapAttribute('Product Bullet Point 2', 'Product_Bullet_Point_2', false);
|
132 |
+
$this->mapAttribute('Product Bullet Point 3', 'Product_Bullet_Point_3', false);
|
133 |
+
$this->mapAttribute('Product Bullet Point 4', 'Product_Bullet_Point_4', false);
|
134 |
+
$this->mapAttribute('Product Bullet Point 5', 'Product_Bullet_Point_5', false);
|
135 |
+
$this->mapAttribute('Alternative Image URL 1', 'Alternative_Image_URL_1', false);
|
136 |
+
$this->mapAttribute('Alternative Image URL 2', 'Alternative_Image_URL_2', false);
|
137 |
+
$this->mapAttribute('Alternative Image URL 3', 'Alternative_Image_URL_3', false);
|
138 |
+
$this->mapAttribute('Alternative Image URL 4', 'Alternative_Image_URL_4', false);
|
139 |
+
$this->mapAttribute('Alternative Image URL 5', 'Alternative_Image_URL_5', false);
|
140 |
+
$this->mapAttribute('Mobile URL', 'Mobile_URL', false);
|
141 |
+
$this->mapAttribute('Related Products', 'Related_Products', false);
|
142 |
+
$this->mapAttribute('Merchandising Type', 'Merchandising_Type', false);
|
143 |
+
$this->mapAttribute('Zip Code', 'Zip_Code', false);
|
144 |
+
$this->mapAttribute('Shipping Weight', 'Shipping_Weight', false);
|
145 |
+
$this->mapAttribute('Format', 'Format', false);
|
146 |
+
$this->mapAttribute('Unit Price', 'Unit_Price', false);
|
147 |
+
$this->mapAttribute('Bundle', 'Bundle', false);
|
148 |
+
$this->mapAttribute('Software Platform', 'Software_Platform', false);
|
149 |
+
$this->mapAttribute('Watch Display Type', 'Watch_Display_Type', false);
|
150 |
+
$this->mapAttribute('Custom', 'Custom', false);
|
151 |
+
|
152 |
+
}
|
153 |
+
|
154 |
+
/**
|
155 |
+
* Configure merchant attributes for CSV and TXT feed
|
156 |
+
*/
|
157 |
+
public function mapAttributeForCSVTEXT()
|
158 |
+
{
|
159 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
160 |
+
foreach ($this->products as $key => $values) {
|
161 |
+
foreach ($values as $attr => $value) {
|
162 |
+
// Allow force strip HTML
|
163 |
+
$value = strip_tags(html_entity_decode($value));
|
164 |
+
// Encode value and attribute
|
165 |
+
$value = utf8_encode($value);
|
166 |
+
$attr = utf8_encode($attr);
|
167 |
+
|
168 |
+
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
|
169 |
+
|
170 |
+
if (gettype($value) == 'array')
|
171 |
+
$value = json_encode($value);
|
172 |
+
|
173 |
+
$this->products[$key][$attr] = $value;
|
174 |
+
}
|
175 |
+
}
|
176 |
+
}
|
177 |
+
}
|
178 |
+
|
179 |
+
/**
|
180 |
+
* Check all the required attributes and make error message
|
181 |
+
*/
|
182 |
+
public function formatRequiredField()
|
183 |
+
{
|
184 |
+
foreach ($this->products as $no => $product) {
|
185 |
+
$upn = 0;
|
186 |
+
if (array_key_exists('Unique Merchant SKU', $product)) {
|
187 |
+
$id = $product['Unique Merchant SKU'];
|
188 |
+
} else {
|
189 |
+
$id = $product['Product Name'];
|
190 |
+
}
|
191 |
+
|
192 |
+
if (!array_key_exists('Product Name', $product)) {
|
193 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Product Name</b>] Missing for <b>$id</b>.";
|
194 |
+
$this->errorCounter++;
|
195 |
+
}
|
196 |
+
|
197 |
+
|
198 |
+
if (!array_key_exists('Unique Merchant SKU', $product)) {
|
199 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Unique Merchant SKU</b>] Missing for <b>$id</b>.";
|
200 |
+
$this->errorCounter++;
|
201 |
+
}
|
202 |
+
|
203 |
+
if (!array_key_exists('Product URL', $product)) {
|
204 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Product URL</b>] Missing for <b>$id</b>.";
|
205 |
+
$this->errorCounter++;
|
206 |
+
}
|
207 |
+
|
208 |
+
if (!array_key_exists('Image URL', $product)) {
|
209 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Image URL</b>] Missing for <b>$id</b>.";
|
210 |
+
$this->errorCounter++;
|
211 |
+
}
|
212 |
+
|
213 |
+
if (!array_key_exists('Current Price', $product)) {
|
214 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Current Price</b>] Missing for <b>$id</b>.";
|
215 |
+
$this->errorCounter++;
|
216 |
+
}
|
217 |
+
|
218 |
+
if (!array_key_exists('Stock Availability', $product)) {
|
219 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Stock Availability</b>] Missing for <b>$id</b>.";
|
220 |
+
$this->errorCounter++;
|
221 |
+
}
|
222 |
+
|
223 |
+
if (!array_key_exists('Condition', $product)) {
|
224 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Condition</b>] Missing for <b>$id</b>.";
|
225 |
+
$this->errorCounter++;
|
226 |
+
}
|
227 |
+
|
228 |
+
if (!array_key_exists('MPN', $product) && !array_key_exists('ISBN', $product)) {
|
229 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>MPN / ISBN</b>] Missing for <b>$id</b>.";
|
230 |
+
$this->errorCounter++;
|
231 |
+
}
|
232 |
+
if (!array_key_exists('UPC', $product) && !array_key_exists('EAN', $product)) {
|
233 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>UPC / EAN</b>] Missing for <b>$id</b>.";
|
234 |
+
$this->errorCounter++;
|
235 |
+
}
|
236 |
+
}
|
237 |
+
}
|
238 |
+
|
239 |
+
/**
|
240 |
+
* Return Feed
|
241 |
+
*
|
242 |
+
* @return array|bool|string
|
243 |
+
*/
|
244 |
+
public function returnFinalProduct()
|
245 |
+
{
|
246 |
+
if ($this->rules['feedType'] == 'xml') {
|
247 |
+
return $this->get_feed($this->products);
|
248 |
+
} elseif ($this->rules['feedType'] == 'txt') {
|
249 |
+
return $this->get_txt_feed();
|
250 |
+
} elseif ($this->rules['feedType'] == 'csv') {
|
251 |
+
return $this->get_csv_feed();
|
252 |
+
}
|
253 |
+
return false;
|
254 |
+
}
|
255 |
+
|
256 |
+
|
257 |
+
/**
|
258 |
+
* Check product's attribute value according to merchant specifications
|
259 |
+
*/
|
260 |
+
public function filterProductValues()
|
261 |
+
{
|
262 |
+
$getProduct = new Woo_Feed_Products();
|
263 |
+
$products = $this->products;
|
264 |
+
|
265 |
+
foreach ($products as $no => $product) {
|
266 |
+
if (array_key_exists('Unique Merchant SKU', $product)) {
|
267 |
+
$id = $product['Unique Merchant SKU'];
|
268 |
+
} else {
|
269 |
+
$id = $product['Product Name'];
|
270 |
+
}
|
271 |
+
// echo "<pre>";
|
272 |
+
// print_r($product);
|
273 |
+
foreach ($product as $key => $value) {
|
274 |
+
switch ($key) {
|
275 |
+
case "Product Name":
|
276 |
+
if (strlen($value) > 90) {
|
277 |
+
$this->errorLog[$this->errorCounter] = "<b>Product Name</b> is more that 90 character for $id.";
|
278 |
+
$this->errorCounter++;
|
279 |
+
}
|
280 |
+
break;
|
281 |
+
case "Image URL":
|
282 |
+
list($width, $height) = getimagesize($value);
|
283 |
+
if ($width < 150 || $height < 150) {
|
284 |
+
$this->errorLog[$this->errorCounter] = "<b>Image Width and Height</b> should be more that 150px for $id.";
|
285 |
+
$this->errorCounter++;
|
286 |
+
}
|
287 |
+
break;
|
288 |
+
case "Stock Availability":
|
289 |
+
if ($value == 'in stock') {
|
290 |
+
$this->products[$no][$key] = "YES";
|
291 |
+
} else if ($value == 'out of stock') {
|
292 |
+
$this->products[$no][$key] = "NO";
|
293 |
+
}
|
294 |
+
break;
|
295 |
+
case "Condition":
|
296 |
+
if ($value != "New") {
|
297 |
+
$this->errorLog[$this->errorCounter] = "<b>Condition</b> should be <b>New</b> for $id.";
|
298 |
+
$this->errorCounter++;
|
299 |
+
}
|
300 |
+
break;
|
301 |
+
case "MPN":
|
302 |
+
if (strlen($value) != 13 || strlen($value) != 10) {
|
303 |
+
$this->errorLog[$this->errorCounter] = "Product [<b>MPN</b>] should be 10 and 13 digit for $id.";
|
304 |
+
$this->errorCounter++;
|
305 |
+
}
|
306 |
+
break;
|
307 |
+
case "ISBN":
|
308 |
+
if (strlen($value) != 13 || strlen($value) != 10) {
|
309 |
+
$this->errorLog[$this->errorCounter] = "Product [<b>ISBN</b>] should be 10 and 13 digit for $id.";
|
310 |
+
$this->errorCounter++;
|
311 |
+
}
|
312 |
+
break;
|
313 |
+
case "UPC":
|
314 |
+
if (strlen($value) != 12) {
|
315 |
+
$this->errorLog[$this->errorCounter] = "Product [<b>UPC</b>] should be 12-digit Universal Product Codes for $id.";
|
316 |
+
$this->errorCounter++;
|
317 |
+
}
|
318 |
+
if (!is_numeric($value)) {
|
319 |
+
$this->errorLog[$this->errorCounter] = "Product [<b>UPC</b>] should be Numeric for $id.";
|
320 |
+
$this->errorCounter++;
|
321 |
+
}
|
322 |
+
break;
|
323 |
+
case "EAN":
|
324 |
+
if (strlen($value) != 13) {
|
325 |
+
$this->errorLog[$this->errorCounter] = "Product [<b>EAN</b>] should be 13-digit EAN for $id.";
|
326 |
+
$this->errorCounter++;
|
327 |
+
}
|
328 |
+
if (!is_numeric($value)) {
|
329 |
+
$this->errorLog[$this->errorCounter] = "Product [<b>EAN</b>] should be Numeric for $id.";
|
330 |
+
$this->errorCounter++;
|
331 |
+
}
|
332 |
+
break;
|
333 |
+
case "Coupon Code":
|
334 |
+
if (strlen($value) > 20) {
|
335 |
+
$this->errorLog[$this->errorCounter] = "[<b>Coupon Code</b>] is more that 20 character for $id.";
|
336 |
+
$this->errorCounter++;
|
337 |
+
}
|
338 |
+
break;
|
339 |
+
case "Coupon Code Description":
|
340 |
+
if (strlen($value) > 150) {
|
341 |
+
$this->errorLog[$this->errorCounter] = "[<b>Coupon Code Description</b>] is more that 150 character for $id.";
|
342 |
+
$this->errorCounter++;
|
343 |
+
}
|
344 |
+
break;
|
345 |
+
case "Product Description":
|
346 |
+
if (strlen($value) > 4000) {
|
347 |
+
$this->errorLog[$this->errorCounter] = "[<b>Product Description</b>] is more that 150 character for $id.";
|
348 |
+
$this->errorCounter++;
|
349 |
+
}
|
350 |
+
break;
|
351 |
+
case "Product Type":
|
352 |
+
$this->products[$no][$key] = str_replace(">", ",", $value);
|
353 |
+
break;
|
354 |
+
default:
|
355 |
+
break;
|
356 |
+
}
|
357 |
+
}
|
358 |
+
}
|
359 |
+
}
|
360 |
+
|
361 |
+
/**
|
362 |
+
* Return Dynamic Category Mapping Values by Parent Product Id
|
363 |
+
*
|
364 |
+
* @param string $mappingName Category Mapping Name
|
365 |
+
* @param int $parent Parent id of the product
|
366 |
+
* @return mixed
|
367 |
+
*/
|
368 |
+
public function get_category_mapping_value($mappingName, $parent)
|
369 |
+
{
|
370 |
+
$getValue = unserialize(get_option($mappingName));
|
371 |
+
$mapp = array_reverse($getValue['cmapping'], true);
|
372 |
+
$categories = get_the_terms($parent, 'product_cat');
|
373 |
+
|
374 |
+
foreach ($categories as $key => $category) {
|
375 |
+
if (!empty($mapp[$category->term_id]))
|
376 |
+
return $mapp[$category->term_id];
|
377 |
+
}
|
378 |
+
return false;
|
379 |
+
}
|
380 |
+
|
381 |
+
/**
|
382 |
+
* Configure the feed according to the rules
|
383 |
+
* @return Shopping
|
384 |
+
*/
|
385 |
+
public function mapProductsByRules()
|
386 |
+
{
|
387 |
+
/**
|
388 |
+
* Get WooCommerce Products
|
389 |
+
* @package Woo_Feed_Products
|
390 |
+
*/
|
391 |
+
$products = new Woo_Feed_Products();
|
392 |
+
|
393 |
+
/**
|
394 |
+
* This variable contain selected Woo attributes from feed making form
|
395 |
+
*
|
396 |
+
* @since 1.0.0
|
397 |
+
* @var array $attributes contain selected Woo attributes from feed making form
|
398 |
+
*/
|
399 |
+
$attributes = $this->rules['attributes'];
|
400 |
+
/**
|
401 |
+
* This variable contain selected Prefix Values from feed making form
|
402 |
+
*
|
403 |
+
* @since 1.0.0
|
404 |
+
* @var array $prefix Prefix Values from feed making form
|
405 |
+
*/
|
406 |
+
$prefix = $this->rules['prefix'];
|
407 |
+
/**
|
408 |
+
* This variable contain selected Prefix Values from feed making form
|
409 |
+
*
|
410 |
+
* @since 1.0.0
|
411 |
+
* @var array $suffix Suffix Values from feed making form
|
412 |
+
*/
|
413 |
+
$suffix = $this->rules['suffix'];
|
414 |
+
/**
|
415 |
+
* This variable contain selected Output Types from feed making form
|
416 |
+
*
|
417 |
+
* @since 1.0.0
|
418 |
+
* @var array $outputType Output Types from feed making form
|
419 |
+
*/
|
420 |
+
$outputType = $this->rules['output_type'];
|
421 |
+
|
422 |
+
/**
|
423 |
+
* This variable contain selected Output Limit from feed making form
|
424 |
+
*
|
425 |
+
* @since 1.0.0
|
426 |
+
* @var array $limit Output Limit from feed making form
|
427 |
+
*/
|
428 |
+
$limit = $this->rules['limit'];
|
429 |
+
/**
|
430 |
+
* This variable contain selected Merchant attributes from feed making form
|
431 |
+
*
|
432 |
+
* @since 1.0.0
|
433 |
+
* @var array $merchantAttributes contain selected Woo attributes from feed making form
|
434 |
+
*/
|
435 |
+
$merchantAttributes = $this->rules['mattributes'];
|
436 |
+
/**
|
437 |
+
* This variable contain attribute types from feed making form
|
438 |
+
*
|
439 |
+
* @since 1.0.0
|
440 |
+
* @var array $type contain attribute types from feed making form
|
441 |
+
*/
|
442 |
+
$type = $this->rules['type'];
|
443 |
+
/**
|
444 |
+
* This variable contain manual output of attribute from feed making form
|
445 |
+
*
|
446 |
+
* @since 1.0.0
|
447 |
+
* @var array $default contain manual output of attribute
|
448 |
+
*/
|
449 |
+
$default = $this->rules['default'];
|
450 |
+
|
451 |
+
/**
|
452 |
+
* This variable contain feed type
|
453 |
+
*
|
454 |
+
* @since 1.0.0
|
455 |
+
* @var array $feedType contain feed type
|
456 |
+
*/
|
457 |
+
$feedType = $this->rules['feedType'];
|
458 |
+
|
459 |
+
// Map Merchant Attributes and Woo Attributes
|
460 |
+
if (count($merchantAttributes)) {
|
461 |
+
foreach ($merchantAttributes as $key => $attr) {
|
462 |
+
if (!empty($attr) && !empty($attributes[$key])) {
|
463 |
+
if ($type[$key] == 'attribute') {
|
464 |
+
$this->mapping[$attr]['value'] = $attributes[$key];
|
465 |
+
$this->mapping[$attr]['suffix'] = $suffix[$key];
|
466 |
+
$this->mapping[$attr]['prefix'] = $prefix[$key];
|
467 |
+
$this->mapping[$attr]['type'] = $outputType[$key];
|
468 |
+
$this->mapping[$attr]['limit'] = $limit[$key];
|
469 |
+
}
|
470 |
+
} else if (empty($attributes[$key])) {
|
471 |
+
if ($type[$key] == 'pattern') {
|
472 |
+
$this->mapping[$attr]['value'] = "wf_pattern_$default[$key]";
|
473 |
+
$this->mapping[$attr]['suffix'] = $suffix[$key];
|
474 |
+
$this->mapping[$attr]['prefix'] = $prefix[$key];
|
475 |
+
$this->mapping[$attr]['type'] = $outputType[$key];
|
476 |
+
$this->mapping[$attr]['limit'] = $limit[$key];
|
477 |
+
}
|
478 |
+
}
|
479 |
+
}
|
480 |
+
}
|
481 |
+
|
482 |
+
// Make Product feed array according to mapping
|
483 |
+
foreach ($products->woo_feed_get_visible_product() as $key => $value) {
|
484 |
+
$i = 0;
|
485 |
+
foreach ($this->mapping as $attr => $rules) {
|
486 |
+
if (array_key_exists($rules['value'], $value)) {
|
487 |
+
|
488 |
+
$output = $rules['prefix'] . $value[$rules['value']] . " " . $rules['suffix'];
|
489 |
+
// Format According to output type
|
490 |
+
if ($rules['type'] == 2) {
|
491 |
+
$output = strip_tags($output);
|
492 |
+
} elseif ($rules['type'] == 3) {
|
493 |
+
$output = absint($output);
|
494 |
+
}
|
495 |
+
// Format According to output limit
|
496 |
+
if (!empty($rules['limit']) && is_numeric($rules['limit'])) {
|
497 |
+
$output = substr($output, 0, $rules['limit']);
|
498 |
+
}
|
499 |
+
$attr = trim($attr);
|
500 |
+
$this->products[$key][$attr] = trim($output);
|
501 |
+
} else {
|
502 |
+
if (!empty($default[$i])) {
|
503 |
+
$output = $rules['prefix'] . str_replace("wf_pattern_", "", $rules['value']) . " " . $rules['suffix'];
|
504 |
+
|
505 |
+
// Format output type
|
506 |
+
if ($rules['type'] == 2) {
|
507 |
+
$output = strip_tags($output);
|
508 |
+
} elseif ($rules['type'] == 3) {
|
509 |
+
$output = absint($output);
|
510 |
+
}
|
511 |
+
// Format According to output limit
|
512 |
+
if (!empty($rules['limit']) && is_numeric($rules['limit'])) {
|
513 |
+
$output = substr($output, 0, $rules['limit']);
|
514 |
+
}
|
515 |
+
$attr = trim($attr);
|
516 |
+
$this->products[$key][$attr] = trim($output);
|
517 |
+
}
|
518 |
+
}
|
519 |
+
$i++;
|
520 |
+
}
|
521 |
+
}
|
522 |
+
return $this->products;
|
523 |
+
}
|
524 |
+
|
525 |
+
/**
|
526 |
+
* Change the products old array key and set new
|
527 |
+
*
|
528 |
+
* @param string $from Attribute Before
|
529 |
+
* @param string $to Attribute After
|
530 |
+
* @param bool $cdata Enclose Feed value
|
531 |
+
*/
|
532 |
+
public function mapAttribute($from, $to, $cdata = false)
|
533 |
+
{
|
534 |
+
$i = 0;
|
535 |
+
foreach ($this->products as $no => $product) {
|
536 |
+
foreach ($product as $key => $value) {
|
537 |
+
if ($key == $from) {
|
538 |
+
unset($this->products[$no][$from]);
|
539 |
+
if ($from == 'images') {
|
540 |
+
$this->products[$no][$to] = $value;
|
541 |
+
} else {
|
542 |
+
$this->products[$no][$to] = $this->formatXMLLine($to, $value, $cdata, true, true);
|
543 |
+
}
|
544 |
+
|
545 |
+
}
|
546 |
+
}
|
547 |
+
$i++;
|
548 |
+
}
|
549 |
+
}
|
550 |
+
|
551 |
+
/**
|
552 |
+
* Format and Make the XML node for the Feed
|
553 |
+
*
|
554 |
+
* @param $attribute
|
555 |
+
* @param $value
|
556 |
+
* @param bool $cdata
|
557 |
+
* @param bool $stripHTML
|
558 |
+
* @param bool $utf8encode
|
559 |
+
* @param string $space
|
560 |
+
* @return string
|
561 |
+
*/
|
562 |
+
function formatXMLLine($attribute, $value, $cdata = false, $stripHTML = true, $utf8encode = true, $space = ' ')
|
563 |
+
{
|
564 |
+
//Make single line for XML
|
565 |
+
$c_leader = '';
|
566 |
+
$c_footer = '';
|
567 |
+
if ($cdata) {
|
568 |
+
$c_leader = '<![CDATA[';
|
569 |
+
$c_footer = ']]>';
|
570 |
+
}
|
571 |
+
//Allow force strip HTML
|
572 |
+
if ($stripHTML)
|
573 |
+
$value = strip_tags(html_entity_decode($value));
|
574 |
+
|
575 |
+
|
576 |
+
if ($utf8encode || $utf8encode == 1) {
|
577 |
+
$value = utf8_encode($value);
|
578 |
+
$attribute = utf8_encode($attribute);
|
579 |
+
}
|
580 |
+
|
581 |
+
if (!$cdata)
|
582 |
+
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
|
583 |
+
|
584 |
+
if (gettype($value) == 'array')
|
585 |
+
$value = json_encode($value);
|
586 |
+
|
587 |
+
return '
|
588 |
+
' . $space . '<' . $attribute . '>' . $c_leader . $value . $c_footer . '</' . $attribute . '>';
|
589 |
+
}
|
590 |
+
|
591 |
+
/**
|
592 |
+
* Responsible to change product array key
|
593 |
+
*
|
594 |
+
* @param $array
|
595 |
+
* @param $old_key
|
596 |
+
* @param $new_key
|
597 |
+
* @return array
|
598 |
+
*/
|
599 |
+
function change_key($array, $old_key, $new_key)
|
600 |
+
{
|
601 |
+
foreach ($this->products as $no => $product) {
|
602 |
+
if (!array_key_exists($old_key, $product))
|
603 |
+
return $array;
|
604 |
+
|
605 |
+
$keys = array_keys($array);
|
606 |
+
$keys[array_search($old_key, $keys)] = $new_key;
|
607 |
+
}
|
608 |
+
return array_combine($keys, $array);
|
609 |
+
}
|
610 |
+
|
611 |
+
/**
|
612 |
+
* Responsible to make XML feed header
|
613 |
+
* @return string
|
614 |
+
*/
|
615 |
+
public function get_feed_header()
|
616 |
+
{
|
617 |
+
$output = '<?xml version="1.0" encoding="UTF-8" ?>
|
618 |
+
<products>';
|
619 |
+
$output .= "\n";
|
620 |
+
return $output;
|
621 |
+
}
|
622 |
+
|
623 |
+
/**
|
624 |
+
* Responsible to make XML feed body
|
625 |
+
* @var array $items Product array
|
626 |
+
* @return string
|
627 |
+
*/
|
628 |
+
public function get_feed($items)
|
629 |
+
{
|
630 |
+
$feed = "";
|
631 |
+
$feed .= $this->get_feed_header();
|
632 |
+
$feed .= "\n";
|
633 |
+
foreach ($items as $item => $products) {
|
634 |
+
$feed .= " <" . $this->feedWrapper . ">";
|
635 |
+
foreach ($products as $key => $value) {
|
636 |
+
if (!empty($value))
|
637 |
+
$feed .= $value;
|
638 |
+
}
|
639 |
+
$feed .= "\n </" . $this->feedWrapper . ">\n";
|
640 |
+
}
|
641 |
+
$feed .= $this->get_feed_footer();
|
642 |
+
|
643 |
+
return $feed;
|
644 |
+
}
|
645 |
+
|
646 |
+
/**
|
647 |
+
* Responsible to make XML feed footer
|
648 |
+
* @return string
|
649 |
+
*/
|
650 |
+
public function get_feed_footer()
|
651 |
+
{
|
652 |
+
$footer = " </products>";
|
653 |
+
return $footer;
|
654 |
+
}
|
655 |
+
|
656 |
+
|
657 |
+
/**
|
658 |
+
* Responsible to make TXT feed
|
659 |
+
* @return string
|
660 |
+
*/
|
661 |
+
public function get_txt_feed()
|
662 |
+
{
|
663 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
664 |
+
$headers = array_keys($this->products[0]);
|
665 |
+
$feed[] = $headers;
|
666 |
+
foreach ($this->products as $no => $product) {
|
667 |
+
$row = array();
|
668 |
+
foreach ($headers as $key => $header) {
|
669 |
+
$row[] = $product[$header];
|
670 |
+
}
|
671 |
+
$feed[] = $row;
|
672 |
+
}
|
673 |
+
$str = "";
|
674 |
+
foreach ($feed as $fields) {
|
675 |
+
$str .= implode("\t", $fields) . "\n";
|
676 |
+
}
|
677 |
+
return $str;
|
678 |
+
}
|
679 |
+
return false;
|
680 |
+
}
|
681 |
+
|
682 |
+
/**
|
683 |
+
* Responsible to make CSV feed
|
684 |
+
* @var $products
|
685 |
+
* @return string
|
686 |
+
*/
|
687 |
+
public function get_csv_feed()
|
688 |
+
{
|
689 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
690 |
+
$headers = array_keys($this->products[0]);
|
691 |
+
$feed[] = $headers;
|
692 |
+
foreach ($this->products as $no => $product) {
|
693 |
+
$row = array();
|
694 |
+
foreach ($headers as $key => $header) {
|
695 |
+
$row[] = $product[$header];
|
696 |
+
}
|
697 |
+
$feed[] = $row;
|
698 |
+
}
|
699 |
+
|
700 |
+
return $feed;
|
701 |
+
}
|
702 |
+
return false;
|
703 |
+
}
|
704 |
}
|
includes/feeds/class-woo-feed-shopzilla.php
CHANGED
@@ -1,668 +1,668 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Class Shopzilla
|
5 |
-
*
|
6 |
-
* Responsible for processing and generating feed for Shopzilla.com
|
7 |
-
*
|
8 |
-
* @since 1.0.0
|
9 |
-
* @package Shopzilla
|
10 |
-
*
|
11 |
-
*/
|
12 |
-
class Shopzilla
|
13 |
-
{
|
14 |
-
|
15 |
-
/**
|
16 |
-
* This variable is responsible for holding all product attributes and their values
|
17 |
-
*
|
18 |
-
* @since 1.0.0
|
19 |
-
* @var array $products Contains all the product attributes to generate feed
|
20 |
-
* @access public
|
21 |
-
*/
|
22 |
-
public $products;
|
23 |
-
|
24 |
-
/**
|
25 |
-
* This variable is responsible for holding feed configuration form values
|
26 |
-
*
|
27 |
-
* @since 1.0.0
|
28 |
-
* @var Shopzilla $rules Contains feed configuration form values
|
29 |
-
* @access public
|
30 |
-
*/
|
31 |
-
public $rules;
|
32 |
-
|
33 |
-
/**
|
34 |
-
* This variable is responsible for mapping store attributes to merchant attribute
|
35 |
-
*
|
36 |
-
* @since 1.0.0
|
37 |
-
* @var Shopzilla $mapping Map store attributes to merchant attribute
|
38 |
-
* @access public
|
39 |
-
*/
|
40 |
-
public $mapping;
|
41 |
-
|
42 |
-
/**
|
43 |
-
* This variable is responsible for generate error logs
|
44 |
-
*
|
45 |
-
* @since 1.0.0
|
46 |
-
* @var Shopzilla $errorLog Generate error logs
|
47 |
-
* @access public
|
48 |
-
*/
|
49 |
-
public $errorLog;
|
50 |
-
|
51 |
-
/**
|
52 |
-
* This variable is responsible for making error number
|
53 |
-
*
|
54 |
-
* @since 1.0.0
|
55 |
-
* @var Shopzilla $errorCounter Generate error number
|
56 |
-
* @access public
|
57 |
-
*/
|
58 |
-
public $errorCounter;
|
59 |
-
|
60 |
-
/**
|
61 |
-
* Feed Wrapper text for enclosing each product information
|
62 |
-
*
|
63 |
-
* @since 1.0.0
|
64 |
-
* @var Shopzilla $feedWrapper Feed Wrapper text
|
65 |
-
* @access public
|
66 |
-
*/
|
67 |
-
private $feedWrapper;
|
68 |
-
|
69 |
-
/**
|
70 |
-
* Define the core functionality to generate feed.
|
71 |
-
*
|
72 |
-
* Set the feed rules. Map products according to the rules and Check required attributes
|
73 |
-
* and their values according to merchant specification.
|
74 |
-
* @var Woo_Generate_Feed $feedRule Contain Feed Configuration
|
75 |
-
* @since 1.0.0
|
76 |
-
*/
|
77 |
-
public function __construct($feedRule)
|
78 |
-
{
|
79 |
-
$this->feedWrapper = 'product';
|
80 |
-
$this->errorCounter = 0;
|
81 |
-
$this->rules = $feedRule;
|
82 |
-
$this->mapProductsByRules();
|
83 |
-
$this->formatRequiredField();
|
84 |
-
$this->filterProductValues();
|
85 |
-
if ($this->rules['feedType'] == 'xml') {
|
86 |
-
$this->mapAttributeForXML();
|
87 |
-
} else {
|
88 |
-
$this->mapAttributeForCSVTEXT();
|
89 |
-
}
|
90 |
-
}
|
91 |
-
|
92 |
-
/**
|
93 |
-
* Configure merchant attributes for XML feed
|
94 |
-
*/
|
95 |
-
public function mapAttributeForXML()
|
96 |
-
{
|
97 |
-
//Basic product information
|
98 |
-
|
99 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
100 |
-
foreach ($this->products as $key => $values) {
|
101 |
-
foreach ($values as $attr => $value) {
|
102 |
-
$this->products[$key][$attr] = $this->formatXMLLine($attr, $value, true, true, true);
|
103 |
-
}
|
104 |
-
}
|
105 |
-
}
|
106 |
-
}
|
107 |
-
|
108 |
-
/**
|
109 |
-
* Configure merchant attributes for CSV and TXT feed
|
110 |
-
*/
|
111 |
-
public function mapAttributeForCSVTEXT()
|
112 |
-
{
|
113 |
-
//Basic product information
|
114 |
-
|
115 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
116 |
-
foreach ($this->products as $key => $values) {
|
117 |
-
foreach ($values as $attr => $value) {
|
118 |
-
//Allow force strip HTML
|
119 |
-
$value = strip_tags(html_entity_decode($value));
|
120 |
-
if ($attr != 'Category') {
|
121 |
-
$value = utf8_encode($value);
|
122 |
-
$attr = utf8_encode($attr);
|
123 |
-
|
124 |
-
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
|
125 |
-
|
126 |
-
if (gettype($value) == 'array')
|
127 |
-
$value = json_encode($value);
|
128 |
-
}
|
129 |
-
|
130 |
-
$this->products[$key][$attr] = $value;
|
131 |
-
}
|
132 |
-
}
|
133 |
-
}
|
134 |
-
}
|
135 |
-
|
136 |
-
/**
|
137 |
-
* Check all the required attributes and make error message
|
138 |
-
*/
|
139 |
-
public function formatRequiredField()
|
140 |
-
{
|
141 |
-
foreach ($this->products as $no => $product) {
|
142 |
-
$upn = 0;
|
143 |
-
if (array_key_exists('Unique ID', $product)) {
|
144 |
-
$id = $product['Unique ID'];
|
145 |
-
} else {
|
146 |
-
$id = $product['Title'];
|
147 |
-
}
|
148 |
-
|
149 |
-
if (!array_key_exists('Unique ID', $product)) {
|
150 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Unique ID</b>] Missing for <b>$id</b>.";
|
151 |
-
$this->errorCounter++;
|
152 |
-
}
|
153 |
-
|
154 |
-
|
155 |
-
if (!array_key_exists('Title', $product)) {
|
156 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Title</b>] Missing for <b>$id</b>.";
|
157 |
-
$this->errorCounter++;
|
158 |
-
}
|
159 |
-
|
160 |
-
if (!array_key_exists('Description', $product)) {
|
161 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Description</b>] Missing for <b>$id</b>.";
|
162 |
-
$this->errorCounter++;
|
163 |
-
}
|
164 |
-
|
165 |
-
if (!array_key_exists('Category', $product)) {
|
166 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Category</b>] Missing for <b>$id</b>.";
|
167 |
-
$this->errorCounter++;
|
168 |
-
}
|
169 |
-
|
170 |
-
if (!array_key_exists('Product URL', $product)) {
|
171 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Product URL</b>] Missing for <b>$id</b>.";
|
172 |
-
$this->errorCounter++;
|
173 |
-
}
|
174 |
-
|
175 |
-
if (!array_key_exists('Image URL', $product)) {
|
176 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Image URL</b>] Missing for <b>$id</b>.";
|
177 |
-
$this->errorCounter++;
|
178 |
-
}
|
179 |
-
|
180 |
-
if (!array_key_exists('Condition', $product)) {
|
181 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Condition</b>] Missing for <b>$id</b>.";
|
182 |
-
$this->errorCounter++;
|
183 |
-
}
|
184 |
-
|
185 |
-
if (!array_key_exists('Availability', $product)) {
|
186 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Availability</b>] Missing for <b>$id</b>.";
|
187 |
-
$this->errorCounter++;
|
188 |
-
}
|
189 |
-
|
190 |
-
if (!array_key_exists('Current price', $product)) {
|
191 |
-
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Current price</b>] Missing for <b>$id</b>.";
|
192 |
-
$this->errorCounter++;
|
193 |
-
}
|
194 |
-
}
|
195 |
-
}
|
196 |
-
|
197 |
-
/**
|
198 |
-
* Return Feed
|
199 |
-
*
|
200 |
-
* @return array|bool|string
|
201 |
-
*/
|
202 |
-
public function returnFinalProduct()
|
203 |
-
{
|
204 |
-
if ($this->rules['feedType'] == 'xml') {
|
205 |
-
return $this->get_feed($this->products);
|
206 |
-
} elseif ($this->rules['feedType'] == 'txt') {
|
207 |
-
return $this->get_txt_feed();
|
208 |
-
} elseif ($this->rules['feedType'] == 'csv') {
|
209 |
-
return $this->get_csv_feed();
|
210 |
-
}
|
211 |
-
return false;
|
212 |
-
}
|
213 |
-
|
214 |
-
/**
|
215 |
-
* Check product's attribute value according to merchant specifications
|
216 |
-
*/
|
217 |
-
public function filterProductValues()
|
218 |
-
{
|
219 |
-
$getProduct = new Woo_Feed_Products();
|
220 |
-
$products = $this->products;
|
221 |
-
|
222 |
-
foreach ($products as $no => $product) {
|
223 |
-
if (array_key_exists('Unique ID', $product)) {
|
224 |
-
$id = $product['Unique ID'];
|
225 |
-
} else {
|
226 |
-
$id = $product['Title'];
|
227 |
-
}
|
228 |
-
// echo "<pre>";
|
229 |
-
// print_r($product);
|
230 |
-
foreach ($product as $key => $value) {
|
231 |
-
switch ($key) {
|
232 |
-
case "Unique ID":
|
233 |
-
if (strlen($value) > 100) {
|
234 |
-
$this->errorLog[$this->errorCounter] = "[<b>Unique ID</b>] is more that 100 character for $id.";
|
235 |
-
$this->errorCounter++;
|
236 |
-
}
|
237 |
-
break;
|
238 |
-
case "Title":
|
239 |
-
if (strlen($value) > 1000) {
|
240 |
-
$this->errorLog[$this->errorCounter] = "[<b>Title</b>] is more that 1000 character for $id.";
|
241 |
-
$this->errorCounter++;
|
242 |
-
}
|
243 |
-
break;
|
244 |
-
case "Description":
|
245 |
-
if (strlen($value) > 3000) {
|
246 |
-
$this->errorLog[$this->errorCounter] = "[<b>Description</b>] is more that 3000 character for $id.";
|
247 |
-
$this->errorCounter++;
|
248 |
-
}
|
249 |
-
break;
|
250 |
-
case "Category":
|
251 |
-
if (strlen($value) > 1000) {
|
252 |
-
$this->errorLog[$this->errorCounter] = "[<b>Category</b>] is more that 1000 character for $id.";
|
253 |
-
$this->errorCounter++;
|
254 |
-
}
|
255 |
-
break;
|
256 |
-
case "Product URL":
|
257 |
-
if (strpos($value, 'http://') == false || strpos($value, 'https://') == false) {
|
258 |
-
$this->errorLog[$this->errorCounter] = "[<b>Product URL</b>] must start with http:// or https:// for $id.";
|
259 |
-
$this->errorCounter++;
|
260 |
-
}
|
261 |
-
|
262 |
-
if (strlen($value) > 2000) {
|
263 |
-
$this->errorLog[$this->errorCounter] = "[<b>Product URL</b>] is more that 2000 character for $id.";
|
264 |
-
$this->errorCounter++;
|
265 |
-
}
|
266 |
-
|
267 |
-
break;
|
268 |
-
case "Image URL":
|
269 |
-
if (strpos($value, 'http://') == false || strpos($value, 'https://') == false) {
|
270 |
-
$this->errorLog[$this->errorCounter] = "[<b>Image URL</b>] must start with http:// or https:// for $id.";
|
271 |
-
$this->errorCounter++;
|
272 |
-
}
|
273 |
-
|
274 |
-
if (strlen($value) > 2000) {
|
275 |
-
$this->errorLog[$this->errorCounter] = "[<b>Image URL</b>] is more that 2000 character for $id.";
|
276 |
-
$this->errorCounter++;
|
277 |
-
}
|
278 |
-
|
279 |
-
list($width, $height) = getimagesize($value);
|
280 |
-
if ($width < 450 || $height < 450) {
|
281 |
-
$this->errorLog[$this->errorCounter] = "<b>Image Width and Height</b> should be more that 450px for $id.";
|
282 |
-
$this->errorCounter++;
|
283 |
-
}
|
284 |
-
|
285 |
-
break;
|
286 |
-
case "Condition":
|
287 |
-
$condition = array("New", "Used", "Refurbished", "Open Box", "OEM");
|
288 |
-
if (!array_key_exists($value, $condition)) {
|
289 |
-
$this->errorLog[$this->errorCounter] = "[<b>Condition</b>] = $value is acceptable for $id.";
|
290 |
-
$this->errorCounter++;
|
291 |
-
}
|
292 |
-
break;
|
293 |
-
case "Availability":
|
294 |
-
$availability = array("In Stock", "Out of Stock", "Available for Order", "PreOrder");
|
295 |
-
if ($value == 'in stock') {
|
296 |
-
$this->products[$no][$key] = "In Stock";
|
297 |
-
} else {
|
298 |
-
$this->products[$no][$key] = "Out of Stock";
|
299 |
-
}
|
300 |
-
|
301 |
-
if (!array_key_exists($this->products[$no][$key], $availability)) {
|
302 |
-
$this->errorLog[$this->errorCounter] = "[<b>Availability</b>] = $value is acceptable for $id.";
|
303 |
-
$this->errorCounter++;
|
304 |
-
}
|
305 |
-
break;
|
306 |
-
case "Current price":
|
307 |
-
if (!is_numeric($value)) {
|
308 |
-
$this->errorLog[$this->errorCounter] = "[<b>Current price</b>] should be numeric for $id.";
|
309 |
-
$this->errorCounter++;
|
310 |
-
}
|
311 |
-
break;
|
312 |
-
case "Original Price":
|
313 |
-
if (!is_numeric($value)) {
|
314 |
-
$this->errorLog[$this->errorCounter] = "[<b>Original price</b>] should be numeric for $id.";
|
315 |
-
$this->errorCounter++;
|
316 |
-
}
|
317 |
-
break;
|
318 |
-
default:
|
319 |
-
break;
|
320 |
-
}
|
321 |
-
}
|
322 |
-
}
|
323 |
-
}
|
324 |
-
|
325 |
-
/**
|
326 |
-
* Return Dynamic Category Mapping Values by Parent Product Id
|
327 |
-
*
|
328 |
-
* @param string $mappingName Category Mapping Name
|
329 |
-
* @param int $parent Parent id of the product
|
330 |
-
* @return mixed
|
331 |
-
*/
|
332 |
-
public function get_category_mapping_value($mappingName, $parent)
|
333 |
-
{
|
334 |
-
$getValue = unserialize(get_option($mappingName));
|
335 |
-
$mapp = array_reverse($getValue['cmapping'], true);
|
336 |
-
$categories = get_the_terms($parent, 'product_cat');
|
337 |
-
|
338 |
-
foreach ($categories as $key => $category) {
|
339 |
-
if (!empty($mapp[$category->term_id]))
|
340 |
-
return $mapp[$category->term_id];
|
341 |
-
}
|
342 |
-
return false;
|
343 |
-
}
|
344 |
-
|
345 |
-
/**
|
346 |
-
* Configure the feed according to the rules
|
347 |
-
* @return Shopping
|
348 |
-
*/
|
349 |
-
public function mapProductsByRules()
|
350 |
-
{
|
351 |
-
/**
|
352 |
-
* Get WooCommerce Products
|
353 |
-
* @package Woo_Feed_Products
|
354 |
-
*/
|
355 |
-
$products = new Woo_Feed_Products();
|
356 |
-
|
357 |
-
/**
|
358 |
-
* This variable contain selected Woo attributes from feed making form
|
359 |
-
*
|
360 |
-
* @since 1.0.0
|
361 |
-
* @var array $attributes contain selected Woo attributes from feed making form
|
362 |
-
*/
|
363 |
-
$attributes = $this->rules['attributes'];
|
364 |
-
/**
|
365 |
-
* This variable contain selected Prefix Values from feed making form
|
366 |
-
*
|
367 |
-
* @since 1.0.0
|
368 |
-
* @var array $prefix Prefix Values from feed making form
|
369 |
-
*/
|
370 |
-
$prefix = $this->rules['prefix'];
|
371 |
-
/**
|
372 |
-
* This variable contain selected Prefix Values from feed making form
|
373 |
-
*
|
374 |
-
* @since 1.0.0
|
375 |
-
* @var array $suffix Suffix Values from feed making form
|
376 |
-
*/
|
377 |
-
$suffix = $this->rules['suffix'];
|
378 |
-
/**
|
379 |
-
* This variable contain selected Output Types from feed making form
|
380 |
-
*
|
381 |
-
* @since 1.0.0
|
382 |
-
* @var array $outputType Output Types from feed making form
|
383 |
-
*/
|
384 |
-
$outputType = $this->rules['output_type'];
|
385 |
-
|
386 |
-
/**
|
387 |
-
* This variable contain selected Output Limit from feed making form
|
388 |
-
*
|
389 |
-
* @since 1.0.0
|
390 |
-
* @var array $limit Output Limit from feed making form
|
391 |
-
*/
|
392 |
-
$limit = $this->rules['limit'];
|
393 |
-
/**
|
394 |
-
* This variable contain selected Merchant attributes from feed making form
|
395 |
-
*
|
396 |
-
* @since 1.0.0
|
397 |
-
* @var array $merchantAttributes contain selected Woo attributes from feed making form
|
398 |
-
*/
|
399 |
-
$merchantAttributes = $this->rules['mattributes'];
|
400 |
-
/**
|
401 |
-
* This variable contain attribute types from feed making form
|
402 |
-
*
|
403 |
-
* @since 1.0.0
|
404 |
-
* @var array $type contain attribute types from feed making form
|
405 |
-
*/
|
406 |
-
$type = $this->rules['type'];
|
407 |
-
/**
|
408 |
-
* This variable contain manual output of attribute from feed making form
|
409 |
-
*
|
410 |
-
* @since 1.0.0
|
411 |
-
* @var array $default contain manual output of attribute
|
412 |
-
*/
|
413 |
-
$default = $this->rules['default'];
|
414 |
-
|
415 |
-
/**
|
416 |
-
* This variable contain feed type
|
417 |
-
*
|
418 |
-
* @since 1.0.0
|
419 |
-
* @var array $feedType contain feed type
|
420 |
-
*/
|
421 |
-
$feedType = $this->rules['feedType'];
|
422 |
-
|
423 |
-
// Map Merchant Attributes and Woo Attributes
|
424 |
-
if (count($merchantAttributes)) {
|
425 |
-
foreach ($merchantAttributes as $key => $attr) {
|
426 |
-
if (!empty($attr) && !empty($attributes[$key])) {
|
427 |
-
if ($type[$key] == 'attribute') {
|
428 |
-
$this->mapping[$attr]['value'] = $attributes[$key];
|
429 |
-
$this->mapping[$attr]['suffix'] = $suffix[$key];
|
430 |
-
$this->mapping[$attr]['prefix'] = $prefix[$key];
|
431 |
-
$this->mapping[$attr]['type'] = $outputType[$key];
|
432 |
-
$this->mapping[$attr]['limit'] = $limit[$key];
|
433 |
-
}
|
434 |
-
} else if (empty($attributes[$key])) {
|
435 |
-
if ($type[$key] == 'pattern') {
|
436 |
-
$this->mapping[$attr]['value'] = "wf_pattern_$default[$key]";
|
437 |
-
$this->mapping[$attr]['suffix'] = $suffix[$key];
|
438 |
-
$this->mapping[$attr]['prefix'] = $prefix[$key];
|
439 |
-
$this->mapping[$attr]['type'] = $outputType[$key];
|
440 |
-
$this->mapping[$attr]['limit'] = $limit[$key];
|
441 |
-
}
|
442 |
-
}
|
443 |
-
}
|
444 |
-
}
|
445 |
-
|
446 |
-
// Make Product feed array according to mapping
|
447 |
-
foreach ($products->woo_feed_get_visible_product() as $key => $value) {
|
448 |
-
$i = 0;
|
449 |
-
foreach ($this->mapping as $attr => $rules) {
|
450 |
-
if (array_key_exists($rules['value'], $value)) {
|
451 |
-
|
452 |
-
$output = $rules['prefix'] . $value[$rules['value']] . " " . $rules['suffix'];
|
453 |
-
// Format According to output type
|
454 |
-
if ($rules['type'] == 2) {
|
455 |
-
$output = strip_tags($output);
|
456 |
-
} elseif ($rules['type'] == 3) {
|
457 |
-
$output = absint($output);
|
458 |
-
}
|
459 |
-
// Format According to output limit
|
460 |
-
if (!empty($rules['limit']) && is_numeric($rules['limit'])) {
|
461 |
-
$output = substr($output, 0, $rules['limit']);
|
462 |
-
}
|
463 |
-
$attr = trim($attr);
|
464 |
-
$this->products[$key][$attr] = trim($output);
|
465 |
-
} else {
|
466 |
-
if (!empty($default[$i])) {
|
467 |
-
$output = $rules['prefix'] . str_replace("wf_pattern_", "", $rules['value']) . " " . $rules['suffix'];
|
468 |
-
if ($rules['type'] == 2) {
|
469 |
-
$output = strip_tags($output);
|
470 |
-
} elseif ($rules['type'] == 3) {
|
471 |
-
$output = absint($output);
|
472 |
-
}
|
473 |
-
// Format According to output limit
|
474 |
-
if (!empty($rules['limit']) && is_numeric($rules['limit'])) {
|
475 |
-
$output = substr($output, 0, $rules['limit']);
|
476 |
-
}
|
477 |
-
$attr = trim($attr);
|
478 |
-
$this->products[$key][$attr] = trim($output);
|
479 |
-
}
|
480 |
-
}
|
481 |
-
$i++;
|
482 |
-
}
|
483 |
-
}
|
484 |
-
|
485 |
-
|
486 |
-
return $this->products;
|
487 |
-
}
|
488 |
-
|
489 |
-
/**
|
490 |
-
* Change the products old array key and set new
|
491 |
-
*
|
492 |
-
* @param string $from Attribute Before
|
493 |
-
* @param string $to Attribute After
|
494 |
-
* @param bool $cdata Enclose Feed value
|
495 |
-
*/
|
496 |
-
public function mapAttribute($from, $to, $cdata = false)
|
497 |
-
{
|
498 |
-
$i = 0;
|
499 |
-
foreach ($this->products as $no => $product) {
|
500 |
-
foreach ($product as $key => $value) {
|
501 |
-
if ($key == $from) {
|
502 |
-
unset($this->products[$no][$from]);
|
503 |
-
if ($from == 'images') {
|
504 |
-
$this->products[$no][$to] = $value;
|
505 |
-
} else {
|
506 |
-
$this->products[$no][$to] = $this->formatXMLLine($to, $value, $cdata, true, true);
|
507 |
-
}
|
508 |
-
|
509 |
-
}
|
510 |
-
}
|
511 |
-
$i++;
|
512 |
-
}
|
513 |
-
}
|
514 |
-
|
515 |
-
/**
|
516 |
-
* Format and Make the XML node for the Feed
|
517 |
-
*
|
518 |
-
* @param $attribute
|
519 |
-
* @param $value
|
520 |
-
* @param bool $cdata
|
521 |
-
* @param bool $stripHTML
|
522 |
-
* @param bool $utf8encode
|
523 |
-
* @param string $space
|
524 |
-
* @return string
|
525 |
-
*/
|
526 |
-
function formatXMLLine($attribute, $value, $cdata = false, $stripHTML = true, $utf8encode = true, $space = ' ')
|
527 |
-
{
|
528 |
-
//Make single line for XML
|
529 |
-
$c_leader = '';
|
530 |
-
$c_footer = '';
|
531 |
-
if ($cdata) {
|
532 |
-
$c_leader = '<![CDATA[';
|
533 |
-
$c_footer = ']]>';
|
534 |
-
}
|
535 |
-
//Allow force strip HTML
|
536 |
-
if ($stripHTML)
|
537 |
-
$value = strip_tags(html_entity_decode($value));
|
538 |
-
|
539 |
-
|
540 |
-
if ($utf8encode || $utf8encode == 1) {
|
541 |
-
$value = utf8_encode($value);
|
542 |
-
$attribute = utf8_encode($attribute);
|
543 |
-
}
|
544 |
-
|
545 |
-
|
546 |
-
if (!$cdata)
|
547 |
-
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
|
548 |
-
|
549 |
-
if (gettype($value) == 'array')
|
550 |
-
$value = json_encode($value);
|
551 |
-
|
552 |
-
|
553 |
-
return '
|
554 |
-
' . $space . '<' . $attribute . '>' . $c_leader . $value . $c_footer . '</' . $attribute . '>';
|
555 |
-
}
|
556 |
-
|
557 |
-
/**
|
558 |
-
* Responsible to change product array key
|
559 |
-
*
|
560 |
-
* @param $array
|
561 |
-
* @param $old_key
|
562 |
-
* @param $new_key
|
563 |
-
* @return array
|
564 |
-
*/
|
565 |
-
function change_key($array, $old_key, $new_key)
|
566 |
-
{
|
567 |
-
foreach ($this->products as $no => $product) {
|
568 |
-
if (!array_key_exists($old_key, $product))
|
569 |
-
return $array;
|
570 |
-
|
571 |
-
$keys = array_keys($array);
|
572 |
-
$keys[array_search($old_key, $keys)] = $new_key;
|
573 |
-
}
|
574 |
-
return array_combine($keys, $array);
|
575 |
-
}
|
576 |
-
|
577 |
-
/**
|
578 |
-
* Responsible to make XML feed header
|
579 |
-
* @return string
|
580 |
-
*/
|
581 |
-
public function get_feed_header()
|
582 |
-
{
|
583 |
-
$output = '<?xml version="1.0" encoding="UTF-8" ?>
|
584 |
-
<products>';
|
585 |
-
$output .= "\n";
|
586 |
-
return $output;
|
587 |
-
}
|
588 |
-
|
589 |
-
/**
|
590 |
-
* Responsible to make XML feed body
|
591 |
-
* @var array $item Product array
|
592 |
-
* @return string
|
593 |
-
*/
|
594 |
-
public function get_feed($items)
|
595 |
-
{
|
596 |
-
$feed = "";
|
597 |
-
$feed .= $this->get_feed_header();
|
598 |
-
$feed .= "\n";
|
599 |
-
foreach ($items as $item => $products) {
|
600 |
-
$feed .= " <" . $this->feedWrapper . ">";
|
601 |
-
foreach ($products as $key => $value) {
|
602 |
-
if (!empty($value))
|
603 |
-
$feed .= $value;
|
604 |
-
}
|
605 |
-
$feed .= "\n </" . $this->feedWrapper . ">\n";
|
606 |
-
}
|
607 |
-
$feed .= $this->get_feed_footer();
|
608 |
-
|
609 |
-
return $feed;
|
610 |
-
}
|
611 |
-
|
612 |
-
/**
|
613 |
-
* Responsible to make XML feed footer
|
614 |
-
* @return string
|
615 |
-
*/
|
616 |
-
public function get_feed_footer()
|
617 |
-
{
|
618 |
-
$footer = " </products>";
|
619 |
-
return $footer;
|
620 |
-
}
|
621 |
-
|
622 |
-
/**
|
623 |
-
* Responsible to make TXT feed
|
624 |
-
* @return string
|
625 |
-
*/
|
626 |
-
public function get_txt_feed()
|
627 |
-
{
|
628 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
629 |
-
$headers = array_keys($this->products[0]);
|
630 |
-
$feed[] = $headers;
|
631 |
-
foreach ($this->products as $no => $product) {
|
632 |
-
$row = array();
|
633 |
-
foreach ($headers as $key => $header) {
|
634 |
-
$row[] = $product[$header];
|
635 |
-
}
|
636 |
-
$feed[] = $row;
|
637 |
-
}
|
638 |
-
$str = "";
|
639 |
-
foreach ($feed as $fields) {
|
640 |
-
$str .= implode("\t", $fields) . "\n";
|
641 |
-
}
|
642 |
-
return $str;
|
643 |
-
}
|
644 |
-
return false;
|
645 |
-
}
|
646 |
-
|
647 |
-
/**
|
648 |
-
* Responsible to make CSV feed
|
649 |
-
* @return string
|
650 |
-
*/
|
651 |
-
public function get_csv_feed()
|
652 |
-
{
|
653 |
-
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
654 |
-
$headers = array_keys($this->products[0]);
|
655 |
-
$feed[] = $headers;
|
656 |
-
foreach ($this->products as $no => $product) {
|
657 |
-
$row = array();
|
658 |
-
foreach ($headers as $key => $header) {
|
659 |
-
$row[] = $product[$header];
|
660 |
-
}
|
661 |
-
$feed[] = $row;
|
662 |
-
}
|
663 |
-
|
664 |
-
return $feed;
|
665 |
-
}
|
666 |
-
return false;
|
667 |
-
}
|
668 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Shopzilla
|
5 |
+
*
|
6 |
+
* Responsible for processing and generating feed for Shopzilla.com
|
7 |
+
*
|
8 |
+
* @since 1.0.0
|
9 |
+
* @package Shopzilla
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Shopzilla
|
13 |
+
{
|
14 |
+
|
15 |
+
/**
|
16 |
+
* This variable is responsible for holding all product attributes and their values
|
17 |
+
*
|
18 |
+
* @since 1.0.0
|
19 |
+
* @var array $products Contains all the product attributes to generate feed
|
20 |
+
* @access public
|
21 |
+
*/
|
22 |
+
public $products;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* This variable is responsible for holding feed configuration form values
|
26 |
+
*
|
27 |
+
* @since 1.0.0
|
28 |
+
* @var Shopzilla $rules Contains feed configuration form values
|
29 |
+
* @access public
|
30 |
+
*/
|
31 |
+
public $rules;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* This variable is responsible for mapping store attributes to merchant attribute
|
35 |
+
*
|
36 |
+
* @since 1.0.0
|
37 |
+
* @var Shopzilla $mapping Map store attributes to merchant attribute
|
38 |
+
* @access public
|
39 |
+
*/
|
40 |
+
public $mapping;
|
41 |
+
|
42 |
+
/**
|
43 |
+
* This variable is responsible for generate error logs
|
44 |
+
*
|
45 |
+
* @since 1.0.0
|
46 |
+
* @var Shopzilla $errorLog Generate error logs
|
47 |
+
* @access public
|
48 |
+
*/
|
49 |
+
public $errorLog;
|
50 |
+
|
51 |
+
/**
|
52 |
+
* This variable is responsible for making error number
|
53 |
+
*
|
54 |
+
* @since 1.0.0
|
55 |
+
* @var Shopzilla $errorCounter Generate error number
|
56 |
+
* @access public
|
57 |
+
*/
|
58 |
+
public $errorCounter;
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Feed Wrapper text for enclosing each product information
|
62 |
+
*
|
63 |
+
* @since 1.0.0
|
64 |
+
* @var Shopzilla $feedWrapper Feed Wrapper text
|
65 |
+
* @access public
|
66 |
+
*/
|
67 |
+
private $feedWrapper;
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Define the core functionality to generate feed.
|
71 |
+
*
|
72 |
+
* Set the feed rules. Map products according to the rules and Check required attributes
|
73 |
+
* and their values according to merchant specification.
|
74 |
+
* @var Woo_Generate_Feed $feedRule Contain Feed Configuration
|
75 |
+
* @since 1.0.0
|
76 |
+
*/
|
77 |
+
public function __construct($feedRule)
|
78 |
+
{
|
79 |
+
$this->feedWrapper = 'product';
|
80 |
+
$this->errorCounter = 0;
|
81 |
+
$this->rules = $feedRule;
|
82 |
+
$this->mapProductsByRules();
|
83 |
+
$this->formatRequiredField();
|
84 |
+
$this->filterProductValues();
|
85 |
+
if ($this->rules['feedType'] == 'xml') {
|
86 |
+
$this->mapAttributeForXML();
|
87 |
+
} else {
|
88 |
+
$this->mapAttributeForCSVTEXT();
|
89 |
+
}
|
90 |
+
}
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Configure merchant attributes for XML feed
|
94 |
+
*/
|
95 |
+
public function mapAttributeForXML()
|
96 |
+
{
|
97 |
+
//Basic product information
|
98 |
+
|
99 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
100 |
+
foreach ($this->products as $key => $values) {
|
101 |
+
foreach ($values as $attr => $value) {
|
102 |
+
$this->products[$key][$attr] = $this->formatXMLLine($attr, $value, true, true, true);
|
103 |
+
}
|
104 |
+
}
|
105 |
+
}
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* Configure merchant attributes for CSV and TXT feed
|
110 |
+
*/
|
111 |
+
public function mapAttributeForCSVTEXT()
|
112 |
+
{
|
113 |
+
//Basic product information
|
114 |
+
|
115 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
116 |
+
foreach ($this->products as $key => $values) {
|
117 |
+
foreach ($values as $attr => $value) {
|
118 |
+
//Allow force strip HTML
|
119 |
+
$value = strip_tags(html_entity_decode($value));
|
120 |
+
if ($attr != 'Category') {
|
121 |
+
$value = utf8_encode($value);
|
122 |
+
$attr = utf8_encode($attr);
|
123 |
+
|
124 |
+
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
|
125 |
+
|
126 |
+
if (gettype($value) == 'array')
|
127 |
+
$value = json_encode($value);
|
128 |
+
}
|
129 |
+
|
130 |
+
$this->products[$key][$attr] = $value;
|
131 |
+
}
|
132 |
+
}
|
133 |
+
}
|
134 |
+
}
|
135 |
+
|
136 |
+
/**
|
137 |
+
* Check all the required attributes and make error message
|
138 |
+
*/
|
139 |
+
public function formatRequiredField()
|
140 |
+
{
|
141 |
+
foreach ($this->products as $no => $product) {
|
142 |
+
$upn = 0;
|
143 |
+
if (array_key_exists('Unique ID', $product)) {
|
144 |
+
$id = $product['Unique ID'];
|
145 |
+
} else {
|
146 |
+
$id = $product['Title'];
|
147 |
+
}
|
148 |
+
|
149 |
+
if (!array_key_exists('Unique ID', $product)) {
|
150 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Unique ID</b>] Missing for <b>$id</b>.";
|
151 |
+
$this->errorCounter++;
|
152 |
+
}
|
153 |
+
|
154 |
+
|
155 |
+
if (!array_key_exists('Title', $product)) {
|
156 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Title</b>] Missing for <b>$id</b>.";
|
157 |
+
$this->errorCounter++;
|
158 |
+
}
|
159 |
+
|
160 |
+
if (!array_key_exists('Description', $product)) {
|
161 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Description</b>] Missing for <b>$id</b>.";
|
162 |
+
$this->errorCounter++;
|
163 |
+
}
|
164 |
+
|
165 |
+
if (!array_key_exists('Category', $product)) {
|
166 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Category</b>] Missing for <b>$id</b>.";
|
167 |
+
$this->errorCounter++;
|
168 |
+
}
|
169 |
+
|
170 |
+
if (!array_key_exists('Product URL', $product)) {
|
171 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Product URL</b>] Missing for <b>$id</b>.";
|
172 |
+
$this->errorCounter++;
|
173 |
+
}
|
174 |
+
|
175 |
+
if (!array_key_exists('Image URL', $product)) {
|
176 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Image URL</b>] Missing for <b>$id</b>.";
|
177 |
+
$this->errorCounter++;
|
178 |
+
}
|
179 |
+
|
180 |
+
if (!array_key_exists('Condition', $product)) {
|
181 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Condition</b>] Missing for <b>$id</b>.";
|
182 |
+
$this->errorCounter++;
|
183 |
+
}
|
184 |
+
|
185 |
+
if (!array_key_exists('Availability', $product)) {
|
186 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Availability</b>] Missing for <b>$id</b>.";
|
187 |
+
$this->errorCounter++;
|
188 |
+
}
|
189 |
+
|
190 |
+
if (!array_key_exists('Current price', $product)) {
|
191 |
+
$this->errorLog[$this->errorCounter] = "Required Attribute [<b>Current price</b>] Missing for <b>$id</b>.";
|
192 |
+
$this->errorCounter++;
|
193 |
+
}
|
194 |
+
}
|
195 |
+
}
|
196 |
+
|
197 |
+
/**
|
198 |
+
* Return Feed
|
199 |
+
*
|
200 |
+
* @return array|bool|string
|
201 |
+
*/
|
202 |
+
public function returnFinalProduct()
|
203 |
+
{
|
204 |
+
if ($this->rules['feedType'] == 'xml') {
|
205 |
+
return $this->get_feed($this->products);
|
206 |
+
} elseif ($this->rules['feedType'] == 'txt') {
|
207 |
+
return $this->get_txt_feed();
|
208 |
+
} elseif ($this->rules['feedType'] == 'csv') {
|
209 |
+
return $this->get_csv_feed();
|
210 |
+
}
|
211 |
+
return false;
|
212 |
+
}
|
213 |
+
|
214 |
+
/**
|
215 |
+
* Check product's attribute value according to merchant specifications
|
216 |
+
*/
|
217 |
+
public function filterProductValues()
|
218 |
+
{
|
219 |
+
$getProduct = new Woo_Feed_Products();
|
220 |
+
$products = $this->products;
|
221 |
+
|
222 |
+
foreach ($products as $no => $product) {
|
223 |
+
if (array_key_exists('Unique ID', $product)) {
|
224 |
+
$id = $product['Unique ID'];
|
225 |
+
} else {
|
226 |
+
$id = $product['Title'];
|
227 |
+
}
|
228 |
+
// echo "<pre>";
|
229 |
+
// print_r($product);
|
230 |
+
foreach ($product as $key => $value) {
|
231 |
+
switch ($key) {
|
232 |
+
case "Unique ID":
|
233 |
+
if (strlen($value) > 100) {
|
234 |
+
$this->errorLog[$this->errorCounter] = "[<b>Unique ID</b>] is more that 100 character for $id.";
|
235 |
+
$this->errorCounter++;
|
236 |
+
}
|
237 |
+
break;
|
238 |
+
case "Title":
|
239 |
+
if (strlen($value) > 1000) {
|
240 |
+
$this->errorLog[$this->errorCounter] = "[<b>Title</b>] is more that 1000 character for $id.";
|
241 |
+
$this->errorCounter++;
|
242 |
+
}
|
243 |
+
break;
|
244 |
+
case "Description":
|
245 |
+
if (strlen($value) > 3000) {
|
246 |
+
$this->errorLog[$this->errorCounter] = "[<b>Description</b>] is more that 3000 character for $id.";
|
247 |
+
$this->errorCounter++;
|
248 |
+
}
|
249 |
+
break;
|
250 |
+
case "Category":
|
251 |
+
if (strlen($value) > 1000) {
|
252 |
+
$this->errorLog[$this->errorCounter] = "[<b>Category</b>] is more that 1000 character for $id.";
|
253 |
+
$this->errorCounter++;
|
254 |
+
}
|
255 |
+
break;
|
256 |
+
case "Product URL":
|
257 |
+
if (strpos($value, 'http://') == false || strpos($value, 'https://') == false) {
|
258 |
+
$this->errorLog[$this->errorCounter] = "[<b>Product URL</b>] must start with http:// or https:// for $id.";
|
259 |
+
$this->errorCounter++;
|
260 |
+
}
|
261 |
+
|
262 |
+
if (strlen($value) > 2000) {
|
263 |
+
$this->errorLog[$this->errorCounter] = "[<b>Product URL</b>] is more that 2000 character for $id.";
|
264 |
+
$this->errorCounter++;
|
265 |
+
}
|
266 |
+
|
267 |
+
break;
|
268 |
+
case "Image URL":
|
269 |
+
if (strpos($value, 'http://') == false || strpos($value, 'https://') == false) {
|
270 |
+
$this->errorLog[$this->errorCounter] = "[<b>Image URL</b>] must start with http:// or https:// for $id.";
|
271 |
+
$this->errorCounter++;
|
272 |
+
}
|
273 |
+
|
274 |
+
if (strlen($value) > 2000) {
|
275 |
+
$this->errorLog[$this->errorCounter] = "[<b>Image URL</b>] is more that 2000 character for $id.";
|
276 |
+
$this->errorCounter++;
|
277 |
+
}
|
278 |
+
|
279 |
+
list($width, $height) = getimagesize($value);
|
280 |
+
if ($width < 450 || $height < 450) {
|
281 |
+
$this->errorLog[$this->errorCounter] = "<b>Image Width and Height</b> should be more that 450px for $id.";
|
282 |
+
$this->errorCounter++;
|
283 |
+
}
|
284 |
+
|
285 |
+
break;
|
286 |
+
case "Condition":
|
287 |
+
$condition = array("New", "Used", "Refurbished", "Open Box", "OEM");
|
288 |
+
if (!array_key_exists($value, $condition)) {
|
289 |
+
$this->errorLog[$this->errorCounter] = "[<b>Condition</b>] = $value is acceptable for $id.";
|
290 |
+
$this->errorCounter++;
|
291 |
+
}
|
292 |
+
break;
|
293 |
+
case "Availability":
|
294 |
+
$availability = array("In Stock", "Out of Stock", "Available for Order", "PreOrder");
|
295 |
+
if ($value == 'in stock') {
|
296 |
+
$this->products[$no][$key] = "In Stock";
|
297 |
+
} else {
|
298 |
+
$this->products[$no][$key] = "Out of Stock";
|
299 |
+
}
|
300 |
+
|
301 |
+
if (!array_key_exists($this->products[$no][$key], $availability)) {
|
302 |
+
$this->errorLog[$this->errorCounter] = "[<b>Availability</b>] = $value is acceptable for $id.";
|
303 |
+
$this->errorCounter++;
|
304 |
+
}
|
305 |
+
break;
|
306 |
+
case "Current price":
|
307 |
+
if (!is_numeric($value)) {
|
308 |
+
$this->errorLog[$this->errorCounter] = "[<b>Current price</b>] should be numeric for $id.";
|
309 |
+
$this->errorCounter++;
|
310 |
+
}
|
311 |
+
break;
|
312 |
+
case "Original Price":
|
313 |
+
if (!is_numeric($value)) {
|
314 |
+
$this->errorLog[$this->errorCounter] = "[<b>Original price</b>] should be numeric for $id.";
|
315 |
+
$this->errorCounter++;
|
316 |
+
}
|
317 |
+
break;
|
318 |
+
default:
|
319 |
+
break;
|
320 |
+
}
|
321 |
+
}
|
322 |
+
}
|
323 |
+
}
|
324 |
+
|
325 |
+
/**
|
326 |
+
* Return Dynamic Category Mapping Values by Parent Product Id
|
327 |
+
*
|
328 |
+
* @param string $mappingName Category Mapping Name
|
329 |
+
* @param int $parent Parent id of the product
|
330 |
+
* @return mixed
|
331 |
+
*/
|
332 |
+
public function get_category_mapping_value($mappingName, $parent)
|
333 |
+
{
|
334 |
+
$getValue = unserialize(get_option($mappingName));
|
335 |
+
$mapp = array_reverse($getValue['cmapping'], true);
|
336 |
+
$categories = get_the_terms($parent, 'product_cat');
|
337 |
+
|
338 |
+
foreach ($categories as $key => $category) {
|
339 |
+
if (!empty($mapp[$category->term_id]))
|
340 |
+
return $mapp[$category->term_id];
|
341 |
+
}
|
342 |
+
return false;
|
343 |
+
}
|
344 |
+
|
345 |
+
/**
|
346 |
+
* Configure the feed according to the rules
|
347 |
+
* @return Shopping
|
348 |
+
*/
|
349 |
+
public function mapProductsByRules()
|
350 |
+
{
|
351 |
+
/**
|
352 |
+
* Get WooCommerce Products
|
353 |
+
* @package Woo_Feed_Products
|
354 |
+
*/
|
355 |
+
$products = new Woo_Feed_Products();
|
356 |
+
|
357 |
+
/**
|
358 |
+
* This variable contain selected Woo attributes from feed making form
|
359 |
+
*
|
360 |
+
* @since 1.0.0
|
361 |
+
* @var array $attributes contain selected Woo attributes from feed making form
|
362 |
+
*/
|
363 |
+
$attributes = $this->rules['attributes'];
|
364 |
+
/**
|
365 |
+
* This variable contain selected Prefix Values from feed making form
|
366 |
+
*
|
367 |
+
* @since 1.0.0
|
368 |
+
* @var array $prefix Prefix Values from feed making form
|
369 |
+
*/
|
370 |
+
$prefix = $this->rules['prefix'];
|
371 |
+
/**
|
372 |
+
* This variable contain selected Prefix Values from feed making form
|
373 |
+
*
|
374 |
+
* @since 1.0.0
|
375 |
+
* @var array $suffix Suffix Values from feed making form
|
376 |
+
*/
|
377 |
+
$suffix = $this->rules['suffix'];
|
378 |
+
/**
|
379 |
+
* This variable contain selected Output Types from feed making form
|
380 |
+
*
|
381 |
+
* @since 1.0.0
|
382 |
+
* @var array $outputType Output Types from feed making form
|
383 |
+
*/
|
384 |
+
$outputType = $this->rules['output_type'];
|
385 |
+
|
386 |
+
/**
|
387 |
+
* This variable contain selected Output Limit from feed making form
|
388 |
+
*
|
389 |
+
* @since 1.0.0
|
390 |
+
* @var array $limit Output Limit from feed making form
|
391 |
+
*/
|
392 |
+
$limit = $this->rules['limit'];
|
393 |
+
/**
|
394 |
+
* This variable contain selected Merchant attributes from feed making form
|
395 |
+
*
|
396 |
+
* @since 1.0.0
|
397 |
+
* @var array $merchantAttributes contain selected Woo attributes from feed making form
|
398 |
+
*/
|
399 |
+
$merchantAttributes = $this->rules['mattributes'];
|
400 |
+
/**
|
401 |
+
* This variable contain attribute types from feed making form
|
402 |
+
*
|
403 |
+
* @since 1.0.0
|
404 |
+
* @var array $type contain attribute types from feed making form
|
405 |
+
*/
|
406 |
+
$type = $this->rules['type'];
|
407 |
+
/**
|
408 |
+
* This variable contain manual output of attribute from feed making form
|
409 |
+
*
|
410 |
+
* @since 1.0.0
|
411 |
+
* @var array $default contain manual output of attribute
|
412 |
+
*/
|
413 |
+
$default = $this->rules['default'];
|
414 |
+
|
415 |
+
/**
|
416 |
+
* This variable contain feed type
|
417 |
+
*
|
418 |
+
* @since 1.0.0
|
419 |
+
* @var array $feedType contain feed type
|
420 |
+
*/
|
421 |
+
$feedType = $this->rules['feedType'];
|
422 |
+
|
423 |
+
// Map Merchant Attributes and Woo Attributes
|
424 |
+
if (count($merchantAttributes)) {
|
425 |
+
foreach ($merchantAttributes as $key => $attr) {
|
426 |
+
if (!empty($attr) && !empty($attributes[$key])) {
|
427 |
+
if ($type[$key] == 'attribute') {
|
428 |
+
$this->mapping[$attr]['value'] = $attributes[$key];
|
429 |
+
$this->mapping[$attr]['suffix'] = $suffix[$key];
|
430 |
+
$this->mapping[$attr]['prefix'] = $prefix[$key];
|
431 |
+
$this->mapping[$attr]['type'] = $outputType[$key];
|
432 |
+
$this->mapping[$attr]['limit'] = $limit[$key];
|
433 |
+
}
|
434 |
+
} else if (empty($attributes[$key])) {
|
435 |
+
if ($type[$key] == 'pattern') {
|
436 |
+
$this->mapping[$attr]['value'] = "wf_pattern_$default[$key]";
|
437 |
+
$this->mapping[$attr]['suffix'] = $suffix[$key];
|
438 |
+
$this->mapping[$attr]['prefix'] = $prefix[$key];
|
439 |
+
$this->mapping[$attr]['type'] = $outputType[$key];
|
440 |
+
$this->mapping[$attr]['limit'] = $limit[$key];
|
441 |
+
}
|
442 |
+
}
|
443 |
+
}
|
444 |
+
}
|
445 |
+
|
446 |
+
// Make Product feed array according to mapping
|
447 |
+
foreach ($products->woo_feed_get_visible_product() as $key => $value) {
|
448 |
+
$i = 0;
|
449 |
+
foreach ($this->mapping as $attr => $rules) {
|
450 |
+
if (array_key_exists($rules['value'], $value)) {
|
451 |
+
|
452 |
+
$output = $rules['prefix'] . $value[$rules['value']] . " " . $rules['suffix'];
|
453 |
+
// Format According to output type
|
454 |
+
if ($rules['type'] == 2) {
|
455 |
+
$output = strip_tags($output);
|
456 |
+
} elseif ($rules['type'] == 3) {
|
457 |
+
$output = absint($output);
|
458 |
+
}
|
459 |
+
// Format According to output limit
|
460 |
+
if (!empty($rules['limit']) && is_numeric($rules['limit'])) {
|
461 |
+
$output = substr($output, 0, $rules['limit']);
|
462 |
+
}
|
463 |
+
$attr = trim($attr);
|
464 |
+
$this->products[$key][$attr] = trim($output);
|
465 |
+
} else {
|
466 |
+
if (!empty($default[$i])) {
|
467 |
+
$output = $rules['prefix'] . str_replace("wf_pattern_", "", $rules['value']) . " " . $rules['suffix'];
|
468 |
+
if ($rules['type'] == 2) {
|
469 |
+
$output = strip_tags($output);
|
470 |
+
} elseif ($rules['type'] == 3) {
|
471 |
+
$output = absint($output);
|
472 |
+
}
|
473 |
+
// Format According to output limit
|
474 |
+
if (!empty($rules['limit']) && is_numeric($rules['limit'])) {
|
475 |
+
$output = substr($output, 0, $rules['limit']);
|
476 |
+
}
|
477 |
+
$attr = trim($attr);
|
478 |
+
$this->products[$key][$attr] = trim($output);
|
479 |
+
}
|
480 |
+
}
|
481 |
+
$i++;
|
482 |
+
}
|
483 |
+
}
|
484 |
+
|
485 |
+
|
486 |
+
return $this->products;
|
487 |
+
}
|
488 |
+
|
489 |
+
/**
|
490 |
+
* Change the products old array key and set new
|
491 |
+
*
|
492 |
+
* @param string $from Attribute Before
|
493 |
+
* @param string $to Attribute After
|
494 |
+
* @param bool $cdata Enclose Feed value
|
495 |
+
*/
|
496 |
+
public function mapAttribute($from, $to, $cdata = false)
|
497 |
+
{
|
498 |
+
$i = 0;
|
499 |
+
foreach ($this->products as $no => $product) {
|
500 |
+
foreach ($product as $key => $value) {
|
501 |
+
if ($key == $from) {
|
502 |
+
unset($this->products[$no][$from]);
|
503 |
+
if ($from == 'images') {
|
504 |
+
$this->products[$no][$to] = $value;
|
505 |
+
} else {
|
506 |
+
$this->products[$no][$to] = $this->formatXMLLine($to, $value, $cdata, true, true);
|
507 |
+
}
|
508 |
+
|
509 |
+
}
|
510 |
+
}
|
511 |
+
$i++;
|
512 |
+
}
|
513 |
+
}
|
514 |
+
|
515 |
+
/**
|
516 |
+
* Format and Make the XML node for the Feed
|
517 |
+
*
|
518 |
+
* @param $attribute
|
519 |
+
* @param $value
|
520 |
+
* @param bool $cdata
|
521 |
+
* @param bool $stripHTML
|
522 |
+
* @param bool $utf8encode
|
523 |
+
* @param string $space
|
524 |
+
* @return string
|
525 |
+
*/
|
526 |
+
function formatXMLLine($attribute, $value, $cdata = false, $stripHTML = true, $utf8encode = true, $space = ' ')
|
527 |
+
{
|
528 |
+
//Make single line for XML
|
529 |
+
$c_leader = '';
|
530 |
+
$c_footer = '';
|
531 |
+
if ($cdata) {
|
532 |
+
$c_leader = '<![CDATA[';
|
533 |
+
$c_footer = ']]>';
|
534 |
+
}
|
535 |
+
//Allow force strip HTML
|
536 |
+
if ($stripHTML)
|
537 |
+
$value = strip_tags(html_entity_decode($value));
|
538 |
+
|
539 |
+
|
540 |
+
if ($utf8encode || $utf8encode == 1) {
|
541 |
+
$value = utf8_encode($value);
|
542 |
+
$attribute = utf8_encode($attribute);
|
543 |
+
}
|
544 |
+
|
545 |
+
|
546 |
+
if (!$cdata)
|
547 |
+
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
|
548 |
+
|
549 |
+
if (gettype($value) == 'array')
|
550 |
+
$value = json_encode($value);
|
551 |
+
|
552 |
+
|
553 |
+
return '
|
554 |
+
' . $space . '<' . $attribute . '>' . $c_leader . $value . $c_footer . '</' . $attribute . '>';
|
555 |
+
}
|
556 |
+
|
557 |
+
/**
|
558 |
+
* Responsible to change product array key
|
559 |
+
*
|
560 |
+
* @param $array
|
561 |
+
* @param $old_key
|
562 |
+
* @param $new_key
|
563 |
+
* @return array
|
564 |
+
*/
|
565 |
+
function change_key($array, $old_key, $new_key)
|
566 |
+
{
|
567 |
+
foreach ($this->products as $no => $product) {
|
568 |
+
if (!array_key_exists($old_key, $product))
|
569 |
+
return $array;
|
570 |
+
|
571 |
+
$keys = array_keys($array);
|
572 |
+
$keys[array_search($old_key, $keys)] = $new_key;
|
573 |
+
}
|
574 |
+
return array_combine($keys, $array);
|
575 |
+
}
|
576 |
+
|
577 |
+
/**
|
578 |
+
* Responsible to make XML feed header
|
579 |
+
* @return string
|
580 |
+
*/
|
581 |
+
public function get_feed_header()
|
582 |
+
{
|
583 |
+
$output = '<?xml version="1.0" encoding="UTF-8" ?>
|
584 |
+
<products>';
|
585 |
+
$output .= "\n";
|
586 |
+
return $output;
|
587 |
+
}
|
588 |
+
|
589 |
+
/**
|
590 |
+
* Responsible to make XML feed body
|
591 |
+
* @var array $item Product array
|
592 |
+
* @return string
|
593 |
+
*/
|
594 |
+
public function get_feed($items)
|
595 |
+
{
|
596 |
+
$feed = "";
|
597 |
+
$feed .= $this->get_feed_header();
|
598 |
+
$feed .= "\n";
|
599 |
+
foreach ($items as $item => $products) {
|
600 |
+
$feed .= " <" . $this->feedWrapper . ">";
|
601 |
+
foreach ($products as $key => $value) {
|
602 |
+
if (!empty($value))
|
603 |
+
$feed .= $value;
|
604 |
+
}
|
605 |
+
$feed .= "\n </" . $this->feedWrapper . ">\n";
|
606 |
+
}
|
607 |
+
$feed .= $this->get_feed_footer();
|
608 |
+
|
609 |
+
return $feed;
|
610 |
+
}
|
611 |
+
|
612 |
+
/**
|
613 |
+
* Responsible to make XML feed footer
|
614 |
+
* @return string
|
615 |
+
*/
|
616 |
+
public function get_feed_footer()
|
617 |
+
{
|
618 |
+
$footer = " </products>";
|
619 |
+
return $footer;
|
620 |
+
}
|
621 |
+
|
622 |
+
/**
|
623 |
+
* Responsible to make TXT feed
|
624 |
+
* @return string
|
625 |
+
*/
|
626 |
+
public function get_txt_feed()
|
627 |
+
{
|
628 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
629 |
+
$headers = array_keys($this->products[0]);
|
630 |
+
$feed[] = $headers;
|
631 |
+
foreach ($this->products as $no => $product) {
|
632 |
+
$row = array();
|
633 |
+
foreach ($headers as $key => $header) {
|
634 |
+
$row[] = $product[$header];
|
635 |
+
}
|
636 |
+
$feed[] = $row;
|
637 |
+
}
|
638 |
+
$str = "";
|
639 |
+
foreach ($feed as $fields) {
|
640 |
+
$str .= implode("\t", $fields) . "\n";
|
641 |
+
}
|
642 |
+
return $str;
|
643 |
+
}
|
644 |
+
return false;
|
645 |
+
}
|
646 |
+
|
647 |
+
/**
|
648 |
+
* Responsible to make CSV feed
|
649 |
+
* @return string
|
650 |
+
*/
|
651 |
+
public function get_csv_feed()
|
652 |
+
{
|
653 |
+
if ( is_countable( $this->products ) && count( $this->products ) ) {
|
654 |
+
$headers = array_keys($this->products[0]);
|
655 |
+
$feed[] = $headers;
|
656 |
+
foreach ($this->products as $no => $product) {
|
657 |
+
$row = array();
|
658 |
+
foreach ($headers as $key => $header) {
|
659 |
+
$row[] = $product[$header];
|
660 |
+
}
|
661 |
+
$feed[] = $row;
|
662 |
+
}
|
663 |
+
|
664 |
+
return $feed;
|
665 |
+
}
|
666 |
+
return false;
|
667 |
+
}
|
668 |
}
|
includes/helper.php
CHANGED
@@ -45,10 +45,10 @@ if( ! function_exists( 'wooFeed_deactivate_plugins' ) ) {
|
|
45 |
* @param mixed $network_wide Whether to deactivate the plugin for all sites in the network.
|
46 |
* @return void
|
47 |
*/
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
}
|
53 |
if( ! function_exists( 'wooFeed_is_supported_php' ) ) {
|
54 |
/**
|
@@ -56,15 +56,38 @@ if( ! function_exists( 'wooFeed_is_supported_php' ) ) {
|
|
56 |
* @since 3.1.41
|
57 |
* @return bool
|
58 |
*/
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
}
|
64 |
if( ! function_exists( 'wooFeed_check_WC' ) ) {
|
65 |
-
|
66 |
-
|
67 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
68 |
}
|
69 |
if( ! function_exists( 'wooFeed_Admin_Notices' ) ) {
|
70 |
/**
|
@@ -73,19 +96,31 @@ if( ! function_exists( 'wooFeed_Admin_Notices' ) ) {
|
|
73 |
* @since 3.1.41
|
74 |
* @return void
|
75 |
*/
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
}
|
90 |
if( ! function_exists( 'checkFTP_connection' ) ) {
|
91 |
/**
|
@@ -107,4 +142,72 @@ if( ! function_exists( 'checkSFTP_connection' ) ) {
|
|
107 |
return ( extension_loaded('ssh2' ) || function_exists( 'ssh2_connect' ) );
|
108 |
}
|
109 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
110 |
// End of file helper.php
|
45 |
* @param mixed $network_wide Whether to deactivate the plugin for all sites in the network.
|
46 |
* @return void
|
47 |
*/
|
48 |
+
function wooFeed_deactivate_plugins( $plugins, $silent = false, $network_wide = null ) {
|
49 |
+
if ( ! function_exists( 'deactivate_plugins' ) ) require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
|
50 |
+
deactivate_plugins( $plugins, $silent, $network_wide );
|
51 |
+
}
|
52 |
}
|
53 |
if( ! function_exists( 'wooFeed_is_supported_php' ) ) {
|
54 |
/**
|
56 |
* @since 3.1.41
|
57 |
* @return bool
|
58 |
*/
|
59 |
+
function wooFeed_is_supported_php(){
|
60 |
+
// PHP version need to be => WOO_FEED_MIN_PHP_VERSION
|
61 |
+
return ! version_compare( PHP_VERSION, WOO_FEED_MIN_PHP_VERSION, '<' );
|
62 |
+
}
|
63 |
}
|
64 |
if( ! function_exists( 'wooFeed_check_WC' ) ) {
|
65 |
+
function wooFeed_check_WC(){
|
66 |
+
return class_exists( 'WooCommerce', false );
|
67 |
+
}
|
68 |
+
}
|
69 |
+
if( ! function_exists( 'wooFeed_is_WC_supported' ) ) {
|
70 |
+
function wooFeed_is_WC_supported() {
|
71 |
+
// Ensure WC is loaded before checking version
|
72 |
+
return ( defined( 'WC_VERSION' ) && version_compare( WC_VERSION, WOO_FEED_MIN_WC_VERSION, '>=' ) );
|
73 |
+
}
|
74 |
+
}
|
75 |
+
if( ! function_exists( 'woo_feed_wc_version_check' ) ) {
|
76 |
+
/**
|
77 |
+
* Check WooCommerce Version
|
78 |
+
* @param string $version
|
79 |
+
* @return bool
|
80 |
+
*/
|
81 |
+
function woo_feed_wc_version_check( $version = '3.0' ) {
|
82 |
+
// calling this function too early (before wc loaded) will not give correct output
|
83 |
+
if ( defined( WC_VERSION ) ) {
|
84 |
+
if ( version_compare( WC_VERSION, $version, ">=" ) ) {
|
85 |
+
return true;
|
86 |
+
}
|
87 |
+
}
|
88 |
+
return false;
|
89 |
+
}
|
90 |
+
|
91 |
}
|
92 |
if( ! function_exists( 'wooFeed_Admin_Notices' ) ) {
|
93 |
/**
|
96 |
* @since 3.1.41
|
97 |
* @return void
|
98 |
*/
|
99 |
+
function wooFeed_Admin_Notices(){
|
100 |
+
//@TODO Refactor this function with admin message class
|
101 |
+
// WC Missing Notice..
|
102 |
+
if ( ! wooFeed_check_WC() ) {
|
103 |
+
$plugin_url = self_admin_url( 'plugin-install.php?s=woocommerce&tab=search&type=term' );
|
104 |
+
/** @noinspection HtmlUnknownTarget */
|
105 |
+
$plugin_url = sprintf( '<a href="%s">%s</a>', $plugin_url, esc_html__( 'WooCommerce', 'woocommerce' ) );
|
106 |
+
$plugin_name = sprintf( '<code>%s</code>', esc_html__( 'WooCommerce Product Feed', 'woo-feed' ) );
|
107 |
+
$wc_name = sprintf( '<code>%s</code>', esc_html__( 'WooCommerce', 'woocommerce' ) );
|
108 |
+
$message = sprintf( esc_html__( '%s requires %s to be installed and active. You can installed/activate %s here.', 'woo-feed' ), $plugin_name, $wc_name, $plugin_url );
|
109 |
+
printf( '<div class="error"><p><strong>%1$s</strong></p></div>', $message );
|
110 |
+
}
|
111 |
+
if( wooFeed_check_WC() && ! wooFeed_is_WC_supported() ) {
|
112 |
+
$plugin_url = self_admin_url( 'plugin-install.php?s=woocommerce&tab=search&type=term' );
|
113 |
+
$wcVersion = defined( 'WC_VERSION' ) ? '<code>'.WC_VERSION.'</code>' : '<code>UNKNOWN</code>';
|
114 |
+
$minVersion = '<code>'.WOO_FEED_MIN_WC_VERSION.'</code>';
|
115 |
+
/** @noinspection HtmlUnknownTarget */
|
116 |
+
$plugin_url = sprintf( '<a href="%s">%s</a>', $plugin_url, esc_html__( 'WooCommerce', 'woocommerce' ) );
|
117 |
+
$plugin_name = sprintf( '<code>%s</code>', esc_html__( 'WooCommerce Product Feed', 'woo-feed' ) );
|
118 |
+
$wc_name = sprintf( '<code>%s</code>', esc_html__( 'WooCommerce', 'woocommerce' ) );
|
119 |
+
$message = sprintf( 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' ),
|
120 |
+
$plugin_name, $wc_name, $minVersion, $wcVersion, $plugin_url );
|
121 |
+
printf( '<div class="error"><p><strong>%1$s</strong></p></div>', $message );
|
122 |
+
}
|
123 |
+
}
|
124 |
}
|
125 |
if( ! function_exists( 'checkFTP_connection' ) ) {
|
126 |
/**
|
142 |
return ( extension_loaded('ssh2' ) || function_exists( 'ssh2_connect' ) );
|
143 |
}
|
144 |
}
|
145 |
+
if( ! function_exists( 'array_splice_assoc' ) ) {
|
146 |
+
/**
|
147 |
+
* Array Splice Associative Array
|
148 |
+
* @see https://www.php.net/manual/en/function.array-splice.php#111204
|
149 |
+
* @param array $input
|
150 |
+
* @param int $offset
|
151 |
+
* @param int $length
|
152 |
+
* @param array $replacement
|
153 |
+
*
|
154 |
+
* @return array
|
155 |
+
*/
|
156 |
+
function array_splice_assoc( $input, $offset, $length, $replacement) {
|
157 |
+
$replacement = (array) $replacement;
|
158 |
+
$key_indices = array_flip(array_keys($input));
|
159 |
+
if (isset($input[$offset]) && is_string($offset)) {
|
160 |
+
$offset = $key_indices[$offset];
|
161 |
+
}
|
162 |
+
if (isset($input[$length]) && is_string($length)) {
|
163 |
+
$length = $key_indices[$length] - $offset;
|
164 |
+
}
|
165 |
+
|
166 |
+
$input = array_slice($input, 0, $offset, TRUE)
|
167 |
+
+ $replacement
|
168 |
+
+ array_slice($input, $offset + $length, NULL, TRUE);
|
169 |
+
return $input;
|
170 |
+
}
|
171 |
+
}
|
172 |
+
// Pro functions...
|
173 |
+
if( ! function_exists( 'woo_feed_get_variable_visibility_options' ) ) {
|
174 |
+
/**
|
175 |
+
* Get Variable visibility options for feed editor
|
176 |
+
* @return array
|
177 |
+
*/
|
178 |
+
function woo_feed_get_variable_visibility_options(){
|
179 |
+
return apply_filters( 'woo_feed_variable_visibility_options', [
|
180 |
+
'n' => __( 'Only Variable Products', 'woo-feed' ),
|
181 |
+
'y' => __( 'Only Product Variations', 'woo-feed' ),
|
182 |
+
'both' => __( 'Both Variable Products and Product Variations', 'woo-feed' ),
|
183 |
+
] );
|
184 |
+
}
|
185 |
+
}
|
186 |
+
if( ! function_exists( 'woo_feed_get_variable_price_options' ) ) {
|
187 |
+
/**
|
188 |
+
* Get Variable price options for feed editor
|
189 |
+
* @return array
|
190 |
+
*/
|
191 |
+
function woo_feed_get_variable_price_options(){
|
192 |
+
return apply_filters( 'woo_feed_variable_price_options', [
|
193 |
+
'first' => __( 'First Variation Price', 'woo-feed' ),
|
194 |
+
'max' => __( 'Max Variation Price', 'woo-feed' ),
|
195 |
+
'min' => __( 'Min Variation Price', 'woo-feed' ),
|
196 |
+
] );
|
197 |
+
}
|
198 |
+
}
|
199 |
+
if( ! function_exists( 'woo_feed_get_variable_quantity_options' ) ) {
|
200 |
+
/**
|
201 |
+
* Get Variable quantity options for feed editor
|
202 |
+
* @return array
|
203 |
+
*/
|
204 |
+
function woo_feed_get_variable_quantity_options(){
|
205 |
+
return apply_filters( 'woo_feed_variable_quantity_options', [
|
206 |
+
'first' => __( 'First Variation Quantity', 'woo-feed' ),
|
207 |
+
'max' => __( 'Max Variation Quantity', 'woo-feed' ),
|
208 |
+
'min' => __( 'Min Variation Quantity', 'woo-feed' ),
|
209 |
+
'sum' => __( 'Sum of Variation Quantity', 'woo-feed' ),
|
210 |
+
] );
|
211 |
+
}
|
212 |
+
}
|
213 |
// End of file helper.php
|
includes/wc-legacy-support.php
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Legacy WooCommerce Support
|
4 |
+
*/
|
5 |
+
if( ! function_exists( 'wc_get_attribute_taxonomy_labels' ) && ! woo_feed_wc_version_check( '3.6.0' ) ) {
|
6 |
+
/**
|
7 |
+
* Support for wc < 3.6.0
|
8 |
+
* Get (cached) attribute taxonomy label and name pairs.
|
9 |
+
* @return array
|
10 |
+
*/
|
11 |
+
function wc_get_attribute_taxonomy_labels(){
|
12 |
+
$prefix = WC_Cache_Helper::get_cache_prefix( 'woocommerce-attributes' );
|
13 |
+
$cache_key = $prefix . 'labels';
|
14 |
+
$cache_value = wp_cache_get( $cache_key, 'woocommerce-attributes' );
|
15 |
+
|
16 |
+
if ( $cache_value ) {
|
17 |
+
return $cache_value;
|
18 |
+
}
|
19 |
+
|
20 |
+
$taxonomy_labels = wp_list_pluck( wc_get_attribute_taxonomies(), 'attribute_label', 'attribute_name' );
|
21 |
+
|
22 |
+
wp_cache_set( $cache_key, $taxonomy_labels, 'woocommerce-attributes' );
|
23 |
+
|
24 |
+
return $taxonomy_labels;
|
25 |
+
}
|
26 |
+
}
|
woo-feed.php
CHANGED
@@ -15,14 +15,20 @@
|
|
15 |
* Plugin Name: WooCommerce Product Feed
|
16 |
* Plugin URI: https://webappick.com/
|
17 |
* Description: This plugin generate WooCommerce product feed for Shopping Engines like Google Shopping,Facebook Product Feed,eBay,Amazon,Idealo and many more..
|
18 |
-
* Version: 3.1.
|
19 |
* Author: WebAppick
|
20 |
* Author URI: https://webappick.com/
|
21 |
* License: GPL v2
|
22 |
* License URI: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
23 |
* Text Domain: woo-feed
|
24 |
* Domain Path: /languages
|
25 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
* WC tested up to: 3.7.1
|
27 |
*
|
28 |
*/
|
@@ -34,7 +40,7 @@ if( ! defined( 'WOO_FEED_VERSION' ) ) {
|
|
34 |
* Plugin Version
|
35 |
* @var string
|
36 |
*/
|
37 |
-
define( 'WOO_FEED_VERSION', '3.1.
|
38 |
}
|
39 |
if( ! defined( 'WOO_FEED_FREE_FILE') ) {
|
40 |
/**
|
@@ -82,6 +88,14 @@ if( ! defined( 'WOO_FEED_MIN_PHP_VERSION' ) ) {
|
|
82 |
*/
|
83 |
define( 'WOO_FEED_MIN_PHP_VERSION', '5.6' );
|
84 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
85 |
if( ! defined( 'WOO_FEED_PLUGIN_BASE_NAME' ) ) {
|
86 |
/**
|
87 |
* Plugin Base name..
|
@@ -398,22 +412,6 @@ if( ! function_exists( 'woo_feed_get_product_information' ) ) {
|
|
398 |
}
|
399 |
add_action('wp_ajax_get_product_information', 'woo_feed_get_product_information');
|
400 |
}
|
401 |
-
if( ! function_exists( 'woo_feed_wc_version_check' ) ) {
|
402 |
-
/**
|
403 |
-
* Check WooCommerce Version
|
404 |
-
* @param string $version
|
405 |
-
* @return bool
|
406 |
-
*/
|
407 |
-
function woo_feed_wc_version_check( $version = '3.0' ) {
|
408 |
-
if ( class_exists( 'WooCommerce' ) ) {
|
409 |
-
global $woocommerce;
|
410 |
-
if ( version_compare( $woocommerce->version, $version, ">=" ) ) {
|
411 |
-
return true;
|
412 |
-
}
|
413 |
-
}
|
414 |
-
return false;
|
415 |
-
}
|
416 |
-
}
|
417 |
if( ! function_exists( 'woo_feed_generate_feed_data' ) ) {
|
418 |
function woo_feed_generate_feed_data($info){
|
419 |
|
15 |
* Plugin Name: WooCommerce Product Feed
|
16 |
* Plugin URI: https://webappick.com/
|
17 |
* Description: This plugin generate WooCommerce product feed for Shopping Engines like Google Shopping,Facebook Product Feed,eBay,Amazon,Idealo and many more..
|
18 |
+
* Version: 3.1.45
|
19 |
* Author: WebAppick
|
20 |
* Author URI: https://webappick.com/
|
21 |
* License: GPL v2
|
22 |
* License URI: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
23 |
* Text Domain: woo-feed
|
24 |
* Domain Path: /languages
|
25 |
+
*
|
26 |
+
* WP Requirement & Test
|
27 |
+
* Requires at least: 4.4
|
28 |
+
* Tested up to: 5.3
|
29 |
+
*
|
30 |
+
* WC Requirement & Test
|
31 |
+
* WC requires at least: 3.2
|
32 |
* WC tested up to: 3.7.1
|
33 |
*
|
34 |
*/
|
40 |
* Plugin Version
|
41 |
* @var string
|
42 |
*/
|
43 |
+
define( 'WOO_FEED_VERSION', '3.1.45' );
|
44 |
}
|
45 |
if( ! defined( 'WOO_FEED_FREE_FILE') ) {
|
46 |
/**
|
88 |
*/
|
89 |
define( 'WOO_FEED_MIN_PHP_VERSION', '5.6' );
|
90 |
}
|
91 |
+
if( ! defined( 'WOO_FEED_MIN_WC_VERSION' ) ) {
|
92 |
+
/**
|
93 |
+
* Minimum PHP Version Supported
|
94 |
+
* @var string
|
95 |
+
* @since 3.1.45
|
96 |
+
*/
|
97 |
+
define( 'WOO_FEED_MIN_WC_VERSION', '3.2' );
|
98 |
+
}
|
99 |
if( ! defined( 'WOO_FEED_PLUGIN_BASE_NAME' ) ) {
|
100 |
/**
|
101 |
* Plugin Base name..
|
412 |
}
|
413 |
add_action('wp_ajax_get_product_information', 'woo_feed_get_product_information');
|
414 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
415 |
if( ! function_exists( 'woo_feed_generate_feed_data' ) ) {
|
416 |
function woo_feed_generate_feed_data($info){
|
417 |
|