[Coding Snippets #5]: Importing WooCommerce Product by Code

in #programminglast year

Hey there, long time, no see once again! Things are very busy between work and raising a baby. Today we are going to talk about a subject that is pretty much hard to find a reliable source as a base:

Importing WooCommerce Products by Code! Ideal for when you want to bulk-import products on a new (or old) e-commerce website.

εικόνα.png


Intro

Adding a product on WooCommerce is a fast but boring process, especially if you have to import 100s or even 1000s of products. If by any chance you have an easy way to access all info on a CSV (from your ERP) or are in a database, then you can speed up the process, from taking weeks to taking a couple of days!

This is going to be a little bit big of a post, but it is worth your time if you need knowledge like this.


Not covered in this post

  • Adding Variable/Virtual/Whatever products, we will only add simple products. Variable products will be covered in the future
  • Creating categories (we will only get the ID from the slug - or the pretty URL)
  • Adding attributes to the database or the product

Requirements

You need at least the following details for each product:

  • Title
  • Price
  • Description
  • SKU
  • An image (a URL accessible online is by far the fastest method, as long as the remote host allows you to directly download the image)
  • A category ID (I will cover how to get the WooCommerce Category ID by the category slug in the post, but not how to create them)

You can also add product attributes to be visible in the "Additional Information" tab below a product, but this will not be covered here, as stated in the "Not covered in this post" section.


Adding a simple product

<?php
$product = new WC_Product_Simple(); // We initialize a simple WooCommerce product

$product->set_name("Super awesome product"); // This is our product title!

$product->set_sku("SAP-001"); // This is the Stock-Keeping Unit code.

$product->set_regular_price("19.99"); // WooCommerce will use the default currency of your store.

$product->set_slug("super-awesome-product"); // Will be used by WordPress as the pretty url, in this case the product's URL will be: www.example.com/product/super-awesome-product

$product->set_description("<p>This is the full product description.</p> <p>WordPress will filter some HTML code out, so be sure to double-check it.</p>");

// You can also set a short description, using the following code:
$product->set_short_description("This is a short description for the Super Awesome Product");

// See the "Downloading an image and getting the ID" section for a basic overview.
$image_id = download_image("https://example.com/static/super-image.jpg", "super-awesome-product") 
$product->set_image_id($image_id); 

// See the "Get a Term ID by the category slug" section for a basic overview.
$term_id = find_term_id('awesome-category')
$product->set_category_ids(array($term_id)); // We will get the Term ID in a later section

$product->save(); // Save the Simple Product to the DB
?>

Downloading an image, and getting the ID

<?php
function download_image($url, $slug) {
   $imagetype = end(explode('/', getimagesize($imageurl)['mime']));
    $uniq_name = date('dmY') . '' . (int) microtime(true);
    $slug = $slug . '-' . substr(time(), -5);
    $filename = $slug . '.' . $imagetype;

    $uploaddir = wp_upload_dir();
    $uploadfile = $uploaddir['path'] . '/' . $filename;
    $contents = file_get_contents($imageurl);
    $savefile = fopen($uploadfile, 'w');
    fwrite($savefile, $contents);
    fclose($savefile);

    $wp_filetype = wp_check_filetype(basename($filename), null);
    $attachment = array(
        'post_mime_type' => $wp_filetype['type'],
        'post_title' => $filename,
        'post_content' => '',
        'post_status' => 'inherit'
    );

    $attach_id = wp_insert_attachment($attachment, $uploadfile);
    $imagenew = get_post($attach_id);
    $fullsizepath = get_attached_file($imagenew->ID);
    $attach_data = wp_generate_attachment_metadata($attach_id, $fullsizepath);
    wp_update_attachment_metadata($attach_id, $attach_data);
    return $attach_id;
}
?>

I will not fully explain this code, but in a nutshell:

  • We provide download_image with a URL (the image we want to set as the default one for the product) and a slug (this could be the same as the product's slug, it's good for Image SEO from what I hear)
  • We get the image using file_get_contents and save it to the WordPress upload folder.
  • We import the image as an attachment and get the Attachment ID that we use as a return on our function.

Get a Term ID by the category slug.

Getting the term's info

<?php
function find_term_id($cat_slug) {
    $termdetails = get_term_by('slug', $cat_slug, 'product_cat');
    return $termdetails->->term_id;
}
?>

get_term_by accepts 3 parameters, you can have an in-depth look at the official WordPress Developer Resources page for "get_term_by".

get_term_by returns an object that holds the following information:

  • term_id (that's what we want)
  • name
  • slug
  • term_group
  • term_taxonomy_id
  • taxonomy
  • description
  • parent
  • count
  • filter

Getting the term's ID

To get the term ID, we want to call $termdetails->term_id (it's an object, not an array, so $termdetails['term_id'] will result in an error)


How to use it for bulk importing

Wrap the code in the 'Adding a simple product' inside a function, and replace all strings with variables. You can use an array for each product's details, and call it in a loop like this:

<?php
foreach ($products AS $product) {
    import_product($product);
}
?>

For this to work though, you must include the WordPress wp-load.php file as well as the image.php include, like this:

<?php
include('wp-load.php');
include_once(ABSPATH . 'wp-admin/includes/image.php');
?>

The wp-load.php path should be relative to the location of the PHP file you're going to use.


How to make it better?

  • You should at least add error handling for downloading the images, saving the product and getting the term ID.

  • Chances are you do not have a pregenerated slug, so you could use the sanitize_title() function to generate one from the product title. See the WordPress Developer Resource page for "sanitize_title"


That's it for this blog post, if you found it useful you upvote and a comment will be more than welcome!

Is there something wrong with my snippets? Let me know!

Sort:  

Thanks for your contribution to the STEMsocial community. Feel free to join us on discord to get to know the rest of us!

Please consider delegating to the @stemsocial account (85% of the curation rewards are returned).

You may also include @stemsocial as a beneficiary of the rewards of this post to get a stronger support. 
 

Congratulations @dimitrisp! You have completed the following achievement on the Hive blockchain And have been rewarded with New badge(s)

You distributed more than 27000 upvotes.
Your next target is to reach 28000 upvotes.

You can view your badges on your board and compare yourself to others in the Ranking
If you no longer want to receive notifications, reply to this comment with the word STOP

Check out our last posts:

Our Hive Power Delegations to the August PUM Winners
Feedback from the September Hive Power Up Day
Hive Power Up Month Challenge - August 2023 Winners List