admin管理员组

文章数量:1122846

In WooCommerce, I have an attribute called License Type. This attribute has 2 terms:

  1. Single Site License
  2. Multi Site License

With the above, I'm trying to create a custom select dropdown, where the option contains the variation ID.

For example, my product has both of those variations assigned. For that product:

  1. Single Site License has an ID of 210
  2. Multi Site License has an ID of 211

So, I'm looking for my output to look something like this:

<select name="pa_license-type" id="pa_license-type">
  <option value="single-site-license" data-variation-id="210">Single Site License</option>
  <option value="multi-site-license" data-variation-id="211">Multi Site License</option>
</select>

To make this dynamic, for each product, I've attempted the following:

if ($product->is_type('variable')) :
  $product_id = $product->get_id();
  $available_variations = $product->get_children();

  $attributes = $product->get_variation_attributes();

  foreach ($attributes as $attribute_name => $options) :
      $taxonomy = str_replace('attribute_', '', $attribute_name);
    $terms = get_terms(array(
      'taxonomy' => $taxonomy,
      'hide_empty' => false,
    ));

    if (!is_wp_error($terms) && !empty($terms)) :

      $attribute_label = wc_attribute_label($taxonomy);
      echo '<label for="' . esc_attr($taxonomy) . '">' . esc_html($attribute_label) . '</label>';
      echo '<select name="' . esc_attr($taxonomy) . '" id="' . esc_attr($taxonomy) . '">';

      $variation_ids_map = array();

      foreach ($terms as $term) :
          $term_slug = $term->slug;
          $current_variation_id = '';

          foreach ($available_variations as $variation_id_candidate) :
            $variation = wc_get_product($variation_id_candidate);
            if ($variation && has_term($term_slug, $taxonomy, $variation->get_id())) :
              $current_variation_id = $variation->get_id();
              break;
            endif;
          endforeach;
          
          $variation_ids_map[$term_slug] = $current_variation_id;
          echo '<option value="' . esc_attr($term_slug) . '" data-variation-id="' . esc_attr($current_variation_id) . '">' . esc_html($term->name) . '</option>';

      endforeach;

      echo '</select>';
    endif;

  endforeach;
endif;
?>

But that yields:

<select name="pa_license-type" id="pa_license-type">
  <option value="single-site-license" data-variation-id="">Single Site License</option>
  <option value="multi-site-license" data-variation-id="">Multi Site License</option>
</select>

Any ideas on where I'm going wrong?

In WooCommerce, I have an attribute called License Type. This attribute has 2 terms:

  1. Single Site License
  2. Multi Site License

With the above, I'm trying to create a custom select dropdown, where the option contains the variation ID.

For example, my product has both of those variations assigned. For that product:

  1. Single Site License has an ID of 210
  2. Multi Site License has an ID of 211

So, I'm looking for my output to look something like this:

<select name="pa_license-type" id="pa_license-type">
  <option value="single-site-license" data-variation-id="210">Single Site License</option>
  <option value="multi-site-license" data-variation-id="211">Multi Site License</option>
</select>

To make this dynamic, for each product, I've attempted the following:

if ($product->is_type('variable')) :
  $product_id = $product->get_id();
  $available_variations = $product->get_children();

  $attributes = $product->get_variation_attributes();

  foreach ($attributes as $attribute_name => $options) :
      $taxonomy = str_replace('attribute_', '', $attribute_name);
    $terms = get_terms(array(
      'taxonomy' => $taxonomy,
      'hide_empty' => false,
    ));

    if (!is_wp_error($terms) && !empty($terms)) :

      $attribute_label = wc_attribute_label($taxonomy);
      echo '<label for="' . esc_attr($taxonomy) . '">' . esc_html($attribute_label) . '</label>';
      echo '<select name="' . esc_attr($taxonomy) . '" id="' . esc_attr($taxonomy) . '">';

      $variation_ids_map = array();

      foreach ($terms as $term) :
          $term_slug = $term->slug;
          $current_variation_id = '';

          foreach ($available_variations as $variation_id_candidate) :
            $variation = wc_get_product($variation_id_candidate);
            if ($variation && has_term($term_slug, $taxonomy, $variation->get_id())) :
              $current_variation_id = $variation->get_id();
              break;
            endif;
          endforeach;
          
          $variation_ids_map[$term_slug] = $current_variation_id;
          echo '<option value="' . esc_attr($term_slug) . '" data-variation-id="' . esc_attr($current_variation_id) . '">' . esc_html($term->name) . '</option>';

      endforeach;

      echo '</select>';
    endif;

  endforeach;
endif;
?>

But that yields:

<select name="pa_license-type" id="pa_license-type">
  <option value="single-site-license" data-variation-id="">Single Site License</option>
  <option value="multi-site-license" data-variation-id="">Multi Site License</option>
</select>

Any ideas on where I'm going wrong?

Share Improve this question asked Jul 14, 2024 at 19:01 FreddyFreddy 1671 silver badge12 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

I think the condition here has_term($term_slug, $taxonomy, $variation->get_id()) won't work for variation. If you want to check term, we need to check with parent variable product instead of checking variation because Woocommerce doesn't store any taxonomy/term attribute to variation.

Instead of using has_term, we can use your existing attributes in get_variation_attributes to get and check condition because a variable product may have defined taxonomy as attribute or custom attribute defined directly in Attributes tab. As you can see in my screenshot below:

So I updated your code to make the data-variation-id work properly

if($product->is_type('variable')) :
        $available_variations = $product->get_children();
        
        if($attributes = $product->get_variation_attributes()){
            foreach($attributes as $attribute_name => $options) :
                $taxonomy        = str_replace('attribute_', '', $attribute_name);
                $attribute_label = wc_attribute_label($taxonomy);
                echo '<label for="' . esc_attr($taxonomy) . '">' . esc_html($attribute_label) . '</label>';
                echo '<select name="' . esc_attr($taxonomy) . '" id="' . esc_attr($taxonomy) . '">';
                
                $variation_ids_map = [];
                
                foreach($options as $option_slug) :
                    $current_variation_id = '';
                    $term                 = get_term_by('slug', $option_slug, $taxonomy);
                    $term_name            = $term ? $term->name : $option_slug; // for custom attribute
                    
                    foreach($available_variations as $variation_id_candidate) :
                        $variation = wc_get_product($variation_id_candidate);
                        if($variation && $variation->attributes[$taxonomy] == $option_slug) :
                            $current_variation_id = $variation->get_id();
                            break;
                        endif;
                    endforeach;
                    
                    $variation_ids_map[$option_slug] = $current_variation_id;
                    
                    echo '<option value="' . esc_attr($option_slug) . '" data-variation-id="' . esc_attr($current_variation_id) . '">' . esc_html($term_name) . '</option>';
                
                endforeach;
                
                echo '</select>';
            
            endforeach;
        }
    endif;

本文标签: phpWooCommerce Custom dropdown for variation selection