-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds suggestions for categories and formats to LinkControl (#22600)
* adds suggestions for categories and formats adds a format search handler adds a category search handler hooks the new handlers in the search endpoint updates LinkControl's fetchLinkSuggestions to handle formats and categories as well * adds concurent search for suggestions also searches for category matches via term query and limits formats with no items * generalizes the category search handler to all terms * lint * adds links to terms search results * adds default listing for empty searches and a stup test class * shows empty terms in results for search and tests pass * REST API: Add pagination to term search handler * Navigation: Remove unnecessary async * REST API: Fix doc comments * REST API: Use null instead of empty string * REST API: Add pagination to page format search handler * REST API: Fix term search handler tests * REST API: Add post format search handler tests * REST API: Only show term subtypes which are REST API enabled * REST API: Use WP_Term_Query's 'search' param * REST API: Use wp_count_terms() instead of WP_Term_Query * REST API: Set fields=all when fetching terms so that they're cached * REST API: Use rest_get_route_for_term() instead of custom method * REST API: Pass forwards-compatible array to rest_post_format_search_query * REST API: Improve stability of WP_REST_Post_Format_Search_Handler tests * REST API: Add test for when no term matches search query * Navigation: Don't call /v2/search?type=post-format if theme does not support formats * REST API: Fix post format handler tests Co-authored-by: Robert Anderson <robert@noisysocks.com>
- Loading branch information
1 parent
d20270f
commit a0f36df
Showing
8 changed files
with
809 additions
and
25 deletions.
There are no files selected for viewing
This file contains 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,120 @@ | ||
<?php | ||
/** | ||
* REST API: WP_REST_Post_Format_Search_Handler class | ||
* | ||
* @package Gutenberg | ||
*/ | ||
|
||
/** | ||
* Core class representing a search handler for post formats in the REST API. | ||
* | ||
* @see WP_REST_Search_Handler | ||
*/ | ||
class WP_REST_Post_Format_Search_Handler extends WP_REST_Search_Handler { | ||
|
||
/** | ||
* Constructor. | ||
*/ | ||
public function __construct() { | ||
$this->type = 'post-format'; | ||
} | ||
|
||
/** | ||
* Searches the object type content for a given search request. | ||
* | ||
* @param WP_REST_Request $request Full REST request. | ||
* @return array Associative array containing an `WP_REST_Search_Handler::RESULT_IDS` containing | ||
* an array of found IDs and `WP_REST_Search_Handler::RESULT_TOTAL` containing the | ||
* total count for the matching search results. | ||
*/ | ||
public function search_items( WP_REST_Request $request ) { | ||
$format_strings = get_post_format_strings(); | ||
$format_slugs = array_keys( $format_strings ); | ||
|
||
$query_args = array(); | ||
|
||
if ( ! empty( $request['search'] ) ) { | ||
$query_args['search'] = $request['search']; | ||
} | ||
|
||
/** | ||
* Filters the query arguments for a search request. | ||
* | ||
* Enables adding extra arguments or setting defaults for a post format search request. | ||
* | ||
* @param array $query_args Key value array of query var to query value. | ||
* @param WP_REST_Request $request The request used. | ||
*/ | ||
$query_args = apply_filters( 'rest_post_format_search_query', $query_args, $request ); | ||
|
||
$found_ids = array(); | ||
foreach ( $format_slugs as $index => $format_slug ) { | ||
if ( ! empty( $query_args['search'] ) ) { | ||
$format_string = get_post_format_string( $format_slug ); | ||
$format_slug_match = stripos( $format_slug, $query_args['search'] ) !== false; | ||
$format_string_match = stripos( $format_string, $query_args['search'] ) !== false; | ||
if ( ! $format_slug_match && ! $format_string_match ) { | ||
continue; | ||
} | ||
} | ||
|
||
$format_link = get_post_format_link( $format_slug ); | ||
if ( $format_link ) { | ||
// Formats don't have an ID, so fake one using the array index. | ||
$found_ids[] = $index + 1; | ||
} | ||
} | ||
|
||
$page = (int) $request['page']; | ||
$per_page = (int) $request['per_page']; | ||
|
||
return array( | ||
self::RESULT_IDS => array_slice( $found_ids, ( $page - 1 ) * $per_page, $per_page ), | ||
self::RESULT_TOTAL => count( $found_ids ), | ||
); | ||
} | ||
|
||
/** | ||
* Prepares the search result for a given ID. | ||
* | ||
* @param int $id Item ID. | ||
* @param array $fields Fields to include for the item. | ||
* @return array Associative array containing all fields for the item. | ||
*/ | ||
public function prepare_item( $id, array $fields ) { | ||
$format_strings = get_post_format_strings(); | ||
$format_slugs = array_keys( $format_strings ); | ||
$format_slug = $format_slugs[ $id - 1 ]; | ||
|
||
$data = array(); | ||
|
||
if ( in_array( WP_REST_Search_Controller::PROP_ID, $fields, true ) ) { | ||
$data[ WP_REST_Search_Controller::PROP_ID ] = $id; | ||
} | ||
|
||
if ( in_array( WP_REST_Search_Controller::PROP_TITLE, $fields, true ) ) { | ||
$data[ WP_REST_Search_Controller::PROP_TITLE ] = get_post_format_string( $format_slug ); | ||
} | ||
|
||
if ( in_array( WP_REST_Search_Controller::PROP_URL, $fields, true ) ) { | ||
$data[ WP_REST_Search_Controller::PROP_URL ] = get_post_format_link( $format_slug ); | ||
} | ||
|
||
if ( in_array( WP_REST_Search_Controller::PROP_TYPE, $fields, true ) ) { | ||
$data[ WP_REST_Search_Controller::PROP_TYPE ] = $this->type; | ||
} | ||
|
||
return $data; | ||
} | ||
|
||
/** | ||
* Prepares links for the search result. | ||
* | ||
* @param string $id Item ID. | ||
* @return array Links for the given item. | ||
*/ | ||
public function prepare_item_links( $id ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable | ||
return array(); | ||
} | ||
|
||
} |
This file contains 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,142 @@ | ||
<?php | ||
/** | ||
* REST API: WP_REST_Terms_Search_Handler class | ||
* | ||
* @package Gutenberg | ||
*/ | ||
|
||
/** | ||
* Core class representing a search handler for term in the REST API. | ||
* | ||
* @see WP_REST_Search_Handler | ||
*/ | ||
class WP_REST_Term_Search_Handler extends WP_REST_Search_Handler { | ||
|
||
/** | ||
* Constructor. | ||
*/ | ||
public function __construct() { | ||
$this->type = 'term'; | ||
|
||
$this->subtypes = array_values( | ||
get_taxonomies( | ||
array( | ||
'public' => true, | ||
'show_in_rest' => true, | ||
), | ||
'names' | ||
) | ||
); | ||
} | ||
|
||
/** | ||
* Searches the object type content for a given search request. | ||
* | ||
* @param WP_REST_Request $request Full REST request. | ||
* @return array Associative array containing an `WP_REST_Search_Handler::RESULT_IDS` containing | ||
* an array of found IDs and `WP_REST_Search_Handler::RESULT_TOTAL` containing the | ||
* total count for the matching search results. | ||
*/ | ||
public function search_items( WP_REST_Request $request ) { | ||
$taxonomies = $request[ WP_REST_Search_Controller::PROP_SUBTYPE ]; | ||
if ( in_array( WP_REST_Search_Controller::TYPE_ANY, $taxonomies, true ) ) { | ||
$taxonomies = $this->subtypes; | ||
} | ||
|
||
$page = (int) $request['page']; | ||
$per_page = (int) $request['per_page']; | ||
|
||
$query_args = array( | ||
'taxonomy' => $taxonomies, | ||
'hide_empty' => false, | ||
'offset' => ( $page - 1 ) * $per_page, | ||
'number' => $per_page, | ||
); | ||
|
||
if ( ! empty( $request['search'] ) ) { | ||
$query_args['search'] = $request['search']; | ||
} | ||
|
||
/** | ||
* Filters the query arguments for a search request. | ||
* | ||
* Enables adding extra arguments or setting defaults for a term search request. | ||
* | ||
* @param array $query_args Key value array of query var to query value. | ||
* @param WP_REST_Request $request The request used. | ||
*/ | ||
$query_args = apply_filters( 'rest_term_search_query', $query_args, $request ); | ||
|
||
$query = new WP_Term_Query(); | ||
$found_terms = $query->query( $query_args ); | ||
$found_ids = wp_list_pluck( $found_terms, 'term_id' ); | ||
|
||
unset( $query_args['offset'], $query_args['number'] ); | ||
|
||
$total = wp_count_terms( $query_args ); | ||
|
||
// wp_count_terms() can return a falsey value when the term has no children. | ||
if ( ! $total ) { | ||
$total = 0; | ||
} | ||
|
||
return array( | ||
self::RESULT_IDS => $found_ids, | ||
self::RESULT_TOTAL => $total, | ||
); | ||
} | ||
|
||
/** | ||
* Prepares the search result for a given ID. | ||
* | ||
* @param int $id Item ID. | ||
* @param array $fields Fields to include for the item. | ||
* @return array Associative array containing all fields for the item. | ||
*/ | ||
public function prepare_item( $id, array $fields ) { | ||
$term = get_term( $id ); | ||
|
||
$data = array(); | ||
|
||
if ( in_array( WP_REST_Search_Controller::PROP_ID, $fields, true ) ) { | ||
$data[ WP_REST_Search_Controller::PROP_ID ] = (int) $id; | ||
} | ||
if ( in_array( WP_REST_Search_Controller::PROP_TITLE, $fields, true ) ) { | ||
$data[ WP_REST_Search_Controller::PROP_TITLE ] = $term->name; | ||
} | ||
if ( in_array( WP_REST_Search_Controller::PROP_URL, $fields, true ) ) { | ||
$data[ WP_REST_Search_Controller::PROP_URL ] = get_term_link( $id ); | ||
} | ||
if ( in_array( WP_REST_Search_Controller::PROP_TYPE, $fields, true ) ) { | ||
$data[ WP_REST_Search_Controller::PROP_TYPE ] = $term->taxonomy; | ||
} | ||
|
||
return $data; | ||
} | ||
|
||
/** | ||
* Prepares links for the search result of a given ID. | ||
* | ||
* @param int $id Item ID. | ||
* @return array Links for the given item. | ||
*/ | ||
public function prepare_item_links( $id ) { | ||
$term = get_term( $id ); | ||
|
||
$links = array(); | ||
|
||
$item_route = rest_get_route_for_term( $term ); | ||
if ( $item_route ) { | ||
$links['self'] = array( | ||
'href' => rest_url( $item_route ), | ||
'embeddable' => true, | ||
); | ||
} | ||
|
||
$links['about'] = array( | ||
'href' => rest_url( sprintf( 'wp/v2/taxonomies/%s', $term->taxonomy ) ), | ||
); | ||
|
||
return $links; | ||
} | ||
} |
This file contains 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 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 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.