Skip to content

Instantly share code, notes, and snippets.

@philipnewcomer
Last active February 11, 2023 19:05
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save philipnewcomer/59a695415f5f9a2dd851deda42d0552f to your computer and use it in GitHub Desktop.
Save philipnewcomer/59a695415f5f9a2dd851deda42d0552f to your computer and use it in GitHub Desktop.
Generate a unique username in WordPress
<?php
/**
* Recursive function to generate a unique username.
*
* If the username already exists, will add a numerical suffix which will increase until a unique username is found.
*
* @param string $username
*
* @return string The unique username.
*/
function generate_unique_username( $username ) {
static $i;
if ( null === $i ) {
$i = 1;
} else {
$i++;
}
if ( ! username_exists( $username ) ) {
return $username;
}
$new_username = sprintf( '%s-%s', $username, $i );
if ( ! username_exists( $new_username ) ) {
return $new_username;
} else {
return call_user_func( __FUNCTION__, $username );
}
}
@poyo12
Copy link

poyo12 commented Jul 4, 2021

@brian-stinar can you help me with this please? I need it to autogenerate username with digits only. The user can only logins with the username name and not emails.

@brian-stinar
Copy link

@poyo12 Here's the free help version:

` function generateRandomString($username = null){

//specify characters to be used in generating random string, do not specify any characters that WordPress does not allow in the creation of usernames.

$characters = "0123456789";
.
.
... everything else the same except for this...
for ($i = 0; $i < 60; $i++) {

`
and then call it with no parameters, like generateRandomString(). Might be better to cut out all reference to $username, if you never, ever want the user to pass in what they'd like ("007" or anything...) This depends on how flexible / reusable you want this code. I'm not going to rewrite this portion during the free help session.

Since that's the first part of the username generation routine. Then, you need to disable email-based logins, probably like this:

remove_filter( 'authenticate', 'wp_authenticate_email_password', 20 );
https://www.wpbeginner.com/plugins/how-to-disable-login-with-email-address-feature-in-wordpress/

Does this make sense? I'm sure the first part of this will work, since I heavily modified this, and used it in a production system. I'm not positive about the second part, but it looks good to me with the filter removal.

Let me know if you want to move onto the paid help session, but this should get you close to where you need to be. Focus on really understanding how those portions work which I said to modify, and you should be able to do it.

@mronikoyi
Copy link

@brian-stinar, i'm looking for the same thing as @poyo12 .
I had someone help me but they simply added it on the register.php from a plugin (i'm afraid that this method will not work if I change that particular plugin to manage my buddypress website).
I was wondering if there was a way to make a standalone plugin that does the same (basically, whenever a person register, a username is generated, either by incrementation from a chosen number, or by random 12 digits generation)
I'm a bit stuck.

@brian-stinar
Copy link

@mronikoyi yes, the cleanest way to do this is with it's OWN plugin. The next thing that would work is to put it in your theme. It's not a good idea to put this in someone else's plugin, since then you'll have the same problems you're describing.

Here's the free help version to get you started:
https://developer.wordpress.org/plugins/intro/

and I recommend using boilerplate plugin code to get started:
https://wppb.me/
https://github.com/DevinVinson/WordPress-Plugin-Boilerplate

Send us a contact request through my consulting company if you want the non-free version of help. These (and the above tested, working code) should be everything you need to get this going.

@mronikoyi
Copy link

thanks @brian-stinar !
I thought so too!

@mronikoyi
Copy link

I didn't knbow about the boilerplate plugin generator! Thanks for the info !

@brian-stinar
Copy link

Sure, no problem. We make a good chunk of cash off open source software, and I try and contribute how I can.

This would actually be a good plugin to write... Maybe I'll have one of my junior level people take care of this.

@mharis
Copy link

mharis commented Sep 23, 2022

Added comment block.

/**
 * Generates a unique username.
 *
 * @param string $username Username to check.
 * @return string username
 */
function generate_unique_username( $username ) {
	$username = sanitize_user( $username );

	static $i;
	if ( null === $i ) {
		$i = 1;
	} else {
		$i ++;
	}
	if ( ! username_exists( $username ) ) {
		return $username;
	}
	$new_username = sprintf( '%s-%s', $username, $i );
	if ( ! username_exists( $new_username ) ) {
		return $new_username;
	} else {
		return call_user_func( __FUNCTION__, $username );
	}
}

@TinkerPaul
Copy link

TinkerPaul commented Oct 15, 2022

New here on GitHub but I thought I'd share my take on this code. My website does not allow user registration. Users are currently created manually. This will allow for use of a csv file (via plugin) to load new users and ensure unique usernames. I replaced the recursive function calls with a while loop. Because of where I hooked into sanitize_user is already performed by the .../includes/user.php edit_user function. Because of hook location removal of the registration error is required.

function generate_unique_username( $errors, $update, $user ) {
        $username = $user->user_login;
        //strip off any trailing digits on the username (Optional, delete if functionality not desired)
        static $loop = 0;
        do {
                $loop++;
                $last = substr($username, strlen($username)-$loop);
        } while ( is_numeric( $last ) );
        $username = substr($username, 0, strlen($username)-($loop-1));

        //iterate to find the next unused username
        $i = 0;
        $new_username = $username;
        while ( username_exists( $new_username ) ) {
                $i ++;
                $new_username = sprintf( '%s%d', $username, $i );
        }

        //Store the new username and clear the error log for username error only
        $user->user_login = $new_username;
        if ($errors->has_errors()) {
                if (in_array('user_login', $errors->get_error_codes()) ) {
                        if(count($errors->get_error_messages( 'user_login' )) == 1) {
                                if(str_contains($errors->get_error_message( 'user_login' ), "This username is already registered")) {
                                        $errors->remove('user_login');
                                }
                        }
                }
        }
}

add_action( 'user_profile_update_errors' , 'generate_unique_username', 10 , 3 );

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment