Skip to content
Advertisement

WooCommerce Product SKU checking is not working

I am trying to create and update woocommerce products automatically from an API. I have created the starting point of the plugin and this is my method that gets the products from the external API and then loops through them and creates a simple product in woocoommerce.

It creates the products perfectly fine however if I run the code twice, the products do not get an update but a whole new batch of them are created (SKU are duplicated without any errors), it seems like the SKU is not recognized even though it exists and I can see it on the product’s dashboard and on the frontend here is my code so far:

// Activating the function when the plugin is activated
public function __construct()
{
    add_action( 'activated_plugin', array($this, 'add_products_from_api') );
}

public function add_products_from_api() {

    // API products url
    $url = 'https://example.com/products';

    // Retreiving the products body from api and decoding the json
    $external_products = wp_remote_retrieve_body(wp_remote_get($url));
    $products = json_decode($external_products, true);

    // Products found 
    if (!empty($products)) {

        foreach ($products as $product) {

            // check if SKU already exists
            $product_id = wc_get_product_id_by_sku($product['id']);

            if (!$product_id) {
                $post = [
                    'post_author' => '',
                    'post_content' => $product['description'],
                    'post_status' => "publish",
                    'post_title' => wp_strip_all_tags($product['title']),
                    'post_name' => $product['title'],
                    'post_parent' => '',
                    'post_type' => "product",
                ];

                // Create product
                $product_id = wp_insert_post($post);

                // Set product type
                wp_set_object_terms($product_id, 'simple', 'product_type');

                update_post_meta($product_id, '_sku', $product['id']);
                update_post_meta($product_id, '_price', $product['price']);
                update_post_meta($product_id, '_manage_stock', "yes");
                update_post_meta($product_id, '_stock', $product['rating']['count']);
            } 
            else {
                // Product already exists
                $post = [
                    'ID' => $product_id,
                    'post_title' => $product['title'],
                    'post_content' => $product['description'],
                ];

                $post_id = wp_update_post($post, true);
                if (is_wp_error($post_id)) {
                    $errors = $post_id->get_error_messages();
                    foreach ($errors as $error) {
                        echo $error;
                    }
                }
            }

            update_post_meta($product_id, '_stock', $product['rating']['count']);
            update_post_meta($product_id, '_price', $product['price']);
        }
    }
}

does anyone have any ideas why the SKUs are present but not recognized and the products just keep duplicating? thanks.

Advertisement

Answer

Short answer will be if you just replace if( !$product_id ) by this if (empty($product_id )) it will solve the issue.

But a proper and working answer will be as you are creating a product in WooCommer then I will recommend using the WooCommerce native CRUD method. I know you have taken reference from my very old answer (I will update that answer shortly) at that time WooCommer do have an inbuilt method for creating products so we have to use WP methods.

Here is the working code sample.

<?php

// Activating the function when the plugin is activated
public function __construct()
{
    add_action( 'activated_plugin', array($this, 'add_products_from_api') );
}

public function add_products_from_api() {
    // API products url
    $url = 'https://fakestoreapi.com/products';

    // Retreiving the products body from api and decoding the json
    $external_products = wp_remote_retrieve_body(wp_remote_get($url));
    $products = json_decode($external_products, true);

    // Products found
    if (!empty($products)) {

        foreach ($products as $product) {

            // check if SKU already exists
            $productID = wc_get_product_id_by_sku($product['id']);

            // Product Do not exists
            if (empty($productID)) {
               $productID = $this->wh_createOrUpdateProduct($product);
            }
            // Product exists with the given SKU
            else {
                $productID = $this->wh_createOrUpdateProduct($product, $productID);
            }
//            echo $productID;
        }
    }
}

protected function wh_createOrUpdateProduct($product, $productId = 0){
    $objProduct = new WC_Product($productId);
    $objProduct->set_sku($product['id']); //Set product SKU.
    $objProduct->set_name($product['title']); //Set product name.
    $objProduct->set_description($product['description']); //Set product description.
    $objProduct->set_description($product['price']); //Set product price.

    // getting product cat ID from name
    $productCatID = $this->wh_getProductCatID($product['category']);


    $objProduct->set_category_ids([$productCatID]); //Set product category ID.
    $objProduct->set_average_rating($product['rating']['rate']); //Set avg. rating of the product.
    $objProduct->set_review_count($product['rating']['count']); //Set total rating of the product.

    $objProduct->set_manage_stock(true); //Set true if you want WooCommerce to manage your stock
    $objProduct->set_stock_quantity($product['rating']['count']); //Set product stock qty.
    $objProduct->set_status('publish'); //Set product status

    $productID = $objProduct->save(); //Saving the data to create new product, it will return product ID.
    return $productID;
}

protected function wh_getProductCatID($catName) {
    $productCatDetails = wp_insert_term($catName, 'product_cat');
    if (is_wp_error($productCatDetails)) {
        if ($productCatDetails->get_error_code() == 'term_exists') {
            $productCatID = $productCatDetails->get_error_data();
        }
        // TO DO: for other error code need to handle it
    } else {
        $productCatID = $productCatDetails['term_id'];
    }
    return $productCatID;
}

working code example

Please Note: I have tested individual methods/functions but I haven’t tested the whole flow. Secondly, I haven’t handled the image part in the above code example, which I believe you will be able to handle easily.

Hope this helps!

Reference:

  • This is the WooCommerce official doc
  • You can also refer to this article where I have explained in detail how to use Product CRUD
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement