diff --git a/docs/hooks.md b/docs/hooks.md index a508224..37eda17 100644 --- a/docs/hooks.md +++ b/docs/hooks.md @@ -30,21 +30,21 @@ do_action( 'wp_abilities_api_categories_init', $registry ); #### Usage Example ```php -add_action( 'wp_abilities_api_categories_init', 'my_plugin_register_categories' ); +add_action( 'wp_abilities_api_categories_init', 'wporg_register_categories' ); /** * Register custom ability categories. * * @param \WP_Ability_Categories_Registry $registry The category registry instance. */ -function my_plugin_register_categories( $registry ) { +function wporg_register_categories( $registry ) { wp_register_ability_category( 'ecommerce', array( - 'label' => __( 'E-commerce', 'my-plugin' ), - 'description' => __( 'Abilities related to e-commerce functionality.', 'my-plugin' ), + 'label' => __( 'E-commerce', 'textdomain' ), + 'description' => __( 'Abilities related to e-commerce functionality.', 'textdomain' ), )); wp_register_ability_category( 'analytics', array( - 'label' => __( 'Analytics', 'my-plugin' ), - 'description' => __( 'Abilities that provide analytical data and insights.', 'my-plugin' ), + 'label' => __( 'Analytics', 'textdomain' ), + 'description' => __( 'Abilities that provide analytical data and insights.', 'textdomain' ), )); } ``` @@ -64,14 +64,14 @@ do_action( 'wp_abilities_api_init', $registry ); #### Usage Example ```php -add_action('wp_abilities_api_init', 'my_plugin_register_abilities'); +add_action('wp_abilities_api_init', 'wporg_register_abilities'); /** * Register custom abilities. */ -function my_plugin_register_abilities() { - wp_register_ability( 'my-plugin/ability', array( - 'label' => __( 'Title', 'my-plugin' ), - 'description' => __( 'Description.', 'my-plugin' ), +function wporg_register_abilities() { + wp_register_ability( 'wporg/ability', array( + 'label' => __( 'Title', 'textdomain' ), + 'description' => __( 'Description.', 'textdomain' ), 'category' => 'analytics', 'input_schema' => array( 'type' => 'object', @@ -82,7 +82,7 @@ function my_plugin_register_abilities() { 'type' => 'string', 'description' => 'The site title.', ), - 'execute_callback' => 'my_plugin_get_site_title', + 'execute_callback' => 'wporg_get_site_title', 'permission_callback' => '__return_true', // Everyone can access this 'meta' => array( 'show_in_rest' => true, // Optional: expose via REST API @@ -100,7 +100,7 @@ do_action( 'wp_before_execute_ability', $ability_name, $input ); #### Parameters -- `$ability_name` (`string`): The namespaced name of the ability being executed (e.g., `my-plugin/get-posts`). +- `$ability_name` (`string`): The namespaced name of the ability being executed (e.g., `wporg/get-posts`). - `$input` (`mixed`): The input data passed to the ability. #### Usage Example @@ -164,7 +164,7 @@ $args = apply_filters( 'wp_register_ability_args', array $args, string $ability_ #### Parameters - `$args` (`array`): The arguments used to instantiate the ability. See [wp_register_ability()](./3.registering-abilities.md#wp_register_ability) for the full list of args. -- `$ability_name` (`string`): The namespaced name of the ability being registered (e.g., `my-plugin/get-posts`). +- `$ability_name` (`string`): The namespaced name of the ability being registered (e.g., `wporg/get-posts`). #### Usage Example @@ -205,7 +205,7 @@ function my_modify_ability_args( array $args, string $ability_name ): array { } return current_user_can( 'my_custom_ability_cap', $ability_name ); - } + }; return $args; } @@ -238,8 +238,8 @@ add_filter( 'wp_register_ability_category_args', 'my_modify_category_args', 10, */ function my_modify_category_args( array $args, string $slug ): array { if ( 'my-category' === $slug ) { - $args['label'] = __( 'My Custom Label', 'my-plugin' ); - $args['description'] = __( 'My custom description for this category.', 'my-plugin' ); + $args['label'] = __( 'My Custom Label', 'textdomain' ); + $args['description'] = __( 'My custom description for this category.', 'textdomain' ); } return $args; } diff --git a/docs/php-api.md b/docs/php-api.md index 3e5665f..61f5bc8 100644 --- a/docs/php-api.md +++ b/docs/php-api.md @@ -24,22 +24,36 @@ wp_register_ability_category( string $slug, array $args ): ?\WP_Ability_Category ### Code Example ```php -add_action( 'wp_abilities_api_categories_init', 'my_plugin_register_categories' ); -function my_plugin_register_categories() { - wp_register_ability_category( 'data-retrieval', array( - 'label' => __( 'Data Retrieval', 'my-plugin' ), - 'description' => __( 'Abilities that retrieve and return data from the WordPress site.', 'my-plugin' ), - )); - - wp_register_ability_category( 'data-modification', array( - 'label' => __( 'Data Modification', 'my-plugin' ), - 'description' => __( 'Abilities that modify data on the WordPress site.', 'my-plugin' ), - )); - - wp_register_ability_category( 'communication', array( - 'label' => __( 'Communication', 'my-plugin' ), - 'description' => __( 'Abilities that send messages or notifications.', 'my-plugin' ), - )); +add_action( 'wp_abilities_api_categories_init', 'wporg_register_categories' ); +/** + * Register custom ability categories. + * + * @return void + */ +function wporg_register_categories() { + wp_register_ability_category( + 'data-retrieval', + array( + 'label' => __( 'Data Retrieval', 'textdomain' ), + 'description' => __( 'Abilities that retrieve and return data from the WordPress site.', 'textdomain' ), + ) + ); + + wp_register_ability_category( + 'data-modification', + array( + 'label' => __( 'Data Modification', 'textdomain' ), + 'description' => __( 'Abilities that modify data on the WordPress site.', 'textdomain' ), + ) + ); + + wp_register_ability_category( + 'communication', + array( + 'label' => __( 'Communication', 'textdomain' ), + 'description' => __( 'Abilities that send messages or notifications.', 'textdomain' ), + ) + ); } ``` @@ -148,235 +162,267 @@ The `$args` array accepts the following keys: The `$name` parameter must follow the pattern `namespace/ability-name`: - **Format:** Must contain only lowercase alphanumeric characters (`a-z`, `0-9`), hyphens (`-`), and one forward slash (`/`) for namespacing. -- **Convention:** Use your plugin slug as the namespace, like `my-plugin/ability-name`. -- **Examples:** `my-plugin/update-settings`, `woocommerce/get-product`, `contact-form/send-message`, `analytics/track-event` +- **Convention:** Use your plugin slug as the namespace, like `wporg/ability-name`. +- **Examples:** `wporg/update-settings`, `woocommerce/get-product`, `contact-form/send-message`, `analytics/track-event` ### Code Examples #### Registering a simple data retrieval Ability without an input schema ```php -add_action( 'wp_abilities_api_init', 'my_plugin_register_site_info_ability' ); -function my_plugin_register_site_info_ability() { - wp_register_ability( 'my-plugin/get-site-info', array( - 'label' => __( 'Get Site Information', 'my-plugin' ), - 'description' => __( 'Retrieves basic information about the WordPress site including name, description, and URL.', 'my-plugin' ), - 'category' => 'data-retrieval', - 'output_schema' => array( - 'type' => 'object', - 'properties' => array( - 'name' => array( - 'type' => 'string', - 'description' => 'Site name' - ), - 'description' => array( - 'type' => 'string', - 'description' => 'Site tagline' - ), - 'url' => array( - 'type' => 'string', - 'format' => 'uri', - 'description' => 'Site URL' - ) - ) - ), - 'execute_callback' => function() { - return array( - 'name' => get_bloginfo( 'name' ), - 'description' => get_bloginfo( 'description' ), - 'url' => home_url() - ); - }, - 'permission_callback' => '__return_true', - 'meta' => array( - 'annotations' => array( - 'readonly' => true, - 'destructive' => false - ), - ), - )); +add_action( 'wp_abilities_api_init', 'wporg_register_site_info_ability' ); +/** + * Register the 'wporg/get-site-info' ability. + * + * @return void + */ +function wporg_register_site_info_ability() { + wp_register_ability( + 'wporg/get-site-info', + array( + 'label' => __( 'Get Site Information', 'textdomain' ), + 'description' => __( 'Retrieves basic information about the WordPress site including name, description, and URL.', 'textdomain' ), + 'category' => 'data-retrieval', + 'output_schema' => array( + 'type' => 'object', + 'properties' => array( + 'name' => array( + 'type' => 'string', + 'description' => 'Site name', + ), + 'description' => array( + 'type' => 'string', + 'description' => 'Site tagline', + ), + 'url' => array( + 'type' => 'string', + 'format' => 'uri', + 'description' => 'Site URL', + ), + ), + ), + 'execute_callback' => function () { + return array( + 'name' => get_bloginfo( 'name' ), + 'description' => get_bloginfo( 'description' ), + 'url' => home_url(), + ); + }, + 'permission_callback' => '__return_true', + 'meta' => array( + 'annotations' => array( + 'readonly' => true, + 'destructive' => false, + ), + ), + ) + ); } ``` #### Registering an Ability with Input Parameters ```php -add_action( 'wp_abilities_api_init', 'my_plugin_register_update_option_ability' ); -function my_plugin_register_update_option_ability() { - wp_register_ability( 'my-plugin/update-option', array( - 'label' => __( 'Update WordPress Option', 'my-plugin' ), - 'description' => __( 'Updates the value of a WordPress option in the database. Requires manage_options capability.', 'my-plugin' ), - 'category' => 'data-modification', - 'input_schema' => array( - 'type' => 'object', - 'properties' => array( - 'option_name' => array( - 'type' => 'string', - 'description' => 'The name of the option to update', - 'minLength' => 1 - ), - 'option_value' => array( - 'description' => 'The new value for the option' - ) - ), - 'required' => array( 'option_name', 'option_value' ), - 'additionalProperties' => false - ), - 'output_schema' => array( - 'type' => 'object', - 'properties' => array( - 'success' => array( - 'type' => 'boolean', - 'description' => 'Whether the option was successfully updated' - ), - 'previous_value' => array( - 'description' => 'The previous value of the option' - ) - ) - ), - 'execute_callback' => function( $input ) { - $option_name = $input['option_name']; - $new_value = $input['option_value']; - - $previous_value = get_option( $option_name ); - $success = update_option( $option_name, $new_value ); - - return array( - 'success' => $success, - 'previous_value' => $previous_value - ); - }, - 'permission_callback' => function() { - return current_user_can( 'manage_options' ); - }, - 'meta' => array( - 'annotations' => array( - 'destructive' => false, - 'idempotent' => true - ), - ), - )); +add_action( 'wp_abilities_api_init', 'wporg_register_update_option_ability' ); +/** + * Register the 'wporg/update-option' ability. + * + * @return void + */ +function wporg_register_update_option_ability() { + wp_register_ability( + 'wporg/update-option', + array( + 'label' => __( 'Update WordPress Option', 'textdomain' ), + 'description' => __( 'Updates the value of a WordPress option in the database. Requires manage_options capability.', 'textdomain' ), + 'category' => 'data-modification', + 'input_schema' => array( + 'type' => 'object', + 'properties' => array( + 'option_name' => array( + 'type' => 'string', + 'description' => 'The name of the option to update', + 'minLength' => 1, + ), + 'option_value' => array( + 'description' => 'The new value for the option', + ), + ), + 'required' => array( 'option_name', 'option_value' ), + 'additionalProperties' => false, + ), + 'output_schema' => array( + 'type' => 'object', + 'properties' => array( + 'success' => array( + 'type' => 'boolean', + 'description' => 'Whether the option was successfully updated', + ), + 'previous_value' => array( + 'description' => 'The previous value of the option', + ), + ), + ), + 'execute_callback' => function ( $input ) { + $option_name = $input['option_name']; + $new_value = $input['option_value']; + + $previous_value = get_option( $option_name ); + $success = update_option( $option_name, $new_value ); + + return array( + 'success' => $success, + 'previous_value' => $previous_value, + ); + }, + 'permission_callback' => function () { + return current_user_can( 'manage_options' ); + }, + 'meta' => array( + 'annotations' => array( + 'destructive' => false, + 'idempotent' => true, + ), + ), + ) + ); } ``` #### Registering an Ability with Plugin Dependencies ```php -add_action( 'wp_abilities_api_init', 'my_plugin_register_woo_stats_ability' ); -function my_plugin_register_woo_stats_ability() { - // Only register if WooCommerce is active - if ( ! class_exists( 'WooCommerce' ) ) { - return; - } +add_action( 'wp_abilities_api_init', 'woo_register_woo_stats_ability' ); +/** + * Register WooCommerce Stats Ability. + * + * @return void + */ +function woo_register_woo_stats_ability() { + // Only register if WooCommerce is active. + if ( ! class_exists( 'WooCommerce' ) ) { + return; + } - wp_register_ability( 'my-plugin/get-woo-stats', array( - 'label' => __( 'Get WooCommerce Statistics', 'my-plugin' ), - 'description' => __( 'Retrieves basic WooCommerce store statistics including total orders and revenue.', 'my-plugin' ), - 'category' => 'ecommerce', - 'input_schema' => array( - 'type' => 'object', - 'properties' => array( - 'period' => array( - 'type' => 'string', - 'enum' => array( 'today', 'week', 'month', 'year' ), - 'default' => 'month', - 'description' => 'Time period for statistics' - ) - ), - 'additionalProperties' => false - ), - 'output_schema' => array( - 'type' => 'object', - 'properties' => array( - 'total_orders' => array( - 'type' => 'integer', - 'description' => 'Number of orders in period' - ), - 'total_revenue' => array( - 'type' => 'number', - 'description' => 'Total revenue in period' - ) - ) - ), - 'execute_callback' => function( $input ) { - $period = $input['period'] ?? 'month'; - - // Implementation would calculate stats based on period - return array( - 'total_orders' => 42, - 'total_revenue' => 1250.50 - ); - }, - 'permission_callback' => function() { - return current_user_can( 'manage_woocommerce' ); - }, - 'meta' => array( - 'requires_plugin' => 'woocommerce' - ) - )); + wp_register_ability( + 'woo/get-woo-stats', + array( + 'label' => __( 'Get WooCommerce Statistics', 'textdomain' ), + 'description' => __( 'Retrieves basic WooCommerce store statistics including total orders and revenue.', 'textdomain' ), + 'category' => 'ecommerce', + 'input_schema' => array( + 'type' => 'object', + 'properties' => array( + 'period' => array( + 'type' => 'string', + 'enum' => array( 'today', 'week', 'month', 'year' ), + 'default' => 'month', + 'description' => 'Time period for statistics', + ), + ), + 'additionalProperties' => false, + ), + 'output_schema' => array( + 'type' => 'object', + 'properties' => array( + 'total_orders' => array( + 'type' => 'integer', + 'description' => 'Number of orders in period', + ), + 'total_revenue' => array( + 'type' => 'number', + 'description' => 'Total revenue in period', + ), + ), + ), + 'execute_callback' => function ( $input ) { + $period = $input['period'] ?? 'month'; + + // Implementation would calculate stats based on period. + return array( + 'total_orders' => 42, + 'total_revenue' => 1250.50, + ); + }, + 'permission_callback' => function () { + return current_user_can( 'manage_woocommerce' ); + }, + 'meta' => array( + 'requires_plugin' => 'woocommerce', + ), + ) + ); } ``` #### Registering an Ability That May Fail ```php -add_action( 'wp_abilities_api_init', 'my_plugin_register_send_email_ability' ); -function my_plugin_register_send_email_ability() { - wp_register_ability( 'my-plugin/send-email', array( - 'label' => __( 'Send Email', 'my-plugin' ), - 'description' => __( 'Sends an email to the specified recipient using WordPress mail functions.', 'my-plugin' ), - 'category' => 'communication', - 'input_schema' => array( - 'type' => 'object', - 'properties' => array( - 'to' => array( - 'type' => 'string', - 'format' => 'email', - 'description' => 'Recipient email address' - ), - 'subject' => array( - 'type' => 'string', - 'minLength' => 1, - 'description' => 'Email subject' - ), - 'message' => array( - 'type' => 'string', - 'minLength' => 1, - 'description' => 'Email message body' - ) - ), - 'required' => array( 'to', 'subject', 'message' ), - 'additionalProperties' => false - ), - 'output_schema' => array( - 'type' => 'object', - 'properties' => array( - 'sent' => array( - 'type' => 'boolean', - 'description' => 'Whether the email was successfully sent' - ) - ) - ), - 'execute_callback' => function( $input ) { - $sent = wp_mail( - $input['to'], - $input['subject'], - $input['message'] - ); - - if ( ! $sent ) { - return new \WP_Error( - 'email_send_failed', - sprintf( __( 'Failed to send email' ), 'my-plugin' ) - ); - } - - return array( 'sent' => true ); - }, - 'permission_callback' => function() { - return current_user_can( 'publish_posts' ); - } - )); +add_action( 'wp_abilities_api_init', 'wporg_register_send_email_ability' ); +/** + * Register the 'wporg/send-email' ability. + * + * @return void + */ +function wporg_register_send_email_ability() { + wp_register_ability( + 'wporg/send-email', + array( + 'label' => __( 'Send Email', 'textdomain' ), + 'description' => __( 'Sends an email to the specified recipient using WordPress mail functions.', 'textdomain' ), + 'category' => 'communication', + 'input_schema' => array( + 'type' => 'object', + 'properties' => array( + 'to' => array( + 'type' => 'string', + 'format' => 'email', + 'description' => 'Recipient email address', + ), + 'subject' => array( + 'type' => 'string', + 'minLength' => 1, + 'description' => 'Email subject', + ), + 'message' => array( + 'type' => 'string', + 'minLength' => 1, + 'description' => 'Email message body', + ), + ), + 'required' => array( 'to', 'subject', 'message' ), + 'additionalProperties' => false, + ), + 'output_schema' => array( + 'type' => 'object', + 'properties' => array( + 'sent' => array( + 'type' => 'boolean', + 'description' => 'Whether the email was successfully sent', + ), + ), + ), + 'execute_callback' => function ( $input ) { + $sent = wp_mail( + $input['to'], + $input['subject'], + $input['message'] + ); + + if ( ! $sent ) { + return new \WP_Error( + 'email_send_failed', + sprintf( __( 'Failed to send email' ), 'textdomain' ) + ); + } + + return array( 'sent' => true ); + }, + 'permission_callback' => function () { + return current_user_can( 'publish_posts' ); + }, + ) + ); } ``` @@ -393,119 +439,128 @@ The `ability_class` parameter allows you to use a custom class that extends `WP_ * This example shows how to extend WP_Ability to add custom behavior * while still leveraging all the standard ability functionality. */ -class My_Plugin_Post_Validator_Ability extends WP_Ability { - /** - * Override the do_execute method to add custom logging. - * - * This demonstrates how you can override methods from WP_Ability - * to customize behavior before or after the standard execution. - * - * @param mixed $input Optional. The input data for the ability. - * @return mixed|\WP_Error The result of the ability execution. - */ - protected function do_execute( $input = null ) { - // Log the execution for debugging purposes - error_log( sprintf( - 'Executing ability: %s with input: %s', - $this->get_name(), - json_encode( $input ) - ) ); - - // Call the parent's do_execute to run the normal execute_callback - $result = parent::do_execute( $input ); - - // Log the result - if ( is_wp_error( $result ) ) { - error_log( sprintf( - 'Ability %s failed: %s', - $this->get_name(), - $result->get_error_message() - ) ); - } else { - error_log( sprintf( - 'Ability %s completed successfully', - $this->get_name() - ) ); - } - - return $result; - } +class WPOrg_Post_Validator_Ability extends WP_Ability { + /** + * Override the do_execute method to add custom logging. + * + * This demonstrates how you can override methods from WP_Ability + * to customize behavior before or after the standard execution. + * + * @param mixed $input Optional. The input data for the ability. + * @return mixed|\WP_Error The result of the ability execution. + */ + protected function do_execute( $input = null ) { + // Log the execution for debugging purposes. + error_log( + sprintf( + 'Executing ability: %s with input: %s', + $this->get_name(), + json_encode( $input ) + ) + ); + + // Call the parent's do_execute to run the normal execute_callback. + $result = parent::do_execute( $input ); + + // Log the result + if ( is_wp_error( $result ) ) { + error_log( + sprintf( + 'Ability %s failed: %s', + $this->get_name(), + $result->get_error_message() + ) + ); + } else { + error_log( + sprintf( + 'Ability %s completed successfully', + $this->get_name() + ) + ); + } + + return $result; + } } /** * Register the ability using the custom ability class. */ -add_action( 'wp_abilities_api_init', 'my_plugin_register_post_validator_ability' ); -function my_plugin_register_post_validator_ability() { - wp_register_ability( 'my-plugin/validate-post', array( - 'label' => __( 'Validate Post', 'my-plugin' ), - 'description' => __( 'Validates that a post exists, is published, and returns its metadata.', 'my-plugin' ), - 'category' => 'data-retrieval', - 'input_schema' => array( - 'type' => 'object', - 'properties' => array( - 'post_id' => array( - 'type' => 'integer', - 'description' => 'The ID of the post to validate', - 'minimum' => 1 - ) - ), - 'required' => array( 'post_id' ), - 'additionalProperties' => false - ), - 'output_schema' => array( - 'type' => 'object', - 'properties' => array( - 'valid' => array( - 'type' => 'boolean', - 'description' => 'Whether the post is valid' - ), - 'post_title' => array( - 'type' => 'string', - 'description' => 'The post title' - ), - 'post_date' => array( - 'type' => 'string', - 'description' => 'The post publication date' - ) - ) - ), - 'execute_callback' => function( $input ) { - $post_id = $input['post_id']; - $post = get_post( $post_id ); - if ( ! $post ) { - return new \WP_Error( - 'invalid_post', - __( 'The specified post does not exist.', 'my-plugin' ) - ); - } - // Check if the post is published - if ( 'publish' !== $post->post_status ) { - return new \WP_Error( - 'post_not_published', - __( 'The specified post is not published.', 'my-plugin' ) - ); - } - // If validation passes, return post information - return array( - 'valid' => true, - 'post_title' => $post->post_title, - 'post_date' => $post->post_date - ); - }, - 'permission_callback' => function() { - // Any logged-in user can validate posts - return is_user_logged_in(); - }, - 'meta' => array( - 'annotations' => array( - 'readonly' => true, - 'destructive' => false - ) - ), - // Specify the custom ability class to use - 'ability_class' => 'My_Plugin_Post_Validator_Ability' - )); +add_action( 'wp_abilities_api_init', 'wporg_register_post_validator_ability' ); +function wporg_register_post_validator_ability() { + wp_register_ability( + 'wporg/validate-post', + array( + 'label' => __( 'Validate Post', 'textdomain' ), + 'description' => __( 'Validates that a post exists, is published, and returns its metadata.', 'textdomain' ), + 'category' => 'data-retrieval', + 'input_schema' => array( + 'type' => 'object', + 'properties' => array( + 'post_id' => array( + 'type' => 'integer', + 'description' => 'The ID of the post to validate', + 'minimum' => 1, + ), + ), + 'required' => array( 'post_id' ), + 'additionalProperties' => false, + ), + 'output_schema' => array( + 'type' => 'object', + 'properties' => array( + 'valid' => array( + 'type' => 'boolean', + 'description' => 'Whether the post is valid', + ), + 'post_title' => array( + 'type' => 'string', + 'description' => 'The post title', + ), + 'post_date' => array( + 'type' => 'string', + 'description' => 'The post publication date', + ), + ), + ), + 'execute_callback' => function ( $input ) { + $post_id = $input['post_id']; + $post = get_post( $post_id ); + if ( ! $post ) { + return new \WP_Error( + 'invalid_post', + __( 'The specified post does not exist.', 'textdomain' ) + ); + } + // Check if the post is published + if ( 'publish' !== $post->post_status ) { + return new \WP_Error( + 'post_not_published', + __( 'The specified post is not published.', 'textdomain' ) + ); + } + // If validation passes, return post information + return array( + 'valid' => true, + 'post_title' => $post->post_title, + 'post_date' => $post->post_date, + ); + }, + 'permission_callback' => function () { + // Any logged-in user can validate posts + return is_user_logged_in(); + }, + 'meta' => array( + 'annotations' => array( + 'readonly' => true, + 'destructive' => false, + ), + ), + // Specify the custom ability class to use + 'ability_class' => 'WPOrg_Post_Validator_Ability', + ) + ); } ``` @@ -536,7 +591,7 @@ wp_has_ability( string $name ): bool ### Code Example ```php -$ability_name = 'my-plugin/get-site-info'; +$ability_name = 'wporg/get-site-info'; if ( wp_has_ability( $ability_name ) ) { // Ability is registered } @@ -560,21 +615,22 @@ To get a single ability object by its name (namespace/ability-name): function wp_get_ability( string $name ): ?WP_Ability // Example: -$site_info_ability = wp_get_ability( 'my-plugin/get-site-info' ); +$site_info_ability = wp_get_ability( 'wporg/get-site-info' ); if ( $site_info_ability ) { - // Ability exists and is registered + // Ability exists and is registered. $site_info = $site_info_ability->execute(); if ( is_wp_error( $site_info ) ) { - // Handle WP_Error + // Handle WP_Error. echo 'Error: ' . $site_info->get_error_message(); } else { - // Use $site_info array + // Use $site_info array. echo 'Site Name: ' . $site_info['name']; } } else { - // Ability not found or not registered + // Ability not found or not registered. } + ``` ### Getting All Registered Abilities (`wp_get_abilities`) @@ -614,7 +670,7 @@ Once you have a `WP_Ability` object (usually from `wp_get_ability`), you execute // public function execute( $input = null ) // Example 1: Ability with no input parameters -$ability = wp_get_ability( 'my-plugin/get-site-info' ); +$ability = wp_get_ability( 'wporg/get-site-info' ); if ( $ability ) { $site_info = $ability->execute(); // No input required if ( is_wp_error( $site_info ) ) { @@ -627,7 +683,7 @@ if ( $ability ) { } // Example 2: Ability with input parameters -$ability = wp_get_ability( 'my-plugin/update-option' ); +$ability = wp_get_ability( 'wporg/update-option' ); if ( $ability ) { $input = array( 'option_name' => 'blogname', @@ -648,7 +704,7 @@ if ( $ability ) { } // Example 3: Ability with complex input validation -$ability = wp_get_ability( 'my-plugin/send-email' ); +$ability = wp_get_ability( 'wporg/send-email' ); if ( $ability ) { $input = array( 'to' => 'user@example.com', @@ -673,7 +729,7 @@ if ( $ability ) { You can check if the current user has permissions to execute the ability, also without executing it. The `check_permissions()` method returns either `true`, `false`, or a `WP_Error` object. `true` means permission is granted, `false` means the user simply lacks permission, and a `WP_Error` return value typically indicates a failure in the permission check process (such as an internal error or misconfiguration). You must use `is_wp_error()` to handle errors properly and distinguish between permission denial and actual errors: ```php -$ability = wp_get_ability( 'my-plugin/update-option' ); +$ability = wp_get_ability( 'wporg/update-option' ); if ( $ability ) { $input = array( 'option_name' => 'blogname', @@ -701,7 +757,7 @@ if ( $ability ) { The `WP_Ability` class provides several getter methods to inspect ability properties: ```php -$ability = wp_get_ability( 'my-plugin/get-site-info' ); +$ability = wp_get_ability( 'wporg/get-site-info' ); if ( $ability ) { // Basic properties echo 'Name: ' . $ability->get_name() . "\n"; @@ -728,7 +784,7 @@ if ( $ability ) { The Abilities API uses several error handling mechanisms: ```php -$ability = wp_get_ability( 'my-plugin/some-ability' ); +$ability = wp_get_ability( 'wporg/some-ability' ); if ( ! $ability ) { // Ability not registered