简体   繁体   中英

Unable to get functionality to work to disable out of stock product variant with sold out message

In my functions.php, I am trying to add a sold out message in the drop down menu for my product variants. So for example if I have shirt that has variants of small, medium and large and the large is out of stock, in the drop down menu the user should see the large option is disabled and contains a sold out message next to 'Large'. The other variants should remain active.

The issue I have with my code below is the following:

  • The code that is commented, this disables the correct product variant that is out of stock, but doesn't add the sold out message.
  • The active code does add the sold out message but it disables all product variants even though it's only one variant that is out of stock.

How can I fix the code to do what I need it to do?

/**
 * Disable out of stock variations
 * https://github.com/woocommerce/woocommerce/blob/826af31e1e3b6e8e5fc3c1004cc517c5c5ec25b1/includes/class-wc-product-variation.php
 * @return Boolean
 */

// function wcbv_variation_is_active( $active, $variation ) {
//  if( ! $variation->is_in_stock() ) {
//  return false;
//  }
//  return $active;
// }
// add_filter( 'woocommerce_variation_is_active', 'wcbv_variation_is_active', 10, 2 );


add_action( 'woocommerce_variation_is_active', 'woocommerce_sold_out_dropdown' );
function woocommerce_sold_out_dropdown() {
?>
<script type="text/javascript">
jQuery( document ).bind( 'woocommerce_update_variation_values', function() {

jQuery( '.variations select option' ).each( function( index, el ) {
var sold_out = '<?php _e( 'sold out', 'woocommerce' ); ?>';
var re = new RegExp( ' - ' + sold_out + '$' );
el = jQuery( el );

if ( el.is( ':disabled' ) ) {
 if ( ! el.html().match( re ) ) el.html( el.html() + ' - ' + sold_out );
} else {
if ( el.html().match( re ) ) el.html( el.html().replace( re,'' ) );
}
} );
} );
</script>
 <?php
}

You can get what you need with this code (your code):

// disable options for unavailable variants
add_filter( 'woocommerce_variation_is_active', 'wcbv_variation_is_active', 10, 2 );
function wcbv_variation_is_active( $active, $variation ) {
    if ( ! $variation->is_in_stock() ) {
        return false;
    }
    return $active;
}

And now, to change the name of each individual option based on stock status you can use the woocommerce_variation_option_name hook like so:

add_filter( 'woocommerce_variation_option_name','add_stock_status_after_option_name', 10, 1 );
function add_stock_status_after_option_name( $option ) {
    // only in frontend
    if ( is_admin() ) {
        return $option;
    }
    // get variable product object
    global $product;
    $variation_ids = $product->get_children();
    foreach ( $variation_ids as $variation_id ) {
        $variation = wc_get_product( $variation_id );
        $variation_attributes = $variation->get_variation_attributes();
        foreach ( $variation_attributes as $key => $value ) {
            // slugify option name
            $option_slug = sanitize_title( $option );
            // check if the current option is equal to the variation slug
            if ( $value == $option_slug ) {
                // check if it is out of stock
                if ( ! $variation->is_in_stock() ) {
                    return $option . ' (Out of stock)';
                }
            }
        }
    }
    return $option;
}

The code has been tested and works correctly. It needs to be added to your theme's functions.php.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM