[wp-trac] [WordPress Trac] #40889: REST API: New terms creation with meta causes PHP Notice
WordPress Trac
noreply at wordpress.org
Tue May 30 23:29:08 UTC 2017
#40889: REST API: New terms creation with meta causes PHP Notice
--------------------------+-----------------------------
Reporter: caercam | Owner:
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: REST API | Version: 4.7
Severity: normal | Keywords:
Focuses: rest-api |
--------------------------+-----------------------------
Creating new terms with the REST API works fine, as long as there is no
meta attached:
{{{
POST https://localhost:8080/wp-json/wp/v2/categories
X-WP-Nonce: 1234567890
Content-Type: application/json
{"name":"A new category","description":"This is a new
category.","meta":{"custom_meta":"Custom Meta Value"}}
-- response --
403 Forbidden
<br />
<b>Notice</b>: Undefined property: WP_Error::$taxonomy in
<b>/var/www/wp47/wp-includes/capabilities.php</b> on line <b>282</b><br />
{"code":"rest_cannot_update","message":"Sorry, you are not allowed to edit
the custom_meta custom field.","data":{"key":"custom_meta","status":403}}
}}}
For the record, here's what happens as far as I can tell. Probably more
detailled than what's really needed, but there's two different issues here
so I'd rather be precise.
1. `WP_REST_Terms_Controller::create_item()` calls
`WP_REST_Meta_Fields::update_value()` with two arguments:
`$request['meta']`, which is what we want, and `$request['id']`, which at
this point is `null`, because we are creating a new term, not editing an
existing one.
2. `WP_REST_Meta_Fields::update_value()` loops through the registered meta
keys and calls `WP_REST_Meta_Fields::update_meta_value()` or
`WP_REST_Meta_Fields::update_multi_meta_value()`.
3. Because `WP_REST_Terms_Controller::create_item()` casted as integer an
ID that does not exist, both meta_value update methods get a `$object_id`
= `0`, and use that value to check for permission to edit meta.
4. Now it's capabilities fairy: `current_user_can()` calls
`WP_User::has_cap()` which calls `map_meta_cap()` which checks for the
term existence with a simple boolean test on the result of `get_term()`.
5. But, because of `$object_id` value being `0`, `get_term()` returns a
`WP_Error` instance, the check mentionned in 4. fails, and we get the
"Undefined property" notice that end up in the REST API request response.
TL;DR: Two issues here:
1. `WP_REST_Terms_Controller::create_item()` passes an unexisting value to
the meta_value upate methods, indirectly triggering a bug in
`map_meta_cap()`;
2. `map_meta_cap()` does not break as it should if `get_term()` returns an
error.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/40889>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list