edition). * * @var array */ public readonly array $features; /** * Ids of apps that must be active first. * * @var string[] */ public readonly array $dependencies; /** * Plain-language consequences of deactivating, shown before the user confirms. * * @var string[] */ public readonly array $deactivation_effects; /** * Builds the app instance. * * @var \Closure(Container): AppInterface */ private \Closure $factory; /** * Creates a definition. * * @param array $args Definition fields. * @phpstan-param array{id: string, name: string, description?: string, category?: string, edition?: string, features?: array, dependencies?: string[], deactivation_effects?: string[], factory: \Closure(Container): AppInterface} $args * @throws \InvalidArgumentException On an invalid id or edition. */ public function __construct( array $args ) { if ( 1 !== preg_match( '/^[a-z0-9_-]{2,64}$/', $args['id'] ) ) { throw new \InvalidArgumentException( esc_html( sprintf( 'Invalid app id "%s".', $args['id'] ) ) ); } $edition = $args['edition'] ?? Edition::FREE; if ( ! Edition::is_valid( $edition ) ) { throw new \InvalidArgumentException( esc_html( sprintf( 'Invalid edition "%s" for app "%s".', $edition, $args['id'] ) ) ); } $this->id = $args['id']; $this->name = $args['name']; $this->description = $args['description'] ?? ''; $this->category = $args['category'] ?? 'tools'; $this->edition = $edition; $this->features = $args['features'] ?? array(); $this->dependencies = array_values( $args['dependencies'] ?? array() ); $this->deactivation_effects = array_values( $args['deactivation_effects'] ?? array() ); $this->factory = $args['factory']; } /** * Builds a new app instance. * * @param Container $container Service container. */ public function create( Container $container ): AppInterface { return ( $this->factory )( $container ); } }