Skip to content
Open
Changes from all commits
Commits
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
98 changes: 98 additions & 0 deletions facebook-commerce.php
Original file line number Diff line number Diff line change
Expand Up @@ -2035,6 +2035,104 @@ public function get_sample_product_feed() {
return wp_json_encode( [ $items ] );
}

/**
* Checks if a post is a WooCommerce product.
*
* @param int $product_id Post ID to check.
* @return bool True if the post is a WooCommerce product.
* @since 3.5.7
*/
private function is_woocommerce_product( $product_id ) {
if ( ! is_numeric( $product_id ) || $product_id <= 0 ) {
return false;
}

$post_type = get_post_type( $product_id );
return in_array( $post_type, [ 'product', 'product_variation' ], true );
}

/**
* Checks if a meta key affects Facebook sync and should trigger last change time update.
*
* @param string $meta_key Meta key to check.
* @return bool True if the meta key is relevant to Facebook sync.
* @since 3.5.7
*/
private function is_meta_key_sync_relevant( $meta_key ) {
// Skip our own meta keys to prevent infinite loops
if ( in_array( $meta_key, [ '_last_change_time', '_fb_sync_last_time' ], true ) ) {
return false;
}

// Skip WordPress internal meta keys
if ( strpos( $meta_key, '_wp_' ) === 0 || strpos( $meta_key, '_edit_' ) === 0 ) {
return false;
}

// Meta keys that affect Facebook sync
$sync_relevant_meta_keys = [
'_regular_price', // -> price
'_sale_price', // -> sale_price
'_stock', // -> availability
'_stock_status', // -> availability
'_thumbnail_id', // -> image_link
'_price', // -> price (calculated field)
'fb_visibility', // -> visibility
'fb_product_description', // -> description
'fb_rich_text_description', // -> rich_text_description
'fb_brand', // -> brand
'fb_mpn', // -> mpn
'fb_size', // -> size
'fb_color', // -> color
'fb_material', // -> material
'fb_pattern', // -> pattern
'fb_age_group', // -> age_group
'fb_gender', // -> gender
'fb_product_condition', // -> condition
'_wc_facebook_sync_enabled', // -> sync settings
'_wc_facebook_product_image_source', // -> sync settings
];

return in_array( $meta_key, $sync_relevant_meta_keys, true );
}

/**
* Checks if the last change time update is rate limited for a product.
*
* @param int $product_id Product ID.
* @return bool True if rate limited, false otherwise.
* @since 3.5.7
*/
private function is_last_change_time_update_rate_limited( $product_id ) {
$cache_key = "last_change_time_{$product_id}";
$cached_time = wp_cache_get( $cache_key, 'facebook_for_woocommerce' );

// If no cached time, allow update
if ( false === $cached_time ) {
return false;
}

// Rate limit to once every 60 seconds (1 minute)
$rate_limit_window = 60;
$current_time = time();

// If the last update was within the rate limit window, prevent update
return ( $current_time - $cached_time ) < $rate_limit_window;
}

/**
* Sets the last change time in cache for rate limiting.
*
* @param int $product_id Product ID.
* @param int $timestamp Timestamp to cache.
* @since 3.5.7
*/
private function set_last_change_time_cache( $product_id, $timestamp ) {
$cache_key = "last_change_time_{$product_id}";
// Cache for 2 minutes (120 seconds) to ensure it persists longer than the rate limit window
wp_cache_set( $cache_key, $timestamp, 'facebook_for_woocommerce', 120 );
}

/**
* Loop through array of WPIDs to remove metadata.
*
Expand Down
Loading