Woocommerce exclude products by different users - php

I have differents shopmanager in my wocommerce, but for now i want that 1 shopmanager can see only all products created from him/her not all. For now they can only modify these products but i want hide different products from different shopmanager..

add_action( 'pre_get_posts', 'custom_pre_get_posts' );
function custom_pre_get_posts( $q ) {
if ( ! $q->is_main_query() ) return;
if ( ! $q->is_post_type_archive() ) return;
if ( ! ( current_user_can( 'edit_product' ) ) && is_shop() ) {
$q->query_vars['author'] = get_current_user_id();
}
remove_action( 'pre_get_posts', 'custom_pre_get_posts_query' );
}
Try this snippet

Related

Optimize Woocommerce function that show specific products only in specific roles

I have the following function that runs on catalogue page and shows or hides specific products from users based on their role. If the user is customer then he can see the products that have checked the set_catalog_visibility (ACF).
The issue is that this function is slowing down my catalogue and i need to optimize it so it will run faster.
add_action('pre_get_posts', function( $query ){
$user = wp_get_current_user();
if ( $query->is_main_query() && is_woocommerce()) {
if (!check_user_role(array('customer','administrator')) || !is_user_logged_in() ) {
$product_ids = get_post_ids_by_meta_key_and_value('prd_clients', 1);
foreach($product_ids as $id){
// Get an instance of the product
$product = wc_get_product($id);
// Change the product visibility
$product->set_catalog_visibility('hidden');
// Save and sync the product visibility
$product->save();
}
}
else{
$product_ids = get_post_ids_by_meta_key_and_value('prd_clients', 1);
foreach($product_ids as $id){
// Get an instance of the product
$product = wc_get_product($id);
// Change the product visibility
$product->set_catalog_visibility('visible');
// Save and sync the product visibility
$product->save();
}
}
}
});
You can done it simply like this:
add_action(
'pre_get_posts',
function( $query ) {
if ( $query->is_main_query() && is_woocommerce() ) {
if ( ! is_user_logged_in() && ( is_user_logged_in() && ! check_user_role( array( 'customer', 'administrator' ) ) ) ) {
$product_ids = get_post_ids_by_meta_key_and_value( 'prd_clients', 1 );
if ( ! empty( $product_ids ) ) {
$query->set( 'post__not_in', $product_ids );
}
}
}
}
);

Woocommerce - Hide payment gateway “cod - cash on delivery” and show bacs - Bank Transfer

Please Guys,
I use two payment gateways on the checkout page:
1° bacs = Bank transfer
2° cod = Cash on Delivery
i need to hide the payment gateway COD = Cash on Delivery, If the user has No Admin Profile (!is_user_admin()), || or it's not logged, || ! is_user_logged_in() then hide.
This is the code that i'm using and it's working.
add_filter( 'woocommerce_available_payment_gateways', 'bbloomer_cod_hide' );
function bbloomer_cod_hide( $available_gateways ) {
if ( isset( $available_gateways['cod']) && !is_user_admin() ) {
unset( $available_gateways['cod'] );
}
return $available_gateways;
}
The problem is...the payment gateway bacs = Bank transfer is also affected and hidden : )
so i tried with this another hook
add_filter( 'woocommerce_available_payment_gateways', 'transfer_enable_bacs' );
function transfer_enable_bacs( $available_gateways ) {
if ( isset( $available_gateways['bacs']) && !is_user_admin() ) {
//unset( $available_gateways['bacs'] );
}
return $available_gateways;
}
But this is not the correct solution. Both payment gateways are hidden.
What am i doing wrong please?
Gratitude!
I think you need to replace is_user_admin with current_user_can
add_filter( 'woocommerce_available_payment_gateways', 'bbloomer_cod_hide' );
function bbloomer_cod_hide( $available_gateways ) {
if ( isset( $available_gateways['cod'] ) && ! current_user_can( 'administrator' ) ) {
unset( $available_gateways['cod'] );
}
return $available_gateways;
}
is_user_admin does not check if the user is an administrator; use current_user_can() for checking roles and capabilities.
https://developer.wordpress.org/reference/functions/is_user_admin/
try the following code:
add_filter( 'woocommerce_available_payment_gateways', 'bbloomer_cod_hide' );
function bbloomer_cod_hide( $available_gateways ) {
if ( !is_user_logged_in() ) || !current_user_can( 'install_themes' ) ) {
unset( $available_gateways['cod'] );
}
return $available_gateways;
}

Disable WooCommerce payment gateway for guests and specific user roles

I have disabled the invoice payment mehtod for one of the user roles in my site ('customer') but now I need to add another user role ('business') to this rule and I can't figure out how to make it work. When I add the second role, the code stops working altogether and it ends up showing the gateway to all users.
Here's the code I'm using to disable the gateway:
I'm not very experienced with PHP so any help will be tremendously appreciated.
If there's any chance you can correct my code to fit the use case, I would be very grateful.
add_filter( 'woocommerce_available_payment_gateways', 'payment_gateway_disable_private' );
function payment_gateway_disable_private( $available_gateways ) {
$user = wp_get_current_user();
if ( isset( $available_gateways['igfw_invoice_gateway'] ) && !is_user_logged_in() || isset( $available_gateways['igfw_invoice_gateway'] ) && in_array('customer', $user->roles) ) {
unset( $available_gateways['igfw_invoice_gateway'] );
}
return $available_gateways;
}
Thoughts?
There is a mistake in your if statement (also you can use current_user_can() function for user roles) like:
add_filter( 'woocommerce_available_payment_gateways', 'payment_gateway_disable_private' );
function payment_gateway_disable_private( $available_gateways ) {
if ( ( ! is_user_logged_in() || current_user_can('customer') || current_user_can('business') )
&& isset( $available_gateways['igfw_invoice_gateway'] ) ) {
unset( $available_gateways['igfw_invoice_gateway'] );
}
return $available_gateways;
}
or with the global $current_user; and array_intersect() function:
add_filter( 'woocommerce_available_payment_gateways', 'payment_gateway_disable_private' );
function payment_gateway_disable_private( $available_gateways ) {
global $current_user;
// Here define your user roles
$user_roles = array( 'customer', 'business' );
if ( ( ! is_user_logged_in() || array_intersect( $current_user->roles, $user_roles ) )
&& isset( $available_gateways['igfw_invoice_gateway'] ) ) {
unset( $available_gateways['igfw_invoice_gateway'] );
}
return $available_gateways;
}
It should better work now.

woocommerce apply coupon programmatically bug

This is the code I am using:
if (!is_admin()):
add_action( 'woocommerce_before_cart', 'apply_matched_coupons' );
//add_action('woocommerce_before_cart_table', 'apply_matched_coupons');
//add_action('woocommerce_before_checkout_form', 'apply_matched_coupons');
function apply_matched_coupons() {
global $woocommerce;
$coupon_code = 'somecodehere';
if ( $woocommerce->cart->has_discount( $coupon_code ) ) return;
if ( $woocommerce->cart->cart_contents_total >= 1 ) {
$woocommerce->cart->add_discount( $coupon_code );
wc_print_notices();
}
}
endif;
The issue I am having is that when I go to the checkout page that the coupon still gets applied. It's not applied on the cart which is the desired result but I don't want it applied at all in this condition.
Any help?
Based on your explanation, it sounds like you should be using the woocommerce_add_to_cart hook, which is run when a product is successfully added to the cart. I also don't think you should be using is_admin(), since that just checks if you're on an admin page...not if the current user is an admin.
I would do something like the following:
add_action( 'woocommerce_add_to_cart', 'apply_matched_coupons' );
function apply_matched_coupons() {
// If the current user is a shop admin
if ( current_user_can( 'manage_woocommerce' ) ) return;
// If the user is on the cart or checkout page
if ( is_cart() || is_checkout() ) return;
$coupon_code = 'somecodehere';
if ( WC()->cart->has_discount( $coupon_code ) ) return;
WC()->cart->add_discount( $coupon_code );
}

dequeue (remove) woocommerce css stylesheets

I am trying to dequeue the woocommerce style sheets from all pages except checkout/cart/receipt pages.
The code form the woocommerce help page (http://docs.woothemes.com/document/disable-the-default-stylesheet/) works to remove the stylesheets entirely.
add_filter( 'woocommerce_enqueue_styles', '__return_empty_array' );
I tried to use this code but it does not work:
add_action( 'wp_enqueue_scripts', 'child_manage_woocommerce_styles', 99 );
function child_manage_woocommerce_styles() {
remove_action( 'wp_head', array( $GLOBALS['woocommerce'], 'generator' ));
if ( function_exists( 'is_woocommerce' ) ) {
if ( ! is_woocommerce() && ! is_cart() && ! is_checkout() ) {
add_filter( 'woocommerce_enqueue_styles', '__return_empty_array' );
}}
}
It is because you are checking that the page is not all of it in once. You have to separate the if statements like:
if ( ! is_woocommerce()) {
add_filter( 'woocommerce_enqueue_styles', '__return_empty_array' );
}}
if ( ! is_cart() ) {
add_filter( 'woocommerce_enqueue_styles', '__return_empty_array' );
}}
if ( is_checkout() ) {
add_filter( 'woocommerce_enqueue_styles', '__return_empty_array' );
}}
That should fix your problem.
Change && with ||
if ( function_exists( 'is_woocommerce' ) ) {
if ( ! is_woocommerce() || ! is_cart() || ! is_checkout() ) {
add_filter( 'woocommerce_enqueue_styles', '__return_empty_array' );
}}
Deregister/Dequeue styles is best practice
https://codex.wordpress.org/Function_Reference/wp_deregister_style
https://codex.wordpress.org/Function_Reference/wp_dequeue_style
But you can use this filter too, to filter out woocommerce styles with any condition.
add_filter( 'style_loader_src', function($href){
if(strpos($href, "name-of-allowed.css") !== false) {
return $href;
}
return false;
});

Categories