Search code examples
phpwordpresswoocommerceproduct-variations

Custom display based on Woocommerce product variations stock data checkbox option


I am trying to add a custom message to variation products, based on their stock quantity and stock status.

So far I got this:

function load_variation_settings_fields( $variation_data, $product, $variation ) {

    // Display shipping delay text when stock quantity exist
    if( $variation->get_stock_quantity() > 0 )
        $variation_data['text_field'] = __('<p class="stock in-stock">Stock: <span>På lager</span><br>Delivery: <span>2-12 hverdage</span></p>'); 
    else $variation_data['text_field'] = __('<p class="stock in-stock">Stock: <span>Out of stock</span><br>Delivery: <span>4-6 weeks</span></p>');

    return $variation_data;
}

It works, and displays the message based on the quantity of each variation, but I need this to only work for one type of stock status (a custom one). I would need to display a different message for a different variation stock status. This is what I have tried:

function load_variation_settings_fields( $variation_data, $product, $variation ) {

    // Display shipping delay text when stock quantity exist
    if( $variation->get_stock_quantity() > 0 && ($stockstatus == 'customstatus'))
        $variation_data['text_field'] = __('<p class="stock in-stock">Stock: <span>In stock</span><br>Delivery: <span>2-12 days</span></p>'); 
    elseif ( ($stockstatus == 'customstatus') )
    $variation_data['text_field'] = __('<p class="stock in-stock">Stock: <span>Out of stock</span><br>Delivery: <span>4-6 weeks</span></p>');

    return $variation_data;
}

It is displayed with this, in the variation.php file:

<div class="woocommerce-variation-custom-text-field">{{{ data.variation.text_field }}}</div>

EDIT: This is my latest attempt, as my custom stock status is stored in the '_stock_status' meta value. Still doesn't work though.

    function load_variation_settings_fields( $variation_data, $product, $variation ) {
    $stockstatus = $product->get_attribute( '_stock_status' );
if( ($stockstatus == 'bestillingsvare') ) {
        // Display shipping delay text when stock quantity exist
        if( $variation->get_stock_quantity() > 0 )
            $variation_data['text_field'] = __('<p class="stock in-stock">Stock: <span>På lager</span><br>Delivery: <span>2-12 hverdage</span></p>'); 
        else $variation_data['text_field'] = __('<p class="stock in-stock">Stock: <span>Out of stock</span><br>Delivery: <span>4-6 weeks</span></p>');
  }
        return $variation_data;
    }

Solution

  • As we don't know really how you set your custom status 'bestillingsvare', it's not possible to reproduce the problem. Next time, it should be necessary to add all related code in your question.

    So here is a similar working solution, with an additional custom setting in your product variations that works for real.

    First, you need to add the following line in /single-product/add-to-cart/variation.php template file:

    <div class="woocommerce-variation-delivery">{{{ data.variation.delivery_html }}}</div>
    

    Then the revisited complete code:

    // Add variation custom checkbox setting option field
    add_action( 'woocommerce_variation_options', 'add_variation_delivery_status_option', 20, 3 );
    function add_variation_delivery_status_option ( $loop, $variation_data, $post_object ) {
        $checked = get_post_meta( $post_object->ID, '_delivery_option', true ) ? true : false;
        ?>
        <label class="tips" data-tip="<?php _e( 'Enable', 'woocommerce' ); ?>">
        <?php _e( 'Delivery?', 'woocommerce' ); ?>
            <input type="checkbox" class="checkbox variation_delivery_option" name="delivery_option_<?php
            echo $loop; ?>" <?php checked( $checked, true ); ?> />
        </label>
        <?php
    }
    
    // Save variation custom checkbox setting option field value
    add_action( 'woocommerce_save_product_variation', 'save_variation_delivery_status_option', 20, 2 );
    function save_variation_delivery_status_option( $variation_id, $i ) {
        $value = isset( $_POST['delivery_option_'.$i] ) ? true : false;
        update_post_meta( $variation_id, '_delivery_option', $value );
    }
    
    // Display in front end the delivery info
    add_filter( 'woocommerce_available_variation', 'display_variation_delivery_status_option', 20, 3 );
    function display_variation_delivery_status_option( $variation_data, $product, $variation ) {
        if( get_post_meta( $variation->get_id(), '_delivery_option', true ) ) {
            $stock_qty      = $variation->get_stock_quantity();
    
            $stock_class    = $stock_qty > 0 ? 'stock in-stock' : 'stock out-of-stock';
            $stock_label    = $stock_qty > 0 ? __('På lager') : __('Out of stock');
            $delivery_delay = $stock_qty > 0 ? __('2-12 hverdage') : __('4-6 weeks');
    
            // Display a shipping delay text when stock quantity exist
            $variation_data['delivery_html'] = sprintf(
                '<p class="%s">' . __('Stock') . ': <span>%s</span><br>
                ' . __('Delivery') . ': <span>%s</span></p>',
                $stock_class, $stock_label, $delivery_delay
            );
        }
        return $variation_data;
    }
    

    Code goes in function.php file of your active child theme (or active theme). It should work.

    In backend variation settings (enabling the delivery option):

    enter image description here

    In Front-end option activated when "In stock":

    enter image description here

    In Front-end option activated when "Out of stock":

    enter image description here

    But as you see to avoid duplicated information, you could use existing availability_html to change the displayed data adding your delivery information to it instead.

    In this case you will not override /single-product/add-to-cart/variation.php template as it is not needed any more, and you will replace in the last function

    $variation_data['delivery_html']
    

    by

    $variation_data['availability_html']
    

    Making the necessary other changes to the code, to get the desired display.