How to Create Product Variations Programmatically Using Taxonomy Attributes
-
I am struggling to create product variations programmatically. I wrote a script that creates WooCommerce products based on information from an API call. Everything works except for one issue regarding product variation attributes.
The problem I am facing is that when my variations are created, the attributes are not assigned, like so:
My desired outcome is for the attributes to be populated. I am assigning taxonomy attributes to the parent product and their values are showing up just fine, like so:
But when using this code to set attributes for my variation:
// set attributes // $pa_format_term->term_id = integer; ID of term // $pa_condition_term->term_id = integer; ID of term $variation->set_attributes( array( 'pa_format' => $pa_format_term->term_id, 'pa_condition' => $pa_condition_term->term_id ) );
The problem where the attributes are not assigned to the variation persists. When I click to edit the WooCommerce product after my full script runs, a popup message is displayed that says, “Adding attributes failed,” which I’m assuming pertains to my issue.
I have tried everything I know of, read dozens of forum posts, pages, etc., and still can’t get this to work. I have tried using the term ‘name’ instead of the ID, which neither works for me.
Here is my full function for reference:
// Create a new product action add_action( 'init', 'create_new_woocommerce_product'); function create_new_woocommerce_product() { global $woo_product_meta; // Download featured image $image_data = @file_get_contents($woo_product_meta['image']); if($image_data) { $filename = basename($woo_product_meta['image']); $upload_file = wp_upload_bits($filename, null, $image_data); if (!$upload_file['error']) { $wp_filetype = wp_check_filetype($filename, null); $attachment = array( 'post_mime_type' => $wp_filetype['type'], 'post_title' => sanitize_file_name($filename), 'post_content' => '', 'post_status' => 'inherit' ); $attachment_id = wp_insert_attachment( $attachment, $upload_file['file']); if (!is_wp_error($attachment_id)) { require_once(ABSPATH . "wp-admin" . '/includes/image.php'); $attachment_data = wp_generate_attachment_metadata( $attachment_id, $upload_file['file'] ); wp_update_attachment_metadata( $attachment_id, $attachment_data ); } } } // Create a new variable product $product = new WC_Product_Variable(); // set title $product->set_name( $woo_product_meta['title'] ); // set tags if they exist $tag_ids = array_map( function ($subject) { // remove unwanted symbols in tags $subject_str = str_replace(array(',', '&', '+', '-', '--', '=', ':', '.', '/', '\\', '@', '#', '$', '%', '^', '*', '(', ')', '[', ']', '{', '}', '\'', '"'), array(' ', ' and ', ' and ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '), $subject); // remove multiple spaces in a row if found $subject_str = preg_replace('/\s+/', ' ', $subject_str); // convert tags to lowercase $subject_str = strtolower($subject_str); $term = get_term_by('name', $subject_str, 'product_tag'); // if term exists if ( $term instanceof WP_Term ) { return (int) $term->term_id; } // if term doesn't exist else { if ( $subject_str !== '' ) { wp_create_term($subject_str, 'product_tag'); // get new tag and set var $new_tag = get_term_by('name', $subject_str, 'product_tag'); if ($new_tag instanceof WP_Term) { // set var to id val of tag return (int) $new_tag->term_id; } else { echo 'Notice: "' . $subject_str . '" was not created. Another tag exists that is too similar.'; } } else { echo 'Notice: a tag input was blank and was skipped; cannot create a blank tag.'; } } }, $woo_product_meta['subjects'] ); $product->set_tag_ids( $tag_ids ); // Set featured image $product->set_image_id($attachment_id); // save progress $product->save(); // set author(s) if ( isset($woo_product_meta['author']) ) { foreach ( $woo_product_meta['author'] as $author ) { // Check if there is a ',' in the author name if ( strpos($author, ',') !== false ) { // Get the last name $woo_meta_author_last_name = substr($author, 0, strpos($author, ',')); // Set the full author name by swapping the first name and last name and removing the comma $woo_meta_author_full_name = substr($author, (strpos($author, ',') + 1)) . " " . $woo_meta_author_last_name; } else { // Set the full name $woo_meta_author_full_name = $author; // Get the last word and set it as the last name $woo_meta_author_last_name = substr(strrchr($author, " "), 1); } // Check if the authors taxonomy exists if ( term_exists( $woo_meta_author_full_name, 'authors' ) ) { // Assign the existing taxonomy item to the product wp_set_object_terms( $product->get_id(), $woo_meta_author_full_name, 'authors', true ); // save progress $product->save(); } else { // Create a new taxonomy item and assign it to the product wp_insert_term( $woo_meta_author_full_name, 'authors', array( 'slug' => sanitize_title( $woo_meta_author_full_name ) ) ); wp_set_object_terms( $product->get_id(), $woo_meta_author_full_name, 'authors', true ); // save progress $product->save(); } } } // Set product attributes $attributes = array(); // add the format attribute $attribute = new WC_Product_Attribute(); $attribute->set_id( wc_attribute_taxonomy_id_by_name( 'pa_format' ) ); $attribute->set_name( 'pa_format' ); // see if current format attribute exists and set as var $pa_format_term = get_term_by('name', $woo_product_meta['format'], 'pa_format'); if(!$pa_format_term){ // create new pa_format term wp_insert_term( $woo_product_meta['format'], // the term 'pa_format' // the taxonomy ); $pa_format_term = get_term_by('name', $woo_product_meta['format'], 'pa_format'); echo 'Created new term for pa_format: ' . $pa_format_term->name; } else { echo 'Existing pa_format term detected: ' . $pa_format_term->name; } $attribute->set_options( array( $pa_format_term->term_id ) ); $attribute->set_position( 0 ); $attribute->set_visible( true ); $attribute->set_variation( true ); $attribute->is_taxonomy( true ); $attributes[] = $attribute; // add the condition attribute $attribute = new WC_Product_Attribute(); $attribute->set_id( wc_attribute_taxonomy_id_by_name( 'pa_condition' ) ); $attribute->set_name( 'pa_condition' ); // see if current condition attribute exists and set as var $pa_condition_term = get_term_by('name', $woo_product_meta['condition'], 'pa_condition'); if(!$pa_condition_term){ // create new pa_format term wp_insert_term( $woo_product_meta['condition'], // the term 'pa_condition' // the taxonomy ); $pa_condition_term = get_term_by('name', $woo_product_meta['condition'], 'pa_condition'); echo 'Created new term for pa_condition: ' . $pa_condition_term->name; } else { echo 'Existing pa_condition term detected: ' . $pa_condition_term->name; } $attribute->set_options( array( $pa_condition_term->term_id ) ); $attribute->set_position( 1 ); $attribute->set_visible( true ); $attribute->set_variation( true ); $attribute->is_taxonomy( true ); $attributes[] = $attribute; $product->set_attributes( $attributes ); // save the changes and go on $product->save(); // create product variation $variation = new WC_Product_Variation(); $variation->set_parent_id( $product->get_id() ); $variation->set_regular_price( $woo_product_meta['price'] ); $variation->save(); // set attributes $variation->set_attributes( array( 'pa_format' => $pa_format_term->term_id, 'pa_condition' => $pa_condition_term->term_id ) ); $variation->save(); // echo variation data for debugging purposes $variation_data = $variation->get_data(); echo '<pre>'; print_r($variation_data); echo '</pre>'; $variation->set_image_id( $attachment_id ); $variation->set_description( $woo_product_meta['description'] ); $variation->set_sku( $woo_product_meta['isbn13'] ); $variation->set_manage_stock( true ); $variation->set_stock_quantity( 0 ); $variation->set_backorders( 'notify' ); // 'yes', 'no' or 'notify' $variation->save(); // Set the custom fields on the variation $variation_id = $variation->get_id(); $variation->update_meta_data('_isbn10_field', sanitize_text_field( $woo_product_meta['isbn10'] ) ); $variation->update_meta_data('_isbn13_field', sanitize_text_field( $woo_product_meta['isbn13'] ) ); $variation->update_meta_data('_language_field', sanitize_text_field( $woo_product_meta['language'] ) ); $variation->update_meta_data('_release_field', sanitize_text_field( $woo_product_meta['date'] ) ); $variation->update_meta_data('_publisher_field', sanitize_text_field( $woo_product_meta['publisher'] ) ); $variation->update_meta_data('_length_field', sanitize_text_field( $woo_product_meta['length'] ) ); // Save the variation $variation->save(); // Save the product $product->save(); // show success message echo '<div>Successfully imported: ' . $woo_product_meta['title'] . '<div>'; do_action( 'create_new_woocommerce_product' ); }
Please help me resolve this issue and let me know what other code snippets and information you might need. Thank you in advance!
Specifications:
- PHP 8.0.29
- WordPress 6.2.2
- WooCommerce 7.8.0
- The topic ‘How to Create Product Variations Programmatically Using Taxonomy Attributes’ is closed to new replies.