Fetch promotions in a WP Cron job (#51650)

* Getting promotions in a WP Cron job to make them async. We don't want this request to affect the performance of wp-admin. See https://github.com/woocommerce/woocommerce/pull/47262#pullrequestreview-2241835763.

* Changelog.

* Made callback method `update_promotions` public.

* Linter errors. Whitespace.
This commit is contained in:
And Finally 2024-09-30 15:49:58 +01:00 committed by GitHub
parent d3b0f153ad
commit a64e227fdc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 46 additions and 11 deletions

View File

@ -0,0 +1,4 @@
Significance: minor
Type: update
Changed how we fetch WooCommerce promotions. We're doing it async so as not to affect the loading of wp-admin.

View File

@ -15,6 +15,7 @@ if ( ! defined( 'ABSPATH' ) ) {
*/ */
class WC_Admin_Marketplace_Promotions { class WC_Admin_Marketplace_Promotions {
const CRON_NAME = 'woocommerce_marketplace_cron_fetch_promotions';
const TRANSIENT_NAME = 'woocommerce_marketplace_promotions_v2'; const TRANSIENT_NAME = 'woocommerce_marketplace_promotions_v2';
const TRANSIENT_LIFE_SPAN = DAY_IN_SECONDS; const TRANSIENT_LIFE_SPAN = DAY_IN_SECONDS;
const PROMOTIONS_API_URL = 'https://woocommerce.com/wp-json/wccom-extensions/3.0/promotions'; const PROMOTIONS_API_URL = 'https://woocommerce.com/wp-json/wccom-extensions/3.0/promotions';
@ -39,7 +40,16 @@ class WC_Admin_Marketplace_Promotions {
public static function init() { public static function init() {
// A legacy hook that can be triggered by action scheduler. // A legacy hook that can be triggered by action scheduler.
add_action( 'woocommerce_marketplace_fetch_promotions', array( __CLASS__, 'clear_deprecated_action' ) ); add_action( 'woocommerce_marketplace_fetch_promotions', array( __CLASS__, 'clear_deprecated_action' ) );
add_action( 'woocommerce_marketplace_fetch_promotions_clear', array( __CLASS__, 'clear_scheduled_event' ) ); add_action(
'woocommerce_marketplace_fetch_promotions_clear',
array(
__CLASS__,
'clear_deprecated_scheduled_event',
)
);
// Fetch promotions from the API and store them in a transient.
add_action( self::CRON_NAME, array( __CLASS__, 'update_promotions' ) );
if ( if (
defined( 'DOING_AJAX' ) && DOING_AJAX defined( 'DOING_AJAX' ) && DOING_AJAX
@ -53,24 +63,33 @@ class WC_Admin_Marketplace_Promotions {
return; return;
} }
self::maybe_update_promotions(); self::schedule_cron_event();
register_deactivation_hook( WC_PLUGIN_FILE, array( __CLASS__, 'clear_cron_event' ) );
self::$locale = ( self::$locale ?? get_user_locale() ) ?? 'en_US'; self::$locale = ( self::$locale ?? get_user_locale() ) ?? 'en_US';
self::maybe_show_bubble_promotions(); self::maybe_show_bubble_promotions();
} }
/** /**
* Fetch promotions from the API and store them in a transient. * Schedule a daily cron event to fetch promotions.
* Fetching can be suppressed by the `woocommerce_marketplace_suppress_promotions` filter. *
* @version 9.5.0
* *
* @return void * @return void
*/ */
private static function maybe_update_promotions() { private static function schedule_cron_event() {
// Fetch promotions if they're not in the transient. if ( ! wp_next_scheduled( self::CRON_NAME ) ) {
if ( false !== get_transient( self::TRANSIENT_NAME ) ) { wp_schedule_event( time(), 'daily', self::CRON_NAME );
return; }
} }
/**
* Fetch promotions from the API and store them in a transient.
*
* @return void
*/
public static function update_promotions() {
// Fetch promotions from the API. // Fetch promotions from the API.
$promotions = self::fetch_marketplace_promotions(); $promotions = self::fetch_marketplace_promotions();
set_transient( self::TRANSIENT_NAME, $promotions, self::TRANSIENT_LIFE_SPAN ); set_transient( self::TRANSIENT_NAME, $promotions, self::TRANSIENT_LIFE_SPAN );
@ -326,12 +345,24 @@ class WC_Admin_Marketplace_Promotions {
} }
/** /**
* Clear the scheduled action that was used to fetch promotions in WooCommerce 8.8. * When WooCommerce is disabled, clear the WP Cron event we use to fetch promotions.
* It's no longer needed as a transient is used to store the data. *
* @version 9.5.0
* *
* @return void * @return void
*/ */
public static function clear_scheduled_event() { public static function clear_cron_event() {
$timestamp = wp_next_scheduled( self::CRON_NAME );
wp_unschedule_event( $timestamp, self::CRON_NAME );
}
/**
* Clear deprecated scheduled action that was used to fetch promotions in WooCommerce 8.8.
* Replaced with a transient in WooCommerce 9.0.
*
* @return void
*/
public static function clear_deprecated_scheduled_event() {
if ( function_exists( 'as_unschedule_all_actions' ) ) { if ( function_exists( 'as_unschedule_all_actions' ) ) {
as_unschedule_all_actions( 'woocommerce_marketplace_fetch_promotions' ); as_unschedule_all_actions( 'woocommerce_marketplace_fetch_promotions' );
} }