This is an advanced level tutorial meant for WordPress experts with excellent PHP skills. This is probably one of the most tricky tasks involving Woocommerce that I have had to learn in several years.
What You Will Learn
- How to create a plugin to import products into WordPress/Woocommerce
- How to create a Woocommerce product using PHP code inside a plugin or theme file.
- How to add product attributes to a product using PHP.
- How to add product variations with PHP to your Woocommerce products.
- How to put it all together and make a plugin capable of creating variable products for Woocommerce with different sizes and prices for each variable product.
First, the PHP Code
<?php
/**
* Plugin Name: Insert Variation Products
* Plugin URI: http://jafty.com/blog/
* Description: Add a variable product with sizes to WP. Errors are written to wp-admin/insert_product_logs.txt file.
* Version: 1.04
* Author: Ian L. of Jafty.com
* Author URI: http://jafty.com
* License: GPL2
* Created On: 10-14-2014
* Updated On: 10-16-2014, 10-17-2014
*/
//call addaprdct function when plugin is activated by admin:
register_activation_hook( __FILE__, ‘addaprdct’ );
function addaprdct(){
global $wpdb;
$cats = array(25);
$insertLog = “insert_product_logs.txt”;//name the log file in wp-admin folder
$post = array(
‘post_title’ => “Product with Variations2”,
‘post_content’ => “product post content goes here…”,
‘post_status’ => “publish”,
‘post_excerpt’ => “product excerpt content…”,
‘post_name’ => “test_prod_vars2”, //name/slug
‘post_type’ => “product”
);
//Create product/post:
$new_post_id = wp_insert_post( $post, $wp_error );
$logtxt = “PrdctID: $new_post_id\n”;
//make product type be variable:
wp_set_object_terms ($new_post_id,’variable’,’product_type’);
//add category to product:
wp_set_object_terms( $new_post_id, 25, ‘product_cat’);
//################### Add size attributes to main product: ####################
//Array for setting attributes
$avail_attributes = array(
‘2xl’,
‘xl’,
‘lg’,
‘md’,
‘sm’
);
wp_set_object_terms($new_post_id, $avail_attributes, ‘pa_size’);
$thedata = Array(‘pa_size’=>Array(
‘name’=>’pa_size’,
‘value’=>”,
‘is_visible’ => ‘1’,
‘is_variation’ => ‘1’,
‘is_taxonomy’ => ‘1’
));
update_post_meta( $new_post_id,’_product_attributes’,$thedata);
//########################## Done adding attributes to product #################
//set product values:
update_post_meta( $new_post_id, ‘_stock_status’, ‘instock’);
update_post_meta( $new_post_id, ‘_weight’, “0.06” );
update_post_meta( $new_post_id, ‘_sku’, “skutest1”);
update_post_meta( $new_post_id, ‘_stock’, “100” );
update_post_meta( $new_post_id, ‘_visibility’, ‘visible’ );
//###################### Add Variation post types for sizes #############################
//insert 5 variations post_types for 2xl, xl, lg, md, sm:
$i=1;
while ($i<=5) {//while creates 5 posts(1 for ea. size variation 2xl, xl etc):
$my_post = array(
‘post_title’=> ‘Variation #’ . $i . ‘ of 5 for prdct#’. $new_post_id,
‘post_name’ => ‘product-‘ . $new_post_id . ‘-variation-‘ . $i,
‘post_status’ => ‘publish’,
‘post_parent’ => $new_post_id,//post is a child post of product post
‘post_type’ => ‘product_variation’,//set post type to product_variation
‘guid’=>home_url() . ‘/?product_variation=product-‘ . $new_post_id . ‘-variation-‘ . $i
);
//Insert ea. post/variation into database:
$attID = wp_insert_post( $my_post );
$logtxt .= “Attribute inserted with ID: $attID\n”;
//set IDs for product_variation posts:
$variation_id = $new_post_id + 1;
$variation_two = $variation_id + 1;
$variation_three = $variation_two + 1;
$variation_four = $variation_three + 1;
$variation_five = $variation_four + 1;
//Create 2xl variation for ea product_variation:
update_post_meta($variation_id, ‘attribute_pa_size’, ‘2xl’);
update_post_meta($variation_id, ‘_price’, 21.99);
update_post_meta($variation_id, ‘_regular_price’, ‘21.99’);
//add size attributes to this variation:
wp_set_object_terms($variation_id, $avail_attributes, ‘pa_size’);
$thedata = Array(‘pa_size’=>Array(
‘name’=>’2xl’,
‘value’=>”,
‘is_visible’ => ‘1’,
‘is_variation’ => ‘1’,
‘is_taxonomy’ => ‘1’
));
update_post_meta( $variation_id,’_product_attributes’,$thedata);
//Create xl variation for ea product_variation:
update_post_meta( $variation_two, ‘attribute_pa_size’, ‘xl’);
update_post_meta( $variation_two, ‘_price’, 20.99 );
update_post_meta( $variation_two, ‘_regular_price’, ‘20.99’);
//add size attributes:
wp_set_object_terms($variation_two, $avail_attributes, ‘pa_size’);
$thedata = Array(‘pa_size’=>Array(
‘name’=>’xl’,
‘value’=>”,
‘is_visible’ => ‘1’,
‘is_variation’ => ‘1’,
‘is_taxonomy’ => ‘1’
));
update_post_meta( $variation_two,’_product_attributes’,$thedata);
//Create lg variation for ea product_variation:
update_post_meta( $variation_three, ‘attribute_pa_size’, ‘lg’);
update_post_meta( $variation_three, ‘_price’, 18.99 );
update_post_meta( $variation_three, ‘_regular_price’, ‘18.99’);
wp_set_object_terms($variation_three, $avail_attributes, ‘pa_size’);
$thedata = Array(‘pa_size’=>Array(
‘name’=>’lg’,
‘value’=>”,
‘is_visible’ => ‘1’,
‘is_variation’ => ‘1’,
‘is_taxonomy’ => ‘1’
));
update_post_meta( $variation_three,’_product_attributes’,$thedata);
//Create md variation for ea product_variation:
update_post_meta( $variation_four, ‘attribute_pa_size’, ‘md’);
update_post_meta( $variation_four, ‘_price’, 18.99 );
update_post_meta( $variation_four, ‘_regular_price’, ‘18.99’);
wp_set_object_terms($variation_four, $avail_attributes, ‘pa_size’);
$thedata = Array(‘pa_size’=>Array(
‘name’=>’md’,
‘value’=>”,
‘is_visible’ => ‘1’,
‘is_variation’ => ‘1’,
‘is_taxonomy’ => ‘1’
));
update_post_meta( $variation_four,’_product_attributes’,$thedata);
//Create sm variation for ea product_variation:
update_post_meta( $variation_five, ‘attribute_pa_size’, ‘sm’);
update_post_meta( $variation_five, ‘_price’, 18.99 );
update_post_meta( $variation_five, ‘_regular_price’, ‘18.99’);
wp_set_object_terms($variation_five, $avail_attributes, ‘pa_size’);
$thedata = Array(‘pa_size’=>Array(
‘name’=>’sm’,
‘value’=>”,
‘is_visible’ => ‘1’,
‘is_variation’ => ‘1’,
‘is_taxonomy’ => ‘1’
));
update_post_meta( $variation_five,’_product_attributes’,$thedata);
$i++;
}//end while i is less than or equal to 5(for 5 size variations)
//############################ Done adding variation posts ############################
//add product image:
//require_once ‘inc/add_pic.php’;
require_once(ABSPATH . ‘wp-admin/includes/file.php’);
require_once(ABSPATH . ‘wp-admin/includes/media.php’);
$thumb_url = “http://sportsweatherstats.com/pics/Logo.png”;
// Download file to temp location
$tmp = download_url( $thumb_url );
// Set variables for storage
// fix file name for query strings
preg_match(‘/[^\?]+\.(jpg|JPG|jpe|JPE|jpeg|JPEG|gif|GIF|png|PNG)/’, $thumb_url, $matches);
$file_array[‘name’] = basename($matches[0]);
$file_array[‘tmp_name’] = $tmp;
// If error storing temporarily, unlink
if ( is_wp_error( $tmp ) ) {
@unlink($file_array[‘tmp_name’]);
$file_array[‘tmp_name’] = ”;
$logtxt .= “Error: download_url error – $tmp\n”;
}else{
$logtxt .= “download_url: $tmp\n”;
}
//use media_handle_sideload to upload img:
$thumbid = media_handle_sideload( $file_array, $new_post_id, ‘gallery desc’ );
// If error storing permanently, unlink
if ( is_wp_error($thumbid) ) {
@unlink($file_array[‘tmp_name’]);
//return $thumbid;
$logtxt .= “Error: media_handle_sideload error – $thumbid\n”;
}else{
$logtxt .= “ThumbID: $thumbid\n”;
}
set_post_thumbnail($new_post_id, $thumbid);
//optionally add second image:
require_once(ABSPATH . “wp-admin” . ‘/includes/image.php’);
$thumb_url2 = “http://sportsweatherstats.com/pics/NFLpredict.png”;
// Download file to temp location
$tmp2 = download_url( $thumb_url2 );
$logtxt .= “download_url2: $tmp2\n”;
// fix file name for query strings
preg_match(‘/[^\?]+\.(jpg|JPG|jpe|JPE|jpeg|JPEG|gif|GIF|png|PNG)/’, $thumb_url2, $matches);
$file_array2[‘name’] = basename($matches[0]);
$file_array2[‘tmp_name’] = $tmp2;
$imgID = media_handle_sideload( $file_array2, $new_post_id, ‘desc’ );
$logtxt .= “ThumbID2: $imgID\n”;
update_post_meta( $new_post_id, ‘_product_image_gallery’, $imgID);
//append to log file(file shows up in wp-admin folder):
$fh2 = fopen($insertLog, ‘a’) or die(“can’t open log file to append”);
fwrite($fh2, $logtxt);
fclose($fh2);
}//end addaprdct function
?>
Code Explained
We start our plugin code out with the PHP comment section that is needed to identify the plugin in WordPress. The only required part of the comment section is the plugin name, but everything down to where it says “created on” is information shown on the plugin’s page in wp-admin/plugins, so you really should use it. Simply modify the code to fit your needs if you are using this code as a starter for a new plugin or leave it as-is if you like my plugin the way it is. This is not meant to be a commercial plugin, it is for experience WordPress developers only. Further development is needed to make it commercially acceptable and useful to the public.
Next, after the PHP comments at the top of the script, we hook into WordPress with register_activation_hook which causes the function named to be executed when the plugin is activated. That means after you install this plugin, the way it is, the product in this example will be created as soon as you activate the plugin from the plugins page.
After we hook into WordPress, we create our main function called “addaprdct()” which adds a single product to Woocommerce. Note that you do need to have Woocommerce installed and set up before you can use this plugin.
The first 22 lines of the addaprdct function add a new product named “Product with Variations”. Also the product type is set to variable and a category of Adult T-Shirts is added as well.
In about the next 20 lines of code, starting with the “Add size attributes to main product:” comment, we add size attributes to the product created in the first 22 lines of PHP code.
Then in the section of code, starting with the “Set product values” comment, we simply use the update_post_meta function to add the necessary values to our product to make it appear in the product shop page and elsewhere on your eCommerce site.
After that, in about the next 100 lines of PHP code that starts with the “Add Variation post types for sizes” comment, we use a while loop to create a post for each of five product variations representing the five common sizes for most T-shirt products, 2xl, xl, lg, md and sm. This was a very complex section of code for me to figure out, so be very careful editing it and good luck, you’ll need it LOL. If you too are doing T-shirts, you shouldn’t have to edit this section much, but you will if you do not use size attributes in your products. And if you do not use attributes or variations at all, you’re lucky because you can eliminate this complex portion of code all together!
Adding Woocommerce Product Images with PHP
In the next section of code, where the comment reading “//add product image:” lies, we download and associate images for our product. Here we add two images(front and back) for our products, but you could do more or less for your own products of course.
To add images, the easiest way is to collect your product images prior to developing this plugin and put them in a folder inside your plugin folder so they are easy to reference. The code above assumes you have place all product images inside a folder named “pics” which sits inside the main plugin’s folder.
The first portion of the image code is for adding a featured image to the product. To do this, we need to include the files named “wp-admin/includes/file.php” and “wp-admin/includes/media.php” using require_once. Those scripts provide the necessary PHP code to import your images with the code following their inclusion. The code to add the featured image is approximately 35 lines long and ends where you see the comment “//optionally add second image:” to mark the next major section of code.
The next section of code just mentioned, beginning with the “//optionally add second image:” comment, is for adding gallery images to the product. If you use an image flipper plugin that shows the back of the product on mouse over of the image, then this is how you add that second needed image. Also even if you don’t use image flipper, all the images you add using this second method will show up in the product’s image gallery when viewing the product in the online shop.
Notice at the start of the second image code section, we include another file, /includes/image.php. That is needed for adding images to he image gallery apparently.
Summary
Finally, the last section of code consisting of about the last half a dozen lines of code, allows us to document what’s going on during testing and debugging by logging messages to a log file. Note that the log file named in the script, insert_product_logs.txt will get written in the wp-admin folder of your WordPress installation, not inside the plugin file as one might expect. You can change this if you want of course. The file name is set towards the top of the script. Put your plugin file’s PHP code in a PHP file and name it insert-variation-products.php and place it and the pics folder inside a folder named insert-variation-products then upload it to your plugins directory using FTP. Then simply go to your wp-admin/plugins page and activate the plugin to create your product to see it work. Then you can expand the plugin to create as many products as you need once you see how it all works using this example plugin.