Carlos Goce
Carlos Goce

Reputation: 1665

Bulk create WooCommerce products programmatically

It is possible to bulk create products on WooCommerce? I am using the wp-cli Product command but it seems that I have to create one by one.

<?php

$products = array(
    array('title' => 'My product 1'),
    array('title' => 'My product 2'),
    // ...
    // 10.000 more products
);

foreach ($products as $product) {
    $cliProduct = new WC_CLI_Product();
    $cliProduct->create(array(), $product);
    WP_CLI::success("Added Product #{$product['title']}");
}

This takes a lot of time since it is going to make a query for each product, even worse, it is going to be a cron job that will be run regularly. I also have to check if the product exist, in that case, update it instead of create a new product.

So the number of queries will be multiplied by 2.

Product Exists? Update it, else Create it

Is there a better way to do this? Maybe I should query the database directly, but it looks dirty.

Is there any WP function to query the database without having to create my own DB connection?

Upvotes: 3

Views: 7706

Answers (3)

WP Developer
WP Developer

Reputation: 1

how to import bulk of products in woocommerce using csv

add_action('wp_ajax_import_csv', 'import_csv');
function import_csv()
{
    if (!isset($_FILES['csv_file'])) {
        wp_send_json_error(['message' => 'No file uploaded.']);
        wp_die();
    }

    $csv_file = $_FILES['csv_file']['tmp_name'];

    if (($handle = fopen($csv_file, 'r')) === false) {
        wp_send_json_error(['message' => 'Could not open CSV file.']);
        wp_die();
    }

    $headers = fgetcsv($handle);
    if (!$headers) {
        fclose($handle);
        wp_send_json_error(['message' => 'Invalid CSV file.']);
        wp_die();
    }

    $products_updated = 0;
    $products_created = 0;
    while (($data = fgetcsv($handle)) !== false) {
        //$data = array_combine($headers, $row);
        $sku = $data[11];
        global $wpdb;
        $product_id = $wpdb->get_var($wpdb->prepare("
            SELECT p.ID 
            FROM {$wpdb->posts} AS p
            INNER JOIN {$wpdb->postmeta} AS pm 
            ON p.ID = pm.post_id
            WHERE p.post_type = 'product' 
            AND pm.meta_key = '_sku' 
            AND pm.meta_value = %s
        ", $sku));


        if ($product_id) {
            $product = wc_get_product($product_id);
            $products_updated++;
        } else {

            $product = new WC_Product_Variable();
            $products_created++;
        }

        $product->set_name($data[0]);
        $product->set_description($data[1]);
        $product->set_price($data[2]);
        $product->set_regular_price($data[2]);
        $product->set_height($data[3]);
        $product->set_width($data[4]);
        $product->set_length($data[5]);
        $product->set_weight($data[6]);
        $product->set_status('publish');
        $product->set_stock_quantity(10);
        $product->set_manage_stock(true);
        $product->set_sku($data[11]);

        $upload_dir = wp_upload_dir();
        $galleryImages = [];

        for ($i = 7; $i <= 10; $i++) {

            if (!empty($data[$i])) {

                $featured_image_path = $upload_dir['path'] . '/' . $data[$i];
                $image_extension = pathinfo($data[$i], PATHINFO_EXTENSION);
                $image_type = 'image/' . $image_extension;

                $attachment =   array(
                    'post_mime_type' => $image_type,
                    'post_title'     =>  $data[$i],
                    'post_status'    => 'inherit',
                    'guid'           => $upload_dir['url'] . '/' . $data[$i]
                );

                $attachment_id = wp_insert_attachment($attachment, $featured_image_path);
                $attachment_data = wp_generate_attachment_metadata($attachment_id, $featured_image_path);
                wp_update_attachment_metadata($attachment_id, $attachment_data);

                if ($i == 7) {
                    $product->set_image_id($attachment_id);
                } else {
                    $galleryImages[] = $attachment_id;
                }
            }
        }

        if (!empty($galleryImages)) {
            $product->set_gallery_image_ids($galleryImages);
        }

        $product_id = $product->save();
    }

    fclose($handle);

    wp_send_json_success([
        'message' => "$products_created products were created, and $products_updated products were updated successfully."
    ]);
}

Upvotes: 0

Raunak Gupta
Raunak Gupta

Reputation: 10809

A small note I had written this answer way back in 2017 at that time WooCommerce version was below < 3.0. So if you are using WooCommerce version 3.0. then please refer to this answer.

As of March 2022 this answer still works but I will recommend using this answer for > v3.0.

Assuming you have an array like this and you have Unique SKU to identify product.

$products = [
    0 => [
        'title' => 'My Simple product 1',
        'sku' => 'sku1',
        'product_cat' => 'My cat'
    //...
    //...
    ],
    1 => [
        'title' => 'My Simple product 1',
        'sku' => 'sku1'
    //...
    //...
    ]
];

Pass the above array through myCustomProduct() method.

function myCustomProduct($product_array)
{
    if (!empty($product_array)):
        foreach ($product_array as $product):
            $product_id = wc_get_product_id_by_sku($product['sku']);
            //no product exist with the given SKU so create one
            if (!$product_id):
                $post = [
                    'post_author' => '',
                    'post_content' => $product['content'],
                    'post_status' => "publish",
                    'post_title' => wp_strip_all_tags($product['title']),
                    'post_name' => $product['title'],
                    'post_parent' => '',
                    'post_type' => "product",
                ];
                //Create Post
                $product_id = wp_insert_post($post, $wp_error);

                //set Product Category
                wp_set_object_terms($product_id, $product['product_cat'], 'product_cat');

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

                update_post_meta($product_id, '_sku', $product['sku']);
                update_post_meta($product_id, 'total_sales', '0');

            //product found
            else:
                $post = [
                    'ID' => $product_id,
                    'post_title' => $product['title'],
                    'post_content' => $product['content'],
                ];
                $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;
//                  }
//              }
            endif;

            update_post_meta($product_id, '_visibility', 'visible');
            update_post_meta($product_id, '_stock_status', 'instock');
            update_post_meta($product_id, '_product_attributes', array());
            update_post_meta($product_id, '_manage_stock', "yes");
            update_post_meta($product_id, '_backorders', "no");
            update_post_meta($product_id, '_stock', $product['qty']);
            update_post_meta($product_id, '_price', $product['price']);
            //update_post_meta($product_id, '_downloadable', 'yes');
            //update_post_meta($product_id, '_virtual', 'yes');
            //update_post_meta($product_id, '_regular_price', "1");
            //update_post_meta($product_id, '_sale_price', "1");
            //update_post_meta($product_id, '_purchase_note', "");
            //update_post_meta($product_id, '_featured', "no");
            //update_post_meta($product_id, '_weight', "");
            //update_post_meta($product_id, '_length', "");
            //update_post_meta($product_id, '_width', "");
            //update_post_meta($product_id, '_height', "");
            //update_post_meta($product_id, '_sale_price_dates_from', "");
            //update_post_meta($product_id, '_sale_price_dates_to', "");
            //update_post_meta($product_id, '_price', "1");
            //update_post_meta($product_id, '_sold_individually', "");
        endforeach;
    endif;
}

This'll give you a brief idea as how to create/update product; if you need any further assistance then you have to share your 4-5 array elements, so that I can get to know what type of product you want to create and what field/meta it will be having.

Hope this helps!

Upvotes: 6

Raunak Gupta
Raunak Gupta

Reputation: 10809

For WooCommerce Version 3.0 or above.

Assuming you have an array like this and you have Unique SKU to identify product.

$products = [
    0 => [
        'title' => 'My Simple product 1',
        'sku' => 'sku1',
        'category_ids' => [23,45]
    //...
    //...
    ],
    1 => [
        'title' => 'My Simple product 1',
        'sku' => 'sku1'
    //...
    //...
    ]
];

Pass the above array through wh_myCustomProduct() method.

function wh_myCustomProduct($product_array)
{
    if (!empty($product_array)):
        foreach ($product_array as $product):
            $product_id = wc_get_product_id_by_sku($product['sku']);
            //no product exist with the given SKU so create one
            if (empty($product_id)):
                
                $product_id = wh_createOrUpdateProduct($product);
            //product found
            else:
                
                $product_id = wh_createOrUpdateProduct($product,$product_id);
            endif;

        endforeach;
    endif;
}

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.


    $objProduct->set_category_ids($product['category_ids']); //Set product category ID.

    $objProduct->set_stock_status('instock');
    $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;
}

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

Related:

Upvotes: 1

Related Questions