Get Item/Product Attribute in WooCommerce Order - wordpress

I'm trying to get Item or Product Attribute in WooCoomerce Order.
How can I get it?
$order = new WC_Order( $order_id );
$items = $order->get_items();
foreach ( $items as $item ) {
$pid = $item['product_id'];
$patt = $pid->get_attribute( 'pa_myattrname' );
echo $patt;
}
Later, I want to insert autoresponder link on attribute, so that after user complete payment, they will automatically subscribed into my autoresponder.
Thank you

I know that it is old question, but that answer may help someone who is looking for nicer option.
There is much simpler way to get product attributes from order. You just need to go into products (items) and then load meta data
// at first get order object
$order = wc_get_order($orderId);
// iterate through order items/products
foreach ($order->get_items() as $item) {
// load meta data - product attributes
foreach ($item->get_meta_data() as $metaData) {
$attribute = $metaData->get_data();
// attribute value
$value = $attribute['value'];
// attribute slug
$slug = $attribute['key'];
}
}

$item['product_id']; will return the integer product_id, you cannot call get_attribute method on it. Using the integer product_id you need to create a Product object and then call the method
$pid = $item['product_id']; // returns the product id
$p = new WC_Product( $pid ); // create an object of WC_Product class
$patt = $p->get_attribute( 'pa_myattrname' ); // call get_attribute method
echo $patt;

Related

How to grab the order status of the last order in WooCommerce via a shortcode

I'm trying to give our customers a better insight in their order status without going to their account. My plan is to print the info on the home page once someone has ordered.
I'm struggling to get the order status to display elsewhere.
Here is the current code I've whipped up based on a code used to grab the product of the last order.
function woostatus() {
// Not available
$na = __( 'N/A', 'woocommerce' );
// For logged in users only
if ( ! is_user_logged_in() ) return $na;
// The current user ID
$user_id = get_current_user_id();
// Get the WC_Customer instance Object for the current user
$customer = new WC_Customer( $user_id );
// Get the last WC_Order Object instance from current customer
$last_order = $customer->get_last_order();
// When empty
if ( empty ( $last_order ) ) return $na;
// Get order date
$order_items = $last_order->get_status();
// Latest WC_Order_Item_Product Object instance
$last_item = end( $order_items );
// Pass product ID to products shortcode
return $order_items;
}
// Register shortcode
add_shortcode( 'display_woostatus', 'woostatus' );
$order_items = $last_order->get_status() will return a string and is therefore not an array. So using end( $order_items ) is a superfluous step.
Use instead:
function woostatus() {
// Not available
$na = __( 'N/A', 'woocommerce' );
// For logged in users only
if ( ! is_user_logged_in() ) return $na;
// The current user ID
$user_id = get_current_user_id();
// Get the WC_Customer instance Object for the current user
$customer = new WC_Customer( $user_id );
// Get the last WC_Order Object instance from current customer
$last_order = $customer->get_last_order();
// When empty
if ( empty ( $last_order ) ) return $na;
// Get order status
$order_status = $last_order->get_status();
// Return
return $order_status;
}
// Register shortcode
add_shortcode( 'display_woostatus', 'woostatus' );
SHORTCODE USAGE
In an existing page:
[display_woostatus]
Or in PHP:
echo do_shortcode('[display_woostatus]');

How to display the last ordered product in WooCommerce via a shortcode

I'm looking for a way to display the last ordered product on another page.
I think it would be possible to maybe create a shortcode in the functions that takes the order details and displays them wherever I add the shortcode.
But I can't seem to figure out how to get it to work. So far I got this information to work with:
add_shortcode( 'displaylast', 'last' );
function last(){
$customer_id = get_current_user_id();
$order = wc_get_customer_last_order( $customer_id );
return $order->get_order();
}
[displaylast] is currently showing me noting. It does work when I change get_order() to get_billing_first_name().
That displays the order name. But I can't seem to get the item that was bought. Maybe there is a get_() that I'm not seeing?
You are close, however you must obtain the last product from the order object.
So you get:
function last() {
// Not available
$na = __( 'N/A', 'woocommerce' );
// For logged in users only
if ( ! is_user_logged_in() ) return $na;
// The current user ID
$user_id = get_current_user_id();
// Get the WC_Customer instance Object for the current user
$customer = new WC_Customer( $user_id );
// Get the last WC_Order Object instance from current customer
$last_order = $customer->get_last_order();
// When empty
if ( empty ( $last_order ) ) return $na;
// Get order items
$order_items = $last_order->get_items();
// Latest WC_Order_Item_Product Object instance
$last_item = end( $order_items );
// Get product ID
$product_id = $last_item->get_variation_id() > 0 ? $last_item->get_variation_id() : $last_item->get_product_id();
// Pass product ID to products shortcode
return do_shortcode("[product id='$product_id']");
}
// Register shortcode
add_shortcode( 'display_last', 'last' );
SHORTCODE USAGE
In an existing page:
[display_last]
Or in PHP:
echo do_shortcode('[display_last]');

Can´t get custom attribute on WooCommerce product

I try to save custom meta data after creating an order in WooCommerce. I try it with the woocommerce_new_order_item hook and in general it works. But I need to store a custom attribute from the ordered product..but I can´t get it.
What I tried:
add_action('woocommerce_new_order_item','add_basic_meta_for_new_quote',10,3); // add extra order metas
function add_basic_meta_for_new_quote($item_id, $values, $cart_item_key)
{
$angebotstext = get_post_meta($item_id, 'angebotstext', false);
wc_add_order_item_meta($item_id, 'angebotstext', $angebotstext);
}
or
add_action('woocommerce_new_order_item','add_basic_meta_for_new_quote',10,3); // add extra order metas
function add_basic_meta_for_new_quote($item_id, $values, $cart_item_key)
{
global $product;
$angebotstext = $product->get_attribute( 'pa_angebotstext' );
wc_add_order_item_meta($item_id, 'angebotstext', $angebotstext);
}
The attribute is saved here:
... and the result for meta_value is always empty, NULL or a:0:{}
Do you have any idea?
-----EDIT----
It worked with this way:
add_action('woocommerce_new_order_item','add_basic_meta_for_new_quote',10,3); // add extra order metas
function add_basic_meta_for_new_quote($item_id, $item, $order_id )
{
if ($order_id) {
$order = wc_get_order( $order_id );
}
# Iterating through each order items (WC_Order_Item_Product objects in WC 3+)
if ($order) {
foreach ( $order->get_items() as $item_id => $item_values ) {
// Product_id
$product_id = $item_values->get_product_id();
$product = wc_get_product($product_id);
$angebotstext = $product->get_attribute('Angebotstext');
if ( !empty($angebotstext) && $angebotstext != NULL ) {
wc_add_order_item_meta($item_id, 'Angebotstext' , $angebotstext);
}
}
}
}
BUT: This code adds my custom attribute two times as meta.... why that? 🤔
The main issue here is if the order contains multiple products, so you're going to face the issue of multiple updates for the same order.
To avoid that or to choose to deal with it the right way, here are some ideas:
To make this works for multiple products:
Changed this part:
wc_add_order_item_meta($item_id, 'Angebotstext _'.$product_id , $angebotstext);
This will add a new custom meta for each product by adding the product ID at the end of each meta_key and the meta_value will be the product unique value for that attribute.
so you're going to find this custom fields on the order page:
Angebotstext_123 = product attribute.
Angebotstext_485 = product
attribute. Angebotstext_951 = product attribute.
the '123', '485' are the product id and the meta value for that meta_key will be that product attribute.
To prevent it from updating multiple times:
if ($order) {
$angebotstext ='';
foreach ( $order->get_items() as $item_id => $item_values ) {
// Product_id
$product_id = $item_values->get_product_id();
$product = wc_get_product($product_id);
$angebotstext = $product->get_attribute('Angebotstext');
$prev_angebotstext = $angebotstext;
if ( !empty($angebotstext) && $angebotstext != NULL && $angebotstext != $prev_angebotstext ) {
wc_add_order_item_meta($item_id, 'Angebotstext' , $angebotstext);
}
}
}
"$prev_angebotstext" is the previous item attribute.
if ( !empty($angebotstext) && $angebotstext != NULL && $angebotstext != $prev_angebotstext )
This condition will check if the current product attribute is equal to the previous product attribute, if yes it will not update the order again.
Thank you!

Woocommerce get_cart in theme function.php get error message "get_cart() on null"

Bellow is code that I use to get products from cart
global $woocommerce;
$items = WC()->cart->get_cart();
I have this code inside functions.php in theme folder.
The issue is every time I run this code, I always get error message saying
"Fatal error: Call to a member function get_cart() on null"
What did I miss ?
You can use like this
global $woocommerce;
$items = $woocommerce->cart->get_cart();
foreach($items as $item => $values)
{
$_product = wc_get_product( $values['data']->get_id());
echo "<b>".$_product->get_title().'</b> <br> Quantity: '.$values['quantity'].'<br>';
$price = get_post_meta($values['product_id'] , '_price', true);
echo " Price: ".$price."<br>";
}
your code is valid, however you are probably calling it from the backend or somewhere where there is no cart. you might be looking to process order items from an order?
// Get an instance of the WC_Order object
$order = wc_get_order($order_id);
// Iterating through each WC_Order_Item_Product objects
foreach ($order->get_items() as $item_key => $item_values):
## Using WC_Order_Item methods ##
// Item ID is directly accessible from the $item_key in the foreach loop or
$item_id = $item_values->get_id();
## Using WC_Order_Item_Product methods ##
$item_name = $item_values->get_name(); // Name of the product
$item_type = $item_values->get_type(); // Type of the order item ("line_item")
endforeach;

Get Woocommerce variation attributes

I am trying to get variations of a variable product on custom product page. I have two attributes, one for sizes as select and the other for colors as swatches. The problem that I cannot display the attribute that I need to display, and when I use the following code it returns a text names of sizes or colors not the select dropdown for sizes or the colors swatches. Any help please ?!
echo implode(', ', wc_get_product_terms( $product_id, 'pa_colors' ));
This is a brief code to solve your question, I let you entire code, you can use only that you need.
The first is check if get_product function exists, and check the product type, to create a correct product object with the id (in my case $idProduct).
It work on woocommerce 3.x, I don't test it on woocommerce < 3.x.
if( function_exists('get_product') ) {
$product = get_product( $idProduct );
if ( $product->is_type( 'variable' ) ) {
$product = new WC_Product_Variable( $idProduct );
$available_variations = $product->get_available_variations(); //get all child variations
$variation_variations = $product- >get_variation_attributes(); // get all attributes by variations
// taxonomy => terms
// pa_attribute-color => array('blue', 'red', green)
// Use ex: get_taxonomy('pa_attribute-color')->labels; to get the Name and not the slug to attributes, it can be the taxonomy
// Use ex: get_term_by('name', 'pa_attribute-color', 'pa_attribute-color); to get the Name/label
$result = array( $available_variations , $attributes); // only to see the result you can use var_dump, error_log, etc.
//...
//...
}elseif ( $product->is_type( 'bundle' ) && class_exists( 'WC_Product_Bundle' ) ) {
$product = new WC_Product_Bundle( $idProduct );
}else{
$product = new WC_Product( $idProduct );
}
}
Also you try with:
$product->get_attribute( $key );
wc_attribute_label($key);
where $key can be pa_color , pa_size, etc
I hope help you.

Resources