Switch user role on subscription expiration in Woocommerce - php

In Woocommerce, I am using YITH WooCommerce Subscription plugin and I want to change user role when a subscription get expired.
For that I know that I have to use this hook:
add_action( 'subscription_expired', 'my_function', 10, 2 );
function my_function( $user_id, $subscription_key ) {
$sub= wcs_get_subscription_from_key( $subscription_key );
// do something
}
Now I have two base roles, agencia and talento, how can I make it so when a subscription expires, it changes the user role from agencia_pro or agencia_pro_plus back to agencia and talento_pro or talento_pro_plus to talento?
How can I make a function that checks the user roles and change it to either talento or agencia based on its current user role?
Thanks.

YITH Woocommerce subscription free plugin seems to be closed and don't allow customizations…
For Official Woocommerce Subscriptions plugin use the following:
add_action( 'woocommerce_subscription_status_expired', 'change_user_role_on_subscription_expired', 10, 1 );
function change_user_role_on_subscription_expired( $subscription ) {
// Get WP_User Object from subscription
$user = new WP_User($subscription->get_user_id());
if ( in_array('agencia_pro', $user->roles) ) {
$user->remove_role( 'agencia_pro' );
$user->add_role( 'agencia' );
}
elseif ( in_array('agencia_pro_plus', $user->roles) ) {
$user->remove_role( 'agencia_pro_plus' );
$user->add_role( 'agencia' );
}
elseif ( in_array('talento_pro', $user->roles) ) {
$user->remove_role( 'talento_pro' );
$user->add_role( 'talento' );
}
elseif ( in_array('talento_pro_plus', $user->roles) ) {
$user->remove_role( 'talento_pro_plus' );
$user->add_role( 'talento' );
}
}
Code goes in function.php file of your active child theme (or active theme). Tested, it should works.

Related

Automatically changing user role upon purchase in WooCommerce

I would like to make a members only section for WooCommerce customers who have made completed purchases, by assigning them a new role as the default for all registered users are "customer".
I've stumbled across some code which can solve this, however with over 200 products in store, it would be a hassle to list all the products individually.
Is there anyway to give a customer who makes ANY purchase a new role?
This is the original code:
add_action( 'woocommerce_order_status_completed', 'wpglorify_change_role_on_purchase' );
function wpglorify_change_role_on_purchase( $order_id ) {
// get order object and items
$order = new WC_Order( $order_id );
$items = $order->get_items();
$product_id = 56; // that's a specific product ID
foreach ( $items as $item ) {
if( $product_id == $item['product_id'] && $order->user_id ) {
$user = new WP_User( $order->user_id );
// Remove old role
$user->remove_role( 'customer' );
// Add new role
$user->add_role( 'editor' );
}
}
}
Updated
You can use the following instead, which will change the user role when a customer make a successful purchase (paid order):
add_action( 'woocommerce_order_status_processing', 'change_role_on_purchase', 10, 2 );
add_action( 'woocommerce_order_status_completed', 'change_role_on_purchase', 10, 2 );
function change_role_on_purchase( $order_id, $order ) {
$user = $order->get_user(); // Get the WP_User Object
// Check for "customer" user roles only
if( is_a( $user, 'WP_User' ) && in_array( 'customer', (array) $user->roles ) ) {
// Remove WooCommerce "customer" role
$user->remove_role( 'customer' );
// Add new role
$user->add_role( 'editor' );
}
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
Note: The WC_Order Object Is already an existing argument for that hooked function (missing from your code).
Addition: To remove all previous roles and assign a new role
This is possible using just the WP_User set_role() method, so in the code, replace:
// Remove WooCommerce "customer" role
$user->remove_role( 'customer' );
// Add new role
$user->add_role( 'editor' );
by:
// Reset user roles and set a new one
$user->set_role( 'editor' );

Allow guest checkout for specific products only in WooCommerce

The following code add a custom field to admin product settings to manage guest checkout at product level:
// Display Guest Checkout Field
add_action( 'woocommerce_product_options_general_product_data', 'woo_add_custom_general_fields' );
function woo_add_custom_general_fields() {
global $woocommerce, $post;
echo '<div class="options_group">';
// Checkbox
woocommerce_wp_checkbox( array(
'id' => '_allow_guest_checkout',
'wrapper_class' => 'show_if_simple',
'label' => __('Checkout', 'woocommerce' ),
'description' => __('Allow Guest Checkout', 'woocommerce' )
) );
echo '</div>';
}
// Save Guest Checkout Field
add_action( 'woocommerce_process_product_meta', 'woo_add_custom_general_fields_save' );
function woo_add_custom_general_fields_save( $post_id ){
$woocommerce_checkbox = isset( $_POST['_allow_guest_checkout'] ) ? 'yes' : 'no';
update_post_meta( $post_id, '_allow_guest_checkout', $woocommerce_checkbox );
}
// Enable Guest Checkout on Certain products
add_filter( 'pre_option_woocommerce_enable_guest_checkout', 'enable_guest_checkout_based_on_product' );
function enable_guest_checkout_based_on_product( $value ) {
if ( WC()->cart ) {
$cart = WC()->cart->get_cart();
foreach ( $cart as $item ) {
if ( get_post_meta( $item['product_id'], '_allow_guest_checkout', true ) == 'yes' ) {
$value = "yes";
} else {
$value = "no";
break;
}
}
}
return $value;
}
But it doesn't work actually. What I am doing wrong? How can I fix it?
I am trying to allow guest purchases for specific products. The admin custom field display and save custom field value is working (the 2 first functions), But login/register never comes up on checkout page, even if there are products in cart that doesn't allow guest checkout.
The filter hook enable_guest_checkout_based_on_product doesn't exist anymore and has been replaced by another hook a bit different.
So your code is going to be:
add_filter( 'woocommerce_checkout_registration_required', 'change_tax_class_user_role', 900 );
function change_tax_class_user_role( $registration_required ) {
if ( ! WC()->cart->is_empty() ) {
$registration_required = false; // Initializing (allowing guest checkout by default)
// Loop through cart items
foreach ( WC()->cart->get_cart() as $item ) {
// Check if there is any item in cart that has not the option "Guest checkout allowed"
if ( get_post_meta( $item['product_id'], '_allow_guest_checkout', true ) !== 'yes' ) {
return true; // Found: Force checkout user registration and exit
}
}
}
return $registration_required;
}
Code goes in functions.php file of your active child theme (or active theme). It should works.
Related continuation: Redirection for non checkout guest allowed in WooCommerce

Custom my account endpoint in Woocommerce just for a specific user role

Following the woocommerce documentation, I added an endpoit to my-account page in woocommerce.
I want to make this endpoint visible only to a specific user role, lets say shop_manager.
Is there a way to redirect to a 404 page users who try to access directly that endpoint?
Thanks in advance.
Assuming that you have already created a custom endpoint to my account section (see this related answer), you can redirect all non allowed user roles to a specific page using template_redirect hook in this simple way:
add_action( 'template_redirect', 'custom_endpoint_redirection' );
function custom_endpoint_redirection() {
$allowed_user_role = 'administrator';
$custom_endpoint = 'my-custom-endpoint';
if ( is_wc_endpoint_url($custom_endpoint) && ! current_user_can($allowed_user_role) ) {
$redirection_url = home_url( '/404/' );
wp_redirect( $redirection_url );
exit;
}
}
You need to specify your custom end point, your allowed user role and the url redirection.
Code goes in functions.php file of your active child theme (or active theme). It could works.
Related:
WooCommerce - Assign endpoints to multiple custom templates in my-account page
WooCommerce: Assigning an endpoint to a custom template in my account pages
WooCommerce: Adding custom template to customer account pages
Custom my account new menu item for a specific user role in Woocommerce
Just add the follows code snippet in your active theme's functions.php and this is only for administrator user role, you can change it as per you -
function add_custom_my_account_endpoint() {
add_rewrite_endpoint( 'shop_manager', EP_PAGES );
}
add_action( 'init', 'add_custom_my_account_endpoint' );
function add_custom_wc_menu_items( $items ) {
$user = wp_get_current_user();
if( $user && in_array( 'administrator', $user->roles ) ){
$items[ 'shop_manager' ] = __( 'Shop Manager', 'text-domain' );
}
return $items;
}
add_filter( 'woocommerce_account_menu_items', 'add_custom_wc_menu_items' );
function add_shop_manager_endpoint_content(){
$user = wp_get_current_user();
if( $user && !in_array( 'administrator', $user->roles ) ) return;
echo "Your content goes here";
}
add_action( 'woocommerce_account_shop_manager_endpoint', 'add_shop_manager_endpoint_content' );
After this just flush_rewrite_rules from Backend Settings > Permalinks. Thats it.

Avoid product backorders for "customer" user role in Woocommerce

I have two types of roles, normal customer and wholesale customers. The wholesale customers should be able to place backorders and the normal customers are not allow to place backorders. I am not a php developer and my code is not working yet, please help me out to make it work:
add_filter( 'woocommerce_product_backorders_allowed', 'woocommerce_product_backorders_allowed', 10, 3 );
function woocommerce_product_backorders_allowed( $backorder_allowed, $product_id, $product ){
$targeted_user_role = 'zakelijke_klant';
$user_data = get_userdata(get_current_user_id());
if ( in_array( $targeted_user_role, $user_data->roles ) ) {
$backorder_allowed = true;
}
return $backorder_allowed;
}
Try the following targeting the normal "customer" user role instead:
add_filter( 'woocommerce_product_backorders_allowed', 'woocommerce_product_backorders_allowed', 10, 3 );
function woocommerce_product_backorders_allowed( $backorder_allowed, $product_id, $product ){
if ( current_user_can('customer') ) {
$backorder_allowed = false;
} else {
$backorder_allowed = true;
}
return $backorder_allowed;
}
Code goes in function.php file of your active child theme (active theme). Tested and works.

Tax class "Zero rate" per user role on specific product ID's

I got this code that will apply tax free on a user role regardless of what they order, which is fine.
But now I need another user role that will apply tax free on specific products id, and I'm not sure how to acomplish that.
The code im using right now for tax free on all products for specific user role is:
// Apply a different tax rate based on the user role.
function wc_diff_rate_for_user( $tax_class, $product ) {
// Getting the current user
$current_user = wp_get_current_user();
$current_user_data = get_userdata($current_user->ID);
if ( in_array( 'administrator', $current_user_data->roles ) || in_array( 'userrolename', $current_user_data->roles ) )
$tax_class = 'Zero Rate';
return $tax_class;
}
add_filter( 'woocommerce_product_tax_class', 'wc_diff_rate_for_user', 1, 2 );
// Fin Apply a different tax rate based on the user role.
Here is the code that will apply this "Zero Rate" tax class for some defined products and some defined user roles:
add_filter( 'woocommerce_product_tax_class', 'wc_diff_rate_for_user', 1, 2 );
function wc_diff_rate_for_user( $tax_class, $product ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Define HERE your targeted products IDs
$products_ids_arr = array(12 ,15, 24);
// Define HERE your targeted user roles
$users_role_arr = array('administrator', 'userrolename');
//Getting the current user data
$user_data = get_userdata(get_current_user_id());
foreach ($users_role_arr as $user_role)
if ( in_array( $user_role, $user_data->roles ) && in_array( $cart_item->id, $products_ids_arr ) ) {
$tax_class = 'Zero Rate';
break;
}
return $tax_class;
}
This code is tested and works.
Code goes in any php file of your active child theme (or theme) or also in any plugin php files.
CASE 1 Via code
You can use add role function like
<?php add_role( $role, $display_name, $capabilities ); ?>
Example
add_role('basic_contributor', 'Basic Contributor', array(
'read' => true, // True allows that capability
'edit_posts' => true,
'delete_posts' => false, // Use false to explicitly deny
));
CASE 2 : Via Plugin
https://wordpress.org/plugins/user-role-editor/

Categories