diff --git a/includes/admin/class-wc-admin-notices.php b/includes/admin/class-wc-admin-notices.php index eb86d023842..ea0d14a72d8 100644 --- a/includes/admin/class-wc-admin-notices.php +++ b/includes/admin/class-wc-admin-notices.php @@ -207,14 +207,16 @@ class WC_Admin_Notices { * If we need to update, include a message with the update button. */ public static function update_notice() { - if ( version_compare( get_option( 'woocommerce_db_version' ), WC_VERSION, '<' ) ) { - $updater = new WC_Background_Updater(); - if ( $updater->is_updating() || ! empty( $_GET['do_update_woocommerce'] ) ) { // WPCS: input var ok, CSRF ok. + if ( WC_Install::needs_db_update() ) { + $next_scheduled_date = WC()->queue()->get_next( 'woocommerce_run_update_callback', null, 'woocommerce-db-updates' ); + + if ( $next_scheduled_date || ! empty( $_GET['do_update_woocommerce'] ) ) { // WPCS: input var ok, CSRF ok. include dirname( __FILE__ ) . '/views/html-notice-updating.php'; } else { include dirname( __FILE__ ) . '/views/html-notice-update.php'; } } else { + WC_Install::update_db_version(); include dirname( __FILE__ ) . '/views/html-notice-updated.php'; } } diff --git a/includes/admin/views/html-notice-update.php b/includes/admin/views/html-notice-update.php index ae6a4f16dfd..e45496de919 100644 --- a/includes/admin/views/html-notice-update.php +++ b/includes/admin/views/html-notice-update.php @@ -18,16 +18,22 @@ $update_url = wp_nonce_url( ?>
- diff --git a/includes/admin/views/html-notice-updated.php b/includes/admin/views/html-notice-updated.php index 03d81f7164d..dae43d5c337 100644 --- a/includes/admin/views/html-notice-updated.php +++ b/includes/admin/views/html-notice-updated.php @@ -1,6 +1,8 @@ diff --git a/includes/admin/views/html-notice-updating.php b/includes/admin/views/html-notice-updating.php index 39f1e907c60..de22ec43e6b 100644 --- a/includes/admin/views/html-notice-updating.php +++ b/includes/admin/views/html-notice-updating.php @@ -8,19 +8,9 @@ if ( ! defined( 'ABSPATH' ) ) { exit; } - -$force_update_url = wp_nonce_url( - add_query_arg( 'force_update_woocommerce', 'true', admin_url( 'admin.php?page=wc-settings' ) ), - 'wc_force_db_update', - 'wc_force_db_update_nonce' -); - ?> diff --git a/includes/class-wc-background-updater.php b/includes/class-wc-background-updater.php index 86047094805..a1253f6c4a2 100644 --- a/includes/class-wc-background-updater.php +++ b/includes/class-wc-background-updater.php @@ -3,6 +3,7 @@ * Background Updater * * @version 2.6.0 + * @deprecated 3.6.0 Replaced with queue. * @package WooCommerce/Classes */ diff --git a/includes/class-wc-install.php b/includes/class-wc-install.php index d013b1aab6b..418ab7ec811 100644 --- a/includes/class-wc-install.php +++ b/includes/class-wc-install.php @@ -132,19 +132,12 @@ class WC_Install { ), ); - /** - * Background update class. - * - * @var object - */ - private static $background_updater; - /** * Hook in tabs. */ public static function init() { add_action( 'init', array( __CLASS__, 'check_version' ), 5 ); - add_action( 'init', array( __CLASS__, 'init_background_updater' ), 5 ); + add_action( 'woocommerce_run_update_callback', array( __CLASS__, 'run_update_callback' ) ); add_action( 'admin_init', array( __CLASS__, 'install_actions' ) ); add_filter( 'plugin_action_links_' . WC_PLUGIN_BASENAME, array( __CLASS__, 'plugin_action_links' ) ); add_filter( 'plugin_row_meta', array( __CLASS__, 'plugin_row_meta' ), 10, 2 ); @@ -152,14 +145,6 @@ class WC_Install { add_filter( 'cron_schedules', array( __CLASS__, 'cron_schedules' ) ); } - /** - * Init background updates - */ - public static function init_background_updater() { - include_once dirname( __FILE__ ) . '/class-wc-background-updater.php'; - self::$background_updater = new WC_Background_Updater(); - } - /** * Check WooCommerce version and run the updater is required. * @@ -172,6 +157,51 @@ class WC_Install { } } + /** + * Run an update callback when triggered by ActionScheduler. + * + * @since 3.6.0 + * @param string $callback Callback name. + */ + public static function run_update_callback( $callback ) { + include_once dirname( __FILE__ ) . '/wc-update-functions.php'; + + if ( is_callable( $callback ) ) { + self::run_update_callback_start( $callback ); + $result = (bool) call_user_func( $callback ); + self::run_update_callback_end( $callback, $result ); + } + } + + /** + * Triggered when a callback will run. + * + * @since 3.6.0 + * @param string $callback Callback name. + */ + protected static function run_update_callback_start( $callback ) { + wc_maybe_define_constant( 'WC_UPDATING', true ); + } + + /** + * Triggered when a callback has ran. + * + * @since 3.6.0 + * @param string $callback Callback name. + * @param bool $result Return value from callback. Non-false need to run again. + */ + protected static function run_update_callback_end( $callback, $result ) { + if ( $result ) { + WC()->queue()->add( + 'woocommerce_run_update_callback', + array( + 'update_callback' => $callback, + ), + 'woocommerce-db-updates' + ); + } + } + /** * Install actions when a update button is clicked within the admin area. * @@ -183,17 +213,6 @@ class WC_Install { self::update(); WC_Admin_Notices::add_notice( 'update' ); } - if ( ! empty( $_GET['force_update_woocommerce'] ) ) { // WPCS: input var ok. - check_admin_referer( 'wc_force_db_update', 'wc_force_db_update_nonce' ); - $blog_id = get_current_blog_id(); - - // Used to fire an action added in WP_Background_Process::_construct() that calls WP_Background_Process::handle_cron_healthcheck(). - // This method will make sure the database updates are executed even if cron is disabled. Nothing will happen if the updates are already running. - do_action( 'wp_' . $blog_id . '_wc_updater_cron' ); - - wp_safe_redirect( admin_url( 'admin.php?page=wc-settings' ) ); - exit; - } } /** @@ -271,7 +290,7 @@ class WC_Install { * @since 3.2.0 * @return boolean */ - private static function needs_db_update() { + public static function needs_db_update() { $current_db_version = get_option( 'woocommerce_db_version', null ); $updates = self::get_db_update_callbacks(); @@ -298,7 +317,6 @@ class WC_Install { private static function maybe_update_db_version() { if ( self::needs_db_update() ) { if ( apply_filters( 'woocommerce_enable_auto_update_db', false ) ) { - self::init_background_updater(); self::update(); } else { WC_Admin_Notices::add_notice( 'update' ); @@ -331,25 +349,23 @@ class WC_Install { */ private static function update() { $current_db_version = get_option( 'woocommerce_db_version' ); - $logger = wc_get_logger(); - $update_queued = false; + $loop = 0; foreach ( self::get_db_update_callbacks() as $version => $update_callbacks ) { if ( version_compare( $current_db_version, $version, '<' ) ) { foreach ( $update_callbacks as $update_callback ) { - $logger->info( - sprintf( 'Queuing %s - %s', $version, $update_callback ), - array( 'source' => 'wc_db_updates' ) + WC()->queue()->schedule_single( + time() + $loop, + 'woocommerce_run_update_callback', + array( + 'update_callback' => $update_callback, + ), + 'woocommerce-db-updates' ); - self::$background_updater->push_to_queue( $update_callback ); - $update_queued = true; + $loop++; } } } - - if ( $update_queued ) { - self::$background_updater->save()->dispatch(); - } } /** diff --git a/includes/cli/class-wc-cli-update-command.php b/includes/cli/class-wc-cli-update-command.php index 3c0c1881f5c..204c188bc5a 100644 --- a/includes/cli/class-wc-cli-update-command.php +++ b/includes/cli/class-wc-cli-update-command.php @@ -37,20 +37,43 @@ class WC_CLI_Update_Command { $current_db_version = get_option( 'woocommerce_db_version' ); $update_count = 0; + $callbacks = WC_Install::get_db_update_callbacks(); + $callbacks_to_run = array(); - foreach ( WC_Install::get_db_update_callbacks() as $version => $update_callbacks ) { + foreach ( $callbacks as $version => $update_callbacks ) { if ( version_compare( $current_db_version, $version, '<' ) ) { foreach ( $update_callbacks as $update_callback ) { - /* translators: %s: DB update callback key */ - WP_CLI::log( sprintf( __( 'Calling update function: %s', 'woocommerce' ), $update_callback ) ); - call_user_func( $update_callback ); - $update_count ++; + $callbacks_to_run[] = $update_callback; } } } + if ( empty( $callbacks_to_run ) ) { + /* translators: %s Database version number */ + WP_CLI::success( sprintf( __( 'No updates required. Database version is %s', 'woocommerce' ), get_option( 'woocommerce_db_version' ) ) ); + return; + } + + /* translators: 1: Number of database updates 2: List of update callbacks */ + WP_CLI::log( sprintf( __( 'Found %1$d updates (%2$s)', 'woocommerce' ), count( $callbacks_to_run ), implode( ', ', $callbacks_to_run ) ) ); + + $progress = \WP_CLI\Utils\make_progress_bar( __( 'Updating database', 'woocommerce' ), count( $callbacks_to_run ) ); // phpcs:ignore PHPCompatibility.LanguageConstructs.NewLanguageConstructs.t_ns_separatorFound + + foreach ( $callbacks_to_run as $update_callback ) { + call_user_func( $update_callback ); + $result = false; + while ( $result ) { + $result = (bool) call_user_func( $update_callback ); + } + $update_count ++; + $progress->tick(); + } + + $progress->finish(); + WC_Admin_Notices::remove_notice( 'update' ); + /* translators: 1: Number of database updates performed 2: Database version number */ - WP_CLI::success( sprintf( __( '%1$d updates complete. Database version is %2$s', 'woocommerce' ), absint( $update_count ), get_option( 'woocommerce_db_version' ) ) ); + WP_CLI::success( sprintf( __( '%1$d update functions completed. Database version is %2$s', 'woocommerce' ), absint( $update_count ), get_option( 'woocommerce_db_version' ) ) ); } }