Get the count of “in stock” product variations for

2020-06-28 16:16发布

问题:

I'm trying to make a snippet for functions.php file that shows only one price of selected variation, thus omitting the price range displayed along with variation price on single product page. I'm using the following code:

    add_action( 'woocommerce_before_single_product', 'my_remove_variation_price' );
$product_variations=$product_variable->get_available_variations;
function my_remove_variation_price() {
  global $product;
  if ( $product->is_type( 'variable' ) {
    remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_price' );
  }
}

The problem is when you have, for instance, two variations of single product and one goes out of stock, this script hides the price of one remaining variation on single product page. I was thinking maybe to have a COUNT of available variations per product and use IF to show them using standard single product template. Or maybe you have better idea how to solve that?

回答1:

To get the "in stock" variations count of a variable product on single product pages you can:

1) Use only php and Woocommerce WC_Product methods:

global $product;
$count_in_stock = 0;

if ( $product->is_type( 'variable' ) ) {
    $variation_ids = $product->get_children(); // Get product variation IDs

    foreach( $variation_ids as $variation_id ){
        $variation = wc_get_product($variation_id);
        if( $variation->is_in_stock() )
            $count_in_stock++;
    }
}

// Your condition
if( $count_in_stock <= 1 ){
   // Do something
}

2) Use a SQL query with few php (quick and lighter):

global $wpdb, $product;
$product_id = $product->get_id();
$count_in_stock = 0;

if ( $product->is_type( 'variable' ) ) {
    $count = $wpdb->get_col("
        SELECT count(p.ID) as in_stock_count FROM {$wpdb->prefix}postmeta as pm
        INNER JOIN {$wpdb->prefix}posts as p ON pm.post_id = p.ID
        WHERE p.post_type LIKE 'product_variation' AND p.post_parent = $product_id
        AND pm.meta_key LIKE '_stock_status' AND pm.meta_value LIKE 'instock'
    ");

    $count_in_stock = reset($count);
}

// Your condition
if( $count_in_stock <= 1 ){
   // Do something
}      

Both codes are tested and work.



回答2:

This is my Final working code, achieved with the help of LoicTheAztec answer:

add_action( 'woocommerce_before_single_product', 'my_remove_variation_price' );
function my_remove_variation_price() {
    global $product;
    $count_in_stock = 0;

    if ( $product->is_type( 'variable' )) {

        $variation_ids = $product->get_children(); // Get product variation IDs

        foreach( $variation_ids as $variation_id ){
            $variation = wc_get_product($variation_id);
            if( $variation->is_in_stock() )
                $count_in_stock++;
        }   
    }

    if( $count_in_stock <= 1 ) 
    {
        remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_price' );
    }   

}