From 4ee7ea28f3e3b244a6189417114d750b7eeac3d8 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Thu, 5 Sep 2024 10:41:10 +0200 Subject: [PATCH 1/8] Improve `active_plugins` filter --- .../Force_Single_Plugin_Preparation.php | 78 ++++++++++++------- 1 file changed, 52 insertions(+), 26 deletions(-) diff --git a/includes/Checker/Preparations/Force_Single_Plugin_Preparation.php b/includes/Checker/Preparations/Force_Single_Plugin_Preparation.php index e3dc76b89..51aa18d9c 100644 --- a/includes/Checker/Preparations/Force_Single_Plugin_Preparation.php +++ b/includes/Checker/Preparations/Force_Single_Plugin_Preparation.php @@ -9,6 +9,7 @@ use Exception; use WordPress\Plugin_Check\Checker\Preparation; +use WP_Plugin_Dependencies; /** * Class for the preparation to force the plugin to be checked as the only active plugin. @@ -20,7 +21,7 @@ class Force_Single_Plugin_Preparation implements Preparation { /** - * Plugin slug. + * Plugin slug of the plugin to check. * * @since 1.0.0 * @var string @@ -74,39 +75,64 @@ public function prepare() { } /** - * Filter active plugins. + * Filters active plugins to only include required ones. + * + * This means: + * + * * The plugin being tested + * * All dependencies of the plugin being tested + * * Plugin Check itself + * * All plugins depending on Plugin Check (they could be adding new checks) * * @since 1.0.0 * - * @param array $active_plugins List of active plugins. - * @return array List of active plugins. + * @param mixed $active_plugins List of active plugins. + * @return mixed List of active plugins. */ public function filter_active_plugins( $active_plugins ) { - if ( is_array( $active_plugins ) && in_array( $this->plugin_basename, $active_plugins, true ) ) { - - if ( defined( 'WP_PLUGIN_CHECK_MAIN_FILE' ) ) { - $plugin_check_file = WP_PLUGIN_CHECK_MAIN_FILE; - } else { - $plugins_dir = defined( 'WP_PLUGIN_DIR' ) ? WP_PLUGIN_DIR : WP_CONTENT_DIR . '/plugins'; - $plugin_check_file = $plugins_dir . '/plugin-check/plugin.php'; - } - - $plugin_base_file = plugin_basename( $plugin_check_file ); - - // If the plugin-check is the only available plugin then return that one only. - if ( $this->plugin_basename === $plugin_base_file ) { + if ( ! is_array( $active_plugins ) ) { + return $active_plugins; + } - return array( - $plugin_base_file, - ); - } + // The plugin being tested isn't actually active yet. + if ( ! in_array( $this->plugin_basename, $active_plugins, true ) ) { + return $active_plugins; + } - return array( - $this->plugin_basename, - $plugin_base_file, - ); + if ( defined( 'WP_PLUGIN_CHECK_MAIN_FILE' ) ) { + $plugin_check_file = WP_PLUGIN_CHECK_MAIN_FILE; + } else { + $plugins_dir = defined( 'WP_PLUGIN_DIR' ) ? WP_PLUGIN_DIR : WP_CONTENT_DIR . '/plugins'; + $plugin_check_file = $plugins_dir . '/plugin-check/plugin.php'; } - return $active_plugins; + $plugin_check_basename = plugin_basename( $plugin_check_file ); + + $new_active_plugins = array( + $this->plugin_basename, // Plugin to test. + $plugin_check_basename, // Plugin Check itself. + ); + + WP_Plugin_Dependencies::initialize(); + + $new_active_plugins = array_merge( + $new_active_plugins, + WP_Plugin_Dependencies::get_dependencies( $this->plugin_basename ) + ); + + $new_active_plugins = array_merge( + $new_active_plugins, + // Include any dependents of Plugin Check, but only if they were already active. + array_filter( + WP_Plugin_Dependencies::get_dependents( dirname( $plugin_check_basename ) ), + static function ( $dependent ) use ( $active_plugins, $new_active_plugins ) { + return in_array( $dependent, $active_plugins, true ) || + in_array( $dependent, $new_active_plugins, true ); + } + ) + ); + + // Removes duplicates, for example if Plugin Check is the plugin being tested. + return array_unique( $new_active_plugins ); } } From 6fc79d986e4e172fa73ee2f5c6438e22c0197040 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Thu, 5 Sep 2024 13:27:18 +0200 Subject: [PATCH 2/8] Add `class_exists` check --- .../Force_Single_Plugin_Preparation.php | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/includes/Checker/Preparations/Force_Single_Plugin_Preparation.php b/includes/Checker/Preparations/Force_Single_Plugin_Preparation.php index 51aa18d9c..212aa44f3 100644 --- a/includes/Checker/Preparations/Force_Single_Plugin_Preparation.php +++ b/includes/Checker/Preparations/Force_Single_Plugin_Preparation.php @@ -113,24 +113,27 @@ public function filter_active_plugins( $active_plugins ) { $plugin_check_basename, // Plugin Check itself. ); - WP_Plugin_Dependencies::initialize(); + // Plugin dependencies support was added in WordPress 6.5. + if ( class_exists( 'WP_Plugin_Dependencies' ) ) { + WP_Plugin_Dependencies::initialize(); - $new_active_plugins = array_merge( - $new_active_plugins, - WP_Plugin_Dependencies::get_dependencies( $this->plugin_basename ) - ); + $new_active_plugins = array_merge( + $new_active_plugins, + WP_Plugin_Dependencies::get_dependencies( $this->plugin_basename ) + ); - $new_active_plugins = array_merge( - $new_active_plugins, - // Include any dependents of Plugin Check, but only if they were already active. - array_filter( - WP_Plugin_Dependencies::get_dependents( dirname( $plugin_check_basename ) ), - static function ( $dependent ) use ( $active_plugins, $new_active_plugins ) { - return in_array( $dependent, $active_plugins, true ) || - in_array( $dependent, $new_active_plugins, true ); - } - ) - ); + $new_active_plugins = array_merge( + $new_active_plugins, + // Include any dependents of Plugin Check, but only if they were already active. + array_filter( + WP_Plugin_Dependencies::get_dependents( dirname( $plugin_check_basename ) ), + static function ( $dependent ) use ( $active_plugins, $new_active_plugins ) { + return in_array( $dependent, $active_plugins, true ) || + in_array( $dependent, $new_active_plugins, true ); + } + ) + ); + } // Removes duplicates, for example if Plugin Check is the plugin being tested. return array_unique( $new_active_plugins ); From 19375f40a3d3847772536dd828c168bc68e6519e Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Thu, 5 Sep 2024 17:34:01 +0200 Subject: [PATCH 3/8] Test a plugin with a dependency --- tests/behat/features/plugin-check.feature | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/tests/behat/features/plugin-check.feature b/tests/behat/features/plugin-check.feature index 36c91d0fb..b4db039fc 100644 --- a/tests/behat/features/plugin-check.feature +++ b/tests/behat/features/plugin-check.feature @@ -440,6 +440,20 @@ Feature: Test that the WP-CLI command works. Given a WP install with the Plugin Check plugin And a Plugin Check add-on being installed + And a wp-content/plugins/foo-dependency/foo-dependency.php file: + """ + Date: Thu, 5 Sep 2024 17:37:00 +0200 Subject: [PATCH 4/8] Add changelog note --- .../Checker/Preparations/Force_Single_Plugin_Preparation.php | 1 + 1 file changed, 1 insertion(+) diff --git a/includes/Checker/Preparations/Force_Single_Plugin_Preparation.php b/includes/Checker/Preparations/Force_Single_Plugin_Preparation.php index 212aa44f3..17348a625 100644 --- a/includes/Checker/Preparations/Force_Single_Plugin_Preparation.php +++ b/includes/Checker/Preparations/Force_Single_Plugin_Preparation.php @@ -85,6 +85,7 @@ public function prepare() { * * All plugins depending on Plugin Check (they could be adding new checks) * * @since 1.0.0 + * @since 1.2.0 Now includes dependencies and dependents. * * @param mixed $active_plugins List of active plugins. * @return mixed List of active plugins. From 1ea158cb8e3c8a2386438450c24a50b088c0c09d Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Thu, 5 Sep 2024 17:37:07 +0200 Subject: [PATCH 5/8] Simplify `in_array` check --- .../Checker/Preparations/Force_Single_Plugin_Preparation.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/includes/Checker/Preparations/Force_Single_Plugin_Preparation.php b/includes/Checker/Preparations/Force_Single_Plugin_Preparation.php index 17348a625..e3e5823b9 100644 --- a/includes/Checker/Preparations/Force_Single_Plugin_Preparation.php +++ b/includes/Checker/Preparations/Force_Single_Plugin_Preparation.php @@ -129,8 +129,7 @@ public function filter_active_plugins( $active_plugins ) { array_filter( WP_Plugin_Dependencies::get_dependents( dirname( $plugin_check_basename ) ), static function ( $dependent ) use ( $active_plugins, $new_active_plugins ) { - return in_array( $dependent, $active_plugins, true ) || - in_array( $dependent, $new_active_plugins, true ); + return in_array( $dependent, $active_plugins, true ); } ) ); From 325f7216ac7cf1a188bebde3315d085f1dc82fcb Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Thu, 5 Sep 2024 17:41:50 +0200 Subject: [PATCH 6/8] Improve CLI error handling when check doesn't exist --- includes/Checker/Abstract_Check_Runner.php | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/includes/Checker/Abstract_Check_Runner.php b/includes/Checker/Abstract_Check_Runner.php index 2d5e8a053..b52db568f 100644 --- a/includes/Checker/Abstract_Check_Runner.php +++ b/includes/Checker/Abstract_Check_Runner.php @@ -10,6 +10,7 @@ use Exception; use WordPress\Plugin_Check\Checker\Preparations\Universal_Runtime_Preparation; use WordPress\Plugin_Check\Utilities\Plugin_Request_Utility; +use WP_CLI; /** * Abstract Check Runner class. @@ -293,9 +294,17 @@ final public function set_categories( $categories ) { final public function prepare() { $cleanup_functions = array(); - if ( $this->has_runtime_check( $this->get_checks_to_run() ) ) { - $preparation = new Universal_Runtime_Preparation( $this->get_check_context() ); - $cleanup_functions[] = $preparation->prepare(); + try { + if ( $this->has_runtime_check( $this->get_checks_to_run() ) ) { + $preparation = new Universal_Runtime_Preparation( $this->get_check_context() ); + $cleanup_functions[] = $preparation->prepare(); + } + } catch ( Exception $error ) { + if ( defined( 'WP_CLI' ) && WP_CLI ) { + WP_CLI::error( $error->getMessage() ); + } else { + throw $error; + } } if ( $this->delete_plugin_folder ) { From e4a3c6ab529231145e13b82a2615d1dcc5891927 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Thu, 5 Sep 2024 17:42:23 +0200 Subject: [PATCH 7/8] Simply use `dirname` --- .../Checker/Preparations/Force_Single_Plugin_Preparation.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/includes/Checker/Preparations/Force_Single_Plugin_Preparation.php b/includes/Checker/Preparations/Force_Single_Plugin_Preparation.php index e3e5823b9..92648cc90 100644 --- a/includes/Checker/Preparations/Force_Single_Plugin_Preparation.php +++ b/includes/Checker/Preparations/Force_Single_Plugin_Preparation.php @@ -103,8 +103,7 @@ public function filter_active_plugins( $active_plugins ) { if ( defined( 'WP_PLUGIN_CHECK_MAIN_FILE' ) ) { $plugin_check_file = WP_PLUGIN_CHECK_MAIN_FILE; } else { - $plugins_dir = defined( 'WP_PLUGIN_DIR' ) ? WP_PLUGIN_DIR : WP_CONTENT_DIR . '/plugins'; - $plugin_check_file = $plugins_dir . '/plugin-check/plugin.php'; + $plugin_check_file = basename( dirname( __DIR__, 3 ) ) . '/plugin.php'; } $plugin_check_basename = plugin_basename( $plugin_check_file ); From 106767c4efffd278b037d5a608b393516fb18f68 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Thu, 5 Sep 2024 18:15:23 +0200 Subject: [PATCH 8/8] Remove unused var --- .../Checker/Preparations/Force_Single_Plugin_Preparation.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/Checker/Preparations/Force_Single_Plugin_Preparation.php b/includes/Checker/Preparations/Force_Single_Plugin_Preparation.php index 92648cc90..cd06e06ad 100644 --- a/includes/Checker/Preparations/Force_Single_Plugin_Preparation.php +++ b/includes/Checker/Preparations/Force_Single_Plugin_Preparation.php @@ -127,7 +127,7 @@ public function filter_active_plugins( $active_plugins ) { // Include any dependents of Plugin Check, but only if they were already active. array_filter( WP_Plugin_Dependencies::get_dependents( dirname( $plugin_check_basename ) ), - static function ( $dependent ) use ( $active_plugins, $new_active_plugins ) { + static function ( $dependent ) use ( $active_plugins ) { return in_array( $dependent, $active_plugins, true ); } )