WooCommerce get custom field from attributte - php

Is it possible to get custom field from product attribute?
And can be connected by variation or product id?
I tried this one:
function color_in_loop(){
global $product;
//Getting product attributes
$attributes = $product->get_attributes();
$values = wc_get_product_terms( $product->id, 'pa_color', array( 'fields' => 'all' ) );
foreach ( $values as $term ) {
$icon = get_term_meta('product_attribute_color', 'pa_color_'.$term->term_id);
echo $icon['url'];
}
}
add_action('woocommerce_after_shop_loop_item', 'color_in_loop');

Your get_term_meta is wrong, and there is no need to use
$attributes = $product->get_attributes();
You can achieve what you are looking for simply with the get_the_terms method since you know the specific attribute you need the icon for.
function color_in_loop(){
global $product;
//Getting product attributes
$product_id = $product->get_id();
$colors = get_the_terms($product_id, 'pa_color');
foreach ( $colors as $color ) {
$icon = get_term_meta($color->term_id,'product_attribute_color',true);
echo $icon['url'];
}
}
add_action('woocommerce_after_shop_loop_item', 'color_in_loop');
It is not tested but it should work

Related

WooCommerce - Output product_attributes list on single-product view

I try to output the whole proudct-attributes on my own single-product.php. I just got that far, that i can output the attribute-slug of every attribute which is not really what i need. I need to output the name and the options of every attribut. Every help is much appreciated:
<?php
global $product;
$attributes = $product->get_attributes();
foreach ( $attributes as $attribute ) {
echo $attribute['name'] . ": ";
$product_attributes = array();
$product_attributes = explode('|',$attribute['value']);
}
?>
You can use wc_attribute_label() function to get attribute label and use get_attribute to get attribute value. check below code.
function custom_woocommerce_single_product_summary(){
global $product;
$attributes = $product->get_attributes();
foreach ( $attributes as $attribute_name => $attribute ) {
$attribute_label = wc_attribute_label( $attribute_name );
$attribute_value = $product->get_attribute( $attribute_name );
echo $attribute_label . ": ".$attribute_value."</br>";
}
}
add_action( 'woocommerce_single_product_summary', 'custom_woocommerce_single_product_summary', 10, 1 );
Tested and Works.

Shortcode that display all product attributes set for a WooCommerce product

I keep searching for a way to do this, but I can't find anything unfortunately.
I an trying to display all the product's attributes and values, separated by a pipe, in a custom place on the single-product (so for that I was thinking to create a shortcode, so I can place it anywhere I want). the output would be something like this:
BRAND: RENAULT | MODEL: 12 | YEAR: 1973
The code on the Woocommerce template product-attributes.php lists the attributes of the current product on single-product page, but it will list it with some styles I don't want in a place I don't want.
I want to create a shortcode with that code, which is:
<?php foreach ( $product_attributes as $product_attribute_key => $product_attribute ) : ?>
<?php echo wp_kses_post( $product_attribute['label'] ); ?>: <?php echo wp_kses_post( $product_attribute['value'] ); ?> |
<?php endforeach; ?>
How can I create a shortcode with it? I know the general code for a shortcode, but I don't know how to actually integrate the above one in it:
function custom_attributes_product_page() {
// integrate the required code
// Output needs to be return
return
}
// register shortcode
add_shortcode('custom-attributes', 'custom_attributes_product_page');
Would be great if this shortcode would list the attributes and their values separated by a column, like I said above (how to do that?)
Any help is highly appreciated.
Try the following shortcode that will display all product attribute(s) set for a product and their value(s), handling custom attributes too:
function get_product_attributes_shortcode($atts ) {
// Extract shortcode attributes
extract( shortcode_atts( array(
'id' => get_the_ID(),
), $atts, 'display-attributes' ) );
global $product;
if ( ! is_a($product, 'WC_Product') ) {
$product = wc_get_product( $id );
}
if ( is_a($product, 'WC_Product') ) {
$html = []; // Initializing
foreach ( $product->get_attributes() as $attribute => $values ) {
$attribute_name = wc_attribute_label($values->get_name());
$attribute_data = $values->get_data();
$is_taxonomy = $attribute_data['is_taxonomy'];
$option_values = array(); // Initializing
// For taxonomy product attribute values
if( $is_taxonomy ) {
$terms = $values->get_terms(); // Get attribute WP_Terms
// Loop through attribute WP_Term(s)
foreach ( $terms as $term ) {
$term_link = get_term_link( $term, $attribute );
$option_values[] = ''.$term->name.'';
}
}
// For "custom" product attributes values
else {
// Loop through attribute option values
foreach ( $values->get_options() as $term_name ) {
$option_values[] = $term_name;
}
}
$html[] = '<strong>' . $attribute_name . '</strong>: ' . implode(', ', $option_values);
}
return '<div class="product-attributes">' . implode(' | ', $html) . '<div>';
}
}
add_shortcode( 'display-attributes', 'get_product_attributes_shortcode' );
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
USAGE: [display-attributes] or with a defined product Id [display-attributes id="254"]
You will get a display like: BRAND: RENAULT | MODEL: 12 | YEAR: 1973
If you don't want the linked terms, replace:
$term_link = get_term_link( $term, $attribute );
$option_values[] = ''.$term->name.'';
by this:
$option_values[] = $term->name;

Get the selected variation attributes from orders in Woocommerce 3

In Woocommerce, I have a report in the admin area that tallies up products sold.There are only 5 products sold on the site but there are 1 or 2 variations on some. The report works great but ignores the variations.
I need to retrieve the attribute value from items ordered to display the data accurately. How do I do this?
get_variation_description() is not working the way I'm applying it.
My code:
$order = wc_get_order( $vs);
//BEGIN NEW RETRIEVE ORDER ITEMS FROM ORDER
foreach( $order->get_items() as $item_id => $item_product ){
$ods = $item_product->get_product_id(); //Get the product ID
$odqty= $item_product->get_quantity(); //Get the product QTY
$item_name = $item_product->get_name(); //Get the product NAME
$item_variation = $item_product->get_variation_description(); //NOT WORKING
}
2020 Update - Handling "Custom Product Attributes" (revamped code)
The WC_Product method get_variation_description() is outdated and deprecated. It's replaced by get_description() method. So you need to get the WC_Product object first.
To get the selected variation attributes, you will use get_variation_attributes( ) method.
// Get an instance of the WC_Order object from an Order ID
$order = wc_get_order( $order_id );
// Loop though order "line items"
foreach( $order->get_items() as $item_id => $item ){
$product_id = $item->get_product_id(); //Get the product ID
$quantity = $item->get_quantity(); //Get the product QTY
$product_name = $item->get_name(); //Get the product NAME
// Get an instance of the WC_Product object (can be a product variation too)
$product = $item->get_product();
// Get the product description (works for product variation too)
$description = $product->get_description();
// Only for product variation
if( $product->is_type('variation') ){
// Get the variation attributes
$variation_attributes = $product->get_variation_attributes();
// Loop through each selected attributes
foreach($variation_attributes as $attribute_taxonomy => $term_slug ){
// Get product attribute name or taxonomy
$taxonomy = str_replace('attribute_', '', $attribute_taxonomy );
// The label name from the product attribute
$attribute_name = wc_attribute_label( $taxonomy, $product );
// The term name (or value) from this attribute
if( taxonomy_exists($taxonomy) ) {
$attribute_value = get_term_by( 'slug', $term_slug, $taxonomy )->name;
} else {
$attribute_value = $term_slug; // For custom product attributes
}
}
}
}
Tested and works for a product variation as all other product types…
It works perfectly to display order item name and attributes key
foreach( $order->get_items() as $order_item_product ) {
$item_meta_data = $order_item_product->get_meta_data();
echo $product_name = $order_item_product->get_name();
echo '<br>';
foreach( $item_meta_data as $meta_data ) {
$meta_data_as_array = $meta_data->get_data();
echo $meta_data_as_array['key'].': '.$meta_data_as_array['value'].'<br>';
}
}
Based on the accepted answer This is so that the typo could be corrected ( i don't have the reputation to do anything else).
notice the $term_slug on the $attribute_value property definition. that is what was missing the $.
// Get an instance of the WC_Order object from an Order ID
$order = wc_get_order( $order_id );
// Loop though order "line items"
foreach( $order->get_items() as $item_id => $item_product ){
$product_id = $item_product->get_product_id(); //Get the product ID
$quantity = $item_product->get_quantity(); //Get the product QTY
$product_name = $item_product->get_name(); //Get the product NAME
// Get an instance of the WC_Product object (can be a product variation too)
$product = $item_product->get_product();
// Get the product description (works for product variation)
$description = $product->get_description();
// Only for product variation
if($product->is_type('variation')){
// Get the variation attributes
$variation_attributes = $product->get_variation_attributes();
// Loop through each selected attributes
foreach($variation_attributes as $attribute_taxonomy => $term_slug){
$taxonomy = str_replace('attribute_', '', $attribute_taxonomy );
// The name of the attribute
$attribute_name = get_taxonomy( $taxonomy )->labels->singular_name;
// The term name (or value) for this attribute
$attribute_value = get_term_by( 'slug', $term_slug, $taxonomy )->name;
}
}
}
For anyone coming across this in the future, I ran into an issue where the last attribute value was not displaying, but when I was looking at orders in the admin it was displaying correctly, so I took a dive into the WooCommerce source code and modified theirs for my needs. You can see their code here if you want to modify it yourself:
\woocommerce\includes\admin\meta-boxes\views\html-order-item-meta.php
Here's what I did to display all keys and values:
$attribute_list = array();
// Start modified code from html-order-item-meta.php
$hidden_order_itemmeta = apply_filters(
'woocommerce_hidden_order_itemmeta',
array(
'_qty',
'_tax_class',
'_product_id',
'_variation_id',
'_line_subtotal',
'_line_subtotal_tax',
'_line_total',
'_line_tax',
'method_id',
'cost',
'_reduced_stock',
'_restock_refunded_items',
)
);
if ($meta_data = $item->get_formatted_meta_data('')) {
foreach ($meta_data as $meta_id => $meta) {
if (in_array($meta->key, $hidden_order_itemmeta, true)) {
continue;
}
$display_key = sanitize_text_field($meta->display_key);
$display_value = sanitize_text_field(force_balance_tags($meta->display_value));
$attribute_list[] = array($display_key => $display_value);
}
}
// End modified code from html-order-item-meta.php
if ($attribute_list) {
$attribute = '';
foreach ($attribute_list as $attributes) {
foreach ($attributes as $attr => $value) {
$attribute .= " - " . $attr . " : " . $value;
}
}
echo $attribute;
}
My code adds each key and value to an array and then loops through to append the key and value to the end of a string with separators. This is what I needed for what I was working on, but it can be easily adapted to fit your needs.

How to show some few attributes on woocommerce category page?

I want to show two of many attributes of my products on category pages namely heating capacity and cooling capacity as i am making an online store in woocommerce and i am working with my custom theme. it is not a variation or something it's just a normal attribute with text which i would like to show something like this as you can see the heating and cooling system listed on the category page itself i tried the code
if (!function_exists('shop_attributes_in_loop')) {
function shop_attributes_in_loop(){
global $product;
$attributes = $product->get_attributes();
if(!empty($attributes)){
$attribute_single = array_keys($attributes);
$myArray = array();
echo '<div class="product_attributes">';
foreach ($attribute_single as $attribute => $value) {
$myArray[] = ucfirst($value);
}
echo implode(', ', $myArray).'</div>';
}
}
}
add_action('woocommerce_after_shop_loop_item', 'shop_attributes_in_loop');
but it shows something wierd like
Placement-of-outdoor-unit, Installation, Pa_model-no-indoor, Pa_model-no-outdoor etc.. can anyone help me..
You can use this snippet for getting custom field value at archive / category page:
add_action( 'woocommerce_after_shop_loop_item', 'custom_display_post_meta', 9 );
function custom_display_post_meta() {
global $product;
$heating_capacity = get_post_meta( $product->id, 'heating_capacity', true );
$cooling_capacity = get_post_meta( $product->id, 'cooling_capacity', true );
echo $heating_capacity;
echo $cooling_capacity;
}
you can read this article as reference: https://www.skyverge.com/blog/add-information-to-woocommerce-shop-page/
I actually found out how its to be done :)
add_action( 'woocommerce_after_shop_loop_item', 'custom_display_post_meta', 9 );
function custom_display_post_meta() {
global $product;
$attr = array('pa_cooling-capacity-watts', 'pa_heating-capacity-watts');
foreach ( $attr as $attribute ) {
$values = wc_get_product_terms( $product->id, $attribute, array( 'fields' => 'names' ) );
echo apply_filters( 'woocommerce_attribute', wpautop( wptexturize( implode( ', ', $values ) ) ), $attribute, $values );
}
}

Woocommerce: get_formatted_name() of a variation

I'm trying to get the name of a variation in woocommerce, currently im using this:
$variationDetails = wc_get_product($variation_id);
$variationDetails->get_formatted_name();
But get_formatted_name() returns a long string with too many details, I only need the simple name of the variation. I've tried with $variationDetails->get_title() but that returns only the product title instead the variation name.
Is there a simple function to get the variation name?
Hopefully this helps had the same problem recently this is what I wrote to get the variations title for a product
$variations = $product->get_available_variations();
$variation_names = array();
foreach ( $variations as $variation ) {
// Get attribute taxonomies
$taxonomies = array_keys($variation['attributes']);
// Loop through variation taxonomies to get variation name and slug
foreach ($taxonomies as $tax) {
$get_term_tax = str_replace('attribute_', '', $tax);
$meta = get_post_meta( $variation['variation_id'], $tax, true );
$term = get_term_by( 'slug', $meta, $get_term_tax );
$var_name = $term->name;
$variation_names[] = $var_name;
}
}

Categories