diff --git a/CHANGELOG.md b/CHANGELOG.md index f39fd607c..dbf5b91af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [unreleased] Unreleased +### Fixed + +- Ensure plugin activation is respected indifferent of plugins that might deactivate others during activation. + ## [4.4.0] 2024-12-08; ## Added diff --git a/src/Module/WPLoader.php b/src/Module/WPLoader.php index b2034c918..eef46e7fa 100644 --- a/src/Module/WPLoader.php +++ b/src/Module/WPLoader.php @@ -1146,12 +1146,17 @@ private function activatePluginsTheme(array $plugins): array // Do not include external plugins, it would create issues at this stage. $pluginsDir = $this->getPluginsFolder(); - return array_values( + $activePlugins = array_values( array_filter( $plugins, static fn(string $plugin) => is_file($pluginsDir . "/$plugin") ) ); + + // During activation some plugins could deactivate other plugins: protect from it. + $database->updateOption('active_plugins', $activePlugins); + + return $activePlugins; } /** diff --git a/tests/unit/lucatume/WPBrowser/Module/WPLoaderArbitraryPluginLocationTest.php b/tests/unit/lucatume/WPBrowser/Module/WPLoaderArbitraryPluginLocationTest.php index b236daa47..71fa377ad 100644 --- a/tests/unit/lucatume/WPBrowser/Module/WPLoaderArbitraryPluginLocationTest.php +++ b/tests/unit/lucatume/WPBrowser/Module/WPLoaderArbitraryPluginLocationTest.php @@ -74,8 +74,83 @@ public function test_loads_plugins_from_default_location_correctly(): void /** * Plugin Name: Test One */ + +function test_one_loaded(){} +PHP + )) { + throw new \RuntimeException('Unable to create test plugin file for plugin test-one'); + } + if (!mkdir($projectDir . '/wp-content/plugins/test-two', 0777, true)) { + throw new \RuntimeException('Unable to create test directory for plugin test-two'); + } + if (!file_put_contents( + $projectDir . '/wp-content/plugins/test-two/plugin.php', + <<< PHP +config = [ + 'wpRootFolder' => $projectDir, + 'dbUrl' => $installationDb->getDbUrl(), + 'tablePrefix' => 'test_', + 'plugins' => [ + 'test-one/plugin.php', + 'test-two/plugin.php', + ] + ]; + $wpLoader = $this->module(); + $projectDirname = basename($projectDir); + + $this->assertInIsolation( + static function () use ($wpLoader, $projectDir) { + chdir($projectDir); + + $wpLoader->_initialize(); + + Assert::assertTrue(function_exists('test_one_loaded')); + Assert::assertTrue(function_exists('test_two_loaded')); + Assert::assertEquals( + ['test-one/plugin.php','test-two/plugin.php'], + get_option('active_plugins') + ); + global $wpdb; + Assert::assertEquals( + serialize(['test-one/plugin.php','test-two/plugin.php']), + $wpdb->get_var("select option_value from {$wpdb->prefix}options where option_name = 'active_plugins'") + ); + } + ); + } + + public function test_loads_plugins_and_ensures_them_loaded(): void + { + $projectDir = FS::tmpDir('wploader_'); + $installation = Installation::scaffold($projectDir); + $dbName = Random::dbName(); + $dbHost = Env::get('WORDPRESS_DB_HOST'); + $dbUser = Env::get('WORDPRESS_DB_USER'); + $dbPassword = Env::get('WORDPRESS_DB_PASSWORD'); + $installationDb = new MysqlDatabase($dbName, $dbUser, $dbPassword, $dbHost, 'wp_'); + if (!mkdir($projectDir . '/wp-content/plugins/test-one', 0777, true)) { + throw new \RuntimeException('Unable to create test directory for plugin test-one'); + } + if (!file_put_contents( + $projectDir . '/wp-content/plugins/test-one/plugin.php', + <<< PHP +get_var("select option_value from {$wpdb->prefix}options where option_name = 'active_plugins'") + ); } ); }