- 
                Notifications
    You must be signed in to change notification settings 
- Fork 33
Add Filtering Capabilities for Registered Abilities #115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
          
     Open
      
      
            galatanovidiu
  wants to merge
  15
  commits into
  trunk
  
    
      
        
          
  
    
      Choose a base branch
      
     
    
      
        
      
      
        
          
          
        
        
          
            
              
              
              
  
           
        
        
          
            
              
              
           
        
       
     
  
        
          
            
          
            
          
        
       
    
      
from
feature/filter-registered-abilities
  
      
      
   
  
    
  
  
  
 
  
      
    base: trunk
Could not load branches
            
              
  
    Branch not found: {{ refName }}
  
            
                
      Loading
              
            Could not load tags
            
            
              Nothing to show
            
              
  
            
                
      Loading
              
            Are you sure you want to change the base?
            Some commits from the old base branch may be removed from the timeline,
            and old review comments may become outdated.
          
          
      
        
          +1,632
        
        
          −4
        
        
          
        
      
    
  
  
     Open
                    Changes from all commits
      Commits
    
    
            Show all changes
          
          
            15 commits
          
        
        Select commit
          Hold shift + click to select a range
      
      01cff2f
              
                feat(abilities-api): Introduce WP_Abilities_Query class
              
              
                galatanovidiu 46d4711
              
                feat(abilities-api): Add filtering capabilities to wp_get_abilities
              
              
                galatanovidiu 3ebeb37
              
                test(abilities-api): Add unit tests for WP_Abilities_Query
              
              
                galatanovidiu 45d3917
              
                docs(abilities-api): Add documentation for querying and filtering abi…
              
              
                galatanovidiu f114dae
              
                Refactor `WP_Abilities_Query` for compatibility
              
              
                galatanovidiu c89f085
              
                Remove redundant empty args check in wp_get_abilities()
              
              
                galatanovidiu 2ca7dae
              
                Clarifies array type annotations in documentation
              
              
                galatanovidiu 68fea1b
              
                Rename validation methods to sanitization methods
              
              
                galatanovidiu de10fa7
              
                Clarifies abilities retrieval and filtering doc
              
              
                galatanovidiu 74c0990
              
                Enforces non-negative offset and valid limit in pagination
              
              
                galatanovidiu 844dddb
              
                Refactor sanitize_pagination_args to use early exit pattern
              
              
                galatanovidiu 937c778
              
                Merge branch 'trunk' into feature/filter-registered-abilities
              
              
                galatanovidiu d3275fd
              
                Refactor ability query args to a reusable PHPStan type
              
              
                galatanovidiu 863b73e
              
                Harden WP_Abilities_Query as an internal class
              
              
                galatanovidiu 8a5c01f
              
                Update includes/abilities-api/class-wp-abilities-query.php
              
              
                galatanovidiu File filter
Filter by extension
Conversations
          Failed to load comments.   
        
        
          
      Loading
        
  Jump to
        
          Jump to file
        
      
      
          Failed to load files.   
        
        
          
      Loading
        
  Diff view
Diff view
There are no files selected for viewing
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,213 @@ | ||
| # 8. Querying and Filtering Abilities | ||
|  | ||
| The Abilities API provides powerful filtering capabilities through the `WP_Abilities_Query` class and the `wp_get_abilities()` function. This allows you to efficiently find and retrieve specific abilities from potentially thousands of registered abilities. | ||
|  | ||
| `wp_get_abilities()` returns an array of `WP_Ability` objects, keyed by ability name. | ||
|  | ||
| When no abilities match the query, an empty array is returned. | ||
|  | ||
| Invalid query parameters are normalized to safe defaults. | ||
|  | ||
| ## Overview | ||
|  | ||
| When working with large numbers of abilities registered by core and various plugins, the query system provides optimized server-side filtering. You can pass query arguments to `wp_get_abilities()` to filter abilities by category, namespace, meta properties, and more. | ||
|  | ||
| ```php | ||
| // Get all abilities | ||
| $abilities = wp_get_abilities(); | ||
|  | ||
| // Filter by category | ||
| $abilities = wp_get_abilities( array( 'category' => 'data-retrieval' ) ); | ||
|  | ||
| // Combine multiple filters | ||
| $abilities = wp_get_abilities( array( | ||
| 'namespace' => 'my-plugin', | ||
| 'category' => 'communication', | ||
| 'orderby' => 'label', | ||
| ) ); | ||
| ``` | ||
|  | ||
| ## Quick Reference: Query Parameters | ||
|  | ||
| | Parameter | Type | Default | Description | | ||
| |-----------|------|---------|-------------| | ||
| | `category` | string\|array | `''` | Filter by category slug. Accepts single value or array for multiple categories (OR logic) | | ||
| | `namespace` | string\|array | `''` | Filter by namespace. Accepts single value or array for multiple namespaces (OR logic) | | ||
| | `search` | string | `''` | Search in name, label, and description (case-insensitive) | | ||
| | `meta` | array | `array()` | Filter by meta properties using nested arrays (AND logic between multiple meta filters) | | ||
| | `orderby` | string | `''` | Sort by: `'name'`, `'label'`, or `'category'`. Empty = no sorting | | ||
| | `order` | string | `'ASC'` | Sort direction: `'ASC'` or `'DESC'` | | ||
| | `limit` | int | `-1` | Maximum results to return. `-1` = unlimited | | ||
| | `offset` | int | `0` | Number of results to skip | | ||
|  | ||
| ## Basic Filtering | ||
|  | ||
| ### Filter by Category | ||
|  | ||
| ```php | ||
| // Get all data retrieval abilities | ||
| $abilities = wp_get_abilities( array( 'category' => 'data-retrieval' ) ); | ||
|  | ||
| // Get all communication abilities | ||
| $abilities = wp_get_abilities( array( 'category' => 'communication' ) ); | ||
|  | ||
| // Get abilities from multiple categories (OR logic) | ||
| $abilities = wp_get_abilities( array( | ||
| 'category' => array( 'math', 'communication', 'data-retrieval' ), | ||
| ) ); | ||
| ``` | ||
|  | ||
| ### Filter by Namespace | ||
|  | ||
| Namespace is the part before the `/` in the ability name (e.g., `my-plugin` in `my-plugin/send-email`). | ||
|  | ||
| ```php | ||
| // Get all abilities from your plugin | ||
| $abilities = wp_get_abilities( array( 'namespace' => 'my-plugin' ) ); | ||
|  | ||
| // Get all WooCommerce abilities | ||
| $abilities = wp_get_abilities( array( 'namespace' => 'woocommerce' ) ); | ||
|  | ||
| // Get abilities from multiple namespaces (OR logic) | ||
| $abilities = wp_get_abilities( array( | ||
| 'namespace' => array( 'my-plugin', 'woocommerce', 'jetpack' ), | ||
| ) ); | ||
| ``` | ||
|  | ||
| ### Search Abilities | ||
|  | ||
| Search is case-insensitive and searches in name, label, and description: | ||
|  | ||
| ```php | ||
| // Find all abilities related to email | ||
| $abilities = wp_get_abilities( array( 'search' => 'email' ) ); | ||
|  | ||
| // Find payment-related abilities | ||
| $abilities = wp_get_abilities( array( 'search' => 'payment' ) ); | ||
| ``` | ||
|  | ||
| ### Combine Multiple Filters | ||
|  | ||
| Filters are cumulative (AND logic): | ||
|  | ||
| ```php | ||
| // Get communication abilities from my-plugin only | ||
| $abilities = wp_get_abilities( array( | ||
| 'category' => 'communication', | ||
| 'namespace' => 'my-plugin', | ||
| ) ); | ||
|  | ||
| // Search for email abilities in the communication category | ||
| $abilities = wp_get_abilities( array( | ||
| 'category' => 'communication', | ||
| 'search' => 'email', | ||
| ) ); | ||
| ``` | ||
|  | ||
| ## Meta Filtering | ||
|  | ||
| Filter abilities by their meta properties, including `show_in_rest`, `annotations`, and custom meta keys. All meta filters use AND logic — abilities must match all specified criteria. | ||
|  | ||
| ### Filter by REST API Visibility | ||
|  | ||
| ```php | ||
| // Get abilities exposed in REST API | ||
| $abilities = wp_get_abilities( array( | ||
| 'meta' => array( | ||
| 'show_in_rest' => true, | ||
| ), | ||
| ) ); | ||
|  | ||
| // Get abilities hidden from REST API | ||
| $abilities = wp_get_abilities( array( | ||
| 'meta' => array( | ||
| 'show_in_rest' => false, | ||
| ), | ||
| ) ); | ||
| ``` | ||
|  | ||
| ### Filter by Annotations | ||
|  | ||
| ```php | ||
| // Get readonly abilities | ||
| $abilities = wp_get_abilities( array( | ||
| 'meta' => array( | ||
| 'annotations' => array( | ||
| 'readonly' => true, | ||
| ), | ||
| ), | ||
| ) ); | ||
|  | ||
| // Get non-destructive, idempotent abilities | ||
| $abilities = wp_get_abilities( array( | ||
| 'meta' => array( | ||
| 'annotations' => array( | ||
| 'destructive' => false, | ||
| 'idempotent' => true, | ||
| ), | ||
| ), | ||
| ) ); | ||
| ``` | ||
|  | ||
| ### Combine Multiple Meta Filters | ||
|  | ||
| When you specify multiple meta conditions, abilities must match all of them (AND logic): | ||
|  | ||
| ```php | ||
| // Get readonly abilities that are exposed in REST API | ||
| $abilities = wp_get_abilities( array( | ||
| 'meta' => array( | ||
| 'show_in_rest' => true, | ||
| 'annotations' => array( | ||
| 'readonly' => true, | ||
| ), | ||
| ), | ||
| ) ); | ||
|  | ||
| // Get REST-enabled, readonly, idempotent abilities | ||
| $abilities = wp_get_abilities( array( | ||
| 'meta' => array( | ||
| 'show_in_rest' => true, | ||
| 'annotations' => array( | ||
| 'readonly' => true, | ||
| 'idempotent' => true, | ||
| ), | ||
| ), | ||
| ) ); | ||
| ``` | ||
|  | ||
| ### Filter by Custom Meta | ||
|  | ||
| You can filter by any custom meta keys you've added to abilities: | ||
|  | ||
| ```php | ||
| $abilities = wp_get_abilities( array( | ||
| 'meta' => array( | ||
| 'custom_key' => 'custom_value', | ||
| 'another_meta' => 'another_value', | ||
| ), | ||
| ) ); | ||
| ``` | ||
|  | ||
| ## Ordering and Pagination | ||
|  | ||
| ```php | ||
| // Order by name, label, or category | ||
| $abilities = wp_get_abilities( array( | ||
| 'orderby' => 'label', | ||
| 'order' => 'ASC', // or 'DESC' | ||
| ) ); | ||
|  | ||
| // Paginate results | ||
| $abilities = wp_get_abilities( array( | ||
| 'limit' => 10, | ||
| 'offset' => 0, | ||
| ) ); | ||
| ``` | ||
|  | ||
| ## See Also | ||
|  | ||
| - [Registering Abilities](3.registering-abilities.md) - How to register abilities with proper metadata | ||
| - [Using Abilities](4.using-abilities.md) - Basic ability usage, execution, and permissions | ||
| - [Registering Categories](7.registering-categories.md) - How to register ability categories | ||
| - [REST API](5.rest-api.md) - REST API endpoints for abilities | ||
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
      
      Oops, something went wrong.
        
    
  
  Add this suggestion to a batch that can be applied as a single commit.
  This suggestion is invalid because no changes were made to the code.
  Suggestions cannot be applied while the pull request is closed.
  Suggestions cannot be applied while viewing a subset of changes.
  Only one suggestion per line can be applied in a batch.
  Add this suggestion to a batch that can be applied as a single commit.
  Applying suggestions on deleted lines is not supported.
  You must change the existing code in this line in order to create a valid suggestion.
  Outdated suggestions cannot be applied.
  This suggestion has been applied or marked resolved.
  Suggestions cannot be applied from pending reviews.
  Suggestions cannot be applied on multi-line comments.
  Suggestions cannot be applied while the pull request is queued to merge.
  Suggestion cannot be applied right now. Please check back later.
  
    
  
    
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a specific need for pagination?
I see that you're trying to mirror
WP_Queryet al (versus adding sorting/filtering as registry methods) but abilities are in a PHP array, not a database. Do we really need a shortcut for what's essentially anarray_slice()?Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Filtering abilities are the most crucial aspect from my perspective. Ordering and pagination are nice-to-haves, but I want to acknowledge that they fit well together in the proposed implementation, as they allow easy selection of a precise number of abilities that meet specific criteria, which might be useful when passing data to an LLM with limited context. @galatanovidiu might have a better overview of the real needs based on the work he has done for the MCP Adapter.