How to show product attribute name in cart page - php

One of my favorite members helgatheviking, gave me a good solution of my previous question to remove the quantity field from cart page for specific product attribute . Below is the function given by her.
add_filter( 'woocommerce_cart_item_quantity', 'remove_cart_item_quantity', 10, 2 );
function remove_cart_item_quantity( $product_quantity, $cart_item_key ){
$cart_item = WC()->cart->cart_contents[ $cart_item_key ];
if( $cart_item['data']->is_type( 'variation' ) ){
$attributes = $cart_item['data']->get_attributes();
// var_dump( $attributes );
if( array_key_exists( 'color', $attributes ) ){
$product_quantity = '';
}
}
return $product_quantity;
}
Now the $product_quantity; return a blank string.
Is it possible to show the name instead of Blank. $product_quantity = ''; What should I replace ? If Selected product has color Green The $product_quantity; should return green.
EXAMPLE:
$product_quantity = '$color'; How could I get the color string from product attribute which in the cart.

I Solve this actually $_pname = WC()->cart->get_item_data( $cart_item ); So you can use $product_quantity = str_ireplace( 'Choose Quantity:', '',$_pname) ;
add_filter( 'woocommerce_cart_item_quantity', 'remove_cart_item_quantity', 10, 2 );
function remove_cart_item_quantity( $product_quantity, $cart_item_key ){
$cart_item = WC()->cart->cart_contents[ $cart_item_key ];
if( $cart_item['data']->is_type( 'variation' ) ){
$attributes = $cart_item['data']->get_attributes();
$_pname = WC()->cart->get_item_data( $cart_item );
if( array_key_exists( 'choose-quantity', $attributes ) ){
$product_quantity = str_ireplace( 'Choose Quantity:', '',$_pname) ;
}
}
return $product_quantity;
}
Output:

Related

Stop adding different type of product to cart and show notice

I am trying to add different product in cart. There are two type of product one is other and another is simple.
I need to grab if simple product in the cart then only simple can added and other in cart then only other.
I don't want to add simple and other type of product simultaneously.
add_action('woocommerce_add_to_cart', 'custome_add_to_cart', 10, 6);
function custome_add_to_cart($cart_id, $product_id, $request_quantity, $variation_id, $variation, $cart_item_data) {
global $woocommerce;
//print_r($cart_item_data); //Current
// die();
//check if product already in cart
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
$product_type = $cart_item['type'];
if ($product_type == 'other'){
if($cart_item_data['type'] == 'other'){
WC()->cart->add_to_cart( $product_id );
// print_r($cart_item); //Old Cart
// die();
}else{
wc_print_notice( 'This type of product not added 1', 'notice' );
}
}else{
//print_r($cart_item); //Old Cart
if($cart_item_data['type'] != 'other'){
WC()->cart->add_to_cart( $product_id );
}else{
wc_print_notice( 'This type of product not added 2', 'notice' );
exit;
}
}
}
}
}
I am using this hook but it's not working for me. It show 503 error.
Instead of using woocommerce_add_to_cart use woocommerce_add_to_cart_validation
This filter returns $passed, $product_id, $quantity, $variation_id, $variations but we need only the type of product.
add_filter( 'woocommerce_add_to_cart_validation', 'woocommerce_add_to_cart_validationcustom', 10, 2 );
function woocommerce_add_to_cart_validationcustom( $passed, $product_id ) {
global $woocommerce;
if(WC()->cart->is_empty()) return true;
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
$product = $cart_item['data'];
$current_type = $product->get_type();
}
//Get the product we are adding as object
$product_to_add = wc_get_product( $product_id );
$type_to_add = $product_to_add->get_type();
// Check if the product type is the same
if ( $current_type !== $type_to_add){
wc_add_notice( sprintf( __( "This is my custom error", "your-theme-language" ) ) ,'error' );
return false;
} else {
return true;
}
}

Woocommerce Product allready in cart

I have this code to show when the product is already in the cart I need it to show the quantity of the product also.
add_filter( 'woocommerce_product_add_to_cart_text', 'wcpt_modify_add_to_cart_text', 9999, 2 );
function wcpt_modify_add_to_cart_text( $text, $product ) {
// if cart is empty return 'Add to Quote'
if ( WC()->cart->is_empty() ) return 'Add to Quote';
// otherwise loop through cart items
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
$product_id = apply_filters( 'woocommerce_cart_item_product_id', $cart_item['product_id'], $cart_item, $cart_item_key );
$qty = $cart_item['quantity'];
// if cart contains current product ID return its quantity
if ( $product->get_id() == $product_id ) {
return $qty . ' - Already Added';
}
}
// if the cart is not empty but the product is not in the cart...
return 'Add to Quote';
}
UPDATED CODE ABOVE UPDATED WITH HOOKS ASWELL
The Code Above works wonders thanks to #businessbloomer the only problem now is that I have to refresh the page to see anything
Code is a bit messy, this revised version should work. I added some inline comments to explain each new section:
add_filter( 'woocommerce_product_add_to_cart_text', 'wcpt_modify_add_to_cart_text', 9999, 2 );
function wcpt_modify_add_to_cart_text( $text, $product ) {
// if cart is empty return 'Add to Quote'
if ( WC()->cart->is_empty() ) return 'Add to Quote';
// otherwise loop through cart items
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
$product_id = apply_filters( 'woocommerce_cart_item_product_id', $cart_item['product_id'], $cart_item, $cart_item_key );
$qty = $cart_item['quantity'];
// if cart contains current product ID return its quantity
if ( $product->get_id() == $product_id ) {
return $qty . ' - Already Added';
}
}
// if cart is not empty but product is not in the cart...
return 'Add to Quote';
}
Screenshot:

Display product categories and "brand" attribute term names under item name everywhere in WooCommerce

I want to display the category & attribute (brand) of each product under the product name in the Cart/checkout page
Example:
"Name of product"
"Category | Brand"
As shown in this image from shop
I would like to display it the same way on the cart page
(and also Thank you page + Order details, but these are lower priority)
I have this code which adds the Category to the cart page, but how can i add the attribute/brand next to it? Refer to this image
add_filter( 'woocommerce_cart_item_name', 'category_under_at_cart', 99, 3);
function category_under_at_cart( $name, $cart_item, $cart_item_key ) {
$product_item = $cart_item['data'];
// make sure to get parent product if variation
if ( $product_item->is_type( 'variation' ) ) {
$product_item = wc_get_product( $product_item->get_parent_id() );
}
$cat_ids = $product_item->get_category_ids();
$attributes = $product_item->get_attributes();
// if product has categories, concatenate cart item name with them
if ( $cat_ids ) $name .= '</br>' . wc_get_product_category_list( $product_item->get_id(), ', ', '<span class="posted_in">' . _n( count( $cat_ids )) . ' ', ' | ','</span>');
return $name;
}
The following will display the formatted product category(ies) and product attribute "brand" term names on minicart, cart, checkout, customer order and email notifications:
// Custom funtion that return the formatted category(ies) and attribute 'brand' term names
function get_categories_and_brand_html( $product_id ){
$product = wc_get_product($product_id);
$cat_names = (array) wp_get_post_terms( $product_id, 'product_cat', ['fields' => 'names'] );
$brand_name = $product->get_attribute('brand');
$output = '';
if ( ! empty($cat_names) || ! empty($brand_name) ) {
$output .= '</br><span class="posted_in">';
if ( ! empty($cat_names) ) {
$output .= implode(', ', $cat_names);
}
if ( ! empty($cat_names) && ! empty($brand_name) ) {
$output .= ' | ';
}
if ( ! empty($brand_name) ) {
$output .= $brand_name;
}
$output .= '</span>';
}
return $output;
}
// Display term names in minicart and cart page
add_filter( 'woocommerce_cart_item_name', 'category_brand_after_cart_item_name', 100, 3 );
function category_brand_after_cart_item_name( $item_name, $cart_item, $cart_item_key ) {
$terms_html = get_categories_and_brand_html( $cart_item['product_id'] );
if ( ! is_checkout() && ! empty($terms_html) ) {
$item_name .= $terms_html;
}
return $item_name;
}
// Display term names in checkout page
add_filter( 'woocommerce_checkout_cart_item_quantity', 'category_brand_after_checkout_item_name', 100, 3 );
function category_brand_after_checkout_item_name( $quantity, $cart_item, $cart_item_key ) {
$terms_html = get_categories_and_brand_html( $cart_item['product_id'] );
if ( is_checkout() && ! empty($terms_html) ) {
$quantity .= $terms_html;
}
return $quantity;
}
// Display term names on customer orders
add_filter( 'woocommerce_order_item_quantity_html', 'category_brand_after_order_item_name', 100, 2 );
function category_brand_after_order_item_name( $item_name, $item ) {
$terms_html = get_categories_and_brand_html( $item->get_product_id() );
if ( is_wc_endpoint_url() && ! empty($terms_html) ) {
$item_name .= $terms_html;
}
return $item_name;
}
// Display term names on email notifications
add_filter( 'woocommerce_order_item_name', 'category_brand_after_email_item_name', 100, 3 );
function category_brand_after_email_item_name( $item_name, $item, $is_visible ) {
$terms_html = get_categories_and_brand_html( $item->get_product_id() );
if ( ! is_wc_endpoint_url() && ! empty($terms_html) ) {
$item_name .= $terms_html;
}
return $item_name;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.

Display parent grouped product name in Woocommerce orders details

For Woocommerce grouped products I am displaying parent product name in cart and checkout pages using the code bellow:
// Adding the grouped product ID custom hidden field data in Cart object
add_action( 'woocommerce_add_cart_item_data', 'save_custom_fields_data_to_cart', 10, 2 );
function save_custom_fields_data_to_cart( $cart_item_data, $product_id ) {
if( ! empty( $_REQUEST['add-to-cart'] ) && $product_id != $_REQUEST['add-to-cart'] ) {
$cart_item_data['custom_data']['grouped_product_id'] = $_REQUEST['add-to-cart'];
$data['grouped_product_id'] = $_REQUEST['add-to-cart'];
// below statement make sure every add to cart action as unique line item
$cart_item_data['custom_data']['unique_key'] = md5( microtime().rand() );
WC()->session->set( 'custom_data', $data );
}
return $cart_item_data;
}
// Add the parent grouped product name to cart items names
add_filter( 'woocommerce_cart_item_name', 'custom_product_title_name', 10, 3 );
function custom_product_title_name( $cart_item_name, $cart_item, $cart_item_key ){
// Only in cart and checkout pages
if ( is_cart() || is_checkout() )
{
// The product object from cart item
$product = $cart_item['data'];
$product_permalink = $product->is_visible() ? $product->get_permalink( $cart_item ) : '';
// The parent product name and data
if( ! empty( $cart_item['custom_data']['grouped_product_id'] ) ){
$group_prod_id = $cart_item['custom_data']['grouped_product_id'];
$group_prod = wc_get_product($group_prod_id);
if ( ! $group_prod->is_type( 'grouped' ) ) return $cart_item_name;
$parent_product_name = $group_prod->get_name();
$group_prod_permalink = $group_prod->is_visible() ? $group_prod->get_permalink() : '';
if ( ! $product_permalink )
return $parent_product_name . ' > ' . $product->get_name();
else
return sprintf( '%s > %s', esc_url( $group_prod_permalink ), $parent_product_name, esc_url( $product_permalink ), $product->get_name() );
}
else
return $cart_item_name;
}
else
return $cart_item_name;
}
Code comes from here: Add the parent product name to each cart item names in WooCommerce
Now I would like to display also this parent product name in orders details and in back-end too.
I will be grateful for any help on this.
I have revisited the original code answer a bit and I have enabled the display of those parent products linked names on orders and email notifications:
// Adding the grouped product ID custom hidden field data in Cart object
add_filter( 'woocommerce_add_cart_item_data', 'save_custom_fields_data_to_cart', 20, 2 );
function save_custom_fields_data_to_cart( $cart_item_data, $product_id ) {
if( ! empty($_REQUEST['add-to-cart']) && $product_id != $_REQUEST['add-to-cart']
&& is_numeric($_REQUEST['add-to-cart']) ){
$group_prod = wc_get_product($_REQUEST['add-to-cart']);
if ( ! $group_prod->is_type( 'grouped' ) )
return $cart_item_data; // Exit
$cart_item_data['grouped_product'] = array(
'id' => $_REQUEST['add-to-cart'],
'name' => $group_prod->get_name(),
'link' => $group_prod->get_permalink(),
'visible' => $group_prod->is_visible(),
);
// Below statement make sure every add to cart action as unique line item
$cart_item_data['grouped_product']['unique_key'] = md5( microtime().rand() );
}
return $cart_item_data;
}
// Add the parent grouped product name to cart items names
add_filter( 'woocommerce_cart_item_name', 'custom_product_title_name', 20, 3 );
function custom_product_title_name( $cart_item_name, $cart_item, $cart_item_key ){
// The product object from cart item
$product = $cart_item['data'];
$product_permalink = $product->is_visible() ? $product->get_permalink( $cart_item ) : '';
// The parent product name and data
if( isset( $cart_item['grouped_product'] ) ){
$group_product = $cart_item['grouped_product'];
$group_prod_link = $product->is_visible() && is_cart() ? $group_product['link'] : '';
if ( ! $group_prod_link )
return $group_product['name'] . ' > ' . $product->get_name();
else
return sprintf(
'%s > %s',
esc_url( $group_prod_link ),
$group_product['name'],
esc_url( $product_permalink ),
$product->get_name()
);
}
else
return $cart_item_name;
}
// Save grouped product data in order item meta
add_action( 'woocommerce_checkout_create_order_line_item', 'added_grouped_order_item_meta', 20, 4 );
function added_grouped_order_item_meta( $item, $cart_item_key, $values, $order ) {
if( isset($values['grouped_product']) ){
$item_id = $item->get_id();
$grouped_data = $values['grouped_product'];
unset($grouped_data['unique_key']);
$item->update_meta_data( '_grouped_product', $grouped_data );
}
}
// Display grouped product linked names in order items (+ email notifications)
add_filter( 'woocommerce_order_item_name', 'custom_order_item_name', 20, 3 );
function custom_order_item_name( $item_name, $item, $is_visible ) {
$product = $item->get_product();
$product_id = $item->get_product_id();
$product_permalink = $is_visible ? $product->get_permalink( $item ) : '';
$grouped_data = wc_get_order_item_meta( $item->get_id(), '_grouped_product', true );
if( empty($grouped_data) ){
$item_name = $product_permalink ? sprintf(
'%s',
esc_url( $product_permalink),
$item->get_name()
) : $item->get_name();
} else {
$item_name = $product_permalink ? sprintf(
'%s > %s',
$grouped_data['link'],
$grouped_data['name'],
esc_url( $product_permalink) ,
$item->get_name()
) : $grouped_data['name'] . ' > ' . $item->get_name();
}
return $item_name;
}
// Display on backend order edit pages
add_action( 'woocommerce_before_order_itemmeta', 'backend_order_item_name_grouped', 20, 3 );
function backend_order_item_name_grouped( $item_id, $item, $product ){
if( ! ( is_admin() && $item->is_type('line_item') ) ) return;
$grouped_data = wc_get_order_item_meta( $item_id, '_grouped_product', true );
if( empty($grouped_data) ) return;
$product_link = admin_url( 'post.php?post=' . $grouped_data['id'] . '&action=edit' );
$grouped_name_html = '' . esc_html( $grouped_data['name'] ) . '';
echo '<br><br><div class="wc-order-item-name">
<small><strong>'.__('Grouped parent').':</strong></small><br>
' . $grouped_name_html . '
</div>';
}
Code goes in function.php file of your active child theme (or theme);
Tested and works.

Save and display a custom field as order item meta data in WooCommerce

In woocommerce, I have maisd wome customizations and I can add a custom text field in my products, Display the values in cart and checkout (see the screenshots below).
Text field in product page:
Value in the cart:
Value in the checkout:
But I can not get it to appear in the purchase details or in the administration section (see the screenshots below).
Checkout details without the value:
Administration orders without the value:
In my code below, could someone tell what I am doing wrong?
The code that I use in my functions.php file:
// Add the field to the product
add_action('woocommerce_before_add_to_cart_button', 'my_custom_checkout_field');
function my_custom_checkout_field() {
global $product;
$id = $product->get_id();
// Get the field name of InputText1
$InputText1Name = get_post_meta($id, 'InputText1', true);
if ((!empty(get_post_meta($id, $InputText1, true)))){
echo '<div id="InputText1">';
echo '<label>'.__($InputText1Name).'</label> <input type="text" name="$InputText1V">';
echo '</div>';
}
}
// Store custom field
function save_my_custom_checkout_field( $cart_item_data, $product_id ) {
if( isset( $_REQUEST['$InputText1V'] ) ) {
$cart_item_data[ '$InputText1V' ] = $_REQUEST['$InputText1V'];
/* below statement make sure every add to cart action as unique line item */
$cart_item_data['unique_key'] = md5( microtime().rand() );
}
return $cart_item_data;
}
add_action( 'woocommerce_add_cart_item_data', 'save_my_custom_checkout_field', 10, 2 );
// Render meta on cart and checkout
function render_meta_on_cart_and_checkout( $cart_data, $cart_item = null ){
// Get the product id inside the cart
foreach( WC()->cart->get_cart() as $cart_item ){
$product_id = $cart_item['product_id'];
}
// Get the field name of InputText1
$InputText1Name = get_post_meta($product_id, 'InputText1', true);
$custom_items = array();
/* Woo 2.4.2 updates */
if( !empty( $cart_data ) ) {
$custom_items = $cart_data;
}
if( isset( $cart_item['$InputText1V'] ) ) {
$custom_items[] = array( "name" => $InputText1Name, "value" => $cart_item['$InputText1V'] );
}
return $custom_items;
}
add_filter( 'woocommerce_get_item_data', 'render_meta_on_cart_and_checkout', 10, 2 );
// Display as order meta
function my_field_order_meta_handler( $item_id, $values, $cart_item_key ) {
if( isset( $values['$InputText1V'] ) ) {
wc_add_order_item_meta( $product_id, "$InputText1V", $values['$InputText1V'] );
}
}
// Update the order meta with field value
add_action('woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta');
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ($_POST['$InputText1V']) update_post_meta( $order_id, '$InputText1Name', esc_attr($_POST['$InputText1V']));
}
// Update the user meta with field value
add_action('woocommerce_checkout_update_user_meta', 'my_custom_checkout_field_update_user_meta');
function my_custom_checkout_field_update_user_meta( $user_id ) {
if ($user_id && $_POST['$InputText1V']) update_user_meta( $user_id, '$InputText1V', esc_attr($_POST['$InputText1V']) );
}
add_filter( 'woocommerce_hidden_order_itemmeta', 'hide_order_item_meta_fields' );
// Display field value on the order edit page
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta( $order ){
$order_id = method_exists( $order, 'get_id' ) ? $order->get_id() : $order->id;
echo '<p><strong>'.__($InputText1V).':</strong> ' . get_post_meta( $order_id, $InputText1V, true ) . '</p>';
}
function hide_order_item_meta_fields( $fields ) {
$fields[] = 'current_view';
$fields[] = 'custom_image';//Add all meta keys to this array,so that it will not be displayed in order meta box
return $fields;
}
add_action( 'woocommerce_after_order_itemmeta', 'order_meta_customized_display',10, 3 );
function order_meta_customized_display( $item_id, $item, $product ){
$order_product_id = $item['product_id'];
$field1name = get_post_meta($order_product_id, 'InputText1', true);
echo'<br>';
print_r($InputText1V);
echo'<br>';
echo $field1name;
echo ': ';
}
There are errors and missing things in your code. You don't need all that functions too and you should really avoid to use $ (and if you can capitals) in your custom field slugs (or in key slugs and even in function names) in your code.
I have tested and revisited your code. Here is what you need and can remove everything else:
// Add the field to the product
add_action('woocommerce_before_add_to_cart_button', 'my_custom_checkout_field');
function my_custom_checkout_field() {
global $product;
$product_id = $product->get_id();
// Get the field name of InputText1
$label = get_post_meta($product_id, 'InputText1', true);
if( ! empty( $label ) ){
echo '<div id="InputText1">
<label>'.$label.':</label> <input type="text" name="custom_slug" value="">
</div>';
}
}
// Store custom field label and value in cart item data
add_filter( 'woocommerce_add_cart_item_data', 'save_my_custom_checkout_field', 10, 2 );
function save_my_custom_checkout_field( $cart_item_data, $product_id ) {
if( isset( $_REQUEST['custom_slug'] ) ) {
$cart_item_data['custom_data']['label'] = get_post_meta($product_id, 'InputText1', true);
$cart_item_data['custom_data']['value'] = sanitize_text_field( $_REQUEST['custom_slug'] );
$cart_item_data['custom_data']['ukey'] = md5( microtime().rand() );
}
return $cart_item_data;
}
// Display items custom fields label and value in cart and checkout pages
add_filter( 'woocommerce_get_item_data', 'render_meta_on_cart_and_checkout', 10, 2 );
function render_meta_on_cart_and_checkout( $cart_data, $cart_item ){
$custom_items = array();
/* Woo 2.4.2 updates */
if( !empty( $cart_data ) ) {
$custom_items = $cart_data;
}
if( isset( $cart_item['custom_data'] ) ) {
$custom_items[] = array(
'name' => $cart_item['custom_data']['label'],
'value' => $cart_item['custom_data']['value'],
);
}
return $custom_items;
}
// Save item custom fields label and value as order item meta data
add_action('woocommerce_add_order_item_meta','save_in_order_item_meta', 10, 3 );
function save_in_order_item_meta( $item_id, $values, $cart_item_key ) {
if( isset( $values['custom_data'] ) ) {
wc_add_order_item_meta( $item_id, $values['custom_data']['label'], $values['custom_data']['value'] );
}
}
Code goes in function.php file of your active child theme (or active theme).
Tested and works.
This way you will get the display in Order received, Order view, Edit order (admin) and email notifications…

Categories