woocommerce_add_to_cart_validation not executed - php

I'm trying to set validation on "add cart" button to my woocommerce.
I use this code in functions.php, but it is not executed:
function test( $passed ) {
//exit(); //it would broke the code
$passed = false;
return $passed;
}
add_filter( 'woocommerce_add_to_cart_validation', 'test', 10, 5 );
I try to set exit() on test() function but nothing. What can i verify?

If you look at the woocommerce source code you can see an example of how filters are added to woocommerce_add_to_cart_validation: https://github.com/woocommerce/woocommerce/blob/d7f768f77919a3f7a059d915894d0e87b2cb3ab1/includes/wc-cart-functions.php#L13-L27
I have personally added woocommerce filters inside of a child theme: https://developer.wordpress.org/themes/advanced-topics/child-themes/ in the file functions.php, wrapped in the <?php ... ?> tag.
You could be running into a priority issue, see this comment for more info on how that could impact your function: https://wordpress.stackexchange.com/a/7998/120919

Related

Using ACF true/false field on WooCommerce single product page

I have a WooCommerce site and in the single product page I have a custom checkbox to agree to terms before the add to cart button, but I am trying to add a true/false field in the dashboard so that this checkbox can be moved to a different position on the page.
My functions look like this:
add_action( 'acf/init', "acf_move_checkbox", 10 );
function acf_move_checkbox() {
$move_cart = get_field('move_cart');
if ($move_cart) {
add_action( 'woocommerce_after_single_product', "acf_product_terms", 10 );
} else {
add_action( 'woocommerce_before_add_to_cart_form', "acf_product_terms", 10 );
}
// More code
}
And nothing is happening, am I along the right lines with this or way off?
While acf/init is similar to the WordPress init action, I wouldn't use it.
Init hooks are performed constantly.. since you want to apply an action on the single product page it's best to use a hook that only applies to that page, and will only run on those kinds of pages.
For example you can use the woocommerce_single_product_summary hook. It might also be useful to test fields by hard coding before retrieving them.
So you get:
function action_woocommerce_single_product_summary() {
// Get field
//$move_cart = get_field( 'move_cart' );
// Set true OR false
$move_cart = false;
// When true
if ( $move_cart ) {
add_action( 'woocommerce_after_single_product', 'my_callback_function', 9 );
} else {
add_action( 'woocommerce_before_add_to_cart_form', 'my_callback_function', 9 );
}
}
add_action( 'woocommerce_single_product_summary', 'action_woocommerce_single_product_summary', 1 );
function my_callback_function() {
echo '<p style="color: red; font-size: 20px;">Hello World!</p>';
}
If the above step works, you can replace the hard coded field with the desired code/field

Disallow purchases from virtual products in WooCommerce

I'm trying to remove the add to cart button from the categories page for products that are not purchasable.
This is my current code, which I have placed in the functions.php file of my child theme;
function buy_filter()
{
if ( ! is_product() ) return;
$product_id=get_the_ID();
$product = wc_get_product($product_id);
if ($product->is_virtual('yes'))
if ($product->is_virtual('yes'))
{
add_filter( 'woocommerce_is_purchasable', '__return_false');
}
}
add_action ('wp', 'buy_filter');
I've managed to remove the button from the individual product pages, however I still can't get it to be removed from the categories page. Now when I inspect the button shows the following code:
<a href="?add-to-cart=16972" data-quantity="1" class="button product_type_simple add_to_cart_button
ajax_add_to_cart" data-product_id="16972" data-product_sku="604544617405" aria-label=
"Add “Federal - 9MM Syntech, 115gr” to your cart" rel="nofollow">Add to cart</a>
Does this button need to be disabled in another way?
I really need this button to be removed as its a product that we only want to sell in our store, but we want people to know that we do stock that product as well.
Below is an image of what it currently looks like, and what I want to go. Ideally, I would like the button gone completely, but I will definitely settle for a replacement to the read more button if that is easier.
To remove it from everywhere (on single pages and category pages) use directly the filter instead, replacing your code with:
add_filter( 'woocommerce_variation_is_purchasable', 'filter_virtual_products', 10, 2 );
add_filter( 'woocommerce_is_purchasable', 'filter_virtual_products', 10, 2 );
function filter_virtual_products( $is_purchasable, $product )
{
if ( $product->is_virtual('yes') ) {
$is_purchasable = false;
}
return $is_purchasable;
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
Please try this code inside your functions.php file
add_filter('woocommerce_is_purchasable', 'woocommerce_cloudways_purchasable');
function woocommerce_cloudways_purchasable($cloudways_purchasable, $product) {
return ($product->id == your_specific_product_id (like 22) ? false : $cloudways_purchasable);
}
Source: https://www.cloudways.com/blog/how-to-remove-hide-or-disable-add-to-cart-button-in-woocommerce/
or Use this plugin will solve your issue without any coding.
https://wordpress.org/plugins/non-purchasable-woocommerce-products/

Allow shortcodes in product variations description in Woocommerce

I would like to use a pods shortcode field inside the woocommerce variable product description but by default the variable description field does not support shortcodes.
The variation description is stored in an array woocommerce_available_variation, so I can't simple call the function do_shortcode($variation).
I am trying to allow short codes in this field by using the below code:
add_filter( 'woocommerce_available_variation', 'shortcode_variation_description');
function shortcode_variation_description( $variation ) {
$variation['variation_description'] = do_shortcode( $variation['variation_description'] );
return $variation;
But it's not working. Why?
When using your code, it works. To test, I have used the Woocommerce shortcode [products] in a variation description as follow:
The imputed text is (where 37 is a real simple product ID):
"This is a description with a shortcode… [products ids="37"] As you can see this shorcode is detected and displayed."
And I get this display:
So it works for real. I have lightly made some little changes to this code version (yours work too):
add_filter( 'woocommerce_available_variation', 'variation_description_allow_shortcodes', 10, 3 );
function variation_description_allow_shortcodes( $variation_data, $product, $variation ) {
$variation_data['variation_description'] = do_shortcode( $variation_data['variation_description'] );
return $variation_data;
}
Code goes in function.php file of your active child theme (active theme). Tested and works.
You can define your own shortcode, see the documentation. You can copy/paste the code because it's wrapped in a class so it won't trigger fatal error due to double declaration.
But shortcode do not work that way :
function shortcode_handler($atts) {
//code goes here
}
add_shortcode("name_of_shortcode","shortcode_handler');

Open a specific product tab programmatically in a Woocommerce

I am using woocommerce. After submission of certain form I want to send it to product page with opening a certain tab, here "Addition Information" tab...
How can I achieve this ?
I have tried url like 'WEBSITE/product/product-3/#tab-additional_information'
But it didn't worked.
Updated:
Yes this is possible with a little bit of javascript and jQuery embedded code in a custom php function hooked in wp_footer action hook.
The call will be made in the url like: WEBSITE/product/product-3/?tab=additional_information
Here is that function code:
add_action( 'wp_footer', 'custom_reordering_product_tabs_action' );
function custom_reordering_product_tabs_action() {
// Only in single product pages and a specific url (using GET method)
if( isset( $_GET['tab'] ) && is_product()) :
?>
<script type="text/javascript">
(function($){
setTimeout(function() {
$('ul.tabs.wc-tabs > li.active').removeClass("active");
$('div#tab-description').hide();
$('ul.tabs.wc-tabs > li.<?php echo $_GET['tab']; ?>_tab').addClass("active");
$('div#tab-<?php echo $_GET['tab']; ?>').show();
}, 500);
})(jQuery);
</script>
<?php
endif;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested on Woocommerce 3+ and works
May be what you can do instead of open a product tab automatically, is to reorder in 1st position automatically that tab trough $_GET method (adding a variable in the url).
The call in your url will need to be like: WEBSITE/product/product-3/?tab=additional_information
You will be able to do it with that custom function hooked in woocommerce_product_tabs filter hook:
add_filter( 'woocommerce_product_tabs', 'custom_reordering_product_tabs_action', 98 );
function custom_reordering_product_tabs_action( $tabs ) {
if( empty( $_GET['tab'] ) ) return $tabs;
$tabs[$_GET['tab']]['priority'] = 2;
return $tabs;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested on Woocommerce 3+ and works

Woocommerce add to cart button redirect to checkout

I created an ecommerce using the plugin woocommerce. I am selling only a subscription so the "/cart/" page is useless. I'm trying to get rid of it so that when my customer click on "Add to cart" button, he ends up on the checkout page.
In WooCommerce 3.6 or later you can use woocommerce_add_to_cart_redirect (props #roman)
add_filter ('woocommerce_add_to_cart_redirect', function( $url, $adding_to_cart ) {
return wc_get_checkout_url();
}, 10, 2 );
Original answer:
you can use a filter in functions.php:
add_filter ('add_to_cart_redirect', 'redirect_to_checkout');
function redirect_to_checkout() {
global $woocommerce;
$checkout_url = $woocommerce->cart->get_checkout_url();
return $checkout_url;
}
it doesn't seem to work with ajax, but it works from the single product pages, which I think is what you use
On WooCommerce (>= 2.1) the function can be simplified as:
function redirect_to_checkout() {
return WC()->cart->get_checkout_url();
}
There is an option within WooCommerce settings that allows you to enable this functionality:
Simply login to your WP admin panel > WooCommerce > Catalog and select the option. I hope this helps!
I've found a simple solution that work like magic.
As mentioned by #Ewout, check the box that says "Redirecto to cart page after succesful addtion".
Woocommerce > Settings > Checkout (Tab) - where you should select pages for cart and checkout, select the checkout page as the cart page (image attached).
That's it. works for me.
Update for WooCommerce 3.5.1
Step 1.
First of all go to WooCommerce Products settings and deactivate AJAX add to cart.
Step 2.
Use woocommerce_add_to_cart_redirect hook to make a redirect to checkout.
add_filter( 'woocommerce_add_to_cart_redirect', function( $url ) {
return wc_get_checkout_url();
});
Of course there some small things are left to do, like changing add to cart buttons text and removing some WooCommerce cart-related notices. I recommend to check this tutorial for more https://rudrastyh.com/woocommerce/redirect-to-checkout-skip-cart.html
#RemiCorson posted this brief but beneficial tutorial:
http://www.remicorson.com/woocommerce-skip-product-cart-pages/
He mentions the same filter as #Ewout above,
add_filter ('add_to_cart_redirect', 'redirect_to_checkout');
function redirect_to_checkout() {
global $woocommerce;
$checkout_url = $woocommerce->cart->get_checkout_url();
return $checkout_url;
}
but one line of code stands out and is of super value for me for my current woocommerce project:
There is a direct link that a user can use to automatically bypass the product page.
http://your-site.com/?add-to-cart=37
'37' will be replaced by your product ID.
This was useful for me to eliminate unnecessary steps and take users directly to checkout from the home page and other non-woocommerce pages/posts.
Filter add_to_cart_redirect is deprecated in WooCommerce 2.6. Use woocommerce_add_to_cart_redirect instead.
Add this to your functions.php :
add_filter ('woocommerce_add_to_cart_redirect', function() {
return WC()->cart->get_checkout_url();
} );
Try the below code in the themes function.php file
add_filter( 'woocommerce_add_to_cart_redirect', 'woo_skip_cart_redirect_checkout' );
function woo_skip_cart_redirect_checkout( $url ) {
return wc_get_checkout_url();
}
On shop page, if you want use ajax and redirect toghether. The second method only when there are some condition, you can use this filter and leave on Woocommerce setting ajax enabled:
add_filter('woocommerce_loop_add_to_cart_link', array( $this, 'add_quantity_input' ), 4, 2);
to remove on a class attribute ajax_add_to_cart and change the href value to checkout url page;
On my template case:
public function add_quantity_input($text = null, $product = null) {
global $product, $woocommerce;
if ( $text != null and $product != null ) {
if(ismycondition($product->id)) {
$s = explode('class="', $text);
$s[2]=str_replace('ajax_add_to_cart', '', $s[2]);
$text = implode('class="', $s);
$text = preg_replace('/<a(.*)href="([^"]*)"(.*)>/','<a$1href="'.$woocommerce->cart->get_checkout_url().'"$3>', $text);
}
}
return $text;
}
I hope that this help.
None of the solutions actually worked out for me, the filter add_to_cart_redirect was triggering on every page,not only on the cart.I did some modification on the suggested answer.
add_filter ('add_to_cart_redirect', 'redirect_to_checkout');
function redirect_to_checkout() {
if(is_cart()){
$checkout_url = WC()->cart->get_checkout_url();
?>
<script>
location = '<?=$checkout_url?>';
</script>
<?php
}
}

Categories