├── ConsoleModule.php ├── actions ├── LogoutAction.php ├── Action.php ├── LoginAction.php ├── SignupAction.php ├── PasswordResetAction.php └── RequestPasswordResetAction.php ├── migrations ├── m161109_112016_rename_user_table.php ├── m170608_141511_rename_columns.php └── m150828_085134_init_user_tables.php ├── models ├── enums │ └── UserStatus.php ├── ResetPasswordForm.php ├── PasswordResetRequestForm.php ├── SignupForm.php ├── LoginForm.php └── UserModel.php ├── events ├── FormEvent.php └── CreateUserEvent.php ├── .php_cs ├── traits └── EventTrait.php ├── views ├── resetPassword.php ├── requestPasswordResetToken.php ├── signup.php └── login.php ├── LICENSE.md ├── composer.json ├── commands ├── UpdatePasswordController.php ├── DeleteController.php ├── CreateController.php └── RoleController.php ├── messages ├── config.php ├── en │ └── yii2mod.user.php ├── uk │ └── yii2mod.user.php └── ru │ └── yii2mod.user.php └── README.md /ConsoleModule.php: -------------------------------------------------------------------------------- 1 | user->logout(); 22 | 23 | return $this->redirectTo(Yii::$app->getHomeUrl()); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /migrations/m161109_112016_rename_user_table.php: -------------------------------------------------------------------------------- 1 | db->schema->getTableSchema('user') === null) { 10 | $this->renameTable('{{%User}}', '{{%user}}'); 11 | } 12 | } 13 | 14 | public function down() 15 | { 16 | if (Yii::$app->db->schema->getTableSchema('User') === null) { 17 | $this->renameTable('{{%user}}', '{{%User}}'); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /models/enums/UserStatus.php: -------------------------------------------------------------------------------- 1 | 'Active', 27 | self::DELETED => 'Deleted', 28 | ]; 29 | } 30 | -------------------------------------------------------------------------------- /events/FormEvent.php: -------------------------------------------------------------------------------- 1 | _form; 26 | } 27 | 28 | /** 29 | * @param Model $form 30 | */ 31 | public function setForm(Model $form) 32 | { 33 | $this->_form = $form; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /events/CreateUserEvent.php: -------------------------------------------------------------------------------- 1 | _user; 26 | } 27 | 28 | /** 29 | * @param UserModel $user 30 | */ 31 | public function setUser(UserModel $user) 32 | { 33 | $this->_user = $user; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /.php_cs: -------------------------------------------------------------------------------- 1 | exclude('vendor') 5 | ->in([__DIR__]); 6 | 7 | $config = PhpCsFixer\Config::create() 8 | ->setUsingCache(false) 9 | ->setRules([ 10 | '@Symfony' => true, 11 | 'phpdoc_align' => false, 12 | 'phpdoc_summary' => false, 13 | 'phpdoc_inline_tag' => false, 14 | 'pre_increment' => false, 15 | 'heredoc_to_nowdoc' => false, 16 | 'cast_spaces' => false, 17 | 'include' => false, 18 | 'phpdoc_no_package' => false, 19 | 'concat_space' => ['spacing' => 'one'], 20 | 'ordered_imports' => true, 21 | 'array_syntax' => ['syntax' => 'short'], 22 | ]) 23 | ->setFinder($finder); 24 | 25 | return $config; 26 | -------------------------------------------------------------------------------- /actions/Action.php: -------------------------------------------------------------------------------- 1 | returnUrl !== null) { 26 | return $this->controller->redirect($this->returnUrl); 27 | } 28 | 29 | return $this->controller->redirect($defaultActionId); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /traits/EventTrait.php: -------------------------------------------------------------------------------- 1 | FormEvent::class, 'form' => $form]); 26 | } 27 | 28 | /** 29 | * @param UserModel $user 30 | * 31 | * @return object 32 | */ 33 | protected function getCreateUserEvent(UserModel $user) 34 | { 35 | return Yii::createObject(['class' => CreateUserEvent::class, 'user' => $user]); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /views/resetPassword.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('yii2mod.user', 'Reset password'); 11 | $this->params['breadcrumbs'][] = $this->title; 12 | ?> 13 |
14 |

title) ?>

15 | 16 |

17 | 18 |
19 |
20 | 'reset-password-form']); ?> 21 | field($model, 'password')->passwordInput() ?> 22 |
23 | 'btn btn-primary']) ?> 24 |
25 | 26 |
27 |
28 |
-------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 yii2mod 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "yii2mod/yii2-user", 3 | "description": "User module", 4 | "type": "yii2-extension", 5 | "keywords": [ 6 | "yii2", 7 | "yii2-user", 8 | "user management", 9 | "user module" 10 | ], 11 | "license": "MIT", 12 | "authors": [ 13 | { 14 | "name": "Dmitry Semenov", 15 | "email": "disemx@gmail.com" 16 | }, 17 | { 18 | "name": "Igor Chepurnoy", 19 | "email": "igorzfort@gmail.com" 20 | } 21 | ], 22 | "require": { 23 | "php": ">=5.6", 24 | "yiisoft/yii2": ">=2.0.8", 25 | "yiisoft/yii2-swiftmailer": "*", 26 | "yii2mod/yii2-enum": "*" 27 | }, 28 | "require-dev": { 29 | "friendsofphp/php-cs-fixer": "~2.0" 30 | }, 31 | "autoload": { 32 | "psr-4": { 33 | "yii2mod\\user\\": "" 34 | } 35 | }, 36 | "repositories": [ 37 | { 38 | "type": "composer", 39 | "url": "https://asset-packagist.org" 40 | } 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /views/requestPasswordResetToken.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('yii2mod.user', 'Recover Password'); 11 | $this->params['breadcrumbs'][] = $this->title; 12 | ?> 13 |
14 |

title) ?>

15 | 16 |

17 | 18 |
19 |
20 | 'request-password-reset-form']); ?> 21 | field($model, 'email'); ?> 22 |
23 | 'btn btn-primary']) ?> 24 |
25 | 26 |
27 |
28 |
29 | -------------------------------------------------------------------------------- /migrations/m170608_141511_rename_columns.php: -------------------------------------------------------------------------------- 1 | renameColumn('{{%user}}', 'passwordHash', 'password_hash'); 10 | $this->renameColumn('{{%user}}', 'passwordResetToken', 'password_reset_token'); 11 | $this->renameColumn('{{%user}}', 'authKey', 'auth_key'); 12 | $this->renameColumn('{{%user}}', 'lastLogin', 'last_login'); 13 | $this->renameColumn('{{%user}}', 'createdAt', 'created_at'); 14 | $this->renameColumn('{{%user}}', 'updatedAt', 'updated_at'); 15 | } 16 | 17 | public function safeDown() 18 | { 19 | $this->renameColumn('{{%user}}', 'password_hash', 'passwordHash'); 20 | $this->renameColumn('{{%user}}', 'password_reset_token', 'passwordResetToken'); 21 | $this->renameColumn('{{%user}}', 'auth_key', 'authKey'); 22 | $this->renameColumn('{{%user}}', 'last_login', 'lastLogin'); 23 | $this->renameColumn('{{%user}}', 'created_at', 'createdAt'); 24 | $this->renameColumn('{{%user}}', 'updated_at', 'updatedAt'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /views/signup.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('yii2mod.user', 'Signup'); 11 | $this->params['breadcrumbs'][] = $this->title; 12 | ?> 13 |
14 |

title) ?>

15 | 16 |

17 | 18 |
19 |
20 | 'form-signup']); ?> 21 | field($model, 'username') ?> 22 | field($model, 'email') ?> 23 | field($model, 'password')->passwordInput() ?> 24 |
25 | 'btn btn-primary', 'name' => 'signup-button']) ?> 26 |
27 | 28 |
29 |
30 |
31 | -------------------------------------------------------------------------------- /commands/UpdatePasswordController.php: -------------------------------------------------------------------------------- 1 | stdout(Yii::t('yii2mod.user', 'User is not found.') . "\n", Console::FG_RED); 31 | } else { 32 | if ($user->resetPassword($password)) { 33 | $this->stdout(Yii::t('yii2mod.user', 'Password has been changed.') . "\n", Console::FG_GREEN); 34 | } else { 35 | $this->stdout(Yii::t('yii2mod.user', 'Error occurred while changing password.') . "\n", Console::FG_RED); 36 | } 37 | } 38 | 39 | return self::EXIT_CODE_NORMAL; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /commands/DeleteController.php: -------------------------------------------------------------------------------- 1 | confirm(Yii::t('yii2mod.user', 'Are you sure you want to delete this user?'))) { 27 | $user = UserModel::findByEmail($email); 28 | if ($user === null) { 29 | $this->stdout(Yii::t('yii2mod.user', 'User is not found.') . "\n", Console::FG_RED); 30 | } else { 31 | if ($user->delete()) { 32 | $this->stdout(Yii::t('yii2mod.user', 'User has been deleted.') . "\n", Console::FG_GREEN); 33 | } else { 34 | $this->stdout(Yii::t('yii2mod.user', 'Error occurred while deleting user.') . "\n", Console::FG_RED); 35 | } 36 | } 37 | } 38 | 39 | return self::EXIT_CODE_NORMAL; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /views/login.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('yii2mod.user', 'Login'); 11 | $this->params['breadcrumbs'][] = $this->title; 12 | ?> 13 |
14 |

title); ?>

15 |

16 |
17 |
18 | 'login-form']); ?> 19 | field($model, 'email'); ?> 20 | field($model, 'password')->passwordInput(); ?> 21 | field($model, 'rememberMe')->checkbox(); ?> 22 |
23 | 24 |
25 |
26 | 'btn btn-primary', 'name' => 'login-button']); ?> 27 |
28 | 29 |
30 |
31 |
32 | -------------------------------------------------------------------------------- /commands/CreateController.php: -------------------------------------------------------------------------------- 1 | UserModel::class, 28 | 'scenario' => 'create', 29 | 'email' => $email, 30 | 'username' => $username, 31 | 'plainPassword' => $password, 32 | ]); 33 | 34 | if ($user->create()) { 35 | $this->stdout(Yii::t('yii2mod.user', 'User has been created.') . "!\n", Console::FG_GREEN); 36 | } else { 37 | $this->stdout(Yii::t('yii2mod.user', 'Please fix the following errors:') . "\n", Console::FG_RED); 38 | foreach ($user->errors as $errors) { 39 | foreach ($errors as $error) { 40 | $this->stdout(' - ' . $error . "\n", Console::FG_RED); 41 | } 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /migrations/m150828_085134_init_user_tables.php: -------------------------------------------------------------------------------- 1 | db->driverName === 'mysql') { 15 | $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB'; 16 | } 17 | 18 | // Create user table 19 | $this->createTable('{{%User}}', [ 20 | 'id' => $this->primaryKey(), 21 | 'username' => $this->string()->notNull()->unique(), 22 | 'authKey' => $this->string(32)->notNull(), 23 | 'passwordHash' => $this->string()->notNull(), 24 | 'passwordResetToken' => $this->string()->unique(), 25 | 'email' => $this->string()->notNull()->unique(), 26 | 'status' => $this->smallInteger()->notNull()->defaultValue(1), 27 | 'createdAt' => $this->integer()->notNull(), 28 | 'updatedAt' => $this->integer()->notNull(), 29 | 'lastLogin' => $this->integer(), 30 | ], $tableOptions); 31 | } 32 | 33 | public function down() 34 | { 35 | $this->dropTable('{{%User}}'); 36 | } 37 | 38 | /* 39 | // Use safeUp/safeDown to run migration code within a transaction 40 | public function safeUp() 41 | { 42 | } 43 | 44 | public function safeDown() 45 | { 46 | } 47 | */ 48 | } 49 | -------------------------------------------------------------------------------- /actions/LoginAction.php: -------------------------------------------------------------------------------- 1 | layout !== null) { 39 | $this->controller->layout = $this->layout; 40 | } 41 | } 42 | 43 | /** 44 | * Logs in a user. 45 | * 46 | * @return string 47 | */ 48 | public function run() 49 | { 50 | if (!Yii::$app->user->isGuest) { 51 | return $this->redirectTo(Yii::$app->getHomeUrl()); 52 | } 53 | 54 | $model = Yii::createObject($this->modelClass); 55 | $load = $model->load(Yii::$app->request->post()); 56 | 57 | if (Yii::$app->request->isAjax) { 58 | Yii::$app->response->format = Response::FORMAT_JSON; 59 | 60 | return ActiveForm::validate($model); 61 | } 62 | 63 | if ($load && $model->login()) { 64 | return $this->redirectTo(Yii::$app->getUser()->getReturnUrl()); 65 | } 66 | 67 | return $this->controller->render($this->view, [ 68 | 'model' => $model, 69 | ]); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /actions/SignupAction.php: -------------------------------------------------------------------------------- 1 | modelClass); 49 | $event = $this->getFormEvent($model); 50 | 51 | $this->trigger(self::EVENT_BEFORE_SIGNUP, $event); 52 | 53 | $load = $model->load(Yii::$app->request->post()); 54 | 55 | if (Yii::$app->request->isAjax) { 56 | Yii::$app->response->format = Response::FORMAT_JSON; 57 | 58 | return ActiveForm::validate($model); 59 | } 60 | 61 | if ($load && ($user = $model->signup()) !== null) { 62 | $this->trigger(self::EVENT_AFTER_SIGNUP, $event); 63 | if (Yii::$app->getUser()->login($user)) { 64 | return $this->redirectTo(Yii::$app->getUser()->getReturnUrl()); 65 | } 66 | } 67 | 68 | return $this->controller->render($this->view, [ 69 | 'model' => $model, 70 | ]); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /models/ResetPasswordForm.php: -------------------------------------------------------------------------------- 1 | user = UserModel::findByPasswordResetToken($token); 41 | 42 | if (!$this->user) { 43 | throw new InvalidParamException('Wrong password reset token.'); 44 | } 45 | 46 | parent::__construct($config); 47 | } 48 | 49 | /** 50 | * @inheritdoc 51 | */ 52 | public function rules() 53 | { 54 | return [ 55 | ['password', 'required'], 56 | ['password', 'string', 'min' => 6], 57 | ]; 58 | } 59 | 60 | /** 61 | * @inheritdoc 62 | */ 63 | public function attributeLabels() 64 | { 65 | return [ 66 | 'password' => Yii::t('yii2mod.user', 'Password'), 67 | ]; 68 | } 69 | 70 | /** 71 | * Resets password. 72 | * 73 | * @return bool if password was reset 74 | */ 75 | public function resetPassword() 76 | { 77 | $user = $this->user; 78 | $user->setPassword($this->password); 79 | $user->removePasswordResetToken(); 80 | 81 | return $user->save(); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /models/PasswordResetRequestForm.php: -------------------------------------------------------------------------------- 1 | 'trim'], 28 | ['email', 'required'], 29 | ['email', 'email'], 30 | ['email', 'exist', 31 | 'targetClass' => Yii::$app->user->identityClass, 32 | 'message' => Yii::t('yii2mod.user', 'User with this email is not found.'), 33 | ], 34 | ['email', 'exist', 35 | 'targetClass' => Yii::$app->user->identityClass, 36 | 'filter' => ['status' => UserStatus::ACTIVE], 37 | 'message' => Yii::t('yii2mod.user', 'Your account has been deactivated, please contact support for details.'), 38 | ], 39 | ]; 40 | } 41 | 42 | /** 43 | * @inheritdoc 44 | */ 45 | public function attributeLabels() 46 | { 47 | return [ 48 | 'email' => Yii::t('yii2mod.user', 'Email'), 49 | ]; 50 | } 51 | 52 | /** 53 | * Sends an email with a link, for resetting the password. 54 | * 55 | * @return bool whether the email was send 56 | */ 57 | public function sendEmail() 58 | { 59 | $user = UserModel::findOne(['status' => UserStatus::ACTIVE, 'email' => $this->email]); 60 | 61 | if (!empty($user)) { 62 | $user->generatePasswordResetToken(); 63 | if ($user->save()) { 64 | return Yii::$app->mailer->compose('passwordResetToken', ['user' => $user]) 65 | ->setFrom([Yii::$app->params['adminEmail'] => Yii::$app->name]) 66 | ->setTo($this->email) 67 | ->setSubject(Yii::t('yii2mod.user', 'Password reset for {0}', Yii::$app->name)) 68 | ->send(); 69 | } 70 | } 71 | 72 | return false; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /actions/PasswordResetAction.php: -------------------------------------------------------------------------------- 1 | modelClass, [$token]); 59 | $event = $this->getFormEvent($model); 60 | $this->trigger(self::EVENT_BEFORE_RESET, $event); 61 | } catch (InvalidParamException $e) { 62 | throw new BadRequestHttpException($e->getMessage()); 63 | } 64 | 65 | if ($model->load(Yii::$app->request->post()) && $model->validate() && $model->resetPassword()) { 66 | $this->trigger(self::EVENT_AFTER_RESET, $event); 67 | Yii::$app->getSession()->setFlash('success', $this->successMessage); 68 | 69 | return $this->redirectTo(Yii::$app->getHomeUrl()); 70 | } 71 | 72 | return $this->controller->render($this->view, [ 73 | 'model' => $model, 74 | ]); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /models/SignupForm.php: -------------------------------------------------------------------------------- 1 | UserModel::class, 'message' => Yii::t('yii2mod.user', 'This username has already been taken.')], 44 | ['username', 'string', 'min' => 2, 'max' => 255], 45 | 46 | ['email', 'trim'], 47 | ['email', 'required'], 48 | ['email', 'email'], 49 | ['email', 'string', 'max' => 255], 50 | ['email', 'unique', 'targetClass' => UserModel::class, 'message' => Yii::t('yii2mod.user', 'This email address has already been taken.')], 51 | 52 | ['password', 'required'], 53 | ['password', 'string', 'min' => 6], 54 | ]; 55 | } 56 | 57 | /** 58 | * @inheritdoc 59 | */ 60 | public function attributeLabels() 61 | { 62 | return [ 63 | 'username' => Yii::t('yii2mod.user', 'Username'), 64 | 'email' => Yii::t('yii2mod.user', 'Email'), 65 | 'password' => Yii::t('yii2mod.user', 'Password'), 66 | ]; 67 | } 68 | 69 | /** 70 | * Signs user up. 71 | * 72 | * @return UserModel|null the saved model or null if saving fails 73 | */ 74 | public function signup() 75 | { 76 | if (!$this->validate()) { 77 | return null; 78 | } 79 | 80 | $this->user = new UserModel(); 81 | $this->user->setAttributes($this->attributes); 82 | $this->user->setPassword($this->password); 83 | $this->user->setLastLogin(time()); 84 | $this->user->generateAuthKey(); 85 | 86 | return $this->user->save() ? $this->user : null; 87 | } 88 | 89 | /** 90 | * @return UserModel|null 91 | */ 92 | public function getUser() 93 | { 94 | return $this->user; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /actions/RequestPasswordResetAction.php: -------------------------------------------------------------------------------- 1 | modelClass); 59 | $event = $this->getFormEvent($model); 60 | 61 | $this->trigger(self::EVENT_BEFORE_REQUEST, $event); 62 | 63 | $load = $model->load(Yii::$app->request->post()); 64 | 65 | if (Yii::$app->request->isAjax) { 66 | Yii::$app->response->format = Response::FORMAT_JSON; 67 | 68 | return ActiveForm::validate($model); 69 | } 70 | 71 | if ($load && $model->validate()) { 72 | if ($model->sendEmail()) { 73 | $this->trigger(self::EVENT_AFTER_REQUEST, $event); 74 | Yii::$app->getSession()->setFlash('success', $this->successMessage); 75 | 76 | return $this->redirectTo(Yii::$app->getHomeUrl()); 77 | } else { 78 | Yii::$app->getSession()->setFlash('error', $this->errorMessage); 79 | } 80 | } 81 | 82 | return $this->controller->render($this->view, [ 83 | 'model' => $model, 84 | ]); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /messages/config.php: -------------------------------------------------------------------------------- 1 | __DIR__ . DIRECTORY_SEPARATOR . '..', 6 | // array, required, list of language codes that the extracted messages 7 | // should be translated to. For example, ['zh-CN', 'de']. 8 | 'languages' => ['en', 'ru', 'uk'], 9 | // string, the name of the function for translating messages. 10 | // Defaults to 'Yii::t'. This is used as a mark to find the messages to be 11 | // translated. You may use a string for single function name or an array for 12 | // multiple function names. 13 | 'translator' => 'Yii::t', 14 | // boolean, whether to sort messages by keys when merging new messages 15 | // with the existing ones. Defaults to false, which means the new (untranslated) 16 | // messages will be separated from the old (translated) ones. 17 | 'sort' => true, 18 | // boolean, whether to remove messages that no longer appear in the source code. 19 | // Defaults to false, which means each of these messages will be enclosed with a pair of '@@' marks. 20 | 'removeUnused' => false, 21 | // array, list of patterns that specify which files (not directories) should be processed. 22 | // If empty or not set, all files will be processed. 23 | // Please refer to "except" for details about the patterns. 24 | 'only' => ['*.php'], 25 | // array, list of patterns that specify which files/directories should NOT be processed. 26 | // If empty or not set, all files/directories will be processed. 27 | // A path matches a pattern if it contains the pattern string at its end. For example, 28 | // '/a/b' will match all files and directories ending with '/a/b'; 29 | // the '*.svn' will match all files and directories whose name ends with '.svn'. 30 | // and the '.svn' will match all files and directories named exactly '.svn'. 31 | // Note, the '/' characters in a pattern matches both '/' and '\'. 32 | // See helpers/FileHelper::findFiles() description for more details on pattern matching rules. 33 | // If a file/directory matches both a pattern in "only" and "except", it will NOT be processed. 34 | 'except' => [ 35 | '.svn', 36 | '.git', 37 | '.gitignore', 38 | '.gitkeep', 39 | '.hgignore', 40 | '.hgkeep', 41 | '/messages', 42 | '/tests', 43 | '/runtime', 44 | '/vendor', 45 | ], 46 | 47 | // 'php' output format is for saving messages to php files. 48 | 'format' => 'php', 49 | // Root directory containing message translations. 50 | 'messagePath' => __DIR__, 51 | // boolean, whether the message file should be overwritten with the merged messages 52 | 'overwrite' => true, 53 | 54 | // Message categories to ignore 55 | 'ignoreCategories' => [ 56 | 'yii', 57 | ], 58 | ]; 59 | -------------------------------------------------------------------------------- /models/LoginForm.php: -------------------------------------------------------------------------------- 1 | Yii::t('yii2mod.user', 'Email'), 56 | 'password' => Yii::t('yii2mod.user', 'Password'), 57 | 'rememberMe' => Yii::t('yii2mod.user', 'Remember Me'), 58 | ]; 59 | } 60 | 61 | /** 62 | * Validates the password. 63 | * This method serves as the inline validation for password. 64 | * 65 | * @param $attribute 66 | * @param $params 67 | */ 68 | public function validatePassword($attribute, $params) 69 | { 70 | if (!$this->hasErrors()) { 71 | $user = $this->getUser(); 72 | if ($user && $user->status === UserStatus::DELETED) { 73 | $this->addError($attribute, Yii::t('yii2mod.user', 'Your account has been deactivated, please contact support for details.')); 74 | } elseif (!$user || !$user->validatePassword($this->password)) { 75 | $this->addError($attribute, Yii::t('yii2mod.user', 'Incorrect email or password.')); 76 | } 77 | } 78 | } 79 | 80 | /** 81 | * Logs in a user using the provided username and password. 82 | * 83 | * @return bool whether the user is logged in successfully 84 | */ 85 | public function login() 86 | { 87 | if ($this->validate()) { 88 | return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600 * 24 * 30 : 0); 89 | } else { 90 | return false; 91 | } 92 | } 93 | 94 | /** 95 | * Finds user by [[email]] 96 | * 97 | * @return UserModel|null 98 | */ 99 | public function getUser() 100 | { 101 | if ($this->user === false) { 102 | $this->user = UserModel::findByEmail($this->email); 103 | } 104 | 105 | return $this->user; 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /messages/en/yii2mod.user.php: -------------------------------------------------------------------------------- 1 | 'Are you sure you want to delete this user?', 21 | 'Email' => 'Email', 22 | 'Error occurred while changing password.' => 'Error occurred while changing password.', 23 | 'Error occurred while deleting user.' => 'Error occurred while deleting user.', 24 | 'Forgot your password?' => 'Forgot your password?', 25 | 'Incorrect email or password.' => 'Incorrect email or password.', 26 | 'Last login' => 'Last login', 27 | 'Login' => 'Login', 28 | 'Password' => 'Password', 29 | 'Password has been changed.' => 'Password has been changed.', 30 | 'Password reset for {0}' => 'Password reset for {0}', 31 | 'Please choose your new password:' => 'Please choose your new password:', 32 | 'Please fill out the following fields to login:' => 'Please fill out the following fields to login:', 33 | 'Please fill out the following fields to signup:' => 'Please fill out the following fields to signup:', 34 | 'Please fill out your email. A link to reset password will be sent there.' => 'Please fill out your email. A link to reset password will be sent there.', 35 | 'Please fix the following errors:' => 'Please fix the following errors:', 36 | 'Recover Password' => 'Recover Password', 37 | 'Registration time' => 'Registration time', 38 | 'Remember Me' => 'Remember Me', 39 | 'Reset password' => 'Reset password', 40 | 'Save' => 'Save', 41 | 'Send' => 'Send', 42 | 'Signup' => 'Signup', 43 | 'Status' => 'Status', 44 | 'The role "{roleName}" is not found.' => 'The role "{roleName}" is not found.', 45 | 'The role has been successfully assigned to the user.' => 'The role has been successfully assigned to the user.', 46 | 'The role has been successfully revoked from the user.' => 'The role has been successfully revoked from the user.', 47 | 'This email address has already been taken.' => 'This email address has already been taken.', 48 | 'This role already assigned to this user.' => 'This role already assigned to this user.', 49 | 'This role is not assigned to this user.' => 'This role is not assigned to this user.', 50 | 'This username has already been taken.' => 'This username has already been taken.', 51 | 'User has been created.' => 'User has been created.', 52 | 'User has been deleted.' => 'User has been deleted.', 53 | 'User is not found.' => 'User is not found.', 54 | 'User with this email is not found.' => 'User with this email is not found.', 55 | 'Username' => 'Username', 56 | 'Your account has been deactivated, please contact support for details.' => 'Your account has been deactivated, please contact support for details.', 57 | ]; 58 | -------------------------------------------------------------------------------- /messages/uk/yii2mod.user.php: -------------------------------------------------------------------------------- 1 | 'Ви дійсно хочете видалити цього користувача?', 21 | 'Email' => 'Email', 22 | 'Error occurred while changing password.' => 'При зміні пароля виникла помилка.', 23 | 'Error occurred while deleting user.' => 'Виникла помилка при видаленні користувача.', 24 | 'Forgot your password?' => 'Забули пароль?', 25 | 'Incorrect email or password.' => 'Неправильний email або пароль.', 26 | 'Last login' => 'Останняя авторизація', 27 | 'Login' => 'Вхід', 28 | 'Password' => 'Пароль', 29 | 'Password has been changed.' => 'Пароль було успішно змінено', 30 | 'Password reset for {0}' => 'Відновлення пароля для {0}', 31 | 'Please choose your new password:' => 'Будь ласка, введіть ваш новий пароль:', 32 | 'Please fill out the following fields to login:' => 'Будь ласка, заповніть наступні поля для входу:', 33 | 'Please fill out the following fields to signup:' => 'Будь ласка, заповніть наступні поля для реєстрації:', 34 | 'Please fill out your email. A link to reset password will be sent there.' => 'Будь ласка, введіть адресу вашої електронної пошти. Посилання для скидання пароля буде вислана на нього.', 35 | 'Please fix the following errors:' => 'Виправте наступні помилки:', 36 | 'Recover Password' => 'Відновлення Пароля', 37 | 'Registration time' => 'Час реєстрації', 38 | 'Remember Me' => 'Запам\'ятати мене', 39 | 'Reset password' => 'Скидання пароля', 40 | 'Save' => 'Зберегти', 41 | 'Send' => 'Відправити', 42 | 'Signup' => 'Реєстрація', 43 | 'Status' => 'Статус', 44 | 'The role "{roleName}" is not found.' => 'Роль "{roleName}" не знайдено.', 45 | 'The role has been successfully assigned to the user.' => 'Роль успішно призначено користувачу.', 46 | 'The role has been successfully revoked from the user.' => 'Роль успішно видалена у користувача.', 47 | 'This email address has already been taken.' => 'Цей адрес електронної пошти вже зайнятий.', 48 | 'This role already assigned to this user.' => 'Ця роль вже призначена користувачеві.', 49 | 'This role is not assigned to this user.' => 'Ця роль не призначена користувачеві.', 50 | 'This username has already been taken.' => 'Це ім\'я вже зайняте .', 51 | 'User has been created.' => 'Користувач був створений.', 52 | 'User has been deleted.' => 'Користувач був видалений.', 53 | 'User is not found.' => 'Користувач не знайдений.', 54 | 'User with this email is not found.' => 'Такий користувач не знайдений', 55 | 'Username' => 'Ім\'я користувача', 56 | 'Your account has been deactivated, please contact support for details.' => 'Ваш аккаунт був заблокований, зверніться в службу підтримки.', 57 | ]; 58 | -------------------------------------------------------------------------------- /commands/RoleController.php: -------------------------------------------------------------------------------- 1 | _authManager = Yii::$app->authManager; 32 | } 33 | 34 | /** 35 | * Assign role to the user 36 | * 37 | * @param $roleName 38 | * @param $email 39 | * 40 | * @return int 41 | * 42 | * @throws Exception 43 | */ 44 | public function actionAssign($roleName, $email) 45 | { 46 | $user = UserModel::findByEmail($email); 47 | 48 | if (empty($user)) { 49 | throw new Exception(Yii::t('yii2mod.user', 'User is not found.')); 50 | } 51 | 52 | $role = $this->findRole($roleName); 53 | 54 | if (in_array($roleName, array_keys($this->_authManager->getRolesByUser($user->id)))) { 55 | $this->stdout(Yii::t('yii2mod.user', 'This role already assigned to this user.') . "\n", Console::FG_RED); 56 | 57 | return self::EXIT_CODE_NORMAL; 58 | } 59 | 60 | $this->_authManager->assign($role, $user->id); 61 | 62 | $this->stdout(Yii::t('yii2mod.user', 'The role has been successfully assigned to the user.') . "\n", Console::FG_GREEN); 63 | 64 | return self::EXIT_CODE_NORMAL; 65 | } 66 | 67 | /** 68 | * Revoke role from the user 69 | * 70 | * @param $roleName 71 | * @param $email 72 | * 73 | * @return int 74 | * 75 | * @throws Exception 76 | */ 77 | public function actionRevoke($roleName, $email) 78 | { 79 | $user = UserModel::findByEmail($email); 80 | 81 | if (empty($user)) { 82 | throw new Exception(Yii::t('yii2mod.user', 'User is not found.')); 83 | } 84 | 85 | $role = $this->findRole($roleName); 86 | 87 | if (!in_array($roleName, array_keys($this->_authManager->getRolesByUser($user->id)))) { 88 | $this->stdout(Yii::t('yii2mod.user', 'This role is not assigned to this user.') . "\n", Console::FG_RED); 89 | 90 | return self::EXIT_CODE_NORMAL; 91 | } 92 | 93 | $this->_authManager->revoke($role, $user->id); 94 | 95 | $this->stdout(Yii::t('yii2mod.user', 'The role has been successfully revoked from the user.') . "\n", Console::FG_GREEN); 96 | 97 | return self::EXIT_CODE_NORMAL; 98 | } 99 | 100 | /** 101 | * Returns the named role. 102 | * 103 | * @param string $roleName 104 | * 105 | * @return Role 106 | * 107 | * @throws Exception 108 | */ 109 | protected function findRole($roleName) 110 | { 111 | if (($role = $this->_authManager->getRole($roleName)) !== null) { 112 | return $role; 113 | } 114 | 115 | throw new Exception(Yii::t('yii2mod.user', 'The role "{roleName}" is not found.', [ 116 | 'roleName' => $roleName, 117 | ])); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /messages/ru/yii2mod.user.php: -------------------------------------------------------------------------------- 1 | 'Вы уверены, что хотите удалить этого пользователя?', 21 | 'Email' => 'Email', 22 | 'Error occurred while changing password.' => 'Произошла ошибка при смене пароля.', 23 | 'Error occurred while deleting user.' => 'Произошла ошибка при удалении пользователя.', 24 | 'Forgot your password?' => 'Забыли пароль?', 25 | 'Incorrect email or password.' => 'Неправильный email или пароль.', 26 | 'Last login' => 'Дата последнего входа', 27 | 'Login' => 'Вход', 28 | 'Password' => 'Пароль', 29 | 'Password has been changed.' => 'Пароль был изменен.', 30 | 'Password reset for {0}' => 'Восстановление пароля для {0}', 31 | 'Please choose your new password:' => 'Пожалуйста, введите ваш новый пароль:', 32 | 'Please fill out the following fields to login:' => 'Пожалуйста, заполните следующие поля для входа:', 33 | 'Please fill out the following fields to signup:' => 'Пожалуйста, заполните следующие поля для регистрации:', 34 | 'Please fill out your email. A link to reset password will be sent there.' => 'Пожалуйста, введите адрес вашей электронной почты. Ссылка для сброса пароля будет выслана на него.', 35 | 'Please fix the following errors:' => 'Пожалуйста, исправьте следующие ошибки:', 36 | 'Recover Password' => 'Восстановление Пароля', 37 | 'Registration time' => 'Время регистрации', 38 | 'Remember Me' => 'Запомнить меня', 39 | 'Reset password' => 'Сброс пароля', 40 | 'Save' => 'Сохранить', 41 | 'Send' => 'Отправить', 42 | 'Signup' => 'Регистрация', 43 | 'Status' => 'Статус', 44 | 'The role "{roleName}" is not found.' => 'Роль "{roleName}" не найдена.', 45 | 'The role has been successfully assigned to the user.' => 'Роль успешно назначена пользователю.', 46 | 'The role has been successfully revoked from the user.' => 'Роль успешно удалена у пользователя.', 47 | 'This email address has already been taken.' => 'Этот адрес электронной почты уже занят.', 48 | 'This role already assigned to this user.' => 'Эта роль уже назначена пользователю.', 49 | 'This role is not assigned to this user.' => 'Эта роль не назначена пользователю.', 50 | 'This username has already been taken.' => 'Это имя пользователя уже занято.', 51 | 'User has been created.' => 'Пользователь был создан.', 52 | 'User has been deleted.' => 'Пользователь был удален.', 53 | 'User is not found.' => 'Пользователь не найден.', 54 | 'User with this email is not found.' => 'Такой пользователь не найден.', 55 | 'Username' => 'Имя пользователя', 56 | 'Your account has been deactivated, please contact support for details.' => 'Ваш аккаунт был заблокирован, обратитесь в службу поддержки.', 57 | ]; 58 | -------------------------------------------------------------------------------- /models/UserModel.php: -------------------------------------------------------------------------------- 1 | Yii::t('yii2mod.user', 'This email address has already been taken.')], 66 | ['username', 'unique', 'message' => Yii::t('yii2mod.user', 'This username has already been taken.')], 67 | ['username', 'string', 'min' => 2, 'max' => 255], 68 | ['email', 'email'], 69 | ['email', 'string', 'max' => 255], 70 | ['plainPassword', 'string', 'min' => 6], 71 | ['plainPassword', 'required', 'on' => 'create'], 72 | ['status', 'default', 'value' => UserStatus::ACTIVE], 73 | ['status', 'in', 'range' => UserStatus::getConstantsByName()], 74 | ]; 75 | } 76 | 77 | /** 78 | * @inheritdoc 79 | */ 80 | public function attributeLabels() 81 | { 82 | return [ 83 | 'username' => Yii::t('yii2mod.user', 'Username'), 84 | 'email' => Yii::t('yii2mod.user', 'Email'), 85 | 'status' => Yii::t('yii2mod.user', 'Status'), 86 | 'created_at' => Yii::t('yii2mod.user', 'Registration time'), 87 | 'last_login' => Yii::t('yii2mod.user', 'Last login'), 88 | 'plainPassword' => Yii::t('yii2mod.user', 'Password'), 89 | ]; 90 | } 91 | 92 | /** 93 | * @inheritdoc 94 | */ 95 | public function behaviors() 96 | { 97 | return [ 98 | TimestampBehavior::class, 99 | ]; 100 | } 101 | 102 | /** 103 | * Create user 104 | * 105 | * @return null|UserModel the saved model or null if saving fails 106 | * 107 | * @throws \Exception 108 | */ 109 | public function create() 110 | { 111 | $transaction = $this->getDb()->beginTransaction(); 112 | 113 | try { 114 | $event = $this->getCreateUserEvent($this); 115 | $this->trigger(self::BEFORE_CREATE, $event); 116 | 117 | $this->setPassword($this->plainPassword); 118 | $this->generateAuthKey(); 119 | 120 | if (!$this->save()) { 121 | $transaction->rollBack(); 122 | 123 | return null; 124 | } 125 | 126 | $this->trigger(self::AFTER_CREATE, $event); 127 | 128 | $transaction->commit(); 129 | 130 | return $this; 131 | } catch (\Exception $e) { 132 | $transaction->rollBack(); 133 | Yii::warning($e->getMessage()); 134 | throw $e; 135 | } 136 | } 137 | 138 | /** 139 | * @inheritdoc 140 | */ 141 | public static function findIdentity($id) 142 | { 143 | return static::findOne($id); 144 | } 145 | 146 | /** 147 | * @inheritdoc 148 | */ 149 | public static function findIdentityByAccessToken($token, $type = null) 150 | { 151 | throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.'); 152 | } 153 | 154 | /** 155 | * Finds user (with active status) by username 156 | * 157 | * @param string $username 158 | * 159 | * @return static|null 160 | */ 161 | public static function findByUsername($username) 162 | { 163 | return static::findOne(['username' => $username, 'status' => UserStatus::ACTIVE]); 164 | } 165 | 166 | /** 167 | * Finds user by email 168 | * 169 | * @param $email 170 | * 171 | * @return null|static 172 | */ 173 | public static function findByEmail($email) 174 | { 175 | return static::findOne(['email' => $email]); 176 | } 177 | 178 | /** 179 | * Finds user by password reset token 180 | * 181 | * @param string $token password reset token 182 | * 183 | * @return static|null 184 | */ 185 | public static function findByPasswordResetToken($token) 186 | { 187 | if (!static::isPasswordResetTokenValid($token)) { 188 | return null; 189 | } 190 | 191 | return static::findOne([ 192 | 'password_reset_token' => $token, 193 | 'status' => UserStatus::ACTIVE, 194 | ]); 195 | } 196 | 197 | /** 198 | * Finds out if password reset token is valid 199 | * 200 | * @param string $token password reset token 201 | * 202 | * @return bool 203 | */ 204 | public static function isPasswordResetTokenValid($token) 205 | { 206 | if (empty($token)) { 207 | return false; 208 | } 209 | 210 | $timestamp = (int) substr($token, strrpos($token, '_') + 1); 211 | $expire = ArrayHelper::getValue(Yii::$app->params, 'user.passwordResetTokenExpire', 3600); 212 | 213 | return $timestamp + $expire >= time(); 214 | } 215 | 216 | /** 217 | * @inheritdoc 218 | */ 219 | public function getId() 220 | { 221 | return $this->getPrimaryKey(); 222 | } 223 | 224 | /** 225 | * @inheritdoc 226 | */ 227 | public function getAuthKey() 228 | { 229 | return $this->auth_key; 230 | } 231 | 232 | /** 233 | * @inheritdoc 234 | */ 235 | public function validateAuthKey($authKey) 236 | { 237 | return $this->getAuthKey() === $authKey; 238 | } 239 | 240 | /** 241 | * Validates password 242 | * 243 | * @param string $password password to validate 244 | * 245 | * @return bool if password provided is valid for current user 246 | */ 247 | public function validatePassword($password) 248 | { 249 | return Yii::$app->getSecurity()->validatePassword($password, $this->password_hash); 250 | } 251 | 252 | /** 253 | * Generates password hash from password and sets it to the model 254 | * 255 | * @param string $password 256 | */ 257 | public function setPassword($password) 258 | { 259 | $this->password_hash = Yii::$app->getSecurity()->generatePasswordHash($password); 260 | } 261 | 262 | /** 263 | * Generates "remember me" authentication key 264 | */ 265 | public function generateAuthKey() 266 | { 267 | $this->auth_key = Yii::$app->getSecurity()->generateRandomString(); 268 | } 269 | 270 | /** 271 | * Generates new password reset token 272 | */ 273 | public function generatePasswordResetToken() 274 | { 275 | $this->password_reset_token = Yii::$app->getSecurity()->generateRandomString() . '_' . time(); 276 | } 277 | 278 | /** 279 | * Removes password reset token 280 | */ 281 | public function removePasswordResetToken() 282 | { 283 | $this->password_reset_token = null; 284 | } 285 | 286 | /** 287 | * @param $lastLogin 288 | */ 289 | public function setLastLogin($lastLogin) 290 | { 291 | $this->last_login = $lastLogin; 292 | } 293 | 294 | /** 295 | * Update last login 296 | */ 297 | public function updateLastLogin() 298 | { 299 | $this->updateAttributes(['last_login' => time()]); 300 | } 301 | 302 | /** 303 | * Resets password. 304 | * 305 | * @param string $password 306 | * 307 | * @return bool 308 | */ 309 | public function resetPassword($password) 310 | { 311 | $this->setPassword($password); 312 | 313 | return $this->save(true, ['password_hash']); 314 | } 315 | } 316 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | 4 | 5 |

Yii2 User Extension

6 |
7 |

8 | 9 | Flexible user registration and authentication module for Yii2 10 | 11 | [![Latest Stable Version](https://poser.pugx.org/yii2mod/yii2-user/v/stable)](https://packagist.org/packages/yii2mod/yii2-user) [![Total Downloads](https://poser.pugx.org/yii2mod/yii2-user/downloads)](https://packagist.org/packages/yii2mod/yii2-user) [![License](https://poser.pugx.org/yii2mod/yii2-user/license)](https://packagist.org/packages/yii2mod/yii2-user) 12 | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/yii2mod/yii2-user/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/yii2mod/yii2-user/?branch=master) [![Build Status](https://travis-ci.org/yii2mod/yii2-user.svg?branch=master)](https://travis-ci.org/yii2mod/yii2-user) 13 | 14 | Installation 15 | ------------ 16 | 17 | The preferred way to install this extension is through [composer](http://getcomposer.org/download/). 18 | 19 | Either run 20 | 21 | ``` 22 | php composer.phar require --prefer-dist yii2mod/yii2-user "*" 23 | ``` 24 | 25 | or add 26 | 27 | ``` 28 | "yii2mod/yii2-user": "*" 29 | ``` 30 | 31 | to the require section of your `composer.json` file. 32 | 33 | ## Actions 34 | 35 | This extension provides several independent action classes, which provides particular operation support: 36 | 37 | 1. **[[yii2mod\user\actions\LoginAction]]** - Logs in a user. The following additional parameters are available: 38 | - `view` - name of the view, which should be rendered. 39 | - `modelClass` - login model class name. 40 | - `layout` - the name of the layout to be applied to this view. 41 | - `returnUrl` - url which user should be redirected to on success. 42 | 2. **[[yii2mod\user\actions\LogoutAction]]** - Logs out the current user. The following additional parameters are available: 43 | - `returnUrl` - url which user should be redirected to on success. 44 | 3. **[[yii2mod\user\actions\SignupAction]]** - Signup a user. The following additional parameters are available: 45 | - `view` - name of the view, which should be rendered. 46 | - `modelClass` - signup model class name. 47 | - `returnUrl` - url which user should be redirected to on success. 48 | 4. **[[yii2mod\user\actions\RequestPasswordResetAction]]** - Request password reset for a user. The following additional parameters are available: 49 | - `view` - name of the view, which should be rendered. 50 | - `modelClass` - request password model class. 51 | - `successMessage` - message to the user when the mail is sent successfully. 52 | - `errorMessage` - error message for the user when the email was not sent. 53 | - `returnUrl` - url which user should be redirected to on success. 54 | 5. **[[yii2mod\user\actions\PasswordResetAction]]** - Reset password for a user. The following additional parameters are available: 55 | - `view` - name of the view, which should be rendered. 56 | - `modelClass` - reset password model class. 57 | - `successMessage` - message to be set on success. 58 | - `returnUrl` - url which user should be redirected to on success. 59 | 60 | Configuration 61 | ============= 62 | 1) If you use this extension without [base template](https://github.com/yii2mod/base), then you need execute migration by the following command: 63 | ``` 64 | php yii migrate/up --migrationPath=@vendor/yii2mod/yii2-user/migrations 65 | ``` 66 | 2) You need to configure the `params` section in your project configuration: 67 | ```php 68 | 'params' => [ 69 | 'user.passwordResetTokenExpire' => 3600 70 | ] 71 | ``` 72 | 3) Your need to create the UserModel class that be extends of [UserModel](https://github.com/yii2mod/yii2-user/blob/master/models/BaseUserModel.php) and configure the property `identityClass` for `user` component in your project configuration, for example: 73 | ```php 74 | 'user' => [ 75 | 'identityClass' => 'yii2mod\user\models\UserModel', 76 | // for update last login date for user, you can call the `afterLogin` event as follows 77 | 'on afterLogin' => function ($event) { 78 | $event->identity->updateLastLogin(); 79 | } 80 | ], 81 | ``` 82 | 83 | 4) For sending emails you need to configure the `mailer` component in the configuration of your project. 84 | 85 | 5) If you don't have the `passwordResetToken.php` template file in the mail folder of your project, then you need to create it, for example: 86 | ```php 87 | urlManager->createAbsoluteUrl(['site/password-reset', 'token' => $user->password_reset_token]); 95 | ?> 96 | 97 | Hello username) ?>, 98 | 99 | Follow the link below to reset your password: 100 | 101 | 102 | 103 | ``` 104 | > This template used for password reset email. 105 | 106 | 6) Add to SiteController (or configure via `$route` param in urlManager): 107 | ```php 108 | /** 109 | * @return array 110 | */ 111 | public function actions() 112 | { 113 | return [ 114 | 'login' => [ 115 | 'class' => 'yii2mod\user\actions\LoginAction' 116 | ], 117 | 'logout' => [ 118 | 'class' => 'yii2mod\user\actions\LogoutAction' 119 | ], 120 | 'signup' => [ 121 | 'class' => 'yii2mod\user\actions\SignupAction' 122 | ], 123 | 'request-password-reset' => [ 124 | 'class' => 'yii2mod\user\actions\RequestPasswordResetAction' 125 | ], 126 | 'password-reset' => [ 127 | 'class' => 'yii2mod\user\actions\PasswordResetAction' 128 | ], 129 | ]; 130 | } 131 | ``` 132 | 133 | You can then access to this actions through the following URL: 134 | 135 | 1. http://localhost/site/login 136 | 2. http://localhost/site/logout 137 | 3. http://localhost/site/signup 138 | 4. http://localhost/site/request-password-reset 139 | 5. http://localhost/site/password-reset 140 | 141 | 7) Also some actions send flash messages, so you should use an AlertWidget to render flash messages on your site. 142 | 143 | Using action events 144 | ------------------- 145 | 146 | You may use the following events: 147 | 148 | ```php 149 | /** 150 | * @return array 151 | */ 152 | public function actions() 153 | { 154 | return [ 155 | 'login' => [ 156 | 'class' => 'yii2mod\user\actions\LoginAction', 157 | 'on beforeLogin' => function ($event) { 158 | // your custom code 159 | }, 160 | 'on afterLogin' => function ($event) { 161 | // your custom code 162 | }, 163 | ], 164 | 'logout' => [ 165 | 'class' => 'yii2mod\user\actions\LogoutAction', 166 | 'on beforeLogout' => function ($event) { 167 | // your custom code 168 | }, 169 | 'on afterLogout' => function ($event) { 170 | // your custom code 171 | }, 172 | ], 173 | 'signup' => [ 174 | 'class' => 'yii2mod\user\actions\SignupAction', 175 | 'on beforeSignup' => function ($event) { 176 | // your custom code 177 | }, 178 | 'on afterSignup' => function ($event) { 179 | // your custom code 180 | }, 181 | ], 182 | 'request-password-reset' => [ 183 | 'class' => 'yii2mod\user\actions\RequestPasswordResetAction', 184 | 'on beforeRequest' => function ($event) { 185 | // your custom code 186 | }, 187 | 'on afterRequest' => function ($event) { 188 | // your custom code 189 | }, 190 | ], 191 | 'password-reset' => [ 192 | 'class' => 'yii2mod\user\actions\PasswordResetAction', 193 | 'on beforeReset' => function ($event) { 194 | // your custom code 195 | }, 196 | 'on afterReset' => function ($event) { 197 | // your custom code 198 | }, 199 | ], 200 | ]; 201 | } 202 | ``` 203 | 204 | # Console commands 205 | 206 | ## Setup 207 | To enable console commands, you need to add module into console config of you app. 208 | `/config/console.php` in yii2-app-basic template, or `/console/config/main.php` in yii2-app-advanced. 209 | 210 | ```php 211 | 212 | return [ 213 | 'id' => 'app-console', 214 | 'modules' => [ 215 | 'user' => [ 216 | 'class' => 'yii2mod\user\ConsoleModule', 217 | ], 218 | ], 219 | 220 | ``` 221 | 222 | ## Available console actions 223 | 224 | - **user/create** - Creates a new user. 225 | 226 | ```sh 227 | 228 | ./yii user/create 229 | 230 | - email (required): string 231 | - username (required): string 232 | - password (required): string 233 | 234 | ``` 235 | 236 | - **user/role/assign** - Assign role to the user. 237 | 238 | ```sh 239 | 240 | ./yii user/role/assign 241 | 242 | - roleName (required): string 243 | - email (required): string 244 | 245 | ``` 246 | 247 | - **user/role/revoke** - Revoke role from the user. 248 | 249 | ```sh 250 | 251 | ./yii user/role/revoke 252 | 253 | - roleName (required): string 254 | - email (required): string 255 | 256 | ``` 257 | 258 | - **user/delete** - Deletes a user. 259 | 260 | ```sh 261 | 262 | ./yii user/delete 263 | 264 | - email (required): string 265 | 266 | ``` 267 | 268 | - **user/update-password** - Updates user's password to given. 269 | 270 | ```sh 271 | 272 | ./yii user/update-password 273 | 274 | - email (required): string 275 | - password (required): string 276 | 277 | ``` 278 | 279 | Internationalization 280 | ---------------------- 281 | 282 | All text and messages introduced in this extension are translatable under category 'yii2mod.user'. 283 | You may use translations provided within this extension, using following application configuration: 284 | 285 | ```php 286 | return [ 287 | 'components' => [ 288 | 'i18n' => [ 289 | 'translations' => [ 290 | 'yii2mod.user' => [ 291 | 'class' => 'yii\i18n\PhpMessageSource', 292 | 'basePath' => '@yii2mod/user/messages', 293 | ], 294 | // ... 295 | ], 296 | ], 297 | // ... 298 | ], 299 | // ... 300 | ]; 301 | ``` 302 | 303 | ## Support us 304 | 305 | Does your business depend on our contributions? Reach out and support us on [Patreon](https://www.patreon.com/yii2mod). 306 | All pledges will be dedicated to allocating workforce on maintenance and new awesome stuff. 307 | --------------------------------------------------------------------------------