Changeset 44250
- Timestamp:
- 12/17/2018 12:23:55 AM (6 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/5.0 merged: 43897
- Property svn:mergeinfo changed
-
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php
r44126 r44250 80 80 register_rest_route( 81 81 $this->rest_namespace, 82 '/' . $this->parent_base . '/(?P< parent>[\d]+)/' . $this->rest_base,82 '/' . $this->parent_base . '/(?P<id>[\d]+)/' . $this->rest_base, 83 83 array( 84 84 'args' => array( … … 91 91 'methods' => WP_REST_Server::READABLE, 92 92 'callback' => array( $this, 'get_items' ), 93 'permission_callback' => array( $this ->revisions_controller, 'get_items_permissions_check' ),93 'permission_callback' => array( $this, 'get_items_permissions_check' ), 94 94 'args' => $this->get_collection_params(), 95 95 ), … … 98 98 'callback' => array( $this, 'create_item' ), 99 99 'permission_callback' => array( $this, 'create_item_permissions_check' ), 100 'args' => $this-> get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),100 'args' => $this->parent_controller->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), 101 101 ), 102 102 'schema' => array( $this, 'get_public_item_schema' ), … … 145 145 146 146 /** 147 * Checks if a given request has access to get autosaves. 148 * 149 * @since 5.0.0 150 * 151 * @param WP_REST_Request $request Full data about the request. 152 * @return true|WP_Error True if the request has read access, WP_Error object otherwise. 153 */ 154 public function get_items_permissions_check( $request ) { 155 $parent = $this->get_parent( $request['id'] ); 156 if ( is_wp_error( $parent ) ) { 157 return $parent; 158 } 159 160 $parent_post_type_obj = get_post_type_object( $parent->post_type ); 161 if ( ! current_user_can( $parent_post_type_obj->cap->edit_post, $parent->ID ) ) { 162 return new WP_Error( 'rest_cannot_read', __( 'Sorry, you are not allowed to view autosaves of this post.' ), array( 'status' => rest_authorization_required_code() ) ); 163 } 164 165 return true; 166 } 167 168 /** 147 169 * Checks if a given request has access to create an autosave revision. 148 170 * … … 178 200 } 179 201 180 $post = get_post( $request ->get_param( 'id' ));202 $post = get_post( $request['id'] ); 181 203 182 204 if ( is_wp_error( $post ) ) { … … 246 268 */ 247 269 public function get_items( $request ) { 248 $parent = $this->get_parent( $request ->get_param( 'parent' ));270 $parent = $this->get_parent( $request['id'] ); 249 271 if ( is_wp_error( $parent ) ) { 250 272 return $parent; … … 390 412 return apply_filters( 'rest_prepare_autosave', $response, $post, $request ); 391 413 } 414 415 /** 416 * Retrieves the query params for the autosaves collection. 417 * 418 * @since 5.0.0 419 * 420 * @return array Collection parameters. 421 */ 422 public function get_collection_params() { 423 return array( 424 'context' => $this->get_context_param( array( 'default' => 'view' ) ), 425 ); 426 } 392 427 } -
trunk/tests/phpunit/tests/rest-api/rest-autosaves-controller.php
r44126 r44250 14 14 protected static $post_id; 15 15 protected static $page_id; 16 protected static $draft_page_id; 16 17 17 18 protected static $autosave_post_id; … … 20 21 protected static $editor_id; 21 22 protected static $contributor_id; 23 24 protected static $parent_page_id; 25 protected static $child_page_id; 26 protected static $child_draft_page_id; 22 27 23 28 protected function set_post_data( $args = array() ) { … … 77 82 ); 78 83 84 self::$draft_page_id = $factory->post->create( array( 85 'post_type' => 'page', 86 'post_status' => 'draft', 87 ) ); 88 self::$parent_page_id = $factory->post->create( array( 89 'post_type' => 'page', 90 ) ); 91 self::$child_page_id = $factory->post->create( array( 92 'post_type' => 'page', 93 'post_parent' => self::$parent_page_id, 94 ) ); 95 self::$child_draft_page_id = $factory->post->create( array( 96 'post_type' => 'page', 97 'post_parent' => self::$parent_page_id, 98 // The "update post" behavior of the autosave endpoint only occurs 99 // when saving a draft/auto-draft authored by the current user. 100 'post_status' => 'draft', 101 'post_author' => self::$editor_id, 102 ) ); 79 103 } 80 104 … … 97 121 public function test_register_routes() { 98 122 $routes = rest_get_server()->get_routes(); 99 $this->assertArrayHasKey( '/wp/v2/posts/(?P< parent>[\d]+)/autosaves', $routes );123 $this->assertArrayHasKey( '/wp/v2/posts/(?P<id>[\d]+)/autosaves', $routes ); 100 124 $this->assertArrayHasKey( '/wp/v2/posts/(?P<parent>[\d]+)/autosaves/(?P<id>[\d]+)', $routes ); 101 $this->assertArrayHasKey( '/wp/v2/pages/(?P< parent>[\d]+)/autosaves', $routes );125 $this->assertArrayHasKey( '/wp/v2/pages/(?P<id>[\d]+)/autosaves', $routes ); 102 126 $this->assertArrayHasKey( '/wp/v2/pages/(?P<parent>[\d]+)/autosaves/(?P<id>[\d]+)', $routes ); 103 127 } … … 118 142 $this->assertEquals( 'view', $data['endpoints'][0]['args']['context']['default'] ); 119 143 $this->assertEqualSets( array( 'view', 'edit', 'embed' ), $data['endpoints'][0]['args']['context']['enum'] ); 144 } 145 146 public function test_registered_query_params() { 147 $request = new WP_REST_Request( 'OPTIONS', '/wp/v2/posts/' . self::$post_id . '/autosaves' ); 148 $response = $this->server->dispatch( $request ); 149 $data = $response->get_data(); 150 $keys = array_keys( $data['endpoints'][0]['args'] ); 151 sort( $keys ); 152 $this->assertEquals( array( 153 'context', 154 'parent', 155 ), $keys ); 120 156 } 121 157 … … 518 554 } 519 555 556 public function test_update_item_draft_page_with_parent() { 557 wp_set_current_user( self::$editor_id ); 558 $request = new WP_REST_Request( 'POST', '/wp/v2/pages/' . self::$child_draft_page_id . '/autosaves' ); 559 $request->add_header( 'content-type', 'application/x-www-form-urlencoded' ); 560 561 $params = $this->set_post_data( 562 array( 563 'id' => self::$child_draft_page_id, 564 'author' => self::$editor_id, 565 ) 566 ); 567 568 $request->set_body_params( $params ); 569 $response = rest_get_server()->dispatch( $request ); 570 $data = $response->get_data(); 571 572 $this->assertEquals( self::$child_draft_page_id, $data['id'] ); 573 $this->assertEquals( self::$parent_page_id, $data['parent'] ); 574 } 575 576 public function test_schema_validation_is_applied() { 577 wp_set_current_user( self::$editor_id ); 578 579 $request = new WP_REST_Request( 'POST', '/wp/v2/pages/' . self::$draft_page_id . '/autosaves' ); 580 $request->add_header( 'content-type', 'application/x-www-form-urlencoded' ); 581 582 $params = $this->set_post_data( array( 583 'id' => self::$draft_page_id, 584 'comment_status' => 'garbage', 585 ) ); 586 587 $request->set_body_params( $params ); 588 589 $response = rest_get_server()->dispatch( $request ); 590 $this->assertNotEquals( 'garbage', get_post( self::$draft_page_id )->comment_status ); 591 } 520 592 } -
trunk/tests/phpunit/tests/rest-api/rest-schema-setup.php
r44218 r44250 90 90 '/wp/v2/posts/(?P<parent>[\\d]+)/revisions', 91 91 '/wp/v2/posts/(?P<parent>[\\d]+)/revisions/(?P<id>[\\d]+)', 92 '/wp/v2/posts/(?P< parent>[\\d]+)/autosaves',92 '/wp/v2/posts/(?P<id>[\\d]+)/autosaves', 93 93 '/wp/v2/posts/(?P<parent>[\\d]+)/autosaves/(?P<id>[\\d]+)', 94 94 '/wp/v2/pages', … … 96 96 '/wp/v2/pages/(?P<parent>[\\d]+)/revisions', 97 97 '/wp/v2/pages/(?P<parent>[\\d]+)/revisions/(?P<id>[\\d]+)', 98 '/wp/v2/pages/(?P< parent>[\\d]+)/autosaves',98 '/wp/v2/pages/(?P<id>[\\d]+)/autosaves', 99 99 '/wp/v2/pages/(?P<parent>[\\d]+)/autosaves/(?P<id>[\\d]+)', 100 100 '/wp/v2/media', … … 102 102 '/wp/v2/blocks', 103 103 '/wp/v2/blocks/(?P<id>[\d]+)', 104 '/wp/v2/blocks/(?P< parent>[\d]+)/autosaves',104 '/wp/v2/blocks/(?P<id>[\d]+)/autosaves', 105 105 '/wp/v2/blocks/(?P<parent>[\d]+)/autosaves/(?P<id>[\d]+)', 106 106 '/wp/v2/types', -
trunk/tests/qunit/fixtures/wp-api-generated.js
r44217 r44250 851 851 ] 852 852 }, 853 "/wp/v2/posts/(?P< parent>[\\d]+)/autosaves": {853 "/wp/v2/posts/(?P<id>[\\d]+)/autosaves": { 854 854 "namespace": "wp/v2", 855 855 "methods": [ … … 878 878 "description": "Scope under which the request is made; determines fields present in response.", 879 879 "type": "string" 880 },881 "page": {882 "required": false,883 "default": 1,884 "description": "Current page of the collection.",885 "type": "integer"886 },887 "per_page": {888 "required": false,889 "description": "Maximum number of items to be returned in result set.",890 "type": "integer"891 },892 "search": {893 "required": false,894 "description": "Limit results to those matching a string.",895 "type": "string"896 },897 "exclude": {898 "required": false,899 "default": [],900 "description": "Ensure result set excludes specific IDs.",901 "type": "array",902 "items": {903 "type": "integer"904 }905 },906 "include": {907 "required": false,908 "default": [],909 "description": "Limit result set to specific IDs.",910 "type": "array",911 "items": {912 "type": "integer"913 }914 },915 "offset": {916 "required": false,917 "description": "Offset the result set by a specific number of items.",918 "type": "integer"919 },920 "order": {921 "required": false,922 "default": "desc",923 "enum": [924 "asc",925 "desc"926 ],927 "description": "Order sort attribute ascending or descending.",928 "type": "string"929 },930 "orderby": {931 "required": false,932 "default": "date",933 "enum": [934 "date",935 "id",936 "include",937 "relevance",938 "slug",939 "include_slugs",940 "title"941 ],942 "description": "Sort collection by object attribute.",943 "type": "string"944 880 } 945 881 } … … 955 891 "type": "integer" 956 892 }, 957 "author": {958 "required": false,959 "description": "The ID for the author of the object.",960 "type": "integer"961 },962 893 "date": { 963 894 "required": false, … … 970 901 "type": "string" 971 902 }, 972 "id": {973 "required": false,974 "description": "Unique identifier for the object.",975 "type": "integer"976 },977 "modified": {978 "required": false,979 "description": "The date the object was last modified, in the site's timezone.",980 "type": "string"981 },982 "modified_gmt": {983 "required": false,984 "description": "The date the object was last modified, as GMT.",985 "type": "string"986 },987 903 "slug": { 988 904 "required": false, 989 905 "description": "An alphanumeric identifier for the object unique to its type.", 906 "type": "string" 907 }, 908 "status": { 909 "required": false, 910 "enum": [ 911 "publish", 912 "future", 913 "draft", 914 "pending", 915 "private" 916 ], 917 "description": "A named status for the object.", 918 "type": "string" 919 }, 920 "password": { 921 "required": false, 922 "description": "A password to protect access to the content and excerpt.", 990 923 "type": "string" 991 924 }, … … 1000 933 "type": "object" 1001 934 }, 935 "author": { 936 "required": false, 937 "description": "The ID for the author of the object.", 938 "type": "integer" 939 }, 1002 940 "excerpt": { 1003 941 "required": false, 1004 942 "description": "The excerpt for the object.", 1005 943 "type": "object" 944 }, 945 "featured_media": { 946 "required": false, 947 "description": "The ID of the featured media for the object.", 948 "type": "integer" 949 }, 950 "comment_status": { 951 "required": false, 952 "enum": [ 953 "open", 954 "closed" 955 ], 956 "description": "Whether or not comments are open on the object.", 957 "type": "string" 958 }, 959 "ping_status": { 960 "required": false, 961 "enum": [ 962 "open", 963 "closed" 964 ], 965 "description": "Whether or not the object can be pinged.", 966 "type": "string" 967 }, 968 "format": { 969 "required": false, 970 "enum": [ 971 "standard", 972 "aside", 973 "chat", 974 "gallery", 975 "link", 976 "image", 977 "quote", 978 "status", 979 "video", 980 "audio" 981 ], 982 "description": "The format for the object.", 983 "type": "string" 984 }, 985 "meta": { 986 "required": false, 987 "description": "Meta fields.", 988 "type": "object" 989 }, 990 "sticky": { 991 "required": false, 992 "description": "Whether or not the object should be treated as sticky.", 993 "type": "boolean" 994 }, 995 "template": { 996 "required": false, 997 "description": "The theme file to use to display the object.", 998 "type": "string" 999 }, 1000 "categories": { 1001 "required": false, 1002 "description": "The terms assigned to the object in the category taxonomy.", 1003 "type": "array", 1004 "items": { 1005 "type": "integer" 1006 } 1007 }, 1008 "tags": { 1009 "required": false, 1010 "description": "The terms assigned to the object in the post_tag taxonomy.", 1011 "type": "array", 1012 "items": { 1013 "type": "integer" 1014 } 1006 1015 } 1007 1016 } … … 1651 1660 ] 1652 1661 }, 1653 "/wp/v2/pages/(?P< parent>[\\d]+)/autosaves": {1662 "/wp/v2/pages/(?P<id>[\\d]+)/autosaves": { 1654 1663 "namespace": "wp/v2", 1655 1664 "methods": [ … … 1678 1687 "description": "Scope under which the request is made; determines fields present in response.", 1679 1688 "type": "string" 1680 },1681 "page": {1682 "required": false,1683 "default": 1,1684 "description": "Current page of the collection.",1685 "type": "integer"1686 },1687 "per_page": {1688 "required": false,1689 "description": "Maximum number of items to be returned in result set.",1690 "type": "integer"1691 },1692 "search": {1693 "required": false,1694 "description": "Limit results to those matching a string.",1695 "type": "string"1696 },1697 "exclude": {1698 "required": false,1699 "default": [],1700 "description": "Ensure result set excludes specific IDs.",1701 "type": "array",1702 "items": {1703 "type": "integer"1704 }1705 },1706 "include": {1707 "required": false,1708 "default": [],1709 "description": "Limit result set to specific IDs.",1710 "type": "array",1711 "items": {1712 "type": "integer"1713 }1714 },1715 "offset": {1716 "required": false,1717 "description": "Offset the result set by a specific number of items.",1718 "type": "integer"1719 },1720 "order": {1721 "required": false,1722 "default": "desc",1723 "enum": [1724 "asc",1725 "desc"1726 ],1727 "description": "Order sort attribute ascending or descending.",1728 "type": "string"1729 },1730 "orderby": {1731 "required": false,1732 "default": "date",1733 "enum": [1734 "date",1735 "id",1736 "include",1737 "relevance",1738 "slug",1739 "include_slugs",1740 "title"1741 ],1742 "description": "Sort collection by object attribute.",1743 "type": "string"1744 1689 } 1745 1690 } … … 1755 1700 "type": "integer" 1756 1701 }, 1757 "author": {1758 "required": false,1759 "description": "The ID for the author of the object.",1760 "type": "integer"1761 },1762 1702 "date": { 1763 1703 "required": false, … … 1770 1710 "type": "string" 1771 1711 }, 1772 "id": {1773 "required": false,1774 "description": "Unique identifier for the object.",1775 "type": "integer"1776 },1777 "modified": {1778 "required": false,1779 "description": "The date the object was last modified, in the site's timezone.",1780 "type": "string"1781 },1782 "modified_gmt": {1783 "required": false,1784 "description": "The date the object was last modified, as GMT.",1785 "type": "string"1786 },1787 1712 "slug": { 1788 1713 "required": false, 1789 1714 "description": "An alphanumeric identifier for the object unique to its type.", 1715 "type": "string" 1716 }, 1717 "status": { 1718 "required": false, 1719 "enum": [ 1720 "publish", 1721 "future", 1722 "draft", 1723 "pending", 1724 "private" 1725 ], 1726 "description": "A named status for the object.", 1727 "type": "string" 1728 }, 1729 "password": { 1730 "required": false, 1731 "description": "A password to protect access to the content and excerpt.", 1790 1732 "type": "string" 1791 1733 }, … … 1800 1742 "type": "object" 1801 1743 }, 1744 "author": { 1745 "required": false, 1746 "description": "The ID for the author of the object.", 1747 "type": "integer" 1748 }, 1802 1749 "excerpt": { 1803 1750 "required": false, 1804 1751 "description": "The excerpt for the object.", 1805 1752 "type": "object" 1753 }, 1754 "featured_media": { 1755 "required": false, 1756 "description": "The ID of the featured media for the object.", 1757 "type": "integer" 1758 }, 1759 "comment_status": { 1760 "required": false, 1761 "enum": [ 1762 "open", 1763 "closed" 1764 ], 1765 "description": "Whether or not comments are open on the object.", 1766 "type": "string" 1767 }, 1768 "ping_status": { 1769 "required": false, 1770 "enum": [ 1771 "open", 1772 "closed" 1773 ], 1774 "description": "Whether or not the object can be pinged.", 1775 "type": "string" 1776 }, 1777 "menu_order": { 1778 "required": false, 1779 "description": "The order of the object in relation to other object of its type.", 1780 "type": "integer" 1781 }, 1782 "meta": { 1783 "required": false, 1784 "description": "Meta fields.", 1785 "type": "object" 1786 }, 1787 "template": { 1788 "required": false, 1789 "description": "The theme file to use to display the object.", 1790 "type": "string" 1806 1791 } 1807 1792 } … … 2585 2570 ] 2586 2571 }, 2587 "/wp/v2/blocks/(?P< parent>[\\d]+)/autosaves": {2572 "/wp/v2/blocks/(?P<id>[\\d]+)/autosaves": { 2588 2573 "namespace": "wp/v2", 2589 2574 "methods": [ … … 2612 2597 "description": "Scope under which the request is made; determines fields present in response.", 2613 2598 "type": "string" 2614 },2615 "page": {2616 "required": false,2617 "default": 1,2618 "description": "Current page of the collection.",2619 "type": "integer"2620 },2621 "per_page": {2622 "required": false,2623 "description": "Maximum number of items to be returned in result set.",2624 "type": "integer"2625 },2626 "search": {2627 "required": false,2628 "description": "Limit results to those matching a string.",2629 "type": "string"2630 },2631 "exclude": {2632 "required": false,2633 "default": [],2634 "description": "Ensure result set excludes specific IDs.",2635 "type": "array",2636 "items": {2637 "type": "integer"2638 }2639 },2640 "include": {2641 "required": false,2642 "default": [],2643 "description": "Limit result set to specific IDs.",2644 "type": "array",2645 "items": {2646 "type": "integer"2647 }2648 },2649 "offset": {2650 "required": false,2651 "description": "Offset the result set by a specific number of items.",2652 "type": "integer"2653 },2654 "order": {2655 "required": false,2656 "default": "desc",2657 "enum": [2658 "asc",2659 "desc"2660 ],2661 "description": "Order sort attribute ascending or descending.",2662 "type": "string"2663 },2664 "orderby": {2665 "required": false,2666 "default": "date",2667 "enum": [2668 "date",2669 "id",2670 "include",2671 "relevance",2672 "slug",2673 "include_slugs",2674 "title"2675 ],2676 "description": "Sort collection by object attribute.",2677 "type": "string"2678 2599 } 2679 2600 } … … 2689 2610 "type": "integer" 2690 2611 }, 2691 "author": {2692 "required": false,2693 "description": "The ID for the author of the object.",2694 "type": "integer"2695 },2696 2612 "date": { 2697 2613 "required": false, … … 2704 2620 "type": "string" 2705 2621 }, 2706 "id": {2707 "required": false,2708 "description": "Unique identifier for the object.",2709 "type": "integer"2710 },2711 "modified": {2712 "required": false,2713 "description": "The date the object was last modified, in the site's timezone.",2714 "type": "string"2715 },2716 "modified_gmt": {2717 "required": false,2718 "description": "The date the object was last modified, as GMT.",2719 "type": "string"2720 },2721 2622 "slug": { 2722 2623 "required": false, 2723 2624 "description": "An alphanumeric identifier for the object unique to its type.", 2625 "type": "string" 2626 }, 2627 "status": { 2628 "required": false, 2629 "enum": [ 2630 "publish", 2631 "future", 2632 "draft", 2633 "pending", 2634 "private" 2635 ], 2636 "description": "A named status for the object.", 2637 "type": "string" 2638 }, 2639 "password": { 2640 "required": false, 2641 "description": "A password to protect access to the content and excerpt.", 2724 2642 "type": "string" 2725 2643 }, … … 2733 2651 "description": "The content for the object.", 2734 2652 "type": "object" 2653 }, 2654 "template": { 2655 "required": false, 2656 "description": "The theme file to use to display the object.", 2657 "type": "string" 2735 2658 } 2736 2659 }
Note: See TracChangeset
for help on using the changeset viewer.