woocommerce hook delete product from the cart - wordpress

what are you doing for it?
i wrote this string in the end of file (wp-content/plugins/woocommerce/woocommerce.php):
add_filter('woocommerce_before_cart_item_quantity_zero', 'wordpress_before_cart_item_quantity_zero', 10, 1);
function wordpress_before_cart_item_quantity_zero($item) {
global $wpdb;
global $woocommerce;
$cart = $woocommerce->cart;
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
$id_product = $cart_item['product_id'];
$wpdb->prepare("DELETE FROM wp_block_product WHERE product_id = %d", $id_product);
$preparing_query = $wpdb->query($preparing_query);
}
var_dump($wpdb);
exit;
}
but when i delete item from the cart it's not working!
i was try do so:
add_action('woocommerce_before_cart_item_quantity_zero', 'wordpress_before_cart_item_quantity_zero');
but it's not working too

According to the source, you're looking for 'woocommerce_cart_item_removed', which runs when an item is removed from the cart:
function so31115243_after_remove_product($cart_item_key) {
// Your custom function
}
add_action( 'woocommerce_cart_item_removed', 'so31115243_after_remove_product' );

There is also a hook that runs before removing the item, which is woocommerce_remove_cart_item.
I believe that is what Danya is looking for in the comment above in case anyone runs into a similar issue.

#rnevius solution works but need to change the priority of the action. For me it was 21 but i think it can change regarding plugins using this.
add_action( 'woocommerce_cart_item_removed', 'so31115243_after_remove_product', 21 );

function so_27030769_maybe_empty_cart() {
global $woocommerce;
$woocommerce->cart->empty_cart();}
add_filter( 'woocommerce_add_to_cart_validation_custom', 'so_27030769_maybe_empty_cart', 10, 3 );
// Usage
apply_filters('woocommerce_add_to_cart_validation_custom','','');

Related

Any way to Overwrite get_stock_quantity in my functions.php?

I am working in Wordpress Multisite and trying to ensure that all the stock info is fetched from the base site tables. I am trying to overwrite get_stock_quantity() woocomerce function in my theme's functions.php. What i found was
public function get_stock_quantity( $context = 'view' ) {
return $this->get_prop( 'stock_quantity', $context );
}
Now this is neither a filter nor an action. I overwrote one filter that is
add_filter( 'woocommerce_product_get_stock_quantity', 'wcs_custom_get_stock_quantity', 1, 2);
function wcs_custom_get_stock_quantity( $availability, $_product ) {
global $wpdb;
$productQuantity = $wpdb->get_results( 'SELECT * FROM '.$wpdb->base_prefix.'postmeta WHERE post_id = '.$_product->get_id() ." AND meta_key = '_stock'", OBJECT );
return $productQuantity[0]->meta_value;
}
But woocommerce_product_get_stock_quantity only works on the Products List page. The individual product-edit page uses get_stock_quantity.
How can I overwrite it without changing Core files?
Thanks
The correct way to alter get_stock_quantity() method depends on the product. AS you have already notice looking at the source code you see that:
return $this->get_prop( 'stock_quantity', $context );
Now get_prop() method is a part of WC_Data class and has a generic filter hook:
$value = apply_filters( $this->get_hook_prefix() . $prop, $value, $this );
And if you look to get_hook_prefix() method you have this:
return 'woocommerce_' . $this->object_type . '_get_';
For product variations the object_type is: product_variation
For other products the object_type is: product
The $prop argument is stock_quantity
So know you can built the related filter hooks. Try this:
add_filter( 'woocommerce_product_get_stock_quantity' ,'custom_get_stock_quantity', 10, 2 );
add_filter( 'woocommerce_product_variation_get_stock_quantity' ,'custom_get_stock_quantity', 10, 2 );
function custom_get_stock_quantity( $value, $product ) {
$value = 15; // <== Just for testing
return $value;
}
So for product variations you use woocommerce_product_variation_get_stock_quantity filter hook.
And for the other cases woocommerce_product_get_stock_quantity filter hook
You can update the database, but remember this code is executed one time each time you list your products, and when you update your product
add_filter( 'woocommerce_product_get_stock_quantity' ,'custom_get_stock_quantity', 10, 2 );
add_filter( 'woocommerce_product_variation_get_stock_quantity' ,'custom_get_stock_quantity', 10, 2 );
function custom_get_stock_quantity( $value, $product ) {
$value = 15; // <== Just for testing
//update dabatabase:
update_post_meta( $product->get_id(), '_stock', $value );
return $value;
}
From what I understand you can use $product->set_stock($value); as well to set the value in database
add_filter( 'woocommerce_product_get_stock_quantity' ,'custom_get_stock_quantity', 10, 2 );
add_filter( 'woocommerce_product_variation_get_stock_quantity' ,'custom_get_stock_quantity', 10, 2 );
function custom_get_stock_quantity( $value, $product ) {
$value = 15; // <== Just for testing
//update dabatabase:
$product->set_stock($value);
return $value;
}

How to call function in other ajax of function

I have a change_flat_rates_cost() function, but it works only when loading the page. but it is necessary for me that function worked at each change of the field "city", (in checkout fields).
I have tried to use ajax function and to call there add_filter() function, but it doesn't help.
I do it to change delivery cost without reset of the page depending on the chosen city
change_flat_rates_cost function (changes the shipping price)
function change_flat_rates_cost($rates, $package) {
$userid = get_current_user_id();
$meta_city = get_user_meta( $userid, 'billing_city', true );
if ( isset( $rates['shipping_method_1'] ) ) {
if ($meta_city == 'City1'){
$rates['shipping_method_1']->cost = 100;
}
if ($meta_city == 'City2'){
$rates['shipping_method_1']->cost = 200;
}
}
return $rates;
}
add_filter( 'woocommerce_package_rates', 'change_flat_rates_cost', 10, 2 );
ajax function:
add_action( 'wp_ajax_change_shipping', 'change_shipping' );
add_action( 'wp_ajax_nopriv_change_shipping', 'change_shipping' );
function change_shipping() {
global $woocommerce;
add_filter( 'woocommerce_package_rates', 'change_flat_rates_cost', 10, 2 );
die();
}
You can add filter as normal "add_filter". No need to put it there in ajax, because anyways there are conditions mentioned in your function.
So, do add_filter normally and instead of using add_filter in ajax function, you should use "apply_filters". This will call your custom shipping function.
I hope I've made it clear.

Woocommerce 2.5: Hide Shipping Methods when free shipping is available not working anymore

I Had this code
/* !Hide Shipping Options Woocommerce */
add_filter( 'woocommerce_available_shipping_methods', 'hide_shipping_based_on_tag' , 10, 1 );
function check_cart_for_share() {
// load the contents of the cart into an array.
global $woocommerce;
$cart = $woocommerce->cart->cart_contents;
$found = false;
// loop through the array looking for the tag you set. Switch to true if the tag is found.
foreach ($cart as $array_item) {
$term_list = wp_get_post_terms( $array_item['product_id'], 'product_tag', array( "fields" => "names" ) );
if (in_array("Heavy",$term_list)) { // Replace "Heavy" with what ever tag you want
$found = true;
break;
}
}
return $found;
}
function hide_shipping_based_on_tag( $available_methods ) {
// use the function above to check the cart for the tag.
if ( check_cart_for_share() ) {
// remove the rate you want
unset( $available_methods['flat_rate'] ); // Replace "flat_rate" with the shipping option that you want to remove.
}
// return the available methods without the one you unset.
return $available_methods;
}
in my function.php - but since woocommerce 2.5 it's not working anymore.
The other shipping methods need to be hidden when free shipping is available.
Any Ideas?
You're using a hook that was used for WooCommerce version 2.1 and below.
Instead, use the woocommerce_package_rates filter..
This code works perfect for latest woocommerce :
add_filter( 'woocommerce_package_rates', 'hide_shipping_when_free_is_available', 10, 2 );
function hide_shipping_when_free_is_available( $rates, $package ) {
// Only modify rates if free_shipping is present
if ( isset( $rates['free_shipping'] ) ) {
// To unset a single rate/method, do the following. This example unsets flat_rate shipping
unset( $rates['flat_rate'] );
// To unset all methods except for free_shipping, do the following
$free_shipping = $rates['free_shipping'];
$rates = array();
$rates['free_shipping'] = $free_shipping;
}
return $rates;
}
I have unset the flat shipping, you can unset other shipping methods if you enabled. This code works fine for me, i tried it yesterday.

Adding product to cart programatically in woocommerce

I'm adding products via ajax using a function in functions.php that looks like this:
function es_add_to_cart()
{
global $woocommerce;
$product_id = $_GET['product_id'];
$woocommerce->cart->add_to_cart( $product_id );
die ( /*returns updated shopping cart */ );
}
This works and the item gets added but only if the cart already contains an item, this leads me to believe that I need to check if there is already a cart and create a new cart if there isn't. I can't find anything on this in the docs however.
Here is the solution to this problem, running $woocommerce->cart->maybe_set_cart_cookies(); after adding any items, so the same function looks like this:
function es_add_to_cart()
{
global $woocommerce;
$product_id = $_GET['product_id'];
$woocommerce->cart->add_to_cart( $product_id );
$woocommerce->cart->maybe_set_cart_cookies();
die ( /*returns updated shopping cart */ );
}

Need Woocommerce to only allow 1 product in the cart. If a product is already in the cart and another 1 is added then it should remove the previous 1

I think this code should work but not exactly sure where to place it. Everywhere I have tried has failed so far...
add_action('init', 'woocommerce_clear_cart');
function woocommerce_clear_cart() {
global $woocommerce, $post, $wpdb;
$url = explode('/', 'http://'.$_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"]);
$slug=$url[4];
$postid = $wpdb->get_var("SELECT ID FROM $wpdb->posts WHERE post_status='publish' AND post_name = '$slug'");
if ($postid){
if ($postid == PRODUCTID1 || $postid == PRODUCTID2){
$woocommerce->cart->empty_cart();
}
}
}
Unfortunately there is no 'action' hook before WooCommerce adds an item to the cart. But they have a 'filter' hook before adding to cart.
That is how I use it:
add_filter( 'woocommerce_add_cart_item_data', 'woo_custom_add_to_cart' );
function woo_custom_add_to_cart( $cart_item_data ) {
global $woocommerce;
$woocommerce->cart->empty_cart();
// Do nothing with the data and return
return $cart_item_data;
}
Based on the accepted answer and the latest Woo version 2.5.1 I updated the function to be slightly cleaner using the code woo uses in class-wc-checkout.php to clear the cart
add_filter( 'woocommerce_add_cart_item_data', '_empty_cart' );
function _empty_cart( $cart_item_data ) {
WC()->cart->empty_cart();
return $cart_item_data;
}
There is a filter/hook that runs before an item is added to the cart as each product goes through validation before it is added.
So when validating a product, we can check if the item if there are already items in the cart and clears those (if the current item is able to be added) and adds an error message.
/**
* When an item is added to the cart, remove other products
*/
function so_27030769_maybe_empty_cart( $valid, $product_id, $quantity ) {
if( ! empty ( WC()->cart->get_cart() ) && $valid ){
WC()->cart->empty_cart();
wc_add_notice( 'Whoa hold up. You can only have 1 item in your cart', 'error' );
}
return $valid;
}
add_filter( 'woocommerce_add_to_cart_validation', 'so_27030769_maybe_empty_cart', 10, 3 );
This worked like a charm for me, removes the previous product and adds the new one with the new product configuration. Cheers
Update: For WooCommerce 3.0.X
function check_if_cart_has_product( $valid, $product_id, $quantity ) {
if(!empty(WC()->cart->get_cart()) && $valid){
foreach (WC()->cart->get_cart() as $cart_item_key => $values) {
$_product = $values['data'];
if( $product_id == $_product->get_id() ) {
unset(WC()->cart->cart_contents[$cart_item_key]);
}
}
}
return $valid;
}
add_filter( 'woocommerce_add_to_cart_validation', 'check_if_cart_has_product', 10, 3 );
For WooCommerce version less than 3.0.X
function check_if_cart_has_product( $valid, $product_id, $quantity ) {
if(!empty(WC()->cart->get_cart()) && $valid){
foreach (WC()->cart->get_cart() as $cart_item_key => $values) {
$_product = $values['data'];
if( $product_id == $_product->id ) {
unset(WC()->cart->cart_contents[$cart_item_key]);
}
}
}
return $valid;
}
add_filter( 'woocommerce_add_to_cart_validation', 'check_if_cart_has_product', 10, 3 );
You have two options:
WooCommerce Min/Max Quantities extension
The following code added to your functions.php theme file
add_filter ( 'woocommerce_before_cart' , 'allow_single_quantity_in_cart' );
function allow_single_quantity_in_cart() {
global $woocommerce;
$cart_contents = $woocommerce->cart->get_cart();
$keys = array_keys ( $cart_contents );
foreach ( $keys as $key ) {
$woocommerce->cart->set_quantity ( $key, 1, true );
}
}
Don't add functions directly to your commerce files...you'll lose all your code when you update.
User functions should always be hooked through the functions.php of your theme.
Add this to your child-themes functions.php (tested in 2022, requires PHP 7 or higher):
add_filter('woocommerce_add_cart_item_data', function($cart_data) {
wc_empty_cart();
return $cart_data;
}, 99);
The "woocommerce_add_cart_item_data" filter fires every time a new item is added to the cart. We use this chance to call "wc_empty_cart" which empties the cart and optionally the persistent cart too. The new items is therefore alone in the cart.
Try this,
For removing the all products from the cart and adding the last added one,
//For removing all the items from the cart
global $woocommerce;
$woocommerce->cart->empty_cart();
$woocommerce->cart->add_to_cart($product_id,$qty);
class file is wp-content/plugins/woocommerce/classes/class-wc-cart.php.
You can add the above code on the add to cart function in functions.php.
Hope its works..
Eu coloco na function.php do tema, o que faço ou no woocomerce
function check_if_cart_has_product( $valid, $product_id, $quantity ) {
if(!empty(WC()->cart->get_cart()) && $valid){
foreach (WC()->cart->get_cart() as $cart_item_key => $values) {
$_product = $values['data'];
if( $product_id == $_product->id ) {
wc_add_notice( 'The product is already in cart', 'error' );
return false;
}
}
}
return $valid;
}
add_filter( 'woocommerce_add_to_cart_validation', 'check_if_cart_has_product', 10, 3 );
On WordPress 5.6.1. no need to add a custom filter or write code there is an option to limit one product add to the cart.

Resources