*/ private array $integrations; /** @var list}>|null Available integrations with their abilities. */ private ?array $loaded = null; private bool $booted = false; public function __construct(Integration ...$integrations) { $this->integrations = array_values($integrations); } /** * Boots every Bootable integration once, in registry order – available or not: Plugin boots on plugins_loaded, * before the theme (Divi) is loaded, so isAvailable() is not known yet (as the hooks were registered before * Bootable). A second call does nothing. */ public function boot(): void { if ($this->booted) { return; } $this->booted = true; foreach ($this->integrations as $integration) { if ($integration instanceof Bootable) { $integration->boot(); } } } /** @return list */ public function available(): array { return array_values(array_filter( $this->integrations, static fn (Integration $integration): bool => $integration->isAvailable() )); } /** @return list */ public function abilities(): array { $abilities = []; foreach ($this->loaded() as [, $own]) { array_push($abilities, ...$own); } return $abilities; } /** * Abilities of the available integrations, grouped by integration id (registry order). * * @return array> */ public function grouped(): array { $groups = []; foreach ($this->loaded() as [$integration, $own]) { $groups[$integration->id()] = array_merge($groups[$integration->id()] ?? [], $own); } return $groups; } /** @return array Ability name => integration id (the ability's group). */ public function groupMap(): array { $map = []; foreach ($this->grouped() as $id => $abilities) { foreach ($abilities as $ability) { $map[$ability->name()] = $id; } } return $map; } /** @return array Integration id => label, of the available integrations. */ public function labels(): array { $labels = []; foreach ($this->loaded() as [$integration]) { $labels[$integration->id()] = $integration->label(); } return $labels; } /** @return list Ids of all known integrations, available or not. */ public function ids(): array { return array_values(array_unique(array_map( static fn (Integration $integration): string => $integration->id(), $this->integrations ))); } /** @return list}> */ private function loaded(): array { if ($this->loaded === null) { $this->loaded = array_map( static fn (Integration $integration): array => [$integration, $integration->abilities()], $this->available() ); } return $this->loaded; } }