/**
  * Test we can update both description and title
  */
 public function test_update_both()
 {
     wp_set_current_user($this->editor_id);
     $request = new WP_REST_Request('POST', sprintf('/wp/v2/posts/%d', $this->post_id));
     $request->set_body_params(array('_yoast_wpseo_title' => '1 2 3', '_yoast_wpseo_metadesc' => '4 5 6'));
     $response = $this->server->dispatch($request);
     $this->assertNotInstanceOf('WP_Error', $response);
     $response = rest_ensure_response($response);
     $this->assertEquals(200, $response->get_status());
     $this->assertEquals('1 2 3', get_post_meta($this->post_id, '_yoast_wpseo_title', true));
     $this->assertEquals('4 5 6', get_post_meta($this->post_id, '_yoast_wpseo_metadesc', true));
 }
 /**
  * Ensure slashes aren't touched in data
  */
 public function test_update_meta_slashed()
 {
     wp_set_current_user($this->admin_id);
     $meta_id = add_comment_meta($this->approved_id, 'testkey', 'testvalue');
     $request = new WP_REST_Request('POST', sprintf('/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id));
     $request->set_body_params(array('key' => 'testkey', 'value' => "test slashed \\' value"));
     $this->server->dispatch($request);
     $meta = get_comment_meta($this->approved_id, 'testkey', false);
     $this->assertNotEmpty($meta);
     $this->assertCount(1, $meta);
     $this->assertEquals("test slashed \\' value", $meta[0]);
 }
Esempio n. 3
0
 /**
  * Test creating a Shipping Zone Method.
  * @since 2.7.0
  */
 public function test_create_method()
 {
     wp_set_current_user($this->user);
     $zone = $this->create_shipping_zone('Zone 1');
     $request = new WP_REST_Request('POST', '/wc/v1/shipping/zones/' . $zone->get_id() . '/methods');
     $request->set_body_params(array('method_id' => 'flat_rate', 'enabled' => false, 'order' => 2));
     $response = $this->server->dispatch($request);
     $data = $response->get_data();
     $this->assertFalse($data['enabled']);
     $this->assertEquals(2, $data['order']);
     $this->assertArrayHasKey('cost', $data['settings']);
     $this->assertEquals('0', $data['settings']['cost']['value']);
 }
Esempio n. 4
0
 public function test_additional_field_update_errors()
 {
     $schema = array('type' => 'integer', 'description' => 'Some integer of mine', 'enum' => array(1, 2, 3, 4), 'context' => array('view', 'edit'));
     register_rest_field('user', 'my_custom_int', array('schema' => $schema, 'get_callback' => array($this, 'additional_field_get_callback'), 'update_callback' => array($this, 'additional_field_update_callback')));
     wp_set_current_user(1);
     if (is_multisite()) {
         $current_user = wp_get_current_user(1);
         update_site_option('site_admins', array($current_user->user_login));
     }
     // Check for error on update.
     $request = new WP_REST_Request('POST', sprintf('/wp/v2/users/%d', self::$user));
     $request->set_body_params(array('my_custom_int' => 'returnError'));
     $response = $this->server->dispatch($request);
     $this->assertErrorResponse('rest_invalid_param', $response, 400);
     global $wp_rest_additional_fields;
     $wp_rest_additional_fields = array();
 }
Esempio n. 5
0
 /**
  * Test batch managing products.
  */
 public function test_products_batch()
 {
     wp_set_current_user($this->user);
     $product = WC_Helper_Product::create_simple_product();
     $product_2 = WC_Helper_Product::create_simple_product();
     $request = new WP_REST_Request('POST', '/wc/v1/products/batch');
     $request->set_body_params(array('update' => array(array('id' => $product->get_id(), 'description' => 'Updated description.')), 'delete' => array($product_2->get_id()), 'create' => array(array('sku' => 'DUMMY SKU BATCH TEST 1', 'regular_price' => '10', 'name' => 'Test Batch Create 1', 'type' => 'external', 'button_text' => 'Test Button'), array('sku' => 'DUMMY SKU BATCH TEST 2', 'regular_price' => '20', 'name' => 'Test Batch Create 2', 'type' => 'simple'))));
     $response = $this->server->dispatch($request);
     $data = $response->get_data();
     $this->assertContains('Updated description.', $data['update'][0]['description']);
     $this->assertEquals('DUMMY SKU BATCH TEST 1', $data['create'][0]['sku']);
     $this->assertEquals('DUMMY SKU BATCH TEST 2', $data['create'][1]['sku']);
     $this->assertEquals('Test Button', $data['create'][0]['button_text']);
     $this->assertEquals('external', $data['create'][0]['type']);
     $this->assertEquals('simple', $data['create'][1]['type']);
     $this->assertEquals($product_2->get_id(), $data['delete'][0]['id']);
     $request = new WP_REST_Request('GET', '/wc/v1/products');
     $response = $this->server->dispatch($request);
     $data = $response->get_data();
     $this->assertEquals(3, count($data));
     $product->delete(true);
     $product_2->delete(true);
 }
Esempio n. 6
0
 public function test_delete_value_custom_name()
 {
     add_post_meta(self::$post_id, 'test_custom_name', 'janet');
     $current = get_post_meta(self::$post_id, 'test_custom_name', true);
     $this->assertEquals('janet', $current);
     $this->grant_write_permission();
     $data = array('meta' => array('new_name' => null));
     $request = new WP_REST_Request('POST', sprintf('/wp/v2/posts/%d', self::$post_id));
     $request->set_body_params($data);
     $response = $this->server->dispatch($request);
     $this->assertEquals(200, $response->get_status());
     $meta = get_post_meta(self::$post_id, 'test_custom_name', false);
     $this->assertEmpty($meta);
 }
 public function test_get_additional_field_registration()
 {
     $schema = array('type' => 'integer', 'description' => 'Some integer of mine', 'enum' => array(1, 2, 3, 4), 'context' => array('view', 'edit'));
     register_api_field('user', 'my_custom_int', array('schema' => $schema, 'get_callback' => array($this, 'additional_field_get_callback'), 'update_callback' => array($this, 'additional_field_update_callback')));
     $request = new WP_REST_Request('OPTIONS', '/wp/v2/users');
     $response = $this->server->dispatch($request);
     $data = $response->get_data();
     $this->assertArrayHasKey('my_custom_int', $data['schema']['properties']);
     $this->assertEquals($schema, $data['schema']['properties']['my_custom_int']);
     wp_set_current_user(1);
     if (is_multisite()) {
         $current_user = wp_get_current_user(1);
         update_site_option('site_admins', array($current_user->user_login));
     }
     $request = new WP_REST_Request('GET', '/wp/v2/users/1');
     $response = $this->server->dispatch($request);
     $this->assertArrayHasKey('my_custom_int', $response->data);
     $request = new WP_REST_Request('POST', '/wp/v2/users/1');
     $request->set_body_params(array('my_custom_int' => 123));
     $response = $this->server->dispatch($request);
     $this->assertEquals(123, get_user_meta(1, 'my_custom_int', true));
     $request = new WP_REST_Request('POST', '/wp/v2/users');
     $request->set_body_params(array('my_custom_int' => 123, 'email' => '*****@*****.**', 'username' => 'abc123', 'password' => 'hello'));
     $response = $this->server->dispatch($request);
     $this->assertEquals(123, $response->data['my_custom_int']);
     global $wp_rest_additional_fields;
     $wp_rest_additional_fields = array();
 }
 /**
  * Ensure slashes aren't touched in data
  */
 public function test_update_meta_slashed()
 {
     $post_id = $this->factory->post->create();
     $meta_id = add_post_meta($post_id, 'testkey', 'testvalue');
     $data = array('key' => 'testkey', 'value' => "test slashed \\' value");
     $request = new WP_REST_Request('POST', sprintf('/wp/v2/posts/%d/meta/%d', $post_id, $meta_id));
     $request->set_body_params($data);
     $response = $this->server->dispatch($request);
     $this->assertNotInstanceOf('WP_Error', $response);
     $meta = get_post_meta($post_id, 'testkey', false);
     $this->assertNotEmpty($meta);
     $this->assertCount(1, $meta);
     $this->assertEquals("test slashed \\' value", $meta[0]);
 }
Esempio n. 9
0
 /**
  * Do a REST Request
  *
  * @param string $method
  * 
  */
 private function do_request($method, $route, $assoc_args)
 {
     if ('internal' === $this->scope) {
         $request = new \WP_REST_Request($method, $route);
         if (in_array($method, array('POST', 'PUT'))) {
             $request->set_body_params($assoc_args);
         } else {
             foreach ($assoc_args as $key => $value) {
                 $request->set_param($key, $value);
             }
         }
         $response = rest_do_request($request);
         if ($error = $response->as_error()) {
             WP_CLI::error($error);
         }
         return array($response->get_status(), $response->get_data(), $response->get_headers());
     } else {
         if ('http' === $this->scope) {
             $response = Utils\http_request($method, rtrim($this->api_url, '/') . $route, $assoc_args);
             $body = json_decode($response->body, true);
             if ($response->status_code >= 400) {
                 if (!empty($body['message'])) {
                     WP_CLI::error($body['message'] . ' ' . json_encode(array('status' => $response->status_code)));
                 } else {
                     switch ($response->status_code) {
                         case 404:
                             WP_CLI::error("No {$this->name} found.");
                             break;
                         default:
                             WP_CLI::error('Could not complete request.');
                             break;
                     }
                 }
             }
             return array($response->status_code, json_decode($response->body, true), $response->headers);
         }
     }
     WP_CLI::error('Invalid scope for REST command.');
 }
Esempio n. 10
0
 /**
  * Test batch managing product reviews.
  */
 public function test_orders_batch()
 {
     wp_set_current_user($this->user);
     $order1 = WC_Helper_Order::create_order();
     $order2 = WC_Helper_Order::create_order();
     $order3 = WC_Helper_Order::create_order();
     $request = new WP_REST_Request('POST', '/wc/v1/orders/batch');
     $request->set_body_params(array('update' => array(array('id' => $order1->get_id(), 'payment_method' => 'updated')), 'delete' => array($order2->get_id(), $order3->get_id())));
     $response = $this->server->dispatch($request);
     $data = $response->get_data();
     $this->assertEquals('updated', $data['update'][0]['payment_method']);
     $this->assertEquals($order2->get_id(), $data['delete'][0]['id']);
     $this->assertEquals($order3->get_id(), $data['delete'][1]['id']);
     $request = new WP_REST_Request('GET', '/wc/v1/orders');
     $response = $this->server->dispatch($request);
     $data = $response->get_data();
     $this->assertEquals(1, count($data));
     wp_delete_post($order1->get_id(), true);
     wp_delete_post($order2->get_id(), true);
     wp_delete_post($order3->get_id(), true);
 }
Esempio n. 11
0
 /**
  * Test validation of image_width.
  *
  * @since  2.7.0
  */
 public function test_validation_image_width()
 {
     wp_set_current_user($this->user);
     $response = $this->server->dispatch(new WP_REST_Request('GET', sprintf('/wc/v1/settings/%s/%s', 'products', 'shop_thumbnail_image_size')));
     $setting = $response->get_data();
     $this->assertEquals(array('width' => 180, 'height' => 180, 'crop' => true), $setting['value']);
     // test bogus
     $request = new WP_REST_Request('PUT', sprintf('/wc/v1/settings/%s/%s', 'products', 'shop_thumbnail_image_size'));
     $request->set_body_params(array('value' => array('width' => 400, 'height' => 200, 'crop' => 'asdasdasd')));
     $response = $this->server->dispatch($request);
     $setting = $response->get_data();
     $this->assertEquals(array('width' => 400, 'height' => 200, 'crop' => true), $setting['value']);
     $request = new WP_REST_Request('PUT', sprintf('/wc/v1/settings/%s/%s', 'products', 'shop_thumbnail_image_size'));
     $request->set_body_params(array('value' => array('width' => 200, 'height' => 100, 'crop' => false)));
     $response = $this->server->dispatch($request);
     $setting = $response->get_data();
     $this->assertEquals(array('width' => 200, 'height' => 100, 'crop' => false), $setting['value']);
 }
 /**
  * Bulk create, update and delete items.
  *
  * @since  2.7.0
  * @param WP_REST_Request $request Full details about the request.
  * @return array Of WP_Error or WP_REST_Response.
  */
 public function batch_items($request)
 {
     // Get the request params.
     $items = array_filter($request->get_params());
     /*
      * Since our batch settings update is group-specific and matches based on the route,
      * we inject the URL parameters (containing group) into the batch items
      */
     if (!empty($items['update'])) {
         $to_update = array();
         foreach ($items['update'] as $item) {
             $to_update[] = array_merge($request->get_url_params(), $item);
         }
         $request = new WP_REST_Request($request->get_method());
         $request->set_body_params(array('update' => $to_update));
     }
     return parent::batch_items($request);
 }
    /**
     * Do a REST Request
     *
     * @param string $method
     *
     */
    private function do_request($method, $route, $assoc_args)
    {
        if (!defined('REST_REQUEST')) {
            define('REST_REQUEST', true);
        }
        $request = new WP_REST_Request($method, $route);
        if (in_array($method, array('POST', 'PUT'))) {
            $request->set_body_params($assoc_args);
        } else {
            foreach ($assoc_args as $key => $value) {
                $request->set_param($key, $value);
            }
        }
        if (defined('SAVEQUERIES') && SAVEQUERIES) {
            $original_queries = is_array($GLOBALS['wpdb']->queries) ? array_keys($GLOBALS['wpdb']->queries) : array();
        }
        $response = rest_do_request($request);
        if (defined('SAVEQUERIES') && SAVEQUERIES) {
            $performed_queries = array();
            foreach ((array) $GLOBALS['wpdb']->queries as $key => $query) {
                if (in_array($key, $original_queries)) {
                    continue;
                }
                $performed_queries[] = $query;
            }
            usort($performed_queries, function ($a, $b) {
                if ($a[1] === $b[1]) {
                    return 0;
                }
                return $a[1] > $b[1] ? -1 : 1;
            });
            $query_count = count($performed_queries);
            $query_total_time = 0;
            foreach ($performed_queries as $query) {
                $query_total_time += $query[1];
            }
            $slow_query_message = '';
            if ($performed_queries && 'wc' === WP_CLI::get_config('debug')) {
                $slow_query_message .= '. Ordered by slowness, the queries are:' . PHP_EOL;
                foreach ($performed_queries as $i => $query) {
                    $i++;
                    $bits = explode(', ', $query[2]);
                    $backtrace = implode(', ', array_slice($bits, 13));
                    $seconds = round($query[1], 6);
                    $slow_query_message .= <<<EOT
{$i}:
- {$seconds} seconds
- {$backtrace}
- {$query[0]}
EOT;
                    $slow_query_message .= PHP_EOL;
                }
            } elseif ('wc' !== WP_CLI::get_config('debug')) {
                $slow_query_message = '. Use --debug=wc to see all queries.';
            }
            $query_total_time = round($query_total_time, 6);
            WP_CLI::debug("wc command executed {$query_count} queries in {$query_total_time} seconds{$slow_query_message}", 'wc');
        }
        if ($error = $response->as_error()) {
            WP_CLI::error($error);
        }
        return array($response->get_status(), $response->get_data(), $response->get_headers());
    }
Esempio n. 14
0
 /**
  * Test batch operations on coupons.
  * @since 2.7.0
  */
 public function test_batch_coupon()
 {
     wp_set_current_user($this->user);
     $coupon_1 = WC_Helper_Coupon::create_coupon('dummycoupon-1');
     $coupon_2 = WC_Helper_Coupon::create_coupon('dummycoupon-2');
     $coupon_3 = WC_Helper_Coupon::create_coupon('dummycoupon-3');
     $coupon_4 = WC_Helper_Coupon::create_coupon('dummycoupon-4');
     $request = new WP_REST_Request('POST', '/wc/v1/coupons/batch');
     $request->set_body_params(array('update' => array(array('id' => $coupon_1->get_id(), 'amount' => '5.15')), 'delete' => array($coupon_2->get_id(), $coupon_3->get_id()), 'create' => array(array('code' => 'new-coupon', 'amount' => '11.00'))));
     $response = $this->server->dispatch($request);
     $data = $response->get_data();
     $this->assertEquals('5.15', $data['update'][0]['amount']);
     $this->assertEquals('11.00', $data['create'][0]['amount']);
     $this->assertEquals('new-coupon', $data['create'][0]['code']);
     $this->assertEquals($coupon_2->get_id(), $data['delete'][0]['id']);
     $this->assertEquals($coupon_3->get_id(), $data['delete'][1]['id']);
     $request = new WP_REST_Request('GET', '/wc/v1/coupons');
     $response = $this->server->dispatch($request);
     $data = $response->get_data();
     $this->assertEquals(3, count($data));
 }
 /**
  * Ensure slashes aren't touched in data
  */
 public function test_update_meta_slashed()
 {
     $meta_id = add_term_meta($this->category_id, 'testkey', 'testvalue');
     $request = new WP_REST_Request('POST', sprintf('/wp/v2/categories/%d/meta/%d', $this->category_id, $meta_id));
     $request->set_body_params(array('key' => 'testkey', 'value' => "test slashed \\' value"));
     $this->server->dispatch($request);
     $meta = get_term_meta($this->category_id, 'testkey', false);
     $this->assertNotEmpty($meta);
     $this->assertCount(1, $meta);
     $this->assertEquals("test slashed \\' value", $meta[0]);
 }
 public function test_additional_field_update_errors()
 {
     $schema = array('type' => 'integer', 'description' => 'Some integer of mine', 'enum' => array(1, 2, 3, 4), 'context' => array('view', 'edit'));
     register_rest_field('tag', 'my_custom_int', array('schema' => $schema, 'get_callback' => array($this, 'additional_field_get_callback'), 'update_callback' => array($this, 'additional_field_update_callback')));
     wp_set_current_user(self::$administrator);
     $tag_id = $this->factory->tag->create();
     // Check for error on update.
     $request = new WP_REST_Request('POST', sprintf('/wp/v2/tags/%d', $tag_id));
     $request->set_body_params(array('my_custom_int' => 'returnError'));
     $response = $this->server->dispatch($request);
     $this->assertErrorResponse('rest_invalid_param', $response, 400);
     global $wp_rest_additional_fields;
     $wp_rest_additional_fields = array();
 }
 /**
  * Ensure slashes aren't touched in data
  */
 public function test_update_meta_slashed()
 {
     wp_set_current_user($this->user);
     $this->allow_user_to_manage_multisite();
     $meta_id = add_user_meta($this->user, 'testkey', 'testvalue');
     $data = array('key' => 'testkey', 'value' => "test slashed \\' value");
     $request = new WP_REST_Request('POST', sprintf('/wp/v2/users/%d/meta/%d', $this->user, $meta_id));
     $request->set_body_params($data);
     $this->server->dispatch($request);
     $meta = get_user_meta($this->user, 'testkey', false);
     $this->assertNotEmpty($meta);
     $this->assertCount(1, $meta);
     $this->assertEquals("test slashed \\' value", $meta[0]);
 }
Esempio n. 18
0
 /**
  * Test customer batch endpoint.
  *
  * @since 2.7.0
  */
 public function test_batch_customer()
 {
     wp_set_current_user(1);
     $customer_1 = WC_Helper_Customer::create_customer('test_batch_customer', 'test123', '*****@*****.**');
     $customer_2 = WC_Helper_Customer::create_customer('test_batch_customer2', 'test123', '*****@*****.**');
     $customer_3 = WC_Helper_Customer::create_customer('test_batch_customer3', 'test123', '*****@*****.**');
     $customer_4 = WC_Helper_Customer::create_customer('test_batch_customer4', 'test123', '*****@*****.**');
     $request = new WP_REST_Request('POST', '/wc/v1/customers/batch');
     $request->set_body_params(array('update' => array(array('id' => $customer_1->get_id(), 'last_name' => 'McTest')), 'delete' => array($customer_2->get_id(), $customer_3->get_id()), 'create' => array(array('username' => 'newuser', 'password' => 'test123', 'email' => '*****@*****.**'))));
     $response = $this->server->dispatch($request);
     $data = $response->get_data();
     $this->assertEquals('McTest', $data['update'][0]['last_name']);
     $this->assertEquals('newuser', $data['create'][0]['username']);
     $this->assertEmpty($data['create'][0]['last_name']);
     $this->assertEquals($customer_2->get_id(), $data['delete'][0]['id']);
     $this->assertEquals($customer_3->get_id(), $data['delete'][1]['id']);
     $request = new WP_REST_Request('GET', '/wc/v1/customers');
     $response = $this->server->dispatch($request);
     $data = $response->get_data();
     $this->assertEquals(3, count($data));
 }
 /**
  * Test batch managing product variations.
  */
 public function test_product_variations_batch()
 {
     wp_set_current_user($this->user);
     $product = WC_Helper_Product::create_variation_product();
     $children = $product->get_children();
     $request = new WP_REST_Request('POST', '/wc/v1/products/' . $product->get_id() . '/variations/batch');
     $request->set_body_params(array('update' => array(array('id' => $children[0], 'description' => 'Updated description.', 'image' => array(array('position' => 0, 'src' => 'https://cldup.com/Dr1Bczxq4q.png', 'alt' => 'test upload image')))), 'delete' => array(array('id' => $children[1])), 'create' => array(array('sku' => 'DUMMY SKU VARIABLE MEDIUM', 'regular_price' => '12', 'description' => 'A medium size.', 'attributes' => array(array('name' => 'pa_size', 'option' => 'medium'))))));
     $response = $this->server->dispatch($request);
     $data = $response->get_data();
     $this->assertContains('Updated description.', $data['update'][0]['description']);
     $this->assertEquals('DUMMY SKU VARIABLE MEDIUM', $data['create'][0]['sku']);
     $this->assertEquals('medium', $data['create'][0]['attributes'][0]['option']);
     $this->assertEquals($children[1], $data['delete'][0]['id']);
     $request = new WP_REST_Request('GET', '/wc/v1/products/' . $product->get_id() . '/variations');
     $response = $this->server->dispatch($request);
     $data = $response->get_data();
     $this->assertEquals(2, count($data));
     $product->delete(true);
 }
Esempio n. 20
0
 /**
  * Tests our classic setting registration to make sure settings added for WP-Admin are available over the API.
  *
  * @since  2.7.0
  */
 public function test_classic_settings()
 {
     wp_set_current_user($this->user);
     // Make sure the group is properly registered
     $response = $this->server->dispatch(new WP_REST_Request('GET', '/wc/v1/settings/products'));
     $data = $response->get_data();
     $this->assertTrue(is_array($data));
     $this->assertContains(array('id' => 'woocommerce_downloads_require_login', 'label' => 'Access Restriction', 'description' => 'Downloads require login', 'type' => 'checkbox', 'default' => 'no', 'tip' => 'This setting does not apply to guest purchases.', 'value' => 'no', '_links' => array('self' => array(array('href' => rest_url('/wc/v1/settings/products/woocommerce_downloads_require_login'))), 'collection' => array(array('href' => rest_url('/wc/v1/settings/products'))))), $data);
     // test get single
     $response = $this->server->dispatch(new WP_REST_Request('GET', '/wc/v1/settings/products/woocommerce_dimension_unit'));
     $data = $response->get_data();
     $this->assertEquals('cm', $data['default']);
     // test update
     $request = new WP_REST_Request('PUT', sprintf('/wc/v1/settings/%s/%s', 'products', 'woocommerce_dimension_unit'));
     $request->set_body_params(array('value' => 'yd'));
     $response = $this->server->dispatch($request);
     $data = $response->get_data();
     $this->assertEquals('yd', $data['value']);
     $this->assertEquals('yd', get_option('woocommerce_dimension_unit'));
 }
 /**
  * Test updating a payment gateway with an invalid id.
  *
  * @since 2.7.0
  */
 public function test_update_payment_gateway_invalid_id()
 {
     wp_set_current_user($this->user);
     $request = new WP_REST_Request('POST', '/wc/v1/payment_gateways/totally_fake_method');
     $request->set_body_params(array('enabled' => true));
     $response = $this->server->dispatch($request);
     $this->assertEquals(404, $response->get_status());
 }
Esempio n. 22
0
 /**
  * Handle serving an API request
  *
  * Matches the current server URI to a route and runs the first matching
  * callback then outputs a JSON representation of the returned value.
  *
  * @uses WP_REST_Server::dispatch()
  */
 public function serve_request($path = null)
 {
     $content_type = isset($_GET['_jsonp']) ? 'application/javascript' : 'application/json';
     $this->send_header('Content-Type', $content_type . '; charset=' . get_option('blog_charset'));
     // Mitigate possible JSONP Flash attacks
     // http://miki.it/blog/2014/7/8/abusing-jsonp-with-rosetta-flash/
     $this->send_header('X-Content-Type-Options', 'nosniff');
     // Proper filter for turning off the JSON API. It is on by default.
     $enabled = apply_filters('rest_enabled', true);
     $jsonp_enabled = apply_filters('rest_jsonp_enabled', true);
     if (!$enabled) {
         echo $this->json_error('rest_disabled', __('The REST API is disabled on this site.'), 404);
         return false;
     }
     if (isset($_GET['_jsonp'])) {
         if (!$jsonp_enabled) {
             echo $this->json_error('rest_callback_disabled', __('JSONP support is disabled on this site.'), 400);
             return false;
         }
         // Check for invalid characters (only alphanumeric allowed)
         if (!is_string($_GET['_jsonp']) || preg_match('/[^\\w\\.]/', $_GET['_jsonp'])) {
             echo $this->json_error('rest_callback_invalid', __('The JSONP callback function is invalid.'), 400);
             return false;
         }
     }
     if (empty($path)) {
         if (isset($_SERVER['PATH_INFO'])) {
             $path = $_SERVER['PATH_INFO'];
         } else {
             $path = '/';
         }
     }
     $request = new WP_REST_Request($_SERVER['REQUEST_METHOD'], $path);
     $request->set_query_params($_GET);
     $request->set_body_params($_POST);
     $request->set_file_params($_FILES);
     $request->set_headers($this->get_headers($_SERVER));
     $request->set_body($this->get_raw_data());
     /**
      * HTTP method override for clients that can't use PUT/PATCH/DELETE. First, we check
      * $_GET['_method']. If that is not set, we check for the HTTP_X_HTTP_METHOD_OVERRIDE
      * header.
      */
     if (isset($_GET['_method'])) {
         $request->set_method($_GET['_method']);
     } elseif (isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'])) {
         $request->set_method($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']);
     }
     $result = $this->check_authentication();
     if (!is_wp_error($result)) {
         $result = $this->dispatch($request);
     }
     // Normalize to either WP_Error or WP_REST_Response...
     $result = rest_ensure_response($result);
     // ...then convert WP_Error across
     if (is_wp_error($result)) {
         $result = $this->error_to_response($result);
     }
     /**
      * Allow modifying the response before returning
      *
      * @param WP_HTTP_ResponseInterface $result  Result to send to the client. Usually a WP_REST_Response
      * @param WP_REST_Server            $this    Server instance
      * @param WP_REST_Request           $request Request used to generate the response
      */
     $result = apply_filters('rest_post_dispatch', rest_ensure_response($result), $this, $request);
     // Wrap the response in an envelope if asked for
     if (isset($_GET['_envelope'])) {
         $result = $this->envelope_response($result, isset($_GET['_embed']));
     }
     // Send extra data from response objects
     $headers = $result->get_headers();
     $this->send_headers($headers);
     $code = $result->get_status();
     $this->set_status($code);
     /**
      * Allow sending the request manually
      *
      * If `$served` is true, the result will not be sent to the client.
      *
      * This is a filter rather than an action, since this is designed to be
      * re-entrant if needed.
      *
      * @param bool                      $served  Whether the request has already been served
      * @param WP_HTTP_ResponseInterface $result  Result to send to the client. Usually a WP_REST_Response
      * @param WP_REST_Request           $request Request used to generate the response
      * @param WP_REST_Server            $this    Server instance
      */
     $served = apply_filters('rest_pre_serve_request', false, $result, $request, $this);
     if (!$served) {
         if ('HEAD' === $request->get_method()) {
             return;
         }
         // Embed links inside the request
         $result = $this->response_to_data($result, isset($_GET['_embed']));
         $result = wp_json_encode($result);
         $json_error_message = $this->get_json_last_error();
         if ($json_error_message) {
             $json_error_obj = new WP_Error('rest_encode_error', $json_error_message, array('status' => 500));
             $result = $this->error_to_response($json_error_obj);
             $result = wp_json_encode($result->data[0]);
         }
         if (isset($_GET['_jsonp'])) {
             // Prepend '/**/' to mitigate possible JSONP Flash attacks
             // http://miki.it/blog/2014/7/8/abusing-jsonp-with-rosetta-flash/
             echo '/**/' . $_GET['_jsonp'] . '(' . $result . ')';
         } else {
             echo $result;
         }
     }
 }
 /**
  * Bulk create, update and delete items.
  *
  * @param WP_REST_Request $request Full details about the request.
  * @return array Of WP_Error or WP_REST_Response.
  */
 public function batch_items($request)
 {
     /** @var WP_REST_Server $wp_rest_server */
     global $wp_rest_server;
     // Get the request params.
     $items = array_filter($request->get_params());
     $response = array();
     // Check batch limit.
     $limit = $this->check_batch_limit($items);
     if (is_wp_error($limit)) {
         return $limit;
     }
     if (!empty($items['create'])) {
         foreach ($items['create'] as $item) {
             $_item = new WP_REST_Request('POST');
             // Default parameters.
             $defaults = array();
             $schema = $this->get_public_item_schema();
             foreach ($schema['properties'] as $arg => $options) {
                 if (isset($options['default'])) {
                     $defaults[$arg] = $options['default'];
                 }
             }
             $_item->set_default_params($defaults);
             // Set request parameters.
             $_item->set_body_params($item);
             $_response = $this->create_item($_item);
             if (is_wp_error($_response)) {
                 $response['create'][] = array('id' => 0, 'error' => array('code' => $_response->get_error_code(), 'message' => $_response->get_error_message(), 'data' => $_response->get_error_data()));
             } else {
                 $response['create'][] = $wp_rest_server->response_to_data($_response, '');
             }
         }
     }
     if (!empty($items['update'])) {
         foreach ($items['update'] as $item) {
             $_item = new WP_REST_Request('PUT');
             $_item->set_body_params($item);
             $_response = $this->update_item($_item);
             if (is_wp_error($_response)) {
                 $response['update'][] = array('id' => $item['id'], 'error' => array('code' => $_response->get_error_code(), 'message' => $_response->get_error_message(), 'data' => $_response->get_error_data()));
             } else {
                 $response['update'][] = $wp_rest_server->response_to_data($_response, '');
             }
         }
     }
     if (!empty($items['delete'])) {
         foreach ($items['delete'] as $id) {
             $_item = new WP_REST_Request('DELETE');
             $_item->set_query_params(array('id' => $id, 'force' => true));
             $_response = $this->delete_item($_item);
             if (is_wp_error($_response)) {
                 $response['delete'][] = array('id' => $id, 'error' => array('code' => $_response->get_error_code(), 'message' => $_response->get_error_message(), 'data' => $_response->get_error_data()));
             } else {
                 $response['delete'][] = $wp_rest_server->response_to_data($_response, '');
             }
         }
     }
     return $response;
 }
Esempio n. 24
0
 /**
  * Test batch managing product reviews.
  */
 public function test_product_reviews_batch()
 {
     wp_set_current_user($this->user);
     $product = WC_Helper_Product::create_simple_product();
     $review_1_id = WC_Helper_Product::create_product_review($product->get_id());
     $review_2_id = WC_Helper_Product::create_product_review($product->get_id());
     $review_3_id = WC_Helper_Product::create_product_review($product->get_id());
     $review_4_id = WC_Helper_Product::create_product_review($product->get_id());
     $request = new WP_REST_Request('POST', '/wc/v1/products/' . $product->get_id() . '/reviews/batch');
     $request->set_body_params(array('update' => array(array('id' => $review_1_id, 'review' => 'Updated review.')), 'delete' => array(array('id' => $review_2_id), array('id' => $review_3_id)), 'create' => array(array('review' => 'New review.', 'name' => 'Justin', 'email' => '*****@*****.**'))));
     $response = $this->server->dispatch($request);
     $data = $response->get_data();
     $this->assertEquals('Updated review.', $data['update'][0]['review']);
     $this->assertEquals('New review.', $data['create'][0]['review']);
     $this->assertEquals($review_2_id, $data['delete'][0]['id']);
     $this->assertEquals($review_3_id, $data['delete'][1]['id']);
     $request = new WP_REST_Request('GET', '/wc/v1/products/' . $product->get_id() . '/reviews');
     $response = $this->server->dispatch($request);
     $data = $response->get_data();
     $this->assertEquals(3, count($data));
 }
 /**
  * Bulk create, update and delete items.
  *
  * @since  2.7.0
  * @param WP_REST_Request $request Full details about the request.
  * @return array Of WP_Error or WP_REST_Response.
  */
 public function batch_items($request)
 {
     $items = array_filter($request->get_params());
     $params = $request->get_url_params();
     $product_id = $params['product_id'];
     $body_params = array();
     foreach (array('update', 'create', 'delete') as $batch_type) {
         if (!empty($items[$batch_type])) {
             $injected_items = array();
             foreach ($items[$batch_type] as $item) {
                 $injected_items[] = array_merge(array('product_id' => $product_id), $item);
             }
             $body_params[$batch_type] = $injected_items;
         }
     }
     $request = new WP_REST_Request($request->get_method());
     $request->set_body_params($body_params);
     return parent::batch_items($request);
 }
Esempio n. 26
0
 public function test_update_page_parent_zero()
 {
     $page_id1 = $this->factory->post->create(array('post_type' => 'page'));
     $page_id2 = $this->factory->post->create(array('post_type' => 'page', 'post_parent' => $page_id1));
     wp_set_current_user(self::$editor_id);
     $request = new WP_REST_Request('PUT', sprintf('/wp/v2/pages/%d', $page_id2));
     $request->set_body_params(array('parent' => 0));
     $response = $this->server->dispatch($request);
     $new_data = $response->get_data();
     $this->assertEquals(0, $new_data['parent']);
 }
 /**
  * Handles serving an API request.
  *
  * Matches the current server URI to a route and runs the first matching
  * callback then outputs a JSON representation of the returned value.
  *
  * @since 4.4.0
  * @access public
  *
  * @see WP_REST_Server::dispatch()
  *
  * @param string $path Optional. The request route. If not set, `$_SERVER['PATH_INFO']` will be used.
  *                     Default null.
  * @return false|null Null if not served and a HEAD request, false otherwise.
  */
 public function serve_request($path = null)
 {
     $content_type = isset($_GET['_jsonp']) ? 'application/javascript' : 'application/json';
     $this->send_header('Content-Type', $content_type . '; charset=' . get_option('blog_charset'));
     $this->send_header('X-Robots-Tag', 'noindex');
     $api_root = get_rest_url();
     if (!empty($api_root)) {
         $this->send_header('Link', '<' . esc_url_raw($api_root) . '>; rel="https://api.w.org/"');
     }
     /*
      * Mitigate possible JSONP Flash attacks.
      *
      * https://miki.it/blog/2014/7/8/abusing-jsonp-with-rosetta-flash/
      */
     $this->send_header('X-Content-Type-Options', 'nosniff');
     $this->send_header('Access-Control-Expose-Headers', 'X-WP-Total, X-WP-TotalPages');
     $this->send_header('Access-Control-Allow-Headers', 'Authorization');
     /**
      * Send nocache headers on authenticated requests.
      *
      * @since 4.4.0
      *
      * @param bool $rest_send_nocache_headers Whether to send no-cache headers.
      */
     $send_no_cache_headers = apply_filters('rest_send_nocache_headers', is_user_logged_in());
     if ($send_no_cache_headers) {
         foreach (wp_get_nocache_headers() as $header => $header_value) {
             $this->send_header($header, $header_value);
         }
     }
     /**
      * Filters whether the REST API is enabled.
      *
      * @since 4.4.0
      *
      * @param bool $rest_enabled Whether the REST API is enabled. Default true.
      */
     $enabled = apply_filters('rest_enabled', true);
     /**
      * Filters whether jsonp is enabled.
      *
      * @since 4.4.0
      *
      * @param bool $jsonp_enabled Whether jsonp is enabled. Default true.
      */
     $jsonp_enabled = apply_filters('rest_jsonp_enabled', true);
     $jsonp_callback = null;
     if (!$enabled) {
         echo $this->json_error('rest_disabled', __('The REST API is disabled on this site.'), 404);
         return false;
     }
     if (isset($_GET['_jsonp'])) {
         if (!$jsonp_enabled) {
             echo $this->json_error('rest_callback_disabled', __('JSONP support is disabled on this site.'), 400);
             return false;
         }
         $jsonp_callback = $_GET['_jsonp'];
         if (!wp_check_jsonp_callback($jsonp_callback)) {
             echo $this->json_error('rest_callback_invalid', __('The JSONP callback function is invalid.'), 400);
             return false;
         }
     }
     if (empty($path)) {
         if (isset($_SERVER['PATH_INFO'])) {
             $path = $_SERVER['PATH_INFO'];
         } else {
             $path = '/';
         }
     }
     $request = new WP_REST_Request($_SERVER['REQUEST_METHOD'], $path);
     $request->set_query_params(wp_unslash($_GET));
     $request->set_body_params(wp_unslash($_POST));
     $request->set_file_params($_FILES);
     $request->set_headers($this->get_headers(wp_unslash($_SERVER)));
     $request->set_body($this->get_raw_data());
     /*
      * HTTP method override for clients that can't use PUT/PATCH/DELETE. First, we check
      * $_GET['_method']. If that is not set, we check for the HTTP_X_HTTP_METHOD_OVERRIDE
      * header.
      */
     if (isset($_GET['_method'])) {
         $request->set_method($_GET['_method']);
     } elseif (isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'])) {
         $request->set_method($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']);
     }
     $result = $this->check_authentication();
     if (!is_wp_error($result)) {
         $result = $this->dispatch($request);
     }
     // Normalize to either WP_Error or WP_REST_Response...
     $result = rest_ensure_response($result);
     // ...then convert WP_Error across.
     if (is_wp_error($result)) {
         $result = $this->error_to_response($result);
     }
     /**
      * Filters the API response.
      *
      * Allows modification of the response before returning.
      *
      * @since 4.4.0
      * @since 4.5.0 Applied to embedded responses.
      *
      * @param WP_HTTP_Response $result  Result to send to the client. Usually a WP_REST_Response.
      * @param WP_REST_Server   $this    Server instance.
      * @param WP_REST_Request  $request Request used to generate the response.
      */
     $result = apply_filters('rest_post_dispatch', rest_ensure_response($result), $this, $request);
     // Wrap the response in an envelope if asked for.
     if (isset($_GET['_envelope'])) {
         $result = $this->envelope_response($result, isset($_GET['_embed']));
     }
     // Send extra data from response objects.
     $headers = $result->get_headers();
     $this->send_headers($headers);
     $code = $result->get_status();
     $this->set_status($code);
     /**
      * Filters whether the request has already been served.
      *
      * Allow sending the request manually - by returning true, the API result
      * will not be sent to the client.
      *
      * @since 4.4.0
      *
      * @param bool             $served  Whether the request has already been served.
      *                                           Default false.
      * @param WP_HTTP_Response $result  Result to send to the client. Usually a WP_REST_Response.
      * @param WP_REST_Request  $request Request used to generate the response.
      * @param WP_REST_Server   $this    Server instance.
      */
     $served = apply_filters('rest_pre_serve_request', false, $result, $request, $this);
     if (!$served) {
         if ('HEAD' === $request->get_method()) {
             return null;
         }
         // Embed links inside the request.
         $result = $this->response_to_data($result, isset($_GET['_embed']));
         $result = wp_json_encode($result);
         $json_error_message = $this->get_json_last_error();
         if ($json_error_message) {
             $json_error_obj = new WP_Error('rest_encode_error', $json_error_message, array('status' => 500));
             $result = $this->error_to_response($json_error_obj);
             $result = wp_json_encode($result->data[0]);
         }
         if ($jsonp_callback) {
             // Prepend '/**/' to mitigate possible JSONP Flash attacks
             // https://miki.it/blog/2014/7/8/abusing-jsonp-with-rosetta-flash/
             echo '/**/' . $jsonp_callback . '(' . $result . ')';
         } else {
             echo $result;
         }
     }
     return null;
 }
 public function test_get_additional_field_registration()
 {
     $schema = array('type' => 'integer', 'description' => 'Some integer of mine', 'enum' => array(1, 2, 3, 4), 'context' => array('view', 'edit'));
     register_api_field('comment', 'my_custom_int', array('schema' => $schema, 'get_callback' => array($this, 'additional_field_get_callback'), 'update_callback' => array($this, 'additional_field_update_callback')));
     $request = new WP_REST_Request('OPTIONS', '/wp/v2/comments');
     $response = $this->server->dispatch($request);
     $data = $response->get_data();
     $this->assertArrayHasKey('my_custom_int', $data['schema']['properties']);
     $this->assertEquals($schema, $data['schema']['properties']['my_custom_int']);
     $request = new WP_REST_Request('GET', '/wp/v2/comments/' . $this->approved_id);
     $response = $this->server->dispatch($request);
     $this->assertArrayHasKey('my_custom_int', $response->data);
     $request = new WP_REST_Request('POST', '/wp/v2/comments/' . $this->approved_id);
     $request->set_body_params(array('my_custom_int' => 123, 'content' => 'abc'));
     wp_set_current_user(1);
     $response = $this->server->dispatch($request);
     $this->assertEquals(123, get_comment_meta($this->approved_id, 'my_custom_int', true));
     $request = new WP_REST_Request('POST', '/wp/v2/comments');
     $request->set_body_params(array('my_custom_int' => 123, 'title' => 'hello', 'post' => $this->post_id));
     $response = $this->server->dispatch($request);
     $this->assertEquals(123, $response->data['my_custom_int']);
     global $wp_rest_additional_fields;
     $wp_rest_additional_fields = array();
 }
 public function test_additional_field_update_errors()
 {
     $schema = array('type' => 'integer', 'description' => 'Some integer of mine', 'enum' => array(1, 2, 3, 4), 'context' => array('view', 'edit'));
     register_rest_field('attachment', 'my_custom_int', array('schema' => $schema, 'get_callback' => array($this, 'additional_field_get_callback'), 'update_callback' => array($this, 'additional_field_update_callback')));
     wp_set_current_user(self::$editor_id);
     $attachment_id = $this->factory->attachment->create_object($this->test_file, 0, array('post_mime_type' => 'image/jpeg', 'post_excerpt' => 'A sample caption', 'post_author' => self::$editor_id));
     // Check for error on update.
     $request = new WP_REST_Request('POST', sprintf('/wp/v2/media/%d', $attachment_id));
     $request->set_body_params(array('my_custom_int' => 'returnError'));
     $response = $this->server->dispatch($request);
     $this->assertErrorResponse('rest_invalid_param', $response, 400);
     global $wp_rest_additional_fields;
     $wp_rest_additional_fields = array();
 }
Esempio n. 30
0
 /**
  * Test Shipping Zone update endpoint with a bad zone ID.
  * @since 2.7.0
  */
 public function test_update_shipping_zone_invalid_id()
 {
     wp_set_current_user($this->user);
     $request = new WP_REST_Request('PUT', '/wc/v1/shipping/zones/1');
     $request->set_body_params(array('name' => 'Zone Test', 'order' => 2));
     $response = $this->server->dispatch($request);
     $this->assertEquals(404, $response->get_status());
 }