</h2>
<div class="changelog point-releases">
- <h3><?php _e( 'Maintenance and Security Release' ); ?></h3>
+ <h3><?php _e( 'Maintenance and Security Releases' ); ?></h3>
+ <p><?php printf( __( '<strong>Version %s</strong> addressed some security issues.' ), '4.7.2' ); ?>
+ <?php printf( __( 'For more information, see <a href="%s">the release notes</a>.' ), 'https://codex.wordpress.org/Version_4.7.2' ); ?>
+ </p>
<p><?php printf( _n( '<strong>Version %1$s</strong> addressed some security issues and fixed %2$s bug.',
'<strong>Version %1$s</strong> addressed some security issues and fixed %2$s bugs.', 62 ), '4.7.1', number_format_i18n( 62 ) ); ?>
<?php printf( __( 'For more information, see <a href="%s">the release notes</a>.' ), 'https://codex.wordpress.org/Version_4.7.1' ); ?>
echo "</strong>\n";
if ( ! is_post_type_hierarchical( $this->screen->post_type ) && 'excerpt' === $mode && current_user_can( 'read_post', $post->ID ) ) {
- the_excerpt();
+ echo esc_html( get_the_excerpt() );
}
get_inline_data( $post );
'post_type' => 'post',
'post_status' => 'draft',
'post_format' => ( ! empty( $_POST['post_format'] ) ) ? sanitize_text_field( $_POST['post_format'] ) : '',
- 'tax_input' => ( ! empty( $_POST['tax_input'] ) ) ? $_POST['tax_input'] : array(),
- 'post_category' => ( ! empty( $_POST['post_category'] ) ) ? $_POST['post_category'] : array(),
);
+ // Only accept categories if the user actually can assign
+ $category_tax = get_taxonomy( 'category' );
+ if ( current_user_can( $category_tax->cap->assign_terms ) ) {
+ $post_data['post_category'] = ( ! empty( $_POST['post_category'] ) ) ? $_POST['post_category'] : array();
+ }
+
+ // Only accept taxonomies if the user can actually assign
+ if ( ! empty( $_POST['tax_input'] ) ) {
+ $tax_input = $_POST['tax_input'];
+ foreach ( $tax_input as $tax => $_ti ) {
+ $tax_object = get_taxonomy( $tax );
+ if ( ! $tax_object || ! current_user_can( $tax_object->cap->assign_terms ) ) {
+ unset( $tax_input[ $tax ] );
+ }
+ }
+
+ $post_data['tax_input'] = $tax_input;
+ }
+
+ // Toggle status to pending if user cannot actually publish
if ( ! empty( $_POST['post_status'] ) && 'publish' === $_POST['post_status'] ) {
if ( current_user_can( 'publish_posts' ) ) {
$post_data['post_status'] = 'publish';
* @since 4.2.0
*
* @param string $src Embed source URL.
- * @return string If not from a supported provider, an empty string. Otherwise, a reformattd embed URL.
+ * @return string If not from a supported provider, an empty string. Otherwise, a reformatted embed URL.
*/
private function _limit_embed( $src ) {
$src = $this->_limit_url( $src );
public function categories_html( $post ) {
$taxonomy = get_taxonomy( 'category' );
+ // Bail if user cannot assign terms
+ if ( ! current_user_can( $taxonomy->cap->assign_terms ) ) {
+ return;
+ }
+
+ // Only show "add" if user can edit terms
if ( current_user_can( $taxonomy->cap->edit_terms ) ) {
?>
<button type="button" class="add-cat-toggle button-link" aria-expanded="false">
wp_enqueue_script( 'json2' );
wp_enqueue_script( 'editor' );
+ $categories_tax = get_taxonomy( 'category' );
+ $show_categories = current_user_can( $categories_tax->cap->assign_terms ) || current_user_can( $categories_tax->cap->edit_terms );
+
+ $tag_tax = get_taxonomy( 'post_tag' );
+ $show_tags = current_user_can( $tag_tax->cap->assign_terms );
+
$supports_formats = false;
$post_format = 0;
</button>
<?php endif; ?>
- <button type="button" class="button-link post-option">
- <span class="dashicons dashicons-category"></span>
- <span class="post-option-title"><?php _e( 'Categories' ); ?></span>
- <span class="dashicons post-option-forward"></span>
- </button>
-
- <button type="button" class="button-link post-option">
- <span class="dashicons dashicons-tag"></span>
- <span class="post-option-title"><?php _e( 'Tags' ); ?></span>
- <span class="dashicons post-option-forward"></span>
- </button>
+ <?php if ( $show_categories ) : ?>
+ <button type="button" class="button-link post-option">
+ <span class="dashicons dashicons-category"></span>
+ <span class="post-option-title"><?php _e( 'Categories' ); ?></span>
+ <span class="dashicons post-option-forward"></span>
+ </button>
+ <?php endif; ?>
+
+ <?php if ( $show_tags ) : ?>
+ <button type="button" class="button-link post-option">
+ <span class="dashicons dashicons-tag"></span>
+ <span class="post-option-title"><?php _e( 'Tags' ); ?></span>
+ <span class="dashicons post-option-forward"></span>
+ </button>
+ <?php endif; ?>
</div>
<?php if ( $supports_formats ) : ?>
</div>
<?php endif; ?>
- <div class="setting-modal is-off-screen is-hidden">
- <button type="button" class="button-link modal-close">
- <span class="dashicons post-option-back"></span>
- <span class="setting-title" aria-hidden="true"><?php _e( 'Categories' ); ?></span>
- <span class="screen-reader-text"><?php _e( 'Back to post options' ) ?></span>
- </button>
- <?php $this->categories_html( $post ); ?>
- </div>
+ <?php if ( $show_categories ) : ?>
+ <div class="setting-modal is-off-screen is-hidden">
+ <button type="button" class="button-link modal-close">
+ <span class="dashicons post-option-back"></span>
+ <span class="setting-title" aria-hidden="true"><?php _e( 'Categories' ); ?></span>
+ <span class="screen-reader-text"><?php _e( 'Back to post options' ) ?></span>
+ </button>
+ <?php $this->categories_html( $post ); ?>
+ </div>
+ <?php endif; ?>
- <div class="setting-modal tags is-off-screen is-hidden">
- <button type="button" class="button-link modal-close">
- <span class="dashicons post-option-back"></span>
- <span class="setting-title" aria-hidden="true"><?php _e( 'Tags' ); ?></span>
- <span class="screen-reader-text"><?php _e( 'Back to post options' ) ?></span>
- </button>
- <?php $this->tags_html( $post ); ?>
- </div>
+ <?php if ( $show_tags ) : ?>
+ <div class="setting-modal tags is-off-screen is-hidden">
+ <button type="button" class="button-link modal-close">
+ <span class="dashicons post-option-back"></span>
+ <span class="setting-title" aria-hidden="true"><?php _e( 'Tags' ); ?></span>
+ <span class="screen-reader-text"><?php _e( 'Back to post options' ) ?></span>
+ </button>
+ <?php $this->tags_html( $post ); ?>
+ </div>
+ <?php endif; ?>
</div><!-- .options-panel -->
</div><!-- .wrapper -->
public static function get_instance( $id ) {
global $wpdb;
- if ( ! is_numeric( $id ) || $id != floor( $id ) || ! $id ) {
+ $comment_id = (int) $id;
+ if ( ! $comment_id ) {
return false;
}
- $comment_id = (int) $id;
-
$_comment = wp_cache_get( $comment_id, 'comment' );
if ( ! $_comment ) {
public static function get_instance( $post_id ) {
global $wpdb;
- if ( ! is_numeric( $post_id ) || $post_id != floor( $post_id ) || ! $post_id ) {
+ $post_id = (int) $post_id;
+ if ( ! $post_id ) {
return false;
}
- $post_id = (int) $post_id;
-
$_post = wp_cache_get( $post_id, 'posts' );
if ( ! $_post ) {
if ( empty( $in_search_post_types ) ) {
$where .= ' AND 1=0 ';
} else {
- $where .= " AND {$wpdb->posts}.post_type IN ('" . join("', '", $in_search_post_types ) . "')";
+ $where .= " AND {$wpdb->posts}.post_type IN ('" . join( "', '", array_map( 'esc_sql', $in_search_post_types ) ) . "')";
}
} elseif ( !empty( $post_type ) && is_array( $post_type ) ) {
- $where .= " AND {$wpdb->posts}.post_type IN ('" . join("', '", $post_type) . "')";
+ $where .= " AND {$wpdb->posts}.post_type IN ('" . join("', '", esc_sql( $post_type ) ) . "')";
} elseif ( ! empty( $post_type ) ) {
- $where .= " AND {$wpdb->posts}.post_type = '$post_type'";
+ $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_type = %s", $post_type );
$post_type_object = get_post_type_object ( $post_type );
} elseif ( $this->is_attachment ) {
$where .= " AND {$wpdb->posts}.post_type = 'attachment'";
public static function get_instance( $term_id, $taxonomy = null ) {
global $wpdb;
- if ( ! is_numeric( $term_id ) || $term_id != floor( $term_id ) || ! $term_id ) {
+ $term_id = (int) $term_id;
+ if ( ! $term_id ) {
return false;
}
- $term_id = (int) $term_id;
-
$_term = wp_cache_get( $term_id, 'terms' );
// If there isn't a cached version, hit the database.
return false;
}
+ if ( isset( $args['args'] ) ) {
+ $common_args = $args['args'];
+ unset( $args['args'] );
+ } else {
+ $common_args = array();
+ }
+
if ( isset( $args['callback'] ) ) {
// Upgrade a single set to multiple.
$args = array( $args );
'args' => array(),
);
foreach ( $args as $key => &$arg_group ) {
- if ( ! is_numeric( $arg_group ) ) {
+ if ( ! is_numeric( $key ) ) {
// Route option, skip here.
continue;
}
$arg_group = array_merge( $defaults, $arg_group );
+ $arg_group['args'] = array_merge( $common_args, $arg_group['args'] );
}
$full_route = '/' . trim( $namespace, '/' ) . '/' . trim( $route, '/' );
) );
register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)', array(
+ 'args' => array(
+ 'id' => array(
+ 'description' => __( 'Unique identifier for the object.' ),
+ 'type' => 'integer',
+ ),
+ ),
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_item' ),
return $response;
}
+ /**
+ * Get the comment, if the ID is valid.
+ *
+ * @since 4.7.2
+ *
+ * @param int $id Supplied ID.
+ * @return WP_Comment|WP_Error Comment object if ID is valid, WP_Error otherwise.
+ */
+ protected function get_comment( $id ) {
+ $error = new WP_Error( 'rest_comment_invalid_id', __( 'Invalid comment ID.' ), array( 'status' => 404 ) );
+ if ( (int) $id <= 0 ) {
+ return $error;
+ }
+
+ $id = (int) $id;
+ $comment = get_comment( $id );
+ if ( empty( $comment ) ) {
+ return $error;
+ }
+
+ if ( ! empty( $comment->comment_post_ID ) ) {
+ $post = get_post( (int) $comment->comment_post_ID );
+ if ( empty( $post ) ) {
+ return new WP_Error( 'rest_post_invalid_id', __( 'Invalid post ID.' ), array( 'status' => 404 ) );
+ }
+ }
+
+ return $comment;
+ }
+
/**
* Checks if a given request has access to read the comment.
*
* @return WP_Error|bool True if the request has read access for the item, error object otherwise.
*/
public function get_item_permissions_check( $request ) {
- $id = (int) $request['id'];
-
- $comment = get_comment( $id );
-
- if ( ! $comment ) {
- return true;
+ $comment = $this->get_comment( $request['id'] );
+ if ( is_wp_error( $comment ) ) {
+ return $comment;
}
if ( ! empty( $request['context'] ) && 'edit' === $request['context'] && ! current_user_can( 'moderate_comments' ) ) {
* @return WP_Error|WP_REST_Response Response object on success, or error object on failure.
*/
public function get_item( $request ) {
- $id = (int) $request['id'];
-
- $comment = get_comment( $id );
- if ( empty( $comment ) ) {
- return new WP_Error( 'rest_comment_invalid_id', __( 'Invalid comment ID.' ), array( 'status' => 404 ) );
- }
-
- if ( ! empty( $comment->comment_post_ID ) ) {
- $post = get_post( $comment->comment_post_ID );
- if ( empty( $post ) ) {
- return new WP_Error( 'rest_post_invalid_id', __( 'Invalid post ID.' ), array( 'status' => 404 ) );
- }
+ $comment = $this->get_comment( $request['id'] );
+ if ( is_wp_error( $comment ) ) {
+ return $comment;
}
$data = $this->prepare_item_for_response( $comment, $request );
* @return WP_Error|bool True if the request has access to update the item, error object otherwise.
*/
public function update_item_permissions_check( $request ) {
+ $comment = $this->get_comment( $request['id'] );
+ if ( is_wp_error( $comment ) ) {
+ return $comment;
+ }
- $id = (int) $request['id'];
-
- $comment = get_comment( $id );
-
- if ( $comment && ! $this->check_edit_permission( $comment ) ) {
+ if ( ! $this->check_edit_permission( $comment ) ) {
return new WP_Error( 'rest_cannot_edit', __( 'Sorry, you are not allowed to edit this comment.' ), array( 'status' => rest_authorization_required_code() ) );
}
* @return WP_Error|WP_REST_Response Response object on success, or error object on failure.
*/
public function update_item( $request ) {
- $id = (int) $request['id'];
-
- $comment = get_comment( $id );
-
- if ( empty( $comment ) ) {
- return new WP_Error( 'rest_comment_invalid_id', __( 'Invalid comment ID.' ), array( 'status' => 404 ) );
+ $comment = $this->get_comment( $request['id'] );
+ if ( is_wp_error( $comment ) ) {
+ return $comment;
}
+ $id = $comment->comment_ID;
+
if ( isset( $request['type'] ) && get_comment_type( $id ) !== $request['type'] ) {
return new WP_Error( 'rest_comment_invalid_type', __( 'Sorry, you are not allowed to change the comment type.' ), array( 'status' => 404 ) );
}
* @return WP_Error|bool True if the request has access to delete the item, error object otherwise.
*/
public function delete_item_permissions_check( $request ) {
- $id = (int) $request['id'];
- $comment = get_comment( $id );
-
- if ( ! $comment ) {
- return new WP_Error( 'rest_comment_invalid_id', __( 'Invalid comment ID.' ), array( 'status' => 404 ) );
+ $comment = $this->get_comment( $request['id'] );
+ if ( is_wp_error( $comment ) ) {
+ return $comment;
}
if ( ! $this->check_edit_permission( $comment ) ) {
* @return WP_Error|WP_REST_Response Response object on success, or error object on failure.
*/
public function delete_item( $request ) {
- $id = (int) $request['id'];
- $force = isset( $request['force'] ) ? (bool) $request['force'] : false;
-
- $comment = get_comment( $id );
-
- if ( empty( $comment ) ) {
- return new WP_Error( 'rest_comment_invalid_id', __( 'Invalid comment ID.' ), array( 'status' => 404 ) );
+ $comment = $this->get_comment( $request['id'] );
+ if ( is_wp_error( $comment ) ) {
+ return $comment;
}
+ $force = isset( $request['force'] ) ? (bool) $request['force'] : false;
+
/**
* Filters whether a comment can be trashed.
*
) );
register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<status>[\w-]+)', array(
+ 'args' => array(
+ 'status' => array(
+ 'description' => __( 'An alphanumeric identifier for the status.' ),
+ 'type' => 'string',
+ ),
+ ),
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_item' ),
) );
register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<type>[\w-]+)', array(
+ 'args' => array(
+ 'type' => array(
+ 'description' => __( 'An alphanumeric identifier for the post type.' ),
+ 'type' => 'string',
+ ),
+ ),
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_item' ),
);
}
register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)', array(
+ 'args' => array(
+ 'id' => array(
+ 'description' => __( 'Unique identifier for the object.' ),
+ 'type' => 'integer',
+ ),
+ ),
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_item' ),
return $response;
}
+ /**
+ * Get the post, if the ID is valid.
+ *
+ * @since 4.7.2
+ *
+ * @param int $id Supplied ID.
+ * @return WP_Post|WP_Error Post object if ID is valid, WP_Error otherwise.
+ */
+ protected function get_post( $id ) {
+ $error = new WP_Error( 'rest_post_invalid_id', __( 'Invalid post ID.' ), array( 'status' => 404 ) );
+ if ( (int) $id <= 0 ) {
+ return $error;
+ }
+
+ $post = get_post( (int) $id );
+ if ( empty( $post ) || empty( $post->ID ) || $this->post_type !== $post->post_type ) {
+ return $error;
+ }
+
+ return $post;
+ }
+
/**
* Checks if a given request has access to read a post.
*
* @return bool|WP_Error True if the request has read access for the item, WP_Error object otherwise.
*/
public function get_item_permissions_check( $request ) {
-
- $post = get_post( (int) $request['id'] );
+ $post = $this->get_post( $request['id'] );
+ if ( is_wp_error( $post ) ) {
+ return $post;
+ }
if ( 'edit' === $request['context'] && $post && ! $this->check_update_permission( $post ) ) {
return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit this post.' ), array( 'status' => rest_authorization_required_code() ) );
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
*/
public function get_item( $request ) {
- $id = (int) $request['id'];
- $post = get_post( $id );
-
- if ( empty( $id ) || empty( $post->ID ) || $this->post_type !== $post->post_type ) {
- return new WP_Error( 'rest_post_invalid_id', __( 'Invalid post ID.' ), array( 'status' => 404 ) );
+ $post = $this->get_post( $request['id'] );
+ if ( is_wp_error( $post ) ) {
+ return $post;
}
$data = $this->prepare_item_for_response( $post, $request );
$response = rest_ensure_response( $data );
if ( is_post_type_viewable( get_post_type_object( $post->post_type ) ) ) {
- $response->link_header( 'alternate', get_permalink( $id ), array( 'type' => 'text/html' ) );
+ $response->link_header( 'alternate', get_permalink( $post->ID ), array( 'type' => 'text/html' ) );
}
return $response;
* @return true|WP_Error True if the request has access to create items, WP_Error object otherwise.
*/
public function create_item_permissions_check( $request ) {
+ if ( ! empty( $request['id'] ) ) {
+ return new WP_Error( 'rest_post_exists', __( 'Cannot create existing post.' ), array( 'status' => 400 ) );
+ }
$post_type = get_post_type_object( $this->post_type );
* @return true|WP_Error True if the request has access to update the item, WP_Error object otherwise.
*/
public function update_item_permissions_check( $request ) {
+ $post = $this->get_post( $request['id'] );
+ if ( is_wp_error( $post ) ) {
+ return $post;
+ }
- $post = get_post( $request['id'] );
$post_type = get_post_type_object( $this->post_type );
if ( $post && ! $this->check_update_permission( $post ) ) {
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
*/
public function update_item( $request ) {
- $id = (int) $request['id'];
- $post = get_post( $id );
-
- if ( empty( $id ) || empty( $post->ID ) || $this->post_type !== $post->post_type ) {
- return new WP_Error( 'rest_post_invalid_id', __( 'Invalid post ID.' ), array( 'status' => 404 ) );
+ $valid_check = $this->get_post( $request['id'] );
+ if ( is_wp_error( $valid_check ) ) {
+ return $valid_check;
}
$post = $this->prepare_item_for_database( $request );
* @return true|WP_Error True if the request has access to delete the item, WP_Error object otherwise.
*/
public function delete_item_permissions_check( $request ) {
-
- $post = get_post( $request['id'] );
+ $post = $this->get_post( $request['id'] );
+ if ( is_wp_error( $post ) ) {
+ return $post;
+ }
if ( $post && ! $this->check_delete_permission( $post ) ) {
return new WP_Error( 'rest_cannot_delete', __( 'Sorry, you are not allowed to delete this post.' ), array( 'status' => rest_authorization_required_code() ) );
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
*/
public function delete_item( $request ) {
- $id = (int) $request['id'];
- $force = (bool) $request['force'];
-
- $post = get_post( $id );
-
- if ( empty( $id ) || empty( $post->ID ) || $this->post_type !== $post->post_type ) {
- return new WP_Error( 'rest_post_invalid_id', __( 'Invalid post ID.' ), array( 'status' => 404 ) );
+ $post = $this->get_post( $request['id'] );
+ if ( is_wp_error( $post ) ) {
+ return $post;
}
+ $id = $post->ID;
+ $force = (bool) $request['force'];
+
$supports_trash = ( EMPTY_TRASH_DAYS > 0 );
if ( 'attachment' === $post->post_type ) {
// Post ID.
if ( isset( $request['id'] ) ) {
- $prepared_post->ID = absint( $request['id'] );
+ $existing_post = $this->get_post( $request['id'] );
+ if ( is_wp_error( $existing_post ) ) {
+ return $existing_post;
+ }
+
+ $prepared_post->ID = $existing_post->ID;
}
$schema = $this->get_item_schema();
public function register_routes() {
register_rest_route( $this->namespace, '/' . $this->parent_base . '/(?P<parent>[\d]+)/' . $this->rest_base, array(
+ 'args' => array(
+ 'parent' => array(
+ 'description' => __( 'The ID for the parent of the object.' ),
+ 'type' => 'integer',
+ ),
+ ),
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_items' ),
) );
register_rest_route( $this->namespace, '/' . $this->parent_base . '/(?P<parent>[\d]+)/' . $this->rest_base . '/(?P<id>[\d]+)', array(
+ 'args' => array(
+ 'parent' => array(
+ 'description' => __( 'The ID for the parent of the object.' ),
+ 'type' => 'integer',
+ ),
+ 'id' => array(
+ 'description' => __( 'Unique identifier for the object.' ),
+ 'type' => 'integer',
+ ),
+ ),
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_item' ),
}
+ /**
+ * Get the parent post, if the ID is valid.
+ *
+ * @since 4.7.2
+ *
+ * @param int $id Supplied ID.
+ * @return WP_Post|WP_Error Post object if ID is valid, WP_Error otherwise.
+ */
+ protected function get_parent( $parent ) {
+ $error = new WP_Error( 'rest_post_invalid_parent', __( 'Invalid post parent ID.' ), array( 'status' => 404 ) );
+ if ( (int) $parent <= 0 ) {
+ return $error;
+ }
+
+ $parent = get_post( (int) $parent );
+ if ( empty( $parent ) || empty( $parent->ID ) || $this->parent_post_type !== $parent->post_type ) {
+ return $error;
+ }
+
+ return $parent;
+ }
+
/**
* Checks if a given request has access to get revisions.
*
* @return true|WP_Error True if the request has read access, WP_Error object otherwise.
*/
public function get_items_permissions_check( $request ) {
-
- $parent = get_post( $request['parent'] );
- if ( ! $parent ) {
- return true;
+ $parent = $this->get_parent( $request['parent'] );
+ if ( is_wp_error( $parent ) ) {
+ return $parent;
}
+
$parent_post_type_obj = get_post_type_object( $parent->post_type );
if ( ! current_user_can( $parent_post_type_obj->cap->edit_post, $parent->ID ) ) {
return new WP_Error( 'rest_cannot_read', __( 'Sorry, you are not allowed to view revisions of this post.' ), array( 'status' => rest_authorization_required_code() ) );
return true;
}
+ /**
+ * Get the revision, if the ID is valid.
+ *
+ * @since 4.7.2
+ *
+ * @param int $id Supplied ID.
+ * @return WP_Post|WP_Error Revision post object if ID is valid, WP_Error otherwise.
+ */
+ protected function get_revision( $id ) {
+ $error = new WP_Error( 'rest_post_invalid_id', __( 'Invalid revision ID.' ), array( 'status' => 404 ) );
+ if ( (int) $id <= 0 ) {
+ return $error;
+ }
+
+ $revision = get_post( (int) $id );
+ if ( empty( $revision ) || empty( $revision->ID ) || 'revision' !== $revision->post_type ) {
+ return $error;
+ }
+
+ return $revision;
+ }
+
/**
* Gets a collection of revisions.
*
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
*/
public function get_items( $request ) {
- $parent = get_post( $request['parent'] );
- if ( ! $request['parent'] || ! $parent || $this->parent_post_type !== $parent->post_type ) {
- return new WP_Error( 'rest_post_invalid_parent', __( 'Invalid post parent ID.' ), array( 'status' => 404 ) );
+ $parent = $this->get_parent( $request['parent'] );
+ if ( is_wp_error( $parent ) ) {
+ return $parent;
}
$revisions = wp_get_post_revisions( $request['parent'] );
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
*/
public function get_item( $request ) {
- $parent = get_post( $request['parent'] );
- if ( ! $request['parent'] || ! $parent || $this->parent_post_type !== $parent->post_type ) {
- return new WP_Error( 'rest_post_invalid_parent', __( 'Invalid post parent ID.' ), array( 'status' => 404 ) );
+ $parent = $this->get_parent( $request['parent'] );
+ if ( is_wp_error( $parent ) ) {
+ return $parent;
}
- $revision = get_post( $request['id'] );
- if ( ! $revision || 'revision' !== $revision->post_type ) {
- return new WP_Error( 'rest_post_invalid_id', __( 'Invalid revision ID.' ), array( 'status' => 404 ) );
+ $revision = $this->get_revision( $request['id'] );
+ if ( is_wp_error( $revision ) ) {
+ return $revision;
}
$response = $this->prepare_item_for_response( $revision, $request );
* @return bool|WP_Error True if the request has access to delete the item, WP_Error object otherwise.
*/
public function delete_item_permissions_check( $request ) {
+ $parent = $this->get_parent( $request['parent'] );
+ if ( is_wp_error( $parent ) ) {
+ return $parent;
+ }
+
+ $revision = $this->get_revision( $request['id'] );
+ if ( is_wp_error( $revision ) ) {
+ return $revision;
+ }
$response = $this->get_items_permissions_check( $request );
if ( ! $response || is_wp_error( $response ) ) {
return $response;
}
- $post = get_post( $request['id'] );
- if ( ! $post ) {
- return new WP_Error( 'rest_post_invalid_id', __( 'Invalid revision ID.' ), array( 'status' => 404 ) );
- }
$post_type = get_post_type_object( 'revision' );
- return current_user_can( $post_type->cap->delete_post, $post->ID );
+ return current_user_can( $post_type->cap->delete_post, $revision->ID );
}
/**
* @return true|WP_Error True on success, or WP_Error object on failure.
*/
public function delete_item( $request ) {
+ $revision = $this->get_revision( $request['id'] );
+ if ( is_wp_error( $revision ) ) {
+ return $revision;
+ }
+
$force = isset( $request['force'] ) ? (bool) $request['force'] : false;
// We don't support trashing for revisions.
return new WP_Error( 'rest_trash_not_supported', __( 'Revisions do not support trashing. Set force=true to delete.' ), array( 'status' => 501 ) );
}
- $revision = get_post( $request['id'] );
$previous = $this->prepare_item_for_response( $revision, $request );
$result = wp_delete_post( $request['id'], true );
) );
register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<taxonomy>[\w-]+)', array(
+ 'args' => array(
+ 'taxonomy' => array(
+ 'description' => __( 'An alphanumeric identifier for the taxonomy.' ),
+ 'type' => 'string',
+ ),
+ ),
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_item' ),
) );
register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)', array(
+ 'args' => array(
+ 'id' => array(
+ 'description' => __( 'Unique identifier for the term.' ),
+ 'type' => 'integer',
+ ),
+ ),
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_item' ),
'methods' => WP_REST_Server::EDITABLE,
'callback' => array( $this, 'update_item' ),
'permission_callback' => array( $this, 'update_item_permissions_check' ),
- 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
+ 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
),
array(
'methods' => WP_REST_Server::DELETABLE,
return $response;
}
+ /**
+ * Get the term, if the ID is valid.
+ *
+ * @since 4.7.2
+ *
+ * @param int $id Supplied ID.
+ * @return WP_Term|WP_Error Term object if ID is valid, WP_Error otherwise.
+ */
+ protected function get_term( $id ) {
+ $error = new WP_Error( 'rest_term_invalid', __( 'Term does not exist.' ), array( 'status' => 404 ) );
+
+ if ( ! $this->check_is_taxonomy_allowed( $this->taxonomy ) ) {
+ return $error;
+ }
+
+ if ( (int) $id <= 0 ) {
+ return $error;
+ }
+
+ $term = get_term( (int) $id, $this->taxonomy );
+ if ( empty( $term ) || $term->taxonomy !== $this->taxonomy ) {
+ return $error;
+ }
+
+ return $term;
+ }
+
/**
* Checks if a request has access to read or edit the specified term.
*
* @return bool|WP_Error True if the request has read access for the item, otherwise false or WP_Error object.
*/
public function get_item_permissions_check( $request ) {
- $tax_obj = get_taxonomy( $this->taxonomy );
- if ( ! $tax_obj || ! $this->check_is_taxonomy_allowed( $this->taxonomy ) ) {
- return false;
+ $term = $this->get_term( $request['id'] );
+ if ( is_wp_error( $term ) ) {
+ return $term;
}
- if ( 'edit' === $request['context'] && ! current_user_can( 'edit_term', (int) $request['id'] ) ) {
+
+ if ( 'edit' === $request['context'] && ! current_user_can( 'edit_term', $term->term_id ) ) {
return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit this term.' ), array( 'status' => rest_authorization_required_code() ) );
}
return true;
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
*/
public function get_item( $request ) {
-
- $term = get_term( (int) $request['id'], $this->taxonomy );
-
- if ( ! $term || $term->taxonomy !== $this->taxonomy ) {
- return new WP_Error( 'rest_term_invalid', __( "Term doesn't exist." ), array( 'status' => 404 ) );
- }
+ $term = $this->get_term( $request['id'] );
if ( is_wp_error( $term ) ) {
return $term;
* @return bool|WP_Error True if the request has access to update the item, false or WP_Error object otherwise.
*/
public function update_item_permissions_check( $request ) {
-
- if ( ! $this->check_is_taxonomy_allowed( $this->taxonomy ) ) {
- return false;
- }
-
- $term = get_term( (int) $request['id'], $this->taxonomy );
-
- if ( ! $term ) {
- return new WP_Error( 'rest_term_invalid', __( "Term doesn't exist." ), array( 'status' => 404 ) );
+ $term = $this->get_term( $request['id'] );
+ if ( is_wp_error( $term ) ) {
+ return $term;
}
if ( ! current_user_can( 'edit_term', $term->term_id ) ) {
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
*/
public function update_item( $request ) {
+ $term = $this->get_term( $request['id'] );
+ if ( is_wp_error( $term ) ) {
+ return $term;
+ }
+
if ( isset( $request['parent'] ) ) {
if ( ! is_taxonomy_hierarchical( $this->taxonomy ) ) {
return new WP_Error( 'rest_taxonomy_not_hierarchical', __( 'Can not set parent term, taxonomy is not hierarchical.' ), array( 'status' => 400 ) );
$prepared_term = $this->prepare_item_for_database( $request );
- $term = get_term( (int) $request['id'], $this->taxonomy );
-
// Only update the term if we haz something to update.
if ( ! empty( $prepared_term ) ) {
$update = wp_update_term( $term->term_id, $term->taxonomy, wp_slash( (array) $prepared_term ) );
}
}
- $term = get_term( (int) $request['id'], $this->taxonomy );
+ $term = get_term( $term->term_id, $this->taxonomy );
/* This action is documented in lib/endpoints/class-wp-rest-terms-controller.php */
do_action( "rest_insert_{$this->taxonomy}", $term, $request, false );
$schema = $this->get_item_schema();
if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) {
- $meta_update = $this->meta->update_value( $request['meta'], (int) $request['id'] );
+ $meta_update = $this->meta->update_value( $request['meta'], $term->term_id );
if ( is_wp_error( $meta_update ) ) {
return $meta_update;
* @return bool|WP_Error True if the request has access to delete the item, otherwise false or WP_Error object.
*/
public function delete_item_permissions_check( $request ) {
- if ( ! $this->check_is_taxonomy_allowed( $this->taxonomy ) ) {
- return false;
- }
-
- $term = get_term( (int) $request['id'], $this->taxonomy );
-
- if ( ! $term ) {
- return new WP_Error( 'rest_term_invalid', __( "Term doesn't exist." ), array( 'status' => 404 ) );
+ $term = $this->get_term( $request['id'] );
+ if ( is_wp_error( $term ) ) {
+ return $term;
}
if ( ! current_user_can( 'delete_term', $term->term_id ) ) {
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
*/
public function delete_item( $request ) {
+ $term = $this->get_term( $request['id'] );
+ if ( is_wp_error( $term ) ) {
+ return $term;
+ }
$force = isset( $request['force'] ) ? (bool) $request['force'] : false;
return new WP_Error( 'rest_trash_not_supported', __( 'Terms do not support trashing. Set force=true to delete.' ), array( 'status' => 501 ) );
}
- $term = get_term( (int) $request['id'], $this->taxonomy );
-
$request->set_param( 'context', 'view' );
$previous = $this->prepare_item_for_response( $term, $request );
) );
register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)', array(
+ 'args' => array(
+ 'id' => array(
+ 'description' => __( 'Unique identifier for the user.' ),
+ 'type' => 'integer',
+ ),
+ ),
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_item' ),
return $response;
}
+ /**
+ * Get the user, if the ID is valid.
+ *
+ * @since 4.7.2
+ *
+ * @param int $id Supplied ID.
+ * @return WP_User|WP_Error True if ID is valid, WP_Error otherwise.
+ */
+ protected function get_user( $id ) {
+ $error = new WP_Error( 'rest_user_invalid_id', __( 'Invalid user ID.' ), array( 'status' => 404 ) );
+ if ( (int) $id <= 0 ) {
+ return $error;
+ }
+
+ $user = get_userdata( (int) $id );
+ if ( empty( $user ) || ! $user->exists() ) {
+ return $error;
+ }
+
+ return $user;
+ }
+
/**
* Checks if a given request has access to read a user.
*
* @return true|WP_Error True if the request has read access for the item, otherwise WP_Error object.
*/
public function get_item_permissions_check( $request ) {
+ $user = $this->get_user( $request['id'] );
+ if ( is_wp_error( $user ) ) {
+ return $user;
+ }
- $id = (int) $request['id'];
- $user = get_userdata( $id );
$types = get_post_types( array( 'show_in_rest' => true ), 'names' );
- if ( empty( $id ) || empty( $user->ID ) ) {
- return new WP_Error( 'rest_user_invalid_id', __( 'Invalid user ID.' ), array( 'status' => 404 ) );
- }
-
- if ( get_current_user_id() === $id ) {
+ if ( get_current_user_id() === $user->ID ) {
return true;
}
if ( 'edit' === $request['context'] && ! current_user_can( 'list_users' ) ) {
return new WP_Error( 'rest_user_cannot_view', __( 'Sorry, you are not allowed to list users.' ), array( 'status' => rest_authorization_required_code() ) );
- } elseif ( ! count_user_posts( $id, $types ) && ! current_user_can( 'edit_user', $id ) && ! current_user_can( 'list_users' ) ) {
+ } elseif ( ! count_user_posts( $user->ID, $types ) && ! current_user_can( 'edit_user', $user->ID ) && ! current_user_can( 'list_users' ) ) {
return new WP_Error( 'rest_user_cannot_view', __( 'Sorry, you are not allowed to list users.' ), array( 'status' => rest_authorization_required_code() ) );
}
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
*/
public function get_item( $request ) {
- $id = (int) $request['id'];
- $user = get_userdata( $id );
-
- if ( empty( $id ) || empty( $user->ID ) ) {
- return new WP_Error( 'rest_user_invalid_id', __( 'Invalid user ID.' ), array( 'status' => 404 ) );
+ $user = $this->get_user( $request['id'] );
+ if ( is_wp_error( $user ) ) {
+ return $user;
}
$user = $this->prepare_item_for_response( $user, $request );
* @return true|WP_Error True if the request has access to update the item, WP_Error object otherwise.
*/
public function update_item_permissions_check( $request ) {
+ $user = $this->get_user( $request['id'] );
+ if ( is_wp_error( $user ) ) {
+ return $user;
+ }
- $id = (int) $request['id'];
-
- if ( ! current_user_can( 'edit_user', $id ) ) {
+ if ( ! current_user_can( 'edit_user', $user->ID ) ) {
return new WP_Error( 'rest_cannot_edit', __( 'Sorry, you are not allowed to edit this user.' ), array( 'status' => rest_authorization_required_code() ) );
}
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
*/
public function update_item( $request ) {
- $id = (int) $request['id'];
- $user = get_userdata( $id );
+ $user = $this->get_user( $request['id'] );
+ if ( is_wp_error( $user ) ) {
+ return $user;
+ }
+
+ $id = $user->ID;
if ( ! $user ) {
return new WP_Error( 'rest_user_invalid_id', __( 'Invalid user ID.' ), array( 'status' => 404 ) );
* @return true|WP_Error True if the request has access to delete the item, WP_Error object otherwise.
*/
public function delete_item_permissions_check( $request ) {
+ $user = $this->get_user( $request['id'] );
+ if ( is_wp_error( $user ) ) {
+ return $user;
+ }
- $id = (int) $request['id'];
-
- if ( ! current_user_can( 'delete_user', $id ) ) {
+ if ( ! current_user_can( 'delete_user', $user->ID ) ) {
return new WP_Error( 'rest_user_cannot_delete', __( 'Sorry, you are not allowed to delete this user.' ), array( 'status' => rest_authorization_required_code() ) );
}
if ( is_multisite() ) {
return new WP_Error( 'rest_cannot_delete', __( 'The user cannot be deleted.' ), array( 'status' => 501 ) );
}
+ $user = $this->get_user( $request['id'] );
+ if ( is_wp_error( $user ) ) {
+ return $user;
+ }
- $id = (int) $request['id'];
+ $id = $user->ID;
$reassign = false === $request['reassign'] ? null : absint( $request['reassign'] );
$force = isset( $request['force'] ) ? (bool) $request['force'] : false;
return new WP_Error( 'rest_trash_not_supported', __( 'Users do not support trashing. Set force=true to delete.' ), array( 'status' => 501 ) );
}
- $user = get_userdata( $id );
-
- if ( ! $user ) {
- return new WP_Error( 'rest_user_invalid_id', __( 'Invalid user ID.' ), array( 'status' => 404 ) );
- }
-
if ( ! empty( $reassign ) ) {
if ( $reassign === $id || ! get_userdata( $reassign ) ) {
return new WP_Error( 'rest_user_invalid_reassign', __( 'Invalid user ID for reassignment.' ), array( 'status' => 400 ) );
*
* @global string $wp_version
*/
-$wp_version = '4.7.1';
+$wp_version = '4.7.2';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.