WordPress.org

Make WordPress Core

Opened 3 months ago

Last modified 3 months ago

#53117 new defect (bug)

Post types which are not public, but which are show_in_rest and publicly_queryable and not exclude_from_search, do not appear in REST API search endpoint

Reported by: benlk Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 5.0
Component: REST API Keywords:
Focuses: rest-api Cc:

Description

I have a custom post type "tease" which is registered with the following code:

	register_post_type(
		'tease',
		array(
			'menu_icon'           => 'dashicons-update',
			'exclude_from_search' => false, // allow us to include these in query results.
			'publicly_queryable'  => true,
			'show_in_nav_menus'   => false, // Don't allow to slot in nav.
			'show_ui'             => true, // Show in admin UI.
			'has_archive'         => false,
			'show_in_rest'        => true,
			'supports'            => array( 'title', 'editor', 'custom-fields' ),
			'map_meta_cap'        => true, // Set to true, so that default capabilities are mapped from posts to Teases.
			'capability_type'     => 'post',
			'taxonomies'          => array( 'category', 'post_tag' ),
		)
	);

Given that it is publicly queryable, shows in the REST API, and is not excluded from search, I would expect to be able to perform a search using the REST API for posts of this type.

However, a search for posts or teases matching the word "patience" returns an error message: /wp-json/wp/v2/search?search=patience&subtype=post,tease

{“code”:“rest_invalid_param”,“message”:“Invalid parameter(s): subtype”,“data”:{“status”:400,“params”:{“subtype”:“subtype[1] is not one of post, page, category, post_tag, and any.“},“details”:{“subtype”:{“code”:“rest_not_in_enum”,“message”:“subtype[1] is not one of post, page, category, post_tag, and any.“,”data”:null}}}}

I get the same error message when I replace "tease" in that URL with a nonexistent post type.

If I modify the post-type registration with 'public' => true, then the search completes.

I'd like to credit @delipeelia for finding the potential cause: WP_REST_Post_Search_Handler only looks for post types which are public or show_in_rest: https://core.trac.wordpress.org/browser/trunk/src/wp-includes/rest-api/search/class-wp-rest-post-search-handler.php#L32

Changing /wp-includes/rest-api/search/class-wp-rest-post-search-handler.php to the following allows the search to work as I would expect it to, but I'm not sure that this is the right way to handle it.

				get_post_types(
					array(
						'exclude_from_search' => false,
						'show_in_rest'        => true,
					),
					'names'
				)

It does seem kind of weird to want to be able to search a non-public post type; the use case here is building a post-picker in the Block Editor that can pick posts or teases, without exposing the existence of teases to visitors to the site. For now, I've marked the post type as public, but that the REST API doesn't allow searching of posts which are marked as searchable does seem like a bug.

Change History (2)

#1 @TimothyBlynJacobs
3 months ago

  • Version changed from 5.7.1 to 5.0

That seems like a sensible change to me. @flixos90 Do you have thoughts?

#2 @benlk
3 months ago

Minor correction: the person I credit with finding the source of the bug is @felipeelia, not the misspelled delipeelia

Note: See TracTickets for help on using tickets.