Search code examples
phpwordpresswoocommerceuser-rolesuser-registration

Additional user role select field in Woocommerce registration


.

A user role selection is needed in WooCommerce registration form. Users should have a pull down menu to select between "customer" and "reseller" (IDs) wordpress role. Unfortunately my attempt to assemble code fails.

The following code does not assign the selected role and I'm stuck. Registered users still get default role "customer" although "reseller" was selected.

I have changed the code from this answer (I dont know whether this code was working anyway)

What I am doing wrong?

The code I am using:

/* To add WooCommerce registration form custom fields. */

function WC_extra_registation_fields() {?>
<p class="form-row form-row-first">
    <label for="reg_role"><?php _e( 'Privat or commercial?', 'woocommerce' ); ?></label>
    <select class="input-text" name="role" id="reg_role"> 
    <option <?php if ( ! empty( $_POST['role'] ) && $_POST['role'] == 'customer') esc_attr_e( 'selected' ); ?> value="customer">private</option> 
    <option <?php if ( ! empty( $_POST['role'] ) && $_POST['role'] == 'reseller') esc_attr_e( 'selected' ); ?> value="reseller">commercial</option>
    </select> 
</p>

<?php
}

add_action( 'woocommerce_register_form', 'WC_extra_registation_fields');


/* To validate WooCommerce registration form custom fields.  */
function WC_validate_reg_form_fields($username, $email, $validation_errors) {
if (isset($_POST['role']) && empty($_POST['role']) ) {
    $validation_errors->add('role_error', __('Role required!', 'woocommerce'));
}

return $validation_errors;
}

add_action('woocommerce_register_post', 'WC_validate_reg_form_fields', 10, 3);


/* To save WooCommerce registration form custom fields. */
function WC_save_registration_form_fields($customer_id) {

//Role field
if (isset($_POST['role'])) {
    update_user_meta($customer_id, 'role', sanitize_text_field($_POST['role']));
}

}

add_action('woocommerce_created_customer', 'WC_save_registration_form_fields');

Solution

  • The user Role "reseller" needs to be created first in Wordpress. This can be done with code or by a plugin, but it's not the purpose of this question/answer.

    The user roles are registered in wp_usermeta table using the meta_key wp_capabilities for an array of values, as a user can have many user roles.

    In Woocommerce registration, the user get anyway registered with 'customer' user role. So you will need to make changes only for 'reseller' choice.

    At this point, you can do 2 things:

    • Case 1 - Change the user role from 'customer' to 'reseller'
    • Case 2 - Add to the customer user role, the 'reseller' user role

    So your code will be:

    add_action( 'woocommerce_register_form', 'wc_extra_registation_fields' );
    function wc_extra_registation_fields() {
        ?>
            <p class="form-row form-row-first">
                <label for="reg_role"><?php _e( 'Privat or commercial?', 'woocommerce' ); ?></label>
                <select class="input-text" name="role" id="reg_role">
                <option <?php if ( ! empty( $_POST['role'] ) && $_POST['role'] == 'customer') esc_attr_e( 'selected' ); ?> value="customer">private</option>
                <option <?php if ( ! empty( $_POST['role'] ) && $_POST['role'] == 'reseller') esc_attr_e( 'selected' ); ?> value="reseller">commercial</option>
                </select>
            </p>
        <?php
    }
    

    and:

    // Validate WooCommerce registration form custom fields.
    add_action( 'woocommerce_register_post', 'wc_validate_reg_form_fields', 10, 3 );
    function wc_validate_reg_form_fields($username, $email, $validation_errors) {
        if (isset($_POST['role']) && empty($_POST['role']) ) {
            $validation_errors->add('role_error', __('Role required!', 'woocommerce'));
        }
        return $validation_errors;
    }
    

    Then you will Add this:

    For CASE 1 (set a unique user role):

    // To save WooCommerce registration form custom fields.
    add_action( 'woocommerce_created_customer', 'wc_save_registration_form_fields' );
    function wc_save_registration_form_fields( $customer_id ) {
        if ( isset($_POST['role']) ) {
            if( $_POST['role'] == 'reseller' ){
                $user = new WP_User($customer_id);
                $user->set_role('reseller');
            }
        }
    }
    

    So in database is correctly registered (as it should be to get readable by Wordpress but only if user role "reseller" exist):

    enter image description here

    Or for CASE 2 (add a 2nd user role):

    // To save WooCommerce registration form custom fields.
    add_action( 'woocommerce_created_customer', 'wc_save_registration_form_fields' );
    function wc_save_registration_form_fields( $customer_id ) {
        if ( isset($_POST['role']) ) {
            if( $_POST['role'] == 'reseller' ){
                $user = new WP_User($customer_id);
                $user->add_role('reseller');
            }
        }
    }
    

    So in database is correctly registered (as it should be to get readable by Wordpress but only if user role "reseller" exist):

    enter image description here

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


    If I use the following code once user is registered:

    $user_roles = wp_get_current_user()->roles;
    print_r($user_roles);
    

    I get this display:

    • For CASE 1: Array ( [0] => reseller )
    • For CASE 2: Array ( [0] => customer [1] => reseller )

    You will certainly need to use a plugin like User Role Editor (if not done yet) to create and define the capabilities of your "reseller" user role…