From 3858c6af8300a5123f63453d23ad5fb259dcf55d Mon Sep 17 00:00:00 2001 From: Mykyta Synelnikov Date: Fri, 4 Apr 2025 12:59:10 +0300 Subject: [PATCH] Refactor Action Scheduler for not only email handling. Updated the Action Scheduler implementation to improve flexibility and clarity. Replaced the 'enable_action_scheduler' option with 'enable_as_email_sending' for better specificity. Introduced hook-based checks to selectively enable email scheduling, ensuring compatibility and optimized performance. --- includes/action-scheduler/class-init.php | 27 ++++++++++++-------- includes/admin/core/class-admin-settings.php | 2 +- includes/class-config.php | 2 +- includes/common/actions/class-emails.php | 12 +++++++-- 4 files changed, 28 insertions(+), 15 deletions(-) diff --git a/includes/action-scheduler/class-init.php b/includes/action-scheduler/class-init.php index 16b96bc3..0c2356fe 100644 --- a/includes/action-scheduler/class-init.php +++ b/includes/action-scheduler/class-init.php @@ -45,11 +45,10 @@ if ( ! class_exists( 'um\action_scheduler\Init' ) ) { add_action( 'init', array( $this, 'add_notice' ) ); } else { add_filter( 'um_settings_structure', array( $this, 'add_setting' ) ); - - if ( UM()->options()->get( 'enable_action_scheduler' ) ) { - $this->enabled = true; - $this->load_library( true ); - } + // Since 2.10.3 we load library as soon as there are required library files. + // Options above are used for enable/disable some Action Scheduler hooks e.g. um_dispatch_email. + $this->enabled = true; + $this->load_library( true ); } } @@ -77,11 +76,11 @@ if ( ! class_exists( 'um\action_scheduler\Init' ) ) { */ public function add_setting( $settings ) { $settings['advanced']['sections']['features']['form_sections']['features']['fields'][] = array( - 'id' => 'enable_action_scheduler', + 'id' => 'enable_as_email_sending', 'type' => 'checkbox', - 'label' => __( 'Action Scheduler', 'ultimate-member' ), - 'checkbox_label' => __( 'Enable Action Scheduler', 'ultimate-member' ), - 'description' => __( 'Check this box if you want to use the Ultimate Member action scheduler. By enabling it, certain tasks like sending system emails will be scheduled to run at optimal times, which can help reduce the load on your server', 'ultimate-member' ), + 'label' => __( 'Email sending by Action Scheduler', 'ultimate-member' ), + 'checkbox_label' => __( 'Enable Action Scheduler for Ultimate Member emails sending', 'ultimate-member' ), + 'description' => __( 'Check this box if you want to use the Action Scheduler for Ultimate Member emails sending. By enabling it, sending system emails will be scheduled to run at optimal times, which can help reduce the load on your server', 'ultimate-member' ), ); return $settings; @@ -131,6 +130,10 @@ if ( ! class_exists( 'um\action_scheduler\Init' ) ) { return $this->verify_wc_action_scheduler() || $this->load_library(); } + public function is_hook_enabled( $hook ) { + return apply_filters( 'um_action_scheduler_is_hook_enabled', $this->is_enabled(), $hook ); + } + /** * Enqueue an action to run one time, as soon as possible. * If Action Scheduler is disabled then do_action_ref_array is called to run action right away. @@ -144,11 +147,12 @@ if ( ! class_exists( 'um\action_scheduler\Init' ) ) { * @return int Еhe action’s ID. Zero if there was an error scheduling the action. The error will be sent to error_log */ public function enqueue_async_action( $hook, $args = array(), $group = '', $unique = false, $priority = 10 ) { - if ( $this->enabled ) { + if ( $this->is_hook_enabled( $hook ) ) { $group = $this->set_group( $group ); return as_enqueue_async_action( $hook, $args, $group, $unique, $priority ); } + // Make then standard action without Action Scheduler. do_action_ref_array( $hook, $args ); return 0; } @@ -166,11 +170,12 @@ if ( ! class_exists( 'um\action_scheduler\Init' ) ) { * @return int The action’s ID. Zero if there was an error scheduling the action. The error will be sent to error_log. */ public function schedule_single_action( $timestamp, $hook, $args = array(), $group = '', $unique = false, $priority = 10 ) { - if ( $this->enabled ) { + if ( $this->is_hook_enabled( $hook ) ) { $group = $this->set_group( $group ); return as_schedule_single_action( $timestamp, $hook, $args, $group, $unique, $priority ); } + // Make then standard action without Action Scheduler. do_action_ref_array( $hook, $args ); return 0; } diff --git a/includes/admin/core/class-admin-settings.php b/includes/admin/core/class-admin-settings.php index ab2c8668..7c51275d 100644 --- a/includes/admin/core/class-admin-settings.php +++ b/includes/admin/core/class-admin-settings.php @@ -1011,7 +1011,7 @@ if ( ! class_exists( 'um\admin\core\Admin_Settings' ) ) { 'enable_blocks' => array( 'sanitize' => 'bool', ), - 'enable_action_scheduler' => array( + 'enable_as_email_sending' => array( 'sanitize' => 'bool', ), 'rest_api_version' => array( diff --git a/includes/class-config.php b/includes/class-config.php index 0a3e9fbb..d7fa2aea 100644 --- a/includes/class-config.php +++ b/includes/class-config.php @@ -733,7 +733,7 @@ if ( ! class_exists( 'um\Config' ) ) { 'secure_notify_admins_banned_accounts__interval' => 'instant', 'secure_allowed_redirect_hosts' => '', 'delete_comments' => false, - 'enable_action_scheduler' => false, + 'enable_as_email_sending' => UM()->options()->get( 'enable_action_scheduler' ), // Use legacy option value by default. It helps during update to set the same value. The last version when we used 'enable_action_scheduler' is 2.10.2 ); add_filter( 'um_get_tabs_from_config', '__return_true' ); diff --git a/includes/common/actions/class-emails.php b/includes/common/actions/class-emails.php index 57991450..f4c485be 100644 --- a/includes/common/actions/class-emails.php +++ b/includes/common/actions/class-emails.php @@ -17,10 +17,18 @@ if ( ! class_exists( 'um\common\actions\Emails' ) ) { class Emails { public function __construct() { + add_filter( 'um_action_scheduler_is_hook_enabled', array( $this, 'is_enabled' ), 10, 2 ); add_action( 'um_dispatch_email', array( $this, 'send' ), 10, 3 ); add_action( 'um_before_email_notification_sending', array( $this, 'before_email_send' ), 10, 2 ); } + public function is_enabled( $is_enabled, $hook ) { + if ( 'um_dispatch_email' === $hook ) { + $is_enabled = UM()->options()->get( 'enable_as_email_sending' ); + } + return $is_enabled; + } + /** * Send an email * @@ -36,7 +44,7 @@ if ( ! class_exists( 'um\common\actions\Emails' ) ) { // @todo Workaround for now. Maybe we need to put base $user_id everytime if ( array_key_exists( 'fetch_user_id', $args ) ) { // When Action Scheduler is enabled, email sending script is located out of basic functionality, so we need to fetch the user for replace placeholders. - if ( UM()->maybe_action_scheduler()->is_enabled() ) { + if ( UM()->maybe_action_scheduler()->is_hook_enabled( 'um_dispatch_email' ) ) { um_fetch_user( $args['fetch_user_id'] ); } unset( $args['fetch_user_id'] ); @@ -56,7 +64,7 @@ if ( ! class_exists( 'um\common\actions\Emails' ) ) { * @return void */ public function before_email_send( $email, $template ) { - if ( ! UM()->maybe_action_scheduler()->is_enabled() ) { + if ( ! UM()->maybe_action_scheduler()->is_hook_enabled( 'um_dispatch_email' ) ) { return; }