/** * check if a request can delete a theme * * @param WP_REST_Request $request * @return WP_Error|boolean */ public function delete_item_permissions_check($request) { if (!current_user_can('delete_themes')) { return new WP_Error('rest_forbidden', __('Sorry, you cannot delete themes'), array('status' => rest_authorization_required_code())); } return true; }
/** * Check whether a given request has permission to execute a specific system status tool. * * @param WP_REST_Request $request Full details about the request. * @return WP_Error|boolean */ public function update_item_permissions_check($request) { if (!wc_rest_check_manager_permissions('system_status', 'edit')) { return new WP_Error('woocommerce_rest_cannot_update', __('Sorry, you cannot update resource.', 'woocommerce'), array('status' => rest_authorization_required_code())); } return true; }
/** * Check whether a given request has permission to view system status. * * @param WP_REST_Request $request Full details about the request. * @return WP_Error|boolean */ public function get_items_permissions_check($request) { if (!wc_rest_check_manager_permissions('system_status', 'read')) { return new WP_Error('woocommerce_rest_cannot_view', __('Sorry, you cannot list resources.', 'woocommerce'), array('status' => rest_authorization_required_code())); } return true; }
/** * Check if a given request has access to read /entry. * * @param WP_REST_Request $request Full details about the request. * * @return WP_Error|boolean */ public function get_items_permissions_check($request) { if ('edit' === $request['context'] && (!current_user_can('connections_edit_entry') || !current_user_can('connections_edit_entry_moderated'))) { return new WP_Error('rest_forbidden_context', __('Sorry, you are not allowed to edit these entries.', 'connections'), array('status' => rest_authorization_required_code())); } return TRUE; }
/** * Prepare a post status object for serialization * * @param stdClass $status Post status data * @param WP_REST_Request $request * @return WP_REST_Response Post status data */ public function prepare_item_for_response($status, $request) { if (false === $status->public && !is_user_logged_in() || true === $status->internal && is_user_logged_in()) { return new WP_Error('rest_cannot_read_status', __('Cannot view status.'), array('status' => rest_authorization_required_code())); } $data = array('name' => $status->label, 'private' => (bool) $status->private, 'protected' => (bool) $status->protected, 'public' => (bool) $status->public, 'queryable' => (bool) $status->publicly_queryable, 'show_in_list' => (bool) $status->show_in_admin_all_list, 'slug' => $status->name); $context = !empty($request['context']) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object($data, $request); $data = $this->filter_response_by_context($data, $context); $response = rest_ensure_response($data); $posts_controller = new WP_REST_Posts_Controller('post'); if ('publish' === $status->name) { $response->add_link('archives', rest_url('/wp/v2/' . $posts_controller->get_post_type_base('post'))); } else { $response->add_link('archives', add_query_arg('status', $status->name, rest_url('/wp/v2/' . $posts_controller->get_post_type_base('post')))); } /** * Filter a status returned from the API. * * Allows modification of the status data right before it is returned. * * @param WP_REST_Response $response The response object. * @param object $status The original status object. * @param WP_REST_Request $request Request used to generate the response. */ return apply_filters('rest_prepare_status', $response, $status, $request); }
/** * Check if a given request has access delete a tax. * * @param WP_REST_Request $request Full details about the request. * @return boolean */ public function delete_item_permissions_check($request) { if (!wc_rest_check_manager_permissions('settings', 'delete')) { return new WP_Error('woocommerce_rest_cannot_delete', __('Sorry, you are not allowed to delete this resource.', 'woocommerce'), array('status' => rest_authorization_required_code())); } return true; }
/** * Check whether a given request has permission to edit payment gateways. * * @param WP_REST_Request $request Full details about the request. * @return WP_Error|boolean */ public function update_items_permissions_check($request) { if (!wc_rest_check_manager_permissions('payment_gateways', 'edit')) { return new WP_Error('woocommerce_rest_cannot_edit', __('Sorry, you are not allowed to edit this resource.', 'woocommerce'), array('status' => rest_authorization_required_code())); } return true; }
/** * Check if a given request has access to read a webhook develivery. * * @param WP_REST_Request $request Full details about the request. * @return WP_Error|boolean */ public function get_item_permissions_check($request) { $post = get_post((int) $request['product_id']); if ($post && !wc_rest_check_post_permissions('product', 'read', $post->ID)) { return new WP_Error('woocommerce_rest_cannot_view', __('Sorry, you cannot view this resource.', 'woocommerce'), array('status' => rest_authorization_required_code())); } return true; }
/** * Check whether a given request has permission to read customers. * * @param WP_REST_Request $request Full details about the request. * @return WP_Error|boolean */ public function get_items_permissions_check($request) { $customer = get_user_by('id', (int) $request['customer_id']); if (!$customer) { return new WP_Error('woocommerce_rest_customer_invalid', __('Resource does not exist.', 'woocommerce'), array('status' => 404)); } if (!wc_rest_check_user_permissions('read', $customer->id)) { return new WP_Error('woocommerce_rest_cannot_view', __('Sorry, you cannot list resources.', 'woocommerce'), array('status' => rest_authorization_required_code())); } return true; }
/** * Check if a given request has access to get revisions * * @param WP_REST_Request $request Full data about the request. * @return WP_Error|bool */ public function get_items_permissions_check($request) { $parent = get_post($request['parent_id']); if (!$parent) { return true; } $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 cannot view revisions of this post.'), array('status' => rest_authorization_required_code())); } return true; }
/** * Check if a given request has access to read a post status. * * @param WP_REST_Request $request Full details about the request. * @return WP_Error|boolean */ public function get_item_permissions_check($request) { $status = get_post_status_object($request['status']); if (empty($status)) { return new WP_Error('rest_status_invalid', __('Invalid resource.'), array('status' => 404)); } $check = $this->check_read_permission($status); if (!$check) { return new WP_Error('rest_cannot_read_status', __('Cannot view resource.'), array('status' => rest_authorization_required_code())); } return true; }
/** * Check if a given request has access a taxonomy * * @param WP_REST_Request $request Full details about the request. * @return WP_Error|boolean */ public function get_item_permissions_check($request) { $tax_obj = get_taxonomy($request['taxonomy']); if ($tax_obj) { if (empty($tax_obj->show_in_rest)) { return false; } if ('edit' === $request['context'] && !current_user_can($tax_obj->cap->manage_terms)) { return new WP_Error('rest_forbidden_context', __('Sorry, you are not allowed to manage this taxonomy.'), array('status' => rest_authorization_required_code())); } } return true; }
/** * Get a specific post type * * @param WP_REST_Request $request * @return array|WP_Error */ public function get_item($request) { $obj = get_post_type_object($request['type']); if (empty($obj)) { return new WP_Error('rest_type_invalid', __('Invalid type.'), array('status' => 404)); } if (empty($obj->show_in_rest)) { return new WP_Error('rest_cannot_read_type', __('Cannot view type.'), array('status' => rest_authorization_required_code())); } if ('edit' === $request['context'] && !current_user_can($obj->cap->edit_posts)) { return new WP_Error('rest_forbidden_context', __('Sorry, you are not allowed to manage this type.'), array('status' => rest_authorization_required_code())); } return $this->prepare_item_for_response($obj, $request); }
/** * Checks if a given request has access to create an attachment. * * @since 4.7.0 * @access public * * @param WP_REST_Request $request Full details about the request. * @return WP_Error|true Boolean true if the attachment may be created, or a WP_Error if not. */ public function create_item_permissions_check($request) { $ret = parent::create_item_permissions_check($request); if (!$ret || is_wp_error($ret)) { return $ret; } if (!current_user_can('upload_files')) { return new WP_Error('rest_cannot_create', __('Sorry, you are not allowed to upload media on this site.'), array('status' => 400)); } // Attaching media to a post requires ability to edit said post. if (!empty($request['post'])) { $parent = get_post((int) $request['post']); $post_parent_type = get_post_type_object($parent->post_type); if (!current_user_can($post_parent_type->cap->edit_post, $request['post'])) { return new WP_Error('rest_cannot_edit', __('Sorry, you are not allowed to upload media to this post.'), array('status' => rest_authorization_required_code())); } } return true; }
/** * Prepare a post type object for serialization * * @param stdClass $post_type Post type data * @param WP_REST_Request $request * @return array Post type data */ public function prepare_item_for_response($post_type, $request) { if (false === $post_type->public) { return new WP_Error('rest_cannot_read_type', __('Cannot view type.'), array('status' => rest_authorization_required_code())); } $data = array('description' => $post_type->description, 'hierarchical' => $post_type->hierarchical, 'labels' => $post_type->labels, 'name' => $post_type->label, 'slug' => $post_type->name); $context = !empty($request['context']) ? $request['context'] : 'view'; $data = $this->filter_response_by_context($data, $context); $data = $this->add_additional_fields_to_object($data, $request); // Wrap the data in a response object. $response = rest_ensure_response($data); $base = !empty($post_type->rest_base) ? $post_type->rest_base : $post_type->name; $response->add_links(array('collection' => array('href' => rest_url('wp/v2/types')), 'item' => array('href' => rest_url(sprintf('wp/v2/%s', $base))))); /** * Filter a post type returned from the API. * * Allows modification of the post type data right before it is returned. * * @param WP_REST_Response $response The response object. * @param object $item The original post type object. * @param WP_REST_Request $request Request used to generate the response. */ return apply_filters('rest_prepare_post_type', $response, $post_type, $request); }
/** * Check if a given request has access delete a order note. * * @param WP_REST_Request $request Full details about the request. * @return boolean */ public function delete_item_permissions_check($request) { $post = get_post((int) $request['order_id']); if ($post && !wc_rest_check_post_permissions($this->post_type, 'delete', $post->ID)) { return new WP_Error('woocommerce_rest_cannot_delete', __('Sorry, you are not allowed to delete this resource.', 'woocommerce'), array('status' => rest_authorization_required_code())); } return true; }
/** * Check if a given request has access to delete meta for a taxonomy. * * @param WP_REST_Request $request Full details about the request. * @return WP_Error|boolean */ public function delete_item_permissions_check($request) { $tax_obj = get_taxonomy($this->parent_taxonomy); $parent = get_term((int) $request['parent_id'], $this->parent_taxonomy); if (empty($parent) || empty($parent->term_id)) { return new WP_Error('rest_term_invalid_id', __('Invalid term id.'), array('status' => 404)); } if (!current_user_can($tax_obj->cap->delete_terms)) { return new WP_Error('rest_forbidden', __('Sorry, you cannot view the meta for this taxonomy.'), array('status' => rest_authorization_required_code())); } return true; }
/** * Check if a given request has access batch create, update and delete items. * * @param WP_REST_Request $request Full details about the request. * @return boolean */ public function batch_items_permissions_check($request) { $permissions = $this->check_permissions($request, 'batch'); if (is_wp_error($permissions)) { return $permissions; } if (!$permissions) { return new WP_Error('woocommerce_rest_cannot_batch', __('Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce'), array('status' => rest_authorization_required_code())); } return true; }
/** * Checks if a given request has access to delete a comment. * * @since 4.7.0 * @access public * * @param WP_REST_Request $request Full details about the request. * @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)); } if (!$this->check_edit_permission($comment)) { return new WP_Error('rest_cannot_delete', __('Sorry, you are not allowed to delete this comment.'), array('status' => rest_authorization_required_code())); } return true; }
/** * Check if a given request has access to create a reaction * * @param WP_REST_Request $request Full details about the request. * @return WP_Error|boolean */ public function create_item_permissions_check($request) { if (!empty($request['post']) && ($post = get_post((int) $request['post']))) { if (!$this->check_read_post_permission($post)) { return new WP_Error('rest_cannot_read_post', __('Sorry, you cannot read the post for this reaction.', 'react'), array('status' => rest_authorization_required_code())); } if (!comments_open($post->ID)) { return new WP_Error('rest_reactions_closed', __('Sorry, reactions are closed on this post.', 'react'), array('status' => 403)); } } return true; }
/** * Check if a given request has access to delete a term * * @param WP_REST_Request $request Full details about the request. * @return WP_Error|boolean */ 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)); } $taxonomy_obj = get_taxonomy($this->taxonomy); if (!current_user_can($taxonomy_obj->cap->delete_terms)) { return new WP_Error('rest_cannot_delete', __('Sorry, you cannot delete terms.'), array('status' => rest_authorization_required_code())); } return true; }
/** * Sanitizes and validates the list of post statuses, including whether the * user can query private statuses. * * @since 4.7.0 * @access public * * @param string|array $statuses One or more post statuses. * @param WP_REST_Request $request Full details about the request. * @param string $parameter Additional parameter to pass to validation. * @return array|WP_Error A list of valid statuses, otherwise WP_Error object. */ public function sanitize_post_statuses($statuses, $request, $parameter) { $statuses = wp_parse_slug_list($statuses); // The default status is different in WP_REST_Attachments_Controller $attributes = $request->get_attributes(); $default_status = $attributes['args']['status']['default']; foreach ($statuses as $status) { if ($status === $default_status) { continue; } $post_type_obj = get_post_type_object($this->post_type); if (current_user_can($post_type_obj->cap->edit_posts)) { $result = rest_validate_request_arg($status, $request, $parameter); if (is_wp_error($result)) { return $result; } } else { return new WP_Error('rest_forbidden_status', __('Status is forbidden.'), array('status' => rest_authorization_required_code())); } } return $statuses; }
/** * Validate whether the user can query private statuses * * @param mixed $value * @param WP_REST_Request $request * @param string $parameter * @return WP_Error|bool */ public function validate_user_can_query_private_statuses($value, $request, $parameter) { if ('publish' === $value) { return true; } $post_type_obj = get_post_type_object($this->post_type); if (current_user_can($post_type_obj->cap->edit_posts)) { return true; } return new WP_Error('rest_forbidden_status', __('Status is forbidden'), array('status' => rest_authorization_required_code())); }
/** * Check if a given request has access batch create, update and delete items. * * @param WP_REST_Request $request Full details about the request. * @return boolean */ public function batch_items_permissions_check($request) { if (!wc_rest_check_user_permissions('batch')) { return new WP_Error('woocommerce_rest_cannot_batch', __('Sorry, you are not allowed to manipule this resource.', 'woocommerce'), array('status' => rest_authorization_required_code())); } return true; }
/** * Determines if the current user is allowed to make the desired roles change. * * @since 4.7.0 * @access protected * * @param integer $user_id User ID. * @param array $roles New user roles. * @return true|WP_Error True if the current user is allowed to make the role change, * otherwise a WP_Error object. */ protected function check_role_update($user_id, $roles) { global $wp_roles; foreach ($roles as $role) { if (!isset($wp_roles->role_objects[$role])) { return new WP_Error('rest_user_invalid_role', sprintf(__('The role %s does not exist.'), $role), array('status' => 400)); } $potential_role = $wp_roles->role_objects[$role]; /* * Don't let anyone with 'edit_users' (admins) edit their own role to something without it. * Multisite super admins can freely edit their blog roles -- they possess all caps. */ if (!(is_multisite() && current_user_can('manage_sites')) && get_current_user_id() === $user_id && !$potential_role->has_cap('edit_users')) { return new WP_Error('rest_user_invalid_role', __('You cannot give resource that role.'), array('status' => rest_authorization_required_code())); } /** Include admin functions to get access to get_editable_roles() */ require_once ABSPATH . 'wp-admin/includes/admin.php'; // The new role must be editable by the logged-in user. $editable_roles = get_editable_roles(); if (empty($editable_roles[$role])) { return new WP_Error('rest_user_invalid_role', __('You cannot give resource that role.'), array('status' => 403)); } } return true; }
/** * Delete a single item. * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error */ public function delete_item($request) { $id = (int) $request['id']; $force = (bool) $request['force']; $post = get_post($id); $product = wc_get_product($id); if (!empty($post->post_type) && 'product_variation' === $post->post_type && 'product' === $this->post_type) { return new WP_Error("woocommerce_rest_invalid_{$this->post_type}_id", __('To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce'), array('status' => 404)); } elseif (empty($id) || empty($post->ID) || $post->post_type !== $this->post_type) { return new WP_Error("woocommerce_rest_{$this->post_type}_invalid_id", __('Invalid post ID.', 'woocommerce'), array('status' => 404)); } $supports_trash = EMPTY_TRASH_DAYS > 0; /** * Filter whether an item is trashable. * * Return false to disable trash support for the item. * * @param boolean $supports_trash Whether the item type support trashing. * @param WP_Post $post The Post object being considered for trashing support. */ $supports_trash = apply_filters("woocommerce_rest_{$this->post_type}_trashable", $supports_trash, $post); if (!wc_rest_check_post_permissions($this->post_type, 'delete', $post->ID)) { /* translators: %s: post type */ return new WP_Error("woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf(__('Sorry, you are not allowed to delete %s.', 'woocommerce'), $this->post_type), array('status' => rest_authorization_required_code())); } $request->set_param('context', 'edit'); $response = $this->prepare_item_for_response($post, $request); // If we're forcing, then delete permanently. if ($force) { if ($product->is_type('variable')) { foreach ($product->get_children() as $child_id) { $child = wc_get_product($child_id); $child->delete(true); } } elseif ($product->is_type('grouped')) { foreach ($product->get_children() as $child_id) { $child = wc_get_product($child_id); $child->set_parent_id(0); $child->save(); } } $product->delete(true); $result = $product->get_id() > 0 ? false : true; } else { // If we don't support trashing for this type, error out. if (!$supports_trash) { /* translators: %s: post type */ return new WP_Error('woocommerce_rest_trash_not_supported', sprintf(__('The %s does not support trashing.', 'woocommerce'), $this->post_type), array('status' => 501)); } // Otherwise, only trash if we haven't already. if ('trash' === $post->post_status) { /* translators: %s: post type */ return new WP_Error('woocommerce_rest_already_trashed', sprintf(__('The %s has already been deleted.', 'woocommerce'), $this->post_type), array('status' => 410)); } // (Note that internally this falls through to `wp_delete_post` if // the trash is disabled.) $product->delete(); $result = 'trash' === $product->get_status(); } if (!$result) { /* translators: %s: post type */ return new WP_Error('woocommerce_rest_cannot_delete', sprintf(__('The %s cannot be deleted.', 'woocommerce'), $this->post_type), array('status' => 500)); } // Delete parent product transients. if ($parent_id = wp_get_post_parent_id($id)) { wc_delete_product_transients($parent_id); } /** * Fires after a single item is deleted or trashed via the REST API. * * @param object $post The deleted or trashed item. * @param WP_REST_Response $response The response data. * @param WP_REST_Request $request The request sent to the API. */ do_action("woocommerce_rest_delete_{$this->post_type}", $post, $response, $request); return $response; }
/** * Check if a given request has access to update a comment * * @param WP_REST_Request $request Full details about the request. * @return bool|WP_Error */ public function update_item_permissions_check($request) { $id = (int) $request['id']; $comment = get_comment($id); if ($comment && !$this->check_edit_permission($comment)) { return new WP_Error('rest_cannot_edit', __('Sorry, you can not edit this comment.'), array('status' => rest_authorization_required_code())); } return true; }
/** * Check for fundamental customize capability to do anything with snapshots. * * @return bool|\WP_Error */ protected function check_initial_access_permission() { if (!current_user_can('customize')) { return new \WP_Error('rest_customize_unauthorized', __('Sorry, Customizer snapshots require proper authentication (the customize capability).', 'customize-snapshots'), array('status' => rest_authorization_required_code())); } return true; }
/** * Check if a given request has access to delete meta for a post. * * @param WP_REST_Request $request Full details about the request. * @return WP_Error|boolean */ public function delete_item_permissions_check($request) { $parent = get_post((int) $request['parent_id']); if (empty($parent) || empty($parent->ID)) { return new WP_Error('rest_post_invalid_id', __('Invalid post id.'), array('status' => 404)); } if (!$this->parent_controller->check_read_permission($parent)) { return new WP_Error('rest_forbidden', __('Sorry, you cannot view this post.'), array('status' => rest_authorization_required_code())); } $post_type = get_post_type_object($parent->post_type); if (!current_user_can($post_type->cap->delete_post, $parent->ID)) { return new WP_Error('rest_forbidden', __('Sorry, you cannot delete the meta for this post.'), array('status' => rest_authorization_required_code())); } return true; }
/** * Delete a single item. * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error */ public function delete_item($request) { $id = (int) $request['id']; $force = (bool) $request['force']; $post = get_post($id); if (empty($id) || empty($post->ID) || !in_array($post->post_type, $this->get_post_types())) { return new WP_Error("woocommerce_rest_{$this->post_type}_invalid_id", __('Invalid post id.', 'woocommerce'), array('status' => 404)); } $supports_trash = EMPTY_TRASH_DAYS > 0; /** * Filter whether an item is trashable. * * Return false to disable trash support for the item. * * @param boolean $supports_trash Whether the item type support trashing. * @param WP_Post $post The Post object being considered for trashing support. */ $supports_trash = apply_filters("woocommerce_rest_{$this->post_type}_trashable", $supports_trash, $post); if (!wc_rest_check_post_permissions($this->post_type, 'delete', $post->ID)) { return new WP_Error("woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf(__('Sorry, you are not allowed to delete %s.', 'woocommerce'), $this->post_type), array('status' => rest_authorization_required_code())); } $request->set_param('context', 'edit'); $response = $this->prepare_item_for_response($post, $request); // If we're forcing, then delete permanently. if ($force) { $result = wp_delete_post($id, true); } else { // If we don't support trashing for this type, error out. if (!$supports_trash) { return new WP_Error('woocommerce_rest_trash_not_supported', sprintf(__('The %s does not support trashing.', 'woocommerce'), $this->post_type), array('status' => 501)); } // Otherwise, only trash if we haven't already. if ('trash' === $post->post_status) { return new WP_Error('woocommerce_rest_already_trashed', sprintf(__('The %s has already been deleted.', 'woocommerce'), $this->post_type), array('status' => 410)); } // (Note that internally this falls through to `wp_delete_post` if // the trash is disabled.) $result = wp_trash_post($id); } if (!$result) { return new WP_Error('woocommerce_rest_cannot_delete', sprintf(__('The %s cannot be deleted.', 'woocommerce'), $this->post_type), array('status' => 500)); } /** * Fires after a single item is deleted or trashed via the REST API. * * @param object $post The deleted or trashed item. * @param WP_REST_Response $response The response data. * @param WP_REST_Request $request The request sent to the API. */ do_action("woocommerce_rest_delete_{$this->post_type}", $post, $response, $request); return $response; }