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; }
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