Skip to content

Commit 4603e92

Browse files
committed
Media: Skip the edit root link when the edit root cannot be read.
The `wp:edit-root` link promises that `_embed` can fetch the edit root, but the recorded ID is not checked, so an edit root that no longer exists, or one the user cannot read, was still offered as a link. The link now uses the same check as the `featured_media` link: it is added only when the edit root is published or the user can read it. The `edit_root` field still reports the recorded ID as is. Follows WordPress/gutenberg#81803. See #65987.
1 parent ea3620e commit 4603e92

2 files changed

Lines changed: 30 additions & 1 deletion

File tree

‎src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1694,14 +1694,19 @@ public function prepare_item_for_response( $item, $request ) {
16941694
* Embeddable link to the edit root, like `featured_media`. Added here rather than
16951695
* in `prepare_links()`, which cannot see the request, and gated like the parent
16961696
* controller's own links so a `_fields` request is not handed a stray `_links`.
1697+
* Like `featured_media`, the link is skipped when the edit root no longer exists
1698+
* or the user cannot read it, although the `edit_root` field still reports the ID.
16971699
*/
16981700
if (
16991701
'edit' === $request['context'] &&
17001702
( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) )
17011703
) {
17021704
$edit_root_id = wp_get_edit_root_attachment_id( $post->ID );
17031705

1704-
if ( $edit_root_id !== (int) $post->ID ) {
1706+
if (
1707+
$edit_root_id !== (int) $post->ID &&
1708+
( 'publish' === get_post_status( $edit_root_id ) || current_user_can( 'read_post', $edit_root_id ) )
1709+
) {
17051710
$response->add_link(
17061711
'https://api.w.org/edit-root',
17071712
rest_url( rest_get_route_for_post( $edit_root_id ) ),

‎tests/phpunit/tests/rest-api/rest-attachments-controller.php‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6567,6 +6567,30 @@ public function test_attachment_recorded_as_its_own_edit_root_reports_none() {
65676567
$this->assertSame( 0, $data['edit_root'] );
65686568
}
65696569

6570+
/**
6571+
* The field reports the recorded ID as is, but the link is only offered when the
6572+
* edit root exists and can be read, in the same way as a featured image.
6573+
*
6574+
* @ticket 65987
6575+
*/
6576+
public function test_missing_edit_root_keeps_the_field_but_omits_the_link() {
6577+
wp_set_current_user( self::$superadmin_id );
6578+
$attachment = self::factory()->attachment->create_upload_object( self::$test_file );
6579+
6580+
update_post_meta( $attachment, '_wp_attachment_edit_root_id', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER );
6581+
6582+
$request = new WP_REST_Request( 'GET', "/wp/v2/media/{$attachment}" );
6583+
$request->set_param( 'context', 'edit' );
6584+
$response = rest_do_request( $request );
6585+
6586+
$this->assertSame( REST_TESTS_IMPOSSIBLY_HIGH_NUMBER, $response->get_data()['edit_root'] );
6587+
$this->assertArrayNotHasKey(
6588+
'https://api.w.org/edit-root',
6589+
$response->get_links(),
6590+
'A missing edit root should carry no link.'
6591+
);
6592+
}
6593+
65706594
/**
65716595
* Trashing is not deleting. `delete_attachment` does not fire for a trashed
65726596
* attachment, and the record is deliberately left in place so that untrashing

0 commit comments

Comments
 (0)