如何将变体库存状态添加到 Woocommerce 产品变体下拉列表

Posted

技术标签:

【中文标题】如何将变体库存状态添加到 Woocommerce 产品变体下拉列表【英文标题】:How to add variation stock status to Woocommerce product variation dropdown 【发布时间】:2018-04-21 03:51:44 【问题描述】:

我想显示 Woocommerce 产品页面上变体下拉列表中显示的每个产品变体的库存状态(例如,有货/缺货)。我已将相关函数复制到主题的 functions.php 文件中,并且可以编辑内容,但不确定如何提取每个变体所需的库存状态。

// 更新了 Woocommerce 产品变体选择 如果(!function_exists('wc_dropdown_variation_attribute_options')) /** * 输出用于购物车表单的变体属性列表。 * * @param 数组 $args * @since 2.4.0 */ /* 函数 wc_dropdown_variation_attribute_options( $args = array() ) $args = wp_parse_args(apply_filters('woocommerce_dropdown_variation_attribute_options_args',$args),数组( '选项' => 假, '属性' => 假, '产品' => 假的, '选中' => 假, '名称' => '', 'id' => '', '类' => '', 'show_option_none' => __( '选择一个选项', 'woocommerce' ), )); $options = $args['options']; $product = $args['product']; $attribute = $args['attribute']; $name = $args['name'] ? $args['name'] : 'attribute_' 。 sanitize_title($属性); $id = $args['id'] ? $args['id'] : sanitize_title($attribute); $class = $args['class']; $show_option_none = $args['show_option_none'] ?真假; $show_option_none_text = $args['show_option_none'] ? $args['show_option_none'] : __( '选择一个选项', 'woocommerce' ); // 我们会尽力隐藏占位符,但是在重置选项时我们需要显示一些东西。 如果(空($options)&&!空($product)&&!空($attribute)) $attributes = $product->get_variation_attributes(); $options = $attributes[ $attribute ]; $html = ''; $html .= '' 。 esc_html($show_option_none_text)。 ''; if ( !empty( $options ) ) if ( $product && taxonomy_exists( $attribute ) ) // 如果这是分类法,则获取术语 - 已排序。我们也需要名字。 $terms = wc_get_product_terms($product->get_id(), $attribute, array('fields' => 'all')); foreach ( $terms 作为 $term ) if ( in_array( $term->slug, $options ) ) $html .= '蛞蝓)。 '" ' . selected( sanitize_title( $args['selected'] ), $term->slug, false ) . '>' . esc_html( apply_filters( 'woocommerce_variation_option_name', $term->name ) ) . ' '; 别的 foreach ( $options 作为 $option ) // 这会处理未清理文本属性的 lt 2.4.0 bw 兼容性。 $selected = sanitize_title( $args['selected'] ) === $args['selected'] ? selected($args['selected'], sanitize_title($option), false) : selected($args['selected'], $option, false); $html .= '' 。 esc_html( apply_filters( 'woocommerce_variation_option_name', $option ) ) 。 '在此处输出库存详细信息'; $html .= ''; 回声应用过滤器('woocommerce_dropdown_variation_attribute_options_html',$html,$args);

我可以提取整个产品的库存水平,但现在针对每个变体。

任何帮助将不胜感激。

【问题讨论】:

确实如此,但是,下面 Ali_k 的解决方案似乎已经成功了。 Ali_k 的解决方案在变量产品中有多个选择字段时并不能真正起作用……我在下面提供了一个更新的答案。检查最后的屏幕截图。从逻辑上讲,如果您真的考虑它,这是行不通的(对于具有多个选项值的多个选择字段)。 对于产品页面上具有多个属性(下拉菜单)的可变产品:***.com/questions/67352047/… 【参考方案1】:

2021 年更新 (仅适用于具有1 个下拉菜单 的可变产品)-感谢@Alex Banks

无论如何,当有只有一个下拉选择字段时,这将真正起作用(所以变体只有一个属性)。

具有多个属性(因此有多个下拉选择字段),它会根据不同的库存状态属性术语组合显示可能出错的内容。

请看最后显示错误展示柜的屏幕截图……

我尝试了 Ali_k 的代码,但是当变量产品有多个下拉菜单时,它在我的测试服务器中不起作用

所以我对 Ali_k 的代码进行了一些更改,以使其在我的测试服务器中工作(使用最新的 WooCommerce 版本)

要处理延期交货,请参阅:Add backorders stock status to Woocommerce variable product dropdown

代码:

// Function that will check the stock status and display the corresponding additional text
function get_stock_status_text( $product, $name, $term_slug )
    foreach ( $product->get_available_variations() as $variation )
        if($variation['attributes'][$name] == $term_slug ) 
            $stock = $variation['is_in_stock'];
            break;
        
    
    return $stock == 1 ? ' - (In Stock)' : ' - (Out of Stock)';


// The hooked function that will add the stock status to the dropdown options elements.
add_filter( 'woocommerce_dropdown_variation_attribute_options_html', 'show_stock_status_in_dropdown', 10, 2);
function show_stock_status_in_dropdown( $html, $args ) 
    // Only if there is a unique variation attribute (one dropdown)
    if( sizeof($args['product']->get_variation_attributes()) == 1 ) :

    $options               = $args['options'];
    $product               = $args['product'];
    $attribute             = $args['attribute']; // The product attribute taxonomy
    $name                  = $args['name'] ? $args['name'] : 'attribute_' . sanitize_title( $attribute );
    $id                    = $args['id'] ? $args['id'] : sanitize_title( $attribute );
    $class                 = $args['class'];
    $show_option_none      = $args['show_option_none'] ? true : false;
    $show_option_none_text = $args['show_option_none'] ? $args['show_option_none'] : __( 'Choose an option', 'woocommerce' );

    if ( empty( $options ) && ! empty( $product ) && ! empty( $attribute ) ) 
        $attributes = $product->get_variation_attributes();
        $options    = $attributes[ $attribute ];
    

    $html = '<select id="' . esc_attr( $id ) . '" class="' . esc_attr( $class ) . '" name="' . esc_attr( $name ) . '" data-attribute_name="attribute_' . esc_attr( sanitize_title( $attribute ) ) . '" data-show_option_none="' . ( $show_option_none ? 'yes' : 'no' ) . '">';
    $html .= '<option value="">' . esc_html( $show_option_none_text ) . '</option>';

    if ( ! empty( $options ) ) 
        if ( $product && taxonomy_exists( $attribute ) ) 
            $terms = wc_get_product_terms( $product->get_id(), $attribute, array( 'fields' => 'all' ) );

            foreach ( $terms as $term ) 
                if ( in_array( $term->slug, $options ) ) 
                    // HERE Added the function to get the text status
                    $stock_status = get_stock_status_text( $product, $name, $term->slug );
                    $html .= '<option value="' . esc_attr( $term->slug ) . '" ' . selected( sanitize_title( $args['selected'] ), $term->slug, false ) . '>' . esc_html( apply_filters( 'woocommerce_variation_option_name', $term->name ) . $stock_status ) . '</option>';
                
            
         else 
            foreach ( $options as $option ) 
                $selected = sanitize_title( $args['selected'] ) === $args['selected'] ? selected( $args['selected'], sanitize_title( $option ), false ) : selected( $args['selected'], $option, false );
                // HERE Added the function to get the text status
                $stock_status = get_stock_status_text( $product, $name, $option );
                $html .= '<option value="' . esc_attr( $option ) . '" ' . $selected . '>' . esc_html( apply_filters( 'woocommerce_variation_option_name', $option ) . $stock_status ) . '</option>';
            
        
    
    $html .= '</select>';

    endif;

    return $html;

代码进入您的活动子主题(或主题)的 function.php 文件或任何插件文件中。

在可变产品中测试和工作只有一个变体属性


使用 Ali_K 的代码,这里是一个可变产品的错误显示文本示例具有多个选择字段 (因此有多个变体属性)

【讨论】:

【参考方案2】:

好的,首先你需要得到这样的产品变体:

$variations = $product->get_available_variations();

在期权循环中,您需要遍历变体并找到当前期权库存状态

foreach ($variations as $variation) 
    if($variation['attributes'][$name] == $option) 
        $stock = $variation['is_in_stock'];

    

在变体循环之外,您需要添加有货和缺货变体的措辞

if( $stock == 1) 
    $stock_content = ' - In stock';
 else 
    $stock_content = ' - Out of stock';

然后更改 html 以包含一个附加变量 ($stock_content)

$html .= '<option value="' . esc_attr( $option ) . '" ' . $selected . '>' . esc_html( $option  .  $stock_content ) . '</option>'; 

所以一个完整的函数应该是这样的:

add_filter( 'woocommerce_dropdown_variation_attribute_options_html', 'show_stock_status_in_dropdown', 10, 2);
function show_stock_status_in_dropdown( $html, $args ) 
    $options = $args['options']; 
    $product = $args['product']; 
    $attribute = $args['attribute']; 
    $name = $args['name'] ? $args['name'] : 'attribute_' . sanitize_title( $attribute ); 
    $id = $args['id'] ? $args['id'] : sanitize_title( $attribute ); 
    $class = $args['class']; 
    $show_option_none = $args['show_option_none'] ? true : false; 
    $show_option_none_text = $args['show_option_none'] ? $args['show_option_none'] : __( 'Choose an option', 'woocommerce' ); 

  // Get all product variations
    $variations = $product->get_available_variations();

    if ( empty( $options ) && ! empty( $product ) && ! empty( $attribute ) )  
        $attributes = $product->get_variation_attributes(); 
        $options = $attributes[ $attribute ]; 
     

    $html = '<select id="' . esc_attr( $id ) . '" class="' . esc_attr( $class ) . '" name="' . esc_attr( $name ) . '" data-attribute_name="attribute_' . esc_attr( sanitize_title( $attribute ) ) . '" data-show_option_none="' . ( $show_option_none ? 'yes' : 'no' ) . '">'; 
    $html .= '<option value="">' . esc_html( $show_option_none_text ) . '</option>'; 

    if ( ! empty( $options ) )  
        if ( $product && taxonomy_exists( $attribute ) )  
          // Get terms if this is a taxonomy - ordered. We need the names too. 
          $terms = wc_get_product_terms( $product->get_id(), $attribute, array( 'fields' => 'all' ) ); 

          foreach ( $terms as $term )  
                if ( in_array( $term->slug, $options ) )  
                    $html .= '<option value="' . esc_attr( $term->slug ) . '" ' . selected( sanitize_title( $args['selected'] ), $term->slug, false ) . '>' . esc_html( apply_filters( 'woocommerce_variation_option_name', $term->name ) ) . '</option>'; 
                 
            
         else 
            foreach ( $options as $option ) 
                    foreach ($variations as $variation) 
                        if($variation['attributes'][$name] == $option) 
                            $stock = $variation['is_in_stock'];
                        
                           
                if( $stock == 1) 
                    $stock_content = ' - (In Stock)';
                 else 
                    $stock_content = ' - (Out of Stock)';
                
                 // This handles < 2.4.0 bw compatibility where text attributes were not sanitized. 
                $selected = sanitize_title( $args['selected'] ) === $args['selected'] ? selected( $args['selected'], sanitize_title( $option ), false ) : selected( $args['selected'], $option, false ); 

                $html .= '<option value="' . esc_attr( $option ) . '" ' . $selected . '>' . esc_html( $option  .  $stock_content ) . '</option>'; 

            
         
     

    $html .= '</select>'; 

    return $html;

【讨论】:

【参考方案3】:

@LoicTheAztec

我也一直在使用您更新的代码来替换延期交货函数,但由于函数调用不存在而遇到错误。

get_the_stock_status() 现在是 get_stock_status() 不是吗?

无论如何,下面的更新代码解决了这个问题以及我遇到的礼品卡插件由于上述错误而无法加载的问题。

// Function that will check the stock status and display the corresponding additional text
function get_stock_status_text( $product, $name, $term_slug )
    foreach ( $product->get_available_variations() as $variation )
        if($variation['attributes'][$name] == $term_slug ) 
            $is_in_stock = $variation['is_in_stock'];
            $backordered = get_post_meta( $variation['variation_id'], '_backorders', true );
            $stock_qty   = get_post_meta( $variation['variation_id'], '_stock', true );
            break;
        
    
    $stock_status_text = $is_in_stock == 1 ? ' - (In Stock)' : ' - (Out of Stock)';
    return $backordered !== 'no' && $stock_qty <= 0 ? ' - (On Backorder)' : $stock_status_text;


// The hooked function that will add the stock status to the dropdown options elements.
add_filter( 'woocommerce_dropdown_variation_attribute_options_html', 'show_stock_status_in_dropdown', 10, 2);
function show_stock_status_in_dropdown( $html, $args ) 

    // Only if there is a unique variation attribute (one dropdown)
    if( sizeof($args['product']->get_variation_attributes()) == 1 ) :

    $options               = $args['options'];
    $product               = $args['product'];
    $attribute             = $args['attribute']; // The product attribute taxonomy
    $name                  = $args['name'] ? $args['name'] : 'attribute_' . sanitize_title( $attribute );
    $id                    = $args['id'] ? $args['id'] : sanitize_title( $attribute );
    $class                 = $args['class'];
    $show_option_none      = $args['show_option_none'] ? true : false;
    $show_option_none_text = $args['show_option_none'] ? $args['show_option_none'] : __( 'Choose an option', 'woocommerce' );

    if ( empty( $options ) && ! empty( $product ) && ! empty( $attribute ) ) 
        $attributes = $product->get_variation_attributes();
        $options    = $attributes[ $attribute ];
    

    $html = '<select id="' . esc_attr( $id ) . '" class="' . esc_attr( $class ) . '" name="' . esc_attr( $name ) . '" data-attribute_name="attribute_' . esc_attr( sanitize_title( $attribute ) ) . '" data-show_option_none="' . ( $show_option_none ? 'yes' : 'no' ) . '">';
    $html .= '<option value="">' . esc_html( $show_option_none_text ) . '</option>';

    if ( ! empty( $options ) ) 
        if ( $product && taxonomy_exists( $attribute ) ) 
            $terms = wc_get_product_terms( $product->get_id(), $attribute, array( 'fields' => 'all' ) );

            foreach ( $terms as $term ) 
                if ( in_array( $term->slug, $options ) ) 
                    // HERE Added the function to get the text status
                    $stock_status = get_stock_status_text( $product, $name, $term->slug );
                    $html .= '<option value="' . esc_attr( $term->slug ) . '" ' . selected( sanitize_title( $args['selected'] ), $term->slug, false ) . '>' . esc_html( apply_filters( 'woocommerce_variation_option_name', $term->name ) . $stock_status ) . '</option>';
                
            
         else 
            foreach ( $options as $option ) 
                $selected = sanitize_title( $args['selected'] ) === $args['selected'] ? selected( $args['selected'], sanitize_title( $option ), false ) : selected( $args['selected'], $option, false );
                // HERE Added the function to get the text status
                $stock_status = get_stock_status( $product, $name, $option );
                $html .= '<option value="' . esc_attr( $option ) . '" ' . $selected . '>' . esc_html( apply_filters( 'woocommerce_variation_option_name', $option ) . $stock_status ) . '</option>';
            
        
    
    $html .= '</select>';

    endif;

    return $html;

【讨论】:

函数名称get_the_stock_status( $product, $name, $option )在我的代码中有错误,需要替换为get_stock_status_text( $product, $name, $option ),但**不能替换为get_stock_status(),这是WooCommerce WC_Product 方法而不是函数。【参考方案4】:

我修改了您的代码,以便仅在下拉菜单中显示库存变化。我做了 $stock return bool,然后

if ($stock_status)
            $html .= '<option value="' . esc_attr( $option ) . '" ' . $selected . '>' . esc_html( apply_filters( 'woocommerce_variation_option_name', $option ) /*. $stock_status*/ ) . '</option>';
            

如果您能想到更好的方法来做到这一点,将不胜感激。 P.S 感谢您提供此解决方案,我不敢相信这不是隐藏缺货变体的默认 woocommerce 行为。

【讨论】:

以上是关于如何将变体库存状态添加到 Woocommerce 产品变体下拉列表的主要内容,如果未能解决你的问题,请参考以下文章

当所有变体的库存水平为 0 时,以编程方式复制 WooCommerce 产品

在Woocommerce中添加并保存管理产品变体自定义字段

如果不在商店中,则隐藏产品变体 - WooCommerce

将高级自定义字段添加到 WooCommerce 产品变体

如果数量超过产品库存,Woocommerce 如何添加消息

如何获得 Woocommerce 变体 ID?