Skip to content

Commit b1e15c1

Browse files
committed
Bring another set of upstream changes planned for v0.2.0 release
1 parent 3347870 commit b1e15c1

File tree

8 files changed

+219
-189
lines changed

8 files changed

+219
-189
lines changed

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

Lines changed: 26 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,16 @@ final class WP_Abilities_Registry {
3939
*
4040
* Do not use this method directly. Instead, use the `wp_register_ability()` function.
4141
*
42-
* @see wp_register_ability()
43-
*
4442
* @since 0.1.0
4543
*
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.
44+
* @see wp_register_ability()
45+
*
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__,
@@ -85,87 +85,30 @@ public function register( string $name, array $properties = array() ): ?WP_Abili
8585
return null;
8686
}
8787

88-
if ( empty( $properties['label'] ) || ! is_string( $properties['label'] ) ) {
89-
_doing_it_wrong(
90-
__METHOD__,
91-
esc_html__( 'The ability properties must contain a `label` string.' ),
92-
'0.1.0'
93-
);
94-
return null;
95-
}
96-
97-
if ( empty( $properties['description'] ) || ! is_string( $properties['description'] ) ) {
98-
_doing_it_wrong(
99-
__METHOD__,
100-
esc_html__( 'The ability properties must contain a `description` string.' ),
101-
'0.1.0'
102-
);
103-
return null;
104-
}
105-
106-
if ( isset( $properties['input_schema'] ) && ! is_array( $properties['input_schema'] ) ) {
107-
_doing_it_wrong(
108-
__METHOD__,
109-
esc_html__( 'The ability properties should provide a valid `input_schema` definition.' ),
110-
'0.1.0'
111-
);
112-
return null;
113-
}
114-
115-
if ( isset( $properties['output_schema'] ) && ! is_array( $properties['output_schema'] ) ) {
116-
_doing_it_wrong(
117-
__METHOD__,
118-
esc_html__( 'The ability properties should provide a valid `output_schema` definition.' ),
119-
'0.1.0'
120-
);
121-
return null;
122-
}
123-
124-
if ( empty( $properties['execute_callback'] ) || ! is_callable( $properties['execute_callback'] ) ) {
125-
_doing_it_wrong(
126-
__METHOD__,
127-
esc_html__( 'The ability properties must contain a valid `execute_callback` function.' ),
128-
'0.1.0'
129-
);
130-
return null;
131-
}
132-
133-
if ( isset( $properties['permission_callback'] ) && ! is_callable( $properties['permission_callback'] ) ) {
134-
_doing_it_wrong(
135-
__METHOD__,
136-
esc_html__( 'The ability properties should provide a valid `permission_callback` function.' ),
137-
'0.1.0'
138-
);
139-
return null;
140-
}
141-
142-
if ( isset( $properties['meta'] ) && ! is_array( $properties['meta'] ) ) {
88+
// The class is only used to instantiate the ability, and is not a property of the ability itself.
89+
if ( isset( $args['ability_class'] ) && ! is_a( $args['ability_class'], WP_Ability::class, true ) ) {
14390
_doing_it_wrong(
14491
__METHOD__,
145-
esc_html__( 'The ability properties should provide a valid `meta` array.' ),
92+
esc_html__( 'The ability args should provide a valid `ability_class` that extends WP_Ability.' ),
14693
'0.1.0'
14794
);
14895
return null;
14996
}
97+
$ability_class = $args['ability_class'] ?? WP_Ability::class;
98+
unset( $args['ability_class'] );
15099

151-
if ( isset( $properties['ability_class'] ) && ! is_a( $properties['ability_class'], WP_Ability::class, true ) ) {
100+
try {
101+
// WP_Ability::prepare_properties() will throw an exception if the properties are invalid.
102+
$ability = new $ability_class( $name, $args );
103+
} catch ( \InvalidArgumentException $e ) {
152104
_doing_it_wrong(
153105
__METHOD__,
154-
esc_html__( 'The ability properties should provide a valid `ability_class` that extends WP_Ability.' ),
106+
esc_html( $e->getMessage() ),
155107
'0.1.0'
156108
);
157109
return null;
158110
}
159111

160-
// The class is only used to instantiate the ability, and is not a property of the ability itself.
161-
$ability_class = $properties['ability_class'] ?? WP_Ability::class;
162-
unset( $properties['ability_class'] );
163-
164-
$ability = new $ability_class(
165-
$name,
166-
$properties
167-
);
168-
169112
$this->registered_abilities[ $name ] = $ability;
170113
return $ability;
171114
}
@@ -175,10 +118,10 @@ public function register( string $name, array $properties = array() ): ?WP_Abili
175118
*
176119
* Do not use this method directly. Instead, use the `wp_unregister_ability()` function.
177120
*
178-
* @see wp_unregister_ability()
179-
*
180121
* @since 0.1.0
181122
*
123+
* @see wp_unregister_ability()
124+
*
182125
* @param string $name The name of the registered ability, with its namespace.
183126
* @return ?\WP_Ability The unregistered ability instance on success, null on failure.
184127
*/
@@ -204,10 +147,10 @@ public function unregister( string $name ): ?WP_Ability {
204147
*
205148
* Do not use this method directly. Instead, use the `wp_get_abilities()` function.
206149
*
207-
* @see wp_get_abilities()
208-
*
209150
* @since 0.1.0
210151
*
152+
* @see wp_get_abilities()
153+
*
211154
* @return \WP_Ability[] The array of registered abilities.
212155
*/
213156
public function get_all_registered(): array {
@@ -231,10 +174,10 @@ public function is_registered( string $name ): bool {
231174
*
232175
* Do not use this method directly. Instead, use the `wp_get_ability()` function.
233176
*
234-
* @see wp_get_ability()
235-
*
236177
* @since 0.1.0
237178
*
179+
* @see wp_get_ability()
180+
*
238181
* @param string $name The name of the registered ability, with its namespace.
239182
* @return ?\WP_Ability The registered ability instance, or null if it is not registered.
240183
*/

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

Lines changed: 79 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -92,29 +92,20 @@ class WP_Ability {
9292
*
9393
* @access private
9494
*
95-
* @see wp_register_ability()
96-
*
9795
* @since 0.1.0
9896
*
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`.
97+
* @see wp_register_ability()
10398
*
104-
* @phpstan-param array{
105-
* label: string,
106-
* description: string,
107-
* input_schema?: array<string,mixed>,
108-
* output_schema?: array<string,mixed>,
109-
* execute_callback: callable( array<string,mixed> $input): (mixed|\WP_Error),
110-
* permission_callback?: ?callable( array<string,mixed> $input ): (bool|\WP_Error),
111-
* meta?: array<string,mixed>,
112-
* ...<string, mixed>,
113-
* } $properties
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`.
114103
*/
115-
public function __construct( string $name, array $properties ) {
104+
public function __construct( string $name, array $args ) {
116105
$this->name = $name;
117106

107+
$properties = $this->prepare_properties( $args );
108+
118109
foreach ( $properties as $property_name => $property_value ) {
119110
if ( ! property_exists( $this, $property_name ) ) {
120111
_doing_it_wrong(
@@ -135,6 +126,77 @@ public function __construct( string $name, array $properties ) {
135126
}
136127
}
137128

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+
138200
/**
139201
* Retrieves the name of the ability, with its namespace.
140202
* Example: `my-plugin/my-ability`.

src/wp-includes/rest-api/endpoints/class-wp-rest-abilities-list-controller.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
/**
33
* REST API list controller for Abilities API.
44
*
5-
* @package abilities-api
6-
* @since 0.1.0
5+
* @package WordPress
6+
* @subpackage Abilities_API
7+
* @since 0.1.0
78
*/
89

910
declare( strict_types = 1 );

src/wp-includes/rest-api/endpoints/class-wp-rest-abilities-run-controller.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
/**
33
* REST API run controller for Abilities API.
44
*
5-
* @package abilities-api
6-
* @since 0.1.0
5+
* @package WordPress
6+
* @subpackage Abilities_API
7+
* @since 0.1.0
78
*/
89

910
declare( strict_types = 1 );

0 commit comments

Comments
 (0)