2

i am trying to get a new user an auto assigned sequence based username(non editable by user) while registration.

so it will be starting from 0000000001 and so on, i have tried certain codes but my registration form went down.

request for help.

1
  • 1
    Should really respond to those who respond to your questions, as ppl soon may stop posting replies if you ignore the responses :-\
    – sMyles
    Commented May 24, 2018 at 20:50

1 Answer 1

1

This all depends on how users are being registered on your site.

TLDR The code below allows you to create custom users from admin area specifying custom usernames, or use GENERATE_CUSTOM_SEQ_USERNAME to generate sequential numbered one. If using registration form other than wp-login.php just set user_login to GENERATE_CUSTOM_SEQ_USERNAME and hide the field using CSS.

If they will be registering through wp-login.php registration page, first you will need to allow empty user_login input field:

/**
 * Filters the errors encountered when a new user is being registered.
 *
 * The filtered WP_Error object may, for example, contain errors for an invalid
 * or existing username or email address. A WP_Error object should always returned,
 * but may or may not contain errors.
 *
 * If any errors are present in $errors, this will abort the user's registration.
 *
 * @since 2.1.0
 *
 * @param WP_Error $errors               A WP_Error object containing any errors encountered
 *                                       during registration.
 * @param string   $sanitized_user_login User's username after it has been sanitized.
 * @param string   $user_email           User's email.
 */
add_filter( 'registration_errors', 'smyles_allow_wp_login_register_empty_user_login', 9999, 3 );

/**
 * Allow empty user_login (username) from wp-login.php registration form
 *
 *
 * @since @@version
 *
 * @param $errors WP_Error
 * @param $sanitized_user_login
 * @param $user_email
 *
 * @return mixed
 */
function smyles_allow_wp_login_register_empty_user_login( $errors, $sanitized_user_login, $user_email ){

    // First remove empty_username error code to make sure there aren't any other errors
    $errors->remove( 'empty_username' );
    $error_codes = $errors->get_error_codes();

    // Return errors and don't process further (we only want to proceed when empty_username is only error code)
    if( ! empty( $error_codes ) ){
        return $errors;
    }

    return $errors;
}

This is done by filtering on the registration errors for wp-login.php and removing the empty_username one.

Next you will need a helper function to generate the sequential username, with the padded zeros. This function uses a length of 10 characters, increasing it by one for each new user. This also verifies the user_login does not exist before setting it to that value.

/**
 * Generate sequential padded user_login
 *
 * @author Myles McNamara
 *
 * @return string
 */
function smyles_generate_next_seq_user_login(){

    // Use 0 as default (if option does not exist yet), as 1 will be used for first user
    $last_user_num = get_option( 'smyles_custom_seq_usernames_last_id', 0 );

    // Create padded username total length of 10 characters, increasing last ID by 1
    $gen_user_login = str_pad( (int) $last_user_num + 1, 10, 0, STR_PAD_LEFT );

    if( username_exists( $gen_user_login ) ){
        // If generated new user login exists, update our last id +1 and do recursive call
        update_option( 'smyles_custom_seq_usernames_last_id', (int) $last_user_num + 1 );
        return smyles_generate_next_seq_user_login();
    }

    return $gen_user_login;
}

You will then need to filter on the user_login handled by the wp_insert_user function. Because we are allowing the wp-login.php to pass an empty user_login from the register_new_user function, we can then check if that value is empty, and return our custom generated one.

You will also notice I added in GENERATE_CUSTOM_SEQ_USERNAME to check passed user_login, this can be useful if you want to use CSS to hide the user login field (in any other registration forms), and have it generate user_login without throwing an error for empty username. As that username technically should never exist, you can just use this as a placeholder to determine if a username should be generated.

This also allows you to create a new user in admin area, and just set GENERATE_CUSTOM_SEQ_USERNAME as username, and it will generate sequential numbered one for you, or create your own custom one.

add_filter( 'pre_user_login', 'smyles_custom_username_seq_pre_user_login' );

/**
 * Set user_login to generated value, only if passed value is empty
 *
 * @author Myles McNamara
 *
 * @param $sanitized_user_login
 *
 * @return string
 */
function smyles_custom_username_seq_pre_user_login( $sanitized_user_login ){

    $sanitized_user_login = trim( $sanitized_user_login ); // to match wp_insert_user handling

    /**
     * The user_login should be empty string when creating from wp-login.php registration page,
     * otherwise will contain a value when called by something else.
     *
     * There is a chance this will be called for updating a user (which is incorrect as wp_update_user should be called),
     * but even when updating a user, the passed user_login should have some type of value.
     */
    if( empty( $sanitized_user_login ) || $sanitized_user_login === 'GENERATE_CUSTOM_SEQ_USERNAME' ){
        $sanitized_user_login = smyles_generate_next_seq_user_login();
    }

    return $sanitized_user_login;
}

The next step would be to update the last used ID in the option, but only after verifying that the user was actually created (and no other error caused failure in creating user):

/**
 * Filters a user's meta values and keys immediately after the user is created or updated
 * and before any user meta is inserted or updated.
 *
 * Does not include contact methods. These are added using `wp_get_user_contact_methods( $user )`.
 *
 * @since 4.4.0
 *
 * @param array   $meta                 {
 *                                      Default meta values and keys for the user.
 *
 * @type string   $nickname             The user's nickname. Default is the user's username.
 * @type string   $first_name           The user's first name.
 * @type string   $last_name            The user's last name.
 * @type string   $description          The user's description.
 * @type bool     $rich_editing         Whether to enable the rich-editor for the user. False if not empty.
 * @type bool     $syntax_highlighting  Whether to enable the rich code editor for the user. False if not empty.
 * @type bool     $comment_shortcuts    Whether to enable keyboard shortcuts for the user. Default false.
 * @type string   $admin_color          The color scheme for a user's admin screen. Default 'fresh'.
 * @type int|bool $use_ssl              Whether to force SSL on the user's admin area. 0|false if SSL is
 *                                          not forced.
 * @type bool     $show_admin_bar_front Whether to show the admin bar on the front end for the user.
 *                                          Default true.
 * }
 *
 * @param WP_User $user                 User object.
 * @param bool    $update               Whether the user is being updated rather than created.
 */
add_filter( 'insert_user_meta', 'smyles_custom_username_seq_verify', 10, 3 );

/**
 * Verify user was created, and then increase option value
 *
 *
 * @author Myles McNamara
 *
 * @param $meta
 * @param $user WP_User
 * @param $update
 *
 * @return mixed
 */
function smyles_custom_username_seq_verify( $meta, $user, $update ){

    // Don't want to verify if this is just an update call
    if( ! $update && $user && $user->user_login ){

        // Check what the last user num was stored as
        $last_user_num = get_option( 'smyles_custom_seq_usernames_last_id', 0 );

        // Verify that user_login of the user that was created, matches what is supposed to be the next user_login
        if( (int) $last_user_num + 1 === (int) $user->user_login ){
            // Update our option after verification
            update_option( 'smyles_custom_seq_usernames_last_id', (int) $user->user_login ); // Type casting to int causes 0000000001 to be 1 (trim leading zeros)
        }

    }

    return $meta;
}

You will probably then want to hide the userlogin input on the wp-login.php form, which you can do with some simple CSS:

add_action( 'register_form', 'smyles_hide_wp_login_username_field' );

function smyles_hide_wp_login_username_field(){

    // Hide the first <p> element in registerform, which is the userlogin input
    echo '<style>#registerform p:first-of-type { display: none; }</style>';

}

https://gist.github.com/tripflex/1acacc19467122cdb1171a5e0b7300dd

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.