PluginManifest
Reads and validates a plugin's milpa.json manifest file. This is the primary source of plugin metadata when milpa.json exists. Falls through to #[PluginMetadata] attributes when milpa.json is absent (handled by Plugins::getMetadata()).
PluginManifest::fromPath()
public static function fromPath(string $manifestPath): selfCreate a manifest from a milpa.json file path.
Parameters
| Name | Type | Description |
|---|---|---|
| $manifestPath | string |
PluginManifest::fromArray()
public static function fromArray(array $data): selfCreate a manifest from an array (useful for scaffolding and testing).
Parameters
| Name | Type | Description |
|---|---|---|
| $data | array<string, mixed> |
PluginManifest::generateFromMetadata()
public static function generateFromMetadata(array $metadata, string $namespace, string $entrypoint, array $warnings = []): arrayGenerate a milpa.json manifest from existing #[PluginMetadata] attributes. The capability entries decide the emitted shape — the generator NEVER invents metadata: - every entry a structured record → the canonical `capabilities` block (milpa-plugin.schema.json), each record validated through core's capability value objects plus the generation-time provider check (`service` present, autoloadable, implementing the declared interface); - every entry a bare FQCN string → the legacy `contracts` block exactly as before, plus a warning in `$warnings` teaching how to reach canonical; - a mix of both shapes → hard failure: one plugin migrates atomically.
Parameters
| Name | Type | Description |
|---|---|---|
| $metadata | array{name?: string, version?: string, author?: string, site?: string, type?: string, provides?: list<(string | array<string, mixed>)>, requires?: list<(string | array<string, mixed>)>, suggests?: list<(string | array<string, mixed>)>} | |
| $namespace | string | Full namespace of the plugin class |
| $entrypoint | string | Plugin filename (e.g., "MailPlugin.php") |
| $warnings | list<string> | Reset and filled with warnings the caller should surface (legacy shape emitted) |
Returns
The manifest data ready to be saved as JSON
Throws
\InvalidArgumentException On mixed entry shapes, malformed records, or providers that do not resolve
PluginManifest::validate()
public function validate(): voidValidate the manifest. Throws on invalid data.
Throws
\InvalidArgumentException If required fields are missing or invalid
PluginManifest::toMetadataArray()
public function toMetadataArray(): arrayConvert to the metadata-array shape (`Plugins::$plugins`) that some consumers still read instead of the typed accessors below. The capability lists carry the RAW declarations of whichever shape the manifest speaks — canonical `capabilities.*` records or legacy `contracts.*` bare FQCNs (see {@see rawCapabilityRecords()}) — because this array feeds the host boot path, whose ingestion ({@see \Milpa\Attributes\PluginMetadata} -> AttributeLoader) accepts both shapes. Reading only `contracts.*` here would blind the boot to every canonical manifest (the Cosecha T2-Major finding).
PluginManifest::getName()
public function getName(): stringVendor/package name (e.g., "acme/mail-plugin").
PluginManifest::getDisplayName()
public function getDisplayName(): stringHuman-readable display name (e.g., "Mail Plugin").
PluginManifest::getDescription()
public function getDescription(): stringShort human-readable summary of what the plugin does.
PluginManifest::getVersion()
public function getVersion(): Milpa\ValueObjects\SemanticVersionPluginManifest::getType()
public function getType(): stringPlugin type: Web, CLI, Mixed, Service.
PluginManifest::getNamespace()
public function getNamespace(): stringPHP namespace (e.g., "Acme\Plugins\ExamplePlugin").
PluginManifest::getEntrypoint()
public function getEntrypoint(): stringMain plugin file relative to plugin directory (e.g., "ExamplePlugin.php").
PluginManifest::getProvides()
public function getProvides(): arrayThe interfaces/services this plugin provides to the capability system.
PluginManifest::getRequires()
public function getRequires(): arrayThe interfaces/services this plugin cannot boot without.
PluginManifest::getSuggests()
public function getSuggests(): arrayThe interfaces/services this plugin can use if available but does not strictly need.
PluginManifest::getProvidedCapabilities()
public function getProvidedCapabilities(): arrayTyped `provides` capability records (D7 wiring seam). Reads the canonical `capabilities.provides` key, falling back to legacy `contracts.provides`, and accepts both record arrays and legacy bare-FQCN strings.
PluginManifest::getRequiredCapabilities()
public function getRequiredCapabilities(): arrayTyped `requires` capability records (D7 wiring seam).
PluginManifest::getSuggestedCapabilities()
public function getSuggestedCapabilities(): arrayTyped `suggests` capability records (D7 wiring seam).
PluginManifest::getComposerDependencies()
public function getComposerDependencies(): arrayComposer packages this plugin depends on, beyond the framework itself.
PluginManifest::getPluginDependencies()
public function getPluginDependencies(): arrayOther Milpa plugins this plugin depends on.
PluginManifest::getMinMilpaVersion()
public function getMinMilpaVersion(): ?stringThe minimum Milpa framework version this plugin requires, or null if unconstrained.
PluginManifest::getPhpVersion()
public function getPhpVersion(): ?stringThe PHP version constraint this plugin requires (e.g. ">=8.2"), or null if unconstrained.
PluginManifest::getEnvVars()
public function getEnvVars(): arrayEnvironment variable names the plugin expects to be set.
PluginManifest::getMigrationsDirectory()
public function getMigrationsDirectory(): ?stringMigrations directory name relative to plugin root (e.g., "Migrations").
PluginManifest::getAuthors()
public function getAuthors(): arrayThe plugin's declared authors.
PluginManifest::getRawData()
public function getRawData(): arrayPluginManifest::toJson()
public function toJson(): stringSerialize the manifest data to JSON string for writing to disk.