[wp-trac] [WordPress Trac] #43316: REST API: Support autosaves

WordPress Trac noreply at wordpress.org
Wed Nov 14 18:12:32 UTC 2018


#43316: REST API: Support autosaves
------------------------------------------+-----------------------
 Reporter:  kraftbj                       |       Owner:  rmccue
     Type:  enhancement                   |      Status:  reopened
 Priority:  normal                        |   Milestone:  5.0
Component:  REST API                      |     Version:
 Severity:  normal                        |  Resolution:
 Keywords:  needs-patch needs-unit-tests  |     Focuses:  rest-api
------------------------------------------+-----------------------

Comment (by TimothyBlynJacobs):

 So in https://github.com/WordPress/gutenberg/issues/10753, it was reported
 that the post parent was being lost during an autosave. In the PR,
 https://github.com/WordPress/gutenberg/pull/11513, @aduth solved this by
 manually unsetting the `post_parent` after the posts controller had set it
 from the request data. This was also accompanied by a change in the JS
 code to not send the `parent` ( the ID of the post being autosaved ) to
 the endpoint as well.

 Looking at that change one might think that the accompanying PHP change
 would be no longer necessary since the parent was no longer being sent
 with the JS code. That's what Daniel and I thought. And looking at the
 autosave controller, came to the conclusion that all fields were
 mistakenly being allowed to be updated and the filtering in
 `_wp_post_revision_fields` should be applied. However, after further
 investigation, that behavior is intentional and any `wp_insert_post`
 compatible field will be updated when the post is a draft and the current
 user is the `post_author` of that post.

 If the `parent` property is no longer being sent in the request data, then
 how is the post parent getting changed? For that we can look at the route
 definition for the autosaves route.

 {{{
 '/' . $this->parent_base . '/(?P<parent>[\d]+)/' . $this->rest_base
 }}}

 Here we find the source of the mysterious parent field. `parent` here is
 indicating the ID of the post being autosaved. The WP REST Request object
 allows you to access any parameter in the request, a JSON param, post
 data, query param and even indeed URL parameters by using
 `WP_REST_Request::get_param()`. So when the request object was sent to the
 posts controller to format it for the database, it saw that indeed the
 `parent` parameter was in the request, and changed the parent ID to be the
 post itself! https://github.com/WordPress/wordpress-develop/blob/5.0/src
 /wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php#L1069

 When WordPress inserts a post object, it applies a filter on the parent ID
 to check that it is valid. The `post_parent` being equal to the `ID` is
 not valid, so WordPress changes the `post_parent` value to `0`. And that
 is how the `post_parent` ends up lost.

 Are we back to unsetting the `post_parent` manually then? No, because
 again, the Classic Editor supports auto-saving the post parent and
 changing it to a different value. So if we unset the post parent, we
 wouldn't be able to autosave any changes to it.

 **TLDR**: Instead, I believe we should change the route definition to use
 `id` as the field name in the URL for the collection and creation route.

 I believe `parent` was chosen to match with
 `WP_REST_Revisions_Controller`. But the only reason the revisions
 controller hasn't run into this issue is that it has no write endpoints.
 Only read and delete. The autosaves controller reuses the revisions
 controller which checks for a `parent` request object. I think we should
 instead have our own version of `get_items_permission_check()`.
 Alternately, we'd need to change the URL parameter in the revisions
 controller which I don't think is feasible for BC reasons.

 ----

 Side note. I really think we should stop subclassing the revisions
 controller and instead subclass the `WP_REST_Controller`. We are already
 instantiating an instance of the revisions controller. The only time I
 could see the subclass being used was to leverage access to the
 `WP_REST_Revisions_Controller::get_parent()` through the
 `$revisions_controller` property because that method is `protected`. We
 can instead inline that definition or make the method public.
 Additionally, by subclassing like this we are advertising that this
 endpoint supports a host of collection parameters that we don't.

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/43316#comment:128>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list