4

I have this code that works for simple product type but not for variable products in WooCommerce:

add_shortcode( 'product_sku_div', 'wc_product_sku_div'); 
function wc_product_sku_div() { 
    global $product;

    return sprintf( '<div class="widget" sp-sku="%s"></div>', $product->get_sku() );
}

How can I make it work for both simple and variable products?

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
neptunee
  • 77
  • 1
  • 4

3 Answers3

6

To make it work also for variable products and their variations, it requires Javascript (jQuery) to get the selected variation SKU for variable products.

Try the following that works for simple an variable product types, displaying the selected variation SKU for variable products:

add_shortcode( 'product_sku_div', 'wc_product_sku_div');
function wc_product_sku_div() {
    global $product;

    if( ! is_a('WC_Product', $product) ) {
        $product = wc_get_product( get_the_id() );
    }

    ## 1 - For variable products (and their variations)
    if( $product->is_type('variable') ) {
        ob_start(); // Starting buffering

        ?>
        <div class="widget" sp-sku=""></div>
        <script type="text/javascript">
        jQuery( function($){
            $('form.variations_form').on('show_variation', function( event, data ){
                $( 'div.widget' ).attr( 'sp-sku', data.sku );
                // For testing
                console.log( 'Variation Id: ' + data.variation_id + ' | Sku: ' + data.sku );
            });
            $('form.variations_form').on('hide_variation', function(){
                $( 'div.widget' ).attr( 'sp-sku', '' );
            });
        });
        </script><?php

        return ob_get_clean(); // return the buffered content
    }
    ## 2 - For other products types
    else {
        return sprintf( '<div class="widget" sp-sku="%s"></div>', $product->get_sku() );
    }
}

Code goes in functions.php file of your active child theme (or active theme). Tested and work.

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • Thanks that is working but it is failing due to the script I'm using adding additional classes. "sp-enabled" and "sp-disabled" once it locks in those classes the SKU changes but since the classes don't, the button doesn't change. Is there a way to refresh all classes that the script might add? – neptunee Feb 18 '20 at 18:13
  • @neptunee My answer here is answering your initial question (with the code and explanations you provide). Using javascript is the only way to make it work as it involves a live evet on client side. Now as you are using something else that is making trouble you should ask a new question providing all the necessary code, to reproduce the issue. Without that nobody could help. – LoicTheAztec Feb 19 '20 at 23:23
2

You need the Variation ID to get the SKU of Variable Product.

If you pass the Variation ID in the below Function, then you can get its SKU.

$product = new WC_Product_Variation($variation_id);
$product->get_sku();

The below code can be used to get the variations of a product. Then lopp the result to get the variation ID and then use that variation ID in the above code to get the result.

$variations = $product->get_available_variations();
Rajeev
  • 1,376
  • 2
  • 15
  • 33
  • Is there a way to refresh the div when a new variable is selected? – neptunee Feb 18 '20 at 06:58
  • Yes, You can refresh the Div using Ajax or you can change the value of div using jQuery based on the selected option. https://stackoverflow.com/questions/42786309/ajax-refresh-div-only-if-variable-changed https://codepen.io/atelierbram/pen/gusxF If my above code solves your question, then do accept it as Answer. – Rajeev Feb 18 '20 at 07:36
1

You need to use get_available_variations();.

add_shortcode( 'product_sku_div', 'wc_product_sku_div'); 
function wc_product_sku_div() { 
    global $product;

    $variants_array = $product->get_available_variations();

    for ($i = 0; $i <  count($variants_array); $i++ ) {
        return sprintf( '<div class="widget" sp-sku="%s"></div>', $variants_array[$i]['sku'] );
    }
}

Reference:

bstone
  • 41
  • 3
  • Hi I think this would work but it appears when a new variable is selected the div is not refreshing. Is there a way to refresh the div when a different variation is selected? – neptunee Feb 18 '20 at 06:53