【问题标题】:Showing "Out of Stock" text next to variation in Woocommerce product with multuiple variations在具有多种变体的 Woocommerce 产品变体旁边显示“缺货”文本
【发布时间】:2021-07-24 20:50:48
【问题描述】:

我一直在到处寻找,但似乎找不到解决一个非常简单问题的方法。我有一家 Woocommerce 商店,如果缺货,我想在变体旁边向用户显示“缺货”消息。我不希望它变灰,我希望用户能够选择它,以便他们可以根据需要查看价格。我在网上找到的大多数 sn-ps 仅在他们的产品有一个变体时才有效,但我需要它至少可以工作两个。我的网站销售移动设备,例如:

如果用户选择 64GB 存储空间,则颜色列表会更新,显示 64GB 中哪些颜色缺货。如果所有颜色都缺货,那么在 64GB 旁边也会显示“缺货”。

如果先选择颜色,则存储-颜色列表然后更新缺货。

有人可以帮我吗?试图让这个工作变得疯狂。下面的代码以我上面提到的确切方式使缺货产品变灰(它适用于多种产品),但我不知道如何针对上述用例进行修改。

add_filter( 'woocommerce_variation_is_active', 'grey_out_variations_when_out_of_stock', 10, 2 );
function grey_out_variations_when_out_of_stock( $grey_out, $variation ){
if ( ! $variation->is_in_stock() ){
  return false;
 }else{
print_r($option_class);
  return $term_name . ' - Out of Stock';;
 }
}

【问题讨论】:

标签: wordpress woocommerce variations


【解决方案1】:

您可以检查产品变体的可用性只有在选择了除一个属性之外的所有属性时,而不是之前。

所有必要的数据都显示在产品页面上,因此您可以使用 jQuery 脚本来处理它。

在变体表单中有 data-product_variations 属性,其中包含一个包含产品变体所有详细信息(变体 ID、库存状态、它使用的属性等)的数组。

然后,您可以在所选属性和可能的​​产品变体之间进行比较。

想法是这样的:

  1. 检查产品页面上是否有多个属性(下拉菜单)
  2. 如果除了一个之外的所有属性(下拉菜单)都被选中,获取属性段和所选选项的属性值
  3. 它将它们与每个变体使用的属性进行比较,如果选择的属性相同,获取最后一个要选择的属性的库存状态
  4. 将文本“缺货”添加到产品变体无库存的每个选项。为此,它将使用woocommerce_update_variation_values 事件,该事件在通过 Ajax 更新选项后触发(否则更改将被覆盖)

以下代码适用于 2 个或更多属性(下拉菜单) 可变产品页面。

// add the text "Out of stock" to each option of the last unselected attribute dropdown
add_action( 'wp_footer', 'add_out_of_stock_text_to_the_last_unselected_attribute_dropdown' );
function add_out_of_stock_text_to_the_last_unselected_attribute_dropdown() {

    ?>
    <script type="text/javascript">

    // initializes a global variable that will contain the attribute values to be updated ("Out of stock")
    let globalAttributesToUpdate;

    jQuery(function($){

        // check if only one attribute is missing to be selected
        function isLastAttribute(){
            // if there is only one dropdown it returns false
            if ( $('form.variations_form select').length == 1 ) {
                return false;
            }
            // counts all selected attributes (excluding "Choose an option")
            let count = 0;
            $('form.variations_form select').each(function(){
                if ( $(this).find(':selected').val() ) {
                    count++;
                }
            });
            // if an attribute has not yet been selected, it returns true
            if ( $('form.variations_form select').length - count == 1 ) {
                return true;
            } else {
                return false;
            }
        }

        $('form.variations_form select').change(function() {
            if ( isLastAttribute() ) {
                // clear the global variable every time
                globalAttributesToUpdate = [];
                let attrToFind = {}; // contains an object with slug and value of the selected attributes
                let attrToSet; // contains the slug of the attribute not yet selected
                $('form.variations_form select').each(function(index,object){
                    if ( $(this).find(":selected").val() ) {
                        attrToFind[$(this).data('attribute_name')] = $(this).find(":selected").val();
                    } else {
                        attrToSet = $(this).data('attribute_name');
                    }
                });
                // gets the value of the "data-product_variations" attribute of the variations form
                let variationData = $('form.variations_form').data("product_variations");
                $(variationData).each(function(index,object) {
                    let attrVariation = object.attributes;
                    let attrVariationLenght = Object.keys(attrVariation).length;
                    let found = 0;
                    let toSet;
                    let valueToSet;
                    // check all possible combinations of attributes (for single variation)
                    // based on the selected attributes
                    $.each( attrVariation, function( attr, value ) {
                        if ( attr in attrToFind && attrToFind[attr] == value ) {
                            found++;
                        } else {
                            // if the variation is out of stock it gets slug and value to add the text "Out of stock"
                            if ( object.is_in_stock == false ) {
                                toSet = attr;
                                valueToSet = value;
                            }
                        }
                    });
                    // if only one attribute is missing
                    if ( attrVariationLenght - found == 1 ) {
                        if ( toSet == attrToSet ) {
                            let obj = {};
                            obj[toSet] = valueToSet;
                            globalAttributesToUpdate.push(obj);
                        }
                    }
                });
            }
        });

        // inserts the text "Out of stock" after updating the variations
        // based on the "globalAttributesToUpdate" global variable
        $('body').on('woocommerce_update_variation_values', function(){
            if ( globalAttributesToUpdate !== undefined && globalAttributesToUpdate.length ) {
                $.each( globalAttributesToUpdate, function( key, attribute ) {
                    $.each( attribute, function( attrName, attrValue ) {
                        $('select[name='+attrName+'] > option[value="'+attrValue+'"]').append( " (Out of stock)" );
                    });
                });
            }
        });
    });
    </script>
    <?php

}

代码已经过测试并且可以运行。将其添加到活动主题的 functions.php 中。

结果

相关答案

【讨论】:

  • 您的代码运行良好!!这正是我的想法。太感谢了。我还有一个问题:如果基于第一个选择的变体,所有变体都缺货,是否可以为第二个变体添加缺货文本?例如,一部手机有两个属性:存储和颜色。用户选择他们所需的存储空间,但所有变体都缺货,因此存储空间立即在其旁边显示缺货文本
【解决方案2】:

add_filter('woocommerce_variation_option_name', 'display_price_in_variation_option_name');
function display_price_in_variation_option_name($term)
{
    global $wpdb, $product;
    $result = $wpdb->get_col("SELECT slug FROM {$wpdb->prefix}terms WHERE name = '$term'");
    $term_slug = (!empty($result)) ? $result[0] : $term;
    $query = "SELECT postmeta.post_id AS product_id
                FROM {$wpdb->prefix}postmeta AS postmeta
                    LEFT JOIN {$wpdb->prefix}posts AS products ON ( products.ID = postmeta.post_id )
                WHERE postmeta.meta_key LIKE 'attribute_%'
                    AND postmeta.meta_value = '$term_slug'
                    AND products.post_parent = $product->id";
    $variation_id = $wpdb->get_col($query);
    $parent = wp_get_post_parent_id($variation_id[0]);
    if ($parent > 0) {
        $_product = new WC_Product_Variation($variation_id[0]);
        $_currency = get_woocommerce_currency_symbol();
        $stock = $_product->is_in_stock() ? 'instock' : 'out of stock';
        return $term . ' (' . $_product->get_price()  . ' ' . $_currency . ') &nbsp;- &nbsp;' . $stock;
    }
    return $term;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-24
    • 2020-11-30
    • 2021-06-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多