diff --git a/includes/Checker/Preparations/Force_Single_Plugin_Preparation.php b/includes/Checker/Preparations/Force_Single_Plugin_Preparation.php new file mode 100644 index 000000000..5041b283d --- /dev/null +++ b/includes/Checker/Preparations/Force_Single_Plugin_Preparation.php @@ -0,0 +1,103 @@ +plugin_basename = $plugin_basename; + } + + /** + * Runs this preparation step for the environment and returns a cleanup function. + * + * @since n.e.x.t + * + * @return callable Cleanup function to revert any changes made here. + * + * @throws Exception Thrown when preparation fails. + */ + public function prepare() { + $valid_plugin = validate_plugin( $this->plugin_basename ); + + // Check if the plugin exists. + if ( is_wp_error( $valid_plugin ) ) { + + throw new Exception( + sprintf( + /* translators: 1: plugin basename, 2: error message */ + __( 'Invalid plugin %1$s: %2$s', 'plugin-check' ), + $this->plugin_basename, + $valid_plugin->get_error_message() + ) + ); + } + + add_filter( 'option_active_plugins', array( $this, 'filter_active_plugins' ) ); + add_filter( 'default_option_active_plugins', array( $this, 'filter_active_plugins' ) ); + + // Return the cleanup function. + return function() { + remove_filter( 'option_active_plugins', array( $this, 'filter_active_plugins' ) ); + remove_filter( 'default_option_active_plugins', array( $this, 'filter_active_plugins' ) ); + }; + } + + /** + * Filter active plugins. + * + * @param array $active_plugins List of active plugins. + * @return array List of active plugins. + */ + public function filter_active_plugins( $active_plugins ) { + if ( is_array( $active_plugins ) && in_array( $this->plugin_basename, $active_plugins, true ) ) { + + $plugin_base_file = plugin_basename( WP_PLUGIN_CHECK_MAIN_FILE ); + + // If the plugin-check is the only available plugin then return that one only. + if ( $this->plugin_basename === $plugin_base_file ) { + + return array( + $plugin_base_file, + ); + } + + return array( + $this->plugin_basename, + $plugin_base_file, + ); + } + + return $active_plugins; + } +} diff --git a/plugin-check.php b/plugin-check.php index 685f752e5..5c31b12b2 100644 --- a/plugin-check.php +++ b/plugin-check.php @@ -17,7 +17,8 @@ define( 'WP_PLUGIN_CHECK_VERSION', 'n.e.x.t' ); define( 'WP_PLUGIN_CHECK_MINIMUM_PHP', '5.6' ); -define( 'WP_PLUGIN_CHECK_PLUGIN_DIR_PATH', plugin_dir_path( __FILE__ ) ); +define( 'WP_PLUGIN_CHECK_MAIN_FILE', __FILE__ ); +define( 'WP_PLUGIN_CHECK_PLUGIN_DIR_PATH', plugin_dir_path( WP_PLUGIN_CHECK_MAIN_FILE ) ); /** * Checks basic requirements and loads the plugin. @@ -42,7 +43,7 @@ function wp_plugin_check_load() { // Setup the plugin. $class_name = 'WordPress\\Plugin_Check\\Plugin_Main'; - $instance = new $class_name( __FILE__ ); + $instance = new $class_name( WP_PLUGIN_CHECK_MAIN_FILE ); $instance->add_hooks(); } diff --git a/tests/Checker/Check_Context_Tests.php b/tests/Checker/Check_Context_Tests.php index 1dfff4926..a5c893bdc 100644 --- a/tests/Checker/Check_Context_Tests.php +++ b/tests/Checker/Check_Context_Tests.php @@ -12,11 +12,11 @@ public function set_up() { parent::set_up(); $this->plugin_name = basename( TESTS_PLUGIN_DIR ); - $this->check_context = new Check_Context( WP_PLUGIN_DIR . '/' . $this->plugin_name . '/plugin-check.php' ); + $this->check_context = new Check_Context( WP_PLUGIN_CHECK_MAIN_FILE ); } public function test_basename() { - $this->assertSame( $this->plugin_name . '/plugin-check.php', $this->check_context->basename() ); + $this->assertSame( plugin_basename( WP_PLUGIN_CHECK_MAIN_FILE ), $this->check_context->basename() ); } public function test_path() { diff --git a/tests/Checker/Preparations/Force_Single_Plugin_Preparation_Tests.php b/tests/Checker/Preparations/Force_Single_Plugin_Preparation_Tests.php new file mode 100644 index 000000000..52b7aa843 --- /dev/null +++ b/tests/Checker/Preparations/Force_Single_Plugin_Preparation_Tests.php @@ -0,0 +1,88 @@ +plugin_basename_file = plugin_basename( WP_PLUGIN_CHECK_MAIN_FILE ); + } + + public function test_prepare_plugin_exists() { + + $preparation = new Force_Single_Plugin_Preparation( 'akismet/akismet.php' ); + + $this->expectException( 'Exception' ); + $this->expectExceptionMessage( 'Invalid plugin akismet/akismet.php: Plugin file does not exist.' ); + $preparation->prepare(); + } + + /** + * @throws Exception Throw exception. + */ + public function test_prepare() { + // Remove the WP tests active plugins filter which interfers with this test. + remove_filter( 'pre_option_active_plugins', 'wp_tests_options' ); + + $preparation = new Force_Single_Plugin_Preparation( $this->plugin_basename_file ); + $active_plugins = array( + 'akismet/akismet.php', + $this->plugin_basename_file, + 'wp-reset/wp-reset.php', + ); + + update_option( 'active_plugins', $active_plugins ); + + $cleanup = $preparation->prepare(); + $before = get_option( 'active_plugins' ); + $cleanup(); + $after = get_option( 'active_plugins' ); + + $this->assertSame( array( $this->plugin_basename_file ), $before ); + $this->assertSame( $active_plugins, $after ); + } + + public function test_filter_active_plugins() { + + $preparation = new Force_Single_Plugin_Preparation( 'wp-reset/wp-reset.php' ); + + $plugins = array( + 'akismet/akismet.php', + $this->plugin_basename_file, + 'wp-reset/wp-reset.php', + ); + + $active_plugins = $preparation->filter_active_plugins( $plugins ); + + $this->assertSame( + array( + 'wp-reset/wp-reset.php', + $this->plugin_basename_file, + ), + $active_plugins + ); + + $plugins = array( + 'akismet/akismet.php', + $this->plugin_basename_file, + 'test-plugin/test-plugin.php', + ); + + $active_plugins = $preparation->filter_active_plugins( $plugins ); + + $this->assertSame( $plugins, $active_plugins ); + } +} diff --git a/tests/Plugin_Context_Tests.php b/tests/Plugin_Context_Tests.php index 74f8b1975..3a865d59c 100644 --- a/tests/Plugin_Context_Tests.php +++ b/tests/Plugin_Context_Tests.php @@ -12,11 +12,11 @@ public function set_up() { parent::set_up(); $this->plugin_name = basename( TESTS_PLUGIN_DIR ); - $this->plugin_context = new Plugin_Context( WP_PLUGIN_DIR . '/' . $this->plugin_name . '/plugin-check.php' ); + $this->plugin_context = new Plugin_Context( WP_PLUGIN_CHECK_MAIN_FILE ); } public function test_basename() { - $this->assertSame( $this->plugin_name . '/plugin-check.php', $this->plugin_context->basename() ); + $this->assertSame( plugin_basename( WP_PLUGIN_CHECK_MAIN_FILE ), $this->plugin_context->basename() ); } public function test_path() { diff --git a/tests/Plugin_Main_Tests.php b/tests/Plugin_Main_Tests.php index 79f472541..755421dac 100644 --- a/tests/Plugin_Main_Tests.php +++ b/tests/Plugin_Main_Tests.php @@ -12,7 +12,7 @@ class Plugin_Main_Tests extends WP_UnitTestCase { public function set_up() { parent::set_up(); - $this->plugin_main = new Plugin_Main( basename( dirname( __DIR__ ) ) . '/plugin-check.php' ); + $this->plugin_main = new Plugin_Main( WP_PLUGIN_CHECK_MAIN_FILE ); } public function test_context() {