Skip to content

feat: folivoro/bradypophila #50

Description

@sixmonkey

feat: folivoro/bradypophila

Summary

A lightweight, standalone WordPress plugin activation library. Reads all installed WordPress plugins from vendor/composer/installed.php and activates them automatically — minus a configurable blacklist.

Works in any Composer-based WordPress setup, completely independent of Sloth. When installed in a Sloth project, the bundled BradypophiliaServiceProvider is discovered automatically.

The problem

In Composer-based WordPress setups, plugins are installed via Composer but not automatically activated. There is no simple, convention-based way to say "activate everything I installed via Composer, except these".

API

Standalone usage — any WordPress project

// Activate everything
Bradypophila::run();

// With inline config
Bradypophila::run([
    'blacklist' => [
        'wpackagist-plugin/cachify',
        'wpackagist-plugin/hello-dolly',
    ],
]);

// From a config file — clean and simple
Bradypophila::run(require __DIR__ . '/bradypophila.php');

// Via constant in wp-config.php
define('BRADYPOPHILA_BLACKLIST', 'wpackagist-plugin/cachify,wpackagist-plugin/hello-dolly');
Bradypophila::run(); // reads constant when no config passed

In functions.php

add_action('plugins_loaded', fn() => Bradypophila::run(
    require __DIR__ . '/bradypophila.php'
));

Config file

// bradypophila.php — plain PHP, no framework needed
return [
    'blacklist' => [
        'wpackagist-plugin/cachify',
    ],

    // or env-driven:
    'blacklist' => explode(',', $_ENV['PLUGINS_BLACKLIST'] ?? ''),
];

Config priority

  1. $config array passed to run() — explicit, highest priority
  2. BRADYPOPHILA_BLACKLIST constant — from wp-config.php
  3. Defaults — activate everything

How it works

Bradypophila::run() reads vendor/composer/installed.php, filters all packages with type === 'wordpress-plugin', derives the plugin slug from the package name and install path, then calls activate_plugin() for any plugin that is installed but not yet active.

// Package: wpackagist-plugin/query-monitor
// Installed to: wp-content/plugins/query-monitor/
// Slug derived: query-monitor/query-monitor.php

Slug derivation:

  1. Read install-path from composer/installed.php
  2. Find the main plugin file by convention (folder name + .php)
  3. Skip silently if no plugin file found

Sloth integration

When installed in a Sloth project, BradypophiliaServiceProvider is discovered automatically via extra.folivoro.providers in composer.json. No manual registration needed.

composer require folivoro/bradypophila

The provider publishes a plugins.php config to the app config directory:

wp sloth vendor:publish --provider="Folivoro\Bradypophila\BradypophiliaServiceProvider" --tag=config
// config/plugins.php
return [
    'blacklist' => [
        // 'wpackagist-plugin/cachify',
    ],
];

And registers a WP-CLI command:

wp sloth plugins:sync
wp sloth plugins:sync --dry-run

Architecture

folivoro/bradypophila/
├── src/
│   ├── Bradypophila.php                    # static run($config = [])
│   ├── InstalledPlugins.php                # reads vendor/composer/installed.php
│   ├── SlugResolver.php                    # derives plugin slug from package
│   ├── Config.php                          # resolves $config array + constant
│   └── BradypophiliaServiceProvider.php    # Sloth ServiceProvider
├── config/
│   └── plugins.php                         # publishable default config
└── composer.json                           # extra.folivoro.providers

composer.json

{
    "name": "folivoro/bradypophila",
    "require": {
        "php": "^8.2"
    },
    "suggest": {
        "folivoro/sloth": "Enables auto-discovery of BradypophiliaServiceProvider"
    },
    "autoload": {
        "psr-4": {
            "Folivoro\\Bradypophila\\": "src/"
        }
    },
    "extra": {
        "folivoro": {
            "providers": [
                "Folivoro\\Bradypophila\\BradypophiliaServiceProvider"
            ]
        }
    }
}

Acceptance criteria

  • Bradypophila::run() activates all Composer-installed WordPress plugins
  • Blacklist via $config array or BRADYPOPHILA_BLACKLIST constant
  • $config takes precedence over constant
  • Slug resolution works for wpackagist-plugin/*, folivoro/* and custom packages
  • Idempotent — already-active plugins are skipped silently
  • BradypophiliaServiceProvider auto-discovered in Sloth projects
  • config/plugins.php publishable via vendor:publish
  • wp sloth plugins:sync and --dry-run available in Sloth
  • No dependencies beyond PHP 8.2 for the core
  • Tests for InstalledPlugins, SlugResolver, Config

Related

  • folivoro/bradypophila-plugin — MU-Plugin wrapper with BRADYPOPHILA_AUTO flag and standalone WP-CLI command for non-Sloth projects

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    • Status
      Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions