Add the variation price to variable product dropdown item names in Woocommerce

前端 未结 2 1833
孤独总比滥情好
孤独总比滥情好 2021-01-25 13:21

I\'m using this code to get the variable product options

$terms = wc_get_product_terms( $bundle_product_id, $name, array( \'fields\' => \'all\' ) );
foreach (         


        
相关标签:
2条回答
  • 2021-01-25 13:30

    Here is my simplified solution to this that is working with WooCommerce 4.7.0. Since we know there is only one attribute for each variation, we can just get the first value to show the correct price for each.

    /**
     * Display price in variation options dropdown for products that have only one attribute.
     *
     * @param  string $term Existing option term value.
     * @return string $term Existing option term value or updated term value with price.
     */
    function display_price_in_variation_options( $term ) {
        $product = wc_get_product();
        $id      = $product->get_id();
        if ( empty( $term ) || empty( $id ) ) {
            return $term;
        }
        if ( $product->is_type( 'variable' ) ) {
            $product_variations = $product->get_available_variations();
        } else {
            return $term;
        }
        foreach ( $product_variations as $variation ) {
            if ( count( $variation['attributes'] ) > 1 ) {
                return $term;
            }
            $attribute = array_values( $variation['attributes'] )[0];
            if ( $attribute === $term ) {
                $term .= ' (' . wp_strip_all_tags( wc_price( $variation['display_price'] ) ) . ')';
            }
        }
        return $term;
    }
    add_filter( 'woocommerce_variation_option_name', 'display_price_in_variation_options' );
    
    0 讨论(0)
  • 2021-01-25 13:48

    It will only work if you have just one product attribute for variations set in the variable product (so only one dropdown).

    If you have more than one dropdowns in your variable product, as the variations are a combination of the different product attributes values, it will not work logically.

    So the following code will display the product variation price in a unique product attribute dropdown:

    // Utility function to get the price of a variation from it's attribute value
    function get_the_variation_price_html( $product, $name, $term_slug ){
        foreach ( $product->get_available_variations() as $variation ){
            if($variation['attributes'][$name] == $term_slug ){
                return strip_tags( $variation['price_html'] );
            }
        }
    }
    
    // Add the price  to the dropdown options items.
    add_filter( 'woocommerce_dropdown_variation_attribute_options_html', 'show_price_in_attribute_dropdown', 10, 2);
    function show_price_in_attribute_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'];
        $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 ) ) {
                        // Get and inserting the price
                        $price_html = get_the_variation_price_html( $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 ) . ' ::: ' . $price_html ) . '</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 );
                    // Get and inserting the price
                    $price_html = get_the_variation_price_html( $product, $name, $term->slug );
                    $html .= '<option value="' . esc_attr( $option ) . '" ' . $selected . '>' . esc_html( apply_filters( 'woocommerce_variation_option_name', $option ) . ' ::: ' . $price_html ) . '</option>';
                }
            }
        }
        $html .= '</select>';
    
        endif;
    
        return $html;
    }
    

    Code goes in function.php file of your active child theme (or active theme). Tested and works.

    0 讨论(0)
提交回复
热议问题