WooCommerce 3.5.4 and WordPress 5.0.3 REST API: Im

2019-08-11 23:32发布

问题:

I am using v2 of the REST API. This code worked fine on an older version of WordPress and WooCommerce. I cannot upload an image to a product.

The first error after the upgrade I got was:

array (
  'code' => 'woocommerce_product_image_upload_error',
  'message' => 'Invalid image: Sorry, this file type is not permitted for security reasons.',
  'data' => 
  array (
    'status' => 400,
  ),

Resolved by adding following in wp-config.php to the bottom of the file:

define('ALLOW_UNFILTERED_UPLOADS', true);

The 2nd error I cannot figure out. The image won't upload and leaves a ghost image where it was uploaded.

Code

<?php
require __DIR__ . '/vendor/autoload.php';

use Automattic\WooCommerce\Client;

$woocommerce = new Client(
    'http://localhost/wordpress', 
    'ck_44b92c00ea35e6cc59c89c29051bf67c22e0df3a', 
    'cs_dd833592a1ef7a00a82c1711fd455db2e4c5bd15',
    [
        'wp_api' => true,
        'version' => 'wc/v2',
    ]
);

$data['create'][] = array(
    'name' => 'TEST',
    'regular_price' => '4.50',
    'description' => 'TEST DESC',
    'type' => 'simple',
    'images' => array(
        array(
            'alt' => '',
            'name' => '',
            'src' => 'http://demo2.phppointofsale.com/PHP-Point-Of-Sale-Prev/index.php/app_files/view/1',
            'position' => 0,
        ),
    )
);


$response = $woocommerce->post('products/batch',$data);
$headers = $woocommerce->http->getResponse()->getHeaders();
var_dump($headers);
var_dump($response);

Response Data

array(13) {
  ["Date"]=>
  string(29) "Thu, 24 Jan 2019 18:22:16 GMT"
  ["Server"]=>
  string(6) "Apache"
  ["X-Powered-By"]=>
  string(9) "PHP/7.2.1"
  ["X-Robots-Tag"]=>
  string(7) "noindex"
  ["Link"]=>
  string(63) "<http://localhost/wordpress/wp-json/>; rel="https://api.w.org/""
  ["X-Content-Type-Options"]=>
  string(7) "nosniff"
  ["Access-Control-Expose-Headers"]=>
  string(27) "X-WP-Total, X-WP-TotalPages"
  ["Access-Control-Allow-Headers"]=>
  string(27) "Authorization, Content-Type"
  ["Expires"]=>
  string(29) "Wed, 11 Jan 1984 05:00:00 GMT"
  ["Cache-Control"]=>
  string(36) "no-cache, must-revalidate, max-age=0"
  ["Allow"]=>
  string(16) "POST, PUT, PATCH"
  ["Content-Length"]=>
  string(3) "139"
  ["Content-Type"]=>
  string(31) "application/json; charset=UTF-8"
}
array(1) {
  ["create"]=>
  array(1) {
    [0]=>
    array(2) {
      ["id"]=>
      int(0)
      ["error"]=>
      array(3) {
        ["code"]=>
        string(36) "woocommerce_product_invalid_image_id"
        ["message"]=>
        string(27) "#82 is an invalid image ID."
        ["data"]=>
        array(1) {
          ["status"]=>
          int(400)
        }
      }
    }
  }
}

Proof https://via.placeholder.com/350x150 is an image

cmuench@cmuench:~$ curl -I "https://via.placeholder.com/350x150";
HTTP/1.1 200 OK
Server: nginx/1.6.2
Date: Mon, 28 Jan 2019 14:07:22 GMT
Content-Type: image/png
Content-Length: 1253
Last-Modified: Sun, 06 Jan 2019 22:00:10 GMT
Connection: keep-alive
ETag: "5c327a6a-4e5"
Expires: Mon, 04 Feb 2019 14:07:22 GMT
Cache-Control: max-age=604800
X-Cache: L1
Accept-Ranges: bytes

http://demo2.phppointofsale.com/PHP-Point-Of-Sale-Prev/index.php/app_files/view/1

headers from actual files (not demo example). Same error as demo example

    header("Cache-Control: max-age=2592000");
    header('Expires: '.gmdate('D, d M Y H:i:s', strtotime('+1 month')).' GMT');
    header('Pragma: cache');
    header('Content-Disposition: inline; filename="'.$file_name.'"');
    header("Content-type: ".get_mime_by_extension($file->file_name));

回答1:

even the remote server returns "Content-Type: image/png", Wordpress's server side retrieval function did not get the file name because lack of the name in your rest request and no filename in the remote server response, which cause the internal wp_attachment_is_image() test failed. Try set the rest request with file name with proper file extension.

refer to the woocommerce source code: https://github.com/woocommerce/woocommerce/blob/00a93ae8f0b200b4def4aea4462fec9d1d5ea96c/includes/api/v2/class-wc-rest-products-v2-controller.php

and Wordpress code: https://core.trac.wordpress.org/browser/tags/5.0.3/src/wp-includes/post.php



回答2:

Just setup a similar environment, your code works, the problem lies with your image link, curl seems to get the url response as html rather than an image (https://via.placeholder.com/350x150). From the docs "src" is a string containing Image URL unfortunately the string you provide is NOT an image url.You'll just need to point to image files directly the code below works fine for me.

<?php
require __DIR__ . '/vendor/autoload.php';

use Automattic\WooCommerce\Client;

$woocommerce = new Client(
    'http://localhost/wordpress', 
    'ck_a3ec02fcd547837c384e43ee6989200cca8f6178', 
    'cs_f60e9ad5c93c9e3bd4adaabd4bd323edddb58f7b',
    [
        'wp_api' => true,
        'version' => 'wc/v2',
    ]
);

$data['create'][] = array(
    'name' => 'TEST',
    'regular_price' => '4.50',
    'description' => 'TEST DESC',
    'type' => 'simple',
    'images' => array(
        array(
            'src' => 'http://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2013/06/T_2_front.jpg',

        ),
    )
);


$response = $woocommerce->post('products/batch',$data);
$headers = $woocommerce->http->getResponse()->getHeaders();
var_dump($headers);
var_dump($response);