CTX Feed – WooCommerce Product Feed Manager Plugin - Version 3.6.1

Version Description

(2020-05-28) = * Fixed: Feed file rename issue fixed.

Download this release

Release Info

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

Code changes from version 3.6.0 to 3.6.1

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.4
7
  Requires PHP: 5.6
8
- Stable tag: 3.6.0
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -305,6 +305,9 @@ Using pro version:
305
 
306
  == Changelog ==
307
 
 
 
 
308
  = 3.6.0 (2020-05-27) =
309
  * Added: new output types added to format attribute output.
310
 
5
  Requires at least: 3.6
6
  Tested Up To: 5.4
7
  Requires PHP: 5.6
8
+ Stable tag: 3.6.1
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
305
 
306
  == Changelog ==
307
 
308
+ = 3.6.1 (2020-05-28) =
309
+ * Fixed: Feed file rename issue fixed.
310
+
311
  = 3.6.0 (2020-05-27) =
312
  * Added: new output types added to format attribute output.
313
 
includes/classes/class-woo-feed-products-v3.php CHANGED
@@ -145,11 +145,17 @@ class Woo_Feed_Products_v3 {
145
  */
146
  protected $processed_merchant_attributes = array();
147
 
148
- /**
149
- * Product types Supported for query
150
- * @var array
151
- */
152
- protected $product_types = array( 'simple', 'variable', 'variation', 'grouped', 'external' );
 
 
 
 
 
 
153
  /**
154
  * Post meta prefix for dropdown item
155
  * @since 3.1.18
145
  */
146
  protected $processed_merchant_attributes = array();
147
 
148
+ /**
149
+ * Product types Supported for query
150
+ * @var array
151
+ */
152
+ protected $product_types = array(
153
+ 'simple',
154
+ 'variable',
155
+ 'variation',
156
+ 'grouped',
157
+ 'external',
158
+ );
159
  /**
160
  * Post meta prefix for dropdown item
161
  * @since 3.1.18
woo-feed.php CHANGED
@@ -11,7 +11,7 @@
11
  * Plugin URI: https://webappick.com/
12
  * Description: Easily generate woocommerce product feed for any marketing channel like Google Shopping(Merchant), Facebook Remarketing, Bing, eBay & more. Support 100+ Merchants.
13
  *
14
- * Version: 3.6.0
15
  * Author: WebAppick
16
  * Author URI: https://webappick.com/
17
  * License: GPL v2
@@ -30,103 +30,103 @@
30
  */
31
 
32
  if ( ! defined( 'ABSPATH' ) ) {
33
- die(); // If this file is called directly, abort.
34
  }
35
 
36
  if ( ! defined( 'WOO_FEED_FREE_VERSION' ) ) {
37
- /**
38
- * Plugin Version
39
- * @var string
40
- * @since 3.1.6
41
- */
42
- define( 'WOO_FEED_FREE_VERSION', '3.6.0' );
43
  }
44
 
45
  if ( ! defined( 'WOO_FEED_FREE_FILE' ) ) {
46
- /**
47
- * Plugin Base File
48
- * @since 3.1.41
49
- * @var string
50
- */
51
- define( 'WOO_FEED_FREE_FILE', __FILE__ );
52
  }
53
  if ( ! defined( 'WOO_FEED_FREE_PATH' ) ) {
54
- /**
55
- * Plugin Path with trailing slash
56
- * @var string dirname( __FILE__ )
57
- * * @since 3.1.6
58
- */
59
- /** @define "WOO_FEED_FREE_PATH" "./" */ // phpcs:ignore
60
- define( 'WOO_FEED_FREE_PATH', plugin_dir_path( WOO_FEED_FREE_FILE ) );
61
  }
62
  if ( ! defined( 'WOO_FEED_FREE_ADMIN_PATH' ) ) {
63
- /**
64
- * Admin File Path with trailing slash
65
- * @var string
66
- * @since 3.1.6
67
- */
68
- define( 'WOO_FEED_FREE_ADMIN_PATH', WOO_FEED_FREE_PATH . 'admin/' );
69
  }
70
 
71
  if ( ! defined( 'WOO_FEED_LIBS_PATH' ) ) {
72
- /**
73
- * Admin File Path with trailing slash
74
- * @var string
75
- */
76
- define( 'WOO_FEED_LIBS_PATH', WOO_FEED_FREE_PATH . 'libs/' );
77
  }
78
  if ( ! defined( 'WOO_FEED_PLUGIN_URL' ) ) {
79
- /**
80
- * Plugin Directory URL
81
- * @var string
82
- * @since 3.1.37
83
- */
84
- define( 'WOO_FEED_PLUGIN_URL', trailingslashit( plugin_dir_url( WOO_FEED_FREE_FILE ) ) );
85
  }
86
  if ( ! defined( 'WOO_FEED_MIN_PHP_VERSION' ) ) {
87
- /**
88
- * Minimum PHP Version Supported
89
- * @var string
90
- * @since 3.1.41
91
- */
92
- define( 'WOO_FEED_MIN_PHP_VERSION', '5.6' );
93
  }
94
  if ( ! defined( 'WOO_FEED_MIN_WC_VERSION' ) ) {
95
- /**
96
- * Minimum WooCommerce Version Supported
97
- * @var string
98
- * @since 3.1.45
99
- */
100
- define( 'WOO_FEED_MIN_WC_VERSION', '3.2' );
101
  }
102
  if ( ! defined( 'WOO_FEED_PLUGIN_BASE_NAME' ) ) {
103
- /**
104
- * Plugin Base name..
105
- * @var string
106
- * @since 3.1.41
107
- */
108
- define( 'WOO_FEED_PLUGIN_BASE_NAME', plugin_basename( WOO_FEED_FREE_FILE ) );
109
  }
110
 
111
  if ( ! defined( 'WOO_FEED_LOG_DIR' ) ) {
112
- $upload_dir = wp_get_upload_dir();
113
- /**
114
- * Log Directory
115
- * @var string
116
- * @since 3.2.1
117
- */
118
- /** @define "WOO_FEED_LOG_DIR" "./../../uploads/woo-feed/logs" */ // phpcs:ignore
119
- define( 'WOO_FEED_LOG_DIR', $upload_dir['basedir'] . '/woo-feed/logs/' );
120
  }
121
 
122
  if ( ! defined( 'WOO_FEED_CACHE_TTL' ) ) {
123
- $_cache_ttl = get_option( 'woo_feed_settings', [ 'cache_ttl' => 6 * HOUR_IN_SECONDS ] );
124
- /**
125
- * Cache TTL
126
- * @var int
127
- * @since 3.3.11
128
- */
129
- define( 'WOO_FEED_CACHE_TTL', $_cache_ttl['cache_ttl'] );
130
  }
131
 
132
  /**
@@ -147,38 +147,38 @@ require_once WOO_FEED_FREE_PATH . 'includes/cron-helper.php';
147
  require_once WOO_FEED_FREE_PATH . 'includes/class-woo-feed-installer.php';
148
 
149
  if ( ! class_exists( 'Woo_Feed' ) ) {
150
- /**
151
- * The core plugin class that is used to define internationalization,
152
- * admin-specific hooks, and public-facing site hooks.
153
- */
154
- require WOO_FEED_FREE_PATH . 'includes/class-woo-feed.php';
155
  }
156
 
157
  if ( ! function_exists( 'run_woo_feed' ) ) {
158
- /**
159
- * Begins execution of the plugin.
160
- *
161
- * Since everything within the plugin is registered via hooks,
162
- * then kicking off the plugin from this point in the file does
163
- * not affect the page life cycle.
164
- *
165
- * @since 1.0.0
166
- */
167
- function run_woo_feed() {
168
- $plugin = new Woo_Feed();
169
- register_activation_hook( WOO_FEED_FREE_FILE, [ 'Woo_Feed_installer', 'install' ] );
170
- register_shutdown_function( 'woo_feed_log_errors_at_shutdown' );
171
- add_action( 'woo_feed_cleanup_logs', 'woo_feed_cleanup_logs' );
172
- /**
173
- * Ensure Feed Plugin runs only if WooCommerce loaded (installed and activated)
174
- * @since 3.1.41
175
- */
176
- add_action( 'plugins_loaded', [ $plugin, 'run' ], PHP_INT_MAX );
177
- add_action( 'admin_notices', 'wooFeed_Admin_Notices' );
178
- WooFeedWebAppickAPI::getInstance();
179
- }
180
-
181
- run_woo_feed();
182
  }
183
 
184
  // ======================================================================================================================*
@@ -187,648 +187,664 @@ if ( ! function_exists( 'run_woo_feed' ) ) {
187
  //
188
  // ======================================================================================================================*
189
  if ( ! function_exists( 'woo_feed_get_product_information' ) ) {
190
- add_action( 'wp_ajax_get_product_information', 'woo_feed_get_product_information' );
191
- /**
192
- * Count Total Products
193
- */
194
- function woo_feed_get_product_information() {
195
- check_ajax_referer( 'wpf_feed_nonce' );
196
- if ( ! current_user_can( 'manage_woocommerce' ) ) {
197
- woo_feed_log_debug_message( 'User doesnt have enough permission.' );
198
- wp_send_json_error( esc_html__( 'Unauthorized Action.', 'woo-feed' ) );
199
- die();
200
- }
201
- // @TODO use only WC_Product_Query it's available from WC 3.2, we don't support earlier versions of wc.
202
- if ( ! isset( $_REQUEST['feed'] ) ) {
203
- wp_send_json_error( esc_html__( 'Invalid Request.', 'woo-feed' ) );
204
- die();
205
- }
206
- $feed = sanitize_text_field( $_REQUEST['feed'] );
207
- $feed = woo_feed_extract_feed_option_name( $feed );
208
- $limit = isset( $_REQUEST['limit'] ) ? absint( $_REQUEST['limit'] ) : 200;
209
- $getConfig = maybe_unserialize( get_option( 'wf_config' . $feed ) );
210
-
211
- if ( woo_feed_wc_version_check( 3.2 ) ) {
212
- if ( woo_feed_is_debugging_enabled() ) {
213
- // clear log, set the pointer to the beginning of the file.
214
- woo_feed_delete_log( $getConfig['filename'] );
215
- woo_feed_log_feed_process( $getConfig['filename'], sprintf( 'Getting Data for %s feed.', $feed ) );
216
- woo_feed_log_feed_process( $getConfig['filename'], 'Generating Feed VIA Ajax...' );
217
- woo_feed_log_feed_process( $getConfig['filename'], sprintf( 'Getting Data for %s feed.', $feed ) );
218
- woo_feed_log_feed_process( $getConfig['filename'], sprintf( 'Current Limit is %d.', $limit ) );
219
- woo_feed_log( $getConfig['filename'], 'Feed Config::' . PHP_EOL . print_r( $getConfig, true ), 'info' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
220
- }
221
- try {
222
- do_action( 'before_woo_feed_get_product_information', $getConfig );
223
- $products = new Woo_Feed_Products_v3( $getConfig );
224
- $ids = $products->query_products();
225
- do_action( 'after_woo_feed_get_product_information', $getConfig );
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 );
232
- }
233
- woo_feed_log_feed_process( $getConfig['filename'], sprintf( 'Total %d batches', count( $batches ) ) );
234
- wp_send_json_success(
235
- [
236
- 'product' => $batches,
237
- 'total' => count( $ids ),
238
- 'success' => true,
239
- ]
240
- );
241
- wp_die();
242
- } else {
243
- wp_send_json_error(
244
- [
245
- 'message' => esc_html__( 'No products found. Add product or change feed config before generate the feed.', 'woo-feed' ),
246
- 'success' => false,
247
- ]
248
- );
249
- wp_die();
250
- }
251
- } catch ( Exception $e ) {
252
- if ( woo_feed_is_debugging_enabled() ) {
253
- $message = 'Error getting Product Ids.' . PHP_EOL . 'Caught Exception :: ' . $e->getMessage();
254
- woo_feed_log( $getConfig['filename'], $message, 'critical', $e, true );
255
- woo_feed_log_fatal_error( $message, $e );
256
- }
257
- wp_send_json_error(
258
- [
259
- 'message' => esc_html__( 'Failed to fetch products.', 'woo-feed' ),
260
- 'success' => false,
261
- ]
262
- );
263
- wp_die();
264
- }
265
- } else {
266
- do_action( 'before_woo_feed_get_product_information', $getConfig );
267
- $products = wp_count_posts( 'product' );
268
- do_action( 'after_woo_feed_get_product_information', $getConfig );
269
- if ( $products->publish > 0 ) {
270
- $data['success'] = true;
271
- wp_send_json_success(
272
- [
273
- 'product' => $products->publish,
274
- 'success' => false,
275
- ]
276
- );
277
- wp_die();
278
- } else {
279
- wp_send_json_error(
280
- [
281
- 'message' => esc_html__( 'No products found. Add product or change feed config before generate the feed.', 'woo-feed' ),
282
- 'success' => false,
283
- ]
284
- );
285
- wp_die();
286
- }
287
- }
288
- }
289
  }
290
  if ( ! function_exists( 'woo_feed_make_batch_feed' ) ) {
291
- add_action( 'wp_ajax_make_batch_feed', 'woo_feed_make_batch_feed' );
292
- /**
293
- * Ajax Batch Callback
294
- * @return void
295
- */
296
- function woo_feed_make_batch_feed() {
297
- check_ajax_referer( 'wpf_feed_nonce' );
298
- if ( ! current_user_can( 'manage_woocommerce' ) ) {
299
- woo_feed_log_debug_message( 'User doesnt have enough permission.' );
300
- wp_send_json_error( esc_html__( 'Unauthorized Action.', 'woo-feed' ) );
301
- die();
302
- }
303
- if ( ! isset( $_REQUEST['feed'] ) ) {
304
- wp_send_json_error( esc_html__( 'Invalid Request.', 'woo-feed' ) );
305
- die();
306
- }
307
-
308
- $feedName = woo_feed_extract_feed_option_name( sanitize_text_field( $_REQUEST['feed'] ) );
309
- $feedInfo = get_option( 'wf_config' . $feedName, false );
310
-
311
- if ( ! $feedInfo ) {
312
- $getFeedConfig = maybe_unserialize( get_option( 'wf_feed_' . $feedName ) );
313
- $feedInfo = $getFeedConfig['feedrules'];
314
- }
315
-
316
- $feedInfo['productIds'] = isset( $_REQUEST['products'] ) ? array_map( 'absint', $_REQUEST['products'] ) : [];
317
- $offset = isset( $_REQUEST['loop'] ) ? absint( $_REQUEST['loop'] ) : 0;
318
- if ( woo_feed_is_debugging_enabled() ) {
319
- if ( 0 == $offset ) {
320
- woo_feed_log_feed_process( $feedInfo['filename'], 'Generating Feed... ' );
321
- }
322
- if ( woo_feed_is_debugging_enabled() ) {
323
- woo_feed_log_feed_process( $feedInfo['filename'], sprintf( 'Processing Loop %d.', ( $offset + 1 ) ) );
324
- $m = 'Processing Product Following Product (IDs) : ' . PHP_EOL;
325
- foreach ( array_chunk( $feedInfo['productIds'], 10 ) as $productIds ) { // pretty print log [B-)=
326
- $m .= implode( ', ', $productIds ) . PHP_EOL;
327
- }
328
- woo_feed_log_feed_process( $feedInfo['filename'], $m );
329
- }
330
- }
331
-
332
- if ( 0 == $offset ) {
333
- woo_feed_unlink_tempFiles( $feedInfo, $feedName );
334
- }
335
- $feed_data = woo_feed_generate_batch_data( $feedInfo, $feedName );
336
- if ( $feed_data ) {
337
- woo_feed_log_feed_process( $feedInfo['filename'], sprintf( 'Done Processing Loop %d.', ( $offset + 1 ) ) );
338
- wp_send_json_success(
339
- [
340
- 'success' => true,
341
- 'products' => 'yes',
342
- ]
343
- );
344
- } else {
345
- woo_feed_log_feed_process( $feedInfo['filename'], sprintf( 'No Products found @ Loop %d.', $offset ) );
346
- wp_send_json_success(
347
- [
348
- 'success' => true,
349
- 'products' => 'no',
350
- 'config' => $feedInfo,
351
- ]
352
- );
353
- }
354
- wp_die();
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
- /**
360
- * Ajax Response for Save Feed File
361
- * @throws Exception
362
- * @return void
363
- */
364
- function woo_feed_save_feed_file() {
365
- check_ajax_referer( 'wpf_feed_nonce' );
366
- if ( ! current_user_can( 'manage_woocommerce' ) ) {
367
- woo_feed_log_debug_message( 'User doesnt have enough permission.' );
368
- wp_send_json_error( esc_html__( 'Unauthorized Action.', 'woo-feed' ) );
369
- die();
370
- }
371
- if ( ! isset( $_REQUEST['feed'] ) ) {
372
- wp_send_json_error( esc_html__( 'Invalid Feed.', 'woo-feed' ) );
373
- die();
374
- }
375
-
376
- $feedName = woo_feed_extract_feed_option_name( sanitize_text_field( $_REQUEST['feed'] ) );
377
- $info = get_option( 'wf_config' . $feedName, false );
378
-
379
- if ( ! $info ) {
380
- $getFeedConfig = maybe_unserialize( get_option( 'wf_feed_' . $feedName ) );
381
- $info = $getFeedConfig['feedrules'];
382
- }
383
-
384
- $feedService = $info['provider'];
385
- $type = $info['feedType'];
386
- woo_feed_log_feed_process( $info['filename'], sprintf( 'Preparing Final Feed (%s) File...', $type ) );
387
- woo_feed_log_feed_process( $info['filename'], 'Getting Batch Chunks' );
388
- $feedHeader = woo_feed_get_batch_feed_info( $feedService, $type, 'wf_store_feed_header_info_' . $feedName );
389
- if ( ! $feedHeader ) {
390
- woo_feed_log_feed_process( $info['filename'], 'Unable to Get Header Chunk' );
391
- }
392
- $feedBody = woo_feed_get_batch_feed_info( $feedService, $type, 'wf_store_feed_body_info_' . $feedName );
393
- if ( ! $feedBody ) {
394
- woo_feed_log_feed_process( $info['filename'], 'Unable to Get Body Chunk' );
395
- }
396
- $feedFooter = woo_feed_get_batch_feed_info( $feedService, $type, 'wf_store_feed_footer_info_' . $feedName );
397
- if ( ! $feedFooter ) {
398
- woo_feed_log_feed_process( $info['filename'], 'Unable to Get Footer Chunk' );
399
- }
400
-
401
- if ( 'csv' == $type ) {
402
- $csvHead[0] = $feedHeader;
403
- if ( ! empty( $csvHead ) && ! empty( $feedBody ) ) {
404
- $string = array_merge( $csvHead, $feedBody );
405
- } else {
406
- $string = array();
407
- }
408
- } else {
409
- $string = $feedHeader . $feedBody . $feedFooter;
410
- }
411
-
412
- $upload_dir = wp_get_upload_dir();
413
- $path = $upload_dir['basedir'] . '/woo-feed/' . $feedService . '/' . $type;
414
- $saveFile = false;
415
- $file = '';
416
- // Check If any products founds
417
- if ( $string && ! empty( $string ) ) {
418
- // Save File
419
- $file = $path . '/' . $feedName . '.' . $type;
420
- try {
421
- $save = new Woo_Feed_Savefile();
422
- if ( 'csv' == $type ) {
423
- $saveFile = $save->saveCSVFile( $path, $file, $string, $info );
424
- } else {
425
- $saveFile = $save->saveFile( $path, $file, $string );
426
- }
427
- if ( $saveFile ) {
428
- $message = 'Feed File Successfully Saved.';
429
- } else {
430
- $message = 'Unable to save Feed file. Check Directory Permission.';
431
- }
432
- woo_feed_log_feed_process( $info['filename'], $message );
433
- } catch ( Exception $e ) {
434
- $message = 'Error Saving Feed File' . PHP_EOL . 'Caught Exception :: ' . $e->getMessage();
435
- woo_feed_log( $info['filename'], $message, 'critical', $e, true );
436
- woo_feed_log_fatal_error( $message, $e );
437
- }
438
- } else {
439
- woo_feed_log_feed_process( $info['filename'], 'No Product Found... Exiting File Save Process...' );
440
- if ( isset( $info['fattribute'] ) && count( $info['fattribute'] ) ) {
441
- $data = [
442
- 'success' => false,
443
- 'message' => esc_html__( 'Products not found with your filtering condition.', 'woo-feed' ),
444
- ];
445
- } else {
446
- $data = [
447
- 'success' => false,
448
- 'message' => esc_html__( 'No Product Found with your feed configuration. Please Update And Generate the feed again.', 'woo-feed' ),
449
- ];
450
- }
451
- wp_send_json_error( $data );
452
- wp_die();
453
- }
454
-
455
- $feed_URL = woo_feed_get_file_url( $feedName, $feedService, $type );
456
- // Save Info into database.
457
- $feedInfo = array(
458
- 'feedrules' => $info,
459
- 'url' => $feed_URL,
460
- 'last_updated' => gmdate( 'Y-m-d H:i:s' ),
461
- );
462
- $feedOldInfo = maybe_unserialize( get_option( 'wf_feed_' . $feedName ) );
463
- if ( isset( $feedOldInfo['status'] ) ) {
464
- $feedInfo['status'] = $feedOldInfo['status'];
465
- } else {
466
- $feedInfo['status'] = 1;
467
- }
468
-
469
- woo_feed_unlink_tempFiles( $info, $feedName );
470
-
471
- woo_feed_log_feed_process( $info['filename'], 'Updating Feed Information.' );
472
-
473
- update_option( 'wf_feed_' . $feedName, serialize( $feedInfo ), false ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize
474
-
475
- if ( $saveFile ) {
476
- // FTP File Upload Info
477
- $ftpEnabled = sanitize_text_field( $info['ftpenabled'] );
478
-
479
- if ( $ftpEnabled ) {
480
- woo_feed_handle_file_transfer( $file, $feedName . '.' . $type, $info );
481
- }
482
-
483
- $cat = woo_feed_check_google_category( $feedInfo );
484
- $data = array(
485
- 'info' => $feedInfo,
486
- 'url' => $feed_URL,
487
- 'cat' => $cat,
488
- 'message' => esc_html__( 'Feed Making Complete', 'woo-feed' ),
489
- );
490
- woo_feed_log_feed_process( $info['filename'], 'Done Processing Feed. Exiting Process...' );
491
- wp_send_json_success( $data );
492
- } else {
493
- woo_feed_log_feed_process( $info['filename'], 'Done Processing Feed. Exiting Process...' );
494
- $data = array(
495
- 'success' => false,
496
- 'message' => esc_html__( 'Failed to save feed file. Please confirm that your WordPress directory have read and write permission.', 'woo-feed' ),
497
- );
498
- wp_send_json_error( $data );
499
- }
500
- wp_die();
501
- }
502
  }
503
  // Ajax Helper.
504
  if ( ! function_exists( 'woo_feed_generate_batch_data' ) ) {
505
- /**
506
- * Generate Feed Data
507
- *
508
- * @param array $info Feed info.
509
- * @param string $feedSlug feed option slug.
510
- *
511
- * @return bool
512
- */
513
- function woo_feed_generate_batch_data( $info, $feedSlug ) {
514
- // parse rules.
515
- $info = woo_feed_parse_feed_rules( isset( $info['feedrules'] ) ? $info['feedrules'] : $info );
516
- try {
517
- do_action( 'before_woo_feed_generate_batch_data', $info );
518
- $status = false;
519
- if ( ! empty( $info['provider'] ) ) {
520
- // Get Post data.
521
- $feedService = sanitize_text_field( $info['provider'] );
522
- $type = sanitize_text_field( $info['feedType'] );
523
- $feedRules = $info;
524
- // Get Feed info.
525
- $products = new Woo_Generate_Feed( $feedService, $feedRules );
526
- woo_feed_log_feed_process( $info['filename'], sprintf( 'Initializing merchant Class %s for %s', $feedService, $info['provider'] ) );
527
- $feed = $products->getProducts();
528
- if ( ! empty( $feed['body'] ) ) {
529
- $feedBody = 'wf_store_feed_body_info_' . $feedSlug;
530
- $prevFeed = woo_feed_get_batch_feed_info( $feedService, $type, $feedBody );
531
- if ( $prevFeed ) {
532
- if ( 'csv' == $type ) {
533
- if ( ! empty( $prevFeed ) ) {
534
- $newFeed = array_merge( $prevFeed, $feed['body'] );
535
- woo_feed_save_batch_feed_info( $feedService, $type, $newFeed, $feedBody, $info );
536
- }
537
- } else {
538
- $newFeed = $prevFeed . $feed['body'];
539
- woo_feed_save_batch_feed_info( $feedService, $type, $newFeed, $feedBody, $info );
540
- }
541
- } else {
542
- woo_feed_save_batch_feed_info( $feedService, $type, $feed['body'], $feedBody, $info );
543
- }
544
- woo_feed_save_batch_feed_info( $feedService, $type, $feed['header'], 'wf_store_feed_header_info_' . $feedSlug, $info );
545
- woo_feed_save_batch_feed_info( $feedService, $type, $feed['footer'], 'wf_store_feed_footer_info_' . $feedSlug, $info );
546
- $status = true;
547
- } else {
548
- $status = false;
549
- }
550
- }
551
- do_action( 'after_woo_feed_generate_batch_data', $info );
552
- return $status;
553
- } catch ( Exception $e ) {
554
- $message = 'Error Generating Product Data.' . PHP_EOL . 'Caught Exception :: ' . $e->getMessage();
555
- woo_feed_log( $info['filename'], $message, 'critical', $e, true );
556
- woo_feed_log_fatal_error( $message, $e );
557
- return false;
558
- }
559
- }
560
  }
561
 
562
  // Menu Callback.
563
  if ( ! function_exists( 'woo_feed_generate_new_feed' ) ) {
564
- /**
565
- * Generate Feed
566
- */
567
- function woo_feed_generate_new_feed() {
568
- if ( isset( $_POST['provider'], $_POST['_wpnonce'], $_POST['filename'], $_POST['feedType'] ) ) {
569
- // Verify Nonce.
570
- if ( ! wp_verify_nonce( sanitize_text_field( $_POST['_wpnonce'] ), 'woo_feed_form_nonce' ) ) {
571
- wp_die( esc_html__( 'Failed security check', 'woo-feed' ), 403 );
572
- }
573
- // Check feed type (file ext).
574
- if ( ! woo_feed_check_valid_extension( sanitize_text_field( $_POST['feedType'] ) ) ) {
575
- wp_die( esc_html__( 'Invalid Feed Type!', 'woo-feed' ), 400 );
576
- }
577
-
578
- $fileName = woo_feed_save_feed_config_data( $_POST );
579
-
580
- wp_safe_redirect(
581
- add_query_arg(
582
- [
583
- 'feed_created' => (int) false !== $fileName,
584
- 'feed_regenerate' => 1,
585
- 'feed_name' => $fileName ? $fileName : '',
586
- ],
587
- admin_url( 'admin.php?page=webappick-manage-feeds' )
588
- )
589
- );
590
- die();
591
- } else {
592
- require WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-admin-display.php';
593
- }
594
- }
595
  }
596
  if ( ! function_exists( 'woo_feed_manage_feed' ) ) {
597
- /**
598
- * Manage Feeds
599
- */
600
- function woo_feed_manage_feed() {
601
- // @TODO use admin_post_ action for form handling.
602
- // Manage action for category mapping.
603
- if ( isset( $_GET['action'] ) && 'edit-feed' == $_GET['action'] ) {
604
- if ( ! defined( 'WOO_FEED_EDIT_CONFIG' ) ) define( 'WOO_FEED_EDIT_CONFIG', true );
605
- if ( count( $_POST ) && isset( $_POST['provider'], $_POST['feed_id'], $_POST['feed_option_name'], $_POST['filename'], $_POST['feedType'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
606
- $nonce = isset( $_POST['_wpnonce'] ) && ! empty( $_POST['_wpnonce'] ) ? sanitize_text_field( $_POST['_wpnonce'] ) : '';
607
- if ( ! wp_verify_nonce( $nonce, 'wf_edit_feed' ) ) {
608
- wp_die( esc_html__( 'Failed security check', 'woo-feed' ), 403 );
609
- }
610
- // Check feed type (file ext)
611
- if ( ! woo_feed_check_valid_extension( sanitize_text_field( $_POST['feedType'] ) ) ) {
612
- wp_die( esc_html__( 'Invalid Feed Type!', 'woo-feed' ), 400 );
613
- }
 
614
 
615
  // check if name is changed... save as new, rename feed isn't implemented ... it can be...
616
- // @TODO delete old feed save data as new feed.
617
- $feed_option_name = ( isset( $_POST['feed_option_name'] ) && ! empty( $_POST['feed_option_name'] ) ) ? sanitize_text_field( $_POST['feed_option_name'] ) : NULL;
618
- // if form submitted via $_POST['edit-feed'] then only config and regenerate otherwise only update the config...
619
- // no need to check other submit button ... eg. $_POST['save_feed_config']
620
- $fileName = woo_feed_save_feed_config_data( $_POST, $feed_option_name, isset( $_POST['edit-feed'] ) );
621
- // redirect to the feed list with status
622
- // @TODO this should be handled in admin_init action for proper redirection to work...
623
- wp_safe_redirect(
624
- add_query_arg(
625
- [
626
- 'feed_updated' => (int) false !== $fileName,
627
- 'feed_regenerate' => (int) isset( $_POST['edit-feed'] ),
628
- 'feed_name' => $fileName ? $fileName : '',
629
- ],
630
- admin_url( 'admin.php?page=webappick-manage-feeds' )
631
- )
632
- );
633
- die();
634
- }
635
- if ( isset( $_GET['feed'] ) && ! empty( $_GET['feed'] ) ) {
636
- global $wpdb, $feedRules, $feedName, $feedId, $provider;
637
- $feedName = sanitize_text_field( $_GET['feed'] );
638
- $feedInfo = maybe_unserialize( get_option( $feedName ) );
639
- if ( false !== $feedInfo ) {
640
- $query = $wpdb->prepare( "SELECT option_id FROM $wpdb->options WHERE option_name = %s LIMIT 1", $feedName );
641
- if ( ! $feedId ) {
642
- $result = $wpdb->get_row( $query ); // phpcs:ignore
643
- if ( $result ) {
644
- $feedId = $result->option_id;
645
- }
646
- }
647
- $provider = strtolower( $feedInfo['feedrules']['provider'] );
648
- $feedRules = $feedInfo['feedrules'];
649
- require WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-edit-template.php';
650
- } else {
651
- update_option( 'wpf_message', esc_html__( 'Feed Does not Exists.', 'woo-feed' ), false );
652
- wp_safe_redirect( admin_url( 'admin.php?page=webappick-manage-feeds&wpf_message=error' ) );
653
- die();
654
- }
655
- }
656
- } else {
657
- // Update Interval.
658
- if ( isset( $_POST['wf_schedule'] ) ) {
659
- if ( isset( $_POST['wf_schedule_nonce'] ) && wp_verify_nonce( sanitize_text_field( $_POST['wf_schedule_nonce'] ), 'wf_schedule' ) ) {
660
- $interval = absint( $_POST['wf_schedule'] );
661
- if ( $interval >= woo_feed_get_minimum_interval_option() ) {
662
- if ( update_option( 'wf_schedule', sanitize_text_field( $_POST['wf_schedule'] ), false ) ) {
663
- wp_clear_scheduled_hook( 'woo_feed_update' );
664
- add_filter( 'cron_schedules', 'Woo_Feed_installer::cron_schedules' ); // phpcs:ignore
665
- wp_schedule_event( time(), 'woo_feed_corn', 'woo_feed_update' );
666
- $update = 1; // success.
667
- } else {
668
- $update = 2; // db fail.
669
- }
670
- } else {
671
- $update = 3; // invalid value.
672
  }
673
- } else {
674
- $update = 4; // invalid nonce.
675
  }
676
- wp_safe_redirect( add_query_arg( [ 'schedule_updated' => $update ], admin_url( 'admin.php?page=webappick-manage-feeds' ) ) );
677
- die();
678
- }
679
- require WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-manage-list.php';
680
- }
681
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
682
  }
683
 
684
  // Get Merchant template.
685
  if ( ! function_exists( 'feed_merchant_view' ) ) {
686
- // Load Feed Templates.
687
- add_action( 'wp_ajax_get_feed_merchant', 'feed_merchant_view' );
688
- /**
689
- * Ajax response for Create/Add Feed config table for selected Merchant/Provider
690
- * @return void
691
- */
692
- function feed_merchant_view() {
693
- check_ajax_referer( 'wpf_feed_nonce' );
694
- if ( ! current_user_can( 'manage_woocommerce' ) ) {
695
- woo_feed_log_debug_message( 'User doesnt have enough permission.' );
696
- wp_send_json_error( esc_html__( 'Unauthorized Action.', 'woo-feed' ) );
697
- die();
698
- }
699
- global $feedRules, $wooFeedDropDown, $merchant, $provider;
700
- $provider = isset( $_REQUEST['merchant'] ) && ! empty( $_REQUEST['merchant'] ) ? strtolower( sanitize_text_field( $_REQUEST['merchant'] ) ) : '';
701
- if ( empty( $provider ) ) {
702
- wp_send_json_error( esc_html__( 'Invalid Merchant', 'woo-feed' ) );
703
- wp_die();
704
- }
705
- $merchant = new Woo_Feed_Merchant( $provider );
706
- $feedRules = $merchant->get_template();
707
- $wooFeedDropDown = new Woo_Feed_Dropdown();
708
- ob_start();
709
- require_once WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-edit-tabs.php';
710
- wp_send_json_success( [
711
- 'tabs' => ob_get_clean(),
712
- 'feedType' => strtolower( $merchant->get_feed_types( true ) ),
713
- 'itemsWrapper' => $feedRules['itemsWrapper'],
714
- 'itemWrapper' => $feedRules['itemWrapper'],
715
- 'delimiter' => $feedRules['delimiter'],
716
- 'enclosure' => $feedRules['enclosure'],
717
- 'extraHeader' => $feedRules['extraHeader'],
718
- ] );
719
- wp_die();
720
- }
721
  }
722
  // Get Google Categories.
723
  if ( ! function_exists( 'woo_feed_get_google_categories' ) ) {
724
- add_action( 'wp_ajax_get_google_categories', 'woo_feed_get_google_categories' );
725
- /**
726
- * Ajax Response for Google Category Dropdown Data
727
- * @return void
728
- */
729
- function woo_feed_get_google_categories() {
730
- check_ajax_referer( 'wpf_feed_nonce' );
731
- if ( ! current_user_can( 'manage_woocommerce' ) ) {
732
- woo_feed_log_debug_message( 'User doesnt have enough permission.' );
733
- wp_send_json_error( esc_html__( 'Unauthorized Action.', 'woo-feed' ) );
734
- wp_die();
735
- }
736
- $wooFeedDropDown = new Woo_Feed_Dropdown();
737
- wp_send_json_success( $wooFeedDropDown->googleTaxonomyArray() );
738
- die();
739
- }
740
  }
741
  // sftp status detection.
742
  if ( ! function_exists( 'woo_feed_get_ssh2_status' ) ) {
743
- add_action( 'wp_ajax_get_ssh2_status', 'woo_feed_get_ssh2_status' );
744
- /**
745
- * Ajax Response for ssh2 status check
746
- * @return void
747
- */
748
- function woo_feed_get_ssh2_status() {
749
- check_ajax_referer( 'wpf_feed_nonce' );
750
- if ( ! current_user_can( 'manage_woocommerce' ) ) {
751
- woo_feed_log_debug_message( 'User doesnt have enough permission.' );
752
- wp_send_json_error( esc_html__( 'Unauthorized Action.', 'woo-feed' ) );
753
- wp_die();
754
- }
755
- if ( extension_loaded( 'ssh2' ) ) {
756
- wp_send_json_success( 'exists' );
757
- } else {
758
- wp_send_json_success( 'not_exists' );
759
- }
760
- wp_die();
761
- }
762
  }
763
  // Feed cron status update.
764
  if ( ! function_exists( 'woo_feed_update_feed_status' ) ) {
765
- /**
766
- * Update feed status
767
- */
768
- add_action( 'wp_ajax_update_feed_status', 'woo_feed_update_feed_status' );
769
- /**
770
- * Ajax Response for Update Feed Status
771
- * @return void
772
- */
773
- function woo_feed_update_feed_status() {
774
- check_ajax_referer( 'wpf_feed_nonce' );
775
- if ( ! current_user_can( 'manage_woocommerce' ) ) {
776
- woo_feed_log_debug_message( 'User doesnt have enough permission.' );
777
- wp_send_json_error( esc_html__( 'Unauthorized Action.', 'woo-feed' ) );
778
- wp_die();
779
- }
780
- if ( ! empty( $_POST['feedName'] ) ) {
781
- $feedInfo = maybe_unserialize( get_option( sanitize_text_field( $_POST['feedName'] ) ) );
782
- $feedInfo['status'] = isset( $_POST['status'] ) && 1 == $_POST['status'] ? 1 : 0;
783
- update_option( sanitize_text_field( $_POST['feedName'] ), serialize( $feedInfo ), false ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize
784
- wp_send_json_success( array( 'status' => true ) );
785
- } else {
786
- wp_send_json_error( array( 'status' => false ) );
787
- }
788
- wp_die();
789
- }
790
  }
791
  // Render and handle settings page options.
792
  if ( ! function_exists( 'woo_feed_config_feed' ) ) {
793
- /**
794
- * Feed Settings Page
795
- * @return void
796
- */
797
- function woo_feed_config_feed(){
798
- if ( isset( $_POST['wa_woo_feed_config'], $_POST['_wpnonce'] ) ) {
799
- check_admin_referer( 'woo-feed-config' );
800
-
801
- $data = [
802
- 'per_batch' => isset( $_POST['batch_limit'] ) ? absint( $_POST['batch_limit'] ) : '',
803
- 'product_query_type' => isset( $_POST['product_query_type'] ) ? sanitize_text_field( $_POST['product_query_type'] ) : '',
804
- 'enable_error_debugging' => isset( $_POST['enable_error_debugging'] ) ? sanitize_text_field( $_POST['enable_error_debugging'] ) : '',
805
- 'cache_ttl' => isset( $_POST['cache_ttl'] ) ? absint( $_POST['cache_ttl'] ) : '',
806
- ];
807
-
808
- woo_feed_save_options( $data );
809
 
810
  // $currencyAPI = isset( $_POST['currency_api_code'] ) ? sanitize_text_field( $_POST['currency_api_code'] ) : '';
811
  // update_option( 'woo_feed_currency_api_code', $currencyAPI, false );
812
-
813
- if ( isset( $_POST['opt_in'] ) && 'on' === $_POST['opt_in'] ) {
814
- WooFeedWebAppickAPI::getInstance()->trackerOptIn();
815
- } else {
816
- WooFeedWebAppickAPI::getInstance()->trackerOptOut();
817
- }
818
- // Actions exec by user from settings page
819
- if ( isset( $_POST['clear_all_logs'] ) && 'on' === $_POST['clear_all_logs'] ) {
820
- woo_feed_delete_all_logs();
821
- }
822
- if ( isset( $_POST['purge_feed_cache'] ) ) {
823
- woo_feed_flush_cache_data();
824
- }
825
-
826
- wp_safe_redirect( admin_url( 'admin.php?page=webappick-feed-settings&settings_updated=1' ) );
827
- die();
828
- }
829
-
830
- require WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-settings.php';
831
- }
832
  }
833
  if ( ! function_exists( 'woo_feed_flash_cache_action' ) ) {
834
  /**
11
  * Plugin URI: https://webappick.com/
12
  * Description: Easily generate woocommerce product feed for any marketing channel like Google Shopping(Merchant), Facebook Remarketing, Bing, eBay & more. Support 100+ Merchants.
13
  *
14
+ * Version: 3.6.1
15
  * Author: WebAppick
16
  * Author URI: https://webappick.com/
17
  * License: GPL v2
30
  */
31
 
32
  if ( ! defined( 'ABSPATH' ) ) {
33
+ die(); // If this file is called directly, abort.
34
  }
35
 
36
  if ( ! defined( 'WOO_FEED_FREE_VERSION' ) ) {
37
+ /**
38
+ * Plugin Version
39
+ * @var string
40
+ * @since 3.1.6
41
+ */
42
+ define( 'WOO_FEED_FREE_VERSION', '3.6.1' );
43
  }
44
 
45
  if ( ! defined( 'WOO_FEED_FREE_FILE' ) ) {
46
+ /**
47
+ * Plugin Base File
48
+ * @since 3.1.41
49
+ * @var string
50
+ */
51
+ define( 'WOO_FEED_FREE_FILE', __FILE__ );
52
  }
53
  if ( ! defined( 'WOO_FEED_FREE_PATH' ) ) {
54
+ /**
55
+ * Plugin Path with trailing slash
56
+ * @var string dirname( __FILE__ )
57
+ * * @since 3.1.6
58
+ */
59
+ /** @define "WOO_FEED_FREE_PATH" "./" */ // phpcs:ignore
60
+ define( 'WOO_FEED_FREE_PATH', plugin_dir_path( WOO_FEED_FREE_FILE ) );
61
  }
62
  if ( ! defined( 'WOO_FEED_FREE_ADMIN_PATH' ) ) {
63
+ /**
64
+ * Admin File Path with trailing slash
65
+ * @var string
66
+ * @since 3.1.6
67
+ */
68
+ define( 'WOO_FEED_FREE_ADMIN_PATH', WOO_FEED_FREE_PATH . 'admin/' );
69
  }
70
 
71
  if ( ! defined( 'WOO_FEED_LIBS_PATH' ) ) {
72
+ /**
73
+ * Admin File Path with trailing slash
74
+ * @var string
75
+ */
76
+ define( 'WOO_FEED_LIBS_PATH', WOO_FEED_FREE_PATH . 'libs/' );
77
  }
78
  if ( ! defined( 'WOO_FEED_PLUGIN_URL' ) ) {
79
+ /**
80
+ * Plugin Directory URL
81
+ * @var string
82
+ * @since 3.1.37
83
+ */
84
+ define( 'WOO_FEED_PLUGIN_URL', trailingslashit( plugin_dir_url( WOO_FEED_FREE_FILE ) ) );
85
  }
86
  if ( ! defined( 'WOO_FEED_MIN_PHP_VERSION' ) ) {
87
+ /**
88
+ * Minimum PHP Version Supported
89
+ * @var string
90
+ * @since 3.1.41
91
+ */
92
+ define( 'WOO_FEED_MIN_PHP_VERSION', '5.6' );
93
  }
94
  if ( ! defined( 'WOO_FEED_MIN_WC_VERSION' ) ) {
95
+ /**
96
+ * Minimum WooCommerce Version Supported
97
+ * @var string
98
+ * @since 3.1.45
99
+ */
100
+ define( 'WOO_FEED_MIN_WC_VERSION', '3.2' );
101
  }
102
  if ( ! defined( 'WOO_FEED_PLUGIN_BASE_NAME' ) ) {
103
+ /**
104
+ * Plugin Base name..
105
+ * @var string
106
+ * @since 3.1.41
107
+ */
108
+ define( 'WOO_FEED_PLUGIN_BASE_NAME', plugin_basename( WOO_FEED_FREE_FILE ) );
109
  }
110
 
111
  if ( ! defined( 'WOO_FEED_LOG_DIR' ) ) {
112
+ $upload_dir = wp_get_upload_dir();
113
+ /**
114
+ * Log Directory
115
+ * @var string
116
+ * @since 3.2.1
117
+ */
118
+ /** @define "WOO_FEED_LOG_DIR" "./../../uploads/woo-feed/logs" */ // phpcs:ignore
119
+ define( 'WOO_FEED_LOG_DIR', $upload_dir['basedir'] . '/woo-feed/logs/' );
120
  }
121
 
122
  if ( ! defined( 'WOO_FEED_CACHE_TTL' ) ) {
123
+ $_cache_ttl = get_option( 'woo_feed_settings', [ 'cache_ttl' => 6 * HOUR_IN_SECONDS ] );
124
+ /**
125
+ * Cache TTL
126
+ * @var int
127
+ * @since 3.3.11
128
+ */
129
+ define( 'WOO_FEED_CACHE_TTL', $_cache_ttl['cache_ttl'] );
130
  }
131
 
132
  /**
147
  require_once WOO_FEED_FREE_PATH . 'includes/class-woo-feed-installer.php';
148
 
149
  if ( ! class_exists( 'Woo_Feed' ) ) {
150
+ /**
151
+ * The core plugin class that is used to define internationalization,
152
+ * admin-specific hooks, and public-facing site hooks.
153
+ */
154
+ require WOO_FEED_FREE_PATH . 'includes/class-woo-feed.php';
155
  }
156
 
157
  if ( ! function_exists( 'run_woo_feed' ) ) {
158
+ /**
159
+ * Begins execution of the plugin.
160
+ *
161
+ * Since everything within the plugin is registered via hooks,
162
+ * then kicking off the plugin from this point in the file does
163
+ * not affect the page life cycle.
164
+ *
165
+ * @since 1.0.0
166
+ */
167
+ function run_woo_feed() {
168
+ $plugin = new Woo_Feed();
169
+ register_activation_hook( WOO_FEED_FREE_FILE, [ 'Woo_Feed_installer', 'install' ] );
170
+ register_shutdown_function( 'woo_feed_log_errors_at_shutdown' );
171
+ add_action( 'woo_feed_cleanup_logs', 'woo_feed_cleanup_logs' );
172
+ /**
173
+ * Ensure Feed Plugin runs only if WooCommerce loaded (installed and activated)
174
+ * @since 3.1.41
175
+ */
176
+ add_action( 'plugins_loaded', [ $plugin, 'run' ], PHP_INT_MAX );
177
+ add_action( 'admin_notices', 'wooFeed_Admin_Notices' );
178
+ WooFeedWebAppickAPI::getInstance();
179
+ }
180
+
181
+ run_woo_feed();
182
  }
183
 
184
  // ======================================================================================================================*
187
  //
188
  // ======================================================================================================================*
189
  if ( ! function_exists( 'woo_feed_get_product_information' ) ) {
190
+ add_action( 'wp_ajax_get_product_information', 'woo_feed_get_product_information' );
191
+ /**
192
+ * Count Total Products
193
+ */
194
+ function woo_feed_get_product_information() {
195
+ check_ajax_referer( 'wpf_feed_nonce' );
196
+ if ( ! current_user_can( 'manage_woocommerce' ) ) {
197
+ woo_feed_log_debug_message( 'User doesnt have enough permission.' );
198
+ wp_send_json_error( esc_html__( 'Unauthorized Action.', 'woo-feed' ) );
199
+ die();
200
+ }
201
+ // @TODO use only WC_Product_Query it's available from WC 3.2, we don't support earlier versions of wc.
202
+ if ( ! isset( $_REQUEST['feed'] ) ) {
203
+ wp_send_json_error( esc_html__( 'Invalid Request.', 'woo-feed' ) );
204
+ die();
205
+ }
206
+ $feed = sanitize_text_field( $_REQUEST['feed'] );
207
+ $feed = woo_feed_extract_feed_option_name( $feed );
208
+ $limit = isset( $_REQUEST['limit'] ) ? absint( $_REQUEST['limit'] ) : 200;
209
+ $getConfig = maybe_unserialize( get_option( 'wf_config' . $feed ) );
210
+
211
+ if ( woo_feed_wc_version_check( 3.2 ) ) {
212
+ if ( woo_feed_is_debugging_enabled() ) {
213
+ // clear log, set the pointer to the beginning of the file.
214
+ woo_feed_delete_log( $getConfig['filename'] );
215
+ woo_feed_log_feed_process( $getConfig['filename'], sprintf( 'Getting Data for %s feed.', $feed ) );
216
+ woo_feed_log_feed_process( $getConfig['filename'], 'Generating Feed VIA Ajax...' );
217
+ woo_feed_log_feed_process( $getConfig['filename'], sprintf( 'Getting Data for %s feed.', $feed ) );
218
+ woo_feed_log_feed_process( $getConfig['filename'], sprintf( 'Current Limit is %d.', $limit ) );
219
+ woo_feed_log( $getConfig['filename'], 'Feed Config::' . PHP_EOL . print_r( $getConfig, true ), 'info' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
220
+ }
221
+ try {
222
+ do_action( 'before_woo_feed_get_product_information', $getConfig );
223
+ $products = new Woo_Feed_Products_v3( $getConfig );
224
+ $ids = $products->query_products();
225
+ do_action( 'after_woo_feed_get_product_information', $getConfig );
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 );
232
+ }
233
+ woo_feed_log_feed_process( $getConfig['filename'], sprintf( 'Total %d batches', count( $batches ) ) );
234
+ wp_send_json_success(
235
+ [
236
+ 'product' => $batches,
237
+ 'total' => count( $ids ),
238
+ 'success' => true,
239
+ ]
240
+ );
241
+ wp_die();
242
+ } else {
243
+ wp_send_json_error(
244
+ [
245
+ 'message' => esc_html__( 'No products found. Add product or change feed config before generate the feed.', 'woo-feed' ),
246
+ 'success' => false,
247
+ ]
248
+ );
249
+ wp_die();
250
+ }
251
+ } catch ( Exception $e ) {
252
+ if ( woo_feed_is_debugging_enabled() ) {
253
+ $message = 'Error getting Product Ids.' . PHP_EOL . 'Caught Exception :: ' . $e->getMessage();
254
+ woo_feed_log( $getConfig['filename'], $message, 'critical', $e, true );
255
+ woo_feed_log_fatal_error( $message, $e );
256
+ }
257
+ wp_send_json_error(
258
+ [
259
+ 'message' => esc_html__( 'Failed to fetch products.', 'woo-feed' ),
260
+ 'success' => false,
261
+ ]
262
+ );
263
+ wp_die();
264
+ }
265
+ } else {
266
+ do_action( 'before_woo_feed_get_product_information', $getConfig );
267
+ $products = wp_count_posts( 'product' );
268
+ do_action( 'after_woo_feed_get_product_information', $getConfig );
269
+ if ( $products->publish > 0 ) {
270
+ $data['success'] = true;
271
+ wp_send_json_success(
272
+ [
273
+ 'product' => $products->publish,
274
+ 'success' => false,
275
+ ]
276
+ );
277
+ wp_die();
278
+ } else {
279
+ wp_send_json_error(
280
+ [
281
+ 'message' => esc_html__( 'No products found. Add product or change feed config before generate the feed.', 'woo-feed' ),
282
+ 'success' => false,
283
+ ]
284
+ );
285
+ wp_die();
286
+ }
287
+ }
288
+ }
289
  }
290
  if ( ! function_exists( 'woo_feed_make_batch_feed' ) ) {
291
+ add_action( 'wp_ajax_make_batch_feed', 'woo_feed_make_batch_feed' );
292
+ /**
293
+ * Ajax Batch Callback
294
+ * @return void
295
+ */
296
+ function woo_feed_make_batch_feed() {
297
+ check_ajax_referer( 'wpf_feed_nonce' );
298
+ if ( ! current_user_can( 'manage_woocommerce' ) ) {
299
+ woo_feed_log_debug_message( 'User doesnt have enough permission.' );
300
+ wp_send_json_error( esc_html__( 'Unauthorized Action.', 'woo-feed' ) );
301
+ die();
302
+ }
303
+ if ( ! isset( $_REQUEST['feed'] ) ) {
304
+ wp_send_json_error( esc_html__( 'Invalid Request.', 'woo-feed' ) );
305
+ die();
306
+ }
307
+
308
+ $feedName = woo_feed_extract_feed_option_name( sanitize_text_field( $_REQUEST['feed'] ) );
309
+ $feedInfo = get_option( 'wf_config' . $feedName, false );
310
+
311
+ if ( ! $feedInfo ) {
312
+ $getFeedConfig = maybe_unserialize( get_option( 'wf_feed_' . $feedName ) );
313
+ $feedInfo = $getFeedConfig['feedrules'];
314
+ }
315
+
316
+ $feedInfo['productIds'] = isset( $_REQUEST['products'] ) ? array_map( 'absint', $_REQUEST['products'] ) : [];
317
+ $offset = isset( $_REQUEST['loop'] ) ? absint( $_REQUEST['loop'] ) : 0;
318
+ if ( woo_feed_is_debugging_enabled() ) {
319
+ if ( 0 == $offset ) {
320
+ woo_feed_log_feed_process( $feedInfo['filename'], 'Generating Feed... ' );
321
+ }
322
+ if ( woo_feed_is_debugging_enabled() ) {
323
+ woo_feed_log_feed_process( $feedInfo['filename'], sprintf( 'Processing Loop %d.', ( $offset + 1 ) ) );
324
+ $m = 'Processing Product Following Product (IDs) : ' . PHP_EOL;
325
+ foreach ( array_chunk( $feedInfo['productIds'], 10 ) as $productIds ) { // pretty print log [B-)=
326
+ $m .= implode( ', ', $productIds ) . PHP_EOL;
327
+ }
328
+ woo_feed_log_feed_process( $feedInfo['filename'], $m );
329
+ }
330
+ }
331
+
332
+ if ( 0 == $offset ) {
333
+ woo_feed_unlink_tempFiles( $feedInfo, $feedName );
334
+ }
335
+ $feed_data = woo_feed_generate_batch_data( $feedInfo, $feedName );
336
+ if ( $feed_data ) {
337
+ woo_feed_log_feed_process( $feedInfo['filename'], sprintf( 'Done Processing Loop %d.', ( $offset + 1 ) ) );
338
+ wp_send_json_success(
339
+ [
340
+ 'success' => true,
341
+ 'products' => 'yes',
342
+ ]
343
+ );
344
+ } else {
345
+ woo_feed_log_feed_process( $feedInfo['filename'], sprintf( 'No Products found @ Loop %d.', $offset ) );
346
+ wp_send_json_success(
347
+ [
348
+ 'success' => true,
349
+ 'products' => 'no',
350
+ 'config' => $feedInfo,
351
+ ]
352
+ );
353
+ }
354
+ wp_die();
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
+ /**
360
+ * Ajax Response for Save Feed File
361
+ * @throws Exception
362
+ * @return void
363
+ */
364
+ function woo_feed_save_feed_file() {
365
+ check_ajax_referer( 'wpf_feed_nonce' );
366
+ if ( ! current_user_can( 'manage_woocommerce' ) ) {
367
+ woo_feed_log_debug_message( 'User doesnt have enough permission.' );
368
+ wp_send_json_error( esc_html__( 'Unauthorized Action.', 'woo-feed' ) );
369
+ die();
370
+ }
371
+ if ( ! isset( $_REQUEST['feed'] ) ) {
372
+ wp_send_json_error( esc_html__( 'Invalid Feed.', 'woo-feed' ) );
373
+ die();
374
+ }
375
+
376
+ $feedName = woo_feed_extract_feed_option_name( sanitize_text_field( $_REQUEST['feed'] ) );
377
+ $info = get_option( 'wf_config' . $feedName, false );
378
+
379
+ if ( ! $info ) {
380
+ $getFeedConfig = maybe_unserialize( get_option( 'wf_feed_' . $feedName ) );
381
+ $info = $getFeedConfig['feedrules'];
382
+ }
383
+
384
+ $feedService = $info['provider'];
385
+ $type = $info['feedType'];
386
+ woo_feed_log_feed_process( $info['filename'], sprintf( 'Preparing Final Feed (%s) File...', $type ) );
387
+ woo_feed_log_feed_process( $info['filename'], 'Getting Batch Chunks' );
388
+ $feedHeader = woo_feed_get_batch_feed_info( $feedService, $type, 'wf_store_feed_header_info_' . $feedName );
389
+ if ( ! $feedHeader ) {
390
+ woo_feed_log_feed_process( $info['filename'], 'Unable to Get Header Chunk' );
391
+ }
392
+ $feedBody = woo_feed_get_batch_feed_info( $feedService, $type, 'wf_store_feed_body_info_' . $feedName );
393
+ if ( ! $feedBody ) {
394
+ woo_feed_log_feed_process( $info['filename'], 'Unable to Get Body Chunk' );
395
+ }
396
+ $feedFooter = woo_feed_get_batch_feed_info( $feedService, $type, 'wf_store_feed_footer_info_' . $feedName );
397
+ if ( ! $feedFooter ) {
398
+ woo_feed_log_feed_process( $info['filename'], 'Unable to Get Footer Chunk' );
399
+ }
400
+
401
+ if ( 'csv' == $type ) {
402
+ $csvHead[0] = $feedHeader;
403
+ if ( ! empty( $csvHead ) && ! empty( $feedBody ) ) {
404
+ $string = array_merge( $csvHead, $feedBody );
405
+ } else {
406
+ $string = array();
407
+ }
408
+ } else {
409
+ $string = $feedHeader . $feedBody . $feedFooter;
410
+ }
411
+
412
+ $upload_dir = wp_get_upload_dir();
413
+ $path = $upload_dir['basedir'] . '/woo-feed/' . $feedService . '/' . $type;
414
+ $saveFile = false;
415
+ $file = '';
416
+ // Check If any products founds
417
+ if ( $string && ! empty( $string ) ) {
418
+ // Save File
419
+ $file = $path . '/' . $feedName . '.' . $type;
420
+ try {
421
+ $save = new Woo_Feed_Savefile();
422
+ if ( 'csv' == $type ) {
423
+ $saveFile = $save->saveCSVFile( $path, $file, $string, $info );
424
+ } else {
425
+ $saveFile = $save->saveFile( $path, $file, $string );
426
+ }
427
+ if ( $saveFile ) {
428
+ $message = 'Feed File Successfully Saved.';
429
+ } else {
430
+ $message = 'Unable to save Feed file. Check Directory Permission.';
431
+ }
432
+ woo_feed_log_feed_process( $info['filename'], $message );
433
+ } catch ( Exception $e ) {
434
+ $message = 'Error Saving Feed File' . PHP_EOL . 'Caught Exception :: ' . $e->getMessage();
435
+ woo_feed_log( $info['filename'], $message, 'critical', $e, true );
436
+ woo_feed_log_fatal_error( $message, $e );
437
+ }
438
+ } else {
439
+ woo_feed_log_feed_process( $info['filename'], 'No Product Found... Exiting File Save Process...' );
440
+ if ( isset( $info['fattribute'] ) && count( $info['fattribute'] ) ) {
441
+ $data = [
442
+ 'success' => false,
443
+ 'message' => esc_html__( 'Products not found with your filtering condition.', 'woo-feed' ),
444
+ ];
445
+ } else {
446
+ $data = [
447
+ 'success' => false,
448
+ 'message' => esc_html__( 'No Product Found with your feed configuration. Please Update And Generate the feed again.', 'woo-feed' ),
449
+ ];
450
+ }
451
+ wp_send_json_error( $data );
452
+ wp_die();
453
+ }
454
+
455
+ $feed_URL = woo_feed_get_file_url( $feedName, $feedService, $type );
456
+ // Save Info into database.
457
+ $feedInfo = array(
458
+ 'feedrules' => $info,
459
+ 'url' => $feed_URL,
460
+ 'last_updated' => gmdate( 'Y-m-d H:i:s' ),
461
+ );
462
+ $feedOldInfo = maybe_unserialize( get_option( 'wf_feed_' . $feedName ) );
463
+ if ( isset( $feedOldInfo['status'] ) ) {
464
+ $feedInfo['status'] = $feedOldInfo['status'];
465
+ } else {
466
+ $feedInfo['status'] = 1;
467
+ }
468
+
469
+ woo_feed_unlink_tempFiles( $info, $feedName );
470
+
471
+ woo_feed_log_feed_process( $info['filename'], 'Updating Feed Information.' );
472
+
473
+ update_option( 'wf_feed_' . $feedName, serialize( $feedInfo ), false ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize
474
+
475
+ if ( $saveFile ) {
476
+ // FTP File Upload Info
477
+ $ftpEnabled = sanitize_text_field( $info['ftpenabled'] );
478
+
479
+ if ( $ftpEnabled ) {
480
+ woo_feed_handle_file_transfer( $file, $feedName . '.' . $type, $info );
481
+ }
482
+
483
+ $cat = woo_feed_check_google_category( $feedInfo );
484
+ $data = array(
485
+ 'info' => $feedInfo,
486
+ 'url' => $feed_URL,
487
+ 'cat' => $cat,
488
+ 'message' => esc_html__( 'Feed Making Complete', 'woo-feed' ),
489
+ );
490
+ woo_feed_log_feed_process( $info['filename'], 'Done Processing Feed. Exiting Process...' );
491
+ wp_send_json_success( $data );
492
+ } else {
493
+ woo_feed_log_feed_process( $info['filename'], 'Done Processing Feed. Exiting Process...' );
494
+ $data = array(
495
+ 'success' => false,
496
+ 'message' => esc_html__( 'Failed to save feed file. Please confirm that your WordPress directory have read and write permission.', 'woo-feed' ),
497
+ );
498
+ wp_send_json_error( $data );
499
+ }
500
+ wp_die();
501
+ }
502
  }
503
  // Ajax Helper.
504
  if ( ! function_exists( 'woo_feed_generate_batch_data' ) ) {
505
+ /**
506
+ * Generate Feed Data
507
+ *
508
+ * @param array $info Feed info.
509
+ * @param string $feedSlug feed option slug.
510
+ *
511
+ * @return bool
512
+ */
513
+ function woo_feed_generate_batch_data( $info, $feedSlug ) {
514
+ // parse rules.
515
+ $info = woo_feed_parse_feed_rules( isset( $info['feedrules'] ) ? $info['feedrules'] : $info );
516
+ try {
517
+ do_action( 'before_woo_feed_generate_batch_data', $info );
518
+ $status = false;
519
+ if ( ! empty( $info['provider'] ) ) {
520
+ // Get Post data.
521
+ $feedService = sanitize_text_field( $info['provider'] );
522
+ $type = sanitize_text_field( $info['feedType'] );
523
+ $feedRules = $info;
524
+ // Get Feed info.
525
+ $products = new Woo_Generate_Feed( $feedService, $feedRules );
526
+ woo_feed_log_feed_process( $info['filename'], sprintf( 'Initializing merchant Class %s for %s', $feedService, $info['provider'] ) );
527
+ $feed = $products->getProducts();
528
+ if ( ! empty( $feed['body'] ) ) {
529
+ $feedBody = 'wf_store_feed_body_info_' . $feedSlug;
530
+ $prevFeed = woo_feed_get_batch_feed_info( $feedService, $type, $feedBody );
531
+ if ( $prevFeed ) {
532
+ if ( 'csv' == $type ) {
533
+ if ( ! empty( $prevFeed ) ) {
534
+ $newFeed = array_merge( $prevFeed, $feed['body'] );
535
+ woo_feed_save_batch_feed_info( $feedService, $type, $newFeed, $feedBody, $info );
536
+ }
537
+ } else {
538
+ $newFeed = $prevFeed . $feed['body'];
539
+ woo_feed_save_batch_feed_info( $feedService, $type, $newFeed, $feedBody, $info );
540
+ }
541
+ } else {
542
+ woo_feed_save_batch_feed_info( $feedService, $type, $feed['body'], $feedBody, $info );
543
+ }
544
+ woo_feed_save_batch_feed_info( $feedService, $type, $feed['header'], 'wf_store_feed_header_info_' . $feedSlug, $info );
545
+ woo_feed_save_batch_feed_info( $feedService, $type, $feed['footer'], 'wf_store_feed_footer_info_' . $feedSlug, $info );
546
+ $status = true;
547
+ } else {
548
+ $status = false;
549
+ }
550
+ }
551
+ do_action( 'after_woo_feed_generate_batch_data', $info );
552
+ return $status;
553
+ } catch ( Exception $e ) {
554
+ $message = 'Error Generating Product Data.' . PHP_EOL . 'Caught Exception :: ' . $e->getMessage();
555
+ woo_feed_log( $info['filename'], $message, 'critical', $e, true );
556
+ woo_feed_log_fatal_error( $message, $e );
557
+ return false;
558
+ }
559
+ }
560
  }
561
 
562
  // Menu Callback.
563
  if ( ! function_exists( 'woo_feed_generate_new_feed' ) ) {
564
+ /**
565
+ * Generate Feed
566
+ */
567
+ function woo_feed_generate_new_feed() {
568
+ if ( isset( $_POST['provider'], $_POST['_wpnonce'], $_POST['filename'], $_POST['feedType'] ) ) {
569
+ // Verify Nonce.
570
+ if ( ! wp_verify_nonce( sanitize_text_field( $_POST['_wpnonce'] ), 'woo_feed_form_nonce' ) ) {
571
+ wp_die( esc_html__( 'Failed security check', 'woo-feed' ), 403 );
572
+ }
573
+ // Check feed type (file ext).
574
+ if ( ! woo_feed_check_valid_extension( sanitize_text_field( $_POST['feedType'] ) ) ) {
575
+ wp_die( esc_html__( 'Invalid Feed Type!', 'woo-feed' ), 400 );
576
+ }
577
+
578
+ $fileName = woo_feed_save_feed_config_data( $_POST );
579
+
580
+ wp_safe_redirect(
581
+ add_query_arg(
582
+ [
583
+ 'feed_created' => (int) false !== $fileName,
584
+ 'feed_regenerate' => 1,
585
+ 'feed_name' => $fileName ? $fileName : '',
586
+ ],
587
+ admin_url( 'admin.php?page=webappick-manage-feeds' )
588
+ )
589
+ );
590
+ die();
591
+ } else {
592
+ require WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-admin-display.php';
593
+ }
594
+ }
595
  }
596
  if ( ! function_exists( 'woo_feed_manage_feed' ) ) {
597
+ /**
598
+ * Manage Feeds
599
+ */
600
+ function woo_feed_manage_feed() {
601
+ // @TODO use admin_post_ action for form handling.
602
+ // Manage action for category mapping.
603
+ if ( isset( $_GET['action'] ) && 'edit-feed' == $_GET['action'] ) {
604
+ if ( ! defined( 'WOO_FEED_EDIT_CONFIG' ) ) define( 'WOO_FEED_EDIT_CONFIG', true );
605
+ if ( count( $_POST ) && isset( $_POST['provider'], $_POST['feed_id'], $_POST['feed_option_name'], $_POST['filename'], $_POST['feedType'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
606
+ $nonce = isset( $_POST['_wpnonce'] ) && ! empty( $_POST['_wpnonce'] ) ? sanitize_text_field( $_POST['_wpnonce'] ) : '';
607
+ if ( ! wp_verify_nonce( $nonce, 'wf_edit_feed' ) ) {
608
+ wp_die( esc_html__( 'Failed security check', 'woo-feed' ), 403 );
609
+ }
610
+ // Check feed type (file ext)
611
+ if ( ! woo_feed_check_valid_extension( sanitize_text_field( $_POST['feedType'] ) ) ) {
612
+ wp_die( esc_html__( 'Invalid Feed Type!', 'woo-feed' ), 400 );
613
+ }
614
+
615
 
616
  // check if name is changed... save as new, rename feed isn't implemented ... it can be...
617
+ // delete old feed save data as new feed.
618
+ $feed_option_name = ( isset( $_POST['feed_option_name'] ) && ! empty( $_POST['feed_option_name'] ) ) ? sanitize_text_field( $_POST['feed_option_name'] ) : null;
619
+ if ( $_POST['filename'] !== $_POST['feed_option_name'] ) {
620
+ $feed_option_name = ( isset( $_POST['filename'] ) && ! empty( $_POST['filename'] ) ) ? sanitize_text_field( $_POST['filename'] ) : null;
621
+ // Delete old feed info & file
622
+ delete_option( 'wf_feed_' . $_POST['feed_option_name'] );
623
+ delete_option( 'wf_config' . $_POST['feed_option_name'] );
624
+
625
+ $upload_dir = wp_get_upload_dir();
626
+ $feedService = $_POST['provider'];
627
+ $type = $_POST['feedType'];
628
+ $old_name = $_POST['feed_option_name'];
629
+ $path = $upload_dir['basedir'] . '/woo-feed/' . $feedService . '/' . $type . '/' . $old_name . '.' . $type;
630
+ if ( file_exists( $path ) ) {
631
+ unlink( $path );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
632
  }
 
 
633
  }
634
+ // if form submitted via $_POST['edit-feed'] then only config and regenerate otherwise only update the config...
635
+ // no need to check other submit button ... eg. $_POST['save_feed_config']
636
+ $fileName = woo_feed_save_feed_config_data( $_POST, $feed_option_name, isset( $_POST['edit-feed'] ) );
637
+ // redirect to the feed list with status
638
+ // @TODO this should be handled in admin_init action for proper redirection to work...
639
+ wp_safe_redirect(
640
+ add_query_arg(
641
+ [
642
+ 'feed_updated' => (int) false !== $fileName,
643
+ 'feed_regenerate' => (int) isset( $_POST['edit-feed'] ),
644
+ 'feed_name' => $fileName ? $fileName : '',
645
+ ],
646
+ admin_url( 'admin.php?page=webappick-manage-feeds' )
647
+ )
648
+ );
649
+ die();
650
+ }
651
+ if ( isset( $_GET['feed'] ) && ! empty( $_GET['feed'] ) ) {
652
+ global $wpdb, $feedRules, $feedName, $feedId, $provider;
653
+ $feedName = sanitize_text_field( $_GET['feed'] );
654
+ $feedInfo = maybe_unserialize( get_option( $feedName ) );
655
+ if ( false !== $feedInfo ) {
656
+ $query = $wpdb->prepare( "SELECT option_id FROM $wpdb->options WHERE option_name = %s LIMIT 1", $feedName );
657
+ if ( ! $feedId ) {
658
+ $result = $wpdb->get_row( $query ); // phpcs:ignore
659
+ if ( $result ) {
660
+ $feedId = $result->option_id;
661
+ }
662
+ }
663
+ $provider = strtolower( $feedInfo['feedrules']['provider'] );
664
+ $feedRules = $feedInfo['feedrules'];
665
+ require WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-edit-template.php';
666
+ } else {
667
+ update_option( 'wpf_message', esc_html__( 'Feed Does not Exists.', 'woo-feed' ), false );
668
+ wp_safe_redirect( admin_url( 'admin.php?page=webappick-manage-feeds&wpf_message=error' ) );
669
+ die();
670
+ }
671
+ }
672
+ } else {
673
+ // Update Interval.
674
+ if ( isset( $_POST['wf_schedule'] ) ) {
675
+ if ( isset( $_POST['wf_schedule_nonce'] ) && wp_verify_nonce( sanitize_text_field( $_POST['wf_schedule_nonce'] ), 'wf_schedule' ) ) {
676
+ $interval = absint( $_POST['wf_schedule'] );
677
+ if ( $interval >= woo_feed_get_minimum_interval_option() ) {
678
+ if ( update_option( 'wf_schedule', sanitize_text_field( $_POST['wf_schedule'] ), false ) ) {
679
+ wp_clear_scheduled_hook( 'woo_feed_update' );
680
+ add_filter( 'cron_schedules', 'Woo_Feed_installer::cron_schedules' ); // phpcs:ignore
681
+ wp_schedule_event( time(), 'woo_feed_corn', 'woo_feed_update' );
682
+ $update = 1; // success.
683
+ } else {
684
+ $update = 2; // db fail.
685
+ }
686
+ } else {
687
+ $update = 3; // invalid value.
688
+ }
689
+ } else {
690
+ $update = 4; // invalid nonce.
691
+ }
692
+ wp_safe_redirect( add_query_arg( [ 'schedule_updated' => $update ], admin_url( 'admin.php?page=webappick-manage-feeds' ) ) );
693
+ die();
694
+ }
695
+ require WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-manage-list.php';
696
+ }
697
+ }
698
  }
699
 
700
  // Get Merchant template.
701
  if ( ! function_exists( 'feed_merchant_view' ) ) {
702
+ // Load Feed Templates.
703
+ add_action( 'wp_ajax_get_feed_merchant', 'feed_merchant_view' );
704
+ /**
705
+ * Ajax response for Create/Add Feed config table for selected Merchant/Provider
706
+ * @return void
707
+ */
708
+ function feed_merchant_view() {
709
+ check_ajax_referer( 'wpf_feed_nonce' );
710
+ if ( ! current_user_can( 'manage_woocommerce' ) ) {
711
+ woo_feed_log_debug_message( 'User doesnt have enough permission.' );
712
+ wp_send_json_error( esc_html__( 'Unauthorized Action.', 'woo-feed' ) );
713
+ die();
714
+ }
715
+ global $feedRules, $wooFeedDropDown, $merchant, $provider;
716
+ $provider = isset( $_REQUEST['merchant'] ) && ! empty( $_REQUEST['merchant'] ) ? strtolower( sanitize_text_field( $_REQUEST['merchant'] ) ) : '';
717
+ if ( empty( $provider ) ) {
718
+ wp_send_json_error( esc_html__( 'Invalid Merchant', 'woo-feed' ) );
719
+ wp_die();
720
+ }
721
+ $merchant = new Woo_Feed_Merchant( $provider );
722
+ $feedRules = $merchant->get_template();
723
+ $wooFeedDropDown = new Woo_Feed_Dropdown();
724
+ ob_start();
725
+ require_once WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-edit-tabs.php';
726
+ wp_send_json_success( [
727
+ 'tabs' => ob_get_clean(),
728
+ 'feedType' => strtolower( $merchant->get_feed_types( true ) ),
729
+ 'itemsWrapper' => $feedRules['itemsWrapper'],
730
+ 'itemWrapper' => $feedRules['itemWrapper'],
731
+ 'delimiter' => $feedRules['delimiter'],
732
+ 'enclosure' => $feedRules['enclosure'],
733
+ 'extraHeader' => $feedRules['extraHeader'],
734
+ ] );
735
+ wp_die();
736
+ }
737
  }
738
  // Get Google Categories.
739
  if ( ! function_exists( 'woo_feed_get_google_categories' ) ) {
740
+ add_action( 'wp_ajax_get_google_categories', 'woo_feed_get_google_categories' );
741
+ /**
742
+ * Ajax Response for Google Category Dropdown Data
743
+ * @return void
744
+ */
745
+ function woo_feed_get_google_categories() {
746
+ check_ajax_referer( 'wpf_feed_nonce' );
747
+ if ( ! current_user_can( 'manage_woocommerce' ) ) {
748
+ woo_feed_log_debug_message( 'User doesnt have enough permission.' );
749
+ wp_send_json_error( esc_html__( 'Unauthorized Action.', 'woo-feed' ) );
750
+ wp_die();
751
+ }
752
+ $wooFeedDropDown = new Woo_Feed_Dropdown();
753
+ wp_send_json_success( $wooFeedDropDown->googleTaxonomyArray() );
754
+ die();
755
+ }
756
  }
757
  // sftp status detection.
758
  if ( ! function_exists( 'woo_feed_get_ssh2_status' ) ) {
759
+ add_action( 'wp_ajax_get_ssh2_status', 'woo_feed_get_ssh2_status' );
760
+ /**
761
+ * Ajax Response for ssh2 status check
762
+ * @return void
763
+ */
764
+ function woo_feed_get_ssh2_status() {
765
+ check_ajax_referer( 'wpf_feed_nonce' );
766
+ if ( ! current_user_can( 'manage_woocommerce' ) ) {
767
+ woo_feed_log_debug_message( 'User doesnt have enough permission.' );
768
+ wp_send_json_error( esc_html__( 'Unauthorized Action.', 'woo-feed' ) );
769
+ wp_die();
770
+ }
771
+ if ( extension_loaded( 'ssh2' ) ) {
772
+ wp_send_json_success( 'exists' );
773
+ } else {
774
+ wp_send_json_success( 'not_exists' );
775
+ }
776
+ wp_die();
777
+ }
778
  }
779
  // Feed cron status update.
780
  if ( ! function_exists( 'woo_feed_update_feed_status' ) ) {
781
+ /**
782
+ * Update feed status
783
+ */
784
+ add_action( 'wp_ajax_update_feed_status', 'woo_feed_update_feed_status' );
785
+ /**
786
+ * Ajax Response for Update Feed Status
787
+ * @return void
788
+ */
789
+ function woo_feed_update_feed_status() {
790
+ check_ajax_referer( 'wpf_feed_nonce' );
791
+ if ( ! current_user_can( 'manage_woocommerce' ) ) {
792
+ woo_feed_log_debug_message( 'User doesnt have enough permission.' );
793
+ wp_send_json_error( esc_html__( 'Unauthorized Action.', 'woo-feed' ) );
794
+ wp_die();
795
+ }
796
+ if ( ! empty( $_POST['feedName'] ) ) {
797
+ $feedInfo = maybe_unserialize( get_option( sanitize_text_field( $_POST['feedName'] ) ) );
798
+ $feedInfo['status'] = isset( $_POST['status'] ) && 1 == $_POST['status'] ? 1 : 0;
799
+ update_option( sanitize_text_field( $_POST['feedName'] ), serialize( $feedInfo ), false ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize
800
+ wp_send_json_success( array( 'status' => true ) );
801
+ } else {
802
+ wp_send_json_error( array( 'status' => false ) );
803
+ }
804
+ wp_die();
805
+ }
806
  }
807
  // Render and handle settings page options.
808
  if ( ! function_exists( 'woo_feed_config_feed' ) ) {
809
+ /**
810
+ * Feed Settings Page
811
+ * @return void
812
+ */
813
+ function woo_feed_config_feed(){
814
+ if ( isset( $_POST['wa_woo_feed_config'], $_POST['_wpnonce'] ) ) {
815
+ check_admin_referer( 'woo-feed-config' );
816
+
817
+ $data = [
818
+ 'per_batch' => isset( $_POST['batch_limit'] ) ? absint( $_POST['batch_limit'] ) : '',
819
+ 'product_query_type' => isset( $_POST['product_query_type'] ) ? sanitize_text_field( $_POST['product_query_type'] ) : '',
820
+ 'enable_error_debugging' => isset( $_POST['enable_error_debugging'] ) ? sanitize_text_field( $_POST['enable_error_debugging'] ) : '',
821
+ 'cache_ttl' => isset( $_POST['cache_ttl'] ) ? absint( $_POST['cache_ttl'] ) : '',
822
+ ];
823
+
824
+ woo_feed_save_options( $data );
825
 
826
  // $currencyAPI = isset( $_POST['currency_api_code'] ) ? sanitize_text_field( $_POST['currency_api_code'] ) : '';
827
  // update_option( 'woo_feed_currency_api_code', $currencyAPI, false );
828
+
829
+ if ( isset( $_POST['opt_in'] ) && 'on' === $_POST['opt_in'] ) {
830
+ WooFeedWebAppickAPI::getInstance()->trackerOptIn();
831
+ } else {
832
+ WooFeedWebAppickAPI::getInstance()->trackerOptOut();
833
+ }
834
+ // Actions exec by user from settings page
835
+ if ( isset( $_POST['clear_all_logs'] ) && 'on' === $_POST['clear_all_logs'] ) {
836
+ woo_feed_delete_all_logs();
837
+ }
838
+ if ( isset( $_POST['purge_feed_cache'] ) ) {
839
+ woo_feed_flush_cache_data();
840
+ }
841
+
842
+ wp_safe_redirect( admin_url( 'admin.php?page=webappick-feed-settings&settings_updated=1' ) );
843
+ die();
844
+ }
845
+
846
+ require WOO_FEED_FREE_ADMIN_PATH . 'partials/woo-feed-settings.php';
847
+ }
848
  }
849
  if ( ! function_exists( 'woo_feed_flash_cache_action' ) ) {
850
  /**