Skip to content

Commit

Permalink
fix(Module/WPLoader) ensure active_plugins
Browse files Browse the repository at this point in the history
Depending on the set up, some plugins might deactivate, or activate,
other plugins during their activation. This ensures the plugins set in
the `plugins` configuration parameter of the `WPLoader` module will
always be loaded, no matter what other plugins might do during their
activation.
  • Loading branch information
lucatume committed Dec 9, 2024
1 parent 52a60fa commit c1c9afb
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 3 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 6 additions & 1 deletion src/Module/WPLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
<?php
/**
* Plugin Name: Test Two
*/
function test_one_loaded(){}
function test_two_loaded(){}
PHP
)) {
throw new \RuntimeException('Unable to create test plugin file for plugin test-two');
}

$this->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
<?php
/**
* Plugin Name: Test One
*/
function test_one_loaded(){}
PHP
)) {
throw new \RuntimeException('Unable to create test plugin file for plugin test-one');
Expand All @@ -89,9 +164,16 @@ function test_one_loaded(){}
<?php
/**
* Plugin Name: Test Two
* Description: During activation this plugin will clear the `active_plugins` option for reasons.
*/
function test_two_loaded(){}
function test_two_loaded(){ }
function test_two_activated(){
update_option('active_plugins', []);
}
register_activation_hook(__FILE__, 'test_two_activated');
PHP
)) {
throw new \RuntimeException('Unable to create test plugin file for plugin test-two');
Expand All @@ -117,6 +199,15 @@ static function () use ($wpLoader, $projectDir) {

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'")
);
}
);
}
Expand Down

0 comments on commit c1c9afb

Please sign in to comment.