Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -326,10 +326,9 @@ public function get_items( $request ) {

$query = new WP_Comment_Query();
$query_result = $query->query( $prepared_args );
$comments = array();

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a minor fix to satisfy static checks.


if ( ! $is_head_request ) {
$comments = array();

foreach ( $query_result as $comment ) {
if ( ! $this->check_read_permission( $comment, $request ) ) {
continue;
Expand Down Expand Up @@ -1243,7 +1242,18 @@ public function prepare_item_for_response( $item, $request ) {
$response = rest_ensure_response( $data );

if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$response->add_links( $this->prepare_links( $comment ) );
$links = $this->prepare_links( $comment );
$response->add_links( $links );

if ( ! empty( $links['self']['href'] ) ) {
$actions = $this->get_available_actions( $comment, $request );

$self = $links['self']['href'];

foreach ( $actions as $rel ) {
$response->add_link( $rel, $self );
}
}
}

/**
Expand Down Expand Up @@ -1346,6 +1356,32 @@ protected function prepare_links( $comment ) {
return $links;
}

/**
* Gets the link relations available for the comment and current user.
*
* @since 7.2.0
*
* @param WP_Comment $comment Comment object.
* @param WP_REST_Request $request Request object.
* @return string[] List of link relations.
*/
protected function get_available_actions( $comment, $request ) {
if ( 'edit' !== $request['context'] ) {
return array();
}

$rels = array();

if ( 'trash' !== $comment->comment_approved && $this->check_edit_permission( $comment ) ) {
/** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php */
if ( apply_filters( 'rest_comment_trashable', ( EMPTY_TRASH_DAYS > 0 ), $comment ) ) {
$rels[] = 'https://api.w.org/action-trash';
}
}

return $rels;
}

/**
* Prepends internal property prefix to query parameters to match our response fields.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -691,6 +691,23 @@ protected function prepare_links( $post ) {
return $links;
}

/**
* Gets the link relations available for the menu item and current user.
*
* Menu items can only be deleted permanently, so the `action-trash` link is skipped.
*
* @since 7.2.0
*
* @param WP_Post $post Post object.
* @param WP_REST_Request $request Request object.
* @return array List of link relations.
*/
protected function get_available_actions( $post, $request ) {
$rels = parent::get_available_actions( $post, $request );

return array_values( array_diff( $rels, array( 'https://api.w.org/action-trash' ) ) );
}

/**
* Retrieves Link Description Objects that should be added to the Schema for the nav menu items collection.
*
Expand All @@ -700,6 +717,7 @@ protected function prepare_links( $post ) {
*/
protected function get_schema_links() {
$links = parent::get_schema_links();
$links = array_values( wp_list_filter( $links, array( 'rel' => 'https://api.w.org/action-trash' ), 'NOT' ) );
$href = rest_url( "{$this->namespace}/{$this->rest_base}/{id}" );
$links[] = array(
'rel' => 'https://api.w.org/menu-item-object',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -455,9 +455,8 @@ static function ( $format ) {
add_filter( 'post_password_required', array( $this, 'check_password_required' ), 10, 2 );
}

$posts = array();

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

if ( ! $is_head_request ) {
$posts = array();

update_post_author_caches( $query_result );
update_post_parent_caches( $query_result );

Expand Down Expand Up @@ -2334,6 +2333,7 @@ protected function prepare_links( $post ) {
* Gets the link relations available for the post and current user.
*
* @since 4.9.8
* @since 7.2.0 Added the `action-trash` link relation.
*
* @param WP_Post $post Post object.
* @param WP_REST_Request $request Request object.
Expand Down Expand Up @@ -2369,6 +2369,19 @@ protected function get_available_actions( $post, $request ) {
}
}

if ( 'trash' !== $post->post_status && $this->check_delete_permission( $post ) ) {
$supports_trash = ( EMPTY_TRASH_DAYS > 0 );

if ( 'attachment' === $post->post_type ) {
$supports_trash = $supports_trash && MEDIA_TRASH;
}

/** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php */
if ( apply_filters( "rest_{$this->post_type}_trashable", $supports_trash, $post ) ) {
$rels[] = 'https://api.w.org/action-trash';
}
}

$taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) );

foreach ( $taxonomies as $tax ) {
Expand Down Expand Up @@ -2840,6 +2853,7 @@ public function get_item_schema() {
* Retrieves Link Description Objects that should be added to the Schema for the posts collection.
*
* @since 4.9.8
* @since 7.2.0 Added the `action-trash` link relation.
*
* @return array
*/
Expand Down Expand Up @@ -2914,6 +2928,12 @@ protected function get_schema_links() {
);
}

$links[] = array(
'rel' => 'https://api.w.org/action-trash',
'title' => __( 'The current user can move this post to the trash.' ),
'href' => $href,
);

$taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) );

foreach ( $taxonomies as $tax ) {
Expand Down
21 changes: 21 additions & 0 deletions tests/phpunit/tests/rest-api/rest-attachments-controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -2635,6 +2635,27 @@ public function test_publish_action_link_does_not_exists() {
$this->assertArrayNotHasKey( 'https://api.w.org/action-publish', $links );
}

/**
* @ticket 63670
*
* @covers WP_REST_Posts_Controller::get_available_actions
*/
public function test_trash_action_link_does_not_exist_without_media_trash() {
$this->assertFalse( MEDIA_TRASH, 'The test expects the default MEDIA_TRASH value.' );

wp_set_current_user( self::$editor_id );

$post = self::factory()->attachment->create( array( 'post_author' => self::$editor_id ) );

$request = new WP_REST_Request( 'GET', "/wp/v2/media/{$post}" );
$request->set_query_params( array( 'context' => 'edit' ) );

$response = rest_get_server()->dispatch( $request );
$links = $response->get_links();

$this->assertArrayNotHasKey( 'https://api.w.org/action-trash', $links );
}

protected function check_post_data( $attachment, $data, $context = 'view', $links = array() ) {
parent::check_post_data( $attachment, $data, $context, $links );

Expand Down
55 changes: 48 additions & 7 deletions tests/phpunit/tests/rest-api/rest-comments-controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -3494,15 +3494,19 @@ protected function check_comment_data( $data, $context, $links ) {
$this->assertSame( mysql_to_rfc3339( $comment->comment_date_gmt ), $data['date_gmt'] );
$this->assertSame( get_comment_link( $comment ), $data['link'] );
$this->assertArrayHasKey( 'author_avatar_urls', $data );
$this->assertSameSets(
array(
'self',
'collection',
'up',
),
array_keys( $links )

$expected_links = array(
'self',
'collection',
'up',
);

if ( 'edit' === $context ) {
$expected_links[] = 'https://api.w.org/action-trash';
}

$this->assertSameSets( $expected_links, array_keys( $links ) );

if ( $comment->comment_post_ID ) {
$this->assertSame( rest_url( '/wp/v2/posts/' . $comment->comment_post_ID ), $links['up'][0]['href'] );
}
Expand Down Expand Up @@ -4189,6 +4193,43 @@ public function test_get_note_with_children_link() {
$this->assertStringContainsString( 'type=note', $children[0]['href'] );
}

/**
* @ticket 63670
*
* @covers WP_REST_Comments_Controller::get_available_actions
*/
public function test_trash_action_link_does_not_exist_when_not_trashable() {
add_filter( 'rest_comment_trashable', '__return_false' );
wp_set_current_user( self::$moderator_id );

$request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/comments/%d', self::$approved_id ) );
$request->set_param( 'context', 'edit' );
$response = rest_get_server()->dispatch( $request );

$this->assertArrayNotHasKey( 'https://api.w.org/action-trash', $response->get_links() );
}

/**
* @ticket 63670
*
* @covers WP_REST_Comments_Controller::get_available_actions
*/
public function test_trash_action_link_does_not_exist_for_trashed_comment() {
$comment_id = self::factory()->comment->create(
array(
'comment_approved' => 'trash',
'comment_post_ID' => self::$post_id,
)
);
wp_set_current_user( self::$moderator_id );

$request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/comments/%d', $comment_id ) );
$request->set_param( 'context', 'edit' );
$response = rest_get_server()->dispatch( $request );

$this->assertArrayNotHasKey( 'https://api.w.org/action-trash', $response->get_links() );
}

/**
* Test retrieving comments by type as authenticated user.
*
Expand Down
72 changes: 72 additions & 0 deletions tests/phpunit/tests/rest-api/rest-posts-controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -5229,6 +5229,22 @@ public function test_sticky_action_ldo_not_registered_for_non_posts() {
$this->assertCount( 0, $publish, 'LDO found on schema.' );
}

/**
* @ticket 63670
*
* @covers WP_REST_Posts_Controller::get_schema_links
*/
public function test_trash_action_ldo_registered() {
$response = rest_get_server()->dispatch( new WP_REST_Request( 'OPTIONS', '/wp/v2/posts' ) );
$data = $response->get_data();
$schema = $data['schema'];

$this->assertArrayHasKey( 'links', $schema );
$trash = wp_list_filter( $schema['links'], array( 'rel' => 'https://api.w.org/action-trash' ) );

$this->assertCount( 1, $trash, 'LDO found on schema.' );
}

public function test_author_action_ldo_registered_for_post_types_with_author_support() {
$response = rest_get_server()->dispatch( new WP_REST_Request( 'OPTIONS', '/wp/v2/posts' ) );
$data = $response->get_data();
Expand Down Expand Up @@ -5373,6 +5389,62 @@ public function test_sticky_action_does_not_exist_for_non_post_posts() {
$this->assertArrayNotHasKey( 'https://api.w.org/action-sticky', $links );
}

/**
* @ticket 63670
*
* @covers WP_REST_Posts_Controller::get_available_actions
*/
public function test_trash_action_exists_for_author() {
wp_set_current_user( self::$author_id );

$post = self::factory()->post->create( array( 'post_author' => self::$author_id ) );

$request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
$request->set_query_params( array( 'context' => 'edit' ) );

$response = rest_get_server()->dispatch( $request );
$links = $response->get_links();

$this->assertArrayHasKey( 'https://api.w.org/action-trash', $links );
}

/**
* @ticket 63670
*
* @covers WP_REST_Posts_Controller::get_available_actions
*/
public function test_trash_action_does_not_exist_when_not_trashable() {
add_filter( 'rest_post_trashable', '__return_false' );
wp_set_current_user( self::$editor_id );

$request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id );
$request->set_query_params( array( 'context' => 'edit' ) );

$response = rest_get_server()->dispatch( $request );
$links = $response->get_links();

$this->assertArrayNotHasKey( 'https://api.w.org/action-trash', $links );
}

/**
* @ticket 63670
*
* @covers WP_REST_Posts_Controller::get_available_actions
*/
public function test_trash_action_does_not_exist_for_trashed_post() {
wp_set_current_user( self::$editor_id );

$post = self::factory()->post->create( array( 'post_status' => 'trash' ) );

$request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
$request->set_query_params( array( 'context' => 'edit' ) );

$response = rest_get_server()->dispatch( $request );
$links = $response->get_links();

$this->assertArrayNotHasKey( 'https://api.w.org/action-trash', $links );
}


public function test_assign_author_action_exists_for_editor() {
wp_set_current_user( self::$editor_id );
Expand Down
32 changes: 32 additions & 0 deletions tests/phpunit/tests/rest-api/wpRestMenuItemsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,38 @@ public function test_get_item() {
$this->check_get_menu_item_response( $response, 'view' );
}

/**
* @ticket 63670
*
* @covers ::get_available_actions
*/
public function test_get_item_has_no_trash_action_link() {
wp_set_current_user( self::$admin_id );
$request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/menu-items/%d', $this->menu_item_id ) );
$request->set_param( 'context', 'edit' );
$response = rest_get_server()->dispatch( $request );
$links = $response->get_links();

$this->assertArrayHasKey( 'self', $links, 'The response should have a self link.' );
$this->assertArrayNotHasKey( 'https://api.w.org/action-trash', $links, 'The response should not have a trash action link.' );
}

/**
* @ticket 63670
*
* @covers ::get_schema_links
*/
public function test_trash_action_ldo_not_registered() {
$response = rest_get_server()->dispatch( new WP_REST_Request( 'OPTIONS', '/wp/v2/menu-items' ) );
$data = $response->get_data();
$schema = $data['schema'];

$this->assertArrayHasKey( 'links', $schema );
$trash = wp_list_filter( $schema['links'], array( 'rel' => 'https://api.w.org/action-trash' ) );

$this->assertCount( 0, $trash, 'LDO found on schema.' );
}

/**
* @ticket 54304
* @covers ::get_items
Expand Down
Loading