Changeset 48273
- Timestamp:
- 07/02/2020 05:55:04 AM (4 years ago)
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/class-wp-taxonomy.php
r47808 r48273 209 209 */ 210 210 public $rest_controller_class; 211 212 /** 213 * The controller instance for this taxonomy's REST API endpoints. 214 * 215 * Lazily computed. Should be accessed using {@see WP_Taxonomy::get_rest_controller()}. 216 * 217 * @since 5.5.0 218 * @var WP_REST_Controller $rest_controller 219 */ 220 public $rest_controller; 211 221 212 222 /** … … 453 463 remove_filter( 'wp_ajax_add-' . $this->name, '_wp_ajax_add_hierarchical_term' ); 454 464 } 465 466 /** 467 * Gets the REST API controller for this taxonomy. 468 * 469 * Will only instantiate the controller class once per request. 470 * 471 * @since 5.5.0 472 * 473 * @return WP_REST_Controller|null The controller instance, or null if the taxonomy 474 * is set not to show in rest. 475 */ 476 public function get_rest_controller() { 477 if ( ! $this->show_in_rest ) { 478 return null; 479 } 480 481 $class = $this->rest_controller_class ? $this->rest_controller_class : WP_REST_Terms_Controller::class; 482 483 if ( ! class_exists( $class ) ) { 484 return null; 485 } 486 487 if ( ! is_subclass_of( $class, WP_REST_Controller::class ) ) { 488 return null; 489 } 490 491 if ( ! $this->rest_controller ) { 492 $this->rest_controller = new $class( $this->name ); 493 } 494 495 if ( ! ( $this->rest_controller instanceof $class ) ) { 496 return null; 497 } 498 499 return $this->rest_controller; 500 } 455 501 } -
trunk/src/wp-includes/rest-api.php
r48242 r48273 235 235 // Terms. 236 236 foreach ( get_taxonomies( array( 'show_in_rest' => true ), 'object' ) as $taxonomy ) { 237 $class = ! empty( $taxonomy->rest_controller_class ) ? $taxonomy->rest_controller_class : 'WP_REST_Terms_Controller'; 238 239 if ( ! class_exists( $class ) ) { 240 continue; 241 } 242 $controller = new $class( $taxonomy->name ); 243 if ( ! is_subclass_of( $controller, 'WP_REST_Controller' ) ) { 237 $controller = $taxonomy->get_rest_controller(); 238 239 if ( ! $controller ) { 244 240 continue; 245 241 } … … 874 870 } 875 871 876 echo "<link rel='https://api.w.org/' href='" . esc_url( $api_root ) . "' />\n"; 872 printf( '<link rel="https://api.w.org/" href="%s" />', esc_url( $api_root ) ); 873 874 $resource = rest_get_queried_resource_route(); 875 876 if ( $resource ) { 877 printf( '<link rel="alternate" type="application/json" href="%s" />', esc_url( rest_url( $resource ) ) ); 878 } 877 879 } 878 880 … … 893 895 } 894 896 895 header( 'Link: <' . esc_url_raw( $api_root ) . '>; rel="https://api.w.org/"', false ); 897 header( sprintf( 'Link: <%s>; rel="https://api.w.org/"', esc_url_raw( $api_root ) ), false ); 898 899 $resource = rest_get_queried_resource_route(); 900 901 if ( $resource ) { 902 header( sprintf( 'Link: <%s>; rel="alternate"; type="application/json"', esc_url_raw( rest_url( $resource ) ) ), false ); 903 } 896 904 } 897 905 … … 1824 1832 return $schema; 1825 1833 } 1834 1835 /** 1836 * Gets the REST API route for a post. 1837 * 1838 * @since 5.5.0 1839 * 1840 * @param int|WP_Post $post Post ID or post object. 1841 * @return string The route path with a leading slash for the given post, or an empty string if there is not a route. 1842 */ 1843 function rest_get_route_for_post( $post ) { 1844 $post = get_post( $post ); 1845 1846 if ( ! $post instanceof WP_Post ) { 1847 return ''; 1848 } 1849 1850 $post_type = get_post_type_object( $post->post_type ); 1851 if ( ! $post_type ) { 1852 return ''; 1853 } 1854 1855 $controller = $post_type->get_rest_controller(); 1856 if ( ! $controller ) { 1857 return ''; 1858 } 1859 1860 $route = ''; 1861 1862 // The only two controllers that we can detect are the Attachments and Posts controllers. 1863 if ( in_array( get_class( $controller ), array( 'WP_REST_Attachments_Controller', 'WP_REST_Posts_Controller' ), true ) ) { 1864 $namespace = 'wp/v2'; 1865 $rest_base = ! empty( $post_type->rest_base ) ? $post_type->rest_base : $post_type->name; 1866 $route = sprintf( '/%s/%s/%d', $namespace, $rest_base, $post->ID ); 1867 } 1868 1869 /** 1870 * Filters the REST API route for a post. 1871 * 1872 * @since 5.5.0 1873 * 1874 * @param string $route The route path. 1875 * @param WP_Post $post The post object. 1876 */ 1877 return apply_filters( 'rest_route_for_post', $route, $post ); 1878 } 1879 1880 /** 1881 * Gets the REST API route for a term. 1882 * 1883 * @since 5.5.0 1884 * 1885 * @param int|WP_Term $term Term ID or term object. 1886 * @return string The route path with a leading slash for the given term, or an empty string if there is not a route. 1887 */ 1888 function rest_get_route_for_term( $term ) { 1889 $term = get_term( $term ); 1890 1891 if ( ! $term instanceof WP_Term ) { 1892 return ''; 1893 } 1894 1895 $taxonomy = get_taxonomy( $term->taxonomy ); 1896 if ( ! $taxonomy ) { 1897 return ''; 1898 } 1899 1900 $controller = $taxonomy->get_rest_controller(); 1901 if ( ! $controller ) { 1902 return ''; 1903 } 1904 1905 $route = ''; 1906 1907 // The only controller that works is the Terms controller. 1908 if ( 'WP_REST_Terms_Controller' === get_class( $controller ) ) { 1909 $namespace = 'wp/v2'; 1910 $rest_base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name; 1911 $route = sprintf( '/%s/%s/%d', $namespace, $rest_base, $term->term_id ); 1912 } 1913 1914 /** 1915 * Filters the REST API route for a term. 1916 * 1917 * @since 5.5.0 1918 * 1919 * @param string $route The route path. 1920 * @param WP_Term $term The term object. 1921 */ 1922 return apply_filters( 'rest_route_for_term', $route, $term ); 1923 } 1924 1925 /** 1926 * Gets the REST route for the currently queried object. 1927 * 1928 * @since 5.5.0 1929 * 1930 * @return string The REST route of the resource, or an empty string if no resource identified. 1931 */ 1932 function rest_get_queried_resource_route() { 1933 if ( is_singular() ) { 1934 $route = rest_get_route_for_post( get_queried_object() ); 1935 } elseif ( is_category() || is_tag() || is_tax() ) { 1936 $route = rest_get_route_for_term( get_queried_object() ); 1937 } elseif ( is_author() ) { 1938 $route = '/wp/v2/users/' . get_queried_object_id(); 1939 } else { 1940 $route = ''; 1941 } 1942 1943 /** 1944 * Filters the REST route for the currently queried object. 1945 * 1946 * @since 5.5.0 1947 * 1948 * @param string $link The route with a leading slash, or an empty string. 1949 */ 1950 return apply_filters( 'rest_queried_resource_route', $route ); 1951 } -
trunk/tests/phpunit/tests/rest-api.php
r48121 r48273 1350 1350 ); 1351 1351 } 1352 1353 /** 1354 * @ticket 49116 1355 */ 1356 public function test_rest_get_route_for_post_non_post() { 1357 $this->assertEquals( '', rest_get_route_for_post( 'garbage' ) ); 1358 } 1359 1360 /** 1361 * @ticket 49116 1362 */ 1363 public function test_rest_get_route_for_post_invalid_post_type() { 1364 register_post_type( 'invalid' ); 1365 $post = self::factory()->post->create_and_get( array( 'post_type' => 'invalid' ) ); 1366 unregister_post_type( 'invalid' ); 1367 1368 $this->assertEquals( '', rest_get_route_for_post( $post ) ); 1369 } 1370 1371 /** 1372 * @ticket 49116 1373 */ 1374 public function test_rest_get_route_for_post_non_rest() { 1375 $post = self::factory()->post->create_and_get( array( 'post_type' => 'custom_css' ) ); 1376 $this->assertEquals( '', rest_get_route_for_post( $post ) ); 1377 } 1378 1379 /** 1380 * @ticket 49116 1381 */ 1382 public function test_rest_get_route_for_post_custom_controller() { 1383 $post = self::factory()->post->create_and_get( array( 'post_type' => 'wp_block' ) ); 1384 $this->assertEquals( '', rest_get_route_for_post( $post ) ); 1385 } 1386 1387 /** 1388 * @ticket 49116 1389 */ 1390 public function test_rest_get_route_for_post() { 1391 $post = self::factory()->post->create_and_get(); 1392 $this->assertEquals( '/wp/v2/posts/' . $post->ID, rest_get_route_for_post( $post ) ); 1393 } 1394 1395 /** 1396 * @ticket 49116 1397 */ 1398 public function test_rest_get_route_for_media() { 1399 $post = self::factory()->attachment->create_and_get(); 1400 $this->assertEquals( '/wp/v2/media/' . $post->ID, rest_get_route_for_post( $post ) ); 1401 } 1402 1403 /** 1404 * @ticket 49116 1405 */ 1406 public function test_rest_get_route_for_post_id() { 1407 $post = self::factory()->post->create_and_get(); 1408 $this->assertEquals( '/wp/v2/posts/' . $post->ID, rest_get_route_for_post( $post->ID ) ); 1409 } 1410 1411 /** 1412 * @ticket 49116 1413 */ 1414 public function test_rest_get_route_for_term_non_term() { 1415 $this->assertEquals( '', rest_get_route_for_term( 'garbage' ) ); 1416 } 1417 1418 /** 1419 * @ticket 49116 1420 */ 1421 public function test_rest_get_route_for_term_invalid_term_type() { 1422 register_taxonomy( 'invalid', 'post' ); 1423 $term = self::factory()->term->create_and_get( array( 'taxonomy' => 'invalid' ) ); 1424 unregister_taxonomy( 'invalid' ); 1425 1426 $this->assertEquals( '', rest_get_route_for_term( $term ) ); 1427 } 1428 1429 /** 1430 * @ticket 49116 1431 */ 1432 public function test_rest_get_route_for_term_non_rest() { 1433 $term = self::factory()->term->create_and_get( array( 'taxonomy' => 'post_format' ) ); 1434 $this->assertEquals( '', rest_get_route_for_term( $term ) ); 1435 } 1436 1437 /** 1438 * @ticket 49116 1439 */ 1440 public function test_rest_get_route_for_term() { 1441 $term = self::factory()->term->create_and_get(); 1442 $this->assertEquals( '/wp/v2/tags/' . $term->term_id, rest_get_route_for_term( $term ) ); 1443 } 1444 1445 /** 1446 * @ticket 49116 1447 */ 1448 public function test_rest_get_route_for_category() { 1449 $term = self::factory()->category->create_and_get(); 1450 $this->assertEquals( '/wp/v2/categories/' . $term->term_id, rest_get_route_for_term( $term ) ); 1451 } 1452 1453 /** 1454 * @ticket 49116 1455 */ 1456 public function test_rest_get_route_for_term_id() { 1457 $term = self::factory()->term->create_and_get(); 1458 $this->assertEquals( '/wp/v2/tags/' . $term->term_id, rest_get_route_for_term( $term->term_id ) ); 1459 } 1352 1460 } -
trunk/tests/phpunit/tests/rest-api/rest-taxonomies-controller.php
r47122 r48273 292 292 } 293 293 294 /** 295 * @ticket 49116 296 */ 297 public function test_get_for_taxonomy_reuses_same_instance() { 298 $this->assertSame( 299 get_taxonomy( 'category' )->get_rest_controller(), 300 get_taxonomy( 'category' )->get_rest_controller() 301 ); 302 } 303 304 /** 305 * @ticket 49116 306 */ 307 public function test_get_for_taxonomy_returns_terms_controller_if_custom_class_not_specified() { 308 register_taxonomy( 309 'test', 310 'post', 311 array( 312 'show_in_rest' => true, 313 ) 314 ); 315 316 $this->assertInstanceOf( 317 WP_REST_Terms_Controller::class, 318 get_taxonomy( 'test' )->get_rest_controller() 319 ); 320 } 321 294 322 }
Note: See TracChangeset
for help on using the changeset viewer.