Custom Username Validator Using Zend_Validate_Abstract for Zend Framework

Do you find yourself having to use multiple steps to validate a new username? If you’ve got a create user screen, or some other form that requires the creation of a username (or some other input that must be unique and is in a datastore), you can create a custom validator that uses a database mapper to validate that the input is unique.

First step, create a lookup method in your mapper (or whatever class you use for datastore access) that will query your datastore to verify the input is unique. In this case, I’m using a MySQL database backend and am using a mapper/model hierarchy and am only showing the relavant function from my mapper class.

[sourcecode=”php”]

public static function isRegisteredUser($username)
{
try
{
$table = new Ashurex_Model_DbTable_UserView();
$stmt = $table->select()
->where(‘username = ?’)
->bind(array($username));

$row = $table->fetchRow($stmt);

if(!($row == null))
{
return true;
}
else
{
return false;
}
}
catch(Exception $e)
{
self::logException(__METHOD__,$ex);
return null;
}
}

[/sourcecode]

Next, we’ll create a custom validator that extends Zend_Validate_Abstract and utilizes our mapper function during validation.

[sourcecode=”php”]
class Ashurex_Validate_Text_Username extends Zend_Validate_Abstract
{
const INVALID = ‘textInvalid';
const NOT_NAME = ‘notName';
const STRING_EMPTY = ‘textStringEmpty';
const STRING_LENGTH = ‘textStringLength';
const NAME_TAKEN = ‘textNameTaken';

protected static $_filter = null;
protected $_allowEmpty;

protected $_messageTemplates = array(
self::INVALID => ‘Invalid characters entered’,
self::NOT_NAME => ‘Input contains characters not valid for a username’,
self::STRING_EMPTY => ‘No input entered’,
self::STRING_LENGTH => ‘Username must be between 6 and 64 characters’,
self::NAME_TAKEN => ‘Username is already taken’
);

public function isValid($value)
{
// Make sure a value was entered
if(($value == null)||($value == ”))
{
$this->_error(self::STRING_EMPTY);
return false;
}

// The value must be a string
if (!is_string($value)) {
$this->_error(self::INVALID);
return false;
}

// Set the internal value to the input
$this->_setValue($value);

// Validate that the input is alphanumeric
$al = new Zend_Validate_Alnum();
if(!$al->isValid($value))
{
$this->_error(self::INVALID);
return false;
}

// Validate that the string length meets requirements
$sl = new Zend_Validate_StringLength(array(‘min’ => 6,’max’ => 64));
if(!$sl->isValid($value))
{
$this->_error(self::STRING_LENGTH);
return false;
}

// Make sure the username doesn’t already exist
if(Ashurex_Model_Mapper_User::isRegisteredUser($value))
{
$this->_error(self::NAME_TAKEN);
return false;
}

return true;
}
}
[/sourcecode]

Finally, we can use our new validator just as we would any other validator. The following code is an excerpt from my custom create user form:
[sourcecode=”php”]
class Ashurex_Form_Admin_AddUser extends Zend_form
{
public function init()
{
$this->setName(‘add_user_form’);
$this->setMethod(‘post’);

$username = new Zend_Form_Element_Text(‘username’);
$username->setFilters(
array(
new Zend_Filter_StringTrim(),
new Zend_Filter_StringToLower(),
));
$username->setValidators(
array(
new Ashurex_Validate_Text_Username(),
));
$username->setRequired(true);
$username->setLabel(‘Username’);

… lots of other code follows …

}
}

[/sourcecode]


Comments are closed.