phpwordpresswoocommerceregistrationuser-roles

Forcing Customer To Choose WooCommerce Role Upon Registration


I have read about this and seen others asking the same thing, but no matter what I do or did, nothing seem to work the way I need it.

I have already removed all other roles (editor, subscriber, contributer, shop manager etc.) and I now only have Administrator and Customer left.

I therefore, need the all new users, when filling out the WooCommerce registration form, to choose between "Buyer" and "Seller".

This is the code I am working with:

add_action( 'woocommerce_register_form', 'user_role_dropdown' );
function user_role_dropdown() {

    $wp_roles = new WP_Roles();
    $wp_roles->use_db = true;
    echo '<select id="role" name="role">';
    
        foreach ( $wp_roles->roles as $key=>$value ) {
        if ( ( $value['name'] !== 'Buyer') && ( $value['name'] !== 'Seller' ) ) {
    
        echo '<option value="' . $key . '">' . $value['name'] . '</option>';
        }
    }
    echo '</select>';
}

add_action( 'personal_options_update', 'save_role_selection_field' );
add_action( 'edit_user_profile_update', 'save_role_selection_field' );
function save_role_selection_field( $user_id ) {

    update_user_meta( $user_id, 'role', $_POST['role'] );
    $user = new WP_User( $user_id );
    $current_user_role = get_current_user_role();
    $user->remove_role( $current_user_role );
    $user->add_role( $_POST['role'] );
}

function get_current_user_role() {
    global $current_user;
    get_currentuserinfo();
    $user_roles = $current_user->roles;
    $user_role = array_shift( $user_roles );
    return $user_role;
};


add_action( 'user_register', 'register_role' );
function register_role( $user_id, $password="", $meta=array() ) {

    $userdata = array();
    $userdata[ 'ID' ] = $user_id;
    $userdata[ 'role' ] = $_POST[ 'role' ];
    if ( $userdata[ 'role' ] ) {
    wp_update_user( $userdata );
    }
}

add_filter( 'registration_errors', 'new_usersroles_registration_errors', 10, 3 );
function new_usersroles_registration_errors( $errors, $sanitized_user_login, $user_email ) {

    if ( empty( $_POST['role'] ) || ! empty( $_POST['role'] ) && trim( $_POST['role'] ) == '' ) {

        $errors->add( 'role_error', __( '<strong>FYI:</strong> You must choose a role for your account. Buyers can not sell. Sellers cannot buy.', 'woocommerce' ) );
    }

    return $errors;
}

add_action( 'user_register', 'new_usersroles_user_register' );
function new_usersroles_user_register( $user_id ) {
$user_id = wp_update_user( array( 'ID' => $user_id, 'role' => $_POST[ 'role' ] ) );
}

Solution

  • There are some confusions with the required hooks and some little mistakes. Use the following to display a custom select field to WooCommerce registration form (validate and save data):

    add_action( 'woocommerce_register_form', 'display_user_role_registration_field' );
    function display_user_role_registration_field() {
    
        $wp_roles = new WP_Roles();
        $wp_roles->use_db = true;
    
        echo '<select id="role" name="role">
            <option value="">' . __("Select a role") . '</option>';
    
        foreach ( $wp_roles->roles as $role_key => $role_data ) {
            if ( in_array($role_data['name'], ['Buyer', 'Seller']) ) {
                echo '<option value="' . $role_key . '">' . $role_data['name'] . '</option>';
            }
        }
        echo '</select>';
    }
    
    // Validate WooCommerce registration select role fields.
    add_action( 'woocommerce_register_post', 'validate_user_role_registration_field', 10, 3 );
    function validate_user_role_registration_field($username, $email, $validation_errors) {
        if (isset($_POST['role']) && empty($_POST['role']) ) {
            $message = __('<strong>FYI:</strong> You must choose a role for your account. Buyers can not sell. Sellers cannot buy.', 'woocommerce');
            $validation_errors->add('role_error', $message);
        }
        return $validation_errors;
    }
    
    // Save WooCommerce registration select role fields.
    add_action( 'woocommerce_created_customer', 'save_user_role_registration_field' );
    function save_user_role_registration_field( $customer_id ) {
        if ( isset($_POST['role']) && ! empty($_POST['role']) ) {
            $user = new WP_User($customer_id);
            $user->set_role($_POST['role']);
        }
    }
    

    Code goes in function.php file of your active child theme (or active theme). Tested and works.

    related: Additional user role select field in Woocommerce registration