How to get a current variation id inside the foreach loop?

52 Views Asked by At

I use this code to make custom variation radio buttons. I have many customization for exactly my purposes and they are almost perfect, so no - 'one of many swatches plugin - is NOT what I maybe search', just PLEASE.

Now I need to add a specific class to variations, that are out of stock, to blur them a little in css. Exactly a class, not attribute 'disabled'.

I needed to remove the attribute 'disabled' from all select options to make all radios clickable, just with another text.

function variation_radio_buttons($html, $args) {    
  global $product;
  $prod_id = $product->get_id();  

     $args = wp_parse_args(apply_filters('woocommerce_dropdown_variation_attribute_options_args', $args), array(
    'options'          => false,
    'attribute'        => false,
    'product'          => false,
    'selected'         => false,
    'name'             => '',
    'id'               => '',
    'class'            => '',
    'show_option_none' => __('Choose an option', 'woocommerce'),
  ));

  if(false === $args['selected'] && $args['attribute'] && $args['product'] instanceof WC_Product) {
    $selected_key     = 'attribute_'.sanitize_title($args['attribute']);
    $args['selected'] = isset($_REQUEST[$selected_key]) ? wc_clean(wp_unslash($_REQUEST[$selected_key])) : $args['product']->get_variation_default_attribute($args['attribute']);
  }

  $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      = (bool)$args['show_option_none'];
  $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];
  }

  $radios = '<div class="variation-radios">';

  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, true)) {                     
          $id = $name.'-'.$term->slug;   

      $radios .= '<div class="attr-container"><div class="radio-span"><label for="'.esc_attr($id). $prod_id.'"><input type="radio" id="'.esc_attr($id). $prod_id .'" name="'.esc_attr($name) .'" value="'.esc_attr($term->slug).'" '.checked(sanitize_title($args['selected']), $term->slug, false).'>'. '<div class="radio-span-label">' . esc_html(apply_filters('woocommerce_variation_option_name', $term->name)). '</div></label></div></div>';
        }
      } 
    } else {
      foreach($options as $option) {
        $id = $name.'-'.$option;
        $checked    = sanitize_title($args['selected']) === $args['selected'] ? checked($args['selected'], sanitize_title($option), false) : checked($args['selected'], $option, false);
        $radios    .= '<div class=""><input type="radio"  id="'.esc_attr($id). $prod_id .'" name="'.esc_attr($name). '" value="'.esc_attr($option).'" id="'.sanitize_title($option).'" '.$checked.'><label for="'.esc_attr($id). $prod_id.'">'.esc_html(apply_filters('woocommerce_variation_option_name', $option)).'</label></div>';
      }
    }
  }

  $radios .= '</div>';
    
  return $html.$radios;
}
add_filter('woocommerce_dropdown_variation_attribute_options_html', 'variation_radio_buttons', 20, 2);

I tried different ways, think that I have to use current variation id inside the loop foreach($terms as $term).

GPT said to, that the class has to be realized on php side, I think so too, so I don't post the js-side, I'll do it if it will be needed. Js would be helpful to add the style if we choose variation by click or change, but it has to be from the start, based on product data.

Like

$variation_id = $product->get_matching_variation_id(array($attribute => $term->slug));
$variation = wc_get_product($variation_id);        
$in_stock_class = $variation && $variation->is_in_stock() ? '' : 'out-of-stock';

And then to use this class in needed place

 $radios    .= '<div class="'. $in_stock_class .'">......

But exactly the string

$variation_id = $product->get_matching_variation_id(array($attribute => $term->slug));

makes all the form to disapear.

var_dump($variation_id) shows 0 with it if to try hardcore for existing variation id - that shows it correctly.

Somehow it can't catch the dynamic value of the current variation, that I need in loop

Maybe I'm wrong and it's an another way to add a class to out of stock variations? I know how to style that radios one by one, and for a small shop it's enough, but I want to have my own custom and right decision. In plugins I saw blured or crossed out-of-stock radios, so somehow it's possible. Please help if you have ideas.

0

There are 0 best solutions below