WooCommerce Changing Simple Product to Variable and Vice Versa, but how to get new variations to show on the frontend?

I am creating a plugin that ties into the Runit System for showing onhand products in WooCommerce. This requires changing products via a Cron job that will update them, from Simple Products to Variable Products and vice versa depending on the quantity of stock and the variations of these products, which change. I have working code, that updates these products in the backend, showing the correct variations, however, it does not update on the front end. The new variations, even when editing Variable Products, do not show on the front end when viewing the actual Product itself. I still see the old variations in there. How to update the variations to use the new variations automatically, instead of having to hit the Update button in the backend Administration when editing the Product?

Is there some sort of function that needs to be called for updating the Variations in WooCommerce that I’m not aware of? I am using the array like this and serializing it before updating the meta_value for the meta_key _product_attributes in wp_postmeta table, like so:

Read More
function ProcessBasicProperties(Array $properties)
{
    $return = array();
    $position = 0;

    if (!empty($properties))
    {
        if (!empty($properties['siz']))
        {
            ++$position;
            $size = !is_array($properties['siz']) ? array($properties['siz']) : array_unique($properties['siz']);
            $return['size'] = array(
                'name' => 'Size',
                'value' => count($size) > 1 ? implode(' | ', $size) : $size[0],
                'is_visible' => count($size) > 1 ? 0 : 1,
                'is_variation' => count($size) > 1 ? 1 : 0,
                'is_taxonomy' => 0,
                'position'  => $position
            );
        }
        if (!empty($properties['ext']))
        {
            ++$position;
            $extension = !is_array($properties['ext']) ? array($properties['ext']) : array_unique($properties['ext']);
            $return['extension'] = array(
                'name' => 'Extension',
                'value' => count($extension) > 1 ? implode(' | ', $extension) : $extension[0],
                'is_visible' => count($extension) > 1 ? 0 : 1,
                'is_variation' => count($extension) > 1 ? 1 : 0,
                'is_taxonomy' => 0,
                'position' => $position
            );
        }
        // styles do not get added to attributes for variable products, instead, with variable products, the style goes into the overall sku of the product (General Properties)
        // So, in short, variable products should not have this key set.
        if (!empty($properties['style']))
        {
            ++$position;
            $return['style'] = array(
                'name' => 'Style',
                'value' => htmlspecialchars($properties['style'], ENT_QUOTES),
                'is_visible' => 1,
                'is_variation' => 0,
                'is_taxonomy' => 0,
                'position' => $position
            );
        }
        if (!empty($properties['color']))
        {
            ++$position;
            $colors = !is_array($properties['color']) ? array($properties['color']) : array_unique($properties['color']);
            $return['color'] = array(
                'name' => 'Color',
                'value' => count($colors) > 1 ? htmlspecialchars(implode(' | ', $colors), ENT_QUOTES) : htmlspecialchars($colors[0], ENT_QUOTES),
                'is_visible' => 1,
                'is_variation' => 0,
                'is_taxonomy' => 0,
                'position' => $position
            );
        }
        if (!empty($properties['gender']))
        {
            ++$position;
            $return['gender'] = array(
                'name' => 'Gender',
                'value' => htmlspecialchars($properties['gender'], ENT_QUOTES),
                'is_visible' => 1,
                'is_variation' => 0,
                'is_taxonomy' => 0,
                'position' => $position
            );
        }
        if (!empty($properties['season']))
        {
            ++$position;
            $return['season'] = array(
                'name' => 'Season',
                'value' => htmlspecialchars($properties['season'], ENT_QUOTES),
                'is_visible' => 1,
                'is_variation' => 0,
                'is_taxonomy' => 0,
                'position' => $position
            );
        }
    }

    return $return;
}

This is a function that returns the proper array that get serialized and inputted into the wp_postmeta table for the meta_value where meta_key = _product_attributes. Each variation also has a meta_key of attribute_size and meta_key of attribute_extension where the meta_value equals the value of that specific variation as required within the wp_postmeta table for that posts variation ID.

I’m at a loss, trying to update the variations of a Variable Product, or when Converting a Simple Product to a Variable Product, that needs to be updated. It shows up fine in the backend admin panel of the product, but when going to the actual product page, it still shows the OLD product variations. The only way to show the new one’s is to go into the backend admin panel of the product and hit the Update button, which than shows all of the new variations. But how to do this programmatically? I thought this was possible? Must be something I’m overlooking here? Perhaps there are terms somewhere that need updating?

Functions that I have tried, that failed to update the product with the new variations, s for small = variation id 181342 and l for large = variation id 181343 from ID column of of wp_posts table or post_id column of the wp_postmeta table for that Variation:

wp_set_object_terms(181342, 's', 'size');
wp_set_object_terms(181343, 'l', 'size');

and

do_action( 'woocommerce_create_product_variation', 181342 );
do_action( 'woocommerce_create_product_variation', 181343 );

None of these update the product as a variation that shows on the front end. It still shows ONLY the old variations on the front end. How to get the size s and l showing on the front end?

Related posts

Leave a Reply

2 comments

  1. Figured it out… looks like you have to update the wp_options table using set_transient… Here’s what I did and it nipped it in the bud:

    $transients = array(
        'name' => array(
            'wc_product_total_stock_' . $product_id,
            'wc_product_children_ids_' . $product_id
        ),
        'values' => array(
            $total_stock,
            $allVariationIDs
        ),
        'filters' => array(
            'woocommerce_stock_amount'
        )
    );
    
    // Set it up so that the variations show in the front end also...
    foreach($transients['name'] as $k => $transient_name)
    {
        set_transient($transient_name, $transients['values'][$k],YEAR_IN_SECONDS);
    
        if (isset($transients['filters'][$k]))
            apply_filters($transients['filters'][$k], $transients['values'][$k]);
    }
    

    $product_id = the actual products ID value.

    $allVariationIDs = an array of all ID values of the variations within the wp_posts table. $total_stock is the new stock of the product, calculating in all variation stock levels.

    Hope this helps someone else to update their variations on the front end, after setting up all wp_posts and wp_postmeta table rows for your products and variations.