I've made some code to synchronise products with a feed. It creates or updates products and variants with stock/price info etc.

I was using a "custom product attribute", i.e. is_taxonomy => 0 in the _product_attributes meta field.

For plugin compatibility reasons I'm trying to move this to a full fledged Product Attribute.

It all seems to work - product and variants appear and are linked - except the selected option for the attribute is the "Any" option of the dropdown :/

Dropdown Issue

I'm setting the pa_available-options term on the parent with both option, and the attribute_pa_available-options meta for the children... I cant see what I have missed.

Weirdly if I open the product in admin and save - it 'corrects' itself. However until I do this - the front end page for the product also has no options in the dropdown.

After Product Update

Here's the code stripped to the fundamentals that produces the issue...

$data = array (
        'sku'           => 'abc123',
        'name'          => 'Product Name',
        'description'   => 'Product description',
        'excerpt'       => 'Product excerpt',
        'price'         => '1.23',
        'options'       => 'DarkerBlueish|DarkerRedish',
        'optionsku'     => 'abc123-b|abc123-r',
        'optionprice'   => '1.23|2.34',
        'optionstock'   => '5|6',
);

$sku = $data['sku'];
echo "Creating  variable prod: ".$Sku." <br>";

global $wpdb;
$product_id = $wpdb->get_results( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key='_sku' AND meta_value='".$sku."' limit 1");

$productId = null;
if ($product_id) {
        $productId = $product_id[0];
}
$update = false;

if($productId && (isset($productId->post_id) && $productId->post_id!='0')) {  // got a real post
        $post = array(
                'ID'            => $productId->post_id,
                'post_type'     => 'product',
                'post_author'   => 1,
                'post_parent'   => '',
                'post_title'    => $data['name'],
                'post_content'  => $data['description'],
                'post_excerpt'  => $data['excerpt'],
        );

        //Update post
        $update=true;
        $post_id = wp_update_post( $post );
        echo "update product: ".$post_id."<br>";
} else {
        $post = array(
                'post_author'   => 1,
                'post_type'     => 'product',
                'post_status'   => 'draft',
                'post_title'    => $data['name'],
                'post_content'  => $data['description'],
                'post_excerpt'  => $data['excerpt'],
        );

        // Create post
        $update=false;

        $post_id = wp_insert_post( $post );
        update_post_meta($post_id, '_sku', $data['sku'] );

        update_post_meta( $post_id, '_visibility', 'visible' );
        update_post_meta( $post_id, '_manage_stock', "yes" );

        wp_set_object_terms ($post_id, 'variable', 'product_type',true);

        echo "created product: ".$post_id."<br>";
}


$avail_attributes = $data['options'];
$Arraylist_Attr = explode("|",$avail_attributes);

$thedata = array(
        'available-options'=> array(
                'name'=>'pa_available-options',
                'value'=> $Arraylist_Attr,
                'is_visible' => '0',
                'is_variation' => '1',
                'is_taxonomy' => '1'
        )
);

update_post_meta( $post_id,'_product_attributes',$thedata);
update_post_meta( $post_id, '_price', $data['price']);

$priceArryList  = explode("|",$data['optionprice']);
$skuArrayList   = explode("|",$data['optionsku']);
$childPriceList = explode("|",$data['optionprice']);
$qtyArrayList   = explode("|",$data['optionstock']);


$tot_qty = 0;
foreach($qtyArrayList AS $qty){
        $tot_qty += $qty;
}
if($tot_qty > 0){
        update_post_meta( $post_id, '_stock_status', 'instock');
}else{
        update_post_meta( $post_id, '_stock_status', 'outofstock');
}
update_post_meta( $post_id, '_stock', $tot_qty);

$i=1;
$idx = 0;

$termslugs = array();
foreach($Arraylist_Attr as $values) {
        $termid = term_exists(  $values, 'pa_available-options' );
        if ( !$termid ) {
                $termid = wp_insert_term( $values, 'pa_available-options' );
        }
        $termid = $termid["term_id"];
        $term_slug = get_term((int)$termid, 'pa_available-options' )->slug; // Get the term slug
        $termslugs[] = $term_slug;
        echo "Term: ".$values." | id: ".$termid." | slug: ".$term_slug."  <br>\n";
}
wp_set_object_terms( $post_id, $termslugs, 'pa_available-options', true );

foreach($Arraylist_Attr as $values) {
        $termid = term_exists(  $values, 'pa_available-options' );
        $termid = $termid["term_id"];
        $term_slug = get_term((int)$termid, 'pa_available-options' )->slug; // Get the term slug


        $post_Title = 'Variation #' . $skuArrayList[$idx];
        $post_Title = $data['name']." - ".$term_slug;
        echo "<br><br>Processing ".$post_Title."<br>\n";

        $product_Attr_id = $wpdb->get_results( "select post_id from $wpdb->postmeta where meta_key='_sku' and meta_value = '".$skuArrayList[$idx]."' order by post_id limit 1;");
        $attrId = null;
        if ($product_Attr_id) {
                $attrId = $product_Attr_id[0];
        }
        $exist_Post_attr = "";
        $update2= false;
        if($attrId && ($attrId->post_id!='' || $attrId->post_id!='0')) {
                $update2 = true;
                $exist_Post_attr = $attrId->post_id;
        }

        $Attribute_post = array(
                'ID'            => $exist_Post_attr,
                'post_type'     => 'product_variation',
                'post_status'   => 'publish',
                'post_name'     => 'product-' . $post_id . '-variation-' . $skuArrayList[$idx],
                'post_parent'   => $post_id,
                'guid'          => home_url() . '/?product_variation=product-' . $post_id . '-variation-' . $skuArrayList[$idx],
                'post_title'    => $post_Title
        );

        echo "About to insert ".$exist_Post_attr."<br>\n";

        // Insert the post into the database
        if (!$update2) { // new post
                echo "New variation<br>\n";
                $var_id = wp_insert_post( $Attribute_post );
        } else {
                echo "Variation existed<br>\n";
                $var_id = $exist_Post_attr;
        }

        echo "var_id: ".$var_id."<br>\n";

        $variable_id = $var_id;

        $sub_product = new WC_Product_Variation( $variable_id );
        $sub_product->save();

        echo "About to update  avail options".$variable_id."<br>\n";
        update_post_meta( $variable_id, 'attribute_pa_available-options', $term_slug);

        update_post_meta( $variable_id, '_sku', $skuArrayList[$idx] );

        update_post_meta( $variable_id, '_price', $childPriceList[$idx] );
        update_post_meta( $variable_id, '_regular_price', $childPriceList[$idx] );

        if($qtyArrayList[$idx] > 0){
                update_post_meta( $variable_id, '_stock_status', 'instock');
        } else {
                update_post_meta( $variable_id, '_stock_status', 'outofstock');
        }
        update_post_meta( $variable_id, '_stock', $qtyArrayList[$idx] );
        update_post_meta( $variable_id, '_manage_stock', "yes" );

        $sub_product->validate_props(); // Check validation

        wc_delete_product_transients($variable_id);


        $idx++;
        $i++;
}

$_product = wc_get_product($post_id);
$_product->variable_product_sync();
$_product->save();

wc_delete_product_transients($post_id);

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.