Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
24aa179
Adding function on Connection to fetch CPI ID. Updating AbstractFeed …
nrostrow-meta Mar 13, 2025
95972b7
Adding newline
nrostrow-meta Mar 13, 2025
6cb3de0
Creating funciton for should skip logic.
nrostrow-meta Mar 14, 2025
28352ce
Merge branch 'main' into conditional_feed_upload_scheduling
nrostrow-meta Mar 14, 2025
8aa4f3e
Merge branch 'main' into conditional_feed_upload_scheduling
nrostrow-meta Mar 17, 2025
ad1d153
Merge branch 'main' into conditional_feed_upload_scheduling
nrostrow-meta Mar 18, 2025
6520355
Merging in main
nrostrow-meta Mar 19, 2025
306ed69
Using get_commerce_partner_integration_id
nrostrow-meta Mar 19, 2025
5534873
Updating call to get_commerce_merchant_settings_id
nrostrow-meta Mar 19, 2025
7054500
Merging main into branch
nrostrow-meta Mar 20, 2025
cba6457
Merge branch 'main' into conditional_feed_upload_scheduling
nrostrow-meta Mar 20, 2025
3e9ae80
Adding some logging
nrostrow-meta Mar 21, 2025
0d58959
Adding test cases for AbstractFeed
nrostrow-meta Mar 21, 2025
7898193
Updating logging values
nrostrow-meta Mar 22, 2025
c2ed3a9
feed_type to feed_name
nrostrow-meta Mar 22, 2025
67acf5c
Adding some additional logging fields
nrostrow-meta Mar 22, 2025
b00d982
Adding more test cases
nrostrow-meta Mar 22, 2025
e98d73b
Updating variable name
nrostrow-meta Mar 22, 2025
8e6fbaf
Merge branch 'main' into conditional_feed_upload_scheduling
nrostrow-meta Mar 22, 2025
b44b8e7
Merge branch 'main' into conditional_feed_upload_scheduling
nrostrow-meta Mar 24, 2025
5a6c8d8
Exception -> /Exception
nrostrow-meta Mar 24, 2025
68d4cee
Checking for CMS ID being set as well in should_skip_feed and updated…
nrostrow-meta Mar 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 50 additions & 9 deletions includes/Feed/AbstractFeed.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ protected function add_hooks(): void {
* @since 3.5.0
*/
public function schedule_feed_generation(): void {
if ( $this->should_skip_feed() ) {
return;
}

$schedule_action_hook_name = self::GENERATE_FEED_ACTION . static::get_data_stream_name();
if ( ! as_next_scheduled_action( $schedule_action_hook_name ) ) {
as_schedule_recurring_action(
Expand All @@ -123,14 +127,32 @@ public function schedule_feed_generation(): void {
* @since 3.5.0
*/
public function regenerate_feed(): void {
// Maybe use new ( experimental ), feed generation framework.
if ( \WC_Facebookcommerce::instance()->get_integration()->is_new_style_feed_generation_enabled() ) {
if ( $this->should_skip_feed() ) {
return;
}

if ( facebook_for_woocommerce()->get_integration()->is_new_style_feed_generation_enabled() ) {
$this->feed_generator->queue_start();
} else {
$this->feed_handler->generate_feed_file();
}
}

/**
* The feed should be skipped if there isn't a Commerce Partner Integration ID set as the ID is required for
* calls to the GraphCommercePartnerIntegrationFileUpdatePost endpoint.
* Overwrite this function if your feed upload uses a different endpoint with different requirements.
*
* @since 3.5.0
*/
public function should_skip_feed(): bool {
$connection_handler = facebook_for_woocommerce()->get_connection_handler();
$cpi_id = $connection_handler->get_commerce_partner_integration_id();
$cms_id = $connection_handler->get_commerce_merchant_settings_id();

return empty( $cpi_id ) || empty( $cms_id );
}

/**
* Trigger the upload flow
* Once feed regenerated, trigger upload via create_upload API
Expand All @@ -147,13 +169,22 @@ public function send_request_to_upload_feed(): void {
);

try {
$cpi_id = get_option( 'wc_facebook_commerce_partner_integration_id', '' );
$cpi_id = facebook_for_woocommerce()->get_connection_handler()->get_commerce_partner_integration_id();
facebook_for_woocommerce()->
get_api()->
create_common_data_feed_upload( $cpi_id, $data );
} catch ( Exception $e ) {
// Log the error and continue.
\WC_Facebookcommerce_Utils::log( "{$name} feed: Failed to create feed upload request: " . $e->getMessage() );
} catch ( \Exception $exception ) {
\WC_Facebookcommerce_Utils::logExceptionImmediatelyToMeta(
$exception,
[
'event' => 'feed_upload',
'event_type' => 'send_request_to_upload_feed',
'extra_data' => [
'feed_name' => $name,
'data' => wp_json_encode( $data ),
],
]
);
}
}

Expand Down Expand Up @@ -244,16 +275,26 @@ public function handle_feed_data_request(): void {
// fpassthru might be disabled in some hosts (like Flywheel).
// phpcs:ignore
if ( \WC_Facebookcommerce_Utils::is_fpassthru_disabled() || ! @fpassthru( $file ) ) {
\WC_Facebookcommerce_Utils::log( "{$name} feed: fpassthru is disabled: getting file contents" );
\WC_Facebookcommerce_Utils::log( "{$name} feed: fpassthru is disabled: getting file contents." );
//phpcs:ignore
$contents = @stream_get_contents( $file );
if ( ! $contents ) {
throw new PluginException( 'Could not get feed file contents.', 500 );
throw new PluginException( "{$name} feed: Could not get feed file contents.", 500 );
}
echo $contents; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
} catch ( \Exception $exception ) {
\WC_Facebookcommerce_Utils::log( "{$name} feed: Could not serve feed. " . $exception->getMessage() . ' (' . $exception->getCode() . ')' );
\WC_Facebookcommerce_Utils::logExceptionImmediatelyToMeta(
$exception,
[
'event' => 'feed_upload',
'event_type' => 'handle_feed_data_request',
'extra_data' => [
'feed_name' => $name,
'file_path' => $file_path,
],
]
);
status_header( $exception->getCode() );
}
exit;
Expand Down
13 changes: 11 additions & 2 deletions includes/Feed/CsvFeedFileWriter.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,17 @@ public function write_feed_file( array $data ): void {

// Step 3: Rename temporary feed file to final feed file.
$this->promote_temp_file();
} catch ( PluginException $e ) {
WC_Facebookcommerce_Utils::logExceptionImmediatelyToMeta( $e );
} catch ( PluginException $exception ) {
\WC_Facebookcommerce_Utils::logExceptionImmediatelyToMeta(
$exception,
[
'event' => 'feed_upload',
'event_type' => 'csv_write_feed_file',
'extra_data' => [
'feed_name' => $this->feed_name,
],
]
);
// Close the temporary file if it is still open.
if ( ! empty( $temp_feed_file ) && is_resource( $temp_feed_file ) ) {
fclose( $temp_feed_file ); // phpcs:ignore
Expand Down
137 changes: 81 additions & 56 deletions includes/Feed/FeedUploadUtils.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,72 +18,97 @@
* @since 3.5.0
*/
class FeedUploadUtils {
const VALUE_TYPE_PERCENTAGE = 'PERCENTAGE';
const VALUE_TYPE_FIXED_AMOUNT = 'FIXED_AMOUNT';
const TARGET_TYPE_SHIPPING = 'SHIPPING';
const TARGET_TYPE_LINE_ITEM = 'LINE_ITEM';
const TARGET_GRANULARITY_ORDER_LEVEL = 'ORDER_LEVEL';
const TARGET_GRANULARITY_ITEM_LEVEL = 'ITEM_LEVEL';
const TARGET_SELECTION_ENTIRE_CATALOG = 'ALL_CATALOG_PRODUCTS';
const TARGET_SELECTION_SPECIFIC_PRODUCTS = 'SPECIFIC_PRODUCTS';
const APPLICATION_TYPE_BUYER_APPLIED = 'BUYER_APPLIED';
const PROMO_SYNC_LOGGING_FLOW_NAME = 'promotion_feed_sync';
const VALUE_TYPE_PERCENTAGE = 'PERCENTAGE';
const VALUE_TYPE_FIXED_AMOUNT = 'FIXED_AMOUNT';
const TARGET_TYPE_SHIPPING = 'SHIPPING';
const TARGET_TYPE_LINE_ITEM = 'LINE_ITEM';
const TARGET_GRANULARITY_ORDER_LEVEL = 'ORDER_LEVEL';
const TARGET_GRANULARITY_ITEM_LEVEL = 'ITEM_LEVEL';
const TARGET_SELECTION_ENTIRE_CATALOG = 'ALL_CATALOG_PRODUCTS';
const TARGET_SELECTION_SPECIFIC_PRODUCTS = 'SPECIFIC_PRODUCTS';
const APPLICATION_TYPE_BUYER_APPLIED = 'BUYER_APPLIED';
const PROMO_SYNC_LOGGING_FLOW_NAME = 'promotion_feed_sync';
const RATINGS_AND_REVIEWS_SYNC_LOGGING_FLOW_NAME = 'ratings_and_reviews_feed_sync';

public static function get_ratings_and_reviews_data( array $query_args ): array {
$comments = get_comments( $query_args );
$reviews_data = array();
try {
$comments = get_comments( $query_args );
$reviews_data = array();

$store_name = get_bloginfo( 'name' );
$store_id = get_option( 'wc_facebook_commerce_merchant_settings_id', '' );
$store_urls = [ wc_get_page_permalink( 'shop' ) ];
$store_name = get_bloginfo( 'name' );
$store_id = facebook_for_woocommerce()->get_connection_handler()->get_commerce_merchant_settings_id();
$store_urls = [ wc_get_page_permalink( 'shop' ) ];

foreach ( $comments as $comment ) {
try {
$post_type = get_post_type( $comment->comment_post_ID );
if ( 'product' !== $post_type ) {
continue;
}
foreach ( $comments as $comment ) {
try {
$post_type = get_post_type( $comment->comment_post_ID );
if ( 'product' !== $post_type ) {
continue;
}

$rating = get_comment_meta( $comment->comment_ID, 'rating', true );
if ( ! is_numeric( $rating ) ) {
continue;
}
$rating = get_comment_meta( $comment->comment_ID, 'rating', true );
if ( ! is_numeric( $rating ) ) {
continue;
}

$reviewer_id = $comment->user_id;
// If reviewer_id is 0 then the reviewer is a logged-out user
$reviewer_is_anonymous = '0' === $reviewer_id ? 'true' : 'false';
$reviewer_id = $comment->user_id;
// If reviewer_id is 0 then the reviewer is a logged-out user
$reviewer_is_anonymous = '0' === $reviewer_id ? 'true' : 'false';

$product = wc_get_product( $comment->comment_post_ID );
if ( null === $product ) {
$product = wc_get_product( $comment->comment_post_ID );
if ( null === $product ) {
continue;
}
$product_name = $product->get_name();
$product_url = $product->get_permalink();
$product_skus = [ $product->get_sku() ];

$reviews_data[] = array(
'aggregator' => 'woocommerce',
'store.name' => $store_name,
'store.id' => $store_id,
'store.storeUrls' => "['" . implode( "','", $store_urls ) . "']",
'review_id' => $comment->comment_ID,
'rating' => intval( $rating ),
'title' => null,
'content' => $comment->comment_content,
'created_at' => $comment->comment_date,
'reviewer.name' => $comment->comment_author,
'reviewer.reviewerID' => $reviewer_id,
'reviewer.isAnonymous' => $reviewer_is_anonymous,
'product.name' => $product_name,
'product.url' => $product_url,
'product.productIdentifiers.skus' => "['" . implode( "','", $product_skus ) . "']",
);
} catch ( \Exception $e ) {
\WC_Facebookcommerce_Utils::logTelemetryToMeta(
'Exception while trying to map product review data for feed',
array(
'flow_name' => self::RATINGS_AND_REVIEWS_SYNC_LOGGING_FLOW_NAME,
'flow_step' => 'map_ratings_and_reviews_data',
'extra_data' => [
'exception_message' => $e->getMessage(),
],
)
);
continue;
}
$product_name = $product->get_name();
$product_url = $product->get_permalink();
$product_skus = [ $product->get_sku() ];

$reviews_data[] = array(
'aggregator' => 'woocommerce',
'store.name' => $store_name,
'store.id' => $store_id,
'store.storeUrls' => "['" . implode( "','", $store_urls ) . "']",
'review_id' => $comment->comment_ID,
'rating' => intval( $rating ),
'title' => null,
'content' => $comment->comment_content,
'created_at' => $comment->comment_date,
'reviewer.name' => $comment->comment_author,
'reviewer.reviewerID' => $reviewer_id,
'reviewer.isAnonymous' => $reviewer_is_anonymous,
'product.name' => $product_name,
'product.url' => $product_url,
'product.productIdentifiers.skus' => "['" . implode( "','", $product_skus ) . "']",
);
} catch ( \Exception $e ) {
continue;
}
}

return $reviews_data;
return $reviews_data;
} catch ( \Exception $exception ) {
\WC_Facebookcommerce_Utils::logExceptionImmediatelyToMeta(
$exception,
[
'event' => self::RATINGS_AND_REVIEWS_SYNC_LOGGING_FLOW_NAME,
'event_type' => 'get_ratings_and_reviews_data',
'extra_data' => [
'query_args' => wp_json_encode( $query_args ),
],
]
);
throw $exception;
}
}

/**
Expand Down Expand Up @@ -124,7 +149,7 @@ public static function get_coupons_data( array $query_args ): array {
'Unknown discount type encountered during feed processing',
array(
'promotion_id' => $coupon_post->ID,
'extra_data' => array( 'discount_type' => $woo_discount_type ),
'extra_data' => [ 'discount_type' => $woo_discount_type ],
'flow_name' => self::PROMO_SYNC_LOGGING_FLOW_NAME,
'flow_step' => 'map_discount_type',
)
Expand Down
2 changes: 1 addition & 1 deletion includes/Handlers/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class Connection {

/** @var string the Commerce Partner Integration ID option name */
const OPTION_COMMERCE_PARTNER_INTEGRATION_ID = 'wc_facebook_commerce_partner_integration_id';

/** @var string|null the generated external merchant settings ID */
private $external_business_id;

Expand Down
Loading