简体   繁体   中英

How to initialize a POST and a PUT method from inside a Wordpress custom endpoint

I am creating a custom endpoint in wordpress, which should do the following: 1. Create the path (done) 2. call a function, which: 2.1. Gets all the products from WooCommerce and stores them in an array (done) 2.2. Compares the products on WooCommerce with products from an external database and if there is any difference in data, get updated (PUT) by the data from the external DB 2.3. If some products exist on the external DB but do not exist on WooCommerce, create them on WooCommerce (POST)

I have managed to get all the data from WooCommerce via wc_get_products ($args) but I cannot find how to write the PUT and the POST method to update or create products. If I use Automatic/WooCommerce to push or put products from a standalone file (not from the custom endpoint) works, but if I keep the Automatic/WooCommerce on the custom endpoint it tells me the following:

Failed to connect to localhost port 8000: Connection refused in /var/www/html/wp-content/plugins/wl-api/vendor/automattic/woocommerce/src/WooCommerce/HttpClient/HttpClient.php on line 417 

which makes total sense because from the custom endpoint I am already connected to WooCommerce and the Automatic/WooCommerce would attempt to connect again. So are there any methods like wc_get_products but for PUT and PUSH?

//CUSTOM ENDPOINT PHP FILE
add_action('rest_api_init', 'customEndpoint');

function customEndpoint() {
    register_rest_route('endpoint', '/transfer', array(
        'methods' => 'GET',
        'callback' => 'get_data',
    ));
}
function get_data() {
    include "updateOrCreate.php";
}

//updateOrCreate.php
require 'vendor/autoload.php';
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

require 'vendor/guzzlehttp/guzzle/src/Client.php';
use Automattic\WooCommerce;
//-----------Connect to the External DB----------
$baseUrl=...;
$externalClient = new GuzzleHttp\Client();
$res = $externalClient->request('GET', $baseUrl, [
    "query" => ['fields' => $fields, 'aktiv' => true],
    'auth' => ['...', '...']
]);
$articles = json_decode($res->getBody());

//-----------Connect to WooCommerce DB
$wooKey= "...";
$wooSecret= "...";
$wooCommerceBaseUrl = "http://localhost:8000";
$wooCommerceClient = new WooCommerce\Client($wooCommerceBaseUrl,
$wooKey, $wooSecret,
[
    'wp_api' => true,
    'version' => 'wc/v3',
]
);
//GET all products from WooCommerce
$args = array(
'status' => 'publish',
'limit' => -1,
);  
$wooExistingProducts = wc_get_products($args);



$productsForWoo= [];

//check if there are no products on woocommerce:
if(empty($wooExistingProducts)){
foreach ($articles as &$article){
//Create the necessary template to initialize the connections between external products and woocommerce product template
    $wooTemplate = [
...
    ];
    array_push($productsForWoo, $wooTemplate);
//CREATE BATCHES OF 10
    if(sizeof($productsForWoo) == 10){
        $data = [
            'create' => $productsForWoo,
        ];
        $wooCommerceClient->post('products/batch', $data);
        $productsForWoo = [];
    }
}
//As there is a big chance that the last batch will have less than 10 products, push them as well to wooCommerce as a last batch
    $data = [
        'create' => $productsForWoo,
    ];
    $wooCommerceClient->post('products/batch', $data);
}
// if there are existing products on woocommerce
else{
//Loop through all existing products on the external DB
    foreach ($articles as &$article){ 
            $did_match = false;
            $wooTemplate = [
                ...
            ];
//loop through all products on WooCommerce
            foreach ($wooExistingProducts as &$product){
//if the product id from the external db matches the id from an existing product on woocommerce
                if(...){
//update that product
            $wooCommerceClient->put('products/'.urlencode($product->id), $wooTemplate);
            $did_match = true;
            break;
        }
    }
//otherwise, if the product from the external db is not found on the woocommerce database, create it
    if(!$did_match){
    array_push($productsForWoo, $wooTemplate);
    if(sizeof($productsForWoo) == 10){
        $data = [
            'create' => $productsForWoo,
        ];
        $wooCommerceClient->post('products/batch', $data);
        $productsForWoo = [];
    }
}
}
//As there is a big chance that the last batch will have less than 10 products, push them as well to wooCommerce as a last batch
            $data = [
            'create' => $productsForWoo,
            ];
            $wooCommerceClient->post('products/batch', $data);
}

I will deeply appreciate any input related to my issue. Thank you!

To get POST and PUT, you'll need to implement the methods (verbs).

You can use:

$verb = $_SERVER['REQUEST_METHOD'];
echo $verb;

... to test what HTTP request method (PUT vs GET) you're using.

Here's a SO article regarding PHP methods which I have bookmarked and often use when troubleshooting this. The code provided there is pretty clean and a great place to start.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM