diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-block-pattern-categories-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-block-pattern-categories-controller.php index 36a753416013f..0de643a37696a 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-block-pattern-categories-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-block-pattern-categories-controller.php @@ -76,16 +76,50 @@ public function get_items_permissions_check( $request ) { * Retrieves all block pattern categories. * * @since 6.0.0 + * @since 6.5.0 Includes user categories from the wp_pattern_category taxonomy in the response if `user` sepecified in the request `source` param. * * @param WP_REST_Request $request Full details about the request. * @return WP_Error|WP_REST_Response Response object on success, or WP_Error object on failure. */ public function get_items( $request ) { - $response = array(); - $categories = WP_Block_Pattern_Categories_Registry::get_instance()->get_all_registered(); - foreach ( $categories as $category ) { - $prepared_category = $this->prepare_item_for_response( $category, $request ); - $response[] = $this->prepare_response_for_collection( $prepared_category ); + $valid_query_args = array( + 'source' => true, + ); + $query_args = array_intersect_key( $request->get_params(), $valid_query_args ); + $response = array(); + $unique_categories = array(); + + if ( is_array( $query_args['source'] ) && in_array( 'user', $query_args['source'], true ) ) { + $user_categories = get_terms( + array( + 'taxonomy' => 'wp_pattern_category', + 'hide_empty' => false, + ) + ); + foreach ( $user_categories as $user_category ) { + $prepared_category = $this->prepare_item_for_response( + array( + 'name' => $user_category->slug, + 'label' => $user_category->name, + 'description' => $user_category->description, + 'id' => $user_category->term_id, + ), + $request + ); + $response[] = $this->prepare_response_for_collection( $prepared_category ); + $unique_categories[] = $user_category->name; + } + } + + if ( ! isset( $query_args['source'] ) || in_array( 'core', $query_args['source'], true ) ) { + $categories = WP_Block_Pattern_Categories_Registry::get_instance()->get_all_registered(); + foreach ( $categories as $category ) { + if ( in_array( $category['label'], $unique_categories, true ) ) { + continue; + } + $prepared_category = $this->prepare_item_for_response( $category, $request ); + $response[] = $this->prepare_response_for_collection( $prepared_category ); + } } return rest_ensure_response( $response ); @@ -95,6 +129,7 @@ public function get_items( $request ) { * Prepare a raw block pattern category before it gets output in a REST API response. * * @since 6.0.0 + * @since 6.5 Added `id` field for identifying user categories * * @param array $item Raw category as registered, before any changes. * @param WP_REST_Request $request Request object. @@ -110,6 +145,11 @@ public function prepare_item_for_response( $item, $request ) { } } + // For backwards compatibility we only want to include the id if the field is explicitly requested. + if ( rest_is_field_included( 'id', $fields ) && isset( $item['id'] ) ) { + $data['id'] = $item['id']; + } + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); @@ -152,6 +192,12 @@ public function get_item_schema() { 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), + 'id' => array( + 'description' => __( 'An optional category id, currently used to provide id for user wp_pattern_category terms' ), + 'type' => 'number', + 'readonly' => true, + 'context' => array( 'view', 'edit', 'embed' ), + ), ), ); @@ -159,4 +205,32 @@ public function get_item_schema() { return $this->add_additional_fields_schema( $this->schema ); } + + /** + * Retrieves the search parameters for the block pattern categories. + * + * @since 6.5.0 Added source param to request. + * + * @return array Collection parameters. + */ + public function get_collection_params() { + $query_params = parent::get_collection_params(); + + $query_params['source'] = array( + 'description' => __( 'Limit result set to specific sources, `core` and/or `user`' ), + 'type' => 'array', + 'items' => array( + 'type' => 'string', + ), + ); + + /** + * Filter collection parameters for the block pattern categories controller. + * + * @since 5.8.0 + * + * @param array $query_params JSON Schema-formatted collection parameters. + */ + return apply_filters( 'rest_pattern_directory_collection_params', $query_params ); + } }