What WooCommerce API should I use on the server?

2019-03-31 21:25发布

I am writing a script to bulk-change product properties such as price, weight and dimension. I need to run the script directly on the server where WordPress (4.7.2) and WooCommerce (2.6.13) are installed. The options I could think of don't seem ideal to me:

  1. WooCommerce non-REST API would be my obvious choice, but it is relegated into a scary legacy folder which smells of deprecated.
  2. WooCommerce REST API (link) seems overkill: why should I go through authentication and use HTTP when I am already on the server and can just use PHP?
  3. Acting on the database via update_post_meta() seems error-prone and hard to maintain given the many relations between WooCommerce product properties; just look here at the amount of logic one has to duplicate just to change a product's price!
  4. WP-CLI could work but AFAIK it would not be as flexible as PHP script; in any case, it is REST-powered since v3.0, so I guess point 2 will apply here, too.

I feel like I am missing something, please help me otherwise my brain will explode :-D

2条回答
看我几分像从前
2楼-- · 2019-03-31 21:53

Well , according to your excellent answer , I just can add that you can use the wordpress api (v2.wp-api.org) itself to run this as a function so it will be protected and you can also add authentication to execute just in case you care about security. Like I normally like to add 2 more plugins for normal setup : api tool box (to change the api route -> wp-json) and wp options and edit the option files for my functions.

查看更多
放我归山
3楼-- · 2019-03-31 21:57

It turns out that you can use the REST API on the server without neither authenticating nor performing an HTTP request: you just need to build a WP_REST_Request object and pass it directly to the API.

Example: Show a Product

Here's an example PHP script which will print information on a product based on its ID, using the REST API. The script should be placed in the WordPress folder and executed in a browser; the product ID is given as a query parameter, ex: http://www.yourwebsite.com/script.php?id=123.

<?php
/* Load WordPress */
require('wp-load.php');

/* Extract the product ID from the query string */
$product_id = isset( $_GET['id'] ) ? $_GET['id'] : false;

if ( $product_id ) {

    /* Create an API controller */
    $api = new WC_REST_Products_Controller();

    /* Build the request to create a new product */
    $request = new WP_REST_Request ('POST', '', '');
    $request['id'] = $product_id;

    /* Execute the request */
    $response = $api->get_item( $request );

    /* Print to screen the response from the API.
    The product information is in $response->data  */
    print_r( $response );

    /* Also print to screen the product object as seen by WooCommerce */
    print_r( wc_get_product( $product_id ) );

}

Example: Create a Product

The next script will create a new product. The product's deatails should be entered directly in the script, in the set_body_params() function. For a list of the allowed fields, just print any product's data using the previous script.

/* Load WordPress */
require('wp-load.php');

/* Create an API controller */
$api = new WC_REST_Products_Controller();

/* Build the request to create a new product */
$request = new WP_REST_Request ('POST', '', '');
$request->set_body_params( array (
    'name' => 'New Product',
    'slug' => 'new-product',
    'type' => 'simple',
    'status' => 'publish',
    'regular_price' => 60,
    'sale_price' => 40,
));

/* Execute the request */
$response = $api->create_item( $request );

/* Print to screen the response from the API */
print_r( $response );

/* Also print to screen the product object as seen by WooCommerce */
print_r( wc_get_product( $response->data['id'] ) );

Some basic security measures

It's not a good idea to leave executable PHP scripts on your website. I would rather incorporate them in a plugin, and make them accessible only to authorized users. To achieve that, it might be useful to prepend the following code to the scripts:

/* Load WordPress. Replace the /cms part in the path if
WordPress is installed in a folder of its own. */
try {
    require($_SERVER['DOCUMENT_ROOT'] . '/cms/wp-load.php');
} catch (Exception $e) {
    require($_SERVER['DOCUMENT_ROOT'] . '/wp-load.php');
}

/* Restrict usage of this script to admins */
if ( ! current_user_can('administrator') ) {
  die;
}
查看更多
登录 后发表回答