I'm building a site with a checkout, the site has 2 products, that need to be sold individually. So to prevent people from adding the first item, leaving the cart, then adding the second item, I wanted to set up the cart to auto-empty. So I decided to test it for the homepage. The initial function I had was this:
function my_empty_cart(){
global $woocommerce;
$woocommerce->cart->empty_cart();
}
add_action('init', 'my_empty_cart');
That works perfectly. But the cart is always empty because of this. So I decided to add in an "if" statement:
function my_empty_cart() {
global $woocommerce;
if ( is_front_page() && isset( $_GET['empty-cart'] ) ) {
$woocommerce->cart->empty_cart();
}
}
add_action( 'init', 'my_empty_cart' );
And that doesn't work...at all. I've tried it with "is_home" and "is_page" (with various page titles and ids). I even tried removing the "&& isset" part, just to test. At this point i'm lost, I've never had this much difficulty with a simple php code and i'm pulling out my hair at this point. Is there something simple i'm just not seeing?
this worked for me (dont relies on WordPress conditional):
/*empty cart if user come to homepage*/
add_action( 'init', 'woocommerce_clear_cart_url' );
function woocommerce_clear_cart_url() {
global $woocommerce;
if ($_SERVER['REQUEST_URI'] === '/') {
$woocommerce->cart->empty_cart();
}
}
Conditional tags (is_home(), is_front_page(), etc) don't work at the time the 'init' hook fires. You can use 'wp' hook instead. It runs immediately after wp class object is set up (http://codex.wordpress.org/Plugin_API/Action_Reference/wp).
function my_empty_cart() {
global $woocommerce;
if ( is_front_page() && isset( $_GET['empty-cart'] ) ) {
$woocommerce->cart->empty_cart();
}
}
add_action( 'wp', 'my_empty_cart' );
Related
I need to show only current user's products on the frontend, that is for the user that are logged in, he/she should be only able to view their own products across the site. I tried the code below but this limits access to all the posts and pages which current user didn't create. And I need to limit only for woocommerce products.
function shapeSpace_set_only_author($query) {
global $current_user;
$query->set('author', $current_user->ID);
}
add_action('pre_get_posts', 'shapeSpace_set_only_author');
You can use dedicated woocommerce_product_query action hook that will restrict the product displayed to:
add_action( 'woocommerce_product_query', 'shapeSpace_set_only_author', 20, 2 );
function shapeSpace_set_only_author ( $q, $query ) {
if( is_admin() ) return;
global $current_user;
$q->set('author', $current_user->ID);
}
Code goes in function.php file of your active child theme (or theme).
Tested and works
Almost there, you just need to specify that you want to alter the query only for products.
add_action( 'pre_get_posts', 'modify_query_show_current_user_products' );
function modify_query_show_current_user_products( $query ) {
global $current_user;
if( ! is_admin() && $query->is_main_query() && isset( $query->query_vars['wc_query'] ) && $query->query_vars['wc_query'] == 'product_query' ) {
$query->set('author', $current_user->ID);
}
}
I'm trying to update my Woocommerce tax rate when a certain coupon is used. For this I'm using this code in my functions.php:
function apply_matched_coupons() {
global $woocommerce;
$coupon_code = '123456';
if ( $woocommerce->cart->has_discount( $coupon_code ) ) {
$tax_class = 'Reduced rate';
}
return $tax_class;
}
add_action( 'woocommerce_product_tax_class','apply_matched_coupons' );
This works perfectly on the frontend, HOWEVER after I put this code in my child theme functions.php I'm getting the following error in the backend when I open the "Products" page in wp-admin:
Fatal error: Call to a member function has_discount() on a non-object in xxxx/xxxx/xxxxx/xxxx/functions.php on line 57
Now I suddenly can't seem to get a list of my products in the backend. The loading of the products is broken after the first product's price.
Any idea how I should modify this code so both the frontend and backend works like it should? I'm a noob at coding so sorry if this is a stupid question!
I searched Google and Stackoverflow and came up with similar code that worked on the frontend but always gave the same error on the backend.
Thanks for the help!
well, first let's tweak your code a bit.
You don't need global $woocommerce; use WC() in place of $woocommerce. And let's add !is_admin() on your if. So it should just work on the frontend.
function apply_matched_coupons() {
$coupon_code = '123456';
if ( !is_admin() && WC()->cart->has_discount( $coupon_code ) ) {
$tax_class = 'Reduced rate';
}
return $tax_class;
}
add_action( 'woocommerce_product_tax_class','apply_matched_coupons' );
Right now I am trying to get it so that whenever someone gets to my site's product page their cart is automatically emptied.
I am using a woocommerce product addon called "Product & Checkout Options for WooCommerce" that allows me to use radiobuttons/checkboxes for my products, I don't know if that will alter any of the code.
I've tried php code such as this but it hasn't worked:
add_filter( 'woocommerce_add_to_cart_validation', 'only_one_in_cart' , 10, 1);
function only_one_in_cart( $cart_item_data ) {
global $woocommerce;
$woocommerce->cart->empty_cart();
unset($cart_item_data['product_meta']);
return true;
}
It's better to add the hook on your single product page, do it with the action woocommerce_before_single_product:
add_action( 'woocommerce_before_single_product', `only_one_in );
function only_one_in_cart() {
global $woocommerce;
$woocommerce->cart->empty_cart();
}
This will empty your cart each time you visit the page, if it's late, then you can add the function into the wp_head hook and validate if you are in the product page by is_product():
add_action( 'wp_head', `only_one_in );
function only_one_in_cart() {
if ( is_product() ){
global $woocommerce;
$woocommerce->cart->empty_cart();
}
}
I want to do two things:
remove the breadcrumbs in category pages, but leave it in single product pages.
remove the title from the shop page.
For the breadcrumbs, I tried this code and it doesn't work:
if( is_archive() ){
add_action( 'init', 'porto_remove_wc_breadcrumbs' );
function porto_remove_wc_breadcrumbs() {
remove_action( 'woocommerce_before_main_content', 'woocommerce_breadcrumb', 20, 0 );
}
}
(without the conditional tag it does work, or if I change the conditional to if(1<2) instead).
no matter what archive page i'm displaying, with the code above the breadcrumbs is shown.
About the second problem, this code doesn't work either:
if( is_shop() ){
add_filter( 'woocommerce_show_page_title' , 'woo_hide_page_title' );
function woo_hide_page_title() {
return false;
}
}
There's still title in shop page after running this code. I guess the solution for both problems are the same.
What am I doing wrong?
everyone, i am trying to stop a plugin function from executing if a certain product id is in the cart. I have tried and written the following code and put them in my theme functions.php, but it doesn't seem to work. Instead, the whole page become blank. Can anyone help me out?
$found = false;
global $woocommerce;
foreach($woocommerce->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if( $_product->id == 1097 ) {
$found = true;
}
}
if ($found){
remove_action('woocommerce_before_order_notes', array($wdt, 'show_field'), 20);
}
By itself, remove_action('woocommerce_before_order_notes', array($wdt, 'show_field'), 20); works. But once i tried to link it to work base on product id, the whole website just cannot load. Thank you!
The variable $wdt does not seam to be initialized. You should ether use the class name(string) or an instance of that class here.
An other guess is that your code runs before the action is added. Make sure you run your code on a later hook in the execution see this for reference: http://codex.wordpress.org/Plugin_API/Action_Reference#Actions_Run_During_a_Typical_Request
So if the code that add the hook runs at init, you can try to run your code at wp_loaded. Like this:
add_action('wp_loaded','my_remove_order_notes');
function my_remove_order_notes()
{
//Your code
}
Also, make sure that the priority parameter matches with the code where the action hook is added. The default priority is 10.
Edit:
Ok, you should not remove the filter. Filters are supposed to be used for manipulating the data and the return the new data back. Like this:
add_filter( 'woocommerce_checkout_fields' , 'custom_remove_order_comments', 99 );
function custom_remove_order_comments( $fields )
{
global $woocommerce;
foreach($woocommerce->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if( $_product->id == 1097 ) {
unset($fields['order']['order_comments']); //Remove the order comments field
}
return $fields; //Return the data back to WooCommerce
}