PHP: Alternate Username if Already Taken

Small, short code snippets that other people may find useful. Do you have a good regex that you would like to share? Share it! Even better, the code can be commented on, and improved.

Moderator: General Moderators

Post Reply
jason
Site Admin
Posts: 1767
Joined: Thu Apr 18, 2002 3:14 pm
Location: Montreal, CA
Contact:

PHP: Alternate Username if Already Taken

Post by jason »

Basically, I needed something that would check to see if the username was already taken, and if it was, suggest other, optional usernames. I came up with this pretty quick. I could actually replace the SQL that's in the loop with a single SQL query, but I need it done before I go back and refactor.

Code: Select all

class NewUsername extends Validator 
{
	var $Username;
	var $OtherValues;
	var $AvailableUsernames;
	
	function NewUsername ( &$Username, $OtherValues )
	{
		$this->Username =& $Username;
		$this->OtherValues = $OtherValues;
		parent::Validator();
	}
	
	function validate ()
	{
		if (strlen($this->Username) < 3 ) {
			$this->setError('Username is too short.  The username you select must be at least 3 characters long.');
			return;
		}
		
		if (strlen($this->Username) >= 20 ) {
			$this->setError('Username is too long. Your username can be a maximum of 20 characters.');
		}
		
		if (!preg_match('/^[a-zA-Z]([a-zA-Z0-9_-]+)?$/',$this->Username )) {
			$this->setError('The username you entered is not in the correct format.  It can only contain letters, numbers,
							underscores (_) ,and a hyphen (-).  It must also start with a letter.');
		}
		
		$FindUsernameSQL = sprintf("SELECT COUNT(*) FROM users WHERE username = '%s' LIMIT 1", $this->Username);
		$db =& staticDatabase();
		list($Count) = $db->simpleQuery($FindUsernameSQL);
		
		if ( $Count > 0 ) {
			$this->AvailableUsernames = $this->getOtherPossibleUsernames();
			$AvailableUsernameStr = "'".implode("', '", $this->AvailableUsernames)."'";
			$ErrorMessage = sprintf("We apologize, but the username '%s' is already in use.  However, you can choose
							one of these other usernames that are available: %s",
							$this->Username, $AvailableUsernameStr);
			$this->setError($ErrorMessage);
			$this->Username = $this->AvailableUsernames[0];
		}
	}
	
	function getAvailableUsernames ()
	{
		return $this->AvailableUsernames;
	}
	
	function getOtherPossibleUsernames ()
	{
		$db =& staticDatabase();
		$CheckPossibleUsernameSQL = "SELECT COUNT(*) FROM users WHERE username = '%s' LIMIT 1";
		
		$FullName = $this->OtherValues['full_name'];
		$PossibleUsernameOptions[] = str_replace(' ', '_', $FullName);
		$PossibleUsernameOptions[] = str_replace(' ', '', $FullName);
		
		for ( $x = 1; $x <= 2; $x++ ) {
			$PossibleUsernameOptions[] = $this->Username.$x;
			$PossibleUsernameOptions[] = $this->Username.'200'.$x;
		}
		
		foreach ( $PossibleUsernameOptions as $Username ) {
			if ( empty($Username) ) continue;
			list($Count) = $db->simpleQuery(sprintf($CheckPossibleUsernameSQL, $Username));
			if ( $Count == 0 ) {
				$AvailableUsernames[] = $Username;
			}
		}
		
		return $AvailableUsernames;
	}
	
	function getClean ()
	{
		return $this->Username;
	}
}
Post Reply