*/ private array $features = array(); /** * Ids of the features that actually registered their hooks. * * @var string[] */ private array $booted = array(); /** * Add one or more features. A repeated id replaces the earlier entry, which * is what lets a site swap an implementation rather than only remove it. */ public function add( Feature ...$features ): self { foreach ( $features as $feature ) { $this->features[ $feature->id() ] = $feature; } return $this; } /** * Remove a feature before the registry boots. */ public function remove( string $id ): self { unset( $this->features[ $id ] ); return $this; } /** * Every registered feature, keyed by id. * * @return array */ public function all(): array { return $this->features; } /** * A single feature, or null when it is not registered. */ public function get( string $id ): ?Feature { return $this->features[ $id ] ?? null; } /** * Whether a feature is switched on, regardless of whether it can run. */ public function is_enabled( string $id ): bool { if ( ! isset( $this->features[ $id ] ) ) { return false; } /** * Filters whether a feature is switched on. * * @param bool $enabled Whether the feature should run. * @param string $id Feature identifier. */ return (bool) apply_filters( 'wpat_feature_enabled', true, $id ); } /** * Whether a feature registered its hooks in this request. */ public function is_active( string $id ): bool { return in_array( $id, $this->booted, true ); } /** * Register the hooks of every enabled, available feature. */ public function boot(): void { /** * Fires before any feature registers its hooks. * * @param Registry $registry The registry. */ do_action( 'wpat_register_features', $this ); foreach ( $this->features as $id => $feature ) { if ( ! $this->is_enabled( $id ) || ! $feature->is_available() ) { continue; } $feature->register(); $this->booted[] = $id; } } /** * A summary of every feature, for the admin and for debugging. * * @return array */ public function summary(): array { $summary = array(); foreach ( $this->features as $id => $feature ) { $summary[] = array( 'id' => $id, 'label' => $feature->label(), 'description' => $feature->description(), 'enabled' => $this->is_enabled( $id ), 'available' => $feature->is_available(), 'active' => $this->is_active( $id ), ); } return $summary; } }