Search by

adachsoft / plugin-discovery

Arkadiusz Adach

Discovers plugin declarations from installed Composer packages.

Package info

gitlab.com/a.adach/plugin-discovery

Issues

pkg:composer/adachsoft/plugin-discovery

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 0

v0.1.0 2026-11-06 14:14 UTC

This package is not auto-updated.

Last update: 2026-11-06 13:33:01 UTC


README

adachsoft/plugin-discovery is a domain-independent PHP library for discovering plugins declared by installed Composer packages. A caller supplies the discovery key, the plugin interface, and the IDs to disable.

The library reads vendor/composer/installed.json. It does not scan source files, instantiate plugin classes, or persist a cache; decoded package metadata is memoized only for the lifetime of a discovery instance.

Requirements

  • PHP 8.3 or later
  • Composer 2

Install the library with Composer:

composer require adachsoft/plugin-discovery

Examples

Declare plugins in a package

A plugin package declares its plugins in composer.json under the discovery key selected by the application:

{
  "extra": {
    "adachsoft/ai-image-contract": {
      "plugins": {
        "xai": "AdachSoft\\AiImageXai\\XaiImagePlugin"
      }
    }
  }
}

Each plugin ID must contain lowercase ASCII letters or digits, optionally separated by ., _, or -, and must be no longer than 64 characters. Each class must exist, implement the interface requested by the caller, be instantiable, and have no required constructor arguments.

Discover plugins

use AdachSoft\PluginDiscovery\Collection\PluginIdVoCollection;
use AdachSoft\PluginDiscovery\PluginDiscoveryFactory;
use AdachSoft\AiImageContract\ImageGeneratorPluginInterface;

$discovery = (new PluginDiscoveryFactory())->create();
$plugins = $discovery->discover(
    'adachsoft/ai-image-contract',
    ImageGeneratorPluginInterface::class,
    PluginIdVoCollection::fromStrings(['minimax']),
);

foreach ($plugins as $plugin) {
    // $plugin->id->value, $plugin->className, and $plugin->packageName are available.
}

PluginDiscoveryFactory::create() uses the first registered Composer autoloader to determine the vendor directory. Pass a vendor directory explicitly when the application needs to select a different Composer installation:

$discovery = (new PluginDiscoveryFactory())->create('/path/to/vendor');

Discovery validates declarations but does not instantiate plugin classes. The consumer is responsible for creating plugin instances.

Exceptions

All library exceptions implement PluginDiscoveryExceptionInterface.

ExceptionWhen it is thrown
InvalidPluginIdExceptionA plugin ID supplied to PluginIdVo or PluginIdVoCollection::fromStrings() is invalid.
InvalidDiscoveryQueryExceptionThe discovery key is empty or the requested interface does not exist.
ComposerMetadataNotFoundExceptionThe Composer vendor directory cannot be determined or installed.json is missing or unreadable.
InvalidComposerMetadataExceptioninstalled.json contains invalid JSON or does not use the supported Composer 2 format.
InvalidPluginDeclarationExceptionA package's plugin map, ID, or class declaration is invalid.
DuplicatePluginIdExceptionMore than one enabled package declares the same plugin ID.

Invalid plugin IDs found in package metadata are reported as InvalidPluginDeclarationException with the original InvalidPluginIdException as the previous exception. Disabled plugin IDs are skipped before class validation, so a broken plugin can be disabled without uninstalling its package. Disabled IDs that are not installed are ignored.

Limitations

  • Only packages listed in Composer 2's installed.json are searched. The root application package is not listed there, so its own plugin declarations are not discovered.
  • The functional test installs fixture packages with Composer and therefore requires the composer executable to be available in PATH.