rest-search-controller.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793
  1. <?php
  2. /**
  3. * WP_REST_Search_Controller tests
  4. *
  5. * @package WordPress
  6. * @subpackage REST_API
  7. */
  8. /**
  9. * Tests for WP_REST_Search_Controller.
  10. *
  11. * @group restapi
  12. */
  13. class WP_Test_REST_Search_Controller extends WP_Test_REST_Controller_Testcase {
  14. /**
  15. * Posts with title 'my-footitle'.
  16. *
  17. * @var array
  18. */
  19. private static $my_title_post_ids = array();
  20. /**
  21. * Pages with title 'my-footitle'.
  22. *
  23. * @var array
  24. */
  25. private static $my_title_page_ids = array();
  26. /**
  27. * Posts with content 'my-foocontent'.
  28. *
  29. * @var array
  30. */
  31. private static $my_content_post_ids = array();
  32. /**
  33. * Categories.
  34. *
  35. * @var int
  36. */
  37. private static $my_category_id;
  38. /**
  39. * Tags.
  40. *
  41. * @var int
  42. */
  43. private static $my_tag_id;
  44. /**
  45. * Create fake data before our tests run.
  46. *
  47. * @param WP_UnitTest_Factory $factory Helper that lets us create fake data.
  48. */
  49. public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) {
  50. add_theme_support( 'post-formats', array( 'aside' ) );
  51. self::$my_title_post_ids = $factory->post->create_many(
  52. 4,
  53. array(
  54. 'post_title' => 'my-footitle',
  55. 'post_type' => 'post',
  56. )
  57. );
  58. self::$my_title_page_ids = $factory->post->create_many(
  59. 4,
  60. array(
  61. 'post_title' => 'my-footitle',
  62. 'post_type' => 'page',
  63. )
  64. );
  65. self::$my_content_post_ids = $factory->post->create_many(
  66. 6,
  67. array(
  68. 'post_content' => 'my-foocontent',
  69. )
  70. );
  71. set_post_format( self::$my_title_post_ids[0], 'aside' );
  72. self::$my_category_id = $factory->term->create(
  73. array(
  74. 'taxonomy' => 'category',
  75. 'name' => 'Test Category',
  76. )
  77. );
  78. self::$my_tag_id = $factory->term->create(
  79. array(
  80. 'taxonomy' => 'post_tag',
  81. 'name' => 'Test Tag',
  82. )
  83. );
  84. }
  85. /**
  86. * Delete our fake data after our tests run.
  87. */
  88. public static function wpTearDownAfterClass() {
  89. remove_theme_support( 'post-formats' );
  90. $post_ids = array_merge(
  91. self::$my_title_post_ids,
  92. self::$my_title_page_ids,
  93. self::$my_content_post_ids
  94. );
  95. foreach ( $post_ids as $post_id ) {
  96. wp_delete_post( $post_id, true );
  97. }
  98. $term_ids = array(
  99. self::$my_category_id,
  100. self::$my_tag_id,
  101. );
  102. foreach ( $term_ids as $term_id ) {
  103. wp_delete_term( $term_id, true );
  104. }
  105. }
  106. /**
  107. * Check that our routes get set up properly.
  108. */
  109. public function test_register_routes() {
  110. $routes = rest_get_server()->get_routes();
  111. $this->assertArrayHasKey( '/wp/v2/search', $routes );
  112. $this->assertCount( 1, $routes['/wp/v2/search'] );
  113. }
  114. /**
  115. * Check the context parameter.
  116. */
  117. public function test_context_param() {
  118. $response = $this->do_request_with_params( array(), 'OPTIONS' );
  119. $data = $response->get_data();
  120. $this->assertSame( 'view', $data['endpoints'][0]['args']['context']['default'] );
  121. $this->assertSame( array( 'view', 'embed' ), $data['endpoints'][0]['args']['context']['enum'] );
  122. }
  123. /**
  124. * Search through all content.
  125. */
  126. public function test_get_items() {
  127. $response = $this->do_request_with_params(
  128. array(
  129. 'per_page' => 100,
  130. )
  131. );
  132. $this->assertSame( 200, $response->get_status() );
  133. $this->assertSameSets(
  134. array_merge(
  135. self::$my_title_post_ids,
  136. self::$my_title_page_ids,
  137. self::$my_content_post_ids
  138. ),
  139. wp_list_pluck( $response->get_data(), 'id' )
  140. );
  141. }
  142. /**
  143. * Search through all content with a low limit.
  144. */
  145. public function test_get_items_with_limit() {
  146. $response = $this->do_request_with_params(
  147. array(
  148. 'per_page' => 3,
  149. )
  150. );
  151. $this->assertSame( 200, $response->get_status() );
  152. $this->assertSame( 3, count( $response->get_data() ) );
  153. }
  154. /**
  155. * Search through posts of any post type.
  156. */
  157. public function test_get_items_search_type_post() {
  158. $response = $this->do_request_with_params(
  159. array(
  160. 'per_page' => 100,
  161. 'type' => 'post',
  162. )
  163. );
  164. $this->assertSame( 200, $response->get_status() );
  165. $this->assertSameSets(
  166. array_merge(
  167. self::$my_title_post_ids,
  168. self::$my_title_page_ids,
  169. self::$my_content_post_ids
  170. ),
  171. wp_list_pluck( $response->get_data(), 'id' )
  172. );
  173. }
  174. /**
  175. * Search through posts of post type 'post'.
  176. */
  177. public function test_get_items_search_type_post_subtype_post() {
  178. $response = $this->do_request_with_params(
  179. array(
  180. 'per_page' => 100,
  181. 'type' => 'post',
  182. 'subtype' => 'post',
  183. )
  184. );
  185. $this->assertSame( 200, $response->get_status() );
  186. $this->assertSameSets(
  187. array_merge(
  188. self::$my_title_post_ids,
  189. self::$my_content_post_ids
  190. ),
  191. wp_list_pluck( $response->get_data(), 'id' )
  192. );
  193. }
  194. /**
  195. * Search through posts of post type 'page'.
  196. */
  197. public function test_get_items_search_type_post_subtype_page() {
  198. $response = $this->do_request_with_params(
  199. array(
  200. 'per_page' => 100,
  201. 'type' => 'post',
  202. 'subtype' => 'page',
  203. )
  204. );
  205. $this->assertSame( 200, $response->get_status() );
  206. $this->assertSameSets(
  207. self::$my_title_page_ids,
  208. wp_list_pluck( $response->get_data(), 'id' )
  209. );
  210. }
  211. /**
  212. * Search through an invalid type
  213. */
  214. public function test_get_items_search_type_invalid() {
  215. $response = $this->do_request_with_params(
  216. array(
  217. 'per_page' => 100,
  218. 'type' => 'invalid',
  219. )
  220. );
  221. $this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
  222. }
  223. /**
  224. * Search through posts of an invalid post type.
  225. */
  226. public function test_get_items_search_type_post_subtype_invalid() {
  227. $response = $this->do_request_with_params(
  228. array(
  229. 'per_page' => 100,
  230. 'type' => 'post',
  231. 'subtype' => 'invalid',
  232. )
  233. );
  234. $this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
  235. }
  236. /**
  237. * Search through posts and pages.
  238. */
  239. public function test_get_items_search_posts_and_pages() {
  240. $response = $this->do_request_with_params(
  241. array(
  242. 'per_page' => 100,
  243. 'type' => 'post',
  244. 'subtype' => 'post,page',
  245. )
  246. );
  247. $this->assertSame( 200, $response->get_status() );
  248. $this->assertSameSets(
  249. array_merge(
  250. self::$my_title_post_ids,
  251. self::$my_title_page_ids,
  252. self::$my_content_post_ids
  253. ),
  254. wp_list_pluck( $response->get_data(), 'id' )
  255. );
  256. }
  257. /**
  258. * Search through all that matches a 'footitle' search.
  259. */
  260. public function test_get_items_search_for_footitle() {
  261. $response = $this->do_request_with_params(
  262. array(
  263. 'per_page' => 100,
  264. 'search' => 'footitle',
  265. )
  266. );
  267. $this->assertSame( 200, $response->get_status() );
  268. $this->assertSameSets(
  269. array_merge(
  270. self::$my_title_post_ids,
  271. self::$my_title_page_ids
  272. ),
  273. wp_list_pluck( $response->get_data(), 'id' )
  274. );
  275. }
  276. /**
  277. * Search through all that matches a 'foocontent' search.
  278. */
  279. public function test_get_items_search_for_foocontent() {
  280. $response = $this->do_request_with_params(
  281. array(
  282. 'per_page' => 100,
  283. 'search' => 'foocontent',
  284. )
  285. );
  286. $this->assertSame( 200, $response->get_status() );
  287. $this->assertSameSets(
  288. self::$my_content_post_ids,
  289. wp_list_pluck( $response->get_data(), 'id' )
  290. );
  291. }
  292. /**
  293. * Test retrieving a single item isn't possible.
  294. */
  295. public function test_get_item() {
  296. /** The search controller does not allow getting individual item content */
  297. $request = new WP_REST_Request( 'GET', '/wp/v2/search' . self::$my_title_post_ids[0] );
  298. $response = rest_get_server()->dispatch( $request );
  299. $this->assertSame( 404, $response->get_status() );
  300. }
  301. /**
  302. * Test creating an item isn't possible.
  303. */
  304. public function test_create_item() {
  305. /** The search controller does not allow creating content */
  306. $request = new WP_REST_Request( 'POST', '/wp/v2/search' );
  307. $response = rest_get_server()->dispatch( $request );
  308. $this->assertSame( 404, $response->get_status() );
  309. }
  310. /**
  311. * Test updating an item isn't possible.
  312. */
  313. public function test_update_item() {
  314. /** The search controller does not allow upading content */
  315. $request = new WP_REST_Request( 'POST', '/wp/v2/search' . self::$my_title_post_ids[0] );
  316. $response = rest_get_server()->dispatch( $request );
  317. $this->assertSame( 404, $response->get_status() );
  318. }
  319. /**
  320. * Test deleting an item isn't possible.
  321. */
  322. public function test_delete_item() {
  323. /** The search controller does not allow deleting content */
  324. $request = new WP_REST_Request( 'DELETE', '/wp/v2/search' . self::$my_title_post_ids[0] );
  325. $response = rest_get_server()->dispatch( $request );
  326. $this->assertSame( 404, $response->get_status() );
  327. }
  328. /**
  329. * Test preparing the data contains the correct fields.
  330. */
  331. public function test_prepare_item() {
  332. $response = $this->do_request_with_params();
  333. $this->assertSame( 200, $response->get_status() );
  334. $data = $response->get_data();
  335. $this->assertSame(
  336. array(
  337. 'id',
  338. 'title',
  339. 'url',
  340. 'type',
  341. 'subtype',
  342. '_links',
  343. ),
  344. array_keys( $data[0] )
  345. );
  346. }
  347. /**
  348. * Test preparing the data with limited fields contains the correct fields.
  349. */
  350. public function test_prepare_item_limit_fields() {
  351. if ( ! method_exists( 'WP_REST_Controller', 'get_fields_for_response' ) ) {
  352. $this->markTestSkipped( 'Limiting fields requires the WP_REST_Controller::get_fields_for_response() method.' );
  353. }
  354. $response = $this->do_request_with_params(
  355. array(
  356. '_fields' => 'id,title',
  357. )
  358. );
  359. $this->assertSame( 200, $response->get_status() );
  360. $data = $response->get_data();
  361. $this->assertSame(
  362. array(
  363. 'id',
  364. 'title',
  365. '_links',
  366. ),
  367. array_keys( $data[0] )
  368. );
  369. }
  370. /**
  371. * Tests the item schema is correct.
  372. */
  373. public function test_get_item_schema() {
  374. $request = new WP_REST_Request( 'OPTIONS', '/wp/v2/search' );
  375. $response = rest_get_server()->dispatch( $request );
  376. $data = $response->get_data();
  377. $properties = $data['schema']['properties'];
  378. $this->assertArrayHasKey( 'id', $properties );
  379. $this->assertArrayHasKey( 'title', $properties );
  380. $this->assertArrayHasKey( 'url', $properties );
  381. $this->assertArrayHasKey( 'type', $properties );
  382. $this->assertArrayHasKey( 'subtype', $properties );
  383. }
  384. /**
  385. * Tests that non-public post types are not allowed.
  386. */
  387. public function test_non_public_post_type() {
  388. $response = $this->do_request_with_params(
  389. array(
  390. 'type' => 'post',
  391. 'subtype' => 'post,nav_menu_item',
  392. )
  393. );
  394. $this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
  395. }
  396. /**
  397. * Test getting items directly with a custom search handler.
  398. */
  399. public function test_custom_search_handler_get_items() {
  400. $controller = new WP_REST_Search_Controller( array( new WP_REST_Test_Search_Handler( 10 ) ) );
  401. $request = $this->get_request(
  402. array(
  403. 'page' => 1,
  404. 'per_page' => 10,
  405. 'type' => 'test',
  406. 'subtype' => array( WP_REST_Search_Controller::TYPE_ANY ),
  407. )
  408. );
  409. $response = $controller->get_items( $request );
  410. $this->assertSameSets( range( 1, 10 ), wp_list_pluck( $response->get_data(), 'id' ) );
  411. $request = $this->get_request(
  412. array(
  413. 'page' => 1,
  414. 'per_page' => 10,
  415. 'type' => 'test',
  416. 'subtype' => array( 'test_first_type' ),
  417. )
  418. );
  419. $response = $controller->get_items( $request );
  420. $this->assertSameSets( range( 1, 5 ), wp_list_pluck( $response->get_data(), 'id' ) );
  421. }
  422. /**
  423. * Test preparing an item directly with a custom search handler.
  424. */
  425. public function test_custom_search_handler_prepare_item() {
  426. $controller = new WP_REST_Search_Controller( array( new WP_REST_Test_Search_Handler( 10 ) ) );
  427. $request = $this->get_request(
  428. array(
  429. 'type' => 'test',
  430. 'subtype' => array( WP_REST_Search_Controller::TYPE_ANY ),
  431. )
  432. );
  433. $response = $controller->prepare_item_for_response( 1, $request );
  434. $data = $response->get_data();
  435. $this->assertSame(
  436. array(
  437. 'id',
  438. 'title',
  439. 'url',
  440. 'type',
  441. 'subtype',
  442. ),
  443. array_keys( $data )
  444. );
  445. }
  446. /**
  447. * Test preparing an item directly with a custom search handler with limited fields.
  448. */
  449. public function test_custom_search_handler_prepare_item_limit_fields() {
  450. if ( ! method_exists( 'WP_REST_Controller', 'get_fields_for_response' ) ) {
  451. $this->markTestSkipped( 'Limiting fields requires the WP_REST_Controller::get_fields_for_response() method.' );
  452. }
  453. $controller = new WP_REST_Search_Controller( array( new WP_REST_Test_Search_Handler( 10 ) ) );
  454. $request = $this->get_request(
  455. array(
  456. 'type' => 'test',
  457. 'subtype' => array( WP_REST_Search_Controller::TYPE_ANY ),
  458. '_fields' => 'id,title',
  459. )
  460. );
  461. $response = $controller->prepare_item_for_response( 1, $request );
  462. $data = $response->get_data();
  463. $this->assertSame(
  464. array(
  465. 'id',
  466. 'title',
  467. ),
  468. array_keys( $data )
  469. );
  470. }
  471. /**
  472. * Test getting the collection params directly with a custom search handler.
  473. */
  474. public function test_custom_search_handler_get_collection_params() {
  475. $controller = new WP_REST_Search_Controller( array( new WP_REST_Test_Search_Handler( 10 ) ) );
  476. $params = $controller->get_collection_params();
  477. $this->assertSame( 'test', $params[ WP_REST_Search_Controller::PROP_TYPE ]['default'] );
  478. $this->assertSameSets( array( 'test' ), $params[ WP_REST_Search_Controller::PROP_TYPE ]['enum'] );
  479. $this->assertSameSets( array( 'test_first_type', 'test_second_type', WP_REST_Search_Controller::TYPE_ANY ), $params[ WP_REST_Search_Controller::PROP_SUBTYPE ]['items']['enum'] );
  480. }
  481. /**
  482. * @ticket 47684
  483. */
  484. public function test_search_result_links_are_embedded() {
  485. $response = $this->do_request_with_params( array( 'per_page' => 1 ) );
  486. $data = rest_get_server()->response_to_data( $response, true )[0];
  487. $this->assertArrayHasKey( '_embedded', $data );
  488. $this->assertArrayHasKey( 'self', $data['_embedded'] );
  489. $this->assertCount( 1, $data['_embedded']['self'] );
  490. $this->assertArrayHasKey( WP_REST_Search_Controller::PROP_ID, $data['_embedded']['self'][0] );
  491. $this->assertSame( $data[ WP_REST_Search_Controller::PROP_ID ], $data['_embedded']['self'][0][ WP_REST_Search_Controller::PROP_ID ] );
  492. }
  493. /**
  494. * Search through terms of any type.
  495. *
  496. * @ticket 51458
  497. */
  498. public function test_get_items_search_type_term() {
  499. $response = $this->do_request_with_params(
  500. array(
  501. 'per_page' => 100,
  502. 'type' => 'term',
  503. )
  504. );
  505. $this->assertSame( 200, $response->get_status() );
  506. $this->assertSameSets(
  507. array(
  508. 0 => 1, // That is the default category.
  509. self::$my_category_id,
  510. self::$my_tag_id,
  511. ),
  512. wp_list_pluck( $response->get_data(), 'id' )
  513. );
  514. }
  515. /**
  516. * Search through terms of subtype 'category'.
  517. *
  518. * @ticket 51458
  519. */
  520. public function test_get_items_search_type_term_subtype_category() {
  521. $response = $this->do_request_with_params(
  522. array(
  523. 'per_page' => 100,
  524. 'type' => 'term',
  525. 'subtype' => 'category',
  526. )
  527. );
  528. $this->assertSame( 200, $response->get_status() );
  529. $this->assertSameSets(
  530. array(
  531. 0 => 1, // That is the default category.
  532. self::$my_category_id,
  533. ),
  534. wp_list_pluck( $response->get_data(), 'id' )
  535. );
  536. }
  537. /**
  538. * Search through posts of an invalid post type.
  539. *
  540. * @ticket 51458
  541. */
  542. public function test_get_items_search_term_subtype_invalid() {
  543. $response = $this->do_request_with_params(
  544. array(
  545. 'per_page' => 100,
  546. 'type' => 'term',
  547. 'subtype' => 'invalid',
  548. )
  549. );
  550. $this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
  551. }
  552. /**
  553. * Search through posts and pages.
  554. *
  555. * @ticket 51458
  556. */
  557. public function test_get_items_search_categories_and_tags() {
  558. $response = $this->do_request_with_params(
  559. array(
  560. 'per_page' => 100,
  561. 'type' => 'term',
  562. 'subtype' => 'category,post_tag',
  563. )
  564. );
  565. $this->assertSame( 200, $response->get_status() );
  566. $this->assertSameSets(
  567. array(
  568. 0 => 1, // This is the default category.
  569. self::$my_category_id,
  570. self::$my_tag_id,
  571. ),
  572. wp_list_pluck( $response->get_data(), 'id' )
  573. );
  574. }
  575. /**
  576. * Search through all that matches a 'Test Category' search.
  577. *
  578. * @ticket 51458
  579. */
  580. public function test_get_items_search_for_test_category() {
  581. $response = $this->do_request_with_params(
  582. array(
  583. 'per_page' => 100,
  584. 'search' => 'Test Category',
  585. 'type' => 'term',
  586. )
  587. );
  588. $this->assertSame( 200, $response->get_status() );
  589. $this->assertSameSets(
  590. array(
  591. self::$my_category_id,
  592. ),
  593. wp_list_pluck( $response->get_data(), 'id' )
  594. );
  595. }
  596. /**
  597. * Search through all that matches a 'Test Tag' search.
  598. *
  599. * @ticket 51458
  600. */
  601. public function test_get_items_search_for_test_tag() {
  602. $response = $this->do_request_with_params(
  603. array(
  604. 'per_page' => 100,
  605. 'search' => 'Test Tag',
  606. 'type' => 'term',
  607. )
  608. );
  609. $this->assertSame( 200, $response->get_status() );
  610. $this->assertSameSets(
  611. array(
  612. self::$my_tag_id,
  613. ),
  614. wp_list_pluck( $response->get_data(), 'id' )
  615. );
  616. }
  617. /**
  618. * Searching for a term that doesn't exist should return an empty result.
  619. *
  620. * @ticket 51458
  621. */
  622. public function test_get_items_search_for_missing_term() {
  623. $response = $this->do_request_with_params(
  624. array(
  625. 'per_page' => 100,
  626. 'search' => 'Doesn\'t exist',
  627. 'type' => 'term',
  628. )
  629. );
  630. $this->assertSame( 200, $response->get_status() );
  631. $this->assertEmpty( $response->get_data() );
  632. }
  633. /**
  634. * Search through post formats of any type.
  635. *
  636. * @ticket 51459
  637. */
  638. public function test_get_items_search_type_post_format() {
  639. $response = $this->do_request_with_params(
  640. array(
  641. 'per_page' => 100,
  642. 'type' => 'post-format',
  643. )
  644. );
  645. $this->assertSame( 200, $response->get_status() );
  646. $this->assertContains(
  647. 'Aside',
  648. wp_list_pluck( $response->get_data(), 'title' )
  649. );
  650. }
  651. /**
  652. * Search through all that matches a 'Aside' search.
  653. *
  654. * @ticket 51459
  655. */
  656. public function test_get_items_search_for_test_post_format() {
  657. $response = $this->do_request_with_params(
  658. array(
  659. 'per_page' => 100,
  660. 'search' => 'Aside',
  661. 'type' => 'post-format',
  662. )
  663. );
  664. $this->assertSame( 200, $response->get_status() );
  665. $this->assertContains(
  666. 'Aside',
  667. wp_list_pluck( $response->get_data(), 'title' )
  668. );
  669. }
  670. /**
  671. * Searching for a post format that doesn't exist should return an empty
  672. * result.
  673. *
  674. * @ticket 51459
  675. */
  676. public function test_get_items_search_for_missing_post_format() {
  677. $response = $this->do_request_with_params(
  678. array(
  679. 'per_page' => 100,
  680. 'search' => 'Doesn\'t exist',
  681. 'type' => 'post-format',
  682. )
  683. );
  684. $this->assertSame( 200, $response->get_status() );
  685. $this->assertEmpty( $response->get_data() );
  686. }
  687. /**
  688. * Perform a REST request to our search endpoint with given parameters.
  689. */
  690. private function do_request_with_params( $params = array(), $method = 'GET' ) {
  691. $request = $this->get_request( $params, $method );
  692. return rest_get_server()->dispatch( $request );
  693. }
  694. /**
  695. * Get a REST request object for given parameters.
  696. */
  697. private function get_request( $params = array(), $method = 'GET' ) {
  698. $request = new WP_REST_Request( $method, '/wp/v2/search' );
  699. foreach ( $params as $param => $value ) {
  700. $request->set_param( $param, $value );
  701. }
  702. return $request;
  703. }
  704. }