Skip to content

Commit a185664

Browse files
committed
Improve the documentation based on the review feedback
1 parent 0b6299f commit a185664

File tree

1 file changed

+93
-87
lines changed

1 file changed

+93
-87
lines changed

src/wp-includes/abilities-api.php

Lines changed: 93 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,78 @@
1717
* - Validate inputs and outputs using JSON Schema.
1818
* - Expose abilities through the REST API.
1919
*
20-
* ## Basic Usage
20+
* ## Working with Abilities
2121
*
22-
* Registering an ability requires three steps:
22+
* Abilities must be registered on the `wp_abilities_api_init` action hook.
23+
* Attempting to register an ability outside of this hook will fail and
24+
* trigger a `_doing_it_wrong()` notice.
25+
26+
* Example:
27+
*
28+
* function my_plugin_register_abilities(): void {
29+
* wp_register_ability(
30+
* 'my-plugin/export-users',
31+
* array(
32+
* 'label' => __( 'Export Users', 'my-plugin' ),
33+
* 'description' => __( 'Exports user data to CSV format.', 'my-plugin' ),
34+
* 'category' => 'data-export',
35+
* 'execute_callback' => 'my_plugin_export_users',
36+
* 'permission_callback' => function(): bool {
37+
* return current_user_can( 'export' );
38+
* },
39+
* 'input_schema' => array(
40+
* 'type' => 'string',
41+
* 'enum' => array( 'subscriber', 'contributor', 'author', 'editor', 'administrator' ),
42+
* 'description' => __( 'Limits the export to users with this role.', 'my-plugin' ),
43+
* 'required' => false,
44+
* ),
45+
* 'output_schema' => array(
46+
* 'type' => 'string',
47+
* 'description' => __( 'User data in CSV format.', 'my-plugin' ),
48+
* 'required' => true,
49+
* ),
50+
* 'meta' => array(
51+
* 'show_in_rest' => true,
52+
* ),
53+
* )
54+
* );
55+
* }
56+
* add_action( 'wp_abilities_api_init', 'my_plugin_register_abilities' );
57+
*
58+
* Once registered, abilities can be checked, retrieved, and managed:
59+
*
60+
* // Checks if an ability is registered, and prints its label.
61+
* if ( wp_has_ability( 'my-plugin/export-users' ) ) {
62+
* $ability = wp_get_ability( 'my-plugin/export-users' );
63+
*
64+
* echo $ability->get_label();
65+
* }
66+
*
67+
* // Gets all registered abilities.
68+
* $all_abilities = wp_get_abilities();
69+
*
70+
* // Unregisters when no longer needed.
71+
* wp_unregister_ability( 'my-plugin/analyze-text' );
72+
*
73+
* ## Best Practices
74+
*
75+
* - Always register abilities on the `wp_abilities_api_init` hook.
76+
* - Use namespaced ability names to prevent conflicts.
77+
* - Implement robust permission checks in permission callbacks.
78+
* - Provide an `input_schema` to ensure data integrity and document expected inputs.
79+
* - Define an `output_schema` to describe return values and validate responses.
80+
* - Return `WP_Error` objects for failures rather than throwing exceptions.
81+
* - Use internationalization functions for all user-facing strings.
82+
*
83+
* @package WordPress
84+
* @subpackage Abilities_API
85+
* @since 6.9.0
86+
*/
87+
88+
declare( strict_types = 1 );
89+
90+
/**
91+
* Registers a new ability using the Abilities API. It requires three steps:
2392
*
2493
* 1. Hook into the `wp_abilities_api_init` action.
2594
* 2. Call `wp_register_ability()` with a namespaced name and configuration.
@@ -85,8 +154,20 @@
85154
*
86155
* ### Input and Output Schemas
87156
*
88-
* Define JSON Schema specifications to validate ability inputs and outputs.
89-
* This ensures data integrity and provides documentation for API consumers:
157+
* Schemas define the expected structure, type, and constraints for ability inputs
158+
* and outputs using JSON Schema syntax. They serve two critical purposes: automatic
159+
* validation of data passed to and returned from abilities, and self-documenting
160+
* API contracts for developers.
161+
*
162+
* WordPress implements a validator based on a subset of the JSON Schema Version 4
163+
* specification (https://json-schema.org/specification-links.html#draft-4).
164+
* For details on supported JSON Schema properties and syntax, see the
165+
* related WordPress REST API Schema documentation:
166+
* https://developer.wordpress.org/rest-api/extending-the-rest-api/schema/#json-schema-basics
167+
*
168+
* Defining schemas is mandatory when there is a value to pass or return.
169+
* They ensure data integrity, improve developer experience, and enable
170+
* better documentation:
90171
*
91172
* 'input_schema' => array(
92173
* 'type' => 'string',
@@ -118,9 +199,10 @@
118199
*
119200
* #### Permission Callback
120201
*
121-
* The permission callback determines whether the current user can execute
122-
* the ability. It receives the same input as the execute callback and must
123-
* return a boolean or `WP_Error`:
202+
* The permission callback determines whether the ability can be executed.
203+
* It receives the same input as the execute callback and must return a
204+
* boolean or `WP_Error`. Common use cases include checking user capabilities,
205+
* validating API keys, or verifying system state:
124206
*
125207
* function my_plugin_can_analyze_text( string $input ): bool|WP_Error {
126208
* return current_user_can( 'edit_posts' );
@@ -137,82 +219,6 @@
137219
*
138220
* This allows abilities to be invoked via HTTP requests to the WordPress REST API.
139221
*
140-
* ## Working with Abilities
141-
*
142-
* Once registered, abilities can be checked, retrieved, and managed:
143-
*
144-
* // Checks if an ability is registered, and prints its label.
145-
* if ( wp_has_ability( 'my-plugin/analyze-text' ) ) {
146-
* $ability = wp_get_ability( 'my-plugin/analyze-text' );
147-
*
148-
* echo $ability->get_label();
149-
* }
150-
*
151-
* // Gets all registered abilities.
152-
* $all_abilities = wp_get_abilities();
153-
*
154-
* // Unregisters when no longer needed.
155-
* wp_unregister_ability( 'my-plugin/analyze-text' );
156-
*
157-
* ## Best Practices
158-
*
159-
* - Always register abilities on the `wp_abilities_api_init` hook.
160-
* - Use namespaced ability names to prevent conflicts.
161-
* - Implement robust permission checks in permission callbacks.
162-
* - Provide an `input_schema` to ensure data integrity and document expected inputs.
163-
* - Define an `output_schema` to describe return values and validate responses.
164-
* - Return `WP_Error` objects for failures rather than throwing exceptions.
165-
* - Use internationalization functions for all user-facing strings.
166-
*
167-
* @package WordPress
168-
* @subpackage Abilities_API
169-
* @since 6.9.0
170-
*/
171-
172-
declare( strict_types = 1 );
173-
174-
/**
175-
* Registers a new ability using the Abilities API.
176-
*
177-
* Abilities must be registered on the `wp_abilities_api_init` action hook.
178-
* Attempting to register an ability outside of this hook will fail and
179-
* trigger a `_doing_it_wrong()` notice.
180-
*
181-
* See the file header for detailed documentation on naming conventions, callbacks,
182-
* schemas, ability categories, and best practices.
183-
*
184-
* Example:
185-
*
186-
* function my_plugin_register_abilities(): void {
187-
* wp_register_ability(
188-
* 'my-plugin/export-users',
189-
* array(
190-
* 'label' => __( 'Export Users', 'my-plugin' ),
191-
* 'description' => __( 'Exports user data to CSV format.', 'my-plugin' ),
192-
* 'category' => 'data-export',
193-
* 'execute_callback' => 'my_plugin_export_users',
194-
* 'permission_callback' => function(): bool {
195-
* return current_user_can( 'export' );
196-
* },
197-
* 'input_schema' => array(
198-
* 'type' => 'string',
199-
* 'enum' => array( 'subscriber', 'contributor', 'author', 'editor', 'administrator' ),
200-
* 'description' => __( 'Limits the export to users with this role.', 'my-plugin' ),
201-
* 'required' => false,
202-
* ),
203-
* 'output_schema' => array(
204-
* 'type' => 'string',
205-
* 'description' => __( 'User data in CSV format.', 'my-plugin' ),
206-
* 'required' => true,
207-
* ),
208-
* 'meta' => array(
209-
* 'show_in_rest' => true,
210-
* ),
211-
* )
212-
* );
213-
* }
214-
* add_action( 'wp_abilities_api_init', 'my_plugin_register_abilities' );
215-
*
216222
* @since 6.9.0
217223
*
218224
* @see WP_Abilities_Registry::register()
@@ -267,9 +273,9 @@ function wp_register_ability( string $name, array $args ): ?WP_Ability {
267273
_doing_it_wrong(
268274
__FUNCTION__,
269275
sprintf(
270-
/* translators: 1: abilities_api_init, 2: string value of the ability name. */
276+
/* translators: 1: wp_abilities_api_init, 2: string value of the ability name. */
271277
esc_html__( 'Abilities must be registered on the %1$s action. The ability %2$s was not registered.' ),
272-
'<code>abilities_api_init</code>',
278+
'<code>wp_abilities_api_init</code>',
273279
'<code>' . esc_html( $name ) . '</code>'
274280
),
275281
'6.9.0'
@@ -454,9 +460,9 @@ function wp_get_abilities(): array {
454460
function wp_register_ability_category( string $slug, array $args ): ?WP_Ability_Category {
455461
if ( ! did_action( 'wp_abilities_api_categories_init' ) ) {
456462
_doing_it_wrong(
457-
__METHOD__,
463+
__FUNCTION__,
458464
sprintf(
459-
/* translators: 1: abilities_api_categories_init, 2: ability category slug. */
465+
/* translators: 1: wp_abilities_api_categories_init, 2: ability category slug. */
460466
__( 'Ability categories must be registered on the %1$s action. The ability category %2$s was not registered.' ),
461467
'<code>wp_abilities_api_categories_init</code>',
462468
'<code>' . esc_html( $slug ) . '</code>'

0 commit comments

Comments
 (0)