|
17 | 17 | * - Validate inputs and outputs using JSON Schema. |
18 | 18 | * - Expose abilities through the REST API. |
19 | 19 | * |
20 | | - * ## Basic Usage |
| 20 | + * ## Working with Abilities |
21 | 21 | * |
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: |
23 | 92 | * |
24 | 93 | * 1. Hook into the `wp_abilities_api_init` action. |
25 | 94 | * 2. Call `wp_register_ability()` with a namespaced name and configuration. |
|
85 | 154 | * |
86 | 155 | * ### Input and Output Schemas |
87 | 156 | * |
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: |
90 | 171 | * |
91 | 172 | * 'input_schema' => array( |
92 | 173 | * 'type' => 'string', |
|
118 | 199 | * |
119 | 200 | * #### Permission Callback |
120 | 201 | * |
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: |
124 | 206 | * |
125 | 207 | * function my_plugin_can_analyze_text( string $input ): bool|WP_Error { |
126 | 208 | * return current_user_can( 'edit_posts' ); |
|
137 | 219 | * |
138 | 220 | * This allows abilities to be invoked via HTTP requests to the WordPress REST API. |
139 | 221 | * |
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 | | - * |
216 | 222 | * @since 6.9.0 |
217 | 223 | * |
218 | 224 | * @see WP_Abilities_Registry::register() |
@@ -267,9 +273,9 @@ function wp_register_ability( string $name, array $args ): ?WP_Ability { |
267 | 273 | _doing_it_wrong( |
268 | 274 | __FUNCTION__, |
269 | 275 | 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. */ |
271 | 277 | 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>', |
273 | 279 | '<code>' . esc_html( $name ) . '</code>' |
274 | 280 | ), |
275 | 281 | '6.9.0' |
@@ -454,9 +460,9 @@ function wp_get_abilities(): array { |
454 | 460 | function wp_register_ability_category( string $slug, array $args ): ?WP_Ability_Category { |
455 | 461 | if ( ! did_action( 'wp_abilities_api_categories_init' ) ) { |
456 | 462 | _doing_it_wrong( |
457 | | - __METHOD__, |
| 463 | + __FUNCTION__, |
458 | 464 | sprintf( |
459 | | - /* translators: 1: abilities_api_categories_init, 2: ability category slug. */ |
| 465 | + /* translators: 1: wp_abilities_api_categories_init, 2: ability category slug. */ |
460 | 466 | __( 'Ability categories must be registered on the %1$s action. The ability category %2$s was not registered.' ), |
461 | 467 | '<code>wp_abilities_api_categories_init</code>', |
462 | 468 | '<code>' . esc_html( $slug ) . '</code>' |
|
0 commit comments