From 3a8826938f43d2702f34011b4aef7b3cce991fa2 Mon Sep 17 00:00:00 2001 From: Yaroslav Voitenko Date: Fri, 16 Feb 2018 15:42:17 +0200 Subject: [PATCH 1/7] created registration on the frontend --- app/forms/RegisterForm.php | 70 ++++++++++++++++++++++++++ app/views/auth/login.php | 6 +++ app/views/auth/register.php | 46 +++++++++++++++++ app/web/controllers/AuthController.php | 45 +++++++++++++---- config/routes.php | 13 ++--- 5 files changed, 164 insertions(+), 16 deletions(-) create mode 100644 app/forms/RegisterForm.php create mode 100644 app/views/auth/register.php diff --git a/app/forms/RegisterForm.php b/app/forms/RegisterForm.php new file mode 100644 index 0000000..e8ddf73 --- /dev/null +++ b/app/forms/RegisterForm.php @@ -0,0 +1,70 @@ + User::className()], + ['passwordRepeat', 'compare', 'compareAttribute' => 'password'], + ]; + } + + /** + * @return array customized attribute labels + */ + public function attributeLabels() + { + return [ + 'passwordRepeat' => 'Repeat Password', + ]; + } + + /** + * Registers a user + * + * @return bool whether the model passes validation + */ + public function register() + { + if ($this->validate()) { + $user = new User(); + $user->email = $user->username = $this->email; + $user->first_name = $this->firstName; + $user->last_name = $this->lastName; + + $user->setPassword($this->password); + $user->generateAuthKey(); + + if (!$user->save()) { + $this->addErrors($user->errors); + + return false; + } + + return true; + } + + return false; + } +} \ No newline at end of file diff --git a/app/views/auth/login.php b/app/views/auth/login.php index a70a473..c9689b6 100755 --- a/app/views/auth/login.php +++ b/app/views/auth/login.php @@ -40,6 +40,12 @@ + +
+
+

Don't have an account?

+
+
You may login with admin/admin or demo/demo.
diff --git a/app/views/auth/register.php b/app/views/auth/register.php new file mode 100644 index 0000000..b379944 --- /dev/null +++ b/app/views/auth/register.php @@ -0,0 +1,46 @@ +title = 'Register'; +$this->params['breadcrumbs'][] = $this->title; + +?> +
+

title) ?>

+ +

Please fill out the following fields to login:

+ + 'register-form', + 'layout' => 'horizontal', + 'fieldConfig' => [ + 'template' => "{label}\n
{input}
\n
{error}
", + 'labelOptions' => ['class' => 'col-lg-1 control-label'], + ], + ]); ?> + + field($model, 'email')->textInput([ + 'autofocus' => true, + 'type' => 'email', + ]) ?> + field($model, 'firstName')->textInput() ?> + field($model, 'lastName')->textInput() ?> + field($model, 'password')->passwordInput() ?> + field($model, 'passwordRepeat')->passwordInput() ?> + +
+
+ 'btn btn-primary']) ?> +
+
+ + + +
+
+

Already have an account?

+
+
+
\ No newline at end of file diff --git a/app/web/controllers/AuthController.php b/app/web/controllers/AuthController.php index 75d6148..3e5380f 100755 --- a/app/web/controllers/AuthController.php +++ b/app/web/controllers/AuthController.php @@ -2,12 +2,12 @@ namespace app\web\controllers; +use app\forms\LoginForm; +use app\forms\RegisterForm; use Yii; use yii\filters\AccessControl; -use yii\web\Response; use yii\filters\VerbFilter; -use app\forms\LoginForm; -use app\forms\ContactForm; +use yii\web\Response; class AuthController extends Controller { @@ -36,7 +36,7 @@ public function behaviors() ], ]; } - + /** * Login action. * @@ -44,21 +44,22 @@ public function behaviors() */ public function actionLogin() { - if ( ! Yii::$app->user->isGuest) { + if (!Yii::$app->user->isGuest) { return $this->goHome(); } - + $model = new LoginForm(); if ($model->load(Yii::$app->request->post()) && $model->login()) { $model->assignAuthenticatedRole(); + return $this->goBack(); } - + return $this->render('login', [ 'model' => $model, ]); } - + /** * Logout action. * @@ -67,8 +68,32 @@ public function actionLogin() public function actionLogout() { Yii::$app->user->logout(); - + return $this->goHome(); } - + + /** + * Register action. + * + * @return string|Response + */ + public function actionRegister() + { + if (!Yii::$app->user->isGuest) { + return $this->goHome(); + } + + $model = new RegisterForm(); + + if ($model->load(Yii::$app->request->post()) && $model->register()) { + Yii::$app->session->addFlash('success', 'You have been successfully registered'); + + return $this->goBack(); + } + + return $this->render('register', [ + 'model' => $model, + ]); + } + } diff --git a/config/routes.php b/config/routes.php index 20b2798..558251d 100755 --- a/config/routes.php +++ b/config/routes.php @@ -1,15 +1,16 @@ 'site/index', - 'login' => 'auth/login', + '/' => 'site/index', + 'login' => 'auth/login', + 'register' => 'auth/register', 'password/forgot' => 'auth/password-request', 'password/update' => 'auth/password-update', - 'logout' => 'site/logout', - + 'logout' => 'site/logout', + '//' => '/', - '/' => '/', - + '/' => '/', + //'admin/permissions/' => 'admin/rbac/permissions/', ]; \ No newline at end of file From 8ac3c18794dd4079f987111024cdcbe1742ed12e Mon Sep 17 00:00:00 2001 From: Yaroslav Voitenko Date: Fri, 16 Feb 2018 15:44:18 +0200 Subject: [PATCH 2/7] updated changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cbc506f..3859835 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ CHANGELOG for Yii2 STARTER PROJECT TEMPLATE *should be replaced with real project changelog later* +v0.8.7 +--------------------- +* Issue #13: Registration is absent + v0.8.6 --------------------- * Fixed unit/functional tests From 5afc8b32ec6fec79578fbd188331978e68b89ade Mon Sep 17 00:00:00 2001 From: Yaroslav Voitenko Date: Fri, 16 Feb 2018 18:07:19 +0200 Subject: [PATCH 3/7] created password restore --- CHANGELOG.md | 4 ++ app/forms/PasswordRequestForm.php | 70 ++++++++++++++++++++++ app/forms/PasswordUpdateForm.php | 54 +++++++++++++++++ app/views/auth/login.php | 20 ++++--- app/views/auth/password-request.php | 37 ++++++++++++ app/views/auth/password-update.php | 37 ++++++++++++ app/web/controllers/AuthController.php | 80 ++++++++++++++++++++++---- config/routes.php | 2 +- 8 files changed, 286 insertions(+), 18 deletions(-) create mode 100644 app/forms/PasswordRequestForm.php create mode 100644 app/forms/PasswordUpdateForm.php create mode 100644 app/views/auth/password-request.php create mode 100644 app/views/auth/password-update.php diff --git a/CHANGELOG.md b/CHANGELOG.md index cbc506f..ad0fad6 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ CHANGELOG for Yii2 STARTER PROJECT TEMPLATE *should be replaced with real project changelog later* +v0.8.7 +--------------------- +* Issue #14: Reset password + v0.8.6 --------------------- * Fixed unit/functional tests diff --git a/app/forms/PasswordRequestForm.php b/app/forms/PasswordRequestForm.php new file mode 100644 index 0000000..54f62c1 --- /dev/null +++ b/app/forms/PasswordRequestForm.php @@ -0,0 +1,70 @@ +validate()) { + $user = User::findByUsername($this->email); + + if (empty($user)) { + return true; //needed for security reasons + } + + $user->generatePasswordResetToken(); + $user->save(); + + Yii::$app->mailer->compose() + ->setTo($user->email) + ->setFrom(settings()->app->systemFriendlyEmail) + ->setSubject('Restore your password on ' . Yii::$app->name) + ->setTextBody($this->getMessageBody($user->password_reset_token)) + ->send(); + + return true; + } + + return false; + } + + /** + * Render a message with reset token + * + * @param string $resetToken + * + * @return string + */ + protected function getMessageBody($resetToken) + { + return 'To restore your password, please, follow this link ' . Url::to([ + 'auth/password-update', + 'token' => $resetToken, + ], true); + } +} \ No newline at end of file diff --git a/app/forms/PasswordUpdateForm.php b/app/forms/PasswordUpdateForm.php new file mode 100644 index 0000000..c721ce3 --- /dev/null +++ b/app/forms/PasswordUpdateForm.php @@ -0,0 +1,54 @@ + 'newPassword'], + ]; + } + + /** + * Updates user's password if $resetToken is valid + * + * @return bool + */ + public function update() + { + $user = User::findByPasswordResetToken($this->resetToken); + + if (empty($user)) { + return false; + } + + if ($this->validate()) { + $user->setPassword($this->newPassword); + $user->removePasswordResetToken(); + + if (!$user->save()) { + $this->addErrors($user->errors); + + return false; + } + + return true; + } + + return false; + } +} \ No newline at end of file diff --git a/app/views/auth/login.php b/app/views/auth/login.php index a70a473..e465f83 100755 --- a/app/views/auth/login.php +++ b/app/views/auth/login.php @@ -5,17 +5,17 @@ /* @var $model app\forms\LoginForm */ -use yii\helpers\Html; use yii\bootstrap\ActiveForm; +use yii\helpers\Html; -$this->title = 'Login'; +$this->title = 'Login'; $this->params['breadcrumbs'][] = $this->title; ?>
- + +
+
+

Forgot your password?

+
+
+
You may login with admin/admin or demo/demo.
To modify the username/password, please check out the code app\models\User::$users. diff --git a/app/views/auth/password-request.php b/app/views/auth/password-request.php new file mode 100644 index 0000000..0c1822c --- /dev/null +++ b/app/views/auth/password-request.php @@ -0,0 +1,37 @@ +title = 'Forgot Password'; +$this->params['breadcrumbs'][] = $this->title; +?> + +
+

title) ?>

+

Enter your email to restore the password:

+ + 'forgot-password-form', + 'layout' => 'horizontal', + 'fieldConfig' => [ + 'template' => "{label}\n
{input}
\n
{error}
", + 'labelOptions' => ['class' => 'col-lg-1 control-label'], + ], + ]); ?> + + field($model, 'email')->textInput(['autofocus' => true]) ?> + +
+
+ 'btn btn-primary', 'name' => 'login-button']) ?> +
+
+ + +
+ diff --git a/app/views/auth/password-update.php b/app/views/auth/password-update.php new file mode 100644 index 0000000..057c7d6 --- /dev/null +++ b/app/views/auth/password-update.php @@ -0,0 +1,37 @@ +title = 'Update Password'; +$this->params['breadcrumbs'][] = $this->title; +?> + +
+

title) ?>

+ + 'update-password-form', + 'layout' => 'horizontal', + 'fieldConfig' => [ + 'template' => "{label}\n
{input}
\n
{error}
", + 'labelOptions' => ['class' => 'col-lg-1 control-label'], + ], + ]); ?> + + field($model, 'newPassword')->passwordInput(['autofocus' => true]) ?> + field($model, 'newPasswordRepeat')->passwordInput() ?> + +
+
+ 'btn btn-primary', 'name' => 'login-button']) ?> +
+
+ + +
+ diff --git a/app/web/controllers/AuthController.php b/app/web/controllers/AuthController.php index 75d6148..e373fa7 100755 --- a/app/web/controllers/AuthController.php +++ b/app/web/controllers/AuthController.php @@ -2,12 +2,15 @@ namespace app\web\controllers; +use app\forms\LoginForm; +use app\forms\PasswordRequestForm; +use app\forms\PasswordUpdateForm; +use app\models\User; use Yii; use yii\filters\AccessControl; -use yii\web\Response; use yii\filters\VerbFilter; -use app\forms\LoginForm; -use app\forms\ContactForm; +use yii\web\NotFoundHttpException; +use yii\web\Response; class AuthController extends Controller { @@ -36,7 +39,7 @@ public function behaviors() ], ]; } - + /** * Login action. * @@ -44,21 +47,22 @@ public function behaviors() */ public function actionLogin() { - if ( ! Yii::$app->user->isGuest) { + if (!Yii::$app->user->isGuest) { return $this->goHome(); } - + $model = new LoginForm(); if ($model->load(Yii::$app->request->post()) && $model->login()) { $model->assignAuthenticatedRole(); + return $this->goBack(); } - + return $this->render('login', [ 'model' => $model, ]); } - + /** * Logout action. * @@ -67,8 +71,64 @@ public function actionLogin() public function actionLogout() { Yii::$app->user->logout(); - + return $this->goHome(); } - + + /** + * Password request action + * + * @return string|Response + */ + public function actionPasswordRequest() + { + if (!Yii::$app->user->isGuest) { + return $this->goHome(); + } + + $model = new PasswordRequestForm(); + + if ($model->load(Yii::$app->request->post()) && $model->request()) { + Yii::$app->session->addFlash('success', 'If the email address is registered in the system, we would send a letter there shortly.'); + + return $this->goBack(); + } + + return $this->render('password-request', [ + 'model' => $model, + ]); + } + + /** + * Password update action + * + * @param string $token + * + * @return string|Response + * @throws NotFoundHttpException + */ + public function actionPasswordUpdate($token) + { + if (!Yii::$app->user->isGuest) { + return $this->goHome(); + } + + if (!User::isPasswordResetTokenValid($token)) { + throw new NotFoundHttpException('Page not found.'); + } + + $model = new PasswordUpdateForm(); + $model->resetToken = $token; + + if ($model->load(Yii::$app->request->post()) && $model->update()) { + Yii::$app->session->addFlash('success', 'Your password has been successfully updated!'); + + return $this->goBack(); + } + + return $this->render('password-update', [ + 'model' => $model, + ]); + } + } diff --git a/config/routes.php b/config/routes.php index 20b2798..963f026 100755 --- a/config/routes.php +++ b/config/routes.php @@ -4,7 +4,7 @@ '/' => 'site/index', 'login' => 'auth/login', 'password/forgot' => 'auth/password-request', - 'password/update' => 'auth/password-update', + 'password/update/' => 'auth/password-update', 'logout' => 'site/logout', '//' => '/', From 4e915fd48fda5177e28367d2b502207dad3b7fe4 Mon Sep 17 00:00:00 2001 From: Yaroslav Voitenko Date: Fri, 16 Feb 2018 18:10:26 +0200 Subject: [PATCH 4/7] fixed code style in views --- app/views/auth/login.php | 2 +- app/views/auth/register.php | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/app/views/auth/login.php b/app/views/auth/login.php index c9689b6..c650f00 100755 --- a/app/views/auth/login.php +++ b/app/views/auth/login.php @@ -43,7 +43,7 @@
-

Don't have an account?

+

Don't have an account?

diff --git a/app/views/auth/register.php b/app/views/auth/register.php index b379944..1b72071 100644 --- a/app/views/auth/register.php +++ b/app/views/auth/register.php @@ -1,5 +1,10 @@
-

Already have an account?

+

Already have an account?

\ No newline at end of file From d5880dfe5e4742bdc48077f48f9103a013b5ab31 Mon Sep 17 00:00:00 2001 From: Yaroslav Voitenko Date: Fri, 16 Feb 2018 19:11:49 +0200 Subject: [PATCH 5/7] added role seclect box in user edit form --- app/models/User.php | 82 +++++++++++-------- .../admin/controllers/UsersController.php | 39 +++++---- app/modules/admin/forms/UserForm.php | 22 +++-- app/modules/admin/views/users/_form.php | 38 +++++---- app/modules/admin/views/users/update.php | 11 ++- 5 files changed, 110 insertions(+), 82 deletions(-) diff --git a/app/models/User.php b/app/models/User.php index 24367ef..3247dcf 100755 --- a/app/models/User.php +++ b/app/models/User.php @@ -11,25 +11,25 @@ * User model * * @property integer $id - * @property string $username - * @property string $password_hash - * @property string $password_reset_token - * @property string $email - * @property string $first_name - * @property string $last_name - * @property string $auth_key + * @property string $username + * @property string $password_hash + * @property string $password_reset_token + * @property string $email + * @property string $first_name + * @property string $last_name + * @property string $auth_key * @property integer $status * @property integer $created_at * @property integer $updated_at - * @property string $password write-only password + * @property string $password write-only password */ class User extends ActiveRecord implements IdentityInterface { use WithStatus; - + const STATUS_ACTIVE = 10; const STATUS_BLOCKED = 0; - + /** * @inheritdoc */ @@ -37,7 +37,7 @@ public static function tableName() { return '{{%user}}'; } - + /** * @inheritdoc */ @@ -52,7 +52,7 @@ public function rules() ['email', 'email'], ]; } - + /** * User full name * (as first/last name) @@ -63,7 +63,7 @@ public function getFullName() { return "{$this->first_name} {$this->last_name}"; } - + /** * List of user status aliases * @@ -72,11 +72,21 @@ public function getFullName() public static function getStatusesList() { return [ - static::STATUS_ACTIVE => 'Active', + static::STATUS_ACTIVE => 'Active', static::STATUS_BLOCKED => 'Blocked', ]; } - + + /** + * @return array + */ + public static function getRolesList() + { + $roles = array_keys(Yii::$app->authManager->getRoles()); + + return array_combine($roles, $roles); + } + /** * Assign a role to user * @@ -86,14 +96,16 @@ public static function getStatusesList() */ public function assignRole($role) { - if (! Yii::$app->authManager->checkAccess($this->id, $role)) { + if (!Yii::$app->authManager->checkAccess($this->id, $role)) { $authRole = Yii::$app->authManager->getRole($role); Yii::$app->authManager->assign($authRole, $this->id); + return true; } + return false; } - + /** * @inheritdoc */ @@ -101,7 +113,7 @@ public static function findIdentity($id) { return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]); } - + /** * @inheritdoc */ @@ -109,7 +121,7 @@ public static function findIdentityByAccessToken($token, $type = null) { throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.'); } - + /** * Finds user by username * @@ -121,7 +133,7 @@ public static function findByUsername($username) { return static::findOne(['username' => $username, 'status' => self::STATUS_ACTIVE]); } - + /** * Finds user by password reset token * @@ -131,16 +143,16 @@ public static function findByUsername($username) */ public static function findByPasswordResetToken($token) { - if ( ! static::isPasswordResetTokenValid($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 * @@ -153,13 +165,13 @@ public static function isPasswordResetTokenValid($token) if (empty($token)) { return false; } - + $timestamp = (int)substr($token, strrpos($token, '_') + 1); - $expire = settings()->app->passwordResetToken; - + $expire = settings()->app->passwordResetToken; + return $timestamp + $expire >= time(); } - + /** * @inheritdoc */ @@ -167,7 +179,7 @@ public function getId() { return $this->getPrimaryKey(); } - + /** * @inheritdoc */ @@ -175,7 +187,7 @@ public function getAuthKey() { return $this->auth_key; } - + /** * @inheritdoc */ @@ -183,7 +195,7 @@ public function validateAuthKey($authKey) { return $this->getAuthKey() === $authKey; } - + /** * Validates password * @@ -195,7 +207,7 @@ public function validatePassword($password) { return Yii::$app->security->validatePassword($password, $this->password_hash); } - + /** * Generates password hash from password and sets it to the model * @@ -205,7 +217,7 @@ public function setPassword($password) { $this->password_hash = Yii::$app->security->generatePasswordHash($password); } - + /** * Generates "remember me" authentication key */ @@ -213,7 +225,7 @@ public function generateAuthKey() { $this->auth_key = Yii::$app->security->generateRandomString(); } - + /** * Generates new password reset token */ @@ -221,7 +233,7 @@ public function generatePasswordResetToken() { $this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time(); } - + /** * Removes password reset token */ @@ -229,5 +241,5 @@ public function removePasswordResetToken() { $this->password_reset_token = null; } - + } diff --git a/app/modules/admin/controllers/UsersController.php b/app/modules/admin/controllers/UsersController.php index f8fac0b..8408125 100755 --- a/app/modules/admin/controllers/UsersController.php +++ b/app/modules/admin/controllers/UsersController.php @@ -2,11 +2,11 @@ namespace app\modules\admin\controllers; -use Yii; -use app\modules\admin\forms\UserForm; -use app\traits\controllers\FindModelOrFail; use app\models\User; +use app\modules\admin\forms\UserForm; use app\modules\admin\models\UserSearch; +use app\traits\controllers\FindModelOrFail; +use Yii; use yii\filters\VerbFilter; /** @@ -15,7 +15,7 @@ class UsersController extends Controller { use FindModelOrFail; - + /** * @inheritdoc */ @@ -24,7 +24,7 @@ public function init() parent::init(); $this->modelClass = UserForm::className(); } - + /** * @inheritdoc */ @@ -39,7 +39,7 @@ public function behaviors() ], ]; } - + /** * Lists all User models. * @@ -47,15 +47,15 @@ public function behaviors() */ public function actionIndex() { - $searchModel = new UserSearch(); + $searchModel = new UserSearch(); $dataProvider = $searchModel->search(Yii::$app->request->queryParams); - + return $this->render('index', [ 'searchModel' => $searchModel, 'dataProvider' => $dataProvider, ]); } - + /** * Creates a new User model. * If creation is successful, the browser will be redirected to the 'view' page. @@ -65,18 +65,18 @@ public function actionIndex() public function actionCreate() { $model = new UserForm(); - + $model->on(User::EVENT_BEFORE_INSERT, [$model, 'generateAuthKey']); - + if ($model->load(Yii::$app->request->post()) && $model->save()) { return $this->redirect(['update', 'id' => $model->id]); } - + return $this->render('create', [ 'model' => $model, ]); } - + /** * Updates an existing User model. * If update is successful, the browser will be redirected to the 'view' page. @@ -87,17 +87,20 @@ public function actionCreate() */ public function actionUpdate($id) { + /** + * @var UserForm $model + */ $model = $this->findModel($id); - + if ($model->load(Yii::$app->request->post()) && $model->save()) { return $this->redirect(['update', 'id' => $model->id]); } - + return $this->render('update', [ 'model' => $model, ]); } - + /** * Deletes an existing User model. * If deletion is successful, the browser will be redirected to the 'index' page. @@ -109,8 +112,8 @@ public function actionUpdate($id) public function actionDelete($id) { $this->findModel($id)->delete(); - + return $this->redirect(['index']); } - + } diff --git a/app/modules/admin/forms/UserForm.php b/app/modules/admin/forms/UserForm.php index 53a804d..f12fd9b 100755 --- a/app/modules/admin/forms/UserForm.php +++ b/app/modules/admin/forms/UserForm.php @@ -3,6 +3,7 @@ namespace app\modules\admin\forms; use app\models\User; +use Yii; class UserForm extends User { @@ -10,12 +11,17 @@ class UserForm extends User * @var string */ public $password; - + /** * @var string */ public $password_repeat; - + + /** + * @var string + */ + public $role; + /** * @inheritdoc * @return array @@ -23,11 +29,12 @@ class UserForm extends User public function rules() { return array_merge(parent::rules(), [ - ['password', 'compare'], - ['password_repeat', 'safe'], + ['password', 'safe'], + ['password_repeat', 'compare', 'compareAttribute' => 'password'], + ['role', 'in', 'range' => array_keys(static::getRolesList())], ]); } - + /** * @inheritdoc * @return bool @@ -37,6 +44,11 @@ public function beforeSave($insert) if ($this->password) { $this->setPassword($this->password); } + + if ($this->role) { + $this->assignRole($this->role); + } + return parent::beforeSave($insert); } } \ No newline at end of file diff --git a/app/modules/admin/views/users/_form.php b/app/modules/admin/views/users/_form.php index 1c05b50..d5e5475 100755 --- a/app/modules/admin/views/users/_form.php +++ b/app/modules/admin/views/users/_form.php @@ -1,40 +1,42 @@
- + 'horizontal', + 'layout' => 'horizontal', ]); ?>
field($model, 'first_name')->textInput(['maxlength' => true]) ?> - + field($model, 'last_name')->textInput(['maxlength' => true]) ?> - + field($model, 'username')->textInput(['maxlength' => true]) ?> - + field($model, 'email')->textInput(['maxlength' => true]) ?> - - field($model, 'password_repeat') - ->passwordInput()->label('Password') ?> - - field($model, 'password') - ->passwordInput()->label('Password Repeat') ?> - + + field($model, 'password')->passwordInput() ?> + + field($model, 'password_repeat')->passwordInput() ?> + field($model, 'status')->dropDownList(User::getStatusesList()) ?> + + field($model, 'role')->dropDownList(User::getRolesList()) ?>
- +
diff --git a/app/modules/admin/views/users/update.php b/app/modules/admin/views/users/update.php index a037c08..f2382a9 100755 --- a/app/modules/admin/views/users/update.php +++ b/app/modules/admin/views/users/update.php @@ -1,18 +1,17 @@ title = "Update {$model->fullName}"; +$this->title = "Update {$model->fullName}"; $this->params['breadcrumbs'][] = ['label' => 'Users', 'url' => ['index']]; $this->params['breadcrumbs'][] = ['label' => $model->fullName, 'url' => ['update', 'id' => $model->id]]; -$this->params['heading'] = 'Users'; -$this->params['subheading'] = $model->fullName; +$this->params['heading'] = 'Users'; +$this->params['subheading'] = $model->fullName; ?>
- + render('_form', [ 'model' => $model, ]) ?> From 2f0e1f191ca5c9894036437bbe783321327b3160 Mon Sep 17 00:00:00 2001 From: Yaroslav Voitenko Date: Mon, 19 Feb 2018 11:36:34 +0200 Subject: [PATCH 6/7] refactored password repeat on the user form in the admin panel, added role selector to the form --- app/modules/admin/forms/UserForm.php | 48 +++++++++++++++++++++---- app/modules/admin/views/users/_form.php | 6 ++-- 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/app/modules/admin/forms/UserForm.php b/app/modules/admin/forms/UserForm.php index f12fd9b..6cd579d 100755 --- a/app/modules/admin/forms/UserForm.php +++ b/app/modules/admin/forms/UserForm.php @@ -15,12 +15,12 @@ class UserForm extends User /** * @var string */ - public $password_repeat; + public $passwordRepeat; /** * @var string */ - public $role; + public $roles; /** * @inheritdoc @@ -30,8 +30,16 @@ public function rules() { return array_merge(parent::rules(), [ ['password', 'safe'], - ['password_repeat', 'compare', 'compareAttribute' => 'password'], - ['role', 'in', 'range' => array_keys(static::getRolesList())], + [ + 'passwordRepeat', + 'required', + 'when' => function () { + return !empty($this->password); + }, + 'whenClient' => 'function() { return $.trim($("#userform-password").val()).length || false; }', + ], + ['passwordRepeat', 'compare', 'compareAttribute' => 'password'], + ['roles', 'in', 'range' => array_keys(static::getRolesList()), 'allowArray' => true], ]); } @@ -45,10 +53,36 @@ public function beforeSave($insert) $this->setPassword($this->password); } - if ($this->role) { - $this->assignRole($this->role); - } + $this->updateUserRoles($this->roles); return parent::beforeSave($insert); } + + /** + * @inheritdoc + */ + public function afterFind() + { + $roles = array_keys(Yii::$app->authManager->getRolesByUser($this->id)); + $roles = array_combine($roles, $roles); + $this->roles = $roles; + + parent::afterFind(); + } + + /** + * @param array|string $roles + */ + protected function updateUserRoles($roles) + { + if (empty($roles)) { + return; + } + + Yii::$app->authManager->revokeAll($this->id); + + foreach ($roles as $role) { + $this->assignRole($role); + } + } } \ No newline at end of file diff --git a/app/modules/admin/views/users/_form.php b/app/modules/admin/views/users/_form.php index d5e5475..6280664 100755 --- a/app/modules/admin/views/users/_form.php +++ b/app/modules/admin/views/users/_form.php @@ -28,11 +28,13 @@ field($model, 'password')->passwordInput() ?> - field($model, 'password_repeat')->passwordInput() ?> + field($model, 'passwordRepeat')->passwordInput() ?> field($model, 'status')->dropDownList(User::getStatusesList()) ?> - field($model, 'role')->dropDownList(User::getRolesList()) ?> + field($model, 'roles')->dropDownList(User::getRolesList(), [ + 'multiple' => 'multiple', + ]) ?>