I'm trying to get terms slug from a specific attribute taxonomy but I get nothing.
$attr_langs = 'pa_languages';
$attr_langs_meta = get_post_meta('id', 'attribute_'.$attr_langs, true);
$term = get_term_by('slug', $attr_langs_meta, $attr_langs);
Thank you so much in advance!
It's normal that it doesn't work as get_post_meta() first function argument needs to be a numerical value but NOT a text string as 'id' (the post ID)…
So you can't get any value for $attr_langs_meta variable.
You can get the product ID in different ways:
1) From the WP_Post object with:
global $post;
$product_id = $post->ID;
2) From the WC_Product object with:
$product_id = $product->get_id();
Now the correct way for to do it is:
// The defined product attribute taxonomy
$taxonomy = 'pa_languages';
// Get an instance of the WC_Product Object (necessary if you don't have it)
// from a dynamic $product_id (or defined $product_id)
$product = wc_get_product($product_id);
// Iterating through the product attributes
foreach($product->get_attributes( ) as $attribute){
// Targeting the defined attribute
if( $attribute->get_name() == $taxonomy){
// Iterating through term IDs for this attribute (set for this product)
foreach($attribute->get_options() as $term_id){
// Get the term slug
$term_slug = get_term( $term_id, $taxonomy )->slug;
// Testing an output
echo 'Term Slug: '. $term_slug .'<br>';
}
}
}
Or also exclusively for a variable product (similar thing):
// The defined product attribute taxonomy
$taxonomy = 'pa_languages';
// Get an instance of the WC_Product Object (necessary if you don't have it)
// from a dynamic $product_id (or defined $product_id)
$product = wc_get_product($product_id);
// Iterating through the variable product variations attributes
foreach ( $product->get_variation_attributes() as $attribute => $terms ) {
// Targeting the defined attribute
if( $attribute == $taxonomy ){
// Iterating through term slugs for this attribute (set for this product)
foreach( $terms as $term_slug ){
// Testing an output
echo 'Term Slug: ' . $term_slug . '<br>';
}
}
}
This should work for you…
Related
I would like to exclude from all WooCommerce coupons the products that have a specific attribute (e.g. attribute_pa_brand => mybrand).
I followed this answer Exclude variations with 2 specific attribute terms from coupon usage in Woocommerce but it seems to apply only to the Variable Product type, while I would only need it for the Simple Product.
I will be grateful for any answer.
The linked code from your question is for product variation type. Now to make it work for simple products and variable products (without targeting specific variations attributes terms), you will use the following:
add_filter( 'woocommerce_coupon_is_valid', 'custom_coupon_validity', 10, 3 );
function custom_coupon_validity( $is_valid, $coupon, $discount ){
// YOUR ATTRIBUTE SETTINGS BELOW:
$taxonomy = 'pa_brand'; // Set the taxonomy (start always with "pa_" + the slug)
$term_names = array('Apple', 'Sony'); // Set your term NAMES to be excluded
$term_ids = array(); // Initializing
// Convert term names to term Ids
foreach ( $term_names as $term_name ) {
// Set each term id in the array
$term_ids[] = get_term_by( 'name', $term_name, $taxonomy )->term_id;
}
// Loop through cart items and check for backordered items
foreach ( WC()->cart->get_cart() as $cart_item ) {
$product = $cart_item['variation_id'] > 0 ? wc_get_product($cart_item['product_id']) : $cart_item['data'];
// Loop through product attributes
foreach( $product->get_attributes() as $attribute => $values ) {
if( $attribute === $taxonomy && array_intersect( $values->get_options(), $term_ids ) ) {
$is_valid = false; // attribute found, coupons are not valid
break; // Stop and exit from the loop
}
}
}
return $is_valid;
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works for simple and variable products on last WooCommerce version.
I would like to display variable products shipping class set for each variant.
I realize that I may need to have a mix of php and Javascript but I would like to get the PHP side right first.
I am guessing the best way to start is to use:
if( $product->is_type( 'simple' ) ) {
$product = wc_get_product();
$shipping_class = $product->get_shipping_class();
} elseif( $product->is_type( 'variable' ) ) {
$product = wc_get_product();
$shipping_class = $product->get_shipping_class();
}
But I am not sure how to get the product variant shipping class or if I am doing this correctly. Looking into wc_get_product_variation or variation to see if it has the answer.
Any help would be appreciated possibly display all as an array and use javascript to hide the selected.
How do I get the variant shipping class?
To get the variations shipping classes of a defined variable product Id, two ways:
1) Using wp_get_post_terms() function for product_shipping_class taxonomy:
// Get the WC_Product_Variable instance Object (if needed)
$product = wc_get_product( $product_id );
// Initializing
$shipping_classes = array();
// Loop through the visible variations IDs
foreach ( $product->get_visible_children() as $variation_id ) {
// Get the variation shipping class WP_Term object
$term = wp_get_post_terms( $variation_id, 'product_shipping_class' );
if( empty($term) ) {
// Get the parent product shipping class WP_Term object
$term = wp_get_post_terms( $product->get_id(), 'product_shipping_class' );
// Set the shipping class slug in an indexed array
$shipping_classes[$variation_id] = $term->slug;
}
}
// Raw output (for testing)
var_dump($shipping_classes);
This will give you an array of variation Id / shipping class pairs.
2) Using get_shipping_class_id() WC_Product method:
// Get the WC_Product_Variable instance Object (if needed)
$product = wc_get_product( $product_id );
// Initializing
$shipping_classes = array();
// Loop through the visible variations IDs
foreach ( $product->get_visible_children() as $variation_id ) {
// Get the Product Variation instance Object
$variation = wc_get_product($variation_id);
// Get the shipping class ID
$term_id = $variation->get_shipping_class_id();
// The shipping class WP_Term Object
$term = get_term_by('term_id', $term_id, 'product_shipping_class');
// Set the shipping class slug in an indexed array
$shipping_classes[$variation_id] = $term->slug;
}
// Raw output (for testing)
var_dump($shipping_classes);
I know that there are a lot of questions already for that matter but im not able to figure out how to get a custom product attribute from an woocommerce order. here is what i have try:
$order = wc_get_order( $order_id );
$order_data = $order->get_data();
foreach ($order->get_items() as $item_key => $item_values) {
$product = $item_values->get_product(); // Get the product
$product_id = $item_values->get_product_id(); // the Product id
$tokens = get_post_meta($product_id, 'Tokens', true);
}
I have also try:
$tokens = $product->get_attribute( 'Tokens' );
and
$tokens = array_shift( wc_get_product_terms( $product_id, 'Tokens', array( 'fields' => 'names' ) ) );
My custom product attribute has the name "Tokens" and the value 5000 but im getting an empty return,
what am i doing wrong?
That can happen for a variable product when the product attribute is not set as an attribute for variations.
So when you have a product variation as order item, you need to get the parent variable product to get your product attribute value (if this product attribute is not set as an attribute for variations).
If it is the case for "Tokens" product attribute, try the following:
$attribute = 'Tokens';
$order = wc_get_order( 857 );
// Loop through order line items
foreach ( $order->get_items() as $item_id => $item ) {
$product = $item->get_product(); // Get the WC_Product object
// For Product Variation type
if( $item->get_variation_id() > 0 ){
$parent = wc_get_product($product->get_parent_id());
$term_names = $parent->get_attribute($attribute);
}
// For other Product types
else {
$term_names = $product->get_attribute($attribute);
}
// Testing display (the string of coma separated term names if many)
if( ! empty( $term_name ) )
echo '<p>'.$term_name.'</p>';
}
Tested and works in Woocommerce 3+
I need to display some custom icons on the product overview (category, archive) page based on a set of ingredients (which is a Woo product attribute).
I am hooking in at woocommerce_after_shop_loop_item_title and that is the right place to display what I want. However, I can't get a list of the slugs for the attributes easily. My goal is to get an array of slugs that is like ['onion', 'fresh-lettuce', 'cheese'] or whatever.
My current try is something like:
add_filter( 'woocommerce_after_shop_loop_item_title', function () {
global $product;
$attrs = $product->get_attributes();
$slugs = $attrs->get_slugs( 'ingredients' );
var_dump( $slugs );
});
But that does not work.
Note that $product->get_attributes() works, but is the same for every product on the category page.
Please advise!
Try the following using WC_Product get_attribute() method:
add_filter( 'woocommerce_after_shop_loop_item_title', 'loop_display_ingredients', 15 );
function loop_display_ingredients() {
global $product;
// The attribute slug
$attribute = 'ingredients';
// Get attribute term names in a coma separated string
$term_names = $product->get_attribute( $attribute );
// Display a coma separted string of term names
echo '<p>' . $term_names . '</p>';
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Now if you want to get the term slugs in a coma separated list, you will use the following:
// The attribute slug
$attribute = 'ingredients';
// Get attribute term names in a coma separated string
$term_names = $product->get_attribute( $attribute );
// Get the array of the WP_Term objects
$term_slugs = array();
$term_names = str_replace(', ', ',', $term_names);
$term_names_array = explode(',', $term_names);
if(reset($term_names_array)){
foreach( $term_names_array as $term_name ){
// Get the WP_Term object for each term name
$term = get_term_by( 'name', $term_name, 'pa_'.$attribute );
// Set the term slug in an array
$term_slugs[] = $term->slug;
}
// Display a coma separted string of term slugs
echo '<p>' . implode(', ', $term_slugs); . '</p>';
}
In Woocommerce I have these attributes and the terms for them:
color: blue(description=1), red(description=2)
size: xl(description=10), m(description=20)
All terms have description fields mentioned above.
For a variable product, I have these variations:
blue-m
red-xl
For the purpose of auto-generating the variations SKU (based on those descriptions) I need to get the description for the attribute term used in each variant (we use different attributes for each variable product).
For example for the variation with red color and xl size, I want to get something like 210 (from descriptions of red and xl)
I tried using $variation['attributes'] and removing extra characters from it to use with get_terms to get the descriptions of the attributes used in a variant, but I couldn't succeed.
Any Idea?
This can be done in an easily once you get the Product variation ID $variation_id this way:
// Initializing
$variation_sku = '';
// Get the product variation object (instance)
$variation = wc_get_product( $variation_id );
// Loop through variation attributes "taxonomy" / "terms" pairs
foreach( $variation->get_variation_attributes() as $attribute => $value ){
$taxonomy = str_replace( 'attribute_', '', $attribute );
$term = get_term_by( 'slug', $value, $taxonomy );
// $term_name = $term->name;
$variation_sku .= $term->description; // <= HERE the Description
}
// Displaying the sku
echo '<p>'.__("SKU: ").$variation_sku.'</p>';