CTX Feed – WooCommerce Product Feed Manager Plugin - Version 3.3.0

Version Description

(2020-02-17) = * Improvement: Validate all source code using WPCS (PHPCS) to match WordPress coding standard. * Improvement: Sanitization and Nonce checking. * Performance: Implement WP Object Caching. * Feature: new filter hook API for adding custom attribute. * Fix: Tax calculation over cron job.

Download this release

Release Info

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

Code changes from version 3.2.19 to 3.3.0

Files changed (44) hide show
  1. README.txt +8 -1
  2. admin/class-woo-feed-admin.php +182 -179
  3. admin/class-woo-feed-manage-list.php +502 -508
  4. admin/css/woo-feed-admin.css +12 -1
  5. admin/partials/templates/common_add-feed.php +95 -126
  6. admin/partials/templates/custom_add-feed.php +78 -100
  7. admin/partials/templates/facebook_add-feed.php +707 -703
  8. admin/partials/templates/google_add-feed.php +705 -695
  9. admin/partials/templates/google_taxonomy.txt +1 -1
  10. admin/partials/templates/pinterest_add-feed.php +705 -694
  11. admin/partials/woo-feed-admin-display.php +50 -30
  12. admin/partials/woo-feed-config.php +17 -30
  13. admin/partials/woo-feed-content-settings.php +19 -36
  14. admin/partials/woo-feed-edit-config.php +121 -0
  15. admin/partials/woo-feed-edit-ftp.php +55 -0
  16. admin/partials/woo-feed-edit-tabs.php +103 -0
  17. admin/partials/woo-feed-edit-template.php +29 -232
  18. admin/partials/woo-feed-manage-list.php +54 -68
  19. admin/partials/woo-feed-pro-vs-free.php +18 -11
  20. includes/class-woo-feed-docs.php +92 -32
  21. includes/class-woo-feed-installer.php +30 -33
  22. includes/class-woo-feed.php +1 -7
  23. includes/classes/class-woo-feed-default-attributes.php +655 -1209
  24. includes/classes/class-woo-feed-dropdown.php +109 -859
  25. includes/classes/class-woo-feed-engine.php +45 -45
  26. includes/classes/class-woo-feed-ftp.php +27 -20
  27. includes/classes/class-woo-feed-list-table.php +209 -129
  28. includes/classes/class-woo-feed-log-handler-file.php +438 -436
  29. includes/classes/class-woo-feed-merchant.php +50 -73
  30. includes/classes/class-woo-feed-products-v3.php +653 -683
  31. includes/classes/class-woo-feed-products.php +351 -363
  32. includes/classes/class-woo-feed-savefile.php +46 -55
  33. includes/classes/class-woo-feed-sftp.php +58 -32
  34. includes/classes/class-woo-feed-webappick-api.php +26 -24
  35. includes/cron-helper.php +92 -0
  36. includes/feeds/class-woo-feed-custom.php +146 -83
  37. includes/feeds/class-woo-feed-facebook.php +533 -498
  38. includes/feeds/class-woo-feed-generate.php +17 -16
  39. includes/feeds/class-woo-feed-google.php +634 -609
  40. includes/feeds/class-woo-feed-pinterest.php +623 -584
  41. includes/helper.php +910 -480
  42. includes/hooks.php +19 -0
  43. includes/log-helper.php +214 -0
  44. woo-feed.php +380 -498
README.txt CHANGED
@@ -5,7 +5,7 @@ Tags:product feed,woocommerce product feed,google shopping feed,google shopping,
5
  Requires at least: 3.6
6
  Tested Up To: 5.3.2
7
  Requires PHP: 5.6
8
- Stable tag: 3.2.19
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -305,6 +305,13 @@ Using pro version:
305
 
306
  == Changelog ==
307
 
 
 
 
 
 
 
 
308
  = 3.2.19 (2020-02-13) =
309
  * Fix JS not loading in all pages for hiding notices.
310
 
5
  Requires at least: 3.6
6
  Tested Up To: 5.3.2
7
  Requires PHP: 5.6
8
+ Stable tag: 3.3.0
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
305
 
306
  == Changelog ==
307
 
308
+ = 3.3.0 (2020-02-17) =
309
+ * Improvement: Validate all source code using WPCS (PHPCS) to match WordPress coding standard.
310
+ * Improvement: Sanitization and Nonce checking.
311
+ * Performance: Implement WP Object Caching.
312
+ * Feature: new filter hook API for adding custom attribute.
313
+ * Fix: Tax calculation over cron job.
314
+
315
  = 3.2.19 (2020-02-13) =
316
  * Fix JS not loading in all pages for hiding notices.
317
 
admin/class-woo-feed-admin.php CHANGED
@@ -10,156 +10,157 @@
10
  * @subpackage Woo_Feed/admin
11
  * @author Ohidul Islam <wahid@webappick.com>
12
  */
13
- class Woo_Feed_Admin
14
- {
15
-
16
- /**
17
- * The ID of this plugin.
18
- *
19
- * @since 1.0.0
20
- * @access private
21
- * @var string $woo_feed The ID of this plugin.
22
- */
23
- private $woo_feed;
24
-
25
- /**
26
- * The version of this plugin.
27
- *
28
- * @since 1.0.0
29
- * @access private
30
- * @var string $version The current version of this plugin.
31
- */
32
- private $version;
33
-
34
- /**
35
- * Initialize the class and set its properties.
36
- *
37
- * @since 1.0.0
38
- *
39
- * @param string $woo_feed The name of this plugin.
40
- * @param string $version The version of this plugin.
41
- */
42
- public function __construct( $woo_feed, $version ) {
43
-
44
- $this->woo_feed = $woo_feed;
45
- $this->version = $version;
46
-
47
- }
48
-
49
- /**
50
- * Register the stylesheets for the admin area.
51
- * @param string $hook
52
- * @since 1.0.0
53
- */
54
- public function enqueue_styles( $hook ) {
55
-
56
- /**
57
- * This function is provided for demonstration purposes only.
58
- *
59
- * An instance of this class should be passed to the run() function
60
- * defined in woo_feed_Loader as all of the hooks are defined
61
- * in that particular class.
62
- *
63
- * The woo_feed_Loader will then create the relationship
64
- * between the defined hooks and the functions defined in this
65
- * class.
66
- */
67
- $mainDeps = [];
68
- if ( false !== strpos( $hook, 'webappick' ) && false !== strpos( $hook, 'feed' ) ) {
69
- wp_register_style( 'selectize', plugin_dir_url(__FILE__) . 'css/selectize.css', array(),$this->version );
70
- wp_register_style( 'slick', plugin_dir_url(__FILE__) . 'css/slick.css', array(),$this->version );
71
- wp_register_style( 'slick-theme', plugin_dir_url(__FILE__) . 'css/slick-theme.css', array(),$this->version );
72
- $mainDeps = array( 'selectize' );
73
- if ( 'woo-feed_page_webappick-feed-pro-vs-free' == $hook ) {
74
- $mainDeps = array_merge( $mainDeps, array( 'slick', 'slick-theme' ) );
75
- }
76
- }
77
- wp_register_style( $this->woo_feed, plugin_dir_url(__FILE__) . 'css/woo-feed-admin.css', $mainDeps, $this->version, 'all' );
78
- wp_enqueue_style( $this->woo_feed );
79
- }
80
-
81
- /**
82
- * Register the JavaScript for the admin area.
83
- * @param string $hook
84
- * @since 1.0.0
85
- */
86
- public function enqueue_scripts( $hook ) {
87
-
88
- /**
89
- * This function is provided for demonstration purposes only.
90
- *
91
- * An instance of this class should be passed to the run() function
92
- * defined in Woo_Feed_Loader as all of the hooks are defined
93
- * in that particular class.
94
- *
95
- * The woo_feed_Loader will then create the relationship
96
- * between the defined hooks and the functions defined in this
97
- * class.
98
- */
99
- wp_enqueue_script( 'jquery' );
100
- wp_enqueue_script( 'wp-util' );
101
- if ( false !== strpos( $hook, 'webappick' ) && false !== strpos( $hook, 'feed' ) ) {
102
- wp_register_script( 'jquery-selectize', plugin_dir_url( __FILE__ ) . 'js/selectize.min.js', array( 'jquery' ), $this->version, false );
103
- wp_register_script( 'jquery-validate', plugin_dir_url( __FILE__ ) . 'js/jquery.validate.min.js', array( 'jquery' ), $this->version, false );
104
- wp_register_script( 'jquery-validate-additional-methods', plugin_dir_url( __FILE__ ) . 'js/additional-methods.min.js', array( 'jquery', 'jquery-validate' ), $this->version, false );
105
- wp_register_script( 'jquery-sortable', plugin_dir_url( __FILE__ ) . 'js/jquery-sortable.js', array( 'jquery' ), $this->version, false );
106
-
107
- if ( ! wp_script_is( 'clipboard', 'registered' ) ) {
108
- wp_register_script( 'clipboard', plugin_dir_url( __FILE__ ) . 'js/clipboard.min.js', [], '2.0.4', false );
109
- }
110
 
111
- $feedScriptDependency = [
112
- 'jquery',
113
- 'clipboard',
114
- 'jquery-selectize',
115
- 'jquery-sortable',
116
- 'jquery-validate',
117
- 'jquery-validate-additional-methods',
118
- 'wp-util',
119
- 'utils',
120
- 'wp-lists',
121
- 'postbox',
122
- 'tags-box',
123
- // 'underscore', 'word-count', 'jquery-ui-autocomplete',
124
- 'jquery-touch-punch',
125
- ];
126
-
127
- wp_register_script($this->woo_feed, plugin_dir_url(__FILE__) . 'js/woo-feed-admin.js', $feedScriptDependency, $this->version, false);
128
- wp_localize_script(
129
- $this->woo_feed,
130
- 'wpf_ajax_obj',
131
- array(
132
- 'wpf_ajax_url' => admin_url( 'admin-ajax.php' ),
133
- 'nonce' => wp_create_nonce( 'wpf_feed_nonce' ),
134
- 'is_feed_edit' => isset( $_GET['page'], $_GET['action'] ) && 'webappick-manage-feeds' == $_GET['page'] && 'edit-feed' == $_GET['action'], // phpcs:ignore WordPress.Security.NonceVerification.Recommended
135
- 'is_feed_add' => isset( $_GET['page'] ) && 'webappick-new-feed' == $_GET['page'], // phpcs:ignore WordPress.Security.NonceVerification.Recommended
136
- 'na' => esc_html__( 'N/A', 'woo-feed' ),
137
- 'regenerate' => esc_html__( 'Generating...', 'woo-feed' ),
138
- 'form' => array(
139
- 'loading_tmpl' => esc_html__( 'Loading Template...', 'woo-feed' ),
140
- 'generate' => esc_html__( 'Delivering Configuration...', 'woo-feed' ),
141
- 'save' => esc_html__( 'Saving Configuration...', 'woo-feed' ),
142
- 'sftp_checking' => esc_html__( 'Wait! Checking Extensions ...', 'woo-feed' ),
143
- 'sftp_warning' => esc_html__( 'Warning! Enable PHP ssh2 extension to use SFTP. Contact your server administrator.',
144
- 'woo-feed' ),
145
- 'sftp_available' => esc_html__( 'SFTP Available!', 'woo-feed' ),
146
- ),
147
- 'ajax' => [
148
- 'url' => admin_url( 'admin-ajax.php' ),
149
- 'nonce' => wp_create_nonce( 'wpf_feed_nonce' ),
150
- 'error' => esc_html__( 'There was an error processing ajax request.', 'woo-feed' ),
151
- ],
152
- )
153
- );
154
- wp_enqueue_script( $this->woo_feed );
155
-
156
- if ( 'woo-feed_page_webappick-feed-pro-vs-free' === $hook ) {
157
- wp_register_script( 'jquery-slick', plugin_dir_url( __FILE__ ) . 'js/slick.js', array( 'jquery' ), $this->version, false );
158
- wp_register_script( 'feed-pro', plugin_dir_url( __FILE__ ) . 'js/pro.js', [ $this->woo_feed, 'jquery-slick' ], $this->version, false );
159
- wp_enqueue_script( 'feed-pro' );
160
- }
161
- }
162
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163
 
164
  /**
165
  * Add Go to Pro and Documentation link
@@ -175,37 +176,37 @@ class Woo_Feed_Admin
175
  $links[] = sprintf( '<a href="%s">%s</a>', esc_url( admin_url( 'admin.php?page=webappick-feed-settings' ) ), __( 'Settings', 'woo-feed' ) );
176
  return $links;
177
  }
178
-
179
- /**
180
- * Register the Plugin's Admin Pages for the admin area.
181
- *
182
- * @since 1.0.0
183
- */
184
- public function load_admin_pages() {
185
- /**
186
- * This function is provided for making admin pages into admin area.
187
- *
188
- * An instance of this class should be passed to the run() function
189
- * defined in WOO_FEED_Loader as all of the hooks are defined
190
- * in that particular class.
191
- *
192
- * The WOO_FEED_Loader will then create the relationship
193
- * between the defined hooks and the functions defined in this
194
- * class.
195
- */
196
- if ( function_exists('add_options_page') ) {
197
- add_menu_page( __('Woo Feed', 'woo-feed'), __('Woo Feed', 'woo-feed'), 'manage_woocommerce', 'webappick-manage-feeds', 'woo_feed_manage_feed', 'dashicons-rss' );
198
- add_submenu_page( 'webappick-manage-feeds', __('Manage Feeds', 'woo-feed'), __('Manage Feeds', 'woo-feed'), 'manage_woocommerce', 'webappick-manage-feeds', 'woo_feed_manage_feed' );
199
- add_submenu_page( 'webappick-manage-feeds', __('Make Feed', 'woo-feed'), __('Make Feed', 'woo-feed'), 'manage_woocommerce', 'webappick-new-feed', 'woo_feed_generate_feed' );
200
- add_submenu_page( 'webappick-manage-feeds', __('Settings', 'woo-feed'), __('Settings', 'woo-feed'), 'manage_woocommerce', 'webappick-feed-settings', 'woo_feed_config_feed' );
201
- add_submenu_page( 'webappick-manage-feeds', __('Documentation', 'woo-feed'), '<span class="woo-feed-docs">' . __('Docs', 'woo-feed') . '</span>', 'manage_woocommerce', 'webappick-feed-docs', array( WooFeedDocs::getInstance(), 'woo_feed_docs' ) );
202
- }
203
- }
204
-
205
  /**
206
  * Redirect user to with new menu slug (if user browser any bookmarked url)
207
- * @since 3.1.7
208
  * @return void
 
209
  */
210
  public function handle_old_menu_slugs() {
211
  global $pagenow;
@@ -216,9 +217,11 @@ class Woo_Feed_Admin
216
  'woo_feed_config_feed' => 'webappick-feed-settings',
217
  'woo_feed_pro_vs_free' => 'webappick-feed-pro-vs-free',
218
  );
219
- if ( $pagenow === 'admin.php' && isset( $_GET['page'] ) && ! empty( $_GET['page'] ) ) {
220
  foreach ( $redirect_to as $from => $to ) {
221
- if ( $_GET['page'] !== $from ) continue;
 
 
222
  wp_safe_redirect( admin_url( 'admin.php?page=' . $to ), 301 );
223
  die();
224
  }
10
  * @subpackage Woo_Feed/admin
11
  * @author Ohidul Islam <wahid@webappick.com>
12
  */
13
+ class Woo_Feed_Admin {
14
+
15
+ /**
16
+ * The ID of this plugin.
17
+ *
18
+ * @since 1.0.0
19
+ * @access private
20
+ * @var string $woo_feed The ID of this plugin.
21
+ */
22
+ private $woo_feed;
23
+
24
+ /**
25
+ * The version of this plugin.
26
+ *
27
+ * @since 1.0.0
28
+ * @access private
29
+ * @var string $version The current version of this plugin.
30
+ */
31
+ private $version;
32
+
33
+ /**
34
+ * Initialize the class and set its properties.
35
+ *
36
+ * @param string $woo_feed The name of this plugin.
37
+ * @param string $version The version of this plugin.
38
+ *
39
+ * @since 1.0.0
40
+ *
41
+ */
42
+ public function __construct( $woo_feed, $version ) {
43
+
44
+ $this->woo_feed = $woo_feed;
45
+ $this->version = $version;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
 
47
+ }
48
+
49
+ /**
50
+ * Register the stylesheets for the admin area.
51
+ *
52
+ * @param string $hook
53
+ *
54
+ * @since 1.0.0
55
+ */
56
+ public function enqueue_styles( $hook ) {
57
+ /**
58
+ * This function is provided for demonstration purposes only.
59
+ *
60
+ * An instance of this class should be passed to the run() function
61
+ * defined in woo_feed_Loader as all of the hooks are defined
62
+ * in that particular class.
63
+ *
64
+ * The woo_feed_Loader will then create the relationship
65
+ * between the defined hooks and the functions defined in this
66
+ * class.
67
+ */
68
+ $mainDeps = array();
69
+ if ( false !== strpos( $hook, 'webappick' ) && false !== strpos( $hook, 'feed' ) ) {
70
+ wp_register_style( 'selectize', plugin_dir_url( __FILE__ ) . 'css/selectize.css', array(), $this->version );
71
+ wp_register_style( 'slick', plugin_dir_url( __FILE__ ) . 'css/slick.css', array(), $this->version );
72
+ wp_register_style( 'slick-theme', plugin_dir_url( __FILE__ ) . 'css/slick-theme.css', array(), $this->version );
73
+ $mainDeps = array( 'selectize', 'list-tables', 'edit' );
74
+ if ( 'woo-feed_page_webappick-feed-pro-vs-free' == $hook ) {
75
+ $mainDeps = array_merge( $mainDeps, array( 'slick', 'slick-theme' ) );
76
+ }
77
+ }
78
+ wp_register_style( $this->woo_feed, plugin_dir_url( __FILE__ ) . 'css/woo-feed-admin.css', $mainDeps, $this->version, 'all' );
79
+ wp_enqueue_style( $this->woo_feed );
80
+ }
81
+
82
+ /**
83
+ * Register the JavaScript for the admin area.
84
+ *
85
+ * @param string $hook
86
+ *
87
+ * @since 1.0.0
88
+ */
89
+ public function enqueue_scripts( $hook ) {
90
+ /**
91
+ * This function is provided for demonstration purposes only.
92
+ *
93
+ * An instance of this class should be passed to the run() function
94
+ * defined in Woo_Feed_Loader as all of the hooks are defined
95
+ * in that particular class.
96
+ *
97
+ * The woo_feed_Loader will then create the relationship
98
+ * between the defined hooks and the functions defined in this
99
+ * class.
100
+ */
101
+ wp_enqueue_script( 'jquery' );
102
+ wp_enqueue_script( 'wp-util' );
103
+ if ( false !== strpos( $hook, 'webappick' ) && false !== strpos( $hook, 'feed' ) ) {
104
+ wp_register_script( 'jquery-selectize', plugin_dir_url( __FILE__ ) . 'js/selectize.min.js', array( 'jquery' ), $this->version, false );
105
+ wp_register_script( 'jquery-validate', plugin_dir_url( __FILE__ ) . 'js/jquery.validate.min.js', array( 'jquery' ), $this->version, false );
106
+ wp_register_script( 'jquery-validate-additional-methods', plugin_dir_url( __FILE__ ) . 'js/additional-methods.min.js', array( 'jquery', 'jquery-validate' ), $this->version, false );
107
+ wp_register_script( 'jquery-sortable', plugin_dir_url( __FILE__ ) . 'js/jquery-sortable.js', array( 'jquery' ), $this->version, false );
108
+
109
+ if ( ! wp_script_is( 'clipboard', 'registered' ) ) {
110
+ wp_register_script( 'clipboard', plugin_dir_url( __FILE__ ) . 'js/clipboard.min.js', [], '2.0.4', false );
111
+ }
112
+
113
+ $feedScriptDependency = [
114
+ 'jquery',
115
+ 'clipboard',
116
+ 'jquery-selectize',
117
+ 'jquery-sortable',
118
+ 'jquery-validate',
119
+ 'jquery-validate-additional-methods',
120
+ 'wp-util',
121
+ 'utils',
122
+ 'wp-lists',
123
+ 'postbox',
124
+ 'tags-box',
125
+ // 'underscore', 'word-count', 'jquery-ui-autocomplete',
126
+ 'jquery-touch-punch',
127
+ ];
128
+
129
+ wp_register_script( $this->woo_feed, plugin_dir_url( __FILE__ ) . 'js/woo-feed-admin.js', $feedScriptDependency, $this->version, false );
130
+ wp_localize_script(
131
+ $this->woo_feed,
132
+ 'wpf_ajax_obj',
133
+ array(
134
+ 'wpf_ajax_url' => admin_url( 'admin-ajax.php' ),
135
+ 'nonce' => wp_create_nonce( 'wpf_feed_nonce' ),
136
+ 'is_feed_edit' => isset( $_GET['page'], $_GET['action'] ) && 'webappick-manage-feeds' == $_GET['page'] && 'edit-feed' == $_GET['action'], // phpcs:ignore WordPress.Security.NonceVerification.Recommended
137
+ 'is_feed_add' => isset( $_GET['page'] ) && 'webappick-new-feed' == $_GET['page'], // phpcs:ignore WordPress.Security.NonceVerification.Recommended
138
+ 'na' => esc_html__( 'N/A', 'woo-feed' ),
139
+ 'regenerate' => esc_html__( 'Generating...', 'woo-feed' ),
140
+ 'form' => array(
141
+ 'loading_tmpl' => esc_html__( 'Loading Template...', 'woo-feed' ),
142
+ 'generate' => esc_html__( 'Delivering Configuration...', 'woo-feed' ),
143
+ 'save' => esc_html__( 'Saving Configuration...', 'woo-feed' ),
144
+ 'sftp_checking' => esc_html__( 'Wait! Checking Extensions ...', 'woo-feed' ),
145
+ 'sftp_warning' => esc_html__( 'Warning! Enable PHP ssh2 extension to use SFTP. Contact your server administrator.', 'woo-feed' ),
146
+ 'sftp_available' => esc_html__( 'SFTP Available!', 'woo-feed' ),
147
+ ),
148
+ 'ajax' => [
149
+ 'url' => admin_url( 'admin-ajax.php' ),
150
+ 'nonce' => wp_create_nonce( 'wpf_feed_nonce' ),
151
+ 'error' => esc_html__( 'There was an error processing ajax request.', 'woo-feed' ),
152
+ ],
153
+ )
154
+ );
155
+ wp_enqueue_script( $this->woo_feed );
156
+
157
+ if ( 'woo-feed_page_webappick-feed-pro-vs-free' === $hook ) {
158
+ wp_register_script( 'jquery-slick', plugin_dir_url( __FILE__ ) . 'js/slick.js', array( 'jquery' ), $this->version, false );
159
+ wp_register_script( 'feed-pro', plugin_dir_url( __FILE__ ) . 'js/pro.js', [ $this->woo_feed, 'jquery-slick' ], $this->version, false );
160
+ wp_enqueue_script( 'feed-pro' );
161
+ }
162
+ }
163
+ }
164
 
165
  /**
166
  * Add Go to Pro and Documentation link
176
  $links[] = sprintf( '<a href="%s">%s</a>', esc_url( admin_url( 'admin.php?page=webappick-feed-settings' ) ), __( 'Settings', 'woo-feed' ) );
177
  return $links;
178
  }
179
+
180
+ /**
181
+ * Register the Plugin's Admin Pages for the admin area.
182
+ *
183
+ * @since 1.0.0
184
+ */
185
+ public function load_admin_pages() {
186
+ /**
187
+ * This function is provided for making admin pages into admin area.
188
+ *
189
+ * An instance of this class should be passed to the run() function
190
+ * defined in WOO_FEED_Loader as all of the hooks are defined
191
+ * in that particular class.
192
+ *
193
+ * The WOO_FEED_Loader will then create the relationship
194
+ * between the defined hooks and the functions defined in this
195
+ * class.
196
+ */
197
+ if ( function_exists( 'add_options_page' ) ) {
198
+ add_menu_page( __( 'Woo Feed', 'woo-feed' ), __( 'Woo Feed', 'woo-feed' ), 'manage_woocommerce', 'webappick-manage-feeds', 'woo_feed_manage_feed', 'dashicons-rss' );
199
+ add_submenu_page( 'webappick-manage-feeds', __( 'Manage Feeds', 'woo-feed' ), __( 'Manage Feeds', 'woo-feed' ), 'manage_woocommerce', 'webappick-manage-feeds', 'woo_feed_manage_feed' );
200
+ add_submenu_page( 'webappick-manage-feeds', __( 'Make Feed', 'woo-feed' ), __( 'Make Feed', 'woo-feed' ), 'manage_woocommerce', 'webappick-new-feed', 'woo_feed_generate_new_feed' );
201
+ add_submenu_page( 'webappick-manage-feeds', __( 'Settings', 'woo-feed' ), __( 'Settings', 'woo-feed' ), 'manage_woocommerce', 'webappick-feed-settings', 'woo_feed_config_feed' );
202
+ add_submenu_page( 'webappick-manage-feeds', __( 'Documentation', 'woo-feed' ), '<span class="woo-feed-docs">' . __( 'Docs', 'woo-feed' ) . '</span>', 'manage_woocommerce', 'webappick-feed-docs', array( WooFeedDocs::getInstance(), 'woo_feed_docs' ) );
203
+ }
204
+ }
205
+
206
  /**
207
  * Redirect user to with new menu slug (if user browser any bookmarked url)
 
208
  * @return void
209
+ * @since 3.1.7
210
  */
211
  public function handle_old_menu_slugs() {
212
  global $pagenow;
217
  'woo_feed_config_feed' => 'webappick-feed-settings',
218
  'woo_feed_pro_vs_free' => 'webappick-feed-pro-vs-free',
219
  );
220
+ if ( 'admin.php' === $pagenow && isset( $plugin_page ) && ! empty( $plugin_page ) ) {
221
  foreach ( $redirect_to as $from => $to ) {
222
+ if ( $plugin_page !== $from ) {
223
+ continue;
224
+ }
225
  wp_safe_redirect( admin_url( 'admin.php?page=' . $to ), 301 );
226
  die();
227
  }
admin/class-woo-feed-manage-list.php CHANGED
@@ -1,6 +1,7 @@
1
- <?php ob_start();
2
 
3
  /**
 
4
  * Feed List
5
  *
6
  * @link https://webappick.com/
@@ -9,523 +10,516 @@
9
  * @package Woo_Feed_DAttribute_list
10
  * @author Ohidul Islam <wahid@webappick.com>
11
  */
12
- class Woo_Feed_Manage_list extends Woo_Feed_List_Table
13
- {
14
-
15
- /** ************************************************************************
16
- * Normally we would be querying data from a database and manipulating that
17
- * for use in your list table. For this example, we're going to simplify it
18
- * slightly and create a pre-built array. Think of this as the data that might
19
- * be returned by $wpdb->query()
20
- *
21
- * In a real-world scenario, you would make your own custom query inside
22
- * this class' prepare_items() method.
23
- *
24
- * @var array
25
- **************************************************************************/
26
-
27
-
28
- /** ************************************************************************
29
- * REQUIRED. Set up a constructor that references the parent constructor. We
30
- * use the parent reference to set some default configs.
31
- ***************************************************************************/
32
- function __construct() {
33
- global $status, $page;
34
-
35
- //Set parent defaults
36
- parent::__construct(array(
37
- 'singular' => __('feed'), //singular name of the listed records
38
- 'plural' => __('feeds'), //plural name of the listed records
39
- 'ajax' => false, //does this table support ajax?
40
- ));
41
-
42
- }
43
-
44
-
45
- /** ************************************************************************
46
- * Recommended. This method is called when the parent class can't find a method
47
- * specifically build for a given column. Generally, it's recommended to include
48
- * one method for each column you want to render, keeping your package class
49
- * neat and organized. For example, if the class needs to process a column
50
- * named 'title', it would first see if a method named $this->column_title()
51
- * exists - if it does, that method will be used. If it doesn't, this one will
52
- * be used. Generally, you should try to use custom column methods as much as
53
- * possible.
54
- *
55
- * Since we have defined a column_title() method later on, this method doesn't
56
- * need to concern itself with any column with a name of 'title'. Instead, it
57
- * needs to handle everything else.
58
- *
59
- * For more detailed insight into how columns are handled, take a look at
60
- * WP_List_Table::single_row_columns()
61
- *
62
- * @param array $item A singular item (one full row's worth of data)
63
- * @param string $column_name The name/slug of the column to be processed
64
- * @return string Text or HTML to be placed inside the column <td>
65
- *
66
- **************************************************************************/
67
  function column_default( $item, $column_name ) {
68
- $getItem = $item['option_name'];
69
  $statusId = $item['option_id'];
70
- $itemInfo = unserialize(get_option($getItem));
71
  global $regenerating, $regeneratingName;
72
- $optionName = str_replace("wf_feed_", "", $getItem );
73
- $spinIcon = ( $regenerating === true && $optionName === $regeneratingName ) ? ' wpf_spin_reverse' : '';
74
- $disableBtn = $regenerating === true ? ' disabled' : '';
75
  switch ( $column_name ) {
76
- case 'option_name':
77
- return $optionName;
78
- case 'status':
79
- if ( ! isset($itemInfo['status']) || $itemInfo['status'] == 1 ) {
80
- return ' <div class="wf_status_wrap"><input style="display: none;" data-index='.$statusId.' id='.$statusId.' checked class="woo_feed_status_input" type="checkbox" value="'.$getItem.'"/>
81
- <label for='.$statusId.' class= "woo-feed_active_status"></label></div>';
82
- }else {
83
- return ' <div class="wf_status_wrap"> <input style="display: none;" data-index='.$statusId.' id='.$statusId.' class="woo_feed_status_input" type="checkbox" value="'.$getItem.'"/>
84
- <label for='.$statusId.' class= "woo-feed_active_status"></label> </div>';
85
- }
86
- case 'provider':
87
- /** @noinspection SpellCheckingInspection */
88
- $provider = $itemInfo['feedrules']['provider'];
89
- return ucwords(str_replace("_", " ", $provider));
90
- case 'type':
91
- /** @noinspection SpellCheckingInspection */
92
- $feedType = $itemInfo['feedrules']['feedType'];
93
- return strtoupper(str_replace("_", " ", $feedType));
94
- case 'url':
95
- /** @noinspection HtmlUnknownAttribute,SpellCheckingInspection */
96
- return sprintf(
97
- '<span class="toClipboard" data-clipboard-target="#_url%1$s" id="_url%1$s">%2$s</span><span class="toClipboard" data-clipboard-target="#_url%1$s">%3$s</span>',
98
- $statusId,
99
- $itemInfo[ $column_name ],
100
- '<img src="data:image/svg+xml,%0A%3Csvg height=\'1024\' width=\'896\' xmlns=\'http://www.w3.org/2000/svg\'%3E%3Cpath d=\'M128 768h256v64H128v-64z m320-384H128v64h320v-64z m128 192V448L384 640l192 192V704h320V576H576z m-288-64H128v64h160v-64zM128 704h160v-64H128v64z m576 64h64v128c-1 18-7 33-19 45s-27 18-45 19H64c-35 0-64-29-64-64V192c0-35 29-64 64-64h192C256 57 313 0 384 0s128 57 128 128h192c35 0 64 29 64 64v320h-64V320H64v576h640V768zM128 256h512c0-35-29-64-64-64h-64c-35 0-64-29-64-64s-29-64-64-64-64 29-64 64-29 64-64 64h-64c-35 0-64 29-64 64z\' /%3E%3C/svg%3E%0A" alt="' . __( 'Copy To Clipboard') . '" class="clippy">' );
101
- case 'last_updated':
102
- return $itemInfo[ $column_name ];
103
- case 'view':
104
- $view = $itemInfo['url'];
105
- /** @noinspection HtmlUnknownTarget */
106
- return sprintf(
107
- '<a href="%1$s" title="%2$s" aria-label="%2$s" target="_blank"><span class="dashicons dashicons-external" aria-hidden="true"></span></a>
 
 
108
  <a id="%3$s" class="wpf_regenerate%6$s" href="#" title="%4$s" aria-label="%4$s"><span class="dashicons dashicons-update-alt%7$s" aria-hidden="true"></span></a>
109
  <a href="%1$s" title="%5$s" aria-label="%5$s" download><span class="dashicons dashicons-download" aria-hidden="true"></span></a>',
110
- $view, __( 'View' ), $getItem, __( 'Regenerate' ), __( 'Download' ), $disableBtn, $spinIcon );
111
- default:
112
- return false;
113
- }
 
 
 
 
 
 
 
114
  }
115
-
116
-
117
- /** ************************************************************************
118
- * Recommended. This is a custom column method and is responsible for what
119
- * is rendered in any column with a name/slug of 'title'. Every time the class
120
- * needs to render a column, it first looks for a method named
121
- * column_{$column_title} - if it exists, that method is run. If it doesn't
122
- * exist, column_default() is called instead.
123
- *
124
- * This example also illustrates how to implement rollover actions. Actions
125
- * should be an associative array formatted as 'slug'=>'link html' - and you
126
- * will need to generate the URLs yourself. You could even ensure the links
127
- *
128
- *
129
- * @see WP_List_Table::::single_row_columns()
130
- * @param array $item A singular item (one full row's worth of data)
131
- * @return string Text to be placed inside the column <td> (movie title only)
132
- **************************************************************************/
133
- function column_option_name( $item ) {
134
- //Build row actions
135
- $edit_nonce = wp_create_nonce('wf_edit_feed');
136
- $delete_nonce = wp_create_nonce('wf_delete_feed');
137
- //$title = '<strong>' . $item['option_name'] . '</strong>';
138
-
139
- $actions = array(
140
- 'edit' => sprintf('<a href="?page=%s&action=%s&feed=%s&_wpnonce=%s">' . __('Edit', 'woo-feed') . '</a>', esc_attr($_REQUEST['page']), 'edit-feed', $item['option_name'], $edit_nonce),
141
- 'delete' => sprintf('<a val="?page=%s&action=%s&feed=%s&_wpnonce=%s" class="single-feed-delete" style="cursor: pointer;">' . __('Delete', 'woo-feed') . '</a>', esc_attr($_REQUEST['page']), 'delete-feed', absint($item['option_id']), $delete_nonce),
142
- );
143
-
144
- //Return the title contents
145
- $name = str_replace("wf_feed_", "", $item['option_name']);
146
- return sprintf('%1$s <span style="color:silver">(id:%2$s)</span>%3$s',
147
- /*$1%s*/
148
- $name,
149
- /*$2%s*/
150
- $item['option_id'],
151
- /*$3%s*/
152
- $this->row_actions($actions)
153
- );
154
- }
155
-
156
- public static function get_feeds( $search = "" ) {
157
- global $wpdb;
158
- $query = $wpdb->prepare("SELECT * FROM $wpdb->options WHERE option_name LIKE %s ORDER BY option_id DESC;", "wf_feed_%");
159
- $result = $wpdb->get_results($query, 'ARRAY_A');
160
-
161
- return $result;
162
- }
163
-
164
- /**
165
- * Delete a Feed.
166
- *
167
- * @param int $id Feed ID
168
- * @return false|int
169
- */
170
- public static function delete_feed( $id ) {
171
- global $wpdb;
172
- self::delete_feed_file($id);
173
- return $wpdb->delete(
174
- "{$wpdb->prefix}options",array( 'option_id' => $id ), array( '%d' )
175
- );
176
- }
177
-
178
- /**
179
- * Delete a Feed File.
180
- *
181
- * @param int $id customer ID
182
- * @return false|int
183
- */
184
- public static function delete_feed_file( $id ) {
185
- global $wpdb;
186
- $mylink = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->options WHERE option_id = %d", $id ) );
187
- $option_name = $mylink->option_name;
188
- $feedInfo = unserialize(get_option($option_name));
189
-
190
- $upload_dir = wp_upload_dir();
191
- $base = $upload_dir['basedir'];
192
- $path = $base . "/woo-feed/" . $feedInfo['feedrules']['provider'] . "/" . $feedInfo['feedrules']['feedType'];
193
- $file = $path . "/" . $feedInfo['feedrules']['filename'] . "." . $feedInfo['feedrules']['feedType'];
194
- unlink($file);
195
- }
196
-
197
- /**
198
- * Returns the count of records in the database.
199
- *
200
- * @return null|string
201
- */
202
- public static function record_count() {
203
- global $wpdb;
204
- $sql = "SELECT * FROM $wpdb->options WHERE option_name like 'wf_feed_%'";
205
- return $wpdb->get_var($sql);
206
- }
207
-
208
- /** Text displayed when no data is available */
209
- public function no_items() {
210
- _e('No feed available.', 'woo-feed');
211
- }
212
-
213
-
214
- /** ************************************************************************
215
- * REQUIRED if displaying checkboxes or using bulk actions! The 'cb' column
216
- * is given special treatment when columns are processed. It ALWAYS needs to
217
- * have it's own method.
218
- *
219
- * @see WP_List_Table::::single_row_columns()
220
- * @param array $item A singular item (one full row's worth of data)
221
- * @return string Text to be placed inside the column <td> (movie title only)
222
- **************************************************************************/
223
- function column_cb( $item ) {
224
- return sprintf(
225
- '<input type="checkbox" name="%1$s[]" value="%2$s" />',
226
- /*$1%s*/
227
- $this->_args['singular'], //Let's simply repurpose the table's singular label ("movie")
228
- /*$2%s*/
229
- $item['option_id'] //The value of the checkbox should be the record's id
230
- );
231
- }
232
-
233
-
234
- function column_name( $item ) {
235
- $edit_nonce = wp_create_nonce('wf_edit_feed');
236
- $delete_nonce = wp_create_nonce('wf_delete_feed');
237
- $title = '<strong>' . $item['option_name'] . '</strong>';
238
- $actions = array(
239
- 'edit' => sprintf('<a href="?page=%s&action=%s&feed=%s&_wpnonce=%s">' . __('Edit', 'woo-feed') . '</a>', esc_attr($_REQUEST['page']), 'edit-feed', absint($item['option_id']), $edit_nonce),
240
- 'delete' => sprintf('<a val="?page=%s&action=%s&feed=%s&_wpnonce=%s" class="single-feed-delete" style="cursor: pointer;">' . __('Delete', 'woo-feed') . '</a>', esc_attr($_REQUEST['page']), 'delete-feed', absint($item['option_id']), $delete_nonce),
241
- );
242
- return $title . $this->row_actions($actions);
243
- }
244
-
245
- /** ************************************************************************
246
- * REQUIRED! This method dictates the table's columns and titles. This should
247
- * return an array where the key is the column slug (and class) and the value
248
- * is the column's title text. If you need a checkbox for bulk actions, refer
249
- * to the $columns array below.
250
- *
251
- * The 'cb' column is treated differently than the rest. If including a checkbox
252
- * column in your table you must create a column_cb() method. If you don't need
253
- * bulk actions or checkboxes, simply leave the 'cb' entry out of your array.
254
- *
255
- * @see WP_List_Table::::single_row_columns()
256
- * @return array An associative array containing column information: 'slugs'=>'Visible Titles'
257
- **************************************************************************/
258
- function get_columns() {
259
- $columns = array(
260
- 'cb' => '<input type="checkbox" />', //Render a checkbox instead of text
261
- 'status' => __('Auto Update'),
262
- 'option_name' => __('File Name'),
263
- 'provider' => __('Provider'),
264
- 'type' => __('Type'),
265
- 'url' => __("Feed URL"),
266
- 'last_updated' => __("Last Updated"),
267
- 'view' => __("Action"),
268
- );
269
- return $columns;
270
- }
271
-
272
-
273
- /** ************************************************************************
274
- * Optional. If you want one or more columns to be sortable (ASC/DESC toggle),
275
- * you will need to register it here. This should return an array where the
276
- * key is the column that needs to be sortable, and the value is db column to
277
- * sort by. Often, the key and value will be the same, but this is not always
278
- * the case (as the value is a column name from the database, not the list table).
279
- *
280
- * This method merely defines which columns should be sortable and makes them
281
- * clickable - it does not handle the actual sorting. You still need to detect
282
- * the ORDERBY and ORDER querystring variables within prepare_items() and sort
283
- * your data accordingly (usually by modifying your query).
284
- *
285
- * @return array An associative array containing all the columns that should be sortable: 'slugs'=>array('data_values',bool)
286
- **************************************************************************/
287
- function get_sortable_columns() {
288
- $sortable_columns = array(
289
- 'option_name' => array( 'option_name', false ),
290
- );
291
- return $sortable_columns;
292
- }
293
-
294
-
295
- /** ************************************************************************
296
- * Optional. If you need to include bulk actions in your list table, this is
297
- * the place to define them. Bulk actions are an associative array in the format
298
- * 'slug'=>'Visible Title'
299
- *
300
- * If this method returns an empty value, no bulk action will be rendered. If
301
- * you specify any bulk actions, the bulk actions box will be rendered with
302
- * the table automatically on display().
303
- *
304
- * Also note that list tables are not automatically wrapped in <form> elements,
305
- * so you will need to create those manually in order for bulk actions to function.
306
- *
307
- * @return array An associative array containing all the bulk actions: 'slugs'=>'Visible Titles'
308
- **************************************************************************/
309
- function get_bulk_actions() {
310
- $actions = array(
311
- 'bulk-delete' => __('Delete'),
312
- );
313
- return $actions;
314
- }
315
-
316
-
317
- /** ************************************************************************
318
- * Optional. You can handle your bulk actions anywhere or anyhow you prefer.
319
- * For this example package, we will handle it in the class to keep things
320
- * clean and organized.
321
- *
322
- * @see $this->prepare_items()
323
- **************************************************************************/
324
- public function process_bulk_action() {
325
- //Detect when a bulk action is being triggered...
326
- if ( 'delete-feed' === $this->current_action() ) {
327
- // In our file that handles the request, verify the nonce.
328
- $nonce = esc_attr($_REQUEST['_wpnonce']);
329
- if ( ! wp_verify_nonce($nonce, 'wf_delete_feed') ) {
330
- update_option('wpf_message', esc_html__( 'Failed To Delete Feed. You do not have sufficient permission to delete.', 'woo-feed' ), false );
331
- wp_safe_redirect(admin_url("admin.php?page=webappick-manage-feeds&wpf_message=error"));
332
- die();
333
- } else {
334
- if ( self::delete_feed(absint($_GET['feed'])) ) {
335
- update_option( 'wpf_message', esc_html__( 'Feed Deleted Successfully', 'woo-feed' ), false );
336
- wp_safe_redirect(admin_url("admin.php?page=webappick-manage-feeds&wpf_message=success"));
337
- die();
338
- } else {
339
- update_option( 'wpf_message', esc_html__( 'Failed To Delete Feed', 'woo-feed' ), false );
340
- wp_safe_redirect(admin_url("admin.php?page=webappick-manage-feeds&wpf_message=error"));
341
- die();
342
- }
343
- }
344
- }
345
- //Detect when a bulk action is being triggered...
346
- if ( 'edit-feed' === $this->current_action() ) {
347
- // In our file that handles the request, verify the nonce.
348
- $nonce = esc_attr( $_REQUEST['_wpnonce'] );
349
- if ( ! wp_verify_nonce( $nonce, 'wf_edit_feed' ) ) {
350
- wp_die( esc_html__( 'You do not have sufficient permission to delete!', 'woo-feed' ) );
351
- }
352
- }
353
-
354
-
355
- // If the delete bulk action is triggered
356
- if ( (isset($_POST['feed'])) && (isset($_POST['action']) && $_POST['action'] == 'bulk-delete')
357
- || (isset($_POST['action2']) && $_POST['action2'] == 'bulk-delete')
358
- ) {
359
- if ( 'bulk-delete' === $this->current_action() ) {
360
- $nonce = esc_attr($_REQUEST['_wpnonce']);
361
- if ( ! wp_verify_nonce($nonce, "bulk-" . $this->_args['plural']) ) {
362
- wp_die( esc_html__( 'You do not have sufficient permission to delete!', 'woo-feed' ) );
363
- } else {
364
- $delete_ids = array_map( 'absint', $_POST['feed'] );
365
- $delete_ids = array_filter( $delete_ids );
366
- // loop over the array of record IDs and delete them
367
- if ( ! empty( $delete_ids ) ) {
368
- $count = count( $delete_ids );
369
- foreach ( $delete_ids as $id ) {
370
- self::delete_feed( $id );
371
-
372
- }
373
- $message = sprintf(
374
- esc_html( _n( '%d Feed Successfully Deleted.', '%d Feeds Successfully Deleted.', $count, 'woo-feed' ) ),
375
- $count
376
- );
377
- update_option( 'wpf_message', $message );
378
- wp_safe_redirect(admin_url("admin.php?page=webappick-manage-feeds&wpf_message=success"));
379
- die();
380
- }
381
- }
382
- }
383
- }
384
- }
385
-
386
-
387
- /** ************************************************************************
388
- * REQUIRED! This is where you prepare your data for display. This method will
389
- * usually be used to query the database, sort and filter the data, and generally
390
- * get it ready to be displayed. At a minimum, we should set $this->items and
391
- * $this->set_pagination_args(), although the following properties and methods
392
- * are frequently interacted with here...
393
- *
394
- * @global WPDB $wpdb
395
- * @uses $this->_column_headers
396
- * @uses $this->items
397
- * @uses $this->get_columns()
398
- * @uses $this->get_sortable_columns()
399
- * @uses $this->get_pagenum()
400
- * @uses $this->set_pagination_args()
401
- **************************************************************************/
402
- function prepare_items() {
403
- global $wpdb; //This is used only if making any database queries
404
-
405
- /**
406
- * First, lets decide how many records per page to show
407
- */
408
- $per_page = 10;
409
-
410
-
411
- /**
412
- * REQUIRED. Now we need to define our column headers. This includes a complete
413
- * array of columns to be displayed (slugs & titles), a list of columns
414
- * to keep hidden, and a list of columns that are sortable. Each of these
415
- * can be defined in another method (as we've done here) before being
416
- * used to build the value for our _column_headers property.
417
- */
418
- $columns = $this->get_columns();
419
- $hidden = array();
420
- $sortable = $this->get_sortable_columns();
421
-
422
-
423
- /**
424
- * REQUIRED. Finally, we build an array to be used by the class for column
425
- * headers. The $this->_column_headers property takes an array which contains
426
- * 3 other arrays. One for all columns, one for hidden columns, and one
427
- * for sortable columns.
428
- */
429
- $this->_column_headers = array( $columns, $hidden, $sortable );
430
-
431
-
432
- /**
433
- * Optional. You can handle your bulk actions however you see fit. In this
434
- * case, we'll handle them within our package just to keep things clean.
435
- */
436
- $this->process_bulk_action();
437
-
438
-
439
- /**
440
- * Instead of querying a database, we're going to fetch the example data
441
- * property we created for use in this plugin. This makes this example
442
- * package slightly different than one you might build on your own. In
443
- * this example, we'll be using array manipulation to sort and paginate
444
- * our data. In a real-world implementation, you will probably want to
445
- * use sort and pagination data to build a custom query instead, as you'll
446
- * be able to use your precisely-queried data immediately.
447
- */
448
- if ( isset($_POST['s']) ) {
449
- $data = $this->get_feeds( sanitize_text_field( $_POST['s'] ) );
450
- } else {
451
- $data = $this->get_feeds();
452
- }
453
-
454
-
455
- /**
456
- * This checks for sorting input and sorts the data in our array accordingly.
457
- *
458
- * In a real-world situation involving a database, you would probably want
459
- * to handle sorting by passing the 'orderby' and 'order' values directly
460
- * to a custom query. The returned data will be pre-sorted, and this array
461
- * sorting technique would be unnecessary.
462
- */
463
- function usort_reorder( $a, $b ) {
464
- $orderby = ( ! empty($_REQUEST['orderby'])) ? sanitize_text_field( $_REQUEST['orderby'] ) : 'option_name'; //If no sort, default to title
465
- $order = ( ! empty($_REQUEST['order'])) ? sanitize_text_field( $_REQUEST['order'] ) : 'asc'; //If no order, default to asc
466
- $result = strcmp($a[ $orderby ], $b[ $orderby ]); //Determine sort order
467
- return ($order === 'asc') ? $result : -$result; //Send final sort direction to usort
468
- }
469
-
470
- usort($data, 'usort_reorder');
471
-
472
-
473
- /***********************************************************************
474
- * ---------------------------------------------------------------------
475
- * vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
476
- *
477
- * In a real-world situation, this is where you would place your query.
478
- *
479
- * For information on making queries in WordPress, see this Codex entry:
480
- * http://codex.wordpress.org/Class_Reference/wpdb
481
- *
482
- * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
483
- * ---------------------------------------------------------------------
484
- **********************************************************************/
485
-
486
-
487
- /**
488
- * REQUIRED for pagination. Let's figure out what page the user is currently
489
- * looking at. We'll need this later, so you should always include it in
490
- * your own package classes.
491
- */
492
- $current_page = $this->get_pagenum();
493
-
494
- /**
495
- * REQUIRED for pagination. Let's check how many items are in our data array.
496
- * In real-world use, this would be the total number of items in your database,
497
- * without filtering. We'll need this later, so you should always include it
498
- * in your own package classes.
499
- */
500
- $total_items = count($data);
501
-
502
-
503
- /**
504
- * The WP_List_Table class does not handle pagination for us, so we need
505
- * to ensure that the data is trimmed to only the current page. We can use
506
- * array_slice() to
507
- */
508
- $data = array_slice($data, (($current_page - 1) * $per_page), $per_page);
509
-
510
-
511
- /**
512
- * REQUIRED. We also have to register our pagination options & calculations.
513
- */
514
- $this->set_pagination_args(array(
515
- 'total_items' => $total_items, //WE have to calculate the total number of items
516
- 'per_page' => $per_page, //WE have to determine how many items to show on a page
517
- 'total_pages' => ceil($total_items / $per_page), //WE have to calculate the total number of pages
518
- ));
519
 
520
  // $this->set_pagination_args( array(
521
  // 'total_items' => $total_items, //WE have to calculate the total number of items
522
  // 'per_page' => $per_page //WE have to determine how many items to show on a page
523
  // ) );
524
-
525
- /**
526
- * REQUIRED. Now we can add our *sorted* data to the items property, where
527
- * it can be used by the rest of the class.
528
- */
529
- $this->items = $data;
530
- }
531
  }
1
+ <?php
2
 
3
  /**
4
+ *
5
  * Feed List
6
  *
7
  * @link https://webappick.com/
10
  * @package Woo_Feed_DAttribute_list
11
  * @author Ohidul Islam <wahid@webappick.com>
12
  */
13
+ class Woo_Feed_Manage_list extends Woo_Feed_List_Table {
14
+
15
+ /** ************************************************************************
16
+ * Normally we would be querying data from a database and manipulating that
17
+ * for use in your list table. For this example, we're going to simplify it
18
+ * slightly and create a pre-built array. Think of this as the data that might
19
+ * be returned by $wpdb->query()
20
+ *
21
+ * In a real-world scenario, you would make your own custom query inside
22
+ * this class' prepare_items() method.
23
+ *
24
+ * @var array
25
+ **************************************************************************/
26
+
27
+
28
+ /** ************************************************************************
29
+ * REQUIRED. Set up a constructor that references the parent constructor. We
30
+ * use the parent reference to set some default configs.
31
+ ***************************************************************************/
32
+ function __construct() {
33
+ //Set parent defaults
34
+ parent::__construct( array(
35
+ 'singular' => __( 'feed', 'woo-feed' ), //singular name of the listed records
36
+ 'plural' => __( 'feeds', 'woo-feed' ), //plural name of the listed records
37
+ 'ajax' => false, //does this table support ajax?
38
+ ) );
39
+
40
+ }
41
+
42
+
43
+ /** ************************************************************************
44
+ * Recommended. This method is called when the parent class can't find a method
45
+ * specifically build for a given column. Generally, it's recommended to include
46
+ * one method for each column you want to render, keeping your package class
47
+ * neat and organized. For example, if the class needs to process a column
48
+ * named 'title', it would first see if a method named $this->column_title()
49
+ * exists - if it does, that method will be used. If it doesn't, this one will
50
+ * be used. Generally, you should try to use custom column methods as much as
51
+ * possible.
52
+ *
53
+ * Since we have defined a column_title() method later on, this method doesn't
54
+ * need to concern itself with any column with a name of 'title'. Instead, it
55
+ * needs to handle everything else.
56
+ *
57
+ * For more detailed insight into how columns are handled, take a look at
58
+ * WP_List_Table::single_row_columns()
59
+ *
60
+ * @param array $item A singular item (one full row's worth of data)
61
+ * @param string $column_name The name/slug of the column to be processed
62
+ *
63
+ * @return string Text or HTML to be placed inside the column <td>
64
+ *
65
+ **************************************************************************/
 
 
66
  function column_default( $item, $column_name ) {
67
+ $getItem = $item['option_name'];
68
  $statusId = $item['option_id'];
69
+ $itemInfo = maybe_unserialize( get_option( $getItem ) );
70
  global $regenerating, $regeneratingName;
71
+ $optionName = str_replace( 'wf_feed_', '', $getItem );
72
+ $spinIcon = ( true === $regenerating && $optionName === $regeneratingName ) ? ' wpf_spin_reverse' : '';
73
+ $disableBtn = true === $regenerating ? ' disabled' : '';
74
  switch ( $column_name ) {
75
+ case 'option_name':
76
+ return $optionName;
77
+ case 'status':
78
+ if ( ! isset( $itemInfo['status'] ) || ( isset( $itemInfo['status'] ) && 1 == $itemInfo['status'] ) ) {
79
+ return ' <div class="wf_status_wrap"><input style="display: none;" data-index=' . $statusId . ' id=' . $statusId . ' checked class="woo_feed_status_input" type="checkbox" value="' . $getItem . '"/>
80
+ <label for=' . $statusId . ' class= "woo-feed_active_status"></label></div>';
81
+ } else {
82
+ return ' <div class="wf_status_wrap"> <input style="display: none;" data-index=' . $statusId . ' id=' . $statusId . ' class="woo_feed_status_input" type="checkbox" value="' . $getItem . '"/>
83
+ <label for=' . $statusId . ' class= "woo-feed_active_status"></label> </div>';
84
+ }
85
+ case 'provider':
86
+ $provider = $itemInfo['feedrules']['provider'];
87
+
88
+ return ucwords( str_replace( '_', ' ', $provider ) );
89
+ case 'type':
90
+ $feedType = $itemInfo['feedrules']['feedType'];
91
+
92
+ return strtoupper( str_replace( '_', ' ', $feedType ) );
93
+ case 'url':
94
+ /** @noinspection SpellCheckingInspection */
95
+ return sprintf(
96
+ '<span class="toClipboard" data-clipboard-target="#_url%1$s" id="_url%1$s">%2$s</span><span class="toClipboard" data-clipboard-target="#_url%1$s">%3$s</span>',
97
+ $statusId,
98
+ $itemInfo[ $column_name ],
99
+ '<img src="data:image/svg+xml,%0A%3Csvg height=\'1024\' width=\'896\' xmlns=\'http://www.w3.org/2000/svg\'%3E%3Cpath d=\'M128 768h256v64H128v-64z m320-384H128v64h320v-64z m128 192V448L384 640l192 192V704h320V576H576z m-288-64H128v64h160v-64zM128 704h160v-64H128v64z m576 64h64v128c-1 18-7 33-19 45s-27 18-45 19H64c-35 0-64-29-64-64V192c0-35 29-64 64-64h192C256 57 313 0 384 0s128 57 128 128h192c35 0 64 29 64 64v320h-64V320H64v576h640V768zM128 256h512c0-35-29-64-64-64h-64c-35 0-64-29-64-64s-29-64-64-64-64 29-64 64-29 64-64 64h-64c-35 0-64 29-64 64z\' /%3E%3C/svg%3E%0A" alt="' . __( 'Copy To Clipboard', 'woo-feed' ) . '" class="clippy">'
100
+ );
101
+ case 'last_updated':
102
+ return $itemInfo[ $column_name ];
103
+ case 'view':
104
+ $view = $itemInfo['url'];
105
+
106
+ /** @noinspection HtmlUnknownTarget */
107
+ return sprintf(
108
+ '<a href="%1$s" title="%2$s" aria-label="%2$s" target="_blank"><span class="dashicons dashicons-external" aria-hidden="true"></span></a>
109
  <a id="%3$s" class="wpf_regenerate%6$s" href="#" title="%4$s" aria-label="%4$s"><span class="dashicons dashicons-update-alt%7$s" aria-hidden="true"></span></a>
110
  <a href="%1$s" title="%5$s" aria-label="%5$s" download><span class="dashicons dashicons-download" aria-hidden="true"></span></a>',
111
+ $view,
112
+ __( 'View', 'woo-feed' ),
113
+ $getItem,
114
+ __( 'Regenerate', 'woo-feed' ),
115
+ __( 'Download', 'woo-feed' ),
116
+ $disableBtn,
117
+ $spinIcon
118
+ );
119
+ default:
120
+ return false;
121
+ }
122
  }
123
+
124
+
125
+ /** ************************************************************************
126
+ * Recommended. This is a custom column method and is responsible for what
127
+ * is rendered in any column with a name/slug of 'title'. Every time the class
128
+ * needs to render a column, it first looks for a method named
129
+ * column_{$column_title} - if it exists, that method is run. If it doesn't
130
+ * exist, column_default() is called instead.
131
+ *
132
+ * This example also illustrates how to implement rollover actions. Actions
133
+ * should be an associative array formatted as 'slug'=>'link html' - and you
134
+ * will need to generate the URLs yourself. You could even ensure the links
135
+ *
136
+ *
137
+ * @param array $item A singular item (one full row's worth of data)
138
+ *
139
+ * @return string Text to be placed inside the column <td> (movie title only)
140
+ **************************************************************************@see WP_List_Table::::single_row_columns()
141
+ */
142
+ function column_option_name( $item ) {
143
+ global $plugin_page;
144
+ //Build row actions
145
+ $edit_nonce = wp_create_nonce( 'wf_edit_feed' );
146
+ $delete_nonce = wp_create_nonce( 'wf_delete_feed' );
147
+ //$title = '<strong>' . $item['option_name'] . '</strong>';
148
+ $actions = array(
149
+ 'edit' => sprintf(
150
+ '<a href="?page=%s&action=%s&feed=%s&_wpnonce=%s">' . __( 'Edit', 'woo-feed' ) . '</a>',
151
+ $plugin_page,
152
+ 'edit-feed',
153
+ $item['option_name'],
154
+ $edit_nonce
155
+ ),
156
+ 'delete' => sprintf(
157
+ '<a val="?page=%s&action=%s&feed=%s&_wpnonce=%s" class="single-feed-delete" style="cursor: pointer;">' . __( 'Delete', 'woo-feed' ) . '</a>',
158
+ $plugin_page,
159
+ 'delete-feed',
160
+ absint( $item['option_id'] ),
161
+ $delete_nonce
162
+ ),
163
+ );
164
+ //Return the title contents
165
+ $name = str_replace( 'wf_feed_', '', $item['option_name'] );
166
+ $config = maybe_unserialize( maybe_unserialize( $item['option_value'] ) );
167
+ if ( isset( $config['feedrules'], $config['feedrules']['filename'] ) ) {
168
+ $name = $config['feedrules']['filename'];
169
+ }
170
+
171
+ return sprintf( '%1$s <span style="color:silver">(id:%2$s)</span>%3$s',
172
+ esc_html( $name ),
173
+ esc_html( $item['option_id'] ),
174
+ $this->row_actions( $actions )
175
+ );
176
+ }
177
+
178
+ public static function get_feeds() {
179
+ global $wpdb;
180
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
181
+ $result = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->options WHERE option_name LIKE %s ORDER BY option_id DESC;", 'wf_feed_%' ), 'ARRAY_A' );
182
+ return $result;
183
+ }
184
+
185
+ /**
186
+ * Delete a Feed.
187
+ *
188
+ * @param int $id Feed ID
189
+ *
190
+ * @return false|int
191
+ */
192
+ public static function delete_feed( $id ) {
193
+ return woo_feed_delete_feed( $id );
194
+ }
195
+
196
+ public static function record_count() {
197
+ global $wpdb;
198
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
199
+ return $wpdb->get_var( $wpdb->prepare( "SELECT * FROM $wpdb->options WHERE option_name like %s", 'wf_feed_%' ) );
200
+ }
201
+
202
+ /** Text displayed when no data is available */
203
+ public function no_items() {
204
+ _e( 'No feed available.', 'woo-feed' );
205
+ }
206
+
207
+
208
+ /** ************************************************************************
209
+ * REQUIRED if displaying checkboxes or using bulk actions! The 'cb' column
210
+ * is given special treatment when columns are processed. It ALWAYS needs to
211
+ * have it's own method.
212
+ *
213
+ * @param array $item A singular item (one full row's worth of data)
214
+ *
215
+ * @return string Text to be placed inside the column <td> (movie title only)
216
+ **************************************************************************@see WP_List_Table::::single_row_columns()
217
+ */
218
+ function column_cb( $item ) {
219
+ return sprintf(
220
+ '<input type="checkbox" name="%1$s[]" value="%2$s" />',
221
+ /*$1%s*/
222
+ $this->_args['singular'], //Let's simply repurpose the table's singular label ("movie")
223
+ /*$2%s*/
224
+ $item['option_id'] //The value of the checkbox should be the record's id
225
+ );
226
+ }
227
+
228
+
229
+ function column_name( $item ) {
230
+ global $plugin_page;
231
+ $edit_nonce = wp_create_nonce( 'wf_edit_feed' );
232
+ $delete_nonce = wp_create_nonce( 'wf_delete_feed' );
233
+ $title = '<strong>' . $item['option_name'] . '</strong>';
234
+ $actions = array(
235
+ 'edit' => sprintf(
236
+ '<a href="?page=%s&action=%s&feed=%s&_wpnonce=%s">' . __( 'Edit', 'woo-feed' ) . '</a>',
237
+ $plugin_page,
238
+ 'edit-feed',
239
+ absint( $item['option_id'] ),
240
+ $edit_nonce
241
+ ),
242
+ 'delete' => sprintf(
243
+ '<a val="?page=%s&action=%s&feed=%s&_wpnonce=%s" class="single-feed-delete" style="cursor: pointer;">' . __( 'Delete', 'woo-feed' ) . '</a>',
244
+ $plugin_page,
245
+ 'delete-feed',
246
+ absint( $item['option_id'] ),
247
+ $delete_nonce
248
+ ),
249
+ );
250
+
251
+ return $title . $this->row_actions( $actions );
252
+ }
253
+
254
+ /** ************************************************************************
255
+ * REQUIRED! This method dictates the table's columns and titles. This should
256
+ * return an array where the key is the column slug (and class) and the value
257
+ * is the column's title text. If you need a checkbox for bulk actions, refer
258
+ * to the $columns array below.
259
+ *
260
+ * The 'cb' column is treated differently than the rest. If including a checkbox
261
+ * column in your table you must create a column_cb() method. If you don't need
262
+ * bulk actions or checkboxes, simply leave the 'cb' entry out of your array.
263
+ *
264
+ * @return array An associative array containing column information: 'slugs'=>'Visible Titles'
265
+ **************************************************************************@see WP_List_Table::::single_row_columns()
266
+ */
267
+ function get_columns() {
268
+ $columns = array(
269
+ 'cb' => '<input type="checkbox" />', //Render a checkbox instead of text
270
+ 'status' => __( 'Auto Update', 'woo-feed' ),
271
+ 'option_name' => __( 'Feed Name', 'woo-feed' ),
272
+ 'provider' => __( 'Provider', 'woo-feed' ),
273
+ 'type' => __( 'Type', 'woo-feed' ),
274
+ 'url' => __( 'Feed URL', 'woo-feed' ),
275
+ 'last_updated' => __( 'Last Updated', 'woo-feed' ),
276
+ 'view' => __( 'Action', 'woo-feed' ),
277
+ );
278
+
279
+ return $columns;
280
+ }
281
+
282
+
283
+ /** ************************************************************************
284
+ * Optional. If you want one or more columns to be sortable (ASC/DESC toggle),
285
+ * you will need to register it here. This should return an array where the
286
+ * key is the column that needs to be sortable, and the value is db column to
287
+ * sort by. Often, the key and value will be the same, but this is not always
288
+ * the case (as the value is a column name from the database, not the list table).
289
+ *
290
+ * This method merely defines which columns should be sortable and makes them
291
+ * clickable - it does not handle the actual sorting. You still need to detect
292
+ * the ORDERBY and ORDER querystring variables within prepare_items() and sort
293
+ * your data accordingly (usually by modifying your query).
294
+ *
295
+ * @return array An associative array containing all the columns that should be sortable: 'slugs'=>array('data_values',bool)
296
+ **************************************************************************/
297
+ function get_sortable_columns() {
298
+ $sortable_columns = array(
299
+ 'option_name' => array( 'option_name', false ),
300
+ );
301
+
302
+ return $sortable_columns;
303
+ }
304
+
305
+
306
+ /** ************************************************************************
307
+ * Optional. If you need to include bulk actions in your list table, this is
308
+ * the place to define them. Bulk actions are an associative array in the format
309
+ * 'slug'=>'Visible Title'
310
+ *
311
+ * If this method returns an empty value, no bulk action will be rendered. If
312
+ * you specify any bulk actions, the bulk actions box will be rendered with
313
+ * the table automatically on display().
314
+ *
315
+ * Also note that list tables are not automatically wrapped in <form> elements,
316
+ * so you will need to create those manually in order for bulk actions to function.
317
+ *
318
+ * @return array An associative array containing all the bulk actions: 'slugs'=>'Visible Titles'
319
+ **************************************************************************/
320
+ function get_bulk_actions() {
321
+ $actions = array(
322
+ 'bulk-delete' => __( 'Delete', 'woo-feed' ),
323
+ );
324
+
325
+ return $actions;
326
+ }
327
+
328
+
329
+ /** ************************************************************************
330
+ * Optional. You can handle your bulk actions anywhere or anyhow you prefer.
331
+ * For this example package, we will handle it in the class to keep things
332
+ * clean and organized.
333
+ *
334
+ * @see $this->prepare_items()
335
+ **************************************************************************/
336
+ public function process_bulk_action() {
337
+ //Detect when a bulk action is being triggered...
338
+ if ( 'delete-feed' === $this->current_action() ) {
339
+ // In our file that handles the request, verify the nonce.
340
+ if ( ! isset( $_REQUEST['_wpnonce'] ) || isset( $_REQUEST['_wpnonce'] ) && ! wp_verify_nonce( sanitize_text_field( $_REQUEST['_wpnonce'] ), 'wf_delete_feed' ) ) {
341
+ update_option( 'wpf_message', esc_html__( 'Failed To Delete Feed. You do not have sufficient permission to delete.', 'woo-feed' ), false );
342
+ wp_safe_redirect( admin_url( "admin.php?page=webappick-manage-feeds&wpf_message=error" ) );
343
+ die();
344
+ } else {
345
+ if ( isset( $_GET['feed'] ) && self::delete_feed( absint( $_GET['feed'] ) ) ) {
346
+ update_option( 'wpf_message', esc_html__( 'Feed Deleted Successfully', 'woo-feed' ), false );
347
+ wp_safe_redirect( admin_url( "admin.php?page=webappick-manage-feeds&wpf_message=success" ) );
348
+ die();
349
+ } else {
350
+ update_option( 'wpf_message', esc_html__( 'Failed To Delete Feed', 'woo-feed' ), false );
351
+ wp_safe_redirect( admin_url( "admin.php?page=webappick-manage-feeds&wpf_message=error" ) );
352
+ die();
353
+ }
354
+ }
355
+ }
356
+
357
+ //Detect when a bulk action is being triggered...
358
+ if ( 'edit-feed' === $this->current_action() ) {
359
+ // In our file that handles the request, verify the nonce.
360
+ if ( ! isset( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( sanitize_text_field( $_REQUEST['_wpnonce'] ), 'wf_edit_feed' ) ) {
361
+ wp_die( esc_html__( 'You do not have sufficient permission to delete!', 'woo-feed' ) );
362
+ }
363
+ }
364
+
365
+ // If the delete bulk action is triggered
366
+ if (
367
+ ( isset( $_POST['feed'] ) ) && ( isset( $_POST['action'] ) && 'bulk-delete' == $_POST['action'] ) ||
368
+ ( isset( $_POST['action2'] ) && 'bulk-delete' == $_POST['action2'] )
369
+ ) {
370
+ if ( 'bulk-delete' === $this->current_action() ) {
371
+ if ( ! isset( $_REQUEST['_wpnonce'] ) || isset( $_REQUEST['_wpnonce'] ) && ! wp_verify_nonce( sanitize_text_field( $_REQUEST['_wpnonce'] ), "bulk-" . $this->_args['plural'] ) ) {
372
+ wp_die( esc_html__( 'You do not have sufficient permission to delete!', 'woo-feed' ) );
373
+ } else {
374
+ $delete_ids = array_map( 'absint', $_POST['feed'] );
375
+ $delete_ids = array_filter( $delete_ids );
376
+ // loop over the array of record IDs and delete them
377
+ if ( ! empty( $delete_ids ) ) {
378
+ $count = count( $delete_ids );
379
+ foreach ( $delete_ids as $id ) {
380
+ self::delete_feed( $id );
381
+ }
382
+ $message = sprintf(
383
+ esc_html(
384
+ /* translators: %d: number of item deleted. */
385
+ _n(
386
+ '%d Feed Successfully Deleted.',
387
+ '%d Feeds Successfully Deleted.',
388
+ $count,
389
+ 'woo-feed'
390
+ )
391
+ ),
392
+ $count
393
+ );
394
+ update_option( 'wpf_message', $message, false );
395
+ wp_safe_redirect( admin_url( 'admin.php?page=webappick-manage-feeds&wpf_message=success' ) );
396
+ die();
397
+ }
398
+ }
399
+ }
400
+ }
401
+ }
402
+
403
+
404
+ /** ************************************************************************
405
+ * REQUIRED! This is where you prepare your data for display. This method will
406
+ * usually be used to query the database, sort and filter the data, and generally
407
+ * get it ready to be displayed. At a minimum, we should set $this->items and
408
+ * $this->set_pagination_args(), although the following properties and methods
409
+ * are frequently interacted with here...
410
+ *
411
+ * @global WPDB $wpdb
412
+ * @uses $this->_column_headers
413
+ * @uses $this->items
414
+ * @uses $this->get_columns()
415
+ * @uses $this->get_sortable_columns()
416
+ * @uses $this->get_pagenum()
417
+ * @uses $this->set_pagination_args()
418
+ **************************************************************************/
419
+ function prepare_items() {
420
+ /**
421
+ * First, lets decide how many records per page to show
422
+ */
423
+ $per_page = 10;
424
+
425
+
426
+ /**
427
+ * REQUIRED. Now we need to define our column headers. This includes a complete
428
+ * array of columns to be displayed (slugs & titles), a list of columns
429
+ * to keep hidden, and a list of columns that are sortable. Each of these
430
+ * can be defined in another method (as we've done here) before being
431
+ * used to build the value for our _column_headers property.
432
+ */
433
+ $columns = $this->get_columns();
434
+ $hidden = array();
435
+ $sortable = $this->get_sortable_columns();
436
+
437
+
438
+ /**
439
+ * REQUIRED. Finally, we build an array to be used by the class for column
440
+ * headers. The $this->_column_headers property takes an array which contains
441
+ * 3 other arrays. One for all columns, one for hidden columns, and one
442
+ * for sortable columns.
443
+ */
444
+ $this->_column_headers = array( $columns, $hidden, $sortable );
445
+
446
+
447
+ /**
448
+ * Optional. You can handle your bulk actions however you see fit. In this
449
+ * case, we'll handle them within our package just to keep things clean.
450
+ */
451
+ $this->process_bulk_action();
452
+
453
+
454
+ /**
455
+ * Instead of querying a database, we're going to fetch the example data
456
+ * property we created for use in this plugin. This makes this example
457
+ * package slightly different than one you might build on your own. In
458
+ * this example, we'll be using array manipulation to sort and paginate
459
+ * our data. In a real-world implementation, you will probably want to
460
+ * use sort and pagination data to build a custom query instead, as you'll
461
+ * be able to use your precisely-queried data immediately.
462
+ */
463
+ $data = $this->get_feeds();
464
+
465
+ usort( $data, 'usort_reorder' );
466
+
467
+
468
+ /***********************************************************************
469
+ * ---------------------------------------------------------------------
470
+ *
471
+ * In a real-world situation, this is where you would place your query.
472
+ *
473
+ * For information on making queries in WordPress, see this Codex entry:
474
+ * http://codex.wordpress.org/Class_Reference/wpdb
475
+ *
476
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
477
+ * ---------------------------------------------------------------------
478
+ **********************************************************************/
479
+
480
+
481
+ /**
482
+ * REQUIRED for pagination. Let's figure out what page the user is currently
483
+ * looking at. We'll need this later, so you should always include it in
484
+ * your own package classes.
485
+ */
486
+ $current_page = $this->get_pagenum();
487
+
488
+ /**
489
+ * REQUIRED for pagination. Let's check how many items are in our data array.
490
+ * In real-world use, this would be the total number of items in your database,
491
+ * without filtering. We'll need this later, so you should always include it
492
+ * in your own package classes.
493
+ */
494
+ $total_items = count( $data );
495
+
496
+
497
+ /**
498
+ * The WP_List_Table class does not handle pagination for us, so we need
499
+ * to ensure that the data is trimmed to only the current page. We can use
500
+ * array_slice() to
501
+ */
502
+ $data = array_slice( $data, ( ( $current_page - 1 ) * $per_page ), $per_page );
503
+
504
+
505
+ /**
506
+ * REQUIRED. We also have to register our pagination options & calculations.
507
+ */
508
+ $this->set_pagination_args( array(
509
+ 'total_items' => $total_items, //WE have to calculate the total number of items
510
+ 'per_page' => $per_page, //WE have to determine how many items to show on a page
511
+ 'total_pages' => ceil( $total_items / $per_page ), //WE have to calculate the total number of pages
512
+ ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
513
 
514
  // $this->set_pagination_args( array(
515
  // 'total_items' => $total_items, //WE have to calculate the total number of items
516
  // 'per_page' => $per_page //WE have to determine how many items to show on a page
517
  // ) );
518
+
519
+ /**
520
+ * REQUIRED. Now we can add our *sorted* data to the items property, where
521
+ * it can be used by the rest of the class.
522
+ */
523
+ $this->items = $data;
524
+ }
525
  }
admin/css/woo-feed-admin.css CHANGED
@@ -314,6 +314,17 @@ p {
314
  display: block;
315
  }
316
 
 
 
 
 
 
 
 
 
 
 
 
317
  .webappick_selector{
318
  background: #0073aa !important;
319
  color: #f1f1f1 !important;
@@ -757,7 +768,7 @@ table.wf-rate-table a.review-star:after {
757
  .wapk-admin .wapk-section,
758
  .wapk-admin >.notice {
759
  /* Restore .warp margin */
760
- margin: 15px 20px 0 20px;
761
  position: relative;
762
  display: block;
763
  }
314
  display: block;
315
  }
316
 
317
+ .wf_tabs [id^="tab"]:checked ~ [id^="wf-tab-content"] { display: block; }
318
+ [id^="wf-tab-content"] { margin-bottom: 40px; }
319
+
320
+ div#wf-tab-content2 table:first-child { padding: 10px 0; }
321
+ div#wf-tab-content2 table:first-child td:nth-child(1) { width: 260px; }
322
+ div#wf-tab-content2 table:first-child td:nth-child(2) { width: 260px; }
323
+
324
+ table.feed-actions tr td:last-child {
325
+ text-align: right;
326
+ }
327
+
328
  .webappick_selector{
329
  background: #0073aa !important;
330
  color: #f1f1f1 !important;
768
  .wapk-admin .wapk-section,
769
  .wapk-admin >.notice {
770
  /* Restore .warp margin */
771
+ margin: 15px 20px 0 20px !important;
772
  position: relative;
773
  display: block;
774
  }
admin/partials/templates/common_add-feed.php CHANGED
@@ -1,128 +1,97 @@
1
- <ul class="wf_tabs">
2
- <li>
3
- <input type="radio" name="wf_tabs" id="tab1" checked/>
4
- <label class="wf-tab-name" for="tab1"><?php _e( 'Feed Config', 'woo-feed' ); ?></label>
5
-
6
- <div id="wf-tab-content1" class="wf-tab-content">
7
- <table class="table tree widefat fixed sorted_table mtable" width="100%" id="table-1">
8
- <thead>
9
- <tr>
10
- <th></th>
11
- <th><?php echo ucfirst( $provider ) . " "; ?><?php _e( 'Attributes', 'woo-feed' ); ?></th>
12
- <th><?php _e( 'Prefix', 'woo-feed' ); ?></th>
13
- <th><?php _e( 'Type', 'woo-feed' ); ?></th>
14
- <th><?php _e( 'Value', 'woo-feed' ); ?></th>
15
- <th><?php _e( 'Suffix', 'woo-feed' ); ?></th>
16
- <th><?php _e( 'Output Type', 'woo-feed' ); ?></th>
17
- <th><?php _e( 'Limit', 'woo-feed' ); ?></th>
18
- <th></th>
19
- </tr>
20
- </thead>
21
- <tbody>
22
- <?php
23
- $merchant = new Woo_Feed_Merchant( $provider );
24
- $template = $merchant->get_merchant_template();
25
- if ( ! $template ) { # Default template
26
- $template = $merchant->get_default_template();
27
- }
28
- foreach ( $template['mattributes'] as $key => $value ) {
29
- $merchantAttribute = $value;
30
- $prefix = $template['prefix'][ $key ];
31
- $type = $template['type'][ $key ]; # Attribute or Pattern
32
- $attrSelected = ( $type == 'attribute' ) ? "selected" : "";
33
- $patternSelected = ( $type == 'pattern' ) ? "selected" : "";
34
- $attribute = $template['attributes'][ $key ];
35
- $pattern = $template['default'][ $key ];
36
- $suffix = $template['suffix'][ $key ];
37
- $outputType = $template['output_type'][ $key ];
38
- $limit = $template['limit'][ $key ];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  ?>
40
- <tr>
41
- <td>
42
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
43
- </td>
44
- <td>
45
- <input type="text" name="mattributes[]"
46
- autocomplete="off" required
47
- value="<?php echo $merchantAttribute; ?>"
48
- class="wf_validate_attr wf_mattributes"/>
49
- </td>
50
- <td>
51
- <input type="text" name="prefix[]" autocomplete="off" value="<?php echo $prefix; ?>"
52
- class="wf_ps"/>
53
- </td>
54
- <td>
55
- <select name="type[]" class="attr_type wfnoempty">
56
- <option <?php echo $attrSelected; ?>
57
- value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
58
- <option <?php echo $patternSelected; ?>
59
- value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
60
- </select>
61
- </td>
62
- <td>
63
- <select <?php echo ( $attrSelected != 'selected' ) ? "style='display:none;'" : ""; ?>
64
- name="attributes[]" required="required"
65
- class="wf_validate_attr wf_attr wf_attributes">
66
- <?php echo $product->attributeDropdown( $attribute ); ?>
67
- </select>
68
- <input value="<?php echo $pattern; ?>" type="text" name="default[]" autocomplete="off"
69
- class="wf_default wf_attributes"
70
- <?php echo ( $patternSelected != 'selected' ) ? "style='display:none;'" : ""; ?>"/>
71
- </td>
72
- <td>
73
- <input type="text" name="suffix[]" autocomplete="off" value="<?php echo $suffix; ?>"
74
- class="wf_ps"/>
75
- </td>
76
- <td>
77
- <select name="output_type[][]" class="outputType wfnoempty">
78
- <option value="1">Default</option>
79
- <option value="2">Strip Tags</option>
80
- <option value="3">UTF-8 Encode</option>
81
- <option value="4">htmlentities</option>
82
- <option value="5">Integer</option>
83
- <option value="6">Price</option>
84
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
85
- <option value="8">CDATA</option>
86
- </select>
87
- <i class="dashicons dashicons-editor-expand expandType"></i>
88
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
89
- </td>
90
- <td>
91
- <input type="text" value="<?php echo $limit; ?>" name="limit[]" class="wf_ps"/>
92
- </td>
93
- <td>
94
- <i class="delRow dashicons dashicons-trash"></i>
95
- </td>
96
- </tr>
97
  <?php
98
- }
99
- ?>
100
- </tbody>
101
- <tfoot>
102
- <tr>
103
- <td>
104
- <button type="button" class="button-small button-primary" id="wf_newRow">
105
- <?php _e( 'Add New Row', 'woo-feed' ); ?>
106
- </button>
107
- </td>
108
- <td colspan="8">
109
-
110
- </td>
111
- </tr>
112
- </tfoot>
113
- </table>
114
- <table class=" widefat fixed">
115
- <tr>
116
- <td align="left" class="">
117
- <div class="makeFeedResponse"></div>
118
- <div class="makeFeedComplete"></div>
119
- </td>
120
- <td align="right">
121
- <button type="submit" class="wfbtn"><?php _e( 'Save & Generate Feed', 'woo-feed' ); ?></button>
122
- </td>
123
- </tr>
124
- </table>
125
- </div>
126
- </li>
127
- <?php include plugin_dir_path(__FILE__) . "../woo-feed-ftp-sftp-template.php"; ?>
128
- </ul>
1
+ <?php
2
+ /**
3
+ * Common Add Feed Template
4
+ */
5
+ if ( ! defined( 'ABSPATH' ) ) {
6
+ die();
7
+ }
8
+ global $provider;
9
+ ?>
10
+ <table class="table tree widefat fixed sorted_table mtable" style="width: 100%;" id="table-1">
11
+ <thead>
12
+ <tr>
13
+ <th></th>
14
+ <th><?php echo esc_html( ucfirst( $provider ) ) . ' '; ?><?php _e( 'Attributes', 'woo-feed' ); ?></th>
15
+ <th><?php _e( 'Prefix', 'woo-feed' ); ?></th>
16
+ <th><?php _e( 'Type', 'woo-feed' ); ?></th>
17
+ <th><?php _e( 'Value', 'woo-feed' ); ?></th>
18
+ <th><?php _e( 'Suffix', 'woo-feed' ); ?></th>
19
+ <th><?php _e( 'Output Type', 'woo-feed' ); ?></th>
20
+ <th><?php _e( 'Command', 'woo-feed' ); ?></th>
21
+ <th></th>
22
+ </tr>
23
+ </thead>
24
+ <tbody>
25
+ <?php
26
+ $merchant = new Woo_Feed_Merchant( $provider );
27
+ $template = $merchant->get_merchant_template();
28
+ if ( ! $template ) { // Default template
29
+ $template = $merchant->get_default_template();
30
+ }
31
+ foreach ( $template['mattributes'] as $key => $value ) {
32
+ $merchantAttribute = $value;
33
+ $prefix = $template['prefix'][ $key ];
34
+ $attrSelected = ( 'attribute' == $template['type'][ $key ] ) ? 'selected' : '';
35
+ $patternSelected = ( 'pattern' == $template['type'][ $key ] ) ? 'selected' : '';
36
+ $attribute = $template['attributes'][ $key ];
37
+ $pattern = $template['default'][ $key ];
38
+ $suffix = $template['suffix'][ $key ];
39
+ $outputType = $template['output_type'][ $key ];
40
+ $limit = $template['limit'][ $key ];
41
+ ?>
42
+ <tr>
43
+ <td><i class="wf_sortedtable dashicons dashicons-menu"></i></td>
44
+ <td>
45
+ <input type="text" name="mattributes[]" autocomplete="off" required value="<?php echo esc_attr( $merchantAttribute ); ?>" class="wf_validate_attr wf_mattributes">
46
+ </td>
47
+ <td>
48
+ <input type="text" name="prefix[]" autocomplete="off" value="<?php echo esc_attr( $prefix ); ?>" class="wf_ps">
49
+ </td>
50
+ <td>
51
+ <select name="type[]" class="attr_type wfnoempty">
52
+ <option <?php echo esc_attr( $attrSelected ); ?> value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
53
+ <option <?php echo esc_attr( $patternSelected ); ?> value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
54
+ </select>
55
+ </td>
56
+ <td>
57
+ <select <?php echo ( 'selected' != $attrSelected ) ? "style='display:none;'" : ''; ?> name="attributes[]" required="required" class="wf_validate_attr wf_attr wf_attributes">
58
+ <?php
59
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
60
+ echo $wooFeedProduct->attributeDropdown( $attribute );
61
  ?>
62
+ </select>
63
+ <input value="<?php echo esc_attr( $pattern ); ?>" type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" <?php echo ( 'selected' != $patternSelected ) ? "style='display:none;'" : ''; ?>">
64
+ </td>
65
+ <td>
66
+ <input type="text" name="suffix[]" autocomplete="off" value="<?php echo esc_attr( $suffix ); ?>" class="wf_ps">
67
+ </td>
68
+ <td>
69
+ <select name="output_type[][]" class="outputType wfnoempty">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  <?php
71
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
72
+ echo $wooFeedDropDown->outputTypes();
73
+ ?>
74
+ </select>
75
+ <i class="dashicons dashicons-editor-expand expandType"></i>
76
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
77
+ </td>
78
+ <td>
79
+ <input type="text" value="<?php echo esc_attr( $limit ); ?>" name="limit[]" class="wf_ps">
80
+ </td>
81
+ <td>
82
+ <i class="delRow dashicons dashicons-trash"></i>
83
+ </td>
84
+ </tr>
85
+ <?php
86
+ }
87
+ ?>
88
+ </tbody>
89
+ <tfoot>
90
+ <tr>
91
+ <td>
92
+ <button type="button" class="button-small button-primary" id="wf_newRow"><?php _e( 'Add New Row', 'woo-feed' ); ?></button>
93
+ </td>
94
+ <td colspan="8"></td>
95
+ </tr>
96
+ </tfoot>
97
+ </table>
 
 
 
 
admin/partials/templates/custom_add-feed.php CHANGED
@@ -1,100 +1,78 @@
1
- <ul class="wf_tabs">
2
- <li>
3
- <input type="radio" name="wf_tabs" id="tab1" checked/>
4
- <label class="wf-tab-name" for="tab1"><?php _e('Feed Config', 'woo-feed'); ?></label>
5
-
6
- <div id="wf-tab-content1" class="wf-tab-content">
7
- <table class="table tree widefat fixed sorted_table mtable" width="100%" id="table-1">
8
- <thead>
9
- <tr>
10
- <th></th>
11
- <th><?php echo ucfirst($provider); ?> <?php _e('Attributes', 'woo-feed'); ?></th>
12
- <th><?php _e('Prefix', 'woo-feed'); ?></th>
13
- <th><?php _e('Type', 'woo-feed'); ?></th>
14
- <th><?php _e('Value', 'woo-feed'); ?></th>
15
- <th><?php _e('Suffix', 'woo-feed'); ?></th>
16
- <th><?php _e('Output Type', 'woo-feed'); ?></th>
17
- <th><?php _e('Output Limit', 'woo-feed'); ?></th>
18
- <th></th>
19
- </tr>
20
- </thead>
21
- <tbody>
22
- <tr>
23
- <td>
24
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
25
- </td>
26
- <td>
27
- <input type="text" name="mattributes[]" autocomplete="off" required
28
- class="wf_validate_attr wf_mattributes wf_mattr"/>
29
- </td>
30
- <td>
31
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
32
- </td>
33
- <td>
34
- <select name="type[]" class="attr_type wfnoempty">
35
- <option value="attribute"><?php _e('Attribute', 'woo-feed'); ?></option>
36
- <option value="pattern"><?php _e('Pattern', 'woo-feed'); ?></option>
37
- </select>
38
- </td>
39
- <td>
40
- <select name="attributes[]" required="required"
41
- class="wf_validate_attr wf_attr wf_attributes">
42
- <?php echo $product->attributeDropdown(); ?>
43
- </select>
44
- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes"
45
- style=" display: none;"/>
46
- </td>
47
- <td>
48
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
49
- </td>
50
- <td>
51
- <select name="output_type[][]" class="outputType wfnoempty">
52
- <option value="1">Default</option>
53
- <option value="2">Strip Tags</option>
54
- <option value="3">UTF-8 Encode</option>
55
- <option value="4">htmlentities</option>
56
- <option value="5">Integer</option>
57
- <option value="6">Price</option>
58
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
59
- <option value="8">CDATA</option>
60
- </select>
61
- <i class="dashicons dashicons-editor-expand expandType"></i>
62
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
63
- </td>
64
- <td>
65
- <input type="text" name="limit[]" class="wf_ps"/>
66
- </td>
67
- <td>
68
- <i class="delRow dashicons dashicons-trash"></i>
69
- </td>
70
- </tr>
71
- </tbody>
72
- <tfoot>
73
- <tr>
74
- <td>
75
- <button type="button" class="button-small button-primary" id="wf_newRow">
76
- <?php _e('Add New Row', 'woo-feed'); ?>
77
- </button>
78
- </td>
79
- <td colspan="8">
80
-
81
- </td>
82
- </tr>
83
- </tfoot>
84
- </table>
85
- <table class=" widefat fixed">
86
- <tr>
87
- <td align="left" class="">
88
- <div class="makeFeedResponse"></div>
89
- <div class="makeFeedComplete"></div>
90
- </td>
91
- <td align="right">
92
- <button type="submit" class="wfbtn"><?php _e( 'Save & Generate Feed', 'woo-feed' ); ?></button>
93
- </td>
94
- </tr>
95
- </table>
96
- </div>
97
- </li>
98
- <?php include plugin_dir_path(__FILE__) . "../woo-feed-ftp-sftp-template.php"; ?>
99
-
100
- </ul>
1
+ <?php
2
+ /**
3
+ * Custom Add Template
4
+ */
5
+ if ( ! defined( 'ABSPATH' ) ) {
6
+ die();
7
+ }
8
+ ?>
9
+ <table class="table tree widefat fixed sorted_table mtable" style="width: 100%;" id="table-1">
10
+ <thead>
11
+ <tr>
12
+ <th></th>
13
+ <th><?php echo esc_html( ucfirst( $provider ) ); ?> <?php _e( 'Attributes', 'woo-feed' ); ?></th>
14
+ <th><?php _e( 'Prefix', 'woo-feed' ); ?></th>
15
+ <th><?php _e( 'Type', 'woo-feed' ); ?></th>
16
+ <th><?php _e( 'Value', 'woo-feed' ); ?></th>
17
+ <th><?php _e( 'Suffix', 'woo-feed' ); ?></th>
18
+ <th><?php _e( 'Output Type', 'woo-feed' ); ?></th>
19
+ <th><?php _e( 'Command', 'woo-feed' ); ?></th>
20
+ <th></th>
21
+ </tr>
22
+ </thead>
23
+ <tbody>
24
+ <tr>
25
+ <td>
26
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
27
+ </td>
28
+ <td>
29
+ <input type="text" name="mattributes[]" autocomplete="off" required class="wf_validate_attr wf_mattributes">
30
+ </td>
31
+ <td>
32
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
33
+ </td>
34
+ <td>
35
+ <select name="type[]" class="attr_type wfnoempty">
36
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
37
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
38
+ </select>
39
+ </td>
40
+ <td>
41
+ <select name="attributes[]" required="required" class="wf_validate_attr wf_attr wf_attributes">
42
+ <?php
43
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
44
+ echo $wooFeedProduct->attributeDropdown();
45
+ ?>
46
+ </select>
47
+ <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;">
48
+ </td>
49
+ <td>
50
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
51
+ </td>
52
+ <td>
53
+ <select name="output_type[][]" class="outputType wfnoempty">
54
+ <?php
55
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
56
+ echo $wooFeedDropDown->outputTypes();
57
+ ?>
58
+ </select>
59
+ <i class="dashicons dashicons-editor-expand expandType"></i>
60
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
61
+ </td>
62
+ <td>
63
+ <input type="text" name="limit[]" class="wf_ps">
64
+ </td>
65
+ <td>
66
+ <i class="delRow dashicons dashicons-trash"></i>
67
+ </td>
68
+ </tr>
69
+ </tbody>
70
+ <tfoot>
71
+ <tr>
72
+ <td>
73
+ <button type="button" class="button-small button-primary" id="wf_newRow"><?php _e( 'Add New Row', 'woo-feed' ); ?></button>
74
+ </td>
75
+ <td colspan="8"></td>
76
+ </tr>
77
+ </tfoot>
78
+ </table>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/partials/templates/facebook_add-feed.php CHANGED
@@ -1,705 +1,709 @@
1
- <ul class="wf_tabs">
2
- <li>
3
- <input type="radio" name="wf_tabs" id="tab1" checked/>
4
- <label class="wf-tab-name" for="tab1"><?php _e('Feed Config', 'woo-feed'); ?></label>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
- <div id="wf-tab-content1" class="wf-tab-content">
7
- <table class="table tree widefat fixed sorted_table mtable" width="100%" id="table-1">
8
- <thead>
9
- <tr>
10
- <th></th>
11
- <th><?php echo ucfirst($provider); ?> <?php _e('Attributes', 'woo-feed'); ?></th>
12
- <th><?php _e('Prefix', 'woo-feed'); ?></th>
13
- <th><?php _e('Type', 'woo-feed'); ?></th>
14
- <th><?php _e('Value', 'woo-feed'); ?></th>
15
- <th><?php _e('Suffix', 'woo-feed'); ?></th>
16
- <th><?php _e('Output Type', 'woo-feed'); ?></th>
17
- <th><?php _e('Output Limit', 'woo-feed'); ?></th>
18
- <th></th>
19
- </tr>
20
- </thead>
21
- <tbody>
22
- <tr>
23
- <td>
24
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
25
- </td>
26
- <td>
27
- <select name="mattributes[]" required class="wf_mattributes">
28
- <?php echo $dropDown->googleAttributesDropdown('id'); ?>
29
- </select>
30
- </td>
31
- <td>
32
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
33
- </td>
34
- <td>
35
- <select name="type[]" class="attr_type wfnoempty">
36
- <option value="attribute"><?php _e('Attribute', 'woo-feed'); ?></option>
37
- <option value="pattern"><?php _e('Pattern', 'woo-feed'); ?></option>
38
- </select>
39
- </td>
40
- <td>
41
- <select name="attributes[]" class="wf_attr wf_attributes">
42
- <?php echo $product->attributeDropdown('id'); ?>
43
- </select>
44
- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes"
45
- style=" display: none;"/>
46
- </td>
47
- <td>
48
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
49
- </td>
50
- <td>
51
- <select name="output_type[][]" class="outputType wfnoempty">
52
- <option value="1">Default</option>
53
- <option value="2">Strip Tags</option>
54
- <option value="3">UTF-8 Encode</option>
55
- <option value="4">htmlentities</option>
56
- <option value="5">Integer</option>
57
- <option value="6">Price</option>
58
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
59
- <option value="8">CDATA</option>
60
- </select>
61
- <i class="dashicons dashicons-editor-expand expandType"></i>
62
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
63
- </td>
64
- <td>
65
- <input type="text" name="limit[]" class="wf_ps"/>
66
- </td>
67
- <td>
68
- <i class="delRow dashicons dashicons-trash"></i>
69
- </td>
70
- </tr>
71
- <tr>
72
- <td>
73
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
74
- </td>
75
- <td>
76
- <select name="mattributes[]" required class="wf_mattributes">
77
- <?php echo $dropDown->googleAttributesDropdown('title'); ?>
78
- </select>
79
- </td>
80
- <td>
81
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
82
- </td>
83
- <td>
84
- <select name="type[]" class="attr_type wfnoempty">
85
- <option value="attribute"><?php _e('Attribute', 'woo-feed'); ?></option>
86
- <option value="pattern"><?php _e('Pattern', 'woo-feed'); ?></option>
87
- </select>
88
- </td>
89
- <td>
90
- <select name="attributes[]" class="wf_attr wf_attributes">
91
- <?php echo $product->attributeDropdown('title'); ?>
92
- </select>
93
- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes"
94
- style=" display: none;"/>
95
- </td>
96
- <td>
97
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
98
- </td>
99
- <td>
100
- <select name="output_type[][]" class="outputType wfnoempty">
101
- <option value="1">Default</option>
102
- <option value="2">Strip Tags</option>
103
- <option value="3">UTF-8 Encode</option>
104
- <option value="4">htmlentities</option>
105
- <option value="5">Integer</option>
106
- <option value="6">Price</option>
107
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
108
- <option value="8">CDATA</option>
109
- </select>
110
- <i class="dashicons dashicons-editor-expand expandType"></i>
111
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
112
- </td>
113
- <td>
114
- <input type="text" name="limit[]" class="wf_ps"/>
115
- </td>
116
- <td>
117
- <i class="delRow dashicons dashicons-trash"></i>
118
- </td>
119
- </tr>
120
- <tr>
121
- <td>
122
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
123
- </td>
124
- <td>
125
- <select name="mattributes[]" required class="wf_mattributes">
126
- <?php echo $dropDown->googleAttributesDropdown('description'); ?>
127
- </select>
128
- </td>
129
- <td>
130
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
131
- </td>
132
- <td>
133
- <select name="type[]" class="attr_type wfnoempty">
134
- <option value="attribute"><?php _e('Attribute', 'woo-feed'); ?></option>
135
- <option value="pattern"><?php _e('Pattern', 'woo-feed'); ?></option>
136
- </select>
137
- </td>
138
- <td>
139
- <select name="attributes[]" class="wf_attr wf_attributes">
140
- <?php echo $product->attributeDropdown('description'); ?>
141
- </select>
142
- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes"
143
- style=" display: none;"/>
144
- </td>
145
- <td>
146
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
147
- </td>
148
- <td>
149
- <select name="output_type[][]" class="outputType wfnoempty">
150
- <option value="1">Default</option>
151
- <option selected value="2">Strip Tags</option>
152
- <option value="3">UTF-8 Encode</option>
153
- <option value="4">htmlentities</option>
154
- <option value="5">Integer</option>
155
- <option value="6">Price</option>
156
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
157
- <option value="8">CDATA</option>
158
- </select>
159
- <i class="dashicons dashicons-editor-expand expandType"></i>
160
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
161
- </td>
162
- <td>
163
- <input type="text" name="limit[]" class="wf_ps" value="5000"/>
164
- </td>
165
- <td>
166
- <i class="delRow dashicons dashicons-trash"></i>
167
- </td>
168
- </tr>
169
- <tr>
170
- <td>
171
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
172
- </td>
173
- <td>
174
- <select name="mattributes[]" required class="wf_mattributes">
175
- <?php echo $dropDown->googleAttributesDropdown('item_group_id'); ?>
176
- </select>
177
- </td>
178
- <td>
179
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
180
- </td>
181
- <td>
182
- <select name="type[]" class="attr_type wfnoempty">
183
- <option value="attribute"><?php _e('Attribute', 'woo-feed'); ?></option>
184
- <option value="pattern"><?php _e('Pattern', 'woo-feed'); ?></option>
185
- </select>
186
- </td>
187
- <td>
188
- <select name="attributes[]" class="wf_attr wf_attributes">
189
- <?php echo $product->attributeDropdown('item_group_id'); ?>
190
- </select>
191
- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes"
192
- style=" display: none;"/>
193
- </td>
194
- <td>
195
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
196
- </td>
197
- <td>
198
- <select name="output_type[][]" class="outputType wfnoempty">
199
- <option value="1">Default</option>
200
- <option value="2">Strip Tags</option>
201
- <option value="3">UTF-8 Encode</option>
202
- <option value="4">htmlentities</option>
203
- <option value="5">Integer</option>
204
- <option value="6">Price</option>
205
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
206
- <option value="8">CDATA</option>
207
- </select>
208
- <i class="dashicons dashicons-editor-expand expandType"></i>
209
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
210
- </td>
211
- <td>
212
- <input type="text" name="limit[]" class="wf_ps"/>
213
- </td>
214
- <td>
215
- <i class="delRow dashicons dashicons-trash"></i>
216
- </td>
217
- </tr>
218
- <tr>
219
- <td>
220
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
221
- </td>
222
- <td>
223
- <select name="mattributes[]" required class="wf_mattributes">
224
- <?php echo $dropDown->googleAttributesDropdown('link'); ?>
225
- </select>
226
- </td>
227
- <td>
228
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
229
- </td>
230
- <td>
231
- <select name="type[]" class="attr_type wfnoempty">
232
- <option value="attribute"><?php _e('Attribute', 'woo-feed'); ?></option>
233
- <option value="pattern"><?php _e('Pattern', 'woo-feed'); ?></option>
234
- </select>
235
- </td>
236
- <td>
237
- <select name="attributes[]" class="wf_attr wf_attributes">
238
- <?php echo $product->attributeDropdown('link'); ?>
239
- </select>
240
- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes"
241
- style=" display: none;"/>
242
- </td>
243
- <td>
244
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
245
- </td>
246
- <td>
247
- <select name="output_type[][]" class="outputType wfnoempty">
248
- <option value="1">Default</option>
249
- <option value="2">Strip Tags</option>
250
- <option value="3">UTF-8 Encode</option>
251
- <option value="4">htmlentities</option>
252
- <option value="5">Integer</option>
253
- <option value="6">Price</option>
254
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
255
- <option value="8">CDATA</option>
256
- </select>
257
- <i class="dashicons dashicons-editor-expand expandType"></i>
258
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
259
- </td>
260
- <td>
261
- <input type="text" name="limit[]" class="wf_ps"/>
262
- </td>
263
- <td>
264
- <i class="delRow dashicons dashicons-trash"></i>
265
- </td>
266
- </tr>
267
- <tr>
268
- <td>
269
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
270
- </td>
271
- <td>
272
- <select name="mattributes[]" required class="wf_mattributes">
273
- <?php echo $dropDown->googleAttributesDropdown('product_type'); ?>
274
- </select>
275
- </td>
276
- <td>
277
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
278
- </td>
279
- <td>
280
- <select name="type[]" class="attr_type wfnoempty">
281
- <option value="attribute"><?php _e('Attribute', 'woo-feed'); ?></option>
282
- <option value="pattern"><?php _e('Pattern', 'woo-feed'); ?></option>
283
- </select>
284
- </td>
285
- <td>
286
- <select name="attributes[]" class="wf_attr wf_attributes">
287
- <?php echo $product->attributeDropdown('product_type'); ?>
288
- </select>
289
- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes"
290
- style=" display: none;"/>
291
- </td>
292
- <td>
293
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
294
- </td>
295
- <td>
296
- <select name="output_type[][]" class="outputType wfnoempty">
297
- <option value="1">Default</option>
298
- <option value="2">Strip Tags</option>
299
- <option value="3">UTF-8 Encode</option>
300
- <option value="4">htmlentities</option>
301
- <option value="5">Integer</option>
302
- <option value="6">Price</option>
303
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
304
- <option value="8">CDATA</option>
305
- </select>
306
- <i class="dashicons dashicons-editor-expand expandType"></i>
307
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
308
- </td>
309
- <td>
310
- <input type="text" name="limit[]" class="wf_ps"/>
311
- </td>
312
- <td>
313
- <i class="delRow dashicons dashicons-trash"></i>
314
- </td>
315
- </tr>
316
- <tr>
317
- <td>
318
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
319
- </td>
320
- <td>
321
- <select name="mattributes[]" required class="wf_mattributes">
322
- <?php echo $dropDown->googleAttributesDropdown('current_category'); ?>
323
- </select>
324
- </td>
325
- <td>
326
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
327
- </td>
328
- <td>
329
- <select name="type[]" class="attr_type wfnoempty">
330
- <option value="attribute"><?php _e('Attribute', 'woo-feed'); ?></option>
331
- <option value="pattern" selected><?php _e('Pattern', 'woo-feed'); ?></option>
332
- </select>
333
- </td>
334
- <td>
335
- <select name="attributes[]" style=" display: none;" class="wf_attr wf_attributes">
336
- <?php echo $product->attributeDropdown(); ?>
337
- </select>
338
- <span class="wf_default wf_attributes">
339
- <select name="default[]" class="selectize">
340
- <?php echo $dropDown->googleTaxonomy(); ?>
341
- </select>
342
- </span>
343
- <span style="font-size: x-small;"><a href="http://webappick.helpscoutdocs.com/article/19-how-to-map-store-category-with-merchant-category" target="_blank">Learn More..</a></span>
344
- </td>
345
- <td>
346
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
347
- </td>
348
- <td>
349
- <select name="output_type[][]" class="outputType wfnoempty">
350
- <option value="1">Default</option>
351
- <option value="2">Strip Tags</option>
352
- <option value="3">UTF-8 Encode</option>
353
- <option value="4">htmlentities</option>
354
- <option value="5">Integer</option>
355
- <option value="6">Price</option>
356
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
357
- <option value="8">CDATA</option>
358
- </select>
359
- <i class="dashicons dashicons-editor-expand expandType"></i>
360
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
361
- </td>
362
- <td>
363
- <input type="text" name="limit[]" class="wf_ps"/>
364
- </td>
365
- <td>
366
- <i class="delRow dashicons dashicons-trash"></i>
367
- </td>
368
- </tr>
369
- <tr>
370
- <td>
371
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
372
- </td>
373
- <td>
374
- <select name="mattributes[]" required class="wf_mattributes">
375
- <?php echo $dropDown->googleAttributesDropdown('image'); ?>
376
- </select>
377
- </td>
378
- <td>
379
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
380
- </td>
381
- <td>
382
- <select name="type[]" class="attr_type wfnoempty">
383
- <option value="attribute"><?php _e('Attribute', 'woo-feed'); ?></option>
384
- <option value="pattern"><?php _e('Pattern', 'woo-feed'); ?></option>
385
- </select>
386
- </td>
387
- <td>
388
- <select name="attributes[]" class="wf_attr wf_attributes">
389
- <?php echo $product->attributeDropdown('image'); ?>
390
- </select>
391
- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes"
392
- style=" display: none;"/>
393
- </td>
394
- <td>
395
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
396
- </td>
397
- <td>
398
- <select name="output_type[][]" class="outputType wfnoempty">
399
- <option value="1">Default</option>
400
- <option value="2">Strip Tags</option>
401
- <option value="3">UTF-8 Encode</option>
402
- <option value="4">htmlentities</option>
403
- <option value="5">Integer</option>
404
- <option value="6">Price</option>
405
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
406
- <option value="8">CDATA</option>
407
- </select>
408
- <i class="dashicons dashicons-editor-expand expandType"></i>
409
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
410
- </td>
411
- <td>
412
- <input type="text" name="limit[]" class="wf_ps"/>
413
- </td>
414
- <td>
415
- <i class="delRow dashicons dashicons-trash"></i>
416
- </td>
417
- </tr>
418
- <tr>
419
- <td>
420
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
421
- </td>
422
- <td>
423
- <select name="mattributes[]" required class="wf_mattributes">
424
- <?php echo $dropDown->googleAttributesDropdown('condition'); ?>
425
- </select>
426
- </td>
427
- <td>
428
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
429
- </td>
430
- <td>
431
- <select name="type[]" class="attr_type wfnoempty">
432
- <option value="attribute"><?php _e('Attribute', 'woo-feed'); ?></option>
433
- <option value="pattern"><?php _e('Pattern', 'woo-feed'); ?></option>
434
- </select>
435
- </td>
436
- <td>
437
- <select name="attributes[]" class="wf_attr wf_attributes">
438
- <?php echo $product->attributeDropdown('condition'); ?>
439
- </select>
440
- <input type="text" style=" display: none;" name="default[]" autocomplete="off" class="wf_default wf_attributes"
441
- />
442
- </td>
443
- <td>
444
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
445
- </td>
446
- <td>
447
- <select name="output_type[][]" class="outputType wfnoempty">
448
- <option value="1">Default</option>
449
- <option value="2">Strip Tags</option>
450
- <option value="3">UTF-8 Encode</option>
451
- <option value="4">htmlentities</option>
452
- <option value="5">Integer</option>
453
- <option value="6">Price</option>
454
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
455
- <option value="8">CDATA</option>
456
- </select>
457
- <i class="dashicons dashicons-editor-expand expandType"></i>
458
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
459
- </td>
460
- <td>
461
- <input type="text" name="limit[]" class="wf_ps"/>
462
- </td>
463
- <td>
464
- <i class="delRow dashicons dashicons-trash"></i>
465
- </td>
466
- </tr>
467
- <tr>
468
- <td>
469
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
470
- </td>
471
- <td>
472
- <select name="mattributes[]" required class="wf_mattributes">
473
- <?php echo $dropDown->googleAttributesDropdown('availability'); ?>
474
- </select>
475
- </td>
476
- <td>
477
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
478
- </td>
479
- <td>
480
- <select name="type[]" class="attr_type wfnoempty">
481
- <option value="attribute"><?php _e('Attribute', 'woo-feed'); ?></option>
482
- <option value="pattern"><?php _e('Pattern', 'woo-feed'); ?></option>
483
- </select>
484
- </td>
485
- <td>
486
- <select name="attributes[]" class="wf_attr wf_attributes">
487
- <?php echo $product->attributeDropdown('availability'); ?>
488
- </select>
489
- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes"
490
- style=" display: none;"/>
491
- </td>
492
- <td>
493
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
494
- </td>
495
- <td>
496
- <select name="output_type[][]" class="outputType wfnoempty">
497
- <option value="1">Default</option>
498
- <option value="2">Strip Tags</option>
499
- <option value="3">UTF-8 Encode</option>
500
- <option value="4">htmlentities</option>
501
- <option value="5">Integer</option>
502
- <option value="6">Price</option>
503
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
504
- <option value="8">CDATA</option>
505
- </select>
506
- <i class="dashicons dashicons-editor-expand expandType"></i>
507
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
508
- </td>
509
- <td>
510
- <input type="text" name="limit[]" class="wf_ps"/>
511
- </td>
512
- <td>
513
- <i class="delRow dashicons dashicons-trash"></i>
514
- </td>
515
- </tr>
516
- <tr>
517
- <td>
518
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
519
- </td>
520
- <td>
521
- <select name="mattributes[]" required class="wf_mattributes">
522
- <?php echo $dropDown->googleAttributesDropdown('price'); ?>
523
- </select>
524
- </td>
525
- <td>
526
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
527
- </td>
528
- <td>
529
- <select name="type[]" class="attr_type wfnoempty">
530
- <option value="attribute"><?php _e('Attribute', 'woo-feed'); ?></option>
531
- <option value="pattern"><?php _e('Pattern', 'woo-feed'); ?></option>
532
- </select>
533
- </td>
534
- <td>
535
- <select name="attributes[]" class="wf_attr wf_attributes">
536
- <?php echo $product->attributeDropdown('price'); ?>
537
- </select>
538
- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes"
539
- style=" display: none;"/>
540
- </td>
541
- <td>
542
- <input type="text" name="suffix[]" value="<?php echo get_woocommerce_currency();?>" autocomplete="off" class="wf_ps"/>
543
- </td>
544
- <td>
545
- <select name="output_type[][]" class="outputType wfnoempty">
546
- <option value="1">Default</option>
547
- <option value="2">Strip Tags</option>
548
- <option value="3">UTF-8 Encode</option>
549
- <option value="4">htmlentities</option>
550
- <option value="5">Integer</option>
551
- <option selected value="6">Price</option>
552
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
553
- <option value="8">CDATA</option>
554
- </select>
555
- <i class="dashicons dashicons-editor-expand expandType"></i>
556
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
557
- </td>
558
- <td>
559
- <input type="text" name="limit[]" class="wf_ps"/>
560
- </td>
561
- <td>
562
- <i class="delRow dashicons dashicons-trash"></i>
563
- </td>
564
- </tr>
565
- <tr>
566
- <td>
567
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
568
- </td>
569
- <td>
570
- <select name="mattributes[]" required class="wf_mattributes">
571
- <?php echo $dropDown->googleAttributesDropdown('sku'); ?>
572
- </select>
573
- </td>
574
- <td>
575
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
576
- </td>
577
- <td>
578
- <select name="type[]" class="attr_type wfnoempty">
579
- <option value="attribute"><?php _e('Attribute', 'woo-feed'); ?></option>
580
- <option value="pattern"><?php _e('Pattern', 'woo-feed'); ?></option>
581
- </select>
582
- </td>
583
- <td>
584
- <select name="attributes[]" class="wf_attr wf_attributes">
585
- <?php echo $product->attributeDropdown('sku'); ?>
586
- </select>
587
- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes"
588
- style=" display: none;"/>
589
- </td>
590
- <td>
591
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
592
- </td>
593
- <td>
594
- <select name="output_type[][]" class="outputType wfnoempty">
595
- <option value="1">Default</option>
596
- <option value="2">Strip Tags</option>
597
- <option value="3">UTF-8 Encode</option>
598
- <option value="4">htmlentities</option>
599
- <option value="5">Integer</option>
600
- <option value="6">Price</option>
601
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
602
- <option value="8">CDATA</option>
603
- </select>
604
- <i class="dashicons dashicons-editor-expand expandType"></i>
605
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
606
- </td>
607
- <td>
608
- <input type="text" name="limit[]" class="wf_ps"/>
609
- </td>
610
- <td>
611
- <i class="delRow dashicons dashicons-trash"></i>
612
- </td>
613
- </tr>
614
- <tr>
615
- <td>
616
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
617
- </td>
618
- <td>
619
- <select name="mattributes[]" required class="wf_mattributes">
620
- <?php echo $dropDown->googleAttributesDropdown('brand'); ?>
621
- </select>
622
- </td>
623
- <td>
624
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
625
- </td>
626
- <td>
627
- <select name="type[]" class="attr_type wfnoempty">
628
- <option value="attribute"><?php _e('Attribute', 'woo-feed'); ?></option>
629
- <option value="pattern" selected><?php _e('Pattern', 'woo-feed'); ?></option>
630
- </select>
631
- </td>
632
- <td>
633
- <select name="attributes[]" style=" display: none;" class="wf_attr wf_attributes">
634
- <?php echo $product->attributeDropdown(); ?>
635
- </select>
636
- <?php
637
- $url = site_url();
638
- $WABrand = "";
639
- // Remove all illegal characters from a url
640
- $url = filter_var($url, FILTER_SANITIZE_URL);
641
- // Validate url
642
- if ( filter_var($url, FILTER_VALIDATE_URL) !== false ) {
643
- $url = parse_url($url);
644
- if ( array_key_exists('host',$url) ) {
645
- $arr = explode('.',$url['host']);
646
- $WABrand = $arr[ count($arr) - 2 ];
647
- }
648
- }
649
-
650
- ?>
651
- <input type="text" name="default[]" value="<?php echo $WABrand; ?>" autocomplete="off" class="wf_default wf_attributes"/>
652
- </td>
653
- <td>
654
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
655
- </td>
656
- <td>
657
- <select name="output_type[][]" class="outputType wfnoempty">
658
- <option value="1">Default</option>
659
- <option value="2">Strip Tags</option>
660
- <option value="3">UTF-8 Encode</option>
661
- <option value="4">htmlentities</option>
662
- <option value="5">Integer</option>
663
- <option value="6">Price</option>
664
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
665
- <option value="8">CDATA</option>
666
- </select>
667
- <i class="dashicons dashicons-editor-expand expandType"></i>
668
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
669
- </td>
670
- <td>
671
- <input type="text" name="limit[]" class="wf_ps"/>
672
- </td>
673
- <td>
674
- <i class="delRow dashicons dashicons-trash"></i>
675
- </td>
676
- </tr>
677
- </tbody>
678
- <tfoot>
679
- <tr>
680
- <td>
681
- <button type="button" class="button-small button-primary" id="wf_newRow">
682
- <?php _e('Add New Row', 'woo-feed'); ?>
683
- </button>
684
- </td>
685
- <td colspan="8">
686
-
687
- </td>
688
- </tr>
689
- </tfoot>
690
- </table>
691
- <table class=" widefat fixed">
692
- <tr>
693
- <td align="left" class="">
694
- <div class="makeFeedResponse"></div>
695
- <div class="makeFeedComplete"></div>
696
- </td>
697
- <td align="right">
698
- <button type="submit" class="wfbtn"><?php _e( 'Save & Generate Feed', 'woo-feed' ); ?></button>
699
- </td>
700
- </tr>
701
  </table>
702
- </div>
703
- </li>
704
- <?php include plugin_dir_path(__FILE__) . "../woo-feed-ftp-sftp-template.php"; ?>
705
- </ul>
1
+ <?php
2
+ /**
3
+ * FaceBook Template
4
+ */
5
+ if ( ! defined( 'ABSPATH' ) ) {
6
+ die();
7
+ }
8
+ global $provider;
9
+ ?>
10
+ <table class="table tree widefat fixed sorted_table mtable" style="width: 100%;" id="table-1">
11
+ <thead>
12
+ <tr>
13
+ <th></th>
14
+ <th><?php echo esc_html( ucfirst( $provider ) ); ?> <?php _e( 'Attributes', 'woo-feed' ); ?></th>
15
+ <th><?php _e( 'Prefix', 'woo-feed' ); ?></th>
16
+ <th><?php _e( 'Type', 'woo-feed' ); ?></th>
17
+ <th><?php _e( 'Value', 'woo-feed' ); ?></th>
18
+ <th><?php _e( 'Suffix', 'woo-feed' ); ?></th>
19
+ <th><?php _e( 'Output Type', 'woo-feed' ); ?></th>
20
+ <th><?php _e( 'Command', 'woo-feed' ); ?></th>
21
+ <th></th>
22
+ </tr>
23
+ </thead>
24
+ <tbody>
25
+ <tr>
26
+ <td>
27
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
28
+ </td>
29
+ <td>
30
+ <select name="mattributes[]" required class="wf_mattributes">
31
+ <?php
32
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
33
+ echo $wooFeedDropDown->googleAttributesDropdown( 'id' );
34
+ ?>
35
+ </select>
36
+ </td>
37
+ <td>
38
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
39
+ </td>
40
+ <td>
41
+ <select name="type[]" class="attr_type wfnoempty">
42
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
43
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
44
+ </select>
45
+ </td>
46
+ <td>
47
+ <select name="attributes[]" class="wf_attr wf_attributes">
48
+ <?php
49
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
50
+ echo $wooFeedProduct->attributeDropdown( 'id' );
51
+ ?>
52
+ </select>
53
+ <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;">
54
+ </td>
55
+ <td>
56
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
57
+ </td>
58
+ <td>
59
+ <select name="output_type[][]" class="outputType wfnoempty">
60
+ <?php
61
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
62
+ echo $wooFeedDropDown->outputTypes();
63
+ ?>
64
+ </select>
65
+ <i class="dashicons dashicons-editor-expand expandType"></i>
66
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
67
+ </td>
68
+ <td>
69
+ <input type="text" name="limit[]" class="wf_ps">
70
+ </td>
71
+ <td>
72
+ <i class="delRow dashicons dashicons-trash"></i>
73
+ </td>
74
+ </tr>
75
+ <tr>
76
+ <td>
77
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
78
+ </td>
79
+ <td>
80
+ <select name="mattributes[]" required class="wf_mattributes">
81
+ <?php
82
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
83
+ echo $wooFeedDropDown->googleAttributesDropdown( 'title' );
84
+ ?>
85
+ </select>
86
+ </td>
87
+ <td>
88
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
89
+ </td>
90
+ <td>
91
+ <select name="type[]" class="attr_type wfnoempty">
92
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
93
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
94
+ </select>
95
+ </td>
96
+ <td>
97
+ <select name="attributes[]" class="wf_attr wf_attributes">
98
+ <?php
99
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
100
+ echo $wooFeedProduct->attributeDropdown( 'title' );
101
+ ?>
102
+ </select>
103
+ <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;">
104
+ </td>
105
+ <td>
106
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
107
+ </td>
108
+ <td>
109
+ <select name="output_type[][]" class="outputType wfnoempty">
110
+ <?php
111
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
112
+ echo $wooFeedDropDown->outputTypes();
113
+ ?>
114
+ </select>
115
+ <i class="dashicons dashicons-editor-expand expandType"></i>
116
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
117
+ </td>
118
+ <td>
119
+ <input type="text" name="limit[]" class="wf_ps">
120
+ </td>
121
+ <td>
122
+ <i class="delRow dashicons dashicons-trash"></i>
123
+ </td>
124
+ </tr>
125
+ <tr>
126
+ <td>
127
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
128
+ </td>
129
+ <td>
130
+ <select name="mattributes[]" required class="wf_mattributes">
131
+ <?php
132
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
133
+ echo $wooFeedDropDown->googleAttributesDropdown( 'description' );
134
+ ?>
135
+ </select>
136
+ </td>
137
+ <td>
138
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
139
+ </td>
140
+ <td>
141
+ <select name="type[]" class="attr_type wfnoempty">
142
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
143
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
144
+ </select>
145
+ </td>
146
+ <td>
147
+ <select name="attributes[]" class="wf_attr wf_attributes">
148
+ <?php
149
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
150
+ echo $wooFeedProduct->attributeDropdown( 'description' );
151
+ ?>
152
+ </select>
153
+ <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;">
154
+ </td>
155
+ <td>
156
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
157
+ </td>
158
+ <td>
159
+ <select name="output_type[][]" class="outputType wfnoempty">
160
+ <?php
161
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
162
+ echo $wooFeedDropDown->outputTypes();
163
+ ?>
164
+ </select>
165
+ <i class="dashicons dashicons-editor-expand expandType"></i>
166
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
167
+ </td>
168
+ <td>
169
+ <input type="text" name="limit[]" class="wf_ps">
170
+ </td>
171
+ <td>
172
+ <i class="delRow dashicons dashicons-trash"></i>
173
+ </td>
174
+ </tr>
175
+ <tr>
176
+ <td>
177
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
178
+ </td>
179
+ <td>
180
+ <select name="mattributes[]" required class="wf_mattributes">
181
+ <?php
182
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
183
+ echo $wooFeedDropDown->googleAttributesDropdown( 'item_group_id' );
184
+ ?>
185
+ </select>
186
+ </td>
187
+ <td>
188
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
189
+ </td>
190
+ <td>
191
+ <select name="type[]" class="attr_type wfnoempty">
192
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
193
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
194
+ </select>
195
+ </td>
196
+ <td>
197
+ <select name="attributes[]" class="wf_attr wf_attributes">
198
+ <?php
199
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
200
+ echo $wooFeedProduct->attributeDropdown( 'item_group_id' );
201
+ ?>
202
+ </select>
203
+ <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;">
204
+ </td>
205
+ <td>
206
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
207
+ </td>
208
+ <td>
209
+ <select name="output_type[][]" class="outputType wfnoempty">
210
+ <?php
211
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
212
+ echo $wooFeedDropDown->outputTypes();
213
+ ?>
214
+ </select>
215
+ <i class="dashicons dashicons-editor-expand expandType"></i>
216
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
217
+ </td>
218
+ <td>
219
+ <input type="text" name="limit[]" class="wf_ps">
220
+ </td>
221
+ <td>
222
+ <i class="delRow dashicons dashicons-trash"></i>
223
+ </td>
224
+ </tr>
225
+ <tr>
226
+ <td>
227
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
228
+ </td>
229
+ <td>
230
+ <select name="mattributes[]" required class="wf_mattributes">
231
+ <?php
232
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
233
+ echo $wooFeedDropDown->googleAttributesDropdown( 'link' );
234
+ ?>
235
+ </select>
236
+ </td>
237
+ <td>
238
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
239
+ </td>
240
+ <td>
241
+ <select name="type[]" class="attr_type wfnoempty">
242
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
243
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
244
+ </select>
245
+ </td>
246
+ <td>
247
+ <select name="attributes[]" class="wf_attr wf_attributes">
248
+ <?php
249
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
250
+ echo $wooFeedProduct->attributeDropdown( 'link' );
251
+ ?>
252
+ </select>
253
+ <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;">
254
+ </td>
255
+ <td>
256
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
257
+ </td>
258
+ <td>
259
+ <select name="output_type[][]" class="outputType wfnoempty">
260
+ <?php
261
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
262
+ echo $wooFeedDropDown->outputTypes();
263
+ ?>
264
+ </select>
265
+ <i class="dashicons dashicons-editor-expand expandType"></i>
266
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
267
+ </td>
268
+ <td>
269
+ <input type="text" name="limit[]" class="wf_ps">
270
+ </td>
271
+ <td>
272
+ <i class="delRow dashicons dashicons-trash"></i>
273
+ </td>
274
+ </tr>
275
+ <tr>
276
+ <td>
277
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
278
+ </td>
279
+ <td>
280
+ <select name="mattributes[]" required class="wf_mattributes">
281
+ <?php
282
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
283
+ echo $wooFeedDropDown->googleAttributesDropdown( 'product_type' );
284
+ ?>
285
+ </select>
286
+ </td>
287
+ <td>
288
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
289
+ </td>
290
+ <td>
291
+ <select name="type[]" class="attr_type wfnoempty">
292
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
293
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
294
+ </select>
295
+ </td>
296
+ <td>
297
+ <select name="attributes[]" class="wf_attr wf_attributes">
298
+ <?php
299
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
300
+ echo $wooFeedProduct->attributeDropdown( 'product_type' );
301
+ ?>
302
+ </select>
303
+ <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;">
304
+ </td>
305
+ <td>
306
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
307
+ </td>
308
+ <td>
309
+ <select name="output_type[][]" class="outputType wfnoempty">
310
+ <?php
311
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
312
+ echo $wooFeedDropDown->outputTypes();
313
+ ?>
314
+ </select>
315
+ <i class="dashicons dashicons-editor-expand expandType"></i>
316
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
317
+ </td>
318
+ <td>
319
+ <input type="text" name="limit[]" class="wf_ps">
320
+ </td>
321
+ <td>
322
+ <i class="delRow dashicons dashicons-trash"></i>
323
+ </td>
324
+ </tr>
325
+ <tr>
326
+ <td>
327
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
328
+ </td>
329
+ <td>
330
+ <select name="mattributes[]" required class="wf_mattributes">
331
+ <?php
332
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
333
+ echo $wooFeedDropDown->googleAttributesDropdown( 'current_category' );
334
+ ?>
335
+ </select>
336
+ </td>
337
+ <td>
338
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
339
+ </td>
340
+ <td>
341
+ <select name="type[]" class="attr_type wfnoempty">
342
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
343
+ <option value="pattern" selected><?php _e( 'Pattern', 'woo-feed' ); ?></option>
344
+ </select>
345
+ </td>
346
+ <td>
347
+ <select name="attributes[]" style=" display: none;" class="wf_attr wf_attributes">
348
+ <?php
349
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
350
+ echo $wooFeedProduct->attributeDropdown();
351
+ ?>
352
+ </select>
353
+ <span class="wf_default wf_attributes">
354
+ <select name="default[]" class="selectize">
355
+ <?php
356
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
357
+ echo $wooFeedDropDown->googleTaxonomy();
358
+ ?>
359
+ </select>
360
+ </span>
361
+ <span style="font-size:x-small;"><a style="color: red" href="http://webappick.helpscoutdocs.com/article/19-how-to-map-store-category-with-merchant-category" target="_blank">Learn More..</a></span>
362
+ </td>
363
+ <td>
364
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
365
+ </td>
366
+ <td>
367
+ <select name="output_type[][]" class="outputType wfnoempty">
368
+ <?php
369
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
370
+ echo $wooFeedDropDown->outputTypes();
371
+ ?>
372
+ </select>
373
+ <i class="dashicons dashicons-editor-expand expandType"></i>
374
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
375
+ </td>
376
+ <td>
377
+ <input type="text" name="limit[]" class="wf_ps">
378
+ </td>
379
+ <td>
380
+ <i class="delRow dashicons dashicons-trash"></i>
381
+ </td>
382
+ </tr>
383
+ <tr>
384
+ <td>
385
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
386
+ </td>
387
+ <td>
388
+ <select name="mattributes[]" required class="wf_mattributes">
389
+ <?php
390
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
391
+ echo $wooFeedDropDown->googleAttributesDropdown( 'image' );
392
+ ?>
393
+ </select>
394
+ </td>
395
+ <td>
396
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
397
+ </td>
398
+ <td>
399
+ <select name="type[]" class="attr_type wfnoempty">
400
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
401
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
402
+ </select>
403
+ </td>
404
+ <td>
405
+ <select name="attributes[]" class="wf_attr wf_attributes">
406
+ <?php
407
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
408
+ echo $wooFeedProduct->attributeDropdown( 'image' );
409
+ ?>
410
+ </select>
411
+ <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;">
412
+ </td>
413
+ <td>
414
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
415
+ </td>
416
+ <td>
417
+ <select name="output_type[][]" class="outputType wfnoempty">
418
+ <?php
419
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
420
+ echo $wooFeedDropDown->outputTypes();
421
+ ?>
422
+ </select>
423
+ <i class="dashicons dashicons-editor-expand expandType"></i>
424
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
425
+ </td>
426
+ <td>
427
+ <input type="text" name="limit[]" class="wf_ps">
428
+ </td>
429
+ <td>
430
+ <i class="delRow dashicons dashicons-trash"></i>
431
+ </td>
432
+ </tr>
433
+ <tr>
434
+ <td>
435
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
436
+ </td>
437
+ <td>
438
+ <select name="mattributes[]" required class="wf_mattributes">
439
+ <?php
440
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
441
+ echo $wooFeedDropDown->googleAttributesDropdown( 'condition' );
442
+ ?>
443
+ </select>
444
+ </td>
445
+ <td>
446
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
447
+ </td>
448
+ <td>
449
+ <select name="type[]" class="attr_type wfnoempty">
450
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
451
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
452
+ </select>
453
+ </td>
454
+ <td>
455
+ <select name="attributes[]" class="wf_attr wf_attributes">
456
+ <?php
457
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
458
+ echo $wooFeedProduct->attributeDropdown( 'condition' );
459
+ ?>
460
+ </select>
461
+ <input type="text" style=" display: none;" name="default[]" autocomplete="off" class="wf_default wf_attributes"
462
+ />
463
+ </td>
464
+ <td>
465
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
466
+ </td>
467
+ <td>
468
+ <select name="output_type[][]" class="outputType wfnoempty">
469
+ <?php
470
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
471
+ echo $wooFeedDropDown->outputTypes();
472
+ ?>
473
+ </select>
474
+ <i class="dashicons dashicons-editor-expand expandType"></i>
475
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
476
+ </td>
477
+ <td>
478
+ <input type="text" name="limit[]" class="wf_ps">
479
+ </td>
480
+ <td>
481
+ <i class="delRow dashicons dashicons-trash"></i>
482
+ </td>
483
+ </tr>
484
+ <tr>
485
+ <td>
486
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
487
+ </td>
488
+ <td>
489
+ <select name="mattributes[]" required class="wf_mattributes">
490
+ <?php
491
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
492
+ echo $wooFeedDropDown->googleAttributesDropdown( 'availability' );
493
+ ?>
494
+ </select>
495
+ </td>
496
+ <td>
497
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
498
+ </td>
499
+ <td>
500
+ <select name="type[]" class="attr_type wfnoempty">
501
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
502
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
503
+ </select>
504
+ </td>
505
+ <td>
506
+ <select name="attributes[]" class="wf_attr wf_attributes">
507
+ <?php
508
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
509
+ echo $wooFeedProduct->attributeDropdown( 'availability' );
510
+ ?>
511
+ </select>
512
+ <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;">
513
+ </td>
514
+ <td>
515
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
516
+ </td>
517
+ <td>
518
+ <select name="output_type[][]" class="outputType wfnoempty">
519
+ <?php
520
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
521
+ echo $wooFeedDropDown->outputTypes();
522
+ ?>
523
+ </select>
524
+ <i class="dashicons dashicons-editor-expand expandType"></i>
525
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
526
+ </td>
527
+ <td>
528
+ <input type="text" name="limit[]" class="wf_ps">
529
+ </td>
530
+ <td>
531
+ <i class="delRow dashicons dashicons-trash"></i>
532
+ </td>
533
+ </tr>
534
+ <tr>
535
+ <td>
536
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
537
+ </td>
538
+ <td>
539
+ <select name="mattributes[]" required class="wf_mattributes">
540
+ <?php
541
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
542
+ echo $wooFeedDropDown->googleAttributesDropdown( 'price' );
543
+ ?>
544
+ </select>
545
+ </td>
546
+ <td>
547
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
548
+ </td>
549
+ <td>
550
+ <select name="type[]" class="attr_type wfnoempty">
551
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
552
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
553
+ </select>
554
+ </td>
555
+ <td>
556
+ <select name="attributes[]" class="wf_attr wf_attributes">
557
+ <?php
558
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
559
+ echo $wooFeedProduct->attributeDropdown( 'price' );
560
+ ?>
561
+ </select>
562
+ <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;">
563
+ </td>
564
+ <td>
565
+ <input type="text" name="suffix[]" value="<?php echo esc_attr( get_woocommerce_currency() ); ?>" autocomplete="off" class="wf_ps">
566
+ </td>
567
+ <td>
568
+ <select name="output_type[][]" class="outputType wfnoempty">
569
+ <?php
570
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
571
+ echo $wooFeedDropDown->outputTypes();
572
+ ?>
573
+ </select>
574
+ <i class="dashicons dashicons-editor-expand expandType"></i>
575
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
576
+ </td>
577
+ <td>
578
+ <input type="text" name="limit[]" class="wf_ps">
579
+ </td>
580
+ <td>
581
+ <i class="delRow dashicons dashicons-trash"></i>
582
+ </td>
583
+ </tr>
584
+ <tr>
585
+ <td>
586
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
587
+ </td>
588
+ <td>
589
+ <select name="mattributes[]" required class="wf_mattributes">
590
+ <?php
591
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
592
+ echo $wooFeedDropDown->googleAttributesDropdown( 'sku' );
593
+ ?>
594
+ </select>
595
+ </td>
596
+ <td>
597
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
598
+ </td>
599
+ <td>
600
+ <select name="type[]" class="attr_type wfnoempty">
601
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
602
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
603
+ </select>
604
+ </td>
605
+ <td>
606
+ <select name="attributes[]" class="wf_attr wf_attributes">
607
+ <?php
608
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
609
+ echo $wooFeedProduct->attributeDropdown( 'sku' );
610
+ ?>
611
+ </select>
612
+ <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;">
613
+ </td>
614
+ <td>
615
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
616
+ </td>
617
+ <td>
618
+ <select name="output_type[][]" class="outputType wfnoempty">
619
+ <?php
620
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
621
+ echo $wooFeedDropDown->outputTypes();
622
+ ?>
623
+ </select>
624
+ <i class="dashicons dashicons-editor-expand expandType"></i>
625
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
626
+ </td>
627
+ <td>
628
+ <input type="text" name="limit[]" class="wf_ps">
629
+ </td>
630
+ <td>
631
+ <i class="delRow dashicons dashicons-trash"></i>
632
+ </td>
633
+ </tr>
634
+ <tr>
635
+ <td>
636
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
637
+ </td>
638
+ <td>
639
+ <select name="mattributes[]" required class="wf_mattributes">
640
+ <?php
641
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
642
+ echo $wooFeedDropDown->googleAttributesDropdown( 'brand' );
643
+ ?>
644
+ </select>
645
+ </td>
646
+ <td>
647
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
648
+ </td>
649
+ <td>
650
+ <select name="type[]" class="attr_type wfnoempty">
651
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
652
+ <option value="pattern" selected><?php _e( 'Pattern', 'woo-feed' ); ?></option>
653
+ </select>
654
+ </td>
655
+ <td>
656
+ <select name="attributes[]" style=" display: none;" class="wf_attr wf_attributes">
657
+ <?php
658
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
659
+ echo $wooFeedProduct->attributeDropdown();
660
+ ?>
661
+ </select>
662
+ <?php
663
+ $url = site_url();
664
+ $WABrand = '';
665
+ // Remove all illegal characters from a url
666
+ $url = filter_var( $url, FILTER_SANITIZE_URL );
667
+ // Validate url
668
+ if ( filter_var( $url, FILTER_VALIDATE_URL ) !== false ) {
669
+ $url = wp_parse_url( $url );
670
+ if ( array_key_exists( 'host', $url ) ) {
671
+ $arr = explode( '.', $url['host'] );
672
+ $WABrand = $arr[ count( $arr ) - 2 ];
673
+ }
674
+ }
675
 
676
+ ?>
677
+ <input type="text" name="default[]" value="<?php echo esc_attr( $WABrand ); ?>" autocomplete="off" class="wf_default wf_attributes"
678
+ />
679
+ </td>
680
+ <td>
681
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
682
+ </td>
683
+ <td>
684
+ <select name="output_type[][]" class="outputType wfnoempty">
685
+ <?php
686
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
687
+ echo $wooFeedDropDown->outputTypes();
688
+ ?>
689
+ </select>
690
+ <i class="dashicons dashicons-editor-expand expandType"></i>
691
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
692
+ </td>
693
+ <td>
694
+ <input type="text" name="limit[]" class="wf_ps">
695
+ </td>
696
+ <td>
697
+ <i class="delRow dashicons dashicons-trash"></i>
698
+ </td>
699
+ </tr>
700
+ </tbody>
701
+ <tfoot>
702
+ <tr>
703
+ <td>
704
+ <button type="button" class="button-small button-primary" id="wf_newRow"><?php _e( 'Add New Row', 'woo-feed' ); ?></button>
705
+ </td>
706
+ <td colspan="8"></td>
707
+ </tr>
708
+ </tfoot>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
709
  </table>
 
 
 
 
admin/partials/templates/google_add-feed.php CHANGED
@@ -1,705 +1,715 @@
1
- <ul class="wf_tabs">
2
- <li>
3
- <input type="radio" name="wf_tabs" id="tab1" checked/>
4
- <label class="wf-tab-name" for="tab1"><?php _e( 'Feed Config', 'woo-feed' ); ?></label>
5
-
6
- <div id="wf-tab-content1" class="wf-tab-content">
7
- <table class="table tree widefat fixed sorted_table mtable" width="100%" id="table-1">
8
- <thead>
9
- <tr>
10
- <th></th>
11
- <th><?php echo ucfirst( $provider ); ?> <?php _e( 'Attributes', 'woo-feed' ); ?></th>
12
- <th><?php _e( 'Prefix', 'woo-feed' ); ?></th>
13
- <th><?php _e( 'Type', 'woo-feed' ); ?></th>
14
- <th><?php _e( 'Value', 'woo-feed' ); ?></th>
15
- <th><?php _e( 'Suffix', 'woo-feed' ); ?></th>
16
- <th><?php _e( 'Output Type', 'woo-feed' ); ?></th>
17
- <th><?php _e( 'Output Limit', 'woo-feed' ); ?></th>
18
- <th></th>
19
- </tr>
20
- </thead>
21
- <tbody>
22
- <tr>
23
- <td>
24
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
25
- </td>
26
- <td>
27
- <select name="mattributes[]" required class="wf_mattributes">
28
- <?php echo $dropDown->googleAttributesDropdown( 'id' ); ?>
29
- </select>
30
- </td>
31
- <td>
32
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
33
- </td>
34
- <td>
35
- <select name="type[]" class="attr_type wfnoempty">
36
- <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
37
- <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
38
- </select>
39
- </td>
40
- <td>
41
- <select name="attributes[]" class="wf_attr wf_attributes">
42
- <?php echo $product->attributeDropdown( 'id' ); ?>
43
- </select>
44
- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;"/>
45
- </td>
46
- <td>
47
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
48
- </td>
49
- <td>
50
- <select name="output_type[][]" class="outputType wfnoempty">
51
- <option value="1">Default</option>
52
- <option value="2">Strip Tags</option>
53
- <option value="3">UTF-8 Encode</option>
54
- <option value="4">htmlentities</option>
55
- <option value="5">Integer</option>
56
- <option value="6">Price</option>
57
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
58
- <option value="8">CDATA</option>
59
- </select>
60
- <i class="dashicons dashicons-editor-expand expandType"></i>
61
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
62
- </td>
63
- <td>
64
- <input type="text" name="limit[]" class="wf_ps"/>
65
- </td>
66
- <td>
67
- <i class="delRow dashicons dashicons-trash"></i>
68
- </td>
69
- </tr>
70
- <tr>
71
- <td>
72
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
73
- </td>
74
- <td>
75
- <select name="mattributes[]" required class="wf_mattributes">
76
- <?php echo $dropDown->googleAttributesDropdown( 'title' ); ?>
77
- </select>
78
- </td>
79
- <td>
80
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
81
- </td>
82
- <td>
83
- <select name="type[]" class="attr_type wfnoempty">
84
- <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
85
- <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
86
- </select>
87
- </td>
88
- <td>
89
- <select name="attributes[]" class="wf_attr wf_attributes">
90
- <?php echo $product->attributeDropdown( 'title' ); ?>
91
- </select>
92
- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;"/>
93
- </td>
94
- <td>
95
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
96
- </td>
97
- <td>
98
- <select name="output_type[][]" class="outputType wfnoempty">
99
- <option value="1">Default</option>
100
- <option value="2">Strip Tags</option>
101
- <option value="3">UTF-8 Encode</option>
102
- <option value="4">htmlentities</option>
103
- <option value="5">Integer</option>
104
- <option value="6">Price</option>
105
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
106
- <option value="8">CDATA</option>
107
- </select>
108
- <i class="dashicons dashicons-editor-expand expandType"></i>
109
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
110
- </td>
111
- <td>
112
- <input type="text" name="limit[]" class="wf_ps"/>
113
- </td>
114
- <td>
115
- <i class="delRow dashicons dashicons-trash"></i>
116
- </td>
117
- </tr>
118
- <tr>
119
- <td>
120
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
121
- </td>
122
- <td>
123
- <select name="mattributes[]" required class="wf_mattributes">
124
- <?php echo $dropDown->googleAttributesDropdown( 'description' ); ?>
125
- </select>
126
- </td>
127
- <td>
128
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
129
- </td>
130
- <td>
131
- <select name="type[]" class="attr_type wfnoempty">
132
- <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
133
- <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
134
- </select>
135
- </td>
136
- <td>
137
- <select name="attributes[]" class="wf_attr wf_attributes">
138
- <?php echo $product->attributeDropdown( 'description' ); ?>
139
- </select>
140
- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;"/>
141
- </td>
142
- <td>
143
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
144
- </td>
145
- <td>
146
- <select name="output_type[][]" class="outputType wfnoempty">
147
- <option value="1">Default</option>
148
- <option selected value="2">Strip Tags</option>
149
- <option value="3">UTF-8 Encode</option>
150
- <option value="4">htmlentities</option>
151
- <option value="5">Integer</option>
152
- <option value="6">Price</option>
153
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
154
- <option value="8">CDATA</option>
155
- </select>
156
- <i class="dashicons dashicons-editor-expand expandType"></i>
157
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
158
- </td>
159
- <td>
160
- <input type="text" name="limit[]" class="wf_ps" value="5000"/>
161
- </td>
162
- <td>
163
- <i class="delRow dashicons dashicons-trash"></i>
164
- </td>
165
- </tr>
166
- <tr>
167
- <td>
168
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
169
- </td>
170
- <td>
171
- <select name="mattributes[]" required class="wf_mattributes">
172
- <?php echo $dropDown->googleAttributesDropdown( 'item_group_id' ); ?>
173
- </select>
174
- </td>
175
- <td>
176
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
177
- </td>
178
- <td>
179
- <select name="type[]" class="attr_type wfnoempty">
180
- <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
181
- <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
182
- </select>
183
- </td>
184
- <td>
185
- <select name="attributes[]" class="wf_attr wf_attributes">
186
- <?php echo $product->attributeDropdown( 'item_group_id' ); ?>
187
- </select>
188
- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;"/>
189
- </td>
190
- <td>
191
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
192
- </td>
193
- <td>
194
- <select name="output_type[][]" class="outputType wfnoempty">
195
- <option value="1">Default</option>
196
- <option value="2">Strip Tags</option>
197
- <option value="3">UTF-8 Encode</option>
198
- <option value="4">htmlentities</option>
199
- <option value="5">Integer</option>
200
- <option value="6">Price</option>
201
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
202
- <option value="8">CDATA</option>
203
- </select>
204
- <i class="dashicons dashicons-editor-expand expandType"></i>
205
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
206
- </td>
207
- <td>
208
- <input type="text" name="limit[]" class="wf_ps"/>
209
- </td>
210
- <td>
211
- <i class="delRow dashicons dashicons-trash"></i>
212
- </td>
213
- </tr>
214
- <tr>
215
- <td>
216
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
217
- </td>
218
- <td>
219
- <select name="mattributes[]" required class="wf_mattributes">
220
- <?php echo $dropDown->googleAttributesDropdown( 'link' ); ?>
221
- </select>
222
- </td>
223
- <td>
224
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
225
- </td>
226
- <td>
227
- <select name="type[]" class="attr_type wfnoempty">
228
- <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
229
- <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
230
- </select>
231
- </td>
232
- <td>
233
- <select name="attributes[]" class="wf_attr wf_attributes">
234
- <?php echo $product->attributeDropdown( 'link' ); ?>
235
- </select>
236
- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;"/>
237
- </td>
238
- <td>
239
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
240
- </td>
241
- <td>
242
- <select name="output_type[][]" class="outputType wfnoempty">
243
- <option value="1">Default</option>
244
- <option value="2">Strip Tags</option>
245
- <option value="3">UTF-8 Encode</option>
246
- <option value="4">htmlentities</option>
247
- <option value="5">Integer</option>
248
- <option value="6">Price</option>
249
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
250
- <option value="8">CDATA</option>
251
- </select>
252
- <i class="dashicons dashicons-editor-expand expandType"></i>
253
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
254
- </td>
255
- <td>
256
- <input type="text" name="limit[]" class="wf_ps"/>
257
- </td>
258
- <td>
259
- <i class="delRow dashicons dashicons-trash"></i>
260
- </td>
261
- </tr>
262
- <tr>
263
- <td>
264
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
265
- </td>
266
- <td>
267
- <select name="mattributes[]" required class="wf_mattributes">
268
- <?php echo $dropDown->googleAttributesDropdown('product_type'); ?>
269
- </select>
270
- </td>
271
- <td>
272
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
273
- </td>
274
- <td>
275
- <select name="type[]" class="attr_type wfnoempty">
276
- <option value="attribute"><?php _e('Attribute','woo-feed');?></option>
277
- <option value="pattern"><?php _e('Pattern','woo-feed');?></option>
278
- </select>
279
- </td>
280
- <td>
281
- <select name="attributes[]" class="wf_attr wf_attributes">
282
- <?php echo $product->attributeDropdown('product_type'); ?>
283
- </select>
284
- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;"/>
285
- </td>
286
- <td>
287
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
288
- </td>
289
- <td>
290
- <select name="output_type[][]" class="outputType wfnoempty">
291
- <option value="1">Default</option>
292
- <option value="2">Strip Tags</option>
293
- <option value="3">UTF-8 Encode</option>
294
- <option value="4">htmlentities</option>
295
- <option value="5">Integer</option>
296
- <option value="6">Price</option>
297
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
298
- <option value="8">CDATA</option>
299
- </select>
300
- <i class="dashicons dashicons-editor-expand expandType"></i>
301
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
302
- </td>
303
- <td>
304
- <input type="text" name="limit[]" class="wf_ps"/>
305
- </td>
306
- <td>
307
- <i class="delRow dashicons dashicons-trash"></i>
308
- </td>
309
- </tr>
310
- <tr>
311
- <td>
312
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
313
- </td>
314
- <td>
315
- <select name="mattributes[]" required class="wf_mattributes">
316
- <?php echo $dropDown->googleAttributesDropdown('current_category'); ?>
317
- </select>
318
- </td>
319
- <td>
320
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
321
- </td>
322
- <td>
323
- <select name="type[]" class="attr_type wfnoempty">
324
- <option value="attribute"><?php _e('Attribute','woo-feed');?></option>
325
- <option value="pattern" selected><?php _e('Pattern','woo-feed');?></option>
326
- </select>
327
- </td>
328
- <!-- <td>-->
329
- <!-- <select name="attributes[]" style=" display: none;" class="wf_attr wf_attributes">-->
330
- <!-- --><?php //echo $product->attributeDropdown(); ?>
331
- <!-- </select>-->
332
- <!-- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" />-->
333
- <!-- <br><span style="font-size:x-small;"><a href="http://webappick.helpscoutdocs.com/article/19-how-to-map-store-category-with-merchant-category" target="_blank">Learn More..</a></span>-->
334
- <!-- </td>-->
335
- <td>
336
- <select name="attributes[]" class="wf_attr wf_attributes" style="display:none;">
337
- <?php echo $product->attributeDropdown( '' ); ?>
338
- </select>
339
- <span class="wf_default wf_attributes">
340
- <select name="default[]" class="selectize">
341
- <?php echo $dropDown->googleTaxonomy(); ?>
342
- </select>
343
- </span>
344
- <span style="font-size:x-small;"><a style="color: red" href="http://webappick.helpscoutdocs.com/article/19-how-to-map-store-category-with-merchant-category" target="_blank">Learn More..</a></span>
345
- </td>
346
- <td>
347
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
348
- </td>
349
- <td>
350
- <select name="output_type[][]" class="outputType wfnoempty">
351
- <option value="1">Default</option>
352
- <option value="2">Strip Tags</option>
353
- <option value="3">UTF-8 Encode</option>
354
- <option value="4">htmlentities</option>
355
- <option value="5">Integer</option>
356
- <option value="6">Price</option>
357
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
358
- <option value="8">CDATA</option>
359
- </select>
360
- <i class="dashicons dashicons-editor-expand expandType"></i>
361
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
362
- </td>
363
- <td>
364
- <input type="text" name="limit[]" class="wf_ps"/>
365
- </td>
366
- <td>
367
- <i class="delRow dashicons dashicons-trash"></i>
368
- </td>
369
- </tr>
370
- <tr>
371
- <td>
372
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
373
- </td>
374
- <td>
375
- <select name="mattributes[]" required class="wf_mattributes">
376
- <?php echo $dropDown->googleAttributesDropdown( 'image' ); ?>
377
- </select>
378
- </td>
379
- <td>
380
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
381
- </td>
382
- <td>
383
- <select name="type[]" class="attr_type wfnoempty">
384
- <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
385
- <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
386
- </select>
387
- </td>
388
- <td>
389
- <select name="attributes[]" class="wf_attr wf_attributes">
390
- <?php echo $product->attributeDropdown( 'image' ); ?>
391
- </select>
392
- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;"/>
393
- </td>
394
- <td>
395
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
396
- </td>
397
- <td>
398
- <select name="output_type[][]" class="outputType wfnoempty">
399
- <option value="1">Default</option>
400
- <option value="2">Strip Tags</option>
401
- <option value="3">UTF-8 Encode</option>
402
- <option value="4">htmlentities</option>
403
- <option value="5">Integer</option>
404
- <option value="6">Price</option>
405
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
406
- <option value="8">CDATA</option>
407
- </select>
408
- <i class="dashicons dashicons-editor-expand expandType"></i>
409
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
410
- </td>
411
- <td>
412
- <input type="text" name="limit[]" class="wf_ps"/>
413
- </td>
414
- <td>
415
- <i class="delRow dashicons dashicons-trash"></i>
416
- </td>
417
- </tr>
418
- <tr>
419
- <td>
420
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
421
- </td>
422
- <td>
423
- <select name="mattributes[]" required class="wf_mattributes">
424
- <?php echo $dropDown->googleAttributesDropdown( 'condition' ); ?>
425
- </select>
426
- </td>
427
- <td>
428
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
429
- </td>
430
- <td>
431
- <select name="type[]" class="attr_type wfnoempty">
432
- <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
433
- <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
434
- </select>
435
- </td>
436
- <td>
437
- <select name="attributes[]" class="wf_attr wf_attributes">
438
- <?php echo $product->attributeDropdown( 'condition' ); ?>
439
- </select>
440
- <input type="text" style=" display: none;" name="default[]" autocomplete="off" class="wf_default wf_attributes"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
441
  />
442
- </td>
443
- <td>
444
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
445
- </td>
446
- <td>
447
- <select name="output_type[][]" class="outputType wfnoempty">
448
- <option value="1">Default</option>
449
- <option value="2">Strip Tags</option>
450
- <option value="3">UTF-8 Encode</option>
451
- <option value="4">htmlentities</option>
452
- <option value="5">Integer</option>
453
- <option value="6">Price</option>
454
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
455
- <option value="8">CDATA</option>
456
- </select>
457
- <i class="dashicons dashicons-editor-expand expandType"></i>
458
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
459
- </td>
460
- <td>
461
- <input type="text" name="limit[]" class="wf_ps"/>
462
- </td>
463
- <td>
464
- <i class="delRow dashicons dashicons-trash"></i>
465
- </td>
466
- </tr>
467
- <tr>
468
- <td>
469
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
470
- </td>
471
- <td>
472
- <select name="mattributes[]" required class="wf_mattributes">
473
- <?php echo $dropDown->googleAttributesDropdown( 'availability' ); ?>
474
- </select>
475
- </td>
476
- <td>
477
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
478
- </td>
479
- <td>
480
- <select name="type[]" class="attr_type wfnoempty">
481
- <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
482
- <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
483
- </select>
484
- </td>
485
- <td>
486
- <select name="attributes[]" class="wf_attr wf_attributes">
487
- <?php echo $product->attributeDropdown( 'availability' ); ?>
488
- </select>
489
- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;"/>
490
- </td>
491
- <td>
492
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
493
- </td>
494
- <td>
495
- <select name="output_type[][]" class="outputType wfnoempty">
496
- <option value="1">Default</option>
497
- <option value="2">Strip Tags</option>
498
- <option value="3">UTF-8 Encode</option>
499
- <option value="4">htmlentities</option>
500
- <option value="5">Integer</option>
501
- <option value="6">Price</option>
502
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
503
- <option value="8">CDATA</option>
504
- </select>
505
- <i class="dashicons dashicons-editor-expand expandType"></i>
506
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
507
- </td>
508
- <td>
509
- <input type="text" name="limit[]" class="wf_ps"/>
510
- </td>
511
- <td>
512
- <i class="delRow dashicons dashicons-trash"></i>
513
- </td>
514
- </tr>
515
- <tr>
516
- <td>
517
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
518
- </td>
519
- <td>
520
- <select name="mattributes[]" required class="wf_mattributes">
521
- <?php echo $dropDown->googleAttributesDropdown( 'price' ); ?>
522
- </select>
523
- </td>
524
- <td>
525
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
526
- </td>
527
- <td>
528
- <select name="type[]" class="attr_type wfnoempty">
529
- <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
530
- <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
531
- </select>
532
- </td>
533
- <td>
534
- <select name="attributes[]" class="wf_attr wf_attributes">
535
- <?php echo $product->attributeDropdown( 'price' ); ?>
536
- </select>
537
- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;"/>
538
- </td>
539
- <td>
540
- <input type="text" name="suffix[]" value="<?php echo get_woocommerce_currency();?>" autocomplete="off" class="wf_ps"/>
541
- </td>
542
- <td>
543
- <select name="output_type[][]" class="outputType wfnoempty">
544
- <option value="1">Default</option>
545
- <option value="2">Strip Tags</option>
546
- <option value="3">UTF-8 Encode</option>
547
- <option value="4">htmlentities</option>
548
- <option value="5">Integer</option>
549
- <option selected value="6">Price</option>
550
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
551
- <option value="8">CDATA</option>
552
- </select>
553
- <i class="dashicons dashicons-editor-expand expandType"></i>
554
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
555
- </td>
556
- <td>
557
- <input type="text" name="limit[]" class="wf_ps"/>
558
- </td>
559
- <td>
560
- <i class="delRow dashicons dashicons-trash"></i>
561
- </td>
562
- </tr>
563
-
564
- <tr>
565
- <td>
566
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
567
- </td>
568
- <td>
569
- <select name="mattributes[]" required class="wf_mattributes">
570
- <?php echo $dropDown->googleAttributesDropdown( 'sku' ); ?>
571
- </select>
572
- </td>
573
- <td>
574
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
575
- </td>
576
- <td>
577
- <select name="type[]" class="attr_type wfnoempty">
578
- <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
579
- <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
580
- </select>
581
- </td>
582
- <td>
583
- <select name="attributes[]" class="wf_attr wf_attributes">
584
- <?php echo $product->attributeDropdown( 'sku' ); ?>
585
- </select>
586
- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;"/>
587
- </td>
588
- <td>
589
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
590
- </td>
591
- <td>
592
- <select name="output_type[][]" class="outputType wfnoempty">
593
- <option value="1">Default</option>
594
- <option value="2">Strip Tags</option>
595
- <option value="3">UTF-8 Encode</option>
596
- <option value="4">htmlentities</option>
597
- <option value="5">Integer</option>
598
- <option value="6">Price</option>
599
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
600
- <option value="8">CDATA</option>
601
- </select>
602
- <i class="dashicons dashicons-editor-expand expandType"></i>
603
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
604
- </td>
605
- <td>
606
- <input type="text" name="limit[]" class="wf_ps"/>
607
- </td>
608
- <td>
609
- <i class="delRow dashicons dashicons-trash"></i>
610
- </td>
611
- </tr>
612
- <tr>
613
- <td>
614
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
615
- </td>
616
- <td>
617
- <select name="mattributes[]" required class="wf_mattributes">
618
- <?php echo $dropDown->googleAttributesDropdown( 'brand' ); ?>
619
- </select>
620
- </td>
621
- <td>
622
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
623
- </td>
624
- <td>
625
- <select name="type[]" class="attr_type wfnoempty">
626
- <option value="attribute" ><?php _e( 'Attribute', 'woo-feed' ); ?></option>
627
- <option value="pattern" selected><?php _e( 'Pattern', 'woo-feed' ); ?></option>
628
- </select>
629
- </td>
630
- <td>
631
- <select name="attributes[]" style=" display: none;" class="wf_attr wf_attributes">
632
- <?php echo $product->attributeDropdown(); ?>
633
- </select>
634
- <?php
635
- $url = site_url();
636
- $WABrand = "";
 
 
 
 
 
 
 
637
  // Remove all illegal characters from a url
638
- $url = filter_var($url, FILTER_SANITIZE_URL);
639
  // Validate url
640
- if ( filter_var($url, FILTER_VALIDATE_URL) !== false ) {
641
- $url = parse_url($url);
642
- if ( array_key_exists('host',$url) ) {
643
- $arr = explode('.',$url['host']);
644
- $WABrand = $arr[ count($arr) - 2 ];
645
  }
646
  }
647
-
648
- ?>
649
- <input type="text" name="default[]" value="<?php echo $WABrand; ?>" autocomplete="off" class="wf_default wf_attributes"/>
650
- </td>
651
- <td>
652
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
653
- </td>
654
- <td>
655
- <select name="output_type[][]" class="outputType wfnoempty">
656
- <option value="1">Default</option>
657
- <option value="2">Strip Tags</option>
658
- <option value="3">UTF-8 Encode</option>
659
- <option value="4">htmlentities</option>
660
- <option value="5">Integer</option>
661
- <option value="6">Price</option>
662
- <option value="7">Remove Space</option>
663
- <option value="10">Remove ShortCodes</option>
664
- <option value="9">Remove Special Character</option>
665
- <option value="8">CDATA</option>
666
- </select>
667
- <i class="dashicons dashicons-editor-expand expandType"></i>
668
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
669
- </td>
670
- <td>
671
- <input type="text" name="limit[]" class="wf_ps"/>
672
- </td>
673
- <td>
674
- <i class="delRow dashicons dashicons-trash"></i>
675
- </td>
676
- </tr>
677
- </tbody>
678
- <tfoot>
679
- <tr>
680
- <td>
681
- <button type="button" class="button-small button-primary" id="wf_newRow">
682
- <?php _e( 'Add New Row', 'woo-feed' ); ?>
683
- </button>
684
- </td>
685
- <td colspan="8">
686
 
687
- </td>
688
- </tr>
689
- </tfoot>
690
- </table>
691
- <table class=" widefat fixed">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
692
  <tr>
693
- <td align="left" class="">
694
- <div class="makeFeedResponse"></div>
695
- <div class="makeFeedComplete"></div>
696
- </td>
697
- <td align="right">
698
- <button type="submit" class="wfbtn"><?php _e( 'Save & Generate Feed', 'woo-feed' ); ?></button>
699
  </td>
 
700
  </tr>
 
701
  </table>
702
- </div>
703
- </li>
704
- <?php include plugin_dir_path(__FILE__) . "../woo-feed-ftp-sftp-template.php"; ?>
705
- </ul>
1
+ <?php
2
+ /**
3
+ * Google Template
4
+ */
5
+ if ( ! defined( 'ABSPATH' ) ) {
6
+ die();
7
+ }
8
+ global $provider;
9
+ ?>
10
+ <table class="table tree widefat fixed sorted_table mtable" style="width: 100%;" id="table-1">
11
+ <thead>
12
+ <tr>
13
+ <th></th>
14
+ <th><?php echo esc_html( ucfirst( $provider ) ); ?> <?php _e( 'Attributes', 'woo-feed' ); ?></th>
15
+ <th><?php _e( 'Prefix', 'woo-feed' ); ?></th>
16
+ <th><?php _e( 'Type', 'woo-feed' ); ?></th>
17
+ <th><?php _e( 'Value', 'woo-feed' ); ?></th>
18
+ <th><?php _e( 'Suffix', 'woo-feed' ); ?></th>
19
+ <th><?php _e( 'Output Type', 'woo-feed' ); ?></th>
20
+ <th><?php _e( 'Command', 'woo-feed' ); ?></th>
21
+ <th></th>
22
+ </tr>
23
+ </thead>
24
+ <tbody>
25
+ <tr>
26
+ <td>
27
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
28
+ </td>
29
+ <td>
30
+ <select name="mattributes[]" required class="wf_mattributes">
31
+ <?php
32
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
33
+ echo $wooFeedDropDown->googleAttributesDropdown( 'id' );
34
+ ?>
35
+ </select>
36
+ </td>
37
+ <td>
38
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
39
+ </td>
40
+ <td>
41
+ <select name="type[]" class="attr_type wfnoempty">
42
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
43
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
44
+ </select>
45
+ </td>
46
+ <td>
47
+ <select name="attributes[]" class="wf_attr wf_attributes">
48
+ <?php
49
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
50
+ echo $wooFeedProduct->attributeDropdown( 'id' );
51
+ ?>
52
+ </select>
53
+ <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;">
54
+ </td>
55
+ <td>
56
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
57
+ </td>
58
+ <td>
59
+ <select name="output_type[][]" class="outputType wfnoempty">
60
+ <?php
61
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
62
+ echo $wooFeedDropDown->outputTypes();
63
+ ?>
64
+ </select>
65
+ <i class="dashicons dashicons-editor-expand expandType"></i>
66
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
67
+ </td>
68
+ <td>
69
+ <input type="text" name="limit[]" autocomplete="off" class="wf_ps">
70
+ </td>
71
+ <td>
72
+ <i class="delRow dashicons dashicons-trash"></i>
73
+ </td>
74
+ </tr>
75
+ <tr>
76
+ <td>
77
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
78
+ </td>
79
+ <td>
80
+ <select name="mattributes[]" required class="wf_mattributes">
81
+ <?php
82
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
83
+ echo $wooFeedDropDown->googleAttributesDropdown( 'title' );
84
+ ?>
85
+ </select>
86
+ </td>
87
+ <td>
88
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
89
+ </td>
90
+ <td>
91
+ <select name="type[]" class="attr_type wfnoempty">
92
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
93
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
94
+ </select>
95
+ </td>
96
+ <td>
97
+ <select name="attributes[]" class="wf_attr wf_attributes">
98
+ <?php
99
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
100
+ echo $wooFeedProduct->attributeDropdown( 'title' );
101
+ ?>
102
+ </select>
103
+ <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;">
104
+ </td>
105
+ <td>
106
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
107
+ </td>
108
+ <td>
109
+ <select name="output_type[][]" class="outputType wfnoempty">
110
+ <?php
111
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
112
+ echo $wooFeedDropDown->outputTypes();
113
+ ?>
114
+ </select>
115
+ <i class="dashicons dashicons-editor-expand expandType"></i>
116
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
117
+ </td>
118
+ <td>
119
+ <input type="text" name="limit[]" autocomplete="off" class="wf_ps">
120
+ </td>
121
+ <td>
122
+ <i class="delRow dashicons dashicons-trash"></i>
123
+ </td>
124
+ </tr>
125
+ <tr>
126
+ <td>
127
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
128
+ </td>
129
+ <td>
130
+ <select name="mattributes[]" required class="wf_mattributes">
131
+ <?php
132
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
133
+ echo $wooFeedDropDown->googleAttributesDropdown( 'description' );
134
+ ?>
135
+ </select>
136
+ </td>
137
+ <td>
138
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
139
+ </td>
140
+ <td>
141
+ <select name="type[]" class="attr_type wfnoempty">
142
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
143
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
144
+ </select>
145
+ </td>
146
+ <td>
147
+ <select name="attributes[]" class="wf_attr wf_attributes">
148
+ <?php
149
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
150
+ echo $wooFeedProduct->attributeDropdown( 'description' );
151
+ ?>
152
+ </select>
153
+ <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;">
154
+ </td>
155
+ <td>
156
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
157
+ </td>
158
+ <td>
159
+ <select name="output_type[][]" class="outputType wfnoempty">
160
+ <?php
161
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
162
+ echo $wooFeedDropDown->outputTypes();
163
+ ?>
164
+ </select>
165
+ <i class="dashicons dashicons-editor-expand expandType"></i>
166
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
167
+ </td>
168
+ <td>
169
+ <input type="text" name="limit[]" autocomplete="off" class="wf_ps">
170
+ </td>
171
+ <td>
172
+ <i class="delRow dashicons dashicons-trash"></i>
173
+ </td>
174
+ </tr>
175
+ <tr>
176
+ <td>
177
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
178
+ </td>
179
+ <td>
180
+ <select name="mattributes[]" required class="wf_mattributes">
181
+ <?php
182
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
183
+ echo $wooFeedDropDown->googleAttributesDropdown( 'item_group_id' );
184
+ ?>
185
+ </select>
186
+ </td>
187
+ <td>
188
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
189
+ </td>
190
+ <td>
191
+ <select name="type[]" class="attr_type wfnoempty">
192
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
193
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
194
+ </select>
195
+ </td>
196
+ <td>
197
+ <select name="attributes[]" class="wf_attr wf_attributes">
198
+ <?php
199
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
200
+ echo $wooFeedProduct->attributeDropdown( 'item_group_id' );
201
+ ?>
202
+ </select>
203
+ <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;">
204
+ </td>
205
+ <td>
206
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
207
+ </td>
208
+ <td>
209
+ <select name="output_type[][]" class="outputType wfnoempty">
210
+ <?php
211
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
212
+ echo $wooFeedDropDown->outputTypes();
213
+ ?>
214
+ </select>
215
+ <i class="dashicons dashicons-editor-expand expandType"></i>
216
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
217
+ </td>
218
+ <td>
219
+ <input type="text" name="limit[]" autocomplete="off" class="wf_ps">
220
+ </td>
221
+ <td>
222
+ <i class="delRow dashicons dashicons-trash"></i>
223
+ </td>
224
+ </tr>
225
+ <tr>
226
+ <td>
227
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
228
+ </td>
229
+ <td>
230
+ <select name="mattributes[]" required class="wf_mattributes">
231
+ <?php
232
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
233
+ echo $wooFeedDropDown->googleAttributesDropdown( 'link' );
234
+ ?>
235
+ </select>
236
+ </td>
237
+ <td>
238
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
239
+ </td>
240
+ <td>
241
+ <select name="type[]" class="attr_type wfnoempty">
242
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
243
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
244
+ </select>
245
+ </td>
246
+ <td>
247
+ <select name="attributes[]" class="wf_attr wf_attributes">
248
+ <?php
249
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
250
+ echo $wooFeedProduct->attributeDropdown( 'link' );
251
+ ?>
252
+ </select>
253
+ <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;">
254
+ </td>
255
+ <td>
256
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
257
+ </td>
258
+ <td>
259
+ <select name="output_type[][]" class="outputType wfnoempty">
260
+ <?php
261
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
262
+ echo $wooFeedDropDown->outputTypes();
263
+ ?>
264
+ </select>
265
+ <i class="dashicons dashicons-editor-expand expandType"></i>
266
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
267
+ </td>
268
+ <td>
269
+ <input type="text" name="limit[]" autocomplete="off" class="wf_ps">
270
+ </td>
271
+ <td>
272
+ <i class="delRow dashicons dashicons-trash"></i>
273
+ </td>
274
+ </tr>
275
+ <tr>
276
+ <td>
277
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
278
+ </td>
279
+ <td>
280
+ <select name="mattributes[]" required class="wf_mattributes">
281
+ <?php
282
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
283
+ echo $wooFeedDropDown->googleAttributesDropdown( 'product_type' );
284
+ ?>
285
+ </select>
286
+ </td>
287
+ <td>
288
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
289
+ </td>
290
+ <td>
291
+ <select name="type[]" class="attr_type wfnoempty">
292
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
293
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
294
+ </select>
295
+ </td>
296
+ <td>
297
+ <select name="attributes[]" class="wf_attr wf_attributes">
298
+ <?php
299
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
300
+ echo $wooFeedProduct->attributeDropdown( 'product_type' );
301
+ ?>
302
+ </select>
303
+ <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;">
304
+ </td>
305
+ <td>
306
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
307
+ </td>
308
+ <td>
309
+ <select name="output_type[][]" class="outputType wfnoempty">
310
+ <?php
311
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
312
+ echo $wooFeedDropDown->outputTypes();
313
+ ?>
314
+ </select>
315
+ <i class="dashicons dashicons-editor-expand expandType"></i>
316
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
317
+ </td>
318
+ <td>
319
+ <input type="text" name="limit[]" autocomplete="off" class="wf_ps">
320
+ </td>
321
+ <td>
322
+ <i class="delRow dashicons dashicons-trash"></i>
323
+ </td>
324
+ </tr>
325
+ <tr>
326
+ <td>
327
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
328
+ </td>
329
+ <td>
330
+ <select name="mattributes[]" required class="wf_mattributes">
331
+ <?php
332
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
333
+ echo $wooFeedDropDown->googleAttributesDropdown( 'current_category' );
334
+ ?>
335
+ </select>
336
+ </td>
337
+ <td>
338
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
339
+ </td>
340
+ <td>
341
+ <select name="type[]" class="attr_type wfnoempty">
342
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
343
+ <option value="pattern" selected><?php _e( 'Pattern', 'woo-feed' ); ?></option>
344
+ </select>
345
+ </td>
346
+ <!-- <td>-->
347
+ <!-- <select name="attributes[]" style=" display: none;" class="wf_attr wf_attributes">-->
348
+ <!-- --><?php // echo $wooFeedProduct->attributeDropdown(); ?>
349
+ <!-- </select>-->
350
+ <!-- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes">-->
351
+ <!-- <br><span style="font-size:x-small;"><a style="color: red" href="http://webappick.helpscoutdocs.com/article/19-how-to-map-store-category-with-merchant-category" target="_blank">Learn More..</a></span>-->
352
+ <!-- </td>-->
353
+ <td>
354
+ <span class="wf_default wf_attributes">
355
+ <select name="default[]" class="selectize">
356
+ <?php
357
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
358
+ echo $wooFeedDropDown->googleTaxonomy();
359
+ ?>
360
+ </select>
361
+ </span>
362
+ <select name="attributes[]" class="wf_attr wf_attributes" style="display:none;">
363
+ <?php
364
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
365
+ echo $wooFeedProduct->attributeDropdown( '' );
366
+ ?>
367
+ </select>
368
+ <span style="font-size:x-small;"><a style="color: red" href="http://webappick.helpscoutdocs.com/article/19-how-to-map-store-category-with-merchant-category" target="_blank">Learn More..</a></span>
369
+ </td>
370
+ <td>
371
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
372
+ </td>
373
+ <td>
374
+ <select name="output_type[][]" class="outputType wfnoempty">
375
+ <?php
376
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
377
+ echo $wooFeedDropDown->outputTypes();
378
+ ?>
379
+ </select>
380
+ <i class="dashicons dashicons-editor-expand expandType"></i>
381
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
382
+ </td>
383
+ <td>
384
+ <input type="text" name="limit[]" autocomplete="off" class="wf_ps">
385
+ </td>
386
+ <td>
387
+ <i class="delRow dashicons dashicons-trash"></i>
388
+ </td>
389
+ </tr>
390
+ <tr>
391
+ <td>
392
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
393
+ </td>
394
+ <td>
395
+ <select name="mattributes[]" required class="wf_mattributes">
396
+ <?php
397
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
398
+ echo $wooFeedDropDown->googleAttributesDropdown( 'image' );
399
+ ?>
400
+ </select>
401
+ </td>
402
+ <td>
403
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
404
+ </td>
405
+ <td>
406
+ <select name="type[]" class="attr_type wfnoempty">
407
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
408
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
409
+ </select>
410
+ </td>
411
+ <td>
412
+ <select name="attributes[]" class="wf_attr wf_attributes">
413
+ <?php
414
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
415
+ echo $wooFeedProduct->attributeDropdown( 'image' );
416
+ ?>
417
+ </select>
418
+ <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;">
419
+ </td>
420
+ <td>
421
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
422
+ </td>
423
+ <td>
424
+ <select name="output_type[][]" class="outputType wfnoempty">
425
+ <?php
426
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
427
+ echo $wooFeedDropDown->outputTypes();
428
+ ?>
429
+ </select>
430
+ <i class="dashicons dashicons-editor-expand expandType"></i>
431
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
432
+ </td>
433
+ <td>
434
+ <input type="text" name="limit[]" autocomplete="off" class="wf_ps">
435
+ </td>
436
+ <td>
437
+ <i class="delRow dashicons dashicons-trash"></i>
438
+ </td>
439
+ </tr>
440
+ <tr>
441
+ <td>
442
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
443
+ </td>
444
+ <td>
445
+ <select name="mattributes[]" required class="wf_mattributes">
446
+ <?php
447
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
448
+ echo $wooFeedDropDown->googleAttributesDropdown( 'condition' );
449
+ ?>
450
+ </select>
451
+ </td>
452
+ <td>
453
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
454
+ </td>
455
+ <td>
456
+ <select name="type[]" class="attr_type wfnoempty">
457
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
458
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
459
+ </select>
460
+ </td>
461
+ <td>
462
+ <select name="attributes[]" class="wf_attr wf_attributes">
463
+ <?php
464
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
465
+ echo $wooFeedProduct->attributeDropdown( 'condition' );
466
+ ?>
467
+ </select>
468
+ <input type="text" style=" display: none;" name="default[]" autocomplete="off" class="wf_default wf_attributes"
469
  />
470
+ </td>
471
+ <td>
472
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
473
+ </td>
474
+ <td>
475
+ <select name="output_type[][]" class="outputType wfnoempty">
476
+ <?php
477
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
478
+ echo $wooFeedDropDown->outputTypes();
479
+ ?>
480
+ </select>
481
+ <i class="dashicons dashicons-editor-expand expandType"></i>
482
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
483
+ </td>
484
+ <td>
485
+ <input type="text" name="limit[]" autocomplete="off" class="wf_ps">
486
+ </td>
487
+ <td>
488
+ <i class="delRow dashicons dashicons-trash"></i>
489
+ </td>
490
+ </tr>
491
+ <tr>
492
+ <td>
493
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
494
+ </td>
495
+ <td>
496
+ <select name="mattributes[]" required class="wf_mattributes">
497
+ <?php
498
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
499
+ echo $wooFeedDropDown->googleAttributesDropdown( 'availability' );
500
+ ?>
501
+ </select>
502
+ </td>
503
+ <td>
504
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
505
+ </td>
506
+ <td>
507
+ <select name="type[]" class="attr_type wfnoempty">
508
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
509
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
510
+ </select>
511
+ </td>
512
+ <td>
513
+ <select name="attributes[]" class="wf_attr wf_attributes">
514
+ <?php
515
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
516
+ echo $wooFeedProduct->attributeDropdown( 'availability' );
517
+ ?>
518
+ </select>
519
+ <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;">
520
+ </td>
521
+ <td>
522
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
523
+ </td>
524
+ <td>
525
+ <select name="output_type[][]" class="outputType wfnoempty">
526
+ <?php
527
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
528
+ echo $wooFeedDropDown->outputTypes();
529
+ ?>
530
+ </select>
531
+ <i class="dashicons dashicons-editor-expand expandType"></i>
532
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
533
+ </td>
534
+ <td>
535
+ <input type="text" name="limit[]" autocomplete="off" class="wf_ps">
536
+ </td>
537
+ <td>
538
+ <i class="delRow dashicons dashicons-trash"></i>
539
+ </td>
540
+ </tr>
541
+ <tr>
542
+ <td>
543
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
544
+ </td>
545
+ <td>
546
+ <select name="mattributes[]" required class="wf_mattributes">
547
+ <?php
548
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
549
+ echo $wooFeedDropDown->googleAttributesDropdown( 'price' );
550
+ ?>
551
+ </select>
552
+ </td>
553
+ <td>
554
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
555
+ </td>
556
+ <td>
557
+ <select name="type[]" class="attr_type wfnoempty">
558
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
559
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
560
+ </select>
561
+ </td>
562
+ <td>
563
+ <select name="attributes[]" class="wf_attr wf_attributes">
564
+ <?php
565
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
566
+ echo $wooFeedProduct->attributeDropdown( 'price' );
567
+ ?>
568
+ </select>
569
+ <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;">
570
+ </td>
571
+ <td>
572
+ <input type="text" name="suffix[]" value="<?php echo esc_attr( get_woocommerce_currency() ); ?>" autocomplete="off" class="wf_ps">
573
+ </td>
574
+ <td>
575
+ <select name="output_type[][]" class="outputType wfnoempty">
576
+ <?php
577
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
578
+ echo $wooFeedDropDown->outputTypes();
579
+ ?>
580
+ </select>
581
+ <i class="dashicons dashicons-editor-expand expandType"></i>
582
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
583
+ </td>
584
+ <td>
585
+ <input type="text" name="limit[]" autocomplete="off" class="wf_ps">
586
+ </td>
587
+ <td>
588
+ <i class="delRow dashicons dashicons-trash"></i>
589
+ </td>
590
+ </tr>
591
+ <tr>
592
+ <td>
593
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
594
+ </td>
595
+ <td>
596
+ <select name="mattributes[]" required class="wf_mattributes">
597
+ <?php
598
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
599
+ echo $wooFeedDropDown->googleAttributesDropdown( 'sku' );
600
+ ?>
601
+ </select>
602
+ </td>
603
+ <td>
604
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
605
+ </td>
606
+ <td>
607
+ <select name="type[]" class="attr_type wfnoempty">
608
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
609
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
610
+ </select>
611
+ </td>
612
+ <td>
613
+ <select name="attributes[]" class="wf_attr wf_attributes">
614
+ <?php
615
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
616
+ echo $wooFeedProduct->attributeDropdown( 'sku' );
617
+ ?>
618
+ </select>
619
+ <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;">
620
+ </td>
621
+ <td>
622
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
623
+ </td>
624
+ <td>
625
+ <select name="output_type[][]" class="outputType wfnoempty">
626
+ <?php
627
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
628
+ echo $wooFeedDropDown->outputTypes();
629
+ ?>
630
+ </select>
631
+ <i class="dashicons dashicons-editor-expand expandType"></i>
632
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
633
+ </td>
634
+ <td>
635
+ <input type="text" name="limit[]" autocomplete="off" class="wf_ps">
636
+ </td>
637
+ <td>
638
+ <i class="delRow dashicons dashicons-trash"></i>
639
+ </td>
640
+ </tr>
641
+ <tr>
642
+ <td>
643
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
644
+ </td>
645
+ <td>
646
+ <select name="mattributes[]" required class="wf_mattributes">
647
+ <?php
648
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
649
+ echo $wooFeedDropDown->googleAttributesDropdown( 'brand' );
650
+ ?>
651
+ </select>
652
+ </td>
653
+ <td>
654
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
655
+ </td>
656
+ <td>
657
+ <select name="type[]" class="attr_type wfnoempty">
658
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
659
+ <option value="pattern" selected><?php _e( 'Pattern', 'woo-feed' ); ?></option>
660
+ </select>
661
+ </td>
662
+ <td>
663
+ <select name="attributes[]" style=" display: none;" class="wf_attr wf_attributes">
664
+ <?php
665
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
666
+ echo $wooFeedProduct->attributeDropdown();
667
+ ?>
668
+ </select>
669
+ <?php
670
+ $url = site_url();
671
+ $WABrand = '';
672
  // Remove all illegal characters from a url
673
+ $url = filter_var( $url, FILTER_SANITIZE_URL );
674
  // Validate url
675
+ if ( filter_var( $url, FILTER_VALIDATE_URL ) !== false ) {
676
+ $url = wp_parse_url( $url );
677
+ if ( array_key_exists( 'host', $url ) ) {
678
+ $arr = explode( '.', $url['host'] );
679
+ $WABrand = $arr[ count( $arr ) - 2 ];
680
  }
681
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
682
 
683
+ ?>
684
+ <input type="text" name="default[]" value="<?php echo esc_attr( $WABrand ); ?>" autocomplete="off" class="wf_default wf_attributes">
685
+ </td>
686
+ <td>
687
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
688
+ </td>
689
+ <td>
690
+ <select name="output_type[][]" class="outputType wfnoempty">
691
+ <?php
692
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
693
+ echo $wooFeedDropDown->outputTypes();
694
+ ?>
695
+ </select>
696
+ <i class="dashicons dashicons-editor-expand expandType"></i>
697
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
698
+ </td>
699
+ <td>
700
+ <input type="text" name="limit[]" autocomplete="off" class="wf_ps">
701
+ </td>
702
+ <td>
703
+ <i class="delRow dashicons dashicons-trash"></i>
704
+ </td>
705
+ </tr>
706
+ </tbody>
707
+ <tfoot>
708
  <tr>
709
+ <td>
710
+ <button type="button" class="button-small button-primary" id="wf_newRow"><?php _e( 'Add New Row', 'woo-feed' ); ?></button>
 
 
 
 
711
  </td>
712
+ <td colspan="8"></td>
713
  </tr>
714
+ </tfoot>
715
  </table>
 
 
 
 
admin/partials/templates/google_taxonomy.txt CHANGED
@@ -1,4 +1,4 @@
1
- # Google_Product_Taxonomy_Version: 2019-07-10
2
  1 - Animals & Pet Supplies
3
  3237 - Animals & Pet Supplies > Live Animals
4
  2 - Animals & Pet Supplies > Pet Supplies
1
+ # Google_Product_Taxonomy_Version: 2019-07-10 https://www.google.com/basepages/producttype/taxonomy-with-ids.en-US.txt
2
  1 - Animals & Pet Supplies
3
  3237 - Animals & Pet Supplies > Live Animals
4
  2 - Animals & Pet Supplies > Pet Supplies
admin/partials/templates/pinterest_add-feed.php CHANGED
@@ -1,704 +1,715 @@
1
- <ul class="wf_tabs">
2
- <li>
3
- <input type="radio" name="wf_tabs" id="tab1" checked/>
4
- <label class="wf-tab-name" for="tab1"><?php _e( 'Feed Config', 'woo-feed' ); ?></label>
5
-
6
- <div id="wf-tab-content1" class="wf-tab-content">
7
- <table class="table tree widefat fixed sorted_table mtable" width="100%" id="table-1">
8
- <thead>
9
- <tr>
10
- <th></th>
11
- <th><?php echo ucfirst( $provider ); ?> <?php _e( 'Attributes', 'woo-feed' ); ?></th>
12
- <th><?php _e( 'Prefix', 'woo-feed' ); ?></th>
13
- <th><?php _e( 'Type', 'woo-feed' ); ?></th>
14
- <th><?php _e( 'Value', 'woo-feed' ); ?></th>
15
- <th><?php _e( 'Suffix', 'woo-feed' ); ?></th>
16
- <th><?php _e( 'Output Type', 'woo-feed' ); ?></th>
17
- <th><?php _e( 'Output Limit', 'woo-feed' ); ?></th>
18
- <th></th>
19
- </tr>
20
- </thead>
21
- <tbody>
22
- <tr>
23
- <td>
24
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
25
- </td>
26
- <td>
27
- <select name="mattributes[]" required class="wf_mattributes">
28
- <?php echo $dropDown->googleAttributesDropdown( 'id' ); ?>
29
- </select>
30
- </td>
31
- <td>
32
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
33
- </td>
34
- <td>
35
- <select name="type[]" class="attr_type wfnoempty">
36
- <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
37
- <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
38
- </select>
39
- </td>
40
- <td>
41
- <select name="attributes[]" class="wf_attr wf_attributes">
42
- <?php echo $product->attributeDropdown( 'id' ); ?>
43
- </select>
44
- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;"/>
45
- </td>
46
- <td>
47
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
48
- </td>
49
- <td>
50
- <select name="output_type[][]" class="outputType wfnoempty">
51
- <option value="1">Default</option>
52
- <option value="2">Strip Tags</option>
53
- <option value="3">UTF-8 Encode</option>
54
- <option value="4">htmlentities</option>
55
- <option value="5">Integer</option>
56
- <option value="6">Price</option>
57
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
58
- <option value="8">CDATA</option>
59
- </select>
60
- <i class="dashicons dashicons-editor-expand expandType"></i>
61
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
62
- </td>
63
- <td>
64
- <input type="text" name="limit[]" class="wf_ps"/>
65
- </td>
66
- <td>
67
- <i class="delRow dashicons dashicons-trash"></i>
68
- </td>
69
- </tr>
70
- <tr>
71
- <td>
72
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
73
- </td>
74
- <td>
75
- <select name="mattributes[]" required class="wf_mattributes">
76
- <?php echo $dropDown->googleAttributesDropdown( 'title' ); ?>
77
- </select>
78
- </td>
79
- <td>
80
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
81
- </td>
82
- <td>
83
- <select name="type[]" class="attr_type wfnoempty">
84
- <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
85
- <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
86
- </select>
87
- </td>
88
- <td>
89
- <select name="attributes[]" class="wf_attr wf_attributes">
90
- <?php echo $product->attributeDropdown( 'title' ); ?>
91
- </select>
92
- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;"/>
93
- </td>
94
- <td>
95
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
96
- </td>
97
- <td>
98
- <select name="output_type[][]" class="outputType wfnoempty">
99
- <option value="1">Default</option>
100
- <option value="2">Strip Tags</option>
101
- <option value="3">UTF-8 Encode</option>
102
- <option value="4">htmlentities</option>
103
- <option value="5">Integer</option>
104
- <option value="6">Price</option>
105
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
106
- <option value="8">CDATA</option>
107
- </select>
108
- <i class="dashicons dashicons-editor-expand expandType"></i>
109
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
110
- </td>
111
- <td>
112
- <input type="text" name="limit[]" class="wf_ps"/>
113
- </td>
114
- <td>
115
- <i class="delRow dashicons dashicons-trash"></i>
116
- </td>
117
- </tr>
118
- <tr>
119
- <td>
120
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
121
- </td>
122
- <td>
123
- <select name="mattributes[]" required class="wf_mattributes">
124
- <?php echo $dropDown->googleAttributesDropdown( 'description' ); ?>
125
- </select>
126
- </td>
127
- <td>
128
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
129
- </td>
130
- <td>
131
- <select name="type[]" class="attr_type wfnoempty">
132
- <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
133
- <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
134
- </select>
135
- </td>
136
- <td>
137
- <select name="attributes[]" class="wf_attr wf_attributes">
138
- <?php echo $product->attributeDropdown( 'description' ); ?>
139
- </select>
140
- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;"/>
141
- </td>
142
- <td>
143
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
144
- </td>
145
- <td>
146
- <select name="output_type[][]" class="outputType wfnoempty">
147
- <option value="1">Default</option>
148
- <option selected value="2">Strip Tags</option>
149
- <option value="3">UTF-8 Encode</option>
150
- <option value="4">htmlentities</option>
151
- <option value="5">Integer</option>
152
- <option value="6">Price</option>
153
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
154
- <option value="8">CDATA</option>
155
- </select>
156
- <i class="dashicons dashicons-editor-expand expandType"></i>
157
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
158
- </td>
159
- <td>
160
- <input type="text" name="limit[]" class="wf_ps" value="5000"/>
161
- </td>
162
- <td>
163
- <i class="delRow dashicons dashicons-trash"></i>
164
- </td>
165
- </tr>
166
- <tr>
167
- <td>
168
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
169
- </td>
170
- <td>
171
- <select name="mattributes[]" required class="wf_mattributes">
172
- <?php echo $dropDown->googleAttributesDropdown( 'item_group_id' ); ?>
173
- </select>
174
- </td>
175
- <td>
176
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
177
- </td>
178
- <td>
179
- <select name="type[]" class="attr_type wfnoempty">
180
- <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
181
- <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
182
- </select>
183
- </td>
184
- <td>
185
- <select name="attributes[]" class="wf_attr wf_attributes">
186
- <?php echo $product->attributeDropdown( 'item_group_id' ); ?>
187
- </select>
188
- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;"/>
189
- </td>
190
- <td>
191
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
192
- </td>
193
- <td>
194
- <select name="output_type[][]" class="outputType wfnoempty">
195
- <option value="1">Default</option>
196
- <option value="2">Strip Tags</option>
197
- <option value="3">UTF-8 Encode</option>
198
- <option value="4">htmlentities</option>
199
- <option value="5">Integer</option>
200
- <option value="6">Price</option>
201
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
202
- <option value="8">CDATA</option>
203
- </select>
204
- <i class="dashicons dashicons-editor-expand expandType"></i>
205
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
206
- </td>
207
- <td>
208
- <input type="text" name="limit[]" class="wf_ps"/>
209
- </td>
210
- <td>
211
- <i class="delRow dashicons dashicons-trash"></i>
212
- </td>
213
- </tr>
214
- <tr>
215
- <td>
216
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
217
- </td>
218
- <td>
219
- <select name="mattributes[]" required class="wf_mattributes">
220
- <?php echo $dropDown->googleAttributesDropdown( 'link' ); ?>
221
- </select>
222
- </td>
223
- <td>
224
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
225
- </td>
226
- <td>
227
- <select name="type[]" class="attr_type wfnoempty">
228
- <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
229
- <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
230
- </select>
231
- </td>
232
- <td>
233
- <select name="attributes[]" class="wf_attr wf_attributes">
234
- <?php echo $product->attributeDropdown( 'link' ); ?>
235
- </select>
236
- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;"/>
237
- </td>
238
- <td>
239
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
240
- </td>
241
- <td>
242
- <select name="output_type[][]" class="outputType wfnoempty">
243
- <option value="1">Default</option>
244
- <option value="2">Strip Tags</option>
245
- <option value="3">UTF-8 Encode</option>
246
- <option value="4">htmlentities</option>
247
- <option value="5">Integer</option>
248
- <option value="6">Price</option>
249
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
250
- <option value="8">CDATA</option>
251
- </select>
252
- <i class="dashicons dashicons-editor-expand expandType"></i>
253
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
254
- </td>
255
- <td>
256
- <input type="text" name="limit[]" class="wf_ps"/>
257
- </td>
258
- <td>
259
- <i class="delRow dashicons dashicons-trash"></i>
260
- </td>
261
- </tr>
262
- <tr>
263
- <td>
264
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
265
- </td>
266
- <td>
267
- <select name="mattributes[]" required class="wf_mattributes">
268
- <?php echo $dropDown->googleAttributesDropdown('product_type'); ?>
269
- </select>
270
- </td>
271
- <td>
272
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
273
- </td>
274
- <td>
275
- <select name="type[]" class="attr_type wfnoempty">
276
- <option value="attribute"><?php _e('Attribute','woo-feed');?></option>
277
- <option value="pattern"><?php _e('Pattern','woo-feed');?></option>
278
- </select>
279
- </td>
280
- <td>
281
- <select name="attributes[]" class="wf_attr wf_attributes">
282
- <?php echo $product->attributeDropdown('product_type'); ?>
283
- </select>
284
- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;"/>
285
- </td>
286
- <td>
287
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
288
- </td>
289
- <td>
290
- <select name="output_type[][]" class="outputType wfnoempty">
291
- <option value="1">Default</option>
292
- <option value="2">Strip Tags</option>
293
- <option value="3">UTF-8 Encode</option>
294
- <option value="4">htmlentities</option>
295
- <option value="5">Integer</option>
296
- <option value="6">Price</option>
297
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
298
- <option value="8">CDATA</option>
299
- </select>
300
- <i class="dashicons dashicons-editor-expand expandType"></i>
301
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
302
- </td>
303
- <td>
304
- <input type="text" name="limit[]" class="wf_ps"/>
305
- </td>
306
- <td>
307
- <i class="delRow dashicons dashicons-trash"></i>
308
- </td>
309
- </tr>
310
- <tr>
311
- <td>
312
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
313
- </td>
314
- <td>
315
- <select name="mattributes[]" required class="wf_mattributes">
316
- <?php echo $dropDown->googleAttributesDropdown('current_category'); ?>
317
- </select>
318
- </td>
319
- <td>
320
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
321
- </td>
322
- <td>
323
- <select name="type[]" class="attr_type wfnoempty">
324
- <option value="attribute"><?php _e('Attribute','woo-feed');?></option>
325
- <option value="pattern" selected><?php _e('Pattern','woo-feed');?></option>
326
- </select>
327
- </td>
328
- <!-- <td>-->
329
- <!-- <select name="attributes[]" style=" display: none;" class="wf_attr wf_attributes">-->
330
- <!-- --><?php //echo $product->attributeDropdown(); ?>
331
- <!-- </select>-->
332
- <!-- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" />-->
333
- <!-- <br><span style="font-size:x-small;"><a href="http://webappick.helpscoutdocs.com/article/19-how-to-map-store-category-with-merchant-category" target="_blank">Learn More..</a></span>-->
334
- <!-- </td>-->
335
- <td>
336
- <select name="attributes[]" class="wf_attr wf_attributes" style="display:none;">
337
- <?php echo $product->attributeDropdown( '' ); ?>
338
- </select>
339
- <span class="wf_default wf_attributes">
340
- <select name="default[]" class="selectize">
341
- <?php echo $dropDown->googleTaxonomy(); ?>
342
- </select>
343
- </span>
344
- <span style="font-size:x-small;"><a style="color: red" href="http://webappick.helpscoutdocs.com/article/19-how-to-map-store-category-with-merchant-category" target="_blank">Learn More..</a></span>
345
- </td>
346
- <td>
347
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
348
- </td>
349
- <td>
350
- <select name="output_type[][]" class="outputType wfnoempty">
351
- <option value="1">Default</option>
352
- <option value="2">Strip Tags</option>
353
- <option value="3">UTF-8 Encode</option>
354
- <option value="4">htmlentities</option>
355
- <option value="5">Integer</option>
356
- <option value="6">Price</option>
357
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
358
- <option value="8">CDATA</option>
359
- </select>
360
- <i class="dashicons dashicons-editor-expand expandType"></i>
361
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
362
- </td>
363
- <td>
364
- <input type="text" name="limit[]" class="wf_ps"/>
365
- </td>
366
- <td>
367
- <i class="delRow dashicons dashicons-trash"></i>
368
- </td>
369
- </tr>
370
- <tr>
371
- <td>
372
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
373
- </td>
374
- <td>
375
- <select name="mattributes[]" required class="wf_mattributes">
376
- <?php echo $dropDown->googleAttributesDropdown( 'image' ); ?>
377
- </select>
378
- </td>
379
- <td>
380
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
381
- </td>
382
- <td>
383
- <select name="type[]" class="attr_type wfnoempty">
384
- <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
385
- <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
386
- </select>
387
- </td>
388
- <td>
389
- <select name="attributes[]" class="wf_attr wf_attributes">
390
- <?php echo $product->attributeDropdown( 'image' ); ?>
391
- </select>
392
- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;"/>
393
- </td>
394
- <td>
395
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
396
- </td>
397
- <td>
398
- <select name="output_type[][]" class="outputType wfnoempty">
399
- <option value="1">Default</option>
400
- <option value="2">Strip Tags</option>
401
- <option value="3">UTF-8 Encode</option>
402
- <option value="4">htmlentities</option>
403
- <option value="5">Integer</option>
404
- <option value="6">Price</option>
405
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
406
- <option value="8">CDATA</option>
407
- </select>
408
- <i class="dashicons dashicons-editor-expand expandType"></i>
409
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
410
- </td>
411
- <td>
412
- <input type="text" name="limit[]" class="wf_ps"/>
413
- </td>
414
- <td>
415
- <i class="delRow dashicons dashicons-trash"></i>
416
- </td>
417
- </tr>
418
- <tr>
419
- <td>
420
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
421
- </td>
422
- <td>
423
- <select name="mattributes[]" required class="wf_mattributes">
424
- <?php echo $dropDown->googleAttributesDropdown( 'condition' ); ?>
425
- </select>
426
- </td>
427
- <td>
428
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
429
- </td>
430
- <td>
431
- <select name="type[]" class="attr_type wfnoempty">
432
- <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
433
- <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
434
- </select>
435
- </td>
436
- <td>
437
- <select name="attributes[]" class="wf_attr wf_attributes">
438
- <?php echo $product->attributeDropdown( 'condition' ); ?>
439
- </select>
440
- <input type="text" style=" display: none;" name="default[]" autocomplete="off" class="wf_default wf_attributes"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
441
  />
442
- </td>
443
- <td>
444
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
445
- </td>
446
- <td>
447
- <select name="output_type[][]" class="outputType wfnoempty">
448
- <option value="1">Default</option>
449
- <option value="2">Strip Tags</option>
450
- <option value="3">UTF-8 Encode</option>
451
- <option value="4">htmlentities</option>
452
- <option value="5">Integer</option>
453
- <option value="6">Price</option>
454
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
455
- <option value="8">CDATA</option>
456
- </select>
457
- <i class="dashicons dashicons-editor-expand expandType"></i>
458
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
459
- </td>
460
- <td>
461
- <input type="text" name="limit[]" class="wf_ps"/>
462
- </td>
463
- <td>
464
- <i class="delRow dashicons dashicons-trash"></i>
465
- </td>
466
- </tr>
467
- <tr>
468
- <td>
469
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
470
- </td>
471
- <td>
472
- <select name="mattributes[]" required class="wf_mattributes">
473
- <?php echo $dropDown->googleAttributesDropdown( 'availability' ); ?>
474
- </select>
475
- </td>
476
- <td>
477
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
478
- </td>
479
- <td>
480
- <select name="type[]" class="attr_type wfnoempty">
481
- <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
482
- <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
483
- </select>
484
- </td>
485
- <td>
486
- <select name="attributes[]" class="wf_attr wf_attributes">
487
- <?php echo $product->attributeDropdown( 'availability' ); ?>
488
- </select>
489
- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;"/>
490
- </td>
491
- <td>
492
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
493
- </td>
494
- <td>
495
- <select name="output_type[][]" class="outputType wfnoempty">
496
- <option value="1">Default</option>
497
- <option value="2">Strip Tags</option>
498
- <option value="3">UTF-8 Encode</option>
499
- <option value="4">htmlentities</option>
500
- <option value="5">Integer</option>
501
- <option value="6">Price</option>
502
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
503
- <option value="8">CDATA</option>
504
- </select>
505
- <i class="dashicons dashicons-editor-expand expandType"></i>
506
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
507
- </td>
508
- <td>
509
- <input type="text" name="limit[]" class="wf_ps"/>
510
- </td>
511
- <td>
512
- <i class="delRow dashicons dashicons-trash"></i>
513
- </td>
514
- </tr>
515
- <tr>
516
- <td>
517
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
518
- </td>
519
- <td>
520
- <select name="mattributes[]" required class="wf_mattributes">
521
- <?php echo $dropDown->googleAttributesDropdown( 'price' ); ?>
522
- </select>
523
- </td>
524
- <td>
525
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
526
- </td>
527
- <td>
528
- <select name="type[]" class="attr_type wfnoempty">
529
- <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
530
- <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
531
- </select>
532
- </td>
533
- <td>
534
- <select name="attributes[]" class="wf_attr wf_attributes">
535
- <?php echo $product->attributeDropdown( 'price' ); ?>
536
- </select>
537
- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;"/>
538
- </td>
539
- <td>
540
- <input type="text" name="suffix[]" value="<?php echo get_woocommerce_currency();?>" autocomplete="off" class="wf_ps"/>
541
- </td>
542
- <td>
543
- <select name="output_type[][]" class="outputType wfnoempty">
544
- <option value="1">Default</option>
545
- <option value="2">Strip Tags</option>
546
- <option value="3">UTF-8 Encode</option>
547
- <option value="4">htmlentities</option>
548
- <option value="5">Integer</option>
549
- <option selected value="6">Price</option>
550
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
551
- <option value="8">CDATA</option>
552
- </select>
553
- <i class="dashicons dashicons-editor-expand expandType"></i>
554
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
555
- </td>
556
- <td>
557
- <input type="text" name="limit[]" class="wf_ps"/>
558
- </td>
559
- <td>
560
- <i class="delRow dashicons dashicons-trash"></i>
561
- </td>
562
- </tr>
563
- <tr>
564
- <td>
565
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
566
- </td>
567
- <td>
568
- <select name="mattributes[]" required class="wf_mattributes">
569
- <?php echo $dropDown->googleAttributesDropdown( 'sku' ); ?>
570
- </select>
571
- </td>
572
- <td>
573
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
574
- </td>
575
- <td>
576
- <select name="type[]" class="attr_type wfnoempty">
577
- <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
578
- <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
579
- </select>
580
- </td>
581
- <td>
582
- <select name="attributes[]" class="wf_attr wf_attributes">
583
- <?php echo $product->attributeDropdown( 'sku' ); ?>
584
- </select>
585
- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;"/>
586
- </td>
587
- <td>
588
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
589
- </td>
590
- <td>
591
- <select name="output_type[][]" class="outputType wfnoempty">
592
- <option value="1">Default</option>
593
- <option value="2">Strip Tags</option>
594
- <option value="3">UTF-8 Encode</option>
595
- <option value="4">htmlentities</option>
596
- <option value="5">Integer</option>
597
- <option value="6">Price</option>
598
- <option value="7">Remove Space</option><option value="10">Remove ShortCodes</option><option value="9">Remove Special Character</option>
599
- <option value="8">CDATA</option>
600
- </select>
601
- <i class="dashicons dashicons-editor-expand expandType"></i>
602
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
603
- </td>
604
- <td>
605
- <input type="text" name="limit[]" class="wf_ps"/>
606
- </td>
607
- <td>
608
- <i class="delRow dashicons dashicons-trash"></i>
609
- </td>
610
- </tr>
611
- <tr>
612
- <td>
613
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
614
- </td>
615
- <td>
616
- <select name="mattributes[]" required class="wf_mattributes">
617
- <?php echo $dropDown->googleAttributesDropdown( 'brand' ); ?>
618
- </select>
619
- </td>
620
- <td>
621
- <input type="text" name="prefix[]" autocomplete="off" class="wf_ps"/>
622
- </td>
623
- <td>
624
- <select name="type[]" class="attr_type wfnoempty">
625
- <option value="attribute" ><?php _e( 'Attribute', 'woo-feed' ); ?></option>
626
- <option value="pattern" selected><?php _e( 'Pattern', 'woo-feed' ); ?></option>
627
- </select>
628
- </td>
629
- <td>
630
- <select name="attributes[]" style=" display: none;" class="wf_attr wf_attributes">
631
- <?php echo $product->attributeDropdown(); ?>
632
- </select>
633
- <?php
634
- $url = site_url();
635
- $WABrand = "";
 
 
 
 
 
 
 
 
636
  // Remove all illegal characters from a url
637
- $url = filter_var($url, FILTER_SANITIZE_URL);
638
  // Validate url
639
- if ( filter_var($url, FILTER_VALIDATE_URL) !== false ) {
640
- $url = parse_url($url);
641
- if ( array_key_exists('host',$url) ) {
642
- $arr = explode('.',$url['host']);
643
- $WABrand = $arr[ count($arr) - 2 ];
644
  }
645
  }
646
-
647
- ?>
648
- <input type="text" name="default[]" value="<?php echo $WABrand; ?>" autocomplete="off" class="wf_default wf_attributes"/>
649
- </td>
650
- <td>
651
- <input type="text" name="suffix[]" autocomplete="off" class="wf_ps"/>
652
- </td>
653
- <td>
654
- <select name="output_type[][]" class="outputType wfnoempty">
655
- <option value="1">Default</option>
656
- <option value="2">Strip Tags</option>
657
- <option value="3">UTF-8 Encode</option>
658
- <option value="4">htmlentities</option>
659
- <option value="5">Integer</option>
660
- <option value="6">Price</option>
661
- <option value="7">Remove Space</option>
662
- <option value="10">Remove ShortCodes</option>
663
- <option value="9">Remove Special Character</option>
664
- <option value="8">CDATA</option>
665
- </select>
666
- <i class="dashicons dashicons-editor-expand expandType"></i>
667
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
668
- </td>
669
- <td>
670
- <input type="text" name="limit[]" class="wf_ps"/>
671
- </td>
672
- <td>
673
- <i class="delRow dashicons dashicons-trash"></i>
674
- </td>
675
- </tr>
676
- </tbody>
677
- <tfoot>
678
- <tr>
679
- <td>
680
- <button type="button" class="button-small button-primary" id="wf_newRow">
681
- <?php _e( 'Add New Row', 'woo-feed' ); ?>
682
- </button>
683
- </td>
684
- <td colspan="8">
685
 
686
- </td>
687
- </tr>
688
- </tfoot>
689
- </table>
690
- <table class=" widefat fixed">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
691
  <tr>
692
- <td align="left" class="">
693
- <div class="makeFeedResponse"></div>
694
- <div class="makeFeedComplete"></div>
695
- </td>
696
- <td align="right">
697
- <button type="submit" class="wfbtn"><?php _e( 'Save & Generate Feed', 'woo-feed' ); ?></button>
698
  </td>
 
699
  </tr>
 
700
  </table>
701
- </div>
702
- </li>
703
- <?php include plugin_dir_path(__FILE__) . "../woo-feed-ftp-sftp-template.php"; ?>
704
- </ul>
1
+ <?php
2
+ /**
3
+ * Pinterest Template
4
+ */
5
+ if ( ! defined( 'ABSPATH' ) ) {
6
+ die();
7
+ }
8
+ global $provider;
9
+ ?>
10
+ <table class="table tree widefat fixed sorted_table mtable" style="width: 100%;" id="table-1">
11
+ <thead>
12
+ <tr>
13
+ <th></th>
14
+ <th><?php echo esc_html( ucfirst( $provider ) ); ?> <?php _e( 'Attributes', 'woo-feed' ); ?></th>
15
+ <th><?php _e( 'Prefix', 'woo-feed' ); ?></th>
16
+ <th><?php _e( 'Type', 'woo-feed' ); ?></th>
17
+ <th><?php _e( 'Value', 'woo-feed' ); ?></th>
18
+ <th><?php _e( 'Suffix', 'woo-feed' ); ?></th>
19
+ <th><?php _e( 'Output Type', 'woo-feed' ); ?></th>
20
+ <th><?php _e( 'Command', 'woo-feed' ); ?></th>
21
+ <th></th>
22
+ </tr>
23
+ </thead>
24
+ <tbody>
25
+ <tr>
26
+ <td>
27
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
28
+ </td>
29
+ <td>
30
+ <select name="mattributes[]" required class="wf_mattributes">
31
+ <?php
32
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
33
+ echo $wooFeedDropDown->googleAttributesDropdown( 'id' );
34
+ ?>
35
+ </select>
36
+ </td>
37
+ <td>
38
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
39
+ </td>
40
+ <td>
41
+ <select name="type[]" class="attr_type wfnoempty">
42
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
43
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
44
+ </select>
45
+ </td>
46
+ <td>
47
+ <select name="attributes[]" class="wf_attr wf_attributes">
48
+ <?php
49
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
50
+ echo $wooFeedProduct->attributeDropdown( 'id' );
51
+ ?>
52
+ </select>
53
+ <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;">
54
+ </td>
55
+ <td>
56
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
57
+ </td>
58
+ <td>
59
+ <select name="output_type[][]" class="outputType wfnoempty">
60
+ <?php
61
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
62
+ echo $wooFeedDropDown->outputTypes();
63
+ ?>
64
+ </select>
65
+ <i class="dashicons dashicons-editor-expand expandType"></i>
66
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
67
+ </td>
68
+ <td>
69
+ <input type="text" name="limit[]" autocomplete="off" class="wf_ps">
70
+ </td>
71
+ <td>
72
+ <i class="delRow dashicons dashicons-trash"></i>
73
+ </td>
74
+ </tr>
75
+ <tr>
76
+ <td>
77
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
78
+ </td>
79
+ <td>
80
+ <select name="mattributes[]" required class="wf_mattributes">
81
+ <?php
82
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
83
+ echo $wooFeedDropDown->googleAttributesDropdown( 'title' );
84
+ ?>
85
+ </select>
86
+ </td>
87
+ <td>
88
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
89
+ </td>
90
+ <td>
91
+ <select name="type[]" class="attr_type wfnoempty">
92
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
93
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
94
+ </select>
95
+ </td>
96
+ <td>
97
+ <select name="attributes[]" class="wf_attr wf_attributes">
98
+ <?php
99
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
100
+ echo $wooFeedProduct->attributeDropdown( 'title' );
101
+ ?>
102
+ </select>
103
+ <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;">
104
+ </td>
105
+ <td>
106
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
107
+ </td>
108
+ <td>
109
+ <select name="output_type[][]" class="outputType wfnoempty">
110
+ <?php
111
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
112
+ echo $wooFeedDropDown->outputTypes();
113
+ ?>
114
+ </select>
115
+ <i class="dashicons dashicons-editor-expand expandType"></i>
116
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
117
+ </td>
118
+ <td>
119
+ <input type="text" name="limit[]" autocomplete="off" class="wf_ps">
120
+ </td>
121
+ <td>
122
+ <i class="delRow dashicons dashicons-trash"></i>
123
+ </td>
124
+ </tr>
125
+ <tr>
126
+ <td>
127
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
128
+ </td>
129
+ <td>
130
+ <select name="mattributes[]" required class="wf_mattributes">
131
+ <?php
132
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
133
+ echo $wooFeedDropDown->googleAttributesDropdown( 'description' );
134
+ ?>
135
+ </select>
136
+ </td>
137
+ <td>
138
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
139
+ </td>
140
+ <td>
141
+ <select name="type[]" class="attr_type wfnoempty">
142
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
143
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
144
+ </select>
145
+ </td>
146
+ <td>
147
+ <select name="attributes[]" class="wf_attr wf_attributes">
148
+ <?php
149
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
150
+ echo $wooFeedProduct->attributeDropdown( 'description' );
151
+ ?>
152
+ </select>
153
+ <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;">
154
+ </td>
155
+ <td>
156
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
157
+ </td>
158
+ <td>
159
+ <select name="output_type[][]" class="outputType wfnoempty">
160
+ <?php
161
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
162
+ echo $wooFeedDropDown->outputTypes();
163
+ ?>
164
+ </select>
165
+ <i class="dashicons dashicons-editor-expand expandType"></i>
166
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
167
+ </td>
168
+ <td>
169
+ <input type="text" name="limit[]" autocomplete="off" class="wf_ps">
170
+ </td>
171
+ <td>
172
+ <i class="delRow dashicons dashicons-trash"></i>
173
+ </td>
174
+ </tr>
175
+ <tr>
176
+ <td>
177
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
178
+ </td>
179
+ <td>
180
+ <select name="mattributes[]" required class="wf_mattributes">
181
+ <?php
182
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
183
+ echo $wooFeedDropDown->googleAttributesDropdown( 'item_group_id' );
184
+ ?>
185
+ </select>
186
+ </td>
187
+ <td>
188
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
189
+ </td>
190
+ <td>
191
+ <select name="type[]" class="attr_type wfnoempty">
192
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
193
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
194
+ </select>
195
+ </td>
196
+ <td>
197
+ <select name="attributes[]" class="wf_attr wf_attributes">
198
+ <?php
199
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
200
+ echo $wooFeedProduct->attributeDropdown( 'item_group_id' );
201
+ ?>
202
+ </select>
203
+ <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;">
204
+ </td>
205
+ <td>
206
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
207
+ </td>
208
+ <td>
209
+ <select name="output_type[][]" class="outputType wfnoempty">
210
+ <?php
211
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
212
+ echo $wooFeedDropDown->outputTypes();
213
+ ?>
214
+ </select>
215
+ <i class="dashicons dashicons-editor-expand expandType"></i>
216
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
217
+ </td>
218
+ <td>
219
+ <input type="text" name="limit[]" autocomplete="off" class="wf_ps">
220
+ </td>
221
+ <td>
222
+ <i class="delRow dashicons dashicons-trash"></i>
223
+ </td>
224
+ </tr>
225
+ <tr>
226
+ <td>
227
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
228
+ </td>
229
+ <td>
230
+ <select name="mattributes[]" required class="wf_mattributes">
231
+ <?php
232
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
233
+ echo $wooFeedDropDown->googleAttributesDropdown( 'link' );
234
+ ?>
235
+ </select>
236
+ </td>
237
+ <td>
238
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
239
+ </td>
240
+ <td>
241
+ <select name="type[]" class="attr_type wfnoempty">
242
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
243
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
244
+ </select>
245
+ </td>
246
+ <td>
247
+ <select name="attributes[]" class="wf_attr wf_attributes">
248
+ <?php
249
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
250
+ echo $wooFeedProduct->attributeDropdown( 'link' );
251
+ ?>
252
+ </select>
253
+ <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;">
254
+ </td>
255
+ <td>
256
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
257
+ </td>
258
+ <td>
259
+ <select name="output_type[][]" class="outputType wfnoempty">
260
+ <?php
261
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
262
+ echo $wooFeedDropDown->outputTypes();
263
+ ?>
264
+ </select>
265
+ <i class="dashicons dashicons-editor-expand expandType"></i>
266
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
267
+ </td>
268
+ <td>
269
+ <input type="text" name="limit[]" autocomplete="off" class="wf_ps">
270
+ </td>
271
+ <td>
272
+ <i class="delRow dashicons dashicons-trash"></i>
273
+ </td>
274
+ </tr>
275
+ <tr>
276
+ <td>
277
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
278
+ </td>
279
+ <td>
280
+ <select name="mattributes[]" required class="wf_mattributes">
281
+ <?php
282
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
283
+ echo $wooFeedDropDown->googleAttributesDropdown( 'product_type' );
284
+ ?>
285
+ </select>
286
+ </td>
287
+ <td>
288
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
289
+ </td>
290
+ <td>
291
+ <select name="type[]" class="attr_type wfnoempty">
292
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
293
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
294
+ </select>
295
+ </td>
296
+ <td>
297
+ <select name="attributes[]" class="wf_attr wf_attributes">
298
+ <?php
299
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
300
+ echo $wooFeedProduct->attributeDropdown( 'product_type' );
301
+ ?>
302
+ </select>
303
+ <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;">
304
+ </td>
305
+ <td>
306
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
307
+ </td>
308
+ <td>
309
+ <select name="output_type[][]" class="outputType wfnoempty">
310
+ <?php
311
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
312
+ echo $wooFeedDropDown->outputTypes();
313
+ ?>
314
+ </select>
315
+ <i class="dashicons dashicons-editor-expand expandType"></i>
316
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
317
+ </td>
318
+ <td>
319
+ <input type="text" name="limit[]" autocomplete="off" class="wf_ps">
320
+ </td>
321
+ <td>
322
+ <i class="delRow dashicons dashicons-trash"></i>
323
+ </td>
324
+ </tr>
325
+ <tr>
326
+ <td>
327
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
328
+ </td>
329
+ <td>
330
+ <select name="mattributes[]" required class="wf_mattributes">
331
+ <?php
332
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
333
+ echo $wooFeedDropDown->googleAttributesDropdown( 'current_category' );
334
+ ?>
335
+ </select>
336
+ </td>
337
+ <td>
338
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
339
+ </td>
340
+ <td>
341
+ <select name="type[]" class="attr_type wfnoempty">
342
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
343
+ <option value="pattern" selected><?php _e( 'Pattern', 'woo-feed' ); ?></option>
344
+ </select>
345
+ </td>
346
+ <!-- <td>-->
347
+ <!-- <select name="attributes[]" style=" display: none;" class="wf_attr wf_attributes">-->
348
+ <!-- --><?php // echo $wooFeedProduct->attributeDropdown(); ?>
349
+ <!-- </select>-->
350
+ <!-- <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes">-->
351
+ <!-- <br><span style="font-size:x-small;"><a style="color: red" href="http://webappick.helpscoutdocs.com/article/19-how-to-map-store-category-with-merchant-category" target="_blank">Learn More..</a></span>-->
352
+ <!-- </td>-->
353
+ <td>
354
+ <span class="wf_default wf_attributes">
355
+ <select name="default[]" class="selectize">
356
+ <?php
357
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
358
+ echo $wooFeedDropDown->googleTaxonomy();
359
+ ?>
360
+ </select>
361
+ </span>
362
+ <select name="attributes[]" class="wf_attr wf_attributes" style="display:none;">
363
+ <?php
364
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
365
+ echo $wooFeedProduct->attributeDropdown( '' );
366
+ ?>
367
+ </select>
368
+ <span style="font-size:x-small;"><a style="color: red" href="http://webappick.helpscoutdocs.com/article/19-how-to-map-store-category-with-merchant-category" target="_blank">Learn More..</a></span>
369
+ </td>
370
+ <td>
371
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
372
+ </td>
373
+ <td>
374
+ <select name="output_type[][]" class="outputType wfnoempty">
375
+ <?php
376
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
377
+ echo $wooFeedDropDown->outputTypes();
378
+ ?>
379
+ </select>
380
+ <i class="dashicons dashicons-editor-expand expandType"></i>
381
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
382
+ </td>
383
+ <td>
384
+ <input type="text" name="limit[]" autocomplete="off" class="wf_ps">
385
+ </td>
386
+ <td>
387
+ <i class="delRow dashicons dashicons-trash"></i>
388
+ </td>
389
+ </tr>
390
+ <tr>
391
+ <td>
392
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
393
+ </td>
394
+ <td>
395
+ <select name="mattributes[]" required class="wf_mattributes">
396
+ <?php
397
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
398
+ echo $wooFeedDropDown->googleAttributesDropdown( 'image' );
399
+ ?>
400
+ </select>
401
+ </td>
402
+ <td>
403
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
404
+ </td>
405
+ <td>
406
+ <select name="type[]" class="attr_type wfnoempty">
407
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
408
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
409
+ </select>
410
+ </td>
411
+ <td>
412
+ <select name="attributes[]" class="wf_attr wf_attributes">
413
+ <?php
414
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
415
+ echo $wooFeedProduct->attributeDropdown( 'image' );
416
+ ?>
417
+ </select>
418
+ <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;">
419
+ </td>
420
+ <td>
421
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
422
+ </td>
423
+ <td>
424
+ <select name="output_type[][]" class="outputType wfnoempty">
425
+ <?php
426
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
427
+ echo $wooFeedDropDown->outputTypes();
428
+ ?>
429
+ </select>
430
+ <i class="dashicons dashicons-editor-expand expandType"></i>
431
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
432
+ </td>
433
+ <td>
434
+ <input type="text" name="limit[]" autocomplete="off" class="wf_ps">
435
+ </td>
436
+ <td>
437
+ <i class="delRow dashicons dashicons-trash"></i>
438
+ </td>
439
+ </tr>
440
+ <tr>
441
+ <td>
442
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
443
+ </td>
444
+ <td>
445
+ <select name="mattributes[]" required class="wf_mattributes">
446
+ <?php
447
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
448
+ echo $wooFeedDropDown->googleAttributesDropdown( 'condition' );
449
+ ?>
450
+ </select>
451
+ </td>
452
+ <td>
453
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
454
+ </td>
455
+ <td>
456
+ <select name="type[]" class="attr_type wfnoempty">
457
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
458
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
459
+ </select>
460
+ </td>
461
+ <td>
462
+ <select name="attributes[]" class="wf_attr wf_attributes">
463
+ <?php
464
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
465
+ echo $wooFeedProduct->attributeDropdown( 'condition' );
466
+ ?>
467
+ </select>
468
+ <input type="text" style=" display: none;" name="default[]" autocomplete="off" class="wf_default wf_attributes"
469
  />
470
+ </td>
471
+ <td>
472
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
473
+ </td>
474
+ <td>
475
+ <select name="output_type[][]" class="outputType wfnoempty">
476
+ <?php
477
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
478
+ echo $wooFeedDropDown->outputTypes();
479
+ ?>
480
+ </select>
481
+ <i class="dashicons dashicons-editor-expand expandType"></i>
482
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
483
+ </td>
484
+ <td>
485
+ <input type="text" name="limit[]" autocomplete="off" class="wf_ps">
486
+ </td>
487
+ <td>
488
+ <i class="delRow dashicons dashicons-trash"></i>
489
+ </td>
490
+ </tr>
491
+ <tr>
492
+ <td>
493
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
494
+ </td>
495
+ <td>
496
+ <select name="mattributes[]" required class="wf_mattributes">
497
+ <?php
498
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
499
+ echo $wooFeedDropDown->googleAttributesDropdown( 'availability' );
500
+ ?>
501
+ </select>
502
+ </td>
503
+ <td>
504
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
505
+ </td>
506
+ <td>
507
+ <select name="type[]" class="attr_type wfnoempty">
508
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
509
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
510
+ </select>
511
+ </td>
512
+ <td>
513
+ <select name="attributes[]" class="wf_attr wf_attributes">
514
+ <?php
515
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
516
+ echo $wooFeedProduct->attributeDropdown( 'availability' );
517
+ ?>
518
+ </select>
519
+ <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;">
520
+ </td>
521
+ <td>
522
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
523
+ </td>
524
+ <td>
525
+ <select name="output_type[][]" class="outputType wfnoempty">
526
+ <?php
527
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
528
+ echo $wooFeedDropDown->outputTypes();
529
+ ?>
530
+ </select>
531
+ <i class="dashicons dashicons-editor-expand expandType"></i>
532
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
533
+ </td>
534
+ <td>
535
+ <input type="text" name="limit[]" autocomplete="off" class="wf_ps">
536
+ </td>
537
+ <td>
538
+ <i class="delRow dashicons dashicons-trash"></i>
539
+ </td>
540
+ </tr>
541
+ <tr>
542
+ <td>
543
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
544
+ </td>
545
+ <td>
546
+ <select name="mattributes[]" required class="wf_mattributes">
547
+ <?php
548
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
549
+ echo $wooFeedDropDown->googleAttributesDropdown( 'price' );
550
+ ?>
551
+ </select>
552
+ </td>
553
+ <td>
554
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
555
+ </td>
556
+ <td>
557
+ <select name="type[]" class="attr_type wfnoempty">
558
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
559
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
560
+ </select>
561
+ </td>
562
+ <td>
563
+ <select name="attributes[]" class="wf_attr wf_attributes">
564
+ <?php
565
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
566
+ echo $wooFeedProduct->attributeDropdown( 'price' );
567
+ ?>
568
+ </select>
569
+ <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;">
570
+ </td>
571
+ <td>
572
+ <input type="text" name="suffix[]" value="<?php echo esc_attr( get_woocommerce_currency() ); ?>" autocomplete="off" class="wf_ps">
573
+ </td>
574
+ <td>
575
+ <select name="output_type[][]" class="outputType wfnoempty">
576
+ <?php
577
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
578
+ echo $wooFeedDropDown->outputTypes();
579
+ ?>
580
+ </select>
581
+ <i class="dashicons dashicons-editor-expand expandType"></i>
582
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
583
+ </td>
584
+ <td>
585
+ <input type="text" name="limit[]" autocomplete="off" class="wf_ps">
586
+ </td>
587
+ <td>
588
+ <i class="delRow dashicons dashicons-trash"></i>
589
+ </td>
590
+ </tr>
591
+ <tr>
592
+ <td>
593
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
594
+ </td>
595
+ <td>
596
+ <select name="mattributes[]" required class="wf_mattributes">
597
+ <?php
598
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
599
+ echo $wooFeedDropDown->googleAttributesDropdown( 'sku' );
600
+ ?>
601
+ </select>
602
+ </td>
603
+ <td>
604
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
605
+ </td>
606
+ <td>
607
+ <select name="type[]" class="attr_type wfnoempty">
608
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
609
+ <option value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
610
+ </select>
611
+ </td>
612
+ <td>
613
+ <select name="attributes[]" class="wf_attr wf_attributes">
614
+ <?php
615
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
616
+ echo $wooFeedProduct->attributeDropdown( 'sku' );
617
+ ?>
618
+ </select>
619
+ <input type="text" name="default[]" autocomplete="off" class="wf_default wf_attributes" style=" display: none;">
620
+ </td>
621
+ <td>
622
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
623
+ </td>
624
+ <td>
625
+ <select name="output_type[][]" class="outputType wfnoempty">
626
+ <?php
627
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
628
+ echo $wooFeedDropDown->outputTypes();
629
+ ?>
630
+ </select>
631
+ <i class="dashicons dashicons-editor-expand expandType"></i>
632
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
633
+ </td>
634
+ <td>
635
+ <input type="text" name="limit[]" autocomplete="off" class="wf_ps">
636
+ </td>
637
+ <td>
638
+ <i class="delRow dashicons dashicons-trash"></i>
639
+ </td>
640
+ </tr>
641
+ <tr>
642
+ <td>
643
+ <i class="wf_sortedtable dashicons dashicons-menu"></i>
644
+ </td>
645
+ <td>
646
+ <select name="mattributes[]" required class="wf_mattributes">
647
+ <?php
648
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
649
+ echo $wooFeedDropDown->googleAttributesDropdown( 'brand' );
650
+ ?>
651
+ </select>
652
+ </td>
653
+ <td>
654
+ <input type="text" name="prefix[]" autocomplete="off" class="wf_ps">
655
+ </td>
656
+ <td>
657
+ <select name="type[]" class="attr_type wfnoempty">
658
+ <option value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
659
+ <option value="pattern" selected><?php _e( 'Pattern', 'woo-feed' ); ?></option>
660
+ </select>
661
+ </td>
662
+ <td>
663
+ <select name="attributes[]" style=" display: none;" class="wf_attr wf_attributes">
664
+ <?php
665
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
666
+ echo $wooFeedProduct->attributeDropdown();
667
+ ?>
668
+ </select>
669
+ <?php
670
+ $url = site_url();
671
+ $WABrand = '';
672
  // Remove all illegal characters from a url
673
+ $url = filter_var( $url, FILTER_SANITIZE_URL );
674
  // Validate url
675
+ if ( filter_var( $url, FILTER_VALIDATE_URL ) !== false ) {
676
+ $url = wp_parse_url( $url );
677
+ if ( array_key_exists( 'host', $url ) ) {
678
+ $arr = explode( '.', $url['host'] );
679
+ $WABrand = $arr[ count( $arr ) - 2 ];
680
  }
681
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
682
 
683
+ ?>
684
+ <input type="text" name="default[]" value="<?php echo esc_attr( $WABrand ); ?>" autocomplete="off" class="wf_default wf_attributes">
685
+ </td>
686
+ <td>
687
+ <input type="text" name="suffix[]" autocomplete="off" class="wf_ps">
688
+ </td>
689
+ <td>
690
+ <select name="output_type[][]" class="outputType wfnoempty">
691
+ <?php
692
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
693
+ echo $wooFeedDropDown->outputTypes();
694
+ ?>
695
+ </select>
696
+ <i class="dashicons dashicons-editor-expand expandType"></i>
697
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
698
+ </td>
699
+ <td>
700
+ <input type="text" name="limit[]" class="wf_ps">
701
+ </td>
702
+ <td>
703
+ <i class="delRow dashicons dashicons-trash"></i>
704
+ </td>
705
+ </tr>
706
+ </tbody>
707
+ <tfoot>
708
  <tr>
709
+ <td>
710
+ <button type="button" class="button-small button-primary" id="wf_newRow"><?php _e( 'Add New Row', 'woo-feed' ); ?></button>
 
 
 
 
711
  </td>
712
+ <td colspan="8"></td>
713
  </tr>
714
+ </tfoot>
715
  </table>
 
 
 
 
admin/partials/woo-feed-admin-display.php CHANGED
@@ -1,5 +1,4 @@
1
  <?php
2
-
3
  /**
4
  * Feed Making View
5
  *
@@ -10,45 +9,67 @@
10
  * @subpackage Woo_Feed/admin/partial
11
  * @author Ohidul Islam <wahid@webappick.com>
12
  */
13
-
14
- global $feedRules, $dropDown, $wooFeedProduct, $wp_meta_boxes;
15
- $current_screen = get_current_screen();
16
- $page = $current_screen->id;
17
- $dropDown = new Woo_Feed_Dropdown();
18
- $wooFeedProduct = $product = new Woo_Feed_Products();
19
- $product->load_attributes();
20
- if ( is_null( $feedRules ) ) {
21
- $feedRules = [
22
- 'provider' => '',
23
- 'ftporsftp' => 'ftp',
24
- 'filename' => '',
25
- 'feedType' => '',
26
- 'is_outOfStock' => 'n',
27
- 'is_variations' => 'n',
28
- 'variable_price' => 'first',
29
- 'variable_quantity' => 'first',
30
- 'feedLanguage' => '',
31
- 'feedCurrency' => '',
32
- 'delimiter' => ',',
33
- 'enclosure' => 'double',
34
- 'extraHeader' => '',
35
- ];
 
 
 
36
  }
37
- if ( $feedRules['provider'] == 'adroll' ) $feedRules['provider'] = 'google';
38
  register_and_do_woo_feed_meta_boxes( $current_screen, $feedRules );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  ?>
40
  <div class="wrap wapk-admin" id="Feed">
41
  <div class="wapk-section">
42
- <h1 class="wp-heading-inline"><?php _e('New WooCommerce Product Feed', 'woo-feed'); ?></h1>
43
  </div>
44
  <div class="wapk-section"><?php WPFFWMessage()->displayMessages(); ?></div>
45
  <hr class="wp-header-end">
46
  <div class="wapk-section">
47
  <form action="" name="feed" id="generateFeed" class="generateFeed add-new" method="post" autocomplete="off">
48
- <input type="hidden" name="original_feed_name" value="">
49
  <input type="hidden" name="feed_id" value="">
50
  <?php
51
- wp_nonce_field('woo_feed_form_nonce');
52
  wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false );
53
  wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false );
54
  ?>
@@ -66,5 +87,4 @@ register_and_do_woo_feed_meta_boxes( $current_screen, $feedRules );
66
  </div>
67
  </form>
68
  </div>
69
- </div><!-- /wrap -->
70
-
1
  <?php
 
2
  /**
3
  * Feed Making View
4
  *
9
  * @subpackage Woo_Feed/admin/partial
10
  * @author Ohidul Islam <wahid@webappick.com>
11
  */
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ die();
14
+ }
15
+ /** @define "WOO_FEED_FREE_ADMIN_PATH" "./../" */
16
+ /**
17
+ * globals
18
+ *
19
+ * @global array $feedRules
20
+ * @global Woo_Feed_Dropdown $wooFeedDropDown
21
+ * @global Woo_Feed_Products $wooFeedProduct
22
+ * @global string $feedName
23
+ * @global int $feedId
24
+ * @global string $provider
25
+ * @global array $wp_meta_boxes
26
+ */
27
+ global $feedRules, $wooFeedDropDown, $wooFeedProduct, $feedName, $feedId, $provider, $wp_meta_boxes;
28
+ $feedName = '';
29
+ $feedId = '';
30
+ $current_screen = get_current_screen();
31
+ $page = $current_screen->id;
32
+ $wooFeedDropDown = new Woo_Feed_Dropdown();
33
+ $wooFeedProduct = new Woo_Feed_Products();
34
+ $wooFeedProduct->load_attributes();
35
+ $feedRules = woo_feed_parse_feed_rules( $feedRules );
36
+ if ( 'adroll' == $feedRules['provider'] ) {
37
+ $feedRules['provider'] = 'google';
38
  }
 
39
  register_and_do_woo_feed_meta_boxes( $current_screen, $feedRules );
40
+ $editorTabs = array(
41
+ 'config' => array(
42
+ 'label' => __( 'Feed Config', 'woo-feed' ),
43
+ 'callback' => 'render_feed_config',
44
+ ),
45
+ 'filter' => array(
46
+ 'label' => __( 'Filter', 'woo-feed' ),
47
+ 'callback' => 'render_filter_config',
48
+ ),
49
+ 'advanced-filter' => array(
50
+ 'label' => __( 'Advanced Filter', 'woo-feed' ),
51
+ 'callback' => 'render_advanced_filter_config',
52
+ ),
53
+ 'ftp' => array(
54
+ 'label' => __( 'FTP/SFTP', 'woo-feed' ),
55
+ 'callback' => 'render_ftp_config',
56
+ ),
57
+ );
58
+ $editorTabs = apply_filters( 'woo_feed_editor_tabs', $editorTabs );
59
+ $isEdit = defined( 'WOO_FEED_EDIT_CONFIG' ) && WOO_FEED_EDIT_CONFIG;
60
  ?>
61
  <div class="wrap wapk-admin" id="Feed">
62
  <div class="wapk-section">
63
+ <h1 class="wp-heading-inline"><?php _e( 'New WooCommerce Product Feed', 'woo-feed' ); ?></h1>
64
  </div>
65
  <div class="wapk-section"><?php WPFFWMessage()->displayMessages(); ?></div>
66
  <hr class="wp-header-end">
67
  <div class="wapk-section">
68
  <form action="" name="feed" id="generateFeed" class="generateFeed add-new" method="post" autocomplete="off">
69
+ <input type="hidden" name="feed_option_name" value="">
70
  <input type="hidden" name="feed_id" value="">
71
  <?php
72
+ wp_nonce_field( 'woo_feed_form_nonce' );
73
  wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false );
74
  wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false );
75
  ?>
87
  </div>
88
  </form>
89
  </div>
90
+ </div><!-- /wrap -->
 
admin/partials/woo-feed-config.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
  /**
3
- * Premium vs Free version
4
  *
5
  * @link https://webappick.com/
6
  * @since 1.0.0
@@ -11,8 +11,8 @@
11
  * @author Ohidul Islam <wahid@webappick.com>
12
  */
13
  $batch_limit = (int) get_option( 'woo_feed_per_batch', 200 );
14
- $queryType = get_option('woo_feed_product_query_type' );
15
- if ( ! $queryType || ! in_array( $queryType, [ 'wc', 'wp', 'both' ] ) ) {
16
  $queryType = 'wc';
17
  }
18
  if ( ! $batch_limit || $batch_limit <= 0 ) {
@@ -21,11 +21,9 @@ if ( ! $batch_limit || $batch_limit <= 0 ) {
21
  ?>
22
  <div class="wrap wapk-admin">
23
  <div class="wapk-section">
24
- <h1 class="wp-heading-inline"><?php _e( 'Settings', 'woo-feed' ); ?></h1>
25
- </div>
26
- <hr class="wp-header-end">
27
- <div class="wapk-section"><?php WPFFWMessage()->displayMessages(); ?></div>
28
- <div class="wapk-section">
29
  <form action="" method="post" autocomplete="off">
30
  <?php wp_nonce_field( 'woo-feed-config' ); ?>
31
  <table class="widefat fixed" role="presentation">
@@ -44,7 +42,7 @@ if ( ! $batch_limit || $batch_limit <= 0 ) {
44
  </td>
45
  </tr>
46
  <tr>
47
- <th scope="row"><label for="woo_feed_product_query_type"><?php _e( 'Product Query Type', 'woo-feed'); ?></label></th>
48
  <td>
49
  <select name="woo_feed_product_query_type" id="woo_feed_product_query_type">
50
  <option value="wc" <?php selected( $queryType, 'wc' ); ?> ><?php esc_html_e( 'WC_Product_Query', 'woo-feed' ); ?></option>
@@ -64,8 +62,7 @@ if ( ! $batch_limit || $batch_limit <= 0 ) {
64
  <input type="checkbox" name="enable_error_debugging" id="enable_error_debugging" value="on" <?php checked( woo_feed_is_debugging_enabled(), true ); ?> >
65
  <?php _e( 'Enable Logging', 'woo-feed' ); ?>
66
  </label>
67
- <p class="description"
68
- style="font-size: smaller;color: #ea3d3d;font-weight: bold;"><?php _e( 'Enabling Logging will decrease performance of feed generation.', 'woo-feed' ); ?></p>
69
  </td>
70
  </tr>
71
  <tr>
@@ -75,8 +72,7 @@ if ( ! $batch_limit || $batch_limit <= 0 ) {
75
  <input type="checkbox" name="clear_all_logs" id="clear_all_logs" value="on">
76
  <?php _e( 'Clear All Log Data', 'woo-feed' ); ?>
77
  </label>
78
- <p class="description"
79
- style="font-size: smaller;color: #ea3d3d;font-weight: bold;"><?php _e( 'This will clear all log files generated by this plugin.', 'woo-feed' ); ?></p>
80
  </td>
81
  </tr>
82
  */
@@ -85,21 +81,14 @@ if ( ! $batch_limit || $batch_limit <= 0 ) {
85
  <td><label for="opt_in"><?php _e( 'Send Debug Info', 'woo-feed' ); ?></label></td>
86
  <td>
87
  <label for="opt_in">
88
- <input type="checkbox" name="opt_in" id="opt_in"
89
- value="on" <?php checked( WooFeedWebAppickAPI::getInstance()->is_tracking_allowed(),
90
- true ); ?>>
91
- <?php _e( 'Allow WooFeed To Collect Debug Info.', 'woo-feed' ); ?>
92
  </label>
93
- <p class="description"><?php
94
- _e( 'To opt out, leave this box unchecked. Your Feed Data remains un-tracked, and no data will be collected. No sensitive data is tracked.',
95
- 'woo-feed' );
96
- ?> <a href="#"
97
- data-toggle_slide=".tracker_collection_list"><?php esc_html_e( 'See What We Collect',
98
- 'webappick' ); ?></a>
99
- </p>
100
  <ul class="tracker_collection_list" style="display: none;">
101
- <li><?php echo implode( '</li><li>',
102
- WooFeedWebAppickAPI::getInstance()->get_data_collection_description() ); ?></li>
 
 
103
  </ul>
104
  </td>
105
  </tr>
@@ -107,8 +96,7 @@ if ( ! $batch_limit || $batch_limit <= 0 ) {
107
  <tr>
108
  <td colspan="2">
109
  <p class="submit" style="text-align: center">
110
- <input type="submit" class="button button-primary" name="wa_woo_feed_config"
111
- value="<?php esc_attr_e( 'Save Changes', 'woo-feed' ); ?>">
112
  </p>
113
  </td>
114
  </tr>
@@ -116,5 +104,4 @@ if ( ! $batch_limit || $batch_limit <= 0 ) {
116
  </table>
117
  </form>
118
  </div>
119
- </div>
120
-
1
  <?php
2
  /**
3
+ * Settings Page
4
  *
5
  * @link https://webappick.com/
6
  * @since 1.0.0
11
  * @author Ohidul Islam <wahid@webappick.com>
12
  */
13
  $batch_limit = (int) get_option( 'woo_feed_per_batch', 200 );
14
+ $queryType = get_option( 'woo_feed_product_query_type' );
15
+ if ( ! $queryType || ! in_array( $queryType, array( 'wc', 'wp', 'both' ) ) ) {
16
  $queryType = 'wc';
17
  }
18
  if ( ! $batch_limit || $batch_limit <= 0 ) {
21
  ?>
22
  <div class="wrap wapk-admin">
23
  <div class="wapk-section">
24
+ <h1 class="wp-heading-inline"><?php _e( 'Settings', 'woo-feed' ); ?></h1>
25
+ <hr class="wp-header-end">
26
+ <?php WPFFWMessage()->displayMessages(); ?>
 
 
27
  <form action="" method="post" autocomplete="off">
28
  <?php wp_nonce_field( 'woo-feed-config' ); ?>
29
  <table class="widefat fixed" role="presentation">
42
  </td>
43
  </tr>
44
  <tr>
45
+ <th scope="row"><label for="woo_feed_product_query_type"><?php _e( 'Product Query Type', 'woo-feed' ); ?></label></th>
46
  <td>
47
  <select name="woo_feed_product_query_type" id="woo_feed_product_query_type">
48
  <option value="wc" <?php selected( $queryType, 'wc' ); ?> ><?php esc_html_e( 'WC_Product_Query', 'woo-feed' ); ?></option>
62
  <input type="checkbox" name="enable_error_debugging" id="enable_error_debugging" value="on" <?php checked( woo_feed_is_debugging_enabled(), true ); ?> >
63
  <?php _e( 'Enable Logging', 'woo-feed' ); ?>
64
  </label>
65
+ <p class="description" style="font-size: smaller;color: #ea3d3d;font-weight: bold;"><?php _e( 'Enabling Logging will decrease performance of feed generation.', 'woo-feed' ); ?></p>
 
66
  </td>
67
  </tr>
68
  <tr>
72
  <input type="checkbox" name="clear_all_logs" id="clear_all_logs" value="on">
73
  <?php _e( 'Clear All Log Data', 'woo-feed' ); ?>
74
  </label>
75
+ <p class="description" style="font-size: smaller;color: #ea3d3d;font-weight: bold;"><?php _e( 'This will clear all log files generated by this plugin.', 'woo-feed' ); ?></p>
 
76
  </td>
77
  </tr>
78
  */
81
  <td><label for="opt_in"><?php _e( 'Send Debug Info', 'woo-feed' ); ?></label></td>
82
  <td>
83
  <label for="opt_in">
84
+ <input type="checkbox" id="opt_in" name="opt_in" value="on" <?php checked( WooFeedWebAppickAPI::getInstance()->is_tracking_allowed(), true ); ?>> <?php _e( 'Allow WooFeed To Collect Debug Info.', 'woo-feed' ); ?>
 
 
 
85
  </label>
86
+ <p class="description"><?php esc_html_e( 'To opt out, leave this box unchecked. Your Feed Data remains un-tracked, and no data will be collected. No sensitive data is tracked.', 'woo-feed' ); ?><br><a href="#" data-toggle_slide=".tracker_collection_list"><?php esc_html_e( 'See What We Collect.', 'woo-feed' ); ?></a></p>
 
 
 
 
 
 
87
  <ul class="tracker_collection_list" style="display: none;">
88
+ <li><?php
89
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
90
+ echo implode( '</li><li>', WooFeedWebAppickAPI::getInstance()->get_data_collection_description() );
91
+ ?></li>
92
  </ul>
93
  </td>
94
  </tr>
96
  <tr>
97
  <td colspan="2">
98
  <p class="submit" style="text-align: center">
99
+ <input type="submit" class="button button-primary" name="wa_woo_feed_config" value="<?php esc_attr_e( 'Save Changes', 'woo-feed' ); ?>">
 
100
  </p>
101
  </td>
102
  </tr>
104
  </table>
105
  </form>
106
  </div>
107
+ </div>
 
admin/partials/woo-feed-content-settings.php CHANGED
@@ -1,6 +1,7 @@
1
  <?php
2
  /**
3
  * Content Settings Table
 
4
  * @package WooFeed
5
  * @subpackage Editor
6
  * @version 1.0.0
@@ -8,18 +9,16 @@
8
  * @author KD <mhamudul.hk@gmail.com>
9
  * @copyright 2019 WebAppick <support@webappick.com>
10
  */
11
- if ( ! defined( 'ABSPATH' ) ) die(); // silence
 
 
12
  /**
13
  * @global array $feedRules
14
- * @global Woo_Feed_Dropdown $dropDown
15
  * @global Woo_Feed_Products $wooFeedProduct
16
  */
17
- global $feedRules, $dropDown, $wooFeedProduct;
18
-
19
- if ( empty( $feedRules['feedLanguage'] ) ) $feedRules['feedLanguage'] = apply_filters('wpml_current_language', NULL);
20
- if ( empty( $feedRules['feedCurrency'] ) ) $feedRules['feedCurrency'] = get_woocommerce_currency();
21
-
22
-
23
  ?>
24
  <table class="widefat fixed">
25
  <thead>
@@ -32,7 +31,10 @@ if ( empty( $feedRules['feedCurrency'] ) ) $feedRules['feedCurrency'] = get_wooc
32
  <th><label for="provider"><?php _e('Template', 'woo-feed'); ?> <span class="requiredIn">*</span></label></th>
33
  <td>
34
  <select wftitle="<?php esc_attr_e( 'Select a template', 'woo-feed' ); ?>" name="provider" id="provider" class="generalInput wfmasterTooltip" required>
35
- <?php echo $dropDown->merchantsDropdown( $feedRules['provider'] ); ?>
 
 
 
36
  </select>
37
  </td>
38
  </tr>
@@ -48,13 +50,7 @@ if ( empty( $feedRules['feedCurrency'] ) ) $feedRules['feedCurrency'] = get_wooc
48
  <select name="feedType" id="feedType" class="generalInput" required>
49
  <option value=""></option>
50
  <?php
51
- $feedTypes = [
52
- 'xml' => 'XML',
53
- 'csv' => 'CSV',
54
- 'txt' => 'TXT',
55
- ];
56
- foreach ( $feedTypes as $type => $label ) {
57
- /** @noinspection HtmlUnknownAttribute */
58
  printf( '<option value="%1$s" %3$s>%2$s</option>', esc_attr( $type ), esc_html( $label ), selected( $feedRules['feedType'], $type, false ) );
59
  }
60
  ?>
@@ -65,13 +61,13 @@ if ( empty( $feedRules['feedCurrency'] ) ) $feedRules['feedCurrency'] = get_wooc
65
  <tr class="itemWrapper" style="display: none;">
66
  <th><label for="itemsWrapper"><?php _e('Items Wrapper', 'woo-feed'); ?> <span class="requiredIn">*</span></label></th>
67
  <td>
68
- <input name="itemsWrapper" id="itemsWrapper" type="text" value="<?php echo ($feedRules['feedType'] == "xml") && isset($feedRules['itemsWrapper']) ? esc_attr($feedRules['itemsWrapper']) : 'products'; ?>" class="generalInput" required="required"/>
69
  </td>
70
  </tr>
71
  <tr class="itemWrapper" style="display: none;">
72
  <th><label for="itemWrapper"><?php _e('Single Item Wrapper', 'woo-feed'); ?> <span class="requiredIn">*</span></label></th>
73
  <td>
74
- <input name="itemWrapper" id="itemWrapper" type="text" value="<?php echo ($feedRules['feedType'] == "xml") && isset($feedRules['itemWrapper']) ? esc_attr($feedRules['itemWrapper']) : 'product'; ?>" class="generalInput" required="required"/>
75
  </td>
76
  </tr>
77
  <?php
@@ -88,20 +84,12 @@ if ( empty( $feedRules['feedCurrency'] ) ) $feedRules['feedCurrency'] = get_wooc
88
  */
89
  ?>
90
  <tr class="wf_csvtxt" style="display: none;">
91
- <th><label for="delimiter"><?php _e('Delimiter', 'woo-feed'); ?> <span class="requiredIn">*</span></label></th>
92
  <td>
93
  <select name="delimiter" id="delimiter" class="generalInput">
94
  <?php
95
- $delimiters = [
96
- ',' => 'Comma',
97
- 'tab' => 'Tab',
98
- ':' => 'Colon',
99
- ' ' => 'Space',
100
- '|' => 'Pipe',
101
- ';' => 'Semi Colon',
102
- ];
103
- foreach ( $delimiters as $k => $v ) {
104
- /** @noinspection HtmlUnknownAttribute */
105
  printf( '<option value="%1$s" %3$s>%2$s</option>', esc_attr( $k ), esc_html( $v ), selected( $feedRules['delimiter'], $k, false ) );
106
  }
107
  ?>
@@ -109,16 +97,11 @@ if ( empty( $feedRules['feedCurrency'] ) ) $feedRules['feedCurrency'] = get_wooc
109
  </td>
110
  </tr>
111
  <tr class="wf_csvtxt" style="display: none;">
112
- <th><label for="enclosure"><?php _e('Enclosure', 'woo-feed'); ?> <span class="requiredIn">*</span></label></th>
113
  <td>
114
  <select name="enclosure" id="enclosure" class="generalInput">
115
  <?php
116
- $enclosures = [
117
- 'double' => '"',
118
- 'single' => '\'',
119
- ' ' => 'None',
120
- ];
121
- foreach ( $enclosures as $k => $v ) {
122
  /** @noinspection HtmlUnknownAttribute */
123
  printf( '<option value="%1$s" %3$s>%2$s</option>', esc_attr( $k ), esc_html( $v ), selected( $feedRules['enclosure'], $k, false ) );
124
  }
1
  <?php
2
  /**
3
  * Content Settings Table
4
+ *
5
  * @package WooFeed
6
  * @subpackage Editor
7
  * @version 1.0.0
9
  * @author KD <mhamudul.hk@gmail.com>
10
  * @copyright 2019 WebAppick <support@webappick.com>
11
  */
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ die(); // silence
14
+ }
15
  /**
16
  * @global array $feedRules
17
+ * @global Woo_Feed_Dropdown $wooFeedDropDown
18
  * @global Woo_Feed_Products $wooFeedProduct
19
  */
20
+ global $feedRules, $wooFeedDropDown, $wooFeedProduct;
21
+ $feedRules = woo_feed_parse_feed_rules( $feedRules );
 
 
 
 
22
  ?>
23
  <table class="widefat fixed">
24
  <thead>
31
  <th><label for="provider"><?php _e('Template', 'woo-feed'); ?> <span class="requiredIn">*</span></label></th>
32
  <td>
33
  <select wftitle="<?php esc_attr_e( 'Select a template', 'woo-feed' ); ?>" name="provider" id="provider" class="generalInput wfmasterTooltip" required>
34
+ <?php
35
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
36
+ echo $wooFeedDropDown->merchantsDropdown( $feedRules['provider'] );
37
+ ?>
38
  </select>
39
  </td>
40
  </tr>
50
  <select name="feedType" id="feedType" class="generalInput" required>
51
  <option value=""></option>
52
  <?php
53
+ foreach ( woo_feed_get_file_types() as $type => $label ) {
 
 
 
 
 
 
54
  printf( '<option value="%1$s" %3$s>%2$s</option>', esc_attr( $type ), esc_html( $label ), selected( $feedRules['feedType'], $type, false ) );
55
  }
56
  ?>
61
  <tr class="itemWrapper" style="display: none;">
62
  <th><label for="itemsWrapper"><?php _e('Items Wrapper', 'woo-feed'); ?> <span class="requiredIn">*</span></label></th>
63
  <td>
64
+ <input name="itemsWrapper" id="itemsWrapper" type="text" value="<?php echo ( 'xml' == $feedRules['feedType'] ) && isset( $feedRules['itemsWrapper'] ) ? esc_attr( $feedRules['itemsWrapper'] ) : 'products'; ?>" class="generalInput" required="required">
65
  </td>
66
  </tr>
67
  <tr class="itemWrapper" style="display: none;">
68
  <th><label for="itemWrapper"><?php _e('Single Item Wrapper', 'woo-feed'); ?> <span class="requiredIn">*</span></label></th>
69
  <td>
70
+ <input name="itemWrapper" id="itemWrapper" type="text" value="<?php echo ( 'xml' == $feedRules['feedType'] ) && isset( $feedRules['itemWrapper'] ) ? esc_attr( $feedRules['itemWrapper'] ) : 'product'; ?>" class="generalInput" required="required">
71
  </td>
72
  </tr>
73
  <?php
84
  */
85
  ?>
86
  <tr class="wf_csvtxt" style="display: none;">
87
+ <th><label for="delimiter"><?php _e( 'Delimiter', 'woo-feed' ); ?> <span class="requiredIn">*</span></label></th>
88
  <td>
89
  <select name="delimiter" id="delimiter" class="generalInput">
90
  <?php
91
+
92
+ foreach ( woo_feed_get_csv_delimiters() as $k => $v ) {
 
 
 
 
 
 
 
 
93
  printf( '<option value="%1$s" %3$s>%2$s</option>', esc_attr( $k ), esc_html( $v ), selected( $feedRules['delimiter'], $k, false ) );
94
  }
95
  ?>
97
  </td>
98
  </tr>
99
  <tr class="wf_csvtxt" style="display: none;">
100
+ <th><label for="enclosure"><?php _e( 'Enclosure', 'woo-feed' ); ?> <span class="requiredIn">*</span></label></th>
101
  <td>
102
  <select name="enclosure" id="enclosure" class="generalInput">
103
  <?php
104
+ foreach ( woo_feed_get_csv_enclosure() as $k => $v ) {
 
 
 
 
 
105
  /** @noinspection HtmlUnknownAttribute */
106
  printf( '<option value="%1$s" %3$s>%2$s</option>', esc_attr( $k ), esc_html( $v ), selected( $feedRules['enclosure'], $k, false ) );
107
  }
admin/partials/woo-feed-edit-config.php ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) {
3
+ die();
4
+ }
5
+ ?><table class="table tree widefat fixed sorted_table mtable" style="width: 100%" id="table-1">
6
+ <thead>
7
+ <tr>
8
+ <th></th>
9
+ <th><?php echo esc_html( ucfirst( $provider ) ); ?> <?php _e( 'Attributes', 'woo-feed' ); ?></th>
10
+ <th><?php _e( 'Prefix', 'woo-feed' ); ?></th>
11
+ <th><?php _e( 'Type', 'woo-feed' ); ?></th>
12
+ <th><?php _e( 'Value', 'woo-feed' ); ?></th>
13
+ <th><?php _e( 'Suffix', 'woo-feed' ); ?></th>
14
+ <th><?php _e( 'Output Type', 'woo-feed' ); ?></th>
15
+ <th><?php _e( 'Command', 'woo-feed' ); ?></th>
16
+ <th></th>
17
+ </tr>
18
+ </thead>
19
+ <tbody>
20
+ <?php
21
+ if ( isset( $feedRules['mattributes'] ) && count( $feedRules['mattributes'] ) > 0 ) {
22
+ $mAttributes = $feedRules['mattributes'];
23
+ $wooAttributes = $feedRules['attributes'];
24
+ $type = $feedRules['type'];
25
+ $default = $feedRules['default'];
26
+ $prefix = $feedRules['prefix'];
27
+ $suffix = $feedRules['suffix'];
28
+ $outputType = $feedRules['output_type'];
29
+ $limit = $feedRules['limit'];
30
+ $counter = 0;
31
+ foreach ( $mAttributes as $merchant => $mAttribute ) {
32
+ ?>
33
+ <tr>
34
+ <td><i class="wf_sortedtable dashicons dashicons-menu"></i></td>
35
+ <td>
36
+ <?php if ( method_exists( $wooFeedDropDown, $feedRules['provider'] . 'AttributesDropdown' ) ) { ?>
37
+ <select name="mattributes[]" class="wf_mattributes">
38
+ <?php
39
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
40
+ echo $wooFeedDropDown->{$feedRules['provider'] . 'AttributesDropdown'}( esc_attr( $mAttribute ) );
41
+ ?>
42
+ </select>
43
+ <?php } else { ?>
44
+ <input type="text" name="mattributes[]" value="<?php echo esc_attr( $mAttribute ); ?>" required class="wf_mattributes">
45
+ <?php } ?>
46
+ </td>
47
+ <td>
48
+ <input type="text" name="prefix[]" value="<?php echo esc_attr( stripslashes( $prefix[ $merchant ] ) ); ?>" autocomplete="off" class="wf_ps"/>
49
+ </td>
50
+ <td>
51
+ <select name="type[]" class="attr_type wfnoempty">
52
+ <option <?php echo ( 'attribute' == $type[ $merchant ] ) ? 'selected="selected" ' : ''; ?>value="attribute"><?php _e( 'Attribute', 'woo-feed' ); ?></option>
53
+ <option <?php echo ( 'pattern' == $type[ $merchant ] ) ? 'selected="selected" ' : ''; ?> value="pattern"><?php _e( 'Pattern', 'woo-feed' ); ?></option>
54
+ </select>
55
+ </td>
56
+ <td>
57
+ <select <?php echo ( 'attribute' == $type[ $merchant ] ) ? '' : 'style=" display: none;" '; ?>name="attributes[]" class="wf_attr wf_attributes">
58
+ <?php
59
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
60
+ echo $wooFeedProduct->attributeDropdown( esc_attr( $wooAttributes[ $merchant ] ) );
61
+ ?>
62
+ </select>
63
+ <?php if ( in_array( $feedRules['provider'], array( 'google', 'facebook', 'pinterest' ) ) && 'current_category' == $mAttribute ) { ?>
64
+ <span <?php echo ( 'pattern' == $type[ $merchant ] ) ? '' : 'style=" display: none;" '; ?>class="wf_default wf_attributes">
65
+ <select name="default[]" class="selectize">
66
+ <?php
67
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
68
+ echo $wooFeedDropDown->googleTaxonomy( esc_attr( $default[ $merchant ] ) );
69
+ ?>
70
+ </select>
71
+ </span>
72
+ <span style="font-size:x-small;"><a style="color: red" href="http://webappick.helpscoutdocs.com/article/19-how-to-map-store-category-with-merchant-category" target="_blank">Learn More..</a></span>
73
+ <?php } else { ?>
74
+ <input <?php echo ( 'pattern' == $type[ $merchant ] ) ? '' : 'style=" display: none;"'; ?>autocomplete="off" class="wf_default wf_attributes " type="text" name="default[]" value="<?php echo esc_attr( $default[ $merchant ] ); ?>"/>
75
+ <?php } ?>
76
+ </td>
77
+ <td>
78
+ <input type="text" name="suffix[]" value="<?php echo esc_attr( stripslashes( $suffix[ $merchant ] ) ); ?>" autocomplete="off" class="wf_ps"/>
79
+ </td>
80
+ <td>
81
+ <select name="output_type[<?php echo esc_attr( $counter ); ?>][]" class="outputType wfnoempty" <?php echo ( isset( $outputType[ $counter ] ) && is_array( $outputType[ $counter ] ) && count( $outputType[ $counter ] ) > 1 ) ? 'multiple="multiple"' : ''; ?>>
82
+ <?php
83
+ foreach ( woo_feed_get_field_output_type_options() as $key => $option ) {
84
+ if ( isset( $outputType[ $counter ] ) ) {
85
+ if ( is_array( $outputType[ $counter ] ) ) {
86
+ $selected = in_array( $key, $outputType[ $counter ] );
87
+ } else {
88
+ $selected = $outputType[ $counter ] == $key;
89
+ }
90
+ } else {
91
+ $selected = '1' == $key;
92
+ }
93
+ printf( '<option value="%s" %s>%s</option>', esc_attr( $key ), selected( $selected, true, false ), esc_html( $option ) );
94
+ }
95
+ ?>
96
+ </select>
97
+ <i class="dashicons dashicons-editor-expand expandType"></i>
98
+ <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
99
+ </td>
100
+ <td>
101
+ <input type="text" name="limit[]" value="<?php echo esc_attr( $limit[ $merchant ] ); ?>" autocomplete="off" class="wf_ps"/>
102
+ </td>
103
+ <td>
104
+ <i class="delRow dashicons dashicons-trash"></i>
105
+ </td>
106
+ </tr>
107
+ <?php
108
+ $counter++;
109
+ }
110
+ }
111
+ ?>
112
+ </tbody>
113
+ <tfoot>
114
+ <tr>
115
+ <td colspan="3">
116
+ <button type="button" class="button-small button-primary" id="wf_newRow"><?php _e( 'Add New Row', 'woo-feed' ); ?></button>
117
+ </td>
118
+ <td colspan="6"></td>
119
+ </tr>
120
+ </tfoot>
121
+ </table>
admin/partials/woo-feed-edit-ftp.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) {
3
+ die();
4
+ }
5
+ ?><table class="table widefat fixed mtable woo-feed-ftp">
6
+ <?php if ( ! checkFTP_connection() && ! checkSFTP_connection() ) { ?>
7
+ <tbody>
8
+ <tr>
9
+ <th><?php esc_attr_e( 'FTP/SFTP module is not found in your server. Please contact your service provider or system administrator to install/enable FTP/SFTP module.', 'woo-feed' ); ?></th>
10
+ </tr>
11
+ </tbody>
12
+ <?php } else { ?>
13
+ <tbody>
14
+ <tr>
15
+ <td><label for="ftpenabled"><?php _e( 'Enabled', 'woo-feed' ); ?></label></td>
16
+ <td>
17
+ <select name="ftpenabled" id="ftpenabled">
18
+ <option <?php echo ( '0' == $feedRules['ftpenabled'] ) ? 'selected="selected" ' : ''; ?>value="0"><?php _e( 'Disabled', 'woo-feed' ); ?></option>
19
+ <option <?php echo ( '1' == $feedRules['ftpenabled'] ) ? 'selected="selected" ' : ''; ?>value="1"><?php _e( 'Enabled', 'woo-feed' ); ?></option>
20
+ </select>
21
+ </td>
22
+ </tr>
23
+ <tr>
24
+ <td><label for="ftporsftp"><?php _e( 'Server Type', 'woo-feed' ); ?></label></td>
25
+ <td>
26
+ <select name="ftporsftp" id="ftporsftp" class="ftporsftp">
27
+ <option <?php echo ( 'ftp' == $feedRules['ftporsftp'] ) ? 'selected="selected" ' : ''; ?> value="ftp"><?php _e( 'FTP', 'woo-feed' ); ?></option>
28
+ <option <?php echo ( 'sftp' == $feedRules['ftporsftp'] ) ? 'selected="selected" ' : ''; ?>value="sftp"><?php _e( 'SFTP', 'woo-feed' ); ?></option>
29
+ </select>
30
+ <span class="ssh2_status"></span>
31
+ </td>
32
+ </tr>
33
+ <tr>
34
+ <td><label for="ftphost"><?php _e( 'Host Name', 'woo-feed' ); ?></label></td>
35
+ <td><input type="text" id="ftphost" value="<?php echo esc_attr( $feedRules['ftphost'] ); ?>" name="ftphost" autocomplete="off"/></td>
36
+ </tr>
37
+ <tr>
38
+ <td><label for="ftpport"><?php _e( 'Port', 'woo-feed' ); ?></label></td>
39
+ <td><input type="text" id="ftpport" value="<?php echo isset( $feedRules['ftpport'] ) ? esc_attr( $feedRules['ftpport'] ) : 21; ?>" name="ftpport" autocomplete="off"/></td>
40
+ </tr>
41
+ <tr>
42
+ <td><label for="ftpuser"><?php _e( 'User Name', 'woo-feed' ); ?></label></td>
43
+ <td><input type="text" id="ftpuser" value="<?php echo esc_attr( $feedRules['ftpuser'] ); ?>" name="ftpuser" autocomplete="off"/></td>
44
+ </tr>
45
+ <tr>
46
+ <td><label for="ftppassword"><?php _e( 'Password', 'woo-feed' ); ?></label></td>
47
+ <td><input type="password" id="ftppassword" value="<?php echo esc_attr( $feedRules['ftppassword'] ); ?>" name="ftppassword" autocomplete="off"/></td>
48
+ </tr>
49
+ <tr>
50
+ <td><label for="ftppath"><?php _e( 'Path', 'woo-feed' ); ?></label></td>
51
+ <td><input type="text" id="ftppath" value="<?php echo esc_attr( $feedRules['ftppath'] ); ?>" name="ftppath" autocomplete="off"/></td>
52
+ </tr>
53
+ </tbody>
54
+ <?php } ?>
55
+ </table>
admin/partials/woo-feed-edit-tabs.php ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * globals
4
+ *
5
+ * @global array $feedRules
6
+ * @global Woo_Feed_Dropdown_Pro $wooFeedDropDown
7
+ * @global Woo_Feed_Products $wooFeedProduct
8
+ * @global string $feedName
9
+ * @global int $feedId
10
+ * @global string $provider
11
+ * @global array $wp_meta_boxes
12
+ */
13
+ global $feedRules, $wooFeedDropDown, $wooFeedProduct, $provider;
14
+ $editorTabs = array(
15
+ 'config' => array(
16
+ 'label' => __( 'Feed Config', 'woo-feed' ),
17
+ 'callback' => 'render_feed_config',
18
+ ),
19
+ 'ftp' => array(
20
+ 'label' => __( 'FTP/SFTP', 'woo-feed' ),
21
+ 'callback' => 'render_ftp_config',
22
+ ),
23
+ );
24
+ $editorTabs = apply_filters( 'woo_feed_editor_tabs', $editorTabs );
25
+ $isEdit = defined( 'WOO_FEED_EDIT_CONFIG' ) && WOO_FEED_EDIT_CONFIG;
26
+ ?>
27
+ <ul class="wf_tabs">
28
+ <?php
29
+ foreach ( $editorTabs as $tabId => $tabConfig ) {
30
+ if ( ! isset( $tabConfig['label'], $tabConfig['callback'] ) ) {
31
+ continue;
32
+ }
33
+ if ( ! is_callable( $tabConfig['callback'] ) ) {
34
+ continue;
35
+ }
36
+ ?>
37
+ <li>
38
+ <input type="radio" name="wf_tabs" id="tab-<?php echo esc_attr( $tabId ); ?>"<?php checked( 'config', $tabId ); ?>>
39
+ <label class="wf-tab-name" for="tab-<?php echo esc_attr( $tabId ); ?>"><?php echo esc_html( $tabConfig['label'] ); ?></label>
40
+ <div id="wf-tab-content-<?php echo esc_attr( $tabId ); ?>" class="wf-tab-content">
41
+ <?php
42
+ /**
43
+ * before tab content
44
+ *
45
+ * @param string $tabId
46
+ * @param array $feedRules
47
+ */
48
+ do_action( 'woo_feed_editor_tab_before_content', $tabId, $feedRules );
49
+ /**
50
+ * before tab content
51
+ *
52
+ * @param array $feedRules
53
+ */
54
+ do_action( "woo_feed_editor_tab_before_{$tabId}_content", $feedRules );
55
+ /**
56
+ * Call the render callback for tab
57
+ *
58
+ * @param string $tabId
59
+ * @param array $feedRules
60
+ * @param bool $isEdit
61
+ */
62
+ call_user_func_array(
63
+ $tabConfig['callback'],
64
+ array(
65
+ $tabId, // tab id
66
+ $feedRules, // feed config/rules
67
+ $isEdit, // is edit mode
68
+ )
69
+ );
70
+ /**
71
+ * after tab content
72
+ *
73
+ * @param string $tabId
74
+ * @param array $feedRules
75
+ */
76
+ do_action( 'woo_feed_editor_tab_after_content', $tabId, $feedRules );
77
+ /**
78
+ * after tab content
79
+ *
80
+ * @param array $feedRules
81
+ */
82
+ do_action( "woo_feed_editor_tab_after_{$tabId}_content", $feedRules );
83
+ ?>
84
+ <table class="feed-actions widefat fixed">
85
+ <tr>
86
+ <td class=''>
87
+ <div class="makeFeedResponse"></div>
88
+ <div class="makeFeedComplete"></div>
89
+ </td>
90
+ <td>
91
+ <?php if ( defined( 'WOO_FEED_EDIT_CONFIG' ) && WOO_FEED_EDIT_CONFIG ) { ?>
92
+ <button name="save_feed_config" type="submit" class="wfbtn updatefeed"><?php _e( 'Save', 'woo-feed' ); ?></button>
93
+ <?php } ?>
94
+ <button name="<?php echo isset( $_GET['action'] ) ? esc_attr( sanitize_text_field( $_GET['action'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended ?>" type="submit" class="wfbtn updatefeed"><?php _e( 'Update and Generate Feed', 'woo-feed' ); ?></button>
95
+ </td>
96
+ </tr>
97
+ </table>
98
+ </div>
99
+ </li>
100
+ <?php
101
+ }
102
+ ?>
103
+ </ul>
admin/partials/woo-feed-edit-template.php CHANGED
@@ -9,34 +9,46 @@
9
  * @subpackage Woo_Feed/admin/partial
10
  * @author Ohidul Islam <wahid@webappick.com>
11
  */
12
- global $feedRules, $dropDown, $wooFeedProduct, $fname, $feedId, $provider, $wp_meta_boxes;
13
- $current_screen = get_current_screen();
14
- $page = $current_screen->id;
15
- $dropDown = new Woo_Feed_Dropdown();
16
- $wooFeedProduct = $product = new Woo_Feed_Products();
17
- $product->load_attributes();
18
- # Condition is for those merchants which support another merchant feed requirements.
19
- if ( $feedRules['provider'] == 'adroll' ) {
20
- $feedRules['provider'] = 'google';
21
  }
22
- if ( ! isset($feedRules['ftporsftp']) ) {
23
- $feedRules['ftporsftp'] = "ftp";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  }
25
- $AttributesDropdown = $feedRules['provider'] . "AttributesDropdown";
26
  register_and_do_woo_feed_meta_boxes( $current_screen, $feedRules );
27
  ?>
28
  <!--suppress SpellCheckingInspection, HtmlFormInputWithoutLabel, HtmlDeprecatedAttribute -->
29
  <div class="wrap wapk-admin" id="Feed">
30
  <div class="wapk-section">
31
- <h2><?php _e('Edit WooCommerce Product Feed', 'woo-feed'); ?></h2>
32
  </div>
33
  <div class="wapk-section"><?php WPFFWMessage()->displayMessages(); ?></div>
34
  <div class="wapk-section">
35
  <form action="" name="feed" id="updatefeed" class="generateFeed" method="post" autocomplete="off">
36
- <input type="hidden" name="original_feed_name" value="<?php echo esc_attr( str_replace( [ 'wf_feed_', 'wf_config' ], '', $fname ) ); ?>">
37
  <input type="hidden" name="feed_id" value="<?php echo esc_attr( $feedId ); ?>">
38
  <?php
39
- wp_nonce_field('wf_edit_feed');
40
  wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false );
41
  wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false );
42
  ?>
@@ -50,223 +62,8 @@ register_and_do_woo_feed_meta_boxes( $current_screen, $feedRules );
50
  </div>
51
  </div>
52
  <div class="clear"></div>
53
- <ul class="wf_tabs">
54
- <li>
55
- <input type="radio" name="wf_tabs" id="tab1" checked/>
56
- <label class="wf-tab-name" for="tab1"><?php _e('Feed Config', 'woo-feed'); ?></label>
57
-
58
- <div id="wf-tab-content1" class="wf-tab-content">
59
- <table class="table tree widefat fixed sorted_table mtable" width="100%" id="table-1">
60
- <thead>
61
- <tr>
62
- <th></th>
63
- <th><?php echo ucfirst($provider); ?> <?php _e('Attributes', 'woo-feed'); ?></th>
64
- <th><?php _e('Prefix', 'woo-feed'); ?></th>
65
- <th><?php _e('Type', 'woo-feed'); ?></th>
66
- <th><?php _e('Value', 'woo-feed'); ?></th>
67
- <th><?php _e('Suffix', 'woo-feed'); ?></th>
68
- <th><?php _e('Output Type', 'woo-feed'); ?></th>
69
- <th><?php _e('Output Limit', 'woo-feed'); ?></th>
70
- <th></th>
71
- </tr>
72
- </thead>
73
- <tbody>
74
- <?php
75
- if ( isset( $feedRules['mattributes'] ) && count( $feedRules['mattributes'] ) > 0 ) {
76
- $mAttributes = $feedRules['mattributes'];
77
- $wooAttributes = $feedRules['attributes'];
78
- $type = $feedRules['type'];
79
- $default = $feedRules['default'];
80
- $prefix = $feedRules['prefix'];
81
- $suffix = $feedRules['suffix'];
82
- $outputType = $feedRules['output_type'];
83
- $limit = $feedRules['limit'];
84
- $counter = 0;
85
- foreach ( $mAttributes as $merchant => $mAttribute ) {
86
- ?>
87
- <tr>
88
-
89
- <td>
90
- <i class="wf_sortedtable dashicons dashicons-menu"></i>
91
- </td>
92
- <td>
93
- <?php if ( method_exists($dropDown, $AttributesDropdown) ) { ?>
94
- <select name="mattributes[]" class="wf_mattributes">
95
- <?php echo $dropDown->$AttributesDropdown(esc_attr($mAttribute)); ?>
96
- </select>
97
- <?php } else { ?>
98
- <input type="text" name="mattributes[]"
99
- value="<?php echo esc_attr($mAttribute); ?>"
100
- required
101
- class="wf_mattributes"/>
102
- <?php } ?>
103
- </td>
104
- <td>
105
- <input type="text" name="prefix[]" value="<?php echo stripslashes($prefix[ $merchant ]); ?>" autocomplete="off" class="wf_ps"/>
106
- </td>
107
- <td>
108
- <select name="type[]" class="attr_type wfnoempty">
109
- <option <?php echo ($type[ $merchant ] == "attribute") ? 'selected="selected"' : ''; ?>value="attribute"><?php _e('Attribute', 'woo-feed'); ?></option>
110
- <option <?php echo ($type[ $merchant ] == "pattern") ? 'selected="selected"' : ''; ?>value="pattern"><?php _e('Pattern', 'woo-feed'); ?></option>
111
- </select>
112
- </td>
113
- <td>
114
- <select <?php echo ($type[ $merchant ] == "attribute") ? '' : 'style=" display: none;" '; ?>name="attributes[]" class="wf_attr wf_attributes">
115
- <?php echo $product->attributeDropdown(esc_attr($wooAttributes[ $merchant ])); ?>
116
- </select>
117
- <?php if ( in_array( $feedRules['provider'], array( 'google', 'facebook', 'pinterest' ) ) && $mAttribute == "current_category" ) { ?>
118
- <span <?php echo ($type[ $merchant ] == "pattern") ? '' : 'style=" display: none;"'; ?>class="wf_default wf_attributes">
119
- <select name="default[]" class="selectize">
120
- <?php echo $dropDown->googleTaxonomy( esc_attr($default[ $merchant ]) ); ?>
121
- </select>
122
- </span>
123
- <span style="font-size:x-small;"><a style="color: red" href="http://webappick.helpscoutdocs.com/article/19-how-to-map-store-category-with-merchant-category" target="_blank">Learn More..</a></span>
124
- <?php }else { ?>
125
- <input <?php echo ($type[ $merchant ] == "pattern") ? '' : 'style=" display: none;"'; ?>autocomplete="off" class="wf_default wf_attributes " type="text" name="default[]" value="<?php echo esc_attr( $default[ $merchant ] ); ?>"/>
126
- <?php } ?>
127
- </td>
128
- <td>
129
- <input type="text" name="suffix[]" value="<?php echo stripslashes($suffix[ $merchant ]); ?>" autocomplete="off" class="wf_ps"/>
130
- </td>
131
- <td>
132
- <select name="output_type[<?php echo $counter; ?>][]" class="outputType wfnoempty" <?php echo ( isset( $outputType[ $counter ] ) && is_array( $outputType[ $counter ] ) && count($outputType[ $counter ]) > 1) ? 'multiple="multiple"' : ''; ?>><?php
133
- foreach ( woo_feed_get_field_output_type_options() as $key => $option ) {
134
- if ( isset( $outputType[ $counter ] ) ) {
135
- if ( is_array( $outputType[ $counter ] ) ) {
136
- $selected = selected( in_array( $key, $outputType[ $counter ] ), true, false );
137
- } else {
138
- $selected = selected( $outputType[ $counter ], $key, false );
139
- }
140
- } else $selected = selected( '1', $key, false );
141
- printf( '<option value="%s"%s>%s</option>', $key, $selected, $option );
142
- }
143
- ?></select>
144
- <i class="dashicons dashicons-editor-expand expandType"></i>
145
- <i style="display: none;" class="dashicons dashicons-editor-contract contractType"></i>
146
- </td>
147
- <td>
148
- <input type="text" name="limit[]" value="<?php echo esc_attr($limit[ $merchant ]); ?>" autocomplete="off" class="wf_ps"/>
149
- </td>
150
- <td>
151
- <i class="delRow dashicons dashicons-trash"></i>
152
- </td>
153
- </tr>
154
-
155
- <?php
156
- $counter++;
157
- }
158
- }
159
- ?>
160
-
161
- </tbody>
162
- <tfoot>
163
- <tr>
164
- <td colspan="3">
165
- <button type="button" class="button-small button-primary"
166
- id="wf_newRow"><?php _e('Add New Row', 'woo-feed'); ?>
167
- </button>
168
- </td>
169
- <td colspan="6">
170
-
171
- </td>
172
- </tr>
173
- </tfoot>
174
- </table>
175
- <table class=" widefat fixed">
176
- <tr>
177
- <td align="left" class="">
178
- <div class="makeFeedResponse"></div>
179
- <div class="makeFeedComplete"></div>
180
- </td>
181
- <td align="right">
182
- <button name="save_feed_config" type="submit" class="wfbtn updatefeed"><?php _e('Save', 'woo-feed'); ?></button>
183
- <button name="<?php echo isset($_GET['action']) ? esc_attr($_GET['action']) : ''; ?>" type="submit" class="wfbtn updatefeed"><?php _e('Update and Generate Feed', 'woo-feed'); ?></button>
184
- </td>
185
- </tr>
186
- </table>
187
- </div>
188
- </li>
189
- <li>
190
- <input type="radio" name="wf_tabs" id="tab3"/>
191
- <label class="wf-tab-name" for="tab3"><?php _e('FTP / SFTP', 'woo-feed'); ?></label>
192
-
193
- <div id="wf-tab-content3" class="wf-tab-content">
194
- <table class="table widefat fixed mtable" width="100%">
195
- <?php if ( ! checkFTP_connection() && ! checkSFTP_connection() ) { ?>
196
- <tbody>
197
- <tr>
198
- <th><?php esc_attr_e( 'FTP/SFTP module is not found in your server. Please contact your service provider or system administrator to install/enable FTP/SFTP module.', 'woo-feed' ); ?></th>
199
- </tr>
200
- </tbody>
201
- <?php } else { ?>
202
- <tbody>
203
- <tr>
204
- <td><?php _e('Enabled', 'woo-feed'); ?></td>
205
- <td>
206
- <select name="ftpenabled" >
207
- <option <?php echo ($feedRules['ftpenabled'] == "0") ? 'selected="selected"' : ''; ?>
208
- value="0"><?php _e('Disabled', 'woo-feed'); ?>
209
- </option>
210
- <option <?php echo ($feedRules['ftpenabled'] == "1") ? 'selected="selected"' : ''; ?>
211
- value="1"><?php _e('Enabled', 'woo-feed'); ?>
212
- </option>
213
- </select>
214
- </td>
215
- </tr>
216
- <tr>
217
- <td><?php _e( 'Server Type', 'woo-feed' ); ?></td>
218
- <td>
219
- <select name="ftporsftp" class="ftporsftp">
220
- <option <?php echo ($feedRules['ftporsftp'] == "ftp") ? 'selected="selected"' : ''; ?> value="ftp"><?php _e( 'FTP', 'woo-feed' ); ?></option>
221
- <option <?php echo ($feedRules['ftporsftp'] == "sftp") ? 'selected="selected"' : ''; ?>value="sftp"><?php _e( 'SFTP', 'woo-feed' ); ?></option>
222
- </select>
223
- <span class="ssh2_status"></span>
224
- </td>
225
- </tr>
226
- <tr>
227
- <td><?php _e('Host Name', 'woo-feed'); ?></td>
228
- <td><input type="text" value="<?php echo esc_attr($feedRules['ftphost']); ?>" name="ftphost"
229
- autocomplete="off"/></td>
230
- </tr>
231
- <tr>
232
- <td><?php _e('User Name', 'woo-feed'); ?></td>
233
- <td><input type="text" value="<?php echo esc_attr($feedRules['ftpuser']); ?>" name="ftpuser"
234
- autocomplete="off"/></td>
235
- </tr>
236
- <tr>
237
- <td><?php _e('Password', 'woo-feed'); ?></td>
238
- <td><input type="password" value="<?php echo esc_attr($feedRules['ftppassword']); ?>"
239
- name="ftppassword" autocomplete="off"/></td>
240
- </tr>
241
- <tr>
242
- <td><?php _e('Port', 'woo-feed'); ?></td>
243
- <td><input type="text" value="<?php echo isset($feedRules['ftpport']) ? esc_attr($feedRules['ftpport']) : 21; ?>"
244
- name="ftpport" autocomplete="off"/></td>
245
- </tr>
246
- <tr>
247
- <td><?php _e('Path (Optional)', 'woo-feed'); ?></td>
248
- <td><input type="text" value="<?php echo esc_attr($feedRules['ftppath']); ?>" name="ftppath"
249
- autocomplete="off"/></td>
250
- </tr>
251
- </tbody>
252
- <?php } ?>
253
- </table>
254
- <table class="widefat fixed">
255
- <tr>
256
- <td align="left" class="">
257
- <div class="makeFeedResponse"></div>
258
- <div class="makeFeedComplete"></div>
259
- </td>
260
- <td align="right">
261
- <button name="save_feed_config" type="submit" class="wfbtn updatefeed"><?php _e('Save', 'woo-feed'); ?></button>
262
- <button name="<?php echo isset($_GET['action']) ? esc_attr($_GET['action']) : ''; ?>" type="submit" class="wfbtn updatefeed"><?php _e('Update and Generate Feed', 'woo-feed'); ?></button>
263
- </td>
264
- </tr>
265
- </table>
266
- </div>
267
- </li>
268
- </ul>
269
  </div>
270
  </form>
271
  </div>
272
- </div>
9
  * @subpackage Woo_Feed/admin/partial
10
  * @author Ohidul Islam <wahid@webappick.com>
11
  */
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ die();
 
 
 
 
 
 
 
14
  }
15
+ /** @define "WOO_FEED_PRO_ADMIN_PATH" "./../" */
16
+ /**
17
+ * globals
18
+ *
19
+ * @global array $feedRules
20
+ * @global Woo_Feed_Dropdown $wooFeedDropDown
21
+ * @global Woo_Feed_Products $wooFeedProduct
22
+ * @global string $feedName
23
+ * @global int $feedId
24
+ * @global string $provider
25
+ * @global array $wp_meta_boxes
26
+ */
27
+ global $feedRules, $wooFeedDropDown, $wooFeedProduct, $feedName, $feedId, $provider, $wp_meta_boxes;
28
+ $current_screen = get_current_screen();
29
+ $page = $current_screen->id;
30
+ $wooFeedDropDown = new Woo_Feed_Dropdown();
31
+ $wooFeedProduct = new Woo_Feed_Products();
32
+ $wooFeedProduct->load_attributes();
33
+ // Condition is for those merchants which support another merchant feed requirements.
34
+ $feedRules = woo_feed_parse_feed_rules( $feedRules );
35
+ if ( 'adroll' == $feedRules['provider'] ) {
36
+ $feedRules['provider'] = 'google';
37
  }
 
38
  register_and_do_woo_feed_meta_boxes( $current_screen, $feedRules );
39
  ?>
40
  <!--suppress SpellCheckingInspection, HtmlFormInputWithoutLabel, HtmlDeprecatedAttribute -->
41
  <div class="wrap wapk-admin" id="Feed">
42
  <div class="wapk-section">
43
+ <h2><?php _e( 'Edit WooCommerce Product Feed', 'woo-feed' ); ?></h2>
44
  </div>
45
  <div class="wapk-section"><?php WPFFWMessage()->displayMessages(); ?></div>
46
  <div class="wapk-section">
47
  <form action="" name="feed" id="updatefeed" class="generateFeed" method="post" autocomplete="off">
48
+ <input type="hidden" name="feed_option_name" value="<?php echo esc_attr( str_replace( array( 'wf_feed_', 'wf_config' ), '', $feedName ) ); ?>">
49
  <input type="hidden" name="feed_id" value="<?php echo esc_attr( $feedId ); ?>">
50
  <?php
51
+ wp_nonce_field( 'wf_edit_feed' );
52
  wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false );
53
  wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false );
54
  ?>
62
  </div>
63
  </div>
64
  <div class="clear"></div>
65
+ <?php require_once WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-edit-tabs.php'; ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  </div>
67
  </form>
68
  </div>
69
+ </div>
admin/partials/woo-feed-manage-list.php CHANGED
@@ -11,10 +11,10 @@
11
  */
12
  $myListTable = new Woo_Feed_Manage_list();
13
  $myListTable->prepare_items();
14
- $limit = get_option( "woo_feed_per_batch", 200 );
15
- $fileName = '';
16
- $message = [];
17
- global $regenerating, $regeneratingName;
18
  $regenerating = false;
19
  // phpcs:ignore WordPress.Security.NonceVerification.Recommended
20
  if ( ( isset( $_GET['feed_created'] ) || isset( $_GET['feed_updated'] ) ) && isset( $_GET['feed_regenerate'] ) && 1 == $_GET['feed_regenerate'] ) {
@@ -27,16 +27,16 @@ if ( ( isset( $_GET['feed_created'] ) || isset( $_GET['feed_updated'] ) ) && iss
27
  $regenerating = true;
28
  }
29
 
30
- # Checking woo version to run different version of feed processing
31
- $woo32 = "no";
32
- if ( woo_feed_wc_version_check(3.2) ) {
33
- $woo32 = 'yes';
34
  }
35
  ?>
36
  <div class="wrap wapk-admin">
37
  <div class="wapk-section">
38
- <h1 class="wp-heading-inline"><?php _e('Manage Feed', 'woo-feed'); ?></h1>
39
- <a href="<?php echo esc_url( admin_url('admin.php?page=webappick-new-feed') ); ?>" class="page-title-action"><?php _e('New Feed', 'woo-feed'); ?></a>
40
  <hr class="wp-header-end">
41
  <?php WPFFWMessage()->displayMessages(); ?>
42
  <div id="feed_progress_table" style="display: none;">
@@ -78,14 +78,16 @@ if ( woo_feed_wc_version_check(3.2) ) {
78
  <td>
79
  <form action="" method="post">
80
  <?php wp_nonce_field( 'wf_schedule', 'wf_schedule_nonce' ); ?>
81
- <label for="wf_schedule"><b><?php esc_html_e( 'Interval', 'woo-feed' ); ?></b></label>
82
- <select name="wf_schedule" id="wf_schedule"><?php
83
- $interval = get_option('wf_schedule');
 
84
  foreach ( woo_feed_get_schedule_interval_options() as $k => $v ) {
85
- printf( '<option value="%s" %s>%s</option>', $k, selected( $interval, $k, false ), $v );
86
  }
87
- ?></select>
88
- <button type="submit" class="button button-primary"><?php esc_html_e('Update Interval', 'woo-feed' ); ?></button>
 
89
  </form>
90
  </td>
91
  </tr>
@@ -93,14 +95,15 @@ if ( woo_feed_wc_version_check(3.2) ) {
93
  </table>
94
  <form id="contact-filter" method="post">
95
  <!-- For plugins, we also need to ensure that the form posts back to our current page -->
96
- <input type="hidden" name="page" value="<?php echo esc_attr( $_REQUEST['page'] ); ?>"/>
97
- <?php //$myListTable->search_box('search', 'search_id'); ?>
98
  <!-- Now we can render the completed list table -->
99
- <?php $myListTable->display() ?>
100
  </form>
101
  </div>
 
102
  <script type="text/javascript">
103
- (function( $, window, document, opts ) {
104
  'use strict';
105
  /**
106
  * All of the code for your admin-facing JavaScript source
@@ -122,35 +125,34 @@ if ( woo_feed_wc_version_check(3.2) ) {
122
  */
123
  $( window ).load(function() {
124
  // noinspection ES6ConvertVarToLetConst
125
- var feedProgress = {
126
  table: $( '#feed_progress_table' ),
127
  status: $( '.feed-progress-status' ),
128
  percentage: $( '.feed-progress-percentage' ),
129
  bar: $( '.feed-progress-bar-fill' ),
130
  barProgress: 10, // Variable responsible to hold progress bar width
131
  },
132
- isRegenerating = false,
133
  regenerateBtn = $( '.wpf_regenerate' ),
134
- fileName = "<?php echo isset( $fileName ) ? $fileName : ''; ?>", // wf_config+xxxx
135
- limit = <?php echo ( $limit ) ? $limit : 200; ?>;
136
- let woo32 = "<?php echo $woo32; ?>";
137
  // feed delete alert
138
  $( '.single-feed-delete' ).click( function ( event ) {
139
  //@TODO move to js file with proper i18n entries.
140
  event.preventDefault();
141
- if ( confirm( '<?php _e('Are You Sure to Delete?','woo-feed');?>' ) ) {
142
- var url = jQuery(this).attr('val');
143
- window.location.href = url;
144
  }
145
  });
146
 
147
  // bulk delete alert
148
  $('#doaction, #doaction2').click(function () {
149
  //@TODO move to js file with proper i18n entries.
150
- return confirm('<?php _e('Are You Sure to Delete?','woo-feed'); ?>');
151
  });
152
  // generate feed
153
- if( fileName !== "" ) {
154
  feedProgress.table.show();
155
  generate_feed();
156
  }
@@ -174,11 +176,11 @@ if ( woo_feed_wc_version_check(3.2) ) {
174
  });
175
 
176
  /*#######################################################
177
- #######-------------------------------------------#######
178
- ####### Ajax Feed Making Functions Start #######
179
- #######-------------------------------------------#######
180
- #########################################################
181
- */
182
 
183
  function showFeedProgress( color ){
184
  feedProgress.bar.css( {
@@ -201,12 +203,12 @@ if ( woo_feed_wc_version_check(3.2) ) {
201
  feed: fileName,
202
  limit: limit,
203
  },
204
- success : function(response) {
205
  console.log( response );
206
  if(response.success) {
207
  if (woo32 === 'yes') {
208
  processFeed_v3(response.data.product);
209
- let total = response.data.total;
210
  console.log("Total " + total + " Products found.");
211
  feedProgress.status.text( "Processing Products..." );
212
  } else {
@@ -223,13 +225,13 @@ if ( woo_feed_wc_version_check(3.2) ) {
223
  }
224
  });
225
  }
226
- function processFeed_v3(batches, n) {
227
- let totalBatch = batches.length;
228
- let progressBatch = 90 / totalBatch;
229
- if (typeof(n) === 'undefined') n = 0;
230
 
231
- let batch = batches[n];
232
- let productBatch = n + 1;
233
  feedProgress.status.text( "Processing Batch " + productBatch + " of " + totalBatch);
234
  showFeedProgress();
235
  console.log( "Processing Batch " + productBatch + " of " + totalBatch );
@@ -270,8 +272,7 @@ if ( woo_feed_wc_version_check(3.2) ) {
270
  function processFeed( n, offset, batch ) {
271
  if ( typeof( offset ) === 'undefined' ) offset = 0;
272
  if ( typeof( batch ) === 'undefined' ) batch = 0;
273
- var batches = Math.ceil( n/limit ),
274
- progressBatch = 90 / batches;
275
  console.log( ( limit*batch ) + " out of " + n + " products processed." );
276
  feedProgress.status.text( "Processing products..." + Math.round( feedProgress.barProgress ) + "%" );
277
  if( batch < batches ) {
@@ -330,11 +331,7 @@ if ( woo_feed_wc_version_check(3.2) ) {
330
  * Save feed file into WordPress upload directory
331
  * after successfully processing the feed
332
  */
333
- function save_feed_file(){
334
- // polylang codes
335
- // var params = window.location.search.slice(1);
336
- // var searchParam = new URLSearchParams(params);
337
- // var old_lang = searchParam.get('old_lang');
338
  $.ajax({
339
  url : opts.wpf_ajax_url,
340
  type : 'post',
@@ -351,10 +348,7 @@ if ( woo_feed_wc_version_check(3.2) ) {
351
  feedProgress.status.text( response.data.message );
352
  regenerateBtn.val( 'Regenerate' );
353
  regenerateBtn.disabled( false );
354
- // var default_polylang = (response.data.default_polylang) ? response.data.default_polylang : '';
355
- window.location.href = "<?php echo admin_url( 'admin.php?page=webappick-manage-feeds&WPFP_WPML_CURLANG=yes&link=' ); ?>" + response.data.url + "&cat=" + response.data.cat;
356
- // Polylang code
357
- // window.location.href = "<?php // echo admin_url('admin.php?WPFP_WPML_CURLANG=yes&page=webappick-manage-feeds&link='); ?>"+url+"&cat="+cat + "&lang=" + old_lang;
358
  }else{
359
  showFeedProgress( "red" );
360
  feedProgress.status.text( response.data.message );
@@ -368,20 +362,12 @@ if ( woo_feed_wc_version_check(3.2) ) {
368
  }
369
 
370
  /*########################################################
371
- #######-------------------------------------------#######
372
- ####### Ajax Feed Making Functions End #######
373
- #######-------------------------------------------#######
374
- #########################################################
375
- */
376
  });
377
- /**
378
- * ...and/or other possibilities.
379
- *
380
- * Ideally, it is not considered best practise to attach more than a
381
- * single DOM-ready or window-load handler for a particular page.
382
- * Although scripts in the WordPress core, Plugins and Themes may be
383
- * practising this, we should strive to set a better example in our own work.
384
- */
385
  })( jQuery, window, document, wpf_ajax_obj );
386
  </script>
387
- </div>
11
  */
12
  $myListTable = new Woo_Feed_Manage_list();
13
  $myListTable->prepare_items();
14
+ $limit = get_option( 'woo_feed_per_batch', 200 );
15
+ $fileName = '';
16
+ $message = array();
17
+ global $regenerating, $regeneratingName, $plugin_page;
18
  $regenerating = false;
19
  // phpcs:ignore WordPress.Security.NonceVerification.Recommended
20
  if ( ( isset( $_GET['feed_created'] ) || isset( $_GET['feed_updated'] ) ) && isset( $_GET['feed_regenerate'] ) && 1 == $_GET['feed_regenerate'] ) {
27
  $regenerating = true;
28
  }
29
 
30
+ // Checking woo version to run different version of feed processing
31
+ $woo32 = 'no';
32
+ if ( woo_feed_wc_version_check( 3.2 ) ) {
33
+ $woo32 = 'yes';
34
  }
35
  ?>
36
  <div class="wrap wapk-admin">
37
  <div class="wapk-section">
38
+ <h1 class="wp-heading-inline"><?php _e( 'Manage Feed', 'woo-feed' ); ?></h1>
39
+ <a href="<?php echo esc_url( admin_url( 'admin.php?page=webappick-new-feed' ) ); ?>" class="page-title-action"><?php _e( 'New Feed', 'woo-feed' ); ?></a>
40
  <hr class="wp-header-end">
41
  <?php WPFFWMessage()->displayMessages(); ?>
42
  <div id="feed_progress_table" style="display: none;">
78
  <td>
79
  <form action="" method="post">
80
  <?php wp_nonce_field( 'wf_schedule', 'wf_schedule_nonce' ); ?>
81
+ <label for="wf_schedule"><b><?php _e( 'Interval', 'woo-feed' ); ?></b></label>
82
+ <select name="wf_schedule" id="wf_schedule">
83
+ <?php
84
+ $interval = get_option( 'wf_schedule' );
85
  foreach ( woo_feed_get_schedule_interval_options() as $k => $v ) {
86
+ printf( '<option value="%s" %s>%s</option>', esc_attr( $k ), selected( $interval, $k, false ), esc_html( $v ) );
87
  }
88
+ ?>
89
+ </select>
90
+ <button type="submit" class="button button-primary"><?php esc_html_e( 'Update Interval', 'woo-feed' ); ?></button>
91
  </form>
92
  </td>
93
  </tr>
95
  </table>
96
  <form id="contact-filter" method="post">
97
  <!-- For plugins, we also need to ensure that the form posts back to our current page -->
98
+ <input type="hidden" name="page" value="<?php echo esc_attr( $plugin_page ); ?>"/>
99
+ <?php // $myListTable->search_box('search', 'search_id'); ?>
100
  <!-- Now we can render the completed list table -->
101
+ <?php $myListTable->display(); ?>
102
  </form>
103
  </div>
104
+ <!--suppress JSUnresolvedVariable, ES6ConvertVarToLetConst -->
105
  <script type="text/javascript">
106
+ (function( $, window, document, opts ) {
107
  'use strict';
108
  /**
109
  * All of the code for your admin-facing JavaScript source
125
  */
126
  $( window ).load(function() {
127
  // noinspection ES6ConvertVarToLetConst
128
+ var feedProgress = {
129
  table: $( '#feed_progress_table' ),
130
  status: $( '.feed-progress-status' ),
131
  percentage: $( '.feed-progress-percentage' ),
132
  bar: $( '.feed-progress-bar-fill' ),
133
  barProgress: 10, // Variable responsible to hold progress bar width
134
  },
135
+ isRegenerating = false,
136
  regenerateBtn = $( '.wpf_regenerate' ),
137
+ fileName = "<?php echo isset( $fileName ) ? esc_attr( $fileName ) : ''; ?>", // wf_config+xxxx
138
+ limit = <?php echo ( $limit ) ? absint( $limit ) : 200; ?>;
139
+ var woo32 = "<?php echo esc_attr( $woo32 ); ?>";
140
  // feed delete alert
141
  $( '.single-feed-delete' ).click( function ( event ) {
142
  //@TODO move to js file with proper i18n entries.
143
  event.preventDefault();
144
+ if ( confirm( '<?php _e( 'Are You Sure to Delete?', 'woo-feed' ); ?>' ) ) {
145
+ window.location.href = jQuery(this).attr('val');
 
146
  }
147
  });
148
 
149
  // bulk delete alert
150
  $('#doaction, #doaction2').click(function () {
151
  //@TODO move to js file with proper i18n entries.
152
+ return confirm('<?php _e( 'Are You Sure to Delete?', 'woo-feed' ); ?>');
153
  });
154
  // generate feed
155
+ if( fileName !== '' ) {
156
  feedProgress.table.show();
157
  generate_feed();
158
  }
176
  });
177
 
178
  /*#######################################################
179
+ #######-------------------------------------------#######
180
+ ####### Ajax Feed Making Functions Start #######
181
+ #######-------------------------------------------#######
182
+ #########################################################
183
+ */
184
 
185
  function showFeedProgress( color ){
186
  feedProgress.bar.css( {
203
  feed: fileName,
204
  limit: limit,
205
  },
206
+ success : function( response ) {
207
  console.log( response );
208
  if(response.success) {
209
  if (woo32 === 'yes') {
210
  processFeed_v3(response.data.product);
211
+ var total = response.data.total;
212
  console.log("Total " + total + " Products found.");
213
  feedProgress.status.text( "Processing Products..." );
214
  } else {
225
  }
226
  });
227
  }
228
+ function processFeed_v3( batches, n ) {
229
+ var totalBatch = batches.length;
230
+ var progressBatch = 90 / totalBatch;
231
+ if ( typeof(n) === 'undefined' ) n = 0;
232
 
233
+ var batch = batches[n];
234
+ var productBatch = n + 1;
235
  feedProgress.status.text( "Processing Batch " + productBatch + " of " + totalBatch);
236
  showFeedProgress();
237
  console.log( "Processing Batch " + productBatch + " of " + totalBatch );
272
  function processFeed( n, offset, batch ) {
273
  if ( typeof( offset ) === 'undefined' ) offset = 0;
274
  if ( typeof( batch ) === 'undefined' ) batch = 0;
275
+ var batches = Math.ceil( n/limit ), progressBatch = 90 / batches;
 
276
  console.log( ( limit*batch ) + " out of " + n + " products processed." );
277
  feedProgress.status.text( "Processing products..." + Math.round( feedProgress.barProgress ) + "%" );
278
  if( batch < batches ) {
331
  * Save feed file into WordPress upload directory
332
  * after successfully processing the feed
333
  */
334
+ function save_feed_file() {
 
 
 
 
335
  $.ajax({
336
  url : opts.wpf_ajax_url,
337
  type : 'post',
348
  feedProgress.status.text( response.data.message );
349
  regenerateBtn.val( 'Regenerate' );
350
  regenerateBtn.disabled( false );
351
+ window.location.href = "<?php echo esc_url( admin_url( 'admin.php?page=webappick-manage-feeds' ) ); ?>&link=" + response.data.url + "&cat=" + response.data.cat;
 
 
 
352
  }else{
353
  showFeedProgress( "red" );
354
  feedProgress.status.text( response.data.message );
362
  }
363
 
364
  /*########################################################
365
+ #######-------------------------------------------#######
366
+ ####### Ajax Feed Making Functions End #######
367
+ #######-------------------------------------------#######
368
+ #########################################################
369
+ */
370
  });
 
 
 
 
 
 
 
 
371
  })( jQuery, window, document, wpf_ajax_obj );
372
  </script>
373
+ </div>
admin/partials/woo-feed-pro-vs-free.php CHANGED
@@ -341,7 +341,7 @@ $testimonials = array(
341
  <?php } ?>
342
  </div>
343
  <div class="feed-features__more">
344
- <a class="wapk-button wapk-button-primary wapk-button-hero" href="https://webappick.com/plugin/woocommerce-product-feed-pro/" target="_blank">See All Features <svg aria-hidden="true" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 17.5 12.5" xml:space="preserve"><path d="M10.6,1.5c-0.4-0.4-0.4-0.9,0-1.3c0.4-0.3,0.9-0.3,1.3,0l5.3,5.3c0.2,0.2,0.3,0.4,0.3,0.7s-0.1,0.5-0.3,0.7 l-5.3,5.3c-0.4,0.4-0.9,0.4-1.3,0c-0.4-0.4-0.4-0.9,0-1.3l3.8-3.8H0.9C0.4,7.1,0,6.7,0,6.2s0.4-0.9,0.9-0.9h13.5L10.6,1.5z M10.6,1.5"></path></svg></a>
345
  </div>
346
  </div>
347
  <div class="clear"></div>
@@ -356,7 +356,10 @@ $testimonials = array(
356
  <img src="<?php echo esc_url( WOO_FEED_PLUGIN_URL ); ?>admin/images/woo-feed-lite.svg" alt="<?php esc_attr_e( 'WooFeed Lite', 'woo-feed' ); ?>">
357
  </div>
358
  <ul class="product-features">
359
- <?php print( $compareTableFreeFeatures ); ?>
 
 
 
360
  </ul>
361
  </div>
362
  <div class="comparison pro">
@@ -364,7 +367,10 @@ $testimonials = array(
364
  <img src="<?php echo esc_url( WOO_FEED_PLUGIN_URL ); ?>admin/images/woo-feed-pro.svg" alt="<?php esc_attr_e( 'WooFeed Pro', 'woo-feed' ); ?>">
365
  </div>
366
  <ul class="product-features">
367
- <?php print( $compareTableProFeatures ); ?>
 
 
 
368
  </ul>
369
  </div>
370
  </div>
@@ -392,22 +398,23 @@ $testimonials = array(
392
  <span class="wapk-price__table__currency"><?php echo esc_html( $price['currency'] ); ?></span>
393
  <?php } ?>
394
  <span class="wapk-price__table__amount"><?php
395
- if ( $integer == 0 && $decimal == 0 ) printf( '<span class="free">%s</span>', esc_html_x( 'Free', 'Free Package Price Display', 'woo-feed' ) );
396
  if ( $integer > 0 || $decimal > 0 ) printf( '<span class="integer-part">%d</span>', esc_html( $integer ) );
397
- if ( $decimal > 0 ) printf( '<span class="decimal-part">.%d</span>', esc_html( $integer ) );
398
- if ( ! empty( $price['period'] ) ) printf( '<span class="period">/%s</span>', $price['period'] );
399
  ?></span>
400
  <?php if ( ! empty( $price['allowed_domain'] ) ) {
401
  if ( is_numeric( $price['allowed_domain'] ) ) {
402
  $allowed = sprintf(
403
- _n( 'For %d Site', 'For %d Sites', $price['allowed_domain'], 'woo-feed' ),
404
- $price['allowed_domain']
 
405
  );
406
- } else $allowed = esc_html( $price['allowed_domain'] );
407
- printf( '<span class="wapk-price__table__amount___legend">%s</span>', $allowed );
408
  } ?>
409
  </div>
410
- <?php printf( '<ul class="wapk-price__table__features">%s</ul>', $pricingFeatures ); ?>
411
  <div class="wapk-price__table__footer">
412
  <a href="<?php echo esc_url( $price['cart_url'] . '&utm_source=freePlugin&utm_medium=go_premium&utm_campaign=free_to_pro&utm_term=wooFeed' ); ?>" class="wapk-button wapk-button-primary wapk-button-hero" target="_blank"><?php esc_html_e( 'Buy Now', 'woo-feed' ); ?></a>
413
  </div>
341
  <?php } ?>
342
  </div>
343
  <div class="feed-features__more">
344
+ <a class="wapk-button wapk-button-primary wapk-button-hero" href="https://webappick.com/plugin/woocommerce-product-feed-pro/" target="_blank"><?php esc_html_e( 'See All Features', 'woo-feed' ); ?> <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 17.5 12.5" xml:space="preserve"><path d="M10.6,1.5c-0.4-0.4-0.4-0.9,0-1.3c0.4-0.3,0.9-0.3,1.3,0l5.3,5.3c0.2,0.2,0.3,0.4,0.3,0.7s-0.1,0.5-0.3,0.7 l-5.3,5.3c-0.4,0.4-0.9,0.4-1.3,0c-0.4-0.4-0.4-0.9,0-1.3l3.8-3.8H0.9C0.4,7.1,0,6.7,0,6.2s0.4-0.9,0.9-0.9h13.5L10.6,1.5z M10.6,1.5"></path></svg></a>
345
  </div>
346
  </div>
347
  <div class="clear"></div>
356
  <img src="<?php echo esc_url( WOO_FEED_PLUGIN_URL ); ?>admin/images/woo-feed-lite.svg" alt="<?php esc_attr_e( 'WooFeed Lite', 'woo-feed' ); ?>">
357
  </div>
358
  <ul class="product-features">
359
+ <?php
360
+ // Data already escaped.
361
+ echo $compareTableFreeFeatures; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
362
+ ?>
363
  </ul>
364
  </div>
365
  <div class="comparison pro">
367
  <img src="<?php echo esc_url( WOO_FEED_PLUGIN_URL ); ?>admin/images/woo-feed-pro.svg" alt="<?php esc_attr_e( 'WooFeed Pro', 'woo-feed' ); ?>">
368
  </div>
369
  <ul class="product-features">
370
+ <?php
371
+ // Data already escaped.
372
+ echo $compareTableProFeatures; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
373
+ ?>
374
  </ul>
375
  </div>
376
  </div>
398
  <span class="wapk-price__table__currency"><?php echo esc_html( $price['currency'] ); ?></span>
399
  <?php } ?>
400
  <span class="wapk-price__table__amount"><?php
401
+ if ( 0 == $integer && 0 == $decimal ) printf( '<span class="free">%s</span>', esc_html_x( 'Free', 'Free Package Price Display', 'woo-feed' ) );
402
  if ( $integer > 0 || $decimal > 0 ) printf( '<span class="integer-part">%d</span>', esc_html( $integer ) );
403
+ if ( $decimal > 0 ) printf( '<span class="decimal-part">.%d</span>', esc_html( $decimal ) );
404
+ if ( ! empty( $price['period'] ) ) printf( '<span class="period">/%s</span>', esc_html( $price['period'] ) );
405
  ?></span>
406
  <?php if ( ! empty( $price['allowed_domain'] ) ) {
407
  if ( is_numeric( $price['allowed_domain'] ) ) {
408
  $allowed = sprintf(
409
+ /* translators: %d: number of allowed domain. */
410
+ _n( 'For %d Site', 'For %d Sites', $price['allowed_domain'], 'woo-feed' ),
411
+ $price['allowed_domain']
412
  );
413
+ } else $allowed = $price['allowed_domain'];
414
+ printf( '<span class="wapk-price__table__amount___legend">%s</span>', esc_html( $allowed ) );
415
  } ?>
416
  </div>
417
+ <?php printf( '<ul class="wapk-price__table__features">%s</ul>', $pricingFeatures ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
418
  <div class="wapk-price__table__footer">
419
  <a href="<?php echo esc_url( $price['cart_url'] . '&utm_source=freePlugin&utm_medium=go_premium&utm_campaign=free_to_pro&utm_term=wooFeed' ); ?>" class="wapk-button wapk-button-primary wapk-button-hero" target="_blank"><?php esc_html_e( 'Buy Now', 'woo-feed' ); ?></a>
420
  </div>
includes/class-woo-feed-docs.php CHANGED
@@ -1,6 +1,7 @@
1
  <?php
2
  /**
3
  * Feed Docs Page Renderer
 
4
  * @version 1.0.0
5
  * @package WooFeed
6
  * @since 3.1.36
@@ -12,26 +13,33 @@ if ( ! class_exists( 'WooFeedDocs' ) ) {
12
  class WooFeedDocs {
13
  /**
14
  * Singleton instance holder
 
15
  * @var WooFeedDocs
16
  */
17
  private static $instance;
18
-
19
  /**
20
  * Get Class Instance
 
21
  * @return WooFeedDocs
22
  */
23
  public static function getInstance() {
24
- if ( self::$instance === null ) self::$instance = new self();
 
 
 
25
  return self::$instance;
26
  }
 
27
  private function __construct() {
28
  add_filter( 'removable_query_args', array( $this, 'filter_removable_query_args' ), 10, 1 );
29
  }
30
-
31
  /**
32
  * Render Docs Page
33
- * @see Woo_Feed_Admin::load_admin_pages()
34
  * @return void
 
35
  */
36
  function woo_feed_docs() {
37
  $faqs = $this->__get_feed_help();
@@ -45,29 +53,41 @@ if ( ! class_exists( 'WooFeedDocs' ) ) {
45
  </div>
46
  <?php if ( ! empty( $faqs ) ) { ?>
47
  <div class="wapk-section">
48
- <?php foreach ( $faqs as $faq ) {
 
49
  $boxId = ( isset( $faq->id ) ) ? $faq->id : sanitize_title( $faq->title );
50
- ?>
51
  <div id="<?php echo esc_attr( $boxId ); ?>" class="postbox <?php echo esc_attr( postbox_classes( $boxId, $current_screen->id ) ); ?>">
52
  <button type="button" class="handlediv" aria-expanded="true">
53
- <span class="screen-reader-text"><?php printf( esc_html__( 'Toggle panel: %s', 'woo-feed' ), $faq->title ) ?></span>
 
 
 
 
 
54
  <span class="toggle-indicator" aria-hidden="true"></span>
55
  </button>
56
- <h2 class="hndle"><?php if ( isset( $faq->icon ) && ! empty( $faq->icon ) ) {
57
- ?><span class="<?php printf( '%s%s',
58
- ( strpos( $faq->icon, 'dashicons' ) !== false ) ? 'dashicons ' : '',
59
- esc_attr( $faq->icon ) ); ?>" aria-hidden="true"></span> <?php
60
- } ?><span><?php echo esc_html( $faq->title ); ?></span></h2>
 
 
 
 
61
  <div class="inside">
62
  <div class="main">
63
  <ul>
64
  <?php foreach ( $faq->questions as $qa ) { ?>
65
  <li>
66
- <span class="<?php if ( isset( $qa->icon ) ) {
67
- printf( '%s%s',
68
- ( strpos( $qa->icon, 'dashicons' ) !== false ) ? 'dashicons ' : '',
69
- esc_attr( $qa->icon ) );
70
- } else { ?>dashicons dashicons-media-text<?php } ?>" aria-hidden="true"></span>
 
 
71
  <a href="<?php echo esc_url( $qa->link ); ?>" target="_blank"><?php echo esc_html( $qa->title ); ?></a>
72
  </li>
73
  <?php } ?>
@@ -85,59 +105,99 @@ if ( ! class_exists( 'WooFeedDocs' ) ) {
85
  </div>
86
  <div class="wapk-cta-content">
87
  <h2><?php _e( 'Still need help?', 'woo-feed' ); ?></h2>
88
- <p><?php _e( 'Have we not answered your question?<br>Don\'t worry, you can contact us for more information...', 'woo-feed') ?></p>
 
 
 
 
 
 
 
89
  </div>
90
  <div class="wapk-cta-action">
91
- <a href="https://wordpress.org/support/plugin/webappick-product-feed-for-woocommerce/#new-topic-0" class="wapk-button wapk-button-primary" target="_blank"><?php _e( 'Get Support', 'woo-feed' ); ?></a>
92
  </div>
93
  </div>
94
  </div>
95
  <?php } else { ?>
96
  <div class="notice notice-warning">
97
- <p><?php printf(
98
- __( 'There\'s some problem loading the docs. Please Click <a href="%s">Here</a> To Fetch Again.', 'woo-feed' ),
99
- admin_url( 'admin.php?page=webappick-feed-docs&reload=1&_nonce=' . wp_create_nonce( 'webappick-feed-docs' ) )
100
- ); ?></p>
101
- <p><?php printf( __( 'If the problem persist please contact <a href="%s">our support</a>.', 'woo-feed' ), 'https://wordpress.org/support/plugin/webappick-product-feed-for-woocommerce/#new-topic-0' ); ?></p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  </div>
103
  <?php } ?>
104
  </div>
105
  <?php
106
  }
107
-
108
  /**
109
  * Get Docs Data
 
110
  * @return array
111
  */
112
  private function __get_feed_help() {
113
  // force fetch docs json.
114
- if ( isset( $_GET['reload'], $_GET['_nonce'] ) && wp_verify_nonce( $_GET['_nonce'], 'webappick-feed-docs' ) ) {
 
 
 
115
  $help_docs = false;
116
- } else $help_docs = get_transient( 'webappick_feed_help_docs' );
 
 
117
  if ( false === $help_docs ) {
118
  // bitbucket cache-control: max-age=900 (15 minutes)
119
  $help_url = 'https://api.bitbucket.org/2.0/snippets/woofeed/jLRxxB/files/woo-feed-docs.json';
120
- $response = wp_remote_get( $help_url, array( 'timeout' => 15 ) );
121
  $help_docs = wp_remote_retrieve_body( $response );
122
- if ( is_wp_error( $response ) || $response['response']['code'] != 200 ) $help_docs = '[]';
 
 
123
  set_transient( 'webappick_feed_help_docs', $help_docs, 12 * HOUR_IN_SECONDS );
124
  }
125
  $help_docs = json_decode( trim( $help_docs ) );
 
126
  return $help_docs;
127
  }
128
-
129
  /**
130
  * Add items to removable query args array
 
131
  * @param array $removable_query_args
 
132
  * @return array
133
  */
134
  function filter_removable_query_args( $removable_query_args ) {
135
  global $pagenow, $plugin_page;
136
- if ( $pagenow === 'admin.php' && $plugin_page === 'webappick-feed-docs' ) {
137
  $removable_query_args = array_merge( $removable_query_args, array( 'reload', '_nonce' ) );
138
  }
 
139
  return $removable_query_args;
140
  }
141
  }
142
  }
143
- // End of file class-woo-feed-docs.php
1
  <?php
2
  /**
3
  * Feed Docs Page Renderer
4
+ *
5
  * @version 1.0.0
6
  * @package WooFeed
7
  * @since 3.1.36
13
  class WooFeedDocs {
14
  /**
15
  * Singleton instance holder
16
+ *
17
  * @var WooFeedDocs
18
  */
19
  private static $instance;
20
+
21
  /**
22
  * Get Class Instance
23
+ *
24
  * @return WooFeedDocs
25
  */
26
  public static function getInstance() {
27
+ if ( null === self::$instance ) {
28
+ self::$instance = new self();
29
+ }
30
+
31
  return self::$instance;
32
  }
33
+
34
  private function __construct() {
35
  add_filter( 'removable_query_args', array( $this, 'filter_removable_query_args' ), 10, 1 );
36
  }
37
+
38
  /**
39
  * Render Docs Page
40
+ *
41
  * @return void
42
+ * @see Woo_Feed_Admin::load_admin_pages()
43
  */
44
  function woo_feed_docs() {
45
  $faqs = $this->__get_feed_help();
53
  </div>
54
  <?php if ( ! empty( $faqs ) ) { ?>
55
  <div class="wapk-section">
56
+ <?php
57
+ foreach ( $faqs as $faq ) {
58
  $boxId = ( isset( $faq->id ) ) ? $faq->id : sanitize_title( $faq->title );
59
+ ?>
60
  <div id="<?php echo esc_attr( $boxId ); ?>" class="postbox <?php echo esc_attr( postbox_classes( $boxId, $current_screen->id ) ); ?>">
61
  <button type="button" class="handlediv" aria-expanded="true">
62
+ <span class="screen-reader-text">
63
+ <?php
64
+ /* translators: %s: FAQ Title */
65
+ printf( esc_html__( 'Toggle panel: %s', 'woo-feed' ), esc_html( $faq->title ) )
66
+ ?>
67
+ </span>
68
  <span class="toggle-indicator" aria-hidden="true"></span>
69
  </button>
70
+ <h2 class="hndle">
71
+ <?php
72
+ if ( isset( $faq->icon ) && ! empty( $faq->icon ) ) {
73
+ ?>
74
+ <span class="<?php printf( '%s%s', ( strpos( $faq->icon, 'dashicons' ) !== false ) ? 'dashicons ' : '', esc_attr( $faq->icon ) ); ?>" aria-hidden="true"></span>
75
+ <?php
76
+ }
77
+ ?>
78
+ <span><?php echo esc_html( $faq->title ); ?></span></h2>
79
  <div class="inside">
80
  <div class="main">
81
  <ul>
82
  <?php foreach ( $faq->questions as $qa ) { ?>
83
  <li>
84
+ <span class="
85
+ <?php
86
+ if ( isset( $qa->icon ) ) {
87
+ printf( '%s%s', ( strpos( $qa->icon, 'dashicons' ) !== false ) ? 'dashicons ' : '', esc_attr( $qa->icon ) );
88
+ } else {
89
+ ?>dashicons dashicons-media-text<?php
90
+ } ?>" aria-hidden="true"></span>
91
  <a href="<?php echo esc_url( $qa->link ); ?>" target="_blank"><?php echo esc_html( $qa->title ); ?></a>
92
  </li>
93
  <?php } ?>
105
  </div>
106
  <div class="wapk-cta-content">
107
  <h2><?php _e( 'Still need help?', 'woo-feed' ); ?></h2>
108
+ <p>
109
+ <?php
110
+ _e(
111
+ 'Have we not answered your question?<br>Don\'t worry, you can contact us for more information...',
112
+ 'woo-feed'
113
+ )
114
+ ?>
115
+ </p>
116
  </div>
117
  <div class="wapk-cta-action">
118
+ <a href="https://webappick.com/support/" class="button button-primary button-hero" target="_blank"><?php _e( 'Get Support', 'woo-feed' ); ?></a>
119
  </div>
120
  </div>
121
  </div>
122
  <?php } else { ?>
123
  <div class="notice notice-warning">
124
+ <p>
125
+ <?php
126
+ printf(
127
+ /* translators: %s: Reload Button */
128
+ esc_html__( 'There\'s some problem loading the docs. Please Click %s To Fetch Again.', 'woo-feed' ),
129
+ sprintf(
130
+ '<a href="%s">%s</a>',
131
+ esc_url( admin_url( 'admin.php?page=webappick-feed-docs&reload=1&_nonce=' . wp_create_nonce( 'webappick-feed-docs' ) ) ),
132
+ esc_html__( 'Here', 'woo-feed' )
133
+ )
134
+ );
135
+ ?>
136
+ </p>
137
+ <p>
138
+ <?php
139
+ printf(
140
+ /* translators: %s: Support Button */
141
+ esc_html__( 'If the problem persist please contact %s.', 'woo-feed' ),
142
+ sprintf(
143
+ '<a href="%s">%s</a>',
144
+ 'https://webappick.com/support/',
145
+ esc_html__( 'our support', 'woo-feed' )
146
+ )
147
+ );
148
+ ?>
149
+ </p>
150
  </div>
151
  <?php } ?>
152
  </div>
153
  <?php
154
  }
155
+
156
  /**
157
  * Get Docs Data
158
+ *
159
  * @return array
160
  */
161
  private function __get_feed_help() {
162
  // force fetch docs json.
163
+ if ( isset( $_GET['reload'], $_GET['_nonce'] ) && wp_verify_nonce(
164
+ sanitize_text_field( $_GET['_nonce'] ),
165
+ 'webappick-feed-docs'
166
+ ) ) {
167
  $help_docs = false;
168
+ } else {
169
+ $help_docs = get_transient( 'webappick_feed_help_docs' );
170
+ }
171
  if ( false === $help_docs ) {
172
  // bitbucket cache-control: max-age=900 (15 minutes)
173
  $help_url = 'https://api.bitbucket.org/2.0/snippets/woofeed/jLRxxB/files/woo-feed-docs.json';
174
+ $response = wp_safe_remote_get( $help_url, array( 'timeout' => 15 ) ); // phpcs:ignore
175
  $help_docs = wp_remote_retrieve_body( $response );
176
+ if ( is_wp_error( $response ) || 200 != $response['response']['code'] ) {
177
+ $help_docs = '[]';
178
+ }
179
  set_transient( 'webappick_feed_help_docs', $help_docs, 12 * HOUR_IN_SECONDS );
180
  }
181
  $help_docs = json_decode( trim( $help_docs ) );
182
+
183
  return $help_docs;
184
  }
185
+
186
  /**
187
  * Add items to removable query args array
188
+ *
189
  * @param array $removable_query_args
190
+ *
191
  * @return array
192
  */
193
  function filter_removable_query_args( $removable_query_args ) {
194
  global $pagenow, $plugin_page;
195
+ if ( 'admin.php' === $pagenow && 'webappick-feed-docs' === $plugin_page ) {
196
  $removable_query_args = array_merge( $removable_query_args, array( 'reload', '_nonce' ) );
197
  }
198
+
199
  return $removable_query_args;
200
  }
201
  }
202
  }
203
+ // End of file class-woo-feed-docs.php
includes/class-woo-feed-installer.php CHANGED
@@ -1,19 +1,21 @@
1
  <?php
2
  /**
3
  * Installer
 
4
  * @package WooFeed
5
  * @version 1.0.0
6
  * @since WooFeed 3.2.1
7
  * @copyright 2019 WebAppick
8
  * @author KD <mhaudul.hk@gmail.com>
9
- *
10
  */
11
- if ( ! defined( 'ABSPATH' ) ) die(); // Silence...
 
 
12
  class Woo_Feed_installer {
13
 
14
  public static function init() {
15
- add_action( 'init', [ __CLASS__, 'check_version' ], 5 );
16
- add_filter( 'cron_schedules', [ __CLASS__, 'cron_schedules' ] );
17
  }
18
 
19
  /**
@@ -27,7 +29,7 @@ class Woo_Feed_installer {
27
  define( 'WOO_FEED_UPDATING', TRUE );
28
  }
29
  self::install();
30
- do_action( 'woo_feed_updated' );
31
  }
32
  }
33
 
@@ -57,7 +59,8 @@ class Woo_Feed_installer {
57
 
58
  // Bail if unsupported php version
59
  if ( ! wooFeed_is_supported_php() ) {
60
- echo '<div class="notice error"><p>'. sprintf( __( 'The Minimum PHP Version Requirement for <b>WooCommerce Product Feed</b> is %1$s. You are Running PHP %2$s', 'woo-feed' ), WOO_FEED_MIN_PHP_VERSION, phpversion() ) .'</p></div>';
 
61
  die();
62
  }
63
 
@@ -70,17 +73,17 @@ class Woo_Feed_installer {
70
  set_transient( 'woo_feed_installing', 'yes', MINUTE_IN_SECONDS * 10 );
71
  woo_feed_maybe_define_constant( 'WOO_FEED_INSTALLING', true );
72
 
73
- self::deactivate_free_version();
74
  self::create_cron_jobs();
75
  self::create_files();
76
  self::update_woo_feed_version();
77
  delete_transient( 'woo_feed_installing' );
78
  }
79
 
80
- private static function deactivate_free_version() {
81
  // Deactivate Free version if pro already available.
82
- if ( wooFeed_is_plugin_active( "webappick-product-feed-for-woocommerce-pro/webappick-product-feed-for-woocommerce-pro.php" ) ) {
83
- echo '<div class="notice error"><p>'. __( 'Please deactivate the <b>WooCommerce Product Feed Pro</b> version to activate free version again.', 'woo-feed' ) .'</p></div>';
84
  die();
85
  }
86
  }
@@ -89,14 +92,15 @@ class Woo_Feed_installer {
89
  * Create cron jobs (clear them first).
90
  */
91
  private static function create_cron_jobs() {
92
- # Schedule Update Interval
93
  if ( ! get_option( 'wf_schedule', false ) ) {
94
- update_option('wf_schedule', HOUR_IN_SECONDS );
95
  }
96
  // clear previous scheduled cron jobs
97
  wp_clear_scheduled_hook( 'woo_feed_corn' );
98
  wp_clear_scheduled_hook( 'woo_feed_cleanup_logs' );
99
- # Schedule Cron jobs
 
100
  wp_schedule_event( time(), 'woo_feed_corn', 'woo_feed_update' );
101
  wp_schedule_event( time() + ( 3 * HOUR_IN_SECONDS ), 'daily', 'woo_feed_cleanup_logs' );
102
  }
@@ -110,25 +114,25 @@ class Woo_Feed_installer {
110
  return;
111
  }
112
  // Install files and folders for uploading files and prevent hotlinking.
113
- $files = [
114
- [
115
  'base' => WOO_FEED_LOG_DIR,
116
  'file' => '.htaccess',
117
  'content' => 'deny from all',
118
- ],
119
- [
120
  'base' => WOO_FEED_LOG_DIR,
121
  'file' => 'index.html',
122
  'content' => '',
123
- ],
124
- ];
125
 
126
  foreach ( $files as $file ) {
127
  if ( wp_mkdir_p( $file['base'] ) && ! file_exists( trailingslashit( $file['base'] ) . $file['file'] ) ) {
128
- $file_handle = @fopen( trailingslashit( $file['base'] ) . $file['file'], 'w' ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged, WordPress.WP.AlternativeFunctions.file_system_read_fopen
129
- if ( $file_handle ) {
130
- fwrite( $file_handle, $file['content'] ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fwrite
131
- fclose( $file_handle ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fclose
132
  }
133
  }
134
  }
@@ -139,17 +143,10 @@ class Woo_Feed_installer {
139
  */
140
  private static function update_woo_feed_version() {
141
  delete_option( 'woo_feed_free_version' );
142
- delete_option( 'woo_feed_version' );
143
- add_option( 'woo_feed_free_version', WOO_FEED_FREE_VERSION );
144
  if ( ! defined( 'WOO_FEED_UPDATING' ) ) {
145
- // check for old version time.
146
- $oldActivation = get_option( 'woo-feed-activation-time', false );
147
- if ( ! $oldActivation ) $oldActivation = time();
148
- update_option( "woo-feed-free-activation-time", $oldActivation );
149
- } else {
150
- if ( $oldActivation = get_option( 'woo-feed-activation-time', false ) ) {
151
- update_option( "woo-feed-free-activation-time", $oldActivation );
152
- }
153
  }
154
  }
155
  }
1
  <?php
2
  /**
3
  * Installer
4
+ *
5
  * @package WooFeed
6
  * @version 1.0.0
7
  * @since WooFeed 3.2.1
8
  * @copyright 2019 WebAppick
9
  * @author KD <mhaudul.hk@gmail.com>
 
10
  */
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ die(); // Silence...
13
+ }
14
  class Woo_Feed_installer {
15
 
16
  public static function init() {
17
+ add_action( 'init', array( __CLASS__, 'check_version' ), 5 );
18
+ add_filter( 'cron_schedules', array( __CLASS__, 'cron_schedules' ) ); // phpcs:ignore
19
  }
20
 
21
  /**
29
  define( 'WOO_FEED_UPDATING', TRUE );
30
  }
31
  self::install();
32
+ do_action( 'woo_feed_plugin_updated' );
33
  }
34
  }
35
 
59
 
60
  // Bail if unsupported php version
61
  if ( ! wooFeed_is_supported_php() ) {
62
+ /* translators: 1: minimum required php version, 2: server php version */
63
+ echo '<div class="notice error"><p>' . sprintf( __( 'The Minimum PHP Version Requirement for <b>WooCommerce Product Feed</b> is %1$s. You are Running PHP %2$s', 'woo-feed' ), WOO_FEED_MIN_PHP_VERSION, phpversion() ) . '</p></div>'; // phpcs:ignore
64
  die();
65
  }
66
 
73
  set_transient( 'woo_feed_installing', 'yes', MINUTE_IN_SECONDS * 10 );
74
  woo_feed_maybe_define_constant( 'WOO_FEED_INSTALLING', true );
75
 
76
+ self::pro_version_warning();
77
  self::create_cron_jobs();
78
  self::create_files();
79
  self::update_woo_feed_version();
80
  delete_transient( 'woo_feed_installing' );
81
  }
82
 
83
+ private static function pro_version_warning() {
84
  // Deactivate Free version if pro already available.
85
+ if ( woo_feed_is_plugin_active( "webappick-product-feed-for-woocommerce-pro/webappick-product-feed-for-woocommerce-pro.php" ) ) {
86
+ echo '<div class="notice error"><p>'. __( 'Please deactivate the <b>WooCommerce Product Feed Pro</b> version to activate free version again.', 'woo-feed' ) .'</p></div>'; // phpcs:ignore
87
  die();
88
  }
89
  }
92
  * Create cron jobs (clear them first).
93
  */
94
  private static function create_cron_jobs() {
95
+ // Schedule Update Interval
96
  if ( ! get_option( 'wf_schedule', false ) ) {
97
+ update_option( 'wf_schedule', HOUR_IN_SECONDS, false );
98
  }
99
  // clear previous scheduled cron jobs
100
  wp_clear_scheduled_hook( 'woo_feed_corn' );
101
  wp_clear_scheduled_hook( 'woo_feed_cleanup_logs' );
102
+ wp_clear_scheduled_hook( 'woo_feed_update' );
103
+ // Schedule Cron jobs
104
  wp_schedule_event( time(), 'woo_feed_corn', 'woo_feed_update' );
105
  wp_schedule_event( time() + ( 3 * HOUR_IN_SECONDS ), 'daily', 'woo_feed_cleanup_logs' );
106
  }
114
  return;
115
  }
116
  // Install files and folders for uploading files and prevent hotlinking.
117
+ $files = array(
118
+ array(
119
  'base' => WOO_FEED_LOG_DIR,
120
  'file' => '.htaccess',
121
  'content' => 'deny from all',
122
+ ),
123
+ array(
124
  'base' => WOO_FEED_LOG_DIR,
125
  'file' => 'index.html',
126
  'content' => '',
127
+ ),
128
+ );
129
 
130
  foreach ( $files as $file ) {
131
  if ( wp_mkdir_p( $file['base'] ) && ! file_exists( trailingslashit( $file['base'] ) . $file['file'] ) ) {
132
+ $file_handle = fopen( trailingslashit( $file['base'] ) . $file['file'], 'w' ); // phpcs:ignore
133
+ if ( false !== $file_handle ) {
134
+ fwrite( $file_handle, $file['content'] ); // phpcs:ignore
135
+ fclose( $file_handle ); // phpcs:ignore
136
  }
137
  }
138
  }
143
  */
144
  private static function update_woo_feed_version() {
145
  delete_option( 'woo_feed_free_version' );
146
+ delete_option( 'woo_feed_version' ); // old option.
147
+ update_option( 'woo_feed_free_version', WOO_FEED_FREE_VERSION, false );
148
  if ( ! defined( 'WOO_FEED_UPDATING' ) ) {
149
+ update_option( 'woo-feed-free-activation-time', get_option( 'woo-feed-activation-time', time() ), false ); // check for old version time.
 
 
 
 
 
 
 
150
  }
151
  }
152
  }
includes/class-woo-feed.php CHANGED
@@ -12,7 +12,7 @@
12
  * @package Woo_Feed
13
  * @subpackage Woo_Feed/includes
14
  */
15
- /** @define "WOO_FEED_FREE_PATH" "./../" */
16
  /**
17
  * The core plugin class.
18
  *
@@ -143,12 +143,6 @@ class Woo_Feed
143
  * The class is a FTP library
144
  */
145
  require_once WOO_FEED_FREE_PATH . 'includes/classes/class-woo-feed-ftp.php';
146
-
147
- /**
148
- * The class
149
- */
150
- require_once WOO_FEED_FREE_PATH . 'includes/classes/class-woo-feed-auto-update.php';
151
-
152
 
153
  /**
154
  * The class responsible for save feed
12
  * @package Woo_Feed
13
  * @subpackage Woo_Feed/includes
14
  */
15
+ /** @define "WOO_FEED_FREE_PATH''./../" */
16
  /**
17
  * The core plugin class.
18
  *
143
  * The class is a FTP library
144
  */
145
  require_once WOO_FEED_FREE_PATH . 'includes/classes/class-woo-feed-ftp.php';
 
 
 
 
 
 
146
 
147
  /**
148
  * The class responsible for save feed
includes/classes/class-woo-feed-default-attributes.php CHANGED
@@ -13,1213 +13,659 @@
13
  * @subpackage Woo_Feed/includes
14
  * @author Ohidul Islam <wahid@webappick.com>
15
  */
16
-
17
- class Woo_Feed_Default_Attributes
18
- {
19
-
20
- public $wooAttributes = array();
21
-
22
- public $googleXMLAttribute = array(
23
- "id" => array( "g:id", false ),
24
- "title" => array( "title", true ),
25
- "description" => array( "description", true ),
26
- "link" => array( "link", true ),
27
- "mobile_link" => array( "mobile_link", true ),
28
- "product_type" => array( "g:product_type", true ),
29
- "current_category" => array( "g:google_product_category", true ),
30
- "image" => array( "g:image_link", true ),
31
- "images" => array( "g:additional_image_link", false ),
32
- "images_1" => array( "g:additional_image_link_1", true ),
33
- "images_2" => array( "g:additional_image_link_2", true ),
34
- "images_3" => array( "g:additional_image_link_3", true ),
35
- "images_4" => array( "g:additional_image_link_4", true ),
36
- "images_5" => array( "g:additional_image_link_5", true ),
37
- "images_6" => array( "g:additional_image_link_6", true ),
38
- "images_7" => array( "g:additional_image_link_7", true ),
39
- "images_8" => array( "g:additional_image_link_8", true ),
40
- "images_9" => array( "g:additional_image_link_9", true ),
41
- "images_10" => array( "g:additional_image_link_10", true ),
42
- "condition" => array( "g:condition", false ),
43
- "availability" => array( "g:availability", false ),
44
- "availability_date" => array( "g:availability_date", false ),
45
- "inventory" => array( "g:inventory", false ),
46
- "price" => array( "g:price", true ),
47
- "sale_price" => array( "g:sale_price", true ),
48
- "sale_price_effective_date" => array( "g:sale_price_effective_date", true ),
49
- "brand" => array( "g:brand", true ),
50
- "sku" => array( "g:mpn", true ),
51
- "upc" => array( "g:gtin", true ),
52
- "identifier_exists" => array( "g:identifier_exists", true ),
53
- "item_group_id" => array( "g:item_group_id", false ),
54
- "color" => array( "g:color", true ),
55
- "gender" => array( "g:gender", true ),
56
- "age_group" => array( "g:age_group", true ),
57
- "material" => array( "g:material", true ),
58
- "pattern" => array( "g:pattern", true ),
59
- "size" => array( "g:size", true ),
60
- "size_type" => array( "g:size_type", true ),
61
- "size_system" => array( "g:size_system", true ),
62
- "tax" => array( "tax", true ),
63
- "tax_country" => array( "g:tax_country", true ),
64
- "tax_region" => array( "g:tax_region", true ),
65
- "tax_rate" => array( "g:tax_rate", true ),
66
- "tax_ship" => array( "g:tax_ship", true ),
67
- "tax_category" => array( "g:tax_category", true ),
68
- "weight" => array( "g:shipping_weight", false ),
69
- "length" => array( "g:shipping_length", false ),
70
- "width" => array( "g:shipping_width", false ),
71
- "height" => array( "g:shipping_height", false ),
72
- "shipping_label" => array( "g:shipping_label", false ),
73
- "shipping_country" => array( "g:shipping_country", false ),
74
- "shipping_service" => array( "g:shipping_service", false ),
75
- "shipping_price" => array( "g:shipping_price", false ),
76
- "shipping_region" => array( "g:shipping_region", false ),
77
- "multipack" => array( "g:multipack", true ),
78
- "is_bundle" => array( "g:is_bundle", true ),
79
- "adult" => array( "g:adult", true ),
80
- "adwords_redirect" => array( "g:adwords_redirect", true ),
81
- "custom_label_0" => array( "g:custom_label_0", true ),
82
- "custom_label_1" => array( "g:custom_label_1", true ),
83
- "custom_label_2" => array( "g:custom_label_2", true ),
84
- "custom_label_3" => array( "g:custom_label_3", true ),
85
- "custom_label_4" => array( "g:custom_label_4", true ),
86
- "excluded_destination" => array( "g:excluded_destination", true ),
87
- "included_destination" => array( "g:included_destination", true ),
88
- "expiration_date" => array( "g:expiration_date", true ),
89
- "unit_pricing_measure" => array( "g:unit_pricing_measure", true ),
90
- "unit_pricing_base_measure" => array( "g:unit_pricing_base_measure", true ),
91
- "energy_efficiency_class" => array( "g:energy_efficiency_class", true ),
92
- "loyalty_points" => array( "g:loyalty_points", true ),
93
- "installment" => array( "g:installment", true ),
94
- "promotion_id" => array( "g:promotion_id", true ),
95
- "cost_of_goods_sold" => array( "g:cost_of_goods_sold", true ),
96
- );
97
- public $googleCSVTXTAttribute = array(
98
- "id" => array( "id", false ),
99
- "title" => array( "title", true ),
100
- "description" => array( "description", true ),
101
- "link" => array( "link", true ),
102
- "mobile_link" => array( "mobile_link", true ),
103
- "product_type" => array( "product type", true ),
104
- "current_category" => array( "google product category", true ),
105
- "image" => array( "image link", true ),
106
- "images" => array( "additional image link", true ),
107
- "images_1" => array( "additional image link 1", true ),
108
- "images_2" => array( "additional image link 2", true ),
109
- "images_3" => array( "additional image link 3", true ),
110
- "images_4" => array( "additional image link 4", true ),
111
- "images_5" => array( "additional image link 5", true ),
112
- "images_6" => array( "additional image link 6", true ),
113
- "images_7" => array( "additional image link 7", true ),
114
- "images_8" => array( "additional image link 8", true ),
115
- "images_9" => array( "additional image link 9", true ),
116
- "images_10" => array( "additional image link 10", true ),
117
- "condition" => array( "condition", false ),
118
- "availability" => array( "availability", false ),
119
- "availability_date" => array( "availability date", false ),
120
- "inventory" => array( "inventory", false ),
121
- "price" => array( "price", true ),
122
- "sale_price" => array( "sale price", true ),
123
- "sale_price_effective_date" => array( "sale price effective date", true ),
124
- "brand" => array( "brand", true ),
125
- "sku" => array( "mpn", true ),
126
- "upc" => array( "gtin", true ),
127
- "identifier_exists" => array( "identifier exists", true ),
128
- "item_group_id" => array( "item group id", false ),
129
- "color" => array( "color", true ),
130
- "gender" => array( "gender", true ),
131
- "age_group" => array( "age group", true ),
132
- "material" => array( "material", true ),
133
- "pattern" => array( "pattern", true ),
134
- "size" => array( "size", true ),
135
- "size_type" => array( "size type", true ),
136
- "size_system" => array( "size system", true ),
137
- "tax" => array( "tax", true ),
138
- "tax_country" => array( "tax country", true ),
139
- "tax_region" => array( "tax region", true ),
140
- "tax_rate" => array( "tax rate", true ),
141
- "tax_ship" => array( "tax ship", true ),
142
- "tax_category" => array( "tax category", true ),
143
- "weight" => array( "shipping weight", false ),
144
- "length" => array( "shipping length", false ),
145
- "width" => array( "shipping width", false ),
146
- "height" => array( "shipping height", false ),
147
- "shipping_label" => array( "shipping label", false ),
148
- "shipping_country" => array( "shipping country", false ),
149
- "shipping_service" => array( "shipping service", false ),
150
- "shipping_price" => array( "shipping price", false ),
151
- "shipping_region" => array( "shipping region", false ),
152
- "multipack" => array( "multipack", true ),
153
- "is_bundle" => array( "is bundle", true ),
154
- "adult" => array( "adult", true ),
155
- "adwords_redirect" => array( "adwords redirect", true ),
156
- "custom_label_0" => array( "custom label 0", true ),
157
- "custom_label_1" => array( "custom label 1", true ),
158
- "custom_label_2" => array( "custom label 2", true ),
159
- "custom_label_3" => array( "custom label 3", true ),
160
- "custom_label_4" => array( "custom label 4", true ),
161
- "excluded_destination" => array( "excluded destination", true ),
162
- "included_destination" => array( "included destination", true ),
163
- "expiration_date" => array( "expiration date", true ),
164
- "unit_pricing_measure" => array( "unit pricing measure", true ),
165
- "unit_pricing_base_measure" => array( "unit pricing base measure", true ),
166
- "energy_efficiency_class" => array( "energy efficiency class", true ),
167
- "loyalty_points" => array( "loyalty points", true ),
168
- "installment" => array( "installment", true ),
169
- "promotion_id" => array( "promotion id", true ),
170
- "cost_of_goods_sold" => array( "cost of goods sold", true ),
171
- );
172
- public $facebookXMLAttribute = array(
173
- "id" => array( "g:id", false ),
174
- "title" => array( "g:title", true ),
175
- "description" => array( "g:description", true ),
176
- "link" => array( "g:link", true ),
177
- "mobile_link" => array( "g:mobile_link", true ),
178
- "product_type" => array( "g:product_type", true ),
179
- "current_category" => array( "g:google_product_category", true ),
180
- "image" => array( "g:image_link", true ),
181
- "images" => array( "g:additional_image_link", false ),
182
- "images_1" => array( "g:additional_image_link_1", true ),
183
- "images_2" => array( "g:additional_image_link_2", true ),
184
- "images_3" => array( "g:additional_image_link_3", true ),
185
- "images_4" => array( "g:additional_image_link_4", true ),
186
- "images_5" => array( "g:additional_image_link_5", true ),
187
- "images_6" => array( "g:additional_image_link_6", true ),
188
- "images_7" => array( "g:additional_image_link_7", true ),
189
- "images_8" => array( "g:additional_image_link_8", true ),
190
- "images_9" => array( "g:additional_image_link_9", true ),
191
- "images_10" => array( "g:additional_image_link_10", true ),
192
- "condition" => array( "g:condition", false ),
193
- "availability" => array( "g:availability", false ),
194
- "inventory" => array( "g:inventory", false ),
195
- "override" => array( "g:override", false ),
196
- "price" => array( "g:price", true ),
197
- "sale_price" => array( "g:sale_price", true ),
198
- "sale_price_effective_date" => array( "g:sale_price_effective_date", true ),
199
- "brand" => array( "g:brand", true ),
200
- "sku" => array( "g:mpn", true ),
201
- "upc" => array( "g:gtin", true ),
202
- "identifier_exists" => array( "g:identifier_exists", true ),
203
- "item_group_id" => array( "g:item_group_id", false ),
204
- "color" => array( "g:color", true ),
205
- "gender" => array( "g:gender", true ),
206
- "age_group" => array( "g:age_group", true ),
207
- "material" => array( "g:material", true ),
208
- "pattern" => array( "g:pattern", true ),
209
- "size" => array( "g:size", true ),
210
- "size_type" => array( "g:size_type", true ),
211
- "size_system" => array( "g:size_system", true ),
212
- "tax" => array( "tax", true ),
213
- "weight" => array( "g:shipping_weight", false ),
214
- "length" => array( "g:shipping_length", false ),
215
- "width" => array( "g:shipping_width", false ),
216
- "height" => array( "g:shipping_height", false ),
217
- "shipping_label" => array( "g:shipping_label", false ),
218
- "shipping_country" => array( "g:shipping_country", false ),
219
- "shipping_service" => array( "g:shipping_service", false ),
220
- "shipping_price" => array( "g:shipping_price", false ),
221
- "shipping_region" => array( "g:shipping_region", false ),
222
- "multipack" => array( "g:multipack", true ),
223
- "is_bundle" => array( "g:is_bundle", true ),
224
- "adult" => array( "g:adult", true ),
225
- "adwords_redirect" => array( "g:adwords_redirect", true ),
226
- "custom_label_0" => array( "g:custom_label_0", true ),
227
- "custom_label_1" => array( "g:custom_label_1", true ),
228
- "custom_label_2" => array( "g:custom_label_2", true ),
229
- "custom_label_3" => array( "g:custom_label_3", true ),
230
- "custom_label_4" => array( "g:custom_label_4", true ),
231
- "excluded_destination" => array( "g:excluded_destination", true ),
232
- "expiration_date" => array( "g:expiration_date", true ),
233
- "unit_pricing_measure" => array( "g:unit_pricing_measure", true ),
234
- "unit_pricing_base_measure" => array( "g:unit_pricing_base_measure", true ),
235
- "energy_efficiency_class" => array( "g:energy_efficiency_class", true ),
236
- "loyalty_points" => array( "g:loyalty_points", true ),
237
- "installment" => array( "g:installment", true ),
238
- "promotion_id" => array( "g:promotion_id", true ),
239
- "cost_of_goods_sold" => array( "g:cost_of_goods_sold", true ),
240
- "availability_date" => array( "g:availability_date", true ),
241
- "tax_category" => array( "g:tax_category", true ),
242
- "included_destination" => array( "g:included_destination", true ),
243
- );
244
- public $facebookCSVTXTAttribute = array(
245
- "id" => array( "id", false ),
246
- "title" => array( "title", true ),
247
- "description" => array( "description", true ),
248
- "link" => array( "link", true ),
249
- "mobile_link" => array( "mobile_link", true ),
250
- "product_type" => array( "product type", true ),
251
- "current_category" => array( "google product category", true ),
252
- "image" => array( "image link", true ),
253
- "images" => array( "additional image link", true ),
254
- "images_1" => array( "additional image link 1", true ),
255
- "images_2" => array( "additional image link 2", true ),
256
- "images_3" => array( "additional image link 3", true ),
257
- "images_4" => array( "additional image link 4", true ),
258
- "images_5" => array( "additional image link 5", true ),
259
- "images_6" => array( "additional image link 6", true ),
260
- "images_7" => array( "additional image link 7", true ),
261
- "images_8" => array( "additional image link 8", true ),
262
- "images_9" => array( "additional image link 9", true ),
263
- "images_10" => array( "additional image link 10", true ),
264
- "condition" => array( "condition", false ),
265
- "availability" => array( "availability", false ),
266
- "inventory" => array( "inventory", false ),
267
- "override" => array( "override", false ),
268
- "price" => array( "price", true ),
269
- "sale_price" => array( "sale price", true ),
270
- "sale_price_effective_date" => array( "sale price effective date", true ),
271
- "brand" => array( "brand", true ),
272
- "sku" => array( "mpn", true ),
273
- "upc" => array( "gtin", true ),
274
- "identifier_exists" => array( "identifier exists", true ),
275
- "item_group_id" => array( "item group id", false ),
276
- "color" => array( "color", true ),
277
- "gender" => array( "gender", true ),
278
- "age_group" => array( "age group", true ),
279
- "material" => array( "material", true ),
280
- "pattern" => array( "pattern", true ),
281
- "size" => array( "size", true ),
282
- "size_type" => array( "size type", true ),
283
- "size_system" => array( "size system", true ),
284
- "tax" => array( "tax", true ),
285
- "weight" => array( "shipping weight", false ),
286
- "length" => array( "shipping length", false ),
287
- "width" => array( "shipping width", false ),
288
- "height" => array( "shipping height", false ),
289
- "shipping_label" => array( "shipping label", false ),
290
- "shipping_country" => array( "shipping country", false ),
291
- "shipping_service" => array( "shipping service", false ),
292
- "shipping_price" => array( "shipping price", false ),
293
- "shipping_region" => array( "shipping region", false ),
294
- "multipack" => array( "multipack", true ),
295
- "is_bundle" => array( "is bundle", true ),
296
- "adult" => array( "adult", true ),
297
- "adwords_redirect" => array( "adwords redirect", true ),
298
- "custom_label_0" => array( "custom label 0", true ),
299
- "custom_label_1" => array( "custom label 1", true ),
300
- "custom_label_2" => array( "custom label 2", true ),
301
- "custom_label_3" => array( "custom label 3", true ),
302
- "custom_label_4" => array( "custom label 4", true ),
303
- "excluded_destination" => array( "excluded destination", true ),
304
- "expiration_date" => array( "expiration date", true ),
305
- "unit_pricing_measure" => array( "unit pricing measure", true ),
306
- "unit_pricing_base_measure" => array( "unit pricing base measure", true ),
307
- "energy_efficiency_class" => array( "energy efficiency class", true ),
308
- "loyalty_points" => array( "loyalty points", true ),
309
- "installment" => array( "installment", true ),
310
- "promotion_id" => array( "promotion id", true ),
311
- "cost_of_goods_sold" => array( "cost of goods sold", true ),
312
- "availability_date" => array( "availability date", true ),
313
- "tax_category" => array( "tax category", true ),
314
- "included_destination" => array( "included destination", true ),
315
- );
316
- public $pinterestXMLAttribute = array(
317
- "id" => array( "g:id", false ),
318
- "title" => array( "title", true ),
319
- "description" => array( "description", true ),
320
- "link" => array( "link", true ),
321
- "mobile_link" => array( "mobile_link", true ),
322
- "product_type" => array( "g:product_type", true ),
323
- "current_category" => array( "g:google_product_category", true ),
324
- "image" => array( "g:image_link", true ),
325
- "images" => array( "g:additional_image_link", false ),
326
- "images_1" => array( "g:additional_image_link_1", true ),
327
- "images_2" => array( "g:additional_image_link_2", true ),
328
- "images_3" => array( "g:additional_image_link_3", true ),
329
- "images_4" => array( "g:additional_image_link_4", true ),
330
- "images_5" => array( "g:additional_image_link_5", true ),
331
- "images_6" => array( "g:additional_image_link_6", true ),
332
- "images_7" => array( "g:additional_image_link_7", true ),
333
- "images_8" => array( "g:additional_image_link_8", true ),
334
- "images_9" => array( "g:additional_image_link_9", true ),
335
- "images_10" => array( "g:additional_image_link_10", true ),
336
- "condition" => array( "g:condition", false ),
337
- "availability" => array( "g:availability", false ),
338
- "availability_date" => array( "g:availability_date", false ),
339
- "inventory" => array( "g:inventory", false ),
340
- "price" => array( "g:price", true ),
341
- "sale_price" => array( "g:sale_price", true ),
342
- "sale_price_effective_date" => array( "g:sale_price_effective_date", true ),
343
- "brand" => array( "g:brand", true ),
344
- "sku" => array( "g:mpn", true ),
345
- "upc" => array( "g:gtin", true ),
346
- "identifier_exists" => array( "g:identifier_exists", true ),
347
- "item_group_id" => array( "g:item_group_id", false ),
348
- "color" => array( "g:color", true ),
349
- "gender" => array( "g:gender", true ),
350
- "age_group" => array( "g:age_group", true ),
351
- "material" => array( "g:material", true ),
352
- "pattern" => array( "g:pattern", true ),
353
- "size" => array( "g:size", true ),
354
- "size_type" => array( "g:size_type", true ),
355
- "size_system" => array( "g:size_system", true ),
356
- "tax" => array( "tax", true ),
357
- "tax_country" => array( "g:tax_country", true ),
358
- "tax_region" => array( "g:tax_region", true ),
359
- "tax_rate" => array( "g:tax_rate", true ),
360
- "tax_ship" => array( "g:tax_ship", true ),
361
- "tax_category" => array( "g:tax_category", true ),
362
- "weight" => array( "g:shipping_weight", false ),
363
- "length" => array( "g:shipping_length", false ),
364
- "width" => array( "g:shipping_width", false ),
365
- "height" => array( "g:shipping_height", false ),
366
- "shipping_label" => array( "g:shipping_label", false ),
367
- "shipping_country" => array( "g:shipping_country", false ),
368
- "shipping_service" => array( "g:shipping_service", false ),
369
- "shipping_price" => array( "g:shipping_price", false ),
370
- "shipping_region" => array( "g:shipping_region", false ),
371
- "multipack" => array( "g:multipack", true ),
372
- "is_bundle" => array( "g:is_bundle", true ),
373
- "adult" => array( "g:adult", true ),
374
- "adwords_redirect" => array( "g:adwords_redirect", true ),
375
- "custom_label_0" => array( "g:custom_label_0", true ),
376
- "custom_label_1" => array( "g:custom_label_1", true ),
377
- "custom_label_2" => array( "g:custom_label_2", true ),
378
- "custom_label_3" => array( "g:custom_label_3", true ),
379
- "custom_label_4" => array( "g:custom_label_4", true ),
380
- "excluded_destination" => array( "g:excluded_destination", true ),
381
- "included_destination" => array( "g:included_destination", true ),
382
- "expiration_date" => array( "g:expiration_date", true ),
383
- "unit_pricing_measure" => array( "g:unit_pricing_measure", true ),
384
- "unit_pricing_base_measure" => array( "g:unit_pricing_base_measure", true ),
385
- "energy_efficiency_class" => array( "g:energy_efficiency_class", true ),
386
- "loyalty_points" => array( "g:loyalty_points", true ),
387
- "installment" => array( "g:installment", true ),
388
- "promotion_id" => array( "g:promotion_id", true ),
389
- "cost_of_goods_sold" => array( "g:cost_of_goods_sold", true ),
390
- );
391
- public $pinterestCSVTXTAttribute = array(
392
- "id" => array( "id", false ),
393
- "title" => array( "title", true ),
394
- "description" => array( "description", true ),
395
- "link" => array( "link", true ),
396
- "mobile_link" => array( "mobile_link", true ),
397
- "product_type" => array( "product_type", true ),
398
- "current_category" => array( "google_product_category", true ),
399
- "image" => array( "image_link", true ),
400
- "images" => array( "additional_image_link", true ),
401
- "images_1" => array( "additional_image_link_1", true ),
402
- "images_2" => array( "additional_image_link_2", true ),
403
- "images_3" => array( "additional_image_link_3", true ),
404
- "images_4" => array( "additional_image_link_4", true ),
405
- "images_5" => array( "additional_image_link_5", true ),
406
- "images_6" => array( "additional_image_link_6", true ),
407
- "images_7" => array( "additional_image_link_7", true ),
408
- "images_8" => array( "additional_image_link_8", true ),
409
- "images_9" => array( "additional_image_link_9", true ),
410
- "images_10" => array( "additional_image_link_10", true ),
411
- "condition" => array( "condition", false ),
412
- "availability" => array( "availability", false ),
413
- "availability_date" => array( "availability_date", false ),
414
- "inventory" => array( "inventory", false ),
415
- "price" => array( "price", true ),
416
- "sale_price" => array( "sale_price", true ),
417
- "sale_price_effective_date" => array( "sale_price_effective_date", true ),
418
- "brand" => array( "brand", true ),
419
- "sku" => array( "mpn", true ),
420
- "upc" => array( "gtin", true ),
421
- "identifier_exists" => array( "identifier exists", true ),
422
- "item_group_id" => array( "item_group_id", false ),
423
- "color" => array( "color", true ),
424
- "gender" => array( "gender", true ),
425
- "age_group" => array( "age_group", true ),
426
- "material" => array( "material", true ),
427
- "pattern" => array( "pattern", true ),
428
- "size" => array( "size", true ),
429
- "size_type" => array( "size_type", true ),
430
- "size_system" => array( "size_system", true ),
431
- "tax" => array( "tax", true ),
432
- "tax_country" => array( "tax_country", true ),
433
- "tax_region" => array( "tax_region", true ),
434
- "tax_rate" => array( "tax_rate", true ),
435
- "tax_ship" => array( "tax_ship", true ),
436
- "tax_category" => array( "tax_category", true ),
437
- "weight" => array( "shipping_weight", false ),
438
- "length" => array( "shipping_length", false ),
439
- "width" => array( "shipping_width", false ),
440
- "height" => array( "shipping_height", false ),
441
- "shipping_label" => array( "shipping_label", false ),
442
- "shipping_country" => array( "shipping_country", false ),
443
- "shipping_service" => array( "shipping_service", false ),
444
- "shipping_price" => array( "shipping_price", false ),
445
- "shipping_region" => array( "shipping_region", false ),
446
- "multipack" => array( "multipack", true ),
447
- "is_bundle" => array( "is_bundle", true ),
448
- "adult" => array( "adult", true ),
449
- "adwords_redirect" => array( "adwords_redirect", true ),
450
- "custom_label_0" => array( "custom_label_0", true ),
451
- "custom_label_1" => array( "custom_label_1", true ),
452
- "custom_label_2" => array( "custom_label_2", true ),
453
- "custom_label_3" => array( "custom_label_3", true ),
454
- "custom_label_4" => array( "custom_label_4", true ),
455
- "excluded_destination" => array( "excluded_destination", true ),
456
- "included_destination" => array( "included_destination", true ),
457
- "expiration_date" => array( "expiration_date", true ),
458
- "unit_pricing_measure" => array( "unit_pricing_measure", true ),
459
- "unit_pricing_base_measure" => array( "unit_pricing_base_measure", true ),
460
- "energy_efficiency_class" => array( "energy_efficiency_class", true ),
461
- "loyalty_points" => array( "loyalty_points", true ),
462
- "installment" => array( "installment", true ),
463
- "promotion_id" => array( "promotion_id", true ),
464
- "cost_of_goods_sold" => array( "cost_of_goods_sold", true ),
465
- );
466
-
467
- public function __construct() {
468
-
469
- }
470
-
471
- public function merchants() {
472
-
473
- $feed_engine = array(
474
- "--1" => "Custom Template",
475
- "custom" => "Custom Feed",
476
- "---1" => "",
477
- );
478
-
479
- $popular_template = array(
480
- "--2" => "Popular Templates",
481
- "google" => "Google Shopping",
482
- "google_local" => "Google Local Product",
483
- "google_local_inventory" => "Google Local Product Inventory",
484
- "adwords" => "Google Adwords",
485
- "facebook" => "Facebook",
486
- "pinterest" => "Pinterest",
487
- "---2" => "",
488
- );
489
-
490
- $others_temp = array(
491
- "shopping" => "eBay (Shopping.com)",
492
- "adroll" => "AdRoll",
493
- "adform" => "AdForm",
494
- "nextag" => "Nextag",
495
- "pricegrabber" => "Price Grabber",
496
- "polyvore" => "Polyvore",
497
- "pricerunner" => "PriceRunner",
498
- "kelkoo" => "Kelkoo",
499
- "shopzilla" => "Shopzilla",
500
- "shopmania" => "Shopmania",
501
- "shopbot" => "Shopbot",
502
- "bing" => "Bing",
503
- "become" => "Become",
504
- "connexity" => "Connexity",
505
-
506
- "pricespy" => "PriceSpy",
507
- "prisjakt" => "Prisjakt",
508
- "twenga" => "Twenga",
509
- "fruugo" => "Fruugo",
510
- "fruugo.au" => "Fruugoaustralia.com",
511
- "bonanza" => "Bonanza",
512
- "bol" => "Bol.com",
513
- "leguide" => "LeGuide",
514
- "real" => "Real",
515
- "crowdfox" => "Crowdfox",
516
- "jet" => "Jet.com",
517
- "wish" => "Wish.com",
518
- "zap.co.il" => "Zap.co.il",
519
- "myshopping.com.au" => "Myshopping.com.au",
520
- "smartly.io" => "Smartly.io",
521
- "stylight.com" => "Stylight.com",
522
- "nextad" => "TheNextAd",
523
- "skinflint.co.uk" => "SkinFlint.co.uk",
524
- "yahoo_nfa" => "Yahoo NFA",
525
- "hintaseuranta.fi" => "Hintaseuranta.fi",
526
- "incurvy" => "Incurvy",
527
- "kijiji.ca" => "Kijiji.ca",
528
- "marktplaats.nl" => "Marktplaats.nl",
529
- "rakuten.de" => "Rakuten",
530
- "shopalike.fr" => "Shopalike.fr",
531
- "spartoo.fi" => "Spartoo.fi",
532
- "webmarchand" => "Webmarchand",
533
- "fashiola" => "Fashiola",
534
- "vergelijk_comparer" => "Vergelijk.be & Comparer.be",
535
- "kieskeurig.nl" => "Kieskeurig.nl",
536
- "beslist.nl" => "Beslist.nl",
537
- "billiger.de" => "Billiger.de",
538
- "vertaa.fi" => "Vertaa.fi",
539
- "cdiscount.fr" => "CDiscount.fr",
540
- "fnac.fr" => "Fnac.fr",
541
- "idealo" => "Idealo",
542
- "miinto.nl" => "Miinto.nl",
543
- 'fyndiq.se' => "Fyndiq.se",
544
- "criteo" => "Criteo",
545
- "avantlink" => "Avantlink",
546
- 'shareasale' => "ShareASale",
547
- "walmart" => "Walmart",
548
- "modina.de" => "Modina.de",
549
- "yandex_csv" => "Yandex (CSV)",
550
- );
551
-
552
- asort($others_temp);
553
- $newTemplate = array();
554
- $newTemplate['--3'] = "Templates";
555
- foreach ( $others_temp as $key => $val ) {
556
- // echo "$key = $val <br>";
557
- $newTemplate[ $key ] = $val;
558
- }
559
- $newTemplate['---3'] = "";
560
-
561
- return array_merge($feed_engine, $popular_template, $newTemplate);
562
- }
563
-
564
-
565
- /**
566
- * Dropdown of Attribute List
567
- *
568
- * @param string $merchant
569
- * @param string $selected
570
- * @return string
571
- */
572
-
573
- public function getAttributeDropDown( $merchant, $selected = "" ) {
574
- $str = "<option></option>";
575
- $method = $merchant . "Attribute";
576
- foreach ( $this->$method() as $key => $value ) {
577
- if ( substr($key, 0, 2) == "--" ) {
578
- $str .= "<optgroup label='$value'>";
579
- } elseif ( substr($key, 0, 2) == "---" ) {
580
- $str .= "</optgroup>";
581
- } else {
582
- $sltd = "";
583
- if ($selected == $key)
584
- $sltd = 'selected="selected"';
585
- $str .= "<option $sltd value='$key'>" . $value . "</option>";
586
- }
587
- }
588
- return $str;
589
- }
590
-
591
- public function googleAttributes() {
592
- $attributes = array(
593
- "--1" => "Basic Information",
594
- "id" => "Product Id[id]",
595
- "title" => "Product Title[title]",
596
- "description" => "Product Description[description]",
597
- "link" => "Product URL[link]",
598
- "mobile_link" => "Product URL[mobile_link]",
599
- "product_type" => "Product Categories[product_type] ",
600
- "current_category" => "Google Product Category[google_product_category]",
601
- "image" => "Main Image[image_link]",
602
- "images" => "Comma Separated Images [additional_image_link]",
603
- "images_1" => "Additional Image 1 [additional_image_link]",
604
- "images_2" => "Additional Image 2 [additional_image_link]",
605
- "images_3" => "Additional Image 3 [additional_image_link]",
606
- "images_4" => "Additional Image 4 [additional_image_link]",
607
- "images_5" => "Additional Image 5 [additional_image_link]",
608
- "images_6" => "Additional Image 6 [additional_image_link]",
609
- "images_7" => "Additional Image 7 [additional_image_link]",
610
- "images_8" => "Additional Image 8 [additional_image_link]",
611
- "images_9" => "Additional Image 9 [additional_image_link]",
612
- "images_10" => "Additional Image 10 [additional_image_link]",
613
- "condition" => "Condition[condition]",
614
- "---1" => "",
615
-
616
- "--2" => "Availability & Price",
617
- "availability" => "Stock Status[availability]",
618
- "availability_date" => "Availability Date[availability_date]",
619
- "cost_of_goods_sold" => "Cost of Goods Sold[cost_of_goods_sold]",
620
- "expiration_date" => "Expiration Date[expiration_date]",
621
- "inventory" => "Facebook Inventory[inventory]",
622
- "override" => "Facebook Override[override]",
623
- "price" => "Regular Price[price]",
624
- "sale_price" => "Sale Price[sale_price]",
625
- "sale_price_effective_date" => "Sale Price Effective Date[sale_price_effective_date]",
626
- "---2" => "",
627
-
628
- "--3" => "Unique Product Identifiers",
629
- "brand" => "Manufacturer[brand]",
630
- "upc" => "GTIN[gtin]",
631
- "sku" => "MPN[mpn]",
632
- "identifier_exists" => "Identifier Exist[identifier_exists]",
633
- "---3" => "",
634
-
635
- "--4" => "Detailed Product Attributes",
636
- "item_group_id" => "Item Group Id[item_group_id]",
637
- "color" => "Color[color]",
638
- "gender" => "Gender[gender]",
639
- "age_group" => "Age Group[age_group]",
640
- "material" => "Material[material]",
641
- "pattern" => "Pattern[pattern]",
642
- "size" => "Size of the item[size]",
643
- "size_type" => "Size Type[size_type]",
644
- "size_system" => "Size System[size_system]",
645
- "---4" => "",
646
-
647
- "--5" => "Tax & Shipping",
648
- // "tax" => "Tax[tax]",
649
- "tax_country" => "Tax Country[tax_country]",
650
- "tax_region" => "Tax Region[tax_region]",
651
- "tax_rate" => "Tax Rate[tax_rate]",
652
- "tax_ship" => "Tax Ship[tax_ship]",
653
- "tax_category" => "Tax[tax_category]",
654
- "shipping_country" => "Shipping Country",
655
- "shipping_region" => "Shipping Region",
656
- "shipping_service" => "Shipping Service",
657
- "shipping_price" => "Shipping Price",
658
- "weight" => "Shipping Weight[shipping_weight]",
659
- "length" => "Shipping Length[shipping_length]",
660
- "width" => "Shipping Width[shipping_width]",
661
- "height" => "Shipping Height[shipping_height]",
662
- "shipping_label" => "Shipping Label[shipping_label]",
663
- "---5" => "",
664
-
665
- "--6" => "Product Combinations",
666
- "multipack" => "Multipack[multipack]",
667
- "is_bundle" => "Is Bundle[is_bundle]",
668
- "---6" => "",
669
-
670
- "--7" => "Adult Products",
671
- "adult" => "Adult[adult]",
672
- "---7" => "",
673
-
674
- "--8" => "AdWord Attributes",
675
- "adwords_redirect" => "Adwords Redirect[adwords_redirect]",
676
- "---8" => "",
677
-
678
- "--9" => "Custom Label Attributes",
679
- "custom_label_0" => "Custom label 0 [custom_label_0]",
680
- "custom_label_1" => "Custom label 1 [custom_label_1]",
681
- "custom_label_2" => "Custom label 2 [custom_label_2]",
682
- "custom_label_3" => "Custom label 3 [custom_label_3]",
683
- "custom_label_4" => "Custom label 4 [custom_label_4]",
684
- "---9" => "",
685
-
686
- "--10" => "Additional Attributes",
687
- "excluded_destination" => "Excluded Destination[excluded_destination]",
688
- "included_destination" => "Included Destination[included_destination]",
689
- "expiration_date" => "Expiration Date [expiration_date]",
690
- "---10" => "",
691
-
692
- "--11" => "Unit Prices (EU Countries and Switzerland Only)",
693
- "unit_pricing_measure" => "Unit Pricing Measure[unit_pricing_measure]",
694
- "unit_pricing_base_measure" => "Unit Pricing Base Measure[unit_pricing_base_measure]",
695
- "---11" => "",
696
-
697
- "--12" => "Energy Labels",
698
- "energy_efficiency_class" => "Energy Efficiency Class[energy_efficiency_class]",
699
- "---12" => "",
700
-
701
- "--13" => "Loyalty Points (Japan Only)",
702
- "loyalty_points" => "loyalty_points[loyalty_points]",
703
- "---13" => "",
704
-
705
- "--14" => "Multiple Installments (Brazil Only)",
706
- "installment" => "Installment[installment]",
707
- "---14" => "",
708
-
709
- "--15" => "Merchant Promotions Attribute",
710
- "promotion_id" => "Promotion Id[promotion_id]",
711
- "---15" => "",
712
- );
713
-
714
- return $attributes;
715
- }
716
-
717
- public function pricegrabberAttribute() {
718
- $attributes = array(
719
- "--1" => "Required Attributes",
720
- "Retsku" => "Retsku",
721
- "Product Title" => "Product Title",
722
- "Detailed Description" => "Detailed Description",
723
- "Categorization" => "Categorization",
724
- "Product URL" => "Product URL",
725
- "Primary Image URL" => "Primary Image URL",
726
- "Selling Price" => "Selling Price",
727
- "Regular Price" => "Regular Price",
728
- "Condition" => "Condition",
729
- "Availability" => "Availability",
730
- "Manufacturer Name" => "Manufacturer Name",
731
- "GTIN" => "GTIN (UPC / EAN / ISBN)",
732
- "Mature" => "Mature",
733
- "---1" => "",
734
- "--2" => "Additional Attributes",
735
- "Parent Retsku" => "Parent Retsku",
736
- "Merchant Categorization" => "Merchant Categorization",
737
- "Manufacturer Part Number" => "Manufacturer Part Number",
738
- "Additional Image URL 1" => "Additional Image URL 1",
739
- "Additional Image URL 2" => "Additional Image URL 2",
740
- "Additional Image URL 3" => "Additional Image URL 3",
741
- "Additional Image URL 4" => "Additional Image URL 4",
742
- "Additional Image URL 5" => "Additional Image URL 5",
743
- "Additional Image URL 6" => "Additional Image URL 6",
744
- "Additional Image URL 7" => "Additional Image URL 7",
745
- "Additional Image URL 8" => "Additional Image URL 8",
746
- "Additional Image URL 9" => "Additional Image URL 9",
747
- "Additional Image URL 10" => "Additional Image URL 10",
748
- "Video URL" => "Video URL",
749
- "Color" => "Color",
750
- "Size" => "Size",
751
- "Material" => "Material",
752
- "Pattern" => "Pattern",
753
- "Gender" => "Gender",
754
- "Age" => "Age",
755
- "Parent UPC" => "Parent UPC",
756
- "Multipack" => "Multipack",
757
- "Shipping Cost" => "Shipping Cost",
758
- "Weight" => "Weight",
759
- "---2" => "",
760
- );
761
- return $attributes;
762
- }
763
-
764
- public function nextagAttribute() {
765
- $attributes = array(
766
- "--1" => "Required Attributes",
767
- "Product Name" => "Product Name",
768
- "Product Description" => "Product Description",
769
- "Image URL" => "Image URL",
770
- "Click-Out URL" => "Click-Out URL",
771
- "Price" => "Price",
772
- "Category" => "Category: Nextag Numeric ID or Other",
773
- "---1" => "",
774
- "--2" => "Additional Attributes",
775
- "Manufacturer" => "Manufacturer",
776
- "Condition" => "Condition",
777
- "Stock Status" => "Stock Status",
778
- "Cost-per-Click " => "Cost-per-Click ",
779
- "Distributor ID " => "Distributor ID ",
780
- "Ground Shipping" => "Ground Shipping",
781
- "Ingram Part #" => "Ingram Part #",
782
- "ISBN" => "ISBN",
783
- "Manufacturer Part #" => "Manufacturer Part #",
784
- "Marketing Message " => "Marketing Message ",
785
- "MUZE ID" => "MUZE ID",
786
- "Seller Part #" => "Seller Part #",
787
- "UPC" => "UPC",
788
- "Weight" => "Weight",
789
- "ListPrice" => "ListPrice",
790
- "---2" => "",
791
- );
792
- return $attributes;
793
- }
794
-
795
- public function kelkooAttribute() {
796
- $attributes = array(
797
- "--1" => "Required Attributes",
798
- "title" => "title",
799
- "product-url" => "product-url",
800
- "price" => "price",
801
- "merchant-category" => "merchant-category",
802
- "ean" => "ean",
803
- "delivery-cost" => "delivery-cost",
804
- "brand" => "brand",
805
- "description" => "description",
806
- "image-url" => "image-url",
807
- "availability" => "availability",
808
- "mpn" => "mpn",
809
- "sku" => "sku",
810
- "---1" => "",
811
- "--2" => "Additional Attributes",
812
- "delivery-time" => "delivery-time",
813
- "condition" => "condition",
814
- "ecotax" => "ecotax",
815
- "warranty" => "warranty",
816
- "mobile-url" => "mobile-url",
817
- "kelkoo-category-id" => "kelkoo-category-id",
818
- "colour" => "colour",
819
- "unit-price" => "unit-price",
820
- "offer-type" => "offer-type",
821
- "merchant-info" => "merchant-info",
822
- "currency" => "currency",
823
- "image-url-2" => "image-url-2",
824
- "image-url-3" => "image-url-3",
825
- "image-url-4" => "image-url-4",
826
- "green-product" => "green-product",
827
- "green-label" => "green-label",
828
- "sales-rank" => "sales-rank",
829
- "unit-quantity" => "unit-quantity",
830
- "made-in" => "made-in",
831
- "occasion" => "occasion",
832
- "efficiency-class" => "efficiency-class",
833
- "shipping-method" => "shipping-method",
834
- "delivery-cost-2" => "delivery-cost-2",
835
- "shipping-method-2" => "shipping-method-2",
836
- "delivery-cost-3" => "delivery-cost-3",
837
- "shipping-method-3" => "shipping-method-3",
838
- "delivery-cost-4" => "delivery-cost-4 ",
839
- "shipping-method-4" => "shipping-method-4",
840
- "zip-code" => "zip-code",
841
- "stock-quantity" => "stock-quantity",
842
- "shipping-weight" => "shipping-weight",
843
- "payment-methods" => "payment-methods",
844
- "voucher-title" => "voucher-title",
845
- "voucher-description" => "voucher-description",
846
- "voucher-url" => "voucher-url",
847
- "voucher-code" => "voucher-code",
848
- "voucher-start-date" => "voucher-start-date",
849
- "voucher-end-date" => "voucher-end-date",
850
- "price-no-rebate" => "price-no-rebate",
851
- "percentage-promo" => "percentage-promo",
852
- "promo-start-date" => "promo-start-date",
853
- "promo-end-dat" => "promo-end-dat",
854
- "user-rating" => "user-rating",
855
- "nb-reviews" => "nb-reviews",
856
- "user-review-link" => "user-review-link",
857
- "video-link" => "video-link",
858
- "video-title" => "video-title",
859
- "---2" => "",
860
- );
861
- return $attributes;
862
- }
863
-
864
- public function shopzillaAttribute() {
865
- $attributes = array(
866
- "--1" => "Required Attributes",
867
- "Unique ID" => "Unique ID",
868
- "Title" => "Title",
869
- "Description" => "Description",
870
- "Category" => "Category",
871
- "Product URL" => "Product URL",
872
- "Image URL" => "Image URL",
873
- "Condition" => "Condition",
874
- "Availability" => "Availability",
875
- "Current Price" => "Current Price",
876
- "---1" => "",
877
- "--2" => "Recommended Attributes",
878
- "Brand" => "Brand",
879
- "GTIN" => "GTIN",
880
- "MPN" => "MPN",
881
- "Ship Cost" => "Ship Cost",
882
- "Ship Weight" => "Ship Weight",
883
- "Bid" => "Bid",
884
- "Regular Price" => "Regular Price",
885
- "Promo Text" => "Promo Text",
886
- "Gender" => "Gender",
887
- "Age Group" => "Age Group",
888
- "Color" => "Color",
889
- "Size" => "Size",
890
- "Material" => "Material",
891
- "Pattern" => "Pattern",
892
- "Item Group ID" => "Item Group ID",
893
- "---2" => "",
894
- "--3" => "Optional Attributes",
895
- "Page ID" => "Page ID",
896
- "Page ID Variant" => "Page ID Variant",
897
- "Generic Title" => "Generic Title",
898
- "Unit Price" => "Unit Price",
899
- "Currency" => "Currency",
900
- "PZN" => "PZN",
901
- "Adult" => "Adult",
902
- "Delivery Period" => "Delivery Period",
903
- "Energy Efficiency Class" => "Energy Efficiency Class",
904
- "---3" => "",
905
- );
906
- return $attributes;
907
- }
908
-
909
- public function shoppingAttribute() {
910
- $attributes = array(
911
- "--1" => "Required Attributes",
912
- "Unique Merchant SKU" => "Unique Merchant SKU",
913
- "Product Name" => "Product Name",
914
- "Product URL" => "Product URL",
915
- "Image URL" => "Image URL",
916
- "Current Price" => "Current Price",
917
- "Stock Availability" => "Stock Availability",
918
- "Condition" => "Condition",
919
- "MPN" => "MPN",
920
- "ISBN" => "ISBN",
921
- "UPC" => "UPC",
922
- "EAN" => "EAN",
923
- "---1" => "",
924
- "--2" => "Additional Attributes",
925
- "Shipping Rate" => "Shipping Rate",
926
- "Original Price" => "Original Price",
927
- "Coupon Code" => "Coupon Code",
928
- "Coupon Code Description" => "Coupon Code Description",
929
- "Manufacturer" => "Brand / Manufacturer",
930
- "Product Description" => "Product Description",
931
- "Product Type" => "Product Type",
932
- "Category" => "Category",
933
- "Category ID" => "Category ID",
934
- "Parent SKU" => "Parent SKU",
935
- "Parent Name" => "Parent Name",
936
- "Top Seller Rank" => "Top Seller Rank",
937
- "Estimated Ship Date" => "Estimated Ship Date",
938
- "Gender" => "Gender",
939
- "Color" => "Color",
940
- "Material" => "Material",
941
- "Size" => "Size",
942
- "Size Unit of Measure" => "Size Unit of Measure",
943
- "Age Range" => "Age Range",
944
- "Stock Description" => "Stock Description",
945
- "Product Launch Date" => "Product Launch Date",
946
- "Product Bullet Point 1" => "Product Bullet Point 1",
947
- "Product Bullet Point 2" => "Product Bullet Point 2",
948
- "Product Bullet Point 3" => "Product Bullet Point 3",
949
- "Product Bullet Point 4" => "Product Bullet Point 4",
950
- "Product Bullet Point 5" => "Product Bullet Point 5",
951
- "Alternative Image URL 1" => "Alternative Image URL 1",
952
- "Alternative Image URL 2" => "Alternative Image URL 2",
953
- "Alternative Image URL 3" => "Alternative Image URL 3",
954
- "Alternative Image URL 4" => "Alternative Image URL 4",
955
- "Alternative Image URL 5" => "Alternative Image URL 5",
956
- "Mobile URL" => "Mobile URL",
957
- "Related Products" => "Related Products",
958
- "Merchandising Type" => "Merchandising Type",
959
- "Zip Code" => "Zip Code",
960
- "Shipping Weight" => "Shipping Weight",
961
- "Format" => "Format",
962
- "Unit Price" => "Unit Price",
963
- "Bundle" => "Bundle",
964
- "Software Platform" => "Software Platform",
965
- "Watch Display Type" => "Watch Display Type",
966
- "Custom" => "Custom",
967
- "---2" => "",
968
- );
969
- return $attributes;
970
- }
971
-
972
- public function shopmaniaAttribute() {
973
- $attributes = array(
974
- "--1" => "Required Attributes",
975
- "Category" => "Category",
976
- "Manufacturer" => "Manufacturer",
977
- "Model" => "Model",
978
- "MPC" => "Merchant Code",
979
- "Name" => "Product name",
980
- "Description" => "Product description",
981
- "URL" => "Product URL",
982
- "Image" => "Image URL",
983
- "Price" => "Product price",
984
- "Currency" => "Currency",
985
- "Shipping" => "Shipping cost",
986
- "Availability" => "Availability",
987
- "GTIN" => "GTIN",
988
- "---1" => "",
989
-
990
- );
991
- return $attributes;
992
- }
993
-
994
- public function leguideAttribute() {
995
- $attributes = array(
996
- "--1" => "",
997
- "category" => "category",
998
- "unique_id" => "unique_id",
999
- "category" => "category",
1000
- "title" => "title",
1001
- "description" => "description",
1002
- "price" => "price",
1003
- "product_URL" => "product_URL",
1004
- "image_URL" => "image_URL",
1005
- "EAN" => "EAN",
1006
- "delivery_charge" => "delivery_charge",
1007
- "availability" => "availability",
1008
- "delivery_time" => "delivery_time",
1009
- "guarantee" => "guarantee",
1010
- "model_reference" => "model_reference",
1011
- "marque" => "marque",
1012
- "MPN" => "MPN",
1013
- "full_price" => "full_price",
1014
- "colour" => "colour",
1015
- "size" => "size",
1016
- "material" => "material",
1017
- "currency" => "currency",
1018
- "second-hand" => "second-hand",
1019
- "type_promotion" => "type_promotion",
1020
- "mobile_URL" => "mobile_URL",
1021
- "unit_price" => "unit_price",
1022
- "---1" => "",
1023
- );
1024
- return $attributes;
1025
- }
1026
-
1027
- public function pricespyAttribute() {
1028
- $attributes = array(
1029
- "--1" => "",
1030
- "Product-name" => "Product-name",
1031
- "Your-item-number" => "Your-item-number",
1032
- "category" => "category",
1033
- "price-including-gst" => "price-including-gst",
1034
- "Product-URL" => "Product-URL",
1035
- "manufacturer" => "manufacturer",
1036
- "manufacturer-SKU" => "manufacturer-SKU",
1037
- "shipping" => "shipping",
1038
- "image-URL" => "image-URL",
1039
- "stock status" => "stock status",
1040
- "---1" => "",
1041
- );
1042
- return $attributes;
1043
- }
1044
-
1045
- public function prisjaktAttribute() {
1046
- $attributes = array(
1047
- "--1" => "",
1048
- "Produktnamn" => "Produktnamn",
1049
- "Art.nr." => "Art.nr.",
1050
- "Kategori" => "Kategori",
1051
- "Pris inkl.moms" => "Pris inkl.moms",
1052
- "Produkt-URL" => "Produkt-URL",
1053
- "Tillverkare" => "Tillverkare",
1054
- "Tillverkar-SKU" => "Tillverkar-SKU",
1055
- "Frakt" => "Frakt",
1056
- "Bild-URL" => "Bild-URL",
1057
- "Lagerstatus" => "Lagerstatus",
1058
- "---1" => "",
1059
- );
1060
- return $attributes;
1061
- }
1062
-
1063
- public function bingAttribute() {
1064
- $attributes = array(
1065
- "id" => "ID",
1066
- "title" => "Title",
1067
- "link" => "Product URL",
1068
- "price" => "Price",
1069
- "description" => "Description",
1070
- "image_link" => "ImageURL",
1071
- "shipping" => "Shipping",
1072
- "required" => "",
1073
- "brand" => "Brand",
1074
- "mpn" => "MPN",
1075
- "gtin" => "GTIN",
1076
- "gender" => "Gender",
1077
- "age_group" => "Age Group",
1078
- "color" => "Color",
1079
- "size" => "Size",
1080
- "item_group_id" => "Item Group Id",
1081
- "material" => "Material",
1082
- "pattern" => "Pattern",
1083
- "adult" => "Adult",
1084
- "availability" => "Availability",
1085
- "product_category" => "Product Category",
1086
- "condition" => "Condition",
1087
- "expiration_date" => "Expiration Date",
1088
- "multipack" => "Multipack",
1089
- "product_type" => "Product Type",
1090
- "mobile_link" => "Mobile Link",
1091
- "seller_name" => "Seller Name",
1092
- "bingads_grouping" => "bingads_grouping",
1093
- "bingads_label" => "bingads_label",
1094
- "bingads_redirect" => "bingads_redirect",
1095
- "custom_label_0" => "custom_label_0",
1096
- "custom_label_1" => "custom_label_1",
1097
- "custom_label_2" => "custom_label_2",
1098
- "custom_label_3" => "custom_label_3",
1099
- "custom_label_4" => "custom_label_4",
1100
- "sale_price" => "Sale Price",
1101
- "sale_price_effective_date" => "Sale Price Effective Date",
1102
- "promotion_ID" => "Promotion Id",
1103
- );
1104
- return $attributes;
1105
- }
1106
-
1107
- public function shopbotAttribute() {
1108
- $attributes = array(
1109
- "--1" => "Required Attributes",
1110
- "ID" => "ID",
1111
- "Product Name" => "Product Name",
1112
- "URL" => "URL",
1113
- "Category" => "Category",
1114
- "Photo URL" => "Photo URL",
1115
- "Price" => "Price",
1116
- "Original Price" => "Original Price",
1117
- "Description" => "Description",
1118
- "MPN" => "MPN",
1119
- "Brand" => "Brand",
1120
- "Shipment Cost" => "Shipment Cost",
1121
- "---1" => "",
1122
- "--2" => "Recommended Attributes",
1123
- "Stock" => "Stock",
1124
- "Promotional Phrase" => "Promotional Phrase",
1125
- "Model" => "Model",
1126
- "Color" => "Color",
1127
- "Product Type" => "Product Type",
1128
- "---2" => "",
1129
-
1130
- );
1131
- return $attributes;
1132
- }
1133
-
1134
- public function becomeAttribute() {
1135
- $attributes = array(
1136
- "--1" => "Required Attributes",
1137
- "Unique ID" => "Unique ID",
1138
- "Title" => "Title",
1139
- "Description" => "Description",
1140
- "Category" => "Category",
1141
- "Product URL" => "Product URL",
1142
- "Image URL" => "Image URL",
1143
- "Condition" => "Condition",
1144
- "Availability" => "Availability",
1145
- "Current Price" => "Current Price",
1146
- "---1" => "",
1147
- "--2" => "Recommended Attributes",
1148
- "Additional Image URL" => "Additional Image URL",
1149
- "Brand" => "Brand",
1150
- "GTIN" => "GTIN",
1151
- "MPN" => "MPN",
1152
- "Ship Cost" => "Ship Cost",
1153
- "Ship Weight" => "Ship Weight",
1154
- "Bid" => "Bid",
1155
- "Regular Price" => "Regular Price",
1156
- "Promo Text" => "Promo Text",
1157
- "Gender" => "Gender",
1158
- "Age Group" => "Age Group",
1159
- "Color" => "Color",
1160
- "Size" => "Size",
1161
- "Material" => "Material",
1162
- "Pattern" => "Pattern",
1163
- "Item Group ID" => "Item Group ID",
1164
- "---2" => "",
1165
- "--3" => "Optional Attributes",
1166
- "Page ID" => "Page ID",
1167
- "Page ID Variant" => "Page ID Variant",
1168
- "Generic Title" => "Generic Title",
1169
- "Unit Price" => "Unit Price",
1170
- "Currency" => "Currency",
1171
- "PZN" => "PZN",
1172
- "Adult" => "Adult",
1173
- "Delivery Period" => "Delivery Period",
1174
- "Energy Efficiency Class" => "Energy Efficiency Class",
1175
-
1176
- "---3" => "",
1177
- );
1178
- return $attributes;
1179
- }
1180
-
1181
- public function connexityAttribute() {
1182
- $attributes = array(
1183
- "--1" => "Required Attributes",
1184
- "Unique ID" => "Unique ID",
1185
- "Title" => "Title",
1186
- "Description" => "Description",
1187
- "Category" => "Category",
1188
- "Product URL" => "Product URL",
1189
- "Image URL" => "Image URL",
1190
- "Condition" => "Condition",
1191
- "Availability" => "Availability",
1192
- "Current Price" => "Current Price",
1193
- "---1" => "",
1194
- "--2" => "Recommended Attributes",
1195
- "Brand" => "Brand",
1196
- "GTIN" => "GTIN",
1197
- "MPN" => "MPN",
1198
- "Ship Cost" => "Ship Cost",
1199
- "Ship Weight" => "Ship Weight",
1200
- "Bid" => "Bid",
1201
- "Regular Price" => "Regular Price",
1202
- "Promo Text" => "Promo Text",
1203
- "Gender" => "Gender",
1204
- "Age Group" => "Age Group",
1205
- "Color" => "Color",
1206
- "Size" => "Size",
1207
- "Material" => "Material",
1208
- "Pattern" => "Pattern",
1209
- "Item Group ID" => "Item Group ID",
1210
- "---2" => "",
1211
- "--3" => "Optional Attributes",
1212
- "Page ID" => "Page ID",
1213
- "Page ID Variant" => "Page ID Variant",
1214
- "Generic Title" => "Generic Title",
1215
- "Unit Price" => "Unit Price",
1216
- "Currency" => "Currency",
1217
- "PZN" => "PZN",
1218
- "Adult" => "Adult",
1219
- "Delivery Period" => "Delivery Period",
1220
- "Energy Efficiency Class" => "Energy Efficiency Class",
1221
- "---3" => "",
1222
- );
1223
- return $attributes;
1224
- }
1225
  }
13
  * @subpackage Woo_Feed/includes
14
  * @author Ohidul Islam <wahid@webappick.com>
15
  */
16
+ class Woo_Feed_Default_Attributes {
17
+
18
+ public $wooAttributes = array();
19
+ public $googleXMLAttribute = array(
20
+ 'id' => array( 'g:id', false ),
21
+ 'title' => array( 'title', true ),
22
+ 'description' => array( 'description', true ),
23
+ 'link' => array( 'link', true ),
24
+ 'mobile_link' => array( 'mobile_link', true ),
25
+ 'product_type' => array( 'g:product_type', true ),
26
+ 'current_category' => array( 'g:google_product_category', true ),
27
+ 'image' => array( 'g:image_link', true ),
28
+ 'images' => array( 'g:additional_image_link', false ),
29
+ 'images_1' => array( 'g:additional_image_link_1', true ),
30
+ 'images_2' => array( 'g:additional_image_link_2', true ),
31
+ 'images_3' => array( 'g:additional_image_link_3', true ),
32
+ 'images_4' => array( 'g:additional_image_link_4', true ),
33
+ 'images_5' => array( 'g:additional_image_link_5', true ),
34
+ 'images_6' => array( 'g:additional_image_link_6', true ),
35
+ 'images_7' => array( 'g:additional_image_link_7', true ),
36
+ 'images_8' => array( 'g:additional_image_link_8', true ),
37
+ 'images_9' => array( 'g:additional_image_link_9', true ),
38
+ 'images_10' => array( 'g:additional_image_link_10', true ),
39
+ 'condition' => array( 'g:condition', false ),
40
+ 'availability' => array( 'g:availability', false ),
41
+ 'availability_date' => array( 'g:availability_date', false ),
42
+ 'inventory' => array( 'g:inventory', false ),
43
+ 'price' => array( 'g:price', true ),
44
+ 'sale_price' => array( 'g:sale_price', true ),
45
+ 'sale_price_effective_date' => array( 'g:sale_price_effective_date', true ),
46
+ 'brand' => array( 'g:brand', true ),
47
+ 'sku' => array( 'g:mpn', true ),
48
+ 'upc' => array( 'g:gtin', true ),
49
+ 'identifier_exists' => array( 'g:identifier_exists', true ),
50
+ 'item_group_id' => array( 'g:item_group_id', false ),
51
+ 'color' => array( 'g:color', true ),
52
+ 'gender' => array( 'g:gender', true ),
53
+ 'age_group' => array( 'g:age_group', true ),
54
+ 'material' => array( 'g:material', true ),
55
+ 'pattern' => array( 'g:pattern', true ),
56
+ 'size' => array( 'g:size', true ),
57
+ 'size_type' => array( 'g:size_type', true ),
58
+ 'size_system' => array( 'g:size_system', true ),
59
+ 'tax' => array( 'tax', true ),
60
+ 'tax_country' => array( 'g:tax_country', true ),
61
+ 'tax_region' => array( 'g:tax_region', true ),
62
+ 'tax_rate' => array( 'g:tax_rate', true ),
63
+ 'tax_ship' => array( 'g:tax_ship', true ),
64
+ 'tax_category' => array( 'g:tax_category', true ),
65
+ 'weight' => array( 'g:shipping_weight', false ),
66
+ 'length' => array( 'g:shipping_length', false ),
67
+ 'width' => array( 'g:shipping_width', false ),
68
+ 'height' => array( 'g:shipping_height', false ),
69
+ 'shipping_label' => array( 'g:shipping_label', false ),
70
+ 'shipping_country' => array( 'g:shipping_country', false ),
71
+ 'shipping_service' => array( 'g:shipping_service', false ),
72
+ 'shipping_price' => array( 'g:shipping_price', false ),
73
+ 'shipping_region' => array( 'g:shipping_region', false ),
74
+ 'multipack' => array( 'g:multipack', true ),
75
+ 'is_bundle' => array( 'g:is_bundle', true ),
76
+ 'adult' => array( 'g:adult', true ),
77
+ 'adwords_redirect' => array( 'g:adwords_redirect', true ),
78
+ 'custom_label_0' => array( 'g:custom_label_0', true ),
79
+ 'custom_label_1' => array( 'g:custom_label_1', true ),
80
+ 'custom_label_2' => array( 'g:custom_label_2', true ),
81
+ 'custom_label_3' => array( 'g:custom_label_3', true ),
82
+ 'custom_label_4' => array( 'g:custom_label_4', true ),
83
+ 'excluded_destination' => array( 'g:excluded_destination', true ),
84
+ 'included_destination' => array( 'g:included_destination', true ),
85
+ 'expiration_date' => array( 'g:expiration_date', true ),
86
+ 'unit_pricing_measure' => array( 'g:unit_pricing_measure', true ),
87
+ 'unit_pricing_base_measure' => array( 'g:unit_pricing_base_measure', true ),
88
+ 'installment_months' => array( 'g:months', true ),
89
+ 'installment_amount' => array( 'g:amount', true ),
90
+ 'subscription_period' => array( 'g:period', true ),
91
+ 'subscription_period_length' => array( 'g:period_length', true ),
92
+ 'subscription_amount' => array( 'g:amount', true ),
93
+ 'energy_efficiency_class' => array( 'g:energy_efficiency_class', true ),
94
+ 'loyalty_points' => array( 'g:loyalty_points', true ),
95
+ 'installment' => array( 'g:installment', true ),
96
+ 'promotion_id' => array( 'g:promotion_id', true ),
97
+ 'cost_of_goods_sold' => array( 'g:cost_of_goods_sold', true ),
98
+ );
99
+ public $googleCSVTXTAttribute = array(
100
+ 'id' => array( 'id', false ),
101
+ 'title' => array( 'title', true ),
102
+ 'description' => array( 'description', true ),
103
+ 'link' => array( 'link', true ),
104
+ 'mobile_link' => array( 'mobile_link', true ),
105
+ 'product_type' => array( 'product type', true ),
106
+ 'current_category' => array( 'google product category', true ),
107
+ 'image' => array( 'image link', true ),
108
+ 'images' => array( 'additional image link', true ),
109
+ 'images_1' => array( 'additional image link 1', true ),
110
+ 'images_2' => array( 'additional image link 2', true ),
111
+ 'images_3' => array( 'additional image link 3', true ),
112
+ 'images_4' => array( 'additional image link 4', true ),
113
+ 'images_5' => array( 'additional image link 5', true ),
114
+ 'images_6' => array( 'additional image link 6', true ),
115
+ 'images_7' => array( 'additional image link 7', true ),
116
+ 'images_8' => array( 'additional image link 8', true ),
117
+ 'images_9' => array( 'additional image link 9', true ),
118
+ 'images_10' => array( 'additional image link 10', true ),
119
+ 'condition' => array( 'condition', false ),
120
+ 'availability' => array( 'availability', false ),
121
+ 'availability_date' => array( 'availability date', false ),
122
+ 'inventory' => array( 'inventory', false ),
123
+ 'price' => array( 'price', true ),
124
+ 'sale_price' => array( 'sale price', true ),
125
+ 'sale_price_effective_date' => array( 'sale price effective date', true ),
126
+ 'brand' => array( 'brand', true ),
127
+ 'sku' => array( 'mpn', true ),
128
+ 'upc' => array( 'gtin', true ),
129
+ 'identifier_exists' => array( 'identifier exists', true ),
130
+ 'item_group_id' => array( 'item group id', false ),
131
+ 'color' => array( 'color', true ),
132
+ 'gender' => array( 'gender', true ),
133
+ 'age_group' => array( 'age group', true ),
134
+ 'material' => array( 'material', true ),
135
+ 'pattern' => array( 'pattern', true ),
136
+ 'size' => array( 'size', true ),
137
+ 'size_type' => array( 'size type', true ),
138
+ 'size_system' => array( 'size system', true ),
139
+ 'tax' => array( 'tax', true ),
140
+ 'tax_country' => array( 'tax country', true ),
141
+ 'tax_region' => array( 'tax region', true ),
142
+ 'tax_rate' => array( 'tax rate', true ),
143
+ 'tax_ship' => array( 'tax ship', true ),
144
+ 'tax_category' => array( 'tax category', true ),
145
+ 'weight' => array( 'shipping weight', false ),
146
+ 'length' => array( 'shipping length', false ),
147
+ 'width' => array( 'shipping width', false ),
148
+ 'height' => array( 'shipping height', false ),
149
+ 'shipping_label' => array( 'shipping label', false ),
150
+ 'shipping_country' => array( 'shipping country', false ),
151
+ 'shipping_service' => array( 'shipping service', false ),
152
+ 'shipping_price' => array( 'shipping price', false ),
153
+ 'shipping_region' => array( 'shipping region', false ),
154
+ 'multipack' => array( 'multipack', true ),
155
+ 'is_bundle' => array( 'is bundle', true ),
156
+ 'adult' => array( 'adult', true ),
157
+ 'adwords_redirect' => array( 'adwords redirect', true ),
158
+ 'custom_label_0' => array( 'custom label 0', true ),
159
+ 'custom_label_1' => array( 'custom label 1', true ),
160
+ 'custom_label_2' => array( 'custom label 2', true ),
161
+ 'custom_label_3' => array( 'custom label 3', true ),
162
+ 'custom_label_4' => array( 'custom label 4', true ),
163
+ 'excluded_destination' => array( 'excluded destination', true ),
164
+ 'included_destination' => array( 'included destination', true ),
165
+ 'expiration_date' => array( 'expiration date', true ),
166
+ 'unit_pricing_measure' => array( 'unit pricing measure', true ),
167
+ 'unit_pricing_base_measure' => array( 'unit pricing base measure', true ),
168
+ 'installment_months' => array( 'months', true ),
169
+ 'installment_amount' => array( 'amount', true ),
170
+ 'subscription_period' => array( 'period', true ),
171
+ 'subscription_period_length' => array( 'period_length', true ),
172
+ 'subscription_amount' => array( 'amount', true ),
173
+ 'energy_efficiency_class' => array( 'energy efficiency class', true ),
174
+ 'loyalty_points' => array( 'loyalty points', true ),
175
+ 'installment' => array( 'installment', true ),
176
+ 'promotion_id' => array( 'promotion id', true ),
177
+ 'cost_of_goods_sold' => array( 'cost of goods sold', true ),
178
+ );
179
+ public $facebookXMLAttribute = array(
180
+ 'id' => array( 'g:id', false ),
181
+ 'title' => array( 'g:title', true ),
182
+ 'description' => array( 'g:description', true ),
183
+ 'link' => array( 'g:link', true ),
184
+ 'mobile_link' => array( 'g:mobile_link', true ),
185
+ 'product_type' => array( 'g:product_type', true ),
186
+ 'current_category' => array( 'g:google_product_category', true ),
187
+ 'image' => array( 'g:image_link', true ),
188
+ 'images' => array( 'g:additional_image_link', false ),
189
+ 'images_1' => array( 'g:additional_image_link_1', true ),
190
+ 'images_2' => array( 'g:additional_image_link_2', true ),
191
+ 'images_3' => array( 'g:additional_image_link_3', true ),
192
+ 'images_4' => array( 'g:additional_image_link_4', true ),
193
+ 'images_5' => array( 'g:additional_image_link_5', true ),
194
+ 'images_6' => array( 'g:additional_image_link_6', true ),
195
+ 'images_7' => array( 'g:additional_image_link_7', true ),
196
+ 'images_8' => array( 'g:additional_image_link_8', true ),
197
+ 'images_9' => array( 'g:additional_image_link_9', true ),
198
+ 'images_10' => array( 'g:additional_image_link_10', true ),
199
+ 'condition' => array( 'g:condition', false ),
200
+ 'availability' => array( 'g:availability', false ),
201
+ 'inventory' => array( 'g:inventory', false ),
202
+ 'override' => array( 'g:override', false ),
203
+ 'price' => array( 'g:price', true ),
204
+ 'sale_price' => array( 'g:sale_price', true ),
205
+ 'sale_price_effective_date' => array( 'g:sale_price_effective_date', true ),
206
+ 'brand' => array( 'g:brand', true ),
207
+ 'sku' => array( 'g:mpn', true ),
208
+ 'upc' => array( 'g:gtin', true ),
209
+ 'identifier_exists' => array( 'g:identifier_exists', true ),
210
+ 'item_group_id' => array( 'g:item_group_id', false ),
211
+ 'color' => array( 'g:color', true ),
212
+ 'gender' => array( 'g:gender', true ),
213
+ 'age_group' => array( 'g:age_group', true ),
214
+ 'material' => array( 'g:material', true ),
215
+ 'pattern' => array( 'g:pattern', true ),
216
+ 'size' => array( 'g:size', true ),
217
+ 'size_type' => array( 'g:size_type', true ),
218
+ 'size_system' => array( 'g:size_system', true ),
219
+ 'tax' => array( 'tax', true ),
220
+ 'weight' => array( 'g:shipping_weight', false ),
221
+ 'length' => array( 'g:shipping_length', false ),
222
+ 'width' => array( 'g:shipping_width', false ),
223
+ 'height' => array( 'g:shipping_height', false ),
224
+ 'shipping_label' => array( 'g:shipping_label', false ),
225
+ 'shipping_country' => array( 'g:shipping_country', false ),
226
+ 'shipping_service' => array( 'g:shipping_service', false ),
227
+ 'shipping_price' => array( 'g:shipping_price', false ),
228
+ 'shipping_region' => array( 'g:shipping_region', false ),
229
+ 'multipack' => array( 'g:multipack', true ),
230
+ 'is_bundle' => array( 'g:is_bundle', true ),
231
+ 'adult' => array( 'g:adult', true ),
232
+ 'adwords_redirect' => array( 'g:adwords_redirect', true ),
233
+ 'custom_label_0' => array( 'g:custom_label_0', true ),
234
+ 'custom_label_1' => array( 'g:custom_label_1', true ),
235
+ 'custom_label_2' => array( 'g:custom_label_2', true ),
236
+ 'custom_label_3' => array( 'g:custom_label_3', true ),
237
+ 'custom_label_4' => array( 'g:custom_label_4', true ),
238
+ 'excluded_destination' => array( 'g:excluded_destination', true ),
239
+ 'expiration_date' => array( 'g:expiration_date', true ),
240
+ 'unit_pricing_measure' => array( 'g:unit_pricing_measure', true ),
241
+ 'unit_pricing_base_measure' => array( 'g:unit_pricing_base_measure', true ),
242
+ 'energy_efficiency_class' => array( 'g:energy_efficiency_class', true ),
243
+ 'loyalty_points' => array( 'g:loyalty_points', true ),
244
+ 'installment' => array( 'g:installment', true ),
245
+ 'promotion_id' => array( 'g:promotion_id', true ),
246
+ 'cost_of_goods_sold' => array( 'g:cost_of_goods_sold', true ),
247
+ 'availability_date' => array( 'g:availability_date', true ),
248
+ 'tax_category' => array( 'g:tax_category', true ),
249
+ 'included_destination' => array( 'g:included_destination', true ),
250
+ );
251
+ public $facebookCSVTXTAttribute = array(
252
+ 'id' => array( 'id', false ),
253
+ 'title' => array( 'title', true ),
254
+ 'description' => array( 'description', true ),
255
+ 'link' => array( 'link', true ),
256
+ 'mobile_link' => array( 'mobile_link', true ),
257
+ 'product_type' => array( 'product type', true ),
258
+ 'current_category' => array( 'google product category', true ),
259
+ 'image' => array( 'image link', true ),
260
+ 'images' => array( 'additional image link', true ),
261
+ 'images_1' => array( 'additional image link 1', true ),
262
+ 'images_2' => array( 'additional image link 2', true ),
263
+ 'images_3' => array( 'additional image link 3', true ),
264
+ 'images_4' => array( 'additional image link 4', true ),
265
+ 'images_5' => array( 'additional image link 5', true ),
266
+ 'images_6' => array( 'additional image link 6', true ),
267
+ 'images_7' => array( 'additional image link 7', true ),
268
+ 'images_8' => array( 'additional image link 8', true ),
269
+ 'images_9' => array( 'additional image link 9', true ),
270
+ 'images_10' => array( 'additional image link 10', true ),
271
+ 'condition' => array( 'condition', false ),
272
+ 'availability' => array( 'availability', false ),
273
+ 'inventory' => array( 'inventory', false ),
274
+ 'override' => array( 'override', false ),
275
+ 'price' => array( 'price', true ),
276
+ 'sale_price' => array( 'sale price', true ),
277
+ 'sale_price_effective_date' => array( 'sale price effective date', true ),
278
+ 'brand' => array( 'brand', true ),
279
+ 'sku' => array( 'mpn', true ),
280
+ 'upc' => array( 'gtin', true ),
281
+ 'identifier_exists' => array( 'identifier exists', true ),
282
+ 'item_group_id' => array( 'item group id', false ),
283
+ 'color' => array( 'color', true ),
284
+ 'gender' => array( 'gender', true ),
285
+ 'age_group' => array( 'age group', true ),
286
+ 'material' => array( 'material', true ),
287
+ 'pattern' => array( 'pattern', true ),
288
+ 'size' => array( 'size', true ),
289
+ 'size_type' => array( 'size type', true ),
290
+ 'size_system' => array( 'size system', true ),
291
+ 'tax' => array( 'tax', true ),
292
+ 'weight' => array( 'shipping weight', false ),
293
+ 'length' => array( 'shipping length', false ),
294
+ 'width' => array( 'shipping width', false ),
295
+ 'height' => array( 'shipping height', false ),
296
+ 'shipping_label' => array( 'shipping label', false ),
297
+ 'shipping_country' => array( 'shipping country', false ),
298
+ 'shipping_service' => array( 'shipping service', false ),
299
+ 'shipping_price' => array( 'shipping price', false ),
300
+ 'shipping_region' => array( 'shipping region', false ),
301
+ 'multipack' => array( 'multipack', true ),
302
+ 'is_bundle' => array( 'is bundle', true ),
303
+ 'adult' => array( 'adult', true ),
304
+ 'adwords_redirect' => array( 'adwords redirect', true ),
305
+ 'custom_label_0' => array( 'custom label 0', true ),
306
+ 'custom_label_1' => array( 'custom label 1', true ),
307
+ 'custom_label_2' => array( 'custom label 2', true ),
308
+ 'custom_label_3' => array( 'custom label 3', true ),
309
+ 'custom_label_4' => array( 'custom label 4', true ),
310
+ 'excluded_destination' => array( 'excluded destination', true ),
311
+ 'expiration_date' => array( 'expiration date', true ),
312
+ 'unit_pricing_measure' => array( 'unit pricing measure', true ),
313
+ 'unit_pricing_base_measure' => array( 'unit pricing base measure', true ),
314
+ 'energy_efficiency_class' => array( 'energy efficiency class', true ),
315
+ 'loyalty_points' => array( 'loyalty points', true ),
316
+ 'installment' => array( 'installment', true ),
317
+ 'promotion_id' => array( 'promotion id', true ),
318
+ 'cost_of_goods_sold' => array( 'cost of goods sold', true ),
319
+ 'availability_date' => array( 'availability date', true ),
320
+ 'tax_category' => array( 'tax category', true ),
321
+ 'included_destination' => array( 'included destination', true ),
322
+ );
323
+ public $pinterestXMLAttribute = array(
324
+ 'id' => array( 'g:id', false ),
325
+ 'title' => array( 'title', true ),
326
+ 'description' => array( 'description', true ),
327
+ 'link' => array( 'link', true ),
328
+ 'mobile_link' => array( 'mobile_link', true ),
329
+ 'product_type' => array( 'g:product_type', true ),
330
+ 'current_category' => array( 'g:google_product_category', true ),
331
+ 'image' => array( 'g:image_link', true ),
332
+ 'images' => array( 'g:additional_image_link', false ),
333
+ 'images_1' => array( 'g:additional_image_link_1', true ),
334
+ 'images_2' => array( 'g:additional_image_link_2', true ),
335
+ 'images_3' => array( 'g:additional_image_link_3', true ),
336
+ 'images_4' => array( 'g:additional_image_link_4', true ),
337
+ 'images_5' => array( 'g:additional_image_link_5', true ),
338
+ 'images_6' => array( 'g:additional_image_link_6', true ),
339
+ 'images_7' => array( 'g:additional_image_link_7', true ),
340
+ 'images_8' => array( 'g:additional_image_link_8', true ),
341
+ 'images_9' => array( 'g:additional_image_link_9', true ),
342
+ 'images_10' => array( 'g:additional_image_link_10', true ),
343
+ 'condition' => array( 'g:condition', false ),
344
+ 'availability' => array( 'g:availability', false ),
345
+ 'availability_date' => array( 'g:availability_date', false ),
346
+ 'inventory' => array( 'g:inventory', false ),
347
+ 'price' => array( 'g:price', true ),
348
+ 'sale_price' => array( 'g:sale_price', true ),
349
+ 'sale_price_effective_date' => array( 'g:sale_price_effective_date', true ),
350
+ 'brand' => array( 'g:brand', true ),
351
+ 'sku' => array( 'g:mpn', true ),
352
+ 'upc' => array( 'g:gtin', true ),
353
+ 'identifier_exists' => array( 'g:identifier_exists', true ),
354
+ 'item_group_id' => array( 'g:item_group_id', false ),
355
+ 'color' => array( 'g:color', true ),
356
+ 'gender' => array( 'g:gender', true ),
357
+ 'age_group' => array( 'g:age_group', true ),
358
+ 'material' => array( 'g:material', true ),
359
+ 'pattern' => array( 'g:pattern', true ),
360
+ 'size' => array( 'g:size', true ),
361
+ 'size_type' => array( 'g:size_type', true ),
362
+ 'size_system' => array( 'g:size_system', true ),
363
+ 'tax' => array( 'tax', true ),
364
+ 'tax_country' => array( 'g:tax_country', true ),
365
+ 'tax_region' => array( 'g:tax_region', true ),
366
+ 'tax_rate' => array( 'g:tax_rate', true ),
367
+ 'tax_ship' => array( 'g:tax_ship', true ),
368
+ 'tax_category' => array( 'g:tax_category', true ),
369
+ 'weight' => array( 'g:shipping_weight', false ),
370
+ 'length' => array( 'g:shipping_length', false ),
371
+ 'width' => array( 'g:shipping_width', false ),
372
+ 'height' => array( 'g:shipping_height', false ),
373
+ 'shipping_label' => array( 'g:shipping_label', false ),
374
+ 'shipping_country' => array( 'g:shipping_country', false ),
375
+ 'shipping_service' => array( 'g:shipping_service', false ),
376
+ 'shipping_price' => array( 'g:shipping_price', false ),
377
+ 'shipping_region' => array( 'g:shipping_region', false ),
378
+ 'multipack' => array( 'g:multipack', true ),
379
+ 'is_bundle' => array( 'g:is_bundle', true ),
380
+ 'adult' => array( 'g:adult', true ),
381
+ 'adwords_redirect' => array( 'g:adwords_redirect', true ),
382
+ 'custom_label_0' => array( 'g:custom_label_0', true ),
383
+ 'custom_label_1' => array( 'g:custom_label_1', true ),
384
+ 'custom_label_2' => array( 'g:custom_label_2', true ),
385
+ 'custom_label_3' => array( 'g:custom_label_3', true ),
386
+ 'custom_label_4' => array( 'g:custom_label_4', true ),
387
+ 'excluded_destination' => array( 'g:excluded_destination', true ),
388
+ 'included_destination' => array( 'g:included_destination', true ),
389
+ 'expiration_date' => array( 'g:expiration_date', true ),
390
+ 'unit_pricing_measure' => array( 'g:unit_pricing_measure', true ),
391
+ 'unit_pricing_base_measure' => array( 'g:unit_pricing_base_measure', true ),
392
+ 'energy_efficiency_class' => array( 'g:energy_efficiency_class', true ),
393
+ 'loyalty_points' => array( 'g:loyalty_points', true ),
394
+ 'installment' => array( 'g:installment', true ),
395
+ 'promotion_id' => array( 'g:promotion_id', true ),
396
+ 'cost_of_goods_sold' => array( 'g:cost_of_goods_sold', true ),
397
+ );
398
+ public $pinterestCSVTXTAttribute = array(
399
+ 'id' => array( 'id', false ),
400
+ 'title' => array( 'title', true ),
401
+ 'description' => array( 'description', true ),
402
+ 'link' => array( 'link', true ),
403
+ 'mobile_link' => array( 'mobile_link', true ),
404
+ 'product_type' => array( 'product_type', true ),
405
+ 'current_category' => array( 'google_product_category', true ),
406
+ 'image' => array( 'image_link', true ),
407
+ 'images' => array( 'additional_image_link', true ),
408
+ 'images_1' => array( 'additional_image_link_1', true ),
409
+ 'images_2' => array( 'additional_image_link_2', true ),
410
+ 'images_3' => array( 'additional_image_link_3', true ),
411
+ 'images_4' => array( 'additional_image_link_4', true ),
412
+ 'images_5' => array( 'additional_image_link_5', true ),
413
+ 'images_6' => array( 'additional_image_link_6', true ),
414
+ 'images_7' => array( 'additional_image_link_7', true ),
415
+ 'images_8' => array( 'additional_image_link_8', true ),
416
+ 'images_9' => array( 'additional_image_link_9', true ),
417
+ 'images_10' => array( 'additional_image_link_10', true ),
418
+ 'condition' => array( 'condition', false ),
419
+ 'availability' => array( 'availability', false ),
420
+ 'availability_date' => array( 'availability_date', false ),
421
+ 'inventory' => array( 'inventory', false ),
422
+ 'price' => array( 'price', true ),
423
+ 'sale_price' => array( 'sale_price', true ),
424
+ 'sale_price_effective_date' => array( 'sale_price_effective_date', true ),
425
+ 'brand' => array( 'brand', true ),
426
+ 'sku' => array( 'mpn', true ),
427
+ 'upc' => array( 'gtin', true ),
428
+ 'identifier_exists' => array( 'identifier exists', true ),
429
+ 'item_group_id' => array( 'item_group_id', false ),
430
+ 'color' => array( 'color', true ),
431
+ 'gender' => array( 'gender', true ),
432
+ 'age_group' => array( 'age_group', true ),
433
+ 'material' => array( 'material', true ),
434
+ 'pattern' => array( 'pattern', true ),
435
+ 'size' => array( 'size', true ),
436
+ 'size_type' => array( 'size_type', true ),
437
+ 'size_system' => array( 'size_system', true ),
438
+ 'tax' => array( 'tax', true ),
439
+ 'tax_country' => array( 'tax_country', true ),
440
+ 'tax_region' => array( 'tax_region', true ),
441
+ 'tax_rate' => array( 'tax_rate', true ),
442
+ 'tax_ship' => array( 'tax_ship', true ),
443
+ 'tax_category' => array( 'tax_category', true ),
444
+ 'weight' => array( 'shipping_weight', false ),
445
+ 'length' => array( 'shipping_length', false ),
446
+ 'width' => array( 'shipping_width', false ),
447
+ 'height' => array( 'shipping_height', false ),
448
+ 'shipping_label' => array( 'shipping_label', false ),
449
+ 'shipping_country' => array( 'shipping_country', false ),
450
+ 'shipping_service' => array( 'shipping_service', false ),
451
+ 'shipping_price' => array( 'shipping_price', false ),
452
+ 'shipping_region' => array( 'shipping_region', false ),
453
+ 'multipack' => array( 'multipack', true ),
454
+ 'is_bundle' => array( 'is_bundle', true ),
455
+ 'adult' => array( 'adult', true ),
456
+ 'adwords_redirect' => array( 'adwords_redirect', true ),
457
+ 'custom_label_0' => array( 'custom_label_0', true ),
458
+ 'custom_label_1' => array( 'custom_label_1', true ),
459
+ 'custom_label_2' => array( 'custom_label_2', true ),
460
+ 'custom_label_3' => array( 'custom_label_3', true ),
461
+ 'custom_label_4' => array( 'custom_label_4', true ),
462
+ 'excluded_destination' => array( 'excluded_destination', true ),
463
+ 'included_destination' => array( 'included_destination', true ),
464
+ 'expiration_date' => array( 'expiration_date', true ),
465
+ 'unit_pricing_measure' => array( 'unit_pricing_measure', true ),
466
+ 'unit_pricing_base_measure' => array( 'unit_pricing_base_measure', true ),
467
+ 'energy_efficiency_class' => array( 'energy_efficiency_class', true ),
468
+ 'loyalty_points' => array( 'loyalty_points', true ),
469
+ 'installment' => array( 'installment', true ),
470
+ 'promotion_id' => array( 'promotion_id', true ),
471
+ 'cost_of_goods_sold' => array( 'cost_of_goods_sold', true ),
472
+ );
473
+
474
+ public function __construct() {
475
+
476
+ }
477
+
478
+ public function merchants() {
479
+ return array(
480
+ '--1' => __( 'Custom Template', 'woo-feed' ),
481
+ 'custom' => __( 'Custom Feed', 'woo-feed' ),
482
+ '---1' => '',
483
+ // popular
484
+ '--2' => __( 'Popular Templates', 'woo-feed' ),
485
+ 'google' => __( 'Google Shopping', 'woo-feed' ),
486
+ 'google_local' => __( 'Google Local Product', 'woo-feed' ),
487
+ 'google_local_inventory' => __( 'Google Local Product Inventory', 'woo-feed' ),
488
+ 'adwords' => __( 'Google Adwords', 'woo-feed' ),
489
+ 'facebook' => __( 'Facebook', 'woo-feed' ),
490
+ 'pinterest' => __( 'Pinterest', 'woo-feed' ),
491
+ 'bing' => __( 'Bing', 'woo-feed' ),
492
+ 'pricespy' => __( 'PriceSpy', 'woo-feed' ),
493
+ 'idealo' => __( 'Idealo', 'woo-feed' ),
494
+ 'yandex_csv' => __( 'Yandex (CSV)', 'woo-feed' ),
495
+ '---2' => '',
496
+ // others
497
+ '--3' => __( 'Templates', 'woo-feed' ),
498
+ 'adform' => __( 'AdForm', 'woo-feed' ),
499
+ 'adroll' => __( 'AdRoll', 'woo-feed' ),
500
+ 'shopping' => __( 'eBay (Shopping.com)', 'woo-feed' ),
501
+ 'nextag' => __( 'Nextag', 'woo-feed' ),
502
+ 'pricegrabber' => __( 'Price Grabber', 'woo-feed' ),
503
+ 'polyvore' => __( 'Polyvore', 'woo-feed' ),
504
+ 'pricerunner' => __( 'PriceRunner', 'woo-feed' ),
505
+ 'kelkoo' => __( 'Kelkoo', 'woo-feed' ),
506
+ 'shopzilla' => __( 'Shopzilla', 'woo-feed' ),
507
+ 'shopmania' => __( 'Shopmania', 'woo-feed' ),
508
+ 'shopbot' => __( 'Shopbot', 'woo-feed' ),
509
+ 'become' => __( 'Become', 'woo-feed' ),
510
+ 'connexity' => __( 'Connexity', 'woo-feed' ),
511
+ 'prisjakt' => __( 'Prisjakt', 'woo-feed' ),
512
+ 'twenga' => __( 'Twenga', 'woo-feed' ),
513
+ 'fruugo' => __( 'Fruugo', 'woo-feed' ),
514
+ 'fruugo.au' => __( 'Fruugoaustralia.com', 'woo-feed' ),
515
+ 'bonanza' => __( 'Bonanza', 'woo-feed' ),
516
+ 'bol' => __( 'Bol.com', 'woo-feed' ),
517
+ 'leguide' => __( 'LeGuide', 'woo-feed' ),
518
+ 'real' => __( 'Real', 'woo-feed' ),
519
+ 'crowdfox' => __( 'Crowdfox', 'woo-feed' ),
520
+ 'jet' => __( 'Jet.com', 'woo-feed' ),
521
+ 'wish' => __( 'Wish.com', 'woo-feed' ),
522
+ 'zap.co.il' => __( 'Zap.co.il', 'woo-feed' ),
523
+ 'myshopping.com.au' => __( 'Myshopping.com.au', 'woo-feed' ),
524
+ 'smartly.io' => __( 'Smartly.io', 'woo-feed' ),
525
+ 'stylight.com' => __( 'Stylight.com', 'woo-feed' ),
526
+ 'nextad' => __( 'TheNextAd', 'woo-feed' ),
527
+ 'skinflint.co.uk' => __( 'SkinFlint.co.uk', 'woo-feed' ),
528
+ 'yahoo_nfa' => __( 'Yahoo NFA', 'woo-feed' ),
529
+ 'hintaseuranta.fi' => __( 'Hintaseuranta.fi', 'woo-feed' ),
530
+ 'incurvy' => __( 'Incurvy', 'woo-feed' ),
531
+ 'kijiji.ca' => __( 'Kijiji.ca', 'woo-feed' ),
532
+ 'marktplaats.nl' => __( 'Marktplaats.nl', 'woo-feed' ),
533
+ 'rakuten.de' => __( 'Rakuten', 'woo-feed' ),
534
+ 'shopalike.fr' => __( 'Shopalike.fr', 'woo-feed' ),
535
+ 'spartoo.fi' => __( 'Spartoo.fi', 'woo-feed' ),
536
+ 'webmarchand' => __( 'Webmarchand', 'woo-feed' ),
537
+ 'fashiola' => __( 'Fashiola', 'woo-feed' ),
538
+ 'vergelijk_comparer' => __( 'Vergelijk.be & Comparer.be', 'woo-feed' ),
539
+ 'kieskeurig.nl' => __( 'Kieskeurig.nl', 'woo-feed' ),
540
+ 'beslist.nl' => __( 'Beslist.nl', 'woo-feed' ),
541
+ 'billiger.de' => __( 'Billiger.de', 'woo-feed' ),
542
+ 'vertaa.fi' => __( 'Vertaa.fi', 'woo-feed' ),
543
+ 'cdiscount.fr' => __( 'CDiscount.fr', 'woo-feed' ),
544
+ 'fnac.fr' => __( 'Fnac.fr', 'woo-feed' ),
545
+ 'miinto.nl' => __( 'Miinto.nl', 'woo-feed' ),
546
+ 'fyndiq.se' => __( 'Fyndiq.se', 'woo-feed' ),
547
+ 'criteo' => __( 'Criteo', 'woo-feed' ),
548
+ 'avantlink' => __( 'Avantlink', 'woo-feed' ),
549
+ 'shareasale' => __( 'ShareASale', 'woo-feed' ),
550
+ 'walmart' => __( 'Walmart', 'woo-feed' ),
551
+ 'modina.de' => __( 'Modina.de', 'woo-feed' ),
552
+ '---3' => '',
553
+ );
554
+ }
555
+
556
+ public function googleAttributes() {
557
+ $attributes = array(
558
+ '--1' => 'Basic Information',
559
+ 'id' => 'Product Id[id]',
560
+ 'title' => 'Product Title[title]',
561
+ 'description' => 'Product Description[description]',
562
+ 'link' => 'Product URL[link]',
563
+ 'mobile_link' => 'Product URL[mobile_link]',
564
+ 'product_type' => 'Product Categories[product_type] ',
565
+ 'current_category' => 'Google Product Category[google_product_category]',
566
+ 'image' => 'Main Image[image_link]',
567
+ 'images' => 'Comma Separated Images [additional_image_link]',
568
+ 'images_1' => 'Additional Image 1 [additional_image_link]',
569
+ 'images_2' => 'Additional Image 2 [additional_image_link]',
570
+ 'images_3' => 'Additional Image 3 [additional_image_link]',
571
+ 'images_4' => 'Additional Image 4 [additional_image_link]',
572
+ 'images_5' => 'Additional Image 5 [additional_image_link]',
573
+ 'images_6' => 'Additional Image 6 [additional_image_link]',
574
+ 'images_7' => 'Additional Image 7 [additional_image_link]',
575
+ 'images_8' => 'Additional Image 8 [additional_image_link]',
576
+ 'images_9' => 'Additional Image 9 [additional_image_link]',
577
+ 'images_10' => 'Additional Image 10 [additional_image_link]',
578
+ 'condition' => 'Condition[condition]',
579
+ '---1' => '',
580
+ '--2' => 'Availability & Price',
581
+ 'availability' => 'Stock Status[availability]',
582
+ 'availability_date' => 'Availability Date[availability_date]',
583
+ 'cost_of_goods_sold' => 'Cost of Goods Sold[cost_of_goods_sold]',
584
+ 'expiration_date' => 'Expiration Date[expiration_date]',
585
+ 'inventory' => 'Facebook Inventory[inventory]',
586
+ 'override' => 'Facebook Override[override]',
587
+ 'price' => 'Regular Price[price]',
588
+ 'sale_price' => 'Sale Price[sale_price]',
589
+ 'sale_price_effective_date' => 'Sale Price Effective Date[sale_price_effective_date]',
590
+ '---2' => '',
591
+ '--3' => 'Unique Product Identifiers',
592
+ 'brand' => 'Manufacturer[brand]',
593
+ 'upc' => 'GTIN[gtin]',
594
+ 'sku' => 'MPN[mpn]',
595
+ 'identifier_exists' => 'Identifier Exist[identifier_exists]',
596
+ '---3' => '',
597
+ '--4' => 'Detailed Product Attributes',
598
+ 'item_group_id' => 'Item Group Id[item_group_id]',
599
+ 'color' => 'Color[color]',
600
+ 'gender' => 'Gender[gender]',
601
+ 'age_group' => 'Age Group[age_group]',
602
+ 'material' => 'Material[material]',
603
+ 'pattern' => 'Pattern[pattern]',
604
+ 'size' => 'Size of the item[size]',
605
+ 'size_type' => 'Size Type[size_type]',
606
+ 'size_system' => 'Size System[size_system]',
607
+ '---4' => '',
608
+ '--5' => 'Tax & Shipping',
609
+ //'tax' => 'Tax[tax]',
610
+ 'tax_country' => 'Tax Country[tax_country]',
611
+ 'tax_region' => 'Tax Region[tax_region]',
612
+ 'tax_rate' => 'Tax Rate[tax_rate]',
613
+ 'tax_ship' => 'Tax Ship[tax_ship]',
614
+ 'tax_category' => 'Tax[tax_category]',
615
+ 'shipping_country' => 'Shipping Country',
616
+ 'shipping_region' => 'Shipping Region',
617
+ 'shipping_service' => 'Shipping Service',
618
+ 'shipping_price' => 'Shipping Price',
619
+ 'weight' => 'Shipping Weight[shipping_weight]',
620
+ 'length' => 'Shipping Length[shipping_length]',
621
+ 'width' => 'Shipping Width[shipping_width]',
622
+ 'height' => 'Shipping Height[shipping_height]',
623
+ 'shipping_label' => 'Shipping Label[shipping_label]',
624
+ '---5' => '',
625
+ '--6' => 'Product Combinations',
626
+ 'multipack' => 'Multipack[multipack]',
627
+ 'is_bundle' => 'Is Bundle[is_bundle]',
628
+ '---6' => '',
629
+ '--7' => 'Adult Products',
630
+ 'adult' => 'Adult[adult]',
631
+ '---7' => '',
632
+ '--8' => 'AdWord Attributes',
633
+ 'adwords_redirect' => 'Adwords Redirect[adwords_redirect]',
634
+ '---8' => '',
635
+ '--9' => 'Custom Label Attributes',
636
+ 'custom_label_0' => 'Custom label 0 [custom_label_0]',
637
+ 'custom_label_1' => 'Custom label 1 [custom_label_1]',
638
+ 'custom_label_2' => 'Custom label 2 [custom_label_2]',
639
+ 'custom_label_3' => 'Custom label 3 [custom_label_3]',
640
+ 'custom_label_4' => 'Custom label 4 [custom_label_4]',
641
+ '---9' => '',
642
+ '--10' => 'Additional Attributes',
643
+ 'excluded_destination' => 'Excluded Destination[excluded_destination]',
644
+ 'included_destination' => 'Included Destination[included_destination]',
645
+ '---10' => '',
646
+ '--11' => 'Unit Prices (EU Countries and Switzerland Only)',
647
+ 'unit_pricing_measure' => 'Unit Pricing Measure[unit_pricing_measure]',
648
+ 'unit_pricing_base_measure' => 'Unit Pricing Base Measure[unit_pricing_base_measure]',
649
+ 'installment_months' => 'Installment Months[months]',
650
+ 'installment_amount' => 'Installment Amount[amount]',
651
+ 'subscription_period' => 'Subscription Period[period]',
652
+ 'subscription_period_length' => 'Subscription Period Length[period_length]',
653
+ 'subscription_amount' => 'Subscription Amount[amount]',
654
+ '---11' => '',
655
+ '--12' => 'Energy Labels',
656
+ 'energy_efficiency_class' => 'Energy Efficiency Class[energy_efficiency_class]',
657
+ '---12' => '',
658
+ '--13' => 'Loyalty Points (Japan Only)',
659
+ 'loyalty_points' => 'loyalty_points[loyalty_points]',
660
+ '---13' => '',
661
+ '--14' => 'Multiple Installments (Brazil Only)',
662
+ 'installment' => 'Installment[installment]',
663
+ '---14' => '',
664
+ '--15' => 'Merchant Promotions Attribute',
665
+ 'promotion_id' => 'Promotion Id[promotion_id]',
666
+ '---15' => '',
667
+ );
668
+
669
+ return $attributes;
670
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
671
  }
includes/classes/class-woo-feed-dropdown.php CHANGED
@@ -1,5 +1,4 @@
1
  <?php
2
-
3
  /**
4
  * The file that defines the merchants attributes dropdown
5
  *
@@ -13,59 +12,96 @@
13
  * @author Ohidul Islam <wahid@webappick.com>
14
  */
15
 
16
- class Woo_Feed_Dropdown
17
- {
18
-
19
- /**
20
- * Dropdown of Merchant List
21
- *
22
- * @param string $selected
23
- * @return string
24
- */
25
- public function merchantsDropdown( $selected = "" ) {
26
- $selected = esc_attr( $selected );
27
- $attributes = new Woo_Feed_Default_Attributes();
28
- $str = "<option></option>";
29
- foreach ( $attributes->merchants() as $key => $value ) {
30
- if ( substr($key, 0, 2) == "--" ) {
31
- $str .= "<optgroup label='$value'>";
32
- } elseif ( substr($key, 0, 2) == "---" ) {
33
- $str .= "</optgroup>";
34
- } else {
35
- $sltd = "";
36
- if ($selected == $key)
37
- $sltd = 'selected="selected"';
38
- $str .= "<option $sltd value='$key'>" . $value . "</option>";
39
- }
40
- }
41
- return $str;
42
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
 
44
  /**
45
  * Read txt file which contains google taxonomy list
 
46
  * @param string $selected
 
47
  * @return string
48
  */
49
- public function googleTaxonomy( $selected = "" ) {
50
  # Get All Google Taxonomies
51
- $fileName = WOO_FEED_FREE_ADMIN_PATH . "/partials/templates/google_taxonomy.txt";
52
- $customTaxonomyFile = fopen($fileName, "r");
53
- $str = "";
54
  if ( ! empty( $selected ) ) {
55
  $selected = trim( $selected );
56
- if ( ! is_numeric( $selected ) ) $selected = html_entity_decode( $selected );
57
- else $selected = (int) $selected;
 
 
 
58
  }
59
  if ( $customTaxonomyFile ) {
60
  // First line contains metadata, ignore it
61
- @fgets( $customTaxonomyFile );
62
- while ( $line = fgets( $customTaxonomyFile ) ) {
63
- list( $catId, $cat ) = explode("-", $line );
64
  $catId = (int) trim( $catId );
65
- $cat = trim( $cat );
66
- /** @noinspection HtmlUnknownAttribute */
67
- $str .= sprintf(
68
- '<option value="%s"%s>%s</option>',
69
  $catId,
70
  selected( $selected, is_numeric( $selected ) ? $catId : $cat, false ),
71
  $cat
@@ -75,6 +111,7 @@ class Woo_Feed_Dropdown
75
  if ( ! empty( $str ) ) {
76
  $str = "<option></option>" . $str;
77
  }
 
78
  return $str;
79
  }
80
 
@@ -85,13 +122,13 @@ class Woo_Feed_Dropdown
85
  */
86
  public function googleTaxonomyArray() {
87
  # Get All Google Taxonomies
88
- $fileName = WOO_FEED_FREE_ADMIN_PATH . "/partials/templates/google_taxonomy.txt";
89
- $customTaxonomyFile = fopen( $fileName, "r" );
90
- $taxonomy = [];
91
  if ( $customTaxonomyFile ) {
92
  // First line contains metadata, ignore it
93
- @fgets( $customTaxonomyFile );
94
- while ( $line = fgets( $customTaxonomyFile ) ) {
95
  list( $catId, $cat ) = explode( "-", $line );
96
  $taxonomy[] = [
97
  'value' => absint( trim( $catId ) ),
@@ -100,820 +137,33 @@ class Woo_Feed_Dropdown
100
  }
101
  }
102
  $taxonomy = array_filter( $taxonomy );
 
103
  return $taxonomy;
104
  }
105
 
106
- public function amazon_clothingAttributesDropdown( $selected = "" ) {
107
- $attributes = new Woo_Feed_Default_Attributes();
108
- $str = "<option></option>";
109
- foreach ( $attributes->amazon_clothingAttributes() as $key => $value ) {
110
- if ( substr($key, 0, 2) == "--" ) {
111
- $str .= "<optgroup label='$value'>";
112
- } elseif ( substr($key, 0, 2) == "---" ) {
113
- $str .= "</optgroup>";
114
- } else {
115
- $sltd = "";
116
- if ($selected == $key)
117
- $sltd = 'selected="selected"';
118
- $str .= "<option $sltd value='$key'>" . $value ." [".$key."]". "</option>";
119
- }
120
- }
121
- return $str;
122
- }
123
-
124
- public function amazon_jewelryAttributesDropdown( $selected = "" ) {
125
- $attributes = new Woo_Feed_Default_Attributes();
126
- $str = "<option></option>";
127
- foreach ( $attributes->amazon_jewelryAttributes() as $key => $value ) {
128
- if ( substr($key, 0, 2) == "--" ) {
129
- $str .= "<optgroup label='$value'>";
130
- } elseif ( substr($key, 0, 2) == "---" ) {
131
- $str .= "</optgroup>";
132
- } else {
133
- $sltd = "";
134
- if ($selected == $key)
135
- $sltd = 'selected="selected"';
136
- $str .= "<option $sltd value='$key'>" . $value ." [".$key."]". "</option>";
137
- }
138
- }
139
- return $str;
140
- }
141
-
142
- public function amazon_jewelry_frAttributesDropdown( $selected = "" ) {
143
- $attributes = new Woo_Feed_Default_Attributes();
144
- $str = "<option></option>";
145
- foreach ( $attributes->amazon_jewelry_frAttributes() as $key => $value ) {
146
- if ( substr($key, 0, 2) == "--" ) {
147
- $str .= "<optgroup label='$value'>";
148
- } elseif ( substr($key, 0, 2) == "---" ) {
149
- $str .= "</optgroup>";
150
- } else {
151
- $sltd = "";
152
- if ($selected == $key)
153
- $sltd = 'selected="selected"';
154
- $str .= "<option $sltd value='$key'>" . $value ." [".$key."]". "</option>";
155
- }
156
- }
157
- return $str;
158
- }
159
-
160
- public function amazon_lightingAttributesDropdown( $selected = "" ) {
161
- $attributes = new Woo_Feed_Default_Attributes();
162
- $str = "<option></option>";
163
- foreach ( $attributes->amazon_lightingAttributes() as $key => $value ) {
164
- if ( substr($key, 0, 2) == "--" ) {
165
- $str .= "<optgroup label='$value'>";
166
- } elseif ( substr($key, 0, 2) == "---" ) {
167
- $str .= "</optgroup>";
168
- } else {
169
- $sltd = "";
170
- if ($selected == $key)
171
- $sltd = 'selected="selected"';
172
- $str .= "<option $sltd value='$key'>" . $value ." [".$key."]". "</option>";
173
- }
174
- }
175
- return $str;
176
- }
177
- public function amazon_wirelessAttributesDropdown( $selected = "" ) {
178
- $attributes = new Woo_Feed_Default_Attributes();
179
- $str = "<option></option>";
180
- foreach ( $attributes->amazon_wirelessAttributes() as $key => $value ) {
181
- if ( substr($key, 0, 2) == "--" ) {
182
- $str .= "<optgroup label='$value'>";
183
- } elseif ( substr($key, 0, 2) == "---" ) {
184
- $str .= "</optgroup>";
185
- } else {
186
- $sltd = "";
187
- if ($selected == $key)
188
- $sltd = 'selected="selected"';
189
- $str .= "<option $sltd value='$key'>" . $value ." [".$key."]". "</option>";
190
- }
191
- }
192
- return $str;
193
- }
194
- public function amazon_autoaccessoryAttributesDropdown( $selected = "" ) {
195
- $attributes = new Woo_Feed_Default_Attributes();
196
- $str = "<option></option>";
197
- foreach ( $attributes->amazon_autoaccessoryAttributes() as $key => $value ) {
198
- if ( substr($key, 0, 2) == "--" ) {
199
- $str .= "<optgroup label='$value'>";
200
- } elseif ( substr($key, 0, 2) == "---" ) {
201
- $str .= "</optgroup>";
202
- } else {
203
- $sltd = "";
204
- if ($selected == $key)
205
- $sltd = 'selected="selected"';
206
- $str .= "<option $sltd value='$key'>" . $value ." [".$key."]". "</option>";
207
- }
208
- }
209
- return $str;
210
- }
211
- public function amazon_tiresandwheelsAttributesDropdown( $selected = "" ) {
212
- $attributes = new Woo_Feed_Default_Attributes();
213
- $str = "<option></option>";
214
- foreach ( $attributes->amazon_tiresandwheelsAttributes() as $key => $value ) {
215
- if ( substr($key, 0, 2) == "--" ) {
216
- $str .= "<optgroup label='$value'>";
217
- } elseif ( substr($key, 0, 2) == "---" ) {
218
- $str .= "</optgroup>";
219
- } else {
220
- $sltd = "";
221
- if ($selected == $key)
222
- $sltd = 'selected="selected"';
223
- $str .= "<option $sltd value='$key'>" . $value ." [".$key."]". "</option>";
224
- }
225
- }
226
- return $str;
227
- }
228
- public function amazon_homeAttributesDropdown( $selected = "" ) {
229
- $attributes = new Woo_Feed_Default_Attributes();
230
- $str = "<option></option>";
231
- foreach ( $attributes->amazon_homeAttributes() as $key => $value ) {
232
- if ( substr($key, 0, 2) == "--" ) {
233
- $str .= "<optgroup label='$value'>";
234
- } elseif ( substr($key, 0, 2) == "---" ) {
235
- $str .= "</optgroup>";
236
- } else {
237
- $sltd = "";
238
- if ($selected == $key)
239
- $sltd = 'selected="selected"';
240
- $str .= "<option $sltd value='$key'>" . $value ." [".$key."]". "</option>";
241
- }
242
- }
243
- return $str;
244
- }
245
- public function amazon_healthAttributesDropdown( $selected = "" ) {
246
- $attributes = new Woo_Feed_Default_Attributes();
247
- $str = "<option></option>";
248
- foreach ( $attributes->amazon_healthAttributes() as $key => $value ) {
249
- if ( substr($key, 0, 2) == "--" ) {
250
- $str .= "<optgroup label='$value'>";
251
- } elseif ( substr($key, 0, 2) == "---" ) {
252
- $str .= "</optgroup>";
253
- } else {
254
- $sltd = "";
255
- if ($selected == $key)
256
- $sltd = 'selected="selected"';
257
- $str .= "<option $sltd value='$key'>" . $value ." [".$key."]". "</option>";
258
- }
259
- }
260
- return $str;
261
- }
262
- public function amazon_babyAttributesDropdown( $selected = "" ) {
263
- $attributes = new Woo_Feed_Default_Attributes();
264
- $str = "<option></option>";
265
- foreach ( $attributes->amazon_babyAttributes() as $key => $value ) {
266
- if ( substr($key, 0, 2) == "--" ) {
267
- $str .= "<optgroup label='$value'>";
268
- } elseif ( substr($key, 0, 2) == "---" ) {
269
- $str .= "</optgroup>";
270
- } else {
271
- $sltd = "";
272
- if ($selected == $key)
273
- $sltd = 'selected="selected"';
274
- $str .= "<option $sltd value='$key'>" . $value ." [".$key."]". "</option>";
275
- }
276
- }
277
- return $str;
278
- }
279
- public function amazon_BookLoaderAttributesDropdown( $selected = "" ) {
280
- $attributes = new Woo_Feed_Default_Attributes();
281
- $str = "<option></option>";
282
- foreach ( $attributes->amazon_BookLoaderAttributes() as $key => $value ) {
283
- if ( substr($key, 0, 2) == "--" ) {
284
- $str .= "<optgroup label='$value'>";
285
- } elseif ( substr($key, 0, 2) == "---" ) {
286
- $str .= "</optgroup>";
287
- } else {
288
- $sltd = "";
289
- if ($selected == $key)
290
- $sltd = 'selected="selected"';
291
- $str .= "<option $sltd value='$key'>" . $value ." [".$key."]". "</option>";
292
- }
293
- }
294
- return $str;
295
- }
296
- public function amazon_CameraAndPhotoAttributesDropdown( $selected = "" ) {
297
- $attributes = new Woo_Feed_Default_Attributes();
298
- $str = "<option></option>";
299
- foreach ( $attributes->amazon_CameraAndPhotoAttributes() as $key => $value ) {
300
- if ( substr($key, 0, 2) == "--" ) {
301
- $str .= "<optgroup label='$value'>";
302
- } elseif ( substr($key, 0, 2) == "---" ) {
303
- $str .= "</optgroup>";
304
- } else {
305
- $sltd = "";
306
- if ($selected == $key)
307
- $sltd = 'selected="selected"';
308
- $str .= "<option $sltd value='$key'>" . $value ." [".$key."]". "</option>";
309
- }
310
- }
311
- return $str;
312
- }
313
- public function amazon_foodandbeveragesAttributesDropdown( $selected = "" ) {
314
- $attributes = new Woo_Feed_Default_Attributes();
315
- $str = "<option></option>";
316
- foreach ( $attributes->amazon_foodandbeveragesAttributes() as $key => $value ) {
317
- if ( substr($key, 0, 2) == "--" ) {
318
- $str .= "<optgroup label='$value'>";
319
- } elseif ( substr($key, 0, 2) == "---" ) {
320
- $str .= "</optgroup>";
321
- } else {
322
- $sltd = "";
323
- if ($selected == $key)
324
- $sltd = 'selected="selected"';
325
- $str .= "<option $sltd value='$key'>" . $value ." [".$key."]". "</option>";
326
- }
327
- }
328
- return $str;
329
- }
330
- public function amazon_computersAttributesDropdown( $selected = "" ) {
331
- $attributes = new Woo_Feed_Default_Attributes();
332
- $str = "<option></option>";
333
- foreach ( $attributes->amazon_computersAttributes() as $key => $value ) {
334
- if ( substr($key, 0, 2) == "--" ) {
335
- $str .= "<optgroup label='$value'>";
336
- } elseif ( substr($key, 0, 2) == "---" ) {
337
- $str .= "</optgroup>";
338
- } else {
339
- $sltd = "";
340
- if ($selected == $key)
341
- $sltd = 'selected="selected"';
342
- $str .= "<option $sltd value='$key'>" . $value ." [".$key."]". "</option>";
343
- }
344
- }
345
- return $str;
346
- }
347
- public function amazon_ConsumerElectronicsAttributesDropdown( $selected = "" ) {
348
- $attributes = new Woo_Feed_Default_Attributes();
349
- $str = "<option></option>";
350
- foreach ( $attributes->amazon_ConsumerElectronicsAttributes() as $key => $value ) {
351
- if ( substr($key, 0, 2) == "--" ) {
352
- $str .= "<optgroup label='$value'>";
353
- } elseif ( substr($key, 0, 2) == "---" ) {
354
- $str .= "</optgroup>";
355
- } else {
356
- $sltd = "";
357
- if ($selected == $key)
358
- $sltd = 'selected="selected"';
359
- $str .= "<option $sltd value='$key'>" . $value ." [".$key."]". "</option>";
360
- }
361
- }
362
- return $str;
363
- }
364
- public function amazon_entertainmentcollectiblesAttributesDropdown( $selected = "" ) {
365
- $attributes = new Woo_Feed_Default_Attributes();
366
- $str = "<option></option>";
367
- foreach ( $attributes->amazon_entertainmentcollectiblesAttributes() as $key => $value ) {
368
- if ( substr($key, 0, 2) == "--" ) {
369
- $str .= "<optgroup label='$value'>";
370
- } elseif ( substr($key, 0, 2) == "---" ) {
371
- $str .= "</optgroup>";
372
- } else {
373
- $sltd = "";
374
- if ($selected == $key)
375
- $sltd = 'selected="selected"';
376
- $str .= "<option $sltd value='$key'>" . $value ." [".$key."]". "</option>";
377
- }
378
- }
379
- return $str;
380
- }
381
- public function amazon_homeimprovementAttributesDropdown( $selected = "" ) {
382
- $attributes = new Woo_Feed_Default_Attributes();
383
- $str = "<option></option>";
384
- foreach ( $attributes->amazon_homeimprovementAttributes() as $key => $value ) {
385
- if ( substr($key, 0, 2) == "--" ) {
386
- $str .= "<optgroup label='$value'>";
387
- } elseif ( substr($key, 0, 2) == "---" ) {
388
- $str .= "</optgroup>";
389
- } else {
390
- $sltd = "";
391
- if ($selected == $key)
392
- $sltd = 'selected="selected"';
393
- $str .= "<option $sltd value='$key'>" . $value ." [".$key."]". "</option>";
394
- }
395
- }
396
- return $str;
397
- }
398
- public function amazon_officeAttributesDropdown( $selected = "" ) {
399
- $attributes = new Woo_Feed_Default_Attributes();
400
- $str = "<option></option>";
401
- foreach ( $attributes->amazon_officeAttributes() as $key => $value ) {
402
- if ( substr($key, 0, 2) == "--" ) {
403
- $str .= "<optgroup label='$value'>";
404
- } elseif ( substr($key, 0, 2) == "---" ) {
405
- $str .= "</optgroup>";
406
- } else {
407
- $sltd = "";
408
- if ($selected == $key)
409
- $sltd = 'selected="selected"';
410
- $str .= "<option $sltd value='$key'>" . $value ." [".$key."]". "</option>";
411
- }
412
- }
413
- return $str;
414
- }
415
- public function amazon_petsuppliesAttributesDropdown( $selected = "" ) {
416
- $attributes = new Woo_Feed_Default_Attributes();
417
- $str = "<option></option>";
418
- foreach ( $attributes->amazon_petsuppliesAttributes() as $key => $value ) {
419
- if ( substr($key, 0, 2) == "--" ) {
420
- $str .= "<optgroup label='$value'>";
421
- } elseif ( substr($key, 0, 2) == "---" ) {
422
- $str .= "</optgroup>";
423
- } else {
424
- $sltd = "";
425
- if ($selected == $key)
426
- $sltd = 'selected="selected"';
427
- $str .= "<option $sltd value='$key'>" . $value ." [".$key."]". "</option>";
428
- }
429
- }
430
- return $str;
431
- }
432
-
433
- public function amazon_sportsmemorabiliaAttributesDropdown( $selected = "" ) {
434
- $attributes = new Woo_Feed_Default_Attributes();
435
- $str = "<option></option>";
436
- foreach ( $attributes->amazon_sportsmemorabiliaAttributes() as $key => $value ) {
437
- if ( substr($key, 0, 2) == "--" ) {
438
- $str .= "<optgroup label='$value'>";
439
- } elseif ( substr($key, 0, 2) == "---" ) {
440
- $str .= "</optgroup>";
441
- } else {
442
- $sltd = "";
443
- if ($selected == $key)
444
- $sltd = 'selected="selected"';
445
- $str .= "<option $sltd value='$key'>" . $value ." [".$key."]". "</option>";
446
- }
447
- }
448
- return $str;
449
- }
450
- public function amazon_shoesAttributesDropdown( $selected = "" ) {
451
- $attributes = new Woo_Feed_Default_Attributes();
452
- $str = "<option></option>";
453
- foreach ( $attributes->amazon_shoesAttributes() as $key => $value ) {
454
- if ( substr($key, 0, 2) == "--" ) {
455
- $str .= "<optgroup label='$value'>";
456
- } elseif ( substr($key, 0, 2) == "---" ) {
457
- $str .= "</optgroup>";
458
- } else {
459
- $sltd = "";
460
- if ($selected == $key)
461
- $sltd = 'selected="selected"';
462
- $str .= "<option $sltd value='$key'>" . $value ." [".$key."]". "</option>";
463
- }
464
- }
465
- return $str;
466
- }
467
- public function amazon_sportsAttributesDropdown( $selected = "" ) {
468
- $attributes = new Woo_Feed_Default_Attributes();
469
- $str = "<option></option>";
470
- foreach ( $attributes->amazon_sportsAttributes() as $key => $value ) {
471
- if ( substr($key, 0, 2) == "--" ) {
472
- $str .= "<optgroup label='$value'>";
473
- } elseif ( substr($key, 0, 2) == "---" ) {
474
- $str .= "</optgroup>";
475
- } else {
476
- $sltd = "";
477
- if ($selected == $key)
478
- $sltd = 'selected="selected"';
479
- $str .= "<option $sltd value='$key'>" . $value ." [".$key."]". "</option>";
480
- }
481
- }
482
- return $str;
483
- }
484
- public function amazon_toysAttributesDropdown( $selected = "" ) {
485
- $attributes = new Woo_Feed_Default_Attributes();
486
- $str = "<option></option>";
487
- foreach ( $attributes->amazon_toysAttributes() as $key => $value ) {
488
- if ( substr($key, 0, 2) == "--" ) {
489
- $str .= "<optgroup label='$value'>";
490
- } elseif ( substr($key, 0, 2) == "---" ) {
491
- $str .= "</optgroup>";
492
- } else {
493
- $sltd = "";
494
- if ($selected == $key)
495
- $sltd = 'selected="selected"';
496
- $str .= "<option $sltd value='$key'>" . $value ." [".$key."]". "</option>";
497
- }
498
- }
499
- return $str;
500
- }
501
- public function amazon_TradingCardsAttributesDropdown( $selected = "" ) {
502
- $attributes = new Woo_Feed_Default_Attributes();
503
- $str = "<option></option>";
504
- foreach ( $attributes->amazon_TradingCardsAttributes() as $key => $value ) {
505
- if ( substr($key, 0, 2) == "--" ) {
506
- $str .= "<optgroup label='$value'>";
507
- } elseif ( substr($key, 0, 2) == "---" ) {
508
- $str .= "</optgroup>";
509
- } else {
510
- $sltd = "";
511
- if ($selected == $key)
512
- $sltd = 'selected="selected"';
513
- $str .= "<option $sltd value='$key'>" . $value ." [".$key."]". "</option>";
514
- }
515
- }
516
- return $str;
517
- }
518
- public function amazon_watchesAttributesDropdown( $selected = "" ) {
519
- $attributes = new Woo_Feed_Default_Attributes();
520
- $str = "<option></option>";
521
- foreach ( $attributes->amazon_watchesAttributes() as $key => $value ) {
522
- if ( substr($key, 0, 2) == "--" ) {
523
- $str .= "<optgroup label='$value'>";
524
- } elseif ( substr($key, 0, 2) == "---" ) {
525
- $str .= "</optgroup>";
526
- } else {
527
- $sltd = "";
528
- if ($selected == $key)
529
- $sltd = 'selected="selected"';
530
- $str .= "<option $sltd value='$key'>" . $value ." [".$key."]". "</option>";
531
- }
532
- }
533
- return $str;
534
- }
535
-
536
- /**
537
- * Dropdown of pricespy Attribute List
538
- *
539
- * @param string $selected
540
- * @return string
541
- */
542
- public function pricespyAttributesDropdown( $selected = "" ) {
543
- $attributes = new Woo_Feed_Default_Attributes();
544
- $str = "<option></option>";
545
- foreach ( $attributes->pricespyAttribute() as $key => $value ) {
546
- if ( substr($key, 0, 2) == "--" ) {
547
- $str .= "<optgroup label='$value'>";
548
- } elseif ( substr($key, 0, 2) == "---" ) {
549
- $str .= "</optgroup>";
550
- } else {
551
- $sltd = "";
552
- if ($selected == $key)
553
- $sltd = 'selected="selected"';
554
- $str .= "<option $sltd value='$key'>" . $value . "</option>";
555
- }
556
- }
557
- return $str;
558
- }
559
-
560
- /**
561
- * Dropdown of pricespy Attribute List
562
- *
563
- * @param string $selected
564
- * @return string
565
- */
566
- public function prisjaktAttributesDropdown( $selected = "" ) {
567
- $attributes = new Woo_Feed_Default_Attributes();
568
- $str = "<option></option>";
569
- foreach ( $attributes->prisjaktAttribute() as $key => $value ) {
570
- if ( substr($key, 0, 2) == "--" ) {
571
- $str .= "<optgroup label='$value'>";
572
- } elseif ( substr($key, 0, 2) == "---" ) {
573
- $str .= "</optgroup>";
574
- } else {
575
- $sltd = "";
576
- if ($selected == $key)
577
- $sltd = 'selected="selected"';
578
- $str .= "<option $sltd value='$key'>" . $value . "</option>";
579
- }
580
- }
581
- return $str;
582
- }
583
-
584
- /**
585
- * Dropdown of Google Attribute List
586
- *
587
- * @param string $selected
588
- * @return string
589
- */
590
- public function googleAttributesDropdown( $selected = "" ) {
591
- $attributes = new Woo_Feed_Default_Attributes();
592
- $str = "<option></option>";
593
- foreach ( $attributes->googleAttributes() as $key => $value ) {
594
- if ( substr($key, 0, 2) == "--" ) {
595
- $str .= "<optgroup label='$value'>";
596
- } elseif ( substr($key, 0, 2) == "---" ) {
597
- $str .= "</optgroup>";
598
- } else {
599
- $sltd = "";
600
- if ($selected == $key)
601
- $sltd = 'selected="selected"';
602
- $str .= "<option $sltd value='$key'>" . $value . "</option>";
603
- }
604
- }
605
- return $str;
606
- }
607
-
608
- /**
609
- * Dropdown of pinterest Attribute List
610
- *
611
- * @param string $selected
612
- * @return string
613
- */
614
- public function pinterestAttributesDropdown( $selected = "" ) {
615
- $attributes = new Woo_Feed_Default_Attributes();
616
- $str = "<option></option>";
617
- foreach ( $attributes->googleAttributes() as $key => $value ) {
618
- if ( substr($key, 0, 2) == "--" ) {
619
- $str .= "<optgroup label='$value'>";
620
- } elseif ( substr($key, 0, 2) == "---" ) {
621
- $str .= "</optgroup>";
622
- } else {
623
- $sltd = "";
624
- if ($selected == $key)
625
- $sltd = 'selected="selected"';
626
- $str .= "<option $sltd value='$key'>" . $value . "</option>";
627
- }
628
- }
629
- return $str;
630
- }
631
-
632
- /**
633
- * Dropdown of Facebook Attribute List
634
- *
635
- * @param string $selected
636
- * @return string
637
- */
638
- public function facebookAttributesDropdown( $selected = "" ) {
639
- $attributes = new Woo_Feed_Default_Attributes();
640
- $str = "<option></option>";
641
- foreach ( $attributes->googleAttributes() as $key => $value ) {
642
- if ( substr($key, 0, 2) == "--" ) {
643
- $str .= "<optgroup label='$value'>";
644
- } elseif ( substr($key, 0, 2) == "---" ) {
645
- $str .= "</optgroup>";
646
- } else {
647
- $sltd = "";
648
- if ($selected == $key)
649
- $sltd = 'selected="selected"';
650
- $str .= "<option $sltd value='$key'>" . $value . "</option>";
651
- }
652
- }
653
- return $str;
654
- }
655
-
656
- /**
657
- * Dropdown of Facebook Attribute List
658
- *
659
- * @param string $selected
660
- * @return string
661
- */
662
- public function shopbotAttributesDropdown( $selected = "" ) {
663
- $attributes = new Woo_Feed_Default_Attributes();
664
- $str = "<option></option>";
665
- foreach ( $attributes->shopbotAttribute() as $key => $value ) {
666
- if ( substr($key, 0, 2) == "--" ) {
667
- $str .= "<optgroup label='$value'>";
668
- } elseif ( substr($key, 0, 2) == "---" ) {
669
- $str .= "</optgroup>";
670
- } else {
671
- $sltd = "";
672
- if ($selected == $key)
673
- $sltd = 'selected="selected"';
674
- $str .= "<option $sltd value='$key'>" . $value . "</option>";
675
- }
676
- }
677
- return $str;
678
- }
679
-
680
- /**
681
- * Dropdown of Amazon Attribute List
682
- *
683
- * @param string $selected
684
- * @return string
685
- */
686
- public function amazonAttributesDropdown( $selected = "" ) {
687
- $attributes = new Woo_Feed_Default_Attributes();
688
- $str = "<option></option>";
689
- foreach ( $attributes->amazonAttributes() as $key => $value ) {
690
- if ( substr($key, 0, 2) == "--" ) {
691
- $str .= "<optgroup label='$value'>";
692
- } elseif ( substr($key, 0, 2) == "---" ) {
693
- $str .= "</optgroup>";
694
- } else {
695
- $sltd = "";
696
- if ($selected == $key)
697
- $sltd = 'selected="selected"';
698
- $str .= "<option $sltd value='$key'>" . $value . "</option>";
699
- }
700
- }
701
- return $str;
702
- }
703
- /**
704
- * Dropdown of Pricegraber Attribute List
705
- *
706
- * @param string $selected
707
- * @return string
708
- */
709
- public function priceGrabberAttributesDropdown( $selected = "" ) {
710
- $attributes = new Woo_Feed_Default_Attributes();
711
- $str = "<option></option>";
712
- foreach ( $attributes->priceGrabberAttribute() as $key => $value ) {
713
- if ( substr($key, 0, 2) == "--" ) {
714
- $str .= "<optgroup label='$value'>";
715
- } elseif ( substr($key, 0, 2) == "---" ) {
716
- $str .= "</optgroup>";
717
- } else {
718
- $sltd = "";
719
- if ($selected == $key)
720
- $sltd = 'selected="selected"';
721
- $str .= "<option $sltd value='$key'>" . $value . "</option>";
722
- }
723
- }
724
- return $str;
725
- }
726
-
727
- /**
728
- * Dropdown of Nextag Attribute List
729
- *
730
- * @param string $selected
731
- * @return string
732
- */
733
- public function nextagAttributesDropdown( $selected = "" ) {
734
- $attributes = new Woo_Feed_Default_Attributes();
735
- $str = "<option></option>";
736
- foreach ( $attributes->nextagAttribute() as $key => $value ) {
737
- if ( substr($key, 0, 2) == "--" ) {
738
- $str .= "<optgroup label='$value'>";
739
- } elseif ( substr($key, 0, 2) == "---" ) {
740
- $str .= "</optgroup>";
741
- } else {
742
- $sltd = "";
743
- if ($selected == $key)
744
- $sltd = 'selected="selected"';
745
- $str .= "<option $sltd value='$key'>" . $value . "</option>";
746
- }
747
- }
748
- return $str;
749
- }
750
-
751
- /**
752
- * Dropdown of kelkoo Attribute List
753
- *
754
- * @param string $selected
755
- * @return string
756
- */
757
- public function kelkooAttributesDropdown( $selected = "" ) {
758
- $attributes = new Woo_Feed_Default_Attributes();
759
- $str = "<option></option>";
760
- foreach ( $attributes->kelkooAttribute() as $key => $value ) {
761
- if ( substr($key, 0, 2) == "--" ) {
762
- $str .= "<optgroup label='$value'>";
763
- } elseif ( substr($key, 0, 2) == "---" ) {
764
- $str .= "</optgroup>";
765
- } else {
766
- $sltd = "";
767
- if ($selected == $key)
768
- $sltd = 'selected="selected"';
769
- $str .= "<option $sltd value='$key'>" . $value . "</option>";
770
- }
771
- }
772
- return $str;
773
- }
774
-
775
- /**
776
- * Dropdown of Shopzilla Attribute List
777
- *
778
- * @param string $selected
779
- * @return string
780
- */
781
- public function shopzillaAttributesDropdown( $selected = "" ) {
782
- $attributes = new Woo_Feed_Default_Attributes();
783
- $str = "<option></option>";
784
- foreach ( $attributes->shopzillaAttribute() as $key => $value ) {
785
- if ( substr($key, 0, 2) == "--" ) {
786
- $str .= "<optgroup label='$value'>";
787
- } elseif ( substr($key, 0, 2) == "---" ) {
788
- $str .= "</optgroup>";
789
- } else {
790
- $sltd = "";
791
- if ($selected == $key)
792
- $sltd = 'selected="selected"';
793
- $str .= "<option $sltd value='$key'>" . $value . "</option>";
794
- }
795
- }
796
- return $str;
797
- }
798
-
799
- /**
800
- * Dropdown of Shopping.com Attribute List
801
- *
802
- * @param string $selected
803
- * @return string
804
- */
805
- public function shoppingAttributesDropdown( $selected = "" ) {
806
- $attributes = new Woo_Feed_Default_Attributes();
807
- $str = "<option></option>";
808
- foreach ( $attributes->shoppingAttribute() as $key => $value ) {
809
- if ( substr($key, 0, 2) == "--" ) {
810
- $str .= "<optgroup label='$value'>";
811
- } elseif ( substr($key, 0, 2) == "---" ) {
812
- $str .= "</optgroup>";
813
- } else {
814
- $sltd = "";
815
- if ($selected == $key)
816
- $sltd = 'selected="selected"';
817
- $str .= "<option $sltd value='$key'>" . $value . "</option>";
818
- }
819
- }
820
- return $str;
821
- }
822
-
823
- /**
824
- * Dropdown of Shopmania Attribute List
825
- *
826
- * @param string $selected
827
- * @return string
828
- */
829
- public function shopmaniaAttributesDropdown( $selected = "" ) {
830
- $attributes = new Woo_Feed_Default_Attributes();
831
- $str = "<option></option>";
832
- foreach ( $attributes->shopmaniaAttribute() as $key => $value ) {
833
- if ( substr($key, 0, 2) == "--" ) {
834
- $str .= "<optgroup label='$value'>";
835
- } elseif ( substr($key, 0, 2) == "---" ) {
836
- $str .= "</optgroup>";
837
- } else {
838
- $sltd = "";
839
- if ($selected == $key)
840
- $sltd = 'selected="selected"';
841
- $str .= "<option $sltd value='$key'>" . $value . "</option>";
842
- }
843
- }
844
- return $str;
845
- }
846
-
847
-
848
- /**
849
- * Dropdown of Bing.com Attribute List
850
- *
851
- * @param string $selected
852
- * @return string
853
- */
854
- public function bingAttributesDropdown( $selected = "" ) {
855
- $attributes = new Woo_Feed_Default_Attributes();
856
- $str = "<option></option>";
857
- foreach ( $attributes->bingAttribute() as $key => $value ) {
858
- if ( substr($key, 0, 2) == "--" ) {
859
- $str .= "<optgroup label='$value'>";
860
- } elseif ( substr($key, 0, 2) == "---" ) {
861
- $str .= "</optgroup>";
862
- } else {
863
- $sltd = "";
864
- if ($selected == $key)
865
- $sltd = 'selected="selected"';
866
- $str .= "<option $sltd value='$key'>" . $value . "</option>";
867
- }
868
- }
869
- return $str;
870
- }
871
-
872
- /**
873
- * Dropdown of become.com Attribute List
874
- *
875
- * @param string $selected
876
- * @return string
877
- */
878
- public function becomeAttributesDropdown( $selected = "" ) {
879
- $attributes = new Woo_Feed_Default_Attributes();
880
- $str = "<option></option>";
881
- foreach ( $attributes->becomeAttribute() as $key => $value ) {
882
- if ( substr($key, 0, 2) == "--" ) {
883
- $str .= "<optgroup label='$value'>";
884
- } elseif ( substr($key, 0, 2) == "---" ) {
885
- $str .= "</optgroup>";
886
- } else {
887
- $sltd = "";
888
- if ($selected == $key)
889
- $sltd = 'selected="selected"';
890
- $str .= "<option $sltd value='$key'>" . $value . "</option>";
891
- }
892
- }
893
- return $str;
894
- }
895
-
896
- /**
897
- * Dropdown of connexity.com Attribute List
898
- *
899
- * @param string $selected
900
- * @return string
901
- */
902
- public function connexityAttributesDropdown( $selected = "" ) {
903
- $attributes = new Woo_Feed_Default_Attributes();
904
- $str = "<option></option>";
905
- foreach ( $attributes->becomeAttribute() as $key => $value ) {
906
- if ( substr($key, 0, 2) == "--" ) {
907
- $str .= "<optgroup label='$value'>";
908
- } elseif ( substr($key, 0, 2) == "---" ) {
909
- $str .= "</optgroup>";
910
- } else {
911
- $sltd = "";
912
- if ($selected == $key)
913
- $sltd = 'selected="selected"';
914
- $str .= "<option $sltd value='$key'>" . $value . "</option>";
915
- }
916
- }
917
- return $str;
918
- }
919
  }
1
  <?php
 
2
  /**
3
  * The file that defines the merchants attributes dropdown
4
  *
12
  * @author Ohidul Islam <wahid@webappick.com>
13
  */
14
 
15
+ class Woo_Feed_Dropdown {
16
+
17
+ public $cats = array();
18
+ public $output_types = array(
19
+ '1' => 'Default',
20
+ '2' => 'Strip Tags',
21
+ '3' => 'UTF-8 Encode',
22
+ '4' => 'htmlentities',
23
+ '5' => 'Integer',
24
+ '6' => 'Price',
25
+ '7' => 'Remove Space',
26
+ '10' => 'Remove ShortCodes',
27
+ '9' => 'Remove Special Character',
28
+ '8' => 'CDATA',
29
+ );
30
+
31
+ public function __construct() {
32
+ }
33
+
34
+ /**
35
+ * Dropdown of Merchant List
36
+ *
37
+ * @param string $selected
38
+ *
39
+ * @return string
40
+ */
41
+ public function merchantsDropdown( $selected = '' ) {
42
+ $selected = esc_attr( $selected );
43
+ $attributes = new Woo_Feed_Default_Attributes();
44
+ $str = '<option></option>';
45
+ foreach ( $attributes->merchants() as $key => $value ) {
46
+ if ( '--' == substr( $key, 0, 2 ) ) {
47
+ $str .= "<optgroup label='$value'>";
48
+ } elseif ( '---' == substr( $key, 0, 2 ) ) {
49
+ $str .= '</optgroup>';
50
+ } else {
51
+ $sltd = '';
52
+ if ( $selected == $key ) {
53
+ $sltd = 'selected="selected"';
54
+ }
55
+ $str .= "<option $sltd value='$key'>" . $value . '</option>';
56
+ }
57
+ }
58
+
59
+ return $str;
60
+ }
61
+
62
+ public function outputTypes() {
63
+ $output_types = get_option( 'woo_feed_output_type_options' );
64
+ if ( ! empty( $output_types ) ) {
65
+ return $output_types;
66
+ }
67
+ $str = '';
68
+ foreach ( $this->output_types as $key => $value ) {
69
+ $str .= "<option value='$key'>" . $value . '</option>';
70
+ }
71
+ update_option( 'woo_feed_output_type_options', $str, false );
72
+
73
+ return $str;
74
+ }
75
 
76
  /**
77
  * Read txt file which contains google taxonomy list
78
+ *
79
  * @param string $selected
80
+ *
81
  * @return string
82
  */
83
+ public function googleTaxonomy( $selected = '' ) {
84
  # Get All Google Taxonomies
85
+ $fileName = WOO_FEED_FREE_ADMIN_PATH . '/partials/templates/google_taxonomy.txt';
86
+ $customTaxonomyFile = fopen( $fileName, 'r' ); // phpcs:ignore
87
+ $str = '';
88
  if ( ! empty( $selected ) ) {
89
  $selected = trim( $selected );
90
+ if ( ! is_numeric( $selected ) ) {
91
+ $selected = html_entity_decode( $selected );
92
+ } else {
93
+ $selected = (int) $selected;
94
+ }
95
  }
96
  if ( $customTaxonomyFile ) {
97
  // First line contains metadata, ignore it
98
+ fgets( $customTaxonomyFile ); // phpcs:ignore
99
+ while ( $line = fgets( $customTaxonomyFile ) ) { // phpcs:ignore
100
+ list( $catId, $cat ) = explode( "-", $line );
101
  $catId = (int) trim( $catId );
102
+ $cat = trim( $cat );
103
+ $str .= sprintf(
104
+ '<option value="%s" %s>%s</option>',
 
105
  $catId,
106
  selected( $selected, is_numeric( $selected ) ? $catId : $cat, false ),
107
  $cat
111
  if ( ! empty( $str ) ) {
112
  $str = "<option></option>" . $str;
113
  }
114
+
115
  return $str;
116
  }
117
 
122
  */
123
  public function googleTaxonomyArray() {
124
  # Get All Google Taxonomies
125
+ $fileName = WOO_FEED_FREE_ADMIN_PATH . '/partials/templates/google_taxonomy.txt';
126
+ $customTaxonomyFile = fopen( $fileName, 'r' ); // phpcs:ignore
127
+ $taxonomy = [];
128
  if ( $customTaxonomyFile ) {
129
  // First line contains metadata, ignore it
130
+ fgets( $customTaxonomyFile ); // phpcs:ignore
131
+ while ( $line = fgets( $customTaxonomyFile ) ) { // phpcs:ignore
132
  list( $catId, $cat ) = explode( "-", $line );
133
  $taxonomy[] = [
134
  'value' => absint( trim( $catId ) ),
137
  }
138
  }
139
  $taxonomy = array_filter( $taxonomy );
140
+
141
  return $taxonomy;
142
  }
143
 
144
+ /**
145
+ * Dropdown of Google Attribute List
146
+ *
147
+ * @param string $selected
148
+ *
149
+ * @return string
150
+ */
151
+ public function googleAttributesDropdown( $selected = '' ) {
152
+ $attributes = new Woo_Feed_Default_Attributes();
153
+ $str = '<option></option>';
154
+ foreach ( $attributes->googleAttributes() as $key => $value ) {
155
+ if ( substr( $key, 0, 2 ) == '--' ) {
156
+ $str .= "<optgroup label='$value'>";
157
+ } elseif ( substr( $key, 0, 2 ) == '---' ) {
158
+ $str .= '</optgroup>';
159
+ } else {
160
+ $str .= "<option value='$key'>" . $value . '</option>';
161
+ }
162
+ }
163
+ $google_attributes = $str;
164
+
165
+ $pos = strpos( $google_attributes, "value='" . $selected . "'" );
166
+
167
+ return substr_replace( $google_attributes, "selected='selected' ", $pos, 0 );
168
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  }
includes/classes/class-woo-feed-engine.php CHANGED
@@ -75,8 +75,8 @@ class WF_Engine
75
  }
76
 
77
  public function stripInvalidXml($value) {
78
- $ret = "";
79
- $current="";
80
  if (empty($value)) {
81
  return $ret;
82
  }
@@ -87,7 +87,7 @@ class WF_Engine
87
  $ret .= chr($current);
88
  }
89
  else {
90
- $ret .= "";
91
  }
92
  }
93
  return $ret;
@@ -157,7 +157,7 @@ class WF_Engine
157
  # Get Woo Attributes
158
  if (!empty($wf_attr)) {
159
  foreach ($wf_attr as $attr_key => $attr_value) {
160
- //$this->storeProducts[$key][$attr_value] = implode(',', wc_get_product_terms($id, str_replace("wf_attr_", "", $attr_value), array('fields' => 'names')));
161
  $this->storeProducts[$key][$attr_value] = $this->productClass->getProductAttribute($id,$attr_value);
162
  }
163
  }
@@ -186,7 +186,7 @@ class WF_Engine
186
  foreach ($rules['type'] as $key22 => $value22) {
187
  # Format Output According to output type
188
  if ($value22 == 2) { # Strip Tags
189
- $output = strip_tags(html_entity_decode($output));
190
  } elseif ($value22 == 3) { # UTF-8 Encode
191
  $output = utf8_encode($output);
192
  } elseif ($value22 == 4) { # htmlentities
@@ -210,7 +210,7 @@ class WF_Engine
210
 
211
  # Format Output According to output limit
212
  if (!empty($rules['limit']) && is_numeric($rules['limit']) && strpos($output, "<![CDATA[") !== false) {
213
- $output = str_replace(array("<![CDATA[", "]]>"), array("", ""), $output);
214
  $output = substr($output, 0, $rules['limit']);
215
  $output = '<![CDATA[' . $output . ']]>';
216
  } elseif (!empty($rules['limit']) && is_numeric($rules['limit'])) {
@@ -219,15 +219,15 @@ class WF_Engine
219
 
220
  # Prefix and Suffix Assign
221
  if (strpos($output, "<![CDATA[") !== false) {
222
- $output = str_replace(array("<![CDATA[", "]]>"), array("", ""), $output);
223
- if(substr($output, 0, 4 ) === "http"){
224
  $output = $this->make_url_with_parameter($rules['prefix'],$output,$rules['suffix']);
225
  }else{
226
- if($attr=='price' || $rules['value']=='sale_price' || $rules['value']=='current_price' && $output != ""){
227
  $suffix=!empty($rules['suffix'])?trim($rules['suffix']):$rules['suffix'];
228
- $output = $rules['prefix'].$output." ".$suffix;
229
  }else{
230
- if($output != "")
231
  {
232
  $output = $rules['prefix'].$output.$rules['suffix'];
233
  }
@@ -235,16 +235,16 @@ class WF_Engine
235
  }
236
  $output = '<![CDATA[' . $output . ']]>';
237
  } else {
238
- if(substr($output, 0, 4 ) === "http"){
239
  $output = $this->make_url_with_parameter($rules['prefix'],$output,$rules['suffix']);
240
  }else{
241
- if($attr=='price' || $rules['value']=='sale_price' || $rules['value']=='current_price' && $output != ""){
242
  $suffix=!empty($rules['suffix'])?trim($rules['suffix']):$rules['suffix'];
243
- $output = $rules['prefix'].$output." ".$suffix;
244
  }else{
245
- if($output != "")
246
  {
247
- $output = $rules['prefix'].$output." ".$rules['suffix'];
248
  }
249
  }
250
  }
@@ -257,7 +257,7 @@ class WF_Engine
257
  } elseif ($output=="0"){
258
  $output="0";
259
  } else{
260
- $output="";
261
  }
262
 
263
  //$attr = trim($attr);
@@ -265,14 +265,14 @@ class WF_Engine
265
  } else {
266
 
267
  if (!empty($default[$i])) {
268
- $output = str_replace("wf_pattern_", "", $rules['value']);
269
  if (!empty($output)) {
270
 
271
  # Format Output According to output type
272
  if(!empty($rules['type'])){
273
  foreach ($rules['type'] as $key22 => $value22) {
274
  if ($value22 == 2) { # Strip Tags
275
- $output = strip_tags(html_entity_decode($output));
276
  } elseif ($value22 == 3) { # UTF-8 Encode
277
  $output = utf8_encode($output);
278
  } elseif ($value22 == 4) { # htmlentities
@@ -290,7 +290,7 @@ class WF_Engine
290
  $output=$this->stripInvalidXml($output);
291
  //$output = preg_replace( '/[^[:print:]]/',' ',$output);
292
  }else if($value22 == 10){
293
- //$output=preg_replace("/\[[^]]+\]/","",$output);
294
  $output=$this->productClass->remove_short_codes($output);
295
  }
296
  }
@@ -298,7 +298,7 @@ class WF_Engine
298
 
299
  # Format Output According to output limit
300
  if (!empty($output) && !empty($rules['limit']) && is_numeric($rules['limit']) && strpos($output, "<![CDATA[") !== false) {
301
- $output = str_replace(array("<![CDATA[", "]]>"), array("", ""), $output);
302
  $output = substr($output, 0, $rules['limit']);
303
  $output = '<![CDATA[' . $output . ']]>';
304
  } elseif (!empty($output) && !empty($rules['limit']) && is_numeric($rules['limit'])) {
@@ -307,15 +307,15 @@ class WF_Engine
307
 
308
  # Prefix and Suffix Assign
309
  if (strpos($output, "<![CDATA[") !== false) {
310
- $output = str_replace(array("<![CDATA[", "]]>"), array("", ""), $output);
311
- if(substr($output, 0, 4 ) === "http"){
312
  $output = $this->make_url_with_parameter($rules['prefix'],$output,$rules['suffix']);
313
  }else{
314
- if($attr=='price' || $rules['value']=='sale_price' || $rules['value']=='current_price' && $output != ""){
315
  $suffix=!empty($rules['suffix'])?trim($rules['suffix']):$rules['suffix'];
316
- $output = $rules['prefix'].$output." ".$suffix;
317
  }else{
318
- if($output != "")
319
  {
320
  $output = $rules['prefix'].$output.$rules['suffix'];
321
  }
@@ -324,14 +324,14 @@ class WF_Engine
324
  $output = '<![CDATA[' . $output . ']]>';
325
 
326
  } else {
327
- if(substr($output, 0, 4 ) === "http"){
328
  $output = $this->make_url_with_parameter($rules['prefix'],$output,$rules['suffix']);
329
  }else{
330
- if($attr=='price'|| $rules['value']=='sale_price' || $rules['value']=='current_price' && $output != ""){
331
  $suffix=!empty($rules['suffix'])?trim($rules['suffix']):$rules['suffix'];
332
- $output = $rules['prefix'].$output." ".$suffix;
333
  }else{
334
- if($output != "")
335
  {
336
  $output = $rules['prefix'].$output.$rules['suffix'];
337
  }
@@ -346,20 +346,20 @@ class WF_Engine
346
  } elseif ($output=="0"){
347
  $output="0";
348
  } else{
349
- $output="";
350
  }
351
 
352
  $attr = trim($attr);
353
  $this->products[$key][$attr] = $output;
354
  } else {
355
- $output = str_replace("wf_pattern_", "", $rules['value']);
356
  if(!empty($output)){
357
  $output=stripslashes($output);
358
  }
359
  if ($output=="0"){
360
  $output="0";
361
  } else{
362
- $output="";
363
  }
364
  $attr = trim($attr);
365
  $this->products[$key][$attr] = $output;
@@ -393,17 +393,17 @@ class WF_Engine
393
 
394
  $EXTRAParam=array();
395
  if(!empty($suffix)){
396
- $suffix=str_replace("?","",$suffix);
397
  $EXTRAParam=$this->proper_parse_str($suffix);
398
  }
399
 
400
  $params=array_merge($URLParam,$EXTRAParam);
401
- if(!empty($params) && $output != ""){
402
  $params=http_build_query($params);
403
  $baseURL=isset($getParam)?$getParam[0]:$output;
404
  $output = $prefix.$baseURL."?".$params;
405
  }else{
406
- if($output != "")
407
  {
408
  $output = $prefix.$output.$suffix;
409
  }
@@ -417,7 +417,7 @@ class WF_Engine
417
  * @param $str
418
  * @return array
419
  */
420
- public function proper_parse_str($str="") {
421
 
422
  # result array
423
  $arr = array();
@@ -485,7 +485,7 @@ class WF_Engine
485
  */
486
  public function get_xml_feed_body()
487
  {
488
- $feed = "";
489
  $itemWrapper = $this->rules['itemWrapper'];
490
  //$feed .= $this->get_feed_header($itemsWrapper, $extraheader);
491
  if (!empty($this->storeProducts)) {
@@ -534,7 +534,7 @@ class WF_Engine
534
  }else if($string=="0"){
535
  return "0";
536
  }else{
537
- return "";
538
  }
539
  }
540
 
@@ -559,7 +559,7 @@ class WF_Engine
559
  }else if($string=="0"){
560
  return "0";
561
  }else{
562
- return "";
563
  }
564
  }
565
 
@@ -585,10 +585,10 @@ class WF_Engine
585
  } elseif ($enclosure == 'single') {
586
  $enclosure = "'";
587
  } else {
588
- $enclosure = "";
589
  }
590
  } else {
591
- $enclosure = "";
592
  }
593
 
594
 
@@ -605,11 +605,11 @@ class WF_Engine
605
  foreach ($this->storeProducts as $no => $product) {
606
  $row = array();
607
  foreach ($headers as $key => $header) {
608
- $row[] = isset($product[$header]) ? $this->processStringForTXT($product[$header]):"";
609
  }
610
  $feed[] = $row;
611
  }
612
- $str = "";
613
  $i=1;
614
  foreach ($feed as $fields) {
615
  if($i==1){
@@ -647,7 +647,7 @@ class WF_Engine
647
  $row = array();
648
  foreach ($headers as $key => $header) {
649
  if($this->rules['provider'] == 'spartoo.fi' && $header == "Parent / Child") {
650
- $_value = isset($product[$header])?$this->processStringForCSV($product[$header]): "";
651
  if($_value == 'variation') {
652
  $row[] = 'child';
653
  } else {
75
  }
76
 
77
  public function stripInvalidXml($value) {
78
+ $ret = '';
79
+ $current='';
80
  if (empty($value)) {
81
  return $ret;
82
  }
87
  $ret .= chr($current);
88
  }
89
  else {
90
+ $ret .= '';
91
  }
92
  }
93
  return $ret;
157
  # Get Woo Attributes
158
  if (!empty($wf_attr)) {
159
  foreach ($wf_attr as $attr_key => $attr_value) {
160
+ //$this->storeProducts[$key][$attr_value] = implode(',', wc_get_product_terms($id, str_replace('wf_attr_', '', $attr_value), array('fields' => 'names')));
161
  $this->storeProducts[$key][$attr_value] = $this->productClass->getProductAttribute($id,$attr_value);
162
  }
163
  }
186
  foreach ($rules['type'] as $key22 => $value22) {
187
  # Format Output According to output type
188
  if ($value22 == 2) { # Strip Tags
189
+ $output = wp_strip_all_tags(html_entity_decode($output));
190
  } elseif ($value22 == 3) { # UTF-8 Encode
191
  $output = utf8_encode($output);
192
  } elseif ($value22 == 4) { # htmlentities
210
 
211
  # Format Output According to output limit
212
  if (!empty($rules['limit']) && is_numeric($rules['limit']) && strpos($output, "<![CDATA[") !== false) {
213
+ $output = str_replace(array("<![CDATA[", "]]>"), array('', ''), $output);
214
  $output = substr($output, 0, $rules['limit']);
215
  $output = '<![CDATA[' . $output . ']]>';
216
  } elseif (!empty($rules['limit']) && is_numeric($rules['limit'])) {
219
 
220
  # Prefix and Suffix Assign
221
  if (strpos($output, "<![CDATA[") !== false) {
222
+ $output = str_replace(array("<![CDATA[", "]]>"), array('', ''), $output);
223
+ if('http' === substr($output, 0, 4 )){
224
  $output = $this->make_url_with_parameter($rules['prefix'],$output,$rules['suffix']);
225
  }else{
226
+ if($attr=='price' || $rules['value']=='sale_price' || $rules['value']=='current_price' && $output != ''){
227
  $suffix=!empty($rules['suffix'])?trim($rules['suffix']):$rules['suffix'];
228
+ $output = $rules['prefix'].$output.''.$suffix;
229
  }else{
230
+ if($output != '')
231
  {
232
  $output = $rules['prefix'].$output.$rules['suffix'];
233
  }
235
  }
236
  $output = '<![CDATA[' . $output . ']]>';
237
  } else {
238
+ if('http' === substr($output, 0, 4 )){
239
  $output = $this->make_url_with_parameter($rules['prefix'],$output,$rules['suffix']);
240
  }else{
241
+ if($attr=='price' || $rules['value']=='sale_price' || $rules['value']=='current_price' && $output != ''){
242
  $suffix=!empty($rules['suffix'])?trim($rules['suffix']):$rules['suffix'];
243
+ $output = $rules['prefix'].$output.''.$suffix;
244
  }else{
245
+ if($output != '')
246
  {
247
+ $output = $rules['prefix'].$output.''.$rules['suffix'];
248
  }
249
  }
250
  }
257
  } elseif ($output=="0"){
258
  $output="0";
259
  } else{
260
+ $output='';
261
  }
262
 
263
  //$attr = trim($attr);
265
  } else {
266
 
267
  if (!empty($default[$i])) {
268
+ $output = str_replace("wf_pattern_", '', $rules['value']);
269
  if (!empty($output)) {
270
 
271
  # Format Output According to output type
272
  if(!empty($rules['type'])){
273
  foreach ($rules['type'] as $key22 => $value22) {
274
  if ($value22 == 2) { # Strip Tags
275
+ $output = wp_strip_all_tags(html_entity_decode($output));
276
  } elseif ($value22 == 3) { # UTF-8 Encode
277
  $output = utf8_encode($output);
278
  } elseif ($value22 == 4) { # htmlentities
290
  $output=$this->stripInvalidXml($output);
291
  //$output = preg_replace( '/[^[:print:]]/',' ',$output);
292
  }else if($value22 == 10){
293
+ //$output=preg_replace("/\[[^]]+\]/",'',$output);
294
  $output=$this->productClass->remove_short_codes($output);
295
  }
296
  }
298
 
299
  # Format Output According to output limit
300
  if (!empty($output) && !empty($rules['limit']) && is_numeric($rules['limit']) && strpos($output, "<![CDATA[") !== false) {
301
+ $output = str_replace(array("<![CDATA[", "]]>"), array('', ''), $output);
302
  $output = substr($output, 0, $rules['limit']);
303
  $output = '<![CDATA[' . $output . ']]>';
304
  } elseif (!empty($output) && !empty($rules['limit']) && is_numeric($rules['limit'])) {
307
 
308
  # Prefix and Suffix Assign
309
  if (strpos($output, "<![CDATA[") !== false) {
310
+ $output = str_replace(array("<![CDATA[", "]]>"), array('', ''), $output);
311
+ if('http' === substr($output, 0, 4 )){
312
  $output = $this->make_url_with_parameter($rules['prefix'],$output,$rules['suffix']);
313
  }else{
314
+ if($attr=='price' || $rules['value']=='sale_price' || $rules['value']=='current_price' && $output != ''){
315
  $suffix=!empty($rules['suffix'])?trim($rules['suffix']):$rules['suffix'];
316
+ $output = $rules['prefix'].$output.''.$suffix;
317
  }else{
318
+ if($output != '')
319
  {
320
  $output = $rules['prefix'].$output.$rules['suffix'];
321
  }
324
  $output = '<![CDATA[' . $output . ']]>';
325
 
326
  } else {
327
+ if('http' === substr($output, 0, 4 )){
328
  $output = $this->make_url_with_parameter($rules['prefix'],$output,$rules['suffix']);
329
  }else{
330
+ if($attr=='price'|| $rules['value']=='sale_price' || $rules['value']=='current_price' && $output != ''){
331
  $suffix=!empty($rules['suffix'])?trim($rules['suffix']):$rules['suffix'];
332
+ $output = $rules['prefix'].$output.''.$suffix;
333
  }else{
334
+ if($output != '')
335
  {
336
  $output = $rules['prefix'].$output.$rules['suffix'];
337
  }
346
  } elseif ($output=="0"){
347
  $output="0";
348
  } else{
349
+ $output='';
350
  }
351
 
352
  $attr = trim($attr);
353
  $this->products[$key][$attr] = $output;
354
  } else {
355
+ $output = str_replace("wf_pattern_", '', $rules['value']);
356
  if(!empty($output)){
357
  $output=stripslashes($output);
358
  }
359
  if ($output=="0"){
360
  $output="0";
361
  } else{
362
+ $output='';
363
  }
364
  $attr = trim($attr);
365
  $this->products[$key][$attr] = $output;
393
 
394
  $EXTRAParam=array();
395
  if(!empty($suffix)){
396
+ $suffix=str_replace("?",'',$suffix);
397
  $EXTRAParam=$this->proper_parse_str($suffix);
398
  }
399
 
400
  $params=array_merge($URLParam,$EXTRAParam);
401
+ if(!empty($params) && $output != ''){
402
  $params=http_build_query($params);
403
  $baseURL=isset($getParam)?$getParam[0]:$output;
404
  $output = $prefix.$baseURL."?".$params;
405
  }else{
406
+ if($output != '')
407
  {
408
  $output = $prefix.$output.$suffix;
409
  }
417
  * @param $str
418
  * @return array
419
  */
420
+ public function proper_parse_str($str='') {
421
 
422
  # result array
423
  $arr = array();
485
  */
486
  public function get_xml_feed_body()
487
  {
488
+ $feed = '';
489
  $itemWrapper = $this->rules['itemWrapper'];
490
  //$feed .= $this->get_feed_header($itemsWrapper, $extraheader);
491
  if (!empty($this->storeProducts)) {
534
  }else if($string=="0"){
535
  return "0";
536
  }else{
537
+ return '';
538
  }
539
  }
540
 
559
  }else if($string=="0"){
560
  return "0";
561
  }else{
562
+ return '';
563
  }
564
  }
565
 
585
  } elseif ($enclosure == 'single') {
586
  $enclosure = "'";
587
  } else {
588
+ $enclosure = '';
589
  }
590
  } else {
591
+ $enclosure = '';
592
  }
593
 
594
 
605
  foreach ($this->storeProducts as $no => $product) {
606
  $row = array();
607
  foreach ($headers as $key => $header) {
608
+ $row[] = isset($product[$header]) ? $this->processStringForTXT($product[$header]):'';
609
  }
610
  $feed[] = $row;
611
  }
612
+ $str = '';
613
  $i=1;
614
  foreach ($feed as $fields) {
615
  if($i==1){
647
  $row = array();
648
  foreach ($headers as $key => $header) {
649
  if($this->rules['provider'] == 'spartoo.fi' && $header == "Parent / Child") {
650
+ $_value = isset($product[$header])?$this->processStringForCSV($product[$header]): '';
651
  if($_value == 'variation') {
652
  $row[] = 'child';
653
  } else {
includes/classes/class-woo-feed-ftp.php CHANGED
@@ -17,45 +17,50 @@ if ( ! defined( 'ABSPATH' ) ) {
17
  /**
18
  * Class FTPClient
19
  */
20
- Class FTPClient {
21
  /**
22
  * Holds The FTP Connection Resource
 
23
  * @var resource
24
  */
25
  private $connection_id;
26
  /**
27
  * Login Check Flag
 
28
  * @var bool
29
  */
30
  private $login_ok = false;
31
  /**
32
  * Message Array
 
33
  * @var array
34
  */
35
  private $message_array = array();
36
-
37
  /**
38
  * FTPClient constructor.
39
  */
40
  public function __construct() {
41
  }
42
-
43
  /**
44
  * Store Log Messages.
 
45
  * @param string $message message to add.
46
  */
47
  private function log_message( $message ) {
48
  $this->message_array[] = $message;
49
  }
50
-
51
  /**
52
  * Get Logs.
 
53
  * @return array
54
  */
55
  public function get_messages() {
56
  return $this->message_array;
57
  }
58
-
59
  /**
60
  * Connect to FTP Server
61
  *
@@ -67,7 +72,7 @@ Class FTPClient {
67
  * @return bool
68
  */
69
  public function connect( $server, $ftp_user, $ftp_password, $is_passive = false, $ftp_port = 21 ) {
70
-
71
  // *** Set up basic connection
72
  $this->connection_id = ftp_connect( $server, $ftp_port );
73
  if ( ! $this->connection_id ) {
@@ -93,9 +98,10 @@ Class FTPClient {
93
  return true;
94
  }
95
  }
96
-
97
  /**
98
  * Check if input is valid octal
 
99
  * @param mixed $input input data.
100
  *
101
  * @return bool
@@ -103,7 +109,7 @@ Class FTPClient {
103
  private function is_octal( $input ) {
104
  return decoct( octdec( $input ) ) == $input;
105
  }
106
-
107
  /**
108
  * Give permission to file.
109
  *
@@ -116,23 +122,24 @@ Class FTPClient {
116
  $result = ftp_chmod( $this->connection_id, $permissions, $remote_filename );
117
  if ( $result ) {
118
  $this->log_message( esc_html__( 'File Permission Granted', 'woo-feed' ) );
119
-
120
  return true;
121
  } else {
122
  $this->log_message( esc_html__( 'File Permission Failed', 'woo-feed' ) );
123
-
124
  return false;
125
  }
126
  } else {
127
  /* translators: Permission Mode */
128
  $this->log_message( sprintf( esc_html__( '%s must be an octal number', 'woo-feed' ), $permissions ) );
129
-
130
  return false;
131
  }
132
  }
133
-
134
  /**
135
  * Make Directory.
 
136
  * @param string $directory Directory name and path.
137
  * @return bool
138
  */
@@ -142,14 +149,14 @@ Class FTPClient {
142
  /* translators: Permission Mode */
143
  $this->log_message( sprintf( esc_html__( 'Directory "%s" created successfully.', 'woo-feed' ), $directory ) );
144
  return true;
145
-
146
  } else {
147
  /* translators: Directory Path */
148
  $this->log_message( sprintf( esc_html__( 'Failed creating directory "%s".', 'woo-feed' ), $directory ) );
149
  return false;
150
  }
151
  }
152
-
153
  /**
154
  * Upload files to FTP server
155
  *
@@ -159,14 +166,14 @@ Class FTPClient {
159
  * @return bool
160
  */
161
  public function upload_file( $file_from, $file_to ) {
162
-
163
  // *** Set the transfer mode
164
- $ascii_array = array( 'txt', 'csv', 'xml' );
165
  $get_extension = explode( '.', $file_from );
166
- $extension = end( $get_extension );
167
-
168
  $mode = in_array( $extension, $ascii_array ) ? FTP_ASCII : FTP_BINARY;
169
-
170
  // *** Upload the file
171
  $upload = ftp_put( $this->connection_id, $file_to, $file_from, $mode );
172
  // *** Check upload status
@@ -179,4 +186,4 @@ Class FTPClient {
179
  return true;
180
  }
181
  }
182
- }
17
  /**
18
  * Class FTPClient
19
  */
20
+ class FTPClient {
21
  /**
22
  * Holds The FTP Connection Resource
23
+ *
24
  * @var resource
25
  */
26
  private $connection_id;
27
  /**
28
  * Login Check Flag
29
+ *
30
  * @var bool
31
  */
32
  private $login_ok = false;
33
  /**
34
  * Message Array
35
+ *
36
  * @var array
37
  */
38
  private $message_array = array();
39
+
40
  /**
41
  * FTPClient constructor.
42
  */
43
  public function __construct() {
44
  }
45
+
46
  /**
47
  * Store Log Messages.
48
+ *
49
  * @param string $message message to add.
50
  */
51
  private function log_message( $message ) {
52
  $this->message_array[] = $message;
53
  }
54
+
55
  /**
56
  * Get Logs.
57
+ *
58
  * @return array
59
  */
60
  public function get_messages() {
61
  return $this->message_array;
62
  }
63
+
64
  /**
65
  * Connect to FTP Server
66
  *
72
  * @return bool
73
  */
74
  public function connect( $server, $ftp_user, $ftp_password, $is_passive = false, $ftp_port = 21 ) {
75
+
76
  // *** Set up basic connection
77
  $this->connection_id = ftp_connect( $server, $ftp_port );
78
  if ( ! $this->connection_id ) {
98
  return true;
99
  }
100
  }
101
+
102
  /**
103
  * Check if input is valid octal
104
+ *
105
  * @param mixed $input input data.
106
  *
107
  * @return bool
109
  private function is_octal( $input ) {
110
  return decoct( octdec( $input ) ) == $input;
111
  }
112
+
113
  /**
114
  * Give permission to file.
115
  *
122
  $result = ftp_chmod( $this->connection_id, $permissions, $remote_filename );
123
  if ( $result ) {
124
  $this->log_message( esc_html__( 'File Permission Granted', 'woo-feed' ) );
125
+
126
  return true;
127
  } else {
128
  $this->log_message( esc_html__( 'File Permission Failed', 'woo-feed' ) );
129
+
130
  return false;
131
  }
132
  } else {
133
  /* translators: Permission Mode */
134
  $this->log_message( sprintf( esc_html__( '%s must be an octal number', 'woo-feed' ), $permissions ) );
135
+
136
  return false;
137
  }
138
  }
139
+
140
  /**
141
  * Make Directory.
142
+ *
143
  * @param string $directory Directory name and path.
144
  * @return bool
145
  */
149
  /* translators: Permission Mode */
150
  $this->log_message( sprintf( esc_html__( 'Directory "%s" created successfully.', 'woo-feed' ), $directory ) );
151
  return true;
152
+
153
  } else {
154
  /* translators: Directory Path */
155
  $this->log_message( sprintf( esc_html__( 'Failed creating directory "%s".', 'woo-feed' ), $directory ) );
156
  return false;
157
  }
158
  }
159
+
160
  /**
161
  * Upload files to FTP server
162
  *
166
  * @return bool
167
  */
168
  public function upload_file( $file_from, $file_to ) {
169
+
170
  // *** Set the transfer mode
171
+ $ascii_array = array( 'txt', 'csv', 'xml' );
172
  $get_extension = explode( '.', $file_from );
173
+ $extension = end( $get_extension );
174
+
175
  $mode = in_array( $extension, $ascii_array ) ? FTP_ASCII : FTP_BINARY;
176
+
177
  // *** Upload the file
178
  $upload = ftp_put( $this->connection_id, $file_to, $file_from, $mode );
179
  // *** Check upload status
186
  return true;
187
  }
188
  }
189
+ }
includes/classes/class-woo-feed-list-table.php CHANGED
@@ -101,10 +101,24 @@ class Woo_Feed_List_Table {
101
  * @access protected
102
  * @var array
103
  */
104
- protected $compat_methods = array( 'set_pagination_args', 'get_views', 'get_bulk_actions', 'bulk_actions',
105
- 'row_actions', 'months_dropdown', 'view_switcher', 'comments_bubble', 'get_items_per_page', 'pagination',
106
- 'get_sortable_columns', 'get_column_info', 'get_table_classes', 'display_tablenav', 'extra_tablenav',
107
- 'single_row_columns' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
 
109
  /**
110
  * Constructor.
@@ -133,21 +147,25 @@ class Woo_Feed_List_Table {
133
  * }
134
  */
135
  public function __construct( $args = array() ) {
136
- $args = wp_parse_args( $args, array(
137
- 'plural' => '',
138
- 'singular' => '',
139
- 'ajax' => false,
140
- 'screen' => null,
141
- ) );
 
 
 
142
 
143
  $this->screen = convert_to_screen( $args['screen'] );
144
 
145
  add_filter( "manage_{$this->screen->id}_columns", array( $this, 'get_columns' ), 0 );
146
 
147
- if ( !$args['plural'] )
148
  $args['plural'] = $this->screen->base;
 
149
 
150
- $args['plural'] = sanitize_key( $args['plural'] );
151
  $args['singular'] = sanitize_key( $args['singular'] );
152
 
153
  $this->_args = $args;
@@ -159,8 +177,8 @@ class Woo_Feed_List_Table {
159
 
160
  if ( empty( $this->modes ) ) {
161
  $this->modes = array(
162
- 'list' => __( 'List View' ),
163
- 'excerpt' => __( 'Excerpt View' )
164
  );
165
  }
166
  }
@@ -255,6 +273,7 @@ class Woo_Feed_List_Table {
255
 
256
  /**
257
  * Prepares the list of items for displaying.
 
258
  * @uses WP_List_Table::set_pagination_args()
259
  *
260
  * @since 3.1.0
@@ -274,19 +293,23 @@ class Woo_Feed_List_Table {
274
  * @param array|string $args Array or string of arguments with information about the pagination.
275
  */
276
  protected function set_pagination_args( $args ) {
277
- $args = wp_parse_args( $args, array(
278
- 'total_items' => 0,
279
- 'total_pages' => 0,
280
- 'per_page' => 0,
281
- ) );
 
 
 
282
 
283
- if ( !$args['total_pages'] && $args['per_page'] > 0 )
284
  $args['total_pages'] = ceil( $args['total_items'] / $args['per_page'] );
 
285
 
286
  // Redirect if page number is invalid and headers are not already sent.
287
  if ( ! headers_sent() && ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) && $args['total_pages'] > 0 && $this->get_pagenum() > $args['total_pages'] ) {
288
  wp_safe_redirect( add_query_arg( 'paged', $args['total_pages'] ) );
289
- die();
290
  }
291
 
292
  $this->_pagination_args = $args;
@@ -307,8 +330,8 @@ class Woo_Feed_List_Table {
307
  return $this->get_pagenum();
308
  }
309
 
310
- if ( isset( $this->_pagination_args[$key] ) ) {
311
- return $this->_pagination_args[$key];
312
  }
313
  }
314
 
@@ -321,7 +344,7 @@ class Woo_Feed_List_Table {
321
  * @return bool
322
  */
323
  public function has_items() {
324
- return !empty( $this->items );
325
  }
326
 
327
  /**
@@ -344,26 +367,31 @@ class Woo_Feed_List_Table {
344
  * @param string $input_id The search input id
345
  */
346
  public function search_box( $text, $input_id ) {
347
- if ( empty( $_REQUEST['s'] ) && !$this->has_items() )
 
348
  return;
349
-
350
  $input_id = $input_id . '-search-input';
351
-
352
- if ( ! empty( $_REQUEST['orderby'] ) )
353
  echo '<input type="hidden" name="orderby" value="' . esc_attr( $_REQUEST['orderby'] ) . '" />';
354
- if ( ! empty( $_REQUEST['order'] ) )
 
355
  echo '<input type="hidden" name="order" value="' . esc_attr( $_REQUEST['order'] ) . '" />';
356
- if ( ! empty( $_REQUEST['post_mime_type'] ) )
 
357
  echo '<input type="hidden" name="post_mime_type" value="' . esc_attr( $_REQUEST['post_mime_type'] ) . '" />';
358
- if ( ! empty( $_REQUEST['detached'] ) )
 
359
  echo '<input type="hidden" name="detached" value="' . esc_attr( $_REQUEST['detached'] ) . '" />';
 
360
  ?>
361
  <p class="search-box">
362
- <label class="screen-reader-text" for="<?php echo $input_id ?>"><?php echo $text; ?>:</label>
363
- <input type="search" id="<?php echo $input_id ?>" name="s" value="<?php _admin_search_query(); ?>" />
364
  <?php submit_button( $text, 'button', '', false, array('id' => 'search-submit') ); ?>
365
  </p>
366
  <?php
 
367
  }
368
 
369
  /**
@@ -399,8 +427,9 @@ class Woo_Feed_List_Table {
399
  */
400
  $views = apply_filters( "views_{$this->screen->id}", $views );
401
 
402
- if ( empty( $views ) )
403
  return;
 
404
 
405
  $this->screen->render_screen_reader_content( 'heading_views' );
406
 
@@ -409,7 +438,7 @@ class Woo_Feed_List_Table {
409
  $views[ $class ] = "\t<li class='$class'>$view";
410
  }
411
  echo implode( " |</li>\n", $views ) . "</li>\n";
412
- echo "</ul>";
413
  }
414
 
415
  /**
@@ -451,13 +480,14 @@ class Woo_Feed_List_Table {
451
  */
452
  $this->_actions = apply_filters( "bulk_actions-{$this->screen->id}", $this->_actions );
453
  $this->_actions = array_intersect_assoc( $this->_actions, $no_new_actions );
454
- $two = '';
455
  } else {
456
  $two = '2';
457
  }
458
 
459
- if ( empty( $this->_actions ) )
460
  return;
 
461
 
462
  echo '<label for="bulk-action-selector-' . esc_attr( $which ) . '" class="screen-reader-text">' . __( 'Select bulk action' ) . '</label>';
463
  echo '<select name="action' . $two . '" id="bulk-action-selector-' . esc_attr( $which ) . "\">\n";
@@ -484,14 +514,17 @@ class Woo_Feed_List_Table {
484
  * @return string|false The action name or False if no action was selected
485
  */
486
  public function current_action() {
487
- if ( isset( $_REQUEST['filter_action'] ) && ! empty( $_REQUEST['filter_action'] ) )
488
  return false;
 
489
 
490
- if ( isset( $_REQUEST['action'] ) && -1 != $_REQUEST['action'] )
491
  return $_REQUEST['action'];
 
492
 
493
- if ( isset( $_REQUEST['action2'] ) && -1 != $_REQUEST['action2'] )
494
  return $_REQUEST['action2'];
 
495
 
496
  return false;
497
  }
@@ -503,21 +536,22 @@ class Woo_Feed_List_Table {
503
  * @access protected
504
  *
505
  * @param array $actions The list of actions
506
- * @param bool $always_visible Whether the actions should be always visible
507
  * @return string
508
  */
509
  protected function row_actions( $actions, $always_visible = false ) {
510
  $action_count = count( $actions );
511
- $i = 0;
512
 
513
- if ( !$action_count )
514
  return '';
 
515
 
516
  $out = '<div class="' . ( $always_visible ? 'row-actions visible' : 'row-actions' ) . '">';
517
  foreach ( $actions as $action => $link ) {
518
  ++$i;
519
  ( $i == $action_count ) ? $sep = '' : $sep = ' | ';
520
- $out .= "<span class='$action'>$link$sep</span>";
521
  }
522
  $out .= '</div>';
523
 
@@ -559,13 +593,18 @@ class Woo_Feed_List_Table {
559
  $extra_checks = $wpdb->prepare( ' AND post_status = %s', sanitize_text_field( $_GET['post_status'] ) );
560
  }
561
 
562
- $months = $wpdb->get_results( $wpdb->prepare( "
 
 
563
  SELECT DISTINCT YEAR( post_date ) AS year, MONTH( post_date ) AS month
564
  FROM $wpdb->posts
565
  WHERE post_type = %s
566
  $extra_checks
567
  ORDER BY post_date DESC
568
- ", $post_type ) );
 
 
 
569
 
570
  /**
571
  * Filter the 'Months' drop-down results.
@@ -579,32 +618,35 @@ class Woo_Feed_List_Table {
579
 
580
  $month_count = count( $months );
581
 
582
- if ( !$month_count || ( 1 == $month_count && 0 == $months[0]->month ) )
583
  return;
 
584
 
585
  $m = isset( $_GET['m'] ) ? (int) $_GET['m'] : 0;
586
- ?>
587
  <label for="filter-by-date" class="screen-reader-text"><?php _e( 'Filter by date' ); ?></label>
588
  <select name="m" id="filter-by-date">
589
  <option<?php selected( $m, 0 ); ?> value="0"><?php _e( 'All dates' ); ?></option>
590
- <?php
591
  foreach ( $months as $arc_row ) {
592
- if ( 0 == $arc_row->year )
593
  continue;
 
594
 
595
  $month = zeroise( $arc_row->month, 2 );
596
- $year = $arc_row->year;
597
 
598
- printf( "<option %s value='%s'>%s</option>\n",
 
599
  selected( $m, $year . $month, false ),
600
  esc_attr( $arc_row->year . $month ),
601
  /* translators: 1: month name, 2: 4-digit year */
602
  sprintf( __( '%1$s %2$d' ), $wp_locale->get_month( $month ), $year )
603
  );
604
  }
605
- ?>
606
  </select>
607
- <?php
608
  }
609
 
610
  /**
@@ -616,24 +658,25 @@ class Woo_Feed_List_Table {
616
  * @param string $current_mode
617
  */
618
  protected function view_switcher( $current_mode ) {
619
- ?>
620
  <input type="hidden" name="mode" value="<?php echo esc_attr( $current_mode ); ?>" />
621
  <div class="view-switch">
622
- <?php
623
- foreach ( $this->modes as $mode => $title ) {
624
- $classes = array( 'view-' . $mode );
625
- if ( $current_mode === $mode )
626
- $classes[] = 'current';
627
- printf(
628
- "<a href='%s' class='%s' id='view-switch-$mode'><span class='screen-reader-text'>%s</span></a>\n",
629
- esc_url( add_query_arg( 'mode', $mode ) ),
630
- implode( ' ', $classes ),
631
- $title
632
- );
633
  }
 
 
 
 
 
 
 
634
  ?>
635
  </div>
636
- <?php
637
  }
638
 
639
  /**
@@ -649,39 +692,60 @@ class Woo_Feed_List_Table {
649
  $approved_comments = get_comments_number();
650
 
651
  $approved_comments_number = number_format_i18n( $approved_comments );
652
- $pending_comments_number = number_format_i18n( $pending_comments );
653
 
654
  $approved_only_phrase = sprintf( _n( '%s comment', '%s comments', $approved_comments ), $approved_comments_number );
655
- $approved_phrase = sprintf( _n( '%s approved comment', '%s approved comments', $approved_comments ), $approved_comments_number );
656
- $pending_phrase = sprintf( _n( '%s pending comment', '%s pending comments', $pending_comments ), $pending_comments_number );
657
 
658
  // No comments at all.
659
  if ( ! $approved_comments && ! $pending_comments ) {
660
- printf( '<span aria-hidden="true">—</span><span class="screen-reader-text">%s</span>',
 
661
  __( 'No comments' )
662
  );
663
- // Approved comments have different display depending on some conditions.
664
  } elseif ( $approved_comments ) {
665
- printf( '<a href="%s" class="post-com-count post-com-count-approved"><span class="comment-count-approved" aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></a>',
666
- esc_url( add_query_arg( array( 'p' => $post_id, 'comment_status' => 'approved' ), admin_url( 'edit-comments.php' ) ) ),
 
 
 
 
 
 
 
 
 
667
  $approved_comments_number,
668
  $pending_comments ? $approved_phrase : $approved_only_phrase
669
  );
670
  } else {
671
- printf( '<span class="post-com-count post-com-count-no-comments"><span class="comment-count comment-count-no-comments" aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></span>',
 
672
  $approved_comments_number,
673
  $pending_comments ? __( 'No approved comments' ) : __( 'No comments' )
674
  );
675
  }
676
 
677
  if ( $pending_comments ) {
678
- printf( '<a href="%s" class="post-com-count post-com-count-pending"><span class="comment-count-pending" aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></a>',
679
- esc_url( add_query_arg( array( 'p' => $post_id, 'comment_status' => 'moderated' ), admin_url( 'edit-comments.php' ) ) ),
 
 
 
 
 
 
 
 
 
680
  $pending_comments_number,
681
  $pending_phrase
682
  );
683
  } else {
684
- printf( '<span class="post-com-count post-com-count-pending post-com-count-no-pending"><span class="comment-count comment-count-no-pending" aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></span>',
 
685
  $pending_comments_number,
686
  $approved_comments ? __( 'No pending comments' ) : __( 'No comments' )
687
  );
@@ -699,8 +763,9 @@ class Woo_Feed_List_Table {
699
  public function get_pagenum() {
700
  $pagenum = isset( $_REQUEST['paged'] ) ? absint( $_REQUEST['paged'] ) : 0;
701
 
702
- if ( isset( $this->_pagination_args['total_pages'] ) && $pagenum > $this->_pagination_args['total_pages'] )
703
  $pagenum = $this->_pagination_args['total_pages'];
 
704
 
705
  return max( 1, $pagenum );
706
  }
@@ -717,8 +782,9 @@ class Woo_Feed_List_Table {
717
  */
718
  protected function get_items_per_page( $option, $default = 20 ) {
719
  $per_page = (int) get_user_option( $option );
720
- if ( empty( $per_page ) || $per_page < 1 )
721
  $per_page = $default;
 
722
 
723
  /**
724
  * Filter the number of items to be displayed on each page of the list table.
@@ -749,8 +815,8 @@ class Woo_Feed_List_Table {
749
  return;
750
  }
751
 
752
- $total_items = $this->_pagination_args['total_items'];
753
- $total_pages = $this->_pagination_args['total_pages'];
754
  $infinite_scroll = false;
755
  if ( isset( $this->_pagination_args['infinite_scroll'] ) ) {
756
  $infinite_scroll = $this->_pagination_args['infinite_scroll'];
@@ -775,17 +841,17 @@ class Woo_Feed_List_Table {
775
 
776
  $disable_first = $disable_last = $disable_prev = $disable_next = false;
777
 
778
- if ( $current == 1 ) {
779
  $disable_first = true;
780
- $disable_prev = true;
781
- }
782
  if ( $current == 2 ) {
783
  $disable_first = true;
784
  }
785
- if ( $current == $total_pages ) {
786
  $disable_last = true;
787
  $disable_next = true;
788
- }
789
  if ( $current == $total_pages - 1 ) {
790
  $disable_last = true;
791
  }
@@ -793,7 +859,8 @@ class Woo_Feed_List_Table {
793
  if ( $disable_first ) {
794
  $page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&laquo;</span>';
795
  } else {
796
- $page_links[] = sprintf( "<a class='first-page button' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
 
797
  esc_url( remove_query_arg( 'paged', $current_url ) ),
798
  __( 'First page' ),
799
  '&laquo;'
@@ -803,8 +870,9 @@ class Woo_Feed_List_Table {
803
  if ( $disable_prev ) {
804
  $page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&lsaquo;</span>';
805
  } else {
806
- $page_links[] = sprintf( "<a class='prev-page button' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
807
- esc_url( add_query_arg( 'paged', max( 1, $current-1 ), $current_url ) ),
 
808
  __( 'Previous page' ),
809
  '&lsaquo;'
810
  );
@@ -814,20 +882,22 @@ class Woo_Feed_List_Table {
814
  $html_current_page = $current;
815
  $total_pages_before = '<span class="screen-reader-text">' . __( 'Current Page' ) . '</span><span id="table-paging" class="paging-input">';
816
  } else {
817
- $html_current_page = sprintf( "%s<input class='current-page' id='current-page-selector' type='text' name='paged' value='%s' size='%d' aria-describedby='table-paging' />",
 
818
  '<label for="current-page-selector" class="screen-reader-text">' . __( 'Current Page' ) . '</label>',
819
  $current,
820
  strlen( $total_pages )
821
  );
822
  }
823
  $html_total_pages = sprintf( "<span class='total-pages'>%s</span>", number_format_i18n( $total_pages ) );
824
- $page_links[] = $total_pages_before . sprintf( _x( '%1$s of %2$s', 'paging' ), $html_current_page, $html_total_pages ) . $total_pages_after;
825
 
826
  if ( $disable_next ) {
827
  $page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&rsaquo;</span>';
828
  } else {
829
- $page_links[] = sprintf( "<a class='next-page button' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
830
- esc_url( add_query_arg( 'paged', min( $total_pages, $current+1 ), $current_url ) ),
 
831
  __( 'Next page' ),
832
  '&rsaquo;'
833
  );
@@ -836,7 +906,8 @@ class Woo_Feed_List_Table {
836
  if ( $disable_last ) {
837
  $page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&raquo;</span>';
838
  } else {
839
- $page_links[] = sprintf( "<a class='last-page button' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
 
840
  esc_url( add_query_arg( 'paged', $total_pages, $current_url ) ),
841
  __( 'Last page' ),
842
  '&raquo;'
@@ -900,7 +971,7 @@ class Woo_Feed_List_Table {
900
  */
901
  protected function get_default_primary_column_name() {
902
  $columns = $this->get_columns();
903
- $column = '';
904
 
905
  if ( empty( $columns ) ) {
906
  return $column;
@@ -947,7 +1018,7 @@ class Woo_Feed_List_Table {
947
  // If the primary column doesn't exist fall back to the
948
  // first non-checkbox column.
949
  if ( ! isset( $columns[ $default ] ) ) {
950
- $default = Woo_Feed_List_Table::get_default_primary_column_name();
951
  }
952
 
953
  /**
@@ -958,7 +1029,7 @@ class Woo_Feed_List_Table {
958
  * @param string $default Column name default for the specific list table, e.g. 'name'.
959
  * @param string $context Screen ID for specific list table, e.g. 'plugins'.
960
  */
961
- $column = apply_filters( 'list_table_primary_column', $default, $this->screen->id );
962
 
963
  if ( empty( $column ) || ! isset( $columns[ $column ] ) ) {
964
  $column = $default;
@@ -989,7 +1060,7 @@ class Woo_Feed_List_Table {
989
  }
990
 
991
  $columns = get_column_headers( $this->screen );
992
- $hidden = get_hidden_columns( $this->screen );
993
 
994
  $sortable_columns = $this->get_sortable_columns();
995
  /**
@@ -1006,17 +1077,19 @@ class Woo_Feed_List_Table {
1006
 
1007
  $sortable = array();
1008
  foreach ( $_sortable as $id => $data ) {
1009
- if ( empty( $data ) )
1010
  continue;
 
1011
 
1012
  $data = (array) $data;
1013
- if ( !isset( $data[1] ) )
1014
  $data[1] = false;
 
1015
 
1016
- $sortable[$id] = $data;
1017
  }
1018
 
1019
- $primary = $this->get_primary_column_name();
1020
  $this->_column_headers = array( $columns, $hidden, $sortable, $primary );
1021
 
1022
  return $this->_column_headers;
@@ -1032,7 +1105,7 @@ class Woo_Feed_List_Table {
1032
  */
1033
  public function get_column_count() {
1034
  list ( $columns, $hidden ) = $this->get_column_info();
1035
- $hidden = array_intersect( array_keys( $columns ), array_filter( $hidden ) );
1036
  return count( $columns ) - count( $hidden );
1037
  }
1038
 
@@ -1066,7 +1139,7 @@ class Woo_Feed_List_Table {
1066
 
1067
  if ( ! empty( $columns['cb'] ) ) {
1068
  static $cb_counter = 1;
1069
- $columns['cb'] = '<label class="screen-reader-text" for="cb-select-all-' . $cb_counter . '">' . __( 'Select All' ) . '</label>'
1070
  . '<input id="cb-select-all-' . $cb_counter . '" type="checkbox" />';
1071
  $cb_counter++;
1072
  }
@@ -1078,24 +1151,25 @@ class Woo_Feed_List_Table {
1078
  $class[] = 'hidden';
1079
  }
1080
 
1081
- if ( 'cb' === $column_key )
1082
  $class[] = 'check-column';
1083
- elseif ( in_array( $column_key, array( 'posts', 'comments', 'links' ) ) )
1084
  $class[] = 'num';
 
1085
 
1086
  if ( $column_key === $primary ) {
1087
  $class[] = 'column-primary';
1088
  }
1089
 
1090
- if ( isset( $sortable[$column_key] ) ) {
1091
- list( $orderby, $desc_first ) = $sortable[$column_key];
1092
 
1093
  if ( $current_orderby === $orderby ) {
1094
- $order = 'asc' === $current_order ? 'desc' : 'asc';
1095
  $class[] = 'sorted';
1096
  $class[] = $current_order;
1097
  } else {
1098
- $order = $desc_first ? 'desc' : 'asc';
1099
  $class[] = 'sortable';
1100
  $class[] = $desc_first ? 'asc' : 'desc';
1101
  }
@@ -1103,12 +1177,13 @@ class Woo_Feed_List_Table {
1103
  $column_display_name = '<a href="' . esc_url( add_query_arg( compact( 'orderby', 'order' ), $current_url ) ) . '"><span>' . $column_display_name . '</span><span class="sorting-indicator"></span></a>';
1104
  }
1105
 
1106
- $tag = ( 'cb' === $column_key ) ? 'td' : 'th';
1107
  $scope = ( 'th' === $tag ) ? 'scope="col"' : '';
1108
- $id = $with_id ? "id='$column_key'" : '';
1109
 
1110
- if ( !empty( $class ) )
1111
  $class = "class='" . join( ' ', $class ) . "'";
 
1112
 
1113
  echo "<$tag $scope $id $class>$column_display_name</$tag>";
1114
  }
@@ -1125,8 +1200,8 @@ class Woo_Feed_List_Table {
1125
 
1126
  $this->display_tablenav( 'top' );
1127
 
1128
- //$this->screen->render_screen_reader_content( 'heading_list' );
1129
- ?>
1130
  <table class="wp-list-table <?php echo implode( ' ', $this->get_table_classes() ); ?>">
1131
  <thead>
1132
  <tr>
@@ -1134,10 +1209,13 @@ class Woo_Feed_List_Table {
1134
  </tr>
1135
  </thead>
1136
 
1137
- <tbody id="the-list"<?php
 
1138
  if ( $singular ) {
1139
  echo " data-wp-lists='list:$singular'";
1140
- } ?>>
 
 
1141
  <?php $this->display_rows_or_placeholder(); ?>
1142
  </tbody>
1143
 
@@ -1148,7 +1226,7 @@ class Woo_Feed_List_Table {
1148
  </tfoot>
1149
 
1150
  </table>
1151
- <?php
1152
  $this->display_tablenav( 'bottom' );
1153
  }
1154
 
@@ -1178,18 +1256,19 @@ class Woo_Feed_List_Table {
1178
  ?>
1179
  <div class="tablenav <?php echo esc_attr( $which ); ?>">
1180
 
1181
- <?php if ( $this->has_items() ): ?>
1182
  <div class="alignleft actions bulkactions">
1183
  <?php $this->bulk_actions( $which ); ?>
1184
  </div>
1185
- <?php endif;
 
1186
  $this->extra_tablenav( $which );
1187
  $this->pagination( $which );
1188
- ?>
1189
 
1190
  <br class="clear" />
1191
  </div>
1192
- <?php
1193
  }
1194
 
1195
  /**
@@ -1225,8 +1304,9 @@ class Woo_Feed_List_Table {
1225
  * @access public
1226
  */
1227
  public function display_rows() {
1228
- foreach ( $this->items as $item )
1229
  $this->single_row( $item );
 
1230
  }
1231
 
1232
  /**
@@ -1299,12 +1379,12 @@ class Woo_Feed_List_Table {
1299
  echo "<td $attributes>";
1300
  echo call_user_func( array( $this, 'column_' . $column_name ), $item );
1301
  echo $this->handle_row_actions( $item, $column_name, $primary );
1302
- echo "</td>";
1303
  } else {
1304
  echo "<td $attributes>";
1305
  echo $this->column_default( $item, $column_name );
1306
  echo $this->handle_row_actions( $item, $column_name, $primary );
1307
- echo "</td>";
1308
  }
1309
  }
1310
  }
@@ -1322,7 +1402,7 @@ class Woo_Feed_List_Table {
1322
  */
1323
  protected function handle_row_actions( $item, $column_name, $primary ) {
1324
  return $column_name === $primary ? '<button type="button" class="toggle-row"><span class="screen-reader-text">' . __( 'Show more details' ) . '</span></button>' : '';
1325
- }
1326
 
1327
  /**
1328
  * Handle an incoming ajax request (called from admin-ajax.php)
@@ -1351,7 +1431,7 @@ class Woo_Feed_List_Table {
1351
  );
1352
  }
1353
  if ( isset( $this->_pagination_args['total_pages'] ) ) {
1354
- $response['total_pages'] = $this->_pagination_args['total_pages'];
1355
  $response['total_pages_i18n'] = number_format_i18n( $this->_pagination_args['total_pages'] );
1356
  }
1357
 
@@ -1369,7 +1449,7 @@ class Woo_Feed_List_Table {
1369
  'screen' => array(
1370
  'id' => $this->screen->id,
1371
  'base' => $this->screen->base,
1372
- )
1373
  );
1374
 
1375
  printf( "<script type='text/javascript'>list_args = %s;</script>\n", wp_json_encode( $args ) );
101
  * @access protected
102
  * @var array
103
  */
104
+ protected $compat_methods = array(
105
+ 'set_pagination_args',
106
+ 'get_views',
107
+ 'get_bulk_actions',
108
+ 'bulk_actions',
109
+ 'row_actions',
110
+ 'months_dropdown',
111
+ 'view_switcher',
112
+ 'comments_bubble',
113
+ 'get_items_per_page',
114
+ 'pagination',
115
+ 'get_sortable_columns',
116
+ 'get_column_info',
117
+ 'get_table_classes',
118
+ 'display_tablenav',
119
+ 'extra_tablenav',
120
+ 'single_row_columns',
121
+ );
122
 
123
  /**
124
  * Constructor.
147
  * }
148
  */
149
  public function __construct( $args = array() ) {
150
+ $args = wp_parse_args(
151
+ $args,
152
+ array(
153
+ 'plural' => '',
154
+ 'singular' => '',
155
+ 'ajax' => false,
156
+ 'screen' => null,
157
+ )
158
+ );
159
 
160
  $this->screen = convert_to_screen( $args['screen'] );
161
 
162
  add_filter( "manage_{$this->screen->id}_columns", array( $this, 'get_columns' ), 0 );
163
 
164
+ if ( ! $args['plural'] ) {
165
  $args['plural'] = $this->screen->base;
166
+ }
167
 
168
+ $args['plural'] = sanitize_key( $args['plural'] );
169
  $args['singular'] = sanitize_key( $args['singular'] );
170
 
171
  $this->_args = $args;
177
 
178
  if ( empty( $this->modes ) ) {
179
  $this->modes = array(
180
+ 'list' => __( 'List View', 'woo-feed' ),
181
+ 'excerpt' => __( 'Excerpt View', 'woo-feed' ),
182
  );
183
  }
184
  }
273
 
274
  /**
275
  * Prepares the list of items for displaying.
276
+ *
277
  * @uses WP_List_Table::set_pagination_args()
278
  *
279
  * @since 3.1.0
293
  * @param array|string $args Array or string of arguments with information about the pagination.
294
  */
295
  protected function set_pagination_args( $args ) {
296
+ $args = wp_parse_args(
297
+ $args,
298
+ array(
299
+ 'total_items' => 0,
300
+ 'total_pages' => 0,
301
+ 'per_page' => 0,
302
+ )
303
+ );
304
 
305
+ if ( ! $args['total_pages'] && $args['per_page'] > 0 ) {
306
  $args['total_pages'] = ceil( $args['total_items'] / $args['per_page'] );
307
+ }
308
 
309
  // Redirect if page number is invalid and headers are not already sent.
310
  if ( ! headers_sent() && ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) && $args['total_pages'] > 0 && $this->get_pagenum() > $args['total_pages'] ) {
311
  wp_safe_redirect( add_query_arg( 'paged', $args['total_pages'] ) );
312
+ exit;
313
  }
314
 
315
  $this->_pagination_args = $args;
330
  return $this->get_pagenum();
331
  }
332
 
333
+ if ( isset( $this->_pagination_args[ $key ] ) ) {
334
+ return $this->_pagination_args[ $key ];
335
  }
336
  }
337
 
344
  * @return bool
345
  */
346
  public function has_items() {
347
+ return ! empty( $this->items );
348
  }
349
 
350
  /**
367
  * @param string $input_id The search input id
368
  */
369
  public function search_box( $text, $input_id ) {
370
+ // phpcs:disable
371
+ if ( empty( $_REQUEST['s'] ) && ! $this->has_items() ) {
372
  return;
373
+ }
374
  $input_id = $input_id . '-search-input';
375
+ if ( isset( $_REQUEST['orderby'] ) && ! empty( $_REQUEST['orderby'] ) ) {
 
376
  echo '<input type="hidden" name="orderby" value="' . esc_attr( $_REQUEST['orderby'] ) . '" />';
377
+ }
378
+ if ( isset( $_REQUEST['order'] ) && ! empty( $_REQUEST['order'] ) ) {
379
  echo '<input type="hidden" name="order" value="' . esc_attr( $_REQUEST['order'] ) . '" />';
380
+ }
381
+ if ( isset( $_REQUEST['post_mime_type'] ) && ! empty( $_REQUEST['post_mime_type'] ) ) {
382
  echo '<input type="hidden" name="post_mime_type" value="' . esc_attr( $_REQUEST['post_mime_type'] ) . '" />';
383
+ }
384
+ if ( isset( $_REQUEST['detached'] ) && ! empty( $_REQUEST['detached'] ) ) {
385
  echo '<input type="hidden" name="detached" value="' . esc_attr( $_REQUEST['detached'] ) . '" />';
386
+ }
387
  ?>
388
  <p class="search-box">
389
+ <label class="screen-reader-text" for="<?php echo esc_attr( $input_id ); ?>"><?php echo esc_html( $text ); ?>:</label>
390
+ <input type="search" id="<?php echo esc_attr( $input_id ); ?>" name="s" value="<?php _admin_search_query(); ?>" />
391
  <?php submit_button( $text, 'button', '', false, array('id' => 'search-submit') ); ?>
392
  </p>
393
  <?php
394
+ // phpcs:enable
395
  }
396
 
397
  /**
427
  */
428
  $views = apply_filters( "views_{$this->screen->id}", $views );
429
 
430
+ if ( empty( $views ) ) {
431
  return;
432
+ }
433
 
434
  $this->screen->render_screen_reader_content( 'heading_views' );
435
 
438
  $views[ $class ] = "\t<li class='$class'>$view";
439
  }
440
  echo implode( " |</li>\n", $views ) . "</li>\n";
441
+ echo '</ul>';
442
  }
443
 
444
  /**
480
  */
481
  $this->_actions = apply_filters( "bulk_actions-{$this->screen->id}", $this->_actions );
482
  $this->_actions = array_intersect_assoc( $this->_actions, $no_new_actions );
483
+ $two = '';
484
  } else {
485
  $two = '2';
486
  }
487
 
488
+ if ( empty( $this->_actions ) ) {
489
  return;
490
+ }
491
 
492
  echo '<label for="bulk-action-selector-' . esc_attr( $which ) . '" class="screen-reader-text">' . __( 'Select bulk action' ) . '</label>';
493
  echo '<select name="action' . $two . '" id="bulk-action-selector-' . esc_attr( $which ) . "\">\n";
514
  * @return string|false The action name or False if no action was selected
515
  */
516
  public function current_action() {
517
+ if ( isset( $_REQUEST['filter_action'] ) && ! empty( $_REQUEST['filter_action'] ) ) {
518
  return false;
519
+ }
520
 
521
+ if ( isset( $_REQUEST['action'] ) && -1 != $_REQUEST['action'] ) {
522
  return $_REQUEST['action'];
523
+ }
524
 
525
+ if ( isset( $_REQUEST['action2'] ) && -1 != $_REQUEST['action2'] ) {
526
  return $_REQUEST['action2'];
527
+ }
528
 
529
  return false;
530
  }
536
  * @access protected
537
  *
538
  * @param array $actions The list of actions
539
+ * @param bool $always_visible Whether the actions should be always visible
540
  * @return string
541
  */
542
  protected function row_actions( $actions, $always_visible = false ) {
543
  $action_count = count( $actions );
544
+ $i = 0;
545
 
546
+ if ( ! $action_count ) {
547
  return '';
548
+ }
549
 
550
  $out = '<div class="' . ( $always_visible ? 'row-actions visible' : 'row-actions' ) . '">';
551
  foreach ( $actions as $action => $link ) {
552
  ++$i;
553
  ( $i == $action_count ) ? $sep = '' : $sep = ' | ';
554
+ $out .= "<span class='$action'>$link$sep</span>";
555
  }
556
  $out .= '</div>';
557
 
593
  $extra_checks = $wpdb->prepare( ' AND post_status = %s', sanitize_text_field( $_GET['post_status'] ) );
594
  }
595
 
596
+ $months = $wpdb->get_results(
597
+ $wpdb->prepare(
598
+ "
599
  SELECT DISTINCT YEAR( post_date ) AS year, MONTH( post_date ) AS month
600
  FROM $wpdb->posts
601
  WHERE post_type = %s
602
  $extra_checks
603
  ORDER BY post_date DESC
604
+ ",
605
+ $post_type
606
+ )
607
+ );
608
 
609
  /**
610
  * Filter the 'Months' drop-down results.
618
 
619
  $month_count = count( $months );
620
 
621
+ if ( ! $month_count || ( 1 == $month_count && 0 == $months[0]->month ) ) {
622
  return;
623
+ }
624
 
625
  $m = isset( $_GET['m'] ) ? (int) $_GET['m'] : 0;
626
+ ?>
627
  <label for="filter-by-date" class="screen-reader-text"><?php _e( 'Filter by date' ); ?></label>
628
  <select name="m" id="filter-by-date">
629
  <option<?php selected( $m, 0 ); ?> value="0"><?php _e( 'All dates' ); ?></option>
630
+ <?php
631
  foreach ( $months as $arc_row ) {
632
+ if ( 0 == $arc_row->year ) {
633
  continue;
634
+ }
635
 
636
  $month = zeroise( $arc_row->month, 2 );
637
+ $year = $arc_row->year;
638
 
639
+ printf(
640
+ "<option %s value='%s'>%s</option>\n",
641
  selected( $m, $year . $month, false ),
642
  esc_attr( $arc_row->year . $month ),
643
  /* translators: 1: month name, 2: 4-digit year */
644
  sprintf( __( '%1$s %2$d' ), $wp_locale->get_month( $month ), $year )
645
  );
646
  }
647
+ ?>
648
  </select>
649
+ <?php
650
  }
651
 
652
  /**
658
  * @param string $current_mode
659
  */
660
  protected function view_switcher( $current_mode ) {
661
+ ?>
662
  <input type="hidden" name="mode" value="<?php echo esc_attr( $current_mode ); ?>" />
663
  <div class="view-switch">
664
+ <?php
665
+ foreach ( $this->modes as $mode => $title ) {
666
+ $classes = array( 'view-' . $mode );
667
+ if ( $current_mode === $mode ) {
668
+ $classes[] = 'current';
 
 
 
 
 
 
669
  }
670
+ printf(
671
+ "<a href='%s' class='%s' id='view-switch-$mode'><span class='screen-reader-text'>%s</span></a>\n",
672
+ esc_url( add_query_arg( 'mode', $mode ) ),
673
+ implode( ' ', $classes ),
674
+ $title
675
+ );
676
+ }
677
  ?>
678
  </div>
679
+ <?php
680
  }
681
 
682
  /**
692
  $approved_comments = get_comments_number();
693
 
694
  $approved_comments_number = number_format_i18n( $approved_comments );
695
+ $pending_comments_number = number_format_i18n( $pending_comments );
696
 
697
  $approved_only_phrase = sprintf( _n( '%s comment', '%s comments', $approved_comments ), $approved_comments_number );
698
+ $approved_phrase = sprintf( _n( '%s approved comment', '%s approved comments', $approved_comments ), $approved_comments_number );
699
+ $pending_phrase = sprintf( _n( '%s pending comment', '%s pending comments', $pending_comments ), $pending_comments_number );
700
 
701
  // No comments at all.
702
  if ( ! $approved_comments && ! $pending_comments ) {
703
+ printf(
704
+ '<span aria-hidden="true">—</span><span class="screen-reader-text">%s</span>',
705
  __( 'No comments' )
706
  );
707
+ // Approved comments have different display depending on some conditions.
708
  } elseif ( $approved_comments ) {
709
+ printf(
710
+ '<a href="%s" class="post-com-count post-com-count-approved"><span class="comment-count-approved" aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></a>',
711
+ esc_url(
712
+ add_query_arg(
713
+ array(
714
+ 'p' => $post_id,
715
+ 'comment_status' => 'approved',
716
+ ),
717
+ admin_url( 'edit-comments.php' )
718
+ )
719
+ ),
720
  $approved_comments_number,
721
  $pending_comments ? $approved_phrase : $approved_only_phrase
722
  );
723
  } else {
724
+ printf(
725
+ '<span class="post-com-count post-com-count-no-comments"><span class="comment-count comment-count-no-comments" aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></span>',
726
  $approved_comments_number,
727
  $pending_comments ? __( 'No approved comments' ) : __( 'No comments' )
728
  );
729
  }
730
 
731
  if ( $pending_comments ) {
732
+ printf(
733
+ '<a href="%s" class="post-com-count post-com-count-pending"><span class="comment-count-pending" aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></a>',
734
+ esc_url(
735
+ add_query_arg(
736
+ array(
737
+ 'p' => $post_id,
738
+ 'comment_status' => 'moderated',
739
+ ),
740
+ admin_url( 'edit-comments.php' )
741
+ )
742
+ ),
743
  $pending_comments_number,
744
  $pending_phrase
745
  );
746
  } else {
747
+ printf(
748
+ '<span class="post-com-count post-com-count-pending post-com-count-no-pending"><span class="comment-count comment-count-no-pending" aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></span>',
749
  $pending_comments_number,
750
  $approved_comments ? __( 'No pending comments' ) : __( 'No comments' )
751
  );
763
  public function get_pagenum() {
764
  $pagenum = isset( $_REQUEST['paged'] ) ? absint( $_REQUEST['paged'] ) : 0;
765
 
766
+ if ( isset( $this->_pagination_args['total_pages'] ) && $pagenum > $this->_pagination_args['total_pages'] ) {
767
  $pagenum = $this->_pagination_args['total_pages'];
768
+ }
769
 
770
  return max( 1, $pagenum );
771
  }
782
  */
783
  protected function get_items_per_page( $option, $default = 20 ) {
784
  $per_page = (int) get_user_option( $option );
785
+ if ( empty( $per_page ) || $per_page < 1 ) {
786
  $per_page = $default;
787
+ }
788
 
789
  /**
790
  * Filter the number of items to be displayed on each page of the list table.
815
  return;
816
  }
817
 
818
+ $total_items = $this->_pagination_args['total_items'];
819
+ $total_pages = $this->_pagination_args['total_pages'];
820
  $infinite_scroll = false;
821
  if ( isset( $this->_pagination_args['infinite_scroll'] ) ) {
822
  $infinite_scroll = $this->_pagination_args['infinite_scroll'];
841
 
842
  $disable_first = $disable_last = $disable_prev = $disable_next = false;
843
 
844
+ if ( $current == 1 ) {
845
  $disable_first = true;
846
+ $disable_prev = true;
847
+ }
848
  if ( $current == 2 ) {
849
  $disable_first = true;
850
  }
851
+ if ( $current == $total_pages ) {
852
  $disable_last = true;
853
  $disable_next = true;
854
+ }
855
  if ( $current == $total_pages - 1 ) {
856
  $disable_last = true;
857
  }
859
  if ( $disable_first ) {
860
  $page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&laquo;</span>';
861
  } else {
862
+ $page_links[] = sprintf(
863
+ "<a class='first-page button' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
864
  esc_url( remove_query_arg( 'paged', $current_url ) ),
865
  __( 'First page' ),
866
  '&laquo;'
870
  if ( $disable_prev ) {
871
  $page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&lsaquo;</span>';
872
  } else {
873
+ $page_links[] = sprintf(
874
+ "<a class='prev-page button' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
875
+ esc_url( add_query_arg( 'paged', max( 1, $current - 1 ), $current_url ) ),
876
  __( 'Previous page' ),
877
  '&lsaquo;'
878
  );
882
  $html_current_page = $current;
883
  $total_pages_before = '<span class="screen-reader-text">' . __( 'Current Page' ) . '</span><span id="table-paging" class="paging-input">';
884
  } else {
885
+ $html_current_page = sprintf(
886
+ "%s<input class='current-page' id='current-page-selector' type='text' name='paged' value='%s' size='%d' aria-describedby='table-paging' />",
887
  '<label for="current-page-selector" class="screen-reader-text">' . __( 'Current Page' ) . '</label>',
888
  $current,
889
  strlen( $total_pages )
890
  );
891
  }
892
  $html_total_pages = sprintf( "<span class='total-pages'>%s</span>", number_format_i18n( $total_pages ) );
893
+ $page_links[] = $total_pages_before . sprintf( _x( '%1$s of %2$s', 'paging' ), $html_current_page, $html_total_pages ) . $total_pages_after;
894
 
895
  if ( $disable_next ) {
896
  $page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&rsaquo;</span>';
897
  } else {
898
+ $page_links[] = sprintf(
899
+ "<a class='next-page button' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
900
+ esc_url( add_query_arg( 'paged', min( $total_pages, $current + 1 ), $current_url ) ),
901
  __( 'Next page' ),
902
  '&rsaquo;'
903
  );
906
  if ( $disable_last ) {
907
  $page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&raquo;</span>';
908
  } else {
909
+ $page_links[] = sprintf(
910
+ "<a class='last-page button' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
911
  esc_url( add_query_arg( 'paged', $total_pages, $current_url ) ),
912
  __( 'Last page' ),
913
  '&raquo;'
971
  */
972
  protected function get_default_primary_column_name() {
973
  $columns = $this->get_columns();
974
+ $column = '';
975
 
976
  if ( empty( $columns ) ) {
977
  return $column;
1018
  // If the primary column doesn't exist fall back to the
1019
  // first non-checkbox column.
1020
  if ( ! isset( $columns[ $default ] ) ) {
1021
+ $default = self::get_default_primary_column_name();
1022
  }
1023
 
1024
  /**
1029
  * @param string $default Column name default for the specific list table, e.g. 'name'.
1030
  * @param string $context Screen ID for specific list table, e.g. 'plugins'.
1031
  */
1032
+ $column = apply_filters( 'list_table_primary_column', $default, $this->screen->id );
1033
 
1034
  if ( empty( $column ) || ! isset( $columns[ $column ] ) ) {
1035
  $column = $default;
1060
  }
1061
 
1062
  $columns = get_column_headers( $this->screen );
1063
+ $hidden = get_hidden_columns( $this->screen );
1064
 
1065
  $sortable_columns = $this->get_sortable_columns();
1066
  /**
1077
 
1078
  $sortable = array();
1079
  foreach ( $_sortable as $id => $data ) {
1080
+ if ( empty( $data ) ) {
1081
  continue;
1082
+ }
1083
 
1084
  $data = (array) $data;
1085
+ if ( ! isset( $data[1] ) ) {
1086
  $data[1] = false;
1087
+ }
1088
 
1089
+ $sortable[ $id ] = $data;
1090
  }
1091
 
1092
+ $primary = $this->get_primary_column_name();
1093
  $this->_column_headers = array( $columns, $hidden, $sortable, $primary );
1094
 
1095
  return $this->_column_headers;
1105
  */
1106
  public function get_column_count() {
1107
  list ( $columns, $hidden ) = $this->get_column_info();
1108
+ $hidden = array_intersect( array_keys( $columns ), array_filter( $hidden ) );
1109
  return count( $columns ) - count( $hidden );
1110
  }
1111
 
1139
 
1140
  if ( ! empty( $columns['cb'] ) ) {
1141
  static $cb_counter = 1;
1142
+ $columns['cb'] = '<label class="screen-reader-text" for="cb-select-all-' . $cb_counter . '">' . __( 'Select All' ) . '</label>'
1143
  . '<input id="cb-select-all-' . $cb_counter . '" type="checkbox" />';
1144
  $cb_counter++;
1145
  }
1151
  $class[] = 'hidden';
1152
  }
1153
 
1154
+ if ( 'cb' === $column_key ) {
1155
  $class[] = 'check-column';
1156
+ } elseif ( in_array( $column_key, array( 'posts', 'comments', 'links' ) ) ) {
1157
  $class[] = 'num';
1158
+ }
1159
 
1160
  if ( $column_key === $primary ) {
1161
  $class[] = 'column-primary';
1162
  }
1163
 
1164
+ if ( isset( $sortable[ $column_key ] ) ) {
1165
+ list( $orderby, $desc_first ) = $sortable[ $column_key ];
1166
 
1167
  if ( $current_orderby === $orderby ) {
1168
+ $order = 'asc' === $current_order ? 'desc' : 'asc';
1169
  $class[] = 'sorted';
1170
  $class[] = $current_order;
1171
  } else {
1172
+ $order = $desc_first ? 'desc' : 'asc';
1173
  $class[] = 'sortable';
1174
  $class[] = $desc_first ? 'asc' : 'desc';
1175
  }
1177
  $column_display_name = '<a href="' . esc_url( add_query_arg( compact( 'orderby', 'order' ), $current_url ) ) . '"><span>' . $column_display_name . '</span><span class="sorting-indicator"></span></a>';
1178
  }
1179
 
1180
+ $tag = ( 'cb' === $column_key ) ? 'td' : 'th';
1181
  $scope = ( 'th' === $tag ) ? 'scope="col"' : '';
1182
+ $id = $with_id ? "id='$column_key'" : '';
1183
 
1184
+ if ( ! empty( $class ) ) {
1185
  $class = "class='" . join( ' ', $class ) . "'";
1186
+ }
1187
 
1188
  echo "<$tag $scope $id $class>$column_display_name</$tag>";
1189
  }
1200
 
1201
  $this->display_tablenav( 'top' );
1202
 
1203
+ // $this->screen->render_screen_reader_content( 'heading_list' );
1204
+ ?>
1205
  <table class="wp-list-table <?php echo implode( ' ', $this->get_table_classes() ); ?>">
1206
  <thead>
1207
  <tr>
1209
  </tr>
1210
  </thead>
1211
 
1212
+ <tbody id="the-list"
1213
+ <?php
1214
  if ( $singular ) {
1215
  echo " data-wp-lists='list:$singular'";
1216
+ }
1217
+ ?>
1218
+ >
1219
  <?php $this->display_rows_or_placeholder(); ?>
1220
  </tbody>
1221
 
1226
  </tfoot>
1227
 
1228
  </table>
1229
+ <?php
1230
  $this->display_tablenav( 'bottom' );
1231
  }
1232
 
1256
  ?>
1257
  <div class="tablenav <?php echo esc_attr( $which ); ?>">
1258
 
1259
+ <?php if ( $this->has_items() ) : ?>
1260
  <div class="alignleft actions bulkactions">
1261
  <?php $this->bulk_actions( $which ); ?>
1262
  </div>
1263
+ <?php
1264
+ endif;
1265
  $this->extra_tablenav( $which );
1266
  $this->pagination( $which );
1267
+ ?>
1268
 
1269
  <br class="clear" />
1270
  </div>
1271
+ <?php
1272
  }
1273
 
1274
  /**
1304
  * @access public
1305
  */
1306
  public function display_rows() {
1307
+ foreach ( $this->items as $item ) {
1308
  $this->single_row( $item );
1309
+ }
1310
  }
1311
 
1312
  /**
1379
  echo "<td $attributes>";
1380
  echo call_user_func( array( $this, 'column_' . $column_name ), $item );
1381
  echo $this->handle_row_actions( $item, $column_name, $primary );
1382
+ echo '</td>';
1383
  } else {
1384
  echo "<td $attributes>";
1385
  echo $this->column_default( $item, $column_name );
1386
  echo $this->handle_row_actions( $item, $column_name, $primary );
1387
+ echo '</td>';
1388
  }
1389
  }
1390
  }
1402
  */
1403
  protected function handle_row_actions( $item, $column_name, $primary ) {
1404
  return $column_name === $primary ? '<button type="button" class="toggle-row"><span class="screen-reader-text">' . __( 'Show more details' ) . '</span></button>' : '';
1405
+ }
1406
 
1407
  /**
1408
  * Handle an incoming ajax request (called from admin-ajax.php)
1431
  );
1432
  }
1433
  if ( isset( $this->_pagination_args['total_pages'] ) ) {
1434
+ $response['total_pages'] = $this->_pagination_args['total_pages'];
1435
  $response['total_pages_i18n'] = number_format_i18n( $this->_pagination_args['total_pages'] );
1436
  }
1437
 
1449
  'screen' => array(
1450
  'id' => $this->screen->id,
1451
  'base' => $this->screen->base,
1452
+ ),
1453
  );
1454
 
1455
  printf( "<script type='text/javascript'>list_args = %s;</script>\n", wp_json_encode( $args ) );
includes/classes/class-woo-feed-log-handler-file.php CHANGED
@@ -1,436 +1,438 @@
1
- <?php
2
- /**
3
- * Log file handler
4
- * @package WooFeed
5
- * @subpackage LogHandler
6
- * @version 1.0.0
7
- * @since WooFeed 3.2.1
8
- * @copyright 2019 WebAppick
9
- * @author KD <mhaudul.hk@gmail.com>
10
- *
11
- */
12
- if ( ! defined( 'ABSPATH' ) ) die(); // Silence...
13
-
14
- class Woo_Feed_Log_Handler_File extends WC_Log_Handler {
15
-
16
- /**
17
- * Stores open file handles.
18
- *
19
- * @var array
20
- */
21
- protected $handles = array();
22
-
23
- /**
24
- * File size limit for log files in bytes.
25
- *
26
- * @var int
27
- */
28
- protected $log_size_limit;
29
-
30
- /**
31
- * Cache logs that could not be written.
32
- *
33
- * If a log is written too early in the request, pluggable functions may be unavailable. These
34
- * logs will be cached and written on 'plugins_loaded' action.
35
- *
36
- * @var array
37
- */
38
- protected $cached_logs = array();
39
-
40
- /**
41
- * Constructor for the logger.
42
- *
43
- * @param int $log_size_limit Optional. Size limit for log files. Default 5mb.
44
- */
45
- public function __construct( $log_size_limit = null ) {
46
- if ( null === $log_size_limit ) {
47
- $log_size_limit = 5 * 1024 * 1024;
48
- }
49
-
50
- $this->log_size_limit = apply_filters( 'woo_feed_log_file_size_limit', $log_size_limit );
51
-
52
- add_action( 'plugins_loaded', array( $this, 'write_cached_logs' ) );
53
- }
54
-
55
- /**
56
- * Destructor.
57
- *
58
- * Cleans up open file handles.
59
- */
60
- public function __destruct() {
61
- foreach ( $this->handles as $handle ) {
62
- if ( is_resource( $handle ) ) {
63
- fclose( $handle ); // @codingStandardsIgnoreLine.
64
- }
65
- }
66
- }
67
-
68
- /**
69
- * Handle a log entry.
70
- *
71
- * @param int $timestamp Log timestamp.
72
- * @param string $level emergency|alert|critical|error|warning|notice|info|debug.
73
- * @param string $message Log message.
74
- * @param array $context {
75
- * Additional information for log handlers.
76
- *
77
- * @type string $source Optional. Determines log file to write to. Default 'log'.
78
- * @type bool $_legacy Optional. Default false. True to use outdated log format
79
- * originally used in deprecated WC_Logger::add calls.
80
- * }
81
- *
82
- * @return bool False if value was not handled and true if value was handled.
83
- */
84
- public function handle( $timestamp, $level, $message, $context ) {
85
-
86
- if ( isset( $context['source'] ) && $context['source'] ) {
87
- $handle = $context['source'];
88
- } else {
89
- $handle = 'log';
90
- }
91
-
92
- $entry = self::format_entry( $timestamp, $level, $message, $context );
93
-
94
- return $this->add( $entry, $handle );
95
- }
96
-
97
- /**
98
- * Builds a log entry text from timestamp, level and message.
99
- *
100
- * @param int $timestamp Log timestamp.
101
- * @param string $level emergency|alert|critical|error|warning|notice|info|debug.
102
- * @param string $message Log message.
103
- * @param array $context Additional information for log handlers.
104
- *
105
- * @return string Formatted log entry.
106
- */
107
- protected static function format_entry( $timestamp, $level, $message, $context ) {
108
-
109
- if ( isset( $context['_legacy'] ) && true === $context['_legacy'] ) {
110
- if ( isset( $context['source'] ) && $context['source'] ) {
111
- $handle = $context['source'];
112
- } else {
113
- $handle = 'log';
114
- }
115
- $message = apply_filters( 'woo_feed_logger_add_message', $message, $handle );
116
- $time = date_i18n( 'm-d-Y @ H:i:s' );
117
- $entry = "{$time} - {$message}";
118
- } else {
119
- $entry = parent::format_entry( $timestamp, $level, $message, $context );
120
- }
121
-
122
- return $entry;
123
- }
124
-
125
- /**
126
- * Open log file for writing.
127
- *
128
- * @param string $handle Log handle.
129
- * @param string $mode Optional. File mode. Default 'a'.
130
- * @return bool Success.
131
- */
132
- protected function open( $handle, $mode = 'a' ) {
133
- if ( $this->is_open( $handle ) ) {
134
- return true;
135
- }
136
-
137
- $file = self::get_log_file_path( $handle );
138
-
139
- if ( $file ) {
140
- if ( ! file_exists( $file ) ) {
141
- $temphandle = @fopen( $file, 'w+' ); // @codingStandardsIgnoreLine.
142
- @fclose( $temphandle ); // @codingStandardsIgnoreLine.
143
-
144
- if ( defined( 'FS_CHMOD_FILE' ) ) {
145
- @chmod( $file, FS_CHMOD_FILE ); // @codingStandardsIgnoreLine.
146
- }
147
- }
148
-
149
- $resource = @fopen( $file, $mode ); // @codingStandardsIgnoreLine.
150
-
151
- if ( $resource ) {
152
- $this->handles[ $handle ] = $resource;
153
- return true;
154
- }
155
- }
156
-
157
- return false;
158
- }
159
-
160
- /**
161
- * Check if a handle is open.
162
- *
163
- * @param string $handle Log handle.
164
- * @return bool True if $handle is open.
165
- */
166
- protected function is_open( $handle ) {
167
- return array_key_exists( $handle, $this->handles ) && is_resource( $this->handles[ $handle ] );
168
- }
169
-
170
- /**
171
- * Close a handle.
172
- *
173
- * @param string $handle Log handle.
174
- * @return bool success
175
- */
176
- protected function close( $handle ) {
177
- $result = false;
178
-
179
- if ( $this->is_open( $handle ) ) {
180
- $result = fclose( $this->handles[ $handle ] ); // @codingStandardsIgnoreLine.
181
- unset( $this->handles[ $handle ] );
182
- }
183
-
184
- return $result;
185
- }
186
-
187
- /**
188
- * Add a log entry to chosen file.
189
- *
190
- * @param string $entry Log entry text.
191
- * @param string $handle Log entry handle.
192
- *
193
- * @return bool True if write was successful.
194
- */
195
- protected function add( $entry, $handle ) {
196
- $result = false;
197
-
198
- if ( $this->should_rotate( $handle ) ) {
199
- $this->log_rotate( $handle );
200
- }
201
-
202
- if ( $this->open( $handle ) && is_resource( $this->handles[ $handle ] ) ) {
203
- $result = fwrite( $this->handles[ $handle ], $entry . PHP_EOL ); // @codingStandardsIgnoreLine.
204
- } else {
205
- $this->cache_log( $entry, $handle );
206
- }
207
-
208
- return false !== $result;
209
- }
210
-
211
- /**
212
- * Clear entries from chosen file.
213
- *
214
- * @param string $handle Log handle.
215
- *
216
- * @return bool
217
- */
218
- public function clear( $handle ) {
219
- $result = false;
220
-
221
- // Close the file if it's already open.
222
- $this->close( $handle );
223
-
224
- /**
225
- * $this->open( $handle, 'w' ) == Open the file for writing only. Place the file pointer at
226
- * the beginning of the file, and truncate the file to zero length.
227
- */
228
- if ( $this->open( $handle, 'w' ) && is_resource( $this->handles[ $handle ] ) ) {
229
- $result = true;
230
- }
231
-
232
- do_action( 'woo_feed_log_clear', $handle );
233
-
234
- return $result;
235
- }
236
-
237
- /**
238
- * Remove/delete the chosen file.
239
- *
240
- * @param string $handle Log handle.
241
- *
242
- * @return bool
243
- */
244
- public function remove( $handle ) {
245
- $removed = false;
246
- $logs = $this->get_log_files();
247
- $handle = sanitize_title( $handle );
248
- if ( isset( $logs[ $handle ] ) && $logs[ $handle ] ) {
249
- $file = realpath( trailingslashit( WOO_FEED_LOG_DIR ) . $logs[ $handle ] );
250
- if ( 0 === stripos( $file, realpath( trailingslashit( WOO_FEED_LOG_DIR ) ) ) && is_file( $file ) && is_writable( $file ) ) { // phpcs:ignore WordPress.VIP.FileSystemWritesDisallow.file_ops_is_writable
251
- $this->close( $file ); // Close first to be certain no processes keep it alive after it is unlinked.
252
- $removed = unlink( $file ); // phpcs:ignore WordPress.VIP.FileSystemWritesDisallow.file_ops_unlink
253
- }
254
- do_action( 'woo_feed_log_remove', $handle, $removed );
255
- }
256
- return $removed;
257
- }
258
-
259
- /**
260
- * Check if log file should be rotated.
261
- *
262
- * Compares the size of the log file to determine whether it is over the size limit.
263
- *
264
- * @param string $handle Log handle.
265
- * @return bool True if if should be rotated.
266
- */
267
- protected function should_rotate( $handle ) {
268
- $file = self::get_log_file_path( $handle );
269
- if ( $file ) {
270
- if ( $this->is_open( $handle ) ) {
271
- $file_stat = fstat( $this->handles[ $handle ] );
272
- return $file_stat['size'] > $this->log_size_limit;
273
- } elseif ( file_exists( $file ) ) {
274
- return filesize( $file ) > $this->log_size_limit;
275
- } else {
276
- return false;
277
- }
278
- } else {
279
- return false;
280
- }
281
- }
282
-
283
- /**
284
- * Rotate log files.
285
- *
286
- * Logs are rotated by prepending '.x' to the '.log' suffix.
287
- * The current log plus 10 historical logs are maintained.
288
- * For example:
289
- * base.9.log -> [ REMOVED ]
290
- * base.8.log -> base.9.log
291
- * ...
292
- * base.0.log -> base.1.log
293
- * base.log -> base.0.log
294
- *
295
- * @param string $handle Log handle.
296
- */
297
- protected function log_rotate( $handle ) {
298
- for ( $i = 8; $i >= 0; $i-- ) {
299
- $this->increment_log_infix( $handle, $i );
300
- }
301
- $this->increment_log_infix( $handle );
302
- }
303
-
304
- /**
305
- * Increment a log file suffix.
306
- *
307
- * @param string $handle Log handle.
308
- * @param null|int $number Optional. Default null. Log suffix number to be incremented.
309
- * @return bool True if increment was successful, otherwise false.
310
- */
311
- protected function increment_log_infix( $handle, $number = null ) {
312
- if ( null === $number ) {
313
- $suffix = '';
314
- $next_suffix = '.0';
315
- } else {
316
- $suffix = '.' . $number;
317
- $next_suffix = '.' . ( $number + 1 );
318
- }
319
-
320
- $rename_from = self::get_log_file_path( "{$handle}{$suffix}" );
321
- $rename_to = self::get_log_file_path( "{$handle}{$next_suffix}" );
322
-
323
- if ( $this->is_open( $rename_from ) ) {
324
- $this->close( $rename_from );
325
- }
326
-
327
- if ( is_writable( $rename_from ) ) { // phpcs:ignore WordPress.VIP.FileSystemWritesDisallow.file_ops_is_writable
328
- return rename( $rename_from, $rename_to ); // phpcs:ignore WordPress.VIP.FileSystemWritesDisallow.file_ops_rename
329
- } else {
330
- return false;
331
- }
332
-
333
- }
334
-
335
- /**
336
- * Get a log file path.
337
- *
338
- * @param string $handle Log name.
339
- * @return bool|string The log file path or false if path cannot be determined.
340
- */
341
- public static function get_log_file_path( $handle ) {
342
- if ( function_exists( 'wp_hash' ) ) {
343
- return trailingslashit( WOO_FEED_LOG_DIR ) . self::get_log_file_name( $handle );
344
- } else {
345
- woo_feed_doing_it_wrong( __METHOD__, __( 'This method should not be called before plugins_loaded.', 'woo-feed' ), '3.0' );
346
- return false;
347
- }
348
- }
349
-
350
- /**
351
- * Get a log file name.
352
- *
353
- * File names consist of the handle, followed by the date, followed by a hash, .log.
354
- *
355
- * @since 3.3
356
- * @param string $handle Log name.
357
- * @return bool|string The log file name or false if cannot be determined.
358
- */
359
- public static function get_log_file_name( $handle ) {
360
- if ( function_exists( 'wp_hash' ) ) {
361
- $date_suffix = gmdate( 'Y-m-d', time() );
362
- $hash_suffix = wp_hash( $handle );
363
- return sanitize_file_name( implode( '-', array( $handle, $date_suffix, $hash_suffix ) ) . '.log' );
364
- } else {
365
- woo_feed_doing_it_wrong( __METHOD__, __( 'This method should not be called before plugins_loaded.', 'woo-feed' ), '3.3' );
366
- return false;
367
- }
368
- }
369
-
370
- /**
371
- * Cache log to write later.
372
- *
373
- * @param string $entry Log entry text.
374
- * @param string $handle Log entry handle.
375
- */
376
- protected function cache_log( $entry, $handle ) {
377
- $this->cached_logs[] = array(
378
- 'entry' => $entry,
379
- 'handle' => $handle,
380
- );
381
- }
382
-
383
- /**
384
- * Write cached logs.
385
- */
386
- public function write_cached_logs() {
387
- foreach ( $this->cached_logs as $log ) {
388
- $this->add( $log['entry'], $log['handle'] );
389
- }
390
- }
391
-
392
- /**
393
- * Delete all logs older than a defined timestamp.
394
- *
395
- * @since 3.4.0
396
- * @param integer $timestamp Timestamp to delete logs before.
397
- */
398
- public static function delete_logs_before_timestamp( $timestamp = 0 ) {
399
- if ( ! $timestamp ) {
400
- return;
401
- }
402
-
403
- $log_files = self::get_log_files();
404
-
405
- foreach ( $log_files as $log_file ) {
406
- $last_modified = filemtime( trailingslashit( WOO_FEED_LOG_DIR ) . $log_file );
407
-
408
- if ( $last_modified < $timestamp ) {
409
- @unlink( trailingslashit( WOO_FEED_LOG_DIR ) . $log_file ); // @codingStandardsIgnoreLine.
410
- }
411
- }
412
- }
413
-
414
- /**
415
- * Get all log files in the log directory.
416
- *
417
- * @since 3.4.0
418
- * @return array
419
- */
420
- public static function get_log_files() {
421
- $files = @scandir( WOO_FEED_LOG_DIR ); // @codingStandardsIgnoreLine.
422
- $result = array();
423
-
424
- if ( ! empty( $files ) ) {
425
- foreach ( $files as $key => $value ) {
426
- if ( ! in_array( $value, array( '.', '..' ), true ) ) {
427
- if ( ! is_dir( $value ) && strstr( $value, '.log' ) ) {
428
- $result[ sanitize_title( $value ) ] = $value;
429
- }
430
- }
431
- }
432
- }
433
-
434
- return $result;
435
- }
436
- }
 
 
1
+ <?php
2
+ /**
3
+ * Log file handler
4
+ *
5
+ * @package WooFeed
6
+ * @subpackage LogHandler
7
+ * @version 1.0.0
8
+ * @since WooFeed 3.2.1
9
+ * @copyright 2019 WebAppick
10
+ * @author KD <mhaudul.hk@gmail.com>
11
+ */
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ die(); // Silence...
14
+ }
15
+
16
+ class Woo_Feed_Log_Handler_File extends WC_Log_Handler {
17
+
18
+ /**
19
+ * Stores open file handles.
20
+ *
21
+ * @var array
22
+ */
23
+ protected $handles = array();
24
+
25
+ /**
26
+ * File size limit for log files in bytes.
27
+ *
28
+ * @var int
29
+ */
30
+ protected $log_size_limit;
31
+
32
+ /**
33
+ * Cache logs that could not be written.
34
+ *
35
+ * If a log is written too early in the request, pluggable functions may be unavailable. These
36
+ * logs will be cached and written on 'plugins_loaded' action.
37
+ *
38
+ * @var array
39
+ */
40
+ protected $cached_logs = array();
41
+
42
+ /**
43
+ * Constructor for the logger.
44
+ *
45
+ * @param int $log_size_limit Optional. Size limit for log files. Default 5mb.
46
+ */
47
+ public function __construct( $log_size_limit = null ) {
48
+ if ( null === $log_size_limit ) {
49
+ $log_size_limit = 5 * 1024 * 1024;
50
+ }
51
+
52
+ $this->log_size_limit = apply_filters( 'woo_feed_log_file_size_limit', $log_size_limit );
53
+
54
+ add_action( 'plugins_loaded', array( $this, 'write_cached_logs' ) );
55
+ }
56
+
57
+ /**
58
+ * Destructor.
59
+ *
60
+ * Cleans up open file handles.
61
+ */
62
+ public function __destruct() {
63
+ foreach ( $this->handles as $handle ) {
64
+ if ( is_resource( $handle ) ) {
65
+ fclose( $handle ); // phpcs:ignore
66
+ }
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Handle a log entry.
72
+ *
73
+ * @param int $timestamp Log timestamp.
74
+ * @param string $level emergency|alert|critical|error|warning|notice|info|debug.
75
+ * @param string $message Log message.
76
+ * @param array $context {
77
+ * Additional information for log handlers.
78
+ *
79
+ * @type string $source Optional. Determines log file to write to. Default 'log'.
80
+ * @type bool $_legacy Optional. Default false. True to use outdated log format
81
+ * originally used in deprecated WC_Logger::add calls.
82
+ * }
83
+ *
84
+ * @return bool False if value was not handled and true if value was handled.
85
+ */
86
+ public function handle( $timestamp, $level, $message, $context ) {
87
+
88
+ if ( isset( $context['source'] ) && $context['source'] ) {
89
+ $handle = $context['source'];
90
+ } else {
91
+ $handle = 'log';
92
+ }
93
+
94
+ $entry = self::format_entry( $timestamp, $level, $message, $context );
95
+
96
+ return $this->add( $entry, $handle );
97
+ }
98
+
99
+ /**
100
+ * Builds a log entry text from timestamp, level and message.
101
+ *
102
+ * @param int $timestamp Log timestamp.
103
+ * @param string $level emergency|alert|critical|error|warning|notice|info|debug.
104
+ * @param string $message Log message.
105
+ * @param array $context Additional information for log handlers.
106
+ *
107
+ * @return string Formatted log entry.
108
+ */
109
+ protected static function format_entry( $timestamp, $level, $message, $context ) {
110
+
111
+ if ( isset( $context['_legacy'] ) && true === $context['_legacy'] ) {
112
+ if ( isset( $context['source'] ) && $context['source'] ) {
113
+ $handle = $context['source'];
114
+ } else {
115
+ $handle = 'log';
116
+ }
117
+ $message = apply_filters( 'woo_feed_logger_add_message', $message, $handle );
118
+ $time = date_i18n( 'm-d-Y @ H:i:s' );
119
+ $entry = "{$time} - {$message}";
120
+ } else {
121
+ $entry = parent::format_entry( $timestamp, $level, $message, $context );
122
+ }
123
+
124
+ return $entry;
125
+ }
126
+
127
+ /**
128
+ * Open log file for writing.
129
+ *
130
+ * @param string $handle Log handle.
131
+ * @param string $mode Optional. File mode. Default 'a'.
132
+ * @return bool Success.
133
+ */
134
+ protected function open( $handle, $mode = 'a' ) {
135
+ if ( $this->is_open( $handle ) ) {
136
+ return true;
137
+ }
138
+
139
+ $file = self::get_log_file_path( $handle );
140
+
141
+ if ( $file ) {
142
+ if ( ! file_exists( $file ) ) {
143
+ $temp_handle = fopen( $file, 'w+' ); // phpcs:ignore
144
+ fclose( $temp_handle ); // phpcs:ignore
145
+
146
+ if ( defined( 'FS_CHMOD_FILE' ) ) {
147
+ chmod( $file, FS_CHMOD_FILE ); // phpcs:ignore
148
+ }
149
+ }
150
+
151
+ $resource = fopen( $file, $mode ); // phpcs:ignore
152
+
153
+ if ( $resource ) {
154
+ $this->handles[ $handle ] = $resource;
155
+ return true;
156
+ }
157
+ }
158
+
159
+ return false;
160
+ }
161
+
162
+ /**
163
+ * Check if a handle is open.
164
+ *
165
+ * @param string $handle Log handle.
166
+ * @return bool True if $handle is open.
167
+ */
168
+ protected function is_open( $handle ) {
169
+ return array_key_exists( $handle, $this->handles ) && is_resource( $this->handles[ $handle ] );
170
+ }
171
+
172
+ /**
173
+ * Close a handle.
174
+ *
175
+ * @param string $handle Log handle.
176
+ * @return bool success
177
+ */
178
+ protected function close( $handle ) {
179
+ $result = false;
180
+
181
+ if ( $this->is_open( $handle ) ) {
182
+ $result = fclose( $this->handles[ $handle ] ); // phpcs:ignore
183
+ unset( $this->handles[ $handle ] );
184
+ }
185
+
186
+ return $result;
187
+ }
188
+
189
+ /**
190
+ * Add a log entry to chosen file.
191
+ *
192
+ * @param string $entry Log entry text.
193
+ * @param string $handle Log entry handle.
194
+ *
195
+ * @return bool True if write was successful.
196
+ */
197
+ protected function add( $entry, $handle ) {
198
+ $result = false;
199
+
200
+ if ( $this->should_rotate( $handle ) ) {
201
+ $this->log_rotate( $handle );
202
+ }
203
+
204
+ if ( $this->open( $handle ) && is_resource( $this->handles[ $handle ] ) ) {
205
+ $result = fwrite( $this->handles[ $handle ], $entry . PHP_EOL ); // phpcs:ignore
206
+ } else {
207
+ $this->cache_log( $entry, $handle );
208
+ }
209
+
210
+ return false !== $result;
211
+ }
212
+
213
+ /**
214
+ * Clear entries from chosen file.
215
+ *
216
+ * @param string $handle Log handle.
217
+ *
218
+ * @return bool
219
+ */
220
+ public function clear( $handle ) {
221
+ $result = false;
222
+
223
+ // Close the file if it's already open.
224
+ $this->close( $handle );
225
+
226
+ /**
227
+ * $this->open( $handle, 'w' ) == Open the file for writing only. Place the file pointer at
228
+ * the beginning of the file, and truncate the file to zero length.
229
+ */
230
+ if ( $this->open( $handle, 'w' ) && is_resource( $this->handles[ $handle ] ) ) {
231
+ $result = true;
232
+ }
233
+
234
+ do_action( 'woo_feed_log_clear', $handle );
235
+
236
+ return $result;
237
+ }
238
+
239
+ /**
240
+ * Remove/delete the chosen file.
241
+ *
242
+ * @param string $handle Log handle.
243
+ *
244
+ * @return bool
245
+ */
246
+ public function remove( $handle ) {
247
+ $removed = false;
248
+ $logs = $this->get_log_files();
249
+ $handle = sanitize_title( $handle );
250
+ if ( isset( $logs[ $handle ] ) && $logs[ $handle ] ) {
251
+ $file = realpath( trailingslashit( WOO_FEED_LOG_DIR ) . $logs[ $handle ] );
252
+ if ( 0 === stripos( $file, realpath( trailingslashit( WOO_FEED_LOG_DIR ) ) ) && is_file( $file ) && is_writable( $file ) ) { // phpcs:ignore
253
+ $this->close( $file ); // Close first to be certain no processes keep it alive after it is unlinked.
254
+ $removed = unlink( $file ); // phpcs:ignore
255
+ }
256
+ do_action( 'woo_feed_log_remove', $handle, $removed );
257
+ }
258
+ return $removed;
259
+ }
260
+
261
+ /**
262
+ * Check if log file should be rotated.
263
+ *
264
+ * Compares the size of the log file to determine whether it is over the size limit.
265
+ *
266
+ * @param string $handle Log handle.
267
+ * @return bool True if if should be rotated.
268
+ */
269
+ protected function should_rotate( $handle ) {
270
+ $file = self::get_log_file_path( $handle );
271
+ if ( $file ) {
272
+ if ( $this->is_open( $handle ) ) {
273
+ $file_stat = fstat( $this->handles[ $handle ] );
274
+ return $file_stat['size'] > $this->log_size_limit;
275
+ } elseif ( file_exists( $file ) ) {
276
+ return filesize( $file ) > $this->log_size_limit;
277
+ } else {
278
+ return false;
279
+ }
280
+ } else {
281
+ return false;
282
+ }
283
+ }
284
+
285
+ /**
286
+ * Rotate log files.
287
+ *
288
+ * Logs are rotated by prepending '.x' to the '.log' suffix.
289
+ * The current log plus 10 historical logs are maintained.
290
+ * For example:
291
+ * base.9.log -> [ REMOVED ]
292
+ * base.8.log -> base.9.log
293
+ * ...
294
+ * base.0.log -> base.1.log
295
+ * base.log -> base.0.log
296
+ *
297
+ * @param string $handle Log handle.
298
+ */
299
+ protected function log_rotate( $handle ) {
300
+ for ( $i = 8; $i >= 0; $i-- ) {
301
+ $this->increment_log_infix( $handle, $i );
302
+ }
303
+ $this->increment_log_infix( $handle );
304
+ }
305
+
306
+ /**
307
+ * Increment a log file suffix.
308
+ *
309
+ * @param string $handle Log handle.
310
+ * @param null|int $number Optional. Default null. Log suffix number to be incremented.
311
+ * @return bool True if increment was successful, otherwise false.
312
+ */
313
+ protected function increment_log_infix( $handle, $number = null ) {
314
+ if ( null === $number ) {
315
+ $suffix = '';
316
+ $next_suffix = '.0';
317
+ } else {
318
+ $suffix = '.' . $number;
319
+ $next_suffix = '.' . ( $number + 1 );
320
+ }
321
+
322
+ $rename_from = self::get_log_file_path( "{$handle}{$suffix}" );
323
+ $rename_to = self::get_log_file_path( "{$handle}{$next_suffix}" );
324
+
325
+ if ( $this->is_open( $rename_from ) ) {
326
+ $this->close( $rename_from );
327
+ }
328
+
329
+ if ( is_writable( $rename_from ) ) { // phpcs:ignore
330
+ return rename( $rename_from, $rename_to ); // phpcs:ignore
331
+ } else {
332
+ return false;
333
+ }
334
+
335
+ }
336
+
337
+ /**
338
+ * Get a log file path.
339
+ *
340
+ * @param string $handle Log name.
341
+ * @return bool|string The log file path or false if path cannot be determined.
342
+ */
343
+ public static function get_log_file_path( $handle ) {
344
+ if ( function_exists( 'wp_hash' ) ) {
345
+ return trailingslashit( WOO_FEED_LOG_DIR ) . self::get_log_file_name( $handle );
346
+ } else {
347
+ woo_feed_doing_it_wrong( __METHOD__, __( 'This method should not be called before plugins_loaded.', 'woo-feed' ), '3.0' );
348
+ return false;
349
+ }
350
+ }
351
+
352
+ /**
353
+ * Get a log file name.
354
+ *
355
+ * File names consist of the handle, followed by the date, followed by a hash, .log.
356
+ *
357
+ * @since 3.3
358
+ * @param string $handle Log name.
359
+ * @return bool|string The log file name or false if cannot be determined.
360
+ */
361
+ public static function get_log_file_name( $handle ) {
362
+ if ( function_exists( 'wp_hash' ) ) {
363
+ $date_suffix = gmdate( 'Y-m-d', time() );
364
+ $hash_suffix = wp_hash( $handle );
365
+ return sanitize_file_name( implode( '-', array( $handle, $date_suffix, $hash_suffix ) ) . '.log' );
366
+ } else {
367
+ woo_feed_doing_it_wrong( __METHOD__, __( 'This method should not be called before plugins_loaded.', 'woo-feed' ), '3.3' );
368
+ return false;
369
+ }
370
+ }
371
+
372
+ /**
373
+ * Cache log to write later.
374
+ *
375
+ * @param string $entry Log entry text.
376
+ * @param string $handle Log entry handle.
377
+ */
378
+ protected function cache_log( $entry, $handle ) {
379
+ $this->cached_logs[] = array(
380
+ 'entry' => $entry,
381
+ 'handle' => $handle,
382
+ );
383
+ }
384
+
385
+ /**
386
+ * Write cached logs.
387
+ */
388
+ public function write_cached_logs() {
389
+ foreach ( $this->cached_logs as $log ) {
390
+ $this->add( $log['entry'], $log['handle'] );
391
+ }
392
+ }
393
+
394
+ /**
395
+ * Delete all logs older than a defined timestamp.
396
+ *
397
+ * @since 3.4.0
398
+ * @param integer $timestamp Timestamp to delete logs before.
399
+ */
400
+ public static function delete_logs_before_timestamp( $timestamp = 0 ) {
401
+ if ( ! $timestamp ) {
402
+ return;
403
+ }
404
+
405
+ $log_files = self::get_log_files();
406
+
407
+ foreach ( $log_files as $log_file ) {
408
+ $last_modified = filemtime( trailingslashit( WOO_FEED_LOG_DIR ) . $log_file );
409
+
410
+ if ( $last_modified < $timestamp ) {
411
+ unlink( trailingslashit( WOO_FEED_LOG_DIR ) . $log_file ); // phpcs:ignore
412
+ }
413
+ }
414
+ }
415
+
416
+ /**
417
+ * Get all log files in the log directory.
418
+ *
419
+ * @since 3.4.0
420
+ * @return array
421
+ */
422
+ public static function get_log_files() {
423
+ $files = scandir( WOO_FEED_LOG_DIR );
424
+ $result = array();
425
+
426
+ if ( ! empty( $files ) && is_array( $files ) ) {
427
+ foreach ( $files as $key => $value ) {
428
+ if ( ! in_array( $value, array( '.', '..' ), true ) ) {
429
+ if ( ! is_dir( $value ) && strstr( $value, '.log' ) ) {
430
+ $result[ sanitize_title( $value ) ] = $value;
431
+ }
432
+ }
433
+ }
434
+ }
435
+
436
+ return $result;
437
+ }
438
+ }
includes/classes/class-woo-feed-merchant.php CHANGED
@@ -7,7 +7,7 @@
7
  */
8
 
9
  class Woo_Feed_Merchant {
10
-
11
  public $merchant;
12
  private $templates = array(
13
  'default' => array(
@@ -38,7 +38,7 @@ class Woo_Feed_Merchant {
38
  'output_type' => array( '1', '1', '1', '1', '1', '1', '1', '1' ),
39
  'limit' => array( '', '', '', '', '', '', '', '' ),
40
  ),
41
- "bol" => array(
42
  'mattributes' => array(
43
  'EAN',
44
  'Internal Reference',
@@ -2778,26 +2778,26 @@ class Woo_Feed_Merchant {
2778
  'limit' => array( '', '', '', '', '', '', '', '', '', '', '', '', '', '', '' ),
2779
  ),
2780
  );
2781
-
2782
  //adroll - smartly.io google
2783
  //admarkt custom 2
2784
-
2785
  public function __construct( $merchant = null ) {
2786
  $this->merchant = $merchant;
2787
  }
2788
-
2789
  public function get_merchant_template() {
2790
  if ( ! is_null( $this->merchant ) && array_key_exists( $this->merchant, $this->templates ) ) {
2791
  return $this->templates[ $this->merchant ];
2792
  }
2793
-
2794
  return false;
2795
  }
2796
-
2797
  public function get_default_template() {
2798
  return $this->templates['default'];
2799
  }
2800
-
2801
  /**
2802
  *
2803
  */
@@ -2805,17 +2805,19 @@ class Woo_Feed_Merchant {
2805
 
2806
  # Follow this common format($info) to add merchant info
2807
  // $info = array(
2808
- // "link" => "", # Merchant's feed specification url
2809
- // "doc" => array( # Plugin documentation for this merchant
2810
- // "link label"=>"link",
2811
  // "link label"=>"link"
2812
  // ),
2813
- // "video" => "", # Video tutorial to make feed for this merchant
2814
- // "feed_file_type" => array(), # Feed file type (XML or CSV or TXT). Can be multiple.
2815
  // );
2816
 
2817
  $merchant_info = array(
2818
- ##################### Google ############################
 
 
2819
  "google" => array(
2820
  "link" => "http://bit.ly/38kmDrl",
2821
  "video" => "https://youtu.be/PTUYgF7DwEo",
@@ -2827,11 +2829,10 @@ class Woo_Feed_Merchant {
2827
  "How to solve micro data error?" => "http://bit.ly/345nIQz",
2828
  "How to configure google product categories?" => "http://bit.ly/2RFWRrP",
2829
  ),
2830
- ),
2831
- "google_local" => "",
2832
- "google_local_inventory" => "",
2833
- "adwords" => "",
2834
- ##################### Facebook ############################
2835
  "facebook" => array(
2836
  "link" => "http://bit.ly/2P5cA1V",
2837
  "video" => "https://youtu.be/Wo3V_nf_eUU",
@@ -2839,141 +2840,116 @@ class Woo_Feed_Merchant {
2839
  "doc" => array(
2840
  "How to configure google product categories?" => "http://bit.ly/2RFWRrP",
2841
  ),
2842
- ),
2843
- ##################### Pinterest ############################
2844
  "pinterest" => array(
2845
  "link" => "http://bit.ly/35h6YXG",
2846
  "feed_file_type" => array( "XML", "CSV", "TXT" ),
2847
  "doc" => array(
2848
  "How to configure google product categories?" => "http://bit.ly/2RFWRrP",
2849
  ),
2850
- ),
2851
- ##################### Bing #############################
2852
  "bing" => array(
2853
  "link" => "http://bit.ly/33ZeuVS",
2854
  "feed_file_type" => array( "XML", "CSV", "TXT" ),
2855
- ),
2856
- ##################### PriceSpy #########################
2857
  "pricespy" => array(
2858
  "link" => "http://bit.ly/2t0rEFm",
2859
  "feed_file_type" => array( "TXT" ),
2860
- ),
2861
- ##################### Prisjakt ##########################
2862
  "prisjakt" => array(
2863
  "link" => "http://bit.ly/36iRT8a",
2864
  "feed_file_type" => array( "TXT" ),
2865
- ),
2866
- ##################### Idealo ############################
2867
  "idealo" => array(
2868
  "link" => "http://bit.ly/2LDgJI0",
2869
  "feed_file_type" => array( "CSV", "TXT" ),
2870
- ),
2871
- ##################### Yandex (CSV) ######################
2872
  "yandex_csv" => array(
2873
  "link" => "http://bit.ly/2t0tsy8",
2874
  "feed_file_type" => array( "CSV", "TXT" ),
2875
- ),
2876
- ##################### Yandex (XML) ######################
2877
  "yandex_xml" => array(
2878
  "link" => "http://bit.ly/2P3pFbH",
2879
  "feed_file_type" => array( "XML" ),
2880
- ),
2881
- ##################### Idealo ############################
2882
  "adroll" => array(
2883
  "link" => "http://bit.ly/2qzPtmt",
2884
  "feed_file_type" => array( "CSV", "XML" ),
2885
- ),
2886
- ##################### Idealo ############################
2887
  "adform" => array(
2888
  "link" => "http://bit.ly/2s6yatQ",
2889
  "feed_file_type" => array( "CSV", "XML" ),
2890
- ),
2891
- ##################### Kelkoo ###########################
2892
  "kelkoo" => array(
2893
  "link" => "http://bit.ly/2RAcqkL",
2894
  "feed_file_type" => array( "CSV", "XML" ),
2895
- ),
2896
- ##################### Shop Mania #######################
2897
  "shopmania" => array(
2898
  "link" => "http://bit.ly/38pE2PA",
2899
  "feed_file_type" => array( "CSV", "XML" ),
2900
- ),
2901
- ##################### Connexity ########################
2902
  "connexity" => array(
2903
  "link" => "http://bit.ly/36lPaLw",
2904
  "feed_file_type" => array( "TXT" ),
2905
- ),
2906
- ##################### Twenga ###########################
2907
  "twenga" => array(
2908
  "link" => "http://bit.ly/2RwTIud",
2909
  "feed_file_type" => array( "XML", "TXT" ),
2910
- ),
2911
- ##################### Fruugo ###########################
2912
  "fruugo" => array(
2913
  "link" => "http://bit.ly/2Yxabjn",
2914
  "feed_file_type" => array( "XML", "CSV" ),
2915
- ),
2916
- ##################### Fruugoaustralia ##################
2917
  "fruugo.au" => array(
2918
  "link" => "http://bit.ly/2Yxabjn",
2919
  "feed_file_type" => array( "XML", "CSV" ),
2920
- ),
2921
- ##################### Price Runner #####################
2922
  "pricerunner" => array(
2923
  "link" => "http://bit.ly/2Pznn3s",
2924
  "feed_file_type" => array( "XML", "CSV", "TXT" ),
2925
- ),
2926
- ##################### Bonanza ##########################
2927
  "bonanza" => array(
2928
  "link" => "http://bit.ly/2Rxi9aK",
2929
  "feed_file_type" => array( "CSV" ),
2930
- ),
2931
- ##################### Bol ##############################
2932
  "bol" => array(
2933
  "link" => "http://bit.ly/2P3MUCu",
2934
  "feed_file_type" => array( "XML", "CSV" ),
2935
- ),
2936
- ##################### Wish.com #########################
2937
  "wish" => array(
2938
  "link" => "http://bit.ly/348iYtc",
2939
  "feed_file_type" => array( "CSV" ),
2940
- ),
2941
- ##################### Myshopping.com.au ################
2942
  "myshopping.com.au" => array(
2943
  "link" => "http://bit.ly/2E6jugI",
2944
  "feed_file_type" => array( "CSV", "TXT", "XML" ),
2945
- ),
2946
- ##################### SkinFlint.co.uk ##################
2947
  "skinflint.co.uk" => array(
2948
  "link" => "http://bit.ly/2sg09qJ",
2949
  "feed_file_type" => array( "CSV" ),
2950
- ),
2951
- ##################### Yahoo NFA ########################
2952
  "yahoo_nfa" => array(
2953
  "link" => "http://bit.ly/2LCC58k",
2954
  "feed_file_type" => array( "CSV", "TXT", "XML" ),
2955
- ),
2956
- ##################### Comparer.be ######################
2957
  "comparer.be" => array(
2958
  "link" => "http://bit.ly/38xz2sa",
2959
  "feed_file_type" => array( "CSV", "XML" ),
2960
- ),
2961
- ##################### rakuten ###########################
2962
  "rakuten.de" => array(
2963
  "link" => "http://bit.ly/2YCDdym",
2964
  "feed_file_type" => array( "CSV", "TXT" ),
2965
- ),
2966
- ##################### Avantlink #########################
2967
  "avantlink" => array(
2968
  "link" => "http://bit.ly/2PuExPv",
2969
  "feed_file_type" => array( "CSV", "TXT", "XML" ),
2970
- ),
2971
- ##################### ShareASale ########################
2972
  "shareasale" => array(
2973
  "link" => "http://bit.ly/36uT1pF",
2974
  "feed_file_type" => array( "CSV", "TXT", "XML" ),
2975
- ),
2976
  );
 
2977
  return $merchant_info;
2978
  }
2979
 
@@ -2985,13 +2961,14 @@ class Woo_Feed_Merchant {
2985
  */
2986
  public function getInfo( $merchant = '' ) {
2987
  $infos = $this->merchantInfo();
2988
- $info = ( isset( $infos[ $merchant ] ) && ! empty( $infos[ $merchant ] ) ) ? $infos[ $merchant ] : [];
2989
  /**
2990
  * Filter single merchant data before retrieve
2991
  * @param array $info
2992
  * @param string $merchant
2993
  */
2994
  $info = apply_filters( 'woo_feed_merchant_info', $info, $merchant );
 
2995
  // ensure common data structure
2996
  return wp_parse_args( $info, [
2997
  'link' => '',
7
  */
8
 
9
  class Woo_Feed_Merchant {
10
+
11
  public $merchant;
12
  private $templates = array(
13
  'default' => array(
38
  'output_type' => array( '1', '1', '1', '1', '1', '1', '1', '1' ),
39
  'limit' => array( '', '', '', '', '', '', '', '' ),
40
  ),
41
+ 'bol' => array(
42
  'mattributes' => array(
43
  'EAN',
44
  'Internal Reference',
2778
  'limit' => array( '', '', '', '', '', '', '', '', '', '', '', '', '', '', '' ),
2779
  ),
2780
  );
2781
+
2782
  //adroll - smartly.io google
2783
  //admarkt custom 2
2784
+
2785
  public function __construct( $merchant = null ) {
2786
  $this->merchant = $merchant;
2787
  }
2788
+
2789
  public function get_merchant_template() {
2790
  if ( ! is_null( $this->merchant ) && array_key_exists( $this->merchant, $this->templates ) ) {
2791
  return $this->templates[ $this->merchant ];
2792
  }
2793
+
2794
  return false;
2795
  }
2796
+
2797
  public function get_default_template() {
2798
  return $this->templates['default'];
2799
  }
2800
+
2801
  /**
2802
  *
2803
  */
2805
 
2806
  # Follow this common format($info) to add merchant info
2807
  // $info = array(
2808
+ // 'link' => '', # Merchant's feed specification url
2809
+ // 'doc' => array( # Plugin documentation for this merchant
2810
+ // 'link label"=>"link',
2811
  // "link label"=>"link"
2812
  // ),
2813
+ // 'video' => '', # Video tutorial to make feed for this merchant
2814
+ // 'feed_file_type' => array(), # Feed file type (XML or CSV or TXT). Can be multiple.
2815
  // );
2816
 
2817
  $merchant_info = array(
2818
+
2819
+
2820
+
2821
  "google" => array(
2822
  "link" => "http://bit.ly/38kmDrl",
2823
  "video" => "https://youtu.be/PTUYgF7DwEo",
2829
  "How to solve micro data error?" => "http://bit.ly/345nIQz",
2830
  "How to configure google product categories?" => "http://bit.ly/2RFWRrP",
2831
  ),
2832
+ ), // Google.
2833
+ "google_local" => '',
2834
+ "google_local_inventory" => '',
2835
+ "adwords" => '',
 
2836
  "facebook" => array(
2837
  "link" => "http://bit.ly/2P5cA1V",
2838
  "video" => "https://youtu.be/Wo3V_nf_eUU",
2840
  "doc" => array(
2841
  "How to configure google product categories?" => "http://bit.ly/2RFWRrP",
2842
  ),
2843
+ ), // Facebook.
 
2844
  "pinterest" => array(
2845
  "link" => "http://bit.ly/35h6YXG",
2846
  "feed_file_type" => array( "XML", "CSV", "TXT" ),
2847
  "doc" => array(
2848
  "How to configure google product categories?" => "http://bit.ly/2RFWRrP",
2849
  ),
2850
+ ), // Pinterest.
 
2851
  "bing" => array(
2852
  "link" => "http://bit.ly/33ZeuVS",
2853
  "feed_file_type" => array( "XML", "CSV", "TXT" ),
2854
+ ), // Bing.
 
2855
  "pricespy" => array(
2856
  "link" => "http://bit.ly/2t0rEFm",
2857
  "feed_file_type" => array( "TXT" ),
2858
+ ), // PriceSpy.
 
2859
  "prisjakt" => array(
2860
  "link" => "http://bit.ly/36iRT8a",
2861
  "feed_file_type" => array( "TXT" ),
2862
+ ), // Prisjakt.
 
2863
  "idealo" => array(
2864
  "link" => "http://bit.ly/2LDgJI0",
2865
  "feed_file_type" => array( "CSV", "TXT" ),
2866
+ ), // Idealo.
 
2867
  "yandex_csv" => array(
2868
  "link" => "http://bit.ly/2t0tsy8",
2869
  "feed_file_type" => array( "CSV", "TXT" ),
2870
+ ), // Yandex (CSV).
 
2871
  "yandex_xml" => array(
2872
  "link" => "http://bit.ly/2P3pFbH",
2873
  "feed_file_type" => array( "XML" ),
2874
+ ), // Yandex (XML).
 
2875
  "adroll" => array(
2876
  "link" => "http://bit.ly/2qzPtmt",
2877
  "feed_file_type" => array( "CSV", "XML" ),
2878
+ ), // adroll
 
2879
  "adform" => array(
2880
  "link" => "http://bit.ly/2s6yatQ",
2881
  "feed_file_type" => array( "CSV", "XML" ),
2882
+ ), // adform
 
2883
  "kelkoo" => array(
2884
  "link" => "http://bit.ly/2RAcqkL",
2885
  "feed_file_type" => array( "CSV", "XML" ),
2886
+ ), // Kelkoo.
 
2887
  "shopmania" => array(
2888
  "link" => "http://bit.ly/38pE2PA",
2889
  "feed_file_type" => array( "CSV", "XML" ),
2890
+ ), // Shop Mania.
 
2891
  "connexity" => array(
2892
  "link" => "http://bit.ly/36lPaLw",
2893
  "feed_file_type" => array( "TXT" ),
2894
+ ), // Connexity.
 
2895
  "twenga" => array(
2896
  "link" => "http://bit.ly/2RwTIud",
2897
  "feed_file_type" => array( "XML", "TXT" ),
2898
+ ), // Twenga.
 
2899
  "fruugo" => array(
2900
  "link" => "http://bit.ly/2Yxabjn",
2901
  "feed_file_type" => array( "XML", "CSV" ),
2902
+ ), // Fruugo.
 
2903
  "fruugo.au" => array(
2904
  "link" => "http://bit.ly/2Yxabjn",
2905
  "feed_file_type" => array( "XML", "CSV" ),
2906
+ ), // Fruugo Australia.
 
2907
  "pricerunner" => array(
2908
  "link" => "http://bit.ly/2Pznn3s",
2909
  "feed_file_type" => array( "XML", "CSV", "TXT" ),
2910
+ ), // Price Runner.
 
2911
  "bonanza" => array(
2912
  "link" => "http://bit.ly/2Rxi9aK",
2913
  "feed_file_type" => array( "CSV" ),
2914
+ ), // Bonanza
 
2915
  "bol" => array(
2916
  "link" => "http://bit.ly/2P3MUCu",
2917
  "feed_file_type" => array( "XML", "CSV" ),
2918
+ ), // Bol.
 
2919
  "wish" => array(
2920
  "link" => "http://bit.ly/348iYtc",
2921
  "feed_file_type" => array( "CSV" ),
2922
+ ), // Wish.com.
 
2923
  "myshopping.com.au" => array(
2924
  "link" => "http://bit.ly/2E6jugI",
2925
  "feed_file_type" => array( "CSV", "TXT", "XML" ),
2926
+ ), // Myshopping.com.au.
 
2927
  "skinflint.co.uk" => array(
2928
  "link" => "http://bit.ly/2sg09qJ",
2929
  "feed_file_type" => array( "CSV" ),
2930
+ ), // SkinFlint.co.uk.
 
2931
  "yahoo_nfa" => array(
2932
  "link" => "http://bit.ly/2LCC58k",
2933
  "feed_file_type" => array( "CSV", "TXT", "XML" ),
2934
+ ), // Yahoo NFA.
 
2935
  "comparer.be" => array(
2936
  "link" => "http://bit.ly/38xz2sa",
2937
  "feed_file_type" => array( "CSV", "XML" ),
2938
+ ), // Comparer.be.
 
2939
  "rakuten.de" => array(
2940
  "link" => "http://bit.ly/2YCDdym",
2941
  "feed_file_type" => array( "CSV", "TXT" ),
2942
+ ), // rakuten.
 
2943
  "avantlink" => array(
2944
  "link" => "http://bit.ly/2PuExPv",
2945
  "feed_file_type" => array( "CSV", "TXT", "XML" ),
2946
+ ), // Avantlink
 
2947
  "shareasale" => array(
2948
  "link" => "http://bit.ly/36uT1pF",
2949
  "feed_file_type" => array( "CSV", "TXT", "XML" ),
2950
+ ), // ShareASale.
2951
  );
2952
+
2953
  return $merchant_info;
2954
  }
2955
 
2961
  */
2962
  public function getInfo( $merchant = '' ) {
2963
  $infos = $this->merchantInfo();
2964
+ $info = ( isset( $infos[ $merchant ] ) && ! empty( $infos[ $merchant ] ) ) ? $infos[ $merchant ] : [];
2965
  /**
2966
  * Filter single merchant data before retrieve
2967
  * @param array $info
2968
  * @param string $merchant
2969
  */
2970
  $info = apply_filters( 'woo_feed_merchant_info', $info, $merchant );
2971
+
2972
  // ensure common data structure
2973
  return wp_parse_args( $info, [
2974
  'link' => '',
includes/classes/class-woo-feed-products-v3.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
  /**
3
  * Created by PhpStorm.
4
  * User: wahid
@@ -14,6 +14,7 @@ class Woo_Feed_Products_v3 {
14
  private $enclosure;
15
  private $delimiter;
16
  private $config;
 
17
  public $products = [];
18
  private $queryType = 'wp';
19
  private $google_shipping_tax = array(
@@ -54,11 +55,13 @@ class Woo_Feed_Products_v3 {
54
  const PRODUCT_TAXONOMY_PREFIX = 'wf_taxo_';
55
 
56
  public function __construct( $config ) {
57
- $this->config = $config;
58
- $this->queryType = get_option('woo_feed_product_query_type');
59
- if ( empty($this->queryType) ) {
60
- $this->queryType = 'wc';
61
- }
 
 
62
  }
63
 
64
  /**
@@ -67,30 +70,23 @@ class Woo_Feed_Products_v3 {
67
  * @return array
68
  */
69
  public function get_wc_query_products() {
70
-
71
- # Query Arguments
72
  $arg = array(
73
  'limit' => 2e3,
74
- 'status' => 'publish',
75
  'orderby' => 'date',
76
  'order' => 'DESC',
77
  'return' => 'ids',
78
  );
79
-
80
-
81
- $types = array(
82
- 'simple',
83
- 'variable',
84
- 'grouped',
85
- 'external',
86
- );
87
-
88
- # Product Type
89
- $arg['type'] = $types;
90
  $query = new WC_Product_Query( $arg );
91
-
 
 
92
  return $query->get_products();
93
- #TODO Error Log
94
  }
95
 
96
  /**
@@ -99,9 +95,9 @@ class Woo_Feed_Products_v3 {
99
  * @return array
100
  */
101
  public function get_wp_query_products() {
102
- # Query Arguments
103
  $args = array(
104
- 'posts_per_page' => 2e3,
105
  'post_type' => 'product',
106
  'post_status' => 'publish',
107
  'order' => 'DESC',
@@ -112,27 +108,30 @@ class Woo_Feed_Products_v3 {
112
  );
113
 
114
  $query = new WP_Query( $args );
115
-
 
 
 
116
  return $query->get_posts();
117
- #TODO Error Log
118
  }
119
 
120
- /** Get products by limit and offset
 
121
  *
122
  * @return array|object
123
  */
124
  public function query_products() {
125
  $products = [];
126
- if ( $this->queryType == 'wc' ) {
127
- $products = $this->get_wc_query_products();
128
- }elseif ( $this->queryType == 'wp' ) {
129
- $products = $this->get_wp_query_products();
130
- }elseif ( $this->queryType == 'both' ) {
131
- $wc = $this->get_wc_query_products();
132
- $wp = $this->get_wp_query_products();
133
- $products = array_unique(array_merge($wc,$wp));
134
- }
135
- return $products;
136
  }
137
 
138
  /**
@@ -142,12 +141,12 @@ class Woo_Feed_Products_v3 {
142
  *
143
  * @param int[] $productIds
144
  *
145
- * @return []
146
  */
147
  public function get_products( $productIds ) {
148
 
149
  if ( empty( $productIds ) ) {
150
- return false;
151
  }
152
 
153
  /**
@@ -161,25 +160,28 @@ class Woo_Feed_Products_v3 {
161
  foreach ( $productIds as $key => $pid ) {
162
 
163
  $product = wc_get_product( $pid );
164
-
165
- # For WP_Query check available product types
166
- if ( $this->queryType == 'wp' ) {
167
  if ( ! in_array( $product->get_type(), $this->product_types ) ) {
 
168
  continue;
169
  }
170
  }
171
 
172
- # Skip for invalid products
173
  if ( ! is_object( $product ) ) {
 
174
  continue;
175
  }
176
 
177
- # Skip for invisible products
178
  if ( ! $product->is_visible() ) {
 
179
  continue;
180
  }
181
 
182
- # Apply variable and variation settings
183
  if ( $product->is_type( 'variable' ) && $product->has_child() ) {
184
  $this->pi ++;
185
  $variations = $product->get_visible_children();
@@ -187,50 +189,52 @@ class Woo_Feed_Products_v3 {
187
  $this->get_products( $variations );
188
  }
189
  }
190
-
191
-
192
- # Add Single item wrapper before product info loop start
193
- if ( $this->config['feedType'] == 'xml' ) {
194
  $this->feedBody .= "\n";
195
- $this->feedBody .= "<" . $this->config['itemWrapper'] . ">";
196
  $this->feedBody .= "\n";
197
  }
198
-
199
- # Unique Merchant Attributes
200
  $mAttributes = array();
201
- # Get Product Attribute values by type and assign to product array
202
  foreach ( $this->config['attributes'] as $attr_key => $attribute ) {
203
 
204
- # Continue for Google Shipping and Tax attributes
205
  $skipFor = array( 'google', 'facebook' );
206
- if ( $this->config['feedType'] == 'xml'
207
- && in_array( $this->config['mattributes'][ $attr_key ], $this->google_shipping_tax )
208
- && in_array( $this->config['provider'], $skipFor ) ) {
 
 
209
  continue;
210
  }
211
 
212
  if ( in_array( $this->config['mattributes'][ $attr_key ],$mAttributes ) ) {
213
  continue;
214
  }
215
-
216
- if ( $this->config['type'][ $attr_key ] == "pattern" ) {
217
  $attributeValue = $this->config['default'][ $attr_key ];
218
  } else { # Get Pattern value
219
  $attributeValue = $this->getAttributeValueByType($product, $attribute);
220
  }
221
 
222
- # Format Output according to Output Type config
223
  $outputType = $this->config['output_type'][ $attr_key ];
224
- if ( $outputType != "default" && ! empty($attributeValue) ) {
225
- $attributeValue = $this->format_output($attributeValue, $outputType);
226
  }
227
 
228
 
229
- # Limit Output
230
  $limit = $this->config['limit'][ $attr_key ];
231
  if ( ! empty($limit) && is_numeric($limit) ) {
232
  if ( strpos($attributeValue, "<![CDATA[") !== false ) {
233
- $attributeValue = str_replace(array( "<![CDATA[", "]]>" ), array( "", "" ), $attributeValue);
234
  $attributeValue = substr($attributeValue, 0, $limit);
235
  $attributeValue = '<![CDATA[' . $attributeValue . ']]>';
236
  } else {
@@ -238,56 +242,56 @@ class Woo_Feed_Products_v3 {
238
  }
239
  }
240
 
241
- # Add Prefix and Suffix into Output
242
  $prefix = $this->config['prefix'][ $attr_key ];
243
  $suffix = $this->config['suffix'][ $attr_key ];
244
 
245
 
246
- if ( $prefix != "" || $suffix != "" ) {
247
  $attributeValue = $this->process_prefix_suffix( $attributeValue, $prefix, $suffix, $attribute );
248
  }
249
 
250
  $pluginAttribute = $this->config['mattributes'][ $attr_key ];
251
  $merchant = $this->config['provider'];
252
  $feedType = $this->config['feedType'];
253
- if ( $this->config['feedType'] == 'xml' ) {
254
 
255
  # Replace XML Nodes according to merchant requirement
256
  $getReplacedAttribute = woo_feed_replace_to_merchant_attribute( $pluginAttribute, $merchant, $feedType );
257
 
258
  # XML does not support space in node. So replace Space with Underscore
259
- $getReplacedAttribute = str_replace( " ", "_", $getReplacedAttribute );
260
 
261
  if ( ! empty($attributeValue) ) {
262
  $attributeValue = trim($attributeValue);
263
  }
264
-
265
- # Add closing XML node if value is empty
266
- if ( $attributeValue != "" ) {
267
  # Add CDATA wrapper for XML feed to prevent XML error.
268
  $attributeValue = woo_feed_add_cdata( $pluginAttribute, $attributeValue, $merchant );
269
 
270
  #TODO Move to proper place
271
  # Replace Google Color attribute value according to requirements
272
- if ( $getReplacedAttribute == 'g:color' ) {
273
- $attributeValue = str_replace( ", ", "/", $attributeValue );
274
  }
275
 
276
  # Strip slash from output
277
  $attributeValue = stripslashes( $attributeValue );
278
-
279
- $this->feedBody .= "<" . $getReplacedAttribute . ">" . "$attributeValue" . "</" . $getReplacedAttribute . ">";
280
  $this->feedBody .= "\n";
281
 
282
  } else {
283
- $this->feedBody .= "<" . $getReplacedAttribute . "/>";
284
  $this->feedBody .= "\n";
285
  }
286
- } elseif ( $this->config['feedType'] == 'csv' ) {
287
  $pluginAttribute = woo_feed_replace_to_merchant_attribute( $pluginAttribute, $merchant, $feedType );
288
  $pluginAttribute = $this->processStringForCSV( $pluginAttribute );
289
  $attributeValue = $this->processStringForCSV( $attributeValue );
290
- } elseif ( $this->config['feedType'] == 'txt' ) {
291
  $pluginAttribute = woo_feed_replace_to_merchant_attribute( $pluginAttribute, $merchant, $feedType );
292
  $pluginAttribute = $this->processStringForTXT( $pluginAttribute );
293
  $attributeValue = $this->processStringForTXT( $attributeValue );
@@ -296,38 +300,45 @@ class Woo_Feed_Products_v3 {
296
  $mAttributes[ $attr_key ] = $this->config['mattributes'][ $attr_key ];
297
  $this->products[ $this->pi ][ $pluginAttribute ] = $attributeValue;
298
  }
299
-
 
 
 
300
  # Process feed data for uncommon merchant feed like Google,Facebook,Pinterest
301
  $this->process_for_merchant($product, $this->pi);
302
-
303
- if ( $this->config['feedType'] == 'xml' ) {
304
- if ( empty($this->feedHeader) ) {
 
 
 
 
 
305
  $this->feedHeader = $this->process_xml_feed_header();
306
  $this->feedFooter = $this->process_xml_feed_footer();
307
-
308
  }
309
-
310
- $this->feedBody .= "</" . $this->config['itemWrapper'] . ">";
311
-
312
-
313
- } elseif ( $this->config['feedType'] == 'txt' ) {
314
- if ( empty($this->feedHeader) ) {
315
  $this->process_txt_feed_header();
316
  }
317
  $this->process_txt_feed_body();
318
  } else {
319
- if ( empty($this->feedHeader) ) {
320
  $this->process_csv_feed_header();
321
  }
322
  $this->process_csv_feed_body();
323
  }
324
-
325
-
326
  $this->pi++;
327
  }
328
 
329
  /**
330
- * Fires before looping through request product for getting product data
331
  * @since 3.2.10
332
  * @param int[] $productIds
333
  * @param array $feedConfig
@@ -346,23 +357,19 @@ class Woo_Feed_Products_v3 {
346
  * @param $productObj WC_Product
347
  * @param $index | Product Index
348
  */
349
-
350
  private function process_for_merchant( $productObj, $index ) {
351
  $product = $this->products[ $index ];
352
  $merchantAttributes = $this->config['mattributes'];
353
-
354
- # Debug Here
355
- # echo "<pre>";print_r($product);print_r($merchantAttributes);die();
356
-
357
- # Format Shipping and Tax data for CSV and TXT feed only for google and facebook
358
- if ( $this->config['provider'] == 'google'
359
- || $this->config['provider'] == 'facebook'
360
- && $this->config['feedType'] != 'xml' ) {
361
-
362
- $shipping = array();
363
- $tax = array();
364
- $s = 0; // Shipping Index
365
- $t = 0; // Tax Index
366
  $shippingAttr = array(
367
  'shipping_country',
368
  'shipping_service',
@@ -375,137 +382,134 @@ class Woo_Feed_Products_v3 {
375
  );
376
  foreach ( $this->products[ $this->pi ] as $attribute => $value ) {
377
  if ( in_array($attribute, $shippingAttr) ) {
378
-
379
- if ( $attribute == "tax_country" ) {
380
  $t++;
381
- $tax[ $t ] .= $value . ":";
382
- } elseif ( $attribute == "tax_region" ) {
383
- $tax[ $t ] .= $value . ":";
384
- } elseif ( $attribute == "tax_rate" ) {
385
- $tax[ $t ] .= $value . ":";
386
- } elseif ( $attribute == "tax_ship" ) {
387
- $tax[ $t ] .= $value . ":";
388
  }
389
-
390
- if ( $attribute == "shipping_country" ) {
391
  $s++;
392
- $shipping[ $s ] .= $value . ":";
393
- } elseif ( $attribute == "shipping_service" ) {
394
- $shipping[ $s ] .= $value . ":";
395
- } elseif ( $attribute == "shipping_price" ) {
396
- $shipping[ $s ] .= $value . ":";
397
- } elseif ( $attribute == "shipping_region" ) {
398
- $shipping[ $s ] .= $value . ":";
399
  }
400
-
401
  unset($this->products[ $this->pi ][ $attribute ]);
402
  }
403
  }
404
-
405
  foreach ( $shipping as $key => $val ) {
406
  $this->products[ $this->pi ]['shipping(country:region:service:price)'] = $val;
407
  }
408
-
409
  foreach ( $tax as $key => $val ) {
410
  $this->products[ $this->pi ]['tax(country:region:rate:tax_ship)'] = $val;
411
  }
412
  }
413
-
414
- if ( $this->config['provider'] == 'google' ) {
415
-
416
- # Reformat Shipping attributes for google, facebook
417
  $s = 0;
418
  $t = 0;
419
- $tax = "";
420
- $shipping = "";
421
- if ( $this->config['feedType'] == 'xml' ) {
422
  foreach ( $merchantAttributes as $key => $value ) {
423
-
424
  if ( ! in_array($value, $this->google_shipping_tax) ) {
425
  continue;
426
  }
427
-
428
  $prefix = $this->config['prefix'][ $key ];
429
  $suffix = $this->config['suffix'][ $key ];
430
-
431
- if ( $this->config['type'][ $key ] == "pattern" ) {
432
  $output = $this->config['default'][ $key ];
433
- } else { # Get Pattern value
434
  $attribute = $this->config['attributes'][ $key ];
435
  $output = $this->getAttributeValueByType($productObj, $attribute);
436
  }
437
-
438
- if ( strpos($value, "price") !== false || strpos($value, "rate") !== false ) {
439
- $suffix = " " . $suffix;
440
  }
441
-
442
-
443
  $output = $prefix . $output . $suffix;
444
-
445
- if ( $value == "shipping_country" ) {
446
- if ( $s == 0 ) {
447
- $shipping .= "<g:shipping>";
448
- $s = 1;
449
- } else {
450
- $shipping .= "</g:shipping>" . "\n";
451
- $shipping .= "<g:shipping>";
452
- }
453
- }elseif ( ! in_array("shipping_country",$merchantAttributes) && $value == "shipping_price" ) {
454
- if ( $s == 0 ) {
455
- $shipping .= "<g:shipping>";
456
- $s = 1;
457
- } else {
458
- $shipping .= "</g:shipping>" . "\n";
459
- $shipping .= "<g:shipping>";
460
- }
461
- }
462
-
463
- if ( $value == "shipping_country" ) {
464
- $shipping .= "<g:country>" . $output . "</g:country>" . "\n";
465
- } elseif ( $value == "shipping_region" ) {
466
- $shipping .= "<g:region>" . $output . "</g:region>" . "\n";
467
- } elseif ( $value == "shipping_service" ) {
468
- $shipping .= "<g:service>" . $output . "</g:service>" . "\n";
469
- } elseif ( $value == "shipping_price" ) {
470
- $shipping .= "<g:price>" . $output . "</g:price>" . "\n";
471
- } elseif ( $value == "tax_country" ) {
472
- if ( $t == 0 ) {
473
- $tax .= "<g:tax>";
474
  $t = 1;
475
  } else {
476
- $tax .= "</g:tax>" . "\n";
477
- $tax .= "<g:tax>";
478
  }
479
- $tax .= "<g:country>" . $output . "</g:country>" . "\n";
480
- } elseif ( $value == "tax_region" ) {
481
- $tax .= "<g:region>" . $output . "</g:region>" . "\n";
482
- } elseif ( $value == "tax_rate" ) {
483
- $tax .= "<g:rate>" . $output . "</g:rate>" . "\n";
484
- } elseif ( $value == "tax_ship" ) {
485
- $tax .= "<g:tax_ship>" . $output . "</g:tax_ship>" . "\n";
486
  }
487
  }
488
-
489
- if ( $s == 1 ) {
490
- $shipping .= "</g:shipping>";
491
  }
492
- if ( $t == 1 ) {
493
- $tax .= "</g:tax>";
494
  }
495
-
496
  $this->feedBody .= $shipping;
497
  $this->feedBody .= $tax;
498
  }
499
- }
500
-
501
- # ADD g:identifier_exists
502
- if ( $this->config['provider'] == 'google' ) {
503
  $identifier = array( 'brand', 'upc', 'sku', 'mpn', 'gtin' );
504
  $countIdentifier = 0;
505
  if ( ! in_array('identifier_exists', $merchantAttributes) ) {
506
  if ( count(array_intersect_key(array_flip($identifier), $product)) >= 2 ) {
507
- # Any 2 required keys exist!
508
- //@TODO Refactor with OR
509
  if ( array_key_exists('brand', $product) && ! empty($product['brand']) ) {
510
  $countIdentifier++;
511
  }
@@ -520,10 +524,10 @@ class Woo_Feed_Products_v3 {
520
  }
521
  if ( array_key_exists('gtin', $product) && ! empty($product['gtin']) ) {
522
  $countIdentifier++;
523
- }
524
- }
525
-
526
- if ( $this->config['feedType'] == 'xml' ) {
527
  if ( $countIdentifier >= 2 ) {
528
  $this->feedBody .= "<g:identifier_exists>yes</g:identifier_exists>";
529
  } else {
@@ -539,7 +543,7 @@ class Woo_Feed_Products_v3 {
539
  }
540
  }
541
  }
542
-
543
  /**
544
  * Generate TXT Feed Header
545
  *
@@ -548,34 +552,34 @@ class Woo_Feed_Products_v3 {
548
  * @return string
549
  */
550
  private function process_txt_feed_header() {
551
- # Set Delimiter
552
- if ( $this->config['delimiter'] == 'tab' ) {
553
  $this->delimiter = "\t";
554
  } else {
555
  $this->delimiter = $this->config['delimiter'];
556
  }
557
-
558
- # Set Enclosure
559
- if ( ! empty($this->config['enclosure']) ) {
560
  $this->enclosure = $this->config['enclosure'];
561
- if ( $this->enclosure == 'double' ) {
562
  $this->enclosure = '"';
563
- } elseif ( $this->enclosure == 'single' ) {
564
  $this->enclosure = "'";
565
  } else {
566
- $this->enclosure = "";
567
  }
568
  } else {
569
- $this->enclosure = "";
570
  }
571
-
572
- $product = $this->products[ $this->pi ];
573
- $headers = array_keys($product);
574
- $this->feedHeader .= $this->enclosure . implode("$this->enclosure$this->delimiter$this->enclosure", $headers) . $this->enclosure . "\n";
575
-
576
  return $this->feedHeader;
577
  }
578
-
579
  /**
580
  * Generate TXT Feed Body
581
  *
@@ -584,13 +588,13 @@ class Woo_Feed_Products_v3 {
584
  * @return string
585
  */
586
  private function process_txt_feed_body() {
587
- $product = $this->products[ $this->pi ];
588
- $productInfo = array_values($product);
589
- $this->feedBody .= $this->enclosure . implode("$this->enclosure$this->delimiter$this->enclosure", $productInfo) . $this->enclosure . "\n";
590
-
591
  return $this->feedBody;
592
  }
593
-
594
  /**
595
  * Generate CSV Feed Header
596
  *
@@ -599,175 +603,172 @@ class Woo_Feed_Products_v3 {
599
  * @return array
600
  */
601
  private function process_csv_feed_header() {
602
- # Set Delimiter
603
- if ( $this->config['delimiter'] == 'tab' ) {
604
  $this->delimiter = "\t";
605
  } else {
606
  $this->delimiter = $this->config['delimiter'];
607
  }
608
-
609
- # Set Enclosure
610
- if ( ! empty($this->config['enclosure']) ) {
611
  $this->enclosure = $this->config['enclosure'];
612
- if ( $this->enclosure == 'double' ) {
613
  $this->enclosure = '"';
614
- } elseif ( $this->enclosure == 'single' ) {
615
  $this->enclosure = "'";
616
  } else {
617
- $this->enclosure = "";
618
  }
619
  } else {
620
- $this->enclosure = "";
621
  }
622
-
623
- $product = $this->products[ $this->pi ];
624
- $this->feedHeader = array_keys($product);
625
-
626
  return $this->feedHeader;
627
  }
628
-
629
  /**
630
  * Generate CSV Feed Body
631
  * @since 3.2.0
632
  * @return array
633
  */
634
  private function process_csv_feed_body() {
635
- $product = $this->products[ $this->pi ];
636
- $this->feedBody[] = array_values($product);
637
-
638
  return $this->feedBody;
639
  }
640
-
641
  /**
642
  * Make XML feed header
643
  * @since 3.2.0
644
  * @return string
645
  */
646
  private function process_xml_feed_header() {
647
- $datetime_now = date("Y-m-d H:i:s");
648
- if ( $this->config["provider"] == 'fruugo.au' ) {
649
- $fruugo_au = "<products version=\"1.0\" standalone=\"yes\">
650
- <datetime>$datetime_now</datetime>
651
- <title>" . get_bloginfo('name') . "</title>
652
- <link>" . get_bloginfo('url') . "</link>
653
- <description>" . get_bloginfo('description') . "</description>";
654
-
655
- return $fruugo_au;
656
- } elseif ( $this->config['provider'] == 'zap.co.il' ) {
657
- $zap = "<STORE>
658
- <datetime>$datetime_now</datetime>
659
- <title>" . get_bloginfo('name') . "</title>
660
- <link>" . get_bloginfo('url') . "</link>
661
- <description>" . get_bloginfo('description') . "</description>
662
- <agency>" . get_bloginfo('name') . "</agency>
663
- <email>" . get_bloginfo('admin_email') . "</email>";
664
-
665
- return $zap;
666
- } elseif ( $this->config['provider'] == 'myshopping.com.au' ) {
667
  return "<productset>";
668
- } elseif ( $this->config['provider'] == 'stylight.com' ) {
669
  return "<products version=\"1.0\" standalone=\"yes\">
670
- <datetime>$datetime_now</datetime>
671
- <title>" . get_bloginfo('name') . "</title>
672
- <link>" . get_bloginfo('url') . "</link>
673
- <description>" . get_bloginfo('description') . "</description>";
674
- } elseif ( $this->config['provider'] == 'nextad' ) {
675
  return "<products version=\"1.0\" standalone=\"yes\">
676
- <datetime>$datetime_now</datetime>
677
- <title>" . get_bloginfo('name') . "</title>
678
- <link>" . get_bloginfo('url') . "</link>
679
- <description>" . get_bloginfo('description') . "</description>";
680
- } elseif ( $this->config['provider'] == 'skinflint.co.uk' ) {
681
  return "<products version=\"1.0\" standalone=\"yes\">
682
- <datetime>$datetime_now</datetime>
683
- <title>" . get_bloginfo('name') . "</title>
684
- <link>" . get_bloginfo('url') . "</link>
685
- <description>" . get_bloginfo('description') . "</description>";
686
- } elseif ( $this->config['provider'] == 'comparer.be' ) {
687
  return "<products version=\"1.0\" standalone=\"yes\">
688
- <datetime>$datetime_now</datetime>
689
- <title>" . get_bloginfo('name') . "</title>
690
- <link>" . get_bloginfo('url') . "</link>
691
- <description>" . get_bloginfo('description') . "</description>";
692
- } elseif ( $this->config['provider'] == 'dooyoo' ) {
693
  return "<products version=\"1.0\" standalone=\"yes\">
694
- <datetime>$datetime_now</datetime>
695
- <title>" . get_bloginfo('name') . "</title>
696
- <link>" . get_bloginfo('url') . "</link>
697
- <description>" . get_bloginfo('description') . "</description>";
698
- } elseif ( $this->config['provider'] == 'hintaseuranta.fi' ) {
699
  return "<products version=\"1.0\" standalone=\"yes\">
700
- <datetime>$datetime_now</datetime>
701
- <title>" . get_bloginfo('name') . "</title>
702
- <link>" . get_bloginfo('url') . "</link>
703
- <description>" . get_bloginfo('description') . "</description>";
704
- } elseif ( $this->config['provider'] == 'incurvy' ) {
705
  return "<products version=\"1.0\" standalone=\"yes\">
706
- <datetime>$datetime_now</datetime>
707
- <title>" . get_bloginfo('name') . "</title>
708
- <link>" . get_bloginfo('url') . "</link>
709
- <description>" . get_bloginfo('description') . "</description>";
710
- } elseif ( $this->config['provider'] == 'kijiji.ca' ) {
711
  return "<products version=\"1.0\" standalone=\"yes\">
712
- <datetime>$datetime_now</datetime>
713
- <title>" . get_bloginfo('name') . "</title>
714
- <link>" . get_bloginfo('url') . "</link>
715
- <description>" . get_bloginfo('description') . "</description>";
716
- } elseif ( $this->config['provider'] == 'marktplaats.nl' ) {
717
  return "<products version=\"1.0\" standalone=\"yes\">
718
- <datetime>$datetime_now</datetime>
719
- <title>" . get_bloginfo('name') . "</title>
720
- <link>" . get_bloginfo('url') . "</link>
721
- <description>" . get_bloginfo('description') . "</description>";
722
- } elseif ( $this->config['provider'] == 'rakuten.de' ) {
723
  return "<products version=\"1.0\" standalone=\"yes\">
724
- <datetime>$datetime_now</datetime>
725
- <title>" . get_bloginfo('name') . "</title>
726
- <link>" . get_bloginfo('url') . "</link>
727
- <description>" . get_bloginfo('description') . "</description>";
728
- } elseif ( $this->config['provider'] == 'shopalike.fr' ) {
729
  return "<products version=\"1.0\" standalone=\"yes\">
730
- <datetime>$datetime_now</datetime>
731
- <title>" . get_bloginfo('name') . "</title>
732
- <link>" . get_bloginfo('url') . "</link>
733
- <description>" . get_bloginfo('description') . "</description>";
734
- } elseif ( $this->config['provider'] == 'spartoo.fi' ) {
735
  return "<products version=\"1.0\" standalone=\"yes\">
736
- <datetime>$datetime_now</datetime>
737
- <title>" . get_bloginfo('name') . "</title>
738
- <link>" . get_bloginfo('url') . "</link>
739
- <description>" . get_bloginfo('description') . "</description>";
740
- } elseif ( $this->config['provider'] == 'webmarchand' ) {
741
  return "<products version=\"1.0\" standalone=\"yes\">
742
- <datetime>$datetime_now</datetime>
743
- <title>" . get_bloginfo('name') . "</title>
744
- <link>" . get_bloginfo('url') . "</link>
745
- <description>" . get_bloginfo('description') . "</description>";
746
  } else {
747
- $wrapper = $this->config['itemsWrapper'];
748
- $extraHeader = isset( $this->config['extraHeader'] ) ? $this->config['extraHeader'] : '';
749
-
750
  $output = '<?xml version="1.0" encoding="UTF-8" ?>';
751
  $output .= "\n";
752
  $output .= '<' . $wrapper . '>';
753
-
754
  // $output .= "\n";
755
- if ( ! empty($extraHeader) ) {
756
- //$output .= $extraHeader;
757
- //$output .= "\n";
758
- }
759
-
760
  return $output;
761
  }
762
  }
763
-
764
  /**
765
  * Make XML feed header
766
  * @since 3.2.0
767
  * @return string
768
  */
769
  private function process_xml_feed_footer() {
770
- if ( in_array($this->config['provider'], [
771
  'fruugo.au',
772
  'stylight.com',
773
  'nextad',
@@ -782,21 +783,21 @@ class Woo_Feed_Products_v3 {
782
  'shopalike.fr',
783
  'spartoo.fi',
784
  'webmarchand',
785
- ]) ) {
786
- return "</products>";
787
- } elseif ( $this->config['provider'] == 'zap.co.il' ) {
788
- return "</STORE>";
789
- } elseif ( $this->config['provider'] == 'myshopping.com.au' ) {
790
- return "</productset>";
791
  } else {
792
  $wrapper = $this->config['itemsWrapper'];
793
- $footer = "\n";
794
- $footer .= "</$wrapper>";
795
-
796
  return $footer;
797
  }
798
  }
799
-
800
  /**
801
  * Process string for TXT CSV Feed
802
  * @since 3.2.0
@@ -806,26 +807,26 @@ class Woo_Feed_Products_v3 {
806
  * @return mixed|string
807
  */
808
  private function processStringForTXT( $string ) {
809
- if ( ! empty($string) ) {
810
- $string = html_entity_decode($string, ENT_HTML401 | ENT_QUOTES); // Convert any HTML entities
811
-
812
- if ( stristr($string, '"') ) {
813
- $string = str_replace('"', '""', $string);
814
  }
815
- $string = str_replace("\n", ' ', $string);
816
- $string = str_replace("\r", ' ', $string);
817
- $string = str_replace("\t", ' ', $string);
818
- $string = trim($string);
819
- $string = stripslashes($string);
820
-
821
  return $string;
822
- } elseif ( $string == "0" ) {
823
- return "0";
824
  } else {
825
- return "";
826
  }
827
  }
828
-
829
  /**
830
  * Process string for CSV
831
  * @since 3.2.0
@@ -835,20 +836,20 @@ class Woo_Feed_Products_v3 {
835
  * @return mixed|string
836
  */
837
  private function processStringForCSV( $string ) {
838
- if ( ! empty($string) ) {
839
- $string = str_replace("\n", ' ', $string);
840
- $string = str_replace("\r", ' ', $string);
841
- $string = trim($string);
842
- $string = stripslashes($string);
843
-
844
  return $string;
845
- } elseif ( $string == "0" ) {
846
- return "0";
847
  } else {
848
- return "";
849
  }
850
  }
851
-
852
  /**
853
  * Get Product Attribute Value by Type
854
  * @since 3.2.0
@@ -859,45 +860,29 @@ class Woo_Feed_Products_v3 {
859
  * @return mixed|string
860
  */
861
  public function getAttributeValueByType( $product, $attribute ) {
862
- # Set call_user_func_array parameters
863
- $params = array( $product );
864
- $method = array( $this, $attribute );
865
-
866
- if ( method_exists($this, $attribute) ) {
867
-
868
- return call_user_func_array($method, $params);
869
-
870
- } elseif ( strpos($attribute, self::PRODUCT_ATTRIBUTE_PREFIX) !== false ) {
871
-
872
- return $this->getProductAttribute($product, $attribute);
873
-
874
- } elseif ( strpos($attribute, self::POST_META_PREFIX) !== false ) {
875
-
876
- return $this->getProductMeta($product, $attribute);
877
-
878
- } elseif ( strpos($attribute, self::PRODUCT_TAXONOMY_PREFIX) !== false ) {
879
-
880
- return $this->getProductTaxonomy($product, $attribute);
881
-
882
- } elseif ( substr($attribute, 0, 6) == "image_" ) {
883
-
884
- # For additional image method images() will be used with extra parameter - image number
885
- $imageKey = explode("_", $attribute);
886
- $params[] = $imageKey[1];
887
- $attribute = "images";
888
- $method = array( $this, $attribute );
889
-
890
- return call_user_func_array($method, $params);
891
  } else {
892
  return $attribute;
893
  }
894
  }
895
-
896
-
897
  /**
898
  * Get Product Id
899
  *
900
- * @param WC_Product $product
901
  *
902
  * @since 3.2.0
903
  * @return mixed
@@ -917,7 +902,7 @@ class Woo_Feed_Products_v3 {
917
  private function title( $product ) {
918
  return $product->get_name();
919
  }
920
-
921
  /**
922
  * Get Yoast Product Title
923
  * @since 3.2.0
@@ -927,15 +912,15 @@ class Woo_Feed_Products_v3 {
927
  * @return mixed
928
  */
929
  private function yoast_wpseo_title( $product ) {
930
- $title = "";
931
- if ( class_exists('WPSEO_Frontend') ) {
932
- $title = WPSEO_Frontend::get_instance()->get_seo_title(get_post($product->get_id()));
933
  }
934
- if ( ! empty($title) ) {
935
  return $title;
936
  }
937
-
938
- return $this->title($product);
939
  }
940
 
941
  /**
@@ -950,11 +935,11 @@ class Woo_Feed_Products_v3 {
950
  $title = '';
951
  if ( class_exists( 'All_in_One_SEO_Pack' ) ) {
952
  global $aioseop_options, $aiosp;
953
- $selfLoadAIOSP = false;
954
- if ( ! is_array( $aioseop_options ) ) $aioseop_options = get_option( 'aioseop_options' );
 
955
  if ( ! ( $aiosp instanceof All_in_One_SEO_Pack ) ) {
956
- $aiosp = new All_in_One_SEO_Pack();
957
- $selfLoadAIOSP = true;
958
  }
959
 
960
  if ( in_array( 'product', $aioseop_options['aiosp_cpostactive'], true ) ) {
@@ -971,40 +956,40 @@ class Woo_Feed_Products_v3 {
971
 
972
  return $this->title( $product );
973
  }
974
-
975
  /**
976
  * Get Product Description
977
  * @since 3.2.0
978
  *
979
- * @param WC_Product $product
980
  *
981
  * @return mixed|string
982
  */
983
  private function description( $product ) {
984
-
985
  $description = $product->get_description();
986
-
987
- # Get Variation Description
988
- if ( $product->is_type('variation') && empty($description) ) {
989
- $parent = wc_get_product($product->get_parent_id());
990
  $description = $parent->get_description();
991
  }
992
- $description = $this->remove_short_codes($description);
993
-
994
- # Add variations attributes after description to prevent Facebook error
995
- if ( $this->config['provider'] == 'facebook' ) {
996
- $variationInfo = explode("-", $product->get_name());
997
- if ( isset($variationInfo[1]) ) {
998
  $extension = $variationInfo[1];
999
  } else {
1000
  $extension = $product->get_id();
1001
  }
1002
- $description .= " " . $extension;
1003
  }
1004
-
1005
  return $description;
1006
  }
1007
-
1008
  /**
1009
  * Get Yoast Product Description
1010
  * @since 3.2.0
@@ -1014,15 +999,15 @@ class Woo_Feed_Products_v3 {
1014
  * @return mixed
1015
  */
1016
  private function yoast_wpseo_metadesc( $product ) {
1017
- $description = "";
1018
- if ( class_exists('WPSEO_Frontend') ) {
1019
- $description = wpseo_replace_vars(WPSEO_Meta::get_value('metadesc', $product->get_id()), get_post($product->get_id()));
1020
  }
1021
- if ( ! empty($description) ) {
1022
  return $description;
1023
  }
1024
-
1025
- return $this->description($product);
1026
  }
1027
 
1028
  /**
@@ -1034,14 +1019,14 @@ class Woo_Feed_Products_v3 {
1034
  * @return mixed
1035
  */
1036
  private function _aioseop_description( $product ) {
1037
- $description = "";
1038
  if ( class_exists( 'All_in_One_SEO_Pack' ) ) {
1039
  global $aioseop_options, $aiosp;
1040
- $selfLoadAIOSP = false;
1041
- if ( ! is_array( $aioseop_options ) ) $aioseop_options = get_option( 'aioseop_options' );
 
1042
  if ( ! ( $aiosp instanceof All_in_One_SEO_Pack ) ) {
1043
- $aiosp = new All_in_One_SEO_Pack();
1044
- $selfLoadAIOSP = true;
1045
  }
1046
  if ( in_array( 'product', $aioseop_options['aiosp_cpostactive'], true ) ) {
1047
  $description = $aiosp->get_main_description( get_post( $product->get_id() ) ); // Get the description.
@@ -1055,7 +1040,7 @@ class Woo_Feed_Products_v3 {
1055
 
1056
  return $this->description( $product );
1057
  }
1058
-
1059
  /**
1060
  * Get Product Short Description
1061
  * @since 3.2.0
@@ -1065,22 +1050,22 @@ class Woo_Feed_Products_v3 {
1065
  * @return mixed|string
1066
  */
1067
  private function short_description( $product ) {
1068
-
1069
  $short_description = $product->get_short_description();
1070
-
1071
- # Get Variation Short Description
1072
- if ( $product->is_type('variation') && empty($short_description) ) {
1073
- $parent = wc_get_product($product->get_parent_id());
1074
  $short_description = $parent->get_short_description();
1075
  }
1076
-
1077
-
1078
- $short_description = $this->remove_short_codes($short_description);
1079
-
1080
  return $short_description;
1081
  }
1082
-
1083
-
1084
  /**
1085
  * At First convert Short Codes and then Remove failed Short Codes from String
1086
  * @since 3.2.0
@@ -1090,22 +1075,23 @@ class Woo_Feed_Products_v3 {
1090
  * @return mixed|string
1091
  */
1092
  private function remove_short_codes( $content ) {
1093
- if ( empty($content) ) {
1094
- return "";
1095
  }
1096
-
1097
- # Remove DIVI Builder Short Codes
1098
- if ( class_exists('ET_Builder_Module') || defined('ET_BUILDER_PLUGIN_VERSION') ) {
1099
- $content = preg_replace('/\[\/?et_pb.*?\]/', '', $content);
 
1100
  }
1101
-
1102
- $content = do_shortcode($content);
1103
-
1104
- $content = woo_feed_stripInvalidXml($content);
1105
-
1106
- return strip_shortcodes($content);
1107
  }
1108
-
1109
  /**
1110
  * Get Product Categories
1111
  * @since 3.2.0
@@ -1116,11 +1102,11 @@ class Woo_Feed_Products_v3 {
1116
  */
1117
  private function product_type( $product ) {
1118
  $id = $product->get_id();
1119
- if ( $product->is_type('variation') ) {
1120
  $id = $product->get_parent_id();
1121
  }
1122
-
1123
- return strip_tags(wc_get_product_category_list($id, ">", ""));
1124
  }
1125
 
1126
  /**
@@ -1144,97 +1130,78 @@ class Woo_Feed_Products_v3 {
1144
  * @return mixed
1145
  */
1146
  private function ex_link( $product ) {
1147
- if ( $product->is_type('external') ) {
1148
  return $product->get_product_url();
1149
  }
1150
 
1151
- return "";
1152
  }
1153
-
1154
  /**
1155
  * Get Product Image
1156
  * @since 3.2.0
1157
  *
1158
- * @param WC_Product $product
1159
  *
1160
  * @return mixed
1161
  */
1162
  private function image( $product ) {
1163
- $id = $product->get_id();
1164
- $image = "";
1165
- if ( $product->is_type('variation') ) {
1166
- $getImage = wp_get_attachment_image_src(get_post_thumbnail_id($id), 'single-post-thumbnail');
1167
- if ( has_post_thumbnail($id) && ! empty($getImage[0]) ) :
1168
- $image = woo_feed_get_formatted_url($getImage[0]);
1169
  else :
1170
- $getImage = wp_get_attachment_image_src(get_post_thumbnail_id($product->get_parent_id()), 'single-post-thumbnail');
1171
- $image = woo_feed_get_formatted_url($getImage[0]);
1172
  endif;
1173
  } else {
1174
- if ( has_post_thumbnail($id) ) :
1175
- $getImage = wp_get_attachment_image_src(get_post_thumbnail_id($id), 'single-post-thumbnail');
1176
- $image = woo_feed_get_formatted_url($getImage[0]);
1177
  else :
1178
- $image = woo_feed_get_formatted_url(wp_get_attachment_url($id));
1179
  endif;
1180
  }
1181
-
1182
  return $image;
1183
  }
1184
-
1185
  /**
1186
  * Get Product Featured Image
1187
  * @since 3.2.0
1188
  *
1189
- * @param WC_Product $product
1190
  *
1191
  * @return mixed
1192
  */
1193
  private function feature_image( $product ) {
1194
- $id = $product->get_id();
1195
- $feature_image = "";
1196
- if ( $product->is_type('variation') ) {
1197
- $getImage = wp_get_attachment_image_src(get_post_thumbnail_id($id), 'single-post-thumbnail');
1198
- if ( has_post_thumbnail($id) && ! empty($getImage[0]) ) :
1199
- $feature_image = woo_feed_get_formatted_url($getImage[0]);
1200
- else :
1201
- $getImage = wp_get_attachment_image_src(get_post_thumbnail_id($product->get_parent_id()), 'single-post-thumbnail');
1202
- $feature_image = woo_feed_get_formatted_url($getImage[0]);
1203
- endif;
1204
- } else {
1205
- if ( has_post_thumbnail($id) ) :
1206
- $getImage = wp_get_attachment_image_src(get_post_thumbnail_id($id), 'single-post-thumbnail');
1207
- $feature_image = woo_feed_get_formatted_url($getImage[0]);
1208
- else :
1209
- $feature_image = woo_feed_get_formatted_url(wp_get_attachment_url($id));
1210
- endif;
1211
- }
1212
-
1213
- return $feature_image;
1214
  }
1215
-
1216
  /**
1217
  * Get Comma Separated Product Images
1218
- * @since 3.2.0
1219
  *
1220
- * @param WC_Product $product
1221
- * @param $additionalImg | Specific Additional Image
1222
  *
1223
  * @return mixed
 
 
1224
  */
1225
- private function images( $product, $additionalImg = "" ) {
1226
- if ( $product->is_type( 'variation' ) ) { # TODO Test Variation Images
 
1227
  $imgUrls = $this->get_product_gallery( wc_get_product( $product->get_parent_id() ) );
1228
  } else {
1229
  $imgUrls = $this->get_product_gallery( $product );
1230
  }
1231
 
1232
- # Return Specific Additional Image URL
1233
- if ( $additionalImg != "" ) {
1234
  if ( array_key_exists( $additionalImg, $imgUrls ) ) {
1235
  return $imgUrls[ $additionalImg ];
1236
  } else {
1237
- return "";
1238
  }
1239
  }
1240
 
@@ -1245,7 +1212,7 @@ class Woo_Feed_Products_v3 {
1245
  * Get Product Gallery Items (URL) array.
1246
  * This can contains empty array values
1247
  * @since 3.2.6
1248
- * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite|WC_Product_Yith_Composite $product
1249
  * @return string[]
1250
  */
1251
  private function get_product_gallery( $product ) {
@@ -1260,7 +1227,7 @@ class Woo_Feed_Products_v3 {
1260
  }
1261
  return $imgUrls;
1262
  }
1263
-
1264
  /**
1265
  * Get Product Condition
1266
  * @since 3.2.0
@@ -1270,9 +1237,9 @@ class Woo_Feed_Products_v3 {
1270
  * @return mixed
1271
  */
1272
  private function condition( $product ) {
1273
- return "new";
1274
  }
1275
-
1276
  /**
1277
  * Get Product Type
1278
  * @since 3.2.0
@@ -1284,7 +1251,7 @@ class Woo_Feed_Products_v3 {
1284
  private function type( $product ) {
1285
  return $product->get_type();
1286
  }
1287
-
1288
  /**
1289
  * Get Product is a bundle product or not
1290
  * @since 3.2.0
@@ -1294,9 +1261,13 @@ class Woo_Feed_Products_v3 {
1294
  * @return mixed
1295
  */
1296
  private function is_bundle( $product ) {
1297
- return "no";
 
 
 
 
1298
  }
1299
-
1300
  /**
1301
  * Get Product is a multi-pack product or not
1302
  * @since 3.2.0
@@ -1306,14 +1277,14 @@ class Woo_Feed_Products_v3 {
1306
  * @return mixed
1307
  */
1308
  private function multipack( $product ) {
1309
- $multi_pack = "";
1310
- if ( $product->is_type('grouped') ) {
1311
- $multi_pack = ( ! empty($product->get_children())) ? count($product->get_children()) : "";
1312
  }
1313
-
1314
  return $multi_pack;
1315
  }
1316
-
1317
  /**
1318
  * Get Product visibility status
1319
  * @since 3.2.0
@@ -1325,7 +1296,7 @@ class Woo_Feed_Products_v3 {
1325
  private function visibility( $product ) {
1326
  return $product->get_catalog_visibility();
1327
  }
1328
-
1329
  /**
1330
  * Get Product Total Rating
1331
  * @since 3.2.0
@@ -1337,7 +1308,7 @@ class Woo_Feed_Products_v3 {
1337
  private function rating_total( $product ) {
1338
  return $product->get_rating_count();
1339
  }
1340
-
1341
  /**
1342
  * Get Product average rating
1343
  * @since 3.2.0
@@ -1349,7 +1320,7 @@ class Woo_Feed_Products_v3 {
1349
  private function rating_average( $product ) {
1350
  return $product->get_average_rating();
1351
  }
1352
-
1353
  /**
1354
  * Get Product tags
1355
  * @since 3.2.0
@@ -1360,19 +1331,19 @@ class Woo_Feed_Products_v3 {
1360
  */
1361
  private function tags( $product ) {
1362
  $id = $product->get_id();
1363
- if ( $product->is_type('variation') ) {
1364
  $id = $product->get_parent_id();
1365
  }
1366
-
1367
- $tags = get_the_term_list($id, "product_tag", "", ",", "");
1368
-
1369
- if ( ! empty($tags) ) {
1370
- return strip_tags($tags);
1371
  }
1372
-
1373
- return "";
1374
  }
1375
-
1376
  /**
1377
  * Get Product Parent Id
1378
  * @since 3.2.0
@@ -1383,13 +1354,13 @@ class Woo_Feed_Products_v3 {
1383
  */
1384
  private function item_group_id( $product ) {
1385
  $id = $product->get_id();
1386
- if ( $product->is_type('variation') ) {
1387
  $id = $product->get_parent_id();
1388
  }
1389
-
1390
  return $id;
1391
  }
1392
-
1393
  /**
1394
  * Get Product SKU
1395
  * @since 3.2.0
@@ -1401,7 +1372,7 @@ class Woo_Feed_Products_v3 {
1401
  private function sku( $product ) {
1402
  return $product->get_sku();
1403
  }
1404
-
1405
  /**
1406
  * Get Product Parent SKU
1407
  * @since 3.2.0
@@ -1411,16 +1382,16 @@ class Woo_Feed_Products_v3 {
1411
  * @return mixed
1412
  */
1413
  private function parent_sku( $product ) {
1414
- if ( $product->is_type('variation') ) {
1415
- $id = $product->get_parent_id();
1416
- $parent = wc_get_product($id);
1417
-
1418
  return $parent->get_sku();
1419
  }
1420
-
1421
  return $product->get_sku();
1422
  }
1423
-
1424
  /**
1425
  * Get Product Availability Status
1426
  * @since 3.2.0
@@ -1430,23 +1401,22 @@ class Woo_Feed_Products_v3 {
1430
  * @return mixed
1431
  */
1432
  private function availability( $product ) {
1433
- $id = $product->get_id();
1434
- $status = get_post_meta($id, '_stock_status', true);
1435
  if ( $status ) {
1436
- if ( $status == 'instock' ) {
1437
  return "in stock";
1438
- } elseif ( $status == 'outofstock' ) {
1439
  return "out of stock";
1440
- } elseif ( $status == 'onbackorder' ) {
1441
  return "on backorder";
1442
  } else {
1443
  return "in stock";
1444
  }
1445
  }
1446
-
1447
  return "in stock";
1448
  }
1449
-
1450
  /**
1451
  * Get Product Quantity
1452
  * @since 3.2.0
@@ -1456,33 +1426,33 @@ class Woo_Feed_Products_v3 {
1456
  * @return mixed
1457
  */
1458
  private function quantity( $product ) {
1459
- if ( $product->is_type('variable') && $product->has_child() ) {
1460
  $visible_children = $product->get_visible_children();
1461
- $qty = array();
1462
  foreach ( $visible_children as $key => $child ) {
1463
- $childQty = get_post_meta($child, '_stock', true);
1464
- $qty[] = (int)$childQty + 0;
1465
  }
1466
-
1467
- if ( isset($this->config['variable_quantity']) ) {
1468
  $vaQty = $this->config['variable_quantity'];
1469
- if ( $vaQty == "max" ) {
1470
- return max($qty);
1471
- } elseif ( $vaQty == "min" ) {
1472
- return min($qty);
1473
- } elseif ( $vaQty == "sum" ) {
1474
- return array_sum($qty);
1475
- } elseif ( $vaQty == "first" ) {
1476
- return ( (int)$qty[0]);
1477
  }
1478
-
1479
- return array_sum($qty);
1480
  }
1481
  }
1482
-
1483
  return $product->get_stock_quantity();
1484
  }
1485
-
1486
  /**
1487
  * Get Product Sale Price Start Date
1488
  * @since 3.2.0
@@ -1493,13 +1463,13 @@ class Woo_Feed_Products_v3 {
1493
  */
1494
  private function sale_price_sdate( $product ) {
1495
  $startDate = $product->get_date_on_sale_from();
1496
- if ( is_object($startDate) ) {
1497
  return $startDate->date_i18n();
1498
  }
1499
-
1500
- return "";
1501
  }
1502
-
1503
  /**
1504
  * Get Product Sale Price End Date
1505
  * @since 3.2.0
@@ -1510,30 +1480,30 @@ class Woo_Feed_Products_v3 {
1510
  */
1511
  private function sale_price_edate( $product ) {
1512
  $endDate = $product->get_date_on_sale_to();
1513
- if ( is_object($endDate) ) {
1514
  return $endDate->date_i18n();
1515
  }
1516
-
1517
- return "";
1518
  }
1519
-
1520
  /**
1521
  * Get Product Regular Price
1522
  * @since 3.2.0
1523
  *
1524
- * @param WC_Product|WC_Product_Grouped|WC_Product_Variable|WC_Product_Variation $product
1525
  *
1526
  * @return mixed
1527
  */
1528
  private function price( $product ) {
1529
  $price = $product->get_regular_price();
1530
  # Set variable product regular price according to setting
1531
- if ( $product->is_type('variable') ) {
1532
- $price = $this->getVariableProductPrice($product, 'regular_price');
1533
- } elseif ( $product->is_type('grouped') ) {
1534
- return $this->getGroupProductPrice($product, 'regular');
1535
  }
1536
-
1537
  return $price;
1538
  }
1539
 
@@ -1541,19 +1511,19 @@ class Woo_Feed_Products_v3 {
1541
  * Get Product Price
1542
  * @since 3.2.0
1543
  *
1544
- * @param WC_Product $product
1545
  *
1546
  * @return mixed
1547
  */
1548
  private function current_price( $product ) {
1549
  $price = $product->get_price();
1550
  # Set variable product current price according to setting
1551
- if ( $product->is_type('variable') ) {
1552
- $price = $this->getVariableProductPrice($product, 'price');
1553
- } elseif ( $product->is_type('grouped') ) {
1554
- return $this->getGroupProductPrice($product, 'current');
1555
  }
1556
-
1557
  return $price;
1558
  }
1559
 
@@ -1561,7 +1531,7 @@ class Woo_Feed_Products_v3 {
1561
  * Get Product Sale Price
1562
  * @since 3.2.0
1563
  *
1564
- * @param WC_Product $product
1565
  *
1566
  * @return mixed
1567
  */
@@ -1571,7 +1541,7 @@ class Woo_Feed_Products_v3 {
1571
  if ( $product->is_type('variable') ) {
1572
  $price = $this->getVariableProductPrice($product, 'sale_price');
1573
  } elseif ( $product->is_type('grouped') ) {
1574
- return $this->getGroupProductPrice($product, 'sale');
1575
  }
1576
 
1577
  return $price;
@@ -1579,11 +1549,12 @@ class Woo_Feed_Products_v3 {
1579
 
1580
  /**
1581
  * Get Product Regular Price with Tax
1582
- * @since 3.2.0
1583
  *
1584
- * @param WC_Product|WC_Product_Variable|WC_Product_Grouped|WC_Product_Composite $product Product Object.
1585
  *
1586
  * @return mixed
 
 
1587
  */
1588
  private function price_with_tax( $product ) {
1589
  $price = $this->price( $product );
@@ -1592,8 +1563,6 @@ class Woo_Feed_Products_v3 {
1592
  $price = $this->getVariableProductPrice( $product, 'regular_price' );
1593
  } elseif ( $product->is_type( 'grouped' ) ) {
1594
  return $this->getGroupProductPrice( $product, 'regular', true );
1595
- } elseif ( $product->is_type( 'composite' ) || $product->is_type( 'yith-composite' ) ) {
1596
- return $this->getCompositeProductPrice( $product, 'regular_price' );
1597
  }
1598
 
1599
  // Get price with tax.
@@ -1606,11 +1575,12 @@ class Woo_Feed_Products_v3 {
1606
 
1607
  /**
1608
  * Get Product Regular Price with Tax
1609
- * @since 3.2.0
1610
  *
1611
- * @param WC_Product|WC_Product_Variable|WC_Product_Grouped|WC_Product_Composite $product
1612
  *
1613
  * @return mixed
 
 
1614
  */
1615
  private function current_price_with_tax( $product ) {
1616
  $price = $this->current_price( $product );
@@ -1619,8 +1589,6 @@ class Woo_Feed_Products_v3 {
1619
  $price = $this->getVariableProductPrice( $product, 'current_price' );
1620
  } elseif ( $product->is_type( 'grouped' ) ) {
1621
  return $this->getGroupProductPrice( $product, 'current', true );
1622
- } elseif ( $product->is_type( 'composite' ) || $product->is_type( 'yith-composite' ) ) {
1623
- return $this->getCompositeProductPrice( $product, 'current_price' );
1624
  }
1625
 
1626
  // Get price with tax
@@ -1633,11 +1601,12 @@ class Woo_Feed_Products_v3 {
1633
 
1634
  /**
1635
  * Get Product Regular Price with Tax
1636
- * @since 3.2.0
1637
  *
1638
- * @param WC_Product|WC_Product_Variable|WC_Product_Grouped|WC_Product_Composite $product
1639
  *
1640
  * @return mixed
 
 
1641
  */
1642
  private function sale_price_with_tax( $product ) {
1643
  $price = $this->sale_price( $product );
@@ -1647,8 +1616,6 @@ class Woo_Feed_Products_v3 {
1647
  $price = $this->getVariableProductPrice( $product, 'sale_price' );
1648
  } elseif ( $product->is_type( 'grouped' ) ) {
1649
  return $this->getGroupProductPrice( $product, 'sale', true );
1650
- } elseif ( $product->is_type( 'composite' ) || $product->is_type( 'yith-composite' ) ) {
1651
- return $this->getCompositeProductPrice( $product, 'sale_price' );
1652
  }
1653
 
1654
  // Get price with tax
@@ -1658,72 +1625,72 @@ class Woo_Feed_Products_v3 {
1658
 
1659
  return $price;
1660
  }
1661
-
1662
  /**
1663
  * Get total price of grouped product
1664
  *
1665
- * @since 3.2.0
1666
- *
1667
  * @param WC_Product_Grouped $grouped
1668
  * @param string $type
1669
  * @param bool $tax
1670
  *
1671
  * @return int|string
 
 
1672
  */
1673
  private function getGroupProductPrice( $grouped, $type, $tax = false ) {
1674
  $groupProductIds = $grouped->get_children();
1675
- $sum = 0;
1676
- if ( ! empty($groupProductIds) ) {
1677
  foreach ( $groupProductIds as $id ) {
1678
- $product = wc_get_product($id);
1679
-
1680
- if ( ! is_object($product) ) {
1681
  continue; // make sure that the product exists..
1682
  }
1683
-
1684
  if ( $tax ) {
1685
- if ( $type == "regular" ) {
1686
- $regularPrice = $this->price_with_tax($product);
1687
- $sum += (float)$regularPrice;
1688
- } elseif ( $type == "current" ) {
1689
- $currentPrice = $this->current_price_with_tax($product);
1690
- $sum += (float)$currentPrice;
1691
  } else {
1692
- $salePrice = $this->sale_price_with_tax($product);
1693
- $sum += (float)$salePrice;
1694
  }
1695
  } else {
1696
- if ( $type == "regular" ) {
1697
- $regularPrice = $this->price($product);
1698
- $sum += (float)$regularPrice;
1699
- } elseif ( $type == "current" ) {
1700
- $currentPrice = $this->current_price($product);
1701
- $sum += (float)$currentPrice;
1702
  } else {
1703
- $salePrice = $this->sale_price($product);
1704
- $sum += (float)$salePrice;
1705
  }
1706
  }
1707
  }
1708
  }
1709
-
1710
  return $sum;
1711
  }
1712
-
1713
  /**
1714
  * Get total price of grouped product
1715
  *
1716
- * @since 3.2.0
1717
- *
1718
  * @param WC_Product|WC_Product_Variable $variable
1719
  * @param string $type regular_price, sale_price & current_price
1720
  *
1721
  * @return int|string
 
 
1722
  */
1723
  private function getVariableProductPrice( $variable, $type ) {
1724
- if ( $type == "regular_price" ) {
1725
  return $variable->get_variation_regular_price();
1726
- } elseif ( $type == "sale_price" ) {
1727
  return $variable->get_variation_sale_price();
1728
  } else {
1729
  return $variable->get_variation_price();
@@ -1732,12 +1699,13 @@ class Woo_Feed_Products_v3 {
1732
 
1733
  /**
1734
  * Return product price with tax
1735
- * @since 3.2.0
1736
  *
1737
- * @param WC_Product $product Product.
1738
- * @param float $price Price.
1739
  *
1740
  * @return float|string
 
 
1741
  */
1742
  public function get_price_with_tax( $product, $price ) {
1743
  if ( woo_feed_wc_version_check( 3.0 ) ) {
@@ -1851,8 +1819,8 @@ class Woo_Feed_Products_v3 {
1851
  */
1852
  private function date_created( $product ) {
1853
  $dateCreated = $product->get_date_created();
1854
-
1855
- return date("Y-m-d", strtotime($dateCreated));
1856
  }
1857
 
1858
  /**
@@ -1865,8 +1833,8 @@ class Woo_Feed_Products_v3 {
1865
  */
1866
  private function date_updated( $product ) {
1867
  $dateModified = $product->get_date_modified();
1868
-
1869
- return date("Y-m-d", strtotime($dateModified));
1870
  }
1871
 
1872
  /**
@@ -1878,13 +1846,13 @@ class Woo_Feed_Products_v3 {
1878
  * @return mixed
1879
  */
1880
  private function sale_price_effective_date( $product ) {
1881
- $sale_price_effective_date = "";
1882
  $from = $this->sale_price_sdate($product);
1883
  $to = $this->sale_price_edate($product);
1884
  if ( ! empty($from) && ! empty($to) ) {
1885
- $from = date("c", strtotime($from));
1886
- $to = date("c", strtotime($to));
1887
- $sale_price_effective_date = "$from" . "/" . "$to";
1888
  }
1889
 
1890
  return $sale_price_effective_date;
@@ -1902,11 +1870,11 @@ class Woo_Feed_Products_v3 {
1902
  */
1903
  public function getProductAttribute( $product, $attr ) {
1904
  $id = $product->get_id();
1905
- $attr = str_replace(self::PRODUCT_ATTRIBUTE_PREFIX, "", $attr);
1906
 
1907
  if ( woo_feed_wc_version_check(3.2) ) {
1908
  if ( woo_feed_wc_version_check(3.6) ) {
1909
- $attr = str_replace("pa_", "", $attr);
1910
  }
1911
  $value = $product->get_attribute($attr);
1912
 
@@ -1928,20 +1896,20 @@ class Woo_Feed_Products_v3 {
1928
  */
1929
  public function getProductMeta( $product, $meta ) {
1930
  $id = $product->get_id();
1931
- $meta = str_replace(self::POST_META_PREFIX, "", $meta);
1932
 
1933
  if ( strpos($meta, 'attribute_pa') !== false ) {
1934
- $productMeta = $this->getProductAttribute($product, str_replace("attribute_", "", $meta));
1935
  } else {
1936
  $productMeta = get_post_meta($id, $meta, true);
1937
  }
1938
 
1939
- //@TODO check pro version
1940
 
1941
- if ( $productMeta == "" ) {
1942
- $postParent = wp_get_post_parent_id($id);
1943
  if ( $postParent > 0 ) {
1944
- $productMeta = get_post_meta($postParent, $meta, true);
1945
  }
1946
  }
1947
 
@@ -1959,14 +1927,14 @@ class Woo_Feed_Products_v3 {
1959
  */
1960
  public function getProductTaxonomy( $product, $taxonomy ) {
1961
  $id = $product->get_id();
1962
- $taxonomy = str_replace(self::PRODUCT_TAXONOMY_PREFIX, "", $taxonomy);
1963
- $taxonomy_list = get_the_term_list($id, $taxonomy, "", ",", "");
1964
 
1965
  if ( ! empty($taxonomy_list) ) {
1966
- return strip_tags($taxonomy_list);
1967
  }
1968
 
1969
- return "";
1970
  }
1971
 
1972
  /**
@@ -1986,14 +1954,14 @@ class Woo_Feed_Products_v3 {
1986
 
1987
  if ( strpos($name, 'price') !== false ) {
1988
  if ( strpos($result, $plus) !== false && strpos($result, $percent) !== false ) {
1989
- $result = str_replace("+", "", $result);
1990
- $result = str_replace("%", "", $result);
1991
  if ( is_numeric($result) ) {
1992
  $result = $conditionName + (($conditionName * $result) / 100);
1993
  }
1994
  } elseif ( strpos($result, $minus) !== false && strpos($result, $percent) !== false ) {
1995
- $result = str_replace("-", "", $result);
1996
- $result = str_replace("%", "", $result);
1997
  if ( is_numeric($result) ) {
1998
  $result = $conditionName - (($conditionName * $result) / 100);
1999
  }
@@ -2026,8 +1994,8 @@ class Woo_Feed_Products_v3 {
2026
  if ( ! empty($outputTypes) && is_array($outputTypes) ) {
2027
 
2028
  # Format Output According to output type
2029
- if ( in_array(2, $outputTypes) ) { # Strip Tags
2030
- $output = strip_tags(html_entity_decode($output));
2031
  }
2032
 
2033
  if ( in_array(3, $outputTypes) ) { # UTF-8 Encode
@@ -2085,24 +2053,26 @@ class Woo_Feed_Products_v3 {
2085
  }
2086
 
2087
  # Add Prefix before Output
2088
- if ( $prefix != "" ) {
2089
  $output = "$prefix" . $output;
2090
  }
2091
 
2092
  # Add Suffix after Output
2093
- if ( $suffix != "" ) {
2094
- if ( $attribute == 'price'
2095
- || $attribute == 'sale_price'
2096
- || $attribute == 'current_price'
2097
- || $attribute == 'price_with_tax'
2098
- || $attribute == 'current_price_with_tax'
2099
- || $attribute == 'sale_price_with_tax'
2100
- || $attribute == 'shipping_price'
2101
- || $attribute == 'tax_rate' ) { # Add space before suffix if attribute contain price
2102
-
2103
- $output = $output . " " . $suffix;
2104
-
2105
- } elseif ( substr( $output, 0, 4 ) === "http" ) {
 
 
2106
 
2107
  # Parse URL Parameters if available into suffix field
2108
  $output = woo_feed_make_url_with_parameter( $output, $suffix );
1
+ <?php /** @noinspection PhpUnusedPrivateMethodInspection, PhpUnused, PhpUnusedLocalVariableInspection, DuplicatedCode */
2
  /**
3
  * Created by PhpStorm.
4
  * User: wahid
14
  private $enclosure;
15
  private $delimiter;
16
  private $config;
17
+ private $post_status = 'publish';
18
  public $products = [];
19
  private $queryType = 'wp';
20
  private $google_shipping_tax = array(
55
  const PRODUCT_TAXONOMY_PREFIX = 'wf_taxo_';
56
 
57
  public function __construct( $config ) {
58
+ $this->config = woo_feed_parse_feed_rules( $config );
59
+ $this->queryType = strtolower( get_option( 'woo_feed_product_query_type', 'wc' ) );
60
+ if ( ! in_array( $this->queryType, [ 'wc', 'wp', 'both' ] ) ) {
61
+ $this->queryType = 'wc';
62
+ }
63
+
64
+ // woo_feed_log_feed_process( $this->config['filename'], sprintf( 'Current Query Type is %s', $this->queryType ) );
65
  }
66
 
67
  /**
70
  * @return array
71
  */
72
  public function get_wc_query_products() {
73
+
74
+ // Query Arguments
75
  $arg = array(
76
  'limit' => 2e3,
77
+ 'status' => $this->post_status,
78
  'orderby' => 'date',
79
  'order' => 'DESC',
80
  'return' => 'ids',
81
  );
82
+
83
+ // Product Type
84
+ $arg['type'] = array( 'simple', 'variable', 'grouped', 'external' );
 
 
 
 
 
 
 
 
85
  $query = new WC_Product_Query( $arg );
86
+ // if( woo_feed_is_debugging_enabled() ) {
87
+ // woo_feed_log_feed_process( $this->config['filename'], sprintf( 'WC_Product_Query Args ::'.PHP_EOL.'%s', print_r( $arg, true ) ) );
88
+ // }
89
  return $query->get_products();
 
90
  }
91
 
92
  /**
95
  * @return array
96
  */
97
  public function get_wp_query_products() {
98
+ // Query Arguments
99
  $args = array(
100
+ 'posts_per_page' => 2e3, // phpcs:ignore
101
  'post_type' => 'product',
102
  'post_status' => 'publish',
103
  'order' => 'DESC',
108
  );
109
 
110
  $query = new WP_Query( $args );
111
+ // if( woo_feed_is_debugging_enabled() ) {
112
+ // woo_feed_log_feed_process( $this->config['filename'], sprintf( 'WP_Query Args ::'.PHP_EOL.'%s', print_r( $args, true ) ) );
113
+ // woo_feed_log_feed_process( $this->config['filename'], sprintf( 'WP_Query Request ::'.PHP_EOL.'%s', $query->request ) );
114
+ // }
115
  return $query->get_posts();
 
116
  }
117
 
118
+ /**
119
+ * Get products by limit and offset
120
  *
121
  * @return array|object
122
  */
123
  public function query_products() {
124
  $products = [];
125
+ if ( 'wc' == $this->queryType ) {
126
+ $products = $this->get_wc_query_products();
127
+ } elseif ( 'wp' == $this->queryType ) {
128
+ $products = $this->get_wp_query_products();
129
+ } elseif ( 'both' == $this->queryType ) {
130
+ $wc = $this->get_wc_query_products();
131
+ $wp = $this->get_wp_query_products();
132
+ $products = array_unique( array_merge( $wc, $wp ) );
133
+ }
134
+ return $products;
135
  }
136
 
137
  /**
141
  *
142
  * @param int[] $productIds
143
  *
144
+ * @return array
145
  */
146
  public function get_products( $productIds ) {
147
 
148
  if ( empty( $productIds ) ) {
149
+ return [];
150
  }
151
 
152
  /**
160
  foreach ( $productIds as $key => $pid ) {
161
 
162
  $product = wc_get_product( $pid );
163
+
164
+ // For WP_Query check available product types
165
+ if ( 'wp' == $this->queryType ) {
166
  if ( ! in_array( $product->get_type(), $this->product_types ) ) {
167
+ // woo_feed_log_feed_process( $this->config['filename'], sprintf( 'Skipping Product :: Invalid Post/Product Type : %s.', $product->get_type() ) );
168
  continue;
169
  }
170
  }
171
 
172
+ // Skip for invalid products
173
  if ( ! is_object( $product ) ) {
174
+ // woo_feed_log_feed_process( $this->config['filename'], 'Skipping Product :: Product data is not a valid WC_Product object.' );
175
  continue;
176
  }
177
 
178
+ // Skip for invisible products
179
  if ( ! $product->is_visible() ) {
180
+ // woo_feed_log_feed_process( $this->config['filename'], 'Skipping Product :: Product is not visible.' );
181
  continue;
182
  }
183
 
184
+ // Apply variable and variation settings
185
  if ( $product->is_type( 'variable' ) && $product->has_child() ) {
186
  $this->pi ++;
187
  $variations = $product->get_visible_children();
189
  $this->get_products( $variations );
190
  }
191
  }
192
+
193
+
194
+ // Add Single item wrapper before product info loop start
195
+ if ( 'xml' == $this->config['feedType'] ) {
196
  $this->feedBody .= "\n";
197
+ $this->feedBody .= '<' . $this->config['itemWrapper'] . '>';
198
  $this->feedBody .= "\n";
199
  }
200
+
201
+ // Unique Merchant Attributes
202
  $mAttributes = array();
203
+ // Get Product Attribute values by type and assign to product array
204
  foreach ( $this->config['attributes'] as $attr_key => $attribute ) {
205
 
206
+ // Continue for Google Shipping and Tax attributes
207
  $skipFor = array( 'google', 'facebook' );
208
+ if (
209
+ 'xml' == $this->config['feedType'] &&
210
+ in_array( $this->config['mattributes'][ $attr_key ], $this->google_shipping_tax ) &&
211
+ in_array( $this->config['provider'], $skipFor )
212
+ ) {
213
  continue;
214
  }
215
 
216
  if ( in_array( $this->config['mattributes'][ $attr_key ],$mAttributes ) ) {
217
  continue;
218
  }
219
+
220
+ if ( 'pattern' == $this->config['type'][ $attr_key ] ) {
221
  $attributeValue = $this->config['default'][ $attr_key ];
222
  } else { # Get Pattern value
223
  $attributeValue = $this->getAttributeValueByType($product, $attribute);
224
  }
225
 
226
+ // Format Output according to Output Type config.
227
  $outputType = $this->config['output_type'][ $attr_key ];
228
+ if ( 'default' != $outputType ) {
229
+ $attributeValue = $this->format_output( $attributeValue, $outputType );
230
  }
231
 
232
 
233
+ // Limit Output
234
  $limit = $this->config['limit'][ $attr_key ];
235
  if ( ! empty($limit) && is_numeric($limit) ) {
236
  if ( strpos($attributeValue, "<![CDATA[") !== false ) {
237
+ $attributeValue = str_replace(array( "<![CDATA[", "]]>" ), array( '', '' ), $attributeValue);
238
  $attributeValue = substr($attributeValue, 0, $limit);
239
  $attributeValue = '<![CDATA[' . $attributeValue . ']]>';
240
  } else {
242
  }
243
  }
244
 
245
+ // Add Prefix and Suffix into Output
246
  $prefix = $this->config['prefix'][ $attr_key ];
247
  $suffix = $this->config['suffix'][ $attr_key ];
248
 
249
 
250
+ if ( '' != $prefix || '' != $suffix ) {
251
  $attributeValue = $this->process_prefix_suffix( $attributeValue, $prefix, $suffix, $attribute );
252
  }
253
 
254
  $pluginAttribute = $this->config['mattributes'][ $attr_key ];
255
  $merchant = $this->config['provider'];
256
  $feedType = $this->config['feedType'];
257
+ if ( 'xml' == $this->config['feedType'] ) {
258
 
259
  # Replace XML Nodes according to merchant requirement
260
  $getReplacedAttribute = woo_feed_replace_to_merchant_attribute( $pluginAttribute, $merchant, $feedType );
261
 
262
  # XML does not support space in node. So replace Space with Underscore
263
+ $getReplacedAttribute = str_replace( '', '_', $getReplacedAttribute );
264
 
265
  if ( ! empty($attributeValue) ) {
266
  $attributeValue = trim($attributeValue);
267
  }
268
+
269
+ // Add closing XML node if value is empty
270
+ if ( '' != $attributeValue ) {
271
  # Add CDATA wrapper for XML feed to prevent XML error.
272
  $attributeValue = woo_feed_add_cdata( $pluginAttribute, $attributeValue, $merchant );
273
 
274
  #TODO Move to proper place
275
  # Replace Google Color attribute value according to requirements
276
+ if ( 'g:color' == $getReplacedAttribute ) {
277
+ $attributeValue = str_replace( ', ', '/', $attributeValue );
278
  }
279
 
280
  # Strip slash from output
281
  $attributeValue = stripslashes( $attributeValue );
282
+
283
+ $this->feedBody .= '<' . $getReplacedAttribute . '>' . "$attributeValue" . '</' . $getReplacedAttribute . '>';
284
  $this->feedBody .= "\n";
285
 
286
  } else {
287
+ $this->feedBody .= '<' . $getReplacedAttribute . '/>';
288
  $this->feedBody .= "\n";
289
  }
290
+ } elseif ( 'csv' == $this->config['feedType'] ) {
291
  $pluginAttribute = woo_feed_replace_to_merchant_attribute( $pluginAttribute, $merchant, $feedType );
292
  $pluginAttribute = $this->processStringForCSV( $pluginAttribute );
293
  $attributeValue = $this->processStringForCSV( $attributeValue );
294
+ } elseif ( 'txt' == $this->config['feedType'] ) {
295
  $pluginAttribute = woo_feed_replace_to_merchant_attribute( $pluginAttribute, $merchant, $feedType );
296
  $pluginAttribute = $this->processStringForTXT( $pluginAttribute );
297
  $attributeValue = $this->processStringForTXT( $attributeValue );
300
  $mAttributes[ $attr_key ] = $this->config['mattributes'][ $attr_key ];
301
  $this->products[ $this->pi ][ $pluginAttribute ] = $attributeValue;
302
  }
303
+
304
+ // try {
305
+ // woo_feed_log_feed_process( $this->config['filename'], 'Processing Merchant Specific Fields' );
306
+ // Process feed data for uncommon merchant feed like Google,Facebook,Pinterest
307
  # Process feed data for uncommon merchant feed like Google,Facebook,Pinterest
308
  $this->process_for_merchant($product, $this->pi);
309
+ // } catch ( Exception $e ) {
310
+ // $message = 'Error Processing Merchant Specific Fields.' . PHP_EOL . 'Caught Exception :: ' . $e->getMessage();
311
+ // woo_feed_log( $this->config['filename'], $message, 'critical', $e, true );
312
+ // woo_feed_log_fatal_error( $message, $e );
313
+ // }
314
+
315
+ if ( 'xml' == $this->config['feedType'] ) {
316
+ if ( empty( $this->feedHeader ) ) {
317
  $this->feedHeader = $this->process_xml_feed_header();
318
  $this->feedFooter = $this->process_xml_feed_footer();
319
+
320
  }
321
+
322
+ $this->feedBody .= '</' . $this->config['itemWrapper'] . '>';
323
+
324
+
325
+ } elseif ( 'txt' == $this->config['feedType'] ) {
326
+ if ( empty( $this->feedHeader ) ) {
327
  $this->process_txt_feed_header();
328
  }
329
  $this->process_txt_feed_body();
330
  } else {
331
+ if ( empty( $this->feedHeader ) ) {
332
  $this->process_csv_feed_header();
333
  }
334
  $this->process_csv_feed_body();
335
  }
336
+ // woo_feed_log_feed_process( $this->config['filename'], 'Done Formatting...' );
 
337
  $this->pi++;
338
  }
339
 
340
  /**
341
+ * Fires after looping through request product for getting product data
342
  * @since 3.2.10
343
  * @param int[] $productIds
344
  * @param array $feedConfig
357
  * @param $productObj WC_Product
358
  * @param $index | Product Index
359
  */
 
360
  private function process_for_merchant( $productObj, $index ) {
361
  $product = $this->products[ $index ];
362
  $merchantAttributes = $this->config['mattributes'];
363
+
364
+ // Format Shipping and Tax data for CSV and TXT feed only for google and facebook
365
+ if ( 'xml' != $this->config['feedType'] && in_array( $this->config['provider'], [ 'google', 'facebook' ] ) ) {
366
+
367
+ $shipping = array();
368
+ $tax = array();
369
+ $installment = array();
370
+ $s = 0; // Shipping Index
371
+ $t = 0; // Tax Index
372
+ $i = 0; // Installment Index
 
 
 
373
  $shippingAttr = array(
374
  'shipping_country',
375
  'shipping_service',
382
  );
383
  foreach ( $this->products[ $this->pi ] as $attribute => $value ) {
384
  if ( in_array($attribute, $shippingAttr) ) {
385
+
386
+ if ( 'tax_country' == $attribute ) {
387
  $t++;
388
+ $tax[ $t ] .= $value . ':';
389
+ } elseif ( 'tax_region' == $attribute ) {
390
+ $tax[ $t ] .= $value . ':';
391
+ } elseif ( 'tax_rate' == $attribute ) {
392
+ $tax[ $t ] .= $value . ':';
393
+ } elseif ( 'tax_ship' == $attribute ) {
394
+ $tax[ $t ] .= $value . ':';
395
  }
396
+
397
+ if ( 'shipping_country' == $attribute ) {
398
  $s++;
399
+ $shipping[ $s ] .= $value . ':';
400
+ } elseif ( 'shipping_service' == $attribute ) {
401
+ $shipping[ $s ] .= $value . ':';
402
+ } elseif ( 'shipping_price' == $attribute ) {
403
+ $shipping[ $s ] .= $value . ':';
404
+ } elseif ( 'shipping_region' == $attribute ) {
405
+ $shipping[ $s ] .= $value . ':';
406
  }
407
+
408
  unset($this->products[ $this->pi ][ $attribute ]);
409
  }
410
  }
411
+
412
  foreach ( $shipping as $key => $val ) {
413
  $this->products[ $this->pi ]['shipping(country:region:service:price)'] = $val;
414
  }
415
+
416
  foreach ( $tax as $key => $val ) {
417
  $this->products[ $this->pi ]['tax(country:region:rate:tax_ship)'] = $val;
418
  }
419
  }
420
+
421
+ if ( 'google' == $this->config['provider'] ) {
422
+
423
+ // Reformat Shipping attributes for google, facebook
424
  $s = 0;
425
  $t = 0;
426
+ $tax = '';
427
+ $shipping = '';
428
+ if ( 'xml' == $this->config['feedType'] ) {
429
  foreach ( $merchantAttributes as $key => $value ) {
430
+
431
  if ( ! in_array($value, $this->google_shipping_tax) ) {
432
  continue;
433
  }
434
+
435
  $prefix = $this->config['prefix'][ $key ];
436
  $suffix = $this->config['suffix'][ $key ];
437
+
438
+ if ( 'pattern' == $this->config['type'][ $key ] ) {
439
  $output = $this->config['default'][ $key ];
440
+ } else { // Get Pattern value.
441
  $attribute = $this->config['attributes'][ $key ];
442
  $output = $this->getAttributeValueByType($productObj, $attribute);
443
  }
444
+
445
+ if ( false !== strpos( $value, 'price' ) || false !== strpos( $value, 'rate' ) ) {
446
+ $suffix = '' . $suffix;
447
  }
448
+
449
+
450
  $output = $prefix . $output . $suffix;
451
+
452
+ if ( 'shipping_country' == $value ) {
453
+ if ( 0 == $s ) {
454
+ $shipping .= '<g:shipping>';
455
+ $s = 1;
456
+ } else {
457
+ $shipping .= '</g:shipping>' . "\n";
458
+ $shipping .= '<g:shipping>';
459
+ }
460
+ } elseif ( ! in_array('shipping_country',$merchantAttributes) && 'shipping_price' == $value ) {
461
+ if ( 0 == $s ) {
462
+ $shipping .= '<g:shipping>';
463
+ $s = 1;
464
+ } else {
465
+ $shipping .= '</g:shipping>' . "\n";
466
+ $shipping .= '<g:shipping>';
467
+ }
468
+ }
469
+
470
+ if ( 'shipping_country' == $value ) {
471
+ $shipping .= '<g:country>' . $output . '</g:country>' . "\n";
472
+ } elseif ( 'shipping_region' == $value ) {
473
+ $shipping .= '<g:region>' . $output . '</g:region>' . "\n";
474
+ } elseif ( 'shipping_service' == $value ) {
475
+ $shipping .= '<g:service>' . $output . '</g:service>' . "\n";
476
+ } elseif ( 'shipping_price' == $value ) {
477
+ $shipping .= '<g:price>' . $output . '</g:price>' . "\n";
478
+ } elseif ( 'tax_country' == $value ) {
479
+ if ( 0 == $t ) {
480
+ $tax .= '<g:tax>';
481
  $t = 1;
482
  } else {
483
+ $tax .= '</g:tax>' . "\n";
484
+ $tax .= '<g:tax>';
485
  }
486
+ $tax .= '<g:country>' . $output . '</g:country>' . "\n";
487
+ } elseif ( 'tax_region' == $value ) {
488
+ $tax .= '<g:region>' . $output . '</g:region>' . "\n";
489
+ } elseif ( 'tax_rate' == $value ) {
490
+ $tax .= '<g:rate>' . $output . '</g:rate>' . "\n";
491
+ } elseif ( 'tax_ship' == $value ) {
492
+ $tax .= '<g:tax_ship>' . $output . '</g:tax_ship>' . "\n";
493
  }
494
  }
495
+
496
+ if ( 1 == $s ) {
497
+ $shipping .= '</g:shipping>';
498
  }
499
+ if ( 1 == $t ) {
500
+ $tax .= '</g:tax>';
501
  }
502
+
503
  $this->feedBody .= $shipping;
504
  $this->feedBody .= $tax;
505
  }
506
+ // ADD g:identifier_exists
 
 
 
507
  $identifier = array( 'brand', 'upc', 'sku', 'mpn', 'gtin' );
508
  $countIdentifier = 0;
509
  if ( ! in_array('identifier_exists', $merchantAttributes) ) {
510
  if ( count(array_intersect_key(array_flip($identifier), $product)) >= 2 ) {
511
+ // Any 2 required keys exist!
512
+ // @TODO Refactor with OR
513
  if ( array_key_exists('brand', $product) && ! empty($product['brand']) ) {
514
  $countIdentifier++;
515
  }
524
  }
525
  if ( array_key_exists('gtin', $product) && ! empty($product['gtin']) ) {
526
  $countIdentifier++;
527
+ }
528
+ }
529
+
530
+ if ( 'xml' == $this->config['feedType'] ) {
531
  if ( $countIdentifier >= 2 ) {
532
  $this->feedBody .= "<g:identifier_exists>yes</g:identifier_exists>";
533
  } else {
543
  }
544
  }
545
  }
546
+
547
  /**
548
  * Generate TXT Feed Header
549
  *
552
  * @return string
553
  */
554
  private function process_txt_feed_header() {
555
+ // Set Delimiter
556
+ if ( 'tab' == $this->config['delimiter'] ) {
557
  $this->delimiter = "\t";
558
  } else {
559
  $this->delimiter = $this->config['delimiter'];
560
  }
561
+
562
+ // Set Enclosure
563
+ if ( ! empty( $this->config['enclosure'] ) ) {
564
  $this->enclosure = $this->config['enclosure'];
565
+ if ( 'double' == $this->enclosure ) {
566
  $this->enclosure = '"';
567
+ } elseif ( 'single' == $this->enclosure ) {
568
  $this->enclosure = "'";
569
  } else {
570
+ $this->enclosure = '';
571
  }
572
  } else {
573
+ $this->enclosure = '';
574
  }
575
+
576
+ $product = $this->products[ $this->pi ];
577
+ $headers = array_keys( $product );
578
+ $this->feedHeader .= $this->enclosure . implode( "$this->enclosure$this->delimiter$this->enclosure", $headers ) . $this->enclosure . "\n";
579
+
580
  return $this->feedHeader;
581
  }
582
+
583
  /**
584
  * Generate TXT Feed Body
585
  *
588
  * @return string
589
  */
590
  private function process_txt_feed_body() {
591
+ $product = $this->products[ $this->pi ];
592
+ $productInfo = array_values( $product );
593
+ $this->feedBody .= $this->enclosure . implode( "$this->enclosure$this->delimiter$this->enclosure", $productInfo ) . $this->enclosure . "\n";
594
+
595
  return $this->feedBody;
596
  }
597
+
598
  /**
599
  * Generate CSV Feed Header
600
  *
603
  * @return array
604
  */
605
  private function process_csv_feed_header() {
606
+ // Set Delimiter
607
+ if ( 'tab' == $this->config['delimiter'] ) {
608
  $this->delimiter = "\t";
609
  } else {
610
  $this->delimiter = $this->config['delimiter'];
611
  }
612
+
613
+ // Set Enclosure
614
+ if ( ! empty( $this->config['enclosure'] ) ) {
615
  $this->enclosure = $this->config['enclosure'];
616
+ if ( 'double' == $this->enclosure ) {
617
  $this->enclosure = '"';
618
+ } elseif ( 'single' == $this->enclosure ) {
619
  $this->enclosure = "'";
620
  } else {
621
+ $this->enclosure = '';
622
  }
623
  } else {
624
+ $this->enclosure = '';
625
  }
626
+
627
+ $product = $this->products[ $this->pi ];
628
+ $this->feedHeader = array_keys( $product );
629
+
630
  return $this->feedHeader;
631
  }
632
+
633
  /**
634
  * Generate CSV Feed Body
635
  * @since 3.2.0
636
  * @return array
637
  */
638
  private function process_csv_feed_body() {
639
+ $product = $this->products[ $this->pi ];
640
+ $this->feedBody[] = array_values( $product );
641
+
642
  return $this->feedBody;
643
  }
644
+
645
  /**
646
  * Make XML feed header
647
  * @since 3.2.0
648
  * @return string
649
  */
650
  private function process_xml_feed_header() {
651
+ $datetime_now = gmdate( "Y-m-d H:i:s" );
652
+ if ( 'fruugo.au' == $this->config["provider"] ) {
653
+ return "<products version=\"1.0\" standalone=\"yes\">
654
+ <datetime>$datetime_now</datetime>
655
+ <title>" . get_bloginfo( 'name' ) . "</title>
656
+ <link>" . get_bloginfo( 'url' ) . "</link>
657
+ <description>" . get_bloginfo( 'description' ) . "</description>";
658
+ } elseif ( 'zap.co.il' == $this->config['provider'] ) {
659
+ return "<STORE>
660
+ <datetime>$datetime_now</datetime>
661
+ <title>" . get_bloginfo( 'name' ) . "</title>
662
+ <link>" . get_bloginfo( 'url' ) . "</link>
663
+ <description>" . get_bloginfo( 'description' ) . "</description>
664
+ <agency>" . get_bloginfo( 'name' ) . "</agency>
665
+ <email>" . get_bloginfo( 'admin_email' ) . "</email>";
666
+
667
+ } elseif ( 'myshopping.com.au' == $this->config['provider'] ) {
 
 
 
668
  return "<productset>";
669
+ } elseif ( 'stylight.com' == $this->config['provider'] ) {
670
  return "<products version=\"1.0\" standalone=\"yes\">
671
+ <datetime>$datetime_now</datetime>
672
+ <title>" . get_bloginfo( 'name' ) . "</title>
673
+ <link>" . get_bloginfo( 'url' ) . "</link>
674
+ <description>" . get_bloginfo( 'description' ) . "</description>";
675
+ } elseif ( 'nextad' == $this->config['provider'] ) {
676
  return "<products version=\"1.0\" standalone=\"yes\">
677
+ <datetime>$datetime_now</datetime>
678
+ <title>" . get_bloginfo( 'name' ) . "</title>
679
+ <link>" . get_bloginfo( 'url' ) . "</link>
680
+ <description>" . get_bloginfo( 'description' ) . "</description>";
681
+ } elseif ( 'skinflint.co.uk' == $this->config['provider'] ) {
682
  return "<products version=\"1.0\" standalone=\"yes\">
683
+ <datetime>$datetime_now</datetime>
684
+ <title>" . get_bloginfo( 'name' ) . "</title>
685
+ <link>" . get_bloginfo( 'url' ) . "</link>
686
+ <description>" . get_bloginfo( 'description' ) . "</description>";
687
+ } elseif ( 'comparer.be' == $this->config['provider'] ) {
688
  return "<products version=\"1.0\" standalone=\"yes\">
689
+ <datetime>$datetime_now</datetime>
690
+ <title>" . get_bloginfo( 'name' ) . "</title>
691
+ <link>" . get_bloginfo( 'url' ) . "</link>
692
+ <description>" . get_bloginfo( 'description' ) . "</description>";
693
+ } elseif ( 'dooyoo' == $this->config['provider'] ) {
694
  return "<products version=\"1.0\" standalone=\"yes\">
695
+ <datetime>$datetime_now</datetime>
696
+ <title>" . get_bloginfo( 'name' ) . "</title>
697
+ <link>" . get_bloginfo( 'url' ) . "</link>
698
+ <description>" . get_bloginfo( 'description' ) . "</description>";
699
+ } elseif ( 'hintaseuranta.fi' == $this->config['provider'] ) {
700
  return "<products version=\"1.0\" standalone=\"yes\">
701
+ <datetime>$datetime_now</datetime>
702
+ <title>" . get_bloginfo( 'name' ) . "</title>
703
+ <link>" . get_bloginfo( 'url' ) . "</link>
704
+ <description>" . get_bloginfo( 'description' ) . "</description>";
705
+ } elseif ( 'incurvy' == $this->config['provider'] ) {
706
  return "<products version=\"1.0\" standalone=\"yes\">
707
+ <datetime>$datetime_now</datetime>
708
+ <title>" . get_bloginfo( 'name' ) . "</title>
709
+ <link>" . get_bloginfo( 'url' ) . "</link>
710
+ <description>" . get_bloginfo( 'description' ) . "</description>";
711
+ } elseif ( 'kijiji.ca' == $this->config['provider'] ) {
712
  return "<products version=\"1.0\" standalone=\"yes\">
713
+ <datetime>$datetime_now</datetime>
714
+ <title>" . get_bloginfo( 'name' ) . "</title>
715
+ <link>" . get_bloginfo( 'url' ) . "</link>
716
+ <description>" . get_bloginfo( 'description' ) . "</description>";
717
+ } elseif ( 'marktplaats.nl' == $this->config['provider'] ) {
718
  return "<products version=\"1.0\" standalone=\"yes\">
719
+ <datetime>$datetime_now</datetime>
720
+ <title>" . get_bloginfo( 'name' ) . "</title>
721
+ <link>" . get_bloginfo( 'url' ) . "</link>
722
+ <description>" . get_bloginfo( 'description' ) . "</description>";
723
+ } elseif ( 'rakuten.de' == $this->config['provider'] ) {
724
  return "<products version=\"1.0\" standalone=\"yes\">
725
+ <datetime>$datetime_now</datetime>
726
+ <title>" . get_bloginfo( 'name' ) . "</title>
727
+ <link>" . get_bloginfo( 'url' ) . "</link>
728
+ <description>" . get_bloginfo( 'description' ) . "</description>";
729
+ } elseif ( 'shopalike.fr' == $this->config['provider'] ) {
730
  return "<products version=\"1.0\" standalone=\"yes\">
731
+ <datetime>$datetime_now</datetime>
732
+ <title>" . get_bloginfo( 'name' ) . "</title>
733
+ <link>" . get_bloginfo( 'url' ) . "</link>
734
+ <description>" . get_bloginfo( 'description' ) . "</description>";
735
+ } elseif ( 'spartoo.fi' == $this->config['provider'] ) {
736
  return "<products version=\"1.0\" standalone=\"yes\">
737
+ <datetime>$datetime_now</datetime>
738
+ <title>" . get_bloginfo( 'name' ) . "</title>
739
+ <link>" . get_bloginfo( 'url' ) . "</link>
740
+ <description>" . get_bloginfo( 'description' ) . "</description>";
741
+ } elseif ( 'webmarchand' == $this->config['provider'] ) {
742
  return "<products version=\"1.0\" standalone=\"yes\">
743
+ <datetime>$datetime_now</datetime>
744
+ <title>" . get_bloginfo( 'name' ) . "</title>
745
+ <link>" . get_bloginfo( 'url' ) . "</link>
746
+ <description>" . get_bloginfo( 'description' ) . "</description>";
747
  } else {
748
+ $wrapper = $this->config['itemsWrapper'];
749
+ $extraHeader = $this->config['extraHeader'];
750
+
751
  $output = '<?xml version="1.0" encoding="UTF-8" ?>';
752
  $output .= "\n";
753
  $output .= '<' . $wrapper . '>';
754
+
755
  // $output .= "\n";
756
+ //if ( ! empty( $extraHeader ) ) {
757
+ //$output .= $extraHeader;
758
+ //$output .= "\n";
759
+ //}
760
+
761
  return $output;
762
  }
763
  }
764
+
765
  /**
766
  * Make XML feed header
767
  * @since 3.2.0
768
  * @return string
769
  */
770
  private function process_xml_feed_footer() {
771
+ if ( in_array( $this->config['provider'], [
772
  'fruugo.au',
773
  'stylight.com',
774
  'nextad',
783
  'shopalike.fr',
784
  'spartoo.fi',
785
  'webmarchand',
786
+ ] ) ) {
787
+ return '</products>';
788
+ } elseif ( 'zap.co.il' == $this->config['provider'] ) {
789
+ return '</STORE>';
790
+ } elseif ( 'myshopping.com.au' == $this->config['provider'] ) {
791
+ return '</productset>';
792
  } else {
793
  $wrapper = $this->config['itemsWrapper'];
794
+ $footer = "\n";
795
+ $footer .= "</$wrapper>";
796
+
797
  return $footer;
798
  }
799
  }
800
+
801
  /**
802
  * Process string for TXT CSV Feed
803
  * @since 3.2.0
807
  * @return mixed|string
808
  */
809
  private function processStringForTXT( $string ) {
810
+ if ( ! empty( $string ) ) {
811
+ $string = html_entity_decode( $string, ENT_HTML401 | ENT_QUOTES ); // Convert any HTML entities
812
+
813
+ if ( stristr( $string, '"' ) ) {
814
+ $string = str_replace( '"', '""', $string );
815
  }
816
+ $string = str_replace( "\n", ' ', $string );
817
+ $string = str_replace( "\r", ' ', $string );
818
+ $string = str_replace( "\t", ' ', $string );
819
+ $string = trim( $string );
820
+ $string = stripslashes( $string );
821
+
822
  return $string;
823
+ } elseif ( '0' == $string ) {
824
+ return '0';
825
  } else {
826
+ return '';
827
  }
828
  }
829
+
830
  /**
831
  * Process string for CSV
832
  * @since 3.2.0
836
  * @return mixed|string
837
  */
838
  private function processStringForCSV( $string ) {
839
+ if ( ! empty( $string ) ) {
840
+ $string = str_replace( "\n", ' ', $string );
841
+ $string = str_replace( "\r", ' ', $string );
842
+ $string = trim( $string );
843
+ $string = stripslashes( $string );
844
+
845
  return $string;
846
+ } elseif ( '0' == $string ) {
847
+ return '0';
848
  } else {
849
+ return '';
850
  }
851
  }
852
+
853
  /**
854
  * Get Product Attribute Value by Type
855
  * @since 3.2.0
860
  * @return mixed|string
861
  */
862
  public function getAttributeValueByType( $product, $attribute ) {
863
+ if ( method_exists( $this, $attribute ) ) {
864
+ return call_user_func_array( array( $this, $attribute ), array( $product ) );
865
+ } elseif ( strpos( $attribute, self::PRODUCT_ATTRIBUTE_PREFIX ) !== false ) {
866
+ return $this->getProductAttribute( $product, $attribute );
867
+ } elseif ( strpos( $attribute, self::POST_META_PREFIX ) !== false ) {
868
+ return $this->getProductMeta( $product, $attribute );
869
+ } elseif ( strpos( $attribute, self::PRODUCT_TAXONOMY_PREFIX ) !== false ) {
870
+ return $this->getProductTaxonomy( $product, $attribute );
871
+ } elseif ( substr( $attribute, 0, 6 ) == 'image_' ) {
872
+ // For additional image method images() will be used with extra parameter - image number
873
+ $imageKey = explode( '_', $attribute );
874
+
875
+ return call_user_func_array( array( $this, 'images' ), array( $product, $imageKey[1] ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
876
  } else {
877
  return $attribute;
878
  }
879
  }
880
+
881
+
882
  /**
883
  * Get Product Id
884
  *
885
+ * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product Product Object.
886
  *
887
  * @since 3.2.0
888
  * @return mixed
902
  private function title( $product ) {
903
  return $product->get_name();
904
  }
905
+
906
  /**
907
  * Get Yoast Product Title
908
  * @since 3.2.0
912
  * @return mixed
913
  */
914
  private function yoast_wpseo_title( $product ) {
915
+ $title = '';
916
+ if ( class_exists( 'WPSEO_Frontend' ) ) {
917
+ $title = WPSEO_Frontend::get_instance()->get_seo_title( get_post( $product->get_id() ) );
918
  }
919
+ if ( ! empty( $title ) ) {
920
  return $title;
921
  }
922
+
923
+ return $this->title( $product );
924
  }
925
 
926
  /**
935
  $title = '';
936
  if ( class_exists( 'All_in_One_SEO_Pack' ) ) {
937
  global $aioseop_options, $aiosp;
938
+ if ( ! is_array( $aioseop_options ) ) {
939
+ $aioseop_options = get_option( 'aioseop_options' );
940
+ }
941
  if ( ! ( $aiosp instanceof All_in_One_SEO_Pack ) ) {
942
+ $aiosp = new All_in_One_SEO_Pack();
 
943
  }
944
 
945
  if ( in_array( 'product', $aioseop_options['aiosp_cpostactive'], true ) ) {
956
 
957
  return $this->title( $product );
958
  }
959
+
960
  /**
961
  * Get Product Description
962
  * @since 3.2.0
963
  *
964
+ * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product Product Object.
965
  *
966
  * @return mixed|string
967
  */
968
  private function description( $product ) {
969
+
970
  $description = $product->get_description();
971
+
972
+ // Get Variation Description
973
+ if ( $product->is_type( 'variation' ) && empty( $description ) ) {
974
+ $parent = wc_get_product( $product->get_parent_id() );
975
  $description = $parent->get_description();
976
  }
977
+ $description = $this->remove_short_codes( $description );
978
+
979
+ // Add variations attributes after description to prevent Facebook error
980
+ if ( 'facebook' == $this->config['provider'] ) {
981
+ $variationInfo = explode( "-", $product->get_name() );
982
+ if ( isset( $variationInfo[1] ) ) {
983
  $extension = $variationInfo[1];
984
  } else {
985
  $extension = $product->get_id();
986
  }
987
+ $description .= ' ' . $extension;
988
  }
989
+
990
  return $description;
991
  }
992
+
993
  /**
994
  * Get Yoast Product Description
995
  * @since 3.2.0
999
  * @return mixed
1000
  */
1001
  private function yoast_wpseo_metadesc( $product ) {
1002
+ $description = '';
1003
+ if ( class_exists( 'WPSEO_Frontend' ) ) {
1004
+ $description = wpseo_replace_vars( WPSEO_Meta::get_value( 'metadesc', $product->get_id() ), get_post( $product->get_id() ) );
1005
  }
1006
+ if ( ! empty( $description ) ) {
1007
  return $description;
1008
  }
1009
+
1010
+ return $this->description( $product );
1011
  }
1012
 
1013
  /**
1019
  * @return mixed
1020
  */
1021
  private function _aioseop_description( $product ) {
1022
+ $description = '';
1023
  if ( class_exists( 'All_in_One_SEO_Pack' ) ) {
1024
  global $aioseop_options, $aiosp;
1025
+ if ( ! is_array( $aioseop_options ) ) {
1026
+ $aioseop_options = get_option( 'aioseop_options' );
1027
+ }
1028
  if ( ! ( $aiosp instanceof All_in_One_SEO_Pack ) ) {
1029
+ $aiosp = new All_in_One_SEO_Pack();
 
1030
  }
1031
  if ( in_array( 'product', $aioseop_options['aiosp_cpostactive'], true ) ) {
1032
  $description = $aiosp->get_main_description( get_post( $product->get_id() ) ); // Get the description.
1040
 
1041
  return $this->description( $product );
1042
  }
1043
+
1044
  /**
1045
  * Get Product Short Description
1046
  * @since 3.2.0
1050
  * @return mixed|string
1051
  */
1052
  private function short_description( $product ) {
1053
+
1054
  $short_description = $product->get_short_description();
1055
+
1056
+ // Get Variation Short Description
1057
+ if ( $product->is_type( 'variation' ) && empty( $short_description ) ) {
1058
+ $parent = wc_get_product( $product->get_parent_id() );
1059
  $short_description = $parent->get_short_description();
1060
  }
1061
+
1062
+
1063
+ $short_description = $this->remove_short_codes( $short_description );
1064
+
1065
  return $short_description;
1066
  }
1067
+
1068
+
1069
  /**
1070
  * At First convert Short Codes and then Remove failed Short Codes from String
1071
  * @since 3.2.0
1075
  * @return mixed|string
1076
  */
1077
  private function remove_short_codes( $content ) {
1078
+ if ( empty( $content ) ) {
1079
+ return '';
1080
  }
1081
+
1082
+ // Remove DIVI Builder Short Codes
1083
+ if ( class_exists( 'ET_Builder_Module' ) || defined( 'ET_BUILDER_PLUGIN_VERSION' ) ) {
1084
+ /** @noinspection RegExpRedundantEscape */
1085
+ $content = preg_replace( '/\[\/?et_pb.*?\]/', '', $content );
1086
  }
1087
+
1088
+ $content = do_shortcode( $content );
1089
+
1090
+ $content = woo_feed_stripInvalidXml( $content );
1091
+
1092
+ return strip_shortcodes( $content );
1093
  }
1094
+
1095
  /**
1096
  * Get Product Categories
1097
  * @since 3.2.0
1102
  */
1103
  private function product_type( $product ) {
1104
  $id = $product->get_id();
1105
+ if ( $product->is_type( 'variation' ) ) {
1106
  $id = $product->get_parent_id();
1107
  }
1108
+
1109
+ return wp_strip_all_tags( wc_get_product_category_list( $id, ">", '' ) );
1110
  }
1111
 
1112
  /**
1130
  * @return mixed
1131
  */
1132
  private function ex_link( $product ) {
1133
+ if ( $product->is_type( 'external' ) ) {
1134
  return $product->get_product_url();
1135
  }
1136
 
1137
+ return '';
1138
  }
1139
+
1140
  /**
1141
  * Get Product Image
1142
  * @since 3.2.0
1143
  *
1144
+ * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product Product Object.
1145
  *
1146
  * @return mixed
1147
  */
1148
  private function image( $product ) {
1149
+ if ( $product->is_type( 'variation' ) ) {
1150
+ $getImage = wp_get_attachment_image_src( get_post_thumbnail_id( $product->get_id() ), 'single-post-thumbnail' );
1151
+ if ( has_post_thumbnail( $product->get_id() ) && ! empty( $getImage[0] ) ) :
1152
+ $image = woo_feed_get_formatted_url( $getImage[0] );
 
 
1153
  else :
1154
+ $getImage = wp_get_attachment_image_src( get_post_thumbnail_id( $product->get_parent_id() ), 'single-post-thumbnail' );
1155
+ $image = woo_feed_get_formatted_url( $getImage[0] );
1156
  endif;
1157
  } else {
1158
+ if ( has_post_thumbnail( $product->get_id() ) ) :
1159
+ $getImage = wp_get_attachment_image_src( get_post_thumbnail_id( $product->get_id() ), 'single-post-thumbnail' );
1160
+ $image = woo_feed_get_formatted_url( $getImage[0] );
1161
  else :
1162
+ $image = woo_feed_get_formatted_url( wp_get_attachment_url( $product->get_id() ) );
1163
  endif;
1164
  }
1165
+
1166
  return $image;
1167
  }
1168
+
1169
  /**
1170
  * Get Product Featured Image
1171
  * @since 3.2.0
1172
  *
1173
+ * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product Product Object.
1174
  *
1175
  * @return mixed
1176
  */
1177
  private function feature_image( $product ) {
1178
+ return $this->image( $product );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1179
  }
1180
+
1181
  /**
1182
  * Get Comma Separated Product Images
 
1183
  *
1184
+ * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product Product Object.
1185
+ * @param string $additionalImg Specific Additional Image.
1186
  *
1187
  * @return mixed
1188
+ * @since 3.2.0
1189
+ *
1190
  */
1191
+ private function images( $product, $additionalImg = '' ) {
1192
+ if ( $product->is_type( 'variation' ) ) {
1193
+ // TODO Test Variation Images
1194
  $imgUrls = $this->get_product_gallery( wc_get_product( $product->get_parent_id() ) );
1195
  } else {
1196
  $imgUrls = $this->get_product_gallery( $product );
1197
  }
1198
 
1199
+ // Return Specific Additional Image URL
1200
+ if ( '' != $additionalImg ) {
1201
  if ( array_key_exists( $additionalImg, $imgUrls ) ) {
1202
  return $imgUrls[ $additionalImg ];
1203
  } else {
1204
+ return '';
1205
  }
1206
  }
1207
 
1212
  * Get Product Gallery Items (URL) array.
1213
  * This can contains empty array values
1214
  * @since 3.2.6
1215
+ * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product
1216
  * @return string[]
1217
  */
1218
  private function get_product_gallery( $product ) {
1227
  }
1228
  return $imgUrls;
1229
  }
1230
+
1231
  /**
1232
  * Get Product Condition
1233
  * @since 3.2.0
1237
  * @return mixed
1238
  */
1239
  private function condition( $product ) {
1240
+ return apply_filters( 'woo_feed_product_condition', 'new', $product );
1241
  }
1242
+
1243
  /**
1244
  * Get Product Type
1245
  * @since 3.2.0
1251
  private function type( $product ) {
1252
  return $product->get_type();
1253
  }
1254
+
1255
  /**
1256
  * Get Product is a bundle product or not
1257
  * @since 3.2.0
1261
  * @return mixed
1262
  */
1263
  private function is_bundle( $product ) {
1264
+ if ( $product->is_type( 'bundle' ) || $product->is_type( 'yith_bundle' ) ) {
1265
+ return "yes";
1266
+ }
1267
+
1268
+ return 'no';
1269
  }
1270
+
1271
  /**
1272
  * Get Product is a multi-pack product or not
1273
  * @since 3.2.0
1277
  * @return mixed
1278
  */
1279
  private function multipack( $product ) {
1280
+ $multi_pack = '';
1281
+ if ( $product->is_type( 'grouped' ) ) {
1282
+ $multi_pack = ( ! empty( $product->get_children() ) ) ? count( $product->get_children() ) : '';
1283
  }
1284
+
1285
  return $multi_pack;
1286
  }
1287
+
1288
  /**
1289
  * Get Product visibility status
1290
  * @since 3.2.0
1296
  private function visibility( $product ) {
1297
  return $product->get_catalog_visibility();
1298
  }
1299
+
1300
  /**
1301
  * Get Product Total Rating
1302
  * @since 3.2.0
1308
  private function rating_total( $product ) {
1309
  return $product->get_rating_count();
1310
  }
1311
+
1312
  /**
1313
  * Get Product average rating
1314
  * @since 3.2.0
1320
  private function rating_average( $product ) {
1321
  return $product->get_average_rating();
1322
  }
1323
+
1324
  /**
1325
  * Get Product tags
1326
  * @since 3.2.0
1331
  */
1332
  private function tags( $product ) {
1333
  $id = $product->get_id();
1334
+ if ( $product->is_type( 'variation' ) ) {
1335
  $id = $product->get_parent_id();
1336
  }
1337
+
1338
+ $tags = get_the_term_list( $id, 'product_tag', '', ',', '' );
1339
+
1340
+ if ( ! empty( $tags ) ) {
1341
+ return wp_strip_all_tags( $tags );
1342
  }
1343
+
1344
+ return '';
1345
  }
1346
+
1347
  /**
1348
  * Get Product Parent Id
1349
  * @since 3.2.0
1354
  */
1355
  private function item_group_id( $product ) {
1356
  $id = $product->get_id();
1357
+ if ( $product->is_type( 'variation' ) ) {
1358
  $id = $product->get_parent_id();
1359
  }
1360
+
1361
  return $id;
1362
  }
1363
+
1364
  /**
1365
  * Get Product SKU
1366
  * @since 3.2.0
1372
  private function sku( $product ) {
1373
  return $product->get_sku();
1374
  }
1375
+
1376
  /**
1377
  * Get Product Parent SKU
1378
  * @since 3.2.0
1382
  * @return mixed
1383
  */
1384
  private function parent_sku( $product ) {
1385
+ if ( $product->is_type( 'variation' ) ) {
1386
+ $id = $product->get_parent_id();
1387
+ $parent = wc_get_product( $id );
1388
+
1389
  return $parent->get_sku();
1390
  }
1391
+
1392
  return $product->get_sku();
1393
  }
1394
+
1395
  /**
1396
  * Get Product Availability Status
1397
  * @since 3.2.0
1401
  * @return mixed
1402
  */
1403
  private function availability( $product ) {
1404
+ $status = $product->get_stock_status();
 
1405
  if ( $status ) {
1406
+ if ( 'instock' == $status ) {
1407
  return "in stock";
1408
+ } elseif ( 'outofstock' == $status ) {
1409
  return "out of stock";
1410
+ } elseif ( 'onbackorder' == $status ) {
1411
  return "on backorder";
1412
  } else {
1413
  return "in stock";
1414
  }
1415
  }
1416
+
1417
  return "in stock";
1418
  }
1419
+
1420
  /**
1421
  * Get Product Quantity
1422
  * @since 3.2.0
1426
  * @return mixed
1427
  */
1428
  private function quantity( $product ) {
1429
+ if ( $product->is_type( 'variable' ) && $product->has_child() ) {
1430
  $visible_children = $product->get_visible_children();
1431
+ $qty = array();
1432
  foreach ( $visible_children as $key => $child ) {
1433
+ $childQty = get_post_meta( $child, '_stock', true );
1434
+ $qty[] = (int) $childQty + 0;
1435
  }
1436
+
1437
+ if ( isset( $this->config['variable_quantity'] ) ) {
1438
  $vaQty = $this->config['variable_quantity'];
1439
+ if ( 'max' == $vaQty ) {
1440
+ return max( $qty );
1441
+ } elseif ( 'min' == $vaQty ) {
1442
+ return min( $qty );
1443
+ } elseif ( 'sum' == $vaQty ) {
1444
+ return array_sum( $qty );
1445
+ } elseif ( 'first' == $vaQty ) {
1446
+ return ( (int) $qty[0] );
1447
  }
1448
+
1449
+ return array_sum( $qty );
1450
  }
1451
  }
1452
+
1453
  return $product->get_stock_quantity();
1454
  }
1455
+
1456
  /**
1457
  * Get Product Sale Price Start Date
1458
  * @since 3.2.0
1463
  */
1464
  private function sale_price_sdate( $product ) {
1465
  $startDate = $product->get_date_on_sale_from();
1466
+ if ( is_object( $startDate ) ) {
1467
  return $startDate->date_i18n();
1468
  }
1469
+
1470
+ return '';
1471
  }
1472
+
1473
  /**
1474
  * Get Product Sale Price End Date
1475
  * @since 3.2.0
1480
  */
1481
  private function sale_price_edate( $product ) {
1482
  $endDate = $product->get_date_on_sale_to();
1483
+ if ( is_object( $endDate ) ) {
1484
  return $endDate->date_i18n();
1485
  }
1486
+
1487
+ return '';
1488
  }
1489
+
1490
  /**
1491
  * Get Product Regular Price
1492
  * @since 3.2.0
1493
  *
1494
+ * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product Object.
1495
  *
1496
  * @return mixed
1497
  */
1498
  private function price( $product ) {
1499
  $price = $product->get_regular_price();
1500
  # Set variable product regular price according to setting
1501
+ if ( $product->is_type( 'variable' ) ) {
1502
+ $price = $this->getVariableProductPrice( $product, 'regular_price' );
1503
+ } elseif ( $product->is_type( 'grouped' ) ) {
1504
+ return $this->getGroupProductPrice( $product, 'regular' );
1505
  }
1506
+
1507
  return $price;
1508
  }
1509
 
1511
  * Get Product Price
1512
  * @since 3.2.0
1513
  *
1514
+ * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product
1515
  *
1516
  * @return mixed
1517
  */
1518
  private function current_price( $product ) {
1519
  $price = $product->get_price();
1520
  # Set variable product current price according to setting
1521
+ if ( $product->is_type( 'variable' ) ) {
1522
+ $price = $this->getVariableProductPrice( $product, 'price' );
1523
+ } elseif ( $product->is_type( 'grouped' ) ) {
1524
+ return $this->getGroupProductPrice( $product, 'current' );
1525
  }
1526
+
1527
  return $price;
1528
  }
1529
 
1531
  * Get Product Sale Price
1532
  * @since 3.2.0
1533
  *
1534
+ * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product
1535
  *
1536
  * @return mixed
1537
  */
1541
  if ( $product->is_type('variable') ) {
1542
  $price = $this->getVariableProductPrice($product, 'sale_price');
1543
  } elseif ( $product->is_type('grouped') ) {
1544
+ return $this->getGroupProductPrice( $product, 'sale' );
1545
  }
1546
 
1547
  return $price;
1549
 
1550
  /**
1551
  * Get Product Regular Price with Tax
 
1552
  *
1553
+ * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product Product Object.
1554
  *
1555
  * @return mixed
1556
+ * @since 3.2.0
1557
+ *
1558
  */
1559
  private function price_with_tax( $product ) {
1560
  $price = $this->price( $product );
1563
  $price = $this->getVariableProductPrice( $product, 'regular_price' );
1564
  } elseif ( $product->is_type( 'grouped' ) ) {
1565
  return $this->getGroupProductPrice( $product, 'regular', true );
 
 
1566
  }
1567
 
1568
  // Get price with tax.
1575
 
1576
  /**
1577
  * Get Product Regular Price with Tax
 
1578
  *
1579
+ * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product
1580
  *
1581
  * @return mixed
1582
+ * @since 3.2.0
1583
+ *
1584
  */
1585
  private function current_price_with_tax( $product ) {
1586
  $price = $this->current_price( $product );
1589
  $price = $this->getVariableProductPrice( $product, 'current_price' );
1590
  } elseif ( $product->is_type( 'grouped' ) ) {
1591
  return $this->getGroupProductPrice( $product, 'current', true );
 
 
1592
  }
1593
 
1594
  // Get price with tax
1601
 
1602
  /**
1603
  * Get Product Regular Price with Tax
 
1604
  *
1605
+ * @param WC_Product|WC_Product_Variable|WC_Product_Grouped $product
1606
  *
1607
  * @return mixed
1608
+ * @since 3.2.0
1609
+ *
1610
  */
1611
  private function sale_price_with_tax( $product ) {
1612
  $price = $this->sale_price( $product );
1616
  $price = $this->getVariableProductPrice( $product, 'sale_price' );
1617
  } elseif ( $product->is_type( 'grouped' ) ) {
1618
  return $this->getGroupProductPrice( $product, 'sale', true );
 
 
1619
  }
1620
 
1621
  // Get price with tax
1625
 
1626
  return $price;
1627
  }
1628
+
1629
  /**
1630
  * Get total price of grouped product
1631
  *
 
 
1632
  * @param WC_Product_Grouped $grouped
1633
  * @param string $type
1634
  * @param bool $tax
1635
  *
1636
  * @return int|string
1637
+ * @since 3.2.0
1638
+ *
1639
  */
1640
  private function getGroupProductPrice( $grouped, $type, $tax = false ) {
1641
  $groupProductIds = $grouped->get_children();
1642
+ $sum = 0;
1643
+ if ( ! empty( $groupProductIds ) ) {
1644
  foreach ( $groupProductIds as $id ) {
1645
+ $product = wc_get_product( $id );
1646
+
1647
+ if ( ! is_object( $product ) ) {
1648
  continue; // make sure that the product exists..
1649
  }
1650
+
1651
  if ( $tax ) {
1652
+ if ( 'regular' == $type ) {
1653
+ $regularPrice = $this->price_with_tax( $product );
1654
+ $sum += (float) $regularPrice;
1655
+ } elseif ( 'current' == $type ) {
1656
+ $currentPrice = $this->current_price_with_tax( $product );
1657
+ $sum += (float) $currentPrice;
1658
  } else {
1659
+ $salePrice = $this->sale_price_with_tax( $product );
1660
+ $sum += (float) $salePrice;
1661
  }
1662
  } else {
1663
+ if ( 'regular' == $type ) {
1664
+ $regularPrice = $this->price( $product );
1665
+ $sum += (float) $regularPrice;
1666
+ } elseif ( 'current' == $type ) {
1667
+ $currentPrice = $this->current_price( $product );
1668
+ $sum += (float) $currentPrice;
1669
  } else {
1670
+ $salePrice = $this->sale_price( $product );
1671
+ $sum += (float) $salePrice;
1672
  }
1673
  }
1674
  }
1675
  }
1676
+
1677
  return $sum;
1678
  }
1679
+
1680
  /**
1681
  * Get total price of grouped product
1682
  *
 
 
1683
  * @param WC_Product|WC_Product_Variable $variable
1684
  * @param string $type regular_price, sale_price & current_price
1685
  *
1686
  * @return int|string
1687
+ * @since 3.2.0
1688
+ *
1689
  */
1690
  private function getVariableProductPrice( $variable, $type ) {
1691
+ if ( 'regular_price' == $type ) {
1692
  return $variable->get_variation_regular_price();
1693
+ } elseif ( 'sale_price' == $type ) {
1694
  return $variable->get_variation_sale_price();
1695
  } else {
1696
  return $variable->get_variation_price();
1699
 
1700
  /**
1701
  * Return product price with tax
 
1702
  *
1703
+ * @param WC_Product $product Product.
1704
+ * @param float $price Price.
1705
  *
1706
  * @return float|string
1707
+ * @since 3.2.0
1708
+ *
1709
  */
1710
  public function get_price_with_tax( $product, $price ) {
1711
  if ( woo_feed_wc_version_check( 3.0 ) ) {
1819
  */
1820
  private function date_created( $product ) {
1821
  $dateCreated = $product->get_date_created();
1822
+
1823
+ return gmdate( 'Y-m-d', strtotime( $dateCreated ) );
1824
  }
1825
 
1826
  /**
1833
  */
1834
  private function date_updated( $product ) {
1835
  $dateModified = $product->get_date_modified();
1836
+
1837
+ return gmdate( 'Y-m-d', strtotime( $dateModified ) );
1838
  }
1839
 
1840
  /**
1846
  * @return mixed
1847
  */
1848
  private function sale_price_effective_date( $product ) {
1849
+ $sale_price_effective_date = '';
1850
  $from = $this->sale_price_sdate($product);
1851
  $to = $this->sale_price_edate($product);
1852
  if ( ! empty($from) && ! empty($to) ) {
1853
+ $from = gmdate("c", strtotime($from));
1854
+ $to = gmdate("c", strtotime($to));
1855
+ $sale_price_effective_date = $from . '/' . $to;
1856
  }
1857
 
1858
  return $sale_price_effective_date;
1870
  */
1871
  public function getProductAttribute( $product, $attr ) {
1872
  $id = $product->get_id();
1873
+ $attr = str_replace(self::PRODUCT_ATTRIBUTE_PREFIX, '', $attr);
1874
 
1875
  if ( woo_feed_wc_version_check(3.2) ) {
1876
  if ( woo_feed_wc_version_check(3.6) ) {
1877
+ $attr = str_replace("pa_", '', $attr);
1878
  }
1879
  $value = $product->get_attribute($attr);
1880
 
1896
  */
1897
  public function getProductMeta( $product, $meta ) {
1898
  $id = $product->get_id();
1899
+ $meta = str_replace(self::POST_META_PREFIX, '', $meta);
1900
 
1901
  if ( strpos($meta, 'attribute_pa') !== false ) {
1902
+ $productMeta = $this->getProductAttribute($product, str_replace("attribute_", '', $meta));
1903
  } else {
1904
  $productMeta = get_post_meta($id, $meta, true);
1905
  }
1906
 
1907
+ // @TODO pro version has output option for choosing meta from parent post. should this exists in free version???...
1908
 
1909
+ if ( '' == $productMeta ) {
1910
+ $postParent = wp_get_post_parent_id( $id );
1911
  if ( $postParent > 0 ) {
1912
+ $productMeta = get_post_meta( $postParent, $meta, true );
1913
  }
1914
  }
1915
 
1927
  */
1928
  public function getProductTaxonomy( $product, $taxonomy ) {
1929
  $id = $product->get_id();
1930
+ $taxonomy = str_replace(self::PRODUCT_TAXONOMY_PREFIX, '', $taxonomy);
1931
+ $taxonomy_list = get_the_term_list( $id, $taxonomy, '', ',', '' );
1932
 
1933
  if ( ! empty($taxonomy_list) ) {
1934
+ return wp_strip_all_tags($taxonomy_list);
1935
  }
1936
 
1937
+ return '';
1938
  }
1939
 
1940
  /**
1954
 
1955
  if ( strpos($name, 'price') !== false ) {
1956
  if ( strpos($result, $plus) !== false && strpos($result, $percent) !== false ) {
1957
+ $result = str_replace("+", '', $result);
1958
+ $result = str_replace("%", '', $result);
1959
  if ( is_numeric($result) ) {
1960
  $result = $conditionName + (($conditionName * $result) / 100);
1961
  }
1962
  } elseif ( strpos($result, $minus) !== false && strpos($result, $percent) !== false ) {
1963
+ $result = str_replace("-", '', $result);
1964
+ $result = str_replace("%", '', $result);
1965
  if ( is_numeric($result) ) {
1966
  $result = $conditionName - (($conditionName * $result) / 100);
1967
  }
1994
  if ( ! empty($outputTypes) && is_array($outputTypes) ) {
1995
 
1996
  # Format Output According to output type
1997
+ if ( in_array( 2, $outputTypes ) ) { // Strip Tags
1998
+ $output = wp_strip_all_tags( html_entity_decode( $output ) );
1999
  }
2000
 
2001
  if ( in_array(3, $outputTypes) ) { # UTF-8 Encode
2053
  }
2054
 
2055
  # Add Prefix before Output
2056
+ if ( '' != $prefix ) {
2057
  $output = "$prefix" . $output;
2058
  }
2059
 
2060
  # Add Suffix after Output
2061
+ if ( '' != $suffix ) {
2062
+ if (
2063
+ 'price' == $attribute ||
2064
+ 'sale_price' == $attribute ||
2065
+ 'current_price' == $attribute ||
2066
+ 'price_with_tax' == $attribute ||
2067
+ 'current_price_with_tax' == $attribute ||
2068
+ 'sale_price_with_tax' == $attribute ||
2069
+ 'shipping_price' == $attribute ||
2070
+ 'tax_rate' == $attribute
2071
+ ) { # Add space before suffix if attribute contain price
2072
+
2073
+ $output = $output . '' . $suffix;
2074
+
2075
+ } elseif ( 'http' === substr( $output, 0, 4 ) ) {
2076
 
2077
  # Parse URL Parameters if available into suffix field
2078
  $output = woo_feed_make_url_with_parameter( $output, $suffix );
includes/classes/class-woo-feed-products.php CHANGED
@@ -1,4 +1,5 @@
1
- <?php
 
2
 
3
  /**
4
  * This is used to store all the information about wooCommerce store products
@@ -74,14 +75,14 @@ class Woo_Feed_Products {
74
  global $wpdb;
75
 
76
 
77
- $limit = "";
78
- $offset = "";
79
- if ( $arg['limit'] != "" && $arg['limit'] != "-1" && $arg['limit'] > 0 ) {
80
  $limit = absint( $arg['limit'] );
81
  $limit = "LIMIT $limit";
82
-
83
-
84
- if ( $arg['offset'] != "" && $arg['offset'] != "-1" ) {
85
  $offset = absint( $arg['offset'] );
86
  $offset = "OFFSET $offset";
87
  }
@@ -96,7 +97,7 @@ class Woo_Feed_Products {
96
  LEFT JOIN $wpdb->postmeta ON ($wpdb->posts.ID = $wpdb->postmeta.post_id)
97
  WHERE $wpdb->posts.post_status = 'publish' AND $wpdb->posts.post_type IN ('product','product_variation')
98
  ORDER BY ID DESC $limit $offset";
99
- $products = $wpdb->get_results($query, ARRAY_A );
100
  return $products;
101
  }
102
 
@@ -116,7 +117,7 @@ class Woo_Feed_Products {
116
  $offset = ! empty( $offset ) && is_numeric( $offset ) ? absint( $offset ) : '0';
117
 
118
  # Process Duplicate Products
119
- if ( $offset == '0' ) {
120
  delete_option( "wf_check_duplicate" );
121
  }
122
  $getIDs = get_option( "wf_check_duplicate" );
@@ -146,13 +147,13 @@ class Woo_Feed_Products {
146
  $prod = wc_get_product($productId);
147
 
148
  $id = $prod->get_id();
149
-
150
  if ( $getIDs ) {
151
- if ( in_array($id,$getIDs) ) {
152
  continue;
153
- }else {
154
- array_push($this->idExist,$id);
155
- }
156
  }else {
157
  array_push($this->idExist,$id);
158
  }
@@ -161,13 +162,13 @@ class Woo_Feed_Products {
161
 
162
  $simple = new WC_Product_Simple( $id );
163
 
164
- $this->productsList[ $this->pi ]["id"] = $simple->get_id();
165
- $this->productsList[ $this->pi ]["title"] = $simple->get_name();
166
- $this->productsList[ $this->pi ]["description"] = $this->remove_short_codes($simple->get_description());
167
  $this->productsList[ $this->pi ]['variation_type'] = $simple->get_type();
168
 
169
  $this->productsList[ $this->pi ]['short_description'] = $this->remove_short_codes($simple->get_short_description());
170
- $this->productsList[ $this->pi ]['product_type'] = strip_tags( wc_get_product_category_list( $id, ">", "" ) );
171
  $this->productsList[ $this->pi ]['link'] = $simple->get_permalink();
172
  $this->productsList[ $this->pi ]['ex_link'] = $simple->get_permalink();
173
 
@@ -194,15 +195,15 @@ class Woo_Feed_Products {
194
  }
195
  }
196
 
197
- $this->productsList[ $this->pi ]['images'] = implode( ",", $imgUrls );
198
- $this->productsList[ $this->pi ]['condition'] = "new";
199
  $this->productsList[ $this->pi ]['type'] = $simple->get_type();
200
- $this->productsList[ $this->pi ]['is_bundle'] = "no";
201
- $this->productsList[ $this->pi ]['multipack'] = "";
202
  $this->productsList[ $this->pi ]['visibility'] = $simple->get_catalog_visibility();
203
  $this->productsList[ $this->pi ]['rating_total'] = $simple->get_rating_count();
204
  $this->productsList[ $this->pi ]['rating_average'] = $simple->get_average_rating();
205
- $this->productsList[ $this->pi ]['tags'] = $this->getProductTaxonomy($id,"product_tag");
206
  $this->productsList[ $this->pi ]['item_group_id'] = $simple->get_id();
207
  $this->productsList[ $this->pi ]['sku'] = $simple->get_sku();
208
  $this->productsList[ $this->pi ]['parent_sku'] = $simple->get_sku();
@@ -229,9 +230,9 @@ class Woo_Feed_Products {
229
  if ( ! empty( $from ) && ! empty( $to ) ) {
230
  $from = gmdate( "c", strtotime( $from ) );
231
  $to = gmdate( "c", strtotime( $to ) );
232
- $this->productsList[ $this->pi ]['sale_price_effective_date'] = "$from" . "/" . "$to";
233
  } else {
234
- $this->productsList[ $this->pi ]['sale_price_effective_date'] = "";
235
  }
236
 
237
  // # Get all Attributes and their values
@@ -247,12 +248,12 @@ class Woo_Feed_Products {
247
 
248
  $external = new WC_Product_External( $id );
249
 
250
- $this->productsList[ $this->pi ]["id"] = $external->get_id();
251
- $this->productsList[ $this->pi ]["title"] = $external->get_name();
252
- $this->productsList[ $this->pi ]["description"] = $this->remove_short_codes($external->get_description());
253
  $this->productsList[ $this->pi ]['variation_type'] = $external->get_type();
254
  $this->productsList[ $this->pi ]['short_description'] = $this->remove_short_codes($external->get_short_description());
255
- $this->productsList[ $this->pi ]['product_type'] = strip_tags( wc_get_product_category_list( $id, ">", "" ) );
256
  $this->productsList[ $this->pi ]['link'] = $external->get_permalink();
257
  $this->productsList[ $this->pi ]['ex_link'] = $external->get_product_url();
258
 
@@ -279,15 +280,15 @@ class Woo_Feed_Products {
279
  }
280
  }
281
 
282
- $this->productsList[ $this->pi ]['images'] = implode( ",", $imgUrls );
283
- $this->productsList[ $this->pi ]['condition'] = "new";
284
  $this->productsList[ $this->pi ]['type'] = $external->get_type();
285
- $this->productsList[ $this->pi ]['is_bundle'] = "no";
286
- $this->productsList[ $this->pi ]['multipack'] = "";
287
  $this->productsList[ $this->pi ]['visibility'] = $external->get_catalog_visibility();
288
  $this->productsList[ $this->pi ]['rating_total'] = $external->get_rating_count();
289
  $this->productsList[ $this->pi ]['rating_average'] = $external->get_average_rating();
290
- $this->productsList[ $this->pi ]['tags'] = $this->getProductTaxonomy($id,"product_tag");
291
  $this->productsList[ $this->pi ]['item_group_id'] = $external->get_id();
292
  $this->productsList[ $this->pi ]['sku'] = $external->get_sku();
293
  $this->productsList[ $this->pi ]['parent_sku'] = $external->get_sku();
@@ -314,9 +315,9 @@ class Woo_Feed_Products {
314
  if ( ! empty( $from ) && ! empty( $to ) ) {
315
  $from = gmdate( "c", strtotime( $from ) );
316
  $to = gmdate( "c", strtotime( $to ) );
317
- $this->productsList[ $this->pi ]['sale_price_effective_date'] = "$from" . "/" . "$to";
318
  } else {
319
- $this->productsList[ $this->pi ]['sale_price_effective_date'] = "";
320
  }
321
 
322
  # Get all Attributes and their values
@@ -332,13 +333,13 @@ class Woo_Feed_Products {
332
 
333
  $grouped = new WC_Product_Grouped( $id );
334
 
335
- $this->productsList[ $this->pi ]["id"] = $grouped->get_id();
336
- $this->productsList[ $this->pi ]["title"] = $grouped->get_name();
337
- $this->productsList[ $this->pi ]["description"] = $this->remove_short_codes($grouped->get_description());
338
  $this->productsList[ $this->pi ]['variation_type'] = $grouped->get_type();
339
 
340
  $this->productsList[ $this->pi ]['short_description'] = $this->remove_short_codes($grouped->get_short_description());
341
- $this->productsList[ $this->pi ]['product_type'] = strip_tags( wc_get_product_category_list( $id, ">", "" ) );//$this->get_product_term_list( $post->ID, 'product_cat', "", ">" );// $this->categories($this->parentID);//TODO
342
  $this->productsList[ $this->pi ]['link'] = $grouped->get_permalink();
343
  $this->productsList[ $this->pi ]['ex_link'] = $grouped->get_permalink();
344
 
@@ -364,15 +365,15 @@ class Woo_Feed_Products {
364
  }
365
  }
366
 
367
- $this->productsList[ $this->pi ]['images'] = implode( ",", $imgUrls );
368
- $this->productsList[ $this->pi ]['condition'] = "new";
369
  $this->productsList[ $this->pi ]['type'] = $grouped->get_type();
370
- $this->productsList[ $this->pi ]['is_bundle'] = "no";
371
- $this->productsList[ $this->pi ]['multipack'] = ( count( $grouped->get_children() ) > 0 ) ? count( $grouped->get_children() ) : "";
372
  $this->productsList[ $this->pi ]['visibility'] = $grouped->get_catalog_visibility();
373
  $this->productsList[ $this->pi ]['rating_total'] = $grouped->get_rating_count();
374
  $this->productsList[ $this->pi ]['rating_average'] = $grouped->get_average_rating();
375
- $this->productsList[ $this->pi ]['tags'] = $this->getProductTaxonomy($id,"product_tag");
376
  $this->productsList[ $this->pi ]['item_group_id'] = $grouped->get_id();
377
  $this->productsList[ $this->pi ]['sku'] = $grouped->get_sku();
378
  $this->productsList[ $this->pi ]['parent_sku'] = $grouped->get_sku();
@@ -398,9 +399,9 @@ class Woo_Feed_Products {
398
  if ( ! empty( $from ) && ! empty( $to ) ) {
399
  $from = gmdate( "c", strtotime( $from ) );
400
  $to = gmdate( "c", strtotime( $to ) );
401
- $this->productsList[ $this->pi ]['sale_price_effective_date'] = "$from" . "/" . "$to";
402
  } else {
403
- $this->productsList[ $this->pi ]['sale_price_effective_date'] = "";
404
  }
405
 
406
  # Get all Attributes and their values
@@ -416,13 +417,13 @@ class Woo_Feed_Products {
416
 
417
  $variable = new WC_Product_Variable( $id );
418
 
419
- $this->productsList[ $this->pi ]["id"] = $variable->get_id();
420
- $this->productsList[ $this->pi ]["title"] = $variable->get_name();
421
- $this->productsList[ $this->pi ]["description"] = $this->remove_short_codes($variable->get_description());
422
  $this->productsList[ $this->pi ]['variation_type'] = $variable->get_type();
423
 
424
  $this->productsList[ $this->pi ]['short_description'] = $this->remove_short_codes($variable->get_short_description());
425
- $this->productsList[ $this->pi ]['product_type'] = strip_tags( wc_get_product_category_list( $id, ">", "" ) );
426
  $this->productsList[ $this->pi ]['link'] = $variable->get_permalink();
427
  $this->productsList[ $this->pi ]['ex_link'] = $variable->get_permalink();
428
 
@@ -449,15 +450,15 @@ class Woo_Feed_Products {
449
  }
450
  }
451
 
452
- $this->productsList[ $this->pi ]['images'] = implode( ",", $imgUrls );
453
- $this->productsList[ $this->pi ]['condition'] = "new";
454
  $this->productsList[ $this->pi ]['type'] = $variable->get_type();
455
- $this->productsList[ $this->pi ]['is_bundle'] = "no";
456
- $this->productsList[ $this->pi ]['multipack'] = "";
457
  $this->productsList[ $this->pi ]['visibility'] = $variable->get_catalog_visibility();
458
  $this->productsList[ $this->pi ]['rating_total'] = $variable->get_rating_count();
459
  $this->productsList[ $this->pi ]['rating_average'] = $variable->get_average_rating();
460
- $this->productsList[ $this->pi ]['tags'] = $this->getProductTaxonomy($id,"product_tag");
461
  $this->productsList[ $this->pi ]['item_group_id'] = $variable->get_id();
462
  $this->productsList[ $this->pi ]['sku'] = $variable->get_sku();
463
  $this->productsList[ $this->pi ]['parent_sku'] = $variable->get_sku();
@@ -486,9 +487,9 @@ class Woo_Feed_Products {
486
  if ( ! empty( $from ) && ! empty( $to ) ) {
487
  $from = gmdate( "c", strtotime( $from ) );
488
  $to = gmdate( "c", strtotime( $to ) );
489
- $this->productsList[ $this->pi ]['sale_price_effective_date'] = "$from" . "/" . "$to";
490
  } else {
491
- $this->productsList[ $this->pi ]['sale_price_effective_date'] = "";
492
  }
493
 
494
  # Get all Attributes and their values
@@ -531,23 +532,23 @@ class Woo_Feed_Products {
531
  }
532
  $short_description = $this->remove_short_codes($short_description);
533
 
534
- $this->productsList[ $this->pi ]["id"] = $variation->get_id();
535
- $this->productsList[ $this->pi ]["title"] = $variation->get_name();
536
 
537
- if ( $this->feedRule['provider'] == 'facebook' ) {
538
  $variationInfo = explode("-",$variation->get_name());
539
  if ( isset($variationInfo[1]) ) {
540
  $extension = $variationInfo[1];
541
  }else {
542
  $extension = $variation->get_id();
543
  }
544
- $description .= " ".$extension;
545
  }
546
 
547
- $this->productsList[ $this->pi ]["description"] = $description;
548
  $this->productsList[ $this->pi ]['variation_type'] = $variation->get_type();
549
  $this->productsList[ $this->pi ]['short_description'] = $short_description;
550
- $this->productsList[ $this->pi ]['product_type'] = strip_tags(wc_get_product_category_list($variation->get_parent_id(),">",""));
551
  $this->productsList[ $this->pi ]['link'] = $variation->get_permalink();
552
  $this->productsList[ $this->pi ]['ex_link'] = $variation->get_permalink();
553
 
@@ -576,15 +577,15 @@ class Woo_Feed_Products {
576
  }
577
  }
578
 
579
- $this->productsList[ $this->pi ]['images'] = implode( ",", $imgUrls );
580
- $this->productsList[ $this->pi ]['condition'] = "new";
581
  $this->productsList[ $this->pi ]['type'] = $variation->get_type();
582
- $this->productsList[ $this->pi ]['is_bundle'] = "no";
583
- $this->productsList[ $this->pi ]['multipack'] = "";
584
  $this->productsList[ $this->pi ]['visibility'] = $variation->get_catalog_visibility();
585
  $this->productsList[ $this->pi ]['rating_total'] = $variation->get_rating_count();
586
  $this->productsList[ $this->pi ]['rating_average'] = $variation->get_average_rating();
587
- $this->productsList[ $this->pi ]['tags'] = $this->getProductTaxonomy($parentId,"product_tag");
588
  $this->productsList[ $this->pi ]['item_group_id'] = $variation->get_parent_id();
589
  $this->productsList[ $this->pi ]['sku'] = $variation->get_sku();
590
  $this->productsList[ $this->pi ]['parent_sku'] = $parent->get_sku();
@@ -611,9 +612,9 @@ class Woo_Feed_Products {
611
  if ( ! empty( $from ) && ! empty( $to ) ) {
612
  $from = gmdate( "c", strtotime( $from ) );
613
  $to = gmdate( "c", strtotime( $to ) );
614
- $this->productsList[ $this->pi ]['sale_price_effective_date'] = "$from" . "/" . "$to";
615
  } else {
616
- $this->productsList[ $this->pi ]['sale_price_effective_date'] = "";
617
  }
618
 
619
  # Get all Attributes and their values
@@ -661,14 +662,14 @@ class Woo_Feed_Products {
661
  if ( empty( $regularPrice ) ) $regularPrice = 0;
662
  $currentPrice = $product->get_price();
663
  if ( empty( $currentPrice ) ) $currentPrice = 0;
664
- if ( $type == "regular" ) {
665
  if ( $taxable ) {
666
- $regularPrice = $this->getPriceWithTax($product);
667
  }
668
  $sum += $regularPrice;
669
- }else {
670
  if ( $taxable ) {
671
- $currentPrice = $this->getPriceWithTax($product);
672
  }
673
  $sum += $currentPrice;
674
  }
@@ -717,13 +718,13 @@ class Woo_Feed_Products {
717
  }
718
  $short_description = $this->remove_short_codes($short_description);
719
 
720
- $this->productsList[ $this->pi ]["id"] = $variation->get_id();
721
- $this->productsList[ $this->pi ]["title"] = $variationTitle;
722
- $this->productsList[ $this->pi ]["description"] = $description;
723
  $this->productsList[ $this->pi ]['variation_type'] = $variation->get_type();
724
 
725
  $this->productsList[ $this->pi ]['short_description'] = $short_description;
726
- $this->productsList[ $this->pi ]['product_type'] = strip_tags(wc_get_product_category_list($variation->get_parent_id(),">",""));
727
  $this->productsList[ $this->pi ]['link'] = $variation->get_permalink();
728
  $this->productsList[ $this->pi ]['ex_link'] = $variation->get_permalink();
729
 
@@ -752,15 +753,15 @@ class Woo_Feed_Products {
752
  }
753
  }
754
 
755
- $this->productsList[ $this->pi ]['images'] = implode( ",", $imgUrls );
756
- $this->productsList[ $this->pi ]['condition'] = "new";
757
  $this->productsList[ $this->pi ]['type'] = $variation->get_type();
758
- $this->productsList[ $this->pi ]['is_bundle'] = "no";
759
- $this->productsList[ $this->pi ]['multipack'] = "";
760
  $this->productsList[ $this->pi ]['visibility'] = $variation->get_catalog_visibility();
761
  $this->productsList[ $this->pi ]['rating_total'] = $variation->get_rating_count();
762
  $this->productsList[ $this->pi ]['rating_average'] = $variation->get_average_rating();
763
- $this->productsList[ $this->pi ]['tags'] = strip_tags(wc_get_product_tag_list($id,","));
764
  $this->productsList[ $this->pi ]['item_group_id'] = $variation->get_parent_id();
765
  $this->productsList[ $this->pi ]['sku'] = $variation->get_sku();
766
  $this->productsList[ $this->pi ]['parent_sku'] = $parent->get_sku();
@@ -785,9 +786,9 @@ class Woo_Feed_Products {
785
  if ( ! empty( $from ) && ! empty( $to ) ) {
786
  $from = gmdate( "c", strtotime( $from ) );
787
  $to = gmdate( "c", strtotime( $to ) );
788
- $this->productsList[ $this->pi ]['sale_price_effective_date'] = "$from" . "/" . "$to";
789
  } else {
790
- $this->productsList[ $this->pi ]['sale_price_effective_date'] = "";
791
  }
792
 
793
  # Get all Attributes and their values
@@ -806,7 +807,7 @@ class Woo_Feed_Products {
806
  // foreach ($metas as $mKey=>$meta){
807
  // if($mKey!="_product_attributes"){
808
  // $metaValue=get_post_meta($id,$mKey,true);
809
- // $this->productsList[ $this->pi ]["wf_cattr_".$mKey]=(!empty($metaValue))?$metaValue:"";
810
  // }
811
  // }
812
  // }
@@ -815,7 +816,7 @@ class Woo_Feed_Products {
815
  // $taxonomies=get_post_taxonomies($id);
816
  // if(!empty($taxonomies)){
817
  // foreach ($taxonomies as $tKey=>$taxonomy){
818
- // $this->productsList[ $this->pi ]["wf_taxo_".$taxonomy]=strip_tags(get_the_term_list($id,$taxonomy,"",",",""));
819
  // }
820
  // }
821
  $this->pi++;
@@ -831,10 +832,10 @@ class Woo_Feed_Products {
831
 
832
  /**
833
  * Get WooCommerce Product
834
- * @param string $feedRule
835
  * @return array
836
  */
837
- public function woo_feed_get_visible_product( $feedRule = "" ) {
838
  wp_cache_delete( 'wf_check_duplicate', 'options' );
839
  $this->feedRule = $feedRule;
840
  $limit = ! empty( $feedRule['Limit'] ) && is_numeric( $feedRule['Limit'] ) ? absint( $feedRule['Limit'] ) : '2000';
@@ -853,7 +854,7 @@ class Woo_Feed_Products {
853
  }
854
 
855
 
856
- if ( $offset == '0' ) {
857
  delete_option( "wf_check_duplicate" );
858
  }
859
  $getIDs = get_option( "wf_check_duplicate" );
@@ -886,7 +887,7 @@ class Woo_Feed_Products {
886
  continue;
887
  }
888
 
889
- $type1 = "";
890
  if ( is_object( $product ) && $product->is_type( 'simple' ) ) {
891
  # No variations to product
892
  $type1 = "simple";
@@ -910,34 +911,34 @@ class Woo_Feed_Products {
910
  continue;
911
  }
912
 
913
- if ( $post->post_status == 'trash' ) {
914
  continue;
915
  }
916
 
917
 
918
- if ( get_post_type() == 'product_variation' && $this->feedRule['provider'] != 'facebook' ) {
919
- if ( $this->parentID != 0 ) {
920
 
921
  $status = get_post( $this->childID );
922
  if ( ! $status || ! is_object( $status ) ) {
923
  continue;
924
  }
925
 
926
- if ( $status->post_status == "trash" ) {
927
  continue;
928
  }
929
 
930
  $parentStatus = get_post( $this->parentID );
931
- if ( $parentStatus && is_object( $parentStatus ) && $parentStatus->post_status != 'publish' ) {
932
  continue;
933
  }
934
 
935
  # Check Valid URL
936
  $mainImage = wp_get_attachment_url( $product->get_image_id() );
937
- $link = $product->get_permalink( $this->childID );
938
 
939
- if ( $this->feedRule['provider'] != 'custom' ) {
940
- if ( substr( trim( $link ), 0, 4 ) !== "http" && substr( trim( $mainImage ), 0, 4 ) !== "http" ) {
941
  continue;
942
  }
943
  }
@@ -969,9 +970,9 @@ class Woo_Feed_Products {
969
  $this->productsList[ $i ]['short_description'] = $post->post_excerpt;
970
  }
971
 
972
- $this->productsList[ $i ]['product_type'] = $this->get_product_term_list( $post->ID, 'product_cat', "", ">" );
973
  $this->productsList[ $i ]['link'] = $link;
974
- $this->productsList[ $i ]['ex_link'] = "";
975
  $this->productsList[ $i ]['image'] = $this->get_formatted_url( $mainImage );
976
 
977
  # Featured Image
@@ -998,8 +999,8 @@ class Woo_Feed_Products {
998
  $mKey ++;
999
  }
1000
  }
1001
- $this->productsList[ $i ]['images'] = implode( ",", $imageLinks );
1002
- $this->productsList[ $i ]['condition'] = "New";
1003
  $this->productsList[ $i ]['type'] = $product->get_type();
1004
  $this->productsList[ $i ]['visibility'] = $this->getAttributeValue( $this->childID, "_visibility" );
1005
  $this->productsList[ $i ]['rating_total'] = $product->get_rating_count();
@@ -1012,11 +1013,11 @@ class Woo_Feed_Products {
1012
  $this->productsList[ $i ]['sale_price_sdate'] = $this->get_date( $this->childID, "_sale_price_dates_from" );
1013
  $this->productsList[ $i ]['sale_price_edate'] = $this->get_date( $this->childID, "_sale_price_dates_to" );
1014
  $this->productsList[ $i ]['price'] = ( $product->get_regular_price() ) ? $product->get_regular_price() : $product->get_price();
1015
- $this->productsList[ $i ]['sale_price'] = ( $product->get_sale_price() ) ? $product->get_sale_price() : "";
1016
- $this->productsList[ $i ]['weight'] = ( $product->get_weight() ) ? $product->get_weight() : "";
1017
- $this->productsList[ $i ]['width'] = ( $product->get_width() ) ? $product->get_width() : "";
1018
- $this->productsList[ $i ]['height'] = ( $product->get_height() ) ? $product->get_height() : "";
1019
- $this->productsList[ $i ]['length'] = ( $product->get_length() ) ? $product->get_length() : "";
1020
 
1021
  # Sale price effective date
1022
  $from = $this->sale_price_effective_date( $this->childID, '_sale_price_dates_from' );
@@ -1024,19 +1025,19 @@ class Woo_Feed_Products {
1024
  if ( ! empty( $from ) && ! empty( $to ) ) {
1025
  $from = gmdate( "c", strtotime( $from ) );
1026
  $to = gmdate( "c", strtotime( $to ) );
1027
- $this->productsList[ $i ]['sale_price_effective_date'] = "$from" . "/" . "$to";
1028
  } else {
1029
- $this->productsList[ $i ]['sale_price_effective_date'] = "";
1030
  }
1031
  }
1032
  } elseif ( get_post_type() == 'product' ) {
1033
- if ( $type1 == 'simple' ) {
1034
 
1035
  $mainImage = wp_get_attachment_url( $product->get_image_id() );
1036
  $link = get_permalink( $post->ID );
1037
 
1038
- if ( $this->feedRule['provider'] != 'custom' ) {
1039
- if ( substr( trim( $link ), 0, 4 ) !== "http" && substr( trim( $mainImage ), 0, 4 ) !== "http" ) {
1040
  continue;
1041
  }
1042
  }
@@ -1057,9 +1058,9 @@ class Woo_Feed_Products {
1057
  $this->productsList[ $i ]['description'] = $post->post_content;
1058
 
1059
  $this->productsList[ $i ]['short_description'] = $post->post_excerpt;
1060
- $this->productsList[ $i ]['product_type'] = $this->get_product_term_list( $post->ID, 'product_cat', "", ">" );
1061
  $this->productsList[ $i ]['link'] = $link;
1062
- $this->productsList[ $i ]['ex_link'] = "";
1063
  $this->productsList[ $i ]['image'] = $this->get_formatted_url( $mainImage );
1064
 
1065
  # Featured Image
@@ -1086,9 +1087,9 @@ class Woo_Feed_Products {
1086
  $mKey ++;
1087
  }
1088
  }
1089
- $this->productsList[ $i ]['images'] = implode( ",", $imageLinks );
1090
 
1091
- $this->productsList[ $i ]['condition'] = "New";
1092
  $this->productsList[ $i ]['type'] = $product->get_type();
1093
  $this->productsList[ $i ]['visibility'] = $this->getAttributeValue( $post->ID, "_visibility" );
1094
  $this->productsList[ $i ]['rating_total'] = $product->get_rating_count();
@@ -1103,11 +1104,11 @@ class Woo_Feed_Products {
1103
  $this->productsList[ $i ]['sale_price_sdate'] = $this->get_date( $post->ID, "_sale_price_dates_from" );
1104
  $this->productsList[ $i ]['sale_price_edate'] = $this->get_date( $post->ID, "_sale_price_dates_to" );
1105
  $this->productsList[ $i ]['price'] = ( $product->get_regular_price() ) ? $product->get_regular_price() : $product->get_price();
1106
- $this->productsList[ $i ]['sale_price'] = ( $product->get_sale_price() ) ? $product->get_sale_price() : "";
1107
- $this->productsList[ $i ]['weight'] = ( $product->get_weight() ) ? $product->get_weight() : "";
1108
- $this->productsList[ $i ]['width'] = ( $product->get_width() ) ? $product->get_width() : "";
1109
- $this->productsList[ $i ]['height'] = ( $product->get_height() ) ? $product->get_height() : "";
1110
- $this->productsList[ $i ]['length'] = ( $product->get_length() ) ? $product->get_length() : "";
1111
 
1112
  # Sale price effective date
1113
  $from = $this->sale_price_effective_date( $post->ID, '_sale_price_dates_from' );
@@ -1115,20 +1116,20 @@ class Woo_Feed_Products {
1115
  if ( ! empty( $from ) && ! empty( $to ) ) {
1116
  $from = gmdate( "c", strtotime( $from ) );
1117
  $to = gmdate( "c", strtotime( $to ) );
1118
- $this->productsList[ $i ]['sale_price_effective_date'] = "$from" . "/" . "$to";
1119
  } else {
1120
- $this->productsList[ $i ]['sale_price_effective_date'] = "";
1121
  }
1122
  }
1123
- elseif ( $type1 == 'external' ) {
1124
 
1125
  $mainImage = wp_get_attachment_url( $product->get_image_id() );
1126
 
1127
  $getLink = new WC_Product_External( $post->ID );
1128
  $EX_link = $getLink->get_product_url();
1129
  $link = get_permalink( $post->ID );
1130
- if ( $this->feedRule['provider'] != 'custom' ) {
1131
- if ( substr( trim( $link ), 0, 4 ) !== "http" && substr( trim( $mainImage ), 0, 4 ) !== "http" ) {
1132
  continue;
1133
  }
1134
  }
@@ -1139,7 +1140,7 @@ class Woo_Feed_Products {
1139
  $this->productsList[ $i ]['description'] = do_shortcode( $post->post_content );
1140
 
1141
  $this->productsList[ $i ]['short_description'] = $post->post_excerpt;
1142
- $this->productsList[ $i ]['product_type'] = $this->get_product_term_list( $post->ID, 'product_cat', "", ">" );
1143
  $this->productsList[ $i ]['link'] = $link;
1144
  $this->productsList[ $i ]['ex_link'] = $EX_link;
1145
  $this->productsList[ $i ]['image'] = $this->get_formatted_url( $mainImage );
@@ -1168,9 +1169,9 @@ class Woo_Feed_Products {
1168
  $mKey ++;
1169
  }
1170
  }
1171
- $this->productsList[ $i ]['images'] = implode( ",", $imageLinks );
1172
 
1173
- $this->productsList[ $i ]['condition'] = "New";
1174
  $this->productsList[ $i ]['type'] = $product->get_type();
1175
  $this->productsList[ $i ]['visibility'] = $this->getAttributeValue( $post->ID, "_visibility" );
1176
  $this->productsList[ $i ]['rating_total'] = $product->get_rating_count();
@@ -1186,11 +1187,11 @@ class Woo_Feed_Products {
1186
  $this->productsList[ $i ]['sale_price_sdate'] = $this->get_date( $post->ID, "_sale_price_dates_from" );
1187
  $this->productsList[ $i ]['sale_price_edate'] = $this->get_date( $post->ID, "_sale_price_dates_to" );
1188
  $this->productsList[ $i ]['price'] = ( $product->get_regular_price() ) ? $product->get_regular_price() : $product->get_price();
1189
- $this->productsList[ $i ]['sale_price'] = ( $product->get_sale_price() ) ? $product->get_sale_price() : "";
1190
- $this->productsList[ $i ]['weight'] = ( $product->get_weight() ) ? $product->get_weight() : "";
1191
- $this->productsList[ $i ]['width'] = ( $product->get_width() ) ? $product->get_width() : "";
1192
- $this->productsList[ $i ]['height'] = ( $product->get_height() ) ? $product->get_height() : "";
1193
- $this->productsList[ $i ]['length'] = ( $product->get_length() ) ? $product->get_length() : "";
1194
 
1195
  # Sale price effective date
1196
  $from = $this->sale_price_effective_date( $post->ID, '_sale_price_dates_from' );
@@ -1198,12 +1199,12 @@ class Woo_Feed_Products {
1198
  if ( ! empty( $from ) && ! empty( $to ) ) {
1199
  $from = gmdate( "c", strtotime( $from ) );
1200
  $to = gmdate( "c", strtotime( $to ) );
1201
- $this->productsList[ $i ]['sale_price_effective_date'] = "$from" . "/" . "$to";
1202
  } else {
1203
- $this->productsList[ $i ]['sale_price_effective_date'] = "";
1204
  }
1205
  }
1206
- elseif ( $type1 == 'grouped' ) {
1207
 
1208
  $grouped = new WC_Product_Grouped( $post->ID );
1209
  $children = $grouped->get_children();
@@ -1215,7 +1216,7 @@ class Woo_Feed_Products {
1215
  $this->childID = $child;
1216
  $post = get_post( $this->childID );
1217
 
1218
- if ( $post->post_status == 'trash' ) {
1219
  continue;
1220
  }
1221
 
@@ -1235,8 +1236,8 @@ class Woo_Feed_Products {
1235
 
1236
  $mainImage = wp_get_attachment_url( $product->get_image_id() );
1237
  $link = get_permalink( $post->ID );
1238
- if ( $this->feedRule['provider'] != 'custom' ) {
1239
- if ( substr( trim( $link ), 0, 4 ) !== "http" && substr( trim( $mainImage ), 0, 4 ) !== "http" ) {
1240
  continue;
1241
  }
1242
  }
@@ -1247,9 +1248,9 @@ class Woo_Feed_Products {
1247
  $this->productsList[ $i ]['description'] = do_shortcode( $post->post_content );
1248
 
1249
  $this->productsList[ $i ]['short_description'] = $post->post_excerpt;
1250
- $this->productsList[ $i ]['product_type'] = $this->get_product_term_list( $post->ID, 'product_cat', "", ">" );
1251
  $this->productsList[ $i ]['link'] = $link;
1252
- $this->productsList[ $i ]['ex_link'] = "";
1253
  $this->productsList[ $i ]['image'] = $this->get_formatted_url( $mainImage );
1254
 
1255
  # Featured Image
@@ -1276,8 +1277,8 @@ class Woo_Feed_Products {
1276
  $mKey ++;
1277
  }
1278
  }
1279
- $this->productsList[ $i ]['images'] = implode( ",", $imageLinks );
1280
- $this->productsList[ $i ]['condition'] = "New";
1281
  $this->productsList[ $i ]['type'] = $product->get_type();
1282
  $this->productsList[ $i ]['visibility'] = $this->getAttributeValue( $post->ID, "_visibility" );
1283
  $this->productsList[ $i ]['rating_total'] = $product->get_rating_count();
@@ -1293,11 +1294,11 @@ class Woo_Feed_Products {
1293
  $this->productsList[ $i ]['sale_price_sdate'] = $this->get_date( $post->ID, "_sale_price_dates_from" );
1294
  $this->productsList[ $i ]['sale_price_edate'] = $this->get_date( $post->ID, "_sale_price_dates_to" );
1295
  $this->productsList[ $i ]['price'] = ( $product->get_regular_price() ) ? $product->get_regular_price() : $product->get_price();
1296
- $this->productsList[ $i ]['sale_price'] = ( $product->get_sale_price() ) ? $product->get_sale_price() : "";
1297
- $this->productsList[ $i ]['weight'] = ( $product->get_weight() ) ? $product->get_weight() : "";
1298
- $this->productsList[ $i ]['width'] = ( $product->get_width() ) ? $product->get_width() : "";
1299
- $this->productsList[ $i ]['height'] = ( $product->get_height() ) ? $product->get_height() : "";
1300
- $this->productsList[ $i ]['length'] = ( $product->get_length() ) ? $product->get_length() : "";
1301
 
1302
  # Sale price effective date
1303
  $from = $this->sale_price_effective_date( $post->ID, '_sale_price_dates_from' );
@@ -1305,21 +1306,21 @@ class Woo_Feed_Products {
1305
  if ( ! empty( $from ) && ! empty( $to ) ) {
1306
  $from = gmdate( "c", strtotime( $from ) );
1307
  $to = gmdate( "c", strtotime( $to ) );
1308
- $this->productsList[ $i ]['sale_price_effective_date'] = "$from" . "/" . "$to";
1309
  } else {
1310
- $this->productsList[ $i ]['sale_price_effective_date'] = "";
1311
  }
1312
  }
1313
  }
1314
  }
1315
- elseif ( $type1 == 'variable' && $product->has_child() ) {
1316
 
1317
  # Check Valid URL
1318
  $mainImage = wp_get_attachment_url( $product->get_image_id() );
1319
  $link = get_permalink( $post->ID );
1320
 
1321
- if ( $this->feedRule['provider'] != 'custom' ) {
1322
- if ( substr( trim( $link ), 0, 4 ) !== "http" && substr( trim( $mainImage ), 0, 4 ) !== "http" ) {
1323
  continue;
1324
  }
1325
  }
@@ -1331,9 +1332,9 @@ class Woo_Feed_Products {
1331
  $this->productsList[ $i ]['description'] = $post->post_content;
1332
 
1333
  $this->productsList[ $i ]['short_description'] = $post->post_excerpt;
1334
- $this->productsList[ $i ]['product_type'] = $this->get_product_term_list( $post->ID, 'product_cat', "", ">" );
1335
  $this->productsList[ $i ]['link'] = $link;
1336
- $this->productsList[ $i ]['ex_link'] = "";
1337
  $this->productsList[ $i ]['image'] = $this->get_formatted_url( $mainImage );
1338
 
1339
  # Featured Image
@@ -1360,9 +1361,9 @@ class Woo_Feed_Products {
1360
  $mKey ++;
1361
  }
1362
  }
1363
- $this->productsList[ $i ]['images'] = implode( ",", $imageLinks );
1364
 
1365
- $this->productsList[ $i ]['condition'] = "New";
1366
  $this->productsList[ $i ]['type'] = $product->get_type();
1367
  $this->productsList[ $i ]['visibility'] = $this->getAttributeValue( $post->ID, "_visibility" );
1368
  $this->productsList[ $i ]['rating_total'] = $product->get_rating_count();
@@ -1380,11 +1381,11 @@ class Woo_Feed_Products {
1380
  $price = ( $product->get_price() ) ? $product->get_price() : false;
1381
 
1382
  $this->productsList[ $i ]['price'] = ( $product->get_regular_price() ) ? $product->get_regular_price() : $price;
1383
- $this->productsList[ $i ]['sale_price'] = ( $product->get_sale_price() ) ? $product->get_sale_price() : "";
1384
- $this->productsList[ $i ]['weight'] = ( $product->get_weight() ) ? $product->get_weight() : "";
1385
- $this->productsList[ $i ]['width'] = ( $product->get_width() ) ? $product->get_width() : "";
1386
- $this->productsList[ $i ]['height'] = ( $product->get_height() ) ? $product->get_height() : "";
1387
- $this->productsList[ $i ]['length'] = ( $product->get_length() ) ? $product->get_length() : "";
1388
 
1389
  # Sale price effective date
1390
  $from = $this->sale_price_effective_date( $post->ID, '_sale_price_dates_from' );
@@ -1392,15 +1393,15 @@ class Woo_Feed_Products {
1392
  if ( ! empty( $from ) && ! empty( $to ) ) {
1393
  $from = gmdate( "c", strtotime( $from ) );
1394
  $to = gmdate( "c", strtotime( $to ) );
1395
- $this->productsList[ $i ]['sale_price_effective_date'] = "$from" . "/" . "$to";
1396
  } else {
1397
- $this->productsList[ $i ]['sale_price_effective_date'] = "";
1398
  }
1399
  }
1400
  }
1401
  $i ++;
1402
  endwhile;
1403
- wp_reset_query();
1404
 
1405
  if ( $getIDs ) {
1406
  $mergedIds = array_merge( $getIDs, $this->idExist );
@@ -1424,7 +1425,7 @@ class Woo_Feed_Products {
1424
  */
1425
  public function remove_short_codes( $content ) {
1426
  if ( empty( $content ) ) {
1427
- return "";
1428
  }
1429
  $content = do_shortcode( $content );
1430
  $content = $this->stripInvalidXml( $content );
@@ -1444,21 +1445,21 @@ class Woo_Feed_Products {
1444
  * @return string
1445
  */
1446
  public function stripInvalidXml( $value ) {
1447
- $ret = "";
1448
- $current = "";
1449
- if ( empty($value) ) {
1450
  return $ret;
1451
  }
1452
- $length = strlen($value);
1453
  for ( $i = 0; $i < $length; $i++ ) {
1454
  $current = ord($value[ $i ]);
1455
- if ( ($current == 0x9) || ($current == 0xA) || ($current == 0xD) || (($current >= 0x20) && ($current <= 0xD7FF)) || (($current >= 0xE000) && ($current <= 0xFFFD)) || (($current >= 0x10000) && ($current <= 0x10FFFF)) ) {
1456
  $ret .= chr($current);
1457
  }
1458
  else {
1459
  $ret .= "";
1460
  }
1461
  }
 
1462
  return $ret;
1463
  }
1464
 
@@ -1468,14 +1469,14 @@ class Woo_Feed_Products {
1468
  * @param $url
1469
  * @return bool|string
1470
  */
1471
- public function get_formatted_url( $url = "" ) {
1472
  if ( ! empty($url) ) {
1473
- if ( substr(trim($url), 0, 4) === "http" || substr(trim($url), 0, 3) === "ftp" || substr(trim($url), 0, 4) === "sftp" ) {
1474
- return rtrim($url, "/");
1475
  } else {
1476
  $base = get_site_url();
1477
  $url = $base . $url;
1478
- return rtrim($url, "/");
1479
  }
1480
  }
1481
  return $url;
@@ -1492,7 +1493,7 @@ class Woo_Feed_Products {
1492
  public function get_date( $id, $name ) {
1493
  $date = $this->getAttributeValue($id, $name);
1494
  if ( $date ) {
1495
- return gmdate("Y-m-d", $date);
1496
  }
1497
  return false;
1498
  }
@@ -1505,11 +1506,12 @@ class Woo_Feed_Products {
1505
  * @return bool|mixed
1506
  */
1507
  public function get_quantity( $id, $name ) {
1508
- $qty = $this->getAttributeValue($id, $name);
1509
  if ( $qty ) {
1510
  return $qty + 0;
1511
  }
1512
- return "0";
 
1513
  }
1514
 
1515
  /**
@@ -1553,18 +1555,20 @@ class Woo_Feed_Products {
1553
  */
1554
 
1555
  public function additionalImages( $Id ) {
1556
- $ids = $this->getAttributeValue($Id,"_product_image_gallery");
1557
- $imgIds = ! empty($ids) ? explode(",",$ids) : "";
1558
-
1559
  $images = array();
1560
- if ( ! empty($imgIds) ) {
1561
  foreach ( $imgIds as $key => $value ) {
1562
  if ( $key < 10 ) {
1563
- $images[ $key ] = wp_get_attachment_url($value);
1564
  }
1565
  }
 
1566
  return $images;
1567
  }
 
1568
  return false;
1569
  }
1570
 
@@ -1576,15 +1580,16 @@ class Woo_Feed_Products {
1576
  * @return string
1577
  */
1578
  public function availability( $id ) {
1579
- $status = $this->getProductMeta($id,"_stock_status");
1580
  if ( $status ) {
1581
- if ( $status == 'instock' ) {
1582
- return "in stock";
1583
- } elseif ( $status == 'outofstock' ) {
1584
- return "out of stock";
1585
  }
1586
  }
1587
- return "in stock";
 
1588
  }
1589
 
1590
  /**
@@ -1597,30 +1602,30 @@ class Woo_Feed_Products {
1597
  * @return string
1598
  */
1599
  public function getProductAttribute( $id,$attr ) {
1600
-
1601
- $attr = str_replace("wf_attr_", "",$attr);
1602
-
1603
- if ( woo_feed_wc_version_check(3.1) ) {
1604
  # Get Product
1605
- $product = wc_get_product($id);
1606
-
1607
- if ( ! is_object($product) ) {
1608
- return "";
1609
  }
1610
-
1611
- if ( woo_feed_wc_version_check(3.6) ) {
1612
- $attr = str_replace("pa_", "",$attr);
1613
- }
1614
-
1615
- $value = $product->get_attribute($attr);
1616
-
1617
- if ( ! empty($value) ) {
1618
- $value = trim($value);
1619
  }
1620
 
1621
  return $value;
1622
- }else {
1623
- return implode(',', wc_get_product_terms($id,$attr, array( 'fields' => 'names' )));
1624
  }
1625
  }
1626
 
@@ -1636,13 +1641,13 @@ class Woo_Feed_Products {
1636
  */
1637
 
1638
  public function getProductMeta( $id,$meta ) {
1639
-
1640
- $meta = str_replace("wf_cattr_", "",$meta);
1641
-
1642
- if ( strpos($meta, 'attribute_pa') !== false ) {
1643
- return $this->getProductAttribute($id,str_replace("attribute_","",$meta));
1644
- }else {
1645
- return get_post_meta($id, $meta, true);
1646
  }
1647
  }
1648
 
@@ -1659,7 +1664,7 @@ class Woo_Feed_Products {
1659
 
1660
  return $this->getProductMeta($id,$name);
1661
  // if (strpos($name, 'attribute_pa') !== false) {
1662
- // $taxonomy = str_replace("attribute_","",$name);
1663
  // $meta = get_post_meta($id,$name, true);
1664
  // $term = get_term_by('slug', $meta, $taxonomy);
1665
  // return $term->name;
@@ -1677,7 +1682,8 @@ class Woo_Feed_Products {
1677
  * @return string
1678
  */
1679
  public function sale_price_effective_date( $id, $name ) {
1680
- return ($date = $this->getAttributeValue($id, $name)) ? date_i18n('Y-m-d', $date) : "";
 
1681
  }
1682
 
1683
 
@@ -1692,64 +1698,13 @@ class Woo_Feed_Products {
1692
  $globalAttributes = wc_get_attribute_taxonomy_labels();
1693
  if ( count( $globalAttributes ) ) {
1694
  foreach ( $globalAttributes as $key => $value ) {
1695
- $info[ "wf_attr_pa_" . $key ] = $value;
1696
  }
1697
  }
1698
 
1699
  return $info;
1700
  }
1701
-
1702
-
1703
- /**
1704
- * Get All Custom Attributes
1705
- * @return array|bool
1706
- */
1707
- public function getAllCustomAttributes() {
1708
- global $wpdb;
1709
- $info = array();
1710
- //Load the main attributes
1711
- /** @noinspection SqlResolve,SpellCheckingInspection */
1712
- $sql = "SELECT DISTINCT( meta_key ) FROM $wpdb->postmeta
1713
- WHERE post_id IN (
1714
- SELECT ID FROM $wpdb->posts WHERE post_type = 'product' OR post_type = 'product_variation'
1715
- ) AND (
1716
- meta_key NOT IN ('_edit_lock', '_wp_old_slug', '_edit_last', '_yith_wcpb_bundle_data', '_wpcom_is_markdown', '_downloadable_files', '_product_attributes', '_children', '_et_builder_version' )
1717
- AND meta_key NOT LIKE '%_et_pb_%'
1718
- )";
1719
- $data = $wpdb->get_results($sql);
1720
- if ( count( $data ) ) {
1721
- foreach ( $data as $key => $value ) {
1722
- /** @noinspection SpellCheckingInspection */
1723
- $info[ "wf_cattr_" . $value->meta_key ] = $value->meta_key;
1724
- }
1725
- return $info;
1726
- }
1727
- return false;
1728
- }
1729
-
1730
-
1731
- /**
1732
- * Get Category Mappings
1733
- * @return bool|array
1734
- */
1735
- public function getCustomCategoryMappedAttributes() {
1736
- global $wpdb;
1737
-
1738
- //Load Custom Category Mapped Attributes
1739
- $sql = $wpdb->prepare("SELECT * FROM $wpdb->options WHERE option_name LIKE %s;", "wf_cmapping_%");
1740
- $data = $wpdb->get_results($sql);
1741
- if ( count($data) ) {
1742
- foreach ( $data as $key => $value ) {
1743
- $info[ $key ] = $value->option_name;
1744
- }
1745
-
1746
- return $info;
1747
- }
1748
-
1749
- return false;
1750
- }
1751
-
1752
-
1753
  /**
1754
  * Local Attribute List to map product value with merchant attributes
1755
  *
@@ -1757,98 +1712,146 @@ class Woo_Feed_Products {
1757
  *
1758
  * @return string
1759
  */
1760
- public function attributeDropdown( $selected = "" ) {
1761
 
1762
- $attributeDropdown = wp_cache_get( 'woo-feed-products-attributes' );
1763
 
1764
- if ( ! $attributeDropdown ) {
1765
  $attributes = array(
1766
- "id" => esc_attr__( "Product Id", 'woo-feed' ),
1767
- "title" => esc_attr__( "Product Title", 'woo-feed' ),
1768
- "description" => esc_attr__( "Product Description", 'woo-feed' ),
1769
- "short_description" => esc_attr__( "Product Short Description", 'woo-feed' ),
1770
- "product_type" => esc_attr__( "Product Local Category", 'woo-feed' ),
1771
- "link" => esc_attr__( "Product URL", 'woo-feed' ),
1772
- "ex_link" => esc_attr__( "External Product URL", 'woo-feed' ),
1773
- "condition" => esc_attr__( "Condition", 'woo-feed' ),
1774
- "item_group_id" => esc_attr__( "Parent Id [Group Id]", 'woo-feed' ),
1775
- "sku" => esc_attr__( "SKU", 'woo-feed' ),
1776
- "parent_sku" => esc_attr__( "Parent SKU", 'woo-feed' ),
1777
- "availability" => esc_attr__( "Availability", 'woo-feed' ),
1778
- "quantity" => esc_attr__( "Quantity", 'woo-feed' ),
1779
- "price" => esc_attr__( "Regular Price", 'woo-feed' ),
1780
- "current_price" => esc_attr__( "Current Price", 'woo-feed' ),
1781
- "sale_price" => esc_attr__( "Sale Price", 'woo-feed' ),
1782
- "price_with_tax" => esc_attr__( "Regular Price With Tax", 'woo-feed' ),
1783
- "current_price_with_tax" => esc_attr__( "Current Price With Tax", 'woo-feed' ),
1784
- "sale_price_with_tax" => esc_attr__( "Sale Price With Tax", 'woo-feed' ),
1785
- "sale_price_sdate" => esc_attr__( "Sale Start Date", 'woo-feed' ),
1786
- "sale_price_edate" => esc_attr__( "Sale End Date", 'woo-feed' ),
1787
- "weight" => esc_attr__( "Weight", 'woo-feed' ),
1788
- "width" => esc_attr__( "Width", 'woo-feed' ),
1789
- "height" => esc_attr__( "Height", 'woo-feed' ),
1790
- "length" => esc_attr__( "Length", 'woo-feed' ),
1791
- "shipping_class" => esc_attr__( "Shipping Class", 'woo-feed' ),
1792
- "type" => esc_attr__( "Product Type", 'woo-feed' ),
1793
- "variation_type" => esc_attr__( "Variation Type", 'woo-feed' ),
1794
- "visibility" => esc_attr__( "Visibility", 'woo-feed' ),
1795
- "rating_total" => esc_attr__( "Total Rating", 'woo-feed' ),
1796
- "rating_average" => esc_attr__( "Average Rating", 'woo-feed' ),
1797
- "tags" => esc_attr__( "Tags", 'woo-feed' ),
1798
- "sale_price_effective_date" => esc_attr__( "Sale Price Effective Date", 'woo-feed' ),
1799
- "is_bundle" => esc_attr__( "Is Bundle", 'woo-feed' ),
1800
- "date_created" => esc_attr__( "Date Created", 'woo-feed' ),
1801
- "date_updated" => esc_attr__( "Date Updated", 'woo-feed' ),
 
 
1802
  );
1803
- $images = array(
1804
- "image" => esc_attr__( "Main Image", 'woo-feed' ),
1805
- "feature_image" => esc_attr__( "Featured Image", 'woo-feed' ),
1806
- "images" => esc_attr__( "Images [Comma Separated]", 'woo-feed' ),
1807
- "image_1" => esc_attr__( "Additional Image 1", 'woo-feed' ),
1808
- "image_2" => esc_attr__( "Additional Image 2", 'woo-feed' ),
1809
- "image_3" => esc_attr__( "Additional Image 3", 'woo-feed' ),
1810
- "image_4" => esc_attr__( "Additional Image 4", 'woo-feed' ),
1811
- "image_5" => esc_attr__( "Additional Image 5", 'woo-feed' ),
1812
- "image_6" => esc_attr__( "Additional Image 6", 'woo-feed' ),
1813
- "image_7" => esc_attr__( "Additional Image 7", 'woo-feed' ),
1814
- "image_8" => esc_attr__( "Additional Image 8", 'woo-feed' ),
1815
- "image_9" => esc_attr__( "Additional Image 9", 'woo-feed' ),
1816
- "image_10" => esc_attr__( "Additional Image 10", 'woo-feed' ),
1817
  );
1818
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1819
  # Primary Attributes
1820
- $attributeDropdown = "<option></option>";
1821
- if ( ! empty( $attributes ) ) {
1822
- $attributeDropdown .= sprintf( "<optgroup label=\"%s\">", esc_attr__( 'Primary Attributes', 'woo-feed' ) );
1823
  foreach ( $attributes as $key => $value ) {
1824
  $attributeDropdown .= sprintf( '<option value="%s">%s</option>', $key, $value );
1825
  }
1826
- $attributeDropdown .= "</optgroup>";
1827
  }
1828
 
1829
  # Additional Images
1830
- if ( ! empty( $images ) ) {
1831
- $attributeDropdown .= sprintf( "<optgroup label=\"%s\">", esc_attr__( 'Image Attributes', 'woo-feed' ) );
1832
  foreach ( $images as $key => $value ) {
1833
  $attributeDropdown .= sprintf( '<option value="%s">%s</option>', $key, $value );
1834
  }
1835
- $attributeDropdown .= "</optgroup>";
1836
  }
1837
 
1838
  # Get All WooCommerce Attributes
1839
- $vAttributes = $this->getAllAttributes();
1840
- if ( $vAttributes && ! empty( $vAttributes ) ) {
1841
- $attributeDropdown .= sprintf( "<optgroup label=\"%s\">", esc_attr__( 'Product Attributes', 'woo-feed' ) );
1842
  foreach ( $vAttributes as $key => $value ) {
1843
  $attributeDropdown .= sprintf( '<option value="%s">%s</option>', $key, $value );
1844
  }
1845
- $attributeDropdown .= "</optgroup>";
1846
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1847
  }
1848
 
1849
- if ( $selected && strpos( $attributeDropdown, 'value="'.$selected.'"' ) !== false ) {
1850
- $attributeDropdown = str_replace( 'value="'.$selected.'"', 'value="'.$selected.'"'.' selected', $attributeDropdown );
1851
  }
 
1852
  return $attributeDropdown;
1853
  }
1854
 
@@ -1858,22 +1861,7 @@ class Woo_Feed_Products {
1858
  public function load_attributes() {
1859
  # Get All WooCommerce Attributes
1860
  $vAttributes = $this->getAllAttributes();
1861
- update_option("wpfw_vAttributes", $vAttributes);
1862
- }
1863
-
1864
- /**
1865
- * Check WooCommerce Version
1866
- * @param string $version
1867
- * @return bool
1868
- */
1869
- public static function version_check( $version = '3.0' ) {
1870
- if ( class_exists( 'WooCommerce' ) ) {
1871
- global $woocommerce;
1872
- if ( version_compare( $woocommerce->version, $version, ">=" ) ) {
1873
- return true;
1874
- }
1875
- }
1876
- return false;
1877
  }
1878
 
1879
  /** Return product price with tax
@@ -1893,7 +1881,7 @@ class Woo_Feed_Products {
1893
  * @return false|string
1894
  */
1895
  public function format_product_date( $date ) {
1896
- return gmdate("Y-m-d",strtotime($date));
1897
  }
1898
 
1899
  /**
@@ -1905,13 +1893,13 @@ class Woo_Feed_Products {
1905
  * @return string
1906
  */
1907
  public function getProductTaxonomy( $id, $taxonomy ) {
1908
- $taxonomy = str_replace("wf_taxo_", "",$taxonomy);
1909
- $Taxo = get_the_term_list($id,$taxonomy,"",",","");
1910
-
1911
- if ( ! empty($Taxo) ) {
1912
- return strip_tags($Taxo);
1913
- }
1914
 
1915
- return "";
1916
  }
1917
  }
1
+ <?php /** @noinspection PhpDeprecationInspection */
2
+ /** @noinspection DuplicatedCode */
3
 
4
  /**
5
  * This is used to store all the information about wooCommerce store products
75
  global $wpdb;
76
 
77
 
78
+ $limit = '';
79
+ $offset = '';
80
+ if ( '' != $arg['limit'] && '-1' != $arg['limit'] && $arg['limit'] > 0 ) {
81
  $limit = absint( $arg['limit'] );
82
  $limit = "LIMIT $limit";
83
+
84
+
85
+ if ( '' != $arg['offset'] && '-1' != $arg['offset'] ) {
86
  $offset = absint( $arg['offset'] );
87
  $offset = "OFFSET $offset";
88
  }
97
  LEFT JOIN $wpdb->postmeta ON ($wpdb->posts.ID = $wpdb->postmeta.post_id)
98
  WHERE $wpdb->posts.post_status = 'publish' AND $wpdb->posts.post_type IN ('product','product_variation')
99
  ORDER BY ID DESC $limit $offset";
100
+ $products = $wpdb->get_results($query, ARRAY_A ); // phpcs:ignore
101
  return $products;
102
  }
103
 
117
  $offset = ! empty( $offset ) && is_numeric( $offset ) ? absint( $offset ) : '0';
118
 
119
  # Process Duplicate Products
120
+ if ( '0' == $offset ) {
121
  delete_option( "wf_check_duplicate" );
122
  }
123
  $getIDs = get_option( "wf_check_duplicate" );
147
  $prod = wc_get_product($productId);
148
 
149
  $id = $prod->get_id();
150
+
151
  if ( $getIDs ) {
152
+ if ( in_array( $id, $getIDs ) ) {
153
  continue;
154
+ } else {
155
+ array_push( $this->idExist, $id );
156
+ }
157
  }else {
158
  array_push($this->idExist,$id);
159
  }
162
 
163
  $simple = new WC_Product_Simple( $id );
164
 
165
+ $this->productsList[ $this->pi ]['id'] = $simple->get_id();
166
+ $this->productsList[ $this->pi ]['title'] = $simple->get_name();
167
+ $this->productsList[ $this->pi ]['description'] = $this->remove_short_codes($simple->get_description());
168
  $this->productsList[ $this->pi ]['variation_type'] = $simple->get_type();
169
 
170
  $this->productsList[ $this->pi ]['short_description'] = $this->remove_short_codes($simple->get_short_description());
171
+ $this->productsList[ $this->pi ]['product_type'] = wp_strip_all_tags( wc_get_product_category_list( $id, ">", '' ) );
172
  $this->productsList[ $this->pi ]['link'] = $simple->get_permalink();
173
  $this->productsList[ $this->pi ]['ex_link'] = $simple->get_permalink();
174
 
195
  }
196
  }
197
 
198
+ $this->productsList[ $this->pi ]['images'] = implode( ',', $imgUrls );
199
+ $this->productsList[ $this->pi ]['condition'] = 'new';
200
  $this->productsList[ $this->pi ]['type'] = $simple->get_type();
201
+ $this->productsList[ $this->pi ]['is_bundle'] = 'no';
202
+ $this->productsList[ $this->pi ]['multipack'] = '';
203
  $this->productsList[ $this->pi ]['visibility'] = $simple->get_catalog_visibility();
204
  $this->productsList[ $this->pi ]['rating_total'] = $simple->get_rating_count();
205
  $this->productsList[ $this->pi ]['rating_average'] = $simple->get_average_rating();
206
+ $this->productsList[ $this->pi ]['tags'] = $this->getProductTaxonomy($id,'product_tag');
207
  $this->productsList[ $this->pi ]['item_group_id'] = $simple->get_id();
208
  $this->productsList[ $this->pi ]['sku'] = $simple->get_sku();
209
  $this->productsList[ $this->pi ]['parent_sku'] = $simple->get_sku();
230
  if ( ! empty( $from ) && ! empty( $to ) ) {
231
  $from = gmdate( "c", strtotime( $from ) );
232
  $to = gmdate( "c", strtotime( $to ) );
233
+ $this->productsList[ $this->pi ]['sale_price_effective_date'] = $from . '/' . $to;
234
  } else {
235
+ $this->productsList[ $this->pi ]['sale_price_effective_date'] = '';
236
  }
237
 
238
  // # Get all Attributes and their values
248
 
249
  $external = new WC_Product_External( $id );
250
 
251
+ $this->productsList[ $this->pi ]['id'] = $external->get_id();
252
+ $this->productsList[ $this->pi ]['title'] = $external->get_name();
253
+ $this->productsList[ $this->pi ]['description'] = $this->remove_short_codes($external->get_description());
254
  $this->productsList[ $this->pi ]['variation_type'] = $external->get_type();
255
  $this->productsList[ $this->pi ]['short_description'] = $this->remove_short_codes($external->get_short_description());
256
+ $this->productsList[ $this->pi ]['product_type'] = wp_strip_all_tags( wc_get_product_category_list( $id, ">", '' ) );
257
  $this->productsList[ $this->pi ]['link'] = $external->get_permalink();
258
  $this->productsList[ $this->pi ]['ex_link'] = $external->get_product_url();
259
 
280
  }
281
  }
282
 
283
+ $this->productsList[ $this->pi ]['images'] = implode( ',', $imgUrls );
284
+ $this->productsList[ $this->pi ]['condition'] = 'new';
285
  $this->productsList[ $this->pi ]['type'] = $external->get_type();
286
+ $this->productsList[ $this->pi ]['is_bundle'] = 'no';
287
+ $this->productsList[ $this->pi ]['multipack'] = '';
288
  $this->productsList[ $this->pi ]['visibility'] = $external->get_catalog_visibility();
289
  $this->productsList[ $this->pi ]['rating_total'] = $external->get_rating_count();
290
  $this->productsList[ $this->pi ]['rating_average'] = $external->get_average_rating();
291
+ $this->productsList[ $this->pi ]['tags'] = $this->getProductTaxonomy($id,'product_tag');
292
  $this->productsList[ $this->pi ]['item_group_id'] = $external->get_id();
293
  $this->productsList[ $this->pi ]['sku'] = $external->get_sku();
294
  $this->productsList[ $this->pi ]['parent_sku'] = $external->get_sku();
315
  if ( ! empty( $from ) && ! empty( $to ) ) {
316
  $from = gmdate( "c", strtotime( $from ) );
317
  $to = gmdate( "c", strtotime( $to ) );
318
+ $this->productsList[ $this->pi ]['sale_price_effective_date'] = $from . '/' . $to;
319
  } else {
320
+ $this->productsList[ $this->pi ]['sale_price_effective_date'] = '';
321
  }
322
 
323
  # Get all Attributes and their values
333
 
334
  $grouped = new WC_Product_Grouped( $id );
335
 
336
+ $this->productsList[ $this->pi ]['id'] = $grouped->get_id();
337
+ $this->productsList[ $this->pi ]['title'] = $grouped->get_name();
338
+ $this->productsList[ $this->pi ]['description'] = $this->remove_short_codes($grouped->get_description());
339
  $this->productsList[ $this->pi ]['variation_type'] = $grouped->get_type();
340
 
341
  $this->productsList[ $this->pi ]['short_description'] = $this->remove_short_codes($grouped->get_short_description());
342
+ $this->productsList[ $this->pi ]['product_type'] = wp_strip_all_tags( wc_get_product_category_list( $id, ">", '' ) );//$this->get_product_term_list( $post->ID, 'product_cat', '', ">" );// $this->categories($this->parentID);//TODO
343
  $this->productsList[ $this->pi ]['link'] = $grouped->get_permalink();
344
  $this->productsList[ $this->pi ]['ex_link'] = $grouped->get_permalink();
345
 
365
  }
366
  }
367
 
368
+ $this->productsList[ $this->pi ]['images'] = implode( ',', $imgUrls );
369
+ $this->productsList[ $this->pi ]['condition'] = 'new';
370
  $this->productsList[ $this->pi ]['type'] = $grouped->get_type();
371
+ $this->productsList[ $this->pi ]['is_bundle'] = 'no';
372
+ $this->productsList[ $this->pi ]['multipack'] = ( count( $grouped->get_children() ) > 0 ) ? count( $grouped->get_children() ) : '';
373
  $this->productsList[ $this->pi ]['visibility'] = $grouped->get_catalog_visibility();
374
  $this->productsList[ $this->pi ]['rating_total'] = $grouped->get_rating_count();
375
  $this->productsList[ $this->pi ]['rating_average'] = $grouped->get_average_rating();
376
+ $this->productsList[ $this->pi ]['tags'] = $this->getProductTaxonomy($id,'product_tag');
377
  $this->productsList[ $this->pi ]['item_group_id'] = $grouped->get_id();
378
  $this->productsList[ $this->pi ]['sku'] = $grouped->get_sku();
379
  $this->productsList[ $this->pi ]['parent_sku'] = $grouped->get_sku();
399
  if ( ! empty( $from ) && ! empty( $to ) ) {
400
  $from = gmdate( "c", strtotime( $from ) );
401
  $to = gmdate( "c", strtotime( $to ) );
402
+ $this->productsList[ $this->pi ]['sale_price_effective_date'] = $from . '/' . $to;
403
  } else {
404
+ $this->productsList[ $this->pi ]['sale_price_effective_date'] = '';
405
  }
406
 
407
  # Get all Attributes and their values
417
 
418
  $variable = new WC_Product_Variable( $id );
419
 
420
+ $this->productsList[ $this->pi ]['id'] = $variable->get_id();
421
+ $this->productsList[ $this->pi ]['title'] = $variable->get_name();
422
+ $this->productsList[ $this->pi ]['description'] = $this->remove_short_codes($variable->get_description());
423
  $this->productsList[ $this->pi ]['variation_type'] = $variable->get_type();
424
 
425
  $this->productsList[ $this->pi ]['short_description'] = $this->remove_short_codes($variable->get_short_description());
426
+ $this->productsList[ $this->pi ]['product_type'] = wp_strip_all_tags( wc_get_product_category_list( $id, ">", '' ) );
427
  $this->productsList[ $this->pi ]['link'] = $variable->get_permalink();
428
  $this->productsList[ $this->pi ]['ex_link'] = $variable->get_permalink();
429
 
450
  }
451
  }
452
 
453
+ $this->productsList[ $this->pi ]['images'] = implode( ',', $imgUrls );
454
+ $this->productsList[ $this->pi ]['condition'] = 'new';
455
  $this->productsList[ $this->pi ]['type'] = $variable->get_type();
456
+ $this->productsList[ $this->pi ]['is_bundle'] = 'no';
457
+ $this->productsList[ $this->pi ]['multipack'] = '';
458
  $this->productsList[ $this->pi ]['visibility'] = $variable->get_catalog_visibility();
459
  $this->productsList[ $this->pi ]['rating_total'] = $variable->get_rating_count();
460
  $this->productsList[ $this->pi ]['rating_average'] = $variable->get_average_rating();
461
+ $this->productsList[ $this->pi ]['tags'] = $this->getProductTaxonomy($id,'product_tag');
462
  $this->productsList[ $this->pi ]['item_group_id'] = $variable->get_id();
463
  $this->productsList[ $this->pi ]['sku'] = $variable->get_sku();
464
  $this->productsList[ $this->pi ]['parent_sku'] = $variable->get_sku();
487
  if ( ! empty( $from ) && ! empty( $to ) ) {
488
  $from = gmdate( "c", strtotime( $from ) );
489
  $to = gmdate( "c", strtotime( $to ) );
490
+ $this->productsList[ $this->pi ]['sale_price_effective_date'] = $from . '/' . $to;
491
  } else {
492
+ $this->productsList[ $this->pi ]['sale_price_effective_date'] = '';
493
  }
494
 
495
  # Get all Attributes and their values
532
  }
533
  $short_description = $this->remove_short_codes($short_description);
534
 
535
+ $this->productsList[ $this->pi ]['id'] = $variation->get_id();
536
+ $this->productsList[ $this->pi ]['title'] = $variation->get_name();
537
 
538
+ if ( 'facebook' == $this->feedRule['provider'] ) {
539
  $variationInfo = explode("-",$variation->get_name());
540
  if ( isset($variationInfo[1]) ) {
541
  $extension = $variationInfo[1];
542
  }else {
543
  $extension = $variation->get_id();
544
  }
545
+ $description .= ''.$extension;
546
  }
547
 
548
+ $this->productsList[ $this->pi ]['description'] = $description;
549
  $this->productsList[ $this->pi ]['variation_type'] = $variation->get_type();
550
  $this->productsList[ $this->pi ]['short_description'] = $short_description;
551
+ $this->productsList[ $this->pi ]['product_type'] = wp_strip_all_tags(wc_get_product_category_list($variation->get_parent_id(),">",''));
552
  $this->productsList[ $this->pi ]['link'] = $variation->get_permalink();
553
  $this->productsList[ $this->pi ]['ex_link'] = $variation->get_permalink();
554
 
577
  }
578
  }
579
 
580
+ $this->productsList[ $this->pi ]['images'] = implode( ',', $imgUrls );
581
+ $this->productsList[ $this->pi ]['condition'] = 'new';
582
  $this->productsList[ $this->pi ]['type'] = $variation->get_type();
583
+ $this->productsList[ $this->pi ]['is_bundle'] = 'no';
584
+ $this->productsList[ $this->pi ]['multipack'] = '';
585
  $this->productsList[ $this->pi ]['visibility'] = $variation->get_catalog_visibility();
586
  $this->productsList[ $this->pi ]['rating_total'] = $variation->get_rating_count();
587
  $this->productsList[ $this->pi ]['rating_average'] = $variation->get_average_rating();
588
+ $this->productsList[ $this->pi ]['tags'] = $this->getProductTaxonomy($parentId,'product_tag');
589
  $this->productsList[ $this->pi ]['item_group_id'] = $variation->get_parent_id();
590
  $this->productsList[ $this->pi ]['sku'] = $variation->get_sku();
591
  $this->productsList[ $this->pi ]['parent_sku'] = $parent->get_sku();
612
  if ( ! empty( $from ) && ! empty( $to ) ) {
613
  $from = gmdate( "c", strtotime( $from ) );
614
  $to = gmdate( "c", strtotime( $to ) );
615
+ $this->productsList[ $this->pi ]['sale_price_effective_date'] = $from . '/' . $to;
616
  } else {
617
+ $this->productsList[ $this->pi ]['sale_price_effective_date'] = '';
618
  }
619
 
620
  # Get all Attributes and their values
662
  if ( empty( $regularPrice ) ) $regularPrice = 0;
663
  $currentPrice = $product->get_price();
664
  if ( empty( $currentPrice ) ) $currentPrice = 0;
665
+ if ( 'regular' == $type ) {
666
  if ( $taxable ) {
667
+ $regularPrice = $this->getPriceWithTax( $product );
668
  }
669
  $sum += $regularPrice;
670
+ } else {
671
  if ( $taxable ) {
672
+ $currentPrice = $this->getPriceWithTax( $product );
673
  }
674
  $sum += $currentPrice;
675
  }
718
  }
719
  $short_description = $this->remove_short_codes($short_description);
720
 
721
+ $this->productsList[ $this->pi ]['id'] = $variation->get_id();
722
+ $this->productsList[ $this->pi ]['title'] = $variationTitle;
723
+ $this->productsList[ $this->pi ]['description'] = $description;
724
  $this->productsList[ $this->pi ]['variation_type'] = $variation->get_type();
725
 
726
  $this->productsList[ $this->pi ]['short_description'] = $short_description;
727
+ $this->productsList[ $this->pi ]['product_type'] = wp_strip_all_tags(wc_get_product_category_list($variation->get_parent_id(),">",''));
728
  $this->productsList[ $this->pi ]['link'] = $variation->get_permalink();
729
  $this->productsList[ $this->pi ]['ex_link'] = $variation->get_permalink();
730
 
753
  }
754
  }
755
 
756
+ $this->productsList[ $this->pi ]['images'] = implode( ',', $imgUrls );
757
+ $this->productsList[ $this->pi ]['condition'] = 'new';
758
  $this->productsList[ $this->pi ]['type'] = $variation->get_type();
759
+ $this->productsList[ $this->pi ]['is_bundle'] = 'no';
760
+ $this->productsList[ $this->pi ]['multipack'] = '';
761
  $this->productsList[ $this->pi ]['visibility'] = $variation->get_catalog_visibility();
762
  $this->productsList[ $this->pi ]['rating_total'] = $variation->get_rating_count();
763
  $this->productsList[ $this->pi ]['rating_average'] = $variation->get_average_rating();
764
+ $this->productsList[ $this->pi ]['tags'] = wp_strip_all_tags(wc_get_product_tag_list($id,','));
765
  $this->productsList[ $this->pi ]['item_group_id'] = $variation->get_parent_id();
766
  $this->productsList[ $this->pi ]['sku'] = $variation->get_sku();
767
  $this->productsList[ $this->pi ]['parent_sku'] = $parent->get_sku();
786
  if ( ! empty( $from ) && ! empty( $to ) ) {
787
  $from = gmdate( "c", strtotime( $from ) );
788
  $to = gmdate( "c", strtotime( $to ) );
789
+ $this->productsList[ $this->pi ]['sale_price_effective_date'] = $from . '/' . $to;
790
  } else {
791
+ $this->productsList[ $this->pi ]['sale_price_effective_date'] = '';
792
  }
793
 
794
  # Get all Attributes and their values
807
  // foreach ($metas as $mKey=>$meta){
808
  // if($mKey!="_product_attributes"){
809
  // $metaValue=get_post_meta($id,$mKey,true);
810
+ // $this->productsList[ $this->pi ]["wf_cattr_".$mKey]=(!empty($metaValue))?$metaValue:'';
811
  // }
812
  // }
813
  // }
816
  // $taxonomies=get_post_taxonomies($id);
817
  // if(!empty($taxonomies)){
818
  // foreach ($taxonomies as $tKey=>$taxonomy){
819
+ // $this->productsList[ $this->pi ]["wf_taxo_".$taxonomy]=wp_strip_all_tags(get_the_term_list($id,$taxonomy,'',',',''));
820
  // }
821
  // }
822
  $this->pi++;
832
 
833
  /**
834
  * Get WooCommerce Product
835
+ * @param array $feedRule
836
  * @return array
837
  */
838
+ public function woo_feed_get_visible_product( $feedRule = array() ) {
839
  wp_cache_delete( 'wf_check_duplicate', 'options' );
840
  $this->feedRule = $feedRule;
841
  $limit = ! empty( $feedRule['Limit'] ) && is_numeric( $feedRule['Limit'] ) ? absint( $feedRule['Limit'] ) : '2000';
854
  }
855
 
856
 
857
+ if ( '0' == $offset ) {
858
  delete_option( "wf_check_duplicate" );
859
  }
860
  $getIDs = get_option( "wf_check_duplicate" );
887
  continue;
888
  }
889
 
890
+ $type1 = '';
891
  if ( is_object( $product ) && $product->is_type( 'simple' ) ) {
892
  # No variations to product
893
  $type1 = "simple";
911
  continue;
912
  }
913
 
914
+ if ( 'trash' == $post->post_status ) {
915
  continue;
916
  }
917
 
918
 
919
+ if ( 'product_variation' == get_post_type() && 'facebook' !== $this->feedRule['provider'] ) {
920
+ if ( 0 != $this->parentID ) {
921
 
922
  $status = get_post( $this->childID );
923
  if ( ! $status || ! is_object( $status ) ) {
924
  continue;
925
  }
926
 
927
+ if ( 'trash' == $status->post_status ) {
928
  continue;
929
  }
930
 
931
  $parentStatus = get_post( $this->parentID );
932
+ if ( $parentStatus && is_object( $parentStatus ) && 'publish' != $parentStatus->post_status ) {
933
  continue;
934
  }
935
 
936
  # Check Valid URL
937
  $mainImage = wp_get_attachment_url( $product->get_image_id() );
938
+ $link = $product->get_permalink();
939
 
940
+ if ( 'custom' != $this->feedRule['provider'] ) {
941
+ if ( 'http' !== substr( trim( $link ), 0, 4 ) && 'http' !== substr( trim( $mainImage ), 0, 4 ) ) {
942
  continue;
943
  }
944
  }
970
  $this->productsList[ $i ]['short_description'] = $post->post_excerpt;
971
  }
972
 
973
+ $this->productsList[ $i ]['product_type'] = $this->get_product_term_list( $post->ID, 'product_cat', '', ">" );
974
  $this->productsList[ $i ]['link'] = $link;
975
+ $this->productsList[ $i ]['ex_link'] = '';
976
  $this->productsList[ $i ]['image'] = $this->get_formatted_url( $mainImage );
977
 
978
  # Featured Image
999
  $mKey ++;
1000
  }
1001
  }
1002
+ $this->productsList[ $i ]['images'] = implode( ',', $imageLinks );
1003
+ $this->productsList[ $i ]['condition'] = 'new';
1004
  $this->productsList[ $i ]['type'] = $product->get_type();
1005
  $this->productsList[ $i ]['visibility'] = $this->getAttributeValue( $this->childID, "_visibility" );
1006
  $this->productsList[ $i ]['rating_total'] = $product->get_rating_count();
1013
  $this->productsList[ $i ]['sale_price_sdate'] = $this->get_date( $this->childID, "_sale_price_dates_from" );
1014
  $this->productsList[ $i ]['sale_price_edate'] = $this->get_date( $this->childID, "_sale_price_dates_to" );
1015
  $this->productsList[ $i ]['price'] = ( $product->get_regular_price() ) ? $product->get_regular_price() : $product->get_price();
1016
+ $this->productsList[ $i ]['sale_price'] = ( $product->get_sale_price() ) ? $product->get_sale_price() : '';
1017
+ $this->productsList[ $i ]['weight'] = ( $product->get_weight() ) ? $product->get_weight() : '';
1018
+ $this->productsList[ $i ]['width'] = ( $product->get_width() ) ? $product->get_width() : '';
1019
+ $this->productsList[ $i ]['height'] = ( $product->get_height() ) ? $product->get_height() : '';
1020
+ $this->productsList[ $i ]['length'] = ( $product->get_length() ) ? $product->get_length() : '';
1021
 
1022
  # Sale price effective date
1023
  $from = $this->sale_price_effective_date( $this->childID, '_sale_price_dates_from' );
1025
  if ( ! empty( $from ) && ! empty( $to ) ) {
1026
  $from = gmdate( "c", strtotime( $from ) );
1027
  $to = gmdate( "c", strtotime( $to ) );
1028
+ $this->productsList[ $i ]['sale_price_effective_date'] = $from . '/' . $to;
1029
  } else {
1030
+ $this->productsList[ $i ]['sale_price_effective_date'] = '';
1031
  }
1032
  }
1033
  } elseif ( get_post_type() == 'product' ) {
1034
+ if ( 'simple' == $type1 ) {
1035
 
1036
  $mainImage = wp_get_attachment_url( $product->get_image_id() );
1037
  $link = get_permalink( $post->ID );
1038
 
1039
+ if ( 'custom' != $this->feedRule['provider'] ) {
1040
+ if ( 'http' !== substr( trim( $link ), 0, 4 ) && 'http' !== substr( trim( $mainImage ), 0, 4 ) ) {
1041
  continue;
1042
  }
1043
  }
1058
  $this->productsList[ $i ]['description'] = $post->post_content;
1059
 
1060
  $this->productsList[ $i ]['short_description'] = $post->post_excerpt;
1061
+ $this->productsList[ $i ]['product_type'] = $this->get_product_term_list( $post->ID, 'product_cat', '', ">" );
1062
  $this->productsList[ $i ]['link'] = $link;
1063
+ $this->productsList[ $i ]['ex_link'] = '';
1064
  $this->productsList[ $i ]['image'] = $this->get_formatted_url( $mainImage );
1065
 
1066
  # Featured Image
1087
  $mKey ++;
1088
  }
1089
  }
1090
+ $this->productsList[ $i ]['images'] = implode( ',', $imageLinks );
1091
 
1092
+ $this->productsList[ $i ]['condition'] = 'new';
1093
  $this->productsList[ $i ]['type'] = $product->get_type();
1094
  $this->productsList[ $i ]['visibility'] = $this->getAttributeValue( $post->ID, "_visibility" );
1095
  $this->productsList[ $i ]['rating_total'] = $product->get_rating_count();
1104
  $this->productsList[ $i ]['sale_price_sdate'] = $this->get_date( $post->ID, "_sale_price_dates_from" );
1105
  $this->productsList[ $i ]['sale_price_edate'] = $this->get_date( $post->ID, "_sale_price_dates_to" );
1106
  $this->productsList[ $i ]['price'] = ( $product->get_regular_price() ) ? $product->get_regular_price() : $product->get_price();
1107
+ $this->productsList[ $i ]['sale_price'] = ( $product->get_sale_price() ) ? $product->get_sale_price() : '';
1108
+ $this->productsList[ $i ]['weight'] = ( $product->get_weight() ) ? $product->get_weight() : '';
1109
+ $this->productsList[ $i ]['width'] = ( $product->get_width() ) ? $product->get_width() : '';
1110
+ $this->productsList[ $i ]['height'] = ( $product->get_height() ) ? $product->get_height() : '';
1111
+ $this->productsList[ $i ]['length'] = ( $product->get_length() ) ? $product->get_length() : '';
1112
 
1113
  # Sale price effective date
1114
  $from = $this->sale_price_effective_date( $post->ID, '_sale_price_dates_from' );
1116
  if ( ! empty( $from ) && ! empty( $to ) ) {
1117
  $from = gmdate( "c", strtotime( $from ) );
1118
  $to = gmdate( "c", strtotime( $to ) );
1119
+ $this->productsList[ $i ]['sale_price_effective_date'] = $from . '/' . $to;
1120
  } else {
1121
+ $this->productsList[ $i ]['sale_price_effective_date'] = '';
1122
  }
1123
  }
1124
+ elseif ( 'external' == $type1 ) {
1125
 
1126
  $mainImage = wp_get_attachment_url( $product->get_image_id() );
1127
 
1128
  $getLink = new WC_Product_External( $post->ID );
1129
  $EX_link = $getLink->get_product_url();
1130
  $link = get_permalink( $post->ID );
1131
+ if ( 'custom' != $this->feedRule['provider'] ) {
1132
+ if ( 'http' !== substr( trim( $link ), 0, 4 ) && 'http' !== substr( trim( $mainImage ), 0, 4 ) ) {
1133
  continue;
1134
  }
1135
  }
1140
  $this->productsList[ $i ]['description'] = do_shortcode( $post->post_content );
1141
 
1142
  $this->productsList[ $i ]['short_description'] = $post->post_excerpt;
1143
+ $this->productsList[ $i ]['product_type'] = $this->get_product_term_list( $post->ID, 'product_cat', '', ">" );
1144
  $this->productsList[ $i ]['link'] = $link;
1145
  $this->productsList[ $i ]['ex_link'] = $EX_link;
1146
  $this->productsList[ $i ]['image'] = $this->get_formatted_url( $mainImage );
1169
  $mKey ++;
1170
  }
1171
  }
1172
+ $this->productsList[ $i ]['images'] = implode( ',', $imageLinks );
1173
 
1174
+ $this->productsList[ $i ]['condition'] = 'new';
1175
  $this->productsList[ $i ]['type'] = $product->get_type();
1176
  $this->productsList[ $i ]['visibility'] = $this->getAttributeValue( $post->ID, "_visibility" );
1177
  $this->productsList[ $i ]['rating_total'] = $product->get_rating_count();
1187
  $this->productsList[ $i ]['sale_price_sdate'] = $this->get_date( $post->ID, "_sale_price_dates_from" );
1188
  $this->productsList[ $i ]['sale_price_edate'] = $this->get_date( $post->ID, "_sale_price_dates_to" );
1189
  $this->productsList[ $i ]['price'] = ( $product->get_regular_price() ) ? $product->get_regular_price() : $product->get_price();
1190
+ $this->productsList[ $i ]['sale_price'] = ( $product->get_sale_price() ) ? $product->get_sale_price() : '';
1191
+ $this->productsList[ $i ]['weight'] = ( $product->get_weight() ) ? $product->get_weight() : '';
1192
+ $this->productsList[ $i ]['width'] = ( $product->get_width() ) ? $product->get_width() : '';
1193
+ $this->productsList[ $i ]['height'] = ( $product->get_height() ) ? $product->get_height() : '';
1194
+ $this->productsList[ $i ]['length'] = ( $product->get_length() ) ? $product->get_length() : '';
1195
 
1196
  # Sale price effective date
1197
  $from = $this->sale_price_effective_date( $post->ID, '_sale_price_dates_from' );
1199
  if ( ! empty( $from ) && ! empty( $to ) ) {
1200
  $from = gmdate( "c", strtotime( $from ) );
1201
  $to = gmdate( "c", strtotime( $to ) );
1202
+ $this->productsList[ $i ]['sale_price_effective_date'] = $from . '/' . $to;
1203
  } else {
1204
+ $this->productsList[ $i ]['sale_price_effective_date'] = '';
1205
  }
1206
  }
1207
+ elseif ( 'grouped' == $type1 ) {
1208
 
1209
  $grouped = new WC_Product_Grouped( $post->ID );
1210
  $children = $grouped->get_children();
1216
  $this->childID = $child;
1217
  $post = get_post( $this->childID );
1218
 
1219
+ if ( 'trash' == $post->post_status ) {
1220
  continue;
1221
  }
1222
 
1236
 
1237
  $mainImage = wp_get_attachment_url( $product->get_image_id() );
1238
  $link = get_permalink( $post->ID );
1239
+ if ( 'custom' != $this->feedRule['provider'] ) {
1240
+ if ( 'http' !== substr( trim( $link ), 0, 4 ) && 'http' !== substr( trim( $mainImage ), 0, 4 ) ) {
1241
  continue;
1242
  }
1243
  }
1248
  $this->productsList[ $i ]['description'] = do_shortcode( $post->post_content );
1249
 
1250
  $this->productsList[ $i ]['short_description'] = $post->post_excerpt;
1251
+ $this->productsList[ $i ]['product_type'] = $this->get_product_term_list( $post->ID, 'product_cat', '', ">" );
1252
  $this->productsList[ $i ]['link'] = $link;
1253
+ $this->productsList[ $i ]['ex_link'] = '';
1254
  $this->productsList[ $i ]['image'] = $this->get_formatted_url( $mainImage );
1255
 
1256
  # Featured Image
1277
  $mKey ++;
1278
  }
1279
  }
1280
+ $this->productsList[ $i ]['images'] = implode( ',', $imageLinks );
1281
+ $this->productsList[ $i ]['condition'] = 'new';
1282
  $this->productsList[ $i ]['type'] = $product->get_type();
1283
  $this->productsList[ $i ]['visibility'] = $this->getAttributeValue( $post->ID, "_visibility" );
1284
  $this->productsList[ $i ]['rating_total'] = $product->get_rating_count();
1294
  $this->productsList[ $i ]['sale_price_sdate'] = $this->get_date( $post->ID, "_sale_price_dates_from" );
1295
  $this->productsList[ $i ]['sale_price_edate'] = $this->get_date( $post->ID, "_sale_price_dates_to" );
1296
  $this->productsList[ $i ]['price'] = ( $product->get_regular_price() ) ? $product->get_regular_price() : $product->get_price();
1297
+ $this->productsList[ $i ]['sale_price'] = ( $product->get_sale_price() ) ? $product->get_sale_price() : '';
1298
+ $this->productsList[ $i ]['weight'] = ( $product->get_weight() ) ? $product->get_weight() : '';
1299
+ $this->productsList[ $i ]['width'] = ( $product->get_width() ) ? $product->get_width() : '';
1300
+ $this->productsList[ $i ]['height'] = ( $product->get_height() ) ? $product->get_height() : '';
1301
+ $this->productsList[ $i ]['length'] = ( $product->get_length() ) ? $product->get_length() : '';
1302
 
1303
  # Sale price effective date
1304
  $from = $this->sale_price_effective_date( $post->ID, '_sale_price_dates_from' );
1306
  if ( ! empty( $from ) && ! empty( $to ) ) {
1307
  $from = gmdate( "c", strtotime( $from ) );
1308
  $to = gmdate( "c", strtotime( $to ) );
1309
+ $this->productsList[ $i ]['sale_price_effective_date'] = $from . '/' . $to;
1310
  } else {
1311
+ $this->productsList[ $i ]['sale_price_effective_date'] = '';
1312
  }
1313
  }
1314
  }
1315
  }
1316
+ elseif ( 'variable' == $type1 && $product->has_child() ) {
1317
 
1318
  # Check Valid URL
1319
  $mainImage = wp_get_attachment_url( $product->get_image_id() );
1320
  $link = get_permalink( $post->ID );
1321
 
1322
+ if ( 'custom' != $this->feedRule['provider'] ) {
1323
+ if ( 'http' !== substr( trim( $link ), 0, 4 ) && 'http' !== substr( trim( $mainImage ), 0, 4 ) ) {
1324
  continue;
1325
  }
1326
  }
1332
  $this->productsList[ $i ]['description'] = $post->post_content;
1333
 
1334
  $this->productsList[ $i ]['short_description'] = $post->post_excerpt;
1335
+ $this->productsList[ $i ]['product_type'] = $this->get_product_term_list( $post->ID, 'product_cat', '', ">" );
1336
  $this->productsList[ $i ]['link'] = $link;
1337
+ $this->productsList[ $i ]['ex_link'] = '';
1338
  $this->productsList[ $i ]['image'] = $this->get_formatted_url( $mainImage );
1339
 
1340
  # Featured Image
1361
  $mKey ++;
1362
  }
1363
  }
1364
+ $this->productsList[ $i ]['images'] = implode( ',', $imageLinks );
1365
 
1366
+ $this->productsList[ $i ]['condition'] = 'new';
1367
  $this->productsList[ $i ]['type'] = $product->get_type();
1368
  $this->productsList[ $i ]['visibility'] = $this->getAttributeValue( $post->ID, "_visibility" );
1369
  $this->productsList[ $i ]['rating_total'] = $product->get_rating_count();
1381
  $price = ( $product->get_price() ) ? $product->get_price() : false;
1382
 
1383
  $this->productsList[ $i ]['price'] = ( $product->get_regular_price() ) ? $product->get_regular_price() : $price;
1384
+ $this->productsList[ $i ]['sale_price'] = ( $product->get_sale_price() ) ? $product->get_sale_price() : '';
1385
+ $this->productsList[ $i ]['weight'] = ( $product->get_weight() ) ? $product->get_weight() : '';
1386
+ $this->productsList[ $i ]['width'] = ( $product->get_width() ) ? $product->get_width() : '';
1387
+ $this->productsList[ $i ]['height'] = ( $product->get_height() ) ? $product->get_height() : '';
1388
+ $this->productsList[ $i ]['length'] = ( $product->get_length() ) ? $product->get_length() : '';
1389
 
1390
  # Sale price effective date
1391
  $from = $this->sale_price_effective_date( $post->ID, '_sale_price_dates_from' );
1393
  if ( ! empty( $from ) && ! empty( $to ) ) {
1394
  $from = gmdate( "c", strtotime( $from ) );
1395
  $to = gmdate( "c", strtotime( $to ) );
1396
+ $this->productsList[ $i ]['sale_price_effective_date'] = $from . '/' . $to;
1397
  } else {
1398
+ $this->productsList[ $i ]['sale_price_effective_date'] = '';
1399
  }
1400
  }
1401
  }
1402
  $i ++;
1403
  endwhile;
1404
+ wp_reset_postdata();
1405
 
1406
  if ( $getIDs ) {
1407
  $mergedIds = array_merge( $getIDs, $this->idExist );
1425
  */
1426
  public function remove_short_codes( $content ) {
1427
  if ( empty( $content ) ) {
1428
+ return '';
1429
  }
1430
  $content = do_shortcode( $content );
1431
  $content = $this->stripInvalidXml( $content );
1445
  * @return string
1446
  */
1447
  public function stripInvalidXml( $value ) {
1448
+ $ret = '';
1449
+ if ( empty( $value ) ) {
 
1450
  return $ret;
1451
  }
1452
+ $length = strlen( $value );
1453
  for ( $i = 0; $i < $length; $i++ ) {
1454
  $current = ord($value[ $i ]);
1455
+ if ( ( 0x9 == $current ) || ( 0xA == $current ) || ( 0xD == $current ) || ( ( $current >= 0x20 ) && ( $current <= 0xD7FF ) ) || ( ( $current >= 0xE000 ) && ( $current <= 0xFFFD ) ) || ( ( $current >= 0x10000 ) && ( $current <= 0x10FFFF ) ) ) {
1456
  $ret .= chr($current);
1457
  }
1458
  else {
1459
  $ret .= "";
1460
  }
1461
  }
1462
+
1463
  return $ret;
1464
  }
1465
 
1469
  * @param $url
1470
  * @return bool|string
1471
  */
1472
+ public function get_formatted_url( $url = '' ) {
1473
  if ( ! empty($url) ) {
1474
+ if ( 'http' === substr(trim($url), 0, 4) || substr(trim($url), 0, 3) === 'ftp' || substr(trim($url), 0, 4) === 'sftp' ) {
1475
+ return rtrim($url, '/');
1476
  } else {
1477
  $base = get_site_url();
1478
  $url = $base . $url;
1479
+ return rtrim($url, '/');
1480
  }
1481
  }
1482
  return $url;
1493
  public function get_date( $id, $name ) {
1494
  $date = $this->getAttributeValue($id, $name);
1495
  if ( $date ) {
1496
+ return gmdate('Y-m-d', $date);
1497
  }
1498
  return false;
1499
  }
1506
  * @return bool|mixed
1507
  */
1508
  public function get_quantity( $id, $name ) {
1509
+ $qty = $this->getAttributeValue( $id, $name );
1510
  if ( $qty ) {
1511
  return $qty + 0;
1512
  }
1513
+
1514
+ return '0';
1515
  }
1516
 
1517
  /**
1555
  */
1556
 
1557
  public function additionalImages( $Id ) {
1558
+ $ids = $this->getAttributeValue( $Id, '_product_image_gallery' );
1559
+ $imgIds = ! empty( $ids ) ? explode( ',', $ids ) : '';
1560
+
1561
  $images = array();
1562
+ if ( ! empty( $imgIds ) ) {
1563
  foreach ( $imgIds as $key => $value ) {
1564
  if ( $key < 10 ) {
1565
+ $images[ $key ] = wp_get_attachment_url( $value );
1566
  }
1567
  }
1568
+
1569
  return $images;
1570
  }
1571
+
1572
  return false;
1573
  }
1574
 
1580
  * @return string
1581
  */
1582
  public function availability( $id ) {
1583
+ $status = $this->getProductMeta( $id, '_stock_status' );
1584
  if ( $status ) {
1585
+ if ( 'instock' == $status ) {
1586
+ return 'in stock';
1587
+ } elseif ( 'outofstock' == $status ) {
1588
+ return 'out of stock';
1589
  }
1590
  }
1591
+
1592
+ return 'in stock';
1593
  }
1594
 
1595
  /**
1602
  * @return string
1603
  */
1604
  public function getProductAttribute( $id,$attr ) {
1605
+
1606
+ $attr = str_replace( 'wf_attr_', '', $attr );
1607
+
1608
+ if ( woo_feed_wc_version_check( 3.1 ) ) {
1609
  # Get Product
1610
+ $product = wc_get_product( $id );
1611
+
1612
+ if ( ! is_object( $product ) ) {
1613
+ return '';
1614
  }
1615
+
1616
+ if ( woo_feed_wc_version_check( 3.6 ) ) {
1617
+ $attr = str_replace( 'pa_', '', $attr );
1618
+ }
1619
+
1620
+ $value = $product->get_attribute( $attr );
1621
+
1622
+ if ( ! empty( $value ) ) {
1623
+ $value = trim( $value );
1624
  }
1625
 
1626
  return $value;
1627
+ } else {
1628
+ return implode( ',', wc_get_product_terms( $id, $attr, array( 'fields' => 'names' ) ) );
1629
  }
1630
  }
1631
 
1641
  */
1642
 
1643
  public function getProductMeta( $id,$meta ) {
1644
+
1645
+ $meta = str_replace( 'wf_cattr_', '', $meta );
1646
+
1647
+ if ( strpos( $meta, 'attribute_pa' ) !== false ) {
1648
+ return $this->getProductAttribute( $id, str_replace( 'attribute_', '', $meta ) );
1649
+ } else {
1650
+ return get_post_meta( $id, $meta, true );
1651
  }
1652
  }
1653
 
1664
 
1665
  return $this->getProductMeta($id,$name);
1666
  // if (strpos($name, 'attribute_pa') !== false) {
1667
+ // $taxonomy = str_replace("attribute_','",$name);
1668
  // $meta = get_post_meta($id,$name, true);
1669
  // $term = get_term_by('slug', $meta, $taxonomy);
1670
  // return $term->name;
1682
  * @return string
1683
  */
1684
  public function sale_price_effective_date( $id, $name ) {
1685
+ $date = $this->getAttributeValue( $id, $name );
1686
+ return ( $date ) ? date_i18n( 'Y-m-d', $date ) : '';
1687
  }
1688
 
1689
 
1698
  $globalAttributes = wc_get_attribute_taxonomy_labels();
1699
  if ( count( $globalAttributes ) ) {
1700
  foreach ( $globalAttributes as $key => $value ) {
1701
+ $info[ 'wf_attr_pa_' . $key ] = $value;
1702
  }
1703
  }
1704
 
1705
  return $info;
1706
  }
1707
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1708
  /**
1709
  * Local Attribute List to map product value with merchant attributes
1710
  *
1712
  *
1713
  * @return string
1714
  */
1715
+ public function attributeDropdown( $selected = '' ) {
1716
 
1717
+ $attributeDropdown = wp_cache_get( 'woo_feed_dropdown_product_attributes' );
1718
 
1719
+ if ( false === $attributeDropdown ) {
1720
  $attributes = array(
1721
+ 'id' => esc_attr__( 'Product Id', 'woo-feed' ),
1722
+ 'title' => esc_attr__( 'Product Title', 'woo-feed' ),
1723
+ 'description' => esc_attr__( 'Product Description', 'woo-feed' ),
1724
+ 'short_description' => esc_attr__( 'Product Short Description', 'woo-feed' ),
1725
+ 'product_type' => esc_attr__( 'Product Local Category', 'woo-feed' ),
1726
+ 'link' => esc_attr__( 'Product URL', 'woo-feed' ),
1727
+ 'ex_link' => esc_attr__( 'External Product URL', 'woo-feed' ),
1728
+ 'condition' => esc_attr__( 'Condition', 'woo-feed' ),
1729
+ 'item_group_id' => esc_attr__( 'Parent Id [Group Id]', 'woo-feed' ),
1730
+ 'sku' => esc_attr__( 'SKU', 'woo-feed' ),
1731
+ 'parent_sku' => esc_attr__( 'Parent SKU', 'woo-feed' ),
1732
+ 'availability' => esc_attr__( 'Availability', 'woo-feed' ),
1733
+ 'quantity' => esc_attr__( 'Quantity', 'woo-feed' ),
1734
+ 'price' => esc_attr__( 'Regular Price', 'woo-feed' ),
1735
+ 'current_price' => esc_attr__( 'Price', 'woo-feed' ),
1736
+ 'sale_price' => esc_attr__( 'Sale Price', 'woo-feed' ),
1737
+ 'price_with_tax' => esc_attr__( 'Regular Price With Tax', 'woo-feed' ),
1738
+ 'current_price_with_tax' => esc_attr__( 'Price With Tax', 'woo-feed' ),
1739
+ 'sale_price_with_tax' => esc_attr__( 'Sale Price With Tax', 'woo-feed' ),
1740
+ 'sale_price_sdate' => esc_attr__( 'Sale Start Date', 'woo-feed' ),
1741
+ 'sale_price_edate' => esc_attr__( 'Sale End Date', 'woo-feed' ),
1742
+ 'weight' => esc_attr__( 'Weight', 'woo-feed' ),
1743
+ 'width' => esc_attr__( 'Width', 'woo-feed' ),
1744
+ 'height' => esc_attr__( 'Height', 'woo-feed' ),
1745
+ 'length' => esc_attr__( 'Length', 'woo-feed' ),
1746
+ 'shipping_class' => esc_attr__( 'Shipping Class', 'woo-feed' ),
1747
+ 'type' => esc_attr__( 'Product Type', 'woo-feed' ),
1748
+ 'variation_type' => esc_attr__( 'Variation Type', 'woo-feed' ),
1749
+ 'visibility' => esc_attr__( 'Visibility', 'woo-feed' ),
1750
+ 'rating_total' => esc_attr__( 'Total Rating', 'woo-feed' ),
1751
+ 'rating_average' => esc_attr__( 'Average Rating', 'woo-feed' ),
1752
+ 'tags' => esc_attr__( 'Tags', 'woo-feed' ),
1753
+ 'sale_price_effective_date' => esc_attr__( 'Sale Price Effective Date', 'woo-feed' ),
1754
+ 'is_bundle' => esc_attr__( 'Is Bundle', 'woo-feed' ),
1755
+ 'author_name' => esc_attr__( 'Author Name', 'woo-feed' ),
1756
+ 'author_email' => esc_attr__( 'Author Email', 'woo-feed' ),
1757
+ 'date_created' => esc_attr__( 'Date Created', 'woo-feed' ),
1758
+ 'date_updated' => esc_attr__( 'Date Updated', 'woo-feed' ),
1759
  );
1760
+ $images = array(
1761
+ 'image' => esc_attr__( 'Main Image', 'woo-feed' ),
1762
+ 'feature_image' => esc_attr__( 'Featured Image', 'woo-feed' ),
1763
+ 'images' => esc_attr__( 'Images [Comma Separated]', 'woo-feed' ),
1764
+ 'image_1' => esc_attr__( 'Additional Image 1', 'woo-feed' ),
1765
+ 'image_2' => esc_attr__( 'Additional Image 2', 'woo-feed' ),
1766
+ 'image_3' => esc_attr__( 'Additional Image 3', 'woo-feed' ),
1767
+ 'image_4' => esc_attr__( 'Additional Image 4', 'woo-feed' ),
1768
+ 'image_5' => esc_attr__( 'Additional Image 5', 'woo-feed' ),
1769
+ 'image_6' => esc_attr__( 'Additional Image 6', 'woo-feed' ),
1770
+ 'image_7' => esc_attr__( 'Additional Image 7', 'woo-feed' ),
1771
+ 'image_8' => esc_attr__( 'Additional Image 8', 'woo-feed' ),
1772
+ 'image_9' => esc_attr__( 'Additional Image 9', 'woo-feed' ),
1773
+ 'image_10' => esc_attr__( 'Additional Image 10', 'woo-feed' ),
1774
  );
1775
 
1776
+ if ( class_exists( 'All_in_One_SEO_Pack' ) ) {
1777
+ $attributes = array_merge( $attributes,
1778
+ [
1779
+ '_aioseop_title' => esc_attr__( 'Title [All in One SEO]', 'woo-feed' ),
1780
+ '_aioseop_description' => esc_attr__( 'Description [All in One SEO]', 'woo-feed' ),
1781
+ ] );
1782
+ }
1783
+ if ( class_exists( 'WPSEO_Frontend' ) ) {
1784
+ $attributes = array_merge( $attributes,
1785
+ [
1786
+ 'yoast_wpseo_title' => esc_attr__( 'Title [Yoast SEO]', 'woo-feed' ),
1787
+ 'yoast_wpseo_metadesc' => esc_attr__( 'Description [Yoast SEO]', 'woo-feed' ),
1788
+ ] );
1789
+ }
1790
+
1791
  # Primary Attributes
1792
+ $attributeDropdown = '<option></option>';
1793
+ if ( is_array( $attributes ) && ! empty( $attributes ) ) {
1794
+ $attributeDropdown .= sprintf( '<optgroup label="%s">', esc_attr__( 'Primary Attributes', 'woo-feed' ) );
1795
  foreach ( $attributes as $key => $value ) {
1796
  $attributeDropdown .= sprintf( '<option value="%s">%s</option>', $key, $value );
1797
  }
1798
+ $attributeDropdown .= '</optgroup>';
1799
  }
1800
 
1801
  # Additional Images
1802
+ if ( is_array( $images ) && ! empty( $images ) ) {
1803
+ $attributeDropdown .= sprintf( '<optgroup label="%s">', esc_attr__( 'Image Attributes', 'woo-feed' ) );
1804
  foreach ( $images as $key => $value ) {
1805
  $attributeDropdown .= sprintf( '<option value="%s">%s</option>', $key, $value );
1806
  }
1807
+ $attributeDropdown .= '</optgroup>';
1808
  }
1809
 
1810
  # Get All WooCommerce Attributes
1811
+ $vAttributes = get_option( 'wpfw_vAttributes', array() );
1812
+ if ( is_array( $vAttributes ) && ! empty( $vAttributes ) ) {
1813
+ $attributeDropdown .= sprintf( '<optgroup label="%s">', esc_attr__( 'Product Attributes', 'woo-feed' ) );
1814
  foreach ( $vAttributes as $key => $value ) {
1815
  $attributeDropdown .= sprintf( '<option value="%s">%s</option>', $key, $value );
1816
  }
1817
+ $attributeDropdown .= '</optgroup>';
1818
  }
1819
+
1820
+ # Get All Custom Attributes
1821
+ $customAttributes = get_option( 'wpfw_customAttributes', array() );
1822
+ if ( is_array( $customAttributes ) && ! empty( $customAttributes ) ) {
1823
+ $attributeDropdown .= sprintf( '<optgroup label="%s">', esc_attr__( 'Product Custom Attributes', 'woo-feed' ) );
1824
+ foreach ( $customAttributes as $key => $value ) {
1825
+ $attributeDropdown .= sprintf( '<option value="%s">%s</option>', $key, $value );
1826
+ }
1827
+ $attributeDropdown .= '</optgroup>';
1828
+ }
1829
+ $postMetas = get_option( 'wpfw_customMetaKeys', array() );
1830
+ if ( is_array( $postMetas ) && ! empty( $postMetas ) ) {
1831
+ $attributeDropdown .= sprintf( '<optgroup label="%s">', esc_attr__( 'Custom Fields/Post Meta', 'woo-feed' ) );
1832
+ foreach ( $postMetas as $key => $value ) {
1833
+ $attributeDropdown .= sprintf( '<option value="%s">%s</option>', $key, $value );
1834
+ }
1835
+ $attributeDropdown .= '</optgroup>';
1836
+ }
1837
+
1838
+ # Get All Custom Taxonomies
1839
+ $customTaxonomy = get_option( 'wpfw_customTaxonomy', array() );
1840
+ if ( is_array( $customTaxonomy ) && ! empty( $customTaxonomy ) ) {
1841
+ $attributeDropdown .= sprintf( '<optgroup label="%s">', esc_attr__( 'Custom Taxonomies', 'woo-feed' ) );
1842
+ foreach ( $customTaxonomy as $key => $value ) {
1843
+ $attributeDropdown .= sprintf( '<option value="%s">%s</option>', $key, $value );
1844
+ }
1845
+ $attributeDropdown .= '</optgroup>';
1846
+ }
1847
+
1848
+ wp_cache_add( 'woo_feed_dropdown_product_attributes', $attributeDropdown, '', WEEK_IN_SECONDS );
1849
  }
1850
 
1851
+ if ( $selected && strpos( $attributeDropdown, 'value="' . $selected . '"' ) !== false ) {
1852
+ $attributeDropdown = str_replace( 'value="' . $selected . '"', 'value="' . $selected . '"' . ' selected', $attributeDropdown );
1853
  }
1854
+
1855
  return $attributeDropdown;
1856
  }
1857
 
1861
  public function load_attributes() {
1862
  # Get All WooCommerce Attributes
1863
  $vAttributes = $this->getAllAttributes();
1864
+ update_option('wpfw_vAttributes', $vAttributes);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1865
  }
1866
 
1867
  /** Return product price with tax
1881
  * @return false|string
1882
  */
1883
  public function format_product_date( $date ) {
1884
+ return gmdate( 'Y-m-d', strtotime( $date ) );
1885
  }
1886
 
1887
  /**
1893
  * @return string
1894
  */
1895
  public function getProductTaxonomy( $id, $taxonomy ) {
1896
+ $taxonomy = str_replace('wf_taxo_', '',$taxonomy);
1897
+ $Taxo = get_the_term_list( $id, $taxonomy, '', ',', '' );
1898
+
1899
+ if ( ! empty( $Taxo ) ) {
1900
+ return wp_strip_all_tags( $Taxo );
1901
+ }
1902
 
1903
+ return '';
1904
  }
1905
  }
includes/classes/class-woo-feed-savefile.php CHANGED
@@ -8,8 +8,7 @@
8
  * @subpackage Woo_Feed/includes
9
  * @author Ohidul Islam <wahid@webappick.com>
10
  */
11
- class Woo_Feed_Savefile
12
- {
13
 
14
  /**
15
  * Check if the directory for feed file exist or not and make directory
@@ -18,15 +17,12 @@ class Woo_Feed_Savefile
18
  * @return bool
19
  */
20
  public function checkDir( $path ) {
21
- if ( ! file_exists( $path ) ) {
22
- return wp_mkdir_p( $path );
23
  }
24
  return true;
25
  }
26
 
27
-
28
-
29
-
30
  /**
31
  * Save CSV Feed file
32
  *
@@ -37,48 +33,37 @@ class Woo_Feed_Savefile
37
  * @return bool
38
  */
39
  public function saveCSVFile( $path, $file, $content, $info ) {
40
- if ( $this->checkDir( $path ) ) {
41
  /**
42
  * @TODO see below
43
  * @see Woo_Feed_Savefile::saveFile()
44
  */
45
- if ( file_exists( $file ) ) @unlink( $file );
46
 
47
- $fp = fopen($file, "wb");
48
 
49
- if ( $info['delimiter'] == 'tab' ) {
50
  $delimiter = "\t";
51
  } else {
52
- $delimiter = ! empty($info['delimiter']) ? trim($info['delimiter']) : $info['delimiter'];
53
- }
54
-
55
- if ( ! empty($info['enclosure']) ) {
56
- $enclosure = $info['enclosure'];
57
- } else {
58
- $enclosure = "";
59
- }
60
-
61
- $enclosure = $info['enclosure'];
62
- if ( count($content) ) {
63
- foreach ( $content as $fields ) {
64
- if ($enclosure == "double")
65
- fputcsv($fp,$fields,$delimiter,chr(34));
66
- elseif ($enclosure == "single")
67
- fputcsv($fp,$fields,$delimiter,chr(39));
68
- else {
69
- fputs($fp,implode($fields,$delimiter)."\n");
70
- }
71
- }
72
  }
73
-
74
- fclose($fp);
75
- chmod($file, 0777);
76
- update_option("WPF_DIRECTORY_PERMISSION_CHECK","");
 
 
 
 
 
 
 
 
 
 
 
77
  return true;
78
  } else {
79
- $upload_dir = wp_upload_dir();
80
- $user_dirname = $upload_dir['basedir'];
81
- update_option("WPF_DIRECTORY_PERMISSION_CHECK"," <b>Directory $user_dirname is not writable</b>");
82
  return false;
83
  }
84
  }
@@ -91,20 +76,26 @@ class Woo_Feed_Savefile
91
  * @param $content
92
  * @return bool
93
  */
94
- public function saveFile( $path, $file, $content ) {
95
- if ( $this->checkDir( $path ) ) {
96
- if ( file_exists( $file ) ) @unlink( $file );
97
- $fp = fopen( $file, "w+" );
98
- fwrite( $fp, $content );
99
- fclose( $fp );
100
- chmod( $file, 0777 );
101
- update_option("WPF_DIRECTORY_PERMISSION_CHECK","");
102
- return true;
103
- } else {
104
- $upload_dir = wp_upload_dir();
105
- $user_dirname = $upload_dir['basedir'];
106
- update_option("WPF_DIRECTORY_PERMISSION_CHECK"," <b>Directory $user_dirname is not writable</b>");
107
- return false;
108
- }
109
- }
110
- }
 
 
 
 
 
 
8
  * @subpackage Woo_Feed/includes
9
  * @author Ohidul Islam <wahid@webappick.com>
10
  */
11
+ class Woo_Feed_Savefile {
 
12
 
13
  /**
14
  * Check if the directory for feed file exist or not and make directory
17
  * @return bool
18
  */
19
  public function checkDir( $path ) {
20
+ if ( ! file_exists($path) ) {
21
+ return wp_mkdir_p($path);
22
  }
23
  return true;
24
  }
25
 
 
 
 
26
  /**
27
  * Save CSV Feed file
28
  *
33
  * @return bool
34
  */
35
  public function saveCSVFile( $path, $file, $content, $info ) {
36
+ if ( $this->checkDir($path) ) {
37
  /**
38
  * @TODO see below
39
  * @see Woo_Feed_Savefile::saveFile()
40
  */
41
+ if ( file_exists( $file ) ) unlink( $file ); // phpcs:ignore
42
 
43
+ $fp = fopen($file, "wb"); // phpcs:ignore
44
 
45
+ if ( 'tab' == $info['delimiter'] ) {
46
  $delimiter = "\t";
47
  } else {
48
+ $delimiter = $info['delimiter'];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  }
50
+
51
+ $enclosure = $info['enclosure'];
52
+ if ( count( $content ) ) {
53
+ foreach ( $content as $fields ) {
54
+ if ( 'double' == $enclosure ) {
55
+ fputcsv( $fp, $fields, $delimiter, chr( 34 ) ); // phpcs:ignore
56
+ } elseif ( 'single' == $enclosure ) {
57
+ fputcsv( $fp, $fields, $delimiter, chr( 39 ) ); // phpcs:ignore
58
+ } else {
59
+ fputs( $fp, implode( $fields, $delimiter ) . "\n" ); // phpcs:ignore
60
+ }
61
+ }
62
+ }
63
+
64
+ fclose( $fp ); // phpcs:ignore
65
  return true;
66
  } else {
 
 
 
67
  return false;
68
  }
69
  }
76
  * @param $content
77
  * @return bool
78
  */
79
+ public function saveFile( $path, $file, $content ) {
80
+ /**
81
+ * @TODO use WP Filesystem API
82
+ * @see https://codex.wordpress.org/Filesystem_API
83
+ * @see http://ottopress.com/2011/tutorial-using-the-wp_filesystem/
84
+ *
85
+ * @TODO Check write permission on installation and show admin warning
86
+ * @see wp_is_writable()
87
+ */
88
+ if ( $this->checkDir( $path ) ) {
89
+ if ( file_exists( $file ) ) {
90
+ unlink( $file ); // phpcs:ignore
91
+ }
92
+ $fp = fopen( $file, "w+" ); // phpcs:ignore
93
+ fwrite( $fp, $content ); // phpcs:ignore
94
+ fclose( $fp ); // phpcs:ignore
95
+ // chmod( $file, 0777 );
96
+ return true;
97
+ } else {
98
+ return false;
99
+ }
100
+ }
101
+ }
includes/classes/class-woo-feed-sftp.php CHANGED
@@ -1,44 +1,70 @@
1
  <?php
2
-
3
  class SFTPConnection
4
  {
5
  private $connection;
6
  private $sftp;
7
-
8
- public function __construct( $host, $port=22 ) {
9
- $this->connection = @ssh2_connect($host, $port);
10
- if ( ! $this->connection)
11
- throw new Exception("Could not connect to $host on port $port.");
 
 
12
  }
13
-
14
- public function login( $username, $password ) {
15
- if ( ! @ssh2_auth_password($this->connection, $username, $password))
16
- throw new Exception("Could not authenticate with username $username " .
17
- "and password $password.");
18
-
19
- $this->sftp = @ssh2_sftp($this->connection);
20
- if ( ! $this->sftp)
21
- throw new Exception("Could not initialize SFTP subsystem.");
 
22
  }
23
-
24
- public function uploadFile( $local_file, $remote_file ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  $sftp = $this->sftp;
26
- $stream = @fopen("ssh2.sftp://$sftp$remote_file", 'w');
27
-
28
- if ( ! $stream)
29
- throw new Exception("Could not open file: $remote_file");
30
-
31
- $data_to_send = @file_get_contents($local_file);
32
- if ($data_to_send === false)
33
- throw new Exception("Could not open local file: $local_file.");
34
-
35
- if (@fwrite($stream, $data_to_send) === false)
36
- throw new Exception("Could not send data from file: $local_file.");
37
-
38
- @fclose($stream);
 
 
 
 
 
 
39
  }
40
- public function deleteFile( $remote_file ) {
41
  $sftp = $this->sftp;
42
- unlink("ssh2.sftp://$sftp$remote_file");
43
  }
44
  }
1
  <?php
2
+ /** @noinspection PhpUnhandledExceptionInspection */
3
  class SFTPConnection
4
  {
5
  private $connection;
6
  private $sftp;
7
+
8
+ public function __construct( $host, $port = 22 ) {
9
+ if ( ! extension_loaded( 'ssh2' ) ) {
10
+ /* translators: 1: server host, 2: server port */
11
+ throw new Exception( sprintf( esc_html__( 'Could not connect to %1$s:%2$s. SSH2 is not enabled on this server.', 'woo-feed' ), $host, $port ) );
12
+ }
13
+ $this->connection = ssh2_connect( $host, $port );
14
  }
15
+
16
+ public function login( $username, $password ) {
17
+ if ( ! ssh2_auth_password( $this->connection, $username, $password ) ) {
18
+ throw new Exception("Could not authenticate with username $username " . "and password $password.");
19
+ }
20
+
21
+ $this->sftp = ssh2_sftp( $this->connection );
22
+ if ( ! $this->sftp ) {
23
+ throw new Exception( "Could not initialize SFTP subsystem." );
24
+ }
25
  }
26
+
27
+ /**
28
+ * @param string $local_file local file to upload
29
+ * @param string $remote_file remote file name
30
+ * @param string $path must use trailing slash. directory path to put the file on remote server.
31
+ *
32
+ * @return bool
33
+ * @throws Exception
34
+ */
35
+ public function upload_file( $local_file, $remote_file, $path ) {
36
+
37
+ if ( ! file_exists( $local_file ) ) {
38
+ throw new Exception( "Local file does't exists.: $local_file." );
39
+ }
40
+ $data_to_send = file_get_contents( $local_file ); // phpcs:ignore
41
+ if ( false === $data_to_send ) {
42
+ throw new Exception( "Could not open local file: $local_file." );
43
+ }
44
+
45
  $sftp = $this->sftp;
46
+ if ( ! is_dir( "ssh2.sftp://$sftp$path" ) ) {
47
+ throw new Exception("Invalid Remote Path: $path");
48
+ }
49
+
50
+ if ( ! is_writeable( "ssh2.sftp://$sftp$path" ) ) { // phpcs:ignore
51
+ throw new Exception("Could not Write file on: $path");
52
+ }
53
+
54
+ $stream = fopen( "ssh2.sftp://$sftp$path$remote_file", 'w' ); // phpcs:ignore
55
+ if ( ! $stream ) {
56
+ throw new Exception("Could not open file: $path$remote_file");
57
+ }
58
+
59
+ if ( false === fwrite( $stream, $data_to_send ) ) { // phpcs:ignore
60
+ throw new Exception("Could not send data from file: $local_file.");
61
+ }
62
+
63
+ fclose( $stream ); // phpcs:ignore
64
+ return true;
65
  }
66
+ public function delete_file( $remote_file ) {
67
  $sftp = $this->sftp;
68
+ unlink("ssh2.sftp://$sftp$remote_file"); // phpcs:ignore
69
  }
70
  }
includes/classes/class-woo-feed-webappick-api.php CHANGED
@@ -265,7 +265,7 @@ if ( ! class_exists( 'WooFeedWebAppickAPI' ) ) {
265
  * @return void
266
  */
267
  public function woo_feed_pro_vs_free(){
268
- /** @define "WOO_FEED_FREE_ADMIN_PATH" "./../../admin/" */ // phpcs:ignore
269
  require WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-pro-vs-free.php';
270
  }
271
 
@@ -385,29 +385,31 @@ if ( ! class_exists( 'WooFeedWebAppickAPI' ) ) {
385
  <?php
386
  }
387
  if ( true === $has_notice ) {
388
- $jss = <<<JSS
389
- (function($){
390
- "use strict";
391
- $(document)
392
- .on('click', '.woo-feed-notice a.button', function (e) {
393
- e.preventDefault();
394
- // noinspection ES6ConvertVarToLetConst
395
- var self = $(this), notice = self.attr('data-response');
396
- if ( 'given' === notice ) {
397
- window.open('https://wordpress.org/support/plugin/webappick-product-feed-for-woocommerce/reviews/?rate=5#new-post', '_blank');
398
- }
399
- self.closest(".woo-feed-notice").slideUp( 200, 'linear' );
400
- wp.ajax.post( 'woo_feed_save_review_notice', { _ajax_nonce: '$nonce', notice: notice } );
401
- })
402
- .on('click', '.woo-feed-notice .notice-dismiss', function (e) {
403
- e.preventDefault();
404
- // noinspection ES6ConvertVarToLetConst
405
- var self = $(this), feed_notice = self.closest('.woo-feed-notice'), which = feed_notice.attr('data-which');
406
- wp.ajax.post( 'woo_feed_hide_notice', { _wpnonce: '$nonce', which: which } );
407
- });
408
- })(jQuery);
409
- JSS;
410
- wp_add_inline_script( 'wp-util', $jss );
 
 
411
  }
412
  }
413
 
265
  * @return void
266
  */
267
  public function woo_feed_pro_vs_free(){
268
+ /** @define "WOO_FEED_FREE_ADMIN_PATH''./../../admin/" */ // phpcs:ignore
269
  require WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-pro-vs-free.php';
270
  }
271
 
385
  <?php
386
  }
387
  if ( true === $has_notice ) {
388
+ add_action( 'admin_print_footer_scripts', function() use ( $nonce ) {
389
+ ?>
390
+ <script>
391
+ (function($){
392
+ "use strict";
393
+ $(document)
394
+ .on('click', '.woo-feed-notice a.button', function (e) {
395
+ e.preventDefault();
396
+ // noinspection ES6ConvertVarToLetConst
397
+ var self = $(this), notice = self.attr('data-response');
398
+ if ( 'given' === notice ) {
399
+ window.open('https://wordpress.org/support/plugin/webappick-product-feed-for-woocommerce/reviews/?rate=5#new-post', '_blank');
400
+ }
401
+ self.closest(".woo-feed-notice").slideUp( 200, 'linear' );
402
+ wp.ajax.post( 'woo_feed_save_review_notice', { _ajax_nonce: '$nonce', notice: notice } );
403
+ })
404
+ .on('click', '.woo-feed-notice .notice-dismiss', function (e) {
405
+ e.preventDefault();
406
+ // noinspection ES6ConvertVarToLetConst
407
+ var self = $(this), feed_notice = self.closest('.woo-feed-notice'), which = feed_notice.attr('data-which');
408
+ wp.ajax.post( 'woo_feed_hide_notice', { _wpnonce: '<?php echo esc_attr( $nonce ); ?>', which: which } );
409
+ });
410
+ })(jQuery)
411
+ </script><?php
412
+ }, 99 );
413
  }
414
  }
415
 
includes/cron-helper.php ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Cron Helper Functions
4
+ * @package WooFeed
5
+ * @subpackage WooFeed_Helper_Functions
6
+ * @version 1.0.0
7
+ * @since WooFeed 3.3.0
8
+ * @author KD <mhamudul.hk@gmail.com>
9
+ * @copyright WebAppick
10
+ */
11
+
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ die(); // Silence...
14
+ }
15
+ /** @define "WOO_FEED_ADMIN_PATH" "./../admin/" */ // phpcs:ignore
16
+
17
+
18
+ // Cron Action.
19
+ if ( ! function_exists( 'woo_feed_cron_update_feed' ) ) {
20
+ /**
21
+ * Scheduled Action Hook
22
+ * @return void
23
+ */
24
+ function woo_feed_cron_update_feed() {
25
+ global $wpdb;
26
+ // if ( woo_feed_is_debugging_enabled() ) {
27
+ // woo_feed_delete_log( 'woo-feed-cron' );
28
+ // woo_feed_log_feed_process( 'woo-feed-cron', 'Preparing WooFeed Auto Update' );
29
+ // $processed = 0;
30
+ // }
31
+ $query = $wpdb->prepare( "SELECT option_name FROM $wpdb->options WHERE option_name LIKE %s;", 'wf_feed_' . "%" );
32
+ $result = $wpdb->get_results( $query, ARRAY_A ); // phpcs:ignore
33
+ foreach ( $result as $option ) {
34
+ $feedInfo = maybe_unserialize( get_option( $option['option_name'] ) );
35
+ if ( ! isset( $feedInfo['feedrules'] ) || isset( $feedInfo['status'] ) && '0' == $feedInfo['status'] ) continue;
36
+ // try {
37
+ // $processed++;
38
+ // if ( woo_feed_is_debugging_enabled() ) {
39
+ // woo_feed_delete_log( $feedInfo['feedrules']['filename'] );
40
+ // woo_feed_log_feed_process( $feedInfo['feedrules']['filename'], sprintf( 'Getting Data for %s feed.', $option ) );
41
+ // woo_feed_log_feed_process( $feedInfo['feedrules']['filename'], 'Generating Feed VIA CRON JOB...' );
42
+ // woo_feed_log_feed_process( $feedInfo['feedrules']['filename'], sprintf( 'Getting Data for %s feed.', $option ) );
43
+ // woo_feed_log_feed_process( $feedInfo['feedrules']['filename'], 'Current Limit is ---.' );
44
+ // woo_feed_log( $feedInfo['feedrules']['filename'], 'Feed Config::' . PHP_EOL . print_r( $feedInfo['feedrules'], true ), 'info' );
45
+ // }
46
+ woo_feed_generate_feed( $feedInfo['feedrules'] );
47
+ // } catch ( Exception $e ) {
48
+ // $message = 'Error Updating Feed Via CRON Job' . PHP_EOL . 'Caught Exception :: ' . $e->getMessage();
49
+ // woo_feed_log( $feedInfo['feedrules']['filename'], $message, 'critical', $e, true );
50
+ // woo_feed_log_fatal_error( $message, $e );
51
+ // }
52
+ }
53
+ // if ( woo_feed_is_debugging_enabled() ) {
54
+ // woo_feed_log_feed_process( 'woo-feed-cron', sprintf( 'Total %d Feed Processed', $processed ) );
55
+ // woo_feed_log_feed_process( 'woo-feed-cron', 'WooFeed Auto Update Completed' );
56
+ // }
57
+ }
58
+
59
+ add_action( 'woo_feed_update', 'woo_feed_cron_update_feed' );
60
+ }
61
+
62
+ // Single Feed Update Cron
63
+ if ( ! function_exists( 'woo_feed_cron_update_single_feed' ) ) {
64
+ /**
65
+ * Scheduled Action Hook
66
+ *
67
+ * @param array $feedName
68
+ *
69
+ * @return void
70
+ */
71
+ function woo_feed_cron_update_single_feed( $feedName ) {
72
+ global $wpdb;
73
+ $feedName = 'wf_feed_' . $feedName[0];
74
+ $result = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->options WHERE option_name = %s", $feedName ), 'ARRAY_A' ); // phpcs:ignore
75
+ if ( ! empty( $result ) ) {
76
+ foreach ( $result as $key => $value ) {
77
+ $feedInfo = maybe_unserialize( get_option( $value['option_name'] ) );
78
+ if ( ! isset( $feedInfo['feedrules'] ) || isset( $feedInfo['status'] ) && "0" == $feedInfo['status'] ) {
79
+ continue;
80
+ }
81
+ woo_feed_generate_feed( $feedInfo['feedrules'] );
82
+ }
83
+ }
84
+ }
85
+
86
+ add_action( 'woo_feed_update_single_feed', 'woo_feed_cron_update_single_feed' );
87
+ }
88
+ add_action( 'woo_feed_after_update_config', function( $data, $feed_slug ) {
89
+ // Schedule Cron.
90
+ wp_schedule_event( time(), 'woo_feed_corn', 'woo_feed_update_single_feed', [ $feed_slug ] );
91
+ }, 10, 3 );
92
+ // End of file cron-helper.php.
includes/feeds/class-woo-feed-custom.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
 
3
  /**
4
  * Class Custom
@@ -9,8 +9,7 @@
9
  * @package Shopping
10
  *
11
  */
12
- class Woo_Feed_Custom
13
- {
14
  /**
15
  * This variable is responsible for holding all product attributes and their values
16
  *
@@ -28,9 +27,9 @@ class Woo_Feed_Custom
28
  * @access public
29
  */
30
  public $rules;
31
-
32
-
33
- /**
34
  * Store product information
35
  *
36
  * @since 1.0.0
@@ -48,16 +47,21 @@ class Woo_Feed_Custom
48
  * @since 1.0.0
49
  */
50
  public function __construct( $feedRule ) {
51
- $this->products = new Woo_Feed_Products_v3($feedRule);
52
- # When update via cron job then set productIds
53
- if ( ! isset($feedRule['productIds']) ) {
54
- $feedRule['productIds'] = $this->products->query_products();
55
- }
56
- $this->products->get_products($feedRule['productIds']);
57
- $this->rules = $feedRule;
 
58
  // $products = new Woo_Feed_Products();
59
- // $storeProducts = $products->woo_feed_get_visible_product($feedRule);
60
- // $engine = new WF_Engine($storeProducts, $feedRule);
 
 
 
 
61
  // $this->products = $engine->mapProductsByRules();
62
  // $this->rules = $feedRule;
63
  // if ($feedRule['feedType'] == 'xml') {
@@ -65,7 +69,6 @@ class Woo_Feed_Custom
65
  // }
66
  }
67
 
68
-
69
  /**
70
  * Prepare Feed For XML Output
71
  *
@@ -91,17 +94,17 @@ class Woo_Feed_Custom
91
  * @param string $space
92
  * @return string
93
  */
94
- function formatXMLLine( $attribute, $value, $space ="" ) {
95
- $attribute = str_replace(" ", "_", $attribute);
96
  //Make child node for XML
97
- if ( ! empty($value))
98
- $value = trim($value);
99
- if ( strpos($value, "<![CDATA[") === false && substr(trim($value), 0, 4) == "http" ) {
100
  $value = "<![CDATA[$value]]>";
101
- } elseif ( strpos($value, "<![CDATA[") === false && ! is_numeric(trim($value)) && ! empty($value) ) {
102
  $value = "<![CDATA[$value]]>";
103
  }
104
- if ( $this->rules['provider'] == 'myshopping.com.au' && $attribute == "Category" ) {
105
  return "$space<$attribute xml:space=\"preserve\">$value</$attribute>";
106
  }
107
  return "
@@ -114,48 +117,55 @@ class Woo_Feed_Custom
114
  * @return array|bool|string
115
  */
116
  public function returnFinalProduct() {
117
- if ( ! empty($this->products) ) {
118
- if ( $this->rules['feedType'] == 'xml' ) {
119
- //return $engine->get_feed($this->products);
120
- $feed = array(
121
- "body" => $this->products->feedBody,
122
- "header" => $this->products->feedHeader,
123
- "footer" => $this->products->feedFooter,
124
- );
125
- //echo "<pre>";print_r($feed);die();
126
- return $feed;
127
- } elseif ( $this->rules['feedType'] == 'txt' ) {
128
- //return $engine->get_txt_feed();
129
- $feed = array(
130
- "body" => $this->products->feedBody,
131
- "header" => $this->products->feedHeader,
132
- "footer" => "",
133
- );
134
- return $feed;
135
- } elseif ( $this->rules['feedType'] == 'csv' ) {
136
- //return $engine->get_csv_feed();
137
- $feed = array(
138
- "body" => $this->products->feedBody,
139
- "header" => $this->products->feedHeader,
140
- "footer" => "",
141
- );
142
- //echo "<pre>";print_r($feed);die();
143
- return $feed;
144
- }
145
- }
146
 
147
  $feed = array(
148
- "body" => "",
149
- "header" => "",
150
- "footer" => "",
151
  );
152
  return $feed;
153
  }
154
 
155
  public function get_header( $engine ) {
156
  $datetime_now = gmdate("Y-m-d H:i:s");
157
-
158
- if ( $this->rules['provider'] == 'zap.co.il' ) {
 
 
 
 
 
 
 
159
  $zap = "<STORE>
160
  <datetime>$datetime_now</datetime>
161
  <title>". get_bloginfo('name') ."</title>
@@ -165,40 +175,96 @@ class Woo_Feed_Custom
165
  <email>". get_bloginfo('admin_email') ."</email>";
166
  return $zap;
167
  }
168
- elseif ( $this->rules['provider'] == 'myshopping.com.au' ) {
169
  return "<productset>";
170
  }
171
- elseif ( in_array($this->rules['provider'], [
172
- 'fruugo.au',
173
- 'stylight.com',
174
- 'nextad',
175
- 'skinflint.co.uk',
176
- 'comparer.be',
177
- 'dooyoo',
178
- 'hintaseuranta.fi',
179
- 'incurvy',
180
- 'kijiji.ca',
181
- 'marktplaats.nl',
182
- 'rakuten.de',
183
- 'shopalike.fr',
184
- 'spartoo.fi',
185
- 'webmarchand',
186
- ]) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
  return "<products version=\"1.0\" standalone=\"yes\">
188
  <datetime>$datetime_now</datetime>
189
  <title>". get_bloginfo('name') ."</title>
190
  <link>". get_bloginfo('url') ."</link>
191
  <description>". get_bloginfo('description') ."</description>";
192
  }
193
- elseif ( $this->rules['provider'] == "fashiola.de" ) {
194
  return "<products version=\"1.0\" standalone=\"yes\">
195
  <datetime>$datetime_now</datetime>
196
  <title>". get_bloginfo('name') ."</title>
197
  <link>". get_bloginfo('url') ."</link>
198
  <description>". get_bloginfo('description') ."</description>";
199
  }
200
- elseif ( $this->rules['provider'] == 'criteo' ) {
201
- return "<channel>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202
  <title>". get_bloginfo('name') ."</title>
203
  <link>". get_bloginfo('url') ."</link>
204
  <description>". get_bloginfo('description') ."</description>";
@@ -209,18 +275,15 @@ class Woo_Feed_Custom
209
  }
210
 
211
  public function get_footer( $engine ) {
212
- if ( in_array($this->rules['provider'], [ 'fruugo.au', 'stylight.com', 'nextad', 'skinflint.co.uk', 'comparer.be', 'dooyoo', 'hintaseuranta.fi', 'incurvy', 'kijiji.ca', 'marktplaats.nl', 'rakuten.de', 'shopalike.fr', 'spartoo.fi', 'webmarchand', 'fashiola.de' ]) ) {
213
  return "</products>";
214
  }
215
- elseif ( $this->rules['provider'] == 'zap.co.il' ) {
216
  return "</STORE>";
217
  }
218
- elseif ( $this->rules['provider'] == 'myshopping.com.au' ) {
219
  return "</productset>";
220
  }
221
- elseif ( $this->rules['provider'] == 'criteo' ) {
222
- return "</channel>";
223
- }
224
  else {
225
  return $engine->get_xml_feed_footer();
226
  }
1
+ <?php /** @noinspection PhpUnusedPrivateMethodInspection, PhpUnused, PhpUnusedPrivateFieldInspection, PhpUnusedLocalVariableInspection, DuplicatedCode */
2
 
3
  /**
4
  * Class Custom
9
  * @package Shopping
10
  *
11
  */
12
+ class Woo_Feed_Custom {
 
13
  /**
14
  * This variable is responsible for holding all product attributes and their values
15
  *
27
  * @access public
28
  */
29
  public $rules;
30
+
31
+
32
+ /**
33
  * Store product information
34
  *
35
  * @since 1.0.0
47
  * @since 1.0.0
48
  */
49
  public function __construct( $feedRule ) {
50
+ $this->products = new Woo_Feed_Products_v3($feedRule);
51
+ # When update via cron job then set productIds
52
+ if ( ! isset($feedRule['productIds']) ) {
53
+ $feedRule['productIds'] = $this->products->query_products();
54
+ }
55
+ $this->products->get_products($feedRule['productIds']);
56
+ $this->rules = $feedRule;
57
+
58
  // $products = new Woo_Feed_Products();
59
+ // $limit =isset($feedRule['Limit'])?esc_html($feedRule['Limit']):'';
60
+ // $offset = isset($feedRule['Offset'])?esc_html($feedRule['Offset']):'';
61
+ // $categories = isset($feedRule['categories']) ? $feedRule['categories']: '';
62
+ // $storeProducts = $products->woo_feed_get_visible_product($limit, $offset,$categories,$feedRule);
63
+ // $feedRule=$products->feedRule;
64
+ // $engine = new WF_Engine($storeProducts,$feedRule);
65
  // $this->products = $engine->mapProductsByRules();
66
  // $this->rules = $feedRule;
67
  // if ($feedRule['feedType'] == 'xml') {
69
  // }
70
  }
71
 
 
72
  /**
73
  * Prepare Feed For XML Output
74
  *
94
  * @param string $space
95
  * @return string
96
  */
97
+ function formatXMLLine( $attribute, $value, $space = '' ) {
98
+ $attribute = str_replace( ' ', '_', $attribute );
99
  //Make child node for XML
100
+ if ( ! empty( $value ) )
101
+ $value = trim( $value );
102
+ if ( false === strpos($value, '<![CDATA[' ) && 'http' == substr(trim($value), 0, 4) ) {
103
  $value = "<![CDATA[$value]]>";
104
+ } elseif ( false === strpos( $value, '<![CDATA[' ) && ! is_numeric( trim( $value ) ) && ! empty( $value ) ) {
105
  $value = "<![CDATA[$value]]>";
106
  }
107
+ if ( 'myshopping.com.au' == $this->rules['provider'] && 'Category' == $attribute ) {
108
  return "$space<$attribute xml:space=\"preserve\">$value</$attribute>";
109
  }
110
  return "
117
  * @return array|bool|string
118
  */
119
  public function returnFinalProduct() {
120
+ if ( ! empty($this->products) ) {
121
+ if ( 'xml' == $this->rules['feedType'] ) {
122
+ //return $engine->get_feed($this->products);
123
+ $feed = array(
124
+ "body" => $this->products->feedBody,
125
+ "header" => $this->products->feedHeader,
126
+ "footer" => $this->products->feedFooter,
127
+ );
128
+ //echo "<pre>";print_r($feed);die();
129
+ return $feed;
130
+ } elseif ( 'txt' == $this->rules['feedType'] ) {
131
+ //return $engine->get_txt_feed();
132
+ $feed = array(
133
+ 'body' => $this->products->feedBody,
134
+ 'header' => $this->products->feedHeader,
135
+ 'footer' => '',
136
+ );
137
+ return $feed;
138
+ } elseif ( 'csv' == $this->rules['feedType'] ) {
139
+ //return $engine->get_csv_feed();
140
+ $feed = array(
141
+ 'body' => $this->products->feedBody,
142
+ 'header' => $this->products->feedHeader,
143
+ 'footer' => '',
144
+ );
145
+
146
+ return $feed;
147
+ }
148
+ }
149
 
150
  $feed = array(
151
+ "body" => '',
152
+ "header" => '',
153
+ "footer" => '',
154
  );
155
  return $feed;
156
  }
157
 
158
  public function get_header( $engine ) {
159
  $datetime_now = gmdate("Y-m-d H:i:s");
160
+ if ( 'fruugo.au' == $this->rules["provider"] ) {
161
+ $fruugo_au = "<products version=\"1.0\" standalone=\"yes\">
162
+ <datetime>$datetime_now</datetime>
163
+ <title>". get_bloginfo('name') ."</title>
164
+ <link>". get_bloginfo('url') ."</link>
165
+ <description>". get_bloginfo('description') ."</description>";
166
+ return $fruugo_au;
167
+ }
168
+ elseif ( 'zap.co.il' == $this->rules['provider'] ) {
169
  $zap = "<STORE>
170
  <datetime>$datetime_now</datetime>
171
  <title>". get_bloginfo('name') ."</title>
175
  <email>". get_bloginfo('admin_email') ."</email>";
176
  return $zap;
177
  }
178
+ elseif ( 'myshopping.com.au' == $this->rules['provider'] ) {
179
  return "<productset>";
180
  }
181
+ elseif ( 'stylight.com' == $this->rules['provider'] ) {
182
+ return "<products version=\"1.0\" standalone=\"yes\">
183
+ <datetime>$datetime_now</datetime>
184
+ <title>". get_bloginfo('name') ."</title>
185
+ <link>". get_bloginfo('url') ."</link>
186
+ <description>". get_bloginfo('description') ."</description>";
187
+ }
188
+ elseif ( 'nextad' == $this->rules['provider'] ) {
189
+ return "<products version=\"1.0\" standalone=\"yes\">
190
+ <datetime>$datetime_now</datetime>
191
+ <title>". get_bloginfo('name') ."</title>
192
+ <link>". get_bloginfo('url') ."</link>
193
+ <description>". get_bloginfo('description') ."</description>";
194
+ }
195
+ elseif ( 'skinflint.co.uk' == $this->rules['provider'] ) {
196
+ return "<products version=\"1.0\" standalone=\"yes\">
197
+ <datetime>$datetime_now</datetime>
198
+ <title>". get_bloginfo('name') ."</title>
199
+ <link>". get_bloginfo('url') ."</link>
200
+ <description>". get_bloginfo('description') ."</description>";
201
+ }
202
+ elseif ( 'comparer.be' == $this->rules['provider'] ) {
203
+ return "<products version=\"1.0\" standalone=\"yes\">
204
+ <datetime>$datetime_now</datetime>
205
+ <title>". get_bloginfo('name') ."</title>
206
+ <link>". get_bloginfo('url') ."</link>
207
+ <description>". get_bloginfo('description') ."</description>";
208
+ }
209
+ elseif ( 'dooyoo' == $this->rules['provider'] ) {
210
+ return "<products version=\"1.0\" standalone=\"yes\">
211
+ <datetime>$datetime_now</datetime>
212
+ <title>". get_bloginfo('name') ."</title>
213
+ <link>". get_bloginfo('url') ."</link>
214
+ <description>". get_bloginfo('description') ."</description>";
215
+ }
216
+ elseif ( 'hintaseuranta.fi' == $this->rules['provider'] ) {
217
+ return "<products version=\"1.0\" standalone=\"yes\">
218
+ <datetime>$datetime_now</datetime>
219
+ <title>". get_bloginfo('name') ."</title>
220
+ <link>". get_bloginfo('url') ."</link>
221
+ <description>". get_bloginfo('description') ."</description>";
222
+ }
223
+ elseif ( 'incurvy' == $this->rules['provider'] ) {
224
+ return "<products version=\"1.0\" standalone=\"yes\">
225
+ <datetime>$datetime_now</datetime>
226
+ <title>". get_bloginfo('name') ."</title>
227
+ <link>". get_bloginfo('url') ."</link>
228
+ <description>". get_bloginfo('description') ."</description>";
229
+ }
230
+ elseif ( 'kijiji.ca' == $this->rules['provider'] ) {
231
+ return "<products version=\"1.0\" standalone=\"yes\">
232
+ <datetime>$datetime_now</datetime>
233
+ <title>". get_bloginfo('name') ."</title>
234
+ <link>". get_bloginfo('url') ."</link>
235
+ <description>". get_bloginfo('description') ."</description>";
236
+ }
237
+ elseif ( 'marktplaats.nl' == $this->rules['provider'] ) {
238
  return "<products version=\"1.0\" standalone=\"yes\">
239
  <datetime>$datetime_now</datetime>
240
  <title>". get_bloginfo('name') ."</title>
241
  <link>". get_bloginfo('url') ."</link>
242
  <description>". get_bloginfo('description') ."</description>";
243
  }
244
+ elseif ( 'rakuten.de' == $this->rules['provider'] ) {
245
  return "<products version=\"1.0\" standalone=\"yes\">
246
  <datetime>$datetime_now</datetime>
247
  <title>". get_bloginfo('name') ."</title>
248
  <link>". get_bloginfo('url') ."</link>
249
  <description>". get_bloginfo('description') ."</description>";
250
  }
251
+ elseif ( 'shopalike.fr' == $this->rules['provider'] ) {
252
+ return "<products version=\"1.0\" standalone=\"yes\">
253
+ <datetime>$datetime_now</datetime>
254
+ <title>". get_bloginfo('name') ."</title>
255
+ <link>". get_bloginfo('url') ."</link>
256
+ <description>". get_bloginfo('description') ."</description>";
257
+ }
258
+ elseif ( 'spartoo.fi' == $this->rules['provider'] ) {
259
+ return "<products version=\"1.0\" standalone=\"yes\">
260
+ <datetime>$datetime_now</datetime>
261
+ <title>". get_bloginfo('name') ."</title>
262
+ <link>". get_bloginfo('url') ."</link>
263
+ <description>". get_bloginfo('description') ."</description>";
264
+ }
265
+ elseif ( 'webmarchand' == $this->rules['provider'] ) {
266
+ return "<products version=\"1.0\" standalone=\"yes\">
267
+ <datetime>$datetime_now</datetime>
268
  <title>". get_bloginfo('name') ."</title>
269
  <link>". get_bloginfo('url') ."</link>
270
  <description>". get_bloginfo('description') ."</description>";
275
  }
276
 
277
  public function get_footer( $engine ) {
278
+ if ( in_array($this->rules['provider'], [ 'fruugo.au', 'stylight.com', 'nextad', 'skinflint.co.uk', 'comparer.be', 'dooyoo', 'hintaseuranta.fi', 'incurvy', 'kijiji.ca', 'marktplaats.nl', 'rakuten.de', 'shopalike.fr', 'spartoo.fi', 'webmarchand' ]) ) {
279
  return "</products>";
280
  }
281
+ elseif ( 'zap.co.il' == $this->rules['provider'] ) {
282
  return "</STORE>";
283
  }
284
+ elseif ( 'myshopping.com.au' == $this->rules['provider'] ) {
285
  return "</productset>";
286
  }
 
 
 
287
  else {
288
  return $engine->get_xml_feed_footer();
289
  }
includes/feeds/class-woo-feed-facebook.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
 
3
  /**
4
  * Class Google
@@ -9,92 +9,95 @@
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 Woo_Feed_Products_v3 $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
- $feedRule['itemWrapper'] = $this->feedWrapper;
88
- $this->products = new Woo_Feed_Products_v3($feedRule);
89
-
90
- # When update via cron job then set productIds
91
- if ( ! isset($feedRule['productIds']) ) {
92
- $feedRule['productIds'] = $this->products->query_products();
93
- }
94
- $this->products->get_products($feedRule['productIds']);
95
- $this->rules = $feedRule;
96
  // $products = new Woo_Feed_Products();
97
- // $storeProducts = $products->woo_feed_get_visible_product($feedRule);
 
 
 
 
98
  // $engine = new WF_Engine($storeProducts, $feedRule);
99
  // $this->products = $engine->mapProductsByRules();
100
  // $this->rules = $feedRule;
@@ -103,421 +106,453 @@ class Woo_Feed_Facebook
103
  // } else {
104
  // $this->mapAttributeForCSVTXT();
105
  // }
106
-
107
- }
108
-
109
-
110
- /**
111
- * Return Feed
112
- *
113
- * @return array|bool|string
114
- */
115
- public function returnFinalProduct() {
116
- if ( ! empty($this->products) ) {
117
-
118
- if ( $this->rules['feedType'] == 'xml' ) {
119
- //return $this->get_feed($this->products);
120
- $feed = array(
121
- "header" => $this->get_xml_feed_header(),
122
- "body" => $this->products->feedBody,
123
- "footer" => $this->get_xml_feed_footer(),
124
- );
125
- return $feed;
126
- } elseif ( $this->rules['feedType'] == 'txt' ) {
127
-
128
- $feed = array(
129
- "body" => $this->products->feedBody,
130
- "header" => $this->products->feedHeader,
131
- "footer" => "",
132
- );
133
- //echo "<pre>";print_r($feed);die();
134
- return $feed;
135
- } elseif ( $this->rules['feedType'] == 'csv' ) {
136
-
137
- $feed = array(
138
- "body" => $this->products->feedBody,
139
- "header" => $this->products->feedHeader,
140
- "footer" => "",
141
- );
142
- return $feed;
143
- }
144
- }
145
-
146
- $feed = array(
147
- "body" => "",
148
- "header" => "",
149
- "footer" => "",
150
- );
151
- return $feed;
152
- }
153
-
154
- /**
155
- * Configure merchant attributes for XML feed
156
- */
157
- public function mapAttributeForXML() {
158
-
159
- $googleXMLAttribute = array(
160
- "id" => array( "g:id", false ),
161
- "title" => array( "g:title", true ),
162
- "description" => array( "g:description", true ),
163
- "link" => array( "g:link", true ),
164
- "mobile_link" => array( "g:mobile_link", true ),
165
- "product_type" => array( "g:product_type", true ),
166
- "current_category" => array( "g:google_product_category", true ),
167
- "image" => array( "g:image_link", true ),
168
- "images" => array( "g:additional_image_link", false ),
169
- "images_1" => array( "g:additional_image_link_1", true ),
170
- "images_2" => array( "g:additional_image_link_2", true ),
171
- "images_3" => array( "g:additional_image_link_3", true ),
172
- "images_4" => array( "g:additional_image_link_4", true ),
173
- "images_5" => array( "g:additional_image_link_5", true ),
174
- "images_6" => array( "g:additional_image_link_6", true ),
175
- "images_7" => array( "g:additional_image_link_7", true ),
176
- "images_8" => array( "g:additional_image_link_8", true ),
177
- "images_9" => array( "g:additional_image_link_9", true ),
178
- "images_10" => array( "g:additional_image_link_10", true ),
179
- "condition" => array( "g:condition", false ),
180
- "availability" => array( "g:availability", false ),
181
- "inventory" => array( "g:inventory", false ),
182
- "override" => array( "g:override", false ),
183
- "price" => array( "g:price", true ),
184
- "sale_price" => array( "g:sale_price", true ),
185
- "sale_price_effective_date" => array( "g:sale_price_effective_date", true ),
186
- "brand" => array( "g:brand", true ),
187
- "sku" => array( "g:mpn", true ),
188
- "upc" => array( "g:gtin", true ),
189
- "identifier_exists" => array( "g:identifier_exists", true ),
190
- "item_group_id" => array( "g:item_group_id", false ),
191
- "color" => array( "g:color", true ),
192
- "gender" => array( "g:gender", true ),
193
- "age_group" => array( "g:age_group", true ),
194
- "material" => array( "g:material", true ),
195
- "pattern" => array( "g:pattern", true ),
196
- "size" => array( "g:size", true ),
197
- "size_type" => array( "g:size_type", true ),
198
- "size_system" => array( "g:size_system", true ),
199
- "tax" => array( "tax", true ),
200
- "weight" => array( "g:shipping_weight", false ),
201
- "length" => array( "g:shipping_length", false ),
202
- "width" => array( "g:shipping_width", false ),
203
- "height" => array( "g:shipping_height", false ),
204
- "shipping_label" => array( "g:shipping_label", false ),
205
- "shipping_country" => array( "g:shipping_country", false ),
206
- "shipping_service" => array( "g:shipping_service", false ),
207
- "shipping_price" => array( "g:shipping_price", false ),
208
- "shipping_region" => array( "g:shipping_region", false ),
209
- "multipack" => array( "g:multipack", true ),
210
- "is_bundle" => array( "g:is_bundle", true ),
211
- "adult" => array( "g:adult", true ),
212
- "adwords_redirect" => array( "g:adwords_redirect", true ),
213
- "custom_label_0" => array( "g:custom_label_0", true ),
214
- "custom_label_1" => array( "g:custom_label_1", true ),
215
- "custom_label_2" => array( "g:custom_label_2", true ),
216
- "custom_label_3" => array( "g:custom_label_3", true ),
217
- "custom_label_4" => array( "g:custom_label_4", true ),
218
- "excluded_destination" => array( "g:excluded_destination", true ),
219
- "expiration_date" => array( "g:expiration_date", true ),
220
- "unit_pricing_measure" => array( "g:unit_pricing_measure", true ),
221
- "unit_pricing_base_measure" => array( "g:unit_pricing_base_measure", true ),
222
- "energy_efficiency_class" => array( "g:energy_efficiency_class", true ),
223
- "loyalty_points" => array( "g:loyalty_points", true ),
224
- "installment" => array( "g:installment", true ),
225
- "promotion_id" => array( "g:promotion_id", true ),
226
- "cost_of_goods_sold" => array( "g:cost_of_goods_sold", true ),
227
- "availability_date" => array( "g:availability_date", true ),
228
- "tax_category" => array( "g:tax_category", true ),
229
- "included_destination" => array( "g:included_destination", true ),
230
- );
231
-
232
- if ( ! empty($this->products) ) {
233
- foreach ( $this->products as $no => $product ) {
234
- foreach ( $product as $key => $value ) {
235
- $this->mapAttribute($no, $key, $googleXMLAttribute[ $key ][0], $value, $googleXMLAttribute[ $key ][0]);
236
- }
237
- $this->process_google_shipping_attribute_for_xml($no);
238
- }
239
- }
240
- }
241
-
242
- /**
243
- * Configure merchant attributes for XML feed
244
- */
245
- public function mapAttributeForCSVTXT() {
246
- //Basic product information
247
- $googleCSVTXTAttribute = array(
248
- "id" => array( "id", false ),
249
- "title" => array( "title", true ),
250
- "description" => array( "description", true ),
251
- "link" => array( "link", true ),
252
- "mobile_link" => array( "mobile_link", true ),
253
- "product_type" => array( "product type", true ),
254
- "current_category" => array( "google product category", true ),
255
- "image" => array( "image link", true ),
256
- "images" => array( "additional image link", true ),
257
- "images_1" => array( "additional image link 1", true ),
258
- "images_2" => array( "additional image link 2", true ),
259
- "images_3" => array( "additional image link 3", true ),
260
- "images_4" => array( "additional image link 4", true ),
261
- "images_5" => array( "additional image link 5", true ),
262
- "images_6" => array( "additional image link 6", true ),
263
- "images_7" => array( "additional image link 7", true ),
264
- "images_8" => array( "additional image link 8", true ),
265
- "images_9" => array( "additional image link 9", true ),
266
- "images_10" => array( "additional image link 10", true ),
267
- "condition" => array( "condition", false ),
268
- "availability" => array( "availability", false ),
269
- "inventory" => array( "inventory", false ),
270
- "override" => array( "override", false ),
271
- "price" => array( "price", true ),
272
- "sale_price" => array( "sale price", true ),
273
- "sale_price_effective_date" => array( "sale price effective date", true ),
274
- "brand" => array( "brand", true ),
275
- "sku" => array( "mpn", true ),
276
- "upc" => array( "gtin", true ),
277
- "identifier_exists" => array( "identifier exists", true ),
278
- "item_group_id" => array( "item group id", false ),
279
- "color" => array( "color", true ),
280
- "gender" => array( "gender", true ),
281
- "age_group" => array( "age group", true ),
282
- "material" => array( "material", true ),
283
- "pattern" => array( "pattern", true ),
284
- "size" => array( "size", true ),
285
- "size_type" => array( "size type", true ),
286
- "size_system" => array( "size system", true ),
287
- "tax" => array( "tax", true ),
288
- "weight" => array( "shipping weight", false ),
289
- "length" => array( "shipping length", false ),
290
- "width" => array( "shipping width", false ),
291
- "height" => array( "shipping height", false ),
292
- "shipping_label" => array( "shipping label", false ),
293
- "shipping_country" => array( "shipping country", false ),
294
- "shipping_service" => array( "shipping service", false ),
295
- "shipping_price" => array( "shipping price", false ),
296
- "shipping_region" => array( "shipping region", false ),
297
- "multipack" => array( "multipack", true ),
298
- "is_bundle" => array( "is bundle", true ),
299
- "adult" => array( "adult", true ),
300
- "adwords_redirect" => array( "adwords redirect", true ),
301
- "custom_label_0" => array( "custom label 0", true ),
302
- "custom_label_1" => array( "custom label 1", true ),
303
- "custom_label_2" => array( "custom label 2", true ),
304
- "custom_label_3" => array( "custom label 3", true ),
305
- "custom_label_4" => array( "custom label 4", true ),
306
- "excluded_destination" => array( "excluded destination", true ),
307
- "expiration_date" => array( "expiration date", true ),
308
- "unit_pricing_measure" => array( "unit pricing measure", true ),
309
- "unit_pricing_base_measure" => array( "unit pricing base measure", true ),
310
- "energy_efficiency_class" => array( "energy efficiency class", true ),
311
- "loyalty_points" => array( "loyalty points", true ),
312
- "installment" => array( "installment", true ),
313
- "promotion_id" => array( "promotion id", true ),
314
- "cost_of_goods_sold" => array( "cost of goods sold", true ),
315
- "availability_date" => array( "availability date", true ),
316
- "tax_category" => array( "tax category", true ),
317
- "included_destination" => array( "included destination", true ),
318
- );
319
-
320
- if ( ! empty($this->products) ) {
321
- foreach ( $this->products as $no => $product ) {
322
- foreach ( $product as $key => $value ) {
323
- $this->mapAttribute($no, $key, str_replace(" ", "_", $googleCSVTXTAttribute[ $key ][0]), $value, $googleCSVTXTAttribute[ $key ][0]);
324
- }
325
- $this->process_google_shipping_attribute_for_CSVTXT($no);
326
- }
327
- }
328
- }
329
-
330
- /**
331
- * Map to google attribute
332
- * @param $no
333
- * @param $from
334
- * @param $to
335
- * @param $value
336
- * @param bool $cdata
337
- * @return array
338
- */
339
- public function mapAttribute( $no, $from, $to, $value, $cdata = false ) {
340
- unset($this->products[ $no ][ $from ]);
341
- if ( $this->rules['feedType'] == 'xml' ) {
342
- return $this->products[ $no ][ $to ] = $this->formatXMLLine($to, $value, $cdata);
343
- } else {
344
- return $this->products[ $no ][ $to ] = $value;
345
- }
346
- }
347
-
348
-
349
- public
350
- function process_google_shipping_attribute_for_xml( $no ) {
351
- $shipping = array( 'g:shipping_country', 'g:shipping_service', 'g:shipping_price', 'g:shipping_region' );
352
- $shippingAttr = array();
353
- $products = $this->products[ $no ];
354
- foreach ( $products as $keyAttr => $valueAttr ) {
355
- if ( in_array($keyAttr, $shipping) ) {
356
- array_push($shippingAttr, array( $keyAttr => $valueAttr ));
357
- unset($this->products[ $no ][ $keyAttr ]);
358
- }
359
- }
360
- if ( count($shippingAttr) ) {
361
- $str = "";
362
- foreach ( $shippingAttr as $key => $attributes ) {
363
- foreach ( $attributes as $keyAttr => $valueAttr ) {
364
- $str .= str_replace("shipping_", "", $valueAttr);
365
- }
366
- }
367
- return $this->products[ $no ]['g:shipping'] = $this->formatXMLLine("g:shipping", $str, false);
368
- }
369
- return false;
370
- }
371
-
372
- public
373
- function process_google_shipping_attribute_for_CSVTXT( $no ) {
374
- $shipping = array( 'shipping_country', 'shipping_service', 'shipping_price', 'shipping_region' );
375
- $shippingAttr = array();
376
- $products = $this->products[ $no ];
377
- foreach ( $products as $keyAttr => $valueAttr ) {
378
- if ( in_array($keyAttr, $shipping) ) {
379
- array_push($shippingAttr, array( $keyAttr => $valueAttr ));
380
- unset($this->products[ $no ][ $keyAttr ]);
381
- }
382
- }
383
- if ( count($shippingAttr) ) {
384
- $str = "";
385
- foreach ( $shippingAttr as $key => $attributes ) {
386
- foreach ( $attributes as $keyAttr => $valueAttr ) {
387
- $country = ($keyAttr == "shipping_country") ? $str .= $valueAttr . ":" : "";
388
- $service = ($keyAttr == "shipping_service") ? $str .= $valueAttr . ":" : "";
389
- $price = ($keyAttr == "shipping_price") ? $str .= $valueAttr : "";
390
- $region = ($keyAttr == "shipping_region") ? $str .= $valueAttr . ":" : "";
391
- }
392
- }
393
- return $this->products[ $no ]['shipping(country:region:service:price)'] = str_replace(" : ", ":", $str);
394
- }
395
- return false;
396
- }
397
-
398
- /**
399
- * Make xml node
400
- *
401
- * @param string $attribute Attribute Name
402
- * @param string $value Attribute Value
403
- * @param bool $cdata
404
- * @param string $space
405
- * @return string
406
- */
407
- function formatXMLLine( $attribute, $value, $cdata, $space = "" ) {
408
- //Make single XML node
409
- if ( ! empty($value))
410
- $value = trim($value);
411
- if (gettype($value) == 'array')
412
- $value = json_encode($value);
413
- if ( strpos($value, "<![CDATA[") === false && substr(trim($value), 0, 4) == "http" ) {
414
- $value = "<![CDATA[$value]]>";
415
- } elseif ( strpos($value, "<![CDATA[") === false && $cdata === true && ! empty($value) ) {
416
- $value = "<![CDATA[$value]]>";
417
- } elseif ( $cdata ) {
418
- if ( ! empty($value) ) {
419
- $value = "<![CDATA[$value]]>";
420
- }
421
- }
422
-
423
- if ( substr($attribute, 0, 23) == 'g:additional_image_link' ) {
424
- $attribute = "g:additional_image_link";
425
- }
426
-
427
- return "
428
- $space<$attribute>$value</$attribute>";
429
- }
430
-
431
-
432
- /**
433
- * Make XML Feed Header
434
- * @return string
435
- */
436
- public function get_xml_feed_header() {
437
- $output = '<?xml version="1.0" encoding="UTF-8" ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
438
  <rss xmlns:g="http://base.google.com/ns/1.0" version="2.0">
439
  <channel>
440
- <title><![CDATA[' . html_entity_decode(get_option('blogname')) . ']]></title>
441
  <link><![CDATA[' . site_url() . ']]></link>
442
- <description><![CDATA[' . html_entity_decode( get_option('blogdescription')) . ']]></description>';
443
- return $output;
444
- }
445
-
446
- /** Make XML Feed
447
- * @param $items
448
- * @return bool|string
449
- */
450
- public function get_xml_feed_body( $items ) {
451
- $feed = "";
452
- //$feed .= $this->get_feed_header();
453
- $feed .= "\n";
454
- if ( $items ) {
455
- foreach ( $items as $item => $products ) {
456
- $feed .= " <".$this->feedWrapper.">";
457
- foreach ( $products as $key => $value ) {
458
- if ( ! empty($value) ) {
459
- $feed .= $value;
460
- }
461
- }
462
- $feed .= "\n </" . $this->feedWrapper . ">\n";
463
- }
464
- // $feed .= $this->get_feed_footer();
465
-
466
- return $feed;
467
- }
468
- return false;
469
- }
470
-
471
- /**
472
- * Make XML Feed Footer
473
- * @return string
474
- */
475
- public function get_xml_feed_footer() {
476
- $footer = " </channel>
 
 
 
 
477
  </rss>";
478
- return $footer;
479
- }
480
-
481
- /**
482
- * Short Products
483
- * @return array
484
- */
485
- public function short_products() {
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
- if ( $this->products ) {
507
- $headers = array_keys($this->products[0]);
508
- $feed[] = $headers;
509
- foreach ( $this->products as $no => $product ) {
510
- $row = array();
511
- foreach ( $headers as $key => $header ) {
512
- if ( strpos($header, "additional image link") !== false ) {
513
- $header = "additional image link";
514
- }
515
- $row[] = isset($product[ $header ]) ? $product[ $header ] : "";
516
- }
517
- $feed[] = $row;
518
- }
519
- return $feed;
520
- }
521
- return false;
522
- }
 
 
 
 
 
523
  }
1
+ <?php /** @noinspection PhpUnusedPrivateMethodInspection, PhpUndefinedMethodInspection, PhpUnused, PhpUnusedPrivateFieldInspection, PhpUnusedLocalVariableInspection, DuplicatedCode, PhpUnusedParameterInspection, PhpForeachNestedOuterKeyValueVariablesConflictInspection, RegExpRedundantEscape */
2
 
3
  /**
4
  * Class Google
9
  * @package Google
10
  *
11
  */
12
+ class Woo_Feed_Facebook {
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 array $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 array $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 array $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 int $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 string $feedWrapper Feed Wrapper text
64
+ * @access public
65
+ */
66
+ public $feedWrapper = 'item';
67
+
68
+ /**
69
+ * Store product information
70
+ *
71
+ * @since 1.0.0
72
+ * @var array $storeProducts
73
+ * @access public
74
+ */
75
+ private $storeProducts;
76
+
77
+ /**
78
+ * Define the core functionality to generate feed.
79
+ *
80
+ * Set the feed rules. Map products according to the rules and Check required attributes
81
+ * and their values according to merchant specification.
82
+ * @var Woo_Generate_Feed $feedRule Contain Feed Configuration
83
+ * @since 1.0.0
84
+ */
85
+ public function __construct( $feedRule ) {
86
+ $feedRule['itemWrapper'] = $this->feedWrapper;
87
+ $this->products = new Woo_Feed_Products_v3( $feedRule );
88
+ # When update via cron job then set productIds
89
+ if ( ! isset( $feedRule['productIds'] ) ) {
90
+ $feedRule['productIds'] = $this->products->query_products();
91
+ }
92
+ $this->products->get_products( $feedRule['productIds'] );
93
+ $this->rules = $feedRule;
94
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  // $products = new Woo_Feed_Products();
96
+ // $limit = isset($feedRule['Limit']) ? esc_html($feedRule['Limit']) : '';
97
+ // $offset = isset($feedRule['Offset']) ? esc_html($feedRule['Offset']) : '';
98
+ // $categories = isset($feedRule['categories']) ? $feedRule['categories']: '';
99
+ // $storeProducts = $products->woo_feed_get_visible_product($limit, $offset,$categories,$feedRule);
100
+ // $feedRule=$products->feedRule;
101
  // $engine = new WF_Engine($storeProducts, $feedRule);
102
  // $this->products = $engine->mapProductsByRules();
103
  // $this->rules = $feedRule;
106
  // } else {
107
  // $this->mapAttributeForCSVTXT();
108
  // }
109
+ }
110
+
111
+
112
+ /**
113
+ * Return Feed
114
+ *
115
+ * @return array|bool|string
116
+ */
117
+ public function returnFinalProduct() {
118
+ if ( ! empty( $this->products ) ) {
119
+
120
+ if ( 'xml' == $this->rules['feedType'] ) {
121
+ //return $this->get_feed($this->products);
122
+ $feed = array(
123
+ "header" => $this->get_xml_feed_header(),
124
+ "body" => $this->products->feedBody,
125
+ "footer" => $this->get_xml_feed_footer(),
126
+ );
127
+
128
+ return $feed;
129
+ } elseif ( 'txt' == $this->rules['feedType'] ) {
130
+
131
+ $feed = array(
132
+ "body" => $this->products->feedBody,
133
+ "header" => $this->products->feedHeader,
134
+ "footer" => '',
135
+ );
136
+
137
+ //echo "<pre>";print_r($feed);die();
138
+ return $feed;
139
+ } elseif ( 'csv' == $this->rules['feedType'] ) {
140
+
141
+ $feed = array(
142
+ "body" => $this->products->feedBody,
143
+ "header" => $this->products->feedHeader,
144
+ "footer" => '',
145
+ );
146
+
147
+ return $feed;
148
+ }
149
+ }
150
+
151
+ $feed = array(
152
+ "body" => '',
153
+ "header" => '',
154
+ "footer" => '',
155
+ );
156
+
157
+ return $feed;
158
+ }
159
+
160
+ /**
161
+ * Configure merchant attributes for XML feed
162
+ */
163
+ public function mapAttributeForXML() {
164
+
165
+ $googleXMLAttribute = array(
166
+ "id" => array( "g:id", false ),
167
+ "title" => array( "g:title", true ),
168
+ "description" => array( "g:description", true ),
169
+ "link" => array( "g:link", true ),
170
+ "mobile_link" => array( "g:mobile_link", true ),
171
+ "product_type" => array( "g:product_type", true ),
172
+ "current_category" => array( "g:google_product_category", true ),
173
+ "image" => array( "g:image_link", true ),
174
+ "images" => array( "g:additional_image_link", false ),
175
+ "images_1" => array( "g:additional_image_link_1", true ),
176
+ "images_2" => array( "g:additional_image_link_2", true ),
177
+ "images_3" => array( "g:additional_image_link_3", true ),
178
+ "images_4" => array( "g:additional_image_link_4", true ),
179
+ "images_5" => array( "g:additional_image_link_5", true ),
180
+ "images_6" => array( "g:additional_image_link_6", true ),
181
+ "images_7" => array( "g:additional_image_link_7", true ),
182
+ "images_8" => array( "g:additional_image_link_8", true ),
183
+ "images_9" => array( "g:additional_image_link_9", true ),
184
+ "images_10" => array( "g:additional_image_link_10", true ),
185
+ "condition" => array( "g:condition", false ),
186
+ "availability" => array( "g:availability", false ),
187
+ "inventory" => array( "g:inventory", false ),
188
+ "override" => array( "g:override", false ),
189
+ "price" => array( "g:price", true ),
190
+ "sale_price" => array( "g:sale_price", true ),
191
+ "sale_price_effective_date" => array( "g:sale_price_effective_date", true ),
192
+ "brand" => array( "g:brand", true ),
193
+ "sku" => array( "g:mpn", true ),
194
+ "upc" => array( "g:gtin", true ),
195
+ "identifier_exists" => array( "g:identifier_exists", true ),
196
+ "item_group_id" => array( "g:item_group_id", false ),
197
+ "color" => array( "g:color", true ),
198
+ "gender" => array( "g:gender", true ),
199
+ "age_group" => array( "g:age_group", true ),
200
+ "material" => array( "g:material", true ),
201
+ "pattern" => array( "g:pattern", true ),
202
+ "size" => array( "g:size", true ),
203
+ "size_type" => array( "g:size_type", true ),
204
+ "size_system" => array( "g:size_system", true ),
205
+ "tax" => array( "tax", true ),
206
+ "weight" => array( "g:shipping_weight", false ),
207
+ "length" => array( "g:shipping_length", false ),
208
+ "width" => array( "g:shipping_width", false ),
209
+ "height" => array( "g:shipping_height", false ),
210
+ "shipping_label" => array( "g:shipping_label", false ),
211
+ "shipping_country" => array( "g:shipping_country", false ),
212
+ "shipping_service" => array( "g:shipping_service", false ),
213
+ "shipping_price" => array( "g:shipping_price", false ),
214
+ "shipping_region" => array( "g:shipping_region", false ),
215
+ "multipack" => array( "g:multipack", true ),
216
+ "is_bundle" => array( "g:is_bundle", true ),
217
+ "adult" => array( "g:adult", true ),
218
+ "adwords_redirect" => array( "g:adwords_redirect", true ),
219
+ "custom_label_0" => array( "g:custom_label_0", true ),
220
+ "custom_label_1" => array( "g:custom_label_1", true ),
221
+ "custom_label_2" => array( "g:custom_label_2", true ),
222
+ "custom_label_3" => array( "g:custom_label_3", true ),
223
+ "custom_label_4" => array( "g:custom_label_4", true ),
224
+ "excluded_destination" => array( "g:excluded_destination", true ),
225
+ "expiration_date" => array( "g:expiration_date", true ),
226
+ "unit_pricing_measure" => array( "g:unit_pricing_measure", true ),
227
+ "unit_pricing_base_measure" => array( "g:unit_pricing_base_measure", true ),
228
+ "energy_efficiency_class" => array( "g:energy_efficiency_class", true ),
229
+ "loyalty_points" => array( "g:loyalty_points", true ),
230
+ "installment" => array( "g:installment", true ),
231
+ "promotion_id" => array( "g:promotion_id", true ),
232
+ "cost_of_goods_sold" => array( "g:cost_of_goods_sold", true ),
233
+ "availability_date" => array( "g:availability_date", true ),
234
+ "tax_category" => array( "g:tax_category", true ),
235
+ "included_destination" => array( "g:included_destination", true ),
236
+ );
237
+
238
+ if ( ! empty( $this->products ) ) {
239
+ foreach ( $this->products as $no => $product ) {
240
+ foreach ( $product as $key => $value ) {
241
+ $this->mapAttribute( $no,
242
+ $key,
243
+ $googleXMLAttribute[ $key ][0],
244
+ $value,
245
+ $googleXMLAttribute[ $key ][0] );
246
+ }
247
+ $this->process_google_shipping_attribute_for_xml( $no );
248
+ }
249
+ }
250
+ }
251
+
252
+ /**
253
+ * Configure merchant attributes for XML feed
254
+ */
255
+ public function mapAttributeForCSVTXT() {
256
+ //Basic product information
257
+ $googleCSVTXTAttribute = array(
258
+ "id" => array( "id", false ),
259
+ "title" => array( "title", true ),
260
+ "description" => array( "description", true ),
261
+ "link" => array( "link", true ),
262
+ "mobile_link" => array( "mobile_link", true ),
263
+ "product_type" => array( "product type", true ),
264
+ "current_category" => array( "google product category", true ),
265
+ "image" => array( "image link", true ),
266
+ "images" => array( "additional image link", true ),
267
+ "images_1" => array( "additional image link 1", true ),
268
+ "images_2" => array( "additional image link 2", true ),
269
+ "images_3" => array( "additional image link 3", true ),
270
+ "images_4" => array( "additional image link 4", true ),
271
+ "images_5" => array( "additional image link 5", true ),
272
+ "images_6" => array( "additional image link 6", true ),
273
+ "images_7" => array( "additional image link 7", true ),
274
+ "images_8" => array( "additional image link 8", true ),
275
+ "images_9" => array( "additional image link 9", true ),
276
+ "images_10" => array( "additional image link 10", true ),
277
+ "condition" => array( "condition", false ),
278
+ "availability" => array( "availability", false ),
279
+ "inventory" => array( "inventory", false ),
280
+ "override" => array( "override", false ),
281
+ "price" => array( "price", true ),
282
+ "sale_price" => array( "sale price", true ),
283
+ "sale_price_effective_date" => array( "sale price effective date", true ),
284
+ "brand" => array( "brand", true ),
285
+ "sku" => array( "mpn", true ),
286
+ "upc" => array( "gtin", true ),
287
+ "identifier_exists" => array( "identifier exists", true ),
288
+ "item_group_id" => array( "item group id", false ),
289
+ "color" => array( "color", true ),
290
+ "gender" => array( "gender", true ),
291
+ "age_group" => array( "age group", true ),
292
+ "material" => array( "material", true ),
293
+ "pattern" => array( "pattern", true ),
294
+ "size" => array( "size", true ),
295
+ "size_type" => array( "size type", true ),
296
+ "size_system" => array( "size system", true ),
297
+ "tax" => array( "tax", true ),
298
+ "weight" => array( "shipping weight", false ),
299
+ "length" => array( "shipping length", false ),
300
+ "width" => array( "shipping width", false ),
301
+ "height" => array( "shipping height", false ),
302
+ "shipping_label" => array( "shipping label", false ),
303
+ "shipping_country" => array( "shipping country", false ),
304
+ "shipping_service" => array( "shipping service", false ),
305
+ "shipping_price" => array( "shipping price", false ),
306
+ "shipping_region" => array( "shipping region", false ),
307
+ "multipack" => array( "multipack", true ),
308
+ "is_bundle" => array( "is bundle", true ),
309
+ "adult" => array( "adult", true ),
310
+ "adwords_redirect" => array( "adwords redirect", true ),
311
+ "custom_label_0" => array( "custom label 0", true ),
312
+ "custom_label_1" => array( "custom label 1", true ),
313
+ "custom_label_2" => array( "custom label 2", true ),
314
+ "custom_label_3" => array( "custom label 3", true ),
315
+ "custom_label_4" => array( "custom label 4", true ),
316
+ "excluded_destination" => array( "excluded destination", true ),
317
+ "expiration_date" => array( "expiration date", true ),
318
+ "unit_pricing_measure" => array( "unit pricing measure", true ),
319
+ "unit_pricing_base_measure" => array( "unit pricing base measure", true ),
320
+ "energy_efficiency_class" => array( "energy efficiency class", true ),
321
+ "loyalty_points" => array( "loyalty points", true ),
322
+ "installment" => array( "installment", true ),
323
+ "promotion_id" => array( "promotion id", true ),
324
+ "cost_of_goods_sold" => array( "cost of goods sold", true ),
325
+ "availability_date" => array( "availability date", true ),
326
+ "tax_category" => array( "tax category", true ),
327
+ "included_destination" => array( "included destination", true ),
328
+ );
329
+
330
+ if ( ! empty( $this->products ) ) {
331
+ foreach ( $this->products as $no => $product ) {
332
+ foreach ( $product as $key => $value ) {
333
+ $this->mapAttribute( $no,
334
+ $key,
335
+ str_replace( ' ', '_', $googleCSVTXTAttribute[ $key ][0] ),
336
+ $value,
337
+ $googleCSVTXTAttribute[ $key ][0] );
338
+ }
339
+ $this->process_google_shipping_attribute_for_CSVTXT( $no );
340
+ }
341
+ }
342
+ }
343
+
344
+ /**
345
+ * Map to google attribute
346
+ *
347
+ * @param string|int $no
348
+ * @param string|int $from
349
+ * @param string|int $to
350
+ * @param mixed $value
351
+ * @param bool $cdata
352
+ *
353
+ * @return array|string
354
+ */
355
+ public function mapAttribute( $no, $from, $to, $value, $cdata = false ) {
356
+ unset( $this->products[ $no ][ $from ] );
357
+ if ( 'xml' == $this->rules['feedType'] ) {
358
+ return $this->products[ $no ][ $to ] = $this->formatXMLLine( $to, $value, $cdata );
359
+ } else {
360
+ return $this->products[ $no ][ $to ] = $value;
361
+ }
362
+ }
363
+
364
+
365
+ public
366
+ function process_google_shipping_attribute_for_xml(
367
+ $no
368
+ ) {
369
+ $shipping = array( 'g:shipping_country', 'g:shipping_service', 'g:shipping_price', 'g: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
+ $str .= str_replace( 'shipping_', '', $valueAttr );
383
+ }
384
+ }
385
+
386
+ return $this->products[ $no ]['g:shipping'] = $this->formatXMLLine( "g:shipping", $str, false );
387
+ }
388
+
389
+ return false;
390
+ }
391
+
392
+ public
393
+ function process_google_shipping_attribute_for_CSVTXT(
394
+ $no
395
+ ) {
396
+ $shipping = array( 'shipping_country', 'shipping_service', 'shipping_price', 'shipping_region' );
397
+ $shippingAttr = array();
398
+ $products = $this->products[ $no ];
399
+ foreach ( $products as $keyAttr => $valueAttr ) {
400
+ if ( in_array( $keyAttr, $shipping ) ) {
401
+ array_push( $shippingAttr, array( $keyAttr => $valueAttr ) );
402
+ unset( $this->products[ $no ][ $keyAttr ] );
403
+ }
404
+ }
405
+ if ( count( $shippingAttr ) ) {
406
+ $str = '';
407
+ foreach ( $shippingAttr as $key => $attributes ) {
408
+ foreach ( $attributes as $keyAttr => $valueAttr ) {
409
+ $country = ( 'shipping_country' == $keyAttr ) ? $str .= $valueAttr . ':' : '';
410
+ $country = ( 'shipping_region' == $keyAttr ) ? $str .= $valueAttr . ':' : '';
411
+ $service = ( 'shipping_service' == $keyAttr ) ? $str .= $valueAttr . ':' : '';
412
+ $price = ( 'shipping_price' == $keyAttr ) ? $str .= $valueAttr : '';
413
+ }
414
+ }
415
+
416
+ return $this->products[ $no ]['shipping(country:region:service:price)'] = str_replace( ' : ', ':', $str );
417
+ }
418
+
419
+ return false;
420
+ }
421
+
422
+ /**
423
+ * Make xml node
424
+ *
425
+ * @param string $attribute Attribute Name
426
+ * @param string $value Attribute Value
427
+ * @param bool $cdata
428
+ * @param string $space
429
+ *
430
+ * @return string
431
+ */
432
+ function formatXMLLine( $attribute, $value, $cdata, $space = '' ) {
433
+ //Make single XML node
434
+ if ( ! empty( $value ) ) {
435
+ $value = trim( $value );
436
+ }
437
+ if ( gettype( $value ) == 'array' ) {
438
+ $value = wp_json_encode( $value );
439
+ }
440
+ if ( false === strpos( $value, "<![CDATA[" ) && 'http' === substr( trim( $value ), 0, 4 ) ) {
441
+ $value = "<![CDATA[$value]]>";
442
+ } elseif ( false === strpos( $value, "<![CDATA[" ) && true === $cdata && ! empty( $value ) ) {
443
+ $value = "<![CDATA[$value]]>";
444
+ } elseif ( $cdata ) {
445
+ if ( ! empty( $value ) ) {
446
+ $value = "<![CDATA[$value]]>";
447
+ }
448
+ }
449
+
450
+ if ( 'g:additional_image_link' == substr( $attribute, 0, 23 ) ) {
451
+ $attribute = "g:additional_image_link";
452
+ }
453
+
454
+ return "$space<$attribute>$value</$attribute>";
455
+ }
456
+
457
+
458
+ /**
459
+ * Make XML Feed Header
460
+ * @return string
461
+ */
462
+ public function get_xml_feed_header() {
463
+ $output = '<?xml version="1.0" encoding="UTF-8" ?>
464
  <rss xmlns:g="http://base.google.com/ns/1.0" version="2.0">
465
  <channel>
466
+ <title><![CDATA[' . html_entity_decode( get_option( 'blogname' ) ) . ']]></title>
467
  <link><![CDATA[' . site_url() . ']]></link>
468
+ <description><![CDATA[' . html_entity_decode( get_option( 'blogdescription' ) ) . ']]></description>';
469
+
470
+ return $output;
471
+ }
472
+
473
+ /**
474
+ * Make XML Feed
475
+ * @param array $items items.
476
+ * @return string
477
+ */
478
+ public function get_xml_feed_body( $items ) {
479
+ $feed = '';
480
+ //$feed .= $this->get_feed_header();
481
+ $feed .= "\n";
482
+ if ( $items ) {
483
+ foreach ( $items as $item => $products ) {
484
+ $feed .= " <" . $this->feedWrapper . ">";
485
+ foreach ( $products as $key => $value ) {
486
+ if ( ! empty( $value ) ) {
487
+ $feed .= $value;
488
+ }
489
+ }
490
+ $feed .= "\n </" . $this->feedWrapper . ">\n";
491
+ }
492
+
493
+ //$feed .= $this->get_feed_footer();
494
+
495
+ return $feed;
496
+ }
497
+
498
+ return false;
499
+ }
500
+
501
+ /**
502
+ * Make XML Feed Footer
503
+ * @return string
504
+ */
505
+ public function get_xml_feed_footer() {
506
+ $footer = " </channel>
507
  </rss>";
508
+
509
+ return $footer;
510
+ }
511
+
512
+ /**
513
+ * Short Products
514
+ * @return array
515
+ */
516
+ public function short_products() {
517
+ if ( $this->products ) {
518
+ update_option( 'wpf_progress', esc_html__('Shorting Products', 'woo-feed' ), false );
519
+ sleep( 1 );
520
+ $array = array();
521
+ $ij = 0;
522
+ foreach ( $this->products as $key => $item ) {
523
+ $array[ $ij ] = $item;
524
+ unset( $this->products[ $key ] );
525
+ $ij ++;
526
+ }
527
+
528
+ return $this->products = $array;
529
+ }
530
+
531
+ return $this->products;
532
+ }
533
+
534
+ /**
535
+ * Responsible to make CSV feed
536
+ * @return string
537
+ */
538
+ public function get_csv_feed() {
539
+ if ( $this->products ) {
540
+ $headers = array_keys( $this->products[0] );
541
+ $feed[] = $headers;
542
+ foreach ( $this->products as $no => $product ) {
543
+ $row = array();
544
+ foreach ( $headers as $key => $header ) {
545
+ if ( strpos( $header, "additional image link" ) !== false ) {
546
+ $header = "additional image link";
547
+ }
548
+ $row[] = isset( $product[ $header ] ) ? $product[ $header ] : '';
549
+ }
550
+ $feed[] = $row;
551
+ }
552
+
553
+ return $feed;
554
+ }
555
+
556
+ return false;
557
+ }
558
  }
includes/feeds/class-woo-feed-generate.php CHANGED
@@ -1,7 +1,8 @@
1
  <?php
2
-
3
- class Woo_Generate_Feed
4
- {
 
5
  /**
6
  * Provider Service Class
7
  * @var Woo_Feed_Google|Woo_Feed_Pinterest|Woo_Feed_Facebook|Woo_Feed_Custom_XML|Woo_Feed_Custom
@@ -14,16 +15,16 @@ class Woo_Generate_Feed
14
  * @param string $feedService
15
  * @param array $feedRule
16
  */
17
- public function __construct( $feedService, $feedRule ) {
18
- $this->service = new $feedService($feedRule);
19
- }
20
-
21
- public function getProducts() {
22
- return $this->service->returnFinalProduct();
23
- }
24
- }
25
-
26
-
27
-
28
-
29
-
1
  <?php
2
+ /**
3
+ * Class Woo_Generate_Feed
4
+ */
5
+ class Woo_Generate_Feed {
6
  /**
7
  * Provider Service Class
8
  * @var Woo_Feed_Google|Woo_Feed_Pinterest|Woo_Feed_Facebook|Woo_Feed_Custom_XML|Woo_Feed_Custom
15
  * @param string $feedService
16
  * @param array $feedRule
17
  */
18
+ public function __construct( $feedService, $feedRule ) {
19
+ $feedService = woo_feed_get_merchant_class( $feedService );
20
+ $this->service = new $feedService( $feedRule );
21
+ }
22
+
23
+ /**
24
+ * Get Product data
25
+ * @return array|bool|string
26
+ */
27
+ public function getProducts() {
28
+ return $this->service->returnFinalProduct();
29
+ }
30
+ }
includes/feeds/class-woo-feed-google.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
 
3
  /**
4
  * Class Google
@@ -9,617 +9,642 @@
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 Woo_Feed_Products_v3 $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
- $feedRule['itemWrapper'] = $this->feedWrapper;
97
- $this->products = new Woo_Feed_Products_v3($feedRule);
98
-
99
- # When update via cron job then set productIds
100
- if ( ! isset($feedRule['productIds']) ) {
101
- $feedRule['productIds'] = $this->products->query_products();
102
- }
103
- $this->products->get_products($feedRule['productIds']);
104
- $this->rules = $feedRule;
105
  // $products = new Woo_Feed_Products();
106
- // $storeProducts = $products->woo_feed_get_visible_product($feedRule);
107
- // if(!empty($storeProducts)){
108
- // $engine = new WF_Engine($storeProducts, $feedRule);
109
- // $this->products = $engine->mapProductsByRules();
110
- // $this->rules = $feedRule;
111
- // if ($feedRule['feedType'] == 'xml') {
112
- // $this->mapAttributeForXML();
113
- // } else {
114
- // $this->mapAttributeForCSVTXT();
115
- // }
116
- // }else{
117
- // $this->products=array();
118
  // }
119
-
120
- }
121
-
122
-
123
- /**
124
- * Return Feed
125
- * @return array
126
- */
127
- //echo "<pre>";print_r($feed);die();
128
- public function returnFinalProduct() {
129
- if ( ! empty($this->products) ) {
130
-
131
- if ( $this->rules['feedType'] == 'xml' ) {
132
- //return $this->get_feed($this->products);
133
- $feed = array(
134
- "body" => $this->products->feedBody,
135
- "header" => $this->get_xml_feed_header(),
136
- "footer" => $this->get_xml_feed_footer(),
137
- );
138
- return $feed;
139
- } elseif ( $this->rules['feedType'] == 'txt' ) {
140
-
141
- $feed = array(
142
- "body" => $this->products->feedBody,
143
- "header" => $this->products->feedHeader,
144
- "footer" => "",
145
- );
146
- //echo "<pre>";print_r($feed);die();
147
- return $feed;
148
- } elseif ( $this->rules['feedType'] == 'csv' ) {
149
-
150
- $feed = array(
151
- "body" => $this->products->feedBody,
152
- "header" => $this->products->feedHeader,
153
- "footer" => "",
154
- );
155
- return $feed;
156
- }
157
- }
158
-
159
- $feed = array(
160
- "body" => "",
161
- "header" => "",
162
- "footer" => "",
163
- );
164
- return $feed;
165
- }
166
-
167
- /**
168
- * Configure merchant attributes for XML feed
169
- */
170
- public function mapAttributeForXML() {
171
-
172
- $googleXMLAttribute = array(
173
- "id" => array( "g:id", false ),
174
- "title" => array( "title", true ),
175
- "description" => array( "description", true ),
176
- "link" => array( "link", true ),
177
- "mobile_link" => array( "mobile_link", true ),
178
- "product_type" => array( "g:product_type", true ),
179
- "current_category" => array( "g:google_product_category", true ),
180
- "image" => array( "g:image_link", true ),
181
- "images" => array( "g:additional_image_link", false ),
182
- "images_1" => array( "g:additional_image_link_1", true ),
183
- "images_2" => array( "g:additional_image_link_2", true ),
184
- "images_3" => array( "g:additional_image_link_3", true ),
185
- "images_4" => array( "g:additional_image_link_4", true ),
186
- "images_5" => array( "g:additional_image_link_5", true ),
187
- "images_6" => array( "g:additional_image_link_6", true ),
188
- "images_7" => array( "g:additional_image_link_7", true ),
189
- "images_8" => array( "g:additional_image_link_8", true ),
190
- "images_9" => array( "g:additional_image_link_9", true ),
191
- "images_10" => array( "g:additional_image_link_10", true ),
192
- "condition" => array( "g:condition", false ),
193
- "availability" => array( "g:availability", false ),
194
- "availability_date" => array( "g:availability_date", false ),
195
- "inventory" => array( "g:inventory", false ),
196
- "price" => array( "g:price", true ),
197
- "sale_price" => array( "g:sale_price", true ),
198
- "sale_price_effective_date" => array( "g:sale_price_effective_date", true ),
199
- "brand" => array( "g:brand", true ),
200
- "sku" => array( "g:mpn", true ),
201
- "upc" => array( "g:gtin", true ),
202
- "identifier_exists" => array( "g:identifier_exists", true ),
203
- "item_group_id" => array( "g:item_group_id", false ),
204
- "color" => array( "g:color", true ),
205
- "gender" => array( "g:gender", true ),
206
- "age_group" => array( "g:age_group", true ),
207
- "material" => array( "g:material", true ),
208
- "pattern" => array( "g:pattern", true ),
209
- "size" => array( "g:size", true ),
210
- "size_type" => array( "g:size_type", true ),
211
- "size_system" => array( "g:size_system", true ),
212
- "tax" => array( "tax", true ),
213
- "tax_country" => array( "g:tax_country", true ),
214
- "tax_region" => array( "g:tax_region", true ),
215
- "tax_rate" => array( "g:tax_rate", true ),
216
- "tax_ship" => array( "g:tax_ship", true ),
217
- "tax_category" => array( "g:tax_category", true ),
218
- "weight" => array( "g:shipping_weight", false ),
219
- "length" => array( "g:shipping_length", false ),
220
- "width" => array( "g:shipping_width", false ),
221
- "height" => array( "g:shipping_height", false ),
222
- "shipping_label" => array( "g:shipping_label", false ),
223
- "shipping_country" => array( "g:shipping_country", false ),
224
- "shipping_service" => array( "g:shipping_service", false ),
225
- "shipping_price" => array( "g:shipping_price", false ),
226
- "shipping_region" => array( "g:shipping_region", false ),
227
- "multipack" => array( "g:multipack", true ),
228
- "is_bundle" => array( "g:is_bundle", true ),
229
- "adult" => array( "g:adult", true ),
230
- "adwords_redirect" => array( "g:adwords_redirect", true ),
231
- "custom_label_0" => array( "g:custom_label_0", true ),
232
- "custom_label_1" => array( "g:custom_label_1", true ),
233
- "custom_label_2" => array( "g:custom_label_2", true ),
234
- "custom_label_3" => array( "g:custom_label_3", true ),
235
- "custom_label_4" => array( "g:custom_label_4", true ),
236
- "excluded_destination" => array( "g:excluded_destination", true ),
237
- "included_destination" => array( "g:included_destination", true ),
238
- "expiration_date" => array( "g:expiration_date", true ),
239
- "unit_pricing_measure" => array( "g:unit_pricing_measure", true ),
240
- "unit_pricing_base_measure" => array( "g:unit_pricing_base_measure", true ),
241
- "energy_efficiency_class" => array( "g:energy_efficiency_class", true ),
242
- "loyalty_points" => array( "g:loyalty_points", true ),
243
- "installment" => array( "g:installment", true ),
244
- "promotion_id" => array( "g:promotion_id", true ),
245
- "cost_of_goods_sold" => array( "g:cost_of_goods_sold", true ),
246
- );
247
-
248
- if ( ! empty($this->products) ) {
249
- foreach ( $this->products as $no => $product ) {
250
- $this->identifier_status_add($no);
251
- foreach ( $product as $key => $value ) {
252
- $this->mapAttribute($no, $key, $googleXMLAttribute[ $key ][0], $value, $googleXMLAttribute[ $key ][0]);
253
- }
254
-
255
- $this->process_google_shipping_attribute_for_xml($no);
256
- $this->process_google_tax_attribute_for_xml($no);
257
- }
258
- }
259
- }
260
-
261
- /**
262
- * Configure merchant attributes for XML feed
263
- */
264
- public function mapAttributeForCSVTXT() {
265
- //Basic product information
266
- $googleCSVTXTAttribute = array(
267
- "id" => array( "id", false ),
268
- "title" => array( "title", true ),
269
- "description" => array( "description", true ),
270
- "link" => array( "link", true ),
271
- "mobile_link" => array( "mobile_link", true ),
272
- "product_type" => array( "product type", true ),
273
- "current_category" => array( "google product category", true ),
274
- "image" => array( "image link", true ),
275
- "images" => array( "additional image link", true ),
276
- "images_1" => array( "additional image link 1", true ),
277
- "images_2" => array( "additional image link 2", true ),
278
- "images_3" => array( "additional image link 3", true ),
279
- "images_4" => array( "additional image link 4", true ),
280
- "images_5" => array( "additional image link 5", true ),
281
- "images_6" => array( "additional image link 6", true ),
282
- "images_7" => array( "additional image link 7", true ),
283
- "images_8" => array( "additional image link 8", true ),
284
- "images_9" => array( "additional image link 9", true ),
285
- "images_10" => array( "additional image link 10", true ),
286
- "condition" => array( "condition", false ),
287
- "availability" => array( "availability", false ),
288
- "availability_date" => array( "availability date", false ),
289
- "inventory" => array( "inventory", false ),
290
- "price" => array( "price", true ),
291
- "sale_price" => array( "sale price", true ),
292
- "sale_price_effective_date" => array( "sale price effective date", true ),
293
- "brand" => array( "brand", true ),
294
- "sku" => array( "mpn", true ),
295
- "upc" => array( "gtin", true ),
296
- "identifier_exists" => array( "identifier exists", true ),
297
- "item_group_id" => array( "item group id", false ),
298
- "color" => array( "color", true ),
299
- "gender" => array( "gender", true ),
300
- "age_group" => array( "age group", true ),
301
- "material" => array( "material", true ),
302
- "pattern" => array( "pattern", true ),
303
- "size" => array( "size", true ),
304
- "size_type" => array( "size type", true ),
305
- "size_system" => array( "size system", true ),
306
- "tax" => array( "tax", true ),
307
- "tax_country" => array( "tax country", true ),
308
- "tax_region" => array( "tax region", true ),
309
- "tax_rate" => array( "tax rate", true ),
310
- "tax_ship" => array( "tax ship", true ),
311
- "tax_category" => array( "tax category", true ),
312
- "weight" => array( "shipping weight", false ),
313
- "length" => array( "shipping length", false ),
314
- "width" => array( "shipping width", false ),
315
- "height" => array( "shipping height", false ),
316
- "shipping_label" => array( "shipping label", false ),
317
- "shipping_country" => array( "shipping country", false ),
318
- "shipping_service" => array( "shipping service", false ),
319
- "shipping_price" => array( "shipping price", false ),
320
- "shipping_region" => array( "shipping region", false ),
321
- "multipack" => array( "multipack", true ),
322
- "is_bundle" => array( "is bundle", true ),
323
- "adult" => array( "adult", true ),
324
- "adwords_redirect" => array( "adwords redirect", true ),
325
- "custom_label_0" => array( "custom label 0", true ),
326
- "custom_label_1" => array( "custom label 1", true ),
327
- "custom_label_2" => array( "custom label 2", true ),
328
- "custom_label_3" => array( "custom label 3", true ),
329
- "custom_label_4" => array( "custom label 4", true ),
330
- "excluded_destination" => array( "excluded destination", true ),
331
- "included_destination" => array( "included destination", true ),
332
- "expiration_date" => array( "expiration date", true ),
333
- "unit_pricing_measure" => array( "unit pricing measure", true ),
334
- "unit_pricing_base_measure" => array( "unit pricing base measure", true ),
335
- "energy_efficiency_class" => array( "energy efficiency class", true ),
336
- "loyalty_points" => array( "loyalty points", true ),
337
- "installment" => array( "installment", true ),
338
- "promotion_id" => array( "promotion id", true ),
339
- "cost_of_goods_sold" => array( "cost of goods sold", true ),
340
- );
341
-
342
- if ( ! empty($this->products) ) {
343
- foreach ( $this->products as $no => $product ) {
344
- foreach ( $product as $key => $value ) {
345
- $this->mapAttribute($no, $key, $googleCSVTXTAttribute[ $key ][0], $value, $googleCSVTXTAttribute[ $key ][0]);
346
- }
347
- $this->process_google_shipping_attribute_for_CSVTXT($no);
348
- }
349
- }
350
- }
351
-
352
- /**
353
- * Map to google attribute
354
- * @param $no
355
- * @param $from
356
- * @param $to
357
- * @param $value
358
- * @param bool $cdata
359
- * @return array
360
- */
361
- public function mapAttribute( $no, $from, $to, $value, $cdata = false ) {
362
- unset($this->products[ $no ][ $from ]);
363
- if ( $to == 'g:color' ) {
364
- $value = str_replace(",","/",$value);
365
- }
366
- if ( $this->rules['feedType'] == 'xml' ) {
367
- return $this->products[ $no ][ $to ] = $this->formatXMLLine($to, $value, $cdata);
368
- } else {
369
- return $this->products[ $no ][ $to ] = $value;
370
- }
371
- }
372
-
373
- public function identifier_status_add( $no ) {
374
- $identifier = array( 'brand', 'upc', 'sku', 'mpn', 'gtin' );
375
- $product = $this->products[ $no ];
376
-
377
- if ( ! array_key_exists('g:identifier_exists',$product) ) {
378
- if ( count(array_intersect_key(array_flip($identifier), $product)) >= 2 ) {
379
- # Any 2 required keys exist!
380
- $countIdentifier = 0;
381
- if ( array_key_exists('brand',$product) && ! empty($product['brand']) ) {
382
- $countIdentifier++;
383
- }
384
- if ( array_key_exists('upc',$product) && ! empty($product['upc']) ) {
385
- $countIdentifier++;
386
- }
387
- if ( array_key_exists('sku',$product) && ! empty($product['sku']) ) {
388
- $countIdentifier++;
389
- }
390
- if ( array_key_exists('mpn',$product) && ! empty($product['mpn']) ) {
391
- $countIdentifier++;
392
- }
393
- if ( array_key_exists('gtin',$product) && ! empty($product['gtin']) ) {
394
- $countIdentifier++;
395
- }
396
- if ( $countIdentifier >= 2 ) {
397
- $this->products[ $no ]["g:identifier_exists"] = $this->formatXMLLine("g:identifier_exists", "yes", $cdata = true);
398
- }else {
399
- $this->products[ $no ]["g:identifier_exists"] = $this->formatXMLLine("g:identifier_exists", "no", $cdata = true);
400
- }
401
- } else {
402
- $this->products[ $no ]["g:identifier_exists"] = $this->formatXMLLine("g:identifier_exists", "no", $cdata = true);
403
- }
404
- }
405
- }
406
-
407
-
408
- /**
409
- * @param $no
410
- * @return bool|string
411
- */
412
- public
413
- function process_google_shipping_attribute_for_xml( $no ) {
414
- $shipping = array( 'g:shipping_country', 'g:shipping_service', 'g:shipping_price', 'g:shipping_region' );
415
- $shippingAttr = array();
416
- $products = $this->products[ $no ];
417
- foreach ( $products as $keyAttr => $valueAttr ) {
418
- if ( in_array($keyAttr, $shipping) ) {
419
- array_push($shippingAttr, array( $keyAttr => $valueAttr ));
420
- unset($this->products[ $no ][ $keyAttr ]);
421
- }
422
- }
423
- if ( count($shippingAttr) ) {
424
- $str = "";
425
- foreach ( $shippingAttr as $key => $attributes ) {
426
- foreach ( $attributes as $keyAttr => $valueAttr ) {
427
- $str .= str_replace("shipping_", "", $valueAttr);
428
- }
429
- }
430
- return $this->products[ $no ]['g:shipping'] = $this->formatXMLLine("g:shipping", $str, false);
431
- }
432
- return false;
433
- }
434
-
435
- public
436
- function process_google_tax_attribute_for_xml( $no ) {
437
- $tax = array( 'g:tax_country', 'g:tax_region', 'g:tax_rate', 'g:tax_ship' );
438
- $taxAttr = array();
439
- $products = $this->products[ $no ];
440
- foreach ( $products as $keyAttr => $valueAttr ) {
441
- if ( in_array($keyAttr, $tax) ) {
442
- array_push($taxAttr, array( $keyAttr => $valueAttr ));
443
- unset($this->products[ $no ][ $keyAttr ]);
444
- }
445
- }
446
- if ( count($taxAttr) ) {
447
- $str = "";
448
- foreach ( $taxAttr as $key => $attributes ) {
449
- foreach ( $attributes as $keyAttr => $valueAttr ) {
450
- // if($keyAttr != "g:tax_ship")
451
- // {
452
- $str .= str_replace("tax_", "", $valueAttr);
453
- $str = str_replace("ship", "tax_ship", $str);
454
- // }
455
- // else
456
- // {
457
- // $str .= $valueAttr;
458
- // }
459
- }
460
- }
461
- return $this->products[ $no ]['g:tax'] = $this->formatXMLLine("g:tax", $str, false);
462
- }
463
- return false;
464
- }
465
-
466
- /**
467
- * @param $no
468
- * @return bool|mixed
469
- */
470
- public
471
- function process_google_shipping_attribute_for_CSVTXT( $no ) {
472
- $shipping = array( 'shipping country', 'shipping service', 'shipping price', 'shipping region' );
473
- $shippingAttr = array();
474
- $products = $this->products[ $no ];
475
- foreach ( $products as $keyAttr => $valueAttr ) {
476
- if ( in_array($keyAttr, $shipping) ) {
477
- array_push($shippingAttr, array( $keyAttr => $valueAttr ));
478
- unset($this->products[ $no ][ $keyAttr ]);
479
- }
480
- }
481
- if ( count($shippingAttr) ) {
482
- $str = "";
483
- foreach ( $shippingAttr as $key => $attributes ) {
484
- foreach ( $attributes as $keyAttr => $valueAttr ) {
485
- $country = ($keyAttr == "shipping country") ? $str .= $valueAttr . ":" : "";
486
- $service = ($keyAttr == "shipping service") ? $str .= $valueAttr . ":" : "";
487
- $price = ($keyAttr == "shipping price") ? $str .= $valueAttr : "";
488
- $region = ($keyAttr == "shipping region") ? $str .= $valueAttr . ":" : "";
489
- }
490
- }
491
- return $this->products[ $no ]['shipping(country:region:service:price)'] = str_replace(" : ",":", $str);
492
- }
493
- return false;
494
- }
495
-
496
- public
497
- function process_google_tax_attribute_for_CSVTXT( $no ) {
498
- $tax = array( 'tax country', 'tax region', 'tax rate', 'tax ship' );
499
- $taxAttr = array();
500
- $products = $this->products[ $no ];
501
- foreach ( $products as $keyAttr => $valueAttr ) {
502
- if ( in_array($keyAttr, $tax) ) {
503
- array_push($taxAttr, array( $keyAttr => $valueAttr ));
504
- unset($this->products[ $no ][ $keyAttr ]);
505
- }
506
- }
507
- if ( count($taxAttr) ) {
508
- $str = "";
509
- foreach ( $taxAttr as $key => $attributes ) {
510
- foreach ( $attributes as $keyAttr => $valueAttr ) {
511
- $country = ($keyAttr == "tax country") ? $str .= $valueAttr . ":" : "";
512
- $region = ($keyAttr == "tax region") ? $str .= $valueAttr . ":" : "";
513
- $rate = ($keyAttr == "tax rate") ? $str .= $valueAttr . ":" : "";
514
- $ship = ($keyAttr == "tax ship") ? $str .= $valueAttr . ":" : "";
515
- }
516
- }
517
- return $this->products[ $no ]['tax(country:region:rate:tax_ship)'] = str_replace(" : ",":", $str);
518
- }
519
- return false;
520
- }
521
-
522
- function formatXMLLine( $attribute, $value, $cdata, $space = "" ) {
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
- } elseif ( $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
- $output = '<?xml version="1.0" encoding="UTF-8" ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
550
  <rss version="2.0" xmlns:g="http://base.google.com/ns/1.0" xmlns:c="http://base.google.com/cns/1.0">
551
  <channel>
552
- <title><![CDATA[' . html_entity_decode(get_option('blogname')) . ']]></title>
553
- <link><![CDATA['.home_url().']]></link>
554
- <description><![CDATA['.html_entity_decode(get_option('blogdescription')).']]></description>';
555
- return $output;
556
- }
557
-
558
- public function get_xml_feed( $items ) {
559
- $feed = "";
560
- //$feed .= $this->get_feed_header();
561
- $feed .= "\n";
562
- if ( $items ) {
563
- foreach ( $items as $item => $products ) {
564
- $feed .= " <" . $this->feedWrapper . ">";
565
-
566
- foreach ( $products as $key => $value ) {
567
- if ( ! empty($value) ) {
568
- $feed .= $value;
569
- }
570
- }
571
- $feed .= "\n </" . $this->feedWrapper . ">\n";
572
- }
573
- //$feed .= $this->get_feed_footer();
574
-
575
- return $feed;
576
- }
577
- return false;
578
- }
579
-
580
- public function get_xml_feed_footer() {
581
- $footer = " </channel>
 
 
 
 
 
 
582
  </rss>";
583
- return $footer;
584
- }
585
-
586
- public function short_products() {
587
- if ( $this->products ) {
588
- update_option('wpf_progress', "Shorting Products");
589
- sleep(1);
590
- $array = array();
591
- $ij = 0;
592
- foreach ( $this->products as $key => $item ) {
593
- $array[ $ij ] = $item;
594
- unset($this->products[ $key ]);
595
- $ij++;
596
- }
597
- return $this->products = $array;
598
- }
599
- return $this->products;
600
- }
601
-
602
- /**
603
- * Responsible to make CSV feed
604
- * @return string
605
- */
606
- public function get_csv_feed() {
607
- if ( $this->products ) {
608
- $headers = array_keys($this->products[0]);
609
- $feed[] = $headers;
610
- foreach ( $this->products as $no => $product ) {
611
- $row = array();
612
- foreach ( $headers as $key => $header ) {
613
- if ( strpos($header, "additional image link") !== false ) {
614
- $header = "additional image link";
615
- }
616
- $row[] = isset($product[ $header ]) ? $product[ $header ] : "";
617
- }
618
- $feed[] = $row;
619
- }
620
- return $feed;
621
- }
622
- return false;
623
- }
624
-
 
 
 
 
 
 
625
  }
1
+ <?php /** @noinspection PhpUnusedPrivateMethodInspection, PhpUndefinedMethodInspection, PhpUnused, PhpUnusedPrivateFieldInspection, PhpUnusedLocalVariableInspection, DuplicatedCode, PhpUnusedParameterInspection, PhpForeachNestedOuterKeyValueVariablesConflictInspection, RegExpRedundantEscape */
2
 
3
  /**
4
  * Class Google
9
  * @package Google
10
  *
11
  */
12
+ class Woo_Feed_Google {
13
+
14
+ /**
15
+ * This variable is responsible for holding all product attributes and their values
16
+ *
17
+ * @since 1.0.0
18
+ * @var Woo_Feed_Products_v3 $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 array $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 array $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 array $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 int $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 string $feedWrapper Feed Wrapper text
64
+ * @access public
65
+ */
66
+ public $feedWrapper = 'item';
67
+
68
+ /**
69
+ * Store product information
70
+ *
71
+ * @since 1.0.0
72
+ * @var array $storeProducts
73
+ * @access public
74
+ */
75
+ private $storeProducts;
76
+
77
+ /**
78
+ * Define the core functionality to generate feed.
79
+ *
80
+ * Set the feed rules. Map products according to the rules and Check required attributes
81
+ * and their values according to merchant specification.
82
+ * @var Woo_Generate_Feed $feedRule Contain Feed Configuration
83
+ * @since 1.0.0
84
+ */
85
+ public function __construct( $feedRule ) {
86
+ $feedRule['itemWrapper'] = $this->feedWrapper;
87
+ $this->products = new Woo_Feed_Products_v3( $feedRule );
88
+
89
+ # When update via cron job then set productIds
90
+ if ( ! isset( $feedRule['productIds'] ) ) {
91
+ //@TODO use limit for free version here for cron calls... {google,facebook,pinterest,custom}
92
+ $feedRule['productIds'] = $this->products->query_products();
93
+ }
94
+ $this->products->get_products( $feedRule['productIds'] );
95
+ $this->rules = $feedRule;
 
 
 
 
 
 
 
 
 
96
  // $products = new Woo_Feed_Products();
97
+ // $limit = isset($feedRule['Limit']) ? esc_html($feedRule['Limit']) : '';
98
+ // $offset = isset($feedRule['Offset']) ? esc_html($feedRule['Offset']) : '';
99
+ // $categories = isset($feedRule['categories']) ? $feedRule['categories']: '';
100
+ // $storeProducts = $products->woo_feed_get_visible_product($limit, $offset,$categories,$feedRule);
101
+ // $feedRule=$products->feedRule;
102
+ // $engine = new WF_Engine($storeProducts, $feedRule);
103
+ // $this->products = $engine->mapProductsByRules();
104
+ // $this->rules = $feedRule;
105
+ // if ($feedRule['feedType'] == 'xml') {
106
+ // $this->mapAttributeForXML();
107
+ // } else {
108
+ // $this->mapAttributeForCSVTXT();
109
  // }
110
+ }
111
+
112
+
113
+ /**
114
+ * Return Feed
115
+ * @return array
116
+ */
117
+ public function returnFinalProduct() {
118
+ if ( ! empty( $this->products ) ) {
119
+ if ( 'xml' == $this->rules['feedType'] ) {
120
+ $feed = array(
121
+ "body" => $this->products->feedBody,
122
+ "header" => $this->get_xml_feed_header(),
123
+ "footer" => $this->get_xml_feed_footer(),
124
+ );
125
+
126
+ return $feed;
127
+ } elseif ( 'txt' == $this->rules['feedType'] ) {
128
+ $feed = array(
129
+ "body" => $this->products->feedBody,
130
+ "header" => $this->products->feedHeader,
131
+ "footer" => '',
132
+ );
133
+ return $feed;
134
+ } elseif ( 'csv' == $this->rules['feedType'] ) {
135
+ $feed = array(
136
+ "body" => $this->products->feedBody,
137
+ "header" => $this->products->feedHeader,
138
+ "footer" => '',
139
+ );
140
+ return $feed;
141
+ }
142
+ }
143
+
144
+ $feed = array(
145
+ "body" => '',
146
+ "header" => '',
147
+ "footer" => '',
148
+ );
149
+
150
+ return $feed;
151
+ }
152
+
153
+ /**
154
+ * Configure merchant attributes for XML feed
155
+ */
156
+ public function mapAttributeForXML() {
157
+
158
+ $googleXMLAttribute = array(
159
+ "id" => array( "g:id", false ),
160
+ "title" => array( "title", true ),
161
+ "description" => array( "description", true ),
162
+ "link" => array( "link", true ),
163
+ "mobile_link" => array( "mobile_link", true ),
164
+ "product_type" => array( "g:product_type", true ),
165
+ "current_category" => array( "g:google_product_category", true ),
166
+ "image" => array( "g:image_link", true ),
167
+ "images" => array( "g:additional_image_link", false ),
168
+ "images_1" => array( "g:additional_image_link_1", true ),
169
+ "images_2" => array( "g:additional_image_link_2", true ),
170
+ "images_3" => array( "g:additional_image_link_3", true ),
171
+ "images_4" => array( "g:additional_image_link_4", true ),
172
+ "images_5" => array( "g:additional_image_link_5", true ),
173
+ "images_6" => array( "g:additional_image_link_6", true ),
174
+ "images_7" => array( "g:additional_image_link_7", true ),
175
+ "images_8" => array( "g:additional_image_link_8", true ),
176
+ "images_9" => array( "g:additional_image_link_9", true ),
177
+ "images_10" => array( "g:additional_image_link_10", true ),
178
+ "condition" => array( "g:condition", false ),
179
+ "availability" => array( "g:availability", false ),
180
+ "availability_date" => array( "g:availability_date", false ),
181
+ "inventory" => array( "g:inventory", false ),
182
+ "price" => array( "g:price", true ),
183
+ "sale_price" => array( "g:sale_price", true ),
184
+ "sale_price_effective_date" => array( "g:sale_price_effective_date", true ),
185
+ "brand" => array( "g:brand", true ),
186
+ "sku" => array( "g:mpn", true ),
187
+ "upc" => array( "g:gtin", true ),
188
+ "identifier_exists" => array( "g:identifier_exists", true ),
189
+ "item_group_id" => array( "g:item_group_id", false ),
190
+ "color" => array( "g:color", true ),
191
+ "gender" => array( "g:gender", true ),
192
+ "age_group" => array( "g:age_group", true ),
193
+ "material" => array( "g:material", true ),
194
+ "pattern" => array( "g:pattern", true ),
195
+ "size" => array( "g:size", true ),
196
+ "size_type" => array( "g:size_type", true ),
197
+ "size_system" => array( "g:size_system", true ),
198
+ "tax" => array( "tax", true ),
199
+ "tax_country" => array( "g:tax_country", true ),
200
+ "tax_region" => array( "g:tax_region", true ),
201
+ "tax_rate" => array( "g:tax_rate", true ),
202
+ "tax_ship" => array( "g:tax_ship", true ),
203
+ "tax_category" => array( "g:tax_category", true ),
204
+ "weight" => array( "g:shipping_weight", false ),
205
+ "length" => array( "g:shipping_length", false ),
206
+ "width" => array( "g:shipping_width", false ),
207
+ "height" => array( "g:shipping_height", false ),
208
+ "shipping_label" => array( "g:shipping_label", false ),
209
+ "shipping_country" => array( "g:shipping_country", false ),
210
+ "shipping_service" => array( "g:shipping_service", false ),
211
+ "shipping_price" => array( "g:shipping_price", false ),
212
+ "shipping_region" => array( "g:shipping_region", false ),
213
+ "multipack" => array( "g:multipack", true ),
214
+ "is_bundle" => array( "g:is_bundle", true ),
215
+ "adult" => array( "g:adult", true ),
216
+ "adwords_redirect" => array( "g:adwords_redirect", true ),
217
+ "custom_label_0" => array( "g:custom_label_0", true ),
218
+ "custom_label_1" => array( "g:custom_label_1", true ),
219
+ "custom_label_2" => array( "g:custom_label_2", true ),
220
+ "custom_label_3" => array( "g:custom_label_3", true ),
221
+ "custom_label_4" => array( "g:custom_label_4", true ),
222
+ "excluded_destination" => array( "g:excluded_destination", true ),
223
+ "included_destination" => array( "g:included_destination", true ),
224
+ "expiration_date" => array( "g:expiration_date", true ),
225
+ "unit_pricing_measure" => array( "g:unit_pricing_measure", true ),
226
+ "unit_pricing_base_measure" => array( "g:unit_pricing_base_measure", true ),
227
+ "energy_efficiency_class" => array( "g:energy_efficiency_class", true ),
228
+ "loyalty_points" => array( "g:loyalty_points", true ),
229
+ "installment" => array( "g:installment", true ),
230
+ "promotion_id" => array( "g:promotion_id", true ),
231
+ "cost_of_goods_sold" => array( "g:cost_of_goods_sold", true ),
232
+ );
233
+
234
+ if ( ! empty( $this->products ) ) {
235
+ foreach ( $this->products as $no => $product ) {
236
+ //echo "<pre>";
237
+ //print_r($product);die();
238
+ $this->identifier_status_add( $no );
239
+ foreach ( $product as $key => $value ) {
240
+ $this->mapAttribute( $no,
241
+ $key,
242
+ $googleXMLAttribute[ $key ][0],
243
+ $value,
244
+ $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
+ //Basic product information
258
+ $googleCSVTXTAttribute = array(
259
+ "id" => array( "id", false ),
260
+ "title" => array( "title", true ),
261
+ "description" => array( "description", true ),
262
+ "link" => array( "link", true ),
263
+ "mobile_link" => array( "mobile_link", true ),
264
+ "product_type" => array( "product type", true ),
265
+ "current_category" => array( "google product category", true ),
266
+ "image" => array( "image link", true ),
267
+ "images" => array( "additional image link", true ),
268
+ "images_1" => array( "additional image link 1", true ),
269
+ "images_2" => array( "additional image link 2", true ),
270
+ "images_3" => array( "additional image link 3", true ),
271
+ "images_4" => array( "additional image link 4", true ),
272
+ "images_5" => array( "additional image link 5", true ),
273
+ "images_6" => array( "additional image link 6", true ),
274
+ "images_7" => array( "additional image link 7", true ),
275
+ "images_8" => array( "additional image link 8", true ),
276
+ "images_9" => array( "additional image link 9", true ),
277
+ "images_10" => array( "additional image link 10", true ),
278
+ "condition" => array( "condition", false ),
279
+ "availability" => array( "availability", false ),
280
+ "availability_date" => array( "availability date", false ),
281
+ "inventory" => array( "inventory", false ),
282
+ "price" => array( "price", true ),
283
+ "sale_price" => array( "sale price", true ),
284
+ "sale_price_effective_date" => array( "sale price effective date", true ),
285
+ "brand" => array( "brand", true ),
286
+ "sku" => array( "mpn", true ),
287
+ "upc" => array( "gtin", true ),
288
+ "identifier_exists" => array( "identifier exists", true ),
289
+ "item_group_id" => array( "item group id", false ),
290
+ "color" => array( "color", true ),
291
+ "gender" => array( "gender", true ),
292
+ "age_group" => array( "age group", true ),
293
+ "material" => array( "material", true ),
294
+ "pattern" => array( "pattern", true ),
295
+ "size" => array( "size", true ),
296
+ "size_type" => array( "size type", true ),
297
+ "size_system" => array( "size system", true ),
298
+ "tax" => array( "tax", true ),
299
+ "tax_country" => array( "tax country", true ),
300
+ "tax_region" => array( "tax region", true ),
301
+ "tax_rate" => array( "tax rate", true ),
302
+ "tax_ship" => array( "tax ship", true ),
303
+ "tax_category" => array( "tax category", true ),
304
+ "weight" => array( "shipping weight", false ),
305
+ "length" => array( "shipping length", false ),
306
+ "width" => array( "shipping width", false ),
307
+ "height" => array( "shipping height", false ),
308
+ "shipping_label" => array( "shipping label", false ),
309
+ "shipping_country" => array( "shipping country", false ),
310
+ "shipping_service" => array( "shipping service", false ),
311
+ "shipping_price" => array( "shipping price", false ),
312
+ "shipping_region" => array( "shipping region", false ),
313
+ "multipack" => array( "multipack", true ),
314
+ "is_bundle" => array( "is bundle", true ),
315
+ "adult" => array( "adult", true ),
316
+ "adwords_redirect" => array( "adwords redirect", true ),
317
+ "custom_label_0" => array( "custom label 0", true ),
318
+ "custom_label_1" => array( "custom label 1", true ),
319
+ "custom_label_2" => array( "custom label 2", true ),
320
+ "custom_label_3" => array( "custom label 3", true ),
321
+ "custom_label_4" => array( "custom label 4", true ),
322
+ "excluded_destination" => array( "excluded destination", true ),
323
+ "included_destination" => array( "included destination", true ),
324
+ "expiration_date" => array( "expiration date", true ),
325
+ "unit_pricing_measure" => array( "unit pricing measure", true ),
326
+ "unit_pricing_base_measure" => array( "unit pricing base measure", true ),
327
+ "energy_efficiency_class" => array( "energy efficiency class", true ),
328
+ "loyalty_points" => array( "loyalty points", true ),
329
+ "installment" => array( "installment", true ),
330
+ "promotion_id" => array( "promotion id", true ),
331
+ "cost_of_goods_sold" => array( "cost of goods sold", true ),
332
+ );
333
+
334
+ if ( ! empty( $this->products ) ) {
335
+ foreach ( $this->products as $no => $product ) {
336
+ foreach ( $product as $key => $value ) {
337
+ $this->mapAttribute( $no,
338
+ $key,
339
+ $googleCSVTXTAttribute[ $key ][0],
340
+ $value,
341
+ $googleCSVTXTAttribute[ $key ][0] );
342
+ }
343
+ $this->process_google_shipping_attribute_for_CSVTXT( $no );
344
+ $this->process_google_tax_attribute_for_CSVTXT( $no );
345
+ }
346
+ }
347
+ }
348
+
349
+ /**
350
+ * Map to google attribute
351
+ *
352
+ * @param $no
353
+ * @param $from
354
+ * @param $to
355
+ * @param $value
356
+ * @param bool $cdata
357
+ *
358
+ * @return array|string
359
+ */
360
+ public function mapAttribute( $no, $from, $to, $value, $cdata = false ) {
361
+ unset( $this->products[ $no ][ $from ] );
362
+ if ( 'g:color' == $to ) {
363
+ $value = str_replace( ',', '/', $value );
364
+ }
365
+ if ( 'xml' == $this->rules['feedType'] ) {
366
+ return $this->products[ $no ][ $to ] = $this->formatXMLLine( $to, $value, $cdata );
367
+ } else {
368
+ return $this->products[ $no ][ $to ] = $value;
369
+ }
370
+ }
371
+
372
+ public function identifier_status_add( $no ) {
373
+ $identifier = array( 'brand', 'upc', 'sku', 'mpn', 'gtin' );
374
+ $product = $this->products[ $no ];
375
+
376
+ if ( ! array_key_exists( 'g:identifier_exists', $product ) ) {
377
+ if ( count( array_intersect_key( array_flip( $identifier ), $product ) ) >= 2 ) {
378
+ # Any 2 required keys exist!
379
+ $countIdentifier = 0;
380
+ if ( array_key_exists( 'brand', $product ) && ! empty( $product['brand'] ) ) {
381
+ $countIdentifier ++;
382
+ }
383
+ if ( array_key_exists( 'upc', $product ) && ! empty( $product['upc'] ) ) {
384
+ $countIdentifier ++;
385
+ }
386
+ if ( array_key_exists( 'sku', $product ) && ! empty( $product['sku'] ) ) {
387
+ $countIdentifier ++;
388
+ }
389
+ if ( array_key_exists( 'mpn', $product ) && ! empty( $product['mpn'] ) ) {
390
+ $countIdentifier ++;
391
+ }
392
+ if ( array_key_exists( 'gtin', $product ) && ! empty( $product['gtin'] ) ) {
393
+ $countIdentifier ++;
394
+ }
395
+ if ( $countIdentifier >= 2 ) {
396
+ $this->products[ $no ]["g:identifier_exists"] = $this->formatXMLLine( "g:identifier_exists",
397
+ "yes",
398
+ $cdata = true );
399
+ } else {
400
+ $this->products[ $no ]["g:identifier_exists"] = $this->formatXMLLine( "g:identifier_exists",
401
+ 'no',
402
+ $cdata = true );
403
+ }
404
+ } else {
405
+ $this->products[ $no ]["g:identifier_exists"] = $this->formatXMLLine( "g:identifier_exists",
406
+ 'no',
407
+ $cdata = true );
408
+ }
409
+ }
410
+ }
411
+
412
+
413
+ public
414
+ function process_google_shipping_attribute_for_xml(
415
+ $no
416
+ ) {
417
+ $shipping = array( 'g:shipping_country', 'g:shipping_service', 'g:shipping_price', 'g:shipping_region' );
418
+ $shippingAttr = array();
419
+ $products = $this->products[ $no ];
420
+ foreach ( $products as $keyAttr => $valueAttr ) {
421
+ if ( in_array( $keyAttr, $shipping ) ) {
422
+ array_push( $shippingAttr, array( $keyAttr => $valueAttr ) );
423
+ unset( $this->products[ $no ][ $keyAttr ] );
424
+ }
425
+ }
426
+ if ( count( $shippingAttr ) ) {
427
+ $str = '';
428
+ foreach ( $shippingAttr as $key => $attributes ) {
429
+ foreach ( $attributes as $keyAttr => $valueAttr ) {
430
+ $str .= str_replace( 'shipping_', '', $valueAttr );
431
+ }
432
+ }
433
+
434
+ return $this->products[ $no ]['g:shipping'] = $this->formatXMLLine( "g:shipping", $str, false );
435
+ }
436
+
437
+ return false;
438
+ }
439
+
440
+ public
441
+ function process_google_tax_attribute_for_xml(
442
+ $no
443
+ ) {
444
+ $tax = array( 'g:tax_country', 'g:tax_region', 'g:tax_rate', 'g:tax_ship' );
445
+ $taxAttr = array();
446
+ $products = $this->products[ $no ];
447
+ foreach ( $products as $keyAttr => $valueAttr ) {
448
+ if ( in_array( $keyAttr, $tax ) ) {
449
+ array_push( $taxAttr, array( $keyAttr => $valueAttr ) );
450
+ unset( $this->products[ $no ][ $keyAttr ] );
451
+ }
452
+ }
453
+ if ( count( $taxAttr ) ) {
454
+ $str = '';
455
+ foreach ( $taxAttr as $key => $attributes ) {
456
+ foreach ( $attributes as $keyAttr => $valueAttr ) {
457
+ // if($keyAttr != "g:tax_ship")
458
+ // {
459
+ $str .= str_replace( 'tax_', '', $valueAttr );
460
+ $str = str_replace( 'ship', 'tax_ship', $str );
461
+ // }
462
+ // else
463
+ // {
464
+ // $str .= $valueAttr;
465
+ // }
466
+ }
467
+ }
468
+
469
+ return $this->products[ $no ]['g:tax'] = $this->formatXMLLine( "g:tax", $str, false );
470
+ }
471
+
472
+ return false;
473
+ }
474
+
475
+ public
476
+ function process_google_shipping_attribute_for_CSVTXT(
477
+ $no
478
+ ) {
479
+ $shipping = array( 'shipping country', 'shipping service', 'shipping price', 'shipping region' );
480
+ $shippingAttr = array();
481
+ $products = $this->products[ $no ];
482
+ foreach ( $products as $keyAttr => $valueAttr ) {
483
+ if ( in_array( $keyAttr, $shipping ) ) {
484
+ array_push( $shippingAttr, array( $keyAttr => $valueAttr ) );
485
+ unset( $this->products[ $no ][ $keyAttr ] );
486
+ }
487
+ }
488
+ if ( count( $shippingAttr ) ) {
489
+ $str = '';
490
+ foreach ( $shippingAttr as $key => $attributes ) {
491
+ foreach ( $attributes as $keyAttr => $valueAttr ) {
492
+ $country = ( 'shipping country' == $keyAttr ) ? $str .= $valueAttr . ':' : '';
493
+ $service = ( 'shipping service' == $keyAttr ) ? $str .= $valueAttr . ':' : '';
494
+ $price = ( 'shipping price' == $keyAttr ) ? $str .= $valueAttr : '';
495
+ $region = ( 'shipping region' == $keyAttr ) ? $str .= $valueAttr . ':' : '';
496
+ }
497
+ }
498
+
499
+ return $this->products[ $no ]['shipping(country:region:service:price)'] = str_replace( ' : ', ':', $str );
500
+ }
501
+
502
+ return false;
503
+ }
504
+
505
+ public
506
+ function process_google_tax_attribute_for_CSVTXT(
507
+ $no
508
+ ) {
509
+ $tax = array( 'tax country', 'tax region', 'tax rate', 'tax ship' );
510
+ $taxAttr = array();
511
+ $products = $this->products[ $no ];
512
+ foreach ( $products as $keyAttr => $valueAttr ) {
513
+ if ( in_array( $keyAttr, $tax ) ) {
514
+ array_push( $taxAttr, array( $keyAttr => $valueAttr ) );
515
+ unset( $this->products[ $no ][ $keyAttr ] );
516
+ }
517
+ }
518
+ if ( count( $taxAttr ) ) {
519
+ $str = '';
520
+ foreach ( $taxAttr as $key => $attributes ) {
521
+ foreach ( $attributes as $keyAttr => $valueAttr ) {
522
+ $country = ( 'tax country' == $keyAttr ) ? $str .= $valueAttr . ':' : '';
523
+ $region = ( 'tax region' == $keyAttr ) ? $str .= $valueAttr . ':' : '';
524
+ $rate = ( 'tax rate' == $keyAttr ) ? $str .= $valueAttr . ':' : '';
525
+ $ship = ( 'tax ship' == $keyAttr ) ? $str .= $valueAttr : '';
526
+ }
527
+ }
528
+
529
+ return $this->products[ $no ]['tax(country:region:rate:tax_ship)'] = str_replace( ' : ', ':', $str );
530
+ }
531
+
532
+ return false;
533
+ }
534
+
535
+ function formatXMLLine( $attribute, $value, $cdata, $space = '' ) {
536
+ //Make single XML node
537
+ if ( ! empty( $value ) ) {
538
+ $value = trim( $value );
539
+ }
540
+ if ( 'array' === gettype( $value ) ) {
541
+ $value = wp_json_encode( $value );
542
+ }
543
+ if ( false === strpos( $value, "<![CDATA[" ) && 'http' == substr( trim( $value ), 0, 4 ) ) {
544
+ $value = "<![CDATA[$value]]>";
545
+ } elseif ( false === strpos( $value, "<![CDATA[" ) && true === $cdata && ! empty( $value ) ) {
546
+ $value = "<![CDATA[$value]]>";
547
+ } elseif ( $cdata ) {
548
+ if ( ! empty( $value ) ) {
549
+ $value = "<![CDATA[$value]]>";
550
+ }
551
+ }
552
+ if ( substr( $attribute, 0, 23 ) == 'g:additional_image_link' ) {
553
+ $attribute = "g:additional_image_link";
554
+ }
555
+
556
+ return "$space<$attribute>$value</$attribute>";
557
+ }
558
+
559
+
560
+ public
561
+ function get_xml_feed_header() {
562
+ $output = '<?xml version="1.0" encoding="UTF-8" ?>
563
  <rss version="2.0" xmlns:g="http://base.google.com/ns/1.0" xmlns:c="http://base.google.com/cns/1.0">
564
  <channel>
565
+ <title><![CDATA[' . html_entity_decode( get_option( 'blogname' ) ) . ']]></title>
566
+ <link><![CDATA[' . site_url() . ']]></link>
567
+ <description><![CDATA[' . html_entity_decode( get_option( 'blogdescription' ) ) . ']]></description>';
568
+
569
+ return $output;
570
+ }
571
+
572
+ public
573
+ function get_xml_feed(
574
+ $items
575
+ ) {
576
+ $feed = '';
577
+ //$feed .= $this->get_feed_header();
578
+ $feed .= "\n";
579
+ if ( $items ) {
580
+ foreach ( $items as $item => $products ) {
581
+ $feed .= " <" . $this->feedWrapper . ">";
582
+ foreach ( $products as $key => $value ) {
583
+ if ( ! empty( $value ) ) {
584
+ $feed .= $value;
585
+ }
586
+ }
587
+ $feed .= "\n </" . $this->feedWrapper . ">\n";
588
+ }
589
+
590
+ //$feed .= $this->get_feed_footer();
591
+
592
+ return $feed;
593
+ }
594
+
595
+ return false;
596
+ }
597
+
598
+ public
599
+ function get_xml_feed_footer() {
600
+ $footer = " </channel>
601
  </rss>";
602
+
603
+ return $footer;
604
+ }
605
+
606
+ public
607
+ function short_products() {
608
+ if ( $this->products ) {
609
+ update_option( 'wpf_progress', esc_html__( 'Shorting Products', 'woo-feed' ), false );
610
+ sleep( 1 );
611
+ $array = array();
612
+ $ij = 0;
613
+ foreach ( $this->products as $key => $item ) {
614
+ $array[ $ij ] = $item;
615
+ unset( $this->products[ $key ] );
616
+ $ij ++;
617
+ }
618
+
619
+ return $this->products = $array;
620
+ }
621
+
622
+ return $this->products;
623
+ }
624
+
625
+ /**
626
+ * Responsible to make CSV feed
627
+ * @return string
628
+ */
629
+ public
630
+ function get_csv_feed() {
631
+ if ( $this->products ) {
632
+ $headers = array_keys( $this->products[0] );
633
+ $feed[] = $headers;
634
+ foreach ( $this->products as $no => $product ) {
635
+ $row = array();
636
+ foreach ( $headers as $key => $header ) {
637
+ if ( strpos( $header, "additional image link" ) !== false ) {
638
+ $header = "additional image link";
639
+ }
640
+ $row[] = isset( $product[ $header ] ) ? $product[ $header ] : '';
641
+ }
642
+ $feed[] = $row;
643
+ }
644
+
645
+ return $feed;
646
+ }
647
+
648
+ return false;
649
+ }
650
  }
includes/feeds/class-woo-feed-pinterest.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
 
3
  /**
4
  * Class Google
@@ -9,95 +9,94 @@
9
  * @package Google
10
  *
11
  */
12
- class Woo_Feed_Pinterest
13
- {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
- /**
16
- * This variable is responsible for holding all product attributes and their values
17
- *
18
- * @since 1.0.0
19
- * @var Woo_Feed_Products_v3 $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
- $feedRule['itemWrapper'] = $this->feedWrapper;
88
- $this->products = new Woo_Feed_Products_v3($feedRule);
89
-
90
- # When update via cron job then set productIds
91
- if ( ! isset($feedRule['productIds']) ) {
92
- $feedRule['productIds'] = $this->products->query_products();
93
- }
94
- $this->products->get_products($feedRule['productIds']);
95
- $this->rules = $feedRule;
96
  // $products = new Woo_Feed_Products();
97
- // $limit = isset($feedRule['Limit']) ? esc_html($feedRule['Limit']) : "";
98
- // $offset = isset($feedRule['Offset']) ? esc_html($feedRule['Offset']) : "";
99
- // $categories = isset($feedRule['categories']) ? $feedRule['categories']: "";
100
- // $storeProducts = $products->woo_feed_get_visible_product($feedRule);
101
  // $feedRule=$products->feedRule;
102
  // $engine = new WF_Engine($storeProducts, $feedRule);
103
  // $this->products = $engine->mapProductsByRules();
@@ -107,504 +106,544 @@ class Woo_Feed_Pinterest
107
  // } else {
108
  // $this->mapAttributeForCSVTXT();
109
  // }
110
- }
111
-
112
-
113
- /**
114
- * Return Feed
115
- * @return array
116
- */
117
- public function returnFinalProduct() {
118
- if ( ! empty($this->products) ) {
119
-
120
- if ( $this->rules['feedType'] == 'xml' ) {
121
- //return $this->get_feed($this->products);
122
- $feed = array(
123
- "header" => $this->get_xml_feed_header(),
124
- "body" => $this->products->feedBody,
125
- "footer" => $this->get_xml_feed_footer(),
126
- );
127
- return $feed;
128
- } elseif ( $this->rules['feedType'] == 'txt' ) {
129
-
130
- $feed = array(
131
- "body" => $this->products->feedBody,
132
- "header" => $this->products->feedHeader,
133
- "footer" => "",
134
- );
135
- //echo "<pre>";print_r($feed);die();
136
- return $feed;
137
- } elseif ( $this->rules['feedType'] == 'csv' ) {
138
-
139
- $feed = array(
140
- "body" => $this->products->feedBody,
141
- "header" => $this->products->feedHeader,
142
- "footer" => "",
143
- );
144
- return $feed;
145
- }
146
- }
147
-
148
- $feed = array(
149
- "body" => "",
150
- "header" => "",
151
- "footer" => "",
152
- );
153
- return $feed;
154
- }
155
-
156
- /**
157
- * Configure merchant attributes for XML feed
158
- */
159
- public function mapAttributeForXML() {
160
-
161
- $googleXMLAttribute = array(
162
- "id" => array( "g:id", false ),
163
- "title" => array( "title", true ),
164
- "description" => array( "description", true ),
165
- "link" => array( "link", true ),
166
- "mobile_link" => array( "mobile_link", true ),
167
- "product_type" => array( "g:product_type", true ),
168
- "current_category" => array( "g:google_product_category", true ),
169
- "image" => array( "g:image_link", true ),
170
- "images" => array( "g:additional_image_link", false ),
171
- "images_1" => array( "g:additional_image_link_1", true ),
172
- "images_2" => array( "g:additional_image_link_2", true ),
173
- "images_3" => array( "g:additional_image_link_3", true ),
174
- "images_4" => array( "g:additional_image_link_4", true ),
175
- "images_5" => array( "g:additional_image_link_5", true ),
176
- "images_6" => array( "g:additional_image_link_6", true ),
177
- "images_7" => array( "g:additional_image_link_7", true ),
178
- "images_8" => array( "g:additional_image_link_8", true ),
179
- "images_9" => array( "g:additional_image_link_9", true ),
180
- "images_10" => array( "g:additional_image_link_10", true ),
181
- "condition" => array( "g:condition", false ),
182
- "availability" => array( "g:availability", false ),
183
- "availability_date" => array( "g:availability_date", false ),
184
- "inventory" => array( "g:inventory", false ),
185
- "price" => array( "g:price", true ),
186
- "sale_price" => array( "g:sale_price", true ),
187
- "sale_price_effective_date" => array( "g:sale_price_effective_date", true ),
188
- "brand" => array( "g:brand", true ),
189
- "sku" => array( "g:mpn", true ),
190
- "upc" => array( "g:gtin", true ),
191
- "identifier_exists" => array( "g:identifier_exists", true ),
192
- "item_group_id" => array( "g:item_group_id", false ),
193
- "color" => array( "g:color", true ),
194
- "gender" => array( "g:gender", true ),
195
- "age_group" => array( "g:age_group", true ),
196
- "material" => array( "g:material", true ),
197
- "pattern" => array( "g:pattern", true ),
198
- "size" => array( "g:size", true ),
199
- "size_type" => array( "g:size_type", true ),
200
- "size_system" => array( "g:size_system", true ),
201
- "tax" => array( "tax", true ),
202
- "tax_country" => array( "g:tax_country", true ),
203
- "tax_region" => array( "g:tax_region", true ),
204
- "tax_rate" => array( "g:tax_rate", true ),
205
- "tax_ship" => array( "g:tax_ship", true ),
206
- "tax_category" => array( "g:tax_category", true ),
207
- "weight" => array( "g:shipping_weight", false ),
208
- "length" => array( "g:shipping_length", false ),
209
- "width" => array( "g:shipping_width", false ),
210
- "height" => array( "g:shipping_height", false ),
211
- "shipping_label" => array( "g:shipping_label", false ),
212
- "shipping_country" => array( "g:shipping_country", false ),
213
- "shipping_service" => array( "g:shipping_service", false ),
214
- "shipping_price" => array( "g:shipping_price", false ),
215
- "shipping_region" => array( "g:shipping_region", false ),
216
- "multipack" => array( "g:multipack", true ),
217
- "is_bundle" => array( "g:is_bundle", true ),
218
- "adult" => array( "g:adult", true ),
219
- "adwords_redirect" => array( "g:adwords_redirect", true ),
220
- "custom_label_0" => array( "g:custom_label_0", true ),
221
- "custom_label_1" => array( "g:custom_label_1", true ),
222
- "custom_label_2" => array( "g:custom_label_2", true ),
223
- "custom_label_3" => array( "g:custom_label_3", true ),
224
- "custom_label_4" => array( "g:custom_label_4", true ),
225
- "excluded_destination" => array( "g:excluded_destination", true ),
226
- "included_destination" => array( "g:included_destination", true ),
227
- "expiration_date" => array( "g:expiration_date", true ),
228
- "unit_pricing_measure" => array( "g:unit_pricing_measure", true ),
229
- "unit_pricing_base_measure" => array( "g:unit_pricing_base_measure", true ),
230
- "energy_efficiency_class" => array( "g:energy_efficiency_class", true ),
231
- "loyalty_points" => array( "g:loyalty_points", true ),
232
- "installment" => array( "g:installment", true ),
233
- "promotion_id" => array( "g:promotion_id", true ),
234
- "cost_of_goods_sold" => array( "g:cost_of_goods_sold", true ),
235
- );
236
-
237
- if ( ! empty($this->products) ) {
238
- foreach ( $this->products as $no => $product ) {
239
- //echo "<pre>";
240
- //print_r($product);die();
241
- $this->identifier_status_add($no);
242
- foreach ( $product as $key => $value ) {
243
- $this->mapAttribute($no, $key, $googleXMLAttribute[ $key ][0], $value, $googleXMLAttribute[ $key ][0]);
244
- }
245
-
246
- $this->process_google_shipping_attribute_for_xml($no);
247
- $this->process_google_tax_attribute_for_xml($no);
248
- }
249
- }
250
- }
251
-
252
- /**
253
- * Configure merchant attributes for XML feed
254
- */
255
- public function mapAttributeForCSVTXT() {
256
- //Basic product information
257
- $googleCSVTXTAttribute = array(
258
- "id" => array( "id", false ),
259
- "title" => array( "title", true ),
260
- "description" => array( "description", true ),
261
- "link" => array( "link", true ),
262
- "mobile_link" => array( "mobile_link", true ),
263
- "product_type" => array( "product_type", true ),
264
- "current_category" => array( "google_product_category", true ),
265
- "image" => array( "image_link", true ),
266
- "images" => array( "additional_image_link", true ),
267
- "images_1" => array( "additional_image_link_1", true ),
268
- "images_2" => array( "additional_image_link_2", true ),
269
- "images_3" => array( "additional_image_link_3", true ),
270
- "images_4" => array( "additional_image_link_4", true ),
271
- "images_5" => array( "additional_image_link_5", true ),
272
- "images_6" => array( "additional_image_link_6", true ),
273
- "images_7" => array( "additional_image_link_7", true ),
274
- "images_8" => array( "additional_image_link_8", true ),
275
- "images_9" => array( "additional_image_link_9", true ),
276
- "images_10" => array( "additional_image_link_10", true ),
277
- "condition" => array( "condition", false ),
278
- "availability" => array( "availability", false ),
279
- "availability_date" => array( "availability_date", false ),
280
- "inventory" => array( "inventory", false ),
281
- "price" => array( "price", true ),
282
- "sale_price" => array( "sale_price", true ),
283
- "sale_price_effective_date" => array( "sale_price_effective_date", true ),
284
- "brand" => array( "brand", true ),
285
- "sku" => array( "mpn", true ),
286
- "upc" => array( "gtin", true ),
287
- "identifier_exists" => array( "identifier exists", true ),
288
- "item_group_id" => array( "item_group_id", false ),
289
- "color" => array( "color", true ),
290
- "gender" => array( "gender", true ),
291
- "age_group" => array( "age_group", true ),
292
- "material" => array( "material", true ),
293
- "pattern" => array( "pattern", true ),
294
- "size" => array( "size", true ),
295
- "size_type" => array( "size_type", true ),
296
- "size_system" => array( "size_system", true ),
297
- "tax" => array( "tax", true ),
298
- "tax_country" => array( "tax_country", true ),
299
- "tax_region" => array( "tax_region", true ),
300
- "tax_rate" => array( "tax_rate", true ),
301
- "tax_ship" => array( "tax_ship", true ),
302
- "tax_category" => array( "tax_category", true ),
303
- "weight" => array( "shipping_weight", false ),
304
- "length" => array( "shipping_length", false ),
305
- "width" => array( "shipping_width", false ),
306
- "height" => array( "shipping_height", false ),
307
- "shipping_label" => array( "shipping_label", false ),
308
- "shipping_country" => array( "shipping_country", false ),
309
- "shipping_service" => array( "shipping_service", false ),
310
- "shipping_price" => array( "shipping_price", false ),
311
- "shipping_region" => array( "shipping_region", false ),
312
- "multipack" => array( "multipack", true ),
313
- "is_bundle" => array( "is_bundle", true ),
314
- "adult" => array( "adult", true ),
315
- "adwords_redirect" => array( "adwords_redirect", true ),
316
- "custom_label_0" => array( "custom_label_0", true ),
317
- "custom_label_1" => array( "custom_label_1", true ),
318
- "custom_label_2" => array( "custom_label_2", true ),
319
- "custom_label_3" => array( "custom_label_3", true ),
320
- "custom_label_4" => array( "custom_label_4", true ),
321
- "excluded_destination" => array( "excluded_destination", true ),
322
- "included_destination" => array( "included_destination", true ),
323
- "expiration_date" => array( "expiration_date", true ),
324
- "unit_pricing_measure" => array( "unit_pricing_measure", true ),
325
- "unit_pricing_base_measure" => array( "unit_pricing_base_measure", true ),
326
- "energy_efficiency_class" => array( "energy_efficiency_class", true ),
327
- "loyalty_points" => array( "loyalty_points", true ),
328
- "installment" => array( "installment", true ),
329
- "promotion_id" => array( "promotion_id", true ),
330
- "cost_of_goods_sold" => array( "cost_of_goods_sold", true ),
331
- );
332
-
333
- if ( ! empty($this->products) ) {
334
- foreach ( $this->products as $no => $product ) {
335
- foreach ( $product as $key => $value ) {
336
- $this->mapAttribute($no, $key, $googleCSVTXTAttribute[ $key ][0], $value, $googleCSVTXTAttribute[ $key ][0]);
337
- }
338
- $this->process_google_shipping_attribute_for_CSVTXT($no);
339
- $this->process_google_tax_attribute_for_CSVTXT($no);
340
- }
341
- }
342
- }
343
-
344
- /**
345
- * Map to google attribute
346
- * @param $no
347
- * @param $from
348
- * @param $to
349
- * @param $value
350
- * @param bool $cdata
351
- * @return array
352
- */
353
- public function mapAttribute( $no, $from, $to, $value, $cdata = false ) {
354
- unset($this->products[ $no ][ $from ]);
355
- if ( $to == 'g:color' ) {
356
- $value = str_replace(",","/",$value);
357
- }
358
- if ( $this->rules['feedType'] == 'xml' ) {
359
- return $this->products[ $no ][ $to ] = $this->formatXMLLine($to, $value, $cdata);
360
- } else {
361
- return $this->products[ $no ][ $to ] = $value;
362
- }
363
- }
364
-
365
- public function identifier_status_add( $no ) {
366
- $identifier = array( 'brand', 'upc', 'sku', 'mpn', 'gtin' );
367
- $product = $this->products[ $no ];
368
-
369
- if ( ! array_key_exists('g:identifier_exists',$product) ) {
370
- if ( count(array_intersect_key(array_flip($identifier), $product)) >= 2 ) {
371
- # Any 2 required keys exist!
372
- $countIdentifier = 0;
373
- if ( array_key_exists('brand',$product) && ! empty($product['brand']) ) {
374
- $countIdentifier++;
375
- }
376
- if ( array_key_exists('upc',$product) && ! empty($product['upc']) ) {
377
- $countIdentifier++;
378
- }
379
- if ( array_key_exists('sku',$product) && ! empty($product['sku']) ) {
380
- $countIdentifier++;
381
- }
382
- if ( array_key_exists('mpn',$product) && ! empty($product['mpn']) ) {
383
- $countIdentifier++;
384
- }
385
- if ( array_key_exists('gtin',$product) && ! empty($product['gtin']) ) {
386
- $countIdentifier++;
387
- }
388
- if ( $countIdentifier >= 2 ) {
389
- $this->products[ $no ]["g:identifier_exists"] = $this->formatXMLLine("g:identifier_exists", "yes", $cdata = true);
390
- }else {
391
- $this->products[ $no ]["g:identifier_exists"] = $this->formatXMLLine("g:identifier_exists", "no", $cdata = true);
392
- }
393
- } else {
394
- $this->products[ $no ]["g:identifier_exists"] = $this->formatXMLLine("g:identifier_exists", "no", $cdata = true);
395
- }
396
- }
397
- }
398
-
399
-
400
-
401
- public
402
- function process_google_shipping_attribute_for_xml( $no ) {
403
- $shipping = array( 'g:shipping_country', 'g:shipping_service', 'g:shipping_price', 'g:shipping_region' );
404
- $shippingAttr = array();
405
- $products = $this->products[ $no ];
406
- foreach ( $products as $keyAttr => $valueAttr ) {
407
- if ( in_array($keyAttr, $shipping) ) {
408
- array_push($shippingAttr, array( $keyAttr => $valueAttr ));
409
- unset($this->products[ $no ][ $keyAttr ]);
410
- }
411
- }
412
- if ( count($shippingAttr) ) {
413
- $str = "";
414
- foreach ( $shippingAttr as $key => $attributes ) {
415
- foreach ( $attributes as $keyAttr => $valueAttr ) {
416
- $str .= str_replace("shipping_", "", $valueAttr);
417
- }
418
- }
419
- return $this->products[ $no ]['g:shipping'] = $this->formatXMLLine("g:shipping", $str, false);
420
- }
421
- return false;
422
- }
423
-
424
- public
425
- function process_google_tax_attribute_for_xml( $no ) {
426
- $tax = array( 'g:tax_country', 'g:tax_region', 'g:tax_rate', 'g:tax_ship' );
427
- $taxAttr = array();
428
- $products = $this->products[ $no ];
429
- foreach ( $products as $keyAttr => $valueAttr ) {
430
- if ( in_array($keyAttr, $tax) ) {
431
- array_push($taxAttr, array( $keyAttr => $valueAttr ));
432
- unset($this->products[ $no ][ $keyAttr ]);
433
- }
434
- }
435
- if ( count($taxAttr) ) {
436
- $str = "";
437
- foreach ( $taxAttr as $key => $attributes ) {
438
- foreach ( $attributes as $keyAttr => $valueAttr ) {
439
- // if($keyAttr != "g:tax_ship")
440
- // {
441
- $str .= str_replace("tax_", "", $valueAttr);
442
- $str = str_replace("ship", "tax_ship", $str);
443
- // }
444
- // else
445
- // {
446
- // $str .= $valueAttr;
447
- // }
448
- }
449
- }
450
- return $this->products[ $no ]['g:tax'] = $this->formatXMLLine("g:tax", $str, false);
451
- }
452
- return false;
453
- }
454
-
455
- public
456
- function process_google_shipping_attribute_for_CSVTXT( $no ) {
457
- $shipping = array( 'shipping country', 'shipping service', 'shipping price', 'shipping region' );
458
- $shippingAttr = array();
459
- $products = $this->products[ $no ];
460
- foreach ( $products as $keyAttr => $valueAttr ) {
461
- if ( in_array($keyAttr, $shipping) ) {
462
- array_push($shippingAttr, array( $keyAttr => $valueAttr ));
463
- unset($this->products[ $no ][ $keyAttr ]);
464
- }
465
- }
466
- if ( count($shippingAttr) ) {
467
- $str = "";
468
- foreach ( $shippingAttr as $key => $attributes ) {
469
- foreach ( $attributes as $keyAttr => $valueAttr ) {
470
- $country = ($keyAttr == "shipping country") ? $str .= $valueAttr . ":" : "";
471
- $service = ($keyAttr == "shipping service") ? $str .= $valueAttr . ":" : "";
472
- $price = ($keyAttr == "shipping price") ? $str .= $valueAttr : "";
473
- $region = ($keyAttr == "shipping region") ? $str .= $valueAttr . ":" : "";
474
- }
475
- }
476
- return $this->products[ $no ]['shipping(country:region:service:price)'] = str_replace(" : ", ":", $str);
477
- }
478
- return false;
479
- }
480
-
481
- public
482
- function process_google_tax_attribute_for_CSVTXT( $no ) {
483
- $tax = array( 'tax country', 'tax region', 'tax rate', 'tax ship' );
484
- $taxAttr = array();
485
- $products = $this->products[ $no ];
486
- foreach ( $products as $keyAttr => $valueAttr ) {
487
- if ( in_array($keyAttr, $tax) ) {
488
- array_push($taxAttr, array( $keyAttr => $valueAttr ));
489
- unset($this->products[ $no ][ $keyAttr ]);
490
- }
491
- }
492
- if ( count($taxAttr) ) {
493
- $str = "";
494
- foreach ( $taxAttr as $key => $attributes ) {
495
- foreach ( $attributes as $keyAttr => $valueAttr ) {
496
- $country = ($keyAttr == "tax country") ? $str .= $valueAttr . ":" : "";
497
- $region = ($keyAttr == "tax region") ? $str .= $valueAttr . ":" : "";
498
- $rate = ($keyAttr == "tax rate") ? $str .= $valueAttr . ":" : "";
499
- $ship = ($keyAttr == "tax ship") ? $str .= $valueAttr . ":" : "";
500
- }
501
- }
502
- return $this->products[ $no ]['tax(country:region:rate:tax_ship)'] = str_replace(" : ",":", $str);
503
- }
504
- return false;
505
- }
506
-
507
- function formatXMLLine( $attribute, $value, $cdata, $space = "" ) {
508
- //Make single XML node
509
- if ( ! empty($value))
510
- $value = trim($value);
511
- if (gettype($value) == 'array')
512
- $value = json_encode($value);
513
- if ( strpos($value, "<![CDATA[") === false && substr(trim($value), 0, 4) == "http" ) {
514
- $value = "<![CDATA[$value]]>";
515
- } elseif ( strpos($value, "<![CDATA[") === false && $cdata === true && ! empty($value) ) {
516
- $value = "<![CDATA[$value]]>";
517
- } elseif ( $cdata ) {
518
- if ( ! empty($value) ) {
519
- $value = "<![CDATA[$value]]>";
520
- }
521
- }
522
- if ( substr($attribute, 0, 23) == 'g:additional_image_link' ) {
523
- $attribute = "g:additional_image_link";
524
- }
525
- return "
526
- $space<$attribute>$value</$attribute>";
527
- }
528
-
529
-
530
- public
531
- function get_xml_feed_header() {
532
- $output = '<?xml version="1.0" encoding="UTF-8" ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
533
  <rss version="2.0" xmlns:g="http://base.google.com/ns/1.0" xmlns:c="http://base.google.com/cns/1.0">
534
  <channel>
535
- <title><![CDATA[' . html_entity_decode(get_option('blogname')) . ']]></title>
536
  <link><![CDATA[' . site_url() . ']]></link>
537
- <description><![CDATA[' . html_entity_decode(get_option('blogdescription')) . ']]></description>';
538
- return $output;
539
- }
540
-
541
- public
542
- function get_xml_feed( $items ) {
543
- $feed = "";
544
- //$feed .= $this->get_feed_header();
545
- $feed .= "\n";
546
- if ( $items ) {
547
- foreach ( $items as $item => $products ) {
548
- $feed .= " <" . $this->feedWrapper . ">";
549
- foreach ( $products as $key => $value ) {
550
- if ( ! empty($value) ) {
551
- $feed .= $value;
552
- }
553
- }
554
- $feed .= "\n </" . $this->feedWrapper . ">\n";
555
- }
556
- //$feed .= $this->get_feed_footer();
557
-
558
- return $feed;
559
- }
560
- return false;
561
- }
562
-
563
- public
564
- function get_xml_feed_footer() {
565
- $footer = " </channel>
 
 
566
  </rss>";
567
- return $footer;
568
- }
569
-
570
- public
571
- function short_products() {
572
- if ( $this->products ) {
573
- update_option('wpf_progress', "Shorting Products");
574
- sleep(1);
575
- $array = array();
576
- $ij = 0;
577
- foreach ( $this->products as $key => $item ) {
578
- $array[ $ij ] = $item;
579
- unset($this->products[ $key ]);
580
- $ij++;
581
- }
582
- return $this->products = $array;
583
- }
584
- return $this->products;
585
- }
586
-
587
- /**
588
- * Responsible to make CSV feed
589
- * @return string
590
- */
591
- public
592
- function get_csv_feed() {
593
- if ( $this->products ) {
594
- $headers = array_keys($this->products[0]);
595
- $feed[] = $headers;
596
- foreach ( $this->products as $no => $product ) {
597
- $row = array();
598
- foreach ( $headers as $key => $header ) {
599
- if ( strpos($header, "additional_image_link") !== false ) {
600
- $header = "additional_image_link";
601
- }
602
- $row[] = isset($product[ $header ]) ? $product[ $header ] : "";
603
- }
604
- $feed[] = $row;
605
- }
606
- return $feed;
607
- }
608
- return false;
609
- }
 
 
 
 
 
610
  }
1
+ <?php /** @noinspection PhpUnusedPrivateMethodInspection, PhpUndefinedMethodInspection, PhpUnused, PhpUnusedPrivateFieldInspection, PhpUnusedLocalVariableInspection, DuplicatedCode, PhpUnusedParameterInspection, PhpForeachNestedOuterKeyValueVariablesConflictInspection, RegExpRedundantEscape */
2
 
3
  /**
4
  * Class Google
9
  * @package Google
10
  *
11
  */
12
+ class Woo_Feed_Pinterest {
13
+
14
+ /**
15
+ * This variable is responsible for holding all product attributes and their values
16
+ *
17
+ * @since 1.0.0
18
+ * @var Woo_Feed_Products_v3 $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 array $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 array $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 array $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 int $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 string $feedWrapper Feed Wrapper text
64
+ * @access public
65
+ */
66
+ public $feedWrapper = 'item';
67
+
68
+ /**
69
+ * Store product information
70
+ *
71
+ * @since 1.0.0
72
+ * @var array $storeProducts
73
+ * @access public
74
+ */
75
+ private $storeProducts;
76
+
77
+ /**
78
+ * Define the core functionality to generate feed.
79
+ *
80
+ * Set the feed rules. Map products according to the rules and Check required attributes
81
+ * and their values according to merchant specification.
82
+ * @var Woo_Generate_Feed $feedRule Contain Feed Configuration
83
+ * @since 1.0.0
84
+ */
85
+ public function __construct( $feedRule ) {
86
+ $feedRule['itemWrapper'] = $this->feedWrapper;
87
+ $this->products = new Woo_Feed_Products_v3( $feedRule );
88
+ # When update via cron job then set productIds
89
+ if ( ! isset( $feedRule['productIds'] ) ) {
90
+ $feedRule['productIds'] = $this->products->query_products();
91
+ }
92
+ $this->products->get_products( $feedRule['productIds'] );
93
+ $this->rules = $feedRule;
94
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  // $products = new Woo_Feed_Products();
96
+ // $limit = isset($feedRule['Limit']) ? esc_html($feedRule['Limit']) : '';
97
+ // $offset = isset($feedRule['Offset']) ? esc_html($feedRule['Offset']) : '';
98
+ // $categories = isset($feedRule['categories']) ? $feedRule['categories']: '';
99
+ // $storeProducts = $products->woo_feed_get_visible_product($limit, $offset,$categories,$feedRule);
100
  // $feedRule=$products->feedRule;
101
  // $engine = new WF_Engine($storeProducts, $feedRule);
102
  // $this->products = $engine->mapProductsByRules();
106
  // } else {
107
  // $this->mapAttributeForCSVTXT();
108
  // }
109
+ }
110
+
111
+
112
+ /**
113
+ * Return Feed
114
+ * @return array
115
+ */
116
+ public function returnFinalProduct() {
117
+ if ( ! empty( $this->products ) ) {
118
+
119
+ if ( 'xml' == $this->rules['feedType'] ) {
120
+ //return $this->get_feed($this->products);
121
+ $feed = array(
122
+ "header" => $this->get_xml_feed_header(),
123
+ "body" => $this->products->feedBody,
124
+ "footer" => $this->get_xml_feed_footer(),
125
+ );
126
+
127
+ return $feed;
128
+ } elseif ( 'txt' == $this->rules['feedType'] ) {
129
+
130
+ $feed = array(
131
+ "body" => $this->products->feedBody,
132
+ "header" => $this->products->feedHeader,
133
+ "footer" => '',
134
+ );
135
+
136
+ //echo "<pre>";print_r($feed);die();
137
+ return $feed;
138
+ } elseif ( 'csv' == $this->rules['feedType'] ) {
139
+
140
+ $feed = array(
141
+ "body" => $this->products->feedBody,
142
+ "header" => $this->products->feedHeader,
143
+ "footer" => '',
144
+ );
145
+
146
+ return $feed;
147
+ }
148
+ }
149
+
150
+ $feed = array(
151
+ "body" => '',
152
+ "header" => '',
153
+ "footer" => '',
154
+ );
155
+
156
+ return $feed;
157
+ }
158
+
159
+ /**
160
+ * Configure merchant attributes for XML feed
161
+ */
162
+ public function mapAttributeForXML() {
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 ( ! empty( $this->products ) ) {
241
+ foreach ( $this->products as $no => $product ) {
242
+ //echo "<pre>";
243
+ //print_r($product);die();
244
+ $this->identifier_status_add( $no );
245
+ foreach ( $product as $key => $value ) {
246
+ $this->mapAttribute( $no,
247
+ $key,
248
+ $googleXMLAttribute[ $key ][0],
249
+ $value,
250
+ $googleXMLAttribute[ $key ][0] );
251
+ }
252
+
253
+ $this->process_google_shipping_attribute_for_xml( $no );
254
+ $this->process_google_tax_attribute_for_xml( $no );
255
+ }
256
+ }
257
+ }
258
+
259
+ /**
260
+ * Configure merchant attributes for XML feed
261
+ */
262
+ public function mapAttributeForCSVTXT() {
263
+ //Basic product information
264
+ $googleCSVTXTAttribute = array(
265
+ "id" => array( "id", false ),
266
+ "title" => array( "title", true ),
267
+ "description" => array( "description", true ),
268
+ "link" => array( "link", true ),
269
+ "mobile_link" => array( "mobile_link", true ),
270
+ "product_type" => array( "product_type", true ),
271
+ "current_category" => array( "google_product_category", true ),
272
+ "image" => array( "image_link", true ),
273
+ "images" => array( "additional_image_link", true ),
274
+ "images_1" => array( "additional_image_link_1", true ),
275
+ "images_2" => array( "additional_image_link_2", true ),
276
+ "images_3" => array( "additional_image_link_3", true ),
277
+ "images_4" => array( "additional_image_link_4", true ),
278
+ "images_5" => array( "additional_image_link_5", true ),
279
+ "images_6" => array( "additional_image_link_6", true ),
280
+ "images_7" => array( "additional_image_link_7", true ),
281
+ "images_8" => array( "additional_image_link_8", true ),
282
+ "images_9" => array( "additional_image_link_9", true ),
283
+ "images_10" => array( "additional_image_link_10", true ),
284
+ "condition" => array( "condition", false ),
285
+ "availability" => array( "availability", false ),
286
+ "availability_date" => array( "availability_date", false ),
287
+ "inventory" => array( "inventory", false ),
288
+ "price" => array( "price", true ),
289
+ "sale_price" => array( "sale_price", true ),
290
+ "sale_price_effective_date" => array( "sale_price_effective_date", true ),
291
+ "brand" => array( "brand", true ),
292
+ "sku" => array( "mpn", true ),
293
+ "upc" => array( "gtin", true ),
294
+ "identifier_exists" => array( "identifier exists", true ),
295
+ "item_group_id" => array( "item_group_id", false ),
296
+ "color" => array( "color", true ),
297
+ "gender" => array( "gender", true ),
298
+ "age_group" => array( "age_group", true ),
299
+ "material" => array( "material", true ),
300
+ "pattern" => array( "pattern", true ),
301
+ "size" => array( "size", true ),
302
+ "size_type" => array( "size_type", true ),
303
+ "size_system" => array( "size_system", true ),
304
+ "tax" => array( "tax", true ),
305
+ "tax_country" => array( "tax_country", true ),
306
+ "tax_region" => array( "tax_region", true ),
307
+ "tax_rate" => array( "tax_rate", true ),
308
+ "tax_ship" => array( "tax_ship", true ),
309
+ "tax_category" => array( "tax_category", true ),
310
+ "weight" => array( "shipping_weight", false ),
311
+ "length" => array( "shipping_length", false ),
312
+ "width" => array( "shipping_width", false ),
313
+ "height" => array( "shipping_height", false ),
314
+ "shipping_label" => array( "shipping_label", false ),
315
+ "shipping_country" => array( "shipping_country", false ),
316
+ "shipping_service" => array( "shipping_service", false ),
317
+ "shipping_price" => array( "shipping_price", false ),
318
+ "shipping_region" => array( "shipping_region", false ),
319
+ "multipack" => array( "multipack", true ),
320
+ "is_bundle" => array( "is_bundle", true ),
321
+ "adult" => array( "adult", true ),
322
+ "adwords_redirect" => array( "adwords_redirect", true ),
323
+ "custom_label_0" => array( "custom_label_0", true ),
324
+ "custom_label_1" => array( "custom_label_1", true ),
325
+ "custom_label_2" => array( "custom_label_2", true ),
326
+ "custom_label_3" => array( "custom_label_3", true ),
327
+ "custom_label_4" => array( "custom_label_4", true ),
328
+ "excluded_destination" => array( "excluded_destination", true ),
329
+ "included_destination" => array( "included_destination", true ),
330
+ "expiration_date" => array( "expiration_date", true ),
331
+ "unit_pricing_measure" => array( "unit_pricing_measure", true ),
332
+ "unit_pricing_base_measure" => array( "unit_pricing_base_measure", true ),
333
+ "energy_efficiency_class" => array( "energy_efficiency_class", true ),
334
+ "loyalty_points" => array( "loyalty_points", true ),
335
+ "installment" => array( "installment", true ),
336
+ "promotion_id" => array( "promotion_id", true ),
337
+ "cost_of_goods_sold" => array( "cost_of_goods_sold", true ),
338
+ );
339
+
340
+ if ( ! empty( $this->products ) ) {
341
+ foreach ( $this->products as $no => $product ) {
342
+ foreach ( $product as $key => $value ) {
343
+ $this->mapAttribute( $no,
344
+ $key,
345
+ $googleCSVTXTAttribute[ $key ][0],
346
+ $value,
347
+ $googleCSVTXTAttribute[ $key ][0] );
348
+ }
349
+ $this->process_google_shipping_attribute_for_CSVTXT( $no );
350
+ $this->process_google_tax_attribute_for_CSVTXT( $no );
351
+ }
352
+ }
353
+ }
354
+
355
+ /**
356
+ * Map to google attribute
357
+ *
358
+ * @param $no
359
+ * @param $from
360
+ * @param $to
361
+ * @param $value
362
+ * @param bool $cdata
363
+ *
364
+ * @return array|string
365
+ */
366
+ public function mapAttribute( $no, $from, $to, $value, $cdata = false ) {
367
+ unset( $this->products[ $no ][ $from ] );
368
+ if ( 'g:color' == $to ) {
369
+ $value = str_replace( ',', '/', $value );
370
+ }
371
+ if ( 'xml' == $this->rules['feedType'] ) {
372
+ return $this->products[ $no ][ $to ] = $this->formatXMLLine( $to, $value, $cdata );
373
+ } else {
374
+ return $this->products[ $no ][ $to ] = $value;
375
+ }
376
+ }
377
+
378
+ public function identifier_status_add( $no ) {
379
+ $identifier = array( 'brand', 'upc', 'sku', 'mpn', 'gtin' );
380
+ $product = $this->products[ $no ];
381
+
382
+ if ( ! array_key_exists( 'g:identifier_exists', $product ) ) {
383
+ if ( count( array_intersect_key( array_flip( $identifier ), $product ) ) >= 2 ) {
384
+ # Any 2 required keys exist!
385
+ $countIdentifier = 0;
386
+ if ( array_key_exists( 'brand', $product ) && ! empty( $product['brand'] ) ) {
387
+ $countIdentifier ++;
388
+ }
389
+ if ( array_key_exists( 'upc', $product ) && ! empty( $product['upc'] ) ) {
390
+ $countIdentifier ++;
391
+ }
392
+ if ( array_key_exists( 'sku', $product ) && ! empty( $product['sku'] ) ) {
393
+ $countIdentifier ++;
394
+ }
395
+ if ( array_key_exists( 'mpn', $product ) && ! empty( $product['mpn'] ) ) {
396
+ $countIdentifier ++;
397
+ }
398
+ if ( array_key_exists( 'gtin', $product ) && ! empty( $product['gtin'] ) ) {
399
+ $countIdentifier ++;
400
+ }
401
+ if ( $countIdentifier >= 2 ) {
402
+ $this->products[ $no ]["g:identifier_exists"] = $this->formatXMLLine( "g:identifier_exists",
403
+ "yes",
404
+ $cdata = true );
405
+ } else {
406
+ $this->products[ $no ]["g:identifier_exists"] = $this->formatXMLLine( "g:identifier_exists",
407
+ 'no',
408
+ $cdata = true );
409
+ }
410
+ } else {
411
+ $this->products[ $no ]["g:identifier_exists"] = $this->formatXMLLine( "g:identifier_exists",
412
+ 'no',
413
+ $cdata = true );
414
+ }
415
+ }
416
+ }
417
+
418
+
419
+ public
420
+ function process_google_shipping_attribute_for_xml(
421
+ $no
422
+ ) {
423
+ $shipping = array( 'g:shipping_country', 'g:shipping_service', 'g:shipping_price', 'g:shipping_region' );
424
+ $shippingAttr = array();
425
+ $products = $this->products[ $no ];
426
+ foreach ( $products as $keyAttr => $valueAttr ) {
427
+ if ( in_array( $keyAttr, $shipping ) ) {
428
+ array_push( $shippingAttr, array( $keyAttr => $valueAttr ) );
429
+ unset( $this->products[ $no ][ $keyAttr ] );
430
+ }
431
+ }
432
+ if ( count( $shippingAttr ) ) {
433
+ $str = '';
434
+ foreach ( $shippingAttr as $key => $attributes ) {
435
+ foreach ( $attributes as $keyAttr => $valueAttr ) {
436
+ $str .= str_replace( 'shipping_', '', $valueAttr );
437
+ }
438
+ }
439
+
440
+ return $this->products[ $no ]['g:shipping'] = $this->formatXMLLine( "g:shipping", $str, false );
441
+ }
442
+
443
+ return false;
444
+ }
445
+
446
+ public
447
+ function process_google_tax_attribute_for_xml(
448
+ $no
449
+ ) {
450
+ $tax = array( 'g:tax_country', 'g:tax_region', 'g:tax_rate', 'g:tax_ship' );
451
+ $taxAttr = array();
452
+ $products = $this->products[ $no ];
453
+ foreach ( $products as $keyAttr => $valueAttr ) {
454
+ if ( in_array( $keyAttr, $tax ) ) {
455
+ array_push( $taxAttr, array( $keyAttr => $valueAttr ) );
456
+ unset( $this->products[ $no ][ $keyAttr ] );
457
+ }
458
+ }
459
+ if ( count( $taxAttr ) ) {
460
+ $str = '';
461
+ foreach ( $taxAttr as $key => $attributes ) {
462
+ foreach ( $attributes as $keyAttr => $valueAttr ) {
463
+ // if($keyAttr != "g:tax_ship")
464
+ // {
465
+ $str .= str_replace( 'tax_', '', $valueAttr );
466
+ $str = str_replace( 'ship', 'tax_ship', $str );
467
+ // }
468
+ // else
469
+ // {
470
+ // $str .= $valueAttr;
471
+ // }
472
+ }
473
+ }
474
+
475
+ return $this->products[ $no ]['g:tax'] = $this->formatXMLLine( "g:tax", $str, false );
476
+ }
477
+
478
+ return false;
479
+ }
480
+
481
+ public
482
+ function process_google_shipping_attribute_for_CSVTXT(
483
+ $no
484
+ ) {
485
+ $shipping = array( 'shipping country', 'shipping service', 'shipping price', 'shipping region' );
486
+ $shippingAttr = array();
487
+ $products = $this->products[ $no ];
488
+ foreach ( $products as $keyAttr => $valueAttr ) {
489
+ if ( in_array( $keyAttr, $shipping ) ) {
490
+ array_push( $shippingAttr, array( $keyAttr => $valueAttr ) );
491
+ unset( $this->products[ $no ][ $keyAttr ] );
492
+ }
493
+ }
494
+ if ( count( $shippingAttr ) ) {
495
+ $str = '';
496
+ foreach ( $shippingAttr as $key => $attributes ) {
497
+ foreach ( $attributes as $keyAttr => $valueAttr ) {
498
+ $country = ( 'shipping country' == $keyAttr ) ? $str .= $valueAttr . ':' : '';
499
+ $service = ( 'shipping service' == $keyAttr ) ? $str .= $valueAttr . ':' : '';
500
+ $price = ( 'shipping price' == $keyAttr ) ? $str .= $valueAttr : '';
501
+ $region = ( 'shipping region' == $keyAttr ) ? $str .= $valueAttr . ':' : '';
502
+ }
503
+ }
504
+
505
+ return $this->products[ $no ]['shipping(country:region:service:price)'] = str_replace( ' : ', ':', $str );
506
+ }
507
+
508
+ return false;
509
+ }
510
+
511
+ public function process_google_tax_attribute_for_CSVTXT( $no ) {
512
+ $tax = array( 'tax country', 'tax region', 'tax rate', 'tax ship' );
513
+ $taxAttr = array();
514
+ $products = $this->products[ $no ];
515
+ foreach ( $products as $keyAttr => $valueAttr ) {
516
+ if ( in_array( $keyAttr, $tax ) ) {
517
+ array_push( $taxAttr, array( $keyAttr => $valueAttr ) );
518
+ unset( $this->products[ $no ][ $keyAttr ] );
519
+ }
520
+ }
521
+ if ( count( $taxAttr ) ) {
522
+ $str = '';
523
+ foreach ( $taxAttr as $key => $attributes ) {
524
+ foreach ( $attributes as $keyAttr => $valueAttr ) {
525
+ $country = ( 'tax country' == $keyAttr ) ? $str .= $valueAttr . ':' : '';
526
+ $region = ( 'tax region' == $keyAttr ) ? $str .= $valueAttr . ':' : '';
527
+ $rate = ( 'tax rate' == $keyAttr ) ? $str .= $valueAttr . ':' : '';
528
+ $ship = ( 'tax ship' == $keyAttr ) ? $str .= $valueAttr : '';
529
+ }
530
+ }
531
+
532
+ return $this->products[ $no ]['tax(country:region:rate:tax_ship)'] = str_replace( ' : ', ':', $str );
533
+ }
534
+
535
+ return false;
536
+ }
537
+
538
+ function formatXMLLine( $attribute, $value, $cdata, $space = '' ) {
539
+ //Make single XML node
540
+ if ( ! empty( $value ) ) {
541
+ $value = trim( $value );
542
+ }
543
+ if ( 'array' == gettype( $value ) ) {
544
+ $value = wp_json_encode( $value );
545
+ }
546
+ if ( false === strpos( $value, "<![CDATA[" ) && 'http' == substr( trim( $value ), 0, 4 ) ) {
547
+ $value = "<![CDATA[$value]]>";
548
+ } elseif ( false === strpos( $value, "<![CDATA[" ) && true === $cdata && ! empty( $value ) ) {
549
+ $value = "<![CDATA[$value]]>";
550
+ } elseif ( $cdata ) {
551
+ if ( ! empty( $value ) ) {
552
+ $value = "<![CDATA[$value]]>";
553
+ }
554
+ }
555
+ if ( 'g:additional_image_link' === substr( $attribute, 0, 23 ) ) {
556
+ $attribute = "g:additional_image_link";
557
+ }
558
+
559
+ return "$space<$attribute>$value</$attribute>";
560
+ }
561
+
562
+
563
+ public function get_xml_feed_header() {
564
+ $output = '<?xml version="1.0" encoding="UTF-8" ?>
565
  <rss version="2.0" xmlns:g="http://base.google.com/ns/1.0" xmlns:c="http://base.google.com/cns/1.0">
566
  <channel>
567
+ <title><![CDATA[' . html_entity_decode( get_option( 'blogname' ) ) . ']]></title>
568
  <link><![CDATA[' . site_url() . ']]></link>
569
+ <description><![CDATA[' . html_entity_decode( get_option( 'blogdescription' ) ) . ']]></description>';
570
+
571
+ return $output;
572
+ }
573
+
574
+ public function get_xml_feed( $items ) {
575
+ $feed = '';
576
+ //$feed .= $this->get_feed_header();
577
+ $feed .= "\n";
578
+ if ( $items ) {
579
+ foreach ( $items as $item => $products ) {
580
+ $feed .= " <" . $this->feedWrapper . ">";
581
+ foreach ( $products as $key => $value ) {
582
+ if ( ! empty( $value ) ) {
583
+ $feed .= $value;
584
+ }
585
+ }
586
+ $feed .= "\n </" . $this->feedWrapper . ">\n";
587
+ }
588
+
589
+ //$feed .= $this->get_feed_footer();
590
+
591
+ return $feed;
592
+ }
593
+
594
+ return false;
595
+ }
596
+
597
+ public
598
+ function get_xml_feed_footer() {
599
+ $footer = " </channel>
600
  </rss>";
601
+
602
+ return $footer;
603
+ }
604
+
605
+ public
606
+ function short_products() {
607
+ if ( $this->products ) {
608
+ update_option( 'wpf_progress', esc_html__( 'Shorting Products', 'woo-feed' ), false );
609
+ sleep( 1 );
610
+ $array = array();
611
+ $ij = 0;
612
+ foreach ( $this->products as $key => $item ) {
613
+ $array[ $ij ] = $item;
614
+ unset( $this->products[ $key ] );
615
+ $ij ++;
616
+ }
617
+
618
+ return $this->products = $array;
619
+ }
620
+
621
+ return $this->products;
622
+ }
623
+
624
+ /**
625
+ * Responsible to make CSV feed
626
+ * @return string
627
+ */
628
+ public
629
+ function get_csv_feed() {
630
+ if ( $this->products ) {
631
+ $headers = array_keys( $this->products[0] );
632
+ $feed[] = $headers;
633
+ foreach ( $this->products as $no => $product ) {
634
+ $row = array();
635
+ foreach ( $headers as $key => $header ) {
636
+ if ( false !== strpos( $header, "additional_image_link" ) ) {
637
+ $header = "additional_image_link";
638
+ }
639
+ $row[] = isset( $product[ $header ] ) ? $product[ $header ] : '';
640
+ }
641
+ $feed[] = $row;
642
+ }
643
+
644
+ return $feed;
645
+ }
646
+
647
+ return false;
648
+ }
649
  }
includes/helper.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
  /**
3
  * Helper Functions
4
  * @package WooFeed
@@ -8,37 +8,45 @@
8
  * @author KD <mhamudul.hk@gmail.com>
9
  * @copyright WebAppick
10
  */
11
- if ( ! defined( 'ABSPATH' ) ) die(); // Silence...
 
 
 
 
12
 
13
  if ( ! function_exists( 'woo_feed_maybe_define_constant' ) ) {
14
  /**
15
  * Define a constant if it is not already defined.
16
  *
17
- * @since 3.2.1
18
- * @param string $name Constant name.
19
- * @param mixed $value Value.
20
  *
21
  * @return void
 
 
22
  */
23
  function woo_feed_maybe_define_constant( $name, $value ) {
 
24
  if ( ! defined( $name ) ) {
25
  define( $name, $value );
26
  }
 
27
  }
28
  }
29
  if ( ! function_exists( 'woo_feed_doing_it_wrong' ) ) {
30
  /**
31
  * Wrapper for _doing_it_wrong.
32
  *
33
- * @since 3.2.1
34
  * @param string $function Function used.
35
  * @param string $message Message to log.
36
  * @param string $version Version the message was added in.
37
  *
38
  * @return void
 
 
39
  */
40
  function woo_feed_doing_it_wrong( $function, $message, $version ) {
41
- // @codingStandardsIgnoreStart
42
  $message .= ' Backtrace: ' . wp_debug_backtrace_summary();
43
 
44
  if ( is_ajax() || WC()->is_rest_api_request() ) {
@@ -47,7 +55,7 @@ if ( ! function_exists( 'woo_feed_doing_it_wrong' ) ) {
47
  } else {
48
  _doing_it_wrong( $function, $message, $version );
49
  }
50
- // @codingStandardsIgnoreEnd
51
  }
52
  }
53
  if ( ! function_exists( 'is_ajax' ) ) {
@@ -61,60 +69,73 @@ if ( ! function_exists( 'is_ajax' ) ) {
61
  return function_exists( 'wp_doing_ajax' ) ? wp_doing_ajax() : defined( 'DOING_AJAX' );
62
  }
63
  }
64
- if ( ! function_exists( 'wooFeed_is_plugin_active' ) ) {
65
  /**
66
  * Determines whether a plugin is active.
67
- * @since 3.1.41
68
- * @see is_plugin_active()
69
  * @param string $plugin Path to the plugin file relative to the plugins directory.
 
70
  * @return bool True, if in the active plugins list. False, not in the list.
 
 
 
71
  */
72
- function wooFeed_is_plugin_active( $plugin ) {
73
- if ( ! function_exists('is_plugin_active') ) include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
 
 
 
74
  return is_plugin_active( $plugin );
75
  }
76
  }
77
  if ( ! function_exists( 'wooFeed_is_plugin_inactive' ) ) {
78
  /**
79
  * Determines whether the plugin is inactive.
80
- * @since 3.1.41
81
- * @see wooFeed_is_plugin_inactive()
82
  *
83
  * @param string $plugin Path to the plugin file relative to the plugins directory.
 
84
  * @return bool True if inactive. False if active.
 
 
 
85
  */
86
  function wooFeed_is_plugin_inactive( $plugin ) {
87
- return ! wooFeed_is_plugin_active( $plugin );
88
  }
89
  }
90
  if ( ! function_exists( 'wooFeed_deactivate_plugins' ) ) {
91
  /**
92
  * Deactivate a single plugin or multiple plugins.
93
  * Wrapper for core deactivate_plugins() function
94
- * @see deactivate_plugins()
95
  * @param string|array $plugins Single plugin or list of plugins to deactivate.
96
  * @param bool $silent Prevent calling deactivation hooks. Default is false.
97
  * @param mixed $network_wide Whether to deactivate the plugin for all sites in the network.
 
98
  * @return void
 
 
99
  */
100
- function wooFeed_deactivate_plugins( $plugins, $silent = false, $network_wide = null ) {
101
- if ( ! function_exists( 'deactivate_plugins' ) ) require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
 
 
102
  deactivate_plugins( $plugins, $silent, $network_wide );
103
  }
104
  }
105
  if ( ! function_exists( 'wooFeed_is_supported_php' ) ) {
106
  /**
107
  * Check if server php version meet minimum requirement
108
- * @since 3.1.41
109
  * @return bool
 
110
  */
111
- function wooFeed_is_supported_php(){
112
  // PHP version need to be => WOO_FEED_MIN_PHP_VERSION
113
  return ! version_compare( PHP_VERSION, WOO_FEED_MIN_PHP_VERSION, '<' );
114
  }
115
  }
116
  if ( ! function_exists( 'wooFeed_check_WC' ) ) {
117
- function wooFeed_check_WC(){
118
  return class_exists( 'WooCommerce', false );
119
  }
120
  }
@@ -127,28 +148,32 @@ if ( ! function_exists( 'wooFeed_is_WC_supported' ) ) {
127
  if ( ! function_exists( 'woo_feed_wc_version_check' ) ) {
128
  /**
129
  * Check WooCommerce Version
 
130
  * @param string $version
 
131
  * @return bool
132
  */
133
  function woo_feed_wc_version_check( $version = '3.0' ) {
134
- if ( ! function_exists( 'get_plugins' ) ) {
135
- require_once ABSPATH . 'wp-admin/includes/plugin.php';
136
- }
137
-
138
  $plugins = get_plugins();
139
- if ( array_key_exists('woocommerce/woocommerce.php',$plugins) ) {
140
  $currentVersion = $plugins['woocommerce/woocommerce.php']['Version'];
141
  if ( version_compare( $currentVersion, $version, ">=" ) ) {
142
  return true;
143
  }
144
  }
 
145
  return false;
146
  }
147
  }
148
  if ( ! function_exists( 'woo_feed_wpml_version_check' ) ) {
149
  /**
150
  * Check WooCommerce Version
 
151
  * @param string $version
 
152
  * @return bool
153
  */
154
  function woo_feed_wpml_version_check( $version = '3.2' ) {
@@ -158,6 +183,7 @@ if ( ! function_exists( 'woo_feed_wpml_version_check' ) ) {
158
  return true;
159
  }
160
  }
 
161
  return false;
162
  }
163
  }
@@ -165,32 +191,43 @@ if ( ! function_exists( 'wooFeed_Admin_Notices' ) ) {
165
  /**
166
  * Display Admin Messages
167
  * @hooked admin_notices
168
- * @since 3.1.41
169
  * @return void
 
170
  */
171
- function wooFeed_Admin_Notices(){
172
  //@TODO Refactor this function with admin message class
173
  // WC Missing Notice..
174
  if ( ! wooFeed_check_WC() ) {
175
  $plugin_url = self_admin_url( 'plugin-install.php?s=woocommerce&tab=search&type=term' );
176
  /** @noinspection HtmlUnknownTarget */
177
- $plugin_url = sprintf( '<a href="%s">%s</a>', $plugin_url, esc_html__( 'WooCommerce', 'woocommerce' ) );
178
  $plugin_name = sprintf( '<code>%s</code>', esc_html__( 'WooCommerce Product Feed', 'woo-feed' ) );
179
- $wc_name = sprintf( '<code>%s</code>', esc_html__( 'WooCommerce', 'woocommerce' ) );
180
- $message = sprintf( esc_html__( '%1$s requires %2$s to be installed and active. You can installed/activate %3$s here.', 'woo-feed' ), $plugin_name, $wc_name, $plugin_url );
181
- printf( '<div class="error"><p><strong>%1$s</strong></p></div>', $message );
 
 
 
 
 
182
  }
183
  if ( wooFeed_check_WC() && ! wooFeed_is_WC_supported() ) {
184
  $plugin_url = self_admin_url( 'plugin-install.php?s=woocommerce&tab=search&type=term' );
185
- $wcVersion = defined( 'WC_VERSION' ) ? '<code>'.WC_VERSION.'</code>' : '<code>UNKNOWN</code>';
186
- $minVersion = '<code>'.WOO_FEED_MIN_WC_VERSION.'</code>';
187
  /** @noinspection HtmlUnknownTarget */
188
- $plugin_url = sprintf( '<a href="%s">%s</a>', $plugin_url, esc_html__( 'WooCommerce', 'woocommerce' ) );
189
  $plugin_name = sprintf( '<code>%s</code>', esc_html__( 'WooCommerce Product Feed', 'woo-feed' ) );
190
- $wc_name = sprintf( '<code>%s</code>', esc_html__( 'WooCommerce', 'woocommerce' ) );
191
- $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' ),
192
- $plugin_name, $wc_name, $minVersion, $wcVersion, $plugin_url );
193
- printf( '<div class="error"><p><strong>%1$s</strong></p></div>', $message );
 
 
 
 
 
 
194
  }
195
  }
196
  }
@@ -201,7 +238,7 @@ if ( ! function_exists( 'checkFTP_connection' ) ) {
201
  * @return bool
202
  */
203
  function checkFTP_connection() {
204
- return ( extension_loaded('ftp' ) || function_exists( 'ftp_connect' ) );
205
  }
206
  }
207
  if ( ! function_exists( 'checkSFTP_connection' ) ) {
@@ -211,52 +248,203 @@ if ( ! function_exists( 'checkSFTP_connection' ) ) {
211
  * @return bool
212
  */
213
  function checkSFTP_connection() {
214
- return ( extension_loaded('ssh2' ) || function_exists( 'ssh2_connect' ) );
215
  }
216
  }
217
  if ( ! function_exists( 'array_splice_assoc' ) ) {
218
  /**
219
  * Array Splice Associative Array
220
  * @see https://www.php.net/manual/en/function.array-splice.php#111204
 
221
  * @param array $input
222
- * @param int $offset
223
- * @param int $length
224
  * @param array $replacement
225
  *
226
  * @return array
227
  */
228
  function array_splice_assoc( $input, $offset, $length, $replacement ) {
229
  $replacement = (array) $replacement;
230
- $key_indices = array_flip(array_keys($input));
231
- if ( isset($input[ $offset ]) && is_string($offset) ) {
232
- $offset = $key_indices[ $offset ];
233
  }
234
- if ( isset($input[ $length ]) && is_string($length) ) {
235
  $length = $key_indices[ $length ] - $offset;
236
  }
237
 
238
- $input = array_slice($input, 0, $offset, TRUE)
239
- + $replacement
240
- + array_slice($input, $offset + $length, NULL, TRUE);
 
 
241
  return $input;
242
  }
243
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
 
245
- // The Editor
246
- if ( ! function_exists( 'register_and_do_woo_feed_meta_boxes' ) ) {
247
  /**
248
- * Registers the default Feed Editor MetaBoxes, and runs the `do_meta_boxes` actions.
 
 
 
 
 
 
 
 
 
 
249
  *
250
- * @since 3.2.6
251
  *
252
- * @see register_and_do_post_meta_boxes()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253
  *
254
- * @param string|WP_Screen $screen Screen identifier. If you have used add_menu_page() or
255
  * add_submenu_page() to create a new screen (and hence screen_id)
256
  * make sure your menu slug conforms to the limits of sanitize_key()
257
  * otherwise the 'screen' menu may not correctly render on your page.
258
- * @param array $feedRules current feed being processed.
 
259
  * @return void
 
 
 
 
260
  */
261
  function register_and_do_woo_feed_meta_boxes( $screen, $feedRules = array() ) {
262
  if ( empty( $screen ) ) {
@@ -266,7 +454,12 @@ if ( ! function_exists( 'register_and_do_woo_feed_meta_boxes' ) ) {
266
  }
267
  // edit page MetaBoxes
268
  if ( 'woo-feed_page_webappick-new-feed' === $screen->id || 'toplevel_page_webappick-manage-feeds' === $screen->id ) {
269
- add_meta_box( 'feed_merchant_info', 'Feed Merchant Info', 'woo_feed_merchant_info_metabox', null, 'side', 'default' );
 
 
 
 
 
270
  }
271
  /**
272
  * This action is documented in wp-admin/includes/meta-boxes.php
@@ -282,32 +475,40 @@ if ( ! function_exists( 'register_and_do_woo_feed_meta_boxes' ) ) {
282
  if ( ! function_exists( 'woo_feed_ajax_merchant_info' ) ) {
283
  add_action( 'wp_ajax_woo_feed_get_merchant_info', 'woo_feed_ajax_merchant_info' );
284
  function woo_feed_ajax_merchant_info() {
285
- if ( isset( $_REQUEST['nonce'] ) && wp_verify_nonce( $_REQUEST['nonce'], 'wpf_feed_nonce' ) ) {
286
- $provider = ( isset( $_REQUEST['provider'] ) && ! empty( $_REQUEST['provider'] ) ) ? sanitize_text_field( $_REQUEST['provider'] ) : '';
 
287
  $merchantInfo = new Woo_Feed_Merchant();
288
- $data = [];
289
- $na = esc_html__( 'N/A', 'woo-feed' );
290
  foreach ( $merchantInfo->getInfo( $provider ) as $k => $v ) {
291
- if ( $k == 'link' ) {
292
  /** @noinspection HtmlUnknownTarget */
293
- $data[ $k ] = empty( $v ) ? $na : sprintf( '<a href="%s" target="_blank">%s</a>', esc_url( $v ), esc_html__( 'Read Article', 'woo-feed' ) );
294
- } elseif ( $k == 'video' ) {
 
 
295
  /** @noinspection HtmlUnknownTarget */
296
- $data[ $k ] = empty( $v ) ? $na : sprintf( '<a href="%s" target="_blank">%s</a>', esc_url( $v ), esc_html__( 'Watch Now', 'woo-feed' ) );
297
- } elseif ( $k == 'feed_file_type' ) {
 
 
298
  if ( ! empty( $v ) ) {
299
- $v = array_map( function( $type ) {
300
  return strtoupper( $type );
301
- }, (array) $v );
 
302
  $data[ $k ] = esc_html( implode( ', ', $v ) );
303
  } else {
304
  $data[ $k ] = $na;
305
  }
306
- } elseif ( $k == 'doc' ) {
307
  $links = '';
308
  foreach ( $v as $label => $link ) {
309
  /** @noinspection HtmlUnknownTarget */
310
- $links .= sprintf( '<li><a href="%s" target="_blank">%s</a></li>', esc_url( $link ), esc_html( $label ) );
 
 
311
  }
312
  $data[ $k ] = empty( $links ) ? $na : $links;
313
  }
@@ -322,47 +523,66 @@ if ( ! function_exists( 'woo_feed_ajax_merchant_info' ) ) {
322
  if ( ! function_exists( 'woo_feed_merchant_info_metabox' ) ) {
323
  /**
324
  * Render Merchant Info Metabox
 
325
  * @param array $feedConfig
 
326
  * @return void
327
  */
328
  function woo_feed_merchant_info_metabox( $feedConfig ) {
329
- $provider = ( isset( $feedConfig['provider'] ) && ! empty( $feedConfig['provider'] ) ) ? $feedConfig['provider'] : '';
330
  $merchantInfo = new Woo_Feed_Merchant();
331
  ?>
332
  <span class="spinner"></span>
333
  <div class="merchant-infos">
334
  <?php foreach ( $merchantInfo->getInfo( $provider ) as $k => $v ) { ?>
335
  <div class="merchant-info-section <?php echo esc_attr( $k ); ?>">
336
- <?php if ( $k == 'link' ) { ?>
337
  <span class="dashicons dashicons-media-document" style="color: #82878c;" aria-hidden="true"></span>
338
  <span><?php esc_html_e( 'Feed Specification:', 'woo-feed' ) ?></span>
339
  <strong class="data"><?php
340
  /** @noinspection HtmlUnknownTarget */
341
- ( empty( $v ) ) ? esc_html_e( 'N/A', 'woo-feed' ) : printf( '<a href="%s" target="_blank">%s</a>', esc_url( $v ), esc_html__( 'Read Article', 'woo-feed' ) );
 
 
 
342
  ?></strong>
343
- <?php } elseif ( $k == 'video' ) { ?>
344
  <span class="dashicons dashicons-video-alt3" style="color: #82878c;" aria-hidden="true"></span>
345
  <span><?php esc_html_e( 'Video Documentation:', 'woo-feed' ) ?></span>
346
  <strong class="data"><?php
347
  /** @noinspection HtmlUnknownTarget */
348
- ( empty( $v ) ) ? esc_html_e( 'N/A', 'woo-feed' ) : printf( '<a href="%s" target="_blank">%s</a>', esc_url( $v ), esc_html__( 'Watch now', 'woo-feed' ) );
 
 
 
349
  ?></strong>
350
- <?php } elseif ( $k == 'feed_file_type' ) { ?>
351
  <span class="dashicons dashicons-media-text" style="color: #82878c;" aria-hidden="true"></span> <?php esc_html_e( 'Format Supported:', 'woo-feed' ) ?>
352
- <strong class="data"><?php echo ( empty( $v ) ) ? esc_html__( 'N/A', 'woo-feed' ) : esc_html( implode( ', ', array_map( function( $type ) {
353
- return strtoupper( $type );
354
- }, (array) $v ) ) ); ?></strong>
 
 
 
 
 
 
 
 
355
  <?php
356
- } elseif ( $k == 'doc' ) { ?>
357
  <span class="dashicons dashicons-editor-help" style="color: #82878c;" aria-hidden="true"></span>
358
  <span><?php esc_html_e( 'Support Docs:', 'woo-feed' ); ?></span>
359
  <ul class="data">
360
  <?php
361
- if ( empty( $v ) ) esc_html_e( 'N/A', 'woo-feed' );
362
- else {
 
363
  foreach ( $v as $label => $link ) {
364
  /** @noinspection HtmlUnknownTarget */
365
- printf( '<li><a href="%s" target="_blank">%s</a></li>', esc_url( $link ), esc_html( $label ) );
 
 
366
  }
367
  }
368
  ?>
@@ -375,8 +595,73 @@ if ( ! function_exists( 'woo_feed_merchant_info_metabox' ) ) {
375
  <?php
376
  }
377
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
378
 
379
- // Sanitization
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
380
  if ( ! function_exists( 'woo_feed_check_google_category' ) ) {
381
  /**
382
  * @param array $feedInfo
@@ -385,22 +670,23 @@ if ( ! function_exists( 'woo_feed_check_google_category' ) ) {
385
  */
386
  function woo_feed_check_google_category( $feedInfo ) {
387
  # Check Google Product Category for Google & Facebook Template and show message
388
- $checkCategory = isset( $feedInfo['feedrules']['mattributes'] ) ? $feedInfo['feedrules']['mattributes'] : [];
389
  $checkCategoryType = isset( $feedInfo['feedrules']['type'] ) ? $feedInfo['feedrules']['type'] : [];
390
- $merchant = isset( $feedInfo['feedrules']['provider'] ) ? $feedInfo['feedrules']['provider'] : [];
391
- $cat = "yes";
392
- if ( in_array($merchant,array( 'google', 'facebook' ) ) && in_array("current_category",$checkCategory) ) {
393
- $catKey = array_search('current_category',$checkCategory);
394
- if ( $checkCategoryType[ $catKey ] == "pattern" ) {
395
  $checkCategoryValue = $feedInfo['feedrules']['default'];
396
- }else {
397
  $checkCategoryValue = $feedInfo['feedrules']['attributes'];
398
  }
399
 
400
- if ( empty($checkCategoryValue[ $catKey ]) ) {
401
- $cat = "no";
402
  }
403
  }
 
404
  return $cat;
405
  }
406
  }
@@ -431,13 +717,16 @@ if ( ! function_exists( 'woo_feed_array_sanitize' ) ) {
431
  }
432
  }
433
  }
 
434
  return $newArray;
435
  }
436
  }
437
  if ( ! function_exists( 'woo_feed_sanitize_form_fields' ) ) {
438
  /**
439
  * Sanitize Form Fields ($_POST Array)
 
440
  * @param array $data
 
441
  * @return array
442
  */
443
  function woo_feed_sanitize_form_fields( $data ) {
@@ -451,17 +740,21 @@ if ( ! function_exists( 'woo_feed_sanitize_form_fields' ) ) {
451
  }
452
  $data[ $k ] = apply_filters( 'woo_feed_sanitize_form_field', $v, $k );
453
  }
 
454
  return $data;
455
  }
456
  }
457
  if ( ! function_exists( 'woo_feed_unique_feed_slug' ) ) {
458
  /**
459
  * Generate Unique slug for feed.
460
- * @see wp_unique_post_slug()
461
  * @param string $slug
462
  * @param string $prefix
463
- * @param int $feedId
 
464
  * @return string
 
 
465
  */
466
  function woo_feed_unique_feed_slug( $slug, $prefix = '', $feedId = null ) {
467
  global $wpdb;
@@ -469,65 +762,91 @@ if ( ! function_exists( 'woo_feed_unique_feed_slug' ) ) {
469
  $disallowed = array( 'siteurl', 'home', 'blogname', 'blogdescription', 'users_can_register', 'admin_email' );
470
  if ( $feedId && $feedId > 0 ) {
471
  $checkSql = "SELECT option_name FROM $wpdb->options WHERE option_name = %s AND option_id != %d LIMIT 1";
472
- $nameCheck = $wpdb->get_var( $wpdb->prepare( $checkSql, $prefix . $slug, $feedId ) );
473
  } else {
474
  $checkSql = "SELECT option_name FROM $wpdb->options WHERE option_name = %s LIMIT 1";
475
- $nameCheck = $wpdb->get_var( $wpdb->prepare( $checkSql, $prefix . $slug ) );
476
  }
 
477
  if ( $nameCheck || in_array( $slug, $disallowed ) ) {
478
  $suffix = 2;
479
  do {
480
- $altName = _truncate_post_slug( $slug, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
481
  if ( $feedId && $feedId > 0 ) {
482
- $nameCheck = $wpdb->get_var( $wpdb->prepare( $checkSql, $prefix . $altName, $feedId ) );
483
  } else {
484
- $nameCheck = $wpdb->get_var( $wpdb->prepare( $checkSql, $prefix . $altName ) );
485
  }
486
- $suffix++;
487
  } while ( $nameCheck );
488
  $slug = $altName;
489
  }
 
490
  return $slug;
491
  }
492
  }
493
  if ( ! function_exists( 'generate_unique_feed_file_name' ) ) {
494
  function generate_unique_feed_file_name( $filename, $type, $provider ) {
495
 
496
- $feedDir = woo_feed_get_file_dir( $provider, $type );
497
  $raw_filename = sanitize_title( $filename, '', 'save' );
498
  // check option name uniqueness ...
499
- $raw_filename = woo_feed_unique_feed_slug( $raw_filename, null );
500
  $raw_filename = sanitize_file_name( $raw_filename . '.' . $type );
501
  $raw_filename = wp_unique_filename( $feedDir, $raw_filename );
502
- $raw_filename = str_replace( '.' . $type , '', $raw_filename );
 
503
  return $raw_filename;
504
  }
505
  }
506
 
507
- // File process
 
 
 
 
 
 
 
 
 
 
 
 
508
  if ( ! function_exists( 'woo_feed_save_feed_config_data' ) ) {
509
  /**
510
  * Sanitize And Save Feed config data (array) to db (option table)
511
- * @param array $data data to be saved in db
512
- * @param null $fileName feed (file) name. optional, if empty or null name will be auto generated
513
- * @param bool $configOnly save only wf_config or both wf_config and wf_feed_. default is only wf_config
 
514
  *
515
  * @return bool|string return false if failed to update. return filename if success
516
  */
517
- function woo_feed_save_feed_config_data( $data, $fileName = null, $configOnly = true ) {
518
- if ( ! is_array( $data ) ) return false;
519
- if ( ! isset( $data['filename'], $data['feedType'], $data['provider'], $data['mattributes'] ) ) return false;
 
 
 
 
520
  // unnecessary form fields to remove
521
  $removables = [ 'closedpostboxesnonce', '_wpnonce', '_wp_http_referer', 'save_feed_config', 'edit-feed' ];
522
  foreach ( $removables as $removable ) {
523
- if ( isset( $data[ $removable ] ) ) unset( $data[ $removable ] );
 
 
524
  }
 
 
525
  // Sanitize Fields
526
  $data = woo_feed_sanitize_form_fields( $data );
527
- if ( empty( $fileName ) ) {
528
- $fileName = generate_unique_feed_file_name( $data['filename'], $data['feedType'], $data['provider'] );
 
 
529
  } else {
530
- $fileName = str_replace( [ 'wf_feed_', 'wf_config' ], '', $fileName );
531
  }
532
  /**
533
  * Before Updating Config to db
@@ -535,98 +854,160 @@ if ( ! function_exists( 'woo_feed_save_feed_config_data' ) ) {
535
  * @param array $config sanitized config
536
  * @param string $feed_option_name option name
537
  */
538
- do_action( 'woo_feed_before_update_config', $data, "wf_config" . $fileName );
539
  # Store Config
540
- $update = update_option( "wf_config" . $fileName, $data, false );
541
  // save if config update ok...
542
- if ( $update && $configOnly === false ) {
543
- $oldFeed = maybe_unserialize( get_option( "wf_feed_" . $fileName ) );
544
  $feedData = array(
545
  'feedrules' => $data,
546
- 'url' => woo_feed_get_file_url( $fileName, $data['provider'], $data['feedType'] ),
547
- 'last_updated' => date("Y-m-d H:i:s"),
548
- 'status' => isset( $oldFeed['status'] ) ? $oldFeed['status'] : 1,
 
549
  );
550
- $update = update_option( 'wf_feed_' . $fileName, maybe_serialize( $feedData ), false );
551
  }
 
552
  // return filename on success or update status
553
- return $update ? $fileName : $update;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
554
  }
555
  }
556
  if ( ! function_exists( 'woo_feed_get_file_url' ) ) {
557
  /**
558
  * Get Feed File URL
 
559
  * @param string $fileName
560
  * @param string $provider
561
  * @param string $type
562
  *
563
  * @return string
564
  */
565
- function woo_feed_get_file_url( $fileName, $provider, $type ) {
566
- $upload_dir = wp_upload_dir();
567
- return esc_url( sprintf( '%s/woo-feed/%s/%s/%s.%s', $upload_dir['baseurl'], $provider, $type, $fileName, $type ) );
568
- }
 
 
 
 
 
 
 
569
  }
570
  if ( ! function_exists( 'woo_feed_check_feed_file' ) ) {
571
  /**
572
  * Check if feed file exists
 
573
  * @param string $fileName
574
  * @param string $provider
575
  * @param string $type
576
  *
577
  * @return bool
578
  */
579
- function woo_feed_check_feed_file( $fileName, $provider, $type ) {
580
- $upload_dir = wp_upload_dir();
581
- return file_exists( sprintf( '%s/woo-feed/%s/%s/%s.%s', $upload_dir['basedir'], $provider, $type, $fileName, $type ) );
582
- }
 
 
 
 
 
 
583
  }
584
  if ( ! function_exists( 'woo_feed_get_file_dir' ) ) {
585
  /**
586
  * Get Feed Directory
 
587
  * @param string $provider
588
  * @param string $feedType
 
589
  * @return string
590
  */
591
  function woo_feed_get_file_dir( $provider, $feedType ) {
592
- $upload_dir = wp_upload_dir();
593
- $base = $upload_dir['basedir'];
594
- return $base . "/woo-feed/" . $provider . "/" . $feedType;
595
  }
596
  }
597
  if ( ! function_exists( 'woo_feed_save_batch_feed_info' ) ) {
598
  /**
599
  * Save Feed Batch Chunk
600
- * @param string $feedService
601
- * @param string $type
602
- * @param string $string
603
- * @param string $fileName
604
- * @param array $info
 
605
  *
606
  * @return bool
607
  */
608
  function woo_feed_save_batch_feed_info( $feedService, $type, $string, $fileName, $info ) {
609
-
610
- $upload_dir = wp_upload_dir();
611
- $base = $upload_dir['basedir'];
612
  $ext = $type;
613
- if ( $type == "csv" ) {
614
- $string = json_encode( $string );
615
- $ext = "json";
616
  }
617
- # Save File
618
- $path = $base . "/woo-feed/" . $feedService . "/" . $type;
619
- $file = $path . "/" . $fileName . "." . $ext;
620
- $save = new Woo_Feed_Savefile();
621
  $status = $save->saveFile( $path, $file, $string );
622
- // if( woo_feed_is_debugging_enabled() ) {
623
- // if( $status ) {
624
  // $message = sprintf( 'Batch chunk file (%s) saved.', $fileName );
625
  // } else {
626
  // $message = sprintf( 'Unable to save batch chunk file %s.', $fileName );
627
  // }
628
  // woo_feed_log_feed_process( $info['filename'], $message );
629
  // }
 
630
  return $status;
631
  }
632
  }
@@ -639,220 +1020,435 @@ if ( ! function_exists( 'woo_feed_get_batch_feed_info' ) ) {
639
  * @return bool|false|mixed|string
640
  */
641
  function woo_feed_get_batch_feed_info( $feedService, $type, $fileName ) {
642
- $upload_dir = wp_upload_dir();
643
- $base = $upload_dir['basedir'];
644
  $ext = $type;
645
- if ( $type == "csv" ) $ext = "json";
 
 
646
  # Save File
647
- $path = $base . "/woo-feed/" . $feedService . "/" . $type;
648
- $file = $path . "/" . $fileName . "." . $ext;
649
- if ( $type == "csv" && file_exists( $file ) ) {
650
- return (file_get_contents($file)) ? json_decode(file_get_contents($file),true) : false;
651
- }elseif ( file_exists( $file ) ) {
652
- return file_get_contents($file);
 
 
 
 
653
  }
 
654
  return false;
655
  }
656
  }
657
  if ( ! function_exists( 'woo_feed_unlink_tempFiles' ) ) {
658
  /**
659
  * Remove temporary feed files
660
- * @param array $files
 
 
 
 
661
  * @return bool
662
  */
663
- function woo_feed_unlink_tempFiles( $files ) {
 
 
 
 
 
664
  if ( ! empty( $files ) ) {
 
665
  foreach ( $files as $key => $file ) {
666
  if ( file_exists( $file ) ) {
667
- @unlink($file);
668
  }
669
  }
 
670
  return true;
671
  }
 
672
  return false;
673
  }
674
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
675
 
676
  // Mics..
677
  if ( ! function_exists( 'woo_feed_remove_query_args' ) ) {
678
  /**
679
  * Add more items to the removable query args array...
 
680
  * @param array $removable_query_args
681
  *
682
  * @return array
683
  */
684
- function woo_feed_remove_query_args( $removable_query_args ) {
685
- if ( isset( $_GET['page'] ) && 'webappick-manage-feeds' == $_GET['page'] ) {
686
- $removable_query_args[] = 'feed_created';
687
- $removable_query_args[] = 'feed_updated';
688
- $removable_query_args[] = 'feed_regenerate';
689
- $removable_query_args[] = 'feed_name';
690
- $removable_query_args[] = 'link';
691
- $removable_query_args[] = 'wpf_message';
692
- $removable_query_args[] = 'cat';
693
- $removable_query_args[] = 'schedule_updated';
694
- /** @noinspection SpellCheckingInspection */
695
- $removable_query_args[] = 'WPFP_WPML_CURLANG';
696
- }
697
- return $removable_query_args;
698
- }
 
 
 
 
699
  add_filter( 'removable_query_args', 'woo_feed_remove_query_args', 10, 1 );
700
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
701
 
702
- // Feed Functions
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
703
  if ( ! function_exists( 'woo_feed_get_field_output_type_options' ) ) {
704
  function woo_feed_get_field_output_type_options() {
705
- return apply_filters( 'woo_feed_field_output_options', [
706
- 1 => esc_html__( 'Default', 'woo-feed' ),
707
- 2 => esc_html__( 'Strip Tags', 'woo-feed' ),
708
- 3 => esc_html__( 'UTF-8 Encode', 'woo-feed' ),
709
- 4 => esc_html__( 'htmlentities', 'woo-feed' ),
710
- 5 => esc_html__( 'Integer', 'woo-feed' ),
711
- 6 => esc_html__( 'Price', 'woo-feed' ),
712
- 7 => esc_html__( 'Remove Space', 'woo-feed' ),
713
- 8 => esc_html__( 'CDATA', 'woo-feed' ),
714
- 9 => esc_html__( 'Remove Special Character', 'woo-feed' ),
715
- 10 => esc_html__( 'Remove ShortCodes', 'woo-feed' ),
716
- ] );
717
  }
718
  }
719
  if ( ! function_exists( 'woo_feed_get_schedule_interval_options' ) ) {
720
- function woo_feed_get_schedule_interval_options(){
721
- return apply_filters( 'woo_feed_schedule_interval_options', [
722
- WEEK_IN_SECONDS => esc_html__( '1 Week', 'woo-feed' ),
723
- DAY_IN_SECONDS => esc_html__( '24 Hours', 'woo-feed' ),
724
- 12 * HOUR_IN_SECONDS => esc_html__( '12 Hours', 'woo-feed' ),
725
- 6 * HOUR_IN_SECONDS => esc_html__( '6 Hours', 'woo-feed' ),
726
- HOUR_IN_SECONDS => esc_html__( '1 Hours', 'woo-feed' ),
727
- 15 * MINUTE_IN_SECONDS => esc_html__( '15 Minutes', 'woo-feed' ),
728
- ] );
 
 
 
 
 
 
729
  }
730
  }
731
  if ( ! function_exists( 'woo_feed_get_minimum_interval_option' ) ) {
732
- function woo_feed_get_minimum_interval_option(){
733
- $intervals = array_keys( woo_feed_get_schedule_interval_options() );
734
- if ( ! empty( $intervals ) ) return end( $intervals );
735
- return 15 * MINUTE_IN_SECONDS;
736
- }
 
 
 
737
  }
738
- if ( ! function_exists('woo_feed_stripInvalidXml' ) ) {
739
  /**
740
  * Remove non supported xml character
 
741
  * @param string $value
 
742
  * @return string
743
  */
744
  function woo_feed_stripInvalidXml( $value ) {
745
- $ret = "";
746
- if (empty($value)) return $ret;
747
- $length = strlen($value);
748
- for ( $i = 0; $i < $length; $i++ ) {
749
- $current = ord($value[ $i ]);
750
- if ( ($current == 0x9) || ($current == 0xA) || ($current == 0xD) || (($current >= 0x20) && ($current <= 0xD7FF)) || (($current >= 0xE000) && ($current <= 0xFFFD)) || (($current >= 0x10000) && ($current <= 0x10FFFF)) ) {
751
- $ret .= chr($current);
 
 
752
  } else {
753
- $ret .= "";
754
  }
755
  }
 
756
  return $ret;
757
  }
758
  }
759
- if ( ! function_exists('woo_feed_get_formatted_url' ) ) {
760
  /**
761
  * Get Formatted URL
 
762
  * @param string $url
763
  *
764
  * @return string
765
  */
766
- function woo_feed_get_formatted_url( $url = "" ) {
767
- if ( ! empty($url) ) {
768
- if ( substr(trim($url), 0, 4) === "http" || substr(trim($url), 0, 3) === "ftp" || substr(trim($url), 0, 4) === "sftp" ) {
769
- return rtrim($url, "/");
 
 
770
  } else {
771
  $base = get_site_url();
772
- $url = $base . $url;
773
- return rtrim($url, "/");
 
774
  }
775
  }
776
- return "";
 
777
  }
778
  }
779
- if ( ! function_exists('array_value_first' ) ) {
780
  /**
781
  * Get First Value of an array
782
- * @since 3.0.0
783
  * @param array $arr
 
784
  * @return mixed|null
 
785
  */
786
  function array_value_first( array $arr ) {
787
  foreach ( $arr as $key => $unused ) {
788
  return $unused;
789
  }
790
- return NULL;
 
791
  }
792
  }
793
- if ( ! function_exists('woo_feed_make_url_with_parameter' ) ) {
794
  /**
795
  * Make proper URL using parameters
 
796
  * @param string $output
797
  * @param string $suffix
 
798
  * @return string
799
  */
800
  function woo_feed_make_url_with_parameter( $output = '', $suffix = '' ) {
801
- if ( empty($output) || empty($suffix) ) {
802
  return $output;
803
  }
804
 
805
- $getParam = explode('?', $output);
806
  $URLParam = array();
807
- if ( isset($getParam[1]) ) {
808
- $URLParam = woo_feed_parse_string($getParam[1]);
809
  }
810
 
811
  $EXTRAParam = array();
812
- if ( ! empty($suffix) ) {
813
- $suffix = str_replace("?", "", $suffix);
814
- $EXTRAParam = woo_feed_parse_string($suffix);
815
  }
816
 
817
- $params = array_merge($URLParam, $EXTRAParam);
818
- if ( ! empty($params) && $output != "" ) {
819
- $params = http_build_query($params);
820
- $baseURL = isset($getParam) ? $getParam[0] : $output;
821
- $output = $baseURL . "?" . $params;
822
  }
823
 
824
  return $output;
825
  }
826
  }
827
- if ( ! function_exists('woo_feed_parse_string' ) ) {
828
  /**
829
  * Parse URL parameter
 
830
  * @param string $str
 
831
  * @return array
832
  */
833
- function woo_feed_parse_string( $str = "" ) {
834
 
835
  # result array
836
  $arr = array();
837
 
838
- if ( empty($str) ) {
839
  return $arr;
840
  }
841
 
842
  # split on outer delimiter
843
- $pairs = explode('&', $str);
844
 
845
- if ( ! empty($pairs) ) {
846
 
847
  # loop through each pair
848
  foreach ( $pairs as $i ) {
849
  # split into name and value
850
- list($name, $value) = explode('=', $i, 2);
851
 
852
  # if name already exists
853
- if ( isset($arr[ $name ]) ) {
854
  # stick multiple values into an array
855
- if ( is_array($arr[ $name ]) ) {
856
  $arr[ $name ][] = $value;
857
  } else {
858
  $arr[ $name ] = array( $arr[ $name ], $value );
@@ -862,8 +1458,8 @@ if ( ! function_exists('woo_feed_parse_string' ) ) {
862
  $arr[ $name ] = $value;
863
  }
864
  }
865
- } elseif ( ! empty($str) ) {
866
- list($name, $value) = explode('=', $str, 2);
867
  $arr[ $name ] = $value;
868
  }
869
 
@@ -871,305 +1467,139 @@ if ( ! function_exists('woo_feed_parse_string' ) ) {
871
  return $arr;
872
  }
873
  }
874
- if ( ! function_exists('woo_feed_replace_to_merchant_attribute' ) ) {
875
  /**
876
  * Parse URL parameter
 
877
  * @param string $pluginAttribute
878
  * @param string $merchant
879
  * @param string feedType CSV XML TXT
 
880
  * @return string
881
  */
882
- function woo_feed_replace_to_merchant_attribute( $pluginAttribute,$merchant,$feedType ) {
883
- $attributeClass = new Woo_Feed_Default_Attributes();
884
- $merchantAttributes = "";
885
- if ( $merchant == "google" && $feedType == 'xml' ) {
886
  $merchantAttributes = $attributeClass->googleXMLAttribute;
887
- }elseif ( $merchant == "google" && ($feedType == 'csv' || $feedType == 'txt' ) ) {
888
  $merchantAttributes = $attributeClass->googleCSVTXTAttribute;
889
- }elseif ( $merchant == "facebook" && $feedType == 'xml' ) {
890
  $merchantAttributes = $attributeClass->facebookXMLAttribute;
891
- }elseif ( $merchant == "facebook" && ($feedType == 'csv' || $feedType == 'txt' ) ) {
892
  $merchantAttributes = $attributeClass->facebookCSVTXTAttribute;
893
- }elseif ( $merchant == "pinterest" && $feedType == 'xml' ) {
894
  $merchantAttributes = $attributeClass->pinterestXMLAttribute;
895
- }elseif ( $merchant == "pinterest" && ($feedType == 'csv' || $feedType == 'txt' ) ) {
896
  $merchantAttributes = $attributeClass->pinterestCSVTXTAttribute;
897
  }
898
 
899
- if ( ! empty($merchantAttributes) && array_key_exists($pluginAttribute,$merchantAttributes) ) {
900
  return $merchantAttributes[ $pluginAttribute ][0];
901
  }
902
 
903
  return $pluginAttribute;
904
  }
905
  }
906
- if ( ! function_exists('woo_feed_add_cdata' ) ) {
907
  /**
908
  * Parse URL parameter
 
909
  * @param string $pluginAttribute
910
  * @param string $attributeValue
911
  * @param string $merchant
 
912
  * @return string
913
  */
914
- function woo_feed_add_cdata( $pluginAttribute,$attributeValue,$merchant ) {
915
- if ( strpos($attributeValue, "<![CDATA[") !== false ) {
916
  return "$attributeValue";
917
  }
918
 
919
- $attributeClass = new Woo_Feed_Default_Attributes();
920
- $merchantAttributes = "";
921
- if ( $merchant == "google" ) {
922
  $merchantAttributes = $attributeClass->googleXMLAttribute;
923
- }elseif ( $merchant == "facebook" ) {
924
  $merchantAttributes = $attributeClass->facebookXMLAttribute;
925
- }elseif ( $merchant == "pinterest" ) {
926
  $merchantAttributes = $attributeClass->pinterestXMLAttribute;
927
  }
928
 
929
- if ( ! empty($merchantAttributes) && array_key_exists($pluginAttribute,$merchantAttributes) ) {
930
- if ( $merchantAttributes[ $pluginAttribute ][1] == 'true' ) {
931
- return "<![CDATA[$attributeValue]]>";
932
- }else {
933
  return "$attributeValue";
934
  }
935
- }elseif ( strpos($attributeValue, "&") !== false ||
936
- substr(trim($attributeValue), 0, 4) == "http" ) {
937
  return "<![CDATA[$attributeValue]]>";
938
- }else {
939
  return "$attributeValue";
940
  }
941
  }
942
  }
943
 
944
- // Log helpers
945
- if ( ! function_exists( 'woo_feed_is_debugging_enabled' ) ) {
946
- function woo_feed_is_debugging_enabled() {
947
- return get_option( 'woo_feed_enable_error_debugging', false ) === 'on';
948
- }
949
- }
950
- if ( ! function_exists( 'woo_feed_get_logger' ) ) {
951
  /**
952
- * Get The logger.
953
  *
954
- * Example:
955
- * woo_feed_get_logger()->debug( 'Test log', [ 'source' => 'test-debug' ] );
 
956
  *
957
- * @since 3.2.1
958
- *
959
- * @return WC_Logger
960
  */
961
- function woo_feed_get_logger() {
962
- static $logger = null;
963
- if ( null !== $logger && is_a( $logger, 'WC_Logger' ) ) {
964
- return $logger;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
965
  }
966
- $logger = new WC_Logger( [ new Woo_Feed_Log_Handler_File() ] );
967
 
968
- return $logger;
969
- }
970
- }
971
- if ( ! function_exists( 'woo_feed_log_errors_at_shutdown' ) ) {
972
- /**
973
- * Shutdown log handler
974
- * @since 3.2.1
975
- * @return void
976
- */
977
- function woo_feed_log_errors_at_shutdown(){
978
- $error = error_get_last();
979
- if ( $error && in_array( $error['type'], array( E_ERROR, E_PARSE, E_COMPILE_ERROR, E_USER_ERROR, E_RECOVERABLE_ERROR ), true ) ) {
980
- /* translators: 1: error message 2: file name and path 3: line number */
981
- $message = sprintf( __( '%1$s in %2$s on line %3$s', 'woo-feed' ), $error['message'], $error['file'], $error['line'] );
982
- woo_feed_log_fatal_error( $message );
983
- do_action( 'woo_feed_shutdown_error', $error );
984
- }
985
- }
986
- }
987
- if ( ! function_exists( 'woo_feed_log' ) ) {
988
- /**
989
- * Write message to log file.
990
- * Write log message if debugging is enable
991
- *
992
- * @since 3.2.1
993
- *
994
- * @param string $source will be use for log file name.
995
- * @param string $message Log message.
996
- * @param string $level One of the following:
997
- * 'emergency': System is unusable.
998
- * 'alert': Action must be taken immediately.
999
- * 'critical': Critical conditions.
1000
- * 'error': Error conditions.
1001
- * 'warning': Warning conditions.
1002
- * 'notice': Normal but significant condition.
1003
- * 'info': Informational messages.
1004
- * 'debug': Debug-level messages.
1005
- * @param mixed $data Extra data for the log handler.
1006
- * @param bool $force_log ignore debugging settings
1007
- * @param bool $wc_log log data in wc-logs directory
1008
- *
1009
- * @return void
1010
- */
1011
- function woo_feed_log( $source, $message, $level = 'debug', $data = null, $force_log = false, $wc_log = false ) {
1012
- if ( woo_feed_is_debugging_enabled() || $force_log === true ) {
1013
- if ( ! in_array( $level, [
1014
- 'emergency',
1015
- 'alert',
1016
- 'critical',
1017
- 'critical',
1018
- 'error',
1019
- 'warning',
1020
- 'notice',
1021
- 'info',
1022
- 'debug',
1023
- ] ) ) {
1024
- return;
1025
- }
1026
- $context = [ 'source' => $source ];
1027
- if ( is_array( $data ) ) {
1028
- if ( isset( $data['source'] ) ) {
1029
- unset( $data['source'] );
1030
- }
1031
- $context = array_merge( $context, $data );
1032
- } else {
1033
- $context['data'] = $data;
1034
- }
1035
- $loggers = [ woo_feed_get_logger() ];
1036
- if ( $wc_log === true ) {
1037
- $loggers[] = wc_get_logger();
1038
- }
1039
- foreach ( $loggers as $logger ) {
1040
- if ( is_callable( [ $logger, $level ] ) ) {
1041
- $logger->$level( $message . PHP_EOL, $context );
1042
- }
1043
- }
1044
- }
1045
- }
1046
- }
1047
- if ( ! function_exists( 'woo_feed_log_fatal_error' ) ) {
1048
- /**
1049
- * Log Fatal Errors in both wc-logs and woo-feed/logs
1050
- *
1051
- * @param string $message The log message.
1052
- * @param mixed $data Extra data for the log handler.
1053
- */
1054
- function woo_feed_log_fatal_error( $message, $data = null ) {
1055
- // woocommerce use 'fatal-errors' as log handler...
1056
- // make no conflicts with woocommerce fatal-errors logs
1057
- woo_feed_log( 'woo-feed-fatal-errors', $message, 'critical', $data, true, true );
1058
- }
1059
- }
1060
- if ( ! function_exists( 'woo_feed_log_debug_message' ) ) {
1061
- /**
1062
- * Log Fatal Errors in both wc-logs and woo-feed/logs
1063
- *
1064
- * @param string $message The log message.
1065
- * @param mixed $data Extra data for the log handler.
1066
- */
1067
- function woo_feed_log_debug_message( $message, $data = null ) {
1068
- // woocommerce use 'fatal-errors' as log handler...
1069
- // make no conflicts with woocommerce fatal-errors logs
1070
- woo_feed_log( 'woo-feed-fatal-errors', $message, 'debug', $data, true, true );
1071
- }
1072
- }
1073
- if ( ! function_exists( 'woo_feed_delete_log' ) ) {
1074
- /**
1075
- * Delete Log file by source or handle name
1076
- *
1077
- * @param string $source log source or handle name
1078
- * @param bool $handle use source as handle
1079
- *
1080
- * @return bool
1081
- */
1082
- function woo_feed_delete_log( $source, $handle = false ) {
1083
- try {
1084
- if ( $source == 'woo-feed-fatal-errors' ) {
1085
- // fatal error are also logged in wc-logs dir.
1086
- if ( class_exists( 'WC_Log_Handler_File', false ) ) {
1087
- $log_handler = new WC_Log_Handler_File();
1088
- $log_handler->remove( $handle == false ? WC_Log_Handler_File::get_log_file_name( $source ) : $source );
1089
- }
1090
- }
1091
- $feed_log_handler = new Woo_Feed_Log_Handler_File();
1092
- return $feed_log_handler->remove( $handle == false ? Woo_Feed_Log_Handler_File::get_log_file_name( $source ) : $source );
1093
- } catch ( Exception $e ) {
1094
- return false;
1095
- }
1096
- }
1097
- }
1098
- if ( ! function_exists( 'woo_feed_delete_all_logs' ) ) {
1099
- function woo_feed_delete_all_logs() {
1100
- // delete the fatal error log
1101
- woo_feed_delete_log( 'woo-feed-fatal-errors' );
1102
- // get all logs
1103
- $logs = Woo_Feed_Log_Handler_File::get_log_files();
1104
- foreach ( array_values( $logs ) as $log ) {
1105
- woo_feed_delete_log( $log, true );
1106
- }
1107
- }
1108
- }
1109
- if ( ! function_exists( 'woo_feed_log_feed_process' ) ) {
1110
- /**
1111
- * Log Feed Generation Progress to individual log file.
1112
- *
1113
- * @since 3.2.1
1114
- *
1115
- * @param string $feed_name Feed name, will be use for log file name.
1116
- * @param string $message Log message.
1117
- * @param mixed $data Extra data for the log handler.
1118
- * @param bool $force_log ignore debugging settings
1119
- *
1120
- * @return void
1121
- */
1122
- function woo_feed_log_feed_process( $feed_name, $message, $data = null, $force_log = false ) {
1123
- woo_feed_log( $feed_name, $message, 'debug', $data, $force_log, false );
1124
  }
1125
  }
1126
 
1127
  // Hooks on feed generating process...
1128
  if ( ! function_exists( 'woo_feed_apply_hooks_before_product_loop' ) ) {
1129
- add_action( 'woo_feed_before_product_loop', 'woo_feed_apply_hooks_before_product_loop', 10, 1 );
1130
  /**
1131
  * Apply Hooks Before Looping through ProductIds
 
1132
  * @param array $feedConfig
1133
  */
1134
  function woo_feed_apply_hooks_before_product_loop( $feedConfig ) {
1135
- // Tax will be the first things to taken care of
1136
  add_filter( 'woocommerce_get_tax_location', 'woo_feed_apply_tax_location_data', 10, 3 );
1137
  }
1138
  }
 
1139
  if ( ! function_exists( 'woo_feed_remove_hooks_before_product_loop' ) ) {
1140
- add_action( 'woo_feed_after_product_loop', 'woo_feed_remove_hooks_before_product_loop', 10, 1 );
1141
  /**
1142
  * Remove Applied Hooks Looping through ProductIds
1143
- * @see woo_feed_apply_hooks_before_product_loop
1144
  * @param array $feedConfig the feed array.
 
 
1145
  */
1146
  function woo_feed_remove_hooks_before_product_loop( $feedConfig ) {
1147
  remove_filter( 'woocommerce_get_tax_location', 'woo_feed_apply_tax_location_data', 10 );
1148
  }
1149
  }
1150
 
1151
- // Price And Tax.
1152
- if ( ! function_exists( 'woo_feed_apply_tax_location_data' ) ) {
1153
- /**
1154
- * Filter and Change Location data for tax calculation
1155
- *
1156
- * @param array $location Location array.
1157
- * @param string $tax_class Tax class.
1158
- * @param WC_Customer $customer WooCommerce Customer Object.
1159
- *
1160
- * @return array
1161
- */
1162
- function woo_feed_apply_tax_location_data( $location, $tax_class, $customer ) {
1163
- // @TODO use filter. add tab in feed editor so user can set custom settings.
1164
- // @TODO tab should not list all country and cities. it only list available tax settings and user can just select one.
1165
- // @TODO then it will extract the location data from it to use here.
1166
- // @TODO with extra input for static tax rate input from user, which will override all other tax setting for the feed.
1167
- return [
1168
- WC()->countries->get_base_country(),
1169
- WC()->countries->get_base_state(),
1170
- WC()->countries->get_base_postcode(),
1171
- WC()->countries->get_base_city(),
1172
- ];
1173
- }
1174
- }
1175
- // End of file helper.php
1
+ <?php /** @noinspection PhpStatementHasEmptyBodyInspection, PhpUnusedLocalVariableInspection, PhpUnusedParameterInspection, PhpIncludeInspection */
2
  /**
3
  * Helper Functions
4
  * @package WooFeed
8
  * @author KD <mhamudul.hk@gmail.com>
9
  * @copyright WebAppick
10
  */
11
+
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ die(); // Silence...
14
+ }
15
+ /** @define "WOO_FEED_FREE_ADMIN_PATH" "./../admin/" */ // phpcs:ignore
16
 
17
  if ( ! function_exists( 'woo_feed_maybe_define_constant' ) ) {
18
  /**
19
  * Define a constant if it is not already defined.
20
  *
21
+ * @param string $name Constant name.
22
+ * @param mixed $value Value.
 
23
  *
24
  * @return void
25
+ * @since 3.2.1
26
+ *
27
  */
28
  function woo_feed_maybe_define_constant( $name, $value ) {
29
+ // phpcs:disable
30
  if ( ! defined( $name ) ) {
31
  define( $name, $value );
32
  }
33
+ // phpcs:enable
34
  }
35
  }
36
  if ( ! function_exists( 'woo_feed_doing_it_wrong' ) ) {
37
  /**
38
  * Wrapper for _doing_it_wrong.
39
  *
 
40
  * @param string $function Function used.
41
  * @param string $message Message to log.
42
  * @param string $version Version the message was added in.
43
  *
44
  * @return void
45
+ * @since 3.2.1
46
+ *
47
  */
48
  function woo_feed_doing_it_wrong( $function, $message, $version ) {
49
+ // phpcs:disable
50
  $message .= ' Backtrace: ' . wp_debug_backtrace_summary();
51
 
52
  if ( is_ajax() || WC()->is_rest_api_request() ) {
55
  } else {
56
  _doing_it_wrong( $function, $message, $version );
57
  }
58
+ // phpcs:enable
59
  }
60
  }
61
  if ( ! function_exists( 'is_ajax' ) ) {
69
  return function_exists( 'wp_doing_ajax' ) ? wp_doing_ajax() : defined( 'DOING_AJAX' );
70
  }
71
  }
72
+ if ( ! function_exists( 'woo_feed_is_plugin_active' ) ) {
73
  /**
74
  * Determines whether a plugin is active.
75
+ *
 
76
  * @param string $plugin Path to the plugin file relative to the plugins directory.
77
+ *
78
  * @return bool True, if in the active plugins list. False, not in the list.
79
+ * @since 3.1.41
80
+ * @see is_plugin_active()
81
+ *
82
  */
83
+ function woo_feed_is_plugin_active( $plugin ) {
84
+ if ( ! function_exists( 'is_plugin_active' ) ) {
85
+ include_once ABSPATH . 'wp-admin/includes/plugin.php';
86
+ }
87
+
88
  return is_plugin_active( $plugin );
89
  }
90
  }
91
  if ( ! function_exists( 'wooFeed_is_plugin_inactive' ) ) {
92
  /**
93
  * Determines whether the plugin is inactive.
 
 
94
  *
95
  * @param string $plugin Path to the plugin file relative to the plugins directory.
96
+ *
97
  * @return bool True if inactive. False if active.
98
+ * @since 3.1.41
99
+ * @see wooFeed_is_plugin_inactive()
100
+ *
101
  */
102
  function wooFeed_is_plugin_inactive( $plugin ) {
103
+ return ! woo_feed_is_plugin_active( $plugin );
104
  }
105
  }
106
  if ( ! function_exists( 'wooFeed_deactivate_plugins' ) ) {
107
  /**
108
  * Deactivate a single plugin or multiple plugins.
109
  * Wrapper for core deactivate_plugins() function
110
+ *
111
  * @param string|array $plugins Single plugin or list of plugins to deactivate.
112
  * @param bool $silent Prevent calling deactivation hooks. Default is false.
113
  * @param mixed $network_wide Whether to deactivate the plugin for all sites in the network.
114
+ *
115
  * @return void
116
+ * @see deactivate_plugins()
117
+ *
118
  */
119
+ function wooFeed_Deactivate_plugins( $plugins, $silent = false, $network_wide = null ) {
120
+ if ( ! function_exists( 'deactivate_plugins' ) ) {
121
+ require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
122
+ }
123
  deactivate_plugins( $plugins, $silent, $network_wide );
124
  }
125
  }
126
  if ( ! function_exists( 'wooFeed_is_supported_php' ) ) {
127
  /**
128
  * Check if server php version meet minimum requirement
 
129
  * @return bool
130
+ * @since 3.1.41
131
  */
132
+ function wooFeed_is_supported_php() {
133
  // PHP version need to be => WOO_FEED_MIN_PHP_VERSION
134
  return ! version_compare( PHP_VERSION, WOO_FEED_MIN_PHP_VERSION, '<' );
135
  }
136
  }
137
  if ( ! function_exists( 'wooFeed_check_WC' ) ) {
138
+ function wooFeed_check_WC() {
139
  return class_exists( 'WooCommerce', false );
140
  }
141
  }
148
  if ( ! function_exists( 'woo_feed_wc_version_check' ) ) {
149
  /**
150
  * Check WooCommerce Version
151
+ *
152
  * @param string $version
153
+ *
154
  * @return bool
155
  */
156
  function woo_feed_wc_version_check( $version = '3.0' ) {
157
+ if ( ! function_exists( 'get_plugins' ) ) {
158
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
159
+ }
 
160
  $plugins = get_plugins();
161
+ if ( array_key_exists( 'woocommerce/woocommerce.php', $plugins ) ) {
162
  $currentVersion = $plugins['woocommerce/woocommerce.php']['Version'];
163
  if ( version_compare( $currentVersion, $version, ">=" ) ) {
164
  return true;
165
  }
166
  }
167
+
168
  return false;
169
  }
170
  }
171
  if ( ! function_exists( 'woo_feed_wpml_version_check' ) ) {
172
  /**
173
  * Check WooCommerce Version
174
+ *
175
  * @param string $version
176
+ *
177
  * @return bool
178
  */
179
  function woo_feed_wpml_version_check( $version = '3.2' ) {
183
  return true;
184
  }
185
  }
186
+
187
  return false;
188
  }
189
  }
191
  /**
192
  * Display Admin Messages
193
  * @hooked admin_notices
 
194
  * @return void
195
+ * @since 3.1.41
196
  */
197
+ function wooFeed_Admin_Notices() {
198
  //@TODO Refactor this function with admin message class
199
  // WC Missing Notice..
200
  if ( ! wooFeed_check_WC() ) {
201
  $plugin_url = self_admin_url( 'plugin-install.php?s=woocommerce&tab=search&type=term' );
202
  /** @noinspection HtmlUnknownTarget */
203
+ $plugin_url = sprintf( '<a href="%s">%s</a>', $plugin_url, esc_html__( 'WooCommerce', 'woo-feed' ) );
204
  $plugin_name = sprintf( '<code>%s</code>', esc_html__( 'WooCommerce Product Feed', 'woo-feed' ) );
205
+ $wc_name = sprintf( '<code>%s</code>', esc_html__( 'WooCommerce', 'woo-feed' ) );
206
+ /* translators: 1: this plugin name, 2: required plugin name, 3: required plugin name and installation url */
207
+ $message = sprintf( esc_html__( '%1$s requires %2$s to be installed and active. You can installed/activate %3$s here.',
208
+ 'woo-feed' ),
209
+ $plugin_name,
210
+ $wc_name,
211
+ $plugin_url );
212
+ printf( '<div class="error"><p><strong>%1$s</strong></p></div>', $message ); // phpcs:ignore
213
  }
214
  if ( wooFeed_check_WC() && ! wooFeed_is_WC_supported() ) {
215
  $plugin_url = self_admin_url( 'plugin-install.php?s=woocommerce&tab=search&type=term' );
216
+ $wcVersion = defined( 'WC_VERSION' ) ? '<code>' . WC_VERSION . '</code>' : '<code>UNKNOWN</code>';
217
+ $minVersion = '<code>' . WOO_FEED_MIN_WC_VERSION . '</code>';
218
  /** @noinspection HtmlUnknownTarget */
219
+ $plugin_url = sprintf( '<a href="%s">%s</a>', $plugin_url, esc_html__( 'WooCommerce', 'woo-feed' ) );
220
  $plugin_name = sprintf( '<code>%s</code>', esc_html__( 'WooCommerce Product Feed', 'woo-feed' ) );
221
+ $wc_name = sprintf( '<code>%s</code>', esc_html__( 'WooCommerce', 'woo-feed' ) );
222
+ /* translators: 1: this plugin name, 2: required plugin name, 3: required plugin required version, 4: required plugin current version, 5: required plugin update url and name */
223
+ $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',
224
+ 'woo-feed' ),
225
+ $plugin_name,
226
+ $wc_name,
227
+ $minVersion,
228
+ $wcVersion,
229
+ $plugin_url );
230
+ printf( '<div class="error"><p><strong>%1$s</strong></p></div>', $message ); // phpcs:ignore
231
  }
232
  }
233
  }
238
  * @return bool
239
  */
240
  function checkFTP_connection() {
241
+ return ( extension_loaded( 'ftp' ) || function_exists( 'ftp_connect' ) );
242
  }
243
  }
244
  if ( ! function_exists( 'checkSFTP_connection' ) ) {
248
  * @return bool
249
  */
250
  function checkSFTP_connection() {
251
+ return ( extension_loaded( 'ssh2' ) || function_exists( 'ssh2_connect' ) );
252
  }
253
  }
254
  if ( ! function_exists( 'array_splice_assoc' ) ) {
255
  /**
256
  * Array Splice Associative Array
257
  * @see https://www.php.net/manual/en/function.array-splice.php#111204
258
+ *
259
  * @param array $input
260
+ * @param string|int $offset
261
+ * @param string|int $length
262
  * @param array $replacement
263
  *
264
  * @return array
265
  */
266
  function array_splice_assoc( $input, $offset, $length, $replacement ) {
267
  $replacement = (array) $replacement;
268
+ $key_indices = array_flip( array_keys( $input ) );
269
+ if ( isset( $input[ $offset ] ) && is_string( $offset ) ) {
270
+ $offset = $key_indices[ $offset ] + 1;
271
  }
272
+ if ( isset( $input[ $length ] ) && is_string( $length ) ) {
273
  $length = $key_indices[ $length ] - $offset;
274
  }
275
 
276
+ $input = array_slice( $input, 0, $offset, true ) + $replacement + array_slice( $input,
277
+ $offset + $length,
278
+ null,
279
+ true );
280
+
281
  return $input;
282
  }
283
  }
284
+ if ( ! function_exists( 'woo_feed_get_merchant_class' ) ) {
285
+ /**
286
+ * @param string $provider
287
+ *
288
+ * @return string
289
+ */
290
+ function woo_feed_get_merchant_class( $provider ) {
291
+ if ( in_array( $provider, [ 'google', 'adroll', 'smartly.io' ] ) ) {
292
+ return 'Woo_Feed_Google';
293
+ } elseif ( 'pinterest' == $provider ) {
294
+ return 'Woo_Feed_Pinterest';
295
+ } elseif ( 'facebook' == $provider ) {
296
+ return 'Woo_Feed_Facebook';
297
+ } elseif ( strpos( $provider, 'amazon' ) !== false ) {
298
+ return 'Woo_Feed_Amazon';
299
+ } elseif ( in_array( $provider, woo_feed_get_custom2_merchant() ) ) {
300
+ return 'Woo_Feed_Custom_XML';
301
+ } else {
302
+ return 'Woo_Feed_Custom';
303
+ }
304
+ }
305
+ }
306
+ if ( ! function_exists( 'woo_feed_handle_file_transfer' ) ) {
307
+ /**
308
+ * Transfer file as per ftp config
309
+ *
310
+ * @param string $fileFrom
311
+ * @param string $fileTo
312
+ * @param array $info
313
+ *
314
+ * @return bool
315
+ */
316
+ function woo_feed_handle_file_transfer( $fileFrom, $fileTo, $info ) {
317
+ try {
318
+ // Upload file to ftp server.
319
+ if ( 1 == (int) $info['ftpenabled'] ) {
320
+ if ( ! file_exists( $fileFrom ) ) {
321
+ // woo_feed_log_feed_process( $info['filename'], 'Unable to process file transfer request. File does not exists.' );
322
+ return false;
323
+ }
324
+ $ftpHost = sanitize_text_field( $info['ftphost'] );
325
+ $ftp_user = sanitize_text_field( $info['ftpuser'] );
326
+ $ftp_password = sanitize_text_field( $info['ftppassword'] );
327
+ $ftpPath = trailingslashit( untrailingslashit( sanitize_text_field( $info['ftppath'] ) ) );
328
+ $ftporsftp = isset( $info['ftporsftp'] ) ? sanitize_text_field( $info['ftporsftp'] ) : 'ftp';
329
+ $ftp_port = isset( $info['ftpport'] ) && ! empty( $info['ftpport'] ) ? absint( $info['ftpport'] ) : 21;
330
+ // woo_feed_log_feed_process( $info['filename'], sprintf( 'Uploading Feed file via %s.', $ftporsftp ) );
331
+ if ( 'ftp' == $ftporsftp ) {
332
+ $ftp = new FTPClient();
333
+ if ( $ftp->connect( $ftpHost, $ftp_user, $ftp_password, false, $ftp_port ) ) {
334
+ return $ftp->upload_file( $fileFrom, $ftpPath . $fileTo );
335
+ }
336
+ } elseif ( 'sftp' == $ftporsftp ) {
337
+ $sftp = new SFTPConnection( $ftpHost, $ftp_port );
338
+ $sftp->login( $ftp_user, $ftp_password );
339
+
340
+ return $sftp->upload_file( $fileFrom, $fileTo, $ftpPath );
341
+ }
342
+ }
343
+
344
+ return false;
345
+ } catch ( Exception $e ) {
346
+ // $message = 'Error Uploading Feed Via ' . $ftporsftp . PHP_EOL . 'Caught Exception :: ' . $e->getMessage();
347
+ // woo_feed_log( $info['filename'], $message, 'critical', $e, true );
348
+ // woo_feed_log_fatal_error( $message, $e );
349
+ return false;
350
+ }
351
+ }
352
+ }
353
+ if ( ! function_exists( 'woo_feed_get_file_types' ) ) {
354
+ function woo_feed_get_file_types() {
355
+ return array(
356
+ 'xml' => 'XML',
357
+ 'csv' => 'CSV',
358
+ 'txt' => 'TXT',
359
+ );
360
+ }
361
+ }
362
 
363
+ // The Editor.
364
+ if ( ! function_exists( 'woo_feed_get_custom2_merchant' ) ) {
365
  /**
366
+ * Get Merchant list that are allowed on Custom2 Template
367
+ * @return array
368
+ */
369
+ function woo_feed_get_custom2_merchant() {
370
+ return array( 'custom2', 'admarkt', 'yandex_xml' );
371
+ }
372
+ }
373
+ if ( ! function_exists( 'woo_feed_parse_feed_rules' ) ) {
374
+ /**
375
+ * Parse Feed Config/Rules to make sure that necessary array keys are exists
376
+ * this will reduce the uses of isset() checking
377
  *
378
+ * @param array $rules
379
  *
380
+ * @return array
381
+ */
382
+ function woo_feed_parse_feed_rules( $rules = [] ) {
383
+ if ( empty( $rules ) ) {
384
+ $rules = [];
385
+ }
386
+ $defaults = [
387
+ 'provider' => '',
388
+ 'filename' => '',
389
+ 'feedType' => '',
390
+ 'ftpenabled' => 0,
391
+ 'ftporsftp' => 'ftp',
392
+ 'ftphost' => '',
393
+ 'ftpport' => '21',
394
+ 'ftpuser' => '',
395
+ 'ftppassword' => '',
396
+ 'ftppath' => '',
397
+ 'is_variations' => 'n',
398
+ 'variable_price' => 'first',
399
+ 'variable_quantity' => 'first',
400
+ 'feedLanguage' => apply_filters( 'wpml_current_language', null ),
401
+ 'feedCurrency' => get_woocommerce_currency(),
402
+ 'delimiter' => ',',
403
+ 'enclosure' => 'double',
404
+ 'extraHeader' => '',
405
+ 'vendors' => [],
406
+ // filters tab
407
+ 'composite_price' => '',
408
+ 'product_ids' => '',
409
+ 'categories' => [],
410
+ 'post_status' => [ 'publish' ],
411
+ 'filter_mode' => [],
412
+ 'is_outOfStock' => 'n',
413
+ 'product_visibility' => 0,
414
+ // include hidden ? 1 yes 0 no
415
+ 'outofstock_visibility' => 0,
416
+ // override wc global option for out-of-stock product hidden from catalog? 1 yes 0 no
417
+ 'ptitle_show' => '',
418
+ 'decimal_separator' => wc_get_price_decimal_separator(),
419
+ 'thousand_separator' => wc_get_price_thousand_separator(),
420
+ 'decimals' => wc_get_price_decimals(),
421
+ ];
422
+ $rules = wp_parse_args( $rules, $defaults );
423
+ $rules['filter_mode'] = wp_parse_args( $rules['filter_mode'],
424
+ [
425
+ 'product_ids' => 'include',
426
+ 'categories' => 'include',
427
+ 'post_status' => 'include',
428
+ ] );
429
+
430
+ return apply_filters( 'woo_feed_parsed_rules', $rules );
431
+ }
432
+ }
433
+ if ( ! function_exists( 'register_and_do_woo_feed_meta_boxes' ) ) {
434
+ /**
435
+ * Registers the default Feed Editor MetaBoxes, and runs the `do_meta_boxes` actions.
436
  *
437
+ * @param string|WP_Screen $screen Screen identifier. If you have used add_menu_page() or
438
  * add_submenu_page() to create a new screen (and hence screen_id)
439
  * make sure your menu slug conforms to the limits of sanitize_key()
440
  * otherwise the 'screen' menu may not correctly render on your page.
441
+ * @param array $feedRules current feed being processed.
442
+ *
443
  * @return void
444
+ * @see register_and_do_post_meta_boxes()
445
+ *
446
+ * @since 3.2.6
447
+ *
448
  */
449
  function register_and_do_woo_feed_meta_boxes( $screen, $feedRules = array() ) {
450
  if ( empty( $screen ) ) {
454
  }
455
  // edit page MetaBoxes
456
  if ( 'woo-feed_page_webappick-new-feed' === $screen->id || 'toplevel_page_webappick-manage-feeds' === $screen->id ) {
457
+ add_meta_box( 'feed_merchant_info',
458
+ 'Feed Merchant Info',
459
+ 'woo_feed_merchant_info_metabox',
460
+ null,
461
+ 'side',
462
+ 'default' );
463
  }
464
  /**
465
  * This action is documented in wp-admin/includes/meta-boxes.php
475
  if ( ! function_exists( 'woo_feed_ajax_merchant_info' ) ) {
476
  add_action( 'wp_ajax_woo_feed_get_merchant_info', 'woo_feed_ajax_merchant_info' );
477
  function woo_feed_ajax_merchant_info() {
478
+ if ( isset( $_REQUEST['nonce'] ) && wp_verify_nonce( sanitize_text_field( $_REQUEST['nonce'] ),
479
+ 'wpf_feed_nonce' ) ) {
480
+ $provider = ( isset( $_REQUEST['provider'] ) && ! empty( $_REQUEST['provider'] ) ) ? sanitize_text_field( $_REQUEST['provider'] ) : '';
481
  $merchantInfo = new Woo_Feed_Merchant();
482
+ $data = [];
483
+ $na = esc_html__( 'N/A', 'woo-feed' );
484
  foreach ( $merchantInfo->getInfo( $provider ) as $k => $v ) {
485
+ if ( 'link' == $k ) {
486
  /** @noinspection HtmlUnknownTarget */
487
+ $data[ $k ] = empty( $v ) ? $na : sprintf( '<a href="%s" target="_blank">%s</a>',
488
+ esc_url( $v ),
489
+ esc_html__( 'Read Article', 'woo-feed' ) );
490
+ } elseif ( 'video' == $k ) {
491
  /** @noinspection HtmlUnknownTarget */
492
+ $data[ $k ] = empty( $v ) ? $na : sprintf( '<a href="%s" target="_blank">%s</a>',
493
+ esc_url( $v ),
494
+ esc_html__( 'Watch Now', 'woo-feed' ) );
495
+ } elseif ( 'feed_file_type' == $k ) {
496
  if ( ! empty( $v ) ) {
497
+ $v = array_map( function ( $type ) {
498
  return strtoupper( $type );
499
+ },
500
+ (array) $v );
501
  $data[ $k ] = esc_html( implode( ', ', $v ) );
502
  } else {
503
  $data[ $k ] = $na;
504
  }
505
+ } elseif ( 'doc' == $k ) {
506
  $links = '';
507
  foreach ( $v as $label => $link ) {
508
  /** @noinspection HtmlUnknownTarget */
509
+ $links .= sprintf( '<li><a href="%s" target="_blank">%s</a></li>',
510
+ esc_url( $link ),
511
+ esc_html( $label ) );
512
  }
513
  $data[ $k ] = empty( $links ) ? $na : $links;
514
  }
523
  if ( ! function_exists( 'woo_feed_merchant_info_metabox' ) ) {
524
  /**
525
  * Render Merchant Info Metabox
526
+ *
527
  * @param array $feedConfig
528
+ *
529
  * @return void
530
  */
531
  function woo_feed_merchant_info_metabox( $feedConfig ) {
532
+ $provider = ( isset( $feedConfig['provider'] ) && ! empty( $feedConfig['provider'] ) ) ? $feedConfig['provider'] : '';
533
  $merchantInfo = new Woo_Feed_Merchant();
534
  ?>
535
  <span class="spinner"></span>
536
  <div class="merchant-infos">
537
  <?php foreach ( $merchantInfo->getInfo( $provider ) as $k => $v ) { ?>
538
  <div class="merchant-info-section <?php echo esc_attr( $k ); ?>">
539
+ <?php if ( 'link' == $k ) { ?>
540
  <span class="dashicons dashicons-media-document" style="color: #82878c;" aria-hidden="true"></span>
541
  <span><?php esc_html_e( 'Feed Specification:', 'woo-feed' ) ?></span>
542
  <strong class="data"><?php
543
  /** @noinspection HtmlUnknownTarget */
544
+ ( empty( $v ) ) ? esc_html_e( 'N/A',
545
+ 'woo-feed' ) : printf( '<a href="%s" target="_blank">%s</a>',
546
+ esc_url( $v ),
547
+ esc_html__( 'Read Article', 'woo-feed' ) );
548
  ?></strong>
549
+ <?php } elseif ( 'video' == $k ) { ?>
550
  <span class="dashicons dashicons-video-alt3" style="color: #82878c;" aria-hidden="true"></span>
551
  <span><?php esc_html_e( 'Video Documentation:', 'woo-feed' ) ?></span>
552
  <strong class="data"><?php
553
  /** @noinspection HtmlUnknownTarget */
554
+ ( empty( $v ) ) ? esc_html_e( 'N/A',
555
+ 'woo-feed' ) : printf( '<a href="%s" target="_blank">%s</a>',
556
+ esc_url( $v ),
557
+ esc_html__( 'Watch now', 'woo-feed' ) );
558
  ?></strong>
559
+ <?php } elseif ( 'feed_file_type' == $k ) { ?>
560
  <span class="dashicons dashicons-media-text" style="color: #82878c;" aria-hidden="true"></span> <?php esc_html_e( 'Format Supported:', 'woo-feed' ) ?>
561
+ <strong class="data"><?php
562
+ if ( empty( $v ) ) {
563
+ esc_html_e( 'N/A', 'woo-feed' );
564
+ } else {
565
+ $v = implode( ', ',
566
+ array_map( function ( $type ) {
567
+ return esc_html( strtoupper( $type ) );
568
+ },
569
+ (array) $v ) );
570
+ echo esc_html( $v );
571
+ } ?></strong>
572
  <?php
573
+ } elseif ( 'doc' == $k ) { ?>
574
  <span class="dashicons dashicons-editor-help" style="color: #82878c;" aria-hidden="true"></span>
575
  <span><?php esc_html_e( 'Support Docs:', 'woo-feed' ); ?></span>
576
  <ul class="data">
577
  <?php
578
+ if ( empty( $v ) ) {
579
+ esc_html_e( 'N/A', 'woo-feed' );
580
+ } else {
581
  foreach ( $v as $label => $link ) {
582
  /** @noinspection HtmlUnknownTarget */
583
+ printf( '<li><a href="%s" target="_blank">%s</a></li>',
584
+ esc_url( $link ),
585
+ esc_html( $label ) );
586
  }
587
  }
588
  ?>
595
  <?php
596
  }
597
  }
598
+ if ( ! function_exists( 'woo_feed_get_csv_delimiters' ) ) {
599
+ /**
600
+ * Get CSV/TXT/TSV Delimiters
601
+ * @return array
602
+ */
603
+ function woo_feed_get_csv_delimiters() {
604
+ return [
605
+ ',' => 'Comma',
606
+ 'tab' => 'Tab',
607
+ ':' => 'Colon',
608
+ ' ' => 'Space',
609
+ '|' => 'Pipe',
610
+ ';' => 'Semi Colon',
611
+ ];
612
+ }
613
+ }
614
+ if ( ! function_exists( 'woo_feed_get_csv_enclosure' ) ) {
615
+ /**
616
+ * Get CSV/TXT/TSV Enclosure for multiple words
617
+ * @return array
618
+ */
619
+ function woo_feed_get_csv_enclosure() {
620
+ return [
621
+ 'double' => '"',
622
+ 'single' => '\'',
623
+ ' ' => 'None',
624
+ ];
625
+ }
626
+ }
627
 
628
+ // Editor Tabs.
629
+ if ( ! function_exists( 'render_feed_config' ) ) {
630
+ /**
631
+ * @param string $tabId
632
+ * @param array $feedRules
633
+ * @param bool $idEdit
634
+ */
635
+ function render_feed_config( $tabId, $feedRules, $idEdit ) {
636
+ global $provider, $wooFeedDropDown, $wooFeedProduct;
637
+ if ( $idEdit ) {
638
+ include WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-edit-config.php';
639
+ } else {
640
+ if ( 'smartly.io' == $provider ) {
641
+ include WOO_FEED_FREE_ADMIN_PATH . 'partials/templates/google_add-feed.php';
642
+ } elseif ( in_array( $provider, woo_feed_get_custom2_merchant() ) ) {
643
+ include WOO_FEED_FREE_ADMIN_PATH . "partials/templates/custom2_add-feed.php";
644
+ } elseif ( file_exists( WOO_FEED_FREE_ADMIN_PATH . 'partials/templates/' . $provider . '_add-feed.php' ) ) {
645
+ include WOO_FEED_FREE_ADMIN_PATH . 'partials/templates/' . $provider . '_add-feed.php';
646
+ } else {
647
+ include WOO_FEED_FREE_ADMIN_PATH . 'partials/templates/common_add-feed.php';
648
+ }
649
+ }
650
+ }
651
+ }
652
+ if ( ! function_exists( 'render_ftp_config' ) ) {
653
+ /**
654
+ * @param string $tabId
655
+ * @param array $feedRules
656
+ * @param bool $idEdit
657
+ */
658
+ function render_ftp_config( $tabId, $feedRules, $idEdit ) {
659
+ global $provider, $wooFeedDropDown, $wooFeedProduct;
660
+ include WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-edit-ftp.php';
661
+ }
662
+ }
663
+
664
+ // Sanitization.
665
  if ( ! function_exists( 'woo_feed_check_google_category' ) ) {
666
  /**
667
  * @param array $feedInfo
670
  */
671
  function woo_feed_check_google_category( $feedInfo ) {
672
  # Check Google Product Category for Google & Facebook Template and show message
673
+ $checkCategory = isset( $feedInfo['feedrules']['mattributes'] ) ? $feedInfo['feedrules']['mattributes'] : [];
674
  $checkCategoryType = isset( $feedInfo['feedrules']['type'] ) ? $feedInfo['feedrules']['type'] : [];
675
+ $merchant = isset( $feedInfo['feedrules']['provider'] ) ? $feedInfo['feedrules']['provider'] : [];
676
+ $cat = "yes";
677
+ if ( in_array( $merchant, array( 'google', 'facebook' ) ) && in_array( "current_category", $checkCategory ) ) {
678
+ $catKey = array_search( 'current_category', $checkCategory );
679
+ if ( 'pattern' == $checkCategoryType[ $catKey ] ) {
680
  $checkCategoryValue = $feedInfo['feedrules']['default'];
681
+ } else {
682
  $checkCategoryValue = $feedInfo['feedrules']['attributes'];
683
  }
684
 
685
+ if ( empty( $checkCategoryValue[ $catKey ] ) ) {
686
+ $cat = 'no';
687
  }
688
  }
689
+
690
  return $cat;
691
  }
692
  }
717
  }
718
  }
719
  }
720
+
721
  return $newArray;
722
  }
723
  }
724
  if ( ! function_exists( 'woo_feed_sanitize_form_fields' ) ) {
725
  /**
726
  * Sanitize Form Fields ($_POST Array)
727
+ *
728
  * @param array $data
729
+ *
730
  * @return array
731
  */
732
  function woo_feed_sanitize_form_fields( $data ) {
740
  }
741
  $data[ $k ] = apply_filters( 'woo_feed_sanitize_form_field', $v, $k );
742
  }
743
+
744
  return $data;
745
  }
746
  }
747
  if ( ! function_exists( 'woo_feed_unique_feed_slug' ) ) {
748
  /**
749
  * Generate Unique slug for feed.
750
+ *
751
  * @param string $slug
752
  * @param string $prefix
753
+ * @param int $feedId
754
+ *
755
  * @return string
756
+ * @see wp_unique_post_slug()
757
+ *
758
  */
759
  function woo_feed_unique_feed_slug( $slug, $prefix = '', $feedId = null ) {
760
  global $wpdb;
762
  $disallowed = array( 'siteurl', 'home', 'blogname', 'blogdescription', 'users_can_register', 'admin_email' );
763
  if ( $feedId && $feedId > 0 ) {
764
  $checkSql = "SELECT option_name FROM $wpdb->options WHERE option_name = %s AND option_id != %d LIMIT 1";
765
+ $nameCheck = $wpdb->get_var( $wpdb->prepare( $checkSql, $prefix . $slug, $feedId ) ); // phpcs:ignore
766
  } else {
767
  $checkSql = "SELECT option_name FROM $wpdb->options WHERE option_name = %s LIMIT 1";
768
+ $nameCheck = $wpdb->get_var( $wpdb->prepare( $checkSql, $prefix . $slug ) ); // phpcs:ignore
769
  }
770
+ // slug found or slug in disallowed list
771
  if ( $nameCheck || in_array( $slug, $disallowed ) ) {
772
  $suffix = 2;
773
  do {
774
+ $altName = _truncate_post_slug( $slug, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
775
  if ( $feedId && $feedId > 0 ) {
776
+ $nameCheck = $wpdb->get_var( $wpdb->prepare( $checkSql, $prefix . $altName, $feedId ) ); // phpcs:ignore
777
  } else {
778
+ $nameCheck = $wpdb->get_var( $wpdb->prepare( $checkSql, $prefix . $altName ) ); // phpcs:ignore
779
  }
780
+ $suffix ++;
781
  } while ( $nameCheck );
782
  $slug = $altName;
783
  }
784
+
785
  return $slug;
786
  }
787
  }
788
  if ( ! function_exists( 'generate_unique_feed_file_name' ) ) {
789
  function generate_unique_feed_file_name( $filename, $type, $provider ) {
790
 
791
+ $feedDir = woo_feed_get_file_dir( $provider, $type );
792
  $raw_filename = sanitize_title( $filename, '', 'save' );
793
  // check option name uniqueness ...
794
+ $raw_filename = woo_feed_unique_feed_slug( $raw_filename, 'wf_feed_' );
795
  $raw_filename = sanitize_file_name( $raw_filename . '.' . $type );
796
  $raw_filename = wp_unique_filename( $feedDir, $raw_filename );
797
+ $raw_filename = str_replace( '.' . $type, '', $raw_filename );
798
+
799
  return $raw_filename;
800
  }
801
  }
802
 
803
+ // File process.
804
+ if ( ! function_exists( 'woo_feed_check_valid_extension' ) ) {
805
+ /**
806
+ * Check Feed File Extension Validity
807
+ *
808
+ * @param string $extension Ext to check.
809
+ *
810
+ * @return bool
811
+ */
812
+ function woo_feed_check_valid_extension( $extension ) {
813
+ return in_array( $extension, array_keys( woo_feed_get_file_types() ) );
814
+ }
815
+ }
816
  if ( ! function_exists( 'woo_feed_save_feed_config_data' ) ) {
817
  /**
818
  * Sanitize And Save Feed config data (array) to db (option table)
819
+ *
820
+ * @param array $data data to be saved in db
821
+ * @param null $feed_option_name feed (file) name. optional, if empty or null name will be auto generated
822
+ * @param bool $configOnly save only wf_config or both wf_config and wf_feed_. default is only wf_config
823
  *
824
  * @return bool|string return false if failed to update. return filename if success
825
  */
826
+ function woo_feed_save_feed_config_data( $data, $feed_option_name = null, $configOnly = true ) {
827
+ if ( ! is_array( $data ) ) {
828
+ return false;
829
+ }
830
+ if ( ! isset( $data['filename'], $data['feedType'], $data['provider'] ) ) {
831
+ return false;
832
+ }
833
  // unnecessary form fields to remove
834
  $removables = [ 'closedpostboxesnonce', '_wpnonce', '_wp_http_referer', 'save_feed_config', 'edit-feed' ];
835
  foreach ( $removables as $removable ) {
836
+ if ( isset( $data[ $removable ] ) ) {
837
+ unset( $data[ $removable ] );
838
+ }
839
  }
840
+ // parse rules
841
+ $data = woo_feed_parse_feed_rules( $data );
842
  // Sanitize Fields
843
  $data = woo_feed_sanitize_form_fields( $data );
844
+ if ( empty( $feed_option_name ) ) {
845
+ $feed_option_name = generate_unique_feed_file_name( $data['filename'],
846
+ $data['feedType'],
847
+ $data['provider'] );
848
  } else {
849
+ $feed_option_name = woo_feed_extract_feed_option_name( $feed_option_name );
850
  }
851
  /**
852
  * Before Updating Config to db
854
  * @param array $config sanitized config
855
  * @param string $feed_option_name option name
856
  */
857
+ do_action( 'woo_feed_before_update_config', $data, "wf_config" . $feed_option_name );
858
  # Store Config
859
+ $update = update_option( "wf_config" . $feed_option_name, $data, false );
860
  // save if config update ok...
861
+ if ( $update && false === $configOnly ) {
862
+ $oldFeed = maybe_unserialize( get_option( "wf_feed_" . $feed_option_name ) );
863
  $feedData = array(
864
  'feedrules' => $data,
865
+ 'url' => woo_feed_get_file_url( $feed_option_name, $data['provider'], $data['feedType'] ),
866
+ 'last_updated' => gmdate( "Y-m-d H:i:s" ),
867
+ 'status' => isset( $oldFeed['status'] ) && 1 == $oldFeed['status'] ? 1 : 0,
868
+ // set old status or disable auto update.
869
  );
870
+ $update = update_option( 'wf_feed_' . $feed_option_name, maybe_serialize( $feedData ), false );
871
  }
872
+
873
  // return filename on success or update status
874
+ return $feed_option_name;
875
+ }
876
+ }
877
+ if ( ! function_exists( 'woo_feed_extract_feed_option_name' ) ) {
878
+ /**
879
+ * Remove Feed Option Name Prefix and return the slug
880
+ *
881
+ * @param string $feed_option_name
882
+ *
883
+ * @return string
884
+ */
885
+ function woo_feed_extract_feed_option_name( $feed_option_name ) {
886
+ return str_replace( [ 'wf_feed_', 'wf_config' ], '', $feed_option_name );
887
+ }
888
+ }
889
+ if ( ! function_exists( 'woo_feed_get_file_path' ) ) {
890
+ /**
891
+ * Get File Path for feed or the file upload path for the plugin to use.
892
+ *
893
+ * @param string $provider provider name.
894
+ * @param string $type feed file type.
895
+ *
896
+ * @return string
897
+ */
898
+ function woo_feed_get_file_path( $provider = '', $type = '' ) {
899
+ $upload_dir = wp_get_upload_dir();
900
+
901
+ return sprintf( '%s/woo-feed/%s/%s/', $upload_dir['basedir'], $provider, $type );
902
+ }
903
+ }
904
+ if ( ! function_exists( 'woo_feed_get_file' ) ) {
905
+ /**
906
+ * Get Feed File URL
907
+ *
908
+ * @param string $fileName
909
+ * @param string $provider
910
+ * @param string $type
911
+ *
912
+ * @return string
913
+ */
914
+ function woo_feed_get_file( $fileName, $provider, $type ) {
915
+ $fileName = woo_feed_extract_feed_option_name( $fileName );
916
+ $path = woo_feed_get_file_path( $provider, $type );
917
+
918
+ return sprintf( '%s/%s.%s', untrailingslashit( $path ), $fileName, $type );
919
  }
920
  }
921
  if ( ! function_exists( 'woo_feed_get_file_url' ) ) {
922
  /**
923
  * Get Feed File URL
924
+ *
925
  * @param string $fileName
926
  * @param string $provider
927
  * @param string $type
928
  *
929
  * @return string
930
  */
931
+ function woo_feed_get_file_url( $fileName, $provider, $type ) {
932
+ $fileName = woo_feed_extract_feed_option_name( $fileName );
933
+ $upload_dir = wp_get_upload_dir();
934
+
935
+ return esc_url( sprintf( '%s/woo-feed/%s/%s/%s.%s',
936
+ $upload_dir['baseurl'],
937
+ $provider,
938
+ $type,
939
+ $fileName,
940
+ $type ) );
941
+ }
942
  }
943
  if ( ! function_exists( 'woo_feed_check_feed_file' ) ) {
944
  /**
945
  * Check if feed file exists
946
+ *
947
  * @param string $fileName
948
  * @param string $provider
949
  * @param string $type
950
  *
951
  * @return bool
952
  */
953
+ function woo_feed_check_feed_file( $fileName, $provider, $type ) {
954
+ $upload_dir = wp_get_upload_dir();
955
+
956
+ return file_exists( sprintf( '%s/woo-feed/%s/%s/%s.%s',
957
+ $upload_dir['basedir'],
958
+ $provider,
959
+ $type,
960
+ $fileName,
961
+ $type ) );
962
+ }
963
  }
964
  if ( ! function_exists( 'woo_feed_get_file_dir' ) ) {
965
  /**
966
  * Get Feed Directory
967
+ *
968
  * @param string $provider
969
  * @param string $feedType
970
+ *
971
  * @return string
972
  */
973
  function woo_feed_get_file_dir( $provider, $feedType ) {
974
+ $upload_dir = wp_get_upload_dir();
975
+
976
+ return sprintf( '%s/woo-feed/%s/%s', $upload_dir['basedir'], $provider, $feedType );
977
  }
978
  }
979
  if ( ! function_exists( 'woo_feed_save_batch_feed_info' ) ) {
980
  /**
981
  * Save Feed Batch Chunk
982
+ *
983
+ * @param string $feedService merchant.
984
+ * @param string $type file type (ext).
985
+ * @param string|array $string data.
986
+ * @param string $fileName file name.
987
+ * @param array $info feed config.
988
  *
989
  * @return bool
990
  */
991
  function woo_feed_save_batch_feed_info( $feedService, $type, $string, $fileName, $info ) {
 
 
 
992
  $ext = $type;
993
+ if ( 'csv' == $type ) {
994
+ $string = wp_json_encode( $string );
995
+ $ext = 'json';
996
  }
997
+ # Save File.
998
+ $path = woo_feed_get_file_dir( $feedService, $type );
999
+ $file = $path . '/' . $fileName . '.' . $ext;
1000
+ $save = new Woo_Feed_Savefile();
1001
  $status = $save->saveFile( $path, $file, $string );
1002
+ // if ( woo_feed_is_debugging_enabled() ) {
1003
+ // if ( $status ) {
1004
  // $message = sprintf( 'Batch chunk file (%s) saved.', $fileName );
1005
  // } else {
1006
  // $message = sprintf( 'Unable to save batch chunk file %s.', $fileName );
1007
  // }
1008
  // woo_feed_log_feed_process( $info['filename'], $message );
1009
  // }
1010
+
1011
  return $status;
1012
  }
1013
  }
1020
  * @return bool|false|mixed|string
1021
  */
1022
  function woo_feed_get_batch_feed_info( $feedService, $type, $fileName ) {
 
 
1023
  $ext = $type;
1024
+ if ( 'csv' == $type ) {
1025
+ $ext = 'json';
1026
+ }
1027
  # Save File
1028
+ $path = woo_feed_get_file_dir( $feedService, $type );
1029
+ $file = $path . '/' . $fileName . '.' . $ext;
1030
+ if ( 'csv' == $type && file_exists( $file ) ) {
1031
+ // should not cache
1032
+ $file = file_get_contents( $file ); // phpcs:ignore
1033
+
1034
+ return ( $file ) ? json_decode( $file, true ) : false;
1035
+ } elseif ( file_exists( $file ) ) {
1036
+ // should not cache
1037
+ return file_get_contents( $file ); // phpcs:ignore
1038
  }
1039
+
1040
  return false;
1041
  }
1042
  }
1043
  if ( ! function_exists( 'woo_feed_unlink_tempFiles' ) ) {
1044
  /**
1045
  * Remove temporary feed files
1046
+ *
1047
+ * @param string $feedService merchant name.
1048
+ * @param string $fileName feed file name.
1049
+ * @param string $type file type (ext).
1050
+ *
1051
  * @return bool
1052
  */
1053
+ function woo_feed_unlink_tempFiles( $feedService, $fileName, $type ) {
1054
+ $path = woo_feed_get_file_dir( $feedService, $type );
1055
+ $files['headerFile'] = $path . '/' . 'wf_store_feed_header_info_' . $fileName . '.' . $type;
1056
+ $files['bodyFile'] = $path . '/' . 'wf_store_feed_body_info_' . $fileName . '.' . $type;
1057
+ $files['footerFile'] = $path . '/' . 'wf_store_feed_footer_info_' . $fileName . '.' . $type;
1058
+
1059
  if ( ! empty( $files ) ) {
1060
+ // woo_feed_log_feed_process( $fileName, sprintf( 'Deleting Temporary Files (%s).', implode( ', ', array_values( $tempFiles ) ) ) );
1061
  foreach ( $files as $key => $file ) {
1062
  if ( file_exists( $file ) ) {
1063
+ unlink( $file ); // phpcs:ignore
1064
  }
1065
  }
1066
+
1067
  return true;
1068
  }
1069
+
1070
  return false;
1071
  }
1072
  }
1073
+ if ( ! function_exists( 'woo_feed_delete_feed' ) ) {
1074
+ /**
1075
+ * Delete feed option and the file from uploads directory
1076
+ *
1077
+ * @param string|int $feed_id feed option name or ID.
1078
+ *
1079
+ * @return bool
1080
+ */
1081
+ function woo_feed_delete_feed( $feed_id ) {
1082
+ global $wpdb;
1083
+ if ( ! is_numeric( $feed_id ) ) {
1084
+ $feed_name = woo_feed_extract_feed_option_name( $feed_id );
1085
+ } else {
1086
+ $feed_data = $wpdb->get_row( $wpdb->prepare( "SELECT option_name FROM $wpdb->options WHERE option_id = %d", $feed_id ) ); // phpcs:ignore
1087
+ $option_name = $feed_data->option_name;
1088
+ $feed_name = woo_feed_extract_feed_option_name( $feed_data->option_name );
1089
+ }
1090
+ $feedInfo = maybe_unserialize( get_option( 'wf_feed_' . $feed_name ) );
1091
+ if ( false !== $feedInfo ) {
1092
+ $feedInfo = $feedInfo['feedrules'];
1093
+ } else {
1094
+ $feedInfo = maybe_unserialize( get_option( 'wf_config' . $feed_name ) );
1095
+ }
1096
+ $deleted = false;
1097
+ $file = woo_feed_get_file( $feed_name, $feedInfo['provider'], $feedInfo['feedType'] );
1098
+ if ( file_exists( $file ) ) {
1099
+ // file exists in upload directory
1100
+ if ( unlink( $file ) ) { // phpcs:ignore
1101
+ delete_option( 'wf_feed_' . $feed_name );
1102
+ delete_option( 'wf_config' . $feed_name );
1103
+ $deleted = true;
1104
+ }
1105
+ } else {
1106
+ delete_option( 'wf_feed_' . $feed_name );
1107
+ delete_option( 'wf_config' . $feed_name );
1108
+ $deleted = true;
1109
+ }
1110
+
1111
+ return $deleted;
1112
+ }
1113
+ }
1114
 
1115
  // Mics..
1116
  if ( ! function_exists( 'woo_feed_remove_query_args' ) ) {
1117
  /**
1118
  * Add more items to the removable query args array...
1119
+ *
1120
  * @param array $removable_query_args
1121
  *
1122
  * @return array
1123
  */
1124
+ function woo_feed_remove_query_args( $removable_query_args ) {
1125
+ global $plugin_page;
1126
+ if ( strpos( $plugin_page, 'webappick' ) !== false ) {
1127
+ $removable_query_args[] = 'feed_created';
1128
+ $removable_query_args[] = 'feed_updated';
1129
+ $removable_query_args[] = 'feed_regenerate';
1130
+ $removable_query_args[] = 'feed_name';
1131
+ $removable_query_args[] = 'link';
1132
+ $removable_query_args[] = 'wpf_message';
1133
+ $removable_query_args[] = 'cat';
1134
+ $removable_query_args[] = 'schedule_updated';
1135
+ $removable_query_args[] = 'settings_updated';
1136
+ /** @noinspection SpellCheckingInspection */
1137
+ $removable_query_args[] = 'WPFP_WPML_CURLANG';
1138
+ }
1139
+
1140
+ return $removable_query_args;
1141
+ }
1142
+
1143
  add_filter( 'removable_query_args', 'woo_feed_remove_query_args', 10, 1 );
1144
  }
1145
+ if ( ! function_exists( 'usort_reorder' ) ) {
1146
+ /**
1147
+ * This checks for sorting input and sorts the data in our array accordingly.
1148
+ *
1149
+ * In a real-world situation involving a database, you would probably want
1150
+ * to handle sorting by passing the 'orderby' and 'order' values directly
1151
+ * to a custom query. The returned data will be pre-sorted, and this array
1152
+ * sorting technique would be unnecessary.
1153
+ *
1154
+ * @param array $a first data.
1155
+ * @param array $b second data.
1156
+ *
1157
+ * @return bool
1158
+ */
1159
+ function usort_reorder( $a, $b ) {
1160
+ // If no sort, default to title
1161
+ $orderby = ( ! empty( $_REQUEST['orderby'] ) ) ? sanitize_text_field( $_REQUEST['orderby'] ) : 'option_name'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
1162
+ // If no order, default to asc
1163
+ $order = ( ! empty( $_REQUEST['order'] ) ) ? sanitize_text_field( $_REQUEST['order'] ) : 'asc'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
1164
+ $result = strcmp( $a[ $orderby ], $b[ $orderby ] ); // Determine sort order
1165
+
1166
+ return ( 'asc' === $order ) ? $result : - $result; // Send final sort direction to usort
1167
+ }
1168
+ }
1169
+ if ( ! function_exists( 'str_replace_trim' ) ) {
1170
+ /**
1171
+ * str_replace() wrapper with trim()
1172
+ *
1173
+ * @param mixed $search The value being searched for, otherwise known as the needle.
1174
+ * An array may be used to designate multiple needles.
1175
+ * @param mixed $replace The replacement value that replaces found search values.
1176
+ * An array may be used to designate multiple replacements.
1177
+ * @param mixed $subject The string or array being searched and replaced on,
1178
+ * otherwise known as the haystack.
1179
+ * @param string $charlist [optional]
1180
+ * Optionally, the stripped characters can also be specified using the charlist parameter.
1181
+ * Simply list all characters that you want to be stripped.
1182
+ * With this you can specify a range of characters.
1183
+ *
1184
+ * @return array|string
1185
+ */
1186
+ function str_replace_trim( $search, $replace, $subject, $charlist = " \t\n\r\0\x0B" ) {
1187
+ $replaced = str_replace( $search, $replace, $subject );
1188
+ if ( is_array( $replaced ) ) {
1189
+ return array_map(
1190
+ function ( $item ) use ( $charlist ) {
1191
+ return trim( $item, $charlist );
1192
+ },
1193
+ $replaced
1194
+ );
1195
+ } else {
1196
+ return trim( $replaced, $charlist );
1197
+ }
1198
+ }
1199
+ }
1200
 
1201
+ // Feed Functions.
1202
+ if ( ! function_exists( 'woo_feed_generate_feed' ) ) {
1203
+ /**
1204
+ * Update Feed Information
1205
+ *
1206
+ * @param array $info
1207
+ *
1208
+ * @return string|bool
1209
+ */
1210
+ function woo_feed_generate_feed( $info ) {
1211
+ if ( false === $info ) {
1212
+ return false;
1213
+ }
1214
+ // parse rules.
1215
+ $info = woo_feed_parse_feed_rules( isset( $info['feedrules'] ) ? $info['feedrules'] : $info );
1216
+ if ( ! empty( $info['provider'] ) ) {
1217
+ do_action( 'before_woo_feed_generate_feed', $info );
1218
+ // Get Post data
1219
+ $feedService = sanitize_text_field( $info['provider'] );
1220
+ $fileName = woo_feed_extract_feed_option_name( sanitize_text_field( $info['filename'] ) );
1221
+ $type = sanitize_text_field( $info['feedType'] );
1222
+ $feedRules = $info;
1223
+ //$feedRules['Limit']='-1';
1224
+ //$feedRules['Offset']='0';
1225
+ // Get Feed info
1226
+ $products = new Woo_Generate_Feed( $feedService, $feedRules );
1227
+ $getString = $products->getProducts();
1228
+ if ( 'csv' == $type ) {
1229
+ $csvHead[0] = $getString['header'];
1230
+ if ( ! empty( $csvHead ) && ! empty( $getString['body'] ) ) {
1231
+ $string = array_merge( $csvHead, $getString['body'] );
1232
+ } else {
1233
+ $string = array();
1234
+ }
1235
+ } else {
1236
+ $string = $getString['header'] . $getString['body'] . $getString['footer'];
1237
+ }
1238
+
1239
+ $saveFile = false;
1240
+ // Check If any products founds
1241
+ if ( $string && ! empty( $string ) ) {
1242
+ // Save File
1243
+ $path = woo_feed_get_file_path( $feedService, $type );
1244
+ $file = woo_feed_get_file( $fileName, $feedService, $type );
1245
+ $save = new Woo_Feed_Savefile();
1246
+ if ( 'csv' == $type ) {
1247
+ $saveFile = $save->saveCSVFile( $path, $file, $string, $info );
1248
+ } else {
1249
+ $saveFile = $save->saveFile( $path, $file, $string );
1250
+ }
1251
+
1252
+ if ( 'json' == $type ) {
1253
+ $type = 'csv';
1254
+ }
1255
+ // Upload file to ftp server
1256
+ if ( 1 == (int) $info['ftpenabled'] ) {
1257
+ woo_feed_handle_file_transfer( $file, $fileName . '.' . $type, $info );
1258
+ }
1259
+ }
1260
+ // Save Info into database
1261
+ $feedInfo = array(
1262
+ 'feedrules' => $feedRules,
1263
+ 'url' => woo_feed_get_file_url( $fileName, $feedService, $type ),
1264
+ 'last_updated' => gmdate( 'Y-m-d H:i:s' ),
1265
+ 'status' => 1,
1266
+ );
1267
+ update_option( 'wf_feed_' . $fileName, serialize( $feedInfo ), false );
1268
+ do_action( 'after_woo_feed_generate_feed', $info );
1269
+ if ( $saveFile ) {
1270
+ $getInfo = maybe_unserialize( get_option( 'wf_feed_' . $fileName ) );
1271
+ $url = $getInfo['url'];
1272
+
1273
+ return $url;
1274
+ } else {
1275
+ return false;
1276
+ }
1277
+ }
1278
+
1279
+ return false;
1280
+ }
1281
+ }
1282
  if ( ! function_exists( 'woo_feed_get_field_output_type_options' ) ) {
1283
  function woo_feed_get_field_output_type_options() {
1284
+ $wooFeedDropDown = new Woo_Feed_Dropdown();
1285
+
1286
+ return apply_filters( 'woo_feed_field_output_options', $wooFeedDropDown->output_types );
 
 
 
 
 
 
 
 
 
1287
  }
1288
  }
1289
  if ( ! function_exists( 'woo_feed_get_schedule_interval_options' ) ) {
1290
+ /**
1291
+ * Get Schedule Intervals
1292
+ * @return mixed
1293
+ */
1294
+ function woo_feed_get_schedule_interval_options() {
1295
+ return apply_filters(
1296
+ 'woo_feed_schedule_interval_options',
1297
+ [
1298
+ WEEK_IN_SECONDS => esc_html__( '1 Week', 'woo-feed' ),
1299
+ DAY_IN_SECONDS => esc_html__( '24 Hours', 'woo-feed' ),
1300
+ 12 * HOUR_IN_SECONDS => esc_html__( '12 Hours', 'woo-feed' ),
1301
+ 6 * HOUR_IN_SECONDS => esc_html__( '6 Hours', 'woo-feed' ),
1302
+ HOUR_IN_SECONDS => esc_html__( '1 Hours', 'woo-feed' ),
1303
+ ]
1304
+ );
1305
  }
1306
  }
1307
  if ( ! function_exists( 'woo_feed_get_minimum_interval_option' ) ) {
1308
+ function woo_feed_get_minimum_interval_option() {
1309
+ $intervals = array_keys( woo_feed_get_schedule_interval_options() );
1310
+ if ( ! empty( $intervals ) ) {
1311
+ return end( $intervals );
1312
+ }
1313
+
1314
+ return 15 * MINUTE_IN_SECONDS;
1315
+ }
1316
  }
1317
+ if ( ! function_exists( 'woo_feed_stripInvalidXml' ) ) {
1318
  /**
1319
  * Remove non supported xml character
1320
+ *
1321
  * @param string $value
1322
+ *
1323
  * @return string
1324
  */
1325
  function woo_feed_stripInvalidXml( $value ) {
1326
+ $ret = '';
1327
+ if ( empty( $value ) ) {
1328
+ return $ret;
1329
+ }
1330
+ $length = strlen( $value );
1331
+ for ( $i = 0; $i < $length; $i ++ ) {
1332
+ $current = ord( $value[ $i ] );
1333
+ if ( ( 0x9 == $current ) || ( 0xA == $current ) || ( 0xD == $current ) || ( ( $current >= 0x20 ) && ( $current <= 0xD7FF ) ) || ( ( $current >= 0xE000 ) && ( $current <= 0xFFFD ) ) || ( ( $current >= 0x10000 ) && ( $current <= 0x10FFFF ) ) ) {
1334
+ $ret .= chr( $current );
1335
  } else {
1336
+ $ret .= '';
1337
  }
1338
  }
1339
+
1340
  return $ret;
1341
  }
1342
  }
1343
+ if ( ! function_exists( 'woo_feed_get_formatted_url' ) ) {
1344
  /**
1345
  * Get Formatted URL
1346
+ *
1347
  * @param string $url
1348
  *
1349
  * @return string
1350
  */
1351
+ function woo_feed_get_formatted_url( $url = '' ) {
1352
+ if ( ! empty( $url ) ) {
1353
+ if ( substr( trim( $url ), 0, 4 ) === "http" || substr( trim( $url ),
1354
+ 0,
1355
+ 3 ) === "ftp" || substr( trim( $url ), 0, 4 ) === "sftp" ) {
1356
+ return rtrim( $url, '/' );
1357
  } else {
1358
  $base = get_site_url();
1359
+ $url = $base . $url;
1360
+
1361
+ return rtrim( $url, '/' );
1362
  }
1363
  }
1364
+
1365
+ return '';
1366
  }
1367
  }
1368
+ if ( ! function_exists( 'array_value_first' ) ) {
1369
  /**
1370
  * Get First Value of an array
1371
+ *
1372
  * @param array $arr
1373
+ *
1374
  * @return mixed|null
1375
+ * @since 3.0.0
1376
  */
1377
  function array_value_first( array $arr ) {
1378
  foreach ( $arr as $key => $unused ) {
1379
  return $unused;
1380
  }
1381
+
1382
+ return null;
1383
  }
1384
  }
1385
+ if ( ! function_exists( 'woo_feed_make_url_with_parameter' ) ) {
1386
  /**
1387
  * Make proper URL using parameters
1388
+ *
1389
  * @param string $output
1390
  * @param string $suffix
1391
+ *
1392
  * @return string
1393
  */
1394
  function woo_feed_make_url_with_parameter( $output = '', $suffix = '' ) {
1395
+ if ( empty( $output ) || empty( $suffix ) ) {
1396
  return $output;
1397
  }
1398
 
1399
+ $getParam = explode( '?', $output );
1400
  $URLParam = array();
1401
+ if ( isset( $getParam[1] ) ) {
1402
+ $URLParam = woo_feed_parse_string( $getParam[1] );
1403
  }
1404
 
1405
  $EXTRAParam = array();
1406
+ if ( ! empty( $suffix ) ) {
1407
+ $suffix = str_replace( '?', '', $suffix );
1408
+ $EXTRAParam = woo_feed_parse_string( $suffix );
1409
  }
1410
 
1411
+ $params = array_merge( $URLParam, $EXTRAParam );
1412
+ if ( ! empty( $params ) && '' != $output ) {
1413
+ $params = http_build_query( $params );
1414
+ $baseURL = isset( $getParam ) ? $getParam[0] : $output;
1415
+ $output = $baseURL . '?' . $params;
1416
  }
1417
 
1418
  return $output;
1419
  }
1420
  }
1421
+ if ( ! function_exists( 'woo_feed_parse_string' ) ) {
1422
  /**
1423
  * Parse URL parameter
1424
+ *
1425
  * @param string $str
1426
+ *
1427
  * @return array
1428
  */
1429
+ function woo_feed_parse_string( $str = '' ) {
1430
 
1431
  # result array
1432
  $arr = array();
1433
 
1434
+ if ( empty( $str ) ) {
1435
  return $arr;
1436
  }
1437
 
1438
  # split on outer delimiter
1439
+ $pairs = explode( '&', $str );
1440
 
1441
+ if ( ! empty( $pairs ) ) {
1442
 
1443
  # loop through each pair
1444
  foreach ( $pairs as $i ) {
1445
  # split into name and value
1446
+ list( $name, $value ) = explode( '=', $i, 2 );
1447
 
1448
  # if name already exists
1449
+ if ( isset( $arr[ $name ] ) ) {
1450
  # stick multiple values into an array
1451
+ if ( is_array( $arr[ $name ] ) ) {
1452
  $arr[ $name ][] = $value;
1453
  } else {
1454
  $arr[ $name ] = array( $arr[ $name ], $value );
1458
  $arr[ $name ] = $value;
1459
  }
1460
  }
1461
+ } elseif ( ! empty( $str ) ) {
1462
+ list( $name, $value ) = explode( '=', $str, 2 );
1463
  $arr[ $name ] = $value;
1464
  }
1465
 
1467
  return $arr;
1468
  }
1469
  }
1470
+ if ( ! function_exists( 'woo_feed_replace_to_merchant_attribute' ) ) {
1471
  /**
1472
  * Parse URL parameter
1473
+ *
1474
  * @param string $pluginAttribute
1475
  * @param string $merchant
1476
  * @param string feedType CSV XML TXT
1477
+ *
1478
  * @return string
1479
  */
1480
+ function woo_feed_replace_to_merchant_attribute( $pluginAttribute, $merchant, $feedType ) {
1481
+ $attributeClass = new Woo_Feed_Default_Attributes();
1482
+ $merchantAttributes = '';
1483
+ if ( 'google' == $merchant && 'xml' == $feedType ) {
1484
  $merchantAttributes = $attributeClass->googleXMLAttribute;
1485
+ } elseif ( 'google' == $merchant && ( 'csv' == $feedType || 'txt' == $feedType ) ) {
1486
  $merchantAttributes = $attributeClass->googleCSVTXTAttribute;
1487
+ } elseif ( 'facebook' == $merchant && 'xml' == $feedType ) {
1488
  $merchantAttributes = $attributeClass->facebookXMLAttribute;
1489
+ } elseif ( 'facebook' == $merchant && ( 'csv' == $feedType || 'txt' == $feedType ) ) {
1490
  $merchantAttributes = $attributeClass->facebookCSVTXTAttribute;
1491
+ } elseif ( 'pinterest' == $merchant && 'xml' == $feedType ) {
1492
  $merchantAttributes = $attributeClass->pinterestXMLAttribute;
1493
+ } elseif ( 'pinterest' == $merchant && ( 'csv' == $feedType || 'txt' == $feedType ) ) {
1494
  $merchantAttributes = $attributeClass->pinterestCSVTXTAttribute;
1495
  }
1496
 
1497
+ if ( ! empty( $merchantAttributes ) && array_key_exists( $pluginAttribute, $merchantAttributes ) ) {
1498
  return $merchantAttributes[ $pluginAttribute ][0];
1499
  }
1500
 
1501
  return $pluginAttribute;
1502
  }
1503
  }
1504
+ if ( ! function_exists( 'woo_feed_add_cdata' ) ) {
1505
  /**
1506
  * Parse URL parameter
1507
+ *
1508
  * @param string $pluginAttribute
1509
  * @param string $attributeValue
1510
  * @param string $merchant
1511
+ *
1512
  * @return string
1513
  */
1514
+ function woo_feed_add_cdata( $pluginAttribute, $attributeValue, $merchant ) {
1515
+ if ( strpos( $attributeValue, "<![CDATA[" ) !== false ) {
1516
  return "$attributeValue";
1517
  }
1518
 
1519
+ $attributeClass = new Woo_Feed_Default_Attributes();
1520
+ $merchantAttributes = '';
1521
+ if ( 'google' == $merchant ) {
1522
  $merchantAttributes = $attributeClass->googleXMLAttribute;
1523
+ } elseif ( 'facebook' == $merchant ) {
1524
  $merchantAttributes = $attributeClass->facebookXMLAttribute;
1525
+ } elseif ( 'pinterest' == $merchant ) {
1526
  $merchantAttributes = $attributeClass->pinterestXMLAttribute;
1527
  }
1528
 
1529
+ if ( ! empty( $merchantAttributes ) && array_key_exists( $pluginAttribute, $merchantAttributes ) ) {
1530
+ if ( 'true' == $merchantAttributes[ $pluginAttribute ][1] ) {
1531
+ return "<![CDATA[$attributeValue]]>";
1532
+ } else {
1533
  return "$attributeValue";
1534
  }
1535
+ } elseif ( false !== strpos( $attributeValue, "&" ) || 'http' == substr( trim( $attributeValue ), 0, 4 ) ) {
 
1536
  return "<![CDATA[$attributeValue]]>";
1537
+ } else {
1538
  return "$attributeValue";
1539
  }
1540
  }
1541
  }
1542
 
1543
+ // Price And Tax.
1544
+ if ( ! function_exists( 'woo_feed_apply_tax_location_data' ) ) {
 
 
 
 
 
1545
  /**
1546
+ * Filter and Change Location data for tax calculation
1547
  *
1548
+ * @param array $location Location array.
1549
+ * @param string $tax_class Tax class.
1550
+ * @param WC_Customer $customer WooCommerce Customer Object.
1551
  *
1552
+ * @return array
 
 
1553
  */
1554
+ function woo_feed_apply_tax_location_data( $location, $tax_class, $customer ) {
1555
+ // @TODO use filter. add tab in feed editor so user can set custom settings.
1556
+ // @TODO tab should not list all country and cities. it only list available tax settings and user can just select one.
1557
+ // @TODO then it will extract the location data from it to use here.
1558
+ $wc_tax_location = [
1559
+ WC()->countries->get_base_country(),
1560
+ WC()->countries->get_base_state(),
1561
+ WC()->countries->get_base_postcode(),
1562
+ WC()->countries->get_base_city(),
1563
+ ];
1564
+ /**
1565
+ * Filter Tax Location to apply before product loop
1566
+ *
1567
+ * @param array $tax_location
1568
+ *
1569
+ * @since 3.3.0
1570
+ */
1571
+ $tax_location = apply_filters( 'woo_feed_tax_location_data', $wc_tax_location );
1572
+ if ( ! is_array( $tax_location ) || ( is_array( $tax_location ) && 4 !== count( $tax_location ) ) ) {
1573
+ $tax_location = $wc_tax_location;
1574
  }
 
1575
 
1576
+ return $tax_location;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1577
  }
1578
  }
1579
 
1580
  // Hooks on feed generating process...
1581
  if ( ! function_exists( 'woo_feed_apply_hooks_before_product_loop' ) ) {
 
1582
  /**
1583
  * Apply Hooks Before Looping through ProductIds
1584
+ *
1585
  * @param array $feedConfig
1586
  */
1587
  function woo_feed_apply_hooks_before_product_loop( $feedConfig ) {
 
1588
  add_filter( 'woocommerce_get_tax_location', 'woo_feed_apply_tax_location_data', 10, 3 );
1589
  }
1590
  }
1591
+
1592
  if ( ! function_exists( 'woo_feed_remove_hooks_before_product_loop' ) ) {
 
1593
  /**
1594
  * Remove Applied Hooks Looping through ProductIds
1595
+ *
1596
  * @param array $feedConfig the feed array.
1597
+ *
1598
+ * @see woo_feed_apply_hooks_before_product_loop
1599
  */
1600
  function woo_feed_remove_hooks_before_product_loop( $feedConfig ) {
1601
  remove_filter( 'woocommerce_get_tax_location', 'woo_feed_apply_tax_location_data', 10 );
1602
  }
1603
  }
1604
 
1605
+ // End of file helper.php.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/hooks.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Default Hooks
4
+ * @package WooFeed
5
+ * @subpackage WooFeed_Helper_Functions
6
+ * @version 1.0.0
7
+ * @since WooFeed 3.3.0
8
+ * @author KD <mhamudul.hk@gmail.com>
9
+ * @copyright WebAppick
10
+ */
11
+
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ die(); // Silence...
14
+ }
15
+ /** @define "WOO_FEED_ADMIN_PATH" "./../admin/" */ // phpcs:ignore
16
+
17
+ add_action( 'woo_feed_before_product_loop', 'woo_feed_apply_hooks_before_product_loop', 10, 1 );
18
+ add_action( 'woo_feed_after_product_loop', 'woo_feed_remove_hooks_before_product_loop', 10, 1 );
19
+ // End of file hooks.php.
includes/log-helper.php ADDED
@@ -0,0 +1,214 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Log Helper Functions
4
+ * @package WooFeed
5
+ * @subpackage WooFeed_Helper_Functions
6
+ * @version 1.0.0
7
+ * @since WooFeed 3.3.0
8
+ * @author KD <mhamudul.hk@gmail.com>
9
+ * @copyright WebAppick
10
+ */
11
+
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ die(); // Silence...
14
+ }
15
+ /** @define "WOO_FEED_ADMIN_PATH" "./../admin/" */ // phpcs:ignore
16
+
17
+ if ( ! function_exists( 'woo_feed_is_debugging_enabled' ) ) {
18
+ function woo_feed_is_debugging_enabled() {
19
+ return get_option( 'woo_feed_enable_error_debugging', false ) === 'on';
20
+ }
21
+ }
22
+ if ( ! function_exists( 'woo_feed_get_logger' ) ) {
23
+ /**
24
+ * Get The logger.
25
+ *
26
+ * Example:
27
+ * woo_feed_get_logger()->debug( 'Test log', [ 'source' => 'test-debug' ] );
28
+ *
29
+ * @since 3.2.1
30
+ *
31
+ * @return WC_Logger
32
+ */
33
+ function woo_feed_get_logger() {
34
+ static $logger = null;
35
+ if ( null !== $logger && is_a( $logger, 'WC_Logger' ) ) {
36
+ return $logger;
37
+ }
38
+ $logger = new WC_Logger( [ new Woo_Feed_Log_Handler_File() ] );
39
+
40
+ return $logger;
41
+ }
42
+ }
43
+ if ( ! function_exists( 'woo_feed_log_errors_at_shutdown' ) ) {
44
+ /**
45
+ * Shutdown log handler
46
+ * @since 3.2.1
47
+ * @return void
48
+ */
49
+ function woo_feed_log_errors_at_shutdown(){
50
+ $error = error_get_last();
51
+ if ( $error && in_array( $error['type'], array( E_ERROR, E_PARSE, E_COMPILE_ERROR, E_USER_ERROR, E_RECOVERABLE_ERROR ), true ) ) {
52
+ /* translators: 1: error message 2: file name and path 3: line number */
53
+ $message = sprintf( __( '%1$s in %2$s on line %3$s', 'woo-feed' ), $error['message'], $error['file'], $error['line'] );
54
+ woo_feed_log_fatal_error( $message );
55
+ do_action( 'woo_feed_shutdown_error', $error );
56
+ }
57
+ }
58
+ }
59
+ if ( ! function_exists( 'woo_feed_log' ) ) {
60
+ /**
61
+ * Write message to log file.
62
+ * Write log message if debugging is enable
63
+ *
64
+ * @since 3.2.1
65
+ *
66
+ * @param string $source will be use for log file name.
67
+ * @param string $message Log message.
68
+ * @param string $level One of the following:
69
+ * 'emergency': System is unusable.
70
+ * 'alert': Action must be taken immediately.
71
+ * 'critical': Critical conditions.
72
+ * 'error': Error conditions.
73
+ * 'warning': Warning conditions.
74
+ * 'notice': Normal but significant condition.
75
+ * 'info': Informational messages.
76
+ * 'debug': Debug-level messages.
77
+ * @param mixed $data Extra data for the log handler.
78
+ * @param bool $force_log ignore debugging settings
79
+ * @param bool $wc_log log data in wc-logs directory
80
+ *
81
+ * @return void
82
+ */
83
+ function woo_feed_log( $source, $message, $level = 'debug', $data = null, $force_log = false, $wc_log = false ) {
84
+ if ( woo_feed_is_debugging_enabled() || true === $force_log ) {
85
+ if ( ! in_array( $level, [
86
+ 'emergency',
87
+ 'alert',
88
+ 'critical',
89
+ 'critical',
90
+ 'error',
91
+ 'warning',
92
+ 'notice',
93
+ 'info',
94
+ 'debug',
95
+ ] ) ) {
96
+ return;
97
+ }
98
+ $context = [ 'source' => $source ];
99
+ if ( is_array( $data ) ) {
100
+ if ( isset( $data['source'] ) ) {
101
+ unset( $data['source'] );
102
+ }
103
+ $context = array_merge( $context, $data );
104
+ } else {
105
+ $context['data'] = $data;
106
+ }
107
+ $loggers = [ woo_feed_get_logger() ];
108
+ if ( true === $wc_log ) {
109
+ $loggers[] = wc_get_logger();
110
+ }
111
+ foreach ( $loggers as $logger ) {
112
+ if ( is_callable( [ $logger, $level ] ) ) {
113
+ $logger->$level( $message . PHP_EOL, $context );
114
+ }
115
+ }
116
+ }
117
+ }
118
+ }
119
+ if ( ! function_exists( 'woo_feed_log_fatal_error' ) ) {
120
+ /**
121
+ * Log Fatal Errors in both wc-logs and woo-feed/logs
122
+ *
123
+ * @param string $message The log message.
124
+ * @param mixed $data Extra data for the log handler.
125
+ */
126
+ function woo_feed_log_fatal_error( $message, $data = null ) {
127
+ // woocommerce use 'fatal-errors' as log handler...
128
+ // make no conflicts with woocommerce fatal-errors logs
129
+ woo_feed_log( 'woo-feed-fatal-errors', $message, 'critical', $data, true, true );
130
+ }
131
+ }
132
+ if ( ! function_exists( 'woo_feed_log_debug_message' ) ) {
133
+ /**
134
+ * Log Fatal Errors in both wc-logs and woo-feed/logs
135
+ *
136
+ * @param string $message The log message.
137
+ * @param mixed $data Extra data for the log handler.
138
+ */
139
+ function woo_feed_log_debug_message( $message, $data = null ) {
140
+ // woocommerce use 'fatal-errors' as log handler...
141
+ // make no conflicts with woocommerce fatal-errors logs
142
+ woo_feed_log( 'woo-feed-fatal-errors', $message, 'debug', $data, true, true );
143
+ }
144
+ }
145
+ if ( ! function_exists( 'woo_feed_delete_log' ) ) {
146
+ /**
147
+ * Delete Log file by source or handle name
148
+ *
149
+ * @param string $source log source or handle name
150
+ * @param bool $handle use source as handle
151
+ *
152
+ * @return bool
153
+ */
154
+ function woo_feed_delete_log( $source, $handle = false ) {
155
+ try {
156
+ if ( 'woo-feed-fatal-errors' == $source ) {
157
+ // fatal error are also logged in wc-logs dir.
158
+ if ( class_exists( 'WC_Log_Handler_File', false ) ) {
159
+ $log_handler = new WC_Log_Handler_File();
160
+ $log_handler->remove( false == $handle ? WC_Log_Handler_File::get_log_file_name( $source ) : $source );
161
+ }
162
+ }
163
+ $feed_log_handler = new Woo_Feed_Log_Handler_File();
164
+ return $feed_log_handler->remove( false == $handle ? Woo_Feed_Log_Handler_File::get_log_file_name( $source ) : $source );
165
+ } catch ( Exception $e ) {
166
+ return false;
167
+ }
168
+ }
169
+ }
170
+ if ( ! function_exists( 'woo_feed_delete_all_logs' ) ) {
171
+ function woo_feed_delete_all_logs() {
172
+ // delete the fatal error log
173
+ woo_feed_delete_log( 'woo-feed-fatal-errors' );
174
+ // get all logs
175
+ $logs = Woo_Feed_Log_Handler_File::get_log_files();
176
+ foreach ( array_values( $logs ) as $log ) {
177
+ woo_feed_delete_log( $log, true );
178
+ }
179
+ }
180
+ }
181
+ if ( ! function_exists( 'woo_feed_log_feed_process' ) ) {
182
+ /**
183
+ * Log Feed Generation Progress to individual log file.
184
+ *
185
+ * @since 3.2.1
186
+ *
187
+ * @param string $feed_name Feed name, will be use for log file name.
188
+ * @param string $message Log message.
189
+ * @param mixed $data Extra data for the log handler.
190
+ * @param bool $force_log ignore debugging settings
191
+ *
192
+ * @return void
193
+ */
194
+ function woo_feed_log_feed_process( $feed_name, $message, $data = null, $force_log = false ) {
195
+ woo_feed_log( $feed_name, $message, 'debug', $data, $force_log, false );
196
+ }
197
+ }
198
+ if ( ! function_exists( 'woo_feed_cleanup_logs' ) ) {
199
+ /**
200
+ * Trigger logging cleanup using the logging class.
201
+ * @return void
202
+ */
203
+ function woo_feed_cleanup_logs() {
204
+ $logger = woo_feed_get_logger();
205
+ // @TODO dont' clear all logs.
206
+ // @TODO clear only the error log.
207
+ // @TODO change shutdown function and send the main error log to wc-logs directory.
208
+ if ( is_callable( array( $logger, 'clear_expired_logs' ) ) ) {
209
+ $logger->clear_expired_logs();
210
+ }
211
+ }
212
+ }
213
+
214
+ // End of file log-helper.php.
woo-feed.php CHANGED
@@ -12,7 +12,7 @@
12
  * Description: This plugin generate WooCommerce product feed for Shopping Engines
13
  * like Google Shopping, Facebook Product Feed, eBay, Amazon, Idealo and many more.
14
  *
15
- * Version: 3.2.19
16
  * Author: WebAppick
17
  * Author URI: https://webappick.com/
18
  * License: GPL v2
@@ -40,10 +40,10 @@ if ( ! defined( 'WOO_FEED_FREE_VERSION' ) ) {
40
  * @var string
41
  * @since 3.1.6
42
  */
43
- define( 'WOO_FEED_FREE_VERSION', '3.2.19' );
44
  }
45
 
46
- if ( ! defined( 'WOO_FEED_FREE_FILE') ) {
47
  /**
48
  * Plugin Base File
49
  * @since 3.1.41
@@ -82,7 +82,7 @@ if ( ! defined( 'WOO_FEED_PLUGIN_URL' ) ) {
82
  * @var string
83
  * @since 3.1.37
84
  */
85
- define( 'WOO_FEED_PLUGIN_URL', trailingslashit( plugin_dir_url(WOO_FEED_FREE_FILE ) ) );
86
  }
87
  if ( ! defined( 'WOO_FEED_MIN_PHP_VERSION' ) ) {
88
  /**
@@ -94,7 +94,7 @@ if ( ! defined( 'WOO_FEED_MIN_PHP_VERSION' ) ) {
94
  }
95
  if ( ! defined( 'WOO_FEED_MIN_WC_VERSION' ) ) {
96
  /**
97
- * Minimum PHP Version Supported
98
  * @var string
99
  * @since 3.1.45
100
  */
@@ -106,11 +106,11 @@ if ( ! defined( 'WOO_FEED_PLUGIN_BASE_NAME' ) ) {
106
  * @var string
107
  * @since 3.1.41
108
  */
109
- define( 'WOO_FEED_PLUGIN_BASE_NAME', plugin_basename(WOO_FEED_FREE_FILE ) );
110
  }
111
 
112
  if ( ! defined( 'WOO_FEED_LOG_DIR' ) ) {
113
- $upload_dir = wp_upload_dir();
114
  /**
115
  * Log Directory
116
  * @var string
@@ -127,7 +127,12 @@ require_once WOO_FEED_FREE_PATH . 'includes/classes/class-woo-feed-webappick-api
127
  /**
128
  * Load Helper functions
129
  */
 
130
  require_once WOO_FEED_FREE_PATH . 'includes/helper.php';
 
 
 
 
131
  /**
132
  * Installer
133
  */
@@ -155,6 +160,7 @@ if ( ! function_exists( 'run_woo_feed' ) ) {
155
  $plugin = new Woo_Feed();
156
  register_activation_hook( WOO_FEED_FREE_FILE, [ 'Woo_Feed_installer', 'install' ] );
157
  //register_shutdown_function( 'woo_feed_log_errors_at_shutdown' );
 
158
  /**
159
  * Ensure Feed Plugin runs only if WooCommerce loaded (installed and activated)
160
  * @since 3.1.41
@@ -166,36 +172,14 @@ if ( ! function_exists( 'run_woo_feed' ) ) {
166
 
167
  run_woo_feed();
168
  }
169
- // Log cleaner.
170
- if ( ! function_exists( 'woo_feed_cleanup_logs' ) ) {
171
- /**
172
- * Trigger logging cleanup using the logging class.
173
- *
174
- * @since 3.4.0
175
- */
176
- function woo_feed_cleanup_logs() {
177
- $logger = woo_feed_get_logger();
178
- // @TODO dont' clear all logs.
179
- // @TODO clear only the error log.
180
- // @TODO change shutdown function and send the main error log to wc-logs directory.
181
- if ( is_callable( array( $logger, 'clear_expired_logs' ) ) ) {
182
- $logger->clear_expired_logs();
183
- }
184
- }
185
-
186
- add_action( 'woo_feed_cleanup_logs', 'woo_feed_cleanup_logs' );
187
- }
188
 
189
- #======================================================================================================================*
190
- #
191
- # Ajax Feed Making Development Start
192
- #
193
- #======================================================================================================================*
194
  if ( ! function_exists( 'woo_feed_get_product_information' ) ) {
195
- add_action('wp_ajax_get_product_information', 'woo_feed_get_product_information');
196
- /**
197
- * Count Total Products
198
- */
199
  /**
200
  * Count Total Products
201
  */
@@ -207,12 +191,18 @@ if ( ! function_exists( 'woo_feed_get_product_information' ) ) {
207
  die();
208
  }
209
  // @TODO use only WC_Product_Query it's available from WC 3.2, we don't support earlier versions of wc.
210
- if ( woo_feed_wc_version_check( 3.2 ) && isset( $_REQUEST['feed'] ) ) {
211
- $feed = sanitize_text_field( $_REQUEST['feed'] );
212
- $limit = isset( $_REQUEST['limit'] ) ? absint( $_REQUEST['limit'] ) : 200;
213
- $getConfig = maybe_unserialize( get_option( $feed ) );
 
 
 
 
 
 
214
  // if ( woo_feed_is_debugging_enabled() ) {
215
- // clear log, set the pointer to the beginning of the file.
216
  // woo_feed_delete_log( $getConfig['filename'] );
217
  // woo_feed_log_feed_process( $getConfig['filename'], sprintf( 'Getting Data for %s feed.', $feed ) );
218
  // woo_feed_log_feed_process( $getConfig['filename'], 'Generating Feed VIA Ajax...' );
@@ -221,11 +211,13 @@ if ( ! function_exists( 'woo_feed_get_product_information' ) ) {
221
  // woo_feed_log( $getConfig['filename'], 'Feed Config::' . PHP_EOL . print_r( $getConfig, true ), 'info' );
222
  // }
223
  try {
 
224
  $products = new Woo_Feed_Products_v3( $getConfig );
225
  $ids = $products->query_products();
 
226
  // woo_feed_log_feed_process( $getConfig['filename'], sprintf( 'Total %d product found', is_array( $ids ) && ! empty( $ids ) ? count( $ids ) : 0 ) );
227
  if ( is_array( $ids ) && ! empty( $ids ) ) {
228
- if ( count( $ids ) > $limit ) {
229
  $batches = array_chunk( $ids, $limit );
230
  } else {
231
  $batches = array( $ids );
@@ -263,7 +255,9 @@ if ( ! function_exists( 'woo_feed_get_product_information' ) ) {
263
  wp_die();
264
  }
265
  } else {
 
266
  $products = wp_count_posts( 'product' );
 
267
  if ( $products->publish > 0 ) {
268
  $data['success'] = true;
269
  wp_send_json_success(
@@ -291,458 +285,307 @@ if ( ! function_exists( 'woo_feed_make_batch_feed' ) ) {
291
  * Ajax Batch Callback
292
  * @return void
293
  */
294
- function woo_feed_make_batch_feed(){
295
- check_ajax_referer('wpf_feed_nonce');
296
  if ( ! current_user_can( 'manage_woocommerce' ) ) {
297
  // woo_feed_log_debug_message( 'User doesnt have enough permission.' );
298
  wp_send_json_error( esc_html__( 'Unauthorized Action.', 'woo-feed' ) );
299
  die();
300
  }
301
- //$limit=sanitize_text_field($_POST['limit']);
302
- //$offset=sanitize_text_field($_POST['offset']);
303
- $feedName = str_replace( "wf_feed_", "", sanitize_text_field( $_POST['feed'] ) );
304
- $feedInfo = get_option( $feedName );
 
 
 
305
 
306
  if ( ! $feedInfo ) {
307
- $getFeedConfig = unserialize(get_option($feedName));
308
- $feedInfo = $getFeedConfig['feedrules'];
309
  }
310
 
311
- $products = array_map( 'absint', $_REQUEST['products'] );
312
- $offset = absint( $_REQUEST['loop'] );
313
- $feedInfo['productIds'] = $products;
314
-
 
 
 
 
 
 
 
 
 
 
 
315
 
316
- if ( $offset == 0 ) {
317
- $fileName = str_replace(" ", "",$feedInfo['filename']);
318
- $type = $feedInfo['feedType'];
319
  $feedService = $feedInfo['provider'];
320
- if ( $type == "csv" ) {
321
- $type = "json";
322
  }
323
-
324
- $upload_dir = wp_upload_dir();
325
- $base = $upload_dir['basedir'];
326
- $path = $base . "/woo-feed/" . $feedService . "/" . $type;
327
-
328
- $tempFiles['headerFile'] = $path . "/" . "wf_store_feed_header_info_".$fileName . "." . $type;
329
- $tempFiles['bodyFile'] = $path . "/" . "wf_store_feed_body_info_".$fileName . "." . $type;
330
- $tempFiles['footerFile'] = $path . "/" . "wf_store_feed_footer_info_".$fileName . "." . $type;
331
-
332
- woo_feed_unlink_tempFiles($tempFiles);
333
  }
334
-
335
-
336
- // $feedInfo['Limit']=$limit;
337
- // $feedInfo['Offset']=$offset;
338
-
339
- $feed_data = woo_feed_generate_feed_data($feedInfo);
340
  if ( $feed_data ) {
341
- $data = array(
342
- "success" => true,
343
- "products" => "yes",
 
 
 
344
  );
345
- wp_send_json_success($data);
346
- die();
347
- }else {
348
- $data = array(
349
- "success" => true,
350
- "products" => "no",
 
 
351
  );
352
- wp_send_json_success($data);
353
- die();
354
  }
 
355
  }
356
  }
357
  if ( ! function_exists( 'woo_feed_save_feed_file' ) ) {
358
- add_action('wp_ajax_save_feed_file', 'woo_feed_save_feed_file');
359
- function woo_feed_save_feed_file(){
360
-
361
- check_ajax_referer('wpf_feed_nonce');
 
 
 
 
362
  if ( ! current_user_can( 'manage_woocommerce' ) ) {
363
  // woo_feed_log_debug_message( 'User doesnt have enough permission.' );
364
  wp_send_json_error( esc_html__( 'Unauthorized Action.', 'woo-feed' ) );
365
  die();
366
  }
367
- $feed = str_replace("wf_feed_", "", sanitize_text_field( $_REQUEST['feed'] ) );
368
- $info = get_option($feed);
 
 
 
 
 
 
369
  if ( ! $info ) {
370
- $getInfo = unserialize(get_option( sanitize_text_field( $_REQUEST['feed'] ) ));
371
- $info = $getInfo['feedrules'];
372
  }
373
 
374
  $feedService = $info['provider'];
375
- $fileName = str_replace(" ", "",$info['filename']);
376
- $type = $info['feedType'];
377
-
378
- $feedHeader = woo_feed_get_batch_feed_info($feedService,$type,"wf_store_feed_header_info_".$fileName);
379
- $feedBody = woo_feed_get_batch_feed_info($feedService,$type,"wf_store_feed_body_info_".$fileName);
380
- $feedFooter = woo_feed_get_batch_feed_info($feedService,$type,"wf_store_feed_footer_info_".$fileName);
 
 
 
381
 
382
- if ( $type == 'csv' ) {
383
  $csvHead[0] = $feedHeader;
384
- if ( ! empty($csvHead) && ! empty($feedBody) ) {
385
- $string = array_merge($csvHead,$feedBody);
386
- }else {
387
  $string = array();
388
  }
389
- }else {
390
- $string = $feedHeader.$feedBody.$feedFooter;
391
  }
392
 
393
- $upload_dir = wp_upload_dir();
394
- $base = $upload_dir['basedir'];
395
- $path = $base . "/woo-feed/" . $feedService . "/" . $type;
396
- $saveFile = false;
397
- # Check If any products founds
398
- if ( $string && ! empty($string) ) {
399
- # Save File
400
- $file = $path . "/" . $fileName . "." . $type;
 
401
  $save = new Woo_Feed_Savefile();
402
- if ( $type == "csv" ) {
403
- $saveFile = $save->saveCSVFile($path, $file, $string, $info);
404
  } else {
405
- $saveFile = $save->saveFile($path, $file, $string);
406
  }
407
- }else {
408
- $data = array(
409
- "success" => false,
410
- "message" => "No Product Found with your feed configuration. Please configure the feed properly.",
411
- );
412
- wp_send_json_error($data);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
413
  wp_die();
414
  }
415
 
416
-
417
- # Save Info into database
418
- $url = $upload_dir['baseurl'] . "/woo-feed/" . $feedService . "/" . $type . "/" . $fileName . "." . $type;
419
  $feedInfo = array(
420
  'feedrules' => $info,
421
- 'url' => $url,
422
- 'last_updated' => gmdate("Y-m-d H:i:s"),
423
  );
424
-
425
- $feedOldInfo = unserialize( get_option( "wf_feed_".$fileName ) );
426
  if ( isset( $feedOldInfo['status'] ) ) {
427
  $feedInfo['status'] = $feedOldInfo['status'];
428
- }else {
429
  $feedInfo['status'] = 1;
430
  }
431
 
432
- if ( ! empty($name) && $name != "wf_feed_" . $fileName ) {
433
- delete_option($name);
434
  }
435
 
436
- //delete_option("wf_config".$fileName);
437
- delete_option("wf_store_feed_header_info_".$fileName);
438
- delete_option("wf_store_feed_body_info_".$fileName);
439
- delete_option("wf_store_feed_footer_info_".$fileName);
440
-
441
- if ($type == "csv") $type = "json";
442
 
443
- # Remove Temp feed files
444
- $tempFiles['headerFile'] = $path . "/" . "wf_store_feed_header_info_".$fileName . "." . $type;
445
- $tempFiles['bodyFile'] = $path . "/" . "wf_store_feed_body_info_".$fileName . "." . $type;
446
- $tempFiles['footerFile'] = $path . "/" . "wf_store_feed_footer_info_".$fileName . "." . $type;
447
 
448
- woo_feed_unlink_tempFiles($tempFiles);
449
- update_option('wf_feed_' . $fileName, serialize($feedInfo));
450
  if ( $saveFile ) {
 
 
451
 
452
- # FTP File Upload Info
453
- $ftpHost = $info['ftphost'];
454
- $ftpUser = $info['ftpuser'];
455
- $ftpPassword = $info['ftppassword'];
456
- $ftpPath = $info['ftppath'];
457
- $ftpEnabled = $info['ftpenabled'];
458
- $ftporsftp = isset($info['ftporsftp']) ? $info['ftporsftp'] : "ftp";
459
- $ftpPort = isset($info['ftpport']) && ! empty($info['ftpport']) ? $info['ftpport'] : 21;
460
- try {
461
- if ($type == "json") $type = "csv";
462
- # Upload file to ftp server
463
- if ( $ftpEnabled ) {
464
- if ( $ftporsftp == "ftp" ) {
465
- $ftp = new FTPClient();
466
- if ( $ftp->connect($ftpHost, $ftpUser, $ftpPassword,false,$ftpPort) ) {
467
- $ftp->uploadFile($file, $fileName . "." . $type);
468
- }
469
- } elseif ( $ftporsftp == "sftp" && extension_loaded ( 'ssh2' ) ) {
470
- $sftp = new SFTPConnection($ftpHost, $ftpPort);
471
- $sftp->login($ftpUser, $ftpPassword);
472
- $sftp->uploadFile($file, "/".$fileName . "." . $type);
473
- }
474
- }
475
- }catch ( Exception $e ) {}
476
- $getInfo = unserialize(get_option('wf_feed_' . $fileName));
477
- $url = $getInfo['url'];
478
-
479
- $cat = woo_feed_check_google_category($feedInfo);
480
 
481
- $data = array(
482
- "info" => $feedInfo,
483
- "url" => $url,
484
- "cat" => $cat,
485
- "message" => "Feed Making Complete",
 
 
 
486
  );
487
- wp_send_json_success($data);
 
488
  } else {
 
489
  $data = array(
490
- "success" => false,
491
- "message" => esc_html__( 'Failed to save feed file. Please confirm that your WordPress directory have Read and Write permission.', 'woo-feed' ),
492
  );
493
- wp_send_json_error($data);
494
  }
495
-
496
  wp_die();
497
  }
498
  }
499
- // Ajax Helper
500
- if ( ! function_exists( 'woo_feed_generate_feed_data' ) ) {
501
- function woo_feed_generate_feed_data( $info ) {
502
-
 
 
 
 
 
 
 
 
 
503
  try {
504
- if ( count($info) && isset($info['provider']) ) {
505
- # GEt Post data
506
- if ( $info['provider'] == 'google' || $info['provider'] == 'adroll' || $info['provider'] == 'smartly.io' ) {
507
- $merchant = "Woo_Feed_Google";
508
- } elseif ( $info['provider'] == 'pinterest' ) {
509
- $merchant = "Woo_Feed_Pinterest";
510
- } elseif ( $info['provider'] == 'facebook' ) {
511
- $merchant = "Woo_Feed_Facebook";
512
- }elseif ( strpos($info['provider'],'amazon') !== FALSE ) {
513
- $merchant = "Woo_Feed_Amazon";
514
- }elseif ( $info['provider'] == 'custom2' ) {
515
- $merchant = "Woo_Feed_Custom2";
516
- } else {
517
- $merchant = "Woo_Feed_Custom";
518
- }
519
-
520
- $feedService = sanitize_text_field($info['provider']);
521
- $fileName = str_replace(" ", "", sanitize_text_field($info['filename']));
522
- $type = sanitize_text_field($info['feedType']);
523
-
524
- $feedRules = $info;
525
-
526
- # Get Feed info
527
- $products = new Woo_Generate_Feed($merchant, $feedRules);
528
  $feed = $products->getProducts();
529
- if ( isset($feed['body']) && ! empty($feed['body']) ) {
530
- $feedHeader = "wf_store_feed_header_info_".$fileName;
531
- $feedBody = "wf_store_feed_body_info_".$fileName;
532
- $feedFooter = "wf_store_feed_footer_info_".$fileName;
533
- $prevFeed = woo_feed_get_batch_feed_info( $feedService, $type, $feedBody );
534
  if ( $prevFeed ) {
535
- if ( $type == 'csv' ) {
536
- if ( ! empty($prevFeed) ) {
537
  $newFeed = array_merge( $prevFeed, $feed['body'] );
538
  woo_feed_save_batch_feed_info( $feedService, $type, $newFeed, $feedBody, $info );
539
  }
540
- }else {
541
- $newFeed = $prevFeed.$feed['body'];
542
  woo_feed_save_batch_feed_info( $feedService, $type, $newFeed, $feedBody, $info );
543
- }
544
- }else {
545
- woo_feed_save_batch_feed_info( $feedService, $type, $feed['body'], $feedBody, $info );
546
- }
547
- woo_feed_save_batch_feed_info( $feedService, $type, $feed['header'], $feedHeader, $info );
548
- woo_feed_save_batch_feed_info( $feedService, $type,$feed['footer'], $feedFooter, $info );
549
- return true;
550
- }else {
551
- return false;
552
- }
553
- }
554
- }catch ( Exception $e ) {
555
- return false;
556
- }
557
- return false;
558
- }
559
- }
560
-
561
- // Cron Action
562
- if ( ! function_exists( 'woo_feed_cron_update_feed' ) ) {
563
- /**
564
- * Scheduled Action Hook
565
- */
566
- function woo_feed_cron_update_feed() {
567
- global $wpdb;
568
- $query = $wpdb->prepare( "SELECT option_name FROM $wpdb->options WHERE option_name LIKE %s;", "wf_feed_%" );
569
- $result = $wpdb->get_results( $query, 'ARRAY_A' );
570
- foreach ( $result as $key => $value ) {
571
- $feedInfo = maybe_unserialize( get_option( $value['option_name'] ) );
572
- if ( ! isset( $feedInfo['feedrules'] ) || isset( $feedInfo['status'] ) && $feedInfo['status'] == "0" ) continue;
573
- woo_feed_add_update( $feedInfo['feedrules'] );
574
- }
575
- }
576
- add_action('woo_feed_update', 'woo_feed_cron_update_feed');
577
- }
578
- // Single Feed Update Cron
579
- if ( ! function_exists( 'woo_feed_cron_update_single_feed' ) ) {
580
- /**
581
- * Scheduled Action Hook
582
- * @param array $feedName
583
- * @return void
584
- */
585
- function woo_feed_cron_update_single_feed( $feedName ) {
586
- global $wpdb;
587
- $feedName = "wf_feed_".$feedName[0];
588
- $result = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->options WHERE option_name = %s", $feedName ),'ARRAY_A');
589
- if ( ! empty( $result ) ) {
590
- foreach ( $result as $key => $value ) {
591
- $feedInfo = maybe_unserialize( get_option( $value['option_name'] ) );
592
- if ( ! isset( $feedInfo['feedrules'] ) || isset( $feedInfo['status'] ) && $feedInfo['status'] == "0" ) continue;
593
- woo_feed_add_update( $feedInfo['feedrules'] );
594
- }
595
- }
596
- }
597
- add_action( 'woo_feed_update_single_feed', 'woo_feed_cron_update_single_feed' );
598
- }
599
- // Cron Helper
600
- if ( ! function_exists( 'woo_feed_add_update' ) ) {
601
- /**
602
- * Update Feed Information
603
- * @param array $info
604
- * @param string $name
605
- * @return string|bool
606
- */
607
- function woo_feed_add_update( $info = array(), $name = "" ) {
608
- if ( count($info) && isset($info['provider']) ) {
609
- # GEt Post data
610
- if ( $info['provider'] == 'google' || $info['provider'] == 'adroll' || $info['provider'] == 'smartly.io' ) {
611
- $merchant = "Woo_Feed_Google";
612
- } elseif ( $info['provider'] == 'pinterest' ) {
613
- $merchant = "Woo_Feed_Pinterest";
614
- } elseif ( $info['provider'] == 'facebook' ) {
615
- $merchant = "Woo_Feed_Facebook";
616
- }elseif ( strpos($info['provider'],'amazon') !== FALSE ) {
617
- $merchant = "Woo_Feed_Amazon";
618
- } else {
619
- $merchant = "Woo_Feed_Custom";
620
- }
621
-
622
-
623
- $feedService = sanitize_text_field($info['provider']);
624
- $fileName = str_replace(" ", "", sanitize_text_field($info['filename']));
625
- $type = sanitize_text_field($info['feedType']);
626
-
627
- $feedRules = $info;
628
-
629
- # Get Feed info
630
- $products = new Woo_Generate_Feed($merchant, $feedRules);
631
- $getString = $products->getProducts();
632
-
633
- if ( $type == 'csv' ) {
634
- $csvHead[0] = $getString['header'];
635
- if ( ! empty($csvHead) && ! empty($getString['body']) ) {
636
- $string = array_merge($csvHead,$getString['body']);
637
- }else {
638
- $string = array();
639
- }
640
- }else {
641
- $string = $getString['header'].$getString['body'].$getString['footer'];
642
- }
643
-
644
- # Check If any products founds
645
- if ( $string && ! empty($string) ) {
646
-
647
- $upload_dir = wp_upload_dir();
648
- $base = $upload_dir['basedir'];
649
-
650
- # Save File
651
- $path = $base . "/woo-feed/" . $feedService . "/" . $type;
652
- $file = $path . "/" . $fileName . "." . $type;
653
- $save = new Woo_Feed_Savefile();
654
- if ( $type == "csv" ) {
655
- $saveFile = $save->saveCSVFile($path, $file, $string, $info);
656
- } else {
657
- $saveFile = $save->saveFile($path, $file, $string);
658
- }
659
-
660
- # FTP File Upload Info
661
- $ftpHost = sanitize_text_field($info['ftphost']);
662
- $ftpUser = sanitize_text_field($info['ftpuser']);
663
- $ftpPassword = sanitize_text_field($info['ftppassword']);
664
- $ftpPath = sanitize_text_field($info['ftppath']);
665
- $ftpPort = isset($info['ftpport']) && ! empty($info['ftpport']) ? sanitize_text_field($info['ftpport']) : 21;
666
- $ftpEnabled = sanitize_text_field($info['ftpenabled']);
667
-
668
- $ftporsftp = isset($info['ftporsftp']) ? sanitize_text_field($info['ftporsftp']) : "ftp";
669
-
670
-
671
- try {
672
- if ( $type == "json" ) {
673
- $type = "csv";
674
- }
675
- # Upload file to ftp server
676
- if ( $ftpEnabled ) {
677
- if ( $ftporsftp == "ftp" ) {
678
- $ftp = new FTPClient();
679
- if ( $ftp->connect($ftpHost, $ftpUser, $ftpPassword,false,$ftpPort) ) {
680
- $ftp->uploadFile($file, $fileName . "." . $type);
681
- }
682
- } elseif ( $ftporsftp == "sftp" && extension_loaded ( 'ssh2' ) ) {
683
- $sftp = new SFTPConnection($ftpHost, $ftpPort);
684
- $sftp->login($ftpUser, $ftpPassword);
685
- $sftp->uploadFile($file, "/".$fileName . "." . $type);
686
  }
 
 
687
  }
688
- }catch ( Exception $e ) {
689
-
690
- }
691
-
692
- # Save Info into database
693
- $url = $upload_dir['baseurl'] . "/woo-feed/" . $feedService . "/" . $type . "/" . $fileName . "." . $type;
694
- $feedInfo = array(
695
- 'feedrules' => $feedRules,
696
- 'url' => $url,
697
- 'last_updated' => gmdate("Y-m-d H:i:s"),
698
- 'status' => 1,
699
- );
700
-
701
-
702
- if ( ! empty($name) && $name != "wf_feed_" . $fileName ) {
703
- delete_option($name);
704
- }
705
-
706
- $update = update_option('wf_feed_' . $fileName, serialize($feedInfo));
707
- if ( $saveFile ) {
708
- $getInfo = unserialize(get_option('wf_feed_' . $fileName));
709
- $url = $getInfo['url'];
710
- return $url;
711
  } else {
712
- return false;
713
  }
714
  }
 
 
 
 
 
 
 
715
  }
716
- return false;
717
  }
718
  }
719
 
720
- if ( ! function_exists( 'woo_feed_generate_feed' ) ) {
 
721
  /**
722
  * Generate Feed
723
  */
724
- function woo_feed_generate_feed() {
725
  if ( isset( $_POST['provider'], $_POST['_wpnonce'], $_POST['filename'], $_POST['feedType'] ) ) {
726
- # Verify Nonce
727
  if ( ! wp_verify_nonce( sanitize_text_field( $_POST['_wpnonce'] ), 'woo_feed_form_nonce' ) ) {
728
- wp_die( 'Failed security check' );
729
  }
730
- # Check feed type (file ext)
731
- if ( ! in_array( $_POST['feedType'], array( 'xml', 'csv', 'txt', 'tsv' ) ) ) {
732
- wp_die( 'Invalid Feed Type!' );
733
  }
734
 
735
  $fileName = woo_feed_save_feed_config_data( $_POST );
736
- # Schedule Cron
737
- $arg = array( $fileName );
738
-
739
- wp_schedule_event(time(), 'woo_feed_corn', 'woo_feed_update_single_feed', $arg );
740
 
741
- wp_safe_redirect( add_query_arg( [
742
- 'feed_created' => (int) false !== $fileName,
743
- 'feed_regenerate' => 1,
744
- 'feed_name' => $fileName ? $fileName : '',
745
- ], admin_url( 'admin.php?page=webappick-manage-feeds' ) ) );
 
 
 
 
 
746
  die();
747
  } else {
748
  require WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-admin-display.php';
@@ -754,112 +597,137 @@ if ( ! function_exists( 'woo_feed_manage_feed' ) ) {
754
  * Manage Feeds
755
  */
756
  function woo_feed_manage_feed() {
757
- // Manage action for category mapping
758
- if ( isset( $_GET['action'] ) && $_GET['action'] == 'edit-feed' ) {
 
759
  if ( ! defined( 'WOO_FEED_EDIT_CONFIG' ) ) define( 'WOO_FEED_EDIT_CONFIG', true );
760
- if ( count( $_POST ) && isset( $_POST['provider'], $_POST['feed_id'], $_POST['filename'], $_POST['feedType'] ) ) {
761
- # Verify Nonce
762
- if ( ! wp_verify_nonce( sanitize_text_field( $_POST['_wpnonce'] ), 'wf_edit_feed' ) ) {
763
- wp_die( 'Failed security check' );
764
  }
765
- # Check feed type (file ext)
766
- if ( ! in_array( $_POST['feedType'], array( 'xml', 'csv', 'txt', 'tsv' ) ) ) {
767
- wp_die( 'Invalid Feed Type!' );
768
  }
 
769
  // check if name is changed... save as new, rename feed isn't implemented ... it can be...
770
  // @TODO delete old feed save data as new feed.
771
- // old/original name
772
- $original_name = ( isset( $_POST['original_feed_name'] ) && ! empty( $_POST['original_feed_name'] ) ) ? sanitize_text_field( $_POST['original_feed_name'] ) : '';
773
- $fileName = sanitize_text_field( $_POST['filename'] );
774
- $fileName = ( $original_name === $fileName ) ? $fileName : null;
775
-
776
  // if form submitted via $_POST['edit-feed'] then only config and regenerate otherwise only update the config...
777
  // no need to check other submit button ... eg. $_POST['save_feed_config']
778
- $fileName = woo_feed_save_feed_config_data( $_POST, $fileName, isset( $_POST['edit-feed'] ) );
779
  // redirect to the feed list with status
780
  // @TODO this should be handled in admin_init action for proper redirection to work...
781
- wp_safe_redirect( add_query_arg( [
782
- 'feed_updated' => (int) false !== $fileName,
783
- 'feed_regenerate' => (int) isset( $_POST['edit-feed'] ),
784
- 'feed_name' => $fileName ? $fileName : '',
785
- ], admin_url( 'admin.php?page=webappick-manage-feeds' ) ) );
 
 
 
 
 
786
  die();
787
  }
788
-
789
  if ( isset( $_GET['feed'] ) && ! empty( $_GET['feed'] ) ) {
790
-
791
- global $wpdb, $feedRules, $fname, $feedId, $provider;
792
- $fname = sanitize_text_field( $_GET['feed'] );
793
- $feedInfo = unserialize( get_option( $fname ) );
794
- $feedId = $wpdb->get_row( $wpdb->prepare( "SELECT option_id FROM $wpdb->options WHERE option_name = %s LIMIT 1", $fname ) );
795
- if ( $feedId ) $feedId = $feedId->option_id;
796
- $provider = strtolower( $feedInfo['feedrules']['provider'] );
797
- $feedRules = $feedInfo['feedrules'];
798
-
799
- require WOO_FEED_FREE_ADMIN_PATH . "partials/woo-feed-edit-template.php";
 
 
 
 
 
 
 
 
 
 
 
 
 
800
  }
801
  } else {
802
- # Update Interval
803
  if ( isset( $_POST['wf_schedule'] ) ) {
804
- if ( isset( $_POST['wf_schedule_nonce'] ) && wp_verify_nonce( sanitize_text_field( $_POST['wf_schedule_nonce'] ),'wf_schedule' ) ) {
805
  $interval = absint( $_POST['wf_schedule'] );
806
  if ( $interval >= woo_feed_get_minimum_interval_option() ) {
807
- if ( update_option('wf_schedule', sanitize_text_field( $_POST['wf_schedule'] ) ) ) {
808
- wp_clear_scheduled_hook('woo_feed_update');
809
- add_filter( 'cron_schedules', 'Woo_Feed_installer::cron_schedules' );
810
  wp_schedule_event( time(), 'woo_feed_corn', 'woo_feed_update' );
811
- $update = 1; // success
812
- } else $update = 2; // db fail
813
- } else $update = 3; // invalid value
814
- } else $update = 4; // invalid nonce
 
 
 
 
 
 
815
  wp_safe_redirect( add_query_arg( [ 'schedule_updated' => $update ], admin_url( 'admin.php?page=webappick-manage-feeds' ) ) );
816
  die();
817
  }
818
- require WOO_FEED_FREE_ADMIN_PATH . "partials/woo-feed-manage-list.php";
819
  }
820
  }
821
  }
822
- // Get Merchant template
 
823
  if ( ! function_exists( 'feed_merchant_view' ) ) {
824
- # Load Feed Templates
825
- add_action('wp_ajax_get_feed_merchant', 'feed_merchant_view');
 
 
 
 
826
  function feed_merchant_view() {
827
- check_ajax_referer('wpf_feed_nonce');
828
  if ( ! current_user_can( 'manage_woocommerce' ) ) {
829
  // woo_feed_log_debug_message( 'User doesnt have enough permission.' );
830
  wp_send_json_error( esc_html__( 'Unauthorized Action.', 'woo-feed' ) );
831
  die();
832
  }
833
- $merchant = $provider = isset( $_REQUEST['merchant'] ) && ! empty( $_REQUEST['merchant'] ) ? sanitize_text_field( $_REQUEST['merchant'] ) : '';
834
- if ( empty( $merchant ) ) wp_die();
835
- ob_start();
836
- /** @noinspection PhpUnusedLocalVariableInspection */
837
- $dropDown = new Woo_Feed_Dropdown();
838
- /** @noinspection PhpUnusedLocalVariableInspection */
839
- $product = new Woo_Feed_Products();
840
- /** @noinspection PhpUnusedLocalVariableInspection */
841
- $attributes = new Woo_Feed_Default_Attributes();
842
-
843
- if ( $merchant == 'smartly.io' ) {
844
- include WOO_FEED_FREE_ADMIN_PATH . "partials/templates/google_add-feed.php";
845
- } elseif ( file_exists(WOO_FEED_FREE_ADMIN_PATH . "partials/templates/" . $merchant . "_add-feed.php") ) {
846
- include WOO_FEED_FREE_ADMIN_PATH . "partials/templates/" . $merchant . "_add-feed.php";
847
- } else {
848
- include WOO_FEED_FREE_ADMIN_PATH . "partials/templates/common_add-feed.php";
849
  }
 
 
 
 
 
 
850
  wp_send_json_success( ob_get_clean() );
851
- die();
852
  }
853
  }
854
- // Get Google Categories
855
  if ( ! function_exists( 'woo_feed_get_google_categories' ) ) {
856
  add_action( 'wp_ajax_get_google_categories', 'woo_feed_get_google_categories' );
 
 
 
 
857
  function woo_feed_get_google_categories() {
858
- check_ajax_referer('wpf_feed_nonce');
859
  if ( ! current_user_can( 'manage_woocommerce' ) ) {
860
  // woo_feed_log_debug_message( 'User doesnt have enough permission.' );
861
  wp_send_json_error( esc_html__( 'Unauthorized Action.', 'woo-feed' ) );
862
- die();
863
  }
864
  $wooFeedDropDown = new Woo_Feed_Dropdown();
865
  wp_send_json_success( $wooFeedDropDown->googleTaxonomyArray() );
@@ -868,43 +736,50 @@ if ( ! function_exists( 'woo_feed_get_google_categories' ) ) {
868
  }
869
  // sftp status detection.
870
  if ( ! function_exists( 'woo_feed_get_ssh2_status' ) ) {
871
- add_action('wp_ajax_get_ssh2_status', 'woo_feed_get_ssh2_status');
 
 
 
 
872
  function woo_feed_get_ssh2_status() {
873
  check_ajax_referer( 'wpf_feed_nonce' );
874
  if ( ! current_user_can( 'manage_woocommerce' ) ) {
875
  // woo_feed_log_debug_message( 'User doesnt have enough permission.' );
876
  wp_send_json_error( esc_html__( 'Unauthorized Action.', 'woo-feed' ) );
877
- die();
878
  }
879
- $php_extension = get_loaded_extensions();
880
- if ( extension_loaded ( 'ssh2' ) ) {
881
- wp_send_json_success('exists');
882
  } else {
883
- wp_send_json_success('not exists');
884
  }
 
885
  }
886
  }
887
- // Feed cron status update
888
  if ( ! function_exists( 'woo_feed_update_feed_status' ) ) {
889
  /**
890
  * Update feed status
891
  */
892
- add_action('wp_ajax_update_feed_status', 'woo_feed_update_feed_status');
893
- function woo_feed_update_feed_status(){
 
 
 
 
 
894
  if ( ! current_user_can( 'manage_woocommerce' ) ) {
895
  // woo_feed_log_debug_message( 'User doesnt have enough permission.' );
896
  wp_send_json_error( esc_html__( 'Unauthorized Action.', 'woo-feed' ) );
897
- die();
898
  }
899
- if ( ! empty($_POST['feedName']) ) {
900
- $feedInfo = unserialize(get_option( sanitize_text_field( $_POST['feedName'] ) ));
901
- $feedInfo['status'] = sanitize_text_field( $_POST['status'] );
902
- $data = array( 'status' => true );
903
- update_option( sanitize_text_field( $_POST['feedName'] ),serialize($feedInfo));
904
- wp_send_json_success($data);
905
- }else {
906
- $data = array( 'status' => false );
907
- wp_send_json_error($data);
908
  }
909
  wp_die();
910
  }
@@ -912,32 +787,39 @@ if ( ! function_exists( 'woo_feed_update_feed_status' ) ) {
912
  // Render and handle settings page options.
913
  if ( ! function_exists( 'woo_feed_config_feed' ) ) {
914
  /**
915
- * Feed config
 
916
  */
917
  function woo_feed_config_feed(){
918
  if ( isset( $_POST['wa_woo_feed_config'], $_POST['_wpnonce'] ) ) {
919
  check_admin_referer( 'woo-feed-config' );
920
- $batch_limit = absint( $_POST['batch_limit'] );
921
- if ( $batch_limit <= 0 ) $batch_limit = 200;
922
- update_option( "woo_feed_per_batch", $batch_limit, false );
923
- $queryType = strtolower( sanitize_text_field( $_POST['woo_feed_product_query_type'] ) );
924
- if ( ! $queryType || ! in_array( $queryType, [ 'wc', 'wp', 'both' ] ) ) {
925
  $queryType = 'wc';
926
  }
927
- update_option( "woo_feed_product_query_type", $queryType,false );
928
- if ( isset( $_POST['enable_error_debugging'] ) && $_POST['enable_error_debugging'] === 'on' ) {
929
- update_option( "woo_feed_enable_error_debugging", 'on', false );
 
 
930
  } else {
931
  delete_option( 'woo_feed_enable_error_debugging' );
932
  }
933
- if ( isset( $_POST['opt_in'] ) ) {
934
  WooFeedWebAppickAPI::getInstance()->trackerOptIn();
935
  } else {
936
  WooFeedWebAppickAPI::getInstance()->trackerOptOut();
937
  }
 
 
 
 
 
938
  }
939
 
940
- require WOO_FEED_FREE_ADMIN_PATH . "partials/woo-feed-config.php";
941
  }
942
  }
943
 
12
  * Description: This plugin generate WooCommerce product feed for Shopping Engines
13
  * like Google Shopping, Facebook Product Feed, eBay, Amazon, Idealo and many more.
14
  *
15
+ * Version: 3.3.0
16
  * Author: WebAppick
17
  * Author URI: https://webappick.com/
18
  * License: GPL v2
40
  * @var string
41
  * @since 3.1.6
42
  */
43
+ define( 'WOO_FEED_FREE_VERSION', '3.3.0' );
44
  }
45
 
46
+ if ( ! defined( 'WOO_FEED_FREE_FILE' ) ) {
47
  /**
48
  * Plugin Base File
49
  * @since 3.1.41
82
  * @var string
83
  * @since 3.1.37
84
  */
85
+ define( 'WOO_FEED_PLUGIN_URL', trailingslashit( plugin_dir_url( WOO_FEED_FREE_FILE ) ) );
86
  }
87
  if ( ! defined( 'WOO_FEED_MIN_PHP_VERSION' ) ) {
88
  /**
94
  }
95
  if ( ! defined( 'WOO_FEED_MIN_WC_VERSION' ) ) {
96
  /**
97
+ * Minimum WooCommerce Version Supported
98
  * @var string
99
  * @since 3.1.45
100
  */
106
  * @var string
107
  * @since 3.1.41
108
  */
109
+ define( 'WOO_FEED_PLUGIN_BASE_NAME', plugin_basename( WOO_FEED_FREE_FILE ) );
110
  }
111
 
112
  if ( ! defined( 'WOO_FEED_LOG_DIR' ) ) {
113
+ $upload_dir = wp_get_upload_dir();
114
  /**
115
  * Log Directory
116
  * @var string
127
  /**
128
  * Load Helper functions
129
  */
130
+ require_once WOO_FEED_FREE_PATH . 'includes/log-helper.php';
131
  require_once WOO_FEED_FREE_PATH . 'includes/helper.php';
132
+ require_once WOO_FEED_FREE_PATH . 'includes/cron-helper.php';
133
+ require_once WOO_FEED_FREE_PATH . 'includes/hooks.php';
134
+
135
+
136
  /**
137
  * Installer
138
  */
160
  $plugin = new Woo_Feed();
161
  register_activation_hook( WOO_FEED_FREE_FILE, [ 'Woo_Feed_installer', 'install' ] );
162
  //register_shutdown_function( 'woo_feed_log_errors_at_shutdown' );
163
+ //add_action( 'woo_feed_cleanup_logs', 'woo_feed_cleanup_logs' );
164
  /**
165
  * Ensure Feed Plugin runs only if WooCommerce loaded (installed and activated)
166
  * @since 3.1.41
172
 
173
  run_woo_feed();
174
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
 
176
+ // ======================================================================================================================*
177
+ //
178
+ // Ajax Feed Making Development Start.
179
+ //
180
+ // ======================================================================================================================*
181
  if ( ! function_exists( 'woo_feed_get_product_information' ) ) {
182
+ add_action( 'wp_ajax_get_product_information', 'woo_feed_get_product_information' );
 
 
 
183
  /**
184
  * Count Total Products
185
  */
191
  die();
192
  }
193
  // @TODO use only WC_Product_Query it's available from WC 3.2, we don't support earlier versions of wc.
194
+ if ( ! isset( $_REQUEST['feed'] ) ) {
195
+ wp_send_json_error( esc_html__( 'Invalid Request.', 'woo-feed' ) );
196
+ die();
197
+ }
198
+ $feed = sanitize_text_field( $_REQUEST['feed'] );
199
+ $feed = woo_feed_extract_feed_option_name( $feed );
200
+ $limit = isset( $_REQUEST['limit'] ) ? absint( $_REQUEST['limit'] ) : 200;
201
+ $getConfig = maybe_unserialize( get_option( 'wf_config' . $feed ) );
202
+
203
+ if ( woo_feed_wc_version_check( 3.2 ) ) {
204
  // if ( woo_feed_is_debugging_enabled() ) {
205
+ // clear log, set the pointer to the beginning of the file.
206
  // woo_feed_delete_log( $getConfig['filename'] );
207
  // woo_feed_log_feed_process( $getConfig['filename'], sprintf( 'Getting Data for %s feed.', $feed ) );
208
  // woo_feed_log_feed_process( $getConfig['filename'], 'Generating Feed VIA Ajax...' );
211
  // woo_feed_log( $getConfig['filename'], 'Feed Config::' . PHP_EOL . print_r( $getConfig, true ), 'info' );
212
  // }
213
  try {
214
+ do_action( 'before_woo_feed_get_product_information', $getConfig );
215
  $products = new Woo_Feed_Products_v3( $getConfig );
216
  $ids = $products->query_products();
217
+ do_action( 'after_woo_feed_get_product_information', $getConfig );
218
  // woo_feed_log_feed_process( $getConfig['filename'], sprintf( 'Total %d product found', is_array( $ids ) && ! empty( $ids ) ? count( $ids ) : 0 ) );
219
  if ( is_array( $ids ) && ! empty( $ids ) ) {
220
+ if ( count( $ids ) > $limit ) { // @TODO $ids = array_slice( $ids, 0, 2e3 ); limit..
221
  $batches = array_chunk( $ids, $limit );
222
  } else {
223
  $batches = array( $ids );
255
  wp_die();
256
  }
257
  } else {
258
+ do_action( 'before_woo_feed_get_product_information', $getConfig );
259
  $products = wp_count_posts( 'product' );
260
+ do_action( 'after_woo_feed_get_product_information', $getConfig );
261
  if ( $products->publish > 0 ) {
262
  $data['success'] = true;
263
  wp_send_json_success(
285
  * Ajax Batch Callback
286
  * @return void
287
  */
288
+ function woo_feed_make_batch_feed() {
289
+ check_ajax_referer( 'wpf_feed_nonce' );
290
  if ( ! current_user_can( 'manage_woocommerce' ) ) {
291
  // woo_feed_log_debug_message( 'User doesnt have enough permission.' );
292
  wp_send_json_error( esc_html__( 'Unauthorized Action.', 'woo-feed' ) );
293
  die();
294
  }
295
+ if ( ! isset( $_REQUEST['feed'] ) ) {
296
+ wp_send_json_error( esc_html__( 'Invalid Request.', 'woo-feed' ) );
297
+ die();
298
+ }
299
+
300
+ $feedName = woo_feed_extract_feed_option_name( sanitize_text_field( $_REQUEST['feed'] ) );
301
+ $feedInfo = get_option( 'wf_config' . $feedName, false );
302
 
303
  if ( ! $feedInfo ) {
304
+ $getFeedConfig = maybe_unserialize( get_option( 'wf_feed_' . $feedName ) );
305
+ $feedInfo = $getFeedConfig['feedrules'];
306
  }
307
 
308
+ $feedInfo['productIds'] = isset( $_REQUEST['products'] ) ? array_map( 'absint', $_REQUEST['products'] ) : [];
309
+ $offset = isset( $_REQUEST['loop'] ) ? absint( $_REQUEST['loop'] ) : 0;
310
+ // if ( woo_feed_is_debugging_enabled() ) {
311
+ // if ( $offset == 0 ) {
312
+ // woo_feed_log_feed_process( $feedInfo['filename'], 'Generating Feed... ' );
313
+ // }
314
+ // if ( woo_feed_is_debugging_enabled() ) {
315
+ // woo_feed_log_feed_process( $feedInfo['filename'], sprintf( 'Processing Loop %d.', ( $offset + 1 ) ) );
316
+ // $m = 'Processing Product Following Product (IDs) : ' . PHP_EOL;
317
+ // foreach( array_chunk( $feedInfo['productIds'], 10 ) as $productIds ) { // pretty print log [B-)=
318
+ // $m .= implode( ', ', $productIds ) . PHP_EOL;
319
+ // }
320
+ // woo_feed_log_feed_process( $feedInfo['filename'], $m );
321
+ // }
322
+ // }
323
 
324
+ if ( 0 == $offset ) {
325
+ $type = $feedInfo['feedType'];
 
326
  $feedService = $feedInfo['provider'];
327
+ if ( 'csv' == $type ) {
328
+ $type = 'json';
329
  }
330
+ woo_feed_unlink_tempFiles( $feedService, $feedName, $type );
 
 
 
 
 
 
 
 
 
331
  }
332
+ $feed_data = woo_feed_generate_batch_data( $feedInfo, $feedName );
 
 
 
 
 
333
  if ( $feed_data ) {
334
+ // woo_feed_log_feed_process( $feedInfo['filename'], sprintf( 'Done Processing Loop %d.', ( $offset + 1 ) ) );
335
+ wp_send_json_success(
336
+ [
337
+ 'success' => true,
338
+ 'products' => 'yes',
339
+ ]
340
  );
341
+ } else {
342
+ // woo_feed_log_feed_process( $feedInfo['filename'], sprintf( 'No Products found @ Loop %d.', $offset ) );
343
+ wp_send_json_success(
344
+ [
345
+ 'success' => true,
346
+ 'products' => 'no',
347
+ 'config' => $feedInfo,
348
+ ]
349
  );
 
 
350
  }
351
+ wp_die();
352
  }
353
  }
354
  if ( ! function_exists( 'woo_feed_save_feed_file' ) ) {
355
+ add_action( 'wp_ajax_save_feed_file', 'woo_feed_save_feed_file' );
356
+ /**
357
+ * Ajax Response for Save Feed File
358
+ * @throws Exception
359
+ * @return void
360
+ */
361
+ function woo_feed_save_feed_file() {
362
+ check_ajax_referer( 'wpf_feed_nonce' );
363
  if ( ! current_user_can( 'manage_woocommerce' ) ) {
364
  // woo_feed_log_debug_message( 'User doesnt have enough permission.' );
365
  wp_send_json_error( esc_html__( 'Unauthorized Action.', 'woo-feed' ) );
366
  die();
367
  }
368
+ if ( ! isset( $_REQUEST['feed'] ) ) {
369
+ wp_send_json_error( esc_html__( 'Invalid Feed.', 'woo-feed' ) );
370
+ die();
371
+ }
372
+
373
+ $feedName = woo_feed_extract_feed_option_name( sanitize_text_field( $_REQUEST['feed'] ) );
374
+ $info = get_option( 'wf_config' . $feedName, false );
375
+
376
  if ( ! $info ) {
377
+ $getFeedConfig = maybe_unserialize( get_option( 'wf_feed_' . $feedName ) );
378
+ $info = $getFeedConfig['feedrules'];
379
  }
380
 
381
  $feedService = $info['provider'];
382
+ $type = $info['feedType'];
383
+ // woo_feed_log_feed_process( $info['filename'], sprintf( 'Preparing Final Feed (%s) File...', $type ) );
384
+ // woo_feed_log_feed_process( $info['filename'], 'Getting Batch Chunks' );
385
+ $feedHeader = woo_feed_get_batch_feed_info( $feedService, $type, 'wf_store_feed_header_info_' . $feedName );
386
+ // if ( ! $feedHeader ) woo_feed_log_feed_process( $info['filename'], 'Unable to Get Header Chunk' );
387
+ $feedBody = woo_feed_get_batch_feed_info( $feedService, $type, 'wf_store_feed_body_info_' . $feedName );
388
+ // if ( ! $feedBody ) woo_feed_log_feed_process( $info['filename'], 'Unable to Get Body Chunk' );
389
+ $feedFooter = woo_feed_get_batch_feed_info( $feedService, $type, 'wf_store_feed_footer_info_' . $feedName );
390
+ // if ( ! $feedFooter ) woo_feed_log_feed_process( $info['filename'], 'Unable to Get Footer Chunk' );
391
 
392
+ if ( 'csv' == $type ) {
393
  $csvHead[0] = $feedHeader;
394
+ if ( ! empty( $csvHead ) && ! empty( $feedBody ) ) {
395
+ $string = array_merge( $csvHead, $feedBody );
396
+ } else {
397
  $string = array();
398
  }
399
+ } else {
400
+ $string = $feedHeader . $feedBody . $feedFooter;
401
  }
402
 
403
+ $upload_dir = wp_get_upload_dir();
404
+ $path = $upload_dir['basedir'] . '/woo-feed/' . $feedService . '/' . $type;
405
+ $saveFile = false;
406
+ $file = '';
407
+ // Check If any products founds
408
+ if ( $string && ! empty( $string ) ) {
409
+ // Save File
410
+ $file = $path . '/' . $feedName . '.' . $type;
411
+ // try {
412
  $save = new Woo_Feed_Savefile();
413
+ if ( 'csv' == $type ) {
414
+ $saveFile = $save->saveCSVFile( $path, $file, $string, $info );
415
  } else {
416
+ $saveFile = $save->saveFile( $path, $file, $string );
417
  }
418
+ // if ( $saveFile ) {
419
+ // $message = 'Feed File Successfully Saved.';
420
+ // } else {
421
+ // $message = 'Unable to save Feed file. Check Directory Permission.';
422
+ // }
423
+ // woo_feed_log_feed_process( $info['filename'], $message );
424
+ // } catch ( Exception $e ) {
425
+ // $message = 'Error Saving Feed File' . PHP_EOL . 'Caught Exception :: ' . $e->getMessage();
426
+ // woo_feed_log( $info['filename'], $message, 'critical', $e, true );
427
+ // woo_feed_log_fatal_error( $message, $e );
428
+ // }
429
+ } else {
430
+ // woo_feed_log_feed_process( $info['filename'], 'No Product Found... Exiting File Save Process...' );
431
+ if ( isset( $info['fattribute'] ) && count( $info['fattribute'] ) ) {
432
+ $data = [
433
+ 'success' => false,
434
+ 'message' => esc_html__( 'Products not found with your filtering condition.', 'woo-feed' ),
435
+ ];
436
+ } else {
437
+ $data = [
438
+ 'success' => false,
439
+ 'message' => esc_html__( 'No Product Found with your feed configuration. Please Update And Generate the feed again.', 'woo-feed' ),
440
+ ];
441
+ }
442
+ wp_send_json_error( $data );
443
  wp_die();
444
  }
445
 
446
+ // Save Info into database.
 
 
447
  $feedInfo = array(
448
  'feedrules' => $info,
449
+ 'url' => woo_feed_get_file_url( $feedName, $feedService, $type ),
450
+ 'last_updated' => gmdate( 'Y-m-d H:i:s' ),
451
  );
452
+ $feedOldInfo = maybe_unserialize( get_option( "wf_feed_" . $feedName ) );
 
453
  if ( isset( $feedOldInfo['status'] ) ) {
454
  $feedInfo['status'] = $feedOldInfo['status'];
455
+ } else {
456
  $feedInfo['status'] = 1;
457
  }
458
 
459
+ if ( 'csv' == $type ) {
460
+ $type = 'json';
461
  }
462
 
463
+ woo_feed_unlink_tempFiles( $feedService, $feedName, $type );
464
+
465
+ // woo_feed_log_feed_process( $info['filename'], 'Updating Feed Information.' );
 
 
 
466
 
467
+ update_option( 'wf_feed_' . $feedName, serialize( $feedInfo ), false );
 
 
 
468
 
 
 
469
  if ( $saveFile ) {
470
+ // FTP File Upload Info
471
+ $ftpEnabled = sanitize_text_field( $info['ftpenabled'] );
472
 
473
+ if ( 'json' == $type ) {
474
+ $type = 'csv';
475
+ }
476
+ if ( $ftpEnabled ) {
477
+ woo_feed_handle_file_transfer( $file, $feedName . '.' . $type, $info );
478
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
479
 
480
+ $cat = woo_feed_check_google_category( $feedInfo );
481
+ $getInfo = maybe_unserialize( get_option( 'wf_feed_' . $feedName ) );
482
+ $url = $getInfo['url'];
483
+ $data = array(
484
+ 'info' => $feedInfo,
485
+ 'url' => $url,
486
+ 'cat' => $cat,
487
+ 'message' => esc_html__( 'Feed Making Complete', 'woo-feed' ),
488
  );
489
+ // woo_feed_log_feed_process( $info['filename'], 'Done Processing Feed. Exiting Process...' );
490
+ wp_send_json_success( $data );
491
  } else {
492
+ // woo_feed_log_feed_process( $info['filename'], 'Done Processing Feed. Exiting Process...' );
493
  $data = array(
494
+ 'success' => false,
495
+ 'message' => esc_html__( 'Failed to save feed file. Please confirm that your WordPress directory have read and write permission.', 'woo-feed' ),
496
  );
497
+ wp_send_json_error( $data );
498
  }
 
499
  wp_die();
500
  }
501
  }
502
+ // Ajax Helper.
503
+ if ( ! function_exists( 'woo_feed_generate_batch_data' ) ) {
504
+ /**
505
+ * Generate Feed Data
506
+ *
507
+ * @param array $info Feed info.
508
+ * @param string $feedSlug feed option slug.
509
+ *
510
+ * @return bool
511
+ */
512
+ function woo_feed_generate_batch_data( $info, $feedSlug ) {
513
+ // parse rules.
514
+ $info = woo_feed_parse_feed_rules( isset( $info['feedrules'] ) ? $info['feedrules'] : $info );
515
  try {
516
+ do_action( 'before_woo_feed_generate_batch_data', $info );
517
+ $status = false;
518
+ if ( ! empty( $info['provider'] ) ) {
519
+ // Get Post data.
520
+ $feedService = sanitize_text_field( $info['provider'] );
521
+ $type = sanitize_text_field( $info['feedType'] );
522
+ $feedRules = $info;
523
+ // Get Feed info.
524
+ $products = new Woo_Generate_Feed( $feedService, $feedRules );
525
+ // woo_feed_log_feed_process( $info['filename'], sprintf( 'Initializing merchant Class %s for %s', $merchant, $info['provider'] ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
526
  $feed = $products->getProducts();
527
+ if ( ! empty( $feed['body'] ) ) {
528
+ $feedBody = 'wf_store_feed_body_info_' . $feedSlug;
529
+ $prevFeed = woo_feed_get_batch_feed_info( $feedService, $type, $feedBody );
 
 
530
  if ( $prevFeed ) {
531
+ if ( 'csv' == $type ) {
532
+ if ( ! empty( $prevFeed ) ) {
533
  $newFeed = array_merge( $prevFeed, $feed['body'] );
534
  woo_feed_save_batch_feed_info( $feedService, $type, $newFeed, $feedBody, $info );
535
  }
536
+ } else {
537
+ $newFeed = $prevFeed . $feed['body'];
538
  woo_feed_save_batch_feed_info( $feedService, $type, $newFeed, $feedBody, $info );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
539
  }
540
+ } else {
541
+ woo_feed_save_batch_feed_info( $feedService, $type, $feed['body'], $feedBody, $info );
542
  }
543
+ woo_feed_save_batch_feed_info( $feedService, $type, $feed['header'], 'wf_store_feed_header_info_' . $feedSlug, $info );
544
+ woo_feed_save_batch_feed_info( $feedService, $type, $feed['footer'], 'wf_store_feed_footer_info_' . $feedSlug, $info );
545
+ $status = true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
546
  } else {
547
+ $status = false;
548
  }
549
  }
550
+ do_action( 'after_woo_feed_generate_batch_data', $info );
551
+ return $status;
552
+ } catch ( Exception $e ) {
553
+ // $message = 'Error Generating Product Data.' . PHP_EOL . 'Caught Exception :: ' . $e->getMessage();
554
+ // woo_feed_log( $info['filename'], $message, 'critical', $e, true );
555
+ // woo_feed_log_fatal_error( $message, $e );
556
+ return false;
557
  }
 
558
  }
559
  }
560
 
561
+ // Menu Callback.
562
+ if ( ! function_exists( 'woo_feed_generate_new_feed' ) ) {
563
  /**
564
  * Generate Feed
565
  */
566
+ function woo_feed_generate_new_feed() {
567
  if ( isset( $_POST['provider'], $_POST['_wpnonce'], $_POST['filename'], $_POST['feedType'] ) ) {
568
+ // Verify Nonce.
569
  if ( ! wp_verify_nonce( sanitize_text_field( $_POST['_wpnonce'] ), 'woo_feed_form_nonce' ) ) {
570
+ wp_die( esc_html__( 'Failed security check', 'woo-feed' ), 403 );
571
  }
572
+ // Check feed type (file ext).
573
+ if ( ! woo_feed_check_valid_extension( sanitize_text_field( $_POST['feedType'] ) ) ) {
574
+ wp_die( esc_html__( 'Invalid Feed Type!', 'woo-feed' ), 400 );
575
  }
576
 
577
  $fileName = woo_feed_save_feed_config_data( $_POST );
 
 
 
 
578
 
579
+ wp_safe_redirect(
580
+ add_query_arg(
581
+ [
582
+ 'feed_created' => (int) false !== $fileName,
583
+ 'feed_regenerate' => 1,
584
+ 'feed_name' => $fileName ? $fileName : '',
585
+ ],
586
+ admin_url( 'admin.php?page=webappick-manage-feeds' )
587
+ )
588
+ );
589
  die();
590
  } else {
591
  require WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-admin-display.php';
597
  * Manage Feeds
598
  */
599
  function woo_feed_manage_feed() {
600
+ // @TODO use admin_post_ action for form handling.
601
+ // Manage action for category mapping.
602
+ if ( isset( $_GET['action'] ) && 'edit-feed' == $_GET['action'] ) {
603
  if ( ! defined( 'WOO_FEED_EDIT_CONFIG' ) ) define( 'WOO_FEED_EDIT_CONFIG', true );
604
+ if ( count( $_POST ) && isset( $_POST['provider'], $_POST['feed_id'], $_POST['feed_option_name'], $_POST['filename'], $_POST['feedType'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
605
+ $nonce = isset( $_POST['_wpnonce'] ) && ! empty( $_POST['_wpnonce'] ) ? sanitize_text_field( $_POST['_wpnonce'] ) : '';
606
+ if ( ! wp_verify_nonce( $nonce, 'wf_edit_feed' ) ) {
607
+ wp_die( esc_html__( 'Failed security check', 'woo-feed' ), 403 );
608
  }
609
+ // Check feed type (file ext)
610
+ if ( ! woo_feed_check_valid_extension( sanitize_text_field( $_POST['feedType'] ) ) ) {
611
+ wp_die( esc_html__( 'Invalid Feed Type!', 'woo-feed' ), 400 );
612
  }
613
+
614
  // check if name is changed... save as new, rename feed isn't implemented ... it can be...
615
  // @TODO delete old feed save data as new feed.
616
+ $feed_option_name = ( isset( $_POST['feed_option_name'] ) && ! empty( $_POST['feed_option_name'] ) ) ? sanitize_text_field( $_POST['feed_option_name'] ) : NULL;
 
 
 
 
617
  // if form submitted via $_POST['edit-feed'] then only config and regenerate otherwise only update the config...
618
  // no need to check other submit button ... eg. $_POST['save_feed_config']
619
+ $fileName = woo_feed_save_feed_config_data( $_POST, $feed_option_name, isset( $_POST['edit-feed'] ) );
620
  // redirect to the feed list with status
621
  // @TODO this should be handled in admin_init action for proper redirection to work...
622
+ wp_safe_redirect(
623
+ add_query_arg(
624
+ [
625
+ 'feed_updated' => (int) false !== $fileName,
626
+ 'feed_regenerate' => (int) isset( $_POST['edit-feed'] ),
627
+ 'feed_name' => $fileName ? $fileName : '',
628
+ ],
629
+ admin_url( 'admin.php?page=webappick-manage-feeds' )
630
+ )
631
+ );
632
  die();
633
  }
 
634
  if ( isset( $_GET['feed'] ) && ! empty( $_GET['feed'] ) ) {
635
+ global $wpdb, $feedRules, $feedName, $feedId, $provider;
636
+ $feedName = sanitize_text_field( $_GET['feed'] );
637
+ $feedInfo = maybe_unserialize( get_option( $feedName ) );
638
+ if ( false !== $feedInfo ) {
639
+ $query = $wpdb->prepare( "SELECT option_id FROM $wpdb->options WHERE option_name = %s LIMIT 1", $feedName );
640
+ if ( ! $feedId ) {
641
+ $result = $wpdb->get_row( $query ); // phpcs:ignore
642
+ if ( $result ) {
643
+ $feedId = $result->option_id;
644
+ }
645
+ }
646
+ $provider = strtolower( $feedInfo['feedrules']['provider'] );
647
+ $feedRules = $feedInfo['feedrules'];
648
+
649
+
650
+
651
+
652
+ require WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-edit-template.php';
653
+ } else {
654
+ update_option( 'wpf_message', esc_html__( 'Feed Does not Exists.', 'woo-feed' ), false );
655
+ wp_safe_redirect( admin_url( 'admin.php?page=webappick-manage-feeds&wpf_message=error' ) );
656
+ die();
657
+ }
658
  }
659
  } else {
660
+ // Update Interval.
661
  if ( isset( $_POST['wf_schedule'] ) ) {
662
+ if ( isset( $_POST['wf_schedule_nonce'] ) && wp_verify_nonce( sanitize_text_field( $_POST['wf_schedule_nonce'] ), 'wf_schedule' ) ) {
663
  $interval = absint( $_POST['wf_schedule'] );
664
  if ( $interval >= woo_feed_get_minimum_interval_option() ) {
665
+ if ( update_option( 'wf_schedule', sanitize_text_field( $_POST['wf_schedule'] ), false ) ) {
666
+ wp_clear_scheduled_hook( 'woo_feed_update' );
667
+ add_filter( 'cron_schedules', 'Woo_Feed_installer::cron_schedules' ); // phpcs:ignore
668
  wp_schedule_event( time(), 'woo_feed_corn', 'woo_feed_update' );
669
+ $update = 1; // success.
670
+ } else {
671
+ $update = 2; // db fail.
672
+ }
673
+ } else {
674
+ $update = 3; // invalid value.
675
+ }
676
+ } else {
677
+ $update = 4; // invalid nonce.
678
+ }
679
  wp_safe_redirect( add_query_arg( [ 'schedule_updated' => $update ], admin_url( 'admin.php?page=webappick-manage-feeds' ) ) );
680
  die();
681
  }
682
+ require WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-manage-list.php';
683
  }
684
  }
685
  }
686
+
687
+ // Get Merchant template.
688
  if ( ! function_exists( 'feed_merchant_view' ) ) {
689
+ // Load Feed Templates.
690
+ add_action( 'wp_ajax_get_feed_merchant', 'feed_merchant_view' );
691
+ /**
692
+ * Ajax response for Create/Add Feed config table for selected Merchant/Provider
693
+ * @return void
694
+ */
695
  function feed_merchant_view() {
696
+ check_ajax_referer( 'wpf_feed_nonce' );
697
  if ( ! current_user_can( 'manage_woocommerce' ) ) {
698
  // woo_feed_log_debug_message( 'User doesnt have enough permission.' );
699
  wp_send_json_error( esc_html__( 'Unauthorized Action.', 'woo-feed' ) );
700
  die();
701
  }
702
+ global $feedRules, $wooFeedDropDown, $wooFeedProduct, $provider;
703
+ $provider = isset( $_REQUEST['merchant'] ) && ! empty( $_REQUEST['merchant'] ) ? sanitize_text_field( $_REQUEST['merchant'] ) : '';
704
+ if ( empty( $provider ) ) {
705
+ wp_send_json_error( esc_html__( 'Invalid Merchant', 'woo-feed' ) );
706
+ wp_die();
 
 
 
 
 
 
 
 
 
 
 
707
  }
708
+ $feedRules = woo_feed_parse_feed_rules( [ 'provider' => $provider ] );
709
+ $wooFeedDropDown = new Woo_Feed_Dropdown();
710
+ $wooFeedProduct = new Woo_Feed_Products();
711
+ $attributes = new Woo_Feed_Default_Attributes();
712
+ ob_start();
713
+ require_once WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-edit-tabs.php';
714
  wp_send_json_success( ob_get_clean() );
715
+ wp_die();
716
  }
717
  }
718
+ // Get Google Categories.
719
  if ( ! function_exists( 'woo_feed_get_google_categories' ) ) {
720
  add_action( 'wp_ajax_get_google_categories', 'woo_feed_get_google_categories' );
721
+ /**
722
+ * Ajax Response for Google Category Dropdown Data
723
+ * @return void
724
+ */
725
  function woo_feed_get_google_categories() {
726
+ check_ajax_referer( 'wpf_feed_nonce' );
727
  if ( ! current_user_can( 'manage_woocommerce' ) ) {
728
  // woo_feed_log_debug_message( 'User doesnt have enough permission.' );
729
  wp_send_json_error( esc_html__( 'Unauthorized Action.', 'woo-feed' ) );
730
+ wp_die();
731
  }
732
  $wooFeedDropDown = new Woo_Feed_Dropdown();
733
  wp_send_json_success( $wooFeedDropDown->googleTaxonomyArray() );
736
  }
737
  // sftp status detection.
738
  if ( ! function_exists( 'woo_feed_get_ssh2_status' ) ) {
739
+ add_action( 'wp_ajax_get_ssh2_status', 'woo_feed_get_ssh2_status' );
740
+ /**
741
+ * Ajax Response for ssh2 status check
742
+ * @return void
743
+ */
744
  function woo_feed_get_ssh2_status() {
745
  check_ajax_referer( 'wpf_feed_nonce' );
746
  if ( ! current_user_can( 'manage_woocommerce' ) ) {
747
  // woo_feed_log_debug_message( 'User doesnt have enough permission.' );
748
  wp_send_json_error( esc_html__( 'Unauthorized Action.', 'woo-feed' ) );
749
+ wp_die();
750
  }
751
+ if ( extension_loaded( 'ssh2' ) ) {
752
+ wp_send_json_success( 'exists' );
 
753
  } else {
754
+ wp_send_json_success( 'not_exists' );
755
  }
756
+ wp_die();
757
  }
758
  }
759
+ // Feed cron status update.
760
  if ( ! function_exists( 'woo_feed_update_feed_status' ) ) {
761
  /**
762
  * Update feed status
763
  */
764
+ add_action( 'wp_ajax_update_feed_status', 'woo_feed_update_feed_status' );
765
+ /**
766
+ * Ajax Response for Update Feed Status
767
+ * @return void
768
+ */
769
+ function woo_feed_update_feed_status() {
770
+ check_ajax_referer( 'wpf_feed_nonce' );
771
  if ( ! current_user_can( 'manage_woocommerce' ) ) {
772
  // woo_feed_log_debug_message( 'User doesnt have enough permission.' );
773
  wp_send_json_error( esc_html__( 'Unauthorized Action.', 'woo-feed' ) );
774
+ wp_die();
775
  }
776
+ if ( ! empty( $_POST['feedName'] ) ) {
777
+ $feedInfo = maybe_unserialize( get_option( sanitize_text_field( $_POST['feedName'] ) ) );
778
+ $feedInfo['status'] = isset( $_POST['status'] ) && 1 == $_POST['status'] ? 1 : 0;
779
+ update_option( sanitize_text_field( $_POST['feedName'] ), serialize( $feedInfo ), false );
780
+ wp_send_json_success( array( 'status' => true ) );
781
+ } else {
782
+ wp_send_json_error( array( 'status' => false ) );
 
 
783
  }
784
  wp_die();
785
  }
787
  // Render and handle settings page options.
788
  if ( ! function_exists( 'woo_feed_config_feed' ) ) {
789
  /**
790
+ * Feed Settings Page
791
+ * @return void
792
  */
793
  function woo_feed_config_feed(){
794
  if ( isset( $_POST['wa_woo_feed_config'], $_POST['_wpnonce'] ) ) {
795
  check_admin_referer( 'woo-feed-config' );
796
+ $batch_limit = isset( $_POST['batch_limit'] ) && $_POST['batch_limit'] > 0 ? absint( $_POST['batch_limit'] ) : 200;
797
+ update_option( 'woo_feed_per_batch', $batch_limit, false );
798
+ $queryType = isset( $_POST['woo_feed_product_query_type'] ) ? strtolower( sanitize_text_field( $_POST['woo_feed_product_query_type'] ) ) : '';
799
+ if ( ! in_array( $queryType, [ 'wc', 'wp', 'both' ] ) ) {
 
800
  $queryType = 'wc';
801
  }
802
+ update_option( 'woo_feed_product_query_type', $queryType, false );
803
+
804
+
805
+ if ( isset( $_POST['enable_error_debugging'] ) && 'on' === $_POST['enable_error_debugging'] ) {
806
+ update_option( 'woo_feed_enable_error_debugging', 'on', false );
807
  } else {
808
  delete_option( 'woo_feed_enable_error_debugging' );
809
  }
810
+ if ( isset( $_POST['opt_in'] ) && 'on' === $_POST['opt_in'] ) {
811
  WooFeedWebAppickAPI::getInstance()->trackerOptIn();
812
  } else {
813
  WooFeedWebAppickAPI::getInstance()->trackerOptOut();
814
  }
815
+ if ( isset( $_POST['clear_all_logs'] ) && 'on' === $_POST['clear_all_logs'] ) {
816
+ woo_feed_delete_all_logs();
817
+ }
818
+ wp_safe_redirect( admin_url( 'admin.php?page=webappick-feed-settings&settings_updated=1' ) );
819
+ die();
820
  }
821
 
822
+ require WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-config.php';
823
  }
824
  }
825