From c0fc1c2a697be26bf4eb28ed3d4db50fe31ca284 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Wed, 21 Feb 2024 10:08:44 +0100 Subject: [PATCH 01/21] Initial effort --- ...ss-wp-rest-post-archive-search-handler.php | 149 ++++++++++++++++++ lib/experimental/rest-api.php | 13 ++ lib/load.php | 1 + .../src/navigation-link/index.php | 27 ++++ .../__experimental-fetch-link-suggestions.ts | 25 ++- 5 files changed, 214 insertions(+), 1 deletion(-) create mode 100644 lib/experimental/class-wp-rest-post-archive-search-handler.php diff --git a/lib/experimental/class-wp-rest-post-archive-search-handler.php b/lib/experimental/class-wp-rest-post-archive-search-handler.php new file mode 100644 index 00000000000000..de62b47bb7de7a --- /dev/null +++ b/lib/experimental/class-wp-rest-post-archive-search-handler.php @@ -0,0 +1,149 @@ +type = 'post-type-archive'; + + $this->subtypes = array( 'post', 'page', 'book', 'product' ); + } + + /** + * Searches terms for a given search request. + * + * @since 5.6.0 + * + * @param WP_REST_Request $request Full REST request. + * @return array { + * Associative array containing found IDs and total count for the matching search results. + * + * @type int[] $ids Found term IDs. + * @type string|int|WP_Error $total Numeric string containing the number of terms in that + * taxonomy, 0 if there are no results, or WP_Error if + * the requested taxonomy does not exist. + * } + */ + 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; + + $args = array( + 'public' => true, + 'has_archive' => true, + 'show_in_rest' => true, + '_builtin' => false, + ); + + $post_types = get_post_types( $args, 'objects' ); + + $search_results = array(); + + + foreach ( $post_types as $post_type ) { + // Check if the search term matches the post type name. + if ( stripos( $post_type->name, $search_term ) !== false ) { + $search_results[] = array( + 'post_type' => $post_type->name, + 'label' => $post_type->label, + 'description' => $post_type->description, + 'has_archive' => $post_type->has_archive, + // Add more information as needed. + ); + } + } + + unset( $query_args['paged'], $query_args['posts_per_page'] ); + + $total = count( $search_results ); + + return array( + self::RESULT_IDS => $found_ids, + self::RESULT_TOTAL => $total, + ); + } + + /** + * Prepares the search result for a given term ID. + * + * @since 5.6.0 + * + * @param int $id Term ID. + * @param array $fields Fields to include for the term. + * @return array { + * Associative array containing fields for the term based on the `$fields` parameter. + * + * @type int $id Optional. Term ID. + * @type string $title Optional. Term name. + * @type string $url Optional. Term permalink URL. + * @type string $type Optional. Term taxonomy name. + * } + */ + public function prepare_item( $id, array $fields ) { + $post_type = get_post_type_object( $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 ] = $post_type->name; + } + if ( in_array( WP_REST_Search_Controller::PROP_URL, $fields, true ) ) { + $data[ WP_REST_Search_Controller::PROP_URL ] = get_post_type_archive_link( $id ); + } + if ( in_array( WP_REST_Search_Controller::PROP_TYPE, $fields, true ) ) { + $data[ WP_REST_Search_Controller::PROP_TYPE ] = $post_type->slug; + } + + return $data; + } + + /** + * Prepares links for the search result of a given ID. + * + * @since 5.6.0 + * + * @param int $id Item ID. + * @return array[] Array of link arrays 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; + } +} diff --git a/lib/experimental/rest-api.php b/lib/experimental/rest-api.php index 6bb2947f889147..d9c21be17570ba 100644 --- a/lib/experimental/rest-api.php +++ b/lib/experimental/rest-api.php @@ -20,6 +20,9 @@ function gutenberg_register_block_editor_settings() { add_action( 'rest_api_init', 'gutenberg_register_block_editor_settings' ); + + + /** * Shim for get_sample_permalink() to add support for auto-draft status. * @@ -92,3 +95,13 @@ function gutenberg_auto_draft_get_sample_permalink( $permalink, $id, $title, $na return $permalink; } add_filter( 'get_sample_permalink', 'gutenberg_auto_draft_get_sample_permalink', 10, 5 ); + + + +function register_post_archive_rest_search_handler( $handlers ) { + $handlers['post_type_archive'] = new WP_REST_Post_Archive_Search_Handler(); + + + return $handlers; +} +add_filter( 'wp_rest_search_handlers', 'register_post_archive_rest_search_handler' ); \ No newline at end of file diff --git a/lib/load.php b/lib/load.php index 6236f0eb04b3c6..ca1907518260d7 100644 --- a/lib/load.php +++ b/lib/load.php @@ -49,6 +49,7 @@ function gutenberg_is_experiment_enabled( $name ) { // WordPress 6.8 compat. require __DIR__ . '/compat/wordpress-6.8/block-comments.php'; require __DIR__ . '/compat/wordpress-6.8/class-gutenberg-rest-comment-controller-6-8.php'; + require_once __DIR__ . '/experimental/class-wp-rest-post-archive-search-handler.php'; // Plugin specific code. require_once __DIR__ . '/class-wp-rest-global-styles-controller-gutenberg.php'; diff --git a/packages/block-library/src/navigation-link/index.php b/packages/block-library/src/navigation-link/index.php index 5653e04fca88a3..5138e7214bacdd 100644 --- a/packages/block-library/src/navigation-link/index.php +++ b/packages/block-library/src/navigation-link/index.php @@ -371,9 +371,13 @@ function block_core_navigation_link_filter_variations( $variations, $block_type * @return array */ function block_core_navigation_link_build_variations() { + + $post_types = get_post_types( array( 'show_in_nav_menus' => true ), 'objects' ); $taxonomies = get_taxonomies( array( 'show_in_nav_menus' => true ), 'objects' ); + + /* * Use two separate arrays as a way to order the variations in the UI. * Known variations (like Post Link and Page Link) are added to the @@ -392,6 +396,29 @@ function block_core_navigation_link_build_variations() { $variations[] = $variation; } } + + // If any of the post types have `has_archive` set to true then add a post-type-archive variation + $has_archive = array_filter( + $post_types, + function( $post_type ) { + return $post_type->has_archive; + } + ); + if ( $has_archive ) { + $variation = array( + 'name' => 'post-type-archive', + 'title' => __( 'Post Type Archive Link' ), + 'description' => __( 'A link to a post type archive' ), + 'attributes' => array( + 'type' => 'all', + 'kind' => 'post-type-archive', + ), + ); + $variations[] = $variation; + } + + + } if ( $taxonomies ) { foreach ( $taxonomies as $taxonomy ) { diff --git a/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.ts b/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.ts index e1a166ee272dbe..205ce16de6d626 100644 --- a/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.ts +++ b/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.ts @@ -21,7 +21,7 @@ export type SearchOptions = { /** * Filters by search type. */ - type?: 'attachment' | 'post' | 'term' | 'post-format'; + type?: 'attachment' | 'post' | 'term' | 'post-format' | 'post-type-archive'; /** * Slug of the post-type or taxonomy. */ @@ -240,6 +240,29 @@ export default async function fetchLinkSuggestions( ); } + if ( ! type || type === 'post-type-archive' ) { + queries.push( + apiFetch< SearchAPIResult[] >( { + path: addQueryArgs( '/wp/v2/search', { + search, + page, + per_page: perPage, + type: 'post-type-archive', + subtype, + } ), + } ) + .then( ( results ) => { + return results.map( ( result ) => { + return { + ...result, + meta: { kind: 'post-type-archive', subtype }, + }; + } ); + } ) + .catch( () => [] ) // Fail by returning no results. + ); + } + const responses = await Promise.all( queries ); let results = responses.flat(); From 35ab8805a2c46b99fda0885be6b70bf571b25e02 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Thu, 7 Nov 2024 12:23:38 +0000 Subject: [PATCH 02/21] Temp debugging --- .../src/fetch/__experimental-fetch-link-suggestions.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.ts b/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.ts index 205ce16de6d626..86cfa88259d5b9 100644 --- a/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.ts +++ b/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.ts @@ -240,7 +240,13 @@ export default async function fetchLinkSuggestions( ); } - if ( ! type || type === 'post-type-archive' ) { + const DEBUGGING_ONLY_REMOVE_BEFORE_MERGE = true; + + if ( + DEBUGGING_ONLY_REMOVE_BEFORE_MERGE || + ! type || + type === 'post-type-archive' + ) { queries.push( apiFetch< SearchAPIResult[] >( { path: addQueryArgs( '/wp/v2/search', { From f6e1372eb18207c959a7f47810d5809a6e8282ea Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Thu, 7 Nov 2024 12:24:54 +0000 Subject: [PATCH 03/21] Basic initial REST API --- ...ss-wp-rest-post-archive-search-handler.php | 83 ++++++++----------- lib/experimental/rest-api.php | 2 +- 2 files changed, 35 insertions(+), 50 deletions(-) diff --git a/lib/experimental/class-wp-rest-post-archive-search-handler.php b/lib/experimental/class-wp-rest-post-archive-search-handler.php index de62b47bb7de7a..c40dbacf7c1617 100644 --- a/lib/experimental/class-wp-rest-post-archive-search-handler.php +++ b/lib/experimental/class-wp-rest-post-archive-search-handler.php @@ -23,12 +23,10 @@ class WP_REST_Post_Archive_Search_Handler extends WP_REST_Search_Handler { */ public function __construct() { $this->type = 'post-type-archive'; - - $this->subtypes = array( 'post', 'page', 'book', 'product' ); } /** - * Searches terms for a given search request. + * Searches post-type archives for a given search request. * * @since 5.6.0 * @@ -36,20 +34,17 @@ public function __construct() { * @return array { * Associative array containing found IDs and total count for the matching search results. * - * @type int[] $ids Found term IDs. - * @type string|int|WP_Error $total Numeric string containing the number of terms in that - * taxonomy, 0 if there are no results, or WP_Error if - * the requested taxonomy does not exist. + * @type int[] $ids Found post archive IDs. + * @type string|int|WP_Error $total Numeric string containing the number of post-type archives found, or WP_Error object. * } */ 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; + + $search_term = $request['search']; $args = array( 'public' => true, - 'has_archive' => true, + 'has_archive' => true, // ensure only posts with archive are considered. 'show_in_rest' => true, '_builtin' => false, ); @@ -57,45 +52,50 @@ public function search_items( WP_REST_Request $request ) { $post_types = get_post_types( $args, 'objects' ); $search_results = array(); + $found_ids = array(); + + if ( ! empty( $post_types ) ) { + foreach ( $post_types as $post_type ) { + // Check if the search term matches the post type name. + if ( empty( $search_term ) || stripos( $post_type->name, $search_term ) !== false ) { + $search_results[] = array( + 'post_type' => $post_type->name, + 'label' => $post_type->label, + 'description' => $post_type->description, + 'has_archive' => $post_type->has_archive, + 'link' => get_post_type_archive_link( $post_type->name ), + // Add more information as needed. + ); - foreach ( $post_types as $post_type ) { - // Check if the search term matches the post type name. - if ( stripos( $post_type->name, $search_term ) !== false ) { - $search_results[] = array( - 'post_type' => $post_type->name, - 'label' => $post_type->label, - 'description' => $post_type->description, - 'has_archive' => $post_type->has_archive, - // Add more information as needed. - ); + $found_ids[] = $post_type->name; + + } } } - unset( $query_args['paged'], $query_args['posts_per_page'] ); - - $total = count( $search_results ); + $page = (int) $request['page']; + $per_page = (int) $request['per_page']; return array( - self::RESULT_IDS => $found_ids, - self::RESULT_TOTAL => $total, + 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 term ID. + * Prepares the search result for a given post archive ID. * * @since 5.6.0 * * @param int $id Term ID. - * @param array $fields Fields to include for the term. + * @param array $fields Fields to include for the post archive. * @return array { - * Associative array containing fields for the term based on the `$fields` parameter. + * Associative array containing fields for the post-archive based on the `$fields` parameter. * - * @type int $id Optional. Term ID. - * @type string $title Optional. Term name. - * @type string $url Optional. Term permalink URL. - * @type string $type Optional. Term taxonomy name. + * @type int $id Optional. Post Archive ID. + * @type string $title Optional. Post Archive name. + * @type string $url Optional. Post Archive permalink URL. * } */ public function prepare_item( $id, array $fields ) { @@ -112,9 +112,6 @@ public function prepare_item( $id, array $fields ) { if ( in_array( WP_REST_Search_Controller::PROP_URL, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_URL ] = get_post_type_archive_link( $id ); } - if ( in_array( WP_REST_Search_Controller::PROP_TYPE, $fields, true ) ) { - $data[ WP_REST_Search_Controller::PROP_TYPE ] = $post_type->slug; - } return $data; } @@ -128,22 +125,10 @@ public function prepare_item( $id, array $fields ) { * @return array[] Array of link arrays 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; } } + diff --git a/lib/experimental/rest-api.php b/lib/experimental/rest-api.php index d9c21be17570ba..aeed8e3f316a53 100644 --- a/lib/experimental/rest-api.php +++ b/lib/experimental/rest-api.php @@ -99,7 +99,7 @@ function gutenberg_auto_draft_get_sample_permalink( $permalink, $id, $title, $na function register_post_archive_rest_search_handler( $handlers ) { - $handlers['post_type_archive'] = new WP_REST_Post_Archive_Search_Handler(); + $handlers[] = new WP_REST_Post_Archive_Search_Handler(); return $handlers; From 6750bb62b29fa380f7ba35dbfeb78816f71d19f9 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Thu, 7 Nov 2024 12:37:34 +0000 Subject: [PATCH 04/21] Avoid unused code --- ...ss-wp-rest-post-archive-search-handler.php | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/lib/experimental/class-wp-rest-post-archive-search-handler.php b/lib/experimental/class-wp-rest-post-archive-search-handler.php index c40dbacf7c1617..4aa07fe8e7ea5a 100644 --- a/lib/experimental/class-wp-rest-post-archive-search-handler.php +++ b/lib/experimental/class-wp-rest-post-archive-search-handler.php @@ -50,26 +50,14 @@ public function search_items( WP_REST_Request $request ) { ); $post_types = get_post_types( $args, 'objects' ); - - $search_results = array(); - $found_ids = array(); + $found_ids = array(); if ( ! empty( $post_types ) ) { foreach ( $post_types as $post_type ) { // Check if the search term matches the post type name. if ( empty( $search_term ) || stripos( $post_type->name, $search_term ) !== false ) { - $search_results[] = array( - 'post_type' => $post_type->name, - 'label' => $post_type->label, - 'description' => $post_type->description, - 'has_archive' => $post_type->has_archive, - 'link' => get_post_type_archive_link( $post_type->name ), - // Add more information as needed. - ); - $found_ids[] = $post_type->name; - } } } @@ -93,26 +81,30 @@ public function search_items( WP_REST_Request $request ) { * @return array { * Associative array containing fields for the post-archive based on the `$fields` parameter. * - * @type int $id Optional. Post Archive ID. + * @type string $id Optional. Post Archive Slug. * @type string $title Optional. Post Archive name. * @type string $url Optional. Post Archive permalink URL. * } */ public function prepare_item( $id, array $fields ) { + + $post_type = get_post_type_object( $id ); $data = array(); if ( in_array( WP_REST_Search_Controller::PROP_ID, $fields, true ) ) { - $data[ WP_REST_Search_Controller::PROP_ID ] = (int) $id; + $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 ] = $post_type->name; + $data[ WP_REST_Search_Controller::PROP_TITLE ] = $post_type->labels->archives; } if ( in_array( WP_REST_Search_Controller::PROP_URL, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_URL ] = get_post_type_archive_link( $id ); } + + return $data; } From f337c9327646e3123e0a39f2920caeeaf0906024 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Thu, 7 Nov 2024 12:49:45 +0000 Subject: [PATCH 05/21] Include post type in results --- .../class-wp-rest-post-archive-search-handler.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/experimental/class-wp-rest-post-archive-search-handler.php b/lib/experimental/class-wp-rest-post-archive-search-handler.php index 4aa07fe8e7ea5a..ca6e2fd1ffe177 100644 --- a/lib/experimental/class-wp-rest-post-archive-search-handler.php +++ b/lib/experimental/class-wp-rest-post-archive-search-handler.php @@ -88,7 +88,6 @@ public function search_items( WP_REST_Request $request ) { */ public function prepare_item( $id, array $fields ) { - $post_type = get_post_type_object( $id ); $data = array(); @@ -103,7 +102,9 @@ public function prepare_item( $id, array $fields ) { $data[ WP_REST_Search_Controller::PROP_URL ] = get_post_type_archive_link( $id ); } - + if ( in_array( WP_REST_Search_Controller::PROP_TYPE, $fields, true ) ) { + $data[ WP_REST_Search_Controller::PROP_TYPE ] = $post_type->name; + } return $data; } From 96fa58cb702af98cc0bed6cefe5e2e7d1640b6fa Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Thu, 7 Nov 2024 12:52:22 +0000 Subject: [PATCH 06/21] Parse search results --- .../__experimental-fetch-link-suggestions.ts | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.ts b/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.ts index 86cfa88259d5b9..9af7e88182610a 100644 --- a/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.ts +++ b/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.ts @@ -240,13 +240,7 @@ export default async function fetchLinkSuggestions( ); } - const DEBUGGING_ONLY_REMOVE_BEFORE_MERGE = true; - - if ( - DEBUGGING_ONLY_REMOVE_BEFORE_MERGE || - ! type || - type === 'post-type-archive' - ) { + if ( ! type || type === 'post-type-archive' ) { queries.push( apiFetch< SearchAPIResult[] >( { path: addQueryArgs( '/wp/v2/search', { @@ -254,14 +248,18 @@ export default async function fetchLinkSuggestions( page, per_page: perPage, type: 'post-type-archive', - subtype, } ), } ) .then( ( results ) => { return results.map( ( result ) => { return { - ...result, - meta: { kind: 'post-type-archive', subtype }, + id: result.id, + url: result.url, + title: + decodeEntities( result.title || '' ) || + __( '(no title)' ), + type: `${ result.type } archive`, + kind: 'post-type-archive', }; } ); } ) From 98bd9a815d4380eb8747ad8e7c3a7d499274d48e Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Thu, 7 Nov 2024 12:58:26 +0000 Subject: [PATCH 07/21] Include correct default results for Post Type Archive variation --- packages/block-library/src/navigation-link/link-ui.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/block-library/src/navigation-link/link-ui.js b/packages/block-library/src/navigation-link/link-ui.js index ee238c71ed28e0..905290fe294277 100644 --- a/packages/block-library/src/navigation-link/link-ui.js +++ b/packages/block-library/src/navigation-link/link-ui.js @@ -63,6 +63,9 @@ export function getSuggestionsQuery( type, kind ) { if ( kind === 'taxonomy' ) { return { type: 'term', subtype: type }; } + if ( kind === 'post-type-archive' ) { + return { type: 'post-type-archive', subtype: type }; + } if ( kind === 'post-type' ) { return { type: 'post', subtype: type }; } From 3e0a3386dbe8b3364bd4f81ebeb7265ffb11b604 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Thu, 7 Nov 2024 13:01:32 +0000 Subject: [PATCH 08/21] Remove redundan type --- packages/block-library/src/navigation-link/link-ui.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/navigation-link/link-ui.js b/packages/block-library/src/navigation-link/link-ui.js index 905290fe294277..cfcc1dd50af815 100644 --- a/packages/block-library/src/navigation-link/link-ui.js +++ b/packages/block-library/src/navigation-link/link-ui.js @@ -64,7 +64,7 @@ export function getSuggestionsQuery( type, kind ) { return { type: 'term', subtype: type }; } if ( kind === 'post-type-archive' ) { - return { type: 'post-type-archive', subtype: type }; + return { type: 'post-type-archive' }; } if ( kind === 'post-type' ) { return { type: 'post', subtype: type }; From 5c63265d6ef2dbf2663e6f0983e1227eb3f69986 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Thu, 7 Nov 2024 13:01:45 +0000 Subject: [PATCH 09/21] Add fallback icon for custom post types --- .../components/link-control/search-item.js | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/packages/block-editor/src/components/link-control/search-item.js b/packages/block-editor/src/components/link-control/search-item.js index fa8d1540b3daed..8ab2bf2accc877 100644 --- a/packages/block-editor/src/components/link-control/search-item.js +++ b/packages/block-editor/src/components/link-control/search-item.js @@ -13,6 +13,7 @@ import { file, home, verse, + customPostType, } from '@wordpress/icons'; import { __unstableStripHTML as stripHTML } from '@wordpress/dom'; import { safeDecodeURI, filterURLForDisplay, getPath } from '@wordpress/url'; @@ -41,18 +42,16 @@ function SearchItemIcon( { isURL, suggestion } ) { icon = verse; } } + } else { + icon = customPostType; } - if ( icon ) { - return ( - - ); - } - - return null; + return ( + + ); } /** From 320aecb6ee66e97ba7f01e60b1e0f2597a83591e Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Thu, 7 Nov 2024 16:02:55 +0000 Subject: [PATCH 10/21] Move handler and init code to 6.8 directories --- .../class-wp-rest-post-archive-search-handler.php | 0 lib/experimental/rest-api.php | 10 ---------- lib/load.php | 2 +- lib/rest-api.php | 10 ++++++++++ 4 files changed, 11 insertions(+), 11 deletions(-) rename lib/{experimental => compat/wordpress-6.8}/class-wp-rest-post-archive-search-handler.php (100%) diff --git a/lib/experimental/class-wp-rest-post-archive-search-handler.php b/lib/compat/wordpress-6.8/class-wp-rest-post-archive-search-handler.php similarity index 100% rename from lib/experimental/class-wp-rest-post-archive-search-handler.php rename to lib/compat/wordpress-6.8/class-wp-rest-post-archive-search-handler.php diff --git a/lib/experimental/rest-api.php b/lib/experimental/rest-api.php index aeed8e3f316a53..894bed81c07aef 100644 --- a/lib/experimental/rest-api.php +++ b/lib/experimental/rest-api.php @@ -95,13 +95,3 @@ function gutenberg_auto_draft_get_sample_permalink( $permalink, $id, $title, $na return $permalink; } add_filter( 'get_sample_permalink', 'gutenberg_auto_draft_get_sample_permalink', 10, 5 ); - - - -function register_post_archive_rest_search_handler( $handlers ) { - $handlers[] = new WP_REST_Post_Archive_Search_Handler(); - - - return $handlers; -} -add_filter( 'wp_rest_search_handlers', 'register_post_archive_rest_search_handler' ); \ No newline at end of file diff --git a/lib/load.php b/lib/load.php index ca1907518260d7..6bbdb9394db3bd 100644 --- a/lib/load.php +++ b/lib/load.php @@ -49,7 +49,7 @@ function gutenberg_is_experiment_enabled( $name ) { // WordPress 6.8 compat. require __DIR__ . '/compat/wordpress-6.8/block-comments.php'; require __DIR__ . '/compat/wordpress-6.8/class-gutenberg-rest-comment-controller-6-8.php'; - require_once __DIR__ . '/experimental/class-wp-rest-post-archive-search-handler.php'; + require __DIR__ . '/compat/wordpress-6.8/class-wp-rest-post-archive-search-handler.php'; // Plugin specific code. require_once __DIR__ . '/class-wp-rest-global-styles-controller-gutenberg.php'; diff --git a/lib/rest-api.php b/lib/rest-api.php index 7570bb19737233..6ec252ac07ee46 100644 --- a/lib/rest-api.php +++ b/lib/rest-api.php @@ -37,3 +37,13 @@ function gutenberg_register_edit_site_export_controller_endpoints() { $edit_site_export_controller->register_routes(); } add_action( 'rest_api_init', 'gutenberg_register_edit_site_export_controller_endpoints' ); + + +/** + * Registers REST search handler for Post Type Archives. + */ +function gutenberg_register_post_archive_rest_search_handler( $handlers ) { + $handlers[] = new WP_REST_Post_Archive_Search_Handler(); + return $handlers; +} +add_filter( 'wp_rest_search_handlers', 'gutenberg_register_post_archive_rest_search_handler' ); \ No newline at end of file From d7b3959a5b6f8fa05816da4a746f3eb9a6696a9d Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Thu, 7 Nov 2024 16:04:10 +0000 Subject: [PATCH 11/21] Update doc blocks --- .../class-wp-rest-post-archive-search-handler.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/compat/wordpress-6.8/class-wp-rest-post-archive-search-handler.php b/lib/compat/wordpress-6.8/class-wp-rest-post-archive-search-handler.php index ca6e2fd1ffe177..f614e0ecbf50b8 100644 --- a/lib/compat/wordpress-6.8/class-wp-rest-post-archive-search-handler.php +++ b/lib/compat/wordpress-6.8/class-wp-rest-post-archive-search-handler.php @@ -4,13 +4,13 @@ * * @package WordPress * @subpackage REST_API - * @since 6.6.0 + * @since 6.8.0 */ /** * Core class representing a search handler for Post Archives in the REST API. * - * @since 5.6.0 + * @since 6.8.0 * * @see WP_REST_Search_Handler */ @@ -19,7 +19,7 @@ class WP_REST_Post_Archive_Search_Handler extends WP_REST_Search_Handler { /** * Constructor. * - * @since 5.6.0 + * @since 6.8.0 */ public function __construct() { $this->type = 'post-type-archive'; @@ -28,7 +28,7 @@ public function __construct() { /** * Searches post-type archives for a given search request. * - * @since 5.6.0 + * @since 6.8.0 * * @param WP_REST_Request $request Full REST request. * @return array { @@ -74,7 +74,7 @@ public function search_items( WP_REST_Request $request ) { /** * Prepares the search result for a given post archive ID. * - * @since 5.6.0 + * @since 6.8.0 * * @param int $id Term ID. * @param array $fields Fields to include for the post archive. @@ -112,7 +112,7 @@ public function prepare_item( $id, array $fields ) { /** * Prepares links for the search result of a given ID. * - * @since 5.6.0 + * @since 6.8.0 * * @param int $id Item ID. * @return array[] Array of link arrays for the given item. From b0e7a3aa74763b7804a063c8c380b8a2d957ac70 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Fri, 8 Nov 2024 11:25:55 +0000 Subject: [PATCH 12/21] Use Gutenberg prefix --- ...p => class-gutenberg-rest-post-archive-search-handler.php} | 0 lib/load.php | 2 +- lib/rest-api.php | 4 ++-- 3 files changed, 3 insertions(+), 3 deletions(-) rename lib/compat/wordpress-6.8/{class-wp-rest-post-archive-search-handler.php => class-gutenberg-rest-post-archive-search-handler.php} (100%) diff --git a/lib/compat/wordpress-6.8/class-wp-rest-post-archive-search-handler.php b/lib/compat/wordpress-6.8/class-gutenberg-rest-post-archive-search-handler.php similarity index 100% rename from lib/compat/wordpress-6.8/class-wp-rest-post-archive-search-handler.php rename to lib/compat/wordpress-6.8/class-gutenberg-rest-post-archive-search-handler.php diff --git a/lib/load.php b/lib/load.php index 6bbdb9394db3bd..08e69e02b37f85 100644 --- a/lib/load.php +++ b/lib/load.php @@ -49,7 +49,7 @@ function gutenberg_is_experiment_enabled( $name ) { // WordPress 6.8 compat. require __DIR__ . '/compat/wordpress-6.8/block-comments.php'; require __DIR__ . '/compat/wordpress-6.8/class-gutenberg-rest-comment-controller-6-8.php'; - require __DIR__ . '/compat/wordpress-6.8/class-wp-rest-post-archive-search-handler.php'; + require __DIR__ . '/compat/wordpress-6.8/class-gutenberg-rest-post-archive-search-handler.php'; // Plugin specific code. require_once __DIR__ . '/class-wp-rest-global-styles-controller-gutenberg.php'; diff --git a/lib/rest-api.php b/lib/rest-api.php index 6ec252ac07ee46..0ef7816405554b 100644 --- a/lib/rest-api.php +++ b/lib/rest-api.php @@ -43,7 +43,7 @@ function gutenberg_register_edit_site_export_controller_endpoints() { * Registers REST search handler for Post Type Archives. */ function gutenberg_register_post_archive_rest_search_handler( $handlers ) { - $handlers[] = new WP_REST_Post_Archive_Search_Handler(); + $handlers[] = new Gutenberg_REST_Post_Archive_Search_Handler(); return $handlers; } -add_filter( 'wp_rest_search_handlers', 'gutenberg_register_post_archive_rest_search_handler' ); \ No newline at end of file +add_filter( 'wp_rest_search_handlers', 'gutenberg_register_post_archive_rest_search_handler' ); From 466a524e41f43eb2a9d9e5e0347887e4d9c85e80 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Fri, 8 Nov 2024 11:28:35 +0000 Subject: [PATCH 13/21] Correct class name prefix --- .../class-gutenberg-rest-post-archive-search-handler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compat/wordpress-6.8/class-gutenberg-rest-post-archive-search-handler.php b/lib/compat/wordpress-6.8/class-gutenberg-rest-post-archive-search-handler.php index f614e0ecbf50b8..8421998f7d4317 100644 --- a/lib/compat/wordpress-6.8/class-gutenberg-rest-post-archive-search-handler.php +++ b/lib/compat/wordpress-6.8/class-gutenberg-rest-post-archive-search-handler.php @@ -14,7 +14,7 @@ * * @see WP_REST_Search_Handler */ -class WP_REST_Post_Archive_Search_Handler extends WP_REST_Search_Handler { +class Gutenberg_REST_Post_Archive_Search_Handler extends WP_REST_Search_Handler { /** * Constructor. From 97265492bea41f851540a2ab308f1e4bded9b136 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Fri, 8 Nov 2024 12:01:25 +0000 Subject: [PATCH 14/21] Fix linting --- .../class-gutenberg-rest-post-archive-search-handler.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/compat/wordpress-6.8/class-gutenberg-rest-post-archive-search-handler.php b/lib/compat/wordpress-6.8/class-gutenberg-rest-post-archive-search-handler.php index 8421998f7d4317..e696f050414fd7 100644 --- a/lib/compat/wordpress-6.8/class-gutenberg-rest-post-archive-search-handler.php +++ b/lib/compat/wordpress-6.8/class-gutenberg-rest-post-archive-search-handler.php @@ -114,14 +114,12 @@ public function prepare_item( $id, array $fields ) { * * @since 6.8.0 * - * @param int $id Item ID. * @return array[] Array of link arrays for the given item. */ - public function prepare_item_links( $id ) { + public function prepare_item_links() { $links = array(); return $links; } } - From 81dac0ce1e8161bdd1b705b7e834a4a9d966c256 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Fri, 8 Nov 2024 12:02:24 +0000 Subject: [PATCH 15/21] More linting --- packages/block-library/src/navigation-link/index.php | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/packages/block-library/src/navigation-link/index.php b/packages/block-library/src/navigation-link/index.php index 5138e7214bacdd..cc5e4ac79fc8e0 100644 --- a/packages/block-library/src/navigation-link/index.php +++ b/packages/block-library/src/navigation-link/index.php @@ -372,12 +372,9 @@ function block_core_navigation_link_filter_variations( $variations, $block_type */ function block_core_navigation_link_build_variations() { - $post_types = get_post_types( array( 'show_in_nav_menus' => true ), 'objects' ); $taxonomies = get_taxonomies( array( 'show_in_nav_menus' => true ), 'objects' ); - - /* * Use two separate arrays as a way to order the variations in the UI. * Known variations (like Post Link and Page Link) are added to the @@ -405,7 +402,7 @@ function( $post_type ) { } ); if ( $has_archive ) { - $variation = array( + $variation = array( 'name' => 'post-type-archive', 'title' => __( 'Post Type Archive Link' ), 'description' => __( 'A link to a post type archive' ), @@ -416,9 +413,6 @@ function( $post_type ) { ); $variations[] = $variation; } - - - } if ( $taxonomies ) { foreach ( $taxonomies as $taxonomy ) { From bd4b2b2d5705f51fcb78a650ad1d5bf688d47874 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Fri, 8 Nov 2024 12:24:37 +0000 Subject: [PATCH 16/21] Update types and fix tests --- ...nberg-rest-post-archive-search-handler.php | 5 +++-- .../components/link-control/search-item.js | 4 ++++ .../__experimental-fetch-link-suggestions.ts | 2 +- .../__experimental-fetch-link-suggestions.js | 19 ++++++++++++++++++- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/lib/compat/wordpress-6.8/class-gutenberg-rest-post-archive-search-handler.php b/lib/compat/wordpress-6.8/class-gutenberg-rest-post-archive-search-handler.php index e696f050414fd7..4bdf331ddc58fe 100644 --- a/lib/compat/wordpress-6.8/class-gutenberg-rest-post-archive-search-handler.php +++ b/lib/compat/wordpress-6.8/class-gutenberg-rest-post-archive-search-handler.php @@ -103,7 +103,7 @@ public function prepare_item( $id, array $fields ) { } if ( in_array( WP_REST_Search_Controller::PROP_TYPE, $fields, true ) ) { - $data[ WP_REST_Search_Controller::PROP_TYPE ] = $post_type->name; + $data[ WP_REST_Search_Controller::PROP_TYPE ] = sprintf( '%s-%s', $post_type->name, __( 'archive' ) ); } return $data; @@ -114,9 +114,10 @@ public function prepare_item( $id, array $fields ) { * * @since 6.8.0 * + * @param int $id Item ID. * @return array[] Array of link arrays for the given item. */ - public function prepare_item_links() { + public function prepare_item_links( $id ) { $links = array(); diff --git a/packages/block-editor/src/components/link-control/search-item.js b/packages/block-editor/src/components/link-control/search-item.js index 8ab2bf2accc877..a790e420484719 100644 --- a/packages/block-editor/src/components/link-control/search-item.js +++ b/packages/block-editor/src/components/link-control/search-item.js @@ -154,6 +154,10 @@ function getVisualTypeName( suggestion ) { return 'blog home'; } + if ( suggestion.kind === 'post-type-archive' ) { + return 'archive'; + } + // Rename 'post_tag' to 'tag'. Ideally, the API would return the localised CPT or taxonomy label. return suggestion.type === 'post_tag' ? 'tag' : suggestion.type; } diff --git a/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.ts b/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.ts index 9af7e88182610a..824de89ed40621 100644 --- a/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.ts +++ b/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.ts @@ -258,7 +258,7 @@ export default async function fetchLinkSuggestions( title: decodeEntities( result.title || '' ) || __( '(no title)' ), - type: `${ result.type } archive`, + type: `${ result.type }`, kind: 'post-type-archive', }; } ); diff --git a/packages/core-data/src/fetch/test/__experimental-fetch-link-suggestions.js b/packages/core-data/src/fetch/test/__experimental-fetch-link-suggestions.js index 6878c74332c3d7..4612a01537cdf5 100644 --- a/packages/core-data/src/fetch/test/__experimental-fetch-link-suggestions.js +++ b/packages/core-data/src/fetch/test/__experimental-fetch-link-suggestions.js @@ -86,6 +86,16 @@ jest.mock( '@wordpress/api-fetch', () => 'http://localhost:8888/wp-content/uploads/2022/03/test-pdf.pdf', }, ] ); + case '/wp/v2/search?search=&per_page=20&type=post-type-archive': + return Promise.resolve( [ + { + id: 'books', + title: 'All Books', + url: 'http://wordpress.local/books/', + type: 'books-archive', + kind: 'post-type-archive', + }, + ] ); default: return Promise.resolve( [ { @@ -187,7 +197,7 @@ describe( 'fetchLinkSuggestions', () => { ); } ); - it( 'returns suggestions from post, term, post-format and media', () => { + it( 'returns suggestions from post, term, post-format, media and post-type-archive', () => { return fetchLinkSuggestions( '', {} ).then( ( suggestions ) => expect( suggestions ).toEqual( [ { @@ -232,6 +242,13 @@ describe( 'fetchLinkSuggestions', () => { type: 'attachment', kind: 'media', }, + { + id: 'books', + title: 'All Books', + url: 'http://wordpress.local/books/', + type: 'books-archive', + kind: 'post-type-archive', + }, ] ) ); } ); From 8e65e9ee8ab30f536617c33800b15faf2d4905c6 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Fri, 8 Nov 2024 14:48:49 +0000 Subject: [PATCH 17/21] Avoid querying for full post type objects where not needed --- ...ss-gutenberg-rest-post-archive-search-handler.php | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/compat/wordpress-6.8/class-gutenberg-rest-post-archive-search-handler.php b/lib/compat/wordpress-6.8/class-gutenberg-rest-post-archive-search-handler.php index 4bdf331ddc58fe..ad3ba98fcae2fe 100644 --- a/lib/compat/wordpress-6.8/class-gutenberg-rest-post-archive-search-handler.php +++ b/lib/compat/wordpress-6.8/class-gutenberg-rest-post-archive-search-handler.php @@ -41,6 +41,8 @@ public function __construct() { public function search_items( WP_REST_Request $request ) { $search_term = $request['search']; + $page = (int) $request['page']; + $per_page = (int) $request['per_page']; $args = array( 'public' => true, @@ -49,22 +51,18 @@ public function search_items( WP_REST_Request $request ) { '_builtin' => false, ); - $post_types = get_post_types( $args, 'objects' ); + $post_types = get_post_types( $args ); $found_ids = array(); if ( ! empty( $post_types ) ) { - foreach ( $post_types as $post_type ) { // Check if the search term matches the post type name. - if ( empty( $search_term ) || stripos( $post_type->name, $search_term ) !== false ) { - $found_ids[] = $post_type->name; + if ( empty( $search_term ) || stripos( $post_type, $search_term ) !== false ) { + $found_ids[] = $post_type; } } } - $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 ), From be1ef66f3563b0717863b9ae71b81da0761876cf Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Fri, 8 Nov 2024 14:53:18 +0000 Subject: [PATCH 18/21] More linting --- .../class-gutenberg-rest-post-archive-search-handler.php | 5 +---- packages/block-library/src/navigation-link/index.php | 3 ++- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/compat/wordpress-6.8/class-gutenberg-rest-post-archive-search-handler.php b/lib/compat/wordpress-6.8/class-gutenberg-rest-post-archive-search-handler.php index ad3ba98fcae2fe..99187574516cb3 100644 --- a/lib/compat/wordpress-6.8/class-gutenberg-rest-post-archive-search-handler.php +++ b/lib/compat/wordpress-6.8/class-gutenberg-rest-post-archive-search-handler.php @@ -116,9 +116,6 @@ public function prepare_item( $id, array $fields ) { * @return array[] Array of link arrays for the given item. */ public function prepare_item_links( $id ) { - - $links = array(); - - return $links; + return array(); } } diff --git a/packages/block-library/src/navigation-link/index.php b/packages/block-library/src/navigation-link/index.php index cc5e4ac79fc8e0..d21d1a350e012a 100644 --- a/packages/block-library/src/navigation-link/index.php +++ b/packages/block-library/src/navigation-link/index.php @@ -394,13 +394,14 @@ function block_core_navigation_link_build_variations() { } } - // If any of the post types have `has_archive` set to true then add a post-type-archive variation + // If any of the post types have `has_archive` set to true then add a post-type-archive variation. $has_archive = array_filter( $post_types, function( $post_type ) { return $post_type->has_archive; } ); + if ( $has_archive ) { $variation = array( 'name' => 'post-type-archive', From 8636df27bbc619e118137f66fa22d458d820bbd2 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Fri, 8 Nov 2024 14:54:44 +0000 Subject: [PATCH 19/21] Another lint --- packages/block-library/src/navigation-link/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/navigation-link/index.php b/packages/block-library/src/navigation-link/index.php index d21d1a350e012a..8f45fc2a77f56a 100644 --- a/packages/block-library/src/navigation-link/index.php +++ b/packages/block-library/src/navigation-link/index.php @@ -397,7 +397,7 @@ function block_core_navigation_link_build_variations() { // If any of the post types have `has_archive` set to true then add a post-type-archive variation. $has_archive = array_filter( $post_types, - function( $post_type ) { + function ( $post_type ) { return $post_type->has_archive; } ); From 29cafb9ef8806d44b8a360e62c021fa33e80cd37 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Fri, 8 Nov 2024 14:56:47 +0000 Subject: [PATCH 20/21] Ignore unused variable sniff to satifsy interace of extended class --- .../class-gutenberg-rest-post-archive-search-handler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compat/wordpress-6.8/class-gutenberg-rest-post-archive-search-handler.php b/lib/compat/wordpress-6.8/class-gutenberg-rest-post-archive-search-handler.php index 99187574516cb3..bcb5c4dfd31a1c 100644 --- a/lib/compat/wordpress-6.8/class-gutenberg-rest-post-archive-search-handler.php +++ b/lib/compat/wordpress-6.8/class-gutenberg-rest-post-archive-search-handler.php @@ -115,7 +115,7 @@ public function prepare_item( $id, array $fields ) { * @param int $id Item ID. * @return array[] Array of link arrays for the given item. */ - public function prepare_item_links( $id ) { + public function prepare_item_links( $id ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable return array(); } } From 7ddfb5ad57283959166297448a266f3e68eb5e2e Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Wed, 13 Nov 2024 09:58:40 +0000 Subject: [PATCH 21/21] Apply suggestions from code review Co-authored-by: Anton Vlasenko <43744263+anton-vlasenko@users.noreply.github.com> --- .../class-gutenberg-rest-post-archive-search-handler.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/compat/wordpress-6.8/class-gutenberg-rest-post-archive-search-handler.php b/lib/compat/wordpress-6.8/class-gutenberg-rest-post-archive-search-handler.php index bcb5c4dfd31a1c..0856b48c04d9dc 100644 --- a/lib/compat/wordpress-6.8/class-gutenberg-rest-post-archive-search-handler.php +++ b/lib/compat/wordpress-6.8/class-gutenberg-rest-post-archive-search-handler.php @@ -35,7 +35,7 @@ public function __construct() { * Associative array containing found IDs and total count for the matching search results. * * @type int[] $ids Found post archive IDs. - * @type string|int|WP_Error $total Numeric string containing the number of post-type archives found, or WP_Error object. + * @type int $total The number of post-type archives found. * } */ public function search_items( WP_REST_Request $request ) { @@ -79,7 +79,7 @@ public function search_items( WP_REST_Request $request ) { * @return array { * Associative array containing fields for the post-archive based on the `$fields` parameter. * - * @type string $id Optional. Post Archive Slug. + * @type id $id Optional. Post Archive Slug. * @type string $title Optional. Post Archive name. * @type string $url Optional. Post Archive permalink URL. * }