1
votes

Based on "How to add variation stock status to Woocommerce product variation dropdown" answer,
I have made some code that shows the custom attribute of a variable product and its presence in the store:

// 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'];
    }

    return $stock == 1 ? '' : ' - 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'] : __('Select size', '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_the_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;
}

On a single product page, I show related products. How to show this attribute (its presence in the store) in the form of a label in related products?

For example:

The product's name

Price - $25

Sizes available: L, XL

1

1 Answers

1
votes

Try this code, I hooked into the woocommerce_after_shop_loop_item and displayed the product attributes. Right now it only works for the size attribute. It is showing the Large, Medium, Small. If you want to show L, XL, M, etc. just edit the size attribute.

add_action( 'woocommerce_after_shop_loop_item', 'mamham_woocommerce_after_shop_loop_item', 10);
function mamham_woocommerce_after_shop_loop_item() {
    global $product;

    // Bail if not in the single product page.
    if ( ! is_product() ) return;

    // Prduct attributes which you want to show.
    // Attributes to show in the slug.
    // 'attribute slug' => 'Text shown';
    $show_attributes = array(
        'size' => 'Sizes available:',
    );

    // Get the slugs.
    $show_slugs = array_keys( $show_attributes );

    // Get product type.
    $product_type = $product->get_type();

    if( 'simple' === $product_type ) {  
        $product_attributes = $product->get_attributes();
        foreach( $product_attributes as $key => $product_attribute ) {
            $slug = substr( $key, 3 );
            if ( in_array( $slug, $show_slugs, TRUE ) ) {
                $terms = $product_attribute->get_terms();
                $terms_output = wp_list_pluck( $terms, 'name');
                $terms_output = implode(', ', $terms_output );
                echo esc_html( "${show_attributes[$slug]} ${terms_output}" );
            }
        }

    } elseif ( 'variable' === $product_type ) {
        $product_variations = $product->get_available_variations();     
        foreach ( $product_variations as $product_variation ) {
            if ( $product_variation['is_in_stock'] && isset( $product_variation['attributes']['attribute_pa_size'] )) {
                $terms_output[] = ucwords( $product_variation['attributes']['attribute_pa_size'] );
            }           
        }       
        if ( ! empty( $terms_output) ) {
            $terms_output = implode(', ', $terms_output );
            echo esc_html( "Sizes available: ${terms_output}" );
        }       
    }
}

Here is the screenshot, I have storefront theme and WooCommerce installed.

enter image description here