Facebook for WooCommerce - Version 3.0.2

Version Description

  • 2022-11-18 =
  • Fix - Properly handle API exceptions
  • Fix - Set correct PHP version in plugin header
  • Dev - Add ArrayAccess implementation to JSONResponse class
Download this release

Release Info

Developer automattic
Plugin Icon Facebook for WooCommerce
Version 3.0.2
Comparing to
See all releases

Code changes from version 3.0.1 to 3.0.2

changelog.txt CHANGED
@@ -1,17 +1,22 @@
1
  *** Facebook for WooCommerce Changelog ***
2
 
3
- = 3.0.1 - 2022-11-17 =
4
- * Fix - Wrong path to the fbutils.php file.
5
-
6
- = 3.0.0 - 2022-11-17 =
7
- * Dev - Adding API Unit Tests.
8
- * Dev - Adding unit test workflow.
9
- * Dev - Adjusting php code styling.
10
- * Dev - Refactoring multiple Facebook APIs into a single one.
11
- * Dev - Removing SkyVerge dependency.
12
- * Dev - Removing deprecations.
13
- * Tweak - WC 5.4 compatibility.
14
-
 
 
 
 
 
15
  = 2.6.30 - 2022-11-09 =
16
  * Fix - Add backward compatibility for WC 6.1, 6.2, and 6.3 versions.
17
  * Fix - Sync product set when the term name changes.
1
  *** Facebook for WooCommerce Changelog ***
2
 
3
+ = 3.0.2 - 2022-11-18 =
4
+ * Fix - Properly handle API exceptions
5
+ * Fix - Set correct PHP version in plugin header
6
+ * Dev - Add ArrayAccess implementation to JSONResponse class
7
+
8
+ = 3.0.1 - 2022-11-17 =
9
+ * Fix - Wrong path to the fbutils.php file.
10
+
11
+ = 3.0.0 - 2022-11-17 =
12
+ * Dev - Adding API Unit Tests.
13
+ * Dev - Adding unit test workflow.
14
+ * Dev - Adjusting php code styling.
15
+ * Dev - Refactoring multiple Facebook APIs into a single one.
16
+ * Dev - Removing SkyVerge dependency.
17
+ * Dev - Removing deprecations.
18
+ * Tweak - WC 5.4 compatibility.
19
+
20
  = 2.6.30 - 2022-11-09 =
21
  * Fix - Add backward compatibility for WC 6.1, 6.2, and 6.3 versions.
22
  * Fix - Sync product set when the term name changes.
facebook-commerce.php CHANGED
@@ -10,12 +10,10 @@
10
  */
11
 
12
  use WooCommerce\Facebook\Admin;
13
- use WooCommerce\Facebook\API;
14
  use WooCommerce\Facebook\Events\AAMSettings;
15
  use WooCommerce\Facebook\Framework\Api\Exception as ApiException;
16
  use WooCommerce\Facebook\Framework\Helper;
17
  use WooCommerce\Facebook\Framework\Plugin\Exception as PluginException;
18
- use WooCommerce\Facebook\Handlers\Connection;
19
  use WooCommerce\Facebook\Products;
20
  use WooCommerce\Facebook\Products\Feed;
21
 
@@ -581,7 +579,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
581
  } while ( $response = $this->facebook_for_woocommerce->get_api()->next( $response, 2 ) );
582
  } catch ( ApiException $e ) {
583
  $message = sprintf( 'There was an error trying to find the IDs for Product Items in the Product Group %s: %s', $product_group_id, $e->getMessage() );
584
- facebook_for_woocommerce()->log( $message );
585
  }
586
  return $product_item_ids;
587
  }
@@ -1205,20 +1203,25 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
1205
  $product_group_data['variants'] = $woo_product->prepare_variants_for_group();
1206
  }
1207
 
1208
- $create_product_group_result = $this->facebook_for_woocommerce->get_api()->create_product_group(
1209
- $this->get_product_catalog_id(),
1210
- $product_group_data
1211
- );
1212
-
1213
- // New variant added
1214
- if ( $create_product_group_result->id ) {
1215
- $fb_product_group_id = $create_product_group_result->id;
1216
- update_post_meta(
1217
- $woo_product->get_id(),
1218
- self::FB_PRODUCT_GROUP_ID,
1219
- $fb_product_group_id
1220
  );
1221
- return $fb_product_group_id;
 
 
 
 
 
 
 
 
 
 
 
 
 
1222
  }
1223
  return null;
1224
  }
@@ -1266,42 +1269,52 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
1266
  $product_group_data['default_product_id'] = $default_product_fbid;
1267
  }
1268
 
1269
- $response = $this->facebook_for_woocommerce->get_api()->update_product_group( $fb_product_group_id, $product_group_data );
1270
- if ( $response->success ) {
1271
- $this->display_success_message(
1272
- 'Updated product group <a href="https://facebook.com/' .
1273
- $fb_product_group_id . '" target="_blank">' . $fb_product_group_id .
1274
- '</a> on Facebook.'
1275
- );
1276
- } else {
1277
- $this->display_error_message(
1278
- 'Updating product group <a href="https://facebook.com/' .
1279
- $fb_product_group_id . '" target="_blank">' . $fb_product_group_id .
1280
- '</a> on Facebook has failed.'
1281
- );
 
 
 
 
 
1282
  }
1283
  }
1284
 
1285
- function create_product_item( $woo_product, $retailer_id, $product_group_id ): string {
1286
- $product_data = $woo_product->prepare_product( $retailer_id );
1287
- $product_result = $this->facebook_for_woocommerce->get_api()->create_product_item( $product_group_id, $product_data );
 
1288
 
1289
- if ( $product_result->id ) {
1290
- $fb_product_item_id = $product_result->id;
1291
 
1292
- update_post_meta(
1293
- $woo_product->get_id(),
1294
- self::FB_PRODUCT_ITEM_ID,
1295
- $fb_product_item_id
1296
- );
1297
 
1298
- $this->display_success_message(
1299
- 'Created product item <a href="https://facebook.com/' .
1300
- $fb_product_item_id . '" target="_blank">' .
1301
- $fb_product_item_id . '</a> on Facebook.'
1302
- );
1303
 
1304
- return $fb_product_item_id;
 
 
 
 
1305
  }
1306
  return '';
1307
  }
@@ -1417,18 +1430,22 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
1417
  if ( empty( $product_data['additional_image_urls'] ) ) {
1418
  $product_data['additional_image_urls'] = '';
1419
  }
1420
-
1421
- $result = $this->facebook_for_woocommerce->get_api()->update_product_item( $fb_product_item_id, $product_data );
1422
- if ( $result->success ) {
1423
- $this->display_success_message(
1424
- 'Updated product <a href="https://facebook.com/' . $fb_product_item_id .
1425
- '" target="_blank">' . $fb_product_item_id . '</a> on Facebook.'
1426
- );
1427
- } else {
1428
- $this->display_error_message(
1429
- 'Updated product <a href="https://facebook.com/' . $fb_product_item_id .
1430
- '" target="_blank">' . $fb_product_item_id . '</a> on Facebook has failed.'
1431
- );
 
 
 
 
1432
  }
1433
  }
1434
 
@@ -1445,19 +1462,24 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
1445
  // check if exists in FB
1446
  $fb_product_set_id = get_term_meta( $product_set_id, self::FB_PRODUCT_SET_ID, true );
1447
 
1448
- // set data and execute API call
1449
- $result = empty( $fb_product_set_id )
1450
- ? $this->facebook_for_woocommerce->get_api()->create_product_set_item( $this->get_product_catalog_id(), $product_set_data )
1451
- : $this->facebook_for_woocommerce->get_api()->update_product_set_item( $fb_product_set_id, $product_set_data );
1452
-
1453
- // update product set to set Facebook Product Set ID
1454
- if ( $result && empty( $fb_product_set_id ) ) {
1455
- $fb_product_set_id = $result->id;
1456
- update_term_meta(
1457
- $product_set_id,
1458
- self::FB_PRODUCT_SET_ID,
1459
- $fb_product_set_id
1460
- );
 
 
 
 
 
1461
  }
1462
  }
1463
 
@@ -1471,7 +1493,12 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
1471
  */
1472
  public function delete_product_set_item( string $fb_product_set_id ) {
1473
  $allow_live_deletion = apply_filters( 'wc_facebook_commerce_allow_live_product_set_deletion', true, $fb_product_set_id );
1474
- $this->facebook_for_woocommerce->get_api()->delete_product_set_item( $fb_product_set_id, $allow_live_deletion );
 
 
 
 
 
1475
  }
1476
 
1477
 
@@ -1960,7 +1987,12 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
1960
  throw new PluginException( __( 'A product sync is in progress. Please wait until the sync finishes before starting a new one.', 'facebook-for-woocommerce' ) );
1961
  }
1962
 
1963
- $catalog = $this->facebook_for_woocommerce->get_api()->get_catalog( $this->get_product_catalog_id() );
 
 
 
 
 
1964
  if ( $catalog->id ) {
1965
  WC_Facebookcommerce_Utils::log( 'Not syncing, invalid product catalog!' );
1966
  WC_Facebookcommerce_Utils::fblog(
@@ -2714,8 +2746,13 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
2714
  $wp_id
2715
  );
2716
  if ( $fb_product_item_id ) {
2717
- $pi_result = $this->facebook_for_woocommerce->get_api()->delete_product_item( $fb_product_item_id );
2718
- WC_Facebookcommerce_Utils::log( $pi_result );
 
 
 
 
 
2719
  }
2720
  }
2721
 
@@ -2730,8 +2767,13 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
2730
  $product_group_id = $this->get_product_fbid( self::FB_PRODUCT_GROUP_ID, $product_id );
2731
  if ( $product_group_id ) {
2732
  // TODO: replace with a call to API::delete_product_group() {WV 2020-05-26}
2733
- $pg_result = $this->facebook_for_woocommerce->get_api()->delete_product_group( $product_group_id );
2734
- \WC_Facebookcommerce_Utils::log( $pg_result );
 
 
 
 
 
2735
  }
2736
  }
2737
 
@@ -2789,14 +2831,19 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
2789
  // sync product with all variations
2790
  $this->facebook_for_woocommerce->get_products_sync_handler()->create_or_update_products( $product_ids );
2791
  } else {
2792
- $fb_product_item_id = $this->get_product_fbid( self::FB_PRODUCT_ITEM_ID, $product_id );
2793
  if ( ! $fb_product_item_id ) {
2794
  \WC_Facebookcommerce_Utils::fblog( $fb_product_item_id . " doesn't exist but underwent a visibility transform.", [], true );
2795
  return;
2796
  }
2797
- $set_visibility = $this->facebook_for_woocommerce->get_api()->update_product_item( $fb_product_item_id, [ 'visibility' => $visibility ] );
2798
- if ( $set_visibility->success ) {
2799
- Products::set_product_visibility( $product, $should_set_visible );
 
 
 
 
 
2800
  }
2801
  }
2802
  }
10
  */
11
 
12
  use WooCommerce\Facebook\Admin;
 
13
  use WooCommerce\Facebook\Events\AAMSettings;
14
  use WooCommerce\Facebook\Framework\Api\Exception as ApiException;
15
  use WooCommerce\Facebook\Framework\Helper;
16
  use WooCommerce\Facebook\Framework\Plugin\Exception as PluginException;
 
17
  use WooCommerce\Facebook\Products;
18
  use WooCommerce\Facebook\Products\Feed;
19
 
579
  } while ( $response = $this->facebook_for_woocommerce->get_api()->next( $response, 2 ) );
580
  } catch ( ApiException $e ) {
581
  $message = sprintf( 'There was an error trying to find the IDs for Product Items in the Product Group %s: %s', $product_group_id, $e->getMessage() );
582
+ WC_Facebookcommerce_Utils::log( $message );
583
  }
584
  return $product_item_ids;
585
  }
1203
  $product_group_data['variants'] = $woo_product->prepare_variants_for_group();
1204
  }
1205
 
1206
+ try {
1207
+ $create_product_group_result = $this->facebook_for_woocommerce->get_api()->create_product_group(
1208
+ $this->get_product_catalog_id(),
1209
+ $product_group_data
 
 
 
 
 
 
 
 
1210
  );
1211
+
1212
+ // New variant added
1213
+ if ( $create_product_group_result->id ) {
1214
+ $fb_product_group_id = $create_product_group_result->id;
1215
+ update_post_meta(
1216
+ $woo_product->get_id(),
1217
+ self::FB_PRODUCT_GROUP_ID,
1218
+ $fb_product_group_id
1219
+ );
1220
+ return $fb_product_group_id;
1221
+ }
1222
+ } catch ( ApiException $e ) {
1223
+ $message = sprintf( 'There was an error trying to create the product group: %s', $e->getMessage() );
1224
+ WC_Facebookcommerce_Utils::log( $message );
1225
  }
1226
  return null;
1227
  }
1269
  $product_group_data['default_product_id'] = $default_product_fbid;
1270
  }
1271
 
1272
+ try {
1273
+ $response = $this->facebook_for_woocommerce->get_api()->update_product_group( $fb_product_group_id, $product_group_data );
1274
+ if ( $response->success ) {
1275
+ $this->display_success_message(
1276
+ 'Updated product group <a href="https://facebook.com/' .
1277
+ $fb_product_group_id . '" target="_blank">' . $fb_product_group_id .
1278
+ '</a> on Facebook.'
1279
+ );
1280
+ } else {
1281
+ $this->display_error_message(
1282
+ 'Updating product group <a href="https://facebook.com/' .
1283
+ $fb_product_group_id . '" target="_blank">' . $fb_product_group_id .
1284
+ '</a> on Facebook has failed.'
1285
+ );
1286
+ }
1287
+ } catch ( ApiException $e ) {
1288
+ $message = sprintf( 'There was an error trying to update Product Group %s: %s', $fb_product_group_id, $e->getMessage() );
1289
+ WC_Facebookcommerce_Utils::log( $message );
1290
  }
1291
  }
1292
 
1293
+ public function create_product_item( $woo_product, $retailer_id, $product_group_id ): string {
1294
+ try {
1295
+ $product_data = $woo_product->prepare_product( $retailer_id );
1296
+ $product_result = $this->facebook_for_woocommerce->get_api()->create_product_item( $product_group_id, $product_data );
1297
 
1298
+ if ( $product_result->id ) {
1299
+ $fb_product_item_id = $product_result->id;
1300
 
1301
+ update_post_meta(
1302
+ $woo_product->get_id(),
1303
+ self::FB_PRODUCT_ITEM_ID,
1304
+ $fb_product_item_id
1305
+ );
1306
 
1307
+ $this->display_success_message(
1308
+ 'Created product item <a href="https://facebook.com/' .
1309
+ $fb_product_item_id . '" target="_blank">' .
1310
+ $fb_product_item_id . '</a> on Facebook.'
1311
+ );
1312
 
1313
+ return $fb_product_item_id;
1314
+ }
1315
+ } catch ( ApiException $e ) {
1316
+ $message = sprintf( 'There was an error trying to create a product item: %s', $e->getMessage() );
1317
+ WC_Facebookcommerce_Utils::log( $message );
1318
  }
1319
  return '';
1320
  }
1430
  if ( empty( $product_data['additional_image_urls'] ) ) {
1431
  $product_data['additional_image_urls'] = '';
1432
  }
1433
+ try {
1434
+ $result = $this->facebook_for_woocommerce->get_api()->update_product_item( $fb_product_item_id, $product_data );
1435
+ if ( $result->success ) {
1436
+ $this->display_success_message(
1437
+ 'Updated product <a href="https://facebook.com/' . $fb_product_item_id .
1438
+ '" target="_blank">' . $fb_product_item_id . '</a> on Facebook.'
1439
+ );
1440
+ } else {
1441
+ $this->display_error_message(
1442
+ 'Updated product <a href="https://facebook.com/' . $fb_product_item_id .
1443
+ '" target="_blank">' . $fb_product_item_id . '</a> on Facebook has failed.'
1444
+ );
1445
+ }
1446
+ } catch ( ApiException $e ) {
1447
+ $message = sprintf( 'There was an error trying to update a product item: %s', $e->getMessage() );
1448
+ WC_Facebookcommerce_Utils::log( $message );
1449
  }
1450
  }
1451
 
1462
  // check if exists in FB
1463
  $fb_product_set_id = get_term_meta( $product_set_id, self::FB_PRODUCT_SET_ID, true );
1464
 
1465
+ try {
1466
+ // set data and execute API call
1467
+ $result = empty( $fb_product_set_id )
1468
+ ? $this->facebook_for_woocommerce->get_api()->create_product_set_item( $this->get_product_catalog_id(), $product_set_data )
1469
+ : $this->facebook_for_woocommerce->get_api()->update_product_set_item( $fb_product_set_id, $product_set_data );
1470
+
1471
+ // update product set to set Facebook Product Set ID
1472
+ if ( $result && empty( $fb_product_set_id ) ) {
1473
+ $fb_product_set_id = $result->id;
1474
+ update_term_meta(
1475
+ $product_set_id,
1476
+ self::FB_PRODUCT_SET_ID,
1477
+ $fb_product_set_id
1478
+ );
1479
+ }
1480
+ } catch ( ApiException $e ) {
1481
+ $message = sprintf( 'There was an error trying to create/update a product set: %s', $e->getMessage() );
1482
+ WC_Facebookcommerce_Utils::log( $message );
1483
  }
1484
  }
1485
 
1493
  */
1494
  public function delete_product_set_item( string $fb_product_set_id ) {
1495
  $allow_live_deletion = apply_filters( 'wc_facebook_commerce_allow_live_product_set_deletion', true, $fb_product_set_id );
1496
+ try {
1497
+ $this->facebook_for_woocommerce->get_api()->delete_product_set_item( $fb_product_set_id, $allow_live_deletion );
1498
+ } catch ( ApiException $e ) {
1499
+ $message = sprintf( 'There was an error trying to delete a product set item: %s', $e->getMessage() );
1500
+ WC_Facebookcommerce_Utils::log( $message );
1501
+ }
1502
  }
1503
 
1504
 
1987
  throw new PluginException( __( 'A product sync is in progress. Please wait until the sync finishes before starting a new one.', 'facebook-for-woocommerce' ) );
1988
  }
1989
 
1990
+ try {
1991
+ $catalog = $this->facebook_for_woocommerce->get_api()->get_catalog($this->get_product_catalog_id());
1992
+ } catch ( ApiException $e ) {
1993
+ $message = sprintf( 'There was an error trying to delete a product set item: %s', $e->getMessage() );
1994
+ WC_Facebookcommerce_Utils::log( $message );
1995
+ }
1996
  if ( $catalog->id ) {
1997
  WC_Facebookcommerce_Utils::log( 'Not syncing, invalid product catalog!' );
1998
  WC_Facebookcommerce_Utils::fblog(
2746
  $wp_id
2747
  );
2748
  if ( $fb_product_item_id ) {
2749
+ try {
2750
+ $pi_result = $this->facebook_for_woocommerce->get_api()->delete_product_item( $fb_product_item_id );
2751
+ WC_Facebookcommerce_Utils::log( $pi_result );
2752
+ } catch ( ApiException $e ) {
2753
+ $message = sprintf( 'There was an error trying to delete a product set item: %s', $e->getMessage() );
2754
+ WC_Facebookcommerce_Utils::log( $message );
2755
+ }
2756
  }
2757
  }
2758
 
2767
  $product_group_id = $this->get_product_fbid( self::FB_PRODUCT_GROUP_ID, $product_id );
2768
  if ( $product_group_id ) {
2769
  // TODO: replace with a call to API::delete_product_group() {WV 2020-05-26}
2770
+ try {
2771
+ $pg_result = $this->facebook_for_woocommerce->get_api()->delete_product_group( $product_group_id );
2772
+ WC_Facebookcommerce_Utils::log( $pg_result );
2773
+ } catch ( ApiException $e ) {
2774
+ $message = sprintf( 'There was an error trying to delete a product group: %s', $e->getMessage() );
2775
+ WC_Facebookcommerce_Utils::log( $message );
2776
+ }
2777
  }
2778
  }
2779
 
2831
  // sync product with all variations
2832
  $this->facebook_for_woocommerce->get_products_sync_handler()->create_or_update_products( $product_ids );
2833
  } else {
2834
+ $fb_product_item_id = $this->get_product_fbid( self::FB_PRODUCT_ITEM_ID, $product->get_id() );
2835
  if ( ! $fb_product_item_id ) {
2836
  \WC_Facebookcommerce_Utils::fblog( $fb_product_item_id . " doesn't exist but underwent a visibility transform.", [], true );
2837
  return;
2838
  }
2839
+ try {
2840
+ $set_visibility = $this->facebook_for_woocommerce->get_api()->update_product_item( $fb_product_item_id, [ 'visibility' => $visibility ] );
2841
+ if ( $set_visibility->success ) {
2842
+ Products::set_product_visibility( $product, $should_set_visible );
2843
+ }
2844
+ } catch ( ApiException $e ) {
2845
+ $message = sprintf( 'There was an error trying to update product item: %s', $e->getMessage() );
2846
+ WC_Facebookcommerce_Utils::log( $message );
2847
  }
2848
  }
2849
  }
facebook-for-woocommerce.php CHANGED
@@ -11,12 +11,12 @@
11
  * Description: Grow your business on Facebook! Use this official plugin to help sell more of your products using Facebook. After completing the setup, you'll be ready to create ads that promote your products and you can also create a shop section on your Page where customers can browse your products on Facebook.
12
  * Author: Facebook
13
  * Author URI: https://www.facebook.com/
14
- * Version: 3.0.1
15
  * Text Domain: facebook-for-woocommerce
16
  * Tested up to: 6.1
17
  * WC requires at least: 5.3
18
  * WC tested up to: 5.4
19
- * Requires PHP: 7.0
20
  *
21
  * @package FacebookCommerce
22
  */
@@ -44,7 +44,7 @@ class WC_Facebook_Loader {
44
  /**
45
  * @var string the plugin version. This must be in the main plugin file to be automatically bumped by Woorelease.
46
  */
47
- const PLUGIN_VERSION = '3.0.1'; // WRCS: DEFINED_VERSION.
48
 
49
  // Minimum PHP version required by this plugin.
50
  const MINIMUM_PHP_VERSION = '7.0.0';
11
  * Description: Grow your business on Facebook! Use this official plugin to help sell more of your products using Facebook. After completing the setup, you'll be ready to create ads that promote your products and you can also create a shop section on your Page where customers can browse your products on Facebook.
12
  * Author: Facebook
13
  * Author URI: https://www.facebook.com/
14
+ * Version: 3.0.2
15
  * Text Domain: facebook-for-woocommerce
16
  * Tested up to: 6.1
17
  * WC requires at least: 5.3
18
  * WC tested up to: 5.4
19
+ * Requires PHP: 7.2
20
  *
21
  * @package FacebookCommerce
22
  */
44
  /**
45
  * @var string the plugin version. This must be in the main plugin file to be automatically bumped by Woorelease.
46
  */
47
+ const PLUGIN_VERSION = '3.0.2'; // WRCS: DEFINED_VERSION.
48
 
49
  // Minimum PHP version required by this plugin.
50
  const MINIMUM_PHP_VERSION = '7.0.0';
i18n/languages/facebook-for-woocommerce.pot CHANGED
@@ -2,21 +2,21 @@
2
  # This file is distributed under the same license as the Facebook for WooCommerce plugin.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: Facebook for WooCommerce 3.0.1\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/facebook-for-woocommerce\n"
7
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
8
  "Language-Team: LANGUAGE <LL@li.org>\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
- "POT-Creation-Date: 2022-11-17T21:20:02+00:00\n"
13
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
14
- "X-Generator: WP-CLI 2.7.0\n"
15
  "X-Domain: facebook-for-woocommerce\n"
16
 
17
  #. Plugin Name of the plugin
18
  #: class-wc-facebookcommerce.php:701
19
- #: facebook-commerce.php:200
20
  #: includes/Admin.php:1468
21
  #: includes/Admin/Settings.php:93
22
  #: includes/Admin/Settings.php:160
@@ -86,54 +86,54 @@ msgstr ""
86
  msgid "Cannot create the API instance because the access token is missing."
87
  msgstr ""
88
 
89
- #: facebook-commerce.php:204
90
  msgid "Facebook Commerce and Dynamic Ads (Pixel) Extension"
91
  msgstr ""
92
 
93
  #. translators: %1$s is referring to facebook product group id.
94
- #: facebook-commerce.php:1248
95
  msgid "Nothing to update for product group for %1$s"
96
  msgstr ""
97
 
98
- #: facebook-commerce.php:1909
99
  msgid "Your connection has expired."
100
  msgstr ""
101
 
102
- #: facebook-commerce.php:1909
103
  msgid "Please click Manage connection > Advanced Options > Update Token to refresh your connection to Facebook."
104
  msgstr ""
105
 
106
  #. translators: Placeholders %s - error message
107
- #: facebook-commerce.php:1916
108
  msgid "There was an error trying to sync the products to Facebook. %s"
109
  msgstr ""
110
 
111
- #: facebook-commerce.php:1935
112
  msgid "Product sync is disabled."
113
  msgstr ""
114
 
115
- #: facebook-commerce.php:1940
116
  msgid "The plugin is not configured or the Catalog ID is missing."
117
  msgstr ""
118
 
119
- #: facebook-commerce.php:1960
120
  msgid "A product sync is in progress. Please wait until the sync finishes before starting a new one."
121
  msgstr ""
122
 
123
- #: facebook-commerce.php:1971
124
  msgid "We've detected that your Facebook Product Catalog is no longer valid. This may happen if it was deleted, but could also be a temporary error. If the error persists, please click Manage connection > Advanced Options > Remove and setup the plugin again."
125
  msgstr ""
126
 
127
- #: facebook-commerce.php:2343
128
  msgid "Hi! We're here to answer any questions you may have."
129
  msgstr ""
130
 
131
- #: facebook-commerce.php:2653
132
  msgid "Facebook for WooCommerce error:"
133
  msgstr ""
134
 
135
  #. translators: Placeholders %1$s - original error message from Facebook API
136
- #: facebook-commerce.php:2872
137
  msgid "There was an issue connecting to the Facebook API: %s"
138
  msgstr ""
139
 
@@ -792,7 +792,7 @@ msgid "Order %1$s paid in %2$s"
792
  msgstr ""
793
 
794
  #: includes/Commerce/Orders.php:580
795
- #: includes/Commerce/Orders.php:815
796
  msgid "Remote ID not found."
797
  msgstr ""
798
 
@@ -801,7 +801,7 @@ msgid "%s is not a valid shipping carrier code."
801
  msgstr ""
802
 
803
  #: includes/Commerce/Orders.php:605
804
- #: includes/Commerce/Orders.php:782
805
  msgid "No valid Facebook products were found."
806
  msgstr ""
807
 
@@ -815,79 +815,79 @@ msgstr ""
815
  msgid "%1$s order could not be fulfilled. %2$s"
816
  msgstr ""
817
 
818
- #: includes/Commerce/Orders.php:677
819
  msgid "Parent order not found."
820
  msgstr ""
821
 
822
- #: includes/Commerce/Orders.php:683
823
  msgid "Remote ID for parent order not found."
824
  msgstr ""
825
 
826
  #. translators: Placeholder: %s - sales channel name, like Facebook or Instagram
827
- #: includes/Commerce/Orders.php:714
828
  msgid "Order refunded on %s."
829
  msgstr ""
830
 
831
  #. translators: Placeholders: %1$s - sales channel name, like Facebook or Instagram, %2$s - error message
832
- #: includes/Commerce/Orders.php:726
833
  msgid "Could not refund %1$s order: %2$s"
834
  msgstr ""
835
 
836
  #. translators: Placeholder: %s - sales channel name, like Facebook or Instagram
837
- #: includes/Commerce/Orders.php:823
838
  msgid "%s order cancelled."
839
  msgstr ""
840
 
841
  #. translators: Placeholders: %1$s - sales channel name, like Facebook or Instagram, %2$s - error message
842
- #: includes/Commerce/Orders.php:833
843
  msgid "%1$s order could not be cancelled. %2$s"
844
  msgstr ""
845
 
846
- #: includes/Commerce/Orders.php:855
847
  msgid "Customer requested cancellation"
848
  msgstr ""
849
 
850
- #: includes/Commerce/Orders.php:856
851
  msgid "Product(s) are out of stock"
852
  msgstr ""
853
 
854
- #: includes/Commerce/Orders.php:857
855
  msgid "Customer address is invalid"
856
  msgstr ""
857
 
858
- #: includes/Commerce/Orders.php:858
859
  msgid "Suspicious order"
860
  msgstr ""
861
 
862
- #: includes/Commerce/Orders.php:859
863
  msgid "Other"
864
  msgstr ""
865
 
866
- #: includes/fbinfobanner.php:176
867
  msgid "Click and redirect."
868
  msgstr ""
869
 
870
- #: includes/fbinfobanner.php:177
871
  msgid "Dismiss this notice."
872
  msgstr ""
873
 
874
- #: includes/fbinfobanner.php:177
875
  msgid "Dismiss"
876
  msgstr ""
877
 
878
- #: includes/fbproductfeed.php:202
879
  msgid "Could not create product catalog feed directory"
880
  msgstr ""
881
 
882
- #: includes/fbproductfeed.php:306
883
  msgid "Could not open the product catalog temporary feed file for writing"
884
  msgstr ""
885
 
886
- #: includes/fbproductfeed.php:313
887
  msgid "Could not open the product catalog feed file for writing"
888
  msgstr ""
889
 
890
- #: includes/fbproductfeed.php:377
891
  msgid "Could not rename the product catalog feed file"
892
  msgstr ""
893
 
2
  # This file is distributed under the same license as the Facebook for WooCommerce plugin.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: Facebook for WooCommerce 3.0.2\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/facebook-for-woocommerce\n"
7
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
8
  "Language-Team: LANGUAGE <LL@li.org>\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
+ "POT-Creation-Date: 2022-11-18T12:26:21-05:00\n"
13
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
14
+ "X-Generator: WP-CLI 2.7.1\n"
15
  "X-Domain: facebook-for-woocommerce\n"
16
 
17
  #. Plugin Name of the plugin
18
  #: class-wc-facebookcommerce.php:701
19
+ #: facebook-commerce.php:198
20
  #: includes/Admin.php:1468
21
  #: includes/Admin/Settings.php:93
22
  #: includes/Admin/Settings.php:160
86
  msgid "Cannot create the API instance because the access token is missing."
87
  msgstr ""
88
 
89
+ #: facebook-commerce.php:202
90
  msgid "Facebook Commerce and Dynamic Ads (Pixel) Extension"
91
  msgstr ""
92
 
93
  #. translators: %1$s is referring to facebook product group id.
94
+ #: facebook-commerce.php:1251
95
  msgid "Nothing to update for product group for %1$s"
96
  msgstr ""
97
 
98
+ #: facebook-commerce.php:1936
99
  msgid "Your connection has expired."
100
  msgstr ""
101
 
102
+ #: facebook-commerce.php:1936
103
  msgid "Please click Manage connection > Advanced Options > Update Token to refresh your connection to Facebook."
104
  msgstr ""
105
 
106
  #. translators: Placeholders %s - error message
107
+ #: facebook-commerce.php:1943
108
  msgid "There was an error trying to sync the products to Facebook. %s"
109
  msgstr ""
110
 
111
+ #: facebook-commerce.php:1962
112
  msgid "Product sync is disabled."
113
  msgstr ""
114
 
115
+ #: facebook-commerce.php:1967
116
  msgid "The plugin is not configured or the Catalog ID is missing."
117
  msgstr ""
118
 
119
+ #: facebook-commerce.php:1987
120
  msgid "A product sync is in progress. Please wait until the sync finishes before starting a new one."
121
  msgstr ""
122
 
123
+ #: facebook-commerce.php:2003
124
  msgid "We've detected that your Facebook Product Catalog is no longer valid. This may happen if it was deleted, but could also be a temporary error. If the error persists, please click Manage connection > Advanced Options > Remove and setup the plugin again."
125
  msgstr ""
126
 
127
+ #: facebook-commerce.php:2375
128
  msgid "Hi! We're here to answer any questions you may have."
129
  msgstr ""
130
 
131
+ #: facebook-commerce.php:2685
132
  msgid "Facebook for WooCommerce error:"
133
  msgstr ""
134
 
135
  #. translators: Placeholders %1$s - original error message from Facebook API
136
+ #: facebook-commerce.php:2919
137
  msgid "There was an issue connecting to the Facebook API: %s"
138
  msgstr ""
139
 
792
  msgstr ""
793
 
794
  #: includes/Commerce/Orders.php:580
795
+ #: includes/Commerce/Orders.php:814
796
  msgid "Remote ID not found."
797
  msgstr ""
798
 
801
  msgstr ""
802
 
803
  #: includes/Commerce/Orders.php:605
804
+ #: includes/Commerce/Orders.php:781
805
  msgid "No valid Facebook products were found."
806
  msgstr ""
807
 
815
  msgid "%1$s order could not be fulfilled. %2$s"
816
  msgstr ""
817
 
818
+ #: includes/Commerce/Orders.php:676
819
  msgid "Parent order not found."
820
  msgstr ""
821
 
822
+ #: includes/Commerce/Orders.php:682
823
  msgid "Remote ID for parent order not found."
824
  msgstr ""
825
 
826
  #. translators: Placeholder: %s - sales channel name, like Facebook or Instagram
827
+ #: includes/Commerce/Orders.php:713
828
  msgid "Order refunded on %s."
829
  msgstr ""
830
 
831
  #. translators: Placeholders: %1$s - sales channel name, like Facebook or Instagram, %2$s - error message
832
+ #: includes/Commerce/Orders.php:725
833
  msgid "Could not refund %1$s order: %2$s"
834
  msgstr ""
835
 
836
  #. translators: Placeholder: %s - sales channel name, like Facebook or Instagram
837
+ #: includes/Commerce/Orders.php:822
838
  msgid "%s order cancelled."
839
  msgstr ""
840
 
841
  #. translators: Placeholders: %1$s - sales channel name, like Facebook or Instagram, %2$s - error message
842
+ #: includes/Commerce/Orders.php:832
843
  msgid "%1$s order could not be cancelled. %2$s"
844
  msgstr ""
845
 
846
+ #: includes/Commerce/Orders.php:854
847
  msgid "Customer requested cancellation"
848
  msgstr ""
849
 
850
+ #: includes/Commerce/Orders.php:855
851
  msgid "Product(s) are out of stock"
852
  msgstr ""
853
 
854
+ #: includes/Commerce/Orders.php:856
855
  msgid "Customer address is invalid"
856
  msgstr ""
857
 
858
+ #: includes/Commerce/Orders.php:857
859
  msgid "Suspicious order"
860
  msgstr ""
861
 
862
+ #: includes/Commerce/Orders.php:858
863
  msgid "Other"
864
  msgstr ""
865
 
866
+ #: includes/fbinfobanner.php:184
867
  msgid "Click and redirect."
868
  msgstr ""
869
 
870
+ #: includes/fbinfobanner.php:185
871
  msgid "Dismiss this notice."
872
  msgstr ""
873
 
874
+ #: includes/fbinfobanner.php:185
875
  msgid "Dismiss"
876
  msgstr ""
877
 
878
+ #: includes/fbproductfeed.php:204
879
  msgid "Could not create product catalog feed directory"
880
  msgstr ""
881
 
882
+ #: includes/fbproductfeed.php:308
883
  msgid "Could not open the product catalog temporary feed file for writing"
884
  msgstr ""
885
 
886
+ #: includes/fbproductfeed.php:315
887
  msgid "Could not open the product catalog feed file for writing"
888
  msgstr ""
889
 
890
+ #: includes/fbproductfeed.php:379
891
  msgid "Could not rename the product catalog feed file"
892
  msgstr ""
893
 
includes/API/Catalog/Product_Item/Response.php CHANGED
@@ -1,5 +1,4 @@
1
  <?php
2
- // phpcs:ignoreFile
3
  /**
4
  * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
5
  *
@@ -11,17 +10,16 @@
11
 
12
  namespace WooCommerce\Facebook\API\Catalog\Product_Item;
13
 
14
- defined( 'ABSPATH' ) or exit;
15
 
16
- use WooCommerce\Facebook\API;
17
 
18
  /**
19
  * Response object for API requests that return a Product Item.
20
  *
21
  * @since 2.0.0
22
  */
23
- class Response extends API\Response {
24
-
25
 
26
  /**
27
  * Gets the Product Item group ID.
@@ -31,15 +29,6 @@ class Response extends API\Response {
31
  * @return string
32
  */
33
  public function get_group_id() {
34
-
35
- $product_group_id = '';
36
-
37
- if ( isset( $this->response_data->product_group->id ) ) {
38
- $product_group_id = $this->response_data->product_group->id;
39
- }
40
-
41
- return $product_group_id;
42
  }
43
-
44
-
45
  }
1
  <?php
 
2
  /**
3
  * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
4
  *
10
 
11
  namespace WooCommerce\Facebook\API\Catalog\Product_Item;
12
 
13
+ defined( 'ABSPATH' ) || exit;
14
 
15
+ use WooCommerce\Facebook\API\Response as BaseResponse;
16
 
17
  /**
18
  * Response object for API requests that return a Product Item.
19
  *
20
  * @since 2.0.0
21
  */
22
+ class Response extends BaseResponse {
 
23
 
24
  /**
25
  * Gets the Product Item group ID.
29
  * @return string
30
  */
31
  public function get_group_id() {
32
+ return $this->response_data['product_group']['id'] ?? '';
 
 
 
 
 
 
 
33
  }
 
 
34
  }
includes/API/Response.php CHANGED
@@ -1,5 +1,4 @@
1
  <?php
2
- // phpcs:ignoreFile
3
  /**
4
  * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
5
  *
@@ -13,7 +12,7 @@ namespace WooCommerce\Facebook\API;
13
 
14
  use WooCommerce\Facebook\Framework\Api\JSONResponse;
15
 
16
- defined( 'ABSPATH' ) or exit;
17
 
18
  /**
19
  * Base API response object
1
  <?php
 
2
  /**
3
  * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
4
  *
12
 
13
  use WooCommerce\Facebook\Framework\Api\JSONResponse;
14
 
15
+ defined( 'ABSPATH' ) || exit;
16
 
17
  /**
18
  * Base API response object
includes/API/Traits/Paginated_Response.php CHANGED
@@ -1,5 +1,4 @@
1
  <?php
2
- // phpcs:ignoreFile
3
  /**
4
  * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
5
  *
@@ -7,12 +6,15 @@
7
  * LICENSE file in the root directory of this source tree.
8
  *
9
  * @package FacebookCommerce
 
 
10
  */
11
 
12
  namespace WooCommerce\Facebook\API\Traits;
13
 
14
- defined( 'ABSPATH' ) or exit;
15
 
 
16
 
17
  /**
18
  * Helper methods to traverse Graph API paged results.
@@ -23,14 +25,12 @@ defined( 'ABSPATH' ) or exit;
23
  */
24
  trait Paginated_Response {
25
 
26
-
27
- /** @var string number of pages retrieved from this response */
28
  private $pages_retrieved = 1;
29
 
30
- /** @var mixed decoded response data */
31
  public $response_data;
32
 
33
-
34
  /**
35
  * Sets the number of pages retrieved from this response.
36
  *
@@ -39,11 +39,9 @@ trait Paginated_Response {
39
  * @param int $pages_retrieved
40
  */
41
  public function set_pages_retrieved( $pages_retrieved ) {
42
-
43
  $this->pages_retrieved = $pages_retrieved;
44
  }
45
 
46
-
47
  /**
48
  * Gets the number of pages retrieved from this response.
49
  *
@@ -52,11 +50,9 @@ trait Paginated_Response {
52
  * @return int
53
  */
54
  public function get_pages_retrieved() {
55
-
56
  return $this->pages_retrieved;
57
  }
58
 
59
-
60
  /**
61
  * Gets the response data.
62
  *
@@ -65,11 +61,9 @@ trait Paginated_Response {
65
  * @return array
66
  */
67
  public function get_data() {
68
-
69
- return ! empty( $this->response_data->data ) ? $this->response_data->data : array();
70
  }
71
 
72
-
73
  /**
74
  * Gets the pagination data.
75
  *
@@ -78,11 +72,9 @@ trait Paginated_Response {
78
  * @return object
79
  */
80
  public function get_pagination_data() {
81
-
82
- return ! empty( $this->response_data->paging ) ? $this->response_data->paging : new \stdClass();
83
  }
84
 
85
-
86
  /**
87
  * Gets the API endpoint for the next page of results.
88
  *
@@ -91,22 +83,17 @@ trait Paginated_Response {
91
  * @return string
92
  */
93
  public function get_next_page_endpoint() {
94
-
95
- return ! empty( $this->get_pagination_data()->next ) ? $this->get_pagination_data()->next : '';
96
  }
97
 
98
-
99
  /**
100
  * Gets the API endpoint for the previous page of results.
101
  *
102
  * @since 2.0.0
103
  *
104
- * @param string
105
  */
106
  public function get_previous_page_endpoint() {
107
-
108
- return ! empty( $this->get_pagination_data()->previous ) ? $this->get_pagination_data()->previous : '';
109
  }
110
-
111
-
112
  }
1
  <?php
 
2
  /**
3
  * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
4
  *
6
  * LICENSE file in the root directory of this source tree.
7
  *
8
  * @package FacebookCommerce
9
+ *
10
+ * phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
11
  */
12
 
13
  namespace WooCommerce\Facebook\API\Traits;
14
 
15
+ use stdClass;
16
 
17
+ defined( 'ABSPATH' ) || exit;
18
 
19
  /**
20
  * Helper methods to traverse Graph API paged results.
25
  */
26
  trait Paginated_Response {
27
 
28
+ /** @var int number of pages retrieved from this response */
 
29
  private $pages_retrieved = 1;
30
 
31
+ /** @var array decoded response data */
32
  public $response_data;
33
 
 
34
  /**
35
  * Sets the number of pages retrieved from this response.
36
  *
39
  * @param int $pages_retrieved
40
  */
41
  public function set_pages_retrieved( $pages_retrieved ) {
 
42
  $this->pages_retrieved = $pages_retrieved;
43
  }
44
 
 
45
  /**
46
  * Gets the number of pages retrieved from this response.
47
  *
50
  * @return int
51
  */
52
  public function get_pages_retrieved() {
 
53
  return $this->pages_retrieved;
54
  }
55
 
 
56
  /**
57
  * Gets the response data.
58
  *
61
  * @return array
62
  */
63
  public function get_data() {
64
+ return $this->response_data['data'] ?? [];
 
65
  }
66
 
 
67
  /**
68
  * Gets the pagination data.
69
  *
72
  * @return object
73
  */
74
  public function get_pagination_data() {
75
+ return $this->response_data['paging'] ?? new stdClass();
 
76
  }
77
 
 
78
  /**
79
  * Gets the API endpoint for the next page of results.
80
  *
83
  * @return string
84
  */
85
  public function get_next_page_endpoint() {
86
+ return $this->get_pagination_data()->next ?? '';
 
87
  }
88
 
 
89
  /**
90
  * Gets the API endpoint for the previous page of results.
91
  *
92
  * @since 2.0.0
93
  *
94
+ * @return string
95
  */
96
  public function get_previous_page_endpoint() {
97
+ return $this->get_pagination_data()->previous ?? '';
 
98
  }
 
 
99
  }
includes/Commerce/Orders.php CHANGED
@@ -652,24 +652,23 @@ class Orders {
652
  */
653
  public function add_order_refund( \WC_Order_Refund $refund, $reason_code ) {
654
 
655
- $plugin = facebook_for_woocommerce();
656
-
657
- $api = $plugin->get_api( $plugin->get_connection_handler()->get_page_access_token() );
658
 
659
- $valid_reason_codes = array(
660
- self::REFUND_REASON_BUYERS_REMORSE,
661
- self::REFUND_REASON_DAMAGED_GOODS,
662
- self::REFUND_REASON_NOT_AS_DESCRIBED,
663
- self::REFUND_REASON_QUALITY_ISSUE,
664
- self::REFUND_REASON_OTHER,
665
- self::REFUND_REASON_WRONG_ITEM,
666
- );
667
 
668
- if ( ! in_array( $reason_code, $valid_reason_codes, true ) ) {
669
- $reason_code = self::REFUND_REASON_OTHER;
670
- }
 
 
 
 
 
671
 
672
- try {
 
 
673
 
674
  $parent_order = wc_get_order( $refund->get_parent_id() );
675
 
@@ -797,17 +796,17 @@ class Orders {
797
  */
798
  public function cancel_order( \WC_Order $order, $reason_code ) {
799
 
800
- $plugin = facebook_for_woocommerce();
801
 
802
- $api = $plugin->get_api( $plugin->get_connection_handler()->get_page_access_token() );
803
 
804
- $valid_reason_codes = array_keys( $this->get_cancellation_reasons() );
805
 
806
- if ( ! in_array( $reason_code, $valid_reason_codes, true ) ) {
807
- $reason_code = self::CANCEL_REASON_OTHER;
808
- }
809
 
810
- try {
 
 
811
 
812
  $remote_id = $order->get_meta( self::REMOTE_ID_META_KEY );
813
 
652
  */
653
  public function add_order_refund( \WC_Order_Refund $refund, $reason_code ) {
654
 
655
+ try {
656
+ $plugin = facebook_for_woocommerce();
 
657
 
658
+ $api = $plugin->get_api( $plugin->get_connection_handler()->get_page_access_token() );
 
 
 
 
 
 
 
659
 
660
+ $valid_reason_codes = array(
661
+ self::REFUND_REASON_BUYERS_REMORSE,
662
+ self::REFUND_REASON_DAMAGED_GOODS,
663
+ self::REFUND_REASON_NOT_AS_DESCRIBED,
664
+ self::REFUND_REASON_QUALITY_ISSUE,
665
+ self::REFUND_REASON_OTHER,
666
+ self::REFUND_REASON_WRONG_ITEM,
667
+ );
668
 
669
+ if ( ! in_array( $reason_code, $valid_reason_codes, true ) ) {
670
+ $reason_code = self::REFUND_REASON_OTHER;
671
+ }
672
 
673
  $parent_order = wc_get_order( $refund->get_parent_id() );
674
 
796
  */
797
  public function cancel_order( \WC_Order $order, $reason_code ) {
798
 
799
+ try {
800
 
801
+ $plugin = facebook_for_woocommerce();
802
 
803
+ $api = $plugin->get_api( $plugin->get_connection_handler()->get_page_access_token() );
804
 
805
+ $valid_reason_codes = array_keys( $this->get_cancellation_reasons() );
 
 
806
 
807
+ if ( ! in_array( $reason_code, $valid_reason_codes, true ) ) {
808
+ $reason_code = self::CANCEL_REASON_OTHER;
809
+ }
810
 
811
  $remote_id = $order->get_meta( self::REMOTE_ID_META_KEY );
812
 
includes/Feed/FeedConfigurationDetection.php CHANGED
@@ -6,6 +6,11 @@ namespace WooCommerce\Facebook\Feed;
6
  defined( 'ABSPATH' ) || exit;
7
 
8
  use Error;
 
 
 
 
 
9
  use WooCommerce\Facebook\Products\Feed;
10
  use WooCommerce\Facebook\Utilities\Heartbeat;
11
 
@@ -78,20 +83,33 @@ class FeedConfigurationDetection {
78
  */
79
  $active_feed_metadata = array();
80
  foreach ( $feed_nodes as $feed ) {
81
- $metadata = $this->get_feed_metadata( $feed['id'] );
 
 
 
 
 
 
82
 
83
  if ( $feed['id'] === $integration_feed_id ) {
84
- $active_feed_metadata = $metadata;
85
  break;
86
  }
87
 
88
- if ( ! array_key_exists( 'latest_upload', $metadata ) || ! array_key_exists( 'start_time', $metadata['latest_upload'] ) ) {
 
 
 
 
89
  continue;
90
  }
 
91
  $metadata['latest_upload_time'] = strtotime( $metadata['latest_upload']['start_time'] );
92
- if ( ! $active_feed_metadata ||
93
- ( $metadata['latest_upload_time'] > $active_feed_metadata['latest_upload_time'] ) ) {
94
- $active_feed_metadata = $metadata;
 
 
95
  }
96
  }
97
 
@@ -102,11 +120,11 @@ class FeedConfigurationDetection {
102
  }
103
 
104
  $active_feed = array();
105
- if ( array_key_exists( 'created_time', $active_feed_metadata ) ) {
106
  $active_feed['created-time'] = gmdate( 'Y-m-d H:i:s', strtotime( $active_feed_metadata['created_time'] ) );
107
  }
108
 
109
- if ( array_key_exists( 'product_count', $active_feed_metadata ) ) {
110
  $active_feed['product-count'] = $active_feed_metadata['product_count'];
111
  }
112
 
@@ -117,18 +135,18 @@ class FeedConfigurationDetection {
117
  * These may both be configured; we will track settings for each individually (i.e. both).
118
  * https://developers.facebook.com/docs/marketing-api/reference/product-feed/
119
  */
120
- if ( array_key_exists( 'schedule', $active_feed_metadata ) ) {
121
  $active_feed['schedule']['interval'] = $active_feed_metadata['schedule']['interval'];
122
  $active_feed['schedule']['interval-count'] = $active_feed_metadata['schedule']['interval_count'];
123
  }
124
- if ( array_key_exists( 'update_schedule', $active_feed_metadata ) ) {
125
  $active_feed['update-schedule']['interval'] = $active_feed_metadata['update_schedule']['interval'];
126
  $active_feed['update-schedule']['interval-count'] = $active_feed_metadata['update_schedule']['interval_count'];
127
  }
128
 
129
  $info['active-feed'] = $active_feed;
130
 
131
- if ( array_key_exists( 'latest_upload', $active_feed_metadata ) ) {
132
  $latest_upload = $active_feed_metadata['latest_upload'];
133
  $upload = array();
134
 
@@ -139,6 +157,12 @@ class FeedConfigurationDetection {
139
  // Get more detailed metadata about the most recent feed upload.
140
  $upload_metadata = $this->get_feed_upload_metadata( $latest_upload['id'] );
141
 
 
 
 
 
 
 
142
  $upload['error-count'] = $upload_metadata['error_count'];
143
  $upload['warning-count'] = $upload_metadata['warning_count'];
144
  $upload['num-detected-items'] = $upload_metadata['num_detected_items'];
@@ -167,12 +191,19 @@ class FeedConfigurationDetection {
167
 
168
  /**
169
  * @param string $product_catalog_id
 
170
  * @return array Facebook Product Feeds.
171
- * @throws \WooCommerce\Facebook\API\Exceptions\Request_Limit_Reached
172
- * @throws \WooCommerce\Facebook\Framework\Api\Exception
173
  */
174
  private function get_feed_nodes_for_catalog( string $product_catalog_id ) {
175
- $response = facebook_for_woocommerce()->get_api()->read_feeds( $product_catalog_id );
 
 
 
 
 
 
176
  return $response->data;
177
  }
178
 
@@ -180,24 +211,31 @@ class FeedConfigurationDetection {
180
  * Given feed id fetch this feed configuration metadata.
181
  *
182
  * @param string $feed_id Facebook Product Feed ID.
183
- * @return \WooCommerce\Facebook\API\Response
184
- * @throws \WooCommerce\Facebook\API\Exceptions\Request_Limit_Reached
185
- * @throws \WooCommerce\Facebook\Framework\Api\Exception
 
186
  */
187
  private function get_feed_metadata( string $feed_id ) {
188
- $response = facebook_for_woocommerce()->get_api()->read_feed( $feed_id );
189
- return $response;
190
  }
191
 
192
  /**
193
  * Given upload id fetch this upload execution metadata.
194
  *
 
 
 
195
  * @throws Error Upload metadata fetch was not successful.
196
- * @param String $upload_id Facebook Feed upload ID.
197
- * @return array Array of feed configurations.
198
  */
199
  private function get_feed_upload_metadata( $upload_id ) {
200
- $response = facebook_for_woocommerce()->get_api()->read_upload( $upload_id );
 
 
 
 
 
 
201
  return $response;
202
  }
203
 
6
  defined( 'ABSPATH' ) || exit;
7
 
8
  use Error;
9
+ use Exception;
10
+ use WC_Facebookcommerce_Utils;
11
+ use WooCommerce\Facebook\API\Exceptions\Request_Limit_Reached;
12
+ use WooCommerce\Facebook\API\Response;
13
+ use WooCommerce\Facebook\Framework\Api\Exception as ApiException;
14
  use WooCommerce\Facebook\Products\Feed;
15
  use WooCommerce\Facebook\Utilities\Heartbeat;
16
 
83
  */
84
  $active_feed_metadata = array();
85
  foreach ( $feed_nodes as $feed ) {
86
+ try {
87
+ $metadata = $this->get_feed_metadata( $feed['id'] );
88
+ } catch ( Exception $e ) {
89
+ $message = sprintf( 'There was an error trying to get feed metadata: %s', $e->getMessage() );
90
+ WC_Facebookcommerce_Utils::log( $message );
91
+ continue;
92
+ }
93
 
94
  if ( $feed['id'] === $integration_feed_id ) {
95
+ $active_feed_metadata = clone $metadata;
96
  break;
97
  }
98
 
99
+ if (
100
+ ! isset( $metadata['latest_upload'] ) ||
101
+ ! is_array( $metadata['latest_upload'] ) ||
102
+ ! array_key_exists( 'start_time', $metadata['latest_upload'] )
103
+ ) {
104
  continue;
105
  }
106
+
107
  $metadata['latest_upload_time'] = strtotime( $metadata['latest_upload']['start_time'] );
108
+ if (
109
+ ! $active_feed_metadata ||
110
+ $metadata['latest_upload_time'] > $active_feed_metadata['latest_upload_time']
111
+ ) {
112
+ $active_feed_metadata = clone $metadata;
113
  }
114
  }
115
 
120
  }
121
 
122
  $active_feed = array();
123
+ if ( isset( $active_feed_metadata['created_time'] ) ) {
124
  $active_feed['created-time'] = gmdate( 'Y-m-d H:i:s', strtotime( $active_feed_metadata['created_time'] ) );
125
  }
126
 
127
+ if ( isset( $active_feed_metadata['product_count'] ) ) {
128
  $active_feed['product-count'] = $active_feed_metadata['product_count'];
129
  }
130
 
135
  * These may both be configured; we will track settings for each individually (i.e. both).
136
  * https://developers.facebook.com/docs/marketing-api/reference/product-feed/
137
  */
138
+ if ( isset( $active_feed_metadata['schedule'] ) ) {
139
  $active_feed['schedule']['interval'] = $active_feed_metadata['schedule']['interval'];
140
  $active_feed['schedule']['interval-count'] = $active_feed_metadata['schedule']['interval_count'];
141
  }
142
+ if ( isset( $active_feed_metadata['update_schedule'] ) ) {
143
  $active_feed['update-schedule']['interval'] = $active_feed_metadata['update_schedule']['interval'];
144
  $active_feed['update-schedule']['interval-count'] = $active_feed_metadata['update_schedule']['interval_count'];
145
  }
146
 
147
  $info['active-feed'] = $active_feed;
148
 
149
+ if ( isset( $active_feed_metadata['latest_upload'] ) ) {
150
  $latest_upload = $active_feed_metadata['latest_upload'];
151
  $upload = array();
152
 
157
  // Get more detailed metadata about the most recent feed upload.
158
  $upload_metadata = $this->get_feed_upload_metadata( $latest_upload['id'] );
159
 
160
+ // If no metadata is available, we can't track any more details.
161
+ if ( ! $upload_metadata ) {
162
+ $info['active-feed']['latest-upload'] = $upload;
163
+ return $info;
164
+ }
165
+
166
  $upload['error-count'] = $upload_metadata['error_count'];
167
  $upload['warning-count'] = $upload_metadata['warning_count'];
168
  $upload['num-detected-items'] = $upload_metadata['num_detected_items'];
191
 
192
  /**
193
  * @param string $product_catalog_id
194
+ *
195
  * @return array Facebook Product Feeds.
196
+ * @throws Request_Limit_Reached
197
+ * @throws ApiException
198
  */
199
  private function get_feed_nodes_for_catalog( string $product_catalog_id ) {
200
+ try {
201
+ $response = facebook_for_woocommerce()->get_api()->read_feeds($product_catalog_id);
202
+ } catch ( \Exception $e ) {
203
+ $message = sprintf( 'There was an error trying to get feed nodes for catalog: %s', $e->getMessage() );
204
+ facebook_for_woocommerce()->log( $message );
205
+ return array();
206
+ }
207
  return $response->data;
208
  }
209
 
211
  * Given feed id fetch this feed configuration metadata.
212
  *
213
  * @param string $feed_id Facebook Product Feed ID.
214
+ *
215
+ * @return Response
216
+ * @throws Request_Limit_Reached
217
+ * @throws ApiException
218
  */
219
  private function get_feed_metadata( string $feed_id ) {
220
+ return facebook_for_woocommerce()->get_api()->read_feed( $feed_id );
 
221
  }
222
 
223
  /**
224
  * Given upload id fetch this upload execution metadata.
225
  *
226
+ * @param string $upload_id Facebook Feed upload ID.
227
+ *
228
+ * @return Response
229
  * @throws Error Upload metadata fetch was not successful.
 
 
230
  */
231
  private function get_feed_upload_metadata( $upload_id ) {
232
+ try {
233
+ $response = facebook_for_woocommerce()->get_api()->read_upload($upload_id);
234
+ } catch ( \Exception $e ) {
235
+ $message = sprintf( 'There was an error trying to get feed upload metadata: %s', $e->getMessage() );
236
+ facebook_for_woocommerce()->log( $message );
237
+ return false;
238
+ }
239
  return $response;
240
  }
241
 
includes/Framework/Api/JSONResponse.php CHANGED
@@ -1,32 +1,32 @@
1
  <?php
2
- // phpcs:ignoreFile
3
  /**
4
  * Facebook for WooCommerce.
5
  */
6
 
7
  namespace WooCommerce\Facebook\Framework\Api;
8
 
9
- defined( 'ABSPATH' ) or exit;
 
 
10
 
11
  /**
12
  * Base JSON API response class.
13
  *
14
  * @since 4.3.0
15
  */
16
- abstract class JSONResponse implements Response {
17
-
18
 
19
  /** @var string string representation of this response */
20
  protected $raw_response_json;
21
 
22
- /** @var mixed decoded response data */
23
  public $response_data;
24
 
25
-
26
  /**
27
  * Build the data object from the raw JSON.
28
  *
29
  * @since 4.3.0
 
30
  * @param string $raw_response_json The raw JSON
31
  */
32
  public function __construct( string $raw_response_json ) {
@@ -34,12 +34,13 @@ abstract class JSONResponse implements Response {
34
  $this->response_data = json_decode( $raw_response_json, true );
35
  }
36
 
37
-
38
  /**
39
  * Magic accessor for response data attributes
40
  *
41
  * @since 4.3.0
 
42
  * @param string $name The attribute name to get.
 
43
  * @return mixed The attribute value
44
  */
45
  public function __get( string $name ) {
@@ -47,28 +48,79 @@ abstract class JSONResponse implements Response {
47
  return $this->response_data[ $name ] ?? null;
48
  }
49
 
50
-
51
  /**
52
  * Get the string representation of this response.
53
  *
54
  * @since 4.3.0
55
- * @see SV_Response::to_string()
56
  * @return string
 
57
  */
58
  public function to_string() {
59
  return $this->raw_response_json;
60
  }
61
 
62
-
63
  /**
64
  * Get the string representation of this response with any and all sensitive elements masked
65
  * or removed.
66
  *
67
  * @since 4.3.0
68
- * @see Response::to_string_safe()
69
  * @return string
 
70
  */
71
  public function to_string_safe() {
72
  return $this->to_string();
73
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  }
1
  <?php
 
2
  /**
3
  * Facebook for WooCommerce.
4
  */
5
 
6
  namespace WooCommerce\Facebook\Framework\Api;
7
 
8
+ use ArrayAccess;
9
+
10
+ defined( 'ABSPATH' ) || exit;
11
 
12
  /**
13
  * Base JSON API response class.
14
  *
15
  * @since 4.3.0
16
  */
17
+ abstract class JSONResponse implements Response, ArrayAccess {
 
18
 
19
  /** @var string string representation of this response */
20
  protected $raw_response_json;
21
 
22
+ /** @var array decoded response data */
23
  public $response_data;
24
 
 
25
  /**
26
  * Build the data object from the raw JSON.
27
  *
28
  * @since 4.3.0
29
+ *
30
  * @param string $raw_response_json The raw JSON
31
  */
32
  public function __construct( string $raw_response_json ) {
34
  $this->response_data = json_decode( $raw_response_json, true );
35
  }
36
 
 
37
  /**
38
  * Magic accessor for response data attributes
39
  *
40
  * @since 4.3.0
41
+ *
42
  * @param string $name The attribute name to get.
43
+ *
44
  * @return mixed The attribute value
45
  */
46
  public function __get( string $name ) {
48
  return $this->response_data[ $name ] ?? null;
49
  }
50
 
 
51
  /**
52
  * Get the string representation of this response.
53
  *
54
  * @since 4.3.0
 
55
  * @return string
56
+ * @see SV_Response::to_string()
57
  */
58
  public function to_string() {
59
  return $this->raw_response_json;
60
  }
61
 
 
62
  /**
63
  * Get the string representation of this response with any and all sensitive elements masked
64
  * or removed.
65
  *
66
  * @since 4.3.0
 
67
  * @return string
68
+ * @see Response::to_string_safe()
69
  */
70
  public function to_string_safe() {
71
  return $this->to_string();
72
  }
73
+
74
+ /**
75
+ * Determine whether the given offset exists.
76
+ *
77
+ * @since 3.0.2
78
+ *
79
+ * @param int|string $offset The offset key.
80
+ *
81
+ * @return bool Whether the offset exists.
82
+ */
83
+ public function offsetExists( $offset ) {
84
+ return array_key_exists( $offset, $this->response_data );
85
+ }
86
+
87
+ /**
88
+ * Get the given offset.
89
+ *
90
+ * @since 3.0.2
91
+ *
92
+ * @param int|string $offset The offset key.
93
+ *
94
+ * @return mixed The offset value.
95
+ */
96
+ public function offsetGet( $offset ) {
97
+ return $this->response_data[ $offset ];
98
+ }
99
+
100
+ /**
101
+ * Set the offset to the given value.
102
+ *
103
+ * @since 3.0.2
104
+ *
105
+ * @param int|string $offset The offset key.
106
+ * @param mixed $value The offset value.
107
+ *
108
+ * @return void
109
+ */
110
+ public function offsetSet( $offset, $value ) {
111
+ $this->response_data[ $offset ] = $value;
112
+ }
113
+
114
+ /**
115
+ * Unset the given offset.
116
+ *
117
+ * @since 3.0.2
118
+ *
119
+ * @param int|string $offset The offset key.
120
+ *
121
+ * @return void
122
+ */
123
+ public function offsetUnset( $offset ) {
124
+ unset( $this->response_data[ $offset ] );
125
+ }
126
  }
includes/fbinfobanner.php CHANGED
@@ -11,6 +11,8 @@
11
 
12
  defined( 'ABSPATH' ) || exit;
13
 
 
 
14
  require_once __DIR__ . '/fbutils.php';
15
 
16
  /**
@@ -131,8 +133,14 @@ class WC_Facebookcommerce_Info_Banner {
131
  // tip pass time cap.
132
  $tip_info = WC_Facebookcommerce_Utils::get_cached_best_tip();
133
  } else {
134
- $tip_info = facebook_for_woocommerce()->get_api()->get_tip_info( $this->external_merchant_settings_id );
135
- update_option( 'fb_info_banner_last_query_time', current_time( 'mysql' ) );
 
 
 
 
 
 
136
  }
137
 
138
  // Not render if no cached best tip, or no best tip returned from FB.
11
 
12
  defined( 'ABSPATH' ) || exit;
13
 
14
+ use WooCommerce\Facebook\Framework\Api\Exception as ApiException;
15
+
16
  require_once __DIR__ . '/fbutils.php';
17
 
18
  /**
133
  // tip pass time cap.
134
  $tip_info = WC_Facebookcommerce_Utils::get_cached_best_tip();
135
  } else {
136
+
137
+ try {
138
+ $tip_info = facebook_for_woocommerce()->get_api()->get_tip_info( $this->external_merchant_settings_id );
139
+ update_option( 'fb_info_banner_last_query_time', current_time( 'mysql' ) );
140
+ } catch ( ApiException $exception ) {
141
+ // always log this error, regardless of debug setting
142
+ facebook_for_woocommerce()->log( 'Could not retrieve tip. ' . $exception->getMessage() );
143
+ }
144
  }
145
 
146
  // Not render if no cached best tip, or no best tip returned from FB.
includes/fbproductfeed.php CHANGED
@@ -14,6 +14,8 @@ defined( 'ABSPATH' ) || exit;
14
  use WooCommerce\Facebook\Framework\Plugin\Exception as PluginException;
15
  use WooCommerce\Facebook\Products;
16
  use WooCommerce\Facebook\Products\Feed;
 
 
17
 
18
  /**
19
  * Initial Sync by Facebook feed class
@@ -603,22 +605,25 @@ class WC_Facebook_Product_Feed {
603
  * @return string
604
  */
605
  public function is_upload_complete( &$settings ) {
 
 
 
 
606
 
607
- $upload_id = facebook_for_woocommerce()->get_integration()->get_upload_id();
608
- $result = facebook_for_woocommerce()->get_api()->read_upload( $upload_id );
609
-
610
- if ( is_wp_error( $result ) || ! isset( $result['body'] ) ) {
611
- $this->log_feed_progress( json_encode( $result ) );
612
- return 'error';
613
- }
614
-
615
- $upload_status = 'error';
616
 
617
- if ( isset( $result->end_time ) ) {
618
- $settings['upload_end_time'] = $result->end_time;
619
- $upload_status = 'complete';
620
- } elseif ( 200 === (int) wp_remote_retrieve_response_code( $result ) ) {
621
- $upload_status = 'in progress';
 
 
 
 
622
  }
623
 
624
  return $upload_status;
14
  use WooCommerce\Facebook\Framework\Plugin\Exception as PluginException;
15
  use WooCommerce\Facebook\Products;
16
  use WooCommerce\Facebook\Products\Feed;
17
+ use WooCommerce\Facebook\Framework\Api\Exception as ApiException;
18
+
19
 
20
  /**
21
  * Initial Sync by Facebook feed class
605
  * @return string
606
  */
607
  public function is_upload_complete( &$settings ) {
608
+ try {
609
+ $upload_status = 'error';
610
+ $upload_id = facebook_for_woocommerce()->get_integration()->get_upload_id();
611
+ $result = facebook_for_woocommerce()->get_api()->read_upload( $upload_id );
612
 
613
+ if ( is_wp_error( $result ) || ! isset( $result['body'] ) ) {
614
+ $this->log_feed_progress( json_encode( $result ) );
615
+ return $upload_status;
616
+ }
 
 
 
 
 
617
 
618
+ if ( isset( $result->end_time ) ) {
619
+ $settings['upload_end_time'] = $result->end_time;
620
+ $upload_status = 'complete';
621
+ } elseif ( 200 === (int) wp_remote_retrieve_response_code( $result ) ) {
622
+ $upload_status = 'in progress';
623
+ }
624
+ } catch ( ApiException $e ) {
625
+ $message = sprintf( 'There was an error trying to upload the configured feed: %s', $e->getMessage() );
626
+ facebook_for_woocommerce()->log( $message );
627
  }
628
 
629
  return $upload_status;
includes/fbutils.php CHANGED
@@ -13,6 +13,7 @@ defined( 'ABSPATH' ) || exit;
13
 
14
  use WooCommerce\Facebook\Events\AAMSettings;
15
  use WooCommerce\Facebook\Events\Normalizer;
 
16
 
17
  /**
18
  * FB Graph API helper functions
@@ -296,7 +297,12 @@ class WC_Facebookcommerce_Utils {
296
  );
297
  $ems = $ems ?: self::$ems;
298
  if ( $ems ) {
299
- facebook_for_woocommerce()->get_api()->log( $ems, $message, $error );
 
 
 
 
 
300
  } else {
301
  error_log(
302
  'external merchant setting is null, something wrong here: ' .
@@ -311,7 +317,12 @@ class WC_Facebookcommerce_Utils {
311
  public static function tip_events_log( $tip_id, $channel_id, $event, $ems = '' ) {
312
  $ems = $ems ?: self::$ems;
313
  if ( $ems ) {
314
- facebook_for_woocommerce()->get_api()->log_tip_event( $tip_id, $channel_id, $event );
 
 
 
 
 
315
  } else {
316
  error_log( 'external merchant setting is null' );
317
  }
13
 
14
  use WooCommerce\Facebook\Events\AAMSettings;
15
  use WooCommerce\Facebook\Events\Normalizer;
16
+ use WooCommerce\Facebook\Framework\Api\Exception as ApiException;
17
 
18
  /**
19
  * FB Graph API helper functions
297
  );
298
  $ems = $ems ?: self::$ems;
299
  if ( $ems ) {
300
+ try {
301
+ facebook_for_woocommerce()->get_api()->log($ems, $message, $error);
302
+ } catch ( ApiException $e ) {
303
+ $message = sprintf( 'There was an error trying to log: %s', $e->getMessage() );
304
+ facebook_for_woocommerce()->log( $message );
305
+ }
306
  } else {
307
  error_log(
308
  'external merchant setting is null, something wrong here: ' .
317
  public static function tip_events_log( $tip_id, $channel_id, $event, $ems = '' ) {
318
  $ems = $ems ?: self::$ems;
319
  if ( $ems ) {
320
+ try {
321
+ facebook_for_woocommerce()->get_api()->log_tip_event($tip_id, $channel_id, $event);
322
+ } catch ( ApiException $e ) {
323
+ $message = sprintf( 'There was an error while logging tip events: %s', $e->getMessage() );
324
+ facebook_for_woocommerce()->log( $message );
325
+ }
326
  } else {
327
  error_log( 'external merchant setting is null' );
328
  }
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: facebook, automattic, woothemes
3
  Tags: facebook, shop, catalog, advertise, pixel, product
4
  Requires at least: 4.4
5
  Tested up to: 6.1
6
- Stable tag: 3.0.1
7
  Requires PHP: 5.6 or greater
8
  MySQL: 5.6 or greater
9
  License: GPLv2 or later
@@ -39,18 +39,23 @@ When opening a bug on GitHub, please give us as many details as possible.
39
 
40
  == Changelog ==
41
 
42
- = 3.0.1 - 2022-11-17 =
43
- * Fix - Wrong path to the fbutils.php file.
44
-
45
- = 3.0.0 - 2022-11-17 =
46
- * Dev - Adding API Unit Tests.
47
- * Dev - Adding unit test workflow.
48
- * Dev - Adjusting php code styling.
49
- * Dev - Refactoring multiple Facebook APIs into a single one.
50
- * Dev - Removing SkyVerge dependency.
51
- * Dev - Removing deprecations.
52
- * Tweak - WC 5.4 compatibility.
53
-
 
 
 
 
 
54
  = 2.6.30 - 2022-11-09 =
55
  * Fix - Add backward compatibility for WC 6.1, 6.2, and 6.3 versions.
56
  * Fix - Sync product set when the term name changes.
3
  Tags: facebook, shop, catalog, advertise, pixel, product
4
  Requires at least: 4.4
5
  Tested up to: 6.1
6
+ Stable tag: 3.0.2
7
  Requires PHP: 5.6 or greater
8
  MySQL: 5.6 or greater
9
  License: GPLv2 or later
39
 
40
  == Changelog ==
41
 
42
+ = 3.0.2 - 2022-11-18 =
43
+ * Fix - Properly handle API exceptions
44
+ * Fix - Set correct PHP version in plugin header
45
+ * Dev - Add ArrayAccess implementation to JSONResponse class
46
+
47
+ = 3.0.1 - 2022-11-17 =
48
+ * Fix - Wrong path to the fbutils.php file.
49
+
50
+ = 3.0.0 - 2022-11-17 =
51
+ * Dev - Adding API Unit Tests.
52
+ * Dev - Adding unit test workflow.
53
+ * Dev - Adjusting php code styling.
54
+ * Dev - Refactoring multiple Facebook APIs into a single one.
55
+ * Dev - Removing SkyVerge dependency.
56
+ * Dev - Removing deprecations.
57
+ * Tweak - WC 5.4 compatibility.
58
+
59
  = 2.6.30 - 2022-11-09 =
60
  * Fix - Add backward compatibility for WC 6.1, 6.2, and 6.3 versions.
61
  * Fix - Sync product set when the term name changes.
vendor/autoload.php CHANGED
@@ -3,10 +3,23 @@
3
  // autoload.php @generated by Composer
4
 
5
  if (PHP_VERSION_ID < 50600) {
6
- echo 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
7
- exit(1);
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  }
9
 
10
  require_once __DIR__ . '/composer/autoload_real.php';
11
 
12
- return ComposerAutoloaderInit6e3b938ce8753eeadec15452bae8a717::getLoader();
3
  // autoload.php @generated by Composer
4
 
5
  if (PHP_VERSION_ID < 50600) {
6
+ if (!headers_sent()) {
7
+ header('HTTP/1.1 500 Internal Server Error');
8
+ }
9
+ $err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
10
+ if (!ini_get('display_errors')) {
11
+ if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
12
+ fwrite(STDERR, $err);
13
+ } elseif (!headers_sent()) {
14
+ echo $err;
15
+ }
16
+ }
17
+ trigger_error(
18
+ $err,
19
+ E_USER_ERROR
20
+ );
21
  }
22
 
23
  require_once __DIR__ . '/composer/autoload_real.php';
24
 
25
+ return ComposerAutoloaderInitca050a41463ac28647bff37744adcf81::getLoader();
vendor/composer/InstalledVersions.php CHANGED
@@ -28,7 +28,7 @@ class InstalledVersions
28
  {
29
  /**
30
  * @var mixed[]|null
31
- * @psalm-var array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}|array{}|null
32
  */
33
  private static $installed;
34
 
@@ -39,7 +39,7 @@ class InstalledVersions
39
 
40
  /**
41
  * @var array[]
42
- * @psalm-var array<string, array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
43
  */
44
  private static $installedByVendor = array();
45
 
@@ -243,7 +243,7 @@ class InstalledVersions
243
 
244
  /**
245
  * @return array
246
- * @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}
247
  */
248
  public static function getRootPackage()
249
  {
@@ -257,7 +257,7 @@ class InstalledVersions
257
  *
258
  * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
259
  * @return array[]
260
- * @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}
261
  */
262
  public static function getRawData()
263
  {
@@ -280,7 +280,7 @@ class InstalledVersions
280
  * Returns the raw data of all installed.php which are currently loaded for custom implementations
281
  *
282
  * @return array[]
283
- * @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
284
  */
285
  public static function getAllRawData()
286
  {
@@ -303,7 +303,7 @@ class InstalledVersions
303
  * @param array[] $data A vendor/composer/installed.php data set
304
  * @return void
305
  *
306
- * @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>} $data
307
  */
308
  public static function reload($data)
309
  {
@@ -313,7 +313,7 @@ class InstalledVersions
313
 
314
  /**
315
  * @return array[]
316
- * @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
317
  */
318
  private static function getInstalled()
319
  {
28
  {
29
  /**
30
  * @var mixed[]|null
31
+ * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
32
  */
33
  private static $installed;
34
 
39
 
40
  /**
41
  * @var array[]
42
+ * @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
43
  */
44
  private static $installedByVendor = array();
45
 
243
 
244
  /**
245
  * @return array
246
+ * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
247
  */
248
  public static function getRootPackage()
249
  {
257
  *
258
  * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
259
  * @return array[]
260
+ * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
261
  */
262
  public static function getRawData()
263
  {
280
  * Returns the raw data of all installed.php which are currently loaded for custom implementations
281
  *
282
  * @return array[]
283
+ * @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
284
  */
285
  public static function getAllRawData()
286
  {
303
  * @param array[] $data A vendor/composer/installed.php data set
304
  * @return void
305
  *
306
+ * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
307
  */
308
  public static function reload($data)
309
  {
313
 
314
  /**
315
  * @return array[]
316
+ * @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
317
  */
318
  private static function getInstalled()
319
  {
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInit6e3b938ce8753eeadec15452bae8a717
6
  {
7
  private static $loader;
8
 
@@ -24,12 +24,12 @@ class ComposerAutoloaderInit6e3b938ce8753eeadec15452bae8a717
24
 
25
  require __DIR__ . '/platform_check.php';
26
 
27
- spl_autoload_register(array('ComposerAutoloaderInit6e3b938ce8753eeadec15452bae8a717', 'loadClassLoader'), true, true);
28
  self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
29
- spl_autoload_unregister(array('ComposerAutoloaderInit6e3b938ce8753eeadec15452bae8a717', 'loadClassLoader'));
30
 
31
  require __DIR__ . '/autoload_static.php';
32
- call_user_func(\Composer\Autoload\ComposerStaticInit6e3b938ce8753eeadec15452bae8a717::getInitializer($loader));
33
 
34
  $loader->register(true);
35
 
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInitca050a41463ac28647bff37744adcf81
6
  {
7
  private static $loader;
8
 
24
 
25
  require __DIR__ . '/platform_check.php';
26
 
27
+ spl_autoload_register(array('ComposerAutoloaderInitca050a41463ac28647bff37744adcf81', 'loadClassLoader'), true, true);
28
  self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
29
+ spl_autoload_unregister(array('ComposerAutoloaderInitca050a41463ac28647bff37744adcf81', 'loadClassLoader'));
30
 
31
  require __DIR__ . '/autoload_static.php';
32
+ call_user_func(\Composer\Autoload\ComposerStaticInitca050a41463ac28647bff37744adcf81::getInitializer($loader));
33
 
34
  $loader->register(true);
35
 
vendor/composer/autoload_static.php CHANGED
@@ -4,7 +4,7 @@
4
 
5
  namespace Composer\Autoload;
6
 
7
- class ComposerStaticInit6e3b938ce8753eeadec15452bae8a717
8
  {
9
  public static $prefixLengthsPsr4 = array (
10
  'W' =>
@@ -301,9 +301,9 @@ class ComposerStaticInit6e3b938ce8753eeadec15452bae8a717
301
  public static function getInitializer(ClassLoader $loader)
302
  {
303
  return \Closure::bind(function () use ($loader) {
304
- $loader->prefixLengthsPsr4 = ComposerStaticInit6e3b938ce8753eeadec15452bae8a717::$prefixLengthsPsr4;
305
- $loader->prefixDirsPsr4 = ComposerStaticInit6e3b938ce8753eeadec15452bae8a717::$prefixDirsPsr4;
306
- $loader->classMap = ComposerStaticInit6e3b938ce8753eeadec15452bae8a717::$classMap;
307
 
308
  }, null, ClassLoader::class);
309
  }
4
 
5
  namespace Composer\Autoload;
6
 
7
+ class ComposerStaticInitca050a41463ac28647bff37744adcf81
8
  {
9
  public static $prefixLengthsPsr4 = array (
10
  'W' =>
301
  public static function getInitializer(ClassLoader $loader)
302
  {
303
  return \Closure::bind(function () use ($loader) {
304
+ $loader->prefixLengthsPsr4 = ComposerStaticInitca050a41463ac28647bff37744adcf81::$prefixLengthsPsr4;
305
+ $loader->prefixDirsPsr4 = ComposerStaticInitca050a41463ac28647bff37744adcf81::$prefixDirsPsr4;
306
+ $loader->classMap = ComposerStaticInitca050a41463ac28647bff37744adcf81::$classMap;
307
 
308
  }, null, ClassLoader::class);
309
  }
vendor/composer/installed.php CHANGED
@@ -1,31 +1,31 @@
1
  <?php return array(
2
  'root' => array(
3
- 'pretty_version' => 'dev-fix/wrong-fbutils-path',
4
- 'version' => 'dev-fix/wrong-fbutils-path',
 
 
5
  'type' => 'wordpress-plugin',
6
  'install_path' => __DIR__ . '/../../',
7
  'aliases' => array(),
8
- 'reference' => '9a999abea8272043f7cab996e12f783a36ee47b5',
9
- 'name' => 'facebookincubator/facebook-for-woocommerce',
10
  'dev' => false,
11
  ),
12
  'versions' => array(
13
  'composer/installers' => array(
14
  'pretty_version' => 'v1.12.0',
15
  'version' => '1.12.0.0',
 
16
  'type' => 'composer-plugin',
17
  'install_path' => __DIR__ . '/./installers',
18
  'aliases' => array(),
19
- 'reference' => 'd20a64ed3c94748397ff5973488761b22f6d3f19',
20
  'dev_requirement' => false,
21
  ),
22
  'facebookincubator/facebook-for-woocommerce' => array(
23
- 'pretty_version' => 'dev-fix/wrong-fbutils-path',
24
- 'version' => 'dev-fix/wrong-fbutils-path',
 
25
  'type' => 'wordpress-plugin',
26
  'install_path' => __DIR__ . '/../../',
27
  'aliases' => array(),
28
- 'reference' => '9a999abea8272043f7cab996e12f783a36ee47b5',
29
  'dev_requirement' => false,
30
  ),
31
  'roundcube/plugin-installer' => array(
@@ -43,10 +43,10 @@
43
  'woocommerce/action-scheduler-job-framework' => array(
44
  'pretty_version' => '2.0.0',
45
  'version' => '2.0.0.0',
 
46
  'type' => 'library',
47
  'install_path' => __DIR__ . '/../woocommerce/action-scheduler-job-framework',
48
  'aliases' => array(),
49
- 'reference' => 'b0b21b9cc87e476ba7f8817050b39274ea7d6732',
50
  'dev_requirement' => false,
51
  ),
52
  ),
1
  <?php return array(
2
  'root' => array(
3
+ 'name' => 'facebookincubator/facebook-for-woocommerce',
4
+ 'pretty_version' => 'dev-hotfix/3.0.2',
5
+ 'version' => 'dev-hotfix/3.0.2',
6
+ 'reference' => 'ff7a8e4ed3bd0893bb4e475ff42b819d6f4e0316',
7
  'type' => 'wordpress-plugin',
8
  'install_path' => __DIR__ . '/../../',
9
  'aliases' => array(),
 
 
10
  'dev' => false,
11
  ),
12
  'versions' => array(
13
  'composer/installers' => array(
14
  'pretty_version' => 'v1.12.0',
15
  'version' => '1.12.0.0',
16
+ 'reference' => 'd20a64ed3c94748397ff5973488761b22f6d3f19',
17
  'type' => 'composer-plugin',
18
  'install_path' => __DIR__ . '/./installers',
19
  'aliases' => array(),
 
20
  'dev_requirement' => false,
21
  ),
22
  'facebookincubator/facebook-for-woocommerce' => array(
23
+ 'pretty_version' => 'dev-hotfix/3.0.2',
24
+ 'version' => 'dev-hotfix/3.0.2',
25
+ 'reference' => 'ff7a8e4ed3bd0893bb4e475ff42b819d6f4e0316',
26
  'type' => 'wordpress-plugin',
27
  'install_path' => __DIR__ . '/../../',
28
  'aliases' => array(),
 
29
  'dev_requirement' => false,
30
  ),
31
  'roundcube/plugin-installer' => array(
43
  'woocommerce/action-scheduler-job-framework' => array(
44
  'pretty_version' => '2.0.0',
45
  'version' => '2.0.0.0',
46
+ 'reference' => 'b0b21b9cc87e476ba7f8817050b39274ea7d6732',
47
  'type' => 'library',
48
  'install_path' => __DIR__ . '/../woocommerce/action-scheduler-job-framework',
49
  'aliases' => array(),
 
50
  'dev_requirement' => false,
51
  ),
52
  ),
vendor/composer/platform_check.php CHANGED
@@ -4,8 +4,8 @@
4
 
5
  $issues = array();
6
 
7
- if (!(PHP_VERSION_ID >= 70400)) {
8
- $issues[] = 'Your Composer dependencies require a PHP version ">= 7.4.0". You are running ' . PHP_VERSION . '.';
9
  }
10
 
11
  if ($issues) {
4
 
5
  $issues = array();
6
 
7
+ if (!(PHP_VERSION_ID >= 70200)) {
8
+ $issues[] = 'Your Composer dependencies require a PHP version ">= 7.2.0". You are running ' . PHP_VERSION . '.';
9
  }
10
 
11
  if ($issues) {