Search code examples
phpwordpresswoocommerceuser-roleswoocommerce-subscriptions

Add a user role using WooCommerce order transition status hooks


I need to add a new role to my recently registered user (upon buying any of my four specific subscription products). Until now, every recently registered user (those who buy a subscription product) get a Subscriber role. While I want them to be Subscriber + Advertiser if they buy any of my 4 target subscription products.

I have tried to use woocommerce_order_status_completed, woocommerce_order_status_processing and woocommerce_order_status_changed hooks, but none of them are working with my code.

I have modified the function and code inside these hooks several times but I got nothing special.

Until now, I have used this code.

add_action( 'woocommerce_order_status_completed', 'so_29647785_convert_customer_role' );   
function so_29647785_convert_customer_role( $order_id ) {

    $order = new WC_Order( $order_id );
    if ( $order->user_id > 0 ) {
        foreach ( $order->get_items() as $order_item ) {
            if( 4008 == $order_item[ 'product_id' ] ) {
                $user = new WP_User( $order->user_id );

                // Add new role
                $user->add_role( 'advertiser' );
            }
        }
    }
}

I will appreciate any help or track.


I have also tried this code and it is helpful in creating a user with both Subscriber + Advertiser roles but I can't do so in my case. Because I need users to be registered with both Subscriber + Advertiser roles only if they will buy four of my target subscription products. While this code is adding both Subscriber + Advertiser to every new user regardless of the product they choose.

add_filter('woocommerce_new_customer_data', 'bbloomer_assign_custom_role', 10, 1);

function bbloomer_assign_custom_role($args) {
  $args['role'] = 'advertiser';
  return $args;
}

Any help will highly be appreciated!


Solution

  • Since Woocommerce 3, your code is outdated and there are some errors and mistakes in your code, like $order_item['product_id'] will not work… Try the following instead:

    add_action( 'woocommerce_order_status_processing', 'order_status_change_add_user_role', 10, 2 );
    add_action( 'woocommerce_order_status_completed', 'order_status_change_add_user_role', 10, 2 );
    function order_status_change_add_user_role( $order_id, $order ) {
        if ( $order->get_user_id() > 0 ) {
            $user = $order->get_user(); // Get an instance of the WP_User object
    
            foreach ( $order->get_items() as $item ) {
                // Check that user role is not set yet and that is matching with a product ID
                if( 4008 == $item->get_product_id() && ! in_array('advertiser', $user->roles) ) {
                    $user->add_role( 'advertiser' ); // Add new role
                    break; // Stop the loop
                }
            }
        }
    }
    

    Code goes in function.php file of your active child theme (or active theme). It should works now.

    Order and order items related since Woocommerce 3: