diff --git a/lib/class-wp-rest-pattern-directory-controller.php b/lib/class-wp-rest-pattern-directory-controller.php index a95fd18498d15d..6fa44c62673a65 100644 --- a/lib/class-wp-rest-pattern-directory-controller.php +++ b/lib/class-wp-rest-pattern-directory-controller.php @@ -84,12 +84,17 @@ public function get_items_permissions_check( $request ) { // phpcs:ignore Variab * @return WP_Error|WP_REST_Response Response object on success, or WP_Error object on failure. */ public function get_items( $request ) { - $query_args = array(); - $category_ids = $request['category']; - $search_term = $request['search']; + $query_args = array(); + $category_id = $request['category']; + $keyword_id = $request['keyword']; + $search_term = $request['search']; - if ( $category_ids ) { - $query_args['pattern-categories'] = $category_ids; + if ( $category_id ) { + $query_args['pattern-categories'] = $category_id; + } + + if ( $keyword_id ) { + $query_args['pattern-keywords'] = $keyword_id; } if ( $search_term ) { @@ -276,6 +281,12 @@ public function get_collection_params() { 'minimum' => 1, ); + $query_params['keyword'] = array( + 'description' => __( 'Limit results to those matching a keyword ID.', 'gutenberg' ), + 'type' => 'integer', + 'minimum' => 1, + ); + /** * Filter collection parameters for the pattern directory controller. * diff --git a/phpunit/class-wp-rest-pattern-directory-controller-test.php b/phpunit/class-wp-rest-pattern-directory-controller-test.php index a58563dd5f34bf..2e3269cfecff8f 100644 --- a/phpunit/class-wp-rest-pattern-directory-controller-test.php +++ b/phpunit/class-wp-rest-pattern-directory-controller-test.php @@ -126,6 +126,31 @@ public function test_get_items_by_category() { } } + /** + * @covers WP_REST_Pattern_Directory_Controller::get_items + * + * @since 5.8.0 + */ + public function test_get_items_by_keyword() { + wp_set_current_user( self::$contributor_id ); + self::mock_successful_response( 'browse-keyword', true ); + + $request = new WP_REST_Request( 'GET', '/__experimental/pattern-directory/patterns' ); + $request->set_query_params( array( 'keyword' => 11 ) ); + $response = rest_do_request( $request ); + $patterns = $response->get_data(); + + $this->assertNotWPError( $response->as_error() ); + $this->assertSame( 200, $response->status ); + $this->assertGreaterThan( 0, count( $patterns ) ); + + array_walk( $patterns, array( $this, 'assertPatternMatchesSchema' ) ); + + foreach ( $patterns as $pattern ) { + $this->assertContains( 'core', $pattern['keywords'] ); + } + } + /** * @covers WP_REST_Pattern_Directory_Controller::get_items * @@ -304,6 +329,11 @@ private static function get_raw_response( $action ) { $response = file_get_contents( __DIR__ . '/fixtures/rest-api/pattern-directory/browse-category-2.json' ); break; + case 'browse-keyword': + // Response from https://api.wordpress.org/patterns/1.0/?pattern-keywords=11. + $response = file_get_contents( __DIR__ . '/fixtures/rest-api/pattern-directory/browse-keyword-11.json' ); + break; + case 'search': // Response from https://api.wordpress.org/patterns/1.0/?search=button. $response = file_get_contents( __DIR__ . '/fixtures/rest-api/pattern-directory/search-button.json' ); diff --git a/phpunit/fixtures/rest-api/pattern-directory/browse-keyword-11.json b/phpunit/fixtures/rest-api/pattern-directory/browse-keyword-11.json new file mode 100644 index 00000000000000..dd7017473e850f --- /dev/null +++ b/phpunit/fixtures/rest-api/pattern-directory/browse-keyword-11.json @@ -0,0 +1 @@ +[{"id":31,"title":{"rendered":"Heading and paragraph"},"content":{"rendered":"\n
These preliminaries settled, he did not care to put off any longer the execution of his design, urged on to it by the thought of all the world was losing by his delay, seeing what wrongs he intended to right, grievances to redress, injustices to repair, abuses to remove, and duties to discharge.<\/p>\n<\/div><\/div>\n","protected":false},"meta":{"spay_email":"","wpop_description":"A heading preceded by a chapter number, and followed by a paragraph.","wpop_viewport_width":1000},"category_slugs":["text"],"keyword_slugs":["core"]},{"id":25,"title":{"rendered":"Large header with a heading"},"content":{"rendered":"\n
Don Quixote<\/strong><\/p>\n<\/div><\/div>\n","protected":false},"meta":{"spay_email":"","wpop_description":"A large hero section with an example background image and a heading in the center.","wpop_viewport_width":1000},"category_slugs":["header"],"keyword_slugs":["core"]},{"id":26,"title":{"rendered":"Large header with a heading and a button"},"content":{"rendered":"\n Thou hast seen<\/strong>
nothing yet<\/strong><\/p>\n\n\n\n