wp/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php
changeset 9 177826044cd9
parent 7 cf61fcea0001
child 16 a86126ab1dd4
equal deleted inserted replaced
8:c7c34916027a 9:177826044cd9
    41 	 *
    41 	 *
    42 	 * @since 4.7.0
    42 	 * @since 4.7.0
    43 	 */
    43 	 */
    44 	public function register_routes() {
    44 	public function register_routes() {
    45 
    45 
    46 		register_rest_route( $this->namespace, '/' . $this->rest_base, array(
    46 		register_rest_route(
       
    47 			$this->namespace,
       
    48 			'/' . $this->rest_base,
    47 			array(
    49 			array(
    48 				'methods'   => WP_REST_Server::READABLE,
    50 				array(
    49 				'callback'  => array( $this, 'get_items' ),
    51 					'methods'             => WP_REST_Server::READABLE,
    50 				'permission_callback' => array( $this, 'get_items_permissions_check' ),
    52 					'callback'            => array( $this, 'get_items' ),
    51 				'args'      => $this->get_collection_params(),
    53 					'permission_callback' => array( $this, 'get_items_permissions_check' ),
    52 			),
    54 					'args'                => $this->get_collection_params(),
       
    55 				),
       
    56 				array(
       
    57 					'methods'             => WP_REST_Server::CREATABLE,
       
    58 					'callback'            => array( $this, 'create_item' ),
       
    59 					'permission_callback' => array( $this, 'create_item_permissions_check' ),
       
    60 					'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),
       
    61 				),
       
    62 				'schema' => array( $this, 'get_public_item_schema' ),
       
    63 			)
       
    64 		);
       
    65 
       
    66 		register_rest_route(
       
    67 			$this->namespace,
       
    68 			'/' . $this->rest_base . '/(?P<id>[\d]+)',
    53 			array(
    69 			array(
    54 				'methods'  => WP_REST_Server::CREATABLE,
    70 				'args'   => array(
    55 				'callback' => array( $this, 'create_item' ),
    71 					'id' => array(
    56 				'permission_callback' => array( $this, 'create_item_permissions_check' ),
    72 						'description' => __( 'Unique identifier for the object.' ),
    57 				'args'     => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),
    73 						'type'        => 'integer',
    58 			),
       
    59 			'schema' => array( $this, 'get_public_item_schema' ),
       
    60 		) );
       
    61 
       
    62 		register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)', array(
       
    63 			'args' => array(
       
    64 				'id' => array(
       
    65 					'description' => __( 'Unique identifier for the object.' ),
       
    66 					'type'        => 'integer',
       
    67 				),
       
    68 			),
       
    69 			array(
       
    70 				'methods'  => WP_REST_Server::READABLE,
       
    71 				'callback' => array( $this, 'get_item' ),
       
    72 				'permission_callback' => array( $this, 'get_item_permissions_check' ),
       
    73 				'args'     => array(
       
    74 					'context'          => $this->get_context_param( array( 'default' => 'view' ) ),
       
    75 					'password' => array(
       
    76 						'description' => __( 'The password for the parent post of the comment (if the post is password protected).' ),
       
    77 						'type'        => 'string',
       
    78 					),
    74 					),
    79 				),
    75 				),
    80 			),
    76 				array(
    81 			array(
    77 					'methods'             => WP_REST_Server::READABLE,
    82 				'methods'  => WP_REST_Server::EDITABLE,
    78 					'callback'            => array( $this, 'get_item' ),
    83 				'callback' => array( $this, 'update_item' ),
    79 					'permission_callback' => array( $this, 'get_item_permissions_check' ),
    84 				'permission_callback' => array( $this, 'update_item_permissions_check' ),
    80 					'args'                => array(
    85 				'args'     => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
    81 						'context'  => $this->get_context_param( array( 'default' => 'view' ) ),
    86 			),
    82 						'password' => array(
    87 			array(
    83 							'description' => __( 'The password for the parent post of the comment (if the post is password protected).' ),
    88 				'methods'  => WP_REST_Server::DELETABLE,
    84 							'type'        => 'string',
    89 				'callback' => array( $this, 'delete_item' ),
    85 						),
    90 				'permission_callback' => array( $this, 'delete_item_permissions_check' ),
       
    91 				'args'     => array(
       
    92 					'force'    => array(
       
    93 						'type'        => 'boolean',
       
    94 						'default'     => false,
       
    95 						'description' => __( 'Whether to bypass trash and force deletion.' ),
       
    96 					),
    86 					),
    97 					'password' => array(
    87 				),
    98 						'description' => __( 'The password for the parent post of the comment (if the post is password protected).' ),
    88 				array(
    99 						'type'        => 'string',
    89 					'methods'             => WP_REST_Server::EDITABLE,
       
    90 					'callback'            => array( $this, 'update_item' ),
       
    91 					'permission_callback' => array( $this, 'update_item_permissions_check' ),
       
    92 					'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
       
    93 				),
       
    94 				array(
       
    95 					'methods'             => WP_REST_Server::DELETABLE,
       
    96 					'callback'            => array( $this, 'delete_item' ),
       
    97 					'permission_callback' => array( $this, 'delete_item_permissions_check' ),
       
    98 					'args'                => array(
       
    99 						'force'    => array(
       
   100 							'type'        => 'boolean',
       
   101 							'default'     => false,
       
   102 							'description' => __( 'Whether to bypass trash and force deletion.' ),
       
   103 						),
       
   104 						'password' => array(
       
   105 							'description' => __( 'The password for the parent post of the comment (if the post is password protected).' ),
       
   106 							'type'        => 'string',
       
   107 						),
   100 					),
   108 					),
   101 				),
   109 				),
   102 			),
   110 				'schema' => array( $this, 'get_public_item_schema' ),
   103 			'schema' => array( $this, 'get_public_item_schema' ),
   111 			)
   104 		) );
   112 		);
   105 	}
   113 	}
   106 
   114 
   107 	/**
   115 	/**
   108 	 * Checks if a given request has access to read comments.
   116 	 * Checks if a given request has access to read comments.
   109 	 *
   117 	 *
   243 		 * @param array           $prepared_args Array of arguments for WP_Comment_Query.
   251 		 * @param array           $prepared_args Array of arguments for WP_Comment_Query.
   244 		 * @param WP_REST_Request $request       The current request.
   252 		 * @param WP_REST_Request $request       The current request.
   245 		 */
   253 		 */
   246 		$prepared_args = apply_filters( 'rest_comment_query', $prepared_args, $request );
   254 		$prepared_args = apply_filters( 'rest_comment_query', $prepared_args, $request );
   247 
   255 
   248 		$query = new WP_Comment_Query;
   256 		$query        = new WP_Comment_Query;
   249 		$query_result = $query->query( $prepared_args );
   257 		$query_result = $query->query( $prepared_args );
   250 
   258 
   251 		$comments = array();
   259 		$comments = array();
   252 
   260 
   253 		foreach ( $query_result as $comment ) {
   261 		foreach ( $query_result as $comment ) {
   254 			if ( ! $this->check_read_permission( $comment, $request ) ) {
   262 			if ( ! $this->check_read_permission( $comment, $request ) ) {
   255 				continue;
   263 				continue;
   256 			}
   264 			}
   257 
   265 
   258 			$data = $this->prepare_item_for_response( $comment, $request );
   266 			$data       = $this->prepare_item_for_response( $comment, $request );
   259 			$comments[] = $this->prepare_response_for_collection( $data );
   267 			$comments[] = $this->prepare_response_for_collection( $data );
   260 		}
   268 		}
   261 
   269 
   262 		$total_comments = (int) $query->found_comments;
   270 		$total_comments = (int) $query->found_comments;
   263 		$max_pages      = (int) $query->max_num_pages;
   271 		$max_pages      = (int) $query->max_num_pages;
   264 
   272 
   265 		if ( $total_comments < 1 ) {
   273 		if ( $total_comments < 1 ) {
   266 			// Out-of-bounds, run the query again without LIMIT for total count.
   274 			// Out-of-bounds, run the query again without LIMIT for total count.
   267 			unset( $prepared_args['number'], $prepared_args['offset'] );
   275 			unset( $prepared_args['number'], $prepared_args['offset'] );
   268 
   276 
   269 			$query = new WP_Comment_Query;
   277 			$query                  = new WP_Comment_Query;
   270 			$prepared_args['count'] = true;
   278 			$prepared_args['count'] = true;
   271 
   279 
   272 			$total_comments = $query->query( $prepared_args );
   280 			$total_comments = $query->query( $prepared_args );
   273 			$max_pages = ceil( $total_comments / $request['per_page'] );
   281 			$max_pages      = ceil( $total_comments / $request['per_page'] );
   274 		}
   282 		}
   275 
   283 
   276 		$response = rest_ensure_response( $comments );
   284 		$response = rest_ensure_response( $comments );
   277 		$response->header( 'X-WP-Total', $total_comments );
   285 		$response->header( 'X-WP-Total', $total_comments );
   278 		$response->header( 'X-WP-TotalPages', $max_pages );
   286 		$response->header( 'X-WP-TotalPages', $max_pages );
   279 
   287 
   280 		$base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ) );
   288 		$base = add_query_arg( urlencode_deep( $request->get_query_params() ), rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ) );
   281 
   289 
   282 		if ( $request['page'] > 1 ) {
   290 		if ( $request['page'] > 1 ) {
   283 			$prev_page = $request['page'] - 1;
   291 			$prev_page = $request['page'] - 1;
   284 
   292 
   285 			if ( $prev_page > $max_pages ) {
   293 			if ( $prev_page > $max_pages ) {
   312 		$error = new WP_Error( 'rest_comment_invalid_id', __( 'Invalid comment ID.' ), array( 'status' => 404 ) );
   320 		$error = new WP_Error( 'rest_comment_invalid_id', __( 'Invalid comment ID.' ), array( 'status' => 404 ) );
   313 		if ( (int) $id <= 0 ) {
   321 		if ( (int) $id <= 0 ) {
   314 			return $error;
   322 			return $error;
   315 		}
   323 		}
   316 
   324 
   317 		$id = (int) $id;
   325 		$id      = (int) $id;
   318 		$comment = get_comment( $id );
   326 		$comment = get_comment( $id );
   319 		if ( empty( $comment ) ) {
   327 		if ( empty( $comment ) ) {
   320 			return $error;
   328 			return $error;
   321 		}
   329 		}
   322 
   330 
   373 		$comment = $this->get_comment( $request['id'] );
   381 		$comment = $this->get_comment( $request['id'] );
   374 		if ( is_wp_error( $comment ) ) {
   382 		if ( is_wp_error( $comment ) ) {
   375 			return $comment;
   383 			return $comment;
   376 		}
   384 		}
   377 
   385 
   378 		$data = $this->prepare_item_for_response( $comment, $request );
   386 		$data     = $this->prepare_item_for_response( $comment, $request );
   379 		$response = rest_ensure_response( $data );
   387 		$response = rest_ensure_response( $data );
   380 
   388 
   381 		return $response;
   389 		return $response;
   382 	}
   390 	}
   383 
   391 
   413 			}
   421 			}
   414 		}
   422 		}
   415 
   423 
   416 		// Limit who can set comment `author`, `author_ip` or `status` to anything other than the default.
   424 		// Limit who can set comment `author`, `author_ip` or `status` to anything other than the default.
   417 		if ( isset( $request['author'] ) && get_current_user_id() !== $request['author'] && ! current_user_can( 'moderate_comments' ) ) {
   425 		if ( isset( $request['author'] ) && get_current_user_id() !== $request['author'] && ! current_user_can( 'moderate_comments' ) ) {
   418 			return new WP_Error( 'rest_comment_invalid_author',
   426 			return new WP_Error(
       
   427 				'rest_comment_invalid_author',
   419 				/* translators: %s: request parameter */
   428 				/* translators: %s: request parameter */
   420 				sprintf( __( "Sorry, you are not allowed to edit '%s' for comments." ), 'author' ),
   429 				sprintf( __( "Sorry, you are not allowed to edit '%s' for comments." ), 'author' ),
   421 				array( 'status' => rest_authorization_required_code() )
   430 				array( 'status' => rest_authorization_required_code() )
   422 			);
   431 			);
   423 		}
   432 		}
   424 
   433 
   425 		if ( isset( $request['author_ip'] ) && ! current_user_can( 'moderate_comments' ) ) {
   434 		if ( isset( $request['author_ip'] ) && ! current_user_can( 'moderate_comments' ) ) {
   426 			if ( empty( $_SERVER['REMOTE_ADDR'] ) || $request['author_ip'] !== $_SERVER['REMOTE_ADDR'] ) {
   435 			if ( empty( $_SERVER['REMOTE_ADDR'] ) || $request['author_ip'] !== $_SERVER['REMOTE_ADDR'] ) {
   427 				return new WP_Error( 'rest_comment_invalid_author_ip',
   436 				return new WP_Error(
       
   437 					'rest_comment_invalid_author_ip',
   428 					/* translators: %s: request parameter */
   438 					/* translators: %s: request parameter */
   429 					sprintf( __( "Sorry, you are not allowed to edit '%s' for comments." ), 'author_ip' ),
   439 					sprintf( __( "Sorry, you are not allowed to edit '%s' for comments." ), 'author_ip' ),
   430 					array( 'status' => rest_authorization_required_code() )
   440 					array( 'status' => rest_authorization_required_code() )
   431 				);
   441 				);
   432 			}
   442 			}
   433 		}
   443 		}
   434 
   444 
   435 		if ( isset( $request['status'] ) && ! current_user_can( 'moderate_comments' ) ) {
   445 		if ( isset( $request['status'] ) && ! current_user_can( 'moderate_comments' ) ) {
   436 			return new WP_Error( 'rest_comment_invalid_status',
   446 			return new WP_Error(
       
   447 				'rest_comment_invalid_status',
   437 				/* translators: %s: request parameter */
   448 				/* translators: %s: request parameter */
   438 				sprintf( __( "Sorry, you are not allowed to edit '%s' for comments." ), 'status' ),
   449 				sprintf( __( "Sorry, you are not allowed to edit '%s' for comments." ), 'status' ),
   439 				array( 'status' => rest_authorization_required_code() )
   450 				array( 'status' => rest_authorization_required_code() )
   440 			);
   451 			);
   441 		}
   452 		}
   513 			&& empty( $prepared_comment['comment_author_url'] );
   524 			&& empty( $prepared_comment['comment_author_url'] );
   514 
   525 
   515 		if ( is_user_logged_in() && $missing_author ) {
   526 		if ( is_user_logged_in() && $missing_author ) {
   516 			$user = wp_get_current_user();
   527 			$user = wp_get_current_user();
   517 
   528 
   518 			$prepared_comment['user_id'] = $user->ID;
   529 			$prepared_comment['user_id']              = $user->ID;
   519 			$prepared_comment['comment_author'] = $user->display_name;
   530 			$prepared_comment['comment_author']       = $user->display_name;
   520 			$prepared_comment['comment_author_email'] = $user->user_email;
   531 			$prepared_comment['comment_author_email'] = $user->user_email;
   521 			$prepared_comment['comment_author_url'] = $user->user_url;
   532 			$prepared_comment['comment_author_url']   = $user->user_url;
   522 		}
   533 		}
   523 
   534 
   524 		// Honor the discussion setting that requires a name and email address of the comment author.
   535 		// Honor the discussion setting that requires a name and email address of the comment author.
   525 		if ( get_option( 'require_name_email' ) ) {
   536 		if ( get_option( 'require_name_email' ) ) {
   526 			if ( empty( $prepared_comment['comment_author'] ) || empty( $prepared_comment['comment_author_email'] ) ) {
   537 			if ( empty( $prepared_comment['comment_author'] ) || empty( $prepared_comment['comment_author_email'] ) ) {
   569 		 * Allows modification of the comment right before it is inserted via wp_insert_comment().
   580 		 * Allows modification of the comment right before it is inserted via wp_insert_comment().
   570 		 * Returning a WP_Error value from the filter will shortcircuit insertion and allow
   581 		 * Returning a WP_Error value from the filter will shortcircuit insertion and allow
   571 		 * skipping further processing.
   582 		 * skipping further processing.
   572 		 *
   583 		 *
   573 		 * @since 4.7.0
   584 		 * @since 4.7.0
   574 		 * @since 4.8.0 $prepared_comment can now be a WP_Error to shortcircuit insertion.
   585 		 * @since 4.8.0 `$prepared_comment` can now be a WP_Error to shortcircuit insertion.
   575 		 *
   586 		 *
   576 		 * @param array|WP_Error  $prepared_comment The prepared comment data for wp_insert_comment().
   587 		 * @param array|WP_Error  $prepared_comment The prepared comment data for wp_insert_comment().
   577 		 * @param WP_REST_Request $request          Request used to insert the comment.
   588 		 * @param WP_REST_Request $request          Request used to insert the comment.
   578 		 */
   589 		 */
   579 		$prepared_comment = apply_filters( 'rest_pre_insert_comment', $prepared_comment, $request );
   590 		$prepared_comment = apply_filters( 'rest_pre_insert_comment', $prepared_comment, $request );
   620 		if ( is_wp_error( $fields_update ) ) {
   631 		if ( is_wp_error( $fields_update ) ) {
   621 			return $fields_update;
   632 			return $fields_update;
   622 		}
   633 		}
   623 
   634 
   624 		$context = current_user_can( 'moderate_comments' ) ? 'edit' : 'view';
   635 		$context = current_user_can( 'moderate_comments' ) ? 'edit' : 'view';
   625 
       
   626 		$request->set_param( 'context', $context );
   636 		$request->set_param( 'context', $context );
       
   637 
       
   638 		/**
       
   639 		 * Fires completely after a comment is created or updated via the REST API.
       
   640 		 *
       
   641 		 * @since 5.0.0
       
   642 		 *
       
   643 		 * @param WP_Comment      $comment  Inserted or updated comment object.
       
   644 		 * @param WP_REST_Request $request  Request object.
       
   645 		 * @param bool            $creating True when creating a comment, false
       
   646 		 *                                  when updating.
       
   647 		 */
       
   648 		do_action( 'rest_after_insert_comment', $comment, $request, true );
   627 
   649 
   628 		$response = $this->prepare_item_for_response( $comment, $request );
   650 		$response = $this->prepare_item_for_response( $comment, $request );
   629 		$response = rest_ensure_response( $response );
   651 		$response = rest_ensure_response( $response );
   630 
   652 
   631 		$response->set_status( 201 );
   653 		$response->set_status( 201 );
   632 		$response->header( 'Location', rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $comment_id ) ) );
   654 		$response->header( 'Location', rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $comment_id ) ) );
   633 
       
   634 
   655 
   635 		return $response;
   656 		return $response;
   636 	}
   657 	}
   637 
   658 
   638 	/**
   659 	/**
   745 			return $fields_update;
   766 			return $fields_update;
   746 		}
   767 		}
   747 
   768 
   748 		$request->set_param( 'context', 'edit' );
   769 		$request->set_param( 'context', 'edit' );
   749 
   770 
       
   771 		/** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php */
       
   772 		do_action( 'rest_after_insert_comment', $comment, $request, false );
       
   773 
   750 		$response = $this->prepare_item_for_response( $comment, $request );
   774 		$response = $this->prepare_item_for_response( $comment, $request );
   751 
   775 
   752 		return rest_ensure_response( $response );
   776 		return rest_ensure_response( $response );
   753 	}
   777 	}
   754 
   778 
   802 
   826 
   803 		$request->set_param( 'context', 'edit' );
   827 		$request->set_param( 'context', 'edit' );
   804 
   828 
   805 		if ( $force ) {
   829 		if ( $force ) {
   806 			$previous = $this->prepare_item_for_response( $comment, $request );
   830 			$previous = $this->prepare_item_for_response( $comment, $request );
   807 			$result = wp_delete_comment( $comment->comment_ID, true );
   831 			$result   = wp_delete_comment( $comment->comment_ID, true );
   808 			$response = new WP_REST_Response();
   832 			$response = new WP_REST_Response();
   809 			$response->set_data( array( 'deleted' => true, 'previous' => $previous->get_data() ) );
   833 			$response->set_data(
       
   834 				array(
       
   835 					'deleted'  => true,
       
   836 					'previous' => $previous->get_data(),
       
   837 				)
       
   838 			);
   810 		} else {
   839 		} else {
   811 			// If this type doesn't support trashing, error out.
   840 			// If this type doesn't support trashing, error out.
   812 			if ( ! $supports_trash ) {
   841 			if ( ! $supports_trash ) {
   813 				/* translators: %s: force=true */
   842 				/* translators: %s: force=true */
   814 				return new WP_Error( 'rest_trash_not_supported', sprintf( __( "The comment does not support trashing. Set '%s' to delete." ), 'force=true' ), array( 'status' => 501 ) );
   843 				return new WP_Error( 'rest_trash_not_supported', sprintf( __( "The comment does not support trashing. Set '%s' to delete." ), 'force=true' ), array( 'status' => 501 ) );
   816 
   845 
   817 			if ( 'trash' === $comment->comment_approved ) {
   846 			if ( 'trash' === $comment->comment_approved ) {
   818 				return new WP_Error( 'rest_already_trashed', __( 'The comment has already been trashed.' ), array( 'status' => 410 ) );
   847 				return new WP_Error( 'rest_already_trashed', __( 'The comment has already been trashed.' ), array( 'status' => 410 ) );
   819 			}
   848 			}
   820 
   849 
   821 			$result = wp_trash_comment( $comment->comment_ID );
   850 			$result   = wp_trash_comment( $comment->comment_ID );
   822 			$comment = get_comment( $comment->comment_ID );
   851 			$comment  = get_comment( $comment->comment_ID );
   823 			$response = $this->prepare_item_for_response( $comment, $request );
   852 			$response = $this->prepare_item_for_response( $comment, $request );
   824 		}
   853 		}
   825 
   854 
   826 		if ( ! $result ) {
   855 		if ( ! $result ) {
   827 			return new WP_Error( 'rest_cannot_delete', __( 'The comment cannot be deleted.' ), array( 'status' => 500 ) );
   856 			return new WP_Error( 'rest_cannot_delete', __( 'The comment cannot be deleted.' ), array( 'status' => 500 ) );
   958 	 * @param WP_Comment $comment Comment object.
   987 	 * @param WP_Comment $comment Comment object.
   959 	 * @return array Links for the given comment.
   988 	 * @return array Links for the given comment.
   960 	 */
   989 	 */
   961 	protected function prepare_links( $comment ) {
   990 	protected function prepare_links( $comment ) {
   962 		$links = array(
   991 		$links = array(
   963 			'self' => array(
   992 			'self'       => array(
   964 				'href' => rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $comment->comment_ID ) ),
   993 				'href' => rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $comment->comment_ID ) ),
   965 			),
   994 			),
   966 			'collection' => array(
   995 			'collection' => array(
   967 				'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ),
   996 				'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ),
   968 			),
   997 			),
   977 
  1006 
   978 		if ( 0 !== (int) $comment->comment_post_ID ) {
  1007 		if ( 0 !== (int) $comment->comment_post_ID ) {
   979 			$post = get_post( $comment->comment_post_ID );
  1008 			$post = get_post( $comment->comment_post_ID );
   980 
  1009 
   981 			if ( ! empty( $post->ID ) ) {
  1010 			if ( ! empty( $post->ID ) ) {
   982 				$obj = get_post_type_object( $post->post_type );
  1011 				$obj  = get_post_type_object( $post->post_type );
   983 				$base = ! empty( $obj->rest_base ) ? $obj->rest_base : $obj->name;
  1012 				$base = ! empty( $obj->rest_base ) ? $obj->rest_base : $obj->name;
   984 
  1013 
   985 				$links['up'] = array(
  1014 				$links['up'] = array(
   986 					'href'       => rest_url( 'wp/v2/' . $base . '/' . $comment->comment_post_ID ),
  1015 					'href'       => rest_url( 'wp/v2/' . $base . '/' . $comment->comment_post_ID ),
   987 					'embeddable' => true,
  1016 					'embeddable' => true,
   996 				'embeddable' => true,
  1025 				'embeddable' => true,
   997 			);
  1026 			);
   998 		}
  1027 		}
   999 
  1028 
  1000 		// Only grab one comment to verify the comment has children.
  1029 		// Only grab one comment to verify the comment has children.
  1001 		$comment_children = $comment->get_children( array(
  1030 		$comment_children = $comment->get_children(
  1002 			'number' => 1,
  1031 			array(
  1003 			'count'  => true
  1032 				'number' => 1,
  1004 		) );
  1033 				'count'  => true,
       
  1034 			)
       
  1035 		);
  1005 
  1036 
  1006 		if ( ! empty( $comment_children ) ) {
  1037 		if ( ! empty( $comment_children ) ) {
  1007 			$args = array(
  1038 			$args = array(
  1008 				'parent' => $comment->comment_ID
  1039 				'parent' => $comment->comment_ID,
  1009 			);
  1040 			);
  1010 
  1041 
  1011 			$rest_url = add_query_arg( $args, rest_url( $this->namespace . '/' . $this->rest_base ) );
  1042 			$rest_url = add_query_arg( $args, rest_url( $this->namespace . '/' . $this->rest_base ) );
  1012 
  1043 
  1013 			$links['children'] = array(
  1044 			$links['children'] = array(
  1112 
  1143 
  1113 		if ( isset( $request['author'] ) ) {
  1144 		if ( isset( $request['author'] ) ) {
  1114 			$user = new WP_User( $request['author'] );
  1145 			$user = new WP_User( $request['author'] );
  1115 
  1146 
  1116 			if ( $user->exists() ) {
  1147 			if ( $user->exists() ) {
  1117 				$prepared_comment['user_id'] = $user->ID;
  1148 				$prepared_comment['user_id']              = $user->ID;
  1118 				$prepared_comment['comment_author'] = $user->display_name;
  1149 				$prepared_comment['comment_author']       = $user->display_name;
  1119 				$prepared_comment['comment_author_email'] = $user->user_email;
  1150 				$prepared_comment['comment_author_email'] = $user->user_email;
  1120 				$prepared_comment['comment_author_url'] = $user->user_url;
  1151 				$prepared_comment['comment_author_url']   = $user->user_url;
  1121 			} else {
  1152 			} else {
  1122 				return new WP_Error( 'rest_comment_author_invalid', __( 'Invalid comment author ID.' ), array( 'status' => 400 ) );
  1153 				return new WP_Error( 'rest_comment_author_invalid', __( 'Invalid comment author ID.' ), array( 'status' => 400 ) );
  1123 			}
  1154 			}
  1124 		}
  1155 		}
  1125 
  1156 
  1183 	 *
  1214 	 *
  1184 	 * @return array
  1215 	 * @return array
  1185 	 */
  1216 	 */
  1186 	public function get_item_schema() {
  1217 	public function get_item_schema() {
  1187 		$schema = array(
  1218 		$schema = array(
  1188 			'$schema'              => 'http://json-schema.org/draft-04/schema#',
  1219 			'$schema'    => 'http://json-schema.org/draft-04/schema#',
  1189 			'title'                => 'comment',
  1220 			'title'      => 'comment',
  1190 			'type'                 => 'object',
  1221 			'type'       => 'object',
  1191 			'properties'           => array(
  1222 			'properties' => array(
  1192 				'id'               => array(
  1223 				'id'                => array(
  1193 					'description'  => __( 'Unique identifier for the object.' ),
  1224 					'description' => __( 'Unique identifier for the object.' ),
  1194 					'type'         => 'integer',
  1225 					'type'        => 'integer',
  1195 					'context'      => array( 'view', 'edit', 'embed' ),
  1226 					'context'     => array( 'view', 'edit', 'embed' ),
  1196 					'readonly'     => true,
  1227 					'readonly'    => true,
  1197 				),
  1228 				),
  1198 				'author'           => array(
  1229 				'author'            => array(
  1199 					'description'  => __( 'The ID of the user object, if author was a user.' ),
  1230 					'description' => __( 'The ID of the user object, if author was a user.' ),
  1200 					'type'         => 'integer',
  1231 					'type'        => 'integer',
  1201 					'context'      => array( 'view', 'edit', 'embed' ),
  1232 					'context'     => array( 'view', 'edit', 'embed' ),
  1202 				),
  1233 				),
  1203 				'author_email'     => array(
  1234 				'author_email'      => array(
  1204 					'description'  => __( 'Email address for the object author.' ),
  1235 					'description' => __( 'Email address for the object author.' ),
  1205 					'type'         => 'string',
  1236 					'type'        => 'string',
  1206 					'format'       => 'email',
  1237 					'format'      => 'email',
  1207 					'context'      => array( 'edit' ),
  1238 					'context'     => array( 'edit' ),
  1208 					'arg_options'  => array(
  1239 					'arg_options' => array(
  1209 						'sanitize_callback' => array( $this, 'check_comment_author_email' ),
  1240 						'sanitize_callback' => array( $this, 'check_comment_author_email' ),
  1210 						'validate_callback' => null, // skip built-in validation of 'email'.
  1241 						'validate_callback' => null, // skip built-in validation of 'email'.
  1211 					),
  1242 					),
  1212 				),
  1243 				),
  1213 				'author_ip'     => array(
  1244 				'author_ip'         => array(
  1214 					'description'  => __( 'IP address for the object author.' ),
  1245 					'description' => __( 'IP address for the object author.' ),
  1215 					'type'         => 'string',
  1246 					'type'        => 'string',
  1216 					'format'       => 'ip',
  1247 					'format'      => 'ip',
  1217 					'context'      => array( 'edit' ),
  1248 					'context'     => array( 'edit' ),
  1218 				),
  1249 				),
  1219 				'author_name'     => array(
  1250 				'author_name'       => array(
  1220 					'description'  => __( 'Display name for the object author.' ),
  1251 					'description' => __( 'Display name for the object author.' ),
  1221 					'type'         => 'string',
  1252 					'type'        => 'string',
  1222 					'context'      => array( 'view', 'edit', 'embed' ),
  1253 					'context'     => array( 'view', 'edit', 'embed' ),
  1223 					'arg_options'  => array(
  1254 					'arg_options' => array(
  1224 						'sanitize_callback' => 'sanitize_text_field',
  1255 						'sanitize_callback' => 'sanitize_text_field',
  1225 					),
  1256 					),
  1226 				),
  1257 				),
  1227 				'author_url'       => array(
  1258 				'author_url'        => array(
  1228 					'description'  => __( 'URL for the object author.' ),
  1259 					'description' => __( 'URL for the object author.' ),
  1229 					'type'         => 'string',
  1260 					'type'        => 'string',
  1230 					'format'       => 'uri',
  1261 					'format'      => 'uri',
  1231 					'context'      => array( 'view', 'edit', 'embed' ),
  1262 					'context'     => array( 'view', 'edit', 'embed' ),
  1232 				),
  1263 				),
  1233 				'author_user_agent'     => array(
  1264 				'author_user_agent' => array(
  1234 					'description'  => __( 'User agent for the object author.' ),
  1265 					'description' => __( 'User agent for the object author.' ),
  1235 					'type'         => 'string',
  1266 					'type'        => 'string',
  1236 					'context'      => array( 'edit' ),
  1267 					'context'     => array( 'edit' ),
  1237 					'arg_options'  => array(
  1268 					'arg_options' => array(
  1238 						'sanitize_callback' => 'sanitize_text_field',
  1269 						'sanitize_callback' => 'sanitize_text_field',
  1239 					),
  1270 					),
  1240 				),
  1271 				),
  1241 				'content'          => array(
  1272 				'content'           => array(
  1242 					'description'     => __( 'The content for the object.' ),
  1273 					'description' => __( 'The content for the object.' ),
  1243 					'type'            => 'object',
  1274 					'type'        => 'object',
  1244 					'context'         => array( 'view', 'edit', 'embed' ),
  1275 					'context'     => array( 'view', 'edit', 'embed' ),
  1245 					'arg_options'     => array(
  1276 					'arg_options' => array(
  1246 						'sanitize_callback' => null, // Note: sanitization implemented in self::prepare_item_for_database()
  1277 						'sanitize_callback' => null, // Note: sanitization implemented in self::prepare_item_for_database()
  1247 						'validate_callback' => null, // Note: validation implemented in self::prepare_item_for_database()
  1278 						'validate_callback' => null, // Note: validation implemented in self::prepare_item_for_database()
  1248 					),
  1279 					),
  1249 					'properties'      => array(
  1280 					'properties'  => array(
  1250 						'raw'         => array(
  1281 						'raw'      => array(
  1251 							'description'     => __( 'Content for the object, as it exists in the database.' ),
  1282 							'description' => __( 'Content for the object, as it exists in the database.' ),
  1252 							'type'            => 'string',
  1283 							'type'        => 'string',
  1253 							'context'         => array( 'edit' ),
  1284 							'context'     => array( 'edit' ),
  1254 						),
  1285 						),
  1255 						'rendered'    => array(
  1286 						'rendered' => array(
  1256 							'description'     => __( 'HTML content for the object, transformed for display.' ),
  1287 							'description' => __( 'HTML content for the object, transformed for display.' ),
  1257 							'type'            => 'string',
  1288 							'type'        => 'string',
  1258 							'context'         => array( 'view', 'edit', 'embed' ),
  1289 							'context'     => array( 'view', 'edit', 'embed' ),
  1259 							'readonly'        => true,
  1290 							'readonly'    => true,
  1260 						),
  1291 						),
  1261 					),
  1292 					),
  1262 				),
  1293 				),
  1263 				'date'             => array(
  1294 				'date'              => array(
  1264 					'description'  => __( "The date the object was published, in the site's timezone." ),
  1295 					'description' => __( "The date the object was published, in the site's timezone." ),
  1265 					'type'         => 'string',
  1296 					'type'        => 'string',
  1266 					'format'       => 'date-time',
  1297 					'format'      => 'date-time',
  1267 					'context'      => array( 'view', 'edit', 'embed' ),
  1298 					'context'     => array( 'view', 'edit', 'embed' ),
  1268 				),
  1299 				),
  1269 				'date_gmt'         => array(
  1300 				'date_gmt'          => array(
  1270 					'description'  => __( 'The date the object was published, as GMT.' ),
  1301 					'description' => __( 'The date the object was published, as GMT.' ),
  1271 					'type'         => 'string',
  1302 					'type'        => 'string',
  1272 					'format'       => 'date-time',
  1303 					'format'      => 'date-time',
  1273 					'context'      => array( 'view', 'edit' ),
  1304 					'context'     => array( 'view', 'edit' ),
  1274 				),
  1305 				),
  1275 				'link'             => array(
  1306 				'link'              => array(
  1276 					'description'  => __( 'URL to the object.' ),
  1307 					'description' => __( 'URL to the object.' ),
  1277 					'type'         => 'string',
  1308 					'type'        => 'string',
  1278 					'format'       => 'uri',
  1309 					'format'      => 'uri',
  1279 					'context'      => array( 'view', 'edit', 'embed' ),
  1310 					'context'     => array( 'view', 'edit', 'embed' ),
  1280 					'readonly'     => true,
  1311 					'readonly'    => true,
  1281 				),
  1312 				),
  1282 				'parent'           => array(
  1313 				'parent'            => array(
  1283 					'description'  => __( 'The ID for the parent of the object.' ),
  1314 					'description' => __( 'The ID for the parent of the object.' ),
  1284 					'type'         => 'integer',
  1315 					'type'        => 'integer',
  1285 					'context'      => array( 'view', 'edit', 'embed' ),
  1316 					'context'     => array( 'view', 'edit', 'embed' ),
  1286 					'default'      => 0,
  1317 					'default'     => 0,
  1287 				),
  1318 				),
  1288 				'post'             => array(
  1319 				'post'              => array(
  1289 					'description'  => __( 'The ID of the associated post object.' ),
  1320 					'description' => __( 'The ID of the associated post object.' ),
  1290 					'type'         => 'integer',
  1321 					'type'        => 'integer',
  1291 					'context'      => array( 'view', 'edit' ),
  1322 					'context'     => array( 'view', 'edit' ),
  1292 					'default'      => 0,
  1323 					'default'     => 0,
  1293 				),
  1324 				),
  1294 				'status'           => array(
  1325 				'status'            => array(
  1295 					'description'  => __( 'State of the object.' ),
  1326 					'description' => __( 'State of the object.' ),
  1296 					'type'         => 'string',
  1327 					'type'        => 'string',
  1297 					'context'      => array( 'view', 'edit' ),
  1328 					'context'     => array( 'view', 'edit' ),
  1298 					'arg_options'  => array(
  1329 					'arg_options' => array(
  1299 						'sanitize_callback' => 'sanitize_key',
  1330 						'sanitize_callback' => 'sanitize_key',
  1300 					),
  1331 					),
  1301 				),
  1332 				),
  1302 				'type'             => array(
  1333 				'type'              => array(
  1303 					'description'  => __( 'Type of Comment for the object.' ),
  1334 					'description' => __( 'Type of Comment for the object.' ),
  1304 					'type'         => 'string',
  1335 					'type'        => 'string',
  1305 					'context'      => array( 'view', 'edit', 'embed' ),
  1336 					'context'     => array( 'view', 'edit', 'embed' ),
  1306 					'readonly'     => true,
  1337 					'readonly'    => true,
  1307 				),
  1338 				),
  1308 			),
  1339 			),
  1309 		);
  1340 		);
  1310 
  1341 
  1311 		if ( get_option( 'show_avatars' ) ) {
  1342 		if ( get_option( 'show_avatars' ) ) {
  1321 					'context'     => array( 'embed', 'view', 'edit' ),
  1352 					'context'     => array( 'embed', 'view', 'edit' ),
  1322 				);
  1353 				);
  1323 			}
  1354 			}
  1324 
  1355 
  1325 			$schema['properties']['author_avatar_urls'] = array(
  1356 			$schema['properties']['author_avatar_urls'] = array(
  1326 				'description'   => __( 'Avatar URLs for the object author.' ),
  1357 				'description' => __( 'Avatar URLs for the object author.' ),
  1327 				'type'          => 'object',
  1358 				'type'        => 'object',
  1328 				'context'       => array( 'view', 'edit', 'embed' ),
  1359 				'context'     => array( 'view', 'edit', 'embed' ),
  1329 				'readonly'      => true,
  1360 				'readonly'    => true,
  1330 				'properties'    => $avatar_properties,
  1361 				'properties'  => $avatar_properties,
  1331 			);
  1362 			);
  1332 		}
  1363 		}
  1333 
  1364 
  1334 		$schema['properties']['meta'] = $this->meta->get_field_schema();
  1365 		$schema['properties']['meta'] = $this->meta->get_field_schema();
  1335 
  1366 
  1347 		$query_params = parent::get_collection_params();
  1378 		$query_params = parent::get_collection_params();
  1348 
  1379 
  1349 		$query_params['context']['default'] = 'view';
  1380 		$query_params['context']['default'] = 'view';
  1350 
  1381 
  1351 		$query_params['after'] = array(
  1382 		$query_params['after'] = array(
  1352 			'description'       => __( 'Limit response to comments published after a given ISO8601 compliant date.' ),
  1383 			'description' => __( 'Limit response to comments published after a given ISO8601 compliant date.' ),
  1353 			'type'              => 'string',
  1384 			'type'        => 'string',
  1354 			'format'            => 'date-time',
  1385 			'format'      => 'date-time',
  1355 		);
  1386 		);
  1356 
  1387 
  1357 		$query_params['author'] = array(
  1388 		$query_params['author'] = array(
  1358 			'description'       => __( 'Limit result set to comments assigned to specific user IDs. Requires authorization.' ),
  1389 			'description' => __( 'Limit result set to comments assigned to specific user IDs. Requires authorization.' ),
  1359 			'type'              => 'array',
  1390 			'type'        => 'array',
  1360 			'items'             => array(
  1391 			'items'       => array(
  1361 				'type'          => 'integer',
  1392 				'type' => 'integer',
  1362 			),
  1393 			),
  1363 		);
  1394 		);
  1364 
  1395 
  1365 		$query_params['author_exclude'] = array(
  1396 		$query_params['author_exclude'] = array(
  1366 			'description'       => __( 'Ensure result set excludes comments assigned to specific user IDs. Requires authorization.' ),
  1397 			'description' => __( 'Ensure result set excludes comments assigned to specific user IDs. Requires authorization.' ),
  1367 			'type'              => 'array',
  1398 			'type'        => 'array',
  1368 			'items'             => array(
  1399 			'items'       => array(
  1369 				'type'          => 'integer',
  1400 				'type' => 'integer',
  1370 			),
  1401 			),
  1371 		);
  1402 		);
  1372 
  1403 
  1373 		$query_params['author_email'] = array(
  1404 		$query_params['author_email'] = array(
  1374 			'default'           => null,
  1405 			'default'     => null,
  1375 			'description'       => __( 'Limit result set to that from a specific author email. Requires authorization.' ),
  1406 			'description' => __( 'Limit result set to that from a specific author email. Requires authorization.' ),
  1376 			'format'            => 'email',
  1407 			'format'      => 'email',
  1377 			'type'              => 'string',
  1408 			'type'        => 'string',
  1378 		);
  1409 		);
  1379 
  1410 
  1380 		$query_params['before'] = array(
  1411 		$query_params['before'] = array(
  1381 			'description'       => __( 'Limit response to comments published before a given ISO8601 compliant date.' ),
  1412 			'description' => __( 'Limit response to comments published before a given ISO8601 compliant date.' ),
  1382 			'type'              => 'string',
  1413 			'type'        => 'string',
  1383 			'format'            => 'date-time',
  1414 			'format'      => 'date-time',
  1384 		);
  1415 		);
  1385 
  1416 
  1386 		$query_params['exclude'] = array(
  1417 		$query_params['exclude'] = array(
  1387 			'description'        => __( 'Ensure result set excludes specific IDs.' ),
  1418 			'description' => __( 'Ensure result set excludes specific IDs.' ),
  1388 			'type'               => 'array',
  1419 			'type'        => 'array',
  1389 			'items'              => array(
  1420 			'items'       => array(
  1390 				'type'           => 'integer',
  1421 				'type' => 'integer',
  1391 			),
  1422 			),
  1392 			'default'            => array(),
  1423 			'default'     => array(),
  1393 		);
  1424 		);
  1394 
  1425 
  1395 		$query_params['include'] = array(
  1426 		$query_params['include'] = array(
  1396 			'description'        => __( 'Limit result set to specific IDs.' ),
  1427 			'description' => __( 'Limit result set to specific IDs.' ),
  1397 			'type'               => 'array',
  1428 			'type'        => 'array',
  1398 			'items'              => array(
  1429 			'items'       => array(
  1399 				'type'           => 'integer',
  1430 				'type' => 'integer',
  1400 			),
  1431 			),
  1401 			'default'            => array(),
  1432 			'default'     => array(),
  1402 		);
  1433 		);
  1403 
  1434 
  1404 		$query_params['offset'] = array(
  1435 		$query_params['offset'] = array(
  1405 			'description'        => __( 'Offset the result set by a specific number of items.' ),
  1436 			'description' => __( 'Offset the result set by a specific number of items.' ),
  1406 			'type'               => 'integer',
  1437 			'type'        => 'integer',
  1407 		);
  1438 		);
  1408 
  1439 
  1409 		$query_params['order']      = array(
  1440 		$query_params['order'] = array(
  1410 			'description'           => __( 'Order sort attribute ascending or descending.' ),
  1441 			'description' => __( 'Order sort attribute ascending or descending.' ),
  1411 			'type'                  => 'string',
  1442 			'type'        => 'string',
  1412 			'default'               => 'desc',
  1443 			'default'     => 'desc',
  1413 			'enum'                  => array(
  1444 			'enum'        => array(
  1414 				'asc',
  1445 				'asc',
  1415 				'desc',
  1446 				'desc',
  1416 			),
  1447 			),
  1417 		);
  1448 		);
  1418 
  1449 
  1419 		$query_params['orderby']    = array(
  1450 		$query_params['orderby'] = array(
  1420 			'description'           => __( 'Sort collection by object attribute.' ),
  1451 			'description' => __( 'Sort collection by object attribute.' ),
  1421 			'type'                  => 'string',
  1452 			'type'        => 'string',
  1422 			'default'               => 'date_gmt',
  1453 			'default'     => 'date_gmt',
  1423 			'enum'                  => array(
  1454 			'enum'        => array(
  1424 				'date',
  1455 				'date',
  1425 				'date_gmt',
  1456 				'date_gmt',
  1426 				'id',
  1457 				'id',
  1427 				'include',
  1458 				'include',
  1428 				'post',
  1459 				'post',
  1430 				'type',
  1461 				'type',
  1431 			),
  1462 			),
  1432 		);
  1463 		);
  1433 
  1464 
  1434 		$query_params['parent'] = array(
  1465 		$query_params['parent'] = array(
  1435 			'default'           => array(),
  1466 			'default'     => array(),
  1436 			'description'       => __( 'Limit result set to comments of specific parent IDs.' ),
  1467 			'description' => __( 'Limit result set to comments of specific parent IDs.' ),
  1437 			'type'              => 'array',
  1468 			'type'        => 'array',
  1438 			'items'             => array(
  1469 			'items'       => array(
  1439 				'type'          => 'integer',
  1470 				'type' => 'integer',
  1440 			),
  1471 			),
  1441 		);
  1472 		);
  1442 
  1473 
  1443 		$query_params['parent_exclude'] = array(
  1474 		$query_params['parent_exclude'] = array(
  1444 			'default'           => array(),
  1475 			'default'     => array(),
  1445 			'description'       => __( 'Ensure result set excludes specific parent IDs.' ),
  1476 			'description' => __( 'Ensure result set excludes specific parent IDs.' ),
  1446 			'type'              => 'array',
  1477 			'type'        => 'array',
  1447 			'items'             => array(
  1478 			'items'       => array(
  1448 				'type'          => 'integer',
  1479 				'type' => 'integer',
  1449 			),
  1480 			),
  1450 		);
  1481 		);
  1451 
  1482 
  1452 		$query_params['post']   = array(
  1483 		$query_params['post'] = array(
  1453 			'default'           => array(),
  1484 			'default'     => array(),
  1454 			'description'       => __( 'Limit result set to comments assigned to specific post IDs.' ),
  1485 			'description' => __( 'Limit result set to comments assigned to specific post IDs.' ),
  1455 			'type'              => 'array',
  1486 			'type'        => 'array',
  1456 			'items'             => array(
  1487 			'items'       => array(
  1457 				'type'          => 'integer',
  1488 				'type' => 'integer',
  1458 			),
  1489 			),
  1459 		);
  1490 		);
  1460 
  1491 
  1461 		$query_params['status'] = array(
  1492 		$query_params['status'] = array(
  1462 			'default'           => 'approve',
  1493 			'default'           => 'approve',
  1508 		if ( $new_status === $old_status ) {
  1539 		if ( $new_status === $old_status ) {
  1509 			return false;
  1540 			return false;
  1510 		}
  1541 		}
  1511 
  1542 
  1512 		switch ( $new_status ) {
  1543 		switch ( $new_status ) {
  1513 			case 'approved' :
  1544 			case 'approved':
  1514 			case 'approve':
  1545 			case 'approve':
  1515 			case '1':
  1546 			case '1':
  1516 				$changed = wp_set_comment_status( $comment_id, 'approve' );
  1547 				$changed = wp_set_comment_status( $comment_id, 'approve' );
  1517 				break;
  1548 				break;
  1518 			case 'hold':
  1549 			case 'hold':
  1519 			case '0':
  1550 			case '0':
  1520 				$changed = wp_set_comment_status( $comment_id, 'hold' );
  1551 				$changed = wp_set_comment_status( $comment_id, 'hold' );
  1521 				break;
  1552 				break;
  1522 			case 'spam' :
  1553 			case 'spam':
  1523 				$changed = wp_spam_comment( $comment_id );
  1554 				$changed = wp_spam_comment( $comment_id );
  1524 				break;
  1555 				break;
  1525 			case 'unspam' :
  1556 			case 'unspam':
  1526 				$changed = wp_unspam_comment( $comment_id );
  1557 				$changed = wp_unspam_comment( $comment_id );
  1527 				break;
  1558 				break;
  1528 			case 'trash' :
  1559 			case 'trash':
  1529 				$changed = wp_trash_comment( $comment_id );
  1560 				$changed = wp_trash_comment( $comment_id );
  1530 				break;
  1561 				break;
  1531 			case 'untrash' :
  1562 			case 'untrash':
  1532 				$changed = wp_untrash_comment( $comment_id );
  1563 				$changed = wp_untrash_comment( $comment_id );
  1533 				break;
  1564 				break;
  1534 			default :
  1565 			default:
  1535 				$changed = false;
  1566 				$changed = false;
  1536 				break;
  1567 				break;
  1537 		}
  1568 		}
  1538 
  1569 
  1539 		return $changed;
  1570 		return $changed;
  1550 	 * @param WP_REST_Request $request Request data to check.
  1581 	 * @param WP_REST_Request $request Request data to check.
  1551 	 * @return bool Whether post can be read.
  1582 	 * @return bool Whether post can be read.
  1552 	 */
  1583 	 */
  1553 	protected function check_read_post_permission( $post, $request ) {
  1584 	protected function check_read_post_permission( $post, $request ) {
  1554 		$posts_controller = new WP_REST_Posts_Controller( $post->post_type );
  1585 		$posts_controller = new WP_REST_Posts_Controller( $post->post_type );
  1555 		$post_type = get_post_type_object( $post->post_type );
  1586 		$post_type        = get_post_type_object( $post->post_type );
  1556 
  1587 
  1557 		$has_password_filter = false;
  1588 		$has_password_filter = false;
  1558 
  1589 
  1559 		// Only check password if a specific post was queried for or a single comment
  1590 		// Only check password if a specific post was queried for or a single comment
  1560 		$requested_post = ! empty( $request['post'] ) && ( !is_array( $request['post'] ) || 1 === count( $request['post'] ) );
  1591 		$requested_post    = ! empty( $request['post'] ) && ( ! is_array( $request['post'] ) || 1 === count( $request['post'] ) );
  1561 		$requested_comment = ! empty( $request['id'] );
  1592 		$requested_comment = ! empty( $request['id'] );
  1562 		if ( ( $requested_post || $requested_comment ) && $posts_controller->can_access_password_content( $post, $request ) ) {
  1593 		if ( ( $requested_post || $requested_comment ) && $posts_controller->can_access_password_content( $post, $request ) ) {
  1563 			add_filter( 'post_password_required', '__return_false' );
  1594 			add_filter( 'post_password_required', '__return_false' );
  1564 
  1595 
  1565 			$has_password_filter = true;
  1596 			$has_password_filter = true;