i want to hide/remove specific messages from woo commerce without modifying basic woocommerce plugin.
There are several types of messages related to coupon like
Coupon code already applied!
Sorry! Coupon 12345 already applied to your cart. (here i essentially want to hide coupon code)
and several others similar to these coupon codes.
i just want to hide these type of coupon/cart messages, others are fine like "Product successfully added!" or any other error messages.
Basically the aim is to show all other messages (Error and success messages) but dont wanna show coupon messages and a coupon code in to these messages.
So, is there any way to do this by doing any hook etc, like one i've found to eliminate all message strings (if i am not wrong).
add_filter( 'woocommerce_coupon_message', '__return_empty_string' );
One more thing is, one message is repeating on cart page several times when i add product in to the car. "Coupon code already applied!" 2,3, to 4 times.
Okay, found solution
go to woocommerce tempaltes, copy notices folder and edit the desired template, in my case its error.php
copy/edit code
<ul class="woocommerce-error">
<?php
foreach ( $messages as $message ) :
if ( $message == "Coupon code already applied!" ) {
$message = "";//empty error string
} else if (strpos($message, 'does not exist!') !== false) {
$message = ""; //empty error string
}
else if (strpos($message, 'Sorry, it seems the coupon') !== false) {
$message = "";//empty error string
}
else if (strpos($message, 'Sorry, this coupon is not applicable to your cart contents') !== false) {
$message = "Sorry, the discount is not applicable to your cart contents"; //updated error string
}
?>
<li><?php echo wp_kses_post( $message ); ?></li>
<?php
break;
endforeach; ?>
</ul>
I know this is an old thread, but I think I have just worked out how to do this for the coupon error messages.
On my store I use WooCommerce Smart Coupons which allows coupons to be sold as gift cards. I don't want people to be able to purchase gift cards using a gift card, so I have added the gift card category to the exclude category list on the coupon usage restriction.
Anyway, I wanted to alter the error message if somebody tried to use a gift card coupon code when there was a gift card in the cart. This is the code I used:
function filter_woocommerce_coupon_error( $err, $err_code, $instance ) {
if ( $err_code == '114' ) {
global $woocommerce;
$categories = $instance->get_excluded_product_categories();
if ( in_array( '15', $categories ) ) {
$err = sprintf( __( 'Sorry, you cannot use a Gift Card to purchase another Gift Card.' ) );
}
}
return $err;
};
add_filter( 'woocommerce_coupon_error', 'filter_woocommerce_coupon_error', 10, 3 );
The $err_code for specific error messages can be found in the file woocommerce/includes/class-wc-coupon.php.
In my case, I wanted to edit error message for error code 114 (E_WC_COUPON_EXCLUDED_CATEGORIES). I also wanted my custom message to only appear if a 114 error was triggered by a gift card being in the cart, not for every 114 error. To solve this I added in the if ( in_array( '15', $categories ) ). What this does is check to see if the error message has been triggered by a product that is in category 15 (this being the gift card category for my store. Change 15 to whichever category you are using).
The $instance variable is what WooCommerce uses to pass the details of the cart/coupon back to the function.
I'm very new to coding, so I am sorry if my code and my explanation isn't great, but it definitely appears to work for me. I added it into functions.php.
So the crux of your question is - how can I customise WooCommerce coupon messages?
I have half an answer - I've customised coupon messages (the green boxed ones) using the "woocommerce_coupon_message" filter. BUT I've not yet been able to get the coupon error messages (the red boxed ones) working using the "woocommerce_coupon_error" filter.
I've tried conditional statements based on a few different methods from Class WC_Cart to no avail. I just cant seem to "intercept" (and then customise) the error messages before they're printed. If somebody has a solution to Coupon Errors I'd be happy to hear it.
Anyhow... the below function is hooked into the "woocommerce_before_cart" & "woocommerce_before_checkout_form" actions so the function works for either page.
It can obviously be customised to no end, but my example basically tests for a valid coupon and then you can change the message or return nothing. You can also test for other conditions to throw up custom notices of all sorts! Much better then modifying template files! :-)
add_action( 'woocommerce_before_cart', 'custom_coupon_messages' );
add_action( 'woocommerce_before_checkout_form', 'custom_coupon_messages' );
function custom_coupon_messages() {
global $woocommerce;
//Set coupon codes.
$coupon_code = 'Bigly-Yuge';
//Set coupon objects.
$coupon_test = new WC_Coupon( 'Bigly-Yuge' );
//Get the cart subtotal. Should return as a Double.
$cart_subtotal = WC()->cart->subtotal;
//If coupon test is passed add coupon.
if ( $coupon_test->is_valid() && $woocommerce->cart->has_discount( $coupon_code ) ) {
//Filter the coupon success message to display a custom message.
add_filter( 'woocommerce_coupon_message', 'filter_woocommerce_coupon_message', 10, 3 );
function filter_woocommerce_coupon_message( $msg, $msg_code, $instance ) {
//Set a custom coupon message.
$msg_code = 'case self::WC_COUPON_SUCCESS';
$msg = __( 'You saved BIGLY YUGE!', 'woocommerce' );
return $msg;
return $msg_code;
//Or return nothing (no message will be displayed - comment out the above/uncomment below).
// return '';
};
//Print the above notice to screen.
wc_print_notices();
}
elseif ( $cart_subtotal > 499 ) {
//Print a notice (the blue boxed one)
wc_print_notice( 'Spend $500 to qualify for the BIGLY YUGE discount!!!', 'notice' );
}
}
Related
In WooCommerce I want to restrict the ordering of subscription products so that if one of them is added to the cart then you cannot add any other non-subscription products. The subscription products are in the array listed with their products ids.
The issue I have is that when a customer adds non-subscription products to the cart and then tries to add a subscription product the code works (as it should).
However, if they first add a subscription product and then try to add non-subscription products the code does not work and it allows all products in the cart.
This is the current code:
// If subscription box ordered limit cart to no other products
add_filter( 'woocommerce_add_to_cart_validation', 'wc_limit_one_per_order', 10, 2 );
function wc_limit_one_per_order( $passed_validation, $product_id ) {
if ( ! in_array( $product_id, array( 245632, 245626, 245623, 245620, 245617, 245614, 245610, 245606, 245601 ) ) ) {
return $passed_validation;
}
if ( WC()->cart->get_cart_contents_count() >= 1 ) {
wc_add_notice( __( 'The subscription box cannot be purchased with other non-subscripton box products. Please, empty your cart first and then add it again.', 'woocommerce' ), 'error' );
return false;
}
return $passed_validation;
}
What are you missing, and you can include this in your function, is to check the cart for its contents. You'll need to loop over the cart items, and review the possibilities. I outlined it below
Firstly check the cart for existing products with subscriptions
Then check what is being added ($product_id). If a subscription exists, and another subscription is added. I guess there is no problem?
After that, you want respond to when a non-subscription product is added while the cart has a subscription product
And lastly, in the final else statement, it's possible to check the alternative: When a non-subscription product is in the cart and a subscription product is added.
Anyway, there might be some mistakes in the code, also with validation parameter. I didn't take that into account. Also, it can easily be simplified. Just wanted to outline all possibilities.
$subscription_products = array( 245632, 245626, 245623, 245620, 245617, 245614, 245610, 245606, 245601 );
foreach (WC()->cart->get_cart() as $cart_item_key => $values) {
$_product = $values['data'];
// is there a subscription in the cart?
if( in_array($_product->get_id(), $subscription_products) ) {
// yes!
// are we adding a subscription product?
if( in_array($product_id, $subscription_products) ) {
// we are. All good.
} else {
// no we are not. We can decide to empty the cart
unset(WC()->cart->cart_contents[$cart_item_key]);
wc_add_notice( 'Custom error message', 'error' );
// OR not add the product (return false)
return false;
}
//
} else {
// no!
// are we adding a subscription product?
if( in_array($product_id, $subscription_products) ) {
// we are. A Problem!
// We can decide to empty the cart
unset(WC()->cart->cart_contents[$cart_item_key]);
wc_add_notice( 'Custom error message', 'error' );
// OR not add the product (return false)
return false;
}
}
}
My question and code is directly based off of this question -
"
I have a store containing 5 categories. It's multivendor and due to shipping complications, I can only sell products from one specific category ('paint') when they are alone in the cart. So I need to prevent add to cart of any non-paint products when the cart contains paint, and display an error message, and I need to prevent paint products being added to a cart containing any other categories, and disaply an error message.
I've tried to cobble together this code from snippets I've found lying around on Stackoverflow and elsewhere. The logic seems to work in my brain, but when I try to implement the code (through functions.php) it prevents any product from being added to the cart unless the cart is empty."
Link to question -
Prevent add to cart if cart contains a specific category (WooCommerce)
I have checked and modified the accepted answer to suit my needs however it doesnt seem to work at all as i have the same question just related to a different category (ie gas instead of paint), it was my understanding that I would just have to modify the "has_term" function in order to get this to work as it is just a matter of pointing to a particular category?
//*** Prevent mixture of gas and other prods in same cart ***//
function dont_add_gas_to_cart_containing_other($validation, $product_id) {
// Set flag false until we find a product in gas
$cart_has_gas = false;
// Set $cat_check true if a cart item is in gas cat
foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item) {
$product = $cart_item['data'];
if (has_term('Gas', 'Gas Tanks & Accessories', $product->id)) {
$cart_has_gas = true;
// break because we only need one "true" to matter here
break;
}
}
$product_is_gas = false;
if (has_term('Gas', 'Gas Tanks & Accessories', $product_id)) {
$product_is_gas = true;
}
// Return true if cart empty
if (!WC()->cart->get_cart_contents_count() == 0) {
// If cart contains gas and product to be added is not gas, display error message and return false.
if ($cart_has_gas && !$product_is_gas) {
wc_add_notice('Sorry, you can only purchase Helium Gas products on their own. To purchase this product, please checkout your current cart or empty your cart and try again', 'error');
$validation = false;
}
// If cart contains a product that is not gas and product to be added is gas, display error message and return false.
elseif (!$cart_has_gas && $product_is_gas) {
wc_add_notice('Sorry, you can only purchase Helium Gas products on their own. To purchase this product, please checkout your current cart or empty your cart and try again', 'error');
$validation = false;
}
}
// Otherwise, return true.
return $validation;
}
add_filter('woocommerce_add_to_cart_validation', 'dont_add_gas_to_cart_containing_other', 10, 2);
Because you gave the category name to the function, you must give the function a slug, second parameter should be 'product_cat' and last parameter should be a Product ID.
$product = $cart_item['data'];
if( has_term( 'gas', 'product_cat', $product->get_id() ) ) {
......
}
I am trying to tackle an issue by renaming the default message below when there are no shipping methods available, either set by rule based plugins or there simply isn't any methods set in WooCommerce.
No shipping method has been selected. Please double check your address, or contact us if you need any help.
I have used the below function using the snippets plugin and I can confirm it changes the message in the cart and checkout underneath the shipping label.
However, if someone then attempts to checkout they get a red WooCommerce error message at the top of the screen which is still the default message above.
How do I also change this error message ? I would like to change it to something different than what my code below shows to give me the flexibility to put a short message in the cart totals box and a longer more informational message as to why no methods are available.
My Function:
add_filter( 'woocommerce_cart_no_shipping_available_html', 'no_shipping_available_html' );
add_filter( 'woocommerce_no_shipping_available_html', 'no_shipping_available_html' );
function no_shipping_available_html( $message ) {
$country = WC()->customer->get_shipping_country();
if ( !empty( $country ) ) {
$all_countries = WC()->countries->get_countries();
return sprintf( 'Orders delivered into the EU are limited to €150 (inc shipping) or a max weight of 2kg. The items in you cart exceed this limit. Please remove an item or reduce the quantity required to bring the order value/weight within the permitted values.', $all_countries[ $country ] );
}
return 'Orders delivered into the EU are limited to €150 (inc shipping) or a max weight of 2kg. The items in you cart exceed this limit. Please remove an item or reduce the quantity required to bring the order value/weight within the permitted values.';
}
This text is located in WC_Checkout Class inside validate_checkout() method. There are no filters to make changes to it, but you can use WordPress gettext filter for that as follows:
add_filter( 'gettext', 'change_checkout_no_shipping_method_text', 10, 3 );
function change_checkout_no_shipping_method_text( $translated_text, $text, $domain ) {
if ( is_checkout() && ! is_wc_endpoint_url() ) {
$original_text = 'No shipping method has been selected. Please double check your address, or contact us if you need any help.';
$new_text = 'Here your own text replacement.';
if ( $text === $original_text ) {
$translated_text = $new_text;
}
}
return $translated_text;
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
You could use a plugin like Loco translate if you want, that makes easier to do your job.. but you could try this code, similar to #LoicTheAztec inside functions.php (either on your theme or child theme file)
add_filter( 'gettext', 'ds_translate_woocommerce_strings', 999, 3 );
function ds_translate_woocommerce_strings( $translated,
$untranslated, $domain ) {
if ( ! is_admin() ) {
switch ($translated) {
case 'the message you want to be translated exactly as you see it in WP':
$translated = 'your new message';
break;
}
}
return $translated;
}
Iin WooCommerce, I've set woocommerce->settings->products->inventory->stock display format to "Never show quantity remaining in stock".
However if a customer ads a product to the cart, continues to cart or checkout page and enter a value higher than we have in stock they get this error message:
Sorry, we do not have enough "{product_name}" in stock to fulfill your order ({available_stock_amount} in stock). Please edit your cart and try again. We apologize for any inconvenience caused.
What filter can I use to edit this output? I don't want it to show (absolutely anywhere on the front end shop) the actual available stock amount.
I've found that this is handled in a function (check_cart_item_stock) in, [root]->wp-content->plugins->woocommerce->includes->class-wc-cart.php on line 491:
if ( ! $product->has_enough_stock( $product_qty_in_cart[ $product->get_stock_managed_by_id() ] ) ) {
/* translators: 1: product name 2: quantity in stock */
$error->add( 'out-of-stock', sprintf( __( 'Sorry, we do not have enough "%1$s" in stock to fulfill your order (%2$s in stock). Please edit your cart and try again. We apologize for any inconvenience caused.', 'woocommerce' ), $product->get_name(), wc_format_stock_quantity_for_display( $product->get_stock_quantity(), $product ) ) );
return $error;
}
So what I want to filter out is the "(%2$s in stock)" part. But I can't find any filter for this.
This messages displayed are located in WC_Cart class source code at line 493 and 522 …
What you can try is to replace the text by your custom text version in this function hooked in WordPress gettex filter hook:
add_filter( 'gettext', 'wc_replacing_cart_stock_notices_texts', 50, 3 );
function wc_replacing_cart_stock_notices_texts( $replacement_text, $source_text, $domain ) {
// Here the sub string to search
$substring_to_search = 'Sorry, we do not have enough';
// The text message replacement
if( strpos( $source_text, $substring_to_search ) ) {
// define here your replacement text
$replacement_text = __( 'Sorry, we do not have enough products in stock to fulfill your order…', $domain );
}
return $replacement_text;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This should works (unstested)…
Thank you #LoicTheAztec for your reply, but I actually found a filter for this after all, woocommerce_add_error
So my final filter (in functions.php) is this:
function remove_stock_info_error($error){
global $woocommerce;
foreach ($woocommerce->cart->cart_contents as $item) {
$product_id = isset($item['variation_id']) ? $item['variation_id'] : $item['product_id'];
$product = new \WC_Product_Factory();
$product = $product->get_product($product_id);
if ($item['quantity'] > $product->get_stock_quantity()){
$name = $product->get_name();
$error = 'Sorry, we do not have enough "'.$name.'" in stock to fulfill your order. Please edit your cart and try again. We apologize for any inconvenience caused.';
return $error;
}
}
}add_filter( 'woocommerce_add_error', 'remove_stock_info_error' );
This should resolve it across the board.
NOTE! I also found that the input boxes have a max attribut, which in turn means that anyone can still see the actual total available amount (by either simply using the built in increment (which will stop when reaching max value) or just enter to high of a value, click update cart and you will get a notice that the amount has to be equal to or less than X (max value)).
To combat this I added a simple JS in my pre-existing "woo-xtra.js":
var qty = $('form.woocommerce-cart-form').find('input.qty');
// Reset max value for quantity input box to hide real stock
qty.attr('max', '');
This way there is no max value, but the user will still get the error (if over the limit) from above :)
I.e. Problem solved
I have stock management enabled on my WooCommerce store as this is critical being that we sell physical goods and products that we stock in our warehouse. Everything about the inventory management works as we need it to, but because we have it enabled, we're getting extra order notes displaying on the Edit Order screens of WooCommerce. This is causing extra data to be saved to our database and also gets based into QuickBooks as order notes that we just do not need to be there.
I've found in the core WooCommerce the function that is adding this order note, I'm just not sure how to remove it without modifying core files. I'm looking for some sort of way to disable or remove it with a hook, filter, or class extension that can be placed in my sites utility plugin.
Screenshot showing sidebar of Edit Order screen with numerous "stock reduced" messages displayed
The code is in the abstract-wc-order.php file (/woocommerce/abstracts/abstract-wc-order.php) starting at lines 2460:
if ( isset( $item['variation_id'] ) && $item['variation_id'] ) {
$this->add_order_note( sprintf( __( 'Item #%s variation #%s stock reduced from %s to %s.', 'woocommerce' ), $item['product_id'], $item['variation_id'], $new_stock + $qty, $new_stock) );
} else {
$this->add_order_note( sprintf( __( 'Item #%s stock reduced from %s to %s.', 'woocommerce' ), $item['product_id'], $new_stock + $qty, $new_stock) );
}
You can grab the comment id and content via the wp_insert_comment action hook and delete it, which would likely prevent it from being sent to Quickbooks. Using a simple strpos match for "stock reduced from" we can check if the comment is for stock reduction.
add_action('wp_insert_comment', 'remove_stock_comment', 10, 2);
function remove_stock_comment($id, $comment) {
if( strpos($comment->comment_content, 'stock reduced from') !== false ) {
wp_delete_comment( $id );
}
}
To further check whether the comment belongs to an order, you can get the comment's POST ID and check its post_type.
Note: I'm not sure whether this solution would break any other functionality, but this is the only solution I could come up with.