From 53ac0db900bcd142d7fa11cd100e2252e99e2fa5 Mon Sep 17 00:00:00 2001 From: Giuseppe Arcifa Date: Fri, 13 Dec 2024 18:07:41 +0100 Subject: [PATCH] Introduced `AbstractTaskManager` to centralize common behaviors of all Task Manager classes, reducing redundancy and improving code clarity and maintainability. Modified Task Managers to instantiate only when their associated WP Cron hooks are scheduled, optimizing resource usage and avoiding errors about unhandled hooks. Ensured recurring WP Cron hooks are cleared after completion using `wp_clear_scheduled_hook`, preventing unnecessary executions. Added `TaskManagerSchedules` class to register new custom schedules for WP Cron jobs via filters, enabling more flexible scheduling for various Task Managers. --- includes/TaskManagers/AbstractTaskManager.php | 69 ++++++++++++++ .../PluginActivationTaskManager.php | 61 +++++-------- .../PluginDeactivationTaskManager.php | 55 ++++-------- .../TaskManagers/PluginInstallTaskManager.php | 60 +++++-------- .../PluginUninstallTaskManager.php | 59 +++++------- includes/TaskManagers/TaskManager.php | 8 +- .../TaskManagers/TaskManagerSchedules.php | 57 ++++++++++++ .../TaskManagers/ThemeInstallTaskManager.php | 89 +++++++------------ 8 files changed, 253 insertions(+), 205 deletions(-) create mode 100644 includes/TaskManagers/AbstractTaskManager.php create mode 100644 includes/TaskManagers/TaskManagerSchedules.php diff --git a/includes/TaskManagers/AbstractTaskManager.php b/includes/TaskManagers/AbstractTaskManager.php new file mode 100644 index 0000000..1c1605c --- /dev/null +++ b/includes/TaskManagers/AbstractTaskManager.php @@ -0,0 +1,69 @@ +execute(); if ( is_wp_error( $status ) ) { @@ -103,10 +101,10 @@ public static function add_to_queue( PluginActivationTask $plugin_activation_tas Check if there is an already existing PluginActivationTask in the queue for a given slug. */ - if ( $queued_plugin['slug'] === $plugin_activation_task->get_slug() ) { + if ( $queued_plugin[ 'slug' ] === $plugin_activation_task->get_slug() ) { return false; } - $queue->insert( $queued_plugin, $queued_plugin['priority'] ); + $queue->insert( $queued_plugin, $queued_plugin[ 'priority' ] ); } // Insert a new PluginActivationTask at the appropriate position in the queue. @@ -136,22 +134,11 @@ public static function remove_from_queue( $plugin ) { /* If the Plugin slug does not match add it back to the queue. */ - if ( $queued_plugin['slug'] !== $plugin ) { - $queue->insert( $queued_plugin, $queued_plugin['priority'] ); + if ( $queued_plugin[ 'slug' ] !== $plugin ) { + $queue->insert( $queued_plugin, $queued_plugin[ 'priority' ] ); } } return \update_option( Options::get_option_name( self::$queue_name ), $queue->to_array() ); } - - /** - * Get the status of a given plugin slug from the queue. - * - * @param string $plugin The slug of the plugin. - * @return boolean - */ - public static function status( $plugin ) { - $plugins = \get_option( Options::get_option_name( self::$queue_name ), array() ); - return array_search( $plugin, array_column( $plugins, 'slug' ), true ); - } } diff --git a/includes/TaskManagers/PluginDeactivationTaskManager.php b/includes/TaskManagers/PluginDeactivationTaskManager.php index ccbe835..326d4d3 100644 --- a/includes/TaskManagers/PluginDeactivationTaskManager.php +++ b/includes/TaskManagers/PluginDeactivationTaskManager.php @@ -1,4 +1,5 @@ execute(); if ( ! $status ) { @@ -101,10 +95,10 @@ public static function add_to_queue( PluginDeactivationTask $plugin_deactivation Check if there is an already existing PluginDeactivationTask in the queue for a given slug. */ - if ( $queued_plugin['slug'] === $plugin_deactivation_task->get_slug() ) { + if ( $queued_plugin[ 'slug' ] === $plugin_deactivation_task->get_slug() ) { return false; } - $queue->insert( $queued_plugin, $queued_plugin['priority'] ); + $queue->insert( $queued_plugin, $queued_plugin[ 'priority' ] ); } // Insert a new PluginDeactivationTask at the appropriate position in the queue. @@ -134,22 +128,11 @@ public static function remove_from_queue( $plugin ) { /* If the Plugin slug does not match add it back to the queue. */ - if ( $queued_plugin['slug'] !== $plugin ) { - $queue->insert( $queued_plugin, $queued_plugin['priority'] ); + if ( $queued_plugin[ 'slug' ] !== $plugin ) { + $queue->insert( $queued_plugin, $queued_plugin[ 'priority' ] ); } } return \update_option( Options::get_option_name( self::$queue_name ), $queue->to_array() ); } - - /** - * Get the status of a given plugin slug from the queue. - * - * @param string $plugin The slug of the plugin. - * @return boolean - */ - public static function status( $plugin ) { - $plugins = \get_option( Options::get_option_name( self::$queue_name ), array() ); - return array_search( $plugin, array_column( $plugins, 'slug' ), true ); - } } diff --git a/includes/TaskManagers/PluginInstallTaskManager.php b/includes/TaskManagers/PluginInstallTaskManager.php index dc1ece8..de3f0e0 100644 --- a/includes/TaskManagers/PluginInstallTaskManager.php +++ b/includes/TaskManagers/PluginInstallTaskManager.php @@ -1,4 +1,5 @@ 30, 'display' => __( 'Once Every Thirty Seconds' ), ); @@ -94,10 +86,10 @@ public function install() { // Recreate the PluginInstall task from the associative array. $plugin_install_task = new PluginInstallTask( - $plugin_to_install['slug'], - $plugin_to_install['activate'], - $plugin_to_install['priority'], - $plugin_to_install['retries'] + $plugin_to_install[ 'slug' ], + $plugin_to_install[ 'activate' ], + $plugin_to_install[ 'priority' ], + $plugin_to_install[ 'retries' ] ); // Update status to the current slug being installed. @@ -151,8 +143,8 @@ public static function add_to_queue( PluginInstallTask $plugin_install_task ) { Check if there is an already existing PluginInstallTask in the queue for a given slug. */ - if ( $queued_plugin['slug'] !== $plugin_install_task->get_slug() ) { - $queue->insert( $queued_plugin, $queued_plugin['priority'] ); + if ( $queued_plugin[ 'slug' ] !== $plugin_install_task->get_slug() ) { + $queue->insert( $queued_plugin, $queued_plugin[ 'priority' ] ); } } @@ -183,24 +175,14 @@ public static function remove_from_queue( $plugin ) { /* If the Plugin slug does not match add it back to the queue. */ - if ( $queued_plugin['slug'] !== $plugin ) { - $queue->insert( $queued_plugin, $queued_plugin['priority'] ); + if ( $queued_plugin[ 'slug' ] !== $plugin ) { + $queue->insert( $queued_plugin, $queued_plugin[ 'priority' ] ); } } return \update_option( Options::get_option_name( self::$queue_name ), $queue->to_array() ); } - /** - * Get the status of a given plugin slug from the queue. - * - * @param string $plugin The slug of the plugin. - * @return boolean - */ - public static function status( $plugin ) { - $plugins = \get_option( Options::get_option_name( self::$queue_name ), array() ); - return array_search( $plugin, array_column( $plugins, 'slug' ), true ); - } /** * Clear all the hook scheduling and update the status option diff --git a/includes/TaskManagers/PluginUninstallTaskManager.php b/includes/TaskManagers/PluginUninstallTaskManager.php index 61bd8c9..faf154e 100644 --- a/includes/TaskManagers/PluginUninstallTaskManager.php +++ b/includes/TaskManagers/PluginUninstallTaskManager.php @@ -1,4 +1,5 @@ 10, 'display' => __( 'Once Every Ten Seconds' ), ); @@ -86,6 +85,7 @@ public function uninstall() { */ $plugin_to_uninstall = array_shift( $plugins ); if ( ! $plugin_to_uninstall ) { + wp_unschedule_event( self::get_hook_name() ); return true; } @@ -94,9 +94,9 @@ public function uninstall() { // Recreate the PluginInstall task from the associative array. $plugin_uninstall_task = new PluginUninstallTask( - $plugin_to_uninstall['slug'], - $plugin_to_uninstall['priority'], - $plugin_to_uninstall['retries'] + $plugin_to_uninstall[ 'slug' ], + $plugin_to_uninstall[ 'priority' ], + $plugin_to_uninstall[ 'retries' ] ); // Execute the PluginUninstall Task. @@ -146,7 +146,7 @@ public static function add_to_queue( PluginUninstallTask $plugin_uninstall_task $plugin_list = Plugins::get_squashed(); // Gets the specified path for the Plugin from the predefined list - $plugin_path = $plugin_list[ $plugin_uninstall_task->get_slug() ]['path']; + $plugin_path = $plugin_list[ $plugin_uninstall_task->get_slug() ][ 'path' ]; if ( ! PluginUninstaller::is_plugin_installed( $plugin_path ) ) { return true; @@ -158,10 +158,10 @@ public static function add_to_queue( PluginUninstallTask $plugin_uninstall_task Check if there is an already existing PluginUninstallTask in the queue for a given slug. */ - if ( $queued_plugin['slug'] === $plugin_uninstall_task->get_slug() ) { + if ( $queued_plugin[ 'slug' ] === $plugin_uninstall_task->get_slug() ) { return false; } - $queue->insert( $queued_plugin, $queued_plugin['priority'] ); + $queue->insert( $queued_plugin, $queued_plugin[ 'priority' ] ); } // Insert a new PluginUninstallTask at the appropriate position in the queue. @@ -172,15 +172,4 @@ public static function add_to_queue( PluginUninstallTask $plugin_uninstall_task return \update_option( Options::get_option_name( self::$queue_name ), $queue->to_array() ); } - - /** - * Returns the status of given plugin slug - uninstalling/completed. - * - * @param string $plugin Plugin Slug - * @return string|false - */ - public static function status( $plugin ) { - $plugins = \get_option( Options::get_option_name( self::$queue_name ), array() ); - return array_search( $plugin, array_column( $plugins, 'slug' ), true ); - } } diff --git a/includes/TaskManagers/TaskManager.php b/includes/TaskManagers/TaskManager.php index 0576e05..156e3b1 100644 --- a/includes/TaskManagers/TaskManager.php +++ b/includes/TaskManagers/TaskManager.php @@ -1,4 +1,5 @@ task_managers as $task_manager ) { - if ( ! empty( get_option( Options::get_option_name( $task_manager::get_queue_name() ), array() ) ) ) { + if ( wp_next_scheduled( $task_manager::get_hook_name() ) || ! empty( get_option( Options::get_option_name( $task_manager::get_queue_name() ), array() ) ) ) { new $task_manager(); } } diff --git a/includes/TaskManagers/TaskManagerSchedules.php b/includes/TaskManagers/TaskManagerSchedules.php new file mode 100644 index 0000000..a7242d6 --- /dev/null +++ b/includes/TaskManagers/TaskManagerSchedules.php @@ -0,0 +1,57 @@ + array( + 'interval' => 30, + 'display' => __( 'Once Every Thirty Seconds' ), + ), + 'ten_seconds' => array( + 'interval' => 10, + 'display' => __( 'Once Every Ten Seconds' ), + ), + ); + } + + /** + * Adds a task manager cron schedule. + * + * @param array $schedules The existing cron schedule. + * @return array + */ + public static function add_schedules( $schedules ) { + foreach ( self::$schedules as $schedule_slug => $schedule_data ) { + if ( ! array_key_exists( $schedule_slug, $schedules ) || $schedule_data[ 'interval' ] !== $schedules[ $schedule_slug ][ 'interval' ] ) { + $schedules[ $schedule_slug ] = $schedule_data; + } + } + + return $schedules; + } +} diff --git a/includes/TaskManagers/ThemeInstallTaskManager.php b/includes/TaskManagers/ThemeInstallTaskManager.php index 4dee92c..7d35280 100644 --- a/includes/TaskManagers/ThemeInstallTaskManager.php +++ b/includes/TaskManagers/ThemeInstallTaskManager.php @@ -1,4 +1,5 @@ 10, - 'display' => __( 'Once Every Ten Seconds' ), - ); - } - - return $schedules; - } - /** * Expedites an existing ThemeInstallTask with a given slug. * @@ -85,10 +59,10 @@ public static function expedite( $theme_slug ) { \update_option( Options::get_option_name( self::$queue_name ), $themes ); $theme_install_task = new ThemeInstallTask( - $theme_to_install['slug'], - $theme_to_install['activate'], - $theme_to_install['priority'], - $theme_to_install['retries'] + $theme_to_install[ 'slug' ], + $theme_to_install[ 'activate' ], + $theme_to_install[ 'priority' ], + $theme_to_install[ 'retries' ] ); // Update status to the current slug being installed. @@ -106,7 +80,7 @@ public static function expedite( $theme_slug ) { then re-queue the task at the end of the queue to be retried. */ if ( $theme_install_task->get_retries() <= self::$retry_limit ) { - array_push( $themes, $theme_install_task->to_array() ); + array_push( $themes, $theme_install_task->to_array() ); } } @@ -138,15 +112,16 @@ public function install() { */ $theme_to_install = array_shift( $themes ); if ( ! $theme_to_install ) { + self::complete(); return true; } // Recreate the ThemeInstallTask from the associative array. $theme_install_task = new ThemeInstallTask( - $theme_to_install['slug'], - $theme_to_install['activate'], - $theme_to_install['priority'], - $theme_to_install['retries'] + $theme_to_install[ 'slug' ], + $theme_to_install[ 'activate' ], + $theme_to_install[ 'priority' ], + $theme_to_install[ 'retries' ] ); // Update status to the current slug being installed. @@ -164,13 +139,13 @@ public function install() { then re-queue the task at the end of the queue to be retried. */ if ( $theme_install_task->get_retries() <= self::$retry_limit ) { - array_push( $themes, $theme_install_task->to_array() ); + array_push( $themes, $theme_install_task->to_array() ); } } // If there are no more themes to be installed then change the status to completed. if ( empty( $themes ) ) { - \update_option( Options::get_option_name( 'theme_init_status' ), 'completed' ); + self::complete(); } // Update the theme install queue. @@ -197,11 +172,11 @@ public static function add_to_queue( ThemeInstallTask $theme_install_task ) { Check if there is an already existing ThemeInstallTask in the queue for a given slug and activation criteria. */ - if ( $queued_theme['slug'] === $theme_install_task->get_slug() - && $queued_theme['activate'] === $theme_install_task->get_activate() ) { + if ( $queued_theme[ 'slug' ] === $theme_install_task->get_slug() + && $queued_theme[ 'activate' ] === $theme_install_task->get_activate() ) { return false; } - $queue->insert( $queued_theme, $queued_theme['priority'] ); + $queue->insert( $queued_theme, $queued_theme[ 'priority' ] ); } // Insert a new ThemeInstallTask at the appropriate position in the queue. @@ -213,14 +188,14 @@ public static function add_to_queue( ThemeInstallTask $theme_install_task ) { return \update_option( Options::get_option_name( self::$queue_name ), $queue->to_array() ); } + /** - * Returns the status of given plugin slug - installing/completed. + * Clear all the hook scheduling and update the status option * - * @param string $theme Theme Slug - * @return string|false + * @return bool */ - public static function status( $theme ) { - $themes = \get_option( Options::get_option_name( self::$queue_name ), array() ); - return array_search( $theme, array_column( $themes, 'slug' ), true ); + private static function complete() { + wp_clear_scheduled_hook( self::get_hook_name() ); + return \update_option( Options::get_option_name( 'theme_init_status' ), 'completed' ); } }