如何根据 woo Commerce 中的变体库存状态更改变体颜色?

How to change variation color based on variation stock status in woo commerce?

在使用 WordPress + Woocommerce 构建的网站上工作,我正在尝试更改产品页面上的属性背景颜色(如果它处于延期交货状态)。

例如,尺寸 4 应该有不同的背景颜色,因为它缺货并且可以延期交货:

WPClever 的 WPC 变体样本 用于属性。

我正在 functions.php 中实现以下代码:

function is_on_backorder() {
    if ( 'onbackorder' === $this->get_stock_status() ) {
        ?>

        <script>
        ( function( $ ) {
            'use strict';
                $( '.wpcvs-term span' ).css("background-color","red");
             ;
        } ( jQuery ) );
    </script>
<?php }
}

这就是 HTML 的样子:

<div class="wpcvs-terms wpcvs-type-button wpcvs-style-rounded" data-attribute="pa_size">
    <span class="wpcvs-term wpcvs-enabled wpcvs-selected" aria-label="US 4" title="US 4" data-term="us-4">
        <span>US 4</span>
    </span>
    <span class="wpcvs-term wpcvs-enabled" aria-label="US 4.5" title="US 4.5" data-term="us-4-5">
        <span>US 4.5</span>
    </span>
    <span class="wpcvs-term wpcvs-enabled" aria-label="US 5" title="US 5" data-term="us-5">
        <span>US 5</span>
    </span>
    <span class="wpcvs-term wpcvs-enabled" aria-label="US 5.5" title="US 5.5" data-term="us-5-5">
        <span>US 5.5</span>
    </span>
    <span class="wpcvs-term wpcvs-enabled" aria-label="US 6" title="US 6" data-term="us-6">
        <span>US 6</span>
    </span>
    <span class="wpcvs-term wpcvs-enabled" aria-label="US 6.5" title="US 6.5" data-term="us-6-5">
        <span>US 6.5</span>
    </span>
    <span class="wpcvs-term wpcvs-enabled" aria-label="US 7" title="US 7" data-term="us-7">
        <span>US 7</span>
    </span>
    <span class="wpcvs-term wpcvs-enabled" aria-label="US 7.5" title="US 7.5" data-term="us-7-5">
        <span>US 7.5</span>
    </span>
    <span class="wpcvs-term wpcvs-enabled" aria-label="US 8" title="US 8" data-term="us-8">
        <span>US 8</span>
    </span>
</div>

这段代码有什么问题?我应该添加一个动作吗?怎么样?

首先,您必须覆盖该变体开关的 HTML。为此,您可以使用 woocommerce_dropdown_variation_attribute_options_html 过滤器挂钩。

但是你必须删除 WPC Variation Swatches 插件的默认过滤器钩子。

下面的函数是帮助您删除在-class 方法中定义的默认过滤器。感谢remove_action or remove_filter with external classes?

function remove_class_action ( $action,$class,$method ) {
    global $wp_filter ;
    if (isset($wp_filter[$action])) {
        $len = strlen($method) ;
        foreach ($wp_filter[$action] as $pri => $actions) {
            foreach ($actions as $name => $def) {
                if (substr($name,-$len) == $method) {
                    if (is_array($def['function'])) {
                        if (get_class($def['function'][0]) == $class) {
                            if (is_object($wp_filter[$action]) && isset($wp_filter[$action]->callbacks)) {
                                unset($wp_filter[$action]->callbacks[$pri][$name]) ;
                            } else {
                                unset($wp_filter[$action][$pri][$name]) ;
                            }
                        }
                    }
                }
            }
        }
    }
}

下面是覆盖 HTML 的函数。

在这个功能上你需要检查每个变体状态。您可以使用 get_available_variations 获取产品变体。

将状态存储在一个数组中并对照术语进行检查,并基于此您可以添加 class。

function custom_variation_attribute_options_html( $html, $args ) {
    
    remove_class_action( 'woocommerce_dropdown_variation_attribute_options_html', 'WPCleverWpcvs', 'variation_attribute_options_html' );

    $options    = $args['options'];
    $product    = $args['product'];
    $attribute  = $args['attribute'];
    $hint       = get_option( 'wpcvs_tooltip', 'top' );
    $hint_class = $hint !== 'no' ? 'hint--' . $hint : '';
    $style      = get_option( 'wpcvs_style', 'square' );
    $attr_id    = wc_attribute_taxonomy_id_by_name( $attribute );
    $wpcvs_html = '';

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

    $variation_statuses = array();

    $variations = $product->get_available_variations();
    
    foreach($variations as $variation){
        
        $variation_id         = $variation['variation_id'];
        $variation_obj        = new WC_Product_variation($variation_id);
        $variation_attributes = $variation_obj->get_variation_attributes();
        $stock_status         = get_post_meta( $variation_id, '_stock_status', true );

        $variation_statuses[$variation_attributes['attribute_pa_size']] = $stock_status;
    }

    if ( $attr_id ) {
        $attr      = wc_get_attribute( $attr_id );
        $attr_type = isset( $attr->type ) ? $attr->type : 'select';

        $terms = wc_get_product_terms(
            $product->get_id(),
            $attribute,
            array(
                'fields' => 'all',
            )
        );

        if ( ( $attr_type === 'select' ) && ( get_option( 'wpcvs_button_default', 'no' ) === 'yes' ) ) {
            $attr_type = 'button';
        }

        $class = '';

        if ( ( $attr_type !== '' ) && ( $attr_type !== 'select' ) ) {
            $wpcvs_html .= '<div class="wpcvs-terms wpcvs-type-' . esc_attr( $attr_type ) . ' wpcvs-style-' . $style . '" data-attribute="' . esc_attr( $attribute ) . '">';

            switch ( $attr_type ) {
                case 'button' :
                    foreach ( $terms as $term ) {

                        if( isset( $variation_statuses[$term->slug] ) ){
                            $class = $variation_statuses[$term->slug];
                        }

                        $val        = get_term_meta( $term->term_id, 'wpcvs_button', true ) ?: $term->name;
                        $tooltip    = get_term_meta( $term->term_id, 'wpcvs_tooltip', true ) ?: $val;
                        $wpcvs_html .= '<span class="wpcvs-term ' . $hint_class . ' '. $class .' " aria-label="' . esc_attr( $tooltip ) . '" title="' . esc_attr( $tooltip ) . '" data-term="' . esc_attr( $term->slug ) . '"><span>' . esc_html( $val ) . '</span></span>';
                    }

                    break;
                case 'color':
                    foreach ( $terms as $term ) {

                        if( isset( $variation_statuses[$term->slug] ) ){
                            $class = $variation_statuses[$term->slug];
                        }

                        $val        = get_term_meta( $term->term_id, 'wpcvs_color', true ) ?: '';
                        $tooltip    = get_term_meta( $term->term_id, 'wpcvs_tooltip', true ) ?: $term->name;
                        $wpcvs_html .= '<span class="wpcvs-term ' . $hint_class . ' '. $class .' " aria-label="' . esc_attr( $tooltip ) . '" title="' . esc_attr( $tooltip ) . '" data-term="' . esc_attr( $term->slug ) . '"><span ' . ( ! empty( $val ) ? 'style="background-color: ' . esc_attr( $val ) . '"' : '' ) . '>' . esc_html( $val ) . '</span></span>';
                    }

                    break;
                case 'image':
                    foreach ( $terms as $term ) {

                        if( isset( $variation_statuses[$term->slug] ) ){
                            $class = $variation_statuses[$term->slug];
                        }

                        $val        = get_term_meta( $term->term_id, 'wpcvs_image', true ) ? wp_get_attachment_thumb_url( get_term_meta( $term->term_id, 'wpcvs_image', true ) ) : wc_placeholder_img_src();
                        $tooltip    = get_term_meta( $term->term_id, 'wpcvs_tooltip', true ) ?: $term->name;
                        $wpcvs_html .= '<span class="wpcvs-term ' . $hint_class . ' '. $class .' " aria-label="' . esc_attr( $tooltip ) . '" title="' . esc_attr( $tooltip ) . '" data-term="' . esc_attr( $term->slug ) . '"><span><img src="' . esc_url( $val ) . '" alt="' . esc_attr( $term->name ) . '"/></span></span>';
                    }

                    break;
                case 'radio':
                    $name = uniqid( 'wpcvs_radio_' );

                    foreach ( $terms as $term ) {

                        if( isset( $variation_statuses[$term->slug] ) ){
                            $class = $variation_statuses[$term->slug];
                        }

                        $val        = get_term_meta( $term->term_id, 'wpcvs_radio', true ) ?: $term->name;
                        $tooltip    = get_term_meta( $term->term_id, 'wpcvs_tooltip', true ) ?: $term->name;
                        $wpcvs_html .= '<span class="wpcvs-term ' . $hint_class . ' '. $class .' " aria-label="' . esc_attr( $tooltip ) . '" title="' . esc_attr( $tooltip ) . '" data-term="' . esc_attr( $term->slug ) . '"><span><input type="radio" name="' . esc_attr( $name ) . '" value="' . esc_attr( $term->slug ) . '"/> ' . esc_html( $val ) . '</span></span>';
                    }

                    break;
                default:
                    break;
            }

            $wpcvs_html .= '</div>';
        }
    } else {
        // custom attribute
        if ( get_option( 'wpcvs_button_default', 'no' ) === 'yes' ) {
            $wpcvs_html .= '<div class="wpcvs-terms wpcvs-type-button wpcvs-style-' . $style . '" data-attribute="' . sanitize_key( esc_attr( $attribute ) ) . '">';

            foreach ( $options as $option ) {
                $wpcvs_html .= '<span class="wpcvs-term ' . $hint_class . '" aria-label="' . esc_attr( $option ) . '" title="' . esc_attr( $option ) . '" data-term="' . esc_attr( $option ) . '"><span>' . esc_html( $option ) . '</span></span>';
            }

            $wpcvs_html .= '</div>';
        }
    }

    return $wpcvs_html . $html;
}

add_filter( 'woocommerce_dropdown_variation_attribute_options_html', 'custom_variation_attribute_options_html', 198, 2 );

function add_custom_css(){
    ?>
    <style type="text/css">
        .wpcvs-term.outofstock  span { background-color: red; color: #ffffff; }
        .wpcvs-term.instock span { background-color: green; color: #ffffff; }
        .wpcvs-term.onbackorder span { background-color: blue; color: #ffffff; }
    </style>
    <?php
}

add_action( 'wp_head', 'add_custom_css', 10, 1 );

已测试并有效。 代码将进入您的活动主题 functions.php