In this tutorial we will discuss about setting up our Yii application
- Our Web Apps will have user registration page
- Our Web Apps will varified user registration trough emails activation
The first thing is we need to look into our User table or our User model. Im setting up my tbl_user as below. Im also insert sample record :
[php]
—
— Table structure for table `tbl_user`
—
CREATE TABLE IF NOT EXISTS `tbl_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(128) COLLATE utf8_unicode_ci NOT NULL,
`password` varchar(128) COLLATE utf8_unicode_ci NOT NULL,
`salt` varchar(128) COLLATE utf8_unicode_ci NOT NULL,
`email` varchar(128) COLLATE utf8_unicode_ci NOT NULL,
`joined` date NOT NULL,
`activationcode` int(11) NOT NULL,
`activationstatus` int(11) NOT NULL,
`profile` text COLLATE utf8_unicode_ci,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=11 ;
—
— Dumping data for table `tbl_user`
—
INSERT INTO `tbl_user` (`id`, `username`, `password`, `salt`, `email`, `joined`, `activationcode`, `activationstatus`, `profile`) VALUES
(1, ‘demo’, ‘2e5c7db760a33498023813489cfadc0b’, ’28b206548469ce62182048fd9cf91760′, ‘webmaster@example.com’, ‘0000-00-00’, 0, 0, NULL);
[/php]
Then we customize our model User.
- We make change at rules().
- We make change at attributeLabels()
- We create generateActivationCode()
[php]
<?php
/**
* This is the model class for table "tbl_user".
*
* The followings are the available columns in table ‘tbl_user’:
* @property integer $id
* @property string $username
* @property string $password
* @property string $salt
* @property string $email
* @property string $profile
* @property string $activationcode
* @property string $activationstatus
*/
class User extends CActiveRecord
{
/**
* Returns the static model of the specified AR class.
* @param string $className active record class name.
* @return User the static model class
*/
public static function model($className=__CLASS__)
{
return parent::model($className);
}
/**
* @return string the associated database table name
*/
public function tableName()
{
return ‘tbl_user’;
}
/**
* @return array validation rules for model attributes.
*/
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array(‘username, password, salt, email, activationcode, activationstatus’, ‘required’),
array(‘username, password, salt, email’, ‘length’, ‘max’=>128),
array(‘profile’, ‘safe’),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
array(‘id, username, password, salt, email, profile’, ‘safe’, ‘on’=>’search’),
);
}
/**
* @return array relational rules.
*/
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
);
}
/**
* @return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
return array(
‘id’ => ‘ID’,
‘username’ => ‘Username’,
‘password’ => ‘Password’,
‘salt’ => ‘Salt’,
’email’ => ‘Email’,
‘profile’ => ‘Profile’,
);
}
/**
* Checks if the given password is correct.
* @param string the password to be validated
* @return boolean whether the password is valid
*/
public function validatePassword($password)
{
return $this->hashPassword($password,$this->salt)===$this->password;
}
/**
* Create activation code.
* @param string email
*/
public function generateActivationCode($email){
return sha1(mt_rand(10000, 99999).time().$email);
}
/**
* Generates the password hash.
* @param string password
* @param string salt
* @return string hash
*/
public function hashPassword($password,$salt)
{
return md5($salt.$password);
}
/**
* Generates a salt that can be used to generate a password hash.
* @return string the salt
*/
public function generateSalt()
{
return uniqid(”,true);
}
}
[/php]
Next, we then need to setup new model name RegisterForm. Why? Because this model will handle the registration form data.
- Define all attributes/properties use in the Registration Form Page
- Define all rules() for properties needed at the Registration Form.
- Define Labels
[php]
<?php
/**
* RegisterForm class.
* RegisterForm is the data structure for keeping
* user login form data. It is used by the ‘register’ action of ‘SiteController’.
*/
class RegisterForm extends CFormModel
{
public $username;
public $password;
public $password_repeat;
public $joined;
public $activationcode;
public $activationstatus;
public $salt;
public $email;
public $verifyCode;
private $_identity;
/**
* Declares the validation rules.
* The rules state that username and password are required,
* and password needs to be authenticated.
*/
public function rules()
{
return array(
// username, password, email are required
array(‘username, password , password_repeat, email’, ‘required’),
// username and email should be unique
array(‘username, email’, ‘unique’, ‘className’ => ‘User’),
// email should be in email format
array(’email’, ’email’),
array(‘password’, ‘compare’, ‘on’=>’registration’, ‘compareAttribute’=>’password_repeat’),
array(‘password_repeat’, ‘safe’),
array(‘verifyCode’, ‘captcha’, ‘allowEmpty’=>!CCaptcha::checkRequirements()),
);
}
/**
* Declares attribute labels.
*/
public function attributeLabels()
{
return array(
‘username’=>’Username’,
‘password’=>’Password’,
‘password_repeat’=>’Verified Password’,
’email’=>’Email’,
‘verifyCode’=>’Verification Code’,
);
}
/**
* Authenticates the password.
* This is the ‘authenticate’ validator as declared in rules().
*/
public function authenticate($attribute,$params)
{
if(!$this->hasErrors())
{
$this->_identity=new UserIdentity($this->username,$this->password);
if(!$this->_identity->authenticate())
$this->addError(‘password’,’Incorrect username or password.’);
}
}
}
[/php]
At SiteController.php,
- Create action named actionRegister() to handle data from registration form .
- Create action named actionActivate() to handle activation url from user email
[php]
//————————————————————————————–
public function actionRegister() {
$model=new RegisterForm;
$newUser = new User;
// if it is ajax validation request
if(isset($_POST[‘ajax’]) && $_POST[‘ajax’]===’login-form’)
{
echo CActiveForm::validate($model);
Yii::app()->end();
}
// collect user input data
if(isset($_POST[‘RegisterForm’]))
{
$model->attributes=$_POST[‘RegisterForm’];
// if ($model->validate()) {
$newUser->username = $model->username;
//$newSalt = $newUser->generateSalt();
$newSalt=$newUser->generateSalt();
$newUser->password = $newUser->hashPassword($model->password,$newSalt);
$newUser->salt = $newSalt;
$newUser->activationcode = $newUser->generateActivationCode($model->email);
// $newUser->activationcode = sha1(mt_rand(10000, 99999).time().$email);
$newUser->activationstatus = 0;
//return $this->hashPassword($password,$this->salt)===$this->password;
$newUser->username = $model->username;
$newUser->email = $model->email;
$newUser->joined = date(‘Y-m-d’);
if ($model->validate() && $newUser->save()) {
//if want to go login, just uncomment this below
// $identity=new UserIdentity($newUser->username,$model->password);
// $identity->authenticate();
// Yii::app()->user->login($identity,0);
//redirect the user to page he/she came from
//email activation code starts—————————————–
$to = $model->email;
$subject = "Welcome To GhazaliTajuddin.com!";
$message = "Thank you for joining!, we have sent you a separate email that contains your activation link";
$from = "FROM: mr.ghazali@gmail.com";
mail($to,$subject,$message,$from);
//echo $to.$subject.$message.$from;
$headers = ‘MIME-Version: 1.0’ . "\r\n";
$headers .= ‘Content-type: text/html; charset=iso-8859-1’ . "\r\n";
$headers .= ‘From: Mr. Ghazali < mr.ghazali@gmail.com>’ . "\r\n";
$subject2 = "Your Activation Link";
$message2 = "<html><body>Please click this below to activate your membership<br />".
Yii::app()->createAbsoluteUrl(‘site/activate’, array(’email’ => $newUser->email)).
"
Thanks you.
". sha1(mt_rand(10000, 99999).time().$email) ."
</body></html>";
mail($to, $subject2, $message2, $headers);
//email activation code end—————————————–
$this->redirect(Yii::app()->user->returnUrl);
}
// }
}
// display the register form
$this->render(‘register’,array(‘model’=>$model));
}
//————————————————————————————–
/**
* Activation Action
*/
public function actionActivate()
{
$email = Yii::app()->request->getQuery(’email’);
// collect user input data
if(isset($email))
{
$model = User::model()->find(’email=:email’, array(‘:email’=>$email));
if($email == $model->email){
$model->activationstatus=1;
$model->validate();
$model->save();
}
}
// display the login form
$this->render(‘activate’,array(‘model’=>$model));
}
[/php]
Finally, we then need to create a view name register under /webapp/protected/views/site/register.php. This views content user registration forms.
[php]
<?php
$this->pageTitle=Yii::app()->name . ‘ – Register’;
$this->breadcrumbs=array(
‘Register’,
);
?>
<h1>Register</h1>
<p>Please fill out the following form:</p>
<div class="form">
<?php $form=$this->beginWidget(‘CActiveForm’, array(
‘id’=>’register-form’,
‘enableClientValidation’=>true,
‘clientOptions’=>array(
‘validateOnSubmit’=>true,
),
)); ?>
<p class="note">Fields with <span class="required">*</span> are required.</p>
<div class="row">
<?php echo $form->labelEx($model,’username’); ?>
<?php echo $form->textField($model,’username’); ?>
<?php echo $form->error($model,’username’); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,’email’); ?>
<?php echo $form->textField($model,’email’); ?>
<?php echo $form->error($model,’email’); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,’password’); ?>
<?php echo $form->passwordField($model,’password’); ?>
<?php echo $form->error($model,’password’); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,’password_repeat’); ?>
<?php echo $form->passwordField($model,’password_repeat’); ?>
<?php echo $form->error($model,’password_repeat’); ?>
</div>
<?php if(CCaptcha::checkRequirements()): ?>
<div class="row">
<?php echo $form->labelEx($model,’verifyCode’); ?>
<div>
<?php $this->widget(‘CCaptcha’); ?>
<?php echo $form->textField($model,’verifyCode’); ?>
</div>
<div class="hint">Please enter the letters as they are shown in the image above.
<br/>Letters are not case-sensitive.</div>
<?php echo $form->error($model,’verifyCode’); ?>
</div>
<?php endif; ?>
<div class="row buttons">
<?php echo CHtml::submitButton(‘Register’); ?>
</div>
<?php $this->endWidget(); ?>
</div><!– form –>
[/php]
Pepe says
Nice article, but I guess there is one mistake in function generateActivationCode, becouse php sha1 function returns string value so activation code in database should be varchar or return value should be cast to int.
Correct me if I’m wrong 🙂
Pepe says
Up: I noticed now that rules in model are correct, so i was wrong. Mod, please remove my post. But i notticed something else, file SiteController.php line 67 of code: there is no such variable as $email, I guess without changing it to $newUser->email or $model->email will result in error.
Ahmad Ghazali Ahmad Tajuddin says
its ok. nice sharing from you.
VOIP Atlanta says
When I originally commented I clicked the “Notify me when new comments are added” checkbox and now each time a comment is added I get three emails with the same comment.
Is there any way you can remove me from that service?
Bless you!
Meridith says
Where did you get the material to compose this post: Understand Yii Authentication Intermediate | GhazaliTajuddin.com ?
Ahmad Ghazali Ahmad Tajuddin says
I combine from many places for personal use only. Why meridith?