Rabu, 09 Desember 2015

Membuat User Login di YII dengan level

Bagaimana cara membuat user login menggunakan database? Begini caranya:

1. Buat tabel user

CREATE TABLE IF NOT EXISTS `user` (
 `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
 `username` varchar(100) NOT NULL,
 `password` varchar(200) NOT NULL,
 `level` tinyint(1) NOT NULL DEFAULT '0',
 PRIMARY KEY (`id`),
 UNIQUE KEY `username_UNIQUE` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


2. Buat model dan CRUD untuk tabel user menggunakan Yii.

3. Buka file _form.php pada /protected/views/user/_form.php. Hapus field untuk password, dan tambahkan field untuk password, password_repeat.

<div class="row">
 <?php echo $form->labelEx($model,'username'); ?>
 <?php echo $form->textField($model,'username',array('size'=>20,'maxlength'=>64)); ?>
 <?php echo $form->error($model,'username'); ?>
 </div>
<div class="row">
 <?php echo $form->labelEx($model,'password'); ?>
 <?php echo $form->passwordField($model,'password',array('size'=>20,'maxlength'=>64)); ?>
 <?php echo $form->error($model,'password'); ?>
 </div>
<div class="row">
 <?php echo $form->labelEx($model,'password_repeat'); ?>
 <?php echo $form->passwordField($model,'password_repeat',array('size'=>20,'maxlength'=>64)); ?>
 <?php echo $form->error($model,'password_repeat'); ?>
 </div>
<div class="row">
 <?php echo $form->labelEx($model,'level'); ?>
 <?php echo $form->dropDownList($model,'level', Yii::app()->user->getUserLevelsList(), array('empty'=>'-- Pilih Level --')); ?> //getUserLevelsList() berada di /protected/components/EWebUser.php
 <?php echo $form->error($model,'level'); ?>
 </div>


4. Buka file User.php pada /protected/models/User.php.

tambah variabel untuk password dan password_repeat

class User extends CActiveRecord
{
 public $password;
 public $password_repeat;



rules()

public function rules()
{
 // NOTE: you should only define rules for those attributes that
 // will receive user inputs.
 return array(
 array('username', 'required'),
 array('username', 'unique'),
 array('username', 'length', 'min'=>3, 'max'=>40),
 array('password, password_repeat', 'required', 'on' => 'passwordset'),
 array('password', 'length', 'min'=>8, 'max'=>40, 'on' => 'passwordset'),
 array('password', 'compare', 'compareAttribute' => 'password_repeat'),
 array('username, password, password_repeat', 'safe'),
 array('level', 'numerical', 'integerOnly'=>true),
 // The following rule is used by search().
 // @todo Please remove those attributes that should not be searched.
 array('username, level', 'safe', 'on'=>'search'),
 );
}



attributeLabels()

public function attributeLabels()
{
 return array(
   'id' => 'ID',
   'username' => 'Username',
   'password' => 'Password',
   'password_repeat' => 'Password Repeat',
   'level' => 'Level',
 );

}

5. Buka file UserIdentity.php di /protected/components/UserIdentity.php.

<?php
class UserIdentity extends CUserIdentity
{
 private $_id;
 private $level;

 /**
 * Authenticates a user.
 * @return boolean whether authentication succeeds.
 */
 public function authenticate()
 {
 $username = strtolower($this->username);
 $user = User::model()->find('LOWER(username)=?', array($username));

 if($user===null)
   $this->errorCode=self::ERROR_USERNAME_INVALID;

 else if(!$user->check($this->password))
   $this->errorCode = self::ERROR_PASSWORD_INVALID;

 else{
   // successful login
   $this->_id = $user->id;
   $this->username = $user->username;
   $this->setState('level', $user->level); //untuk memanggil level di database menggunakan EWebUser.php nanti
   $this->errorCode = self::ERROR_NONE;
 }
 return $this->errorCode == self::ERROR_NONE;
 }

 public function getId()
 {
   return $this->_id;
 }
}


6. Buka file EWebUser.php di /protected/components/EWebUser.php.

<?php
class EWebUser extends CWebUser
{
 private $_userTable = array
 (
   0=>'Member',
   1=>'Moderator',
   8=>'Admin',
   9=>'Owner'
 );

 protected $_model;

function isAdmin()
 {
 //Access this via Yii::app()->user->isAdmin()

   return (Yii::app()->user->isGuest) ? FALSE : $this->level == 8;
 }

 public function isSuperadmin()
 {
 //Access this via Yii::app()->user->isSuperadmin()
   return (Yii::app()->user->isGuest) ? FALSE : $this->level == 9;
 }

 public function canAccess($minimumLevel)
 {
 //Access this via Yii::app()->user->canAccess(9)
   return (Yii::app()->user->isGuest) ? FALSE : $this->level >= $minimumLevel;
 }

 public function getRoleName()
 {
 //Access this via Yii::app()->user->roleName()
   return (Yii::app()->user->isGuest) ? '' : $this->getUserLabel($this->level);
 }

 public function getUserLabel($level)
 {
 //Use this for example as a column in CGridView.columns:
 //
 //array('value'=>'Yii::app()->user->getUserLabel($data->level)'),
   return $this->_userTable[$level];
 }

 public function getUserLevelsList()
 {
 //Access this via Yii::app()->user->getUserLevelsList()
   return $this->_userTable;
 }
}
?>


7. Buka file main.php di /protected/config/main.php. Tambahkan class untuk EWebUser di components.

// application components
'components'=>array(
   'user'=>array(
   // enable cookie-based authentication
   'allowAutoLogin'=>true,
   'class'=>'application.components.EWebUser',
 ),


8. Buka file User.php lagi, untuk membuat hash.

hash()

/**
 * Using the crypt library that comes with PHP and providing no salt value,
 * so that it is randomly generated by the library.
 */
 public function hash($value)
 {
   return crypt($value);
 }



beforeSave()

/**
 * We need to call the encryption function whenever we store a password,
 * – on create and on update –
 * so we will overload the beforeSave function to do the hashing.
 */
protected function beforeSave()
{
 if (parent::beforeSave()) {
   if (!empty($this->password))
     $this->password = $this->hash($this->password);

   /* contoh kalau ada tgl_masuk dan tgl keluar
   if ($this->isNewRecord)
     $this->tgl_masuk = new CDbExpression('NOW()');

   $this->tgl_update = new CDbExpression('NOW()');
   */

   return true;
 }
 return false;

}

9. Buka file UserController.php di /protected/controllers/UserController.php.

actionCreate()

public function actionCreate()
 {
   $model=new User('passwordset'); //scenario passwordset digunakan pada rules() di model User.php seperti 'on'=>'passwordset'
   // Uncomment the following line if AJAX validation is needed
   // $this->performAjaxValidation($model);
   if(isset($_POST['User']))
   {
     $model->attributes=$_POST['User'];
     if($model->save())
        $this->redirect(array('view','id'=>$model->id));
   }
   $this->render('create',array(
     'model'=>$model,
   ));
 }




actionUpdate()

public function actionUpdate($id)
{
   $model=$this->loadModel($id);
  // Uncomment the following line if AJAX validation is needed
  // $this->performAjaxValidation($model);
  if(isset($_POST['User']))
   {
     $model->attributes=$_POST['User'];

     // We only want to apply the scenario when a password field has been entered,
     // so set the scenario on the model conditionally.
     if ($model->password || $model->password_repeat)
       $model->scenario = 'passwordset';

     if($model->save())
       $this->redirect(array('view','id'=>$model->id));
   }
  $this->render('update',array(
   'model'=>$model,
  ));
}

10. Buka User.php dan tambahkan fungsi check agar pada saat login akan dicek hashnya.

/**
 * For logging in, function to check a password value against the hashed value.
 */
public function check($value)
{
 $new_hash = crypt($value, $this->password);

 if ($new_hash == $this->password) {
   return true;
 }
 return false;
}


Selamat Mencoba dan Semoga Bermanfaat...