I believe it is correct.
The one you posted is worried about the password being empty with if (!empty($this->password).
What the function afterValidate() does is encrypt the password after validation! After it check the rules(), and if you followed the chapter there are rules that check that the password is required.
After checking the password is not empty with rules() then the afterValidate() function is executed therefore it’s almost the same logic as if (!empty($this->password).
Edit:
So in other word:
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('password', 'compare'),
array('password_repeat', 'safe'),
array('email, username, password', 'required'),
array('email, username, password', 'length', 'max'=>256),
array('email, username', 'unique'),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
array('id, email, username, password, last_login_time, create_time, create_user_id, update_time, update_user_id', 'safe', 'on'=>'search'),
);
}
This function, rules(), is executed first and then aftervalidate().
array(‘email, username, password’, ‘required’) <— this makes sure that password is not empty.
EDIT:
BTW all these code snippets are in User Model AR.