Skip to content
This repository was archived by the owner on Feb 5, 2026. It is now read-only.

Commit 118c476

Browse files
gziolojustlevineemdashcodes
authored
Refactor the usage of $properties param to $args to align with WordPress usage (#59)
* dev: replace `WP_Ability::validate_properties()` with `::prepare_args()` * Rename properties to args in `WP_Ability` * Improve coding style according to conventions * Update since version * Fix coding style issue reported in WP core * Ensure there are no deprecation warning in PHP 8.3+ * Update version to account for the API changes applied --------- Co-authored-by: Dovid Levine <david@axepress.dev> Co-authored-by: justlevine <justlevine@git.wordpress.org> Co-authored-by: gziolo <gziolo@git.wordpress.org> Co-authored-by: emdashcodes <emdashcodes@git.wordpress.org>
1 parent 21af812 commit 118c476

7 files changed

Lines changed: 189 additions & 190 deletions

File tree

abilities-api.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* Plugin URI: https://github.com/WordPress/abilities-api
1313
* Description: Provides a framework for registering and executing AI abilities in WordPress.
1414
* Requires at least: 6.8
15-
* Version: 0.1.0
15+
* Version: 0.2.0
1616
* Requires PHP: 7.2
1717
* Author: WordPress.org Contributors
1818
* Author URI: https://github.com/WordPress/abilities-api/graphs/contributors

includes/abilities-api.php

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@
2222
*
2323
* @see WP_Abilities_Registry::register()
2424
*
25-
* @param string $name The name of the ability. The name must be a string containing a namespace
26-
* prefix, i.e. `my-plugin/my-ability`. It can only contain lowercase
27-
* alphanumeric characters, dashes and the forward slash.
28-
* @param array<string,mixed> $properties An associative array of properties for the ability. This should include
29-
* `label`, `description`, `input_schema`, `output_schema`, `execute_callback`,
30-
* `permission_callback`, `meta`, and `ability_class`.
25+
* @param string $name The name of the ability. The name must be a string containing a namespace
26+
* prefix, i.e. `my-plugin/my-ability`. It can only contain lowercase
27+
* alphanumeric characters, dashes and the forward slash.
28+
* @param array<string,mixed> $args An associative array of arguments for the ability. This should include
29+
* `label`, `description`, `input_schema`, `output_schema`, `execute_callback`,
30+
* `permission_callback`, `meta`, and `ability_class`.
3131
* @return ?\WP_Ability An instance of registered ability on success, null on failure.
3232
*
3333
* @phpstan-param array{
@@ -40,9 +40,9 @@
4040
* meta?: array<string,mixed>,
4141
* ability_class?: class-string<\WP_Ability>,
4242
* ...<string, mixed>
43-
* } $properties
43+
* } $args
4444
*/
45-
function wp_register_ability( string $name, array $properties = array() ): ?WP_Ability {
45+
function wp_register_ability( string $name, array $args ): ?WP_Ability {
4646
if ( ! did_action( 'abilities_api_init' ) ) {
4747
_doing_it_wrong(
4848
__FUNCTION__,
@@ -57,7 +57,7 @@ function wp_register_ability( string $name, array $properties = array() ): ?WP_A
5757
return null;
5858
}
5959

60-
return WP_Abilities_Registry::get_instance()->register( $name, $properties );
60+
return WP_Abilities_Registry::get_instance()->register( $name, $args );
6161
}
6262

6363
/**

includes/abilities-api/class-wp-abilities-registry.php

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,12 @@ final class WP_Abilities_Registry {
4343
*
4444
* @see wp_register_ability()
4545
*
46-
* @param string $name The name of the ability. The name must be a string containing a namespace
47-
* prefix, i.e. `my-plugin/my-ability`. It can only contain lowercase
48-
* alphanumeric characters, dashes and the forward slash.
49-
* @param array<string,mixed> $properties An associative array of properties for the ability. This should include
50-
* `label`, `description`, `input_schema`, `output_schema`,
51-
* `execute_callback`, `permission_callback`, `meta`, and ability_class.
46+
* @param string $name The name of the ability. The name must be a string containing a namespace
47+
* prefix, i.e. `my-plugin/my-ability`. It can only contain lowercase
48+
* alphanumeric characters, dashes and the forward slash.
49+
* @param array<string,mixed> $args An associative array of arguments for the ability. This should include
50+
* `label`, `description`, `input_schema`, `output_schema`,
51+
* `execute_callback`, `permission_callback`, `meta`, and ability_class.
5252
* @return ?\WP_Ability The registered ability instance on success, null on failure.
5353
*
5454
* @phpstan-param array{
@@ -61,9 +61,9 @@ final class WP_Abilities_Registry {
6161
* meta?: array<string,mixed>,
6262
* ability_class?: class-string<\WP_Ability>,
6363
* ...<string, mixed>
64-
* } $properties
64+
* } $args
6565
*/
66-
public function register( string $name, array $properties = array() ): ?WP_Ability {
66+
public function register( string $name, array $args ): ?WP_Ability {
6767
if ( ! preg_match( '/^[a-z0-9-]+\/[a-z0-9-]+$/', $name ) ) {
6868
_doing_it_wrong(
6969
__METHOD__,
@@ -86,23 +86,20 @@ public function register( string $name, array $properties = array() ): ?WP_Abili
8686
}
8787

8888
// The class is only used to instantiate the ability, and is not a property of the ability itself.
89-
if ( isset( $properties['ability_class'] ) && ! is_a( $properties['ability_class'], WP_Ability::class, true ) ) {
89+
if ( isset( $args['ability_class'] ) && ! is_a( $args['ability_class'], WP_Ability::class, true ) ) {
9090
_doing_it_wrong(
9191
__METHOD__,
92-
esc_html__( 'The ability properties should provide a valid `ability_class` that extends WP_Ability.' ),
92+
esc_html__( 'The ability args should provide a valid `ability_class` that extends WP_Ability.' ),
9393
'0.1.0'
9494
);
9595
return null;
9696
}
97-
$ability_class = $properties['ability_class'] ?? WP_Ability::class;
98-
unset( $properties['ability_class'] );
97+
$ability_class = $args['ability_class'] ?? WP_Ability::class;
98+
unset( $args['ability_class'] );
9999

100100
try {
101-
// WP_Ability::validate_properties() will throw an exception if the properties are invalid.
102-
$ability = new $ability_class(
103-
$name,
104-
$properties
105-
);
101+
// WP_Ability::prepare_properties() will throw an exception if the properties are invalid.
102+
$ability = new $ability_class( $name, $args );
106103
} catch ( \InvalidArgumentException $e ) {
107104
_doing_it_wrong(
108105
__METHOD__,

includes/abilities-api/class-wp-ability.php

Lines changed: 77 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -96,15 +96,15 @@ class WP_Ability {
9696
*
9797
* @see wp_register_ability()
9898
*
99-
* @param string $name The name of the ability, with its namespace.
100-
* @param array<string,mixed> $properties An associative array of properties for the ability. This should
101-
* include `label`, `description`, `input_schema`, `output_schema`,
102-
* `execute_callback`, `permission_callback`, and `meta`.
99+
* @param string $name The name of the ability, with its namespace.
100+
* @param array<string,mixed> $args An associative array of arguments for the ability. This should
101+
* include `label`, `description`, `input_schema`, `output_schema`,
102+
* `execute_callback`, `permission_callback`, and `meta`.
103103
*/
104-
public function __construct( string $name, array $properties ) {
104+
public function __construct( string $name, array $args ) {
105105
$this->name = $name;
106106

107-
$this->validate_properties( $properties );
107+
$properties = $this->prepare_properties( $args );
108108

109109
foreach ( $properties as $property_name => $property_value ) {
110110
if ( ! property_exists( $this, $property_name ) ) {
@@ -126,6 +126,77 @@ public function __construct( string $name, array $properties ) {
126126
}
127127
}
128128

129+
/**
130+
* Prepares and validates the properties used to instantiate the ability.
131+
*
132+
* Errors are thrown as exceptions instead of \WP_Errors to allow for simpler handling and overloading. They are then
133+
* caught and converted to a WP_Error when by WP_Abilities_Registry::register().
134+
*
135+
* @since 0.2.0
136+
*
137+
* @see WP_Abilities_Registry::register()
138+
*
139+
* @param array<string,mixed> $args An associative array of arguments used to instantiate the class.
140+
* @return array<string,mixed> The validated and prepared properties.
141+
* @throws \InvalidArgumentException if an argument is invalid.
142+
*
143+
* @phpstan-return array{
144+
* label: string,
145+
* description: string,
146+
* input_schema?: array<string,mixed>,
147+
* output_schema?: array<string,mixed>,
148+
* execute_callback: callable( array<string,mixed> $input): (mixed|\WP_Error),
149+
* permission_callback?: ?callable( array<string,mixed> $input ): (bool|\WP_Error),
150+
* meta?: array<string,mixed>,
151+
* ...<string, mixed>,
152+
* } $args
153+
*/
154+
protected function prepare_properties( array $args ): array {
155+
if ( empty( $args['label'] ) || ! is_string( $args['label'] ) ) {
156+
throw new \InvalidArgumentException(
157+
esc_html__( 'The ability properties must contain a `label` string.' )
158+
);
159+
}
160+
161+
if ( empty( $args['description'] ) || ! is_string( $args['description'] ) ) {
162+
throw new \InvalidArgumentException(
163+
esc_html__( 'The ability properties must contain a `description` string.' )
164+
);
165+
}
166+
167+
if ( isset( $args['input_schema'] ) && ! is_array( $args['input_schema'] ) ) {
168+
throw new \InvalidArgumentException(
169+
esc_html__( 'The ability properties should provide a valid `input_schema` definition.' )
170+
);
171+
}
172+
173+
if ( isset( $args['output_schema'] ) && ! is_array( $args['output_schema'] ) ) {
174+
throw new \InvalidArgumentException(
175+
esc_html__( 'The ability properties should provide a valid `output_schema` definition.' )
176+
);
177+
}
178+
179+
if ( empty( $args['execute_callback'] ) || ! is_callable( $args['execute_callback'] ) ) {
180+
throw new \InvalidArgumentException(
181+
esc_html__( 'The ability properties must contain a valid `execute_callback` function.' )
182+
);
183+
}
184+
185+
if ( isset( $args['permission_callback'] ) && ! is_callable( $args['permission_callback'] ) ) {
186+
throw new \InvalidArgumentException(
187+
esc_html__( 'The ability properties should provide a valid `permission_callback` function.' )
188+
);
189+
}
190+
191+
if ( isset( $args['meta'] ) && ! is_array( $args['meta'] ) ) {
192+
throw new \InvalidArgumentException(
193+
esc_html__( 'The ability properties should provide a valid `meta` array.' )
194+
);
195+
}
196+
197+
return $args;
198+
}
199+
129200
/**
130201
* Retrieves the name of the ability, with its namespace.
131202
* Example: `my-plugin/my-ability`.
@@ -193,76 +264,6 @@ public function get_meta(): array {
193264
return $this->meta;
194265
}
195266

196-
/**
197-
* Validates the properties used to instantiate the ability.
198-
*
199-
* Errors are thrown as exceptions instead of \WP_Errors to allow for simpler handling and overloading. They are then
200-
* caught and converted to a WP_Error when by WP_Abilities_Registry::register().
201-
*
202-
* @since n.e.x.t
203-
*
204-
* @see WP_Abilities_Registry::register()
205-
*
206-
* @param array<string,mixed> $properties An associative array of properties to validate.
207-
*
208-
* @return void
209-
* @throws \InvalidArgumentException if the properties are invalid.
210-
*
211-
* @phpstan-assert array{
212-
* label: string,
213-
* description: string,
214-
* input_schema?: array<string,mixed>,
215-
* output_schema?: array<string,mixed>,
216-
* execute_callback: callable( array<string,mixed> $input): (mixed|\WP_Error),
217-
* permission_callback?: ?callable( array<string,mixed> $input ): (bool|\WP_Error),
218-
* meta?: array<string,mixed>,
219-
* ...<string, mixed>,
220-
* } $properties
221-
*/
222-
protected function validate_properties( array $properties ) {
223-
if ( empty( $properties['label'] ) || ! is_string( $properties['label'] ) ) {
224-
throw new \InvalidArgumentException(
225-
esc_html__( 'The ability properties must contain a `label` string.' )
226-
);
227-
}
228-
229-
if ( empty( $properties['description'] ) || ! is_string( $properties['description'] ) ) {
230-
throw new \InvalidArgumentException(
231-
esc_html__( 'The ability properties must contain a `description` string.' )
232-
);
233-
}
234-
235-
if ( isset( $properties['input_schema'] ) && ! is_array( $properties['input_schema'] ) ) {
236-
throw new \InvalidArgumentException(
237-
esc_html__( 'The ability properties should provide a valid `input_schema` definition.' )
238-
);
239-
}
240-
241-
if ( isset( $properties['output_schema'] ) && ! is_array( $properties['output_schema'] ) ) {
242-
throw new \InvalidArgumentException(
243-
esc_html__( 'The ability properties should provide a valid `output_schema` definition.' )
244-
);
245-
}
246-
247-
if ( empty( $properties['execute_callback'] ) || ! is_callable( $properties['execute_callback'] ) ) {
248-
throw new \InvalidArgumentException(
249-
esc_html__( 'The ability properties must contain a valid `execute_callback` function.' )
250-
);
251-
}
252-
253-
if ( isset( $properties['permission_callback'] ) && ! is_callable( $properties['permission_callback'] ) ) {
254-
throw new \InvalidArgumentException(
255-
esc_html__( 'The ability properties should provide a valid `permission_callback` function.' )
256-
);
257-
}
258-
259-
if ( isset( $properties['meta'] ) && ! is_array( $properties['meta'] ) ) {
260-
throw new \InvalidArgumentException(
261-
esc_html__( 'The ability properties should provide a valid `meta` array.' )
262-
);
263-
}
264-
}
265-
266267
/**
267268
* Validates input data against the input schema.
268269
*

includes/bootstrap.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
// Version of the plugin.
2121
if ( ! defined( 'WP_ABILITIES_API_VERSION' ) ) {
22-
define( 'WP_ABILITIES_API_VERSION', '0.1.0' );
22+
define( 'WP_ABILITIES_API_VERSION', '0.2.0' );
2323
}
2424

2525
// Load core classes if they are not already defined (for non-Composer installs or direct includes).

0 commit comments

Comments
 (0)