2017-10-20 43 views
0

J'ai un modèle utilisateur qui stocke les utilisateurs dans la base de données. Avec GII, créez un CRUD pour pouvoir enregistrer et mettre à jour les utilisateurs. Le problème est avec le mot de passe. Comment faire pour quand je crée un utilisateur pour charger un mot de passe et quand je le mets à jour si je veux pouvoir le mettre à jour?yii2 utilisateur CRUD créer ou mettre à jour avec mot de passe

Ma table:

CREATE TABLE user ( id int (11) NOT NULL, username varchar (250) NOT NULL, auth_key varchar (32) NOT NULL, password_hash varchar (255) NOT NULL, password_reset_token varchar (255) NOT NULL, email varchar (255) NOT NULL, status smallint (6) NOT NULL, role_id int (11) NOT NULL, created_at date/heure NOT NULL, updated_at date/heure NOT NULL ) MOTEUR = InnoDB DEFAULT CHARSET = latin1;

Ma forme:

<?php 

use yii\helpers\Html; 
use yii\widgets\ActiveForm; 
use yii\helpers\ArrayHelper; 
use app\models\Role; 

/* @var $this yii\web\View */ 
/* @var $model app\models\User */ 
/* @var $form yii\widgets\ActiveForm */ 
?> 

<div class="user-form"> 

    <?php $form = ActiveForm::begin(); ?> 

    <?= $form->field($model, 'username')->textInput(['maxlength' => true]) ?> 

    <?= $form->field($model, 'email')->textInput(['maxlength' => true]) ?> 

    <?= $form->field($model, 'role_id')->dropDownList(
      ArrayHelper::map(Role::find()->all(),'id','description'), 
      ['prompt'=> Yii::t('app', 'Select...')] 
    )?> 

    <?= $form->field($model, 'newPassword')->passwordInput(['placeholder' => Yii::t('app', 'Password'), 'value' => ''])->label('') ?> 

    <?= $form->field($model, 'status')->checkBox(['label' => Yii::t('app', 'Status'), 'selected' => $model->status])?> 

    <div class="form-group"> 
     <?= Html::submitButton($model->isNewRecord ? Yii::t('app', 'Create') : Yii::t('app', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?> 
    </div> 

    <?php ActiveForm::end(); ?> 

</div> 

Mon contrôleur:

<?php 

namespace app\controllers; 

use Yii; 
use app\models\User; 
use app\models\Permission; 
use app\models\search\UserSearch; 
use yii\web\Controller; 
use yii\web\NotFoundHttpException; 
use yii\filters\VerbFilter; 

/** 
* UserController implements the CRUD actions for User model. 
*/ 
class UserController extends Controller 
{ 
    /** 
    * @inheritdoc 
    */ 
    public function behaviors() 
    { 
     return [ 
      'access' => [ 
       'class' => \yii\filters\AccessControl::className(), 
       'rules' => [ 
        [ 
         'actions' => ['index','view','update','create','delete'], 
         'allow' => true, 
         'roles' => ['@'], 
         'matchCallback' => function ($rule, $action) { 
          return Permission::hasAllowed($action->controller->id,$action->id); 
         } 
        ],     
       ], 
      ],  
      'verbs' => [ 
       'class' => VerbFilter::className(), 
       'actions' => [ 
        'delete' => ['POST'], 
       ], 
      ], 
     ]; 
    } 

    /** 
    * Lists all User models. 
    * @return mixed 
    */ 
    public function actionIndex() 
    { 
     $searchModel = new UserSearch(); 
     $dataProvider = $searchModel->search(Yii::$app->request->queryParams); 

     return $this->render('index', [ 
      'searchModel' => $searchModel, 
      'dataProvider' => $dataProvider, 
     ]); 
    } 

    /** 
    * Displays a single User model. 
    * @param integer $id 
    * @return mixed 
    */ 
    public function actionView($id) 
    { 
     return $this->render('view', [ 
      'model' => $this->findModel($id), 
     ]); 
    } 

    /** 
    * Creates a new User model. 
    * If creation is successful, the browser will be redirected to the 'view' page. 
    * @return mixed 
    */ 
    public function actionCreate() 
    { 
     $model = new User(); 

     if ($model->load(Yii::$app->request->post()) && $model->save()) { 
      Yii::$app->session->setFlash('success', Yii::t('app', 'Successful create!'));    
      return $this->redirect(['view', 'id' => $model->id]); 
     } else { 
      return $this->render('create', [ 
       'model' => $model, 
      ]); 
     } 
    } 

    /** 
    * Updates an existing User model. 
    * If update is successful, the browser will be redirected to the 'view' page. 
    * @param integer $id 
    * @return mixed 
    */ 
    public function actionUpdate($id) 
    { 
     $model = $this->findModel($id); 

     if ($model->load(Yii::$app->request->post()) && $model->save()) { 
      Yii::$app->session->setFlash('success', Yii::t('app', 'Successful update!'));    
      return $this->redirect(['view', 'id' => $model->id]); 
     } else { 
      return $this->render('update', [ 
       'model' => $model, 
      ]); 
     } 
    } 

    /** 
    * Deletes an existing User model. 
    * If deletion is successful, the browser will be redirected to the 'index' page. 
    * @param integer $id 
    * @return mixed 
    */ 
    public function actionDelete($id) 
    { 
     $this->findModel($id)->delete(); 

     return $this->redirect(['index']); 
    } 

    /** 
    * Finds the User model based on its primary key value. 
    * If the model is not found, a 404 HTTP exception will be thrown. 
    * @param integer $id 
    * @return User the loaded model 
    * @throws NotFoundHttpException if the model cannot be found 
    */ 
    protected function findModel($id) 
    { 
     if (($model = User::findOne($id)) !== null) { 
      return $model; 
     } else { 
      throw new NotFoundHttpException('The requested page does not exist.'); 
     } 
    } 
} 

Mon modèle:

<?php 
namespace app\models; 

use Yii; 
use yii\base\NotSupportedException; 
use yii\behaviors\TimestampBehavior; 
use yii\db\ActiveRecord; 
use yii\db\Expression; 
use yii\web\IdentityInterface; 

/** 
* User model 
* 
* @property integer $id 
* @property string $username 
* @property string $password_hash 
* @property string $password_reset_token 
* @property string $email 
* @property string $auth_key 
* @property integer $status 
* @property integer $created_at 
* @property integer $updated_at 
* @property string $password write-only password 
*/ 
class User extends ActiveRecord implements IdentityInterface 
{ 
    const STATUS_DELETED = 0; 
    const STATUS_ACTIVE = 1; 

    /** 
    * @inheritdoc 
    */ 
    public static function tableName() 
    { 
     return '{{%user}}'; 
    } 

    /** 
    * @inheritdoc 
    */ 
    /* 
    public function behaviors() 
    { 
     return [ 
      TimestampBehavior::className(), 
     ]; 
    } 
    */ 

    public function behaviors() 
    { 
     return [ 
      'timestamp' => [ 
       'class' => TimestampBehavior::className(), 
       'attributes' => [ 
        ActiveRecord::EVENT_BEFORE_INSERT => ['created_at', 'updated_at'], 
        ActiveRecord::EVENT_BEFORE_UPDATE => ['updated_at'] 
       ], 
       'value' => new Expression('NOW()'), 
      ], 
     ]; 
    } 

    /** 
    * @inheritdoc 
    */ 
    public function rules() 
    { 
     return [ 
      [['status', 'role_id', 'username','email'], 'required'], 
      ['status', 'default', 'value' => self::STATUS_ACTIVE], 
      ['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED]], 
      [['role_id'], 'exist', 'skipOnError' => true, 'targetClass' => Role::className(), 'targetAttribute' => ['role_id' => 'id']], 
     ]; 
    } 

    /** 
    * @inheritdoc 
    */ 
    public static function findIdentity($id) 
    { 
     return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]); 
    } 

    /** 
    * @inheritdoc 
    */ 
    public static function findIdentityByAccessToken($token, $type = null) 
    { 
     throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.'); 
    } 

    /** 
    * Finds user by username 
    * 
    * @param string $username 
    * @return static|null 
    */ 
    public static function findByUsername($username) 
    { 
     return static::findOne(['username' => $username, 'status' => self::STATUS_ACTIVE]); 
    } 

    /** 
    * Finds user by password reset token 
    * 
    * @param string $token password reset token 
    * @return static|null 
    */ 
    public static function findByPasswordResetToken($token) 
    { 
     if (!static::isPasswordResetTokenValid($token)) { 
      return null; 
     } 

     return static::findOne([ 
      'password_reset_token' => $token, 
      'status' => self::STATUS_ACTIVE, 
     ]); 
    } 

    /** 
    * Finds out if password reset token is valid 
    * 
    * @param string $token password reset token 
    * @return bool 
    */ 
    public static function isPasswordResetTokenValid($token) 
    { 
     if (empty($token)) { 
      return false; 
     } 

     $timestamp = (int) substr($token, strrpos($token, '_') + 1); 
     $expire = Yii::$app->params['user.passwordResetTokenExpire']; 
     return $timestamp + $expire >= time(); 
    } 

    /** 
    * @inheritdoc 
    */ 
    public function getId() 
    { 
     return $this->getPrimaryKey(); 
    } 

    /** 
    * @inheritdoc 
    */ 
    public function getAuthKey() 
    { 
     return $this->auth_key; 
    } 

    /** 
    * @inheritdoc 
    */ 
    public function validateAuthKey($authKey) 
    { 
     return $this->getAuthKey() === $authKey; 
    } 

    /** 
    * Validates password 
    * 
    * @param string $password password to validate 
    * @return bool if password provided is valid for current user 
    */ 
    public function validatePassword($password) 
    { 
     return Yii::$app->security->validatePassword($password, $this->password_hash); 
    } 

    /** 
    * Generates password hash from password and sets it to the model 
    * 
    * @param string $password 
    */ 
    public function setPassword($password) 
    { 
     $this->password_hash = Yii::$app->security->generatePasswordHash($password); 
    } 

    /** 
    * Generates "remember me" authentication key 
    */ 
    public function generateAuthKey() 
    { 
     $this->auth_key = Yii::$app->security->generateRandomString(); 
    } 

    /** 
    * Generates new password reset token 
    */ 
    public function generatePasswordResetToken() 
    { 
     $this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time(); 
    } 

    /** 
    * Removes password reset token 
    */ 
    public function removePasswordResetToken() 
    { 
     $this->password_reset_token = null; 
    } 

    public static function isActive() 
    { 
     return Yii::$app->user->identity->status == self::STATUS_ACTIVE; 
    } 

    /** 
    * @return \yii\db\ActiveQuery 
    */ 
    public function getRole() 
    { 
     return $this->hasOne(Role::className(), ['id' => 'role_id']); 
    } 

    /** 
    * @inheritdoc 
    */ 
    public function attributeLabels() 
    { 
     return [ 
      'id' => Yii::t('app', 'ID'), 
      'status' => Yii::t('app', 'Status Active'), 
     ]; 
    } 

} 

Répondre

0

Vous pouvez utiliser l'événement beforeSave dans votre modèle utilisateur

public function beforeSave($insert) { 
     if ($insert) { 
      $this->setPassword($this->password_hash); 
     } else { 
      if (!empty($this->password_hash)) { 
       $this->setPassword($this->password_hash); 
      } else { 
       $this->password_hash = (string) $this->getOldAttribute('password_hash'); 
      } 
     } 
     return parent::beforeSave($insert); 
    } 

et mettre à jour l'action de mise à jour dans votre contrôleur

/** 
    * Updates an existing User model. 
    * If update is successful, the browser will be redirected to the 'view' page. 
    * @param integer $id 
    * @return mixed 
    */ 
    public function actionUpdate($id) 
    { 
     $model = $this->findModel($id); 
     $model->setAttribute('password_hash', null); 
     if ($model->load(Yii::$app->request->post()) && $model->save()) { 
      Yii::$app->session->setFlash('success', Yii::t('app', 'Successful update!'));    
      return $this->redirect(['view', 'id' => $model->id]); 
     } else { 
      return $this->render('update', [ 
       'model' => $model, 
      ]); 
     } 
    } 

et mettre à jour votre champ de vision de formulaire pour

<?= $form->field($model, 'password_hash')->passwordInput(['placeholder' => Yii::t('app', 'Password'), 'value' => ''])->label(false) ?> 

mettre à jour votre modèle utilisateur validations règles

/** 
    * @inheritdoc 
    */ 
    public function rules() 
    { 
     return [ 
      [['status', 'role_id', 'username','email'], 'required'], 
      ['password_hash', 'required', 'on' => 'insert'], 
      ['password_hash', 'string'], 
      ['status', 'default', 'value' => self::STATUS_ACTIVE], 
      ['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED]], 
      [['role_id'], 'exist', 'skipOnError' => true, 'targetClass' => Role::className(), 'targetAttribute' => ['role_id' => 'id']], 
     ]; 
    } 
+0

Dont je besoin d'un changement de voir le formulaire? champ ($ model, 'newPassword') -> passwordInput (['placeholder' => Yii :: t ('app', 'Mot de passe'), 'value' => '']) -> label (' ')?> – user2643472

+0

J'essaye cette solution mais ne met jamais à jour le mot de passe quand le champ n'est pas vide. – user2643472

+0

oui votre formulaire doit avoir champ ($ model, 'password_hash') -> passwordInput (['placeholder' => Yii :: t ('app', 'mot de passe'), 'value' => '']) - > label ('')?> Vous n'avez pas besoin d'introduire un nouveau champ – Nader