Skip to content

Commit 694b717

Browse files
include possible meta keys and taxonomies on the schema
1 parent aaca9cd commit 694b717

2 files changed

Lines changed: 77 additions & 14 deletions

File tree

src/wp-includes/abilities/class-wp-post-type-abilities.php

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,11 @@ private static function build_get_input_schema( WP_Post_Type $post_type_object )
143143
$query_properties = array(
144144
'tax' => self::build_query_group_schema(
145145
__( 'Taxonomy query to filter posts by taxonomy terms.' ),
146-
self::build_tax_clause_schema()
146+
self::build_tax_clause_schema( $slug )
147147
),
148148
'meta' => self::build_query_group_schema(
149149
__( 'Meta query to filter posts by post meta values.' ),
150-
self::build_meta_clause_schema()
150+
self::build_meta_clause_schema( $slug )
151151
),
152152
'date' => self::build_date_query_schema(),
153153
);
@@ -310,17 +310,25 @@ private static function build_query_group_schema( string $description, array $le
310310
*
311311
* @since 7.0.0
312312
*
313+
* @param string $post_type_slug The post type slug.
313314
* @return array The JSON schema for a taxonomy query clause.
314315
*/
315-
private static function build_tax_clause_schema(): array {
316+
private static function build_tax_clause_schema( string $post_type_slug ): array {
317+
$allowed_taxonomies = self::get_allowed_taxonomies( $post_type_slug );
318+
319+
$taxonomy_schema = array(
320+
'type' => 'string',
321+
'description' => __( 'Taxonomy slug to query.' ),
322+
);
323+
if ( ! empty( $allowed_taxonomies ) ) {
324+
$taxonomy_schema['enum'] = $allowed_taxonomies;
325+
}
326+
316327
return array(
317328
'type' => 'object',
318329
'required' => array( 'taxonomy', 'terms' ),
319330
'properties' => array(
320-
'taxonomy' => array(
321-
'type' => 'string',
322-
'description' => __( 'Taxonomy slug to query.' ),
323-
),
331+
'taxonomy' => $taxonomy_schema,
324332
'terms' => array(
325333
'type' => 'array',
326334
'description' => __( 'Taxonomy terms to match.' ),
@@ -352,17 +360,25 @@ private static function build_tax_clause_schema(): array {
352360
*
353361
* @since 7.0.0
354362
*
363+
* @param string $post_type_slug The post type slug.
355364
* @return array The JSON schema for a meta query clause.
356365
*/
357-
private static function build_meta_clause_schema(): array {
366+
private static function build_meta_clause_schema( string $post_type_slug ): array {
367+
$allowed_meta_keys = self::get_allowed_meta_keys( $post_type_slug );
368+
369+
$key_schema = array(
370+
'type' => 'string',
371+
'description' => __( 'Meta key to query.' ),
372+
);
373+
if ( ! empty( $allowed_meta_keys ) ) {
374+
$key_schema['enum'] = $allowed_meta_keys;
375+
}
376+
358377
return array(
359378
'type' => 'object',
360379
'required' => array( 'key' ),
361380
'properties' => array(
362-
'key' => array(
363-
'type' => 'string',
364-
'description' => __( 'Meta key to query.' ),
365-
),
381+
'key' => $key_schema,
366382
'value' => array(
367383
'type' => array( 'string', 'integer', 'array' ),
368384
'description' => __( 'Meta value to match. Use an array for BETWEEN, NOT BETWEEN, IN, and NOT IN comparisons.' ),

tests/phpunit/tests/abilities-api/wpPostTypeAbilitiesRest.php

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,14 @@ class Tests_Abilities_API_WpPostTypeAbilitiesRest extends WP_Test_REST_TestCase
4545
* @param WP_UnitTest_Factory $factory Test factory.
4646
*/
4747
public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ): void {
48+
// Unregister any existing abilities and categories to start fresh.
49+
foreach ( wp_get_abilities() as $ability ) {
50+
wp_unregister_ability( $ability->get_name() );
51+
}
52+
foreach ( wp_get_ability_categories() as $category ) {
53+
wp_unregister_ability_category( $category->get_slug() );
54+
}
55+
4856
// Ensure core abilities are registered.
4957
remove_action( 'wp_abilities_api_categories_init', '_unhook_core_ability_categories_registration', 1 );
5058
remove_action( 'wp_abilities_api_init', '_unhook_core_abilities_registration', 1 );
@@ -198,6 +206,43 @@ public function set_up(): void {
198206
'show_in_abilities' => true,
199207
)
200208
);
209+
210+
// Unregister all existing abilities so we can re-register with updated schema.
211+
foreach ( wp_get_abilities() as $ability ) {
212+
wp_unregister_ability( $ability->get_name() );
213+
}
214+
215+
// Remove core abilities registration to prevent ALL abilities from being registered
216+
// when we only want to re-register post type abilities with updated schema.
217+
remove_action( 'wp_abilities_api_init', 'wp_register_core_abilities' );
218+
219+
// Simulate the init action to allow re-registration without "doing it wrong" warning.
220+
$this->simulate_doing_wp_abilities_init_action();
221+
222+
// Re-register all post type abilities so the schema includes the meta keys enum.
223+
WP_Post_Type_Abilities::register();
224+
225+
// Clean up the simulated action.
226+
$this->end_simulated_wp_abilities_init_action();
227+
}
228+
229+
/**
230+
* Simulates the `wp_abilities_api_init` action.
231+
*
232+
* This makes `doing_action('wp_abilities_api_init')` return true without
233+
* firing all hooks registered on that action.
234+
*/
235+
private function simulate_doing_wp_abilities_init_action(): void {
236+
global $wp_current_filter;
237+
$wp_current_filter[] = 'wp_abilities_api_init';
238+
}
239+
240+
/**
241+
* Ends the simulated `wp_abilities_api_init` action.
242+
*/
243+
private function end_simulated_wp_abilities_init_action(): void {
244+
global $wp_current_filter;
245+
array_pop( $wp_current_filter );
201246
}
202247

203248
/**
@@ -628,7 +673,8 @@ public function test_meta_query_with_invalid_key_returns_error(): void {
628673
$this->assertSame( 400, $response->get_status() );
629674

630675
$data = $response->get_data();
631-
$this->assertSame( 'invalid_meta_key', $data['code'] );
676+
// Schema validation catches invalid meta keys.
677+
$this->assertSame( 'ability_invalid_input', $data['code'] );
632678
}
633679

634680
/**
@@ -692,7 +738,8 @@ public function test_tax_query_with_non_public_taxonomy_returns_error(): void {
692738
$this->assertSame( 400, $response->get_status() );
693739

694740
$data = $response->get_data();
695-
$this->assertSame( 'invalid_taxonomy', $data['code'] );
741+
// Schema validation catches non-public taxonomies.
742+
$this->assertSame( 'ability_invalid_input', $data['code'] );
696743

697744
// Clean up.
698745
unregister_taxonomy( 'private_tax' );

0 commit comments

Comments
 (0)