Display custom texts based on shipping classes in WooCommerce cart - php

Here is what I have and it works great for 1 shipping class, but want to have separate messages for different shipping classes:
// Display a custom text under cart item name in cart page
add_filter( 'woocommerce_cart_item_name', 'custom_text_cart_item_name', 10, 3 );
function custom_text_cart_item_name( $item_name, $cart_item, $cart_item_key ) {
// Here below define your shipping class slug
$shipping_class = '5-gallon';
if( is_cart() && $cart_item['data']->get_shipping_class() === $shipping_class ) {
$item_name .= '<br /><div class="item-shipping-class">' . __("Please call confirm shipping rates", "woocommerce") . '</div>';
}
return $item_name; }

For multiple shipping classes with different messages you can use the following:
// Display a custom text under cart item name in cart page
add_filter( 'woocommerce_cart_item_name', 'custom_text_cart_item_name', 10, 3 );
function custom_text_cart_item_name( $item_name, $cart_item, $cart_item_key ) {
// Only on cart page
if( ! is_cart() )
return $item_name;
// Here below define your shipping classes slugs (one by line)
$shipping_class_1 = '5-gallon';
$shipping_class_2 = '10-gallon';
$shipping_class = $cart_item['data']->get_shipping_class();
// First shipping class
if( $shipping_class === $shipping_class_1 ) {
$item_name .= '<br /><div class="item-shipping-class">' . __("Please call confirm shipping rates", "woocommerce") . '</div>';
}
// 2nd shipping class
elseif( $shipping_class === $shipping_class_2 ) {
$item_name .= '<br /><div class="item-shipping-class">' . __("Some different messageā€¦", "woocommerce") . '</div>';
}
return $item_name;
}
Code goes in functions.php file of the active child theme (or active theme). It should works.

Related

Replace the product name by the Sku in My account view order pages

Using Woocommerce, I would like to add SKU instead of the product name in the order view page of My Account /my-account/view-order/[orderid]/
I am able to add the SKU with a link using the code below.
The SKU is displayed just after the product name on the same line.
add_filter( 'woocommerce_order_item_name', 'display_sku_in_order_item', 20, 3 );
function display_sku_in_order_item( $item_name, $item, $is_visible ) {
if( is_wc_endpoint_url( 'view-order' ) ) {
$product = $item->get_product();
if( $sku = $product->get_sku() )
$item_name .= '' . __( "Product ", "woocommerce") . $sku . '';
}
return $item_name;
}
However, I would like to remove the product name but I don't know the code to write to do this. Any help please?
You just need to replace $item_name .= by $item_name = in your code, like:
add_filter( 'woocommerce_order_item_name', 'display_sku_in_order_item', 20, 3 );
function display_sku_in_order_item( $item_name, $item, $is_visible ) {
if( is_wc_endpoint_url( 'view-order' ) ) {
$product = $item->get_product();
if( $sku = $product->get_sku() )
$item_name = '' . __( "Product ", "woocommerce") . $sku . '';
}
return $item_name;
}
Code goes in function.php file of your active child theme (or active theme). It should work.

Add a delivery time based on custom fields calculations for WooCommerce Flat rate Shipping method

I use code that displays a custom field on the product edit page. This text box shows the cooking time on the single product page.
Here is the code:
// Backend: Display additional product fields
add_action( 'woocommerce_product_options_general_product_data', 'add_time_field_general_product_data' );
function add_time_field_general_product_data() {
// Custom Time Field
woocommerce_wp_text_input( array(
'id' => '_custom_time',
'label' => __( 'Time for cooking', 'woocommerce' ),
));
}
// Backend: Save the data value from the custom fields
add_action( 'woocommerce_admin_process_product_object', 'save_time_custom_fields_values' );
function save_time_custom_fields_values( $product ) {
// Save Custom Time Field
if( isset( $_POST['_custom_time'] ) ) {
$product->update_meta_data( '_custom_time', sanitize_text_field( $_POST['_custom_time'] ) );
}
}
// Display custom fields values under item name in checkout
add_filter( 'woocommerce_checkout_cart_item_quantity', 'custom_time_field_checkout_item_name', 10, 3 );
function custom_time_field_checkout_item_name( $item_qty, $cart_item, $cart_item_key ) {
if( $value4 = $cart_item['data']->get_meta('_custom_time') ) {
$item_qty .= '<br /><div class="my-custom-style"><strong>' . __("Time for cooking", "woocommerce") . ':</strong> ' . $value4 . ' min.</div>';
}
return $item_qty;
}
// Display custom fields values on orders and email notifications
add_filter( 'woocommerce_order_item_name', 'custom_time_field_order_item_name', 10, 2 );
function custom_time_field_order_item_name( $item_name, $item ) {
$product = $item->get_product();
if( $value4 = $product->get_meta('_custom_time') ) {
$item_name .= '<br /><span class="my-custom-style"><strong>' . __("Time for cooking", "woocommerce") . ':</strong> ' . $value4 . ' min.</span>';
}
return $item_name;
}
How can get the following functionality based on this code?
For example, a customer adds several dishes to a cart and checkout order. He sees how much time will be cooking this or that dish.
But when the customer chooses the delivery by courier (Flat Rate), in the same block, the delivery time is shown.
Flat Rate = $10
Delivery time = (the longest cooking time is selected from the order) min. + 45 min.
As I understand it, need to get the data of the custom field '_custom_time' when placing the order. Then, somehow need to get the highest value of this field and add 45 minutes.
I ask for your help! I hope that the answer to this question will be useful to many developers.
Try the following codethat will display a delivery time (calculated from the highest item cooking time value + 45 minutes) when a "flat rate" shipping method is selected on checkout page:
add_action( 'woocommerce_after_shipping_rate', 'action_after_shipping_rate_callback', 10, 2 );
function action_after_shipping_rate_callback( $method, $index ) {
$chosen_shipping_id = WC()->session->get( 'chosen_shipping_methods' )[$index];
if( is_checkout() && $method->method_id === 'flat_rate' && $method->id === $chosen_shipping_id ) {
$extra_time = 45; // Additional time to be added
$data_array = []; // Initializing
// Loop through car items
foreach ( WC()->cart->get_cart() as $cart_item ) {
if( $cooking_time = $cart_item['data']->get_meta('_custom_time') ) {
$data_array[] = (int) $cooking_time;
}
}
if ( sizeof($data_array) ) {
$max_time = (int) max($data_array);
$delivery_time = $max_time + $extra_time;
echo '<br><small style="margin-left:2em;border:solid 1px #ccc;padding:2px 5px;"><strong>' . __("Delivery time", "woocommerce") . '</strong>: ' . $delivery_time . ' min.</small>';
}
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
To enable that in cart page too, remove is_checkout() && from the IF statement.

Add shipping class under items in New Order email in WooCommerce?

I am trying to add the shipping class under each product to the new order emails for both admin and customers in WooCommerce. This is my first time posting a question so please forgive me if there are formatting issues.
I used the code found here: https://wordpress.stackexchange.com/questions/291637/woocommerce-add-shipping-class-below-each-product-in-shopping-cart-page
That adds the shipping class below each product in the cart but I want to be able to show it on the order emails also.
I am just unsure of which objects to call to grab the data for each product in the new order email.
Here's the code I'm using:
add_action( 'woocommerce_order_item_meta_start', 'ts_order_item_meta_start', 10, 4 );
function ts_order_item_meta_start( $item_id, $item, $order, $plain_text, $item_name ){
$product = $cart_item['data']; // Get the WC_Product object instance
$shipping_class_id = $product->get_shipping_class_id(); // Shipping class ID
$shipping_class_term = get_term( $shipping_class_id, 'product_shipping_class' );
if( empty( $shipping_class_id ) )
return $item_name; // Return default product title (in case of)
$label = __( 'Shipping class', 'woocommerce' );
return $item_name . '<br>
<p class="item-shipping_class" style="margin:12px 0 0;">
<strong>' .$label . ': </strong>' . $shipping_class_term->name . '</p>';
}
I expected the shipping class to be listed below each product in the "New Order" email but currently adding this code returns an internal server error upon checkout.
The following will display The product shipping class name in Woocommerce "New Order" Email notification:
// Setting the email_is as a global variable
add_action('woocommerce_email_before_order_table', 'the_email_id_as_a_global', 1, 4);
function the_email_id_as_a_global($order, $sent_to_admin, $plain_text, $email ){
$GLOBALS['email_id_str'] = $email->id;
}
// Display Items shipping class name in New Order email notification
add_filter( 'woocommerce_order_item_name', 'custom_order_item_name', 10, 3 );
function custom_order_item_name( $item_name, $item, $is_visible ) {
// Targeting email notifications only
if( is_wc_endpoint_url() ) return $item_name;
// Get the WC_Product object (from order item)
$product = $item->get_product();
if( $shipping_class_id = $product->get_shipping_class_id() ){
// Getting the email ID global variable
$refNameGlobalsVar = $GLOBALS;
$email_id = $refNameGlobalsVar['email_id_str'];
// Only for New Order email notification
if( ! empty($email_id) && 'new_order' === $email_id ) {
$shipping_class_name = get_term( $shipping_class_id, 'product_shipping_class' )->name;
$item_name .= '<br><p class="item-shipping_class" style="margin:12px 0 0;">
<strong>' . __( 'Shipping class', 'woocommerce' ) . ': </strong>' . $shipping_class_name . '</p>';
}
}
return $item_name;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.

Show SKU on cart and checkout pages in Woocommerce 3

I would like to display SKU on cart (Under product column ) and checkout page.
I searched SO, but all answers are for old versions of WooCommerce and non of them is for 3.x.
How can I show SKU on cart and checkout pages in Woocommerce 3?
2021 Update
You can do it with a custom unction hooked in woocommerce_cart_item_name action hook, this way:
// Display the sku below cart item name
add_filter( 'woocommerce_cart_item_name', 'display_sku_after_item_name', 5, 3 );
function display_sku_after_item_name( $item_name, $cart_item, $cart_item_key ) {
$product = $cart_item['data']; // The WC_Product Object
if( is_cart() && $product->get_sku() ) {
$item_name .= '<br><span class="item-sku">'. $product->get_sku() . '</span>';
}
return $item_name;
}
// Display the sku below under cart item name in checkout
add_filter( 'woocommerce_checkout_cart_item_quantity', 'display_sku_after_item_qty', 5, 3 );
function display_sku_after_item_qty( $item_quantity, $cart_item, $cart_item_key ) {
$product = $cart_item['data']; // The WC_Product Object
if( $product->get_sku() ) {
$item_quantity .= '<br><span class="item-sku">'. $product->get_sku() . '</span>';
}
return $item_quantity;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and works on WooCommerce 3+. You will get:
And
Related similar: How to Show SKU with product title in Order received page and Email order
You'll need to do some template overrides.
Cart
Copy plugins/woocommerce/templates/cart/cart.php into your theme file at my_theme/woocommerce/cart/cart.php if it isn't already there. Then add the following at approx line #85
// Meta data
// (this is already in cart.php; look for it for where to place the next snippet)
echo WC()->cart->get_item_data( $cart_item );
// Add SKU below product name
if ( !empty($_product->get_sku()) ) { ?>
<div class="sku">
<small><?php echo "SKU: ". $_product->get_sku(); ?></small>
</div>
<?php }
Checkout
Copy plugins/woocommerce/templates/checkout/review-order.php into your theme file at my_theme/woocommerce/checkout/review-order.php if it isn't already there. Then add the following at approx line #43
<?php
// (this is already in review-order.php; look for it for where to place the next snippet)
echo WC()->cart->get_item_data( $cart_item ); ?>
<?php
// Add SKU below product name
if ( !empty($_product->get_sku()) ) { ?>
<div class="sku">
<small><?php echo "SKU: ". $_product->get_sku(); ?></small>
</div>
<?php } ?>
You can do it with this way:
/**
* #snippet Show SKU # WooCommerce Cart
* #author Khalid Almallahi
*/
add_action( 'woocommerce_after_cart_item_name', 'abukotsh_sku_below_cart_item_name', 11, 2 );
function abukotsh_sku_below_cart_item_name( $cart_item, $cart_item_key ) {
$_product = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key );
$sku = $_product->get_sku();
if ( ! $sku ) return;
echo '<p><small>SKU: ' . $sku . '</small></p>';
}

WooCommerce: Display also product variation description on cart items

I'm trying to display my product variation description in my Cart. I have tried inserting this code in the cart.php template:
if ( $_product->is_type( 'variation' ) ) {echo $_product->get_variation_description();}
By following this documentation https://docs.woocommerce.com/document/template-structure/
But it's still not showing up.
Not sure what I'm doing wrong here.
Can anyone help on this?
Updated for WooCommerce version 3 and above
Since WooCommerce 3, get_variation_description() is now deprecated and replaced by get_description() WC_Product method.
To get your product item variation description (filtering variation product type condition), you can use the following hooked function instead:
// Cart page (and mini cart)
add_filter( 'woocommerce_cart_item_name', 'cart_item_product_description', 20, 3);
function cart_item_product_description( $item_name, $cart_item, $cart_item_key ) {
if ( ! is_checkout() ) {
if( $cart_item['variation_id'] > 0 ) {
$description = $cart_item['data']->get_description(); // variation description
} else {
$description = $cart_item['data']->get_short_description(); // product short description (for others)
}
if ( ! empty($description) ) {
return $item_name . '<br><div class="description">
<strong>' . __( 'Description', 'woocommerce' ) . '</strong>: '. $description . '
</div>';
}
}
return $item_name;
}
// Checkout page
add_filter( 'woocommerce_checkout_cart_item_quantity', 'cart_item_checkout_product_description', 20, 3);
function cart_item_checkout_product_description( $item_quantity, $cart_item, $cart_item_key ) {
if( $cart_item['variation_id'] > 0 ) {
$description = $cart_item['data']->get_description(); // variation description
} else {
$description = $cart_item['data']->get_short_description(); // product short description (for others)
}
if ( ! empty($description) ) {
return $item_quantity . '<br><div class="description">
<strong>' . __( 'Description', 'woocommerce' ) . '</strong>: '. $description . '
</div>';
}
return $item_quantity;
}
Now the description is just displayed between the title and the variation attributes values (if there is any).
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
This will work for WC 3.0
add_filter( 'woocommerce_cart_item_name', 'cart_variation_description', 20, 3);
function cart_variation_description( $title, $cart_item, $cart_item_key ) {
$item = $cart_item['data'];
if(!empty($item) && $item->is_type( 'variation' ) ) {
return $item->get_name();
} else
return $title;
}
You can get it via global variable $woocommerce also-
global $woocommerce;
$cart_data = $woocommerce->cart->get_cart();
foreach ($cart_data as $value) {
$_product = $value['data'];
if( $_product->is_type( 'variation' ) ){
echo $_product->id . '<br>';
}
}
I already check it.

Categories