Skip to content

[Feature Request]: Allow the activation of dependencies before package #9

Description

@meszarosrob

Is your feature request related to a problem?

When testing a plugin that depends on other plugins, such as WooCommerce, woocommerce has to be activated before the plugin itself, otherwise, an error is thrown and the process stops:

Warning: Failed to activate plugin. XXX requires 1 plugin to be installed and activated: WooCommerce. Please contact your network administrator.
Error: No plugins activated.

Currently, this is not something we support. However, since we have multiple WooCommerce payment gateways and other extensions, this won't be a one-time requirement.

Describe the desired solution

A possible solution could be to take into account the Requires Plugins field from the plugin header https://make.wordpress.org/core/2024/03/05/introducing-plugin-dependencies-in-wordpress-6-5/.

/**
 * Plugin Name: Some
 * Requires Plugins: woocommerce
 */

And have a dedicated task that would do something similar:

readonly class ActivateTestedPluginDependencies implements Task
{
    public function __construct(
        private LocalDependencyPath $packageRootPath,
        private WpCli $wpCli,
    ) {
    }

    public function execute(): void
    {
        $name = Path::getFilenameWithoutExtension($this->packageRootPath->path());

        $requiredDependencies = json_decode(
            $this->wpCli->run(['plugin', 'get', $name, '--format=json', '--field=requires_plugins']),
            true,
        );

        if ($requiredDependencies === '') {
            return;
        }

        foreach (explode(',',  $requiredDependencies) as $dependency) {
            $this->wpCli->run(['plugin', 'activate', $dependency]);
        }
    }
}

Describe the alternatives that you have considered

Currently, this can be circumvented by customizing the setup as follows:

Bootstrap::init(
    $packagePath,
    new BootstrapLifecycle(
        setup: static function (): void {
            try {
                WpTestEnv::setup();
            } catch (Throwable) {
            }

            WpTestEnv::runWpCliCommand(['plugin', 'activate', 'woocommerce']);
            ServiceLocator::retrieve(ActivateTestedPlugin::class)->execute();
        },
    ),
);

First, we need to catch the exception thrown by the missing dependency, activate the dependency (in this case, WooCommerce), and then call the activation step/task again.

Additional context

The activation of the test plugin happens automatically using ActivateTestedPlugin which is part of the "setup" phases.

https://github.com/inpsyde/wp-phpunit-integration/blob/main/src/Task/ActivateTestedPlugin.php

Setup::class => static function (ContainerInterface $container): Setup {
$contextual = (match ($container->get(PackageTypeDetector::class)->determine()) {
PackageType::Plugin => [
$container->get(SymlinkTestedPlugin::class),
$container->get(ActivateTestedPlugin::class),
],
PackageType::Theme => [
$container->get(SymlinkTestedTheme::class),
$container->get(ActivateTestedTheme::class),
],
default => []
});
return new Setup(
$container->get(CreateSqliteDbDropIn::class),
$container->get(CreateEmptyWpThemesDir::class),
$container->get(CreateWpConfig::class),
$container->get(DefineRequiredWpConstants::class),
$container->get(EnableWpDebug::class),
$container->get(InstallMultisiteWp::class),
$container->get(MaybeUpgradeCoreWp::class),
...$contextual,
);
},

We don't throw a specific exception from the CLI, so we can't differentiate between the WP-CLI activation problem and something else.

The WpCli does not return anything at this point.

public function run(array $args): void

Code of Conduct

  • I agree to follow this project's Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions