[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