Woocommerce, show/hide added to cart message based on parameters - php

When adding product to cart user is redirected to cart/payment window and has 'added to cart' notice present. This is the default way I would like to keep, but with addition of my custom method.
My custom button allows customer to stay on shop site while adding another products. However when he enters cart/payment he gets flooded with multiple 'added to cart' messages, which looks just bad:
multiple messages
I want to know if there is option to turn off messages but only if user clicked my custom button.
I've tried attaching get parameter to button and reading it in my code:
add_filter( 'wc_add_to_cart_message_html', 'filter_wc_add_to_cart_message_html', 10, 2 );
function filter_wc_add_to_cart_message_html( $message, $products ) {
$showMSG = get_query_var('show-cmsg');
if ( $showMSG ){
return $message;
}
return null;
}
But the get_query_var always results in null, no matter the get parameters. I've registered it:
function add_custom_query_vars( $vars ){
$vars[] = "show-cmsg";
return $vars;
}
Is there a way to hide the messages depending on which button user pressed?
Or if you can block woocommerce from genereting messages if you pressed custom button?
Or just a way to even limit the messages to 1 most recent instead of showing all at once?
I would also do same for some other error mesasges, but If i would find answer to this then I quess i would manage errors.

You should use session because add_custom_query_vars just add key not value that's why you getting always null.
So for the session first check session_start() or not, then set the value in the session after that you can get anywhere accordingly.
Example:
function woo_register_session() {
if(!session_id() || session_status() == PHP_SESSION_NONE){
session_start();
}
$_SESSION['show_cmsg'] = true;
}
add_action( 'init', 'woo_register_session' );
Then get the session and use it in your function accordingly
add_filter( 'wc_add_to_cart_message_html', 'filter_wc_add_to_cart_message_html', 10, 2 );
function filter_wc_add_to_cart_message_html( $message, $products ) {
$showMSG = $_SESSION['show_cmsg'] ? true : false;
if ( $showMSG ){
return $message;
}
return null;
}
Another alternate function for message
add_filter( 'wc_add_to_cart_message', 'woo_add_to_cart_message' );
function woo_add_to_cart_message() {
$showMSG = $_SESSION['show_cmsg'] ? true : false;
if($showMSG){
if (get_option('woocommerce_cart_redirect_after_add')=='yes') :
$return_to = get_permalink(woocommerce_get_page_id('shop'));
$message = sprintf('%s %s', $return_to, __('Continue Shopping →', 'woocommerce'), __('Product successfully added to your cart.', 'woocommerce') );
else :
$message = sprintf('%s %s', get_permalink(woocommerce_get_page_id('cart')), __('View Cart →', 'woocommerce'), __('Product successfully added to your cart.', 'woocommerce') );
endif;
}else{
$message = null;
}
return $message;
}

I managed to find solution:
function filter_wc_add_to_cart_message_html( $message, $products ) {
$urlp = explode('/', $_SERVER['REQUEST_URI']);
$urlp = $urlp[1];
if ( $urlp == 'potwierdzenie'){
return $message;
}
return null;
}
I just check if user in checkout url when buying product, then I'm showing the notice. If user is still on shop page or any other page, notice won't show. This prevents the multiple 'added to cart' messages in checkout.

Related

Customized Woocommerce checkout fields reverting to default after page load

I have renamed the "shipping_country" label of my woocommerce checkout page successfully using this code:
add_filter( 'woocommerce_checkout_fields', 'rename_woo_checkout_fields' );
function rename_woo_checkout_fields( $fields ) {
$fields['shipping']['shipping_country']['label'] = 'Country';
return $fields;
}
But when I try to add additional labels and placeholders which I want to change, it doesn't work. Well, something strange happens actually. When I refresh the page to apply the changes, it seems to work, but the page is still loading and after a second, reverts back to what it was originally. (the shipping_country field DOES still work, but all of the other fields I add the above happens.
I tried changing the sequence but it does not matter.
The fields I am trying to change which do not work are:
$fields['billing']['billing_address_1']['label'] = 'Address';
$fields['billing']['billing_address_1']['placeholder'] = 'Street and house number';
$fields['billing']['billing_city']['label'] = 'City';
$fields['billing']['billing_postcode']['label'] = 'Postcode';
$fields['shipping']['shipping_postcode']['label'] = 'Postcode';
$fields['shipping']['shipping_city']['label'] = 'City';
$fields['shipping']['shipping_city']['placeholder'] = 'City';
$fields['shipping']['shipping_address_1']['label'] = 'Address';
$fields['shipping']['shipping_address_1']['placeholder'] = 'Street and house number';
$fields['order']['order_comments']['placeholder'] = 'Special notes';
What could it be that is making the page revert the changes before it completes loading the page?
Try the following instead:
// For billing and shipping fields
add_filter( 'woocommerce_default_address_fields', 'custom_default_address_fields' );
function custom_default_address_fields( $address_fields ) {
if ( is_checkout() ) {
$address_fields['address_1']['label'] = __('Address', 'woocommerce');
$address_fields['address_1']['placeholder'] = __('Street and house number', 'woocommerce');
$address_fields['country']['label'] = __('Country', 'woocommerce');
$address_fields['postcode']['label'] = __('Postcode', 'woocommerce');
$address_fields['city']['label'] = __('City', 'woocommerce');
$address_fields['city']['placeholder'] = __('City', 'woocommerce');
}
return $address_fields;
}
add_filter( 'woocommerce_checkout_fields', 'change_checkout_fields' );
function change_checkout_fields( $fields ) {
$fields['order']['order_comments']['placeholder'] = __('Special notes');
return $fields;
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works on last WooCommerce version (5.0.0).

Check if item is already in cart, if yes, then redirect user to checkout without adding product

I have a wordpress shop, where I sell digital products.
What the function should do:
User clicks add to cart button.
Function checks if the item is already in the cart.
If yes: Redirect user to checkout page without adding the product to cart (so the quantity doesn't change, it stays at 1).
If no: Redirect to checkout and add product to cart (quantity goes from 0 to 1).
What the function looks like:
add_filter('woocommerce_add_to_cart_validation', 'my_validation_handler', 10, 2);
function my_validation_handler($is_valid, $product_id) {
$url = WC()->cart->get_checkout_url();
foreach(WC()->cart->get_cart() as $cart_item_key => $values) {
if ($values['data']->id == $product_id) {
$url = WC()->cart->get_checkout_url();
wp_redirect($url);
exit();
}
else {
return $is_valid;
}
}
}
What happens:
When I implement the code in the functions.php of my child theme: (I already have the product in the cart) I click on the add to cart button again, but nothing happens.
If the cart is empty same thing, nothing happens, no reload nothing, I'm still on the products page.
Important detail:
I know there is a native WooCommerce function (sold seperately). But I have a custom products page and I don't want a message to appear that says "you already added that to cart".
Since I'm retargeting website visitors, the item is still in there sometimes from their last visit. And a expire session solution also not really what I'm looking for.
You can use the following, explanation as comment lines in the code
function my_validation_handler( $passed, $product_id, $quantity, $variation_id = null, $variations = null ) {
// Get checkout url
$checkout_url = wc_get_checkout_url();
// Set variable
$in_cart = false;
// Loop
foreach( WC()->cart->get_cart() as $cart_item ) {
if ( $cart_item['data']->get_id() == $product_id ) {
$in_cart = true;
break;
}
}
// True
if ( $in_cart ) {
wp_safe_redirect( $checkout_url );
exit();
} else {
// Add product to cart
WC()->cart->add_to_cart( $product_id, $quantity );
wp_safe_redirect( $checkout_url );
exit();
}
return $passed;
}
add_filter( 'woocommerce_add_to_cart_validation', 'my_validation_handler', 10, 5 );

AJAX add custom product order meta data from single product page

I've built an add to cart process that successfully creates a "personalisation" field when the item is added to the cart. Using the standard 'add to cart' button, the page reloads and all is well. I wanted to improve the UX by making the basket update via AJAX, which I've implemented and again working ok.
However, this stops the cart item data meta from registering because the request is not defined - the hook isn't able to grab input values from the page any more. The hook I'm using to define and write the meta fields to is 'woocommerce_add_cart_item_data'
I tried creating my own separate AJAX function to define the content of the field separately, using $_SESSION instead of $_REQUEST (inspired by this answer -> how to pass ajax data to woocommerce filter?)
Unfortunately this seemingly fires after 'woocommerce_add_cart_item_data' has run, so the meta data does not come through (in fact it ends up showing on the next product added, since the variable is defined late and not accessed until the 2nd product is added).
I'd really appreciate some help with either:
(1) Amending the code so 'woocommerce_add_cart_item_data' is able to take data from the AJAX add to cart action I made, or
(2) Amend my custom AJAX call so session data is able to be applied in a timely order (unsure if this is achievable based on what I've seen so far).
// Create AJAX add to cart button
function add_cart_btn($prod) {
echo apply_filters( 'woocommerce_loop_add_to_cart_link',
sprintf( 'Add to bag',
esc_url( $prod->add_to_cart_url() ),
esc_attr( $prod->id ),
esc_attr( $prod->get_sku() ),
$prod->is_purchasable() ? 'add_to_cart_button' : '',
esc_attr( $prod->product_type ),
esc_html( $prod->add_to_cart_text() )
),
$prod );
}
add_cart_btn($product);
// functions.php
/* Saves field data */
function save_add_custom_info_field( $cart_item_data, $product_id ) {
if( isset( $_REQUEST['custom_info_message'] ) ) {
// *** $_REQUEST['custom_info_message'] not defined ***
$cart_item_data[ 'custom_info_message' ] = $_REQUEST['custom_info_message'];
$cart_item_data['unique_key'] = md5( microtime().rand() );
}
return $cart_item_data;
}
add_action( 'woocommerce_add_cart_item_data', 'save_add_custom_info_field', 10, 2 );
/* Renders field entry on cart and checkout */
function render_mssg_meta_on_cart_and_checkout( $cart_data, $cart_item = null ) {
$custom_items = array();
if( !empty( $cart_data ) ) {
$custom_items = $cart_data;
}
if( isset( $cart_item['custom_info_message'] ) ) {
$custom_items[] = array( "name" => 'Personalisation / Customisation', "value" => $cart_item['custom_info_message'] );
}
return $custom_items;
}
add_filter( 'woocommerce_get_item_data',
'render_mssg_meta_on_cart_and_checkout', 10, 2 );
// *** Attempted solution with AJAX - Use $_SESSION['message'] in 'save_add_custom_info_field' function above instead of $_REQUEST... delivered after 'woocommerce_add_cart_item_data' so doesn't work
function set_customised_message() {
$message = $_POST['message'];
define( 'DOING_AJAX', true );
if ( ! defined( 'WP_ADMIN' ) ) {
define( 'WP_ADMIN', true );
}
session_start();
$_SESSION['message'] = $message;
echo $message;
die();
}
I expect custom meta to show on the cart/checkout pages, but it isn't due to the variable being either $cart_item['custom_info_message'] being undefined, or session variable from AJAX call not being available.
I've managed to solve this by updating the product meta data after it is added to the cart (via AJAX) - amending set_customised_message function above. Note the AJAX call required a timeout delay of 1s in order to work.
Leaving it here in case anyone else is having a similar issue.
function set_customised_message() {
$cart = WC()->cart->cart_contents;
foreach( $cart as $cart_item_id=>$cart_item ) {
echo $cart_item['unique_key'];
$cart_item['custom_info_message'] = $message;
echo $cart_item['custom_info_message'];
WC()->cart->cart_contents[$cart_item_id] = $cart_item;
}
WC()->cart->set_session();
}
Thanks to https://pluginrepublic.com/how-to-update-existing-woocommerce-cart-meta-data/ for this solution

Why does the 'Added to cart' message still come up?

I have coded a custom 'Added to cart' message for WooCommerce and after that I used the conditional tag 'is_cart()' to disable the message on the cart page but it still shows up.
How can I disable the message being shown on cart page?
Here is my code example:
function iw_add_to_cart_message_function( $message, $product_id ) {
if (!is_cart()) {
$message = sprintf(esc_html__('%s has been added by to your cart pompidompidom.','iwebbers'), get_the_title( $product_id ) );
return $message;
}
}
add_filter( 'wc_add_to_cart_message', 'iw_add_to_cart_message_function', 10, 2 );
I just tried the following IF STATEMENT and it works:
global $woocommerce;
if (get_option('woocommerce_cart_redirect_after_add')=='no') {
Function wc_add_to_cart_message
it Return message rather than add it.
go refer link: docs.woocommerce

Set cart permalink when cart is not empty

I have no cart link set in the backend of WooCommerce. Instead I have the cart redirected to the checkout page. This works fine, however now I end up with empty urls. When I add a product to the cart I get the message 'successfully added to the cart, see the cart here'. 'See the cart here' is linked to wc_get_page_permalink( 'cart' ), but this is not set.
Is it possible through a function to set the wc_get_page_permalink( 'cart' ) ONLY when items are in the cart?
I tried something like:
function custom_continue_shopping_redirect_url ( $product_id ) {
$url = "http://www.url.com"; // Add your link here
return $url;
}
add_filter('wc_add_to_cart_message', 'custom_continue_shopping_redirect_url');
But that is obviously replacing the whole add to cart message.
Thanks.
You missed some code. try it this way:
add_filter( 'wc_add_to_cart_message', 'custom_continue_shopping_redirect_url', 10, 2 );
function custom_continue_shopping_redirect_url( $message, $product_id ) {
global $woocommerce;
// $permalink = get_permalink(woocommerce_get_page_id('shop')); // replaced by:
$permalink = get_permalink(woocommerce_get_page_id('cart')); // your link here.
$message = sprintf('%s %s', $permalink, __('Continue Shopping', 'woocommerce'), __('Product successfully added to your cart.', 'woocommerce') );
return $message;
}
You will have to fine tune your replacement link. You can also change the text…
References:
Hookr: wc_add_to_cart_message
Alternative for the wc_add_to_cart_message hook in Woocommerce for WP
Custom Add To Cart Messages - GitHub

Categories