public function test_get_items_orderby()
 {
     wp_set_object_terms($this->post_id, array('Banana', 'Carrot', 'Apple'), 'post_tag');
     $request = new WP_REST_Request('GET', sprintf('/wp/v2/posts/%d/terms/tag', $this->post_id));
     $request->set_param('orderby', 'term_order');
     $response = $this->server->dispatch($request);
     $data = $response->get_data();
     $this->assertEquals('Banana', $data[0]['name']);
     $this->assertEquals('Carrot', $data[1]['name']);
     $this->assertEquals('Apple', $data[2]['name']);
     $request = new WP_REST_Request('GET', sprintf('/wp/v2/posts/%d/terms/tag', $this->post_id));
     $request->set_param('orderby', 'name');
     $request->set_param('order', 'asc');
     $response = $this->server->dispatch($request);
     $data = $response->get_data();
     $this->assertEquals('Apple', $data[0]['name']);
     $this->assertEquals('Banana', $data[1]['name']);
     $this->assertEquals('Carrot', $data[2]['name']);
     $request = new WP_REST_Request('GET', sprintf('/wp/v2/posts/%d/terms/tag', $this->post_id));
     $request->set_param('orderby', 'name');
     $request->set_param('order', 'desc');
     $response = $this->server->dispatch($request);
     $data = $response->get_data();
     $this->assertEquals('Carrot', $data[0]['name']);
     $this->assertEquals('Banana', $data[1]['name']);
     $this->assertEquals('Apple', $data[2]['name']);
 }
 public function test_get_items()
 {
     $request = new WP_REST_Request('GET', '/wp/v2/users');
     $request->set_param('context', 'view');
     $response = $this->server->dispatch($request);
     $this->assertEquals(200, $response->get_status());
 }
 public function test_get_taxonomies_with_types()
 {
     $request = new WP_REST_Request('GET', '/wp/v2/taxonomies');
     $request->set_param('post_type', 'post');
     $response = $this->server->dispatch($request);
     $this->check_taxonomies_for_type_response('post', $response);
 }
Ejemplo n.º 4
0
 function test_rest_pre_serve_request_headers()
 {
     if (!function_exists('xdebug_get_headers')) {
         $this->markTestSkipped('xdebug is required for this test');
     }
     $post = $this->factory()->post->create_and_get(array('post_title' => 'Hello World'));
     $request = new WP_REST_Request('GET', '/oembed/1.0/embed');
     $request->set_param('url', get_permalink($post->ID));
     $request->set_param('format', 'xml');
     $server = new WP_REST_Server();
     $response = $server->dispatch($request);
     $output = get_echo('_oembed_rest_pre_serve_request', array(true, $response, $request, $server));
     $this->assertNotEmpty($output);
     $headers = xdebug_get_headers();
     $this->assertTrue(in_array('Content-Type: text/xml; charset=' . get_option('blog_charset'), $headers));
 }
 /**
  * @test
  * it should return true if current user can edit post
  */
 public function it_should_return_true_if_current_user_can_edit_post()
 {
     $post_id = $this->factory()->post->create();
     wp_set_current_user(1);
     $sut = $this->make_instance();
     $supported_actions = $sut->supported_actions();
     $request = new \WP_REST_Request('create', '/some-path');
     $request->set_param('post_id', $post_id);
     $out = $sut->verify_auth($request, reset($supported_actions));
     $this->assertTrue($out);
 }
Ejemplo n.º 6
0
 /**
  * Test HTTP headers set by the rest_pre_serve_request method.
  */
 function test_rest_pre_serve_request_headers()
 {
     if (!function_exists('xdebug_get_headers')) {
         $this->markTestSkipped('xdebug is required for this test');
     }
     require_once dirname(__FILE__) . '/../vendor/json-rest-api/plugin.php';
     require_once dirname(__FILE__) . '/../includes/class-wp-rest-oembed-controller.php';
     $user = $this->factory->user->create_and_get(array('display_name' => 'John Doe'));
     $post = $this->factory->post->create_and_get(array('post_author' => $user->ID, 'post_title' => 'Hello World'));
     $request = new WP_REST_Request('GET', '/wp/v2/oembed');
     $request->set_param('url', get_permalink($post->ID));
     $request->set_param('format', 'xml');
     $server = new WP_REST_Server();
     $response = $server->dispatch($request);
     ob_start();
     _oembed_rest_pre_serve_request(true, $response, $request, $server);
     $output = ob_get_clean();
     $this->assertNotEmpty($output);
     $headers = xdebug_get_headers();
     $this->assertTrue(in_array('Content-Type: text/xml; charset=' . get_option('blog_charset'), $headers));
 }
 /**
  * Get all graph data items
  * @param WP_REST_Request $request The current request
  * @return Array|WP_Error
  */
 public function get_items($request)
 {
     $result = array();
     // Fetch all skills
     $request->set_param('per_page', -1);
     $allSkills = parent::get_items($request);
     // Filter all skills to only return the ones tagged as starting skills
     foreach ($allSkills->data as $skill) {
         if ($skill['starting_skill']) {
             $result[] = $skill;
         }
     }
     return $result;
 }
 /**
  * Create a single Shipping Zone.
  *
  * @param WP_REST_Request $request Full details about the request.
  * @return WP_REST_Request|WP_Error
  */
 public function create_item($request)
 {
     $zone = new WC_Shipping_Zone(null);
     if (!is_null($request->get_param('name'))) {
         $zone->set_zone_name($request->get_param('name'));
     }
     if (!is_null($request->get_param('order'))) {
         $zone->set_zone_order($request->get_param('order'));
     }
     $zone->create();
     if ($zone->get_id() !== 0) {
         $request->set_param('id', $zone->get_id());
         $response = $this->get_item($request);
         $response->set_status(201);
         $response->header('Location', rest_url(sprintf('/%s/%s/%d', $this->namespace, $this->rest_base, $zone->get_id())));
         return $response;
     } else {
         return new WP_Error('woocommerce_rest_shipping_zone_not_created', __("Resource cannot be created. Check to make sure 'order' and 'name' are present.", 'woocommerce'), array('status' => 500));
     }
 }
 /**
  * Register's all endpoints as commands once WP and WC have all loaded.
  */
 public static function after_wp_load()
 {
     global $wp_rest_server;
     $wp_rest_server = new WP_REST_Server();
     do_action('rest_api_init', $wp_rest_server);
     $request = new WP_REST_Request('GET', '/');
     $request->set_param('context', 'help');
     $response = $wp_rest_server->dispatch($request);
     $response_data = $response->get_data();
     if (empty($response_data)) {
         return;
     }
     // Loop through all of our endpoints and register any valid WC endpoints.
     foreach ($response_data['routes'] as $route => $route_data) {
         // Only register WC endpoints
         if (substr($route, 0, 4) !== '/wc/') {
             continue;
         }
         // Only register endpoints with schemas
         if (empty($route_data['schema']['title'])) {
             WP_CLI::debug(sprintf(__('No schema title found for %s, skipping REST command registration.', 'woocommerce'), $route), 'wc');
             continue;
         }
         // Ignore batch endpoints
         if ('batch' === $route_data['schema']['title']) {
             continue;
         }
         // Disable specific endpoints
         $route_pieces = explode('/', $route);
         $endpoint_piece = str_replace('/wc/' . $route_pieces[2] . '/', '', $route);
         if (in_array($endpoint_piece, self::$disabled_endpoints)) {
             continue;
         }
         self::register_route_commands(new WC_CLI_REST_Command($route_data['schema']['title'], $route, $route_data['schema']), $route, $route_data);
     }
 }
Ejemplo n.º 10
0
 public function test_delete_user_reassign_passed_as_0_reassigns_author()
 {
     $user_id = $this->factory->user->create();
     $this->allow_user_to_manage_multisite();
     wp_set_current_user(self::$user);
     $test_post = $this->factory->post->create(array('post_author' => $user_id));
     $request = new WP_REST_Request('DELETE', sprintf('/wp/v2/users/%d', $user_id));
     $request['force'] = true;
     $request->set_param('reassign', 0);
     $response = $this->server->dispatch($request);
     // Not implemented in multisite.
     if (is_multisite()) {
         $this->assertErrorResponse('rest_cannot_delete', $response, 501);
         return;
     }
     $test_post = get_post($test_post);
     $this->assertEquals(0, $test_post->post_author);
 }
 /**
  * Delete a single term from a taxonomy
  *
  * @param WP_REST_Request $request Full details about the request
  * @return WP_REST_Response|WP_Error
  */
 public function delete_item($request)
 {
     $force = isset($request['force']) ? (bool) $request['force'] : false;
     // We don't support trashing for this type, error out
     if (!$force) {
         return new WP_Error('rest_trash_not_supported', __('Terms do not support trashing.'), array('status' => 501));
     }
     $term = get_term((int) $request['id'], $this->taxonomy);
     $request->set_param('context', 'view');
     $response = $this->prepare_item_for_response($term, $request);
     $data = $response->get_data();
     $data = array('data' => $data, 'deleted' => true);
     $response->set_data($data);
     $retval = wp_delete_term($term->term_id, $term->taxonomy);
     if (!$retval) {
         return new WP_Error('rest_cannot_delete', __('The term cannot be deleted.'), array('status' => 500));
     }
     /**
      * Fires after a single term is deleted via the REST API.
      *
      * @param WP_Term         $term    The deleted term.
      * @param array           $data    The response data.
      * @param WP_REST_Request $request The request sent to the API.
      */
     do_action("rest_delete_{$this->taxonomy}", $term, $data, $request);
     return $response;
 }
Ejemplo n.º 12
0
 public function test_products_filter_post_status()
 {
     wp_set_current_user($this->user);
     for ($i = 0; $i < 8; $i++) {
         $product = WC_Helper_Product::create_simple_product();
         if (0 === $i % 2) {
             wp_update_post(array('ID' => $product->get_id(), 'post_status' => 'draft'));
         }
     }
     // Test filtering with filter[post_status]=publish
     $request = new WP_REST_Request('GET', '/wc/v1/products');
     $request->set_param('filter', array('post_status' => 'publish'));
     $response = $this->server->dispatch($request);
     $products = $response->get_data();
     $this->assertEquals(4, count($products));
     foreach ($products as $product) {
         $this->assertEquals('publish', $product['status']);
     }
     // Test filtering with filter[post_status]=draft
     $request = new WP_REST_Request('GET', '/wc/v1/products');
     $request->set_param('filter', array('post_status' => 'draft'));
     $response = $this->server->dispatch($request);
     $products = $response->get_data();
     $this->assertEquals(4, count($products));
     foreach ($products as $product) {
         $this->assertEquals('draft', $product['status']);
     }
     // Test filtering with status=publish
     $request = new WP_REST_Request('GET', '/wc/v1/products');
     $request->set_param('status', 'publish');
     $response = $this->server->dispatch($request);
     $products = $response->get_data();
     $this->assertEquals(4, count($products));
     foreach ($products as $product) {
         $this->assertEquals('publish', $product['status']);
     }
     // Test filtering with status=draft
     $request = new WP_REST_Request('GET', '/wc/v1/products');
     $request->set_param('status', 'draft');
     $response = $this->server->dispatch($request);
     $products = $response->get_data();
     $this->assertEquals(4, count($products));
     foreach ($products as $product) {
         $this->assertEquals('draft', $product['status']);
     }
     // Test filtering with status=draft and filter[post_status]=publish
     // filter[post_status]=publish should win
     $request = new WP_REST_Request('GET', '/wc/v1/products');
     $request->set_param('status', 'draft');
     $request->set_param('filter', array('post_status' => 'publish'));
     $response = $this->server->dispatch($request);
     $products = $response->get_data();
     $this->assertEquals(4, count($products));
     foreach ($products as $product) {
         $this->assertEquals('publish', $product['status']);
     }
     // Test filtering with no filters - which should return 'any' (all 8)
     $request = new WP_REST_Request('GET', '/wc/v1/products');
     $response = $this->server->dispatch($request);
     $products = $response->get_data();
     $this->assertEquals(8, count($products));
 }
 /**
  * Delete a single tax.
  *
  * @param WP_REST_Request $request Full details about the request.
  * @return WP_Error|WP_REST_Response
  */
 public function delete_item($request)
 {
     global $wpdb;
     $id = (int) $request['id'];
     $force = isset($request['force']) ? (bool) $request['force'] : false;
     // We don't support trashing for this type, error out.
     if (!$force) {
         return new WP_Error('woocommerce_rest_trash_not_supported', __('Taxes do not support trashing.', 'woocommerce'), array('status' => 501));
     }
     $tax = WC_Tax::_get_tax_rate($id, OBJECT);
     if (empty($id) || empty($tax)) {
         return new WP_Error('woocommerce_rest_invalid_id', __('Invalid resource ID.', 'woocommerce'), array('status' => 400));
     }
     $request->set_param('context', 'edit');
     $response = $this->prepare_item_for_response($tax, $request);
     WC_Tax::_delete_tax_rate($id);
     if (0 === $wpdb->rows_affected) {
         return new WP_Error('woocommerce_rest_cannot_delete', __('The resource cannot be deleted.', 'woocommerce'), array('status' => 500));
     }
     /**
      * Fires after a tax is deleted via the REST API.
      *
      * @param stdClass         $tax      The tax data.
      * @param WP_REST_Response $response The response returned from the API.
      * @param WP_REST_Request  $request  The request sent to the API.
      */
     do_action('woocommerce_rest_delete_tax', $tax, $response, $request);
     return $response;
 }
 public function test_delete_item()
 {
     $post_id = $this->factory->post->create(array('post_title' => 'Deleted post'));
     wp_set_current_user(self::$editor_id);
     $request = new WP_REST_Request('DELETE', sprintf('/wp/v2/posts/%d', $post_id));
     $request->set_param('force', 'false');
     $response = $this->server->dispatch($request);
     $this->assertNotInstanceOf('WP_Error', $response);
     $this->assertEquals(200, $response->get_status());
     $data = $response->get_data();
     $this->assertEquals('Deleted post', $data['title']['raw']);
     $this->assertEquals('trash', $data['status']);
 }
 /**
  * Delete a single customer.
  *
  * @param WP_REST_Request $request Full details about the request.
  * @return WP_Error|WP_REST_Response
  */
 public function delete_item($request)
 {
     $id = (int) $request['id'];
     $reassign = isset($request['reassign']) ? absint($request['reassign']) : null;
     $force = isset($request['force']) ? (bool) $request['force'] : false;
     // We don't support trashing for this type, error out.
     if (!$force) {
         return new WP_Error('woocommerce_rest_trash_not_supported', __('Customers do not support trashing.', 'woocommerce'), array('status' => 501));
     }
     $customer = get_userdata($id);
     if (!$customer) {
         return new WP_Error('woocommerce_rest_invalid_id', __('Invalid resource id.', 'woocommerce'), array('status' => 400));
     }
     if (!empty($reassign)) {
         if ($reassign === $id || !get_userdata($reassign)) {
             return new WP_Error('woocommerce_rest_customer_invalid_reassign', __('Invalid resource id for reassignment.', 'woocommerce'), array('status' => 400));
         }
     }
     $request->set_param('context', 'edit');
     $response = $this->prepare_item_for_response($customer, $request);
     /** Include admin customer functions to get access to wp_delete_user() */
     require_once ABSPATH . 'wp-admin/includes/user.php';
     $result = wp_delete_user($id, $reassign);
     if (!$result) {
         return new WP_Error('woocommerce_rest_cannot_delete', __('The resource cannot be deleted.', 'woocommerce'), array('status' => 500));
     }
     /**
      * Fires after a customer is deleted via the REST API.
      *
      * @param WP_User          $customer The customer data.
      * @param WP_REST_Response $response The response returned from the API.
      * @param WP_REST_Request  $request  The request sent to the API.
      */
     do_action('woocommerce_rest_delete_customer', $customer, $response, $request);
     return $response;
 }
 /**
  * Setting an item to "null" will essentially restore it to it's default value.
  */
 public function test_update_item_with_null()
 {
     update_option('posts_per_page', 9);
     wp_set_current_user($this->administrator);
     $request = new WP_REST_Request('PUT', '/wp/v2/settings');
     $request->set_param('posts_per_page', null);
     $response = $this->server->dispatch($request);
     $data = $response->get_data();
     $this->assertEquals(200, $response->get_status());
     $this->assertEquals(10, $data['posts_per_page']);
 }
Ejemplo n.º 17
0
 /**
  * Test deleting a Shipping Zone Method.
  * @since 2.7.0
  */
 public function test_delete_method()
 {
     wp_set_current_user($this->user);
     $zone = $this->create_shipping_zone('Zone 1');
     $instance_id = $zone->add_shipping_method('flat_rate');
     $methods = $zone->get_shipping_methods();
     $method = $methods[$instance_id];
     $request = new WP_REST_Request('DELETE', '/wc/v1/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id);
     $request->set_param('force', true);
     $response = $this->server->dispatch($request);
     $this->assertEquals(200, $response->get_status());
 }
 /**
  * Test update item.
  */
 function test_update_item()
 {
     wp_set_current_user($this->factory()->user->create(array('role' => 'administrator')));
     $post = get_post($this->snapshot_by_status['publish']);
     $request = new \WP_REST_Request('PUT', '/wp/v2/customize_snapshots/' . $post->ID);
     $request->set_param('content', array('blogname' => array('value' => 'test')));
     $response = $this->server->dispatch($request);
     $this->assertErrorResponse('invalid-method', $response);
 }
 /**
  * Delete a single term from a taxonomy
  *
  * @param WP_REST_Request $request Full details about the request
  * @return WP_REST_Response|WP_Error
  */
 public function delete_item($request)
 {
     // Get the actual term_id
     $term = get_term_by('term_taxonomy_id', (int) $request['id'], $this->taxonomy);
     $get_request = new WP_REST_Request('GET', rest_url('wp/v2/terms/' . $this->get_taxonomy_base($term->taxonomy) . '/' . (int) $request['id']));
     $get_request->set_param('context', 'view');
     $response = $this->prepare_item_for_response($term, $get_request);
     $data = $response->get_data();
     $data = array('data' => $data, 'deleted' => true);
     $response->set_data($data);
     $retval = wp_delete_term($term->term_id, $term->taxonomy);
     if (!$retval) {
         return new WP_Error('rest_cannot_delete', __('The term cannot be deleted.'), array('status' => 500));
     }
     return $response;
 }
 /**
  * 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;
 }
 /**
  * Update (execute) a tool.
  * @param  WP_REST_Request $request
  * @return WP_Error|WP_REST_Response
  */
 public function update_item($request)
 {
     $tools = $this->get_tools();
     if (empty($tools[$request['id']])) {
         return new WP_Error('woocommerce_rest_system_status_tool_invalid_id', __('Invalid tool ID.', 'woocommerce'), array('status' => 404));
     }
     $tool = $tools[$request['id']];
     $tool = array('id' => $request['id'], 'name' => $tool['name'], 'action' => $tool['button'], 'description' => $tool['desc']);
     $execute_return = $this->execute_tool($request['id']);
     $tool = array_merge($tool, $execute_return);
     $request->set_param('context', 'edit');
     $response = $this->prepare_item_for_response($tool, $request);
     return rest_ensure_response($response);
 }
 /**
  * Delete a single webhook.
  *
  * @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 = isset($request['force']) ? (bool) $request['force'] : false;
     // We don't support trashing for this type, error out.
     if (!$force) {
         return new WP_Error('woocommerce_rest_trash_not_supported', __('Webhooks do not support trashing.', 'woocommerce'), array('status' => 501));
     }
     $post = get_post($id);
     if (empty($id) || empty($post->ID) || $this->post_type !== $post->post_type) {
         return new WP_Error("woocommerce_rest_{$this->post_type}_invalid_id", __('Invalid post ID.', 'woocommerce'), array('status' => 404));
     }
     $request->set_param('context', 'edit');
     $response = $this->prepare_item_for_response($post, $request);
     $result = wp_delete_post($id, true);
     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);
     // Clear cache.
     delete_transient('woocommerce_webhook_ids');
     return $response;
 }
 /**
  * Check if a given request has access to create a post/term relationship.
  *
  * @param  WP_REST_Request $request Full details about the request.
  * @return bool|WP_Error
  */
 public function create_item_permissions_check($request)
 {
     $post_request = new WP_REST_Request();
     $post_request->set_param('id', $request['post_id']);
     $post_check = $this->posts_controller->update_item_permissions_check($post_request);
     if (!$post_check || is_wp_error($post_check)) {
         return $post_check;
     }
     return true;
 }
Ejemplo n.º 24
0
 /**
  * Test getting submissions
  *
  * @since 6.0
  */
 public function testGetSubmissions()
 {
     $form = $this->_createForm();
     $this->_createSubmission($form->data['id']);
     $this->_createSubmission($form->data['id']);
     $this->_createSubmission($form->data['id']);
     $this->_createSubmission($form->data['id']);
     $request = new WP_REST_Request();
     $request->set_param('id', $form->data['id']);
     $get_submissions_result = $this->api->get_submissions($request);
     $submissions = $get_submissions_result->data;
     $this->assertEquals(4, count($submissions));
     foreach ($submissions as $submission_object) {
         $submission = get_post($submission_object['id']);
         $this->assertTrue(!empty($submission));
         $data = get_post_meta($submission_object['id'], 'ccf_submission_data', true);
         $this->assertTrue(!empty($data));
     }
 }
 /**
  * Delete a single order note.
  *
  * @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 = isset($request['force']) ? (bool) $request['force'] : false;
     // We don't support trashing for this type, error out.
     if (!$force) {
         return new WP_Error('woocommerce_rest_trash_not_supported', __('Webhooks do not support trashing.', 'woocommerce'), array('status' => 501));
     }
     $order = get_post((int) $request['order_id']);
     if (empty($order->post_type) || $this->post_type !== $order->post_type) {
         return new WP_Error('woocommerce_rest_order_invalid_id', __('Invalid order id.', 'woocommerce'), array('status' => 404));
     }
     $note = get_comment($id);
     if (empty($id) || empty($note) || intval($note->comment_post_ID) !== intval($order->ID)) {
         return new WP_Error('woocommerce_rest_invalid_id', __('Invalid resource id.', 'woocommerce'), array('status' => 404));
     }
     $request->set_param('context', 'edit');
     $response = $this->prepare_item_for_response($note, $request);
     $result = wp_delete_comment($note->comment_ID, true);
     if (!$result) {
         return new WP_Error('woocommerce_rest_cannot_delete', sprintf(__('The %s cannot be deleted.', 'woocommerce'), 'order_note'), array('status' => 500));
     }
     /**
      * Fires after a order note is deleted or trashed via the REST API.
      *
      * @param WP_Comment       $note     The deleted or trashed order note.
      * @param WP_REST_Response $response The response data.
      * @param WP_REST_Request  $request  The request sent to the API.
      */
     do_action('woocommerce_rest_delete_order_note', $note, $response, $request);
     return $response;
 }
 /**
  * Delete a comment.
  *
  * @param  WP_REST_Request $request Full details about the request.
  * @return WP_Error|WP_REST_Response
  */
 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));
     }
     /**
      * Filter whether a comment is trashable.
      *
      * Return false to disable trash support for the post.
      *
      * @param boolean $supports_trash Whether the post type support trashing.
      * @param WP_Post $comment        The comment object being considered for trashing support.
      */
     $supports_trash = apply_filters('rest_comment_trashable', EMPTY_TRASH_DAYS > 0, $comment);
     $get_request = new WP_REST_Request('GET', rest_url('/wp/v2/comments/' . $id));
     $get_request->set_param('context', 'edit');
     $response = $this->prepare_item_for_response($comment, $get_request);
     if ($force) {
         $result = wp_delete_comment($comment->comment_ID, true);
         $status = 'deleted';
     } else {
         // If we don't support trashing for this type, error out
         if (!$supports_trash) {
             return new WP_Error('rest_trash_not_supported', __('The comment does not support trashing.'), array('status' => 501));
         }
         $result = wp_trash_comment($comment->comment_ID);
         $status = 'trashed';
     }
     $data = $response->get_data();
     $data = array('data' => $data, $status => true);
     $response->set_data($data);
     if (!$result) {
         return new WP_Error('rest_cannot_delete', __('The comment cannot be deleted.'), array('status' => 500));
     }
     /**
      * Fires after a comment is deleted via the REST API.
      *
      * @param object          $comment The deleted comment data.
      * @param array           $data    Delete status data.
      * @param WP_REST_Request $request The request sent to the API.
      */
     do_action('rest_delete_comment', $comment, $data, $request);
     return $response;
 }
 public function verify_attachment_roundtrip($input = array(), $expected_output = array())
 {
     // Create the post
     $request = new WP_REST_Request('POST', '/wp/v2/media');
     $request->set_header('Content-Type', 'image/jpeg');
     $request->set_header('Content-Disposition', 'attachment; filename=canola.jpg');
     $request->set_body(file_get_contents($this->test_file));
     foreach ($input as $name => $value) {
         $request->set_param($name, $value);
     }
     $response = $this->server->dispatch($request);
     $this->assertEquals(201, $response->get_status());
     $actual_output = $response->get_data();
     // Remove <p class="attachment"> from rendered description
     // see https://core.trac.wordpress.org/ticket/38679
     $content = $actual_output['description']['rendered'];
     $content = explode("\n", trim($content));
     if (preg_match('/^<p class="attachment">/', $content[0])) {
         $content = implode("\n", array_slice($content, 1));
         $actual_output['description']['rendered'] = $content;
     }
     // Compare expected API output to actual API output
     $this->assertEquals($expected_output['title']['raw'], $actual_output['title']['raw']);
     $this->assertEquals($expected_output['title']['rendered'], trim($actual_output['title']['rendered']));
     $this->assertEquals($expected_output['description']['raw'], $actual_output['description']['raw']);
     $this->assertEquals($expected_output['description']['rendered'], trim($actual_output['description']['rendered']));
     $this->assertEquals($expected_output['caption']['raw'], $actual_output['caption']['raw']);
     $this->assertEquals($expected_output['caption']['rendered'], trim($actual_output['caption']['rendered']));
     // Compare expected API output to WP internal values
     $post = get_post($actual_output['id']);
     $this->assertEquals($expected_output['title']['raw'], $post->post_title);
     $this->assertEquals($expected_output['description']['raw'], $post->post_content);
     $this->assertEquals($expected_output['caption']['raw'], $post->post_excerpt);
     // Update the post
     $request = new WP_REST_Request('PUT', sprintf('/wp/v2/media/%d', $actual_output['id']));
     foreach ($input as $name => $value) {
         $request->set_param($name, $value);
     }
     $response = $this->server->dispatch($request);
     $this->assertEquals(200, $response->get_status());
     $actual_output = $response->get_data();
     // Remove <p class="attachment"> from rendered description
     // see https://core.trac.wordpress.org/ticket/38679
     $content = $actual_output['description']['rendered'];
     $content = explode("\n", trim($content));
     if (preg_match('/^<p class="attachment">/', $content[0])) {
         $content = implode("\n", array_slice($content, 1));
         $actual_output['description']['rendered'] = $content;
     }
     // Compare expected API output to actual API output
     $this->assertEquals($expected_output['title']['raw'], $actual_output['title']['raw']);
     $this->assertEquals($expected_output['title']['rendered'], trim($actual_output['title']['rendered']));
     $this->assertEquals($expected_output['description']['raw'], $actual_output['description']['raw']);
     $this->assertEquals($expected_output['description']['rendered'], trim($actual_output['description']['rendered']));
     $this->assertEquals($expected_output['caption']['raw'], $actual_output['caption']['raw']);
     $this->assertEquals($expected_output['caption']['rendered'], trim($actual_output['caption']['rendered']));
     // Compare expected API output to WP internal values
     $post = get_post($actual_output['id']);
     $this->assertEquals($expected_output['title']['raw'], $post->post_title);
     $this->assertEquals($expected_output['description']['raw'], $post->post_content);
     $this->assertEquals($expected_output['caption']['raw'], $post->post_excerpt);
 }
 /**
  * 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/&lt;product_id&gt;/variations/&lt;id&gt; 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;
 }
 public function test_get_namespace_index()
 {
     $server = new WP_REST_Server();
     $server->register_route('test/example', '/test/example/some-route', array(array('methods' => WP_REST_Server::READABLE, 'callback' => '__return_true'), array('methods' => WP_REST_Server::DELETABLE, 'callback' => '__return_true')));
     $server->register_route('test/another', '/test/another/route', array(array('methods' => WP_REST_Server::READABLE, 'callback' => '__return_false')));
     $request = new WP_REST_Request();
     $request->set_param('namespace', 'test/example');
     $index = rest_ensure_response($server->get_namespace_index($request));
     $data = $index->get_data();
     // Check top-level.
     $this->assertEquals('test/example', $data['namespace']);
     $this->assertArrayHasKey('routes', $data);
     // Check we have the route we expect...
     $this->assertArrayHasKey('/test/example/some-route', $data['routes']);
     // ...and none we don't.
     $this->assertArrayNotHasKey('/test/another/route', $data['routes']);
 }
 public function test_update_item_parent_non_hierarchical_taxonomy()
 {
     wp_set_current_user($this->administrator);
     $term = get_term_by('id', $this->factory->tag->create(), 'post_tag');
     $request = new WP_REST_Request('POST', '/wp/v2/terms/tag/' . $term->term_taxonomy_id);
     $request->set_param('parent', 9999);
     $response = $this->server->dispatch($request);
     $this->assertErrorResponse('rest_taxonomy_not_hierarchical', $response, 400);
 }