├── .gitignore ├── README.md ├── composer.json ├── docs ├── BusinessConcept.md ├── GeneralUsage.md ├── Installation.md ├── README.md ├── Troubleshotting.md ├── advanced │ └── Configuration.md ├── basic │ └── Configuration.md └── simple │ └── Configuration.md └── src ├── Bootstrap.php ├── Helper.php ├── base ├── Action.php ├── ActiveRecord.php ├── Command.php ├── ConsoleController.php ├── Model.php ├── Module.php ├── WebController.php ├── actions │ ├── ChangePasswordAction.php │ ├── LoginAction.php │ ├── LogoutAction.php │ └── RegisterAction.php ├── migrations │ └── BaseMigration.php ├── models │ ├── ChangePasswordForm.php │ ├── LoginForm.php │ ├── RegisterForm.php │ └── UserAccounts.php └── traits │ └── AjaxValidationTrait.php ├── basic ├── EmailableInterface.php ├── Mailer.php ├── Module.php ├── UserConfirmableInterface.php ├── UserRecoveryableInterface.php ├── actions │ ├── CommandCreateAction.php │ ├── ConfirmAction.php │ ├── RecoveryPasswordAction.php │ ├── ResendConfirmAction.php │ └── ResetPasswordAction.php ├── commands │ └── UserController.php ├── controllers │ ├── ManagerController.php │ └── SecurityController.php ├── migrations │ └── m150703_191015_init.php ├── models │ ├── LoginForm.php │ ├── RecoveryForm.php │ ├── RegisterForm.php │ ├── ResendForm.php │ └── UserAccounts.php └── views │ ├── mails │ ├── html │ │ ├── confirm.php │ │ ├── recovery.php │ │ └── reset.php │ ├── layouts │ │ ├── html.php │ │ └── text.php │ └── text │ │ ├── confirm.php │ │ ├── recovery.php │ │ └── reset.php │ ├── manager │ ├── _columns.php │ ├── _form.php │ ├── create.php │ ├── index.php │ ├── update.php │ └── view.php │ └── security │ ├── confirm.php │ ├── login.php │ ├── recovery.php │ ├── register.php │ ├── resend.php │ └── reset.php ├── messages └── vi │ └── user.php └── simple ├── Module.php ├── actions └── CommandCreateAction.php ├── commands └── UserController.php ├── controllers ├── ManagerController.php └── SecurityController.php ├── migrations └── m150703_191015_init.php ├── models ├── ChangePasswordForm.php ├── LoginForm.php ├── RegisterForm.php ├── UserAccounts.php └── UserSearch.php └── views ├── manager ├── _assignment.php ├── _columns.php ├── _detail.php ├── _form.php ├── create.php ├── index.php ├── update.php └── view.php └── security ├── change-password.php ├── login.php └── register.php /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | nbproject 12 | vendor 13 | composer 14 | composer.lock 15 | composer.phar 16 | 17 | # Windows Installer files 18 | *.cab 19 | *.msi 20 | *.msm 21 | *.msp 22 | 23 | # Windows shortcuts 24 | *.lnk 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #Yii2-user-plus 2 | 3 | [![Latest Stable Version](https://poser.pugx.org/johnitvn/yii2-user-plus/v/stable)](https://packagist.org/packages/johnitvn/yii2-user-plus) 4 | [![License](https://poser.pugx.org/johnitvn/yii2-user-plus/license)](https://packagist.org/packages/johnitvn/yii2-user-plus) 5 | [![Total Downloads](https://poser.pugx.org/johnitvn/yii2-user-plus/downloads)](https://packagist.org/packages/johnitvn/yii2-user-plus) 6 | [![Monthly Downloads](https://poser.pugx.org/johnitvn/yii2-user-plus/d/monthly)](https://packagist.org/packages/johnitvn/yii2-user-plus) 7 | [![Daily Downloads](https://poser.pugx.org/johnitvn/yii2-user-plus/d/daily)](https://packagist.org/packages/johnitvn/yii2-user-plus) 8 | 9 | User Plus is high flexible user management extension for yii2. 10 | 11 | Most of web applications need user management feature. Notwithstanding it simple or advance application. Some applications need need register and login function. Some applications just need login feature login. 12 | Or some applications else need reset forgotten passwords feature. Rather than re-implementing this on each application, you can use which is a high flexible user management module for Yii2 that handles common tasks such as authentication, registration, confirmation and password retrieval and more. Special not only you can choose business model match your user management requirement. But also you just need override what you want to change. You can override one of views, one of controller, even one of action of controller which don't need to change anything else. User Plus can easy extend, too. 13 | 14 | 15 | ##Document 16 | [Modules Business Concept](https://github.com/johnitvn/yii2-user-plus/blob/master/docs/BusinessConcept.md)
17 | [Instalation](https://github.com/johnitvn/yii2-user-plus/blob/master/docs/Installation.md)
18 | [General Usage](https://github.com/johnitvn/yii2-user-plus/blob/master/docs/GeneralUsage.md)
19 | [Definitive Guide](https://github.com/johnitvn/yii2-user-plus/tree/master/docs)
20 | 21 | 22 | 23 | ##Development roadmap 24 | #### Version 1.0.0 (Released as beta version) 25 | Features of this version: 26 | + Manager user 27 | + Registration,Signin,Signout handler 28 | + Recovery password handler 29 | + Confirmation hanler 30 | 31 | #### Version 1.1.0 32 | Features of this version: 33 | + All of feature in version 1.0.0 34 | + Social authencation 35 | + User profile handler 36 | 37 | #### Version 1.2.0 38 | + All of feature in lower version 39 | + OAuth login 40 | + Api for manager user 41 | 42 | 43 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "johnitvn/yii2-user-plus", 3 | "description":"High flexible user management extension for yii2", 4 | "type": "yii2-extension", 5 | "license": "Apache-2.0", 6 | "authors": [ 7 | { 8 | "name": "John Martin", 9 | "email": "john.itvn@gmail.com", 10 | "homepage": "https://github.com/johnitvn?tab=repositories" 11 | } 12 | ], 13 | "support": { 14 | "issues": "https://github.com/johnitvn/yii2-user-plus/issues?state=open", 15 | "source": "https://github.com/johnitvn/yii2-user-plus" 16 | }, 17 | "suggest": { 18 | "johnitvn/yii2-rbac-plus": "Database role base access control manager for yii2" 19 | }, 20 | "minimum-stability": "dev", 21 | "require": { 22 | "yiisoft/yii2": ">=2.0.4", 23 | "yiisoft/yii2-bootstrap": "~2.0", 24 | "yiisoft/yii2-swiftmailer": "~2.0", 25 | "yiisoft/yii2-authclient": "~2.0", 26 | "yiisoft/yii2-jui": "*", 27 | "johnitvn/yii2-ajaxcrud": "2.0.3" 28 | }, 29 | "autoload": { 30 | "psr-4": { 31 | "johnitvn\\userplus\\": "src/" 32 | } 33 | }, 34 | "extra": { 35 | "bootstrap": "johnitvn\\userplus\\Bootstrap" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /docs/BusinessConcept.md: -------------------------------------------------------------------------------- 1 | Modules business concept 2 | ----- 3 | User Plus provider 3 modules(simple,basic and advanced). 4 | Per module contain one concept for handler user management workflow. 5 | You must understanding concept of three module. 6 | 7 | #####1. Simple Module: 8 | As name of module, it useful for simple business. 9 | ###### The feature of this module is: 10 | + User login handler(You can choose login is username/email) 11 | + User register handler(You can enable/disable user register) 12 | + User logout handler 13 | + CRUD operations for user management 14 | + Create administrator( Just accept create administrator from command) 15 | 16 | ###### When do you should use simple module? 17 | + You have simple business with user flow 18 | + You don't need register confirmation function 19 | + Example: You have backend application for manager products. So you just need login feature and don't need user register. 20 | So simple module is best choice for you 21 | 22 | #####2. Basic Module: 23 | ###### Basic module contain all features of simple module and following below 24 | + After user register, application will send an email to user. And user must go to confirm link in email to confirm their account. 25 | + You can disable/enable confirmation feature 26 | + You can disable/enable unconfirmed user login, too 27 | + Additionally user can recovery password via email 28 | + You can disable/enable recovery password function 29 | + Because user confirmation and recovery password need send email to user. So this module required user register with username, email and password. You sill can choose login with email/username like simple module 30 | 31 | ###### When do you should use simple module? 32 |     (Updating) 33 | 34 | #####3. Advance Module: 35 |     (Developing) -------------------------------------------------------------------------------- /docs/GeneralUsage.md: -------------------------------------------------------------------------------- 1 | Usage 2 | ----- 3 | 4 | ###Console commands: 5 | You only can manager user when your account is administrator. 6 | So you must create administrator via command user/create-admin in the fist. 7 | And after that you can login and manager user. You also can set administrator to other user when your account is administrator. 8 | 9 | ````bash 10 | $ yii 11 | - user User manager commands 12 | user/create-admin Create new administrator account. 13 | ```` 14 | 15 | Now let run console command. And enter your account information. 16 | 17 | ```bash 18 | $ yii user/create-admin 19 | ``` 20 | 21 | The information of account depending on the module you choose. 22 | Example for simple module you need username/email and password. 23 | The default login field is username. You can see [Configuration](https://github.com/johnitvn/yii2-user-plus/tree/master/docs#2-configuration) for more information 24 | 25 | ### Listing of available route 26 | After create administrator you can login to application , the listing of available route is:
27 | 28 | + /user/security/login 29 | + /user/security/logout 30 | + /user/security/register 31 | + /user/manager 32 | -------------------------------------------------------------------------------- /docs/Installation.md: -------------------------------------------------------------------------------- 1 | Installation 2 | ----- 3 | After you choose module business you want. Now, go to configuration. 4 | 5 | 1. The first add to web config following below: 6 | ````php 7 | 'modules'=>[ 8 | 'user'=>[ 9 | 'class'=>'johnitvn\userplus\{{ModuleName}}\Module', 10 | // You can add other config after 11 | ] 12 | ], 13 | 'components'=>[ 14 | 'user' => [ 15 | 'identityClass' => 'johnitvn\userplus\{{ModuleName}}\models\UserAccounts', 16 | ], 17 | ] 18 | ```` 19 | Let replace `{{ModuleName}}` to simple or basic or advanced 20 | 21 | 2. Next, add to console config following bellow: 22 | ````php 23 | 'modules'=>[ 24 | 'user'=>'johnitvn\userplus\{{ModuleName}}\Module', 25 | ], 26 | 'components'=>[ 27 | 'user' => [ 28 | 'class'=>'yii\web\User', 29 | 'identityClass' => 'johnitvn\userplus\{{ModuleName}}\models\UserAccounts', 30 | 'loginUrl'=>'/user/security/login' 31 | ], 32 | ] 33 | ```` 34 | 35 | 3. The last thing is run the migrate command 36 | ````bash 37 | $ yii migrate/up --migrationPath=@userplus/{{ModuleName}}/migrations 38 | ```` 39 | 40 | 4. Additional when you want to user basic/advanced module with confirmation and recovery password feature. You must config mailer component for send email 41 | ````php 42 | 'components' => [ 43 | 'mailer' => [ 44 | 'class' => 'yii\swiftmailer\Mailer', 45 | ], 46 | ], 47 | ```` 48 | 49 | You can read [Yii2 mailling tutorial](http://www.yiiframework.com/doc-2.0/guide-tutorial-mailing.html) for more detail about swift mailer 50 | 51 | This example will show to you sending email via remote smtp server (gmail) 52 | 53 | ````php 54 | 'mailer' => [ 55 | 'class' => 'yii\swiftmailer\Mailer', 56 | 'transport' => [ 57 | 'class' => 'Swift_SmtpTransport', 58 | 'host' => 'localhost', 59 | 'username' => 'username', 60 | 'password' => 'password', 61 | 'port' => '587', 62 | 'encryption' => 'tls', 63 | ], 64 | ], 65 | ```` -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | #Definitive guide User Plus 2 | 3 | ## 1. Getting started with User Plus 4 | Quick guide to getting started with User Plus Module 5 | 6 | 1.1 [Modules Business Concept](https://github.com/johnitvn/yii2-user-plus/blob/master/docs/BusinessConcept.md)
7 | 1.2 [Instalation](https://github.com/johnitvn/yii2-user-plus/blob/master/docs/Installation.md)
8 | 1.3 [General Usage](https://github.com/johnitvn/yii2-user-plus/blob/master/docs/GeneralUsage.md)
9 | 1.4 [Troubleshotting](https://github.com/johnitvn/yii2-user-plus/blob/master/docs/Troubleshotting.md)
10 | 11 | 12 | ## 2. Configuration 13 | This section will be show to use how to config User Plus Module. You must select for yourself one module matching business. 14 | 15 | 2.1 [Configuration for simple module](https://github.com/johnitvn/yii2-user-plus/blob/master/docs/simple/Configuration.md)
16 | 2.2 [Configuration for basic module](https://github.com/johnitvn/yii2-user-plus/blob/master/docs/basic/Configuration.md)
17 | 2.3 [Configuration for advanced module](https://github.com/johnitvn/yii2-user-plus/blob/master/docs/advanced/Configuration.md)
18 | -------------------------------------------------------------------------------- /docs/Troubleshotting.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnitvn/yii2-user-plus/c89a643f5285222f7b6d5877e80cc82cb3e766ad/docs/Troubleshotting.md -------------------------------------------------------------------------------- /docs/advanced/Configuration.md: -------------------------------------------------------------------------------- 1 | Configuration for advanced module 2 | --- 3 | 4 | >Updatting -------------------------------------------------------------------------------- /docs/basic/Configuration.md: -------------------------------------------------------------------------------- 1 | Configuration for basic module 2 | --- 3 | 4 | >Updatting 5 | -------------------------------------------------------------------------------- /docs/simple/Configuration.md: -------------------------------------------------------------------------------- 1 | Configuration for simple module 2 | --- 3 | 4 | List of simple module config variable avaiable: 5 | 6 | + rememberFor(integer): Time to remember user login.
7 | + Default time rememberFor is 3600*24(1 day). 8 | + You must set `rememberFor=0` or `enableAutoLogin=false` in the user component config to disable remember user login feature. 9 | + You must set `rememberFor>0` or `enableAutoLogin=true` in the user component config to enable remember user login feature. 10 | + enableRegister(boolean): Enable user register.
11 | Default user register is disable. 12 | + modelMap(array): Array of model mapping.
13 | Default list of model map for simple module is 14 | ````php 15 | [ 16 | 'UserSearch' => 'johnitvn\userplus\simple\models\UserSearch', 17 | 'UserAccounts' => 'johnitvn\userplus\simple\models\UserAccounts', 18 | 'LoginForm' => 'johnitvn\userplus\simple\models\LoginForm', 19 | 'RegisterForm' => 'johnitvn\userplus\simple\models\RegisterForm', 20 | 'ChangePasswordForm' => 'johnitvn\userplus\simple\models\ChangePasswordForm', 21 | ] 22 | ```` 23 | + enableSecurityHandler(boolean): Enable/Disable security controller. 24 | Default security handler is true. So you can access to routes `/user/security/*` 25 | 26 | -------------------------------------------------------------------------------- /src/Bootstrap.php: -------------------------------------------------------------------------------- 1 | 11 | * @since 1.0.0 12 | */ 13 | class Bootstrap implements BootstrapInterface { 14 | 15 | /** 16 | * Initial application compoments and modules need for extension 17 | * @param \yii\base\Application $app The application currently running 18 | * @return void 19 | */ 20 | public function bootstrap($app) { 21 | if (Yii::$app->hasModule('user')) { 22 | 23 | // Set alias for extension source 24 | Yii::setAlias("@userplus", __DIR__); 25 | Yii::setAlias("@johnitvn/userplus", __DIR__); 26 | 27 | // Setup i18n compoment for translate all category user* 28 | if (!isset(Yii::$app->get('i18n')->translations['user*'])) { 29 | Yii::$app->get('i18n')->translations['user*'] = [ 30 | 'class' => 'yii\i18n\PhpMessageSource', 31 | 'basePath' => __DIR__ . '/messages', 32 | ]; 33 | } 34 | 35 | 36 | if (Helper::isConsoleApplication()) { 37 | $module = Yii::$app->getModule('user'); 38 | // Mapping command controller 39 | foreach ($module->getCommandControllerMap() as $key => $value) { 40 | Yii::$app->controllerMap[$key] = [ 41 | 'class' => $value, 42 | ]; 43 | } 44 | // Don't catch all controller with its namespace 45 | $module->controllerNamespace = 'johnitvn\userplus\fake'; 46 | } 47 | 48 | if (Yii::$app->hasModule('rbac')) { 49 | $rbacModule = Yii::$app->getModule('rbac'); 50 | if (get_class($rbacModule) === 'johnitvn\rbacplus\Module') { 51 | $rbacModule->beforeCreateController = [$this, 'beforeRbacCreateController']; 52 | } 53 | } 54 | } 55 | } 56 | 57 | /** 58 | * Config for intergrate with Rbac plus extension 59 | * @param string $route 60 | * @return boolean 61 | * @throws \yii\web\ForbiddenHttpException 62 | */ 63 | public function beforeRbacCreateController($route) { 64 | $user = Yii::$app->user; 65 | if ($user->isGuest || !$user->identity->isAdministrator()) { 66 | throw new \yii\web\ForbiddenHttpException(Yii::t('yii', 'You are not allowed to perform this action.')); 67 | } 68 | return true; 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/Helper.php: -------------------------------------------------------------------------------- 1 | 8 | * @since 1.0.0 9 | */ 10 | class Helper { 11 | 12 | /** 13 | * Dump expression with PRE tag 14 | * @param mixed $expression The expression want to dump 15 | * @param bool $die exit application after dump or not 16 | * @return void 17 | * @see http://php.net/manual/en/function.var-dump.php 18 | */ 19 | public static function dump($expression, $die = false) { 20 | echo '
';
21 |         var_dump($expression);
22 |         echo '
'; 23 | !$die or die(); 24 | } 25 | 26 | /** 27 | * Check is yii console application or not. 28 | * @return boolean Return true if is console application 29 | */ 30 | public static function isConsoleApplication() { 31 | return \Yii::$app instanceof \yii\console\Application; 32 | } 33 | 34 | 35 | /** 36 | * Generate password 37 | * @return string The random password with 8 chars 38 | */ 39 | public static function generatePassword(){ 40 | return static::generateRandomString(8,false); 41 | } 42 | 43 | /** 44 | * Generate random string 45 | * @param integer $lenght The lenght of random string (Default: 32) 46 | * @param boolean $withTime With prefix timestamp or not 47 | * @param string $delimiter Delimiter string between time and random string 48 | * @return string Random string 49 | */ 50 | public static function generateRandomString($lenght = 32, $withTime = true, $delimiter = "$") { 51 | if ($withTime) { 52 | $time = strval(time()); 53 | $rString = \Yii::$app->security->generateRandomString($lenght - strlen($time)); 54 | return $time . $delimiter . $rString; 55 | } else { 56 | return \Yii::$app->security->generateRandomString($lenght); 57 | } 58 | } 59 | 60 | /** 61 | * 62 | * @param mixed $object 63 | * @return string the name space of object 64 | */ 65 | public static function getNamespace($object){ 66 | $class = new \ReflectionClass($object::className()); 67 | return $class->getNamespaceName(); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/base/Action.php: -------------------------------------------------------------------------------- 1 | User Plus extension. 10 | * 11 | * @author John Martin 12 | * @since 1.0.0 13 | */ 14 | class Action extends YiiAction { 15 | 16 | /** 17 | * @var Module The curent user plus module(Subclass of johnitvn\userplus\base\Module) 18 | */ 19 | protected $userPlusModule; 20 | 21 | /** 22 | * Initial of action 23 | */ 24 | public function init() { 25 | // get instance of user module 26 | $this->userPlusModule = Yii::$app->getModule('user'); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/base/ActiveRecord.php: -------------------------------------------------------------------------------- 1 | User Plus extension. 10 | * 11 | * @author John Martin 12 | * @since 1.0.0 13 | */ 14 | class ActiveRecord extends YiiActiveRecord { 15 | 16 | /** 17 | * @var Module The curent user plus module(Subclass of johnitvn\userplus\base\Module) 18 | */ 19 | protected $userPlusModule; 20 | 21 | /** 22 | * Initial of action 23 | */ 24 | public function init() { 25 | // get instance of user module 26 | $this->userPlusModule = Yii::$app->getModule('user'); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/base/Command.php: -------------------------------------------------------------------------------- 1 | User Plus extension. 10 | * 11 | * @author John Martin 12 | * @since 1.0.0 13 | * @property ConsoleController $controller 14 | */ 15 | class Command extends YiiAction { 16 | 17 | /** 18 | * @var Module The curent user plus module(Subclass of johnitvn\userplus\base\Module) 19 | */ 20 | protected $userPlusModule; 21 | 22 | /** 23 | * Initial of action 24 | */ 25 | public function init() { 26 | // get instance of user module 27 | $this->userPlusModule = Yii::$app->getModule('user'); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/base/ConsoleController.php: -------------------------------------------------------------------------------- 1 | User Plus extension. 10 | * 11 | * @author John Martin 12 | * @since 1.0.0 13 | * 14 | */ 15 | class ConsoleController extends Controller { 16 | 17 | /** 18 | * @var Module The curent user plus module(Subclass of johnitvn\userplus\base\Module) 19 | */ 20 | protected $userPlusModule; 21 | 22 | /** 23 | * Initial of action 24 | */ 25 | public function init() { 26 | // get instance of user module 27 | $this->userPlusModule = Yii::$app->getModule('user'); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/base/Model.php: -------------------------------------------------------------------------------- 1 | User Plus extension. 10 | * 11 | * @author John Martin 12 | * @since 1.0.0 13 | */ 14 | class Model extends YiiModel { 15 | 16 | /** 17 | * @var Module The curent user plus module(Subclass of johnitvn\userplus\base\Module) 18 | */ 19 | protected $userPlusModule; 20 | 21 | /** 22 | * Initial of action 23 | */ 24 | public function init() { 25 | // get instance of user module 26 | $this->userPlusModule = Yii::$app->getModule('user'); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/base/Module.php: -------------------------------------------------------------------------------- 1 | User Plus extension 11 | * @author John Martin 12 | * @since 1.0.0 13 | */ 14 | abstract class Module extends YiiModule { 15 | 16 | /** 17 | * @var integer Time to remember user login. 18 | * Default is 1 day 19 | */ 20 | public $rememberFor = 3600 * 24; 21 | 22 | /** 23 | * @var boolean enableRegister Enable user register. 24 | * Default user register is disable 25 | */ 26 | public $enableRegister = false; 27 | 28 | /** 29 | * @var array modelMap Model mapping. 30 | * Use for extends module. 31 | */ 32 | public $modelMap = []; 33 | 34 | /** 35 | * 36 | * @var boolean Enable/Disable security controller 37 | */ 38 | public $enableSecurityHandler = true; 39 | private $rbac; 40 | 41 | /** 42 | * Initial module 43 | * @return void 44 | */ 45 | public function init() { 46 | // Initial model map 47 | $this->modelMap = ArrayHelper::merge($this->getDefaultModelMap(), $this->modelMap); 48 | $this->controllerNamespace = $this->getWebControllerNamespace(); 49 | } 50 | 51 | public function createControllerByID($id) { 52 | if ($id == 'security' && !$this->enableSecurityHandler) { 53 | return null; 54 | } else { 55 | return parent::createControllerByID($id); 56 | } 57 | } 58 | 59 | public function beforeAction($action) { 60 | $aId = $action->id; 61 | if ($aId == "register" && !$this->enableRegister) { 62 | throw new \yii\web\NotFoundHttpException("Page not found"); 63 | } else { 64 | return parent::beforeAction($action); 65 | } 66 | } 67 | 68 | public function getCommandControllerMap() { 69 | return []; 70 | } 71 | 72 | /** 73 | * Return default model map for modules. 74 | * When user not config model for map so we will get model class 75 | * from this default model map 76 | * @return array Default model map 77 | */ 78 | abstract protected function getDefaultModelMap(); 79 | 80 | /** 81 | * Return web controller namespace. 82 | * @return string The web app controller namespace 83 | */ 84 | abstract protected function getWebControllerNamespace(); 85 | 86 | /** 87 | * Return console controller namespace. 88 | * @return array The console app controller namespace 89 | */ 90 | abstract protected function getConsoleControllerNamespace(); 91 | 92 | /** 93 | * Get model class from model map. 94 | * 95 | * @param string $name The name of model 96 | * @return string The model's class 97 | * 98 | * @see Module::$modelMap 99 | */ 100 | public function getModelClassName($name) { 101 | return $this->modelMap[$name]; 102 | } 103 | 104 | /** 105 | * Create instance of model with name of model and config. 106 | * This function will get class of model from Module::getModelClass() 107 | * And create instance of that class with array config input 108 | * @param type $name 109 | * @param array $config 110 | */ 111 | public function createModelInstance($name, array $config = []) { 112 | $config['class'] = $this->getModelClassName($name); 113 | return Yii::createObject($config); 114 | } 115 | 116 | } 117 | -------------------------------------------------------------------------------- /src/base/WebController.php: -------------------------------------------------------------------------------- 1 | User Plus extension. 9 | * 10 | * @author John Martin 11 | * @since 1.0.0 12 | */ 13 | class WebController extends Controller { 14 | 15 | /** 16 | * @var Module The curent user plus module(Subclass of johnitvn\userplus\base\Module) 17 | */ 18 | protected $userPlusModule; 19 | 20 | /** 21 | * Initial of action 22 | */ 23 | public function init() { 24 | // get instance of user module 25 | $this->userPlusModule = Yii::$app->getModule('user'); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/base/actions/ChangePasswordAction.php: -------------------------------------------------------------------------------- 1 | 12 | * @since 1.0.0 13 | */ 14 | class ChangePasswordAction extends Action{ 15 | 16 | use AjaxValidationTrait; 17 | 18 | /** 19 | * @var string the view file to be rendered. If not set, it will take the value of [[id]]. 20 | * That means, if you name the action as "error" in "SiteController", then the view name 21 | * would be "error", and the corresponding view file would be "views/site/error.php". 22 | */ 23 | public $view; 24 | 25 | /** 26 | * Runs the change password action. 27 | * After change password application will force user to relogin 28 | * ````php 29 | * $user = Yii::$app->getUser(); 30 | * $user->logout(); 31 | * return $this->controller->redirect($user->loginUrl); 32 | * ```` 33 | * @return string result content 34 | */ 35 | public function run() { 36 | $model = $this->userPlusModule->createModelInstance('ChangePasswordForm'); 37 | 38 | $this->performAjaxValidation($model); 39 | 40 | if ($model->load(Yii::$app->request->post()) && $model->changePassword()) { 41 | $user = Yii::$app->getUser(); 42 | $user->logout(); 43 | return $this->controller->redirect($user->loginUrl); 44 | } else { 45 | $view = $this->view == null ? $this->id : $this->view; 46 | return $this->controller->render($view, [ 47 | 'model' => $model, 48 | ]); 49 | } 50 | } 51 | 52 | 53 | } -------------------------------------------------------------------------------- /src/base/actions/LoginAction.php: -------------------------------------------------------------------------------- 1 | 11 | * @since 1.0.0 12 | */ 13 | class LoginAction extends Action{ 14 | 15 | use AjaxValidationTrait; 16 | 17 | /** 18 | * @var string the view file to be rendered. If not set, it will take the value of [[id]]. 19 | * That means, if you name the action as "error" in "SiteController", then the view name 20 | * would be "error", and the corresponding view file would be "views/site/error.php". 21 | */ 22 | public $view; 23 | 24 | /** 25 | * Runs the login action. 26 | * Afther login action application will to redirect to back url user request 27 | * ````php 28 | * $this->controller->goBack() 29 | * ```` 30 | * @return string result content 31 | */ 32 | public function run() { 33 | $model = $this->userPlusModule->createModelInstance('LoginForm'); 34 | 35 | $this->performAjaxValidation($model); 36 | 37 | if ($model->load(Yii::$app->request->post()) && $model->login()) { 38 | return $this->controller->goHome(); 39 | } else { 40 | $view = $this->view == null ? $this->id : $this->view; 41 | return $this->controller->render($view, [ 42 | 'model' => $model, 43 | ]); 44 | } 45 | } 46 | 47 | 48 | } -------------------------------------------------------------------------------- /src/base/actions/LogoutAction.php: -------------------------------------------------------------------------------- 1 | 11 | * @since 1.0.0 12 | */ 13 | class LogoutAction extends Action{ 14 | 15 | use AjaxValidationTrait; 16 | 17 | /** 18 | * Runs the logout action. 19 | * After logout application will redirect to login 20 | * ````php 21 | * $this->controller->redirect(ii::$app->getUser()->loginUrl); 22 | * ```` 23 | * @return string result content 24 | */ 25 | public function run() { 26 | $user = Yii::$app->getUser(); 27 | $user->logout(); 28 | return $this->controller->redirect($user->loginUrl); 29 | } 30 | 31 | 32 | } -------------------------------------------------------------------------------- /src/base/actions/RegisterAction.php: -------------------------------------------------------------------------------- 1 | 11 | * @since 1.0.0 12 | */ 13 | class RegisterAction extends Action{ 14 | 15 | use AjaxValidationTrait; 16 | 17 | /** 18 | * @var string the view file to be rendered. If not set, it will take the value of [[id]]. 19 | * That means, if you name the action as "error" in "SiteController", then the view name 20 | * would be "error", and the corresponding view file would be "views/site/error.php". 21 | */ 22 | public $view; 23 | 24 | /** 25 | * Runs the register action 26 | * After register application will redirect to login url 27 | * ````php 28 | * $this->controller->redirect($user->loginUrl) 29 | * ```` 30 | * @return string result content 31 | */ 32 | public function run() { 33 | $model = $this->userPlusModule->createModelInstance('RegisterForm'); 34 | 35 | $this->performAjaxValidation($model); 36 | 37 | if ($model->load(Yii::$app->request->post()) && $model->register()) { 38 | $user = Yii::$app->getUser(); 39 | return $this->controller->redirect($user->loginUrl); 40 | } else { 41 | $view = $this->view == null ? $this->id : $this->view; 42 | return $this->controller->render($view, [ 43 | 'model' => $model, 44 | ]); 45 | } 46 | } 47 | 48 | 49 | } -------------------------------------------------------------------------------- /src/base/migrations/BaseMigration.php: -------------------------------------------------------------------------------- 1 | 8 | * @since 1.0.0 9 | */ 10 | class BaseMigration extends \yii\db\Migration 11 | { 12 | /** 13 | * @var string 14 | */ 15 | protected $tableOptions; 16 | /** 17 | * @inheritdoc 18 | */ 19 | public function init() 20 | { 21 | parent::init(); 22 | switch (Yii::$app->db->driverName) { 23 | case 'mysql': 24 | $this->tableOptions = 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=InnoDB'; 25 | break; 26 | case 'pgsql': 27 | 28 | $this->tableOptions = null; 29 | break; 30 | default: 31 | throw new \RuntimeException('Your database is not supported!'); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /src/base/models/ChangePasswordForm.php: -------------------------------------------------------------------------------- 1 | 12 | * @since 1.0.0 13 | */ 14 | class ChangePasswordForm extends Model{ 15 | 16 | /** 17 | * @var string User email address 18 | */ 19 | public $old_password; 20 | 21 | /** 22 | * @var string Password 23 | */ 24 | public $new_password; 25 | 26 | /** 27 | * @var string Confirm Password 28 | */ 29 | public $confirm_password; 30 | 31 | 32 | /** 33 | * @inheritdoc 34 | */ 35 | public function rules() 36 | { 37 | return [ 38 | // email rules 39 | 'oldPasswordRequired' => ['old_password', 'required'], 40 | 41 | // password rules 42 | 'newPasswordRequired' => ['new_password', 'required'], 43 | 'newPasswordLength' => ['new_password', 'string', 'min' => 6], 44 | 45 | // confirm password rules 46 | 'confirmPasswordRequired' => ['confirm_password', 'required'], 47 | 'confirmPasswordCompare' => ['confirm_password', 'compare', 'compareAttribute'=>'new_password', 'message'=>Yii::t("user","Comfirm Passwords don't match")], 48 | ]; 49 | } 50 | 51 | /** 52 | * @inheritdoc 53 | */ 54 | public function attributeLabels() 55 | { 56 | return [ 57 | 'old_password' => Yii::t('user', 'Old Password'), 58 | 'new_password' => Yii::t('user', 'New Password'), 59 | 'confirm_password' => Yii::t('user', 'Comfirm New Password'), 60 | ]; 61 | 62 | 63 | 64 | } 65 | 66 | /** 67 | * @inheritdoc 68 | */ 69 | public function formName() 70 | { 71 | return 'change-password-form'; 72 | } 73 | 74 | /** 75 | * Change pasword of current user loged in. 76 | * 77 | * @return bool Change pasword was success or not 78 | */ 79 | public function changePassword() 80 | { 81 | if (!$this->validate()) { 82 | return false; 83 | } 84 | 85 | $modelClass = $this->userPlusModule->getModelClassName('UserAccounts'); 86 | $user = call_user_func($modelClass."::findOne",Yii::$app->user->getId()); 87 | $user->scenario = 'change_password'; 88 | 89 | $this->loadAttributes($user); 90 | if (!$user->changePassword()) { 91 | $this->addErrors($user->getErrors()); 92 | return false; 93 | } 94 | 95 | return true; 96 | } 97 | 98 | /** 99 | * Loads attributes to the user model. 100 | * @param UserAccounts $user 101 | */ 102 | protected function loadAttributes($user){ 103 | $user->setAttributes($this->attributes); 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /src/base/models/LoginForm.php: -------------------------------------------------------------------------------- 1 | 11 | * @since 1.0.0 12 | */ 13 | class LoginForm extends Model{ 14 | 15 | /** @var string The login field*/ 16 | public $login; 17 | 18 | /** @var string User's plain password */ 19 | public $password; 20 | 21 | /** @var string Whether to remember the user */ 22 | public $rememberMe = false; 23 | 24 | /** @var johnitvn\userplus\base\models\UserAccounts The instance of johnitvn\userplus\base\models\UserAccounts*/ 25 | protected $user; 26 | 27 | 28 | /** @inheritdoc */ 29 | public function attributeLabels() 30 | { 31 | return [ 32 | 'login' => Yii::t('user', 'Login'), 33 | 'password' => Yii::t('user', 'Password'), 34 | 'rememberMe' => Yii::t('user', 'Remember me next time'), 35 | ]; 36 | } 37 | 38 | /** @inheritdoc */ 39 | public function formName() 40 | { 41 | return 'login-form'; 42 | } 43 | 44 | 45 | /** @inheritdoc */ 46 | public function beforeValidate() 47 | { 48 | if (parent::beforeValidate()) { 49 | $userClassName = $this->userPlusModule->getModelClassName('UserAccounts'); 50 | $this->user = call_user_func($userClassName.'::findIdentityByLogin',$this->login); 51 | return true; 52 | } else { 53 | return false; 54 | } 55 | } 56 | 57 | 58 | /** @inheritdoc */ 59 | public function rules() 60 | { 61 | return [ 62 | 'requiredFields' => [['login', 'password'], 'required'], 63 | 'loginTrim' => ['login', 'trim'], 64 | 'loginInfoValidate' => [ 65 | 'password', 66 | function ($attribute) { 67 | if ($this->user === null || !$this->user->validatePassword($this->password) ) { 68 | $this->addError($attribute, Yii::t('user', 'Invalid login or password')); 69 | } 70 | } 71 | ], 72 | 'accountAvaiable' => [ 73 | 'password', 74 | function ($attribute) { 75 | if ($this->user->isBlocked()) { 76 | $this->addError($attribute, Yii::t('user', 'Your account has been blocked')); 77 | } 78 | } 79 | ], 80 | 'rememberMe' => ['rememberMe', 'boolean'], 81 | ]; 82 | } 83 | 84 | /** 85 | * Validates form and logs the user in. 86 | * 87 | * @return bool whether the user is logged in successfully 88 | */ 89 | public function login() 90 | { 91 | if ($this->validate()) { 92 | return Yii::$app->getUser()->login($this->user,$this->rememberMe?$this->userPlusModule->rememberFor:0); 93 | } else { 94 | return false; 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/base/models/RegisterForm.php: -------------------------------------------------------------------------------- 1 | 11 | * @since 1.0.0 12 | */ 13 | class RegisterForm extends Model{ 14 | 15 | /** 16 | * @var string User email address 17 | */ 18 | public $login; 19 | 20 | /** 21 | * @var string Password 22 | */ 23 | public $password; 24 | 25 | /** 26 | * @var string Confirm Password 27 | */ 28 | public $confirm_password; 29 | 30 | 31 | /** 32 | * @inheritdoc 33 | */ 34 | public function rules() 35 | { 36 | return [ 37 | 'loginTrim' => ['login', 'filter', 'filter' => 'trim'], 38 | 'loginRequired' => ['login', 'required'], 39 | 'loginUnique' => [ 40 | 'login', 41 | 'unique', 42 | 'targetClass' => $this->userPlusModule->getModelClassName('UserAccounts'), 43 | 'message' => Yii::t('user', 'This account has already been taken') 44 | ], 45 | 'passwordRequired' => ['password', 'required'], 46 | 'passwordLength' => ['password', 'string', 'min' => 6], 47 | 'confirmPasswordRequired' => ['confirm_password', 'required'], 48 | 'confirmPasswordCompare' => ['confirm_password', 'compare', 'compareAttribute'=>'password', 'message'=>Yii::t("user","Comfirm Passwords don't match")], 49 | ]; 50 | } 51 | 52 | /** 53 | * @inheritdoc 54 | */ 55 | public function attributeLabels() 56 | { 57 | return [ 58 | 'login' => Yii::t('user', 'Login'), 59 | 'password' => Yii::t('user', 'Password'), 60 | 'confirm_password' => Yii::t('user', 'Comfirm Password'), 61 | ]; 62 | 63 | 64 | 65 | } 66 | 67 | /** 68 | * @inheritdoc 69 | */ 70 | public function formName() 71 | { 72 | return 'register-form'; 73 | } 74 | 75 | /** 76 | * Registers a new user account. 77 | * 78 | * @return bool registration was successful or not 79 | */ 80 | public function register() 81 | { 82 | if (!$this->validate()) { 83 | return false; 84 | } 85 | 86 | $user = $this->userPlusModule->createModelInstance('UserAccounts',['scenario' => 'register']); 87 | 88 | $this->loadAttributes($user); 89 | 90 | if (!$user->register()) { 91 | return false; 92 | } 93 | 94 | return true; 95 | } 96 | 97 | /** 98 | * Loads attributes to the user model. 99 | * @param UserAccounts $user 100 | */ 101 | protected function loadAttributes($user){ 102 | $user->setAttributes($this->attributes); 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /src/base/models/UserAccounts.php: -------------------------------------------------------------------------------- 1 | User Plus extension 10 | * @author John Martin 11 | * @since 1.0.0 12 | * 13 | * @property integer $id 14 | * @property string $login 15 | * @property string $username 16 | * @property string $password_hash 17 | * @property string $auth_key 18 | * @property integer $administrator 19 | * @property integer $creator 20 | * @property string $creator_ip 21 | * @property string $confirm_token 22 | * @property string $recovery_token 23 | * @property integer $blocked_at 24 | * @property integer $confirmed_at 25 | * @property integer $created_at 26 | * @property integer $updated_at 27 | */ 28 | class UserAccounts extends ActiveRecord implements IdentityInterface { 29 | 30 | /** 31 | * @var User Accounts Event 32 | */ 33 | const BEFORE_CREATE = 'beforeCreate'; 34 | 35 | /** 36 | * @var User Accounts Event 37 | */ 38 | const AFTER_CREATE = 'afterCreate'; 39 | 40 | /** 41 | * @var User Accounts Event 42 | */ 43 | const BEFORE_CONSOLE_CREATE = 'beforeConsoleCreate'; 44 | 45 | /** 46 | * @var User Accounts Event 47 | */ 48 | const AFTER_CONSOLE_CREATE = 'afterConsoleCreate'; 49 | 50 | /** 51 | * @var User Accounts Event 52 | */ 53 | const BEFORE_REGISTER = 'beforeRegister'; 54 | 55 | /** 56 | * @var User Accounts Event 57 | */ 58 | const AFTER_REGISTER = 'afterRegister'; 59 | 60 | /** 61 | * @var User Accounts Event 62 | */ 63 | const BEFORE_CHANGE_PASSWORD = 'beforeChangePassword'; 64 | 65 | /** 66 | * @var User Accounts Event 67 | */ 68 | const AFTER_CHANGE_PASSWORD = 'afterChangePassword'; 69 | 70 | /** 71 | * @var Use for creator field when user created by console application 72 | */ 73 | const CREATOR_BY_CONSOLE = -2; 74 | 75 | /** 76 | * @var Use for creator field when user registed by yourself 77 | */ 78 | const CREATOR_BY_REGISTER = -1; 79 | 80 | /** 81 | * 82 | * @var string User's plain password 83 | */ 84 | public $password; 85 | 86 | /** 87 | * 88 | * @var string User comfirm password(Need for creat,register,change password) 89 | */ 90 | public $confirm_password; 91 | 92 | 93 | /** 94 | * 95 | * @var string Old password use for change password 96 | */ 97 | public $old_password; 98 | 99 | /** 100 | * 101 | * @var string New password use for change password 102 | */ 103 | public $new_password; 104 | 105 | /** 106 | * Returns the validation rules for attributes. 107 | * @return array validation rules 108 | * @see http://www.yiiframework.com/doc-2.0/yii-base-model.html#rules()-detail 109 | */ 110 | public function rules() { 111 | return [ 112 | // login rules 113 | 'loginRequired' => ['login', 'required', 'on' => ['register', 'create', 'console-create']], 114 | 'loginLength' => ['login', 'string', 'max' => 255], 115 | 'loginUnique' => ['login', 'unique', 'message' => Yii::t('user', 'This account name has already been taken')], 116 | 'loginTrim' => ['login', 'trim'], 117 | // password rules 118 | 'passwordRequired' => ['password', 'required', 'on' => ['register', 'create', 'console-create']], 119 | 'passwordLength' => ['password', 'string', 'min' => 6], 120 | //confirm password rules 121 | 'confirmPasswordRequired' => ['password', 'required', 'on' => ['register', 'create']], 122 | 'confirmPasswordLength' => ['confirm_password', 'compare', 'compareAttribute' => 'password', 'message' => Yii::t("user", "Comfirm Passwords don't match")], 123 | 'oldPasswordRequired' => ['old_password', 'required', 'on' => ['change_password']], 124 | 125 | ]; 126 | } 127 | 128 | /** 129 | * Returns a list of scenarios and the corresponding active attributes. 130 | * @return array a list of scenarios and the corresponding active attributes. 131 | * @see http://www.yiiframework.com/doc-2.0/yii-base-model.html#scenarios()-detail 132 | */ 133 | public function scenarios() { 134 | return [ 135 | 'create' => ['login', 'password', 'confirm_password'], 136 | 'register' => ['login', 'password', 'confirm_password', 'confirm_token'], 137 | 'console-create' => ['login', 'password'], 138 | 'toggle-block' => ['blocked_at'], 139 | 'block' => ['blocked_at'], 140 | 'unblock' => ['blocked_at'], 141 | 'toggle-administrator' => ['administrator'], 142 | 'update'=> ['password', 'confirm_password'], 143 | 'change_password' => ['password', 'confirm_password','new_password','old_password'], 144 | ]; 145 | } 146 | 147 | /** 148 | * Returns the attribute labels. 149 | * @return array Attribute labels (name => label). 150 | * @see http://www.yiiframework.com/doc-2.0/yii-base-model.html#attributeLabels()-detail 151 | */ 152 | public function attributeLabels() 153 | { 154 | return [ 155 | 'id' => Yii::t('app', 'ID'), 156 | 'login' => Yii::t('app', 'Login'), 157 | 'password_hash' => Yii::t('app', 'Password Hash'), 158 | 'auth_key' => Yii::t('app', 'Auth Key'), 159 | 'administrator' => Yii::t('app', 'Administrator'), 160 | 'creator' => Yii::t('app', 'Creator'), 161 | 'creator_ip' => Yii::t('app', 'Creator Ip'), 162 | 'confirm_token' => Yii::t('app', 'Confirm Token'), 163 | 'recovery_token' => Yii::t('app', 'Recovery Token'), 164 | 'blocked_at' => Yii::t('app', 'Blocked At'), 165 | 'confirmed_at' => Yii::t('app', 'Confirmed At'), 166 | 'created_at' => Yii::t('app', 'Created At'), 167 | 'updated_at' => Yii::t('app', 'Updated At'), 168 | ]; 169 | } 170 | 171 | /** 172 | * This method is called at the beginning of inserting or updating a record. 173 | * @param boolean $insert whether this method called while inserting a record. 174 | * If false, it means the method is called while updating a record. 175 | * @return boolean whether the insertion or updating should continue. 176 | * If false, the insertion or updating will be cancelled. 177 | * @see http://www.yiiframework.com/doc-2.0/yii-db-baseactiverecord.html#beforeSave()-detail 178 | */ 179 | public function beforeSave($insert) { 180 | if ($insert) { 181 | $this->blocked_at = null; 182 | $this->created_at = time(); 183 | $this->updated_at = -1; 184 | } else { 185 | $this->updated_at = time(); 186 | } 187 | 188 | if ($this->password !== null) { 189 | $this->setPassword($this->password); 190 | } 191 | return true; 192 | } 193 | 194 | 195 | public function consoleCreate(){ 196 | $this->trigger(self::BEFORE_CONSOLE_CREATE); 197 | 198 | $this->administrator = true; 199 | $this->creator = self::CREATOR_BY_CONSOLE; 200 | $this->creator_ip = Yii::t('user','Local'); 201 | $this->confirmed_at = time(); 202 | 203 | if(!$this->save()){ 204 | return false; 205 | } 206 | $this->trigger(self::AFTER_CONSOLE_CREATE); 207 | return true; 208 | } 209 | 210 | 211 | /** 212 | * Create user 213 | * @return boolean whether user creat success 214 | */ 215 | public function create($creatorUserId){ 216 | $this->trigger(self::BEFORE_CREATE); 217 | 218 | $this->creator = $creatorUserId; 219 | $this->administrator = false; 220 | $this->confirmed_at = time(); 221 | $this->prepareCreatorIp(); 222 | 223 | if(!$this->save()){ 224 | return false; 225 | } 226 | $this->trigger(self::AFTER_CREATE); 227 | return true; 228 | } 229 | 230 | /** 231 | * Register user 232 | * @return boolean whether user register success 233 | */ 234 | public function register(){ 235 | $this->trigger(self::BEFORE_REGISTER); 236 | 237 | $this->administrator = false; 238 | $this->creator = self::CREATOR_BY_REGISTER; 239 | $this->prepareCreatorIp(); 240 | 241 | if(!$this->save()){ 242 | return false; 243 | } 244 | 245 | $this->trigger(self::AFTER_REGISTER); 246 | return true; 247 | } 248 | 249 | /** 250 | * Register user 251 | * @return boolean whether user register success 252 | */ 253 | public function changePassword(){ 254 | $this->trigger(self::BEFORE_CHANGE_PASSWORD); 255 | if($this->validatePassword($this->old_password)){ 256 | $this->password = $this->new_password; 257 | if(!$this->save()){ 258 | return false; 259 | } 260 | }else{ 261 | $this->addError('old_password',Yii::t("user","Your current password is not match")); 262 | return false; 263 | } 264 | 265 | 266 | $this->trigger(self::AFTER_CHANGE_PASSWORD); 267 | return true; 268 | } 269 | 270 | /** 271 | * Block user 272 | * @return boolean whether user block success 273 | */ 274 | public function block(){ 275 | $this->blocked_at = time(); 276 | return $this->save(); 277 | } 278 | 279 | /** 280 | * Unblock user 281 | * @return boolean whether user unblock success 282 | */ 283 | public function unblock(){ 284 | $this->blocked_at = null; 285 | return $this->save(); 286 | } 287 | 288 | /** 289 | * Toggle block user 290 | * @return boolean whether toogle success 291 | */ 292 | public function toggleBlock(){ 293 | $this->blocked_at = $this->blocked_at==null?time():null; 294 | return $this->Save(); 295 | } 296 | 297 | 298 | /** 299 | * Toggle administrator perimistion of user 300 | * @return boolean whether toogle success 301 | */ 302 | public function toggleAdministrator(){ 303 | $this->administrator = $this->administrator?0:1; 304 | return $this->Save(); 305 | } 306 | 307 | 308 | /** 309 | * Check user is actived status 310 | * 311 | * @return boolean whether user is actived 312 | */ 313 | public function isBlocked(){ 314 | return $this->blocked_at !== null ; 315 | } 316 | 317 | /** 318 | * Check administrator permistion of user 319 | * 320 | * @return boolean whether user is super user 321 | */ 322 | public function isAdministrator(){ 323 | return $this->administrator == true; 324 | } 325 | 326 | /** 327 | * Validates password 328 | * 329 | * @param string $password password to validate 330 | * @return boolean if password provided is valid for current user 331 | */ 332 | public function validatePassword($password) 333 | { 334 | return Yii::$app->security->validatePassword($password, $this->password_hash); 335 | } 336 | 337 | /** 338 | * Generates password hash from password and sets it to the model 339 | * 340 | * @param string $password 341 | */ 342 | public function setPassword($password) 343 | { 344 | $this->password_hash = Yii::$app->security->generatePasswordHash($password); 345 | } 346 | 347 | /** 348 | * Find user by login field 349 | * 350 | * @param string $email email to find 351 | * @return boolean|UserAccounts 352 | */ 353 | public static function findIdentityByLogin($login){ 354 | $model = static::findOne(['login'=>$login]); 355 | return $model; 356 | } 357 | 358 | /** 359 | * Finds an identity by the given ID. 360 | * @param string|integer $id the ID to be looked for 361 | * @return IdentityInterface the identity object that matches the given ID. 362 | * Null should be returned if such an identity cannot be found 363 | * or the identity is not in an active state (disabled, deleted, etc.) 364 | */ 365 | public static function findIdentity($id) { 366 | return static::findOne($id); 367 | } 368 | 369 | /** 370 | * Returns an ID that can uniquely identify a user identity. 371 | * @return string|integer an ID that uniquely identifies a user identity. 372 | */ 373 | public function getId() { 374 | return $this->id; 375 | } 376 | 377 | /** 378 | * Finds an identity by the given token. 379 | * @param mixed $token the token to be looked for 380 | * @param mixed $type the type of the token. The value of this parameter depends on the implementation. 381 | * For example, [[\yii\filters\auth\HttpBearerAuth]] will set this parameter to be `yii\filters\auth\HttpBearerAuth`. 382 | * @return IdentityInterface the identity object that matches the given token. 383 | * Null should be returned if such an identity cannot be found 384 | * or the identity is not in an active state (disabled, deleted, etc.) 385 | */ 386 | public static function findIdentityByAccessToken($token, $type = null) { 387 | throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.'); 388 | } 389 | 390 | /** 391 | * Returns a key that can be used to check the validity of a given identity ID. 392 | * 393 | * The key should be unique for each individual user, and should be persistent 394 | * so that it can be used to check the validity of the user identity. 395 | * 396 | * The space of such keys should be big enough to defeat potential identity attacks. 397 | * 398 | * This is required if [[User::enableAutoLogin]] is enabled. 399 | * @return string a key that is used to check the validity of a given identity ID. 400 | * @see validateAuthKey() 401 | */ 402 | public function getAuthKey() { 403 | return $this->auth_key; 404 | } 405 | 406 | /** 407 | * Validates the given auth key. 408 | * 409 | * This is required if [[User::enableAutoLogin]] is enabled. 410 | * @param string $authKey the given auth key 411 | * @return boolean whether the given auth key is valid. 412 | * @see getAuthKey() 413 | */ 414 | public function validateAuthKey($authKey) { 415 | return $this->getAuthKey() === $authKey; 416 | } 417 | 418 | public static function tableName() { 419 | return 'user_accounts'; 420 | } 421 | 422 | /** 423 | * Setup creator's ip is current client ip 424 | * @return void 425 | */ 426 | protected function prepareCreatorIp(){ 427 | if (!empty($_SERVER['HTTP_CLIENT_IP'])) { 428 | $this->creator_ip = $_SERVER['HTTP_CLIENT_IP']; 429 | } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { 430 | $this->creator_ip = $_SERVER['HTTP_X_FORWARDED_FOR']; 431 | } else { 432 | $this->creator_ip = $_SERVER['REMOTE_ADDR']; 433 | } 434 | } 435 | 436 | 437 | 438 | } 439 | -------------------------------------------------------------------------------- /src/base/traits/AjaxValidationTrait.php: -------------------------------------------------------------------------------- 1 | 13 | * @since 1.0.0 14 | */ 15 | trait AjaxValidationTrait 16 | { 17 | 18 | /** 19 | * Perform ajax validation. 20 | * 21 | * @param Model $model 22 | * 23 | * @throws \yii\base\ExitException 24 | */ 25 | protected function performAjaxValidation(Model $model) 26 | { 27 | if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) { 28 | Yii::$app->response->format = Response::FORMAT_JSON; 29 | echo json_encode(ActiveForm::validate($model)); 30 | Yii::$app->end(); 31 | } 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/basic/EmailableInterface.php: -------------------------------------------------------------------------------- 1 | 8 | * @since 1.0.0 9 | */ 10 | interface EmailableInterface { 11 | 12 | public function getEmail(); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/basic/Mailer.php: -------------------------------------------------------------------------------- 1 | 11 | * @since 1.0.0 12 | */ 13 | class Mailer extends Object { 14 | 15 | /** 16 | * @var string 17 | */ 18 | public $viewPath = '@userplus/basic/views/mails'; 19 | 20 | /** 21 | * @var string|array The sender's email
22 | * Default: `Yii::$app->params['adminEmail']` OR `no-reply@example.com` 23 | */ 24 | public $sender; 25 | 26 | /** 27 | * @var string The subject of welcome email 28 | */ 29 | public $welcomeSubject; 30 | 31 | /** 32 | * @var string The subject of comfirmation and recomfirmation email 33 | */ 34 | public $confirmationSubject; 35 | 36 | /** 37 | * @var string The subject of recovery password email 38 | */ 39 | public $recoverySubject; 40 | 41 | /** 42 | * @var string The subject of reset password email 43 | */ 44 | public $resetPasswordSubject; 45 | 46 | /** 47 | * Sends an email to a user after registration. 48 | * 49 | * @param EmailableInterface $user The user model implemented UserEmailSendable 50 | * @param array|null $data The data array pass to email view 51 | * @return bool 52 | */ 53 | public function sendWelcomeMessage(EmailableInterface $user, array $data = null) { 54 | // Get email send to 55 | $email = $user->getEmail(); 56 | return $this->send($email, $this->welcomeSubject, 'welcome', $data); 57 | } 58 | 59 | /** 60 | * Sends an email to a user with confirmation link. 61 | * 62 | * @param EmailableInterface $user The user model implemented UserEmailSendable 63 | * @param array|null $data The data array pass to email view 64 | * 65 | * @return bool 66 | */ 67 | public function sendConfirmationMessage(EmailableInterface $user, array $data = null) { 68 | // Get email send to 69 | $email = $user->getEmail(); 70 | // Send email 71 | return $this->send($email, $this->confirmationSubject, 'confirm', $data); 72 | } 73 | 74 | /** 75 | * Sends an email to a user with reconfirmation link. 76 | * 77 | * @param EmailableInterface $user The user model implemented UserEmailSendable 78 | * @param array|null $data The data array pass to email view 79 | * 80 | * @return bool 81 | */ 82 | public function sendReconfirmationMessage(EmailableInterface $user, array $data = null) { 83 | return $this->sendConfirmationMessage($user, $data); 84 | } 85 | 86 | /** 87 | * Sends an email to a user with recovery link. 88 | * 89 | * @param EmailableInterface $user The user model implemented UserEmailSendable 90 | * @param array|null $data The data array pass to email view 91 | * 92 | * @return bool 93 | */ 94 | public function sendRecoveryMessage(EmailableInterface $user, array $data = null) { 95 | // Get email send to 96 | $email = $user->getEmail(); 97 | // Send email 98 | return $this->send($email, $this->recoverySubject, 'recovery', $data); 99 | } 100 | 101 | public function sendResetPasswordMessage(EmailableInterface $user, array $data = null) { 102 | // Get email send to 103 | $email = $user->getEmail(); 104 | // Send email 105 | return $this->send($email, $this->resetPasswordSubject, 'reset', $data); 106 | } 107 | 108 | /** 109 | * Do send email email 110 | * @param string $to 111 | * @param string $subject 112 | * @param string $view 113 | * @param array|null $params 114 | * 115 | * @return bool 116 | */ 117 | protected function send($to, $subject, $view, array $data = null) { 118 | /** @var \yii\mail\BaseMailer $mailer */ 119 | $mailer = Yii::$app->mailer; 120 | $mailer->viewPath = $this->viewPath; 121 | 122 | if ($this->sender === null) { 123 | $this->sender = isset(Yii::$app->params['adminEmail']) ? Yii::$app->params['adminEmail'] : 'no-reply@example.com'; 124 | } 125 | 126 | return $mailer->compose(['html' => 'html/' . $view, 'text' => 'text/' . $view], $data) 127 | ->setTo($to) 128 | ->setFrom($this->sender) 129 | ->setSubject($subject) 130 | ->send(); 131 | } 132 | 133 | } 134 | -------------------------------------------------------------------------------- /src/basic/Module.php: -------------------------------------------------------------------------------- 1 | 25 | * @since 1.0.0 26 | * 27 | */ 28 | class Module extends BaseModule { 29 | 30 | public $enableUnconfirmedLogin = true; 31 | public $enableConfirmation = false; 32 | public $confirmWithin = 86400; // 24 hours 33 | public $confirmationHandlerRoute = '/user/security/confirm'; 34 | public $enableRecoveryPassword = false; 35 | public $resetPasswordHandlerRoute = '/user/security/reset'; 36 | 37 | /** 38 | * 39 | * @var integer The lenght of token use for recovery and confirmation 40 | */ 41 | public $tokenLenght = 32; 42 | 43 | /** 44 | * 45 | * @var johnitvn\userplus\basic\Mailer The mailer instance 46 | */ 47 | public $mailer; 48 | 49 | public function init() { 50 | parent::init(); 51 | $mailer = \yii\helpers\ArrayHelper::merge($this->mailer, ['class' => 'johnitvn\userplus\basic\Mailer']); 52 | $this->mailer = \Yii::createObject($mailer); 53 | } 54 | 55 | public function getCommandControllerMap() { 56 | return [ 57 | 'user' => $this->getConsoleControllerNamespace() . '\\UserController', 58 | ]; 59 | } 60 | 61 | /** 62 | * Return default model map for modules. 63 | * When user not config model for map so we will get model class 64 | * from this default model map 65 | * @return array Default model map 66 | */ 67 | protected function getDefaultModelMap() { 68 | $parentMap = parent::getDefaultModelMap(); 69 | $parentMap['LoginForm'] = 'johnitvn\userplus\basic\models\LoginForm'; 70 | $parentMap['RegisterForm'] = 'johnitvn\userplus\basic\models\RegisterForm'; 71 | $parentMap['UserAccounts'] = 'johnitvn\userplus\basic\models\UserAccounts'; 72 | $parentMap['RecoveryForm'] = 'johnitvn\userplus\basic\models\RecoveryForm'; 73 | $parentMap['ResendForm'] = 'johnitvn\userplus\basic\models\ResendForm'; 74 | return $parentMap; 75 | } 76 | 77 | /** 78 | * Return web controller namespace. 79 | * @return string The web app controller namespace 80 | */ 81 | protected function getWebControllerNamespace() { 82 | return 'johnitvn\userplus\basic\controllers'; 83 | } 84 | 85 | /** 86 | * Return console controller namespace. 87 | * @return array The console app controller namespace 88 | */ 89 | protected function getConsoleControllerNamespace() { 90 | return 'johnitvn\userplus\basic\commands'; 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /src/basic/UserConfirmableInterface.php: -------------------------------------------------------------------------------- 1 | 7 | * @since 1.0.0 8 | */ 9 | interface UserConfirmableInterface extends EmailableInterface{ 10 | 11 | public function isConfirmed(); 12 | 13 | public function resendConfirmation(); 14 | 15 | public function confirm(); 16 | 17 | public function generateConfirmToken(); 18 | 19 | public static function findIdentityByConfirmToken($token); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/basic/UserRecoveryableInterface.php: -------------------------------------------------------------------------------- 1 | 8 | * @since 1.0.0 9 | */ 10 | interface UserRecoveryableInterface extends EmailableInterface{ 11 | 12 | public function recovery(); 13 | 14 | public function resetPassword(); 15 | 16 | public function generateRecoveryToken(); 17 | 18 | public static function findIdentityByRecoveryToken($token); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/basic/actions/CommandCreateAction.php: -------------------------------------------------------------------------------- 1 | 12 | * @since 1.0.0 13 | */ 14 | class CommandCreateAction extends Command { 15 | 16 | /** 17 | * Create new administrator account. 18 | * 19 | * @return string result content 20 | */ 21 | public function run() { 22 | $this->doCreateAdministrator(Yii::t('user', 'Email'), Yii::t('user', 'Username'), Yii::t('user', 'Password')); 23 | } 24 | 25 | /** 26 | * Do create administrator 27 | * @param string $loginAttributeLabel The login atrribute's label for prompt 28 | * @param string $passwordAttributeLabel The password atrribute's label for prompt 29 | */ 30 | public function doCreateAdministrator($loginAttributeLabel, $usernameAtrributeLabel, $passwordAttributeLabel) { 31 | $login = $this->controller->prompt('Enter ' . $loginAttributeLabel . ':', ['required']); 32 | $username = $this->controller->prompt('Enter ' . $usernameAtrributeLabel . ':', ['required']); 33 | $password = $this->controller->prompt('Enter ' . $passwordAttributeLabel . ':', ['required']); 34 | 35 | $user = $this->userPlusModule->createModelInstance('UserAccounts', [ 36 | 'login' => $login, 37 | 'password' => $password, 38 | 'username' => $username, 39 | 'scenario' => 'console-create', 40 | ]); 41 | 42 | if ($user->consoleCreate()) { 43 | $this->controller->stdout(Yii::t('user', 'User has been created') . "!\n", Console::FG_GREEN); 44 | } else { 45 | $this->controller->stdout(Yii::t('user', 'Please fix following errors:') . "\n", Console::FG_RED); 46 | foreach ($user->errors as $errors) { 47 | foreach ($errors as $error) { 48 | $this->controller->stdout(' - ' . $error . "\n", Console::FG_RED); 49 | } 50 | } 51 | $this->promptToRetry($loginAttributeLabel, $usernameAtrributeLabel, $passwordAttributeLabel); 52 | } 53 | } 54 | 55 | /** 56 | * Prompt user to retry 57 | * @param string $loginAttributeLabel The login atrribute's label for prompt 58 | * @param string $passwordAttributeLabel The password atrribute's label for prompt 59 | */ 60 | private function promptToRetry($loginAttributeLabel, $usernameAtrributeLabel, $passwordAttributeLabel) { 61 | $exit = strtolower($this->controller->prompt('Do you want to retry?[Yes|No]', ['default' => 'N'])); 62 | if ($exit === "yes" || $exit === "y") { 63 | $this->doCreateAdministrator($loginAttributeLabel, $usernameAtrributeLabel, $passwordAttributeLabel); 64 | } else if ($exit == "no" || $exit == "n") { 65 | exit(); 66 | } else { 67 | $this->promptToRetry($loginAttributeLabel, $usernameAtrributeLabel, $passwordAttributeLabel); 68 | } 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/basic/actions/ConfirmAction.php: -------------------------------------------------------------------------------- 1 | 12 | * @since 1.0.0 13 | */ 14 | class ConfirmAction extends Action { 15 | 16 | use AjaxValidationTrait; 17 | 18 | /** 19 | * @var string the view file to be rendered. If not set, it will take the value of [[id]]. 20 | * That means, if you name the action as "error" in "SiteController", then the view name 21 | * would be "error", and the corresponding view file would be "views/site/error.php". 22 | */ 23 | public $view; 24 | 25 | /** 26 | * Runs the confirm action 27 | * 28 | * @return string result content 29 | */ 30 | public function run($token) { 31 | $userClassName = $this->userPlusModule->getModelClassName('UserAccounts'); 32 | $view = $this->view == null ? $this->id : $this->view; 33 | if (($model = call_user_func($userClassName . '::findIdentityByConfirmToken', $token)) !== null) { 34 | if ($this->userPlusModule->confirmWithin != false) { 35 | $time = explode("$", $token)[0]; 36 | $waitTime = time() - intval($time); 37 | $confirmWithin = $this->userPlusModule->confirmWithin; 38 | if ($waitTime > $confirmWithin) { 39 | return $this->controller->render($view, [ 40 | 'success' => false, 41 | 'message' => Yii::t('user', 'The confirmation link is invalid or expired. Please try requesting a new one.'), 42 | ]); 43 | } 44 | } 45 | 46 | if ($model->confirm()) { 47 | return $this->controller->render($view, [ 48 | 'success' => true, 49 | 'message' => Yii::t('user', 'Thank you, registration is now complete.'), 50 | ]); 51 | } else { 52 | return $this->controller->render($view, [ 53 | 'success' => false, 54 | 'message' => Yii::t('user','Something went wrong and your account has not been confirmed.'), 55 | ]); 56 | } 57 | 58 | } else { 59 | $view = $this->view == null ? $this->id : $this->view; 60 | return $this->controller->render($view, [ 61 | 'success' => false, 62 | 'message' => Yii::t('user','Something went wrong and your account has not been confirmed.') 63 | ]); 64 | } 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/basic/actions/RecoveryPasswordAction.php: -------------------------------------------------------------------------------- 1 | 12 | * @since 1.0.0 13 | */ 14 | class RecoveryPasswordAction extends Action { 15 | 16 | use AjaxValidationTrait; 17 | 18 | /** 19 | * @var string the view file to be rendered. If not set, it will take the value of [[id]]. 20 | * That means, if you name the action as "error" in "SiteController", then the view name 21 | * would be "error", and the corresponding view file would be "views/site/error.php". 22 | */ 23 | public $view; 24 | 25 | /** 26 | * Runs the reset password action 27 | * 28 | * @return string result content 29 | */ 30 | public function run() { 31 | $model = $this->userPlusModule->createModelInstance('RecoveryForm'); 32 | 33 | $this->performAjaxValidation($model); 34 | $view = $this->view == null ? $this->id : $this->view; 35 | 36 | if ($model->load(Yii::$app->request->post()) && $model->recovery()) { 37 | return $this->controller->render($view, [ 38 | 'alert' => true, 39 | 'model' => $model, 40 | ]); 41 | } else { 42 | return $this->controller->render($view, [ 43 | 'alert' => false, 44 | 'model' => $model, 45 | ]); 46 | } 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/basic/actions/ResendConfirmAction.php: -------------------------------------------------------------------------------- 1 | 12 | * @since 1.0.0 13 | */ 14 | class ResendConfirmAction extends Action { 15 | 16 | use AjaxValidationTrait; 17 | 18 | /** 19 | * @var string the view file to be rendered. If not set, it will take the value of [[id]]. 20 | * That means, if you name the action as "error" in "SiteController", then the view name 21 | * would be "error", and the corresponding view file would be "views/site/error.php". 22 | */ 23 | public $view; 24 | 25 | /** 26 | * Runs the reset password action 27 | * 28 | * @return string result content 29 | */ 30 | public function run() { 31 | $model = $this->userPlusModule->createModelInstance('ResendForm'); 32 | 33 | $this->performAjaxValidation($model); 34 | $view = $this->view == null ? $this->id : $this->view; 35 | $model->load(Yii::$app->request->post()); 36 | if ($model->load(Yii::$app->request->post()) && $model->resendConfirmation()) { 37 | return $this->controller->render($view, [ 38 | 'alert' => true, 39 | 'model' => $model, 40 | ]); 41 | } else { 42 | return $this->controller->render($view, [ 43 | 'alert' => false, 44 | 'model' => $model, 45 | ]); 46 | } 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/basic/actions/ResetPasswordAction.php: -------------------------------------------------------------------------------- 1 | 12 | * @since 1.0.0 13 | */ 14 | class ResetPasswordAction extends Action { 15 | 16 | use AjaxValidationTrait; 17 | 18 | /** 19 | * @var string the view file to be rendered. If not set, it will take the value of [[id]]. 20 | * That means, if you name the action as "error" in "SiteController", then the view name 21 | * would be "error", and the corresponding view file would be "views/site/error.php". 22 | */ 23 | public $view; 24 | 25 | /** 26 | * Runs the reset password action 27 | * 28 | * @return string result content 29 | */ 30 | public function run($token) { 31 | $modelClassName = $this->userPlusModule->getModelClassName('UserAccounts'); 32 | $view = $this->view == null ? $this->id : $this->view; 33 | if (($userModel = call_user_func($modelClassName . '::findIdentityByRecoveryToken', $token)) !== null && $userModel->resetPassword()) { 34 | return $this->controller->render($view, [ 35 | 'success' => true, 36 | 'message' => Yii::t("user", 'The new password will send to your email. Please change your password after login'), 37 | ]); 38 | } else { 39 | return $this->controller->render($view, [ 40 | 'success' => false, 41 | 'message' => Yii::t("user", 'Something went wrong and your account can not reset password please retry request again.'), 42 | ]); 43 | } 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/basic/commands/UserController.php: -------------------------------------------------------------------------------- 1 | 9 | * @since 1.0.0 10 | */ 11 | class UserController extends ConsoleController{ 12 | 13 | /** 14 | * @inheritdoc 15 | */ 16 | public function actions() { 17 | return [ 18 | 'create-admin'=>'johnitvn\userplus\basic\actions\CommandCreateAction', 19 | ]; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/basic/controllers/ManagerController.php: -------------------------------------------------------------------------------- 1 | 11 | * @since 1.0.0 12 | */ 13 | class ManagerController extends BaseController { 14 | 15 | /** 16 | * @inheritdoc 17 | */ 18 | public function behaviors() { 19 | $behaviors = parent::behaviors(); 20 | $behaviors['verbs']['actions']['hand-confirm'] = ['post']; 21 | return $behaviors; 22 | } 23 | 24 | /** 25 | * @inheritdoc 26 | */ 27 | public function actionHandConfirm($id) { 28 | $model = $this->findModel($id); 29 | $model->scenario = 'confirm'; 30 | $model->confirm(); 31 | Yii::$app->response->format = Response::FORMAT_JSON; 32 | return ['forceClose' => true, 'forceReload' => true]; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/basic/controllers/SecurityController.php: -------------------------------------------------------------------------------- 1 | 10 | * @since 1.0.0 11 | */ 12 | class SecurityController extends BaseController { 13 | 14 | protected $registerView = '@userplus/basic/views/security/register'; 15 | 16 | protected $loginView = '@userplus/basic/views/security/login'; 17 | 18 | /** 19 | * @inheritdoc 20 | */ 21 | public function actions() { 22 | $actions = parent::actions(); 23 | $actions['confirm'] = 'johnitvn\userplus\basic\actions\ConfirmAction'; 24 | $actions['recovery'] = 'johnitvn\userplus\basic\actions\RecoveryPasswordAction'; 25 | $actions['reset'] = 'johnitvn\userplus\basic\actions\ResetPasswordAction'; 26 | $actions['resend'] = 'johnitvn\userplus\basic\actions\ResendConfirmAction'; 27 | return $actions; 28 | } 29 | 30 | /** 31 | * @inheritdoc 32 | */ 33 | public function behaviors() { 34 | $behaviors = parent::behaviors(); 35 | $behaviors['access']['only'][] = 'confirm'; 36 | $behaviors['access']['only'][] = 'recovery'; 37 | $behaviors['access']['only'][] = 'reset'; 38 | $behaviors['access']['only'][] = 'resend'; 39 | $behaviors['access']['rules'][] = [ 40 | 'actions' => ['confirm', 'recovery', 'reset', 'resend'], 41 | 'allow' => true, 42 | 'roles' => ['?'], 43 | ]; 44 | return $behaviors; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/basic/migrations/m150703_191015_init.php: -------------------------------------------------------------------------------- 1 | createTable('user_accounts', [ 10 | 'id' => Schema::TYPE_PK, 11 | 'login' => Schema::TYPE_STRING . '(255) NOT NULL', 12 | 'username' => Schema::TYPE_STRING . '(255) NOT NULL', 13 | 'password_hash' => Schema::TYPE_STRING . '(255) NOT NULL', 14 | 'auth_key' => Schema::TYPE_STRING . '(255) NOT NULL', 15 | 'administrator' => Schema::TYPE_INTEGER, 16 | 'creator' => Schema::TYPE_INTEGER, 17 | 'creator_ip' => Schema::TYPE_STRING . '(40)', 18 | 'confirm_token' => Schema::TYPE_STRING, 19 | 'recovery_token' => Schema::TYPE_STRING, 20 | 'blocked_at' => Schema::TYPE_INTEGER, 21 | 'confirmed_at' => Schema::TYPE_INTEGER, 22 | 'created_at' => Schema::TYPE_INTEGER . ' NOT NULL', 23 | 'updated_at' => Schema::TYPE_INTEGER . ' NOT NULL', 24 | ], $this->tableOptions); 25 | 26 | $this->createIndex('user_unique_login', 'user_accounts', 'login', true); 27 | $this->createIndex('user_unique_username', 'user_accounts', 'username', true); 28 | } 29 | 30 | public function down() { 31 | $this->dropTable('user_accounts'); 32 | return true; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/basic/models/LoginForm.php: -------------------------------------------------------------------------------- 1 | 11 | * @since 1.0.0 12 | */ 13 | class LoginForm extends BaseLoginForm { 14 | 15 | public function rules(){ 16 | $rules = parent::rules(); 17 | $rules['accountConfirmed'] = [ 18 | 'login', 19 | function ($attribute) { 20 | if ($this->user!==null&&!$this->userPlusModule->enableUnconfirmedLogin&&!$this->user->isConfirmed()) { 21 | $this->addError($attribute, Yii::t('user', 'Your account is not confirmed')); 22 | } 23 | } 24 | ]; 25 | return $rules; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/basic/models/RecoveryForm.php: -------------------------------------------------------------------------------- 1 | 10 | * @since 1.0.0 11 | */ 12 | class RecoveryForm extends Model { 13 | 14 | /** @var string User's plain password */ 15 | public $login; 16 | 17 | 18 | /** @inheritdoc */ 19 | public function attributeLabels() 20 | { 21 | return [ 22 | 'login' => Yii::t('user', 'Email'), 23 | ]; 24 | } 25 | 26 | /** @inheritdoc */ 27 | public function formName() 28 | { 29 | return 'recovery-form'; 30 | } 31 | 32 | /** @inheritdoc */ 33 | public function rules() 34 | { 35 | return [ 36 | 'requiredFields' => [['login'], 'required'], 37 | 'loginTrim' => ['login', 'trim'], 38 | 'loginPattern' => ['login', 'email'], 39 | ]; 40 | } 41 | 42 | public function recovery(){ 43 | if(!$this->validate()){ 44 | return false; 45 | }else{ 46 | $modelClass = $this->userPlusModule->getModelClassName('UserAccounts'); 47 | $user = call_user_func($modelClass.'::findIdentityByEmail',$this->login); 48 | if($user!==null){ 49 | $user->scenario = 'recovery'; 50 | return $user->recovery(); 51 | }else{ 52 | $this->addError('login',Yii::t("user","We didn't found any account corresponds with this email")); 53 | } 54 | } 55 | } 56 | 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/basic/models/RegisterForm.php: -------------------------------------------------------------------------------- 1 | 11 | * @since 1.0.0 12 | */ 13 | class RegisterForm extends BaseRegisterForm { 14 | 15 | public $username; 16 | 17 | public function attributeLabels() { 18 | $labels = parent::attributeLabels(); 19 | $labels['login'] = Yii::t('user', 'Email'); 20 | $labels['username'] = Yii::t('user', 'Username'); 21 | return $labels; 22 | } 23 | 24 | public function rules() { 25 | $rules = parent::rules(); 26 | 27 | $rules['loginPattern'] = ['login', 'email']; 28 | 29 | $rules['usernameRequired'] = ['username', 'required']; 30 | $rules['usernamePattern'] = ['username', 'match', 'pattern' => '/^[-a-zA-Z0-9_\.@]+$/']; 31 | $rules['usernameLength'] = ['username', 'string', 'min' => 3, 'max' => 255]; 32 | 33 | return $rules; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/basic/models/ResendForm.php: -------------------------------------------------------------------------------- 1 | 11 | * @since 1.0.0 12 | */ 13 | class ResendForm extends Model { 14 | 15 | /** @var string User's plain password */ 16 | public $login; 17 | 18 | /** @inheritdoc */ 19 | public function attributeLabels() { 20 | return [ 21 | 'login' => Yii::t('user', 'Email'), 22 | ]; 23 | } 24 | 25 | /** @inheritdoc */ 26 | public function formName() { 27 | return 'resend-form'; 28 | } 29 | 30 | /** @inheritdoc */ 31 | public function rules() { 32 | return [ 33 | 'requiredFields' => [['login'], 'required'], 34 | 'loginTrim' => ['login', 'trim'], 35 | 'loginPattern' => ['login', 'email'], 36 | ]; 37 | } 38 | 39 | /** 40 | * Resend confirmation email to user. 41 | * If use already confirmed. Don't accept resend confirm email request 42 | * @return boolean 43 | */ 44 | public function resendConfirmation() { 45 | if (!$this->validate()) { 46 | return false; 47 | } else { 48 | $modelClass = $this->userPlusModule->getModelClassName('UserAccounts'); 49 | $user = call_user_func($modelClass . '::findIdentityByEmail', $this->login); 50 | if ($user !== null) { 51 | if ($user->confirmed_at !== null) { 52 | // user is confirmed 53 | $this->addError('login', Yii::t("user", "Your account is confirmed. You can login now")); 54 | return false; 55 | } else { 56 | $user->scenario = 'confirm'; 57 | return $user->resendConfirmation(); 58 | } 59 | } else { 60 | $this->addError('login', Yii::t("user", "We didn't found any account corresponds with this email")); 61 | } 62 | } 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/basic/models/UserAccounts.php: -------------------------------------------------------------------------------- 1 | 15 | * @since 1.0.0 16 | */ 17 | class UserAccounts extends BaseUserAccounts implements UserConfirmableInterface, UserRecoveryableInterface { 18 | 19 | /** 20 | * @var User Accounts Event 21 | */ 22 | const BEFORE_RESET_PASSWORD = 'beforeResetPassword'; 23 | 24 | /** 25 | * @var User Accounts Event 26 | */ 27 | const AFTER_RESET_PASSWORD = 'afterResetPassword'; 28 | 29 | /** 30 | * @var User Accounts Event 31 | */ 32 | const BEFORE_CONFIRM = 'beforeConfirm'; 33 | 34 | /** 35 | * @var User Accounts Event 36 | */ 37 | const AFTER_CONFIRM = 'afterConfirm'; 38 | 39 | /** 40 | * @var User Accounts Event 41 | */ 42 | const BEFORE_RECONFIRM = 'beforeReconfirm'; 43 | 44 | /** 45 | * @var User Accounts Event 46 | */ 47 | const AFTER_RECONFIRM = 'afterReconfirm'; 48 | 49 | /** 50 | * @var User Accounts Event 51 | */ 52 | const BEFORE_RECOVERY = 'beforeRecovery'; 53 | 54 | /** 55 | * @var User Accounts Event 56 | */ 57 | const AFTER_RECOVERY = 'afterRecovery'; 58 | 59 | /** 60 | * Instace of johnitvn\userplus\basic\Mailer 61 | * @var johnitvn\userplus\basic\Mailer 62 | */ 63 | protected $mailer; 64 | 65 | /** 66 | * @inheritdoc 67 | */ 68 | public function init() { 69 | parent::init(); 70 | $this->mailer = $this->userPlusModule->mailer; 71 | $this->on(self::AFTER_REGISTER, [$this, 'afterRegister']); 72 | $this->on(self::AFTER_RECOVERY, [$this, 'afterRecovery']); 73 | $this->on(self::AFTER_RESET_PASSWORD, [$this, 'afterResetPassword']); 74 | } 75 | 76 | /** 77 | * @inheritdoc 78 | */ 79 | public function rules() { 80 | $rules = parent::rules(); 81 | $rules['usernameRequired'] = ['username', 'required']; 82 | $rules['usernamePattern'] = ['username', 'match', 'pattern' => '/^[-a-zA-Z0-9_\.@]+$/']; 83 | $rules['usernameLength'] = ['username', 'string', 'min' => 3, 'max' => 255]; 84 | $rules['usernameUnique'] = ['username', 'unique', 'message' => Yii::t('user', 'This username has already been taken')]; 85 | 86 | $rules['loginUnique'] = ['login', 'unique', 'message' => Yii::t('user', 'This email has already been taken for other account')]; 87 | $rules['loginPattern'] = ['login', 'email']; 88 | return $rules; 89 | } 90 | 91 | /** 92 | * @inheritdoc 93 | */ 94 | public function attributeLabels() { 95 | $labels = parent::attributeLabels(); 96 | $labels['login'] = Yii::t('user', 'Email'); 97 | $labels['username'] = Yii::t('user', 'Username'); 98 | return $labels; 99 | } 100 | 101 | public function scenarios() { 102 | $scenarios = parent::scenarios(); 103 | $scenarios['register'][] = 'username'; 104 | $scenarios['create'][] = 'username'; 105 | $scenarios['console-create'][] = 'username'; 106 | $scenarios['confirm'] = ['confirm_token', 'confirmed_at']; 107 | $scenarios['recovery'] = ['recovery_token']; 108 | $scenarios['reset-password'] = ['password']; 109 | return $scenarios; 110 | } 111 | 112 | /** 113 | * Get username of user 114 | * @return string Return the username of use 115 | */ 116 | public function getUsername() { 117 | return $this->username; 118 | } 119 | 120 | /** 121 | * Do all jobs after register 122 | * @return boolean 123 | */ 124 | public function afterRegister() { 125 | if ($this->userPlusModule->enableConfirmation) { 126 | $token = $this->generateConfirmToken(); 127 | $route = $this->userPlusModule->confirmationHandlerRoute; 128 | $url = Url::to([$route, 'token' => $token], true); 129 | if (!$this->save()) { 130 | return false; 131 | } 132 | $this->mailer->sendConfirmationMessage($this, ['url' => $url]); 133 | } 134 | } 135 | 136 | /** 137 | * Find user by login field 138 | * 139 | * @param string email/username to find 140 | * @return boolean|UserAccounts 141 | */ 142 | public static function findIdentityByLogin($login) { 143 | $userPlusModule = \Yii::$app->getModule('user'); 144 | if ($userPlusModule->loginType == "username") { 145 | $model = static::findOne(['username' => $login]); 146 | } else { 147 | $model = static::findOne(['login' => $login]); 148 | } 149 | return $model; 150 | } 151 | 152 | public static function findIdentityByEmail($email) { 153 | return static::findOne(['login' => $email]); 154 | } 155 | 156 | /** 157 | * 158 | * @return boolean 159 | */ 160 | public function isConfirmed() { 161 | return $this->confirmed_at !== null; 162 | } 163 | 164 | /** 165 | * 166 | * @return string 167 | */ 168 | public function getEmail() { 169 | return $this->login; 170 | } 171 | 172 | /** 173 | * 174 | * @return boolean 175 | */ 176 | public function confirm() { 177 | $this->trigger(self::BEFORE_CONFIRM); 178 | $this->scenario = 'confirm'; 179 | $this->confirm_token = null; 180 | $this->confirmed_at = time(); 181 | if (!$this->save()) { 182 | return false; 183 | } 184 | $this->trigger(self::AFTER_CONFIRM); 185 | return true; 186 | } 187 | 188 | /** 189 | * 190 | * @return boolean 191 | */ 192 | public function recovery() { 193 | $this->trigger(self::BEFORE_RECOVERY); 194 | $this->generateRecoveryToken(); 195 | if (!$this->save()) { 196 | return false; 197 | } 198 | $this->trigger(self::AFTER_RECOVERY); 199 | return true; 200 | } 201 | 202 | /** 203 | * Do all jobs when after recovery 204 | */ 205 | public function afterRecovery() { 206 | $token = $this->recovery_token; 207 | $route = $this->userPlusModule->resetPasswordHandlerRoute; 208 | $url = Url::to([$route, 'token' => $token], true); 209 | $this->mailer->sendRecoveryMessage($this, ['url' => $url]); 210 | } 211 | 212 | /** 213 | * 214 | * @return boolean 215 | */ 216 | public function resetPassword() { 217 | $this->trigger(self::BEFORE_RESET_PASSWORD); 218 | $this->scenario = 'reset-password'; 219 | $this->password = Helper::generatePassword(); 220 | if (!$this->save()) { 221 | return false; 222 | } 223 | 224 | $this->trigger(self::AFTER_RESET_PASSWORD); 225 | return true; 226 | } 227 | 228 | /** 229 | * 230 | */ 231 | public function afterResetPassword() { 232 | $this->mailer->sendResetPasswordMessage($this, ['password' => $this->password]); 233 | } 234 | 235 | /** 236 | * 237 | * @return boolean 238 | */ 239 | public function resendConfirmation() { 240 | $this->trigger(self::BEFORE_RECONFIRM); 241 | $token = $this->generateConfirmToken(); 242 | $route = $this->userPlusModule->confirmationHandlerRoute; 243 | $url = Url::to([$route, 'token' => $token], true); 244 | if (!$this->save()) { 245 | return false; 246 | } 247 | $this->mailer->sendReconfirmationMessage($this, ['url' => $url]); 248 | $this->trigger(self::AFTER_RECONFIRM); 249 | return true; 250 | } 251 | 252 | /** 253 | * 254 | * @return string 255 | */ 256 | public function generateConfirmToken() { 257 | $token = Helper::generateRandomString($this->userPlusModule->tokenLenght); 258 | $this->confirm_token = $token; 259 | return $this->confirm_token; 260 | } 261 | 262 | /** 263 | * 264 | * @return string 265 | */ 266 | public function generateRecoveryToken() { 267 | $token = Helper::generateRandomString($this->userPlusModule->tokenLenght); 268 | $this->recovery_token = $token; 269 | return $this->recovery_token; 270 | } 271 | 272 | /** 273 | * 274 | * @param string $token 275 | * @return UserAccounts 276 | */ 277 | public static function findIdentityByConfirmToken($token) { 278 | return UserAccounts::findOne(['confirm_token' => $token]); 279 | } 280 | 281 | /** 282 | * 283 | * @param string $token 284 | * @return UserAccounts 285 | */ 286 | public static function findIdentityByRecoveryToken($token) { 287 | return UserAccounts::findOne(['recovery_token' => $token]); 288 | } 289 | 290 | } 291 | -------------------------------------------------------------------------------- /src/basic/views/mails/html/confirm.php: -------------------------------------------------------------------------------- 1 | 4 |

5 | , 6 |

7 |

8 | name) ?>. 9 | . 10 |

11 |

12 | "; ?>. 13 |

14 |

15 | . 16 |

17 |

18 | . 19 |

-------------------------------------------------------------------------------- /src/basic/views/mails/html/recovery.php: -------------------------------------------------------------------------------- 1 | 4 |

5 | , 6 |

7 |

8 | name) ?>. 9 | . 10 |

11 |

12 | 13 |

14 |

15 | . 16 |

17 |

18 | . 19 |

-------------------------------------------------------------------------------- /src/basic/views/mails/html/reset.php: -------------------------------------------------------------------------------- 1 | 4 |

5 | , 6 |

7 |

8 | name) ?>. 9 | . 10 |

11 |

12 | {0}',$password) ?>. 13 |

14 |

15 | . 16 |

17 | -------------------------------------------------------------------------------- /src/basic/views/mails/layouts/html.php: -------------------------------------------------------------------------------- 1 | beginPage() ?> 2 | 3 | 4 | 5 | 6 | 7 | head() ?> 8 | 9 | 10 | 11 | 12 | 13 | 26 | 27 | 28 |
14 |
15 | 16 | 17 | 22 | 23 |
18 | beginBody() ?> 19 | 20 | endBody() ?> 21 |
24 |
25 |
29 | 30 | 43 | 44 | 45 | 46 | 47 | 48 | endPage() ?> -------------------------------------------------------------------------------- /src/basic/views/mails/layouts/text.php: -------------------------------------------------------------------------------- 1 | beginPage() ?> 2 | beginBody() ?> 3 | 4 | endBody() ?> 5 | endPage() ?> -------------------------------------------------------------------------------- /src/basic/views/mails/text/confirm.php: -------------------------------------------------------------------------------- 1 | , 2 | name) ?>. 3 | . 4 | . 5 | . 6 | . -------------------------------------------------------------------------------- /src/basic/views/mails/text/recovery.php: -------------------------------------------------------------------------------- 1 | , 2 | 3 | name) ?>. 4 | . 5 | 6 | 7 | 8 | . 9 | 10 | . -------------------------------------------------------------------------------- /src/basic/views/mails/text/reset.php: -------------------------------------------------------------------------------- 1 | , 2 | name) ?>. 3 | . 4 | . 5 | . 6 | -------------------------------------------------------------------------------- /src/basic/views/manager/_columns.php: -------------------------------------------------------------------------------- 1 | 'kartik\grid\CheckboxColumn', 10 | 'width' => '20px', 11 | ], 12 | [ 13 | 'class' => '\kartik\grid\DataColumn', 14 | 'attribute' => 'id', 15 | 'width' => '40px', 16 | ], 17 | [ 18 | 'class' => '\kartik\grid\DataColumn', 19 | 'attribute' => 'username', 20 | ], 21 | [ 22 | 'class' => '\kartik\grid\DataColumn', 23 | 'attribute' => 'login', 24 | ], 25 | [ 26 | 'class' => '\kartik\grid\DataColumn', 27 | 'attribute' => 'created_at', 28 | 'value' => function($model) { 29 | return date('d/m/Y', $model->created_at); 30 | }, 31 | 'filter' => DatePicker::widget([ 32 | 'model' => $searchModel, 33 | 'attribute' => 'created_at', 34 | 'dateFormat' => 'php:Y-m-d', 35 | 'options' => [ 36 | 'class' => 'form-control', 37 | ], 38 | ]), 39 | ], 40 | [ 41 | 'class' => '\kartik\grid\DataColumn', 42 | 'width' => '50px', 43 | 'attribute' => 'confirmed_at', 44 | 'label'=>'Confirmation', 45 | 'value' => function ($model) { 46 | if ($model->confirmed_at === null) { 47 | return Html::a(Yii::t('user', 'Confirm'), ['hand-confirm', 'id' => $model->id], [ 48 | 'class' => 'btn btn-xs btn-primary btn-block', 49 | 'role' => 'modal-remote', 50 | 'data-confirm' => false, 'data-method' => false, // for overide yii data api 51 | 'data-request-method' => 'post', 52 | 'data-confirm-title' => Yii::t('user', 'Are you sure?'), 53 | 'data-confirm-message' => Yii::t('user', 'Are you sure you want to confirm for this user?'), 54 | ]); 55 | } else { 56 | return 'Confirmed'; 57 | } 58 | }, 59 | 'format' => 'raw' 60 | ], 61 | [ 62 | 'class' => '\kartik\grid\DataColumn', 63 | 'width' => '50px', 64 | 'attribute' => 'blocked_at', 65 | 'label'=>'Status', 66 | 'value' => function ($model) { 67 | if ($model->blocked_at !== null) { 68 | return Html::a(Yii::t('user', 'Unblock'), ['toggle-block', 'id' => $model->id], [ 69 | 'class' => 'btn btn-xs btn-warning btn-block', 70 | 'role' => 'modal-remote', 71 | 'data-confirm' => false, 'data-method' => false, // for overide yii data api 72 | 'data-request-method' => 'post', 73 | 'data-confirm-title' => Yii::t('user', 'Are you sure?'), 74 | 'data-confirm-message' => Yii::t('user', 'Are you sure you want to unblock this user?'), 75 | ]); 76 | } else { 77 | return Html::a(Yii::t('user', 'Block'), ['toggle-block', 'id' => $model->id], [ 78 | 'class' => 'btn btn-xs btn-danger btn-block', 79 | 'role' => 'modal-remote', 80 | 'data-confirm' => false, 'data-method' => false, // for overide yii data api 81 | 'data-request-method' => 'post', 82 | 'data-confirm-title' => Yii::t('user', 'Are you sure?'), 83 | 'data-confirm-message' => Yii::t('user', 'Are you sure you want to unblock this user?'), 84 | ]); 85 | } 86 | }, 87 | 'format' => 'raw' 88 | ], 89 | ]; 90 | 91 | 92 | $rbacModule = Yii::$app->getModule('rbac'); 93 | 94 | $columns[] = [ 95 | 'class' => '\kartik\grid\DataColumn', 96 | 'width' => '130px', 97 | 'attribute' => 'administrator', 98 | 'value' => function ($model) { 99 | if (!$model->administrator) { 100 | return Html::a(Yii::t('user', 'Set SU'), ['toggle-superuser', 'id' => $model->id], [ 101 | 'class' => 'btn btn-xs btn-danger btn-block', 102 | 'role' => 'modal-remote', 103 | 'data-confirm' => false, 'data-method' => false, // for overide yii data api 104 | 'data-request-method' => 'post', 105 | 'data-confirm-title' => Yii::t('user', 'Are you sure?'), 106 | 'data-confirm-message' => Yii::t('user', 'Are you sure you want to unblock this user?'), 107 | ]); 108 | } else { 109 | return Html::a(Yii::t('user', 'Remove SU'), ['toggle-superuser', 'id' => $model->id], [ 110 | 'class' => 'btn btn-xs btn-info btn-block', 111 | 'role' => 'modal-remote', 112 | 'data-confirm' => false, 'data-method' => false, // for overide yii data api 113 | 'data-request-method' => 'post', 114 | 'data-confirm-title' => Yii::t('user', 'Are you sure?'), 115 | 'data-confirm-message' => Yii::t('user', 'Are you sure you want to unblock this user?'), 116 | ]); 117 | } 118 | }, 119 | 'format' => 'raw', 120 | 'filter' => [0 => 'Not Admin', 1 => 'Admin'], 121 | ]; 122 | 123 | if (get_class($rbacModule) === 'johnitvn\rbacplus\Module') { 124 | /** 125 | * Intergrate with Rbac Plus extension 126 | */ 127 | $columns[] = [ 128 | 'class' => 'kartik\grid\DataColumn', 129 | 'header' => Yii::t('rbac', 'Assignment'), 130 | 'hAlign' => 'center', 131 | 'value'=>function($model){ 132 | return Html::a('', 133 | ['/rbac/assignment/assignment', 'id' => $model->id], 134 | [ 135 | 'role' => 'modal-remote', 136 | 'title' => Yii::t('user', 'Assignment'), 137 | ] 138 | ); 139 | }, 140 | 'format' => 'raw', 141 | 'visible' => Yii::$app->user->identity->isAdministrator(), 142 | ]; 143 | 144 | } 145 | 146 | $columns[] = [ 147 | 'class' => 'kartik\grid\ActionColumn', 148 | 'dropdown' => false, 149 | 'vAlign' => 'middle', 150 | 'urlCreator' => function($action, $model, $key, $index) { 151 | return Url::to([$action, 'id' => $key]); 152 | }, 153 | 'viewOptions' => ['role' => 'modal-remote', 'title' => 'View', 'data-toggle' => 'tooltip'], 154 | 'updateOptions' => ['role' => 'modal-remote', 'title' => 'Update', 'data-toggle' => 'tooltip'], 155 | 'deleteOptions' => ['role' => 'modal-remote', 'title' => 'Delete', 156 | 'data-confirm' => false, 'data-method' => false, // for overide yii data api 157 | 'data-request-method' => 'post', 158 | 'data-toggle' => 'tooltip', 159 | 'data-confirm-title' => 'Are you sure?', 160 | 'data-confirm-message' => 'Are you sure want to delete this item'], 161 | ]; 162 | 163 | return $columns; -------------------------------------------------------------------------------- /src/basic/views/manager/_form.php: -------------------------------------------------------------------------------- 1 | 5 | 6 |
7 | 8 | 9 | 10 | field($model, 'login')->textInput(['maxlength' => true]) ?> 11 | 12 | field($model, 'username')->textInput(['maxlength' => true]) ?> 13 | 14 | field($model, 'password')->passwordInput(['maxlength' => true]) ?> 15 | 16 | field($model, 'confirm_password')->passwordInput(['maxlength' => true]) ?> 17 | 18 | request->isAjax) { ?> 19 |
20 | isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?> 21 |
22 | 23 | 24 | 25 | 26 |
27 | -------------------------------------------------------------------------------- /src/basic/views/manager/create.php: -------------------------------------------------------------------------------- 1 |
2 | render('_form', [ 3 | 'model' => $model, 4 | ]) ?> 5 |
6 | -------------------------------------------------------------------------------- /src/basic/views/manager/index.php: -------------------------------------------------------------------------------- 1 | title = 'Users'; 10 | $this->params['breadcrumbs'][] = $this->title; 11 | 12 | CrudAsset::register($this); 13 | 14 | ?> 15 |
16 |
17 | 'crud-datatable', 19 | 'dataProvider' => $dataProvider, 20 | 'filterModel' => $searchModel, 21 | 'pjax'=>true, 22 | 'columns' => require(__DIR__.'/_columns.php'), 23 | 'toolbar'=> [ 24 | ['content'=> 25 | Html::a('', ['create'], 26 | ['role'=>'modal-remote','title'=> 'Create new Users','class'=>'btn btn-default']). 27 | Html::a('', [''], 28 | ['data-pjax'=>1, 'class'=>'btn btn-default', 'title'=>'Reset Grid']). 29 | '{toggleData}'. 30 | '{export}' 31 | ], 32 | ], 33 | 'striped' => true, 34 | 'condensed' => true, 35 | 'responsive' => true, 36 | 'panel' => [ 37 | 'type' => 'primary', 38 | 'heading' => ' Users listing', 39 | 'before'=>'* Resize table columns just like a spreadsheet by dragging the column edges.', 40 | 'after'=>BulkButtonWidget::widget([ 41 | 'buttons'=> Html::a('  Delete All', 42 | ["bulk-delete"] , 43 | [ 44 | "class"=>"btn btn-danger btn-xs", 45 | 'role'=>'modal-remote-bulk', 46 | 'data-confirm'=>false, 'data-method'=>false,// for overide yii data api 47 | 'data-request-method'=>'post', 48 | 'data-confirm-title'=>'Are you sure?', 49 | 'data-confirm-message'=>'Are you sure want to delete all this items' 50 | ]).' '. 51 | Html::a('  Block All', 52 | ["bulk-block"] , 53 | [ 54 | "class"=>"btn btn-danger btn-xs", 55 | 'role'=>'modal-remote-bulk', 56 | 'data-confirm'=>false, 'data-method'=>false,// for overide yii data api 57 | 'data-request-method'=>'post', 58 | 'data-confirm-title'=>'Are you sure?', 59 | 'data-confirm-message'=>'Are you sure want to block all this items' 60 | ]).' '. 61 | Html::a('  Unblock All', 62 | ["bulk-unblock"] , 63 | [ 64 | "class"=>"btn btn-warning btn-xs", 65 | 'role'=>'modal-remote-bulk', 66 | 'data-confirm'=>false, 'data-method'=>false,// for overide yii data api 67 | 'data-request-method'=>'post', 68 | 'data-confirm-title'=>'Are you sure?', 69 | 'data-confirm-message'=>'Are you sure want to unblock all this items' 70 | ]), 71 | ]). 72 | '
', 73 | ] 74 | ])?> 75 |
76 |
77 | "ajaxCrubModal", 79 | "footer"=>"",// always need it for jquery plugin 80 | ])?> 81 | 82 | -------------------------------------------------------------------------------- /src/basic/views/manager/update.php: -------------------------------------------------------------------------------- 1 |
2 | render('_form', [ 3 | 'model' => $model, 4 | ]) ?> 5 | 6 |
7 | -------------------------------------------------------------------------------- /src/basic/views/manager/view.php: -------------------------------------------------------------------------------- 1 | 8 |
9 | 10 | $model, 12 | 'attributes' => [ 13 | 'id', 14 | 'login', 15 | 'username', 16 | [ 17 | 'attribute'=>'administrator', 18 | 'value'=> $model['administrator']?"Yes":"No" 19 | ], 20 | [ 21 | 'attribute'=>'creator', 22 | 'format' => 'raw', 23 | 'value'=> $model['creator']==-1?"Created by Console": 24 | $model['creator']==-2?"User register by my self": 25 | Html::a(UserAccounts::findOne($model['creator'])->login,['/user/manager/view','id'=>UserAccounts::findOne($model['creator'])->id],["role"=>"modal-remote"]) 26 | ], 27 | 'creator_ip', 28 | [ 29 | 'attribute'=>'blocked_at', 30 | 'value'=> $model['blocked_at']==null?"Not blocked":date("d/m/Y H:i:s",$model['blocked_at']) 31 | ], 32 | [ 33 | 'attribute'=>'confirmed_at', 34 | 'value'=>$model['confirmed_at']==null?'Unconfirmed':date("d/m/Y H:i:s",$model['confirmed_at']) 35 | ], 36 | [ 37 | 'attribute'=>'created_at', 38 | 'value'=>date("d/m/Y H:i:s",$model['created_at']) 39 | ], 40 | [ 41 | 'attribute'=>'updated_at', 42 | 'value'=>$model['updated_at']==-1?\Yii::t("user","Never Update"):date("d/m/Y H:i:s",$model['updated_at']) 43 | ], 44 | ], 45 | ]) ?> 46 | 47 |
48 | -------------------------------------------------------------------------------- /src/basic/views/security/confirm.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('user', 'Confirmation'); 7 | ?> 8 | -------------------------------------------------------------------------------- /src/basic/views/security/login.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('user', 'Sign in'); 7 | $module = Yii::$app->getModule('user'); 8 | ?> 9 |
10 |
11 |
12 |
13 |

title) ?>

14 |
15 |
16 | 'login-form', 18 | 'enableAjaxValidation' => true, 19 | 'enableClientValidation' => false, 20 | 'validateOnBlur' => false, 21 | 'validateOnType' => false, 22 | 'validateOnChange' => false, 23 | ]) ?> 24 | 25 | field($model, 'login', ['inputOptions' => ['autofocus' => 'autofocus', 'class' => 'form-control', 'tabindex' => '1']]) ?> 26 | 27 | field($model, 'password', ['inputOptions' => ['class' => 'form-control', 'tabindex' => '2']])->passwordInput()->label(Yii::t('user', 'Password')) ?> 28 | enableRecoveryPassword): ?> 29 |

30 | 31 | field($model, 'rememberMe')->checkbox(['tabindex' => '4']) ?> 32 | 33 | 'btn btn-primary btn-block', 'tabindex' => '3']) ?> 34 | 35 | 36 |
37 |
38 | enableRegister): ?> 39 |

40 | 41 |

42 | 43 | enableConfirmation): ?> 44 |

45 | 46 |

47 | 48 |
49 |
50 | -------------------------------------------------------------------------------- /src/basic/views/security/recovery.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('user', 'Recovery Password'); 5 | $module = Yii::$app->getModule('user'); 6 | 7 | if($alert):?> 8 | 14 | 15 | 16 |
17 |
18 |
19 |
20 |

title) ?>

21 |
22 |
23 | 'recovery-form', 25 | 'enableAjaxValidation' => true, 26 | 'enableClientValidation' => false, 27 | ]); ?> 28 | 29 | field($model, 'login') ?> 30 | 31 | 'btn btn-primary btn-block']) ?> 32 | 33 |
34 |
35 |

36 | 37 |

38 | enableRegister): ?> 39 |

40 | 41 |

42 | 43 |
44 |
-------------------------------------------------------------------------------- /src/basic/views/security/register.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('user', 'Sign up'); 5 | ?> 6 |
7 |
8 |
9 |
10 |

title) ?>

11 |
12 |
13 | 'registration-form', 15 | 'enableAjaxValidation' => true, 16 | 'enableClientValidation' => false, 17 | ]); ?> 18 | 19 | field($model, 'username') ?> 20 | 21 | field($model, 'login') ?> 22 | 23 | field($model, 'password')->passwordInput() ?> 24 | 25 | field($model, 'confirm_password')->passwordInput() ?> 26 | 27 | 'btn btn-primary btn-block']) ?> 28 | 29 | 30 |
31 |
32 |

33 | 34 |

35 |
36 |
-------------------------------------------------------------------------------- /src/basic/views/security/resend.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('user', 'Resend confirm email'); 5 | $module = Yii::$app->getModule('user'); 6 | 7 | if($alert):?> 8 | 14 | 15 | 16 |
17 |
18 |
19 |
20 |

title) ?>

21 |
22 |
23 | 'resend-form', 25 | 'enableAjaxValidation' => true, 26 | 'enableClientValidation' => false, 27 | ]); ?> 28 | 29 | field($model, 'login') ?> 30 | 31 | 'btn btn-primary btn-block']) ?> 32 | 33 |
34 |
35 |

36 | 37 |

38 | enableRegister): ?> 39 |

40 | 41 |

42 | 43 |
44 |
-------------------------------------------------------------------------------- /src/basic/views/security/reset.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('user', 'Reset Password'); 3 | ?> 4 | -------------------------------------------------------------------------------- /src/messages/vi/user.php: -------------------------------------------------------------------------------- 1 | 21 | * @since 1.0.0 22 | * 23 | */ 24 | class Module extends BaseModule { 25 | 26 | /** 27 | * @var array modelMap Model mapping. 28 | * Need for customize model. 29 | * Simple module required three model UserAccounts,LoginForm,RegisterForm 30 | * ````php 31 | * [ 32 | * 'UserSearch'=>'', 33 | * 'UserAccounts'=>'', 34 | * 'LoginForm'=>'', 35 | * 'RegisterForm'=>'' 36 | * ] 37 | * ```` 38 | */ 39 | public $modelMap = []; 40 | 41 | /** 42 | * @var string The login type accept "email"/"username". 43 | * Default is username 44 | */ 45 | public $loginType = "username"; 46 | 47 | /** 48 | * Initial module 49 | * @return void 50 | */ 51 | public function init() { 52 | parent::init(); 53 | if ($this->loginType !== "username" & $this->loginType !== "email") { 54 | throw new yii\base\InvalidConfigException('loginType just accept "username"/"email".'); 55 | } 56 | } 57 | 58 | public function getCommandControllerMap() { 59 | return [ 60 | 'user' => $this->getConsoleControllerNamespace() . '\\UserController', 61 | ]; 62 | } 63 | 64 | /** 65 | * Return default model map for modules. 66 | * When user not config model for map so we will get model class 67 | * from this default model map 68 | * @return array Default model map 69 | */ 70 | protected function getDefaultModelMap() { 71 | return [ 72 | 'UserSearch' => 'johnitvn\userplus\simple\models\UserSearch', 73 | 'UserAccounts' => 'johnitvn\userplus\simple\models\UserAccounts', 74 | 'LoginForm' => 'johnitvn\userplus\simple\models\LoginForm', 75 | 'RegisterForm' => 'johnitvn\userplus\simple\models\RegisterForm', 76 | 'ChangePasswordForm' => 'johnitvn\userplus\simple\models\ChangePasswordForm', 77 | ]; 78 | } 79 | 80 | /** 81 | * Return console controller namespace. 82 | * @return array The console app controller namespace 83 | */ 84 | protected function getConsoleControllerNamespace() { 85 | return 'johnitvn\userplus\simple\commands'; 86 | } 87 | 88 | /** 89 | * Return web controller namespace. 90 | * @return string The web app controller namespace 91 | */ 92 | protected function getWebControllerNamespace() { 93 | return 'johnitvn\userplus\simple\controllers'; 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /src/simple/actions/CommandCreateAction.php: -------------------------------------------------------------------------------- 1 | 12 | * @since 1.0.0 13 | */ 14 | class CommandCreateAction extends Command { 15 | 16 | /** 17 | * Create new administrator account. 18 | * 19 | * @return string result content 20 | */ 21 | public function run() { 22 | $this->doCreateAdministrator(Yii::t('user', 'Login'), Yii::t('user', 'Password')); 23 | } 24 | 25 | /** 26 | * Do create administrator 27 | * @param string $loginAttributeLabel The login atrribute's label for prompt 28 | * @param string $passwordAttributeLabel The password atrribute's label for prompt 29 | */ 30 | public function doCreateAdministrator($loginAttributeLabel, $passwordAttributeLabel) { 31 | $login = $this->controller->prompt('Enter ' . $loginAttributeLabel . ':', ['required']); 32 | $password = $this->controller->prompt('Enter ' . $passwordAttributeLabel . ':', ['required']); 33 | 34 | $user = $this->userPlusModule->createModelInstance('UserAccounts', [ 35 | 'login' => $login, 36 | 'password' => $password, 37 | 'scenario' => 'console-create', 38 | ]); 39 | 40 | if ($user->consoleCreate()) { 41 | $this->controller->stdout(Yii::t('user', 'User has been created') . "!\n", Console::FG_GREEN); 42 | } else { 43 | $this->controller->stdout(Yii::t('user', 'Please fix following errors:') . "\n", Console::FG_RED); 44 | 45 | foreach ($user->errors as $errors) { 46 | foreach ($errors as $error) { 47 | $this->controller->stdout(' - ' . $error . "\n", Console::FG_RED); 48 | } 49 | } 50 | $this->promptToRetry($loginAttributeLabel, $passwordAttributeLabel); 51 | } 52 | } 53 | 54 | /** 55 | * Prompt user to retry 56 | * @param string $loginAttributeLabel The login atrribute's label for prompt 57 | * @param string $passwordAttributeLabel The password atrribute's label for prompt 58 | */ 59 | private function promptToRetry($loginAttributeLabel, $passwordAttributeLabel) { 60 | $exit = $this->controller->prompt('Do you want to retry?[Yes|No]', ['default' => 'N']); 61 | $exit = strtolower($exit); 62 | if ($exit == "yes" || $exit == "y") { 63 | $this->doCreateAdministrator($loginAttributeLabel, $passwordAttributeLabel); 64 | } else if ($exit == "no" || $exit == "n") { 65 | exit(); 66 | } else { 67 | $this->promptToRetry($loginAttributeLabel, $passwordAttributeLabel); 68 | } 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/simple/commands/UserController.php: -------------------------------------------------------------------------------- 1 | 11 | * @since 1.0.0 12 | */ 13 | class UserController extends ConsoleController { 14 | 15 | /** 16 | * @inheritdoc 17 | */ 18 | public function actions() { 19 | return [ 20 | 'create-admin' => 'johnitvn\userplus\simple\actions\CommandCreateAction', 21 | ]; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/simple/controllers/ManagerController.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 1.0.0 17 | */ 18 | class ManagerController extends WebController { 19 | 20 | /** 21 | * @inheritdoc 22 | */ 23 | public function beforeAction($action) { 24 | if (!parent::beforeAction($action)) { 25 | return false; 26 | } else if (Yii::$app->user->isGuest || !Yii::$app->user->identity->isAdministrator()) { 27 | throw new \yii\web\ForbiddenHttpException(Yii::t('user', 'You are not allowed to perform this action.')); 28 | } else { 29 | return true; 30 | } 31 | } 32 | 33 | /** 34 | * @inheritdoc 35 | */ 36 | public function behaviors() { 37 | return [ 38 | 'verbs' => [ 39 | 'class' => VerbFilter::className(), 40 | 'actions' => [ 41 | 'delete' => ['post'], 42 | 'bulk-delete' => ['post'], 43 | 'toggle-block' => ['post'], 44 | 'toggle-superuser' => ['post'], 45 | ], 46 | ], 47 | ]; 48 | } 49 | 50 | /** 51 | * Lists all UserAccounts models. 52 | * @return mixed 53 | */ 54 | public function actionIndex() { 55 | $searchModel = $this->userPlusModule->createModelInstance('UserSearch'); 56 | $dataProvider = $searchModel->search(Yii::$app->request->queryParams); 57 | 58 | return $this->render('index', [ 59 | 'searchModel' => $searchModel, 60 | 'dataProvider' => $dataProvider, 61 | ]); 62 | } 63 | 64 | /** 65 | * Displays a single UserAccounts model. 66 | * @param integer $id 67 | * @return mixed 68 | */ 69 | public function actionView($id) { 70 | $request = Yii::$app->request; 71 | if ($request->isAjax) { 72 | Yii::$app->response->format = Response::FORMAT_JSON; 73 | return [ 74 | 'title' => "User #" . $id, 75 | 'content' => $this->renderPartial('view', [ 76 | 'model' => $this->findModel($id), 77 | ]), 78 | 'footer' => Html::button('Close', ['class' => 'btn btn-default pull-left', 'data-dismiss' => "modal"]) . 79 | Html::a('Edit', ['update', 'id' => $id], ['class' => 'btn btn-primary', 'role' => 'modal-remote']) 80 | ]; 81 | } else { 82 | return $this->render('view', [ 83 | 'model' => $this->findModel($id), 84 | ]); 85 | } 86 | } 87 | 88 | /** 89 | * Creates a new UserAccounts model. 90 | * For ajax request will return json object 91 | * and for non-ajax request if creation is successful, the browser will be redirected to the 'view' page. 92 | * @return mixed 93 | */ 94 | public function actionCreate() { 95 | $request = Yii::$app->request; 96 | $model = $this->userPlusModule->createModelInstance('UserAccounts', ['scenario' => 'create']); 97 | 98 | if ($request->isAjax) { 99 | /* 100 | * Process for ajax request 101 | */ 102 | Yii::$app->response->format = Response::FORMAT_JSON; 103 | if ($request->isGet) { 104 | return [ 105 | 'title' => "Create new User", 106 | 'content' => $this->renderPartial('create', [ 107 | 'model' => $model, 108 | ]), 109 | 'footer' => Html::button('Close', ['class' => 'btn btn-default pull-left', 'data-dismiss' => "modal"]) . 110 | Html::button('Save', ['class' => 'btn btn-primary', 'type' => "submit"]) 111 | ]; 112 | } else if ($model->load($request->post()) && $model->create(Yii::$app->user->getId())) { 113 | return [ 114 | 'forceReload' => 'true', 115 | 'title' => "Create new User", 116 | 'content' => 'Create User success', 117 | 'footer' => Html::button('Close', ['class' => 'btn btn-default pull-left', 'data-dismiss' => "modal"]) . 118 | Html::a('Create More', ['create'], ['class' => 'btn btn-primary', 'role' => 'modal-remote']) 119 | ]; 120 | } else { 121 | return [ 122 | 'title' => "Create new User", 123 | 'content' => $this->renderPartial('create', [ 124 | 'model' => $model, 125 | ]), 126 | 'footer' => Html::button('Close', ['class' => 'btn btn-default pull-left', 'data-dismiss' => "modal"]) . 127 | Html::button('Save', ['class' => 'btn btn-primary', 'type' => "submit"]) 128 | ]; 129 | } 130 | } else { 131 | /* 132 | * Process for non-ajax request 133 | */ 134 | if ($model->load($request->post()) && $model->create(Yii::$app->user->getId())) { 135 | return $this->redirect(['view', 'id' => $model->id]); 136 | } else { 137 | return $this->render('create', [ 138 | 'model' => $model, 139 | ]); 140 | } 141 | } 142 | } 143 | 144 | /** 145 | * Updates an existing UserAccounts model. 146 | * For ajax request will return json object 147 | * and for non-ajax request if update is successful, the browser will be redirected to the 'view' page. 148 | * @param integer $id 149 | * @return mixed 150 | */ 151 | public function actionUpdate($id) { 152 | $request = Yii::$app->request; 153 | $model = $this->findModel($id); 154 | $model->scenario = 'update'; 155 | 156 | if ($request->isAjax) { 157 | /* 158 | * Process for ajax request 159 | */ 160 | Yii::$app->response->format = Response::FORMAT_JSON; 161 | if ($request->isGet) { 162 | return [ 163 | 'title' => "Update User #" . $id, 164 | 'content' => $this->renderPartial('update', [ 165 | 'model' => $this->findModel($id), 166 | ]), 167 | 'footer' => Html::button('Close', ['class' => 'btn btn-default pull-left', 'data-dismiss' => "modal"]) . 168 | Html::button('Save', ['class' => 'btn btn-primary', 'type' => "submit"]) 169 | ]; 170 | } else if ($model->load($request->post()) && $model->save()) { 171 | return [ 172 | 'forceReload' => 'true', 173 | 'title' => "User #" . $id, 174 | 'content' => $this->renderPartial('view', [ 175 | 'model' => $this->findModel($id), 176 | ]), 177 | 'footer' => Html::button('Close', ['class' => 'btn btn-default pull-left', 'data-dismiss' => "modal"]) . 178 | Html::a('Edit', ['update', 'id' => $id], ['class' => 'btn btn-primary', 'role' => 'modal-remote']) 179 | ]; 180 | } else { 181 | return [ 182 | 'title' => "Update User #" . $id, 183 | 'content' => $this->renderPartial('update', [ 184 | 'model' => $this->findModel($id), 185 | ]), 186 | 'footer' => Html::button('Close', ['class' => 'btn btn-default pull-left', 'data-dismiss' => "modal"]) . 187 | Html::button('Save', ['class' => 'btn btn-primary', 'type' => "submit"]) 188 | ]; 189 | } 190 | } else { 191 | /* 192 | * Process for non-ajax request 193 | */ 194 | if ($model->load($request->post()) && $model->save()) { 195 | return $this->redirect(['view', 'id' => $model->id]); 196 | } else { 197 | return $this->render('update', [ 198 | 'model' => $model, 199 | ]); 200 | } 201 | } 202 | } 203 | 204 | /** 205 | * Delete an existing UserAccounts model. 206 | * For ajax request will return json object 207 | * and for non-ajax request if deletion is successful, the browser will be redirected to the 'index' page. 208 | * @param integer $id 209 | * @return mixed 210 | */ 211 | public function actionDelete($id) { 212 | $request = Yii::$app->request; 213 | if (Yii::$app->user->getId() == $id) { 214 | if ($request->isAjax) { 215 | Yii::$app->response->format = Response::FORMAT_JSON; 216 | return [ 217 | 'title' => 'An error occurred', 218 | 'content' => 'You can not delete yourself', 219 | 'footer' => Html::button('Close', ['class' => 'btn btn-default pull-left', 'data-dismiss' => "modal"]) 220 | ]; 221 | } else { 222 | return $this->redirect(['index']); 223 | } 224 | } 225 | 226 | //$this->findModel($id)->delete(); 227 | 228 | if ($request->isAjax) { 229 | /* 230 | * Process for ajax request 231 | */ 232 | $this->findModel($id)->delete(); 233 | Yii::$app->response->format = Response::FORMAT_JSON; 234 | return ['forceClose' => true, 'forceReload' => true]; 235 | } else { 236 | /* 237 | * Process for non-ajax request 238 | */ 239 | return $this->redirect(['index']); 240 | } 241 | } 242 | 243 | public function actionToggleBlock($id) { 244 | $model = $this->findModel($id); 245 | $model->scenario = 'toggle-block'; 246 | 247 | Yii::$app->response->format = Response::FORMAT_JSON; 248 | 249 | if (Yii::$app->user->getId() == $id) { 250 | return [ 251 | 'title' => 'An error occurred', 252 | 'content' => 'You can not block yourself', 253 | 'footer' => Html::button('Close', ['class' => 'btn btn-default pull-left', 'data-dismiss' => "modal"]) 254 | ]; 255 | } 256 | 257 | 258 | if ($model != null && $model->toggleBlock()) { 259 | return ['forceClose' => true, 'forceReload' => true]; 260 | } else { 261 | return [ 262 | 'title' => 'An error occurred', 263 | 'content' => 'Can not toggle block this user. Getting unknow error', 264 | 'footer' => Html::button('Close', ['class' => 'btn btn-default pull-left', 'data-dismiss' => "modal"]) 265 | ]; 266 | return; 267 | } 268 | } 269 | 270 | public function actionToggleSuperuser($id) { 271 | $model = $this->findModel($id); 272 | $model->scenario = 'toggle-administrator'; 273 | 274 | Yii::$app->response->format = Response::FORMAT_JSON; 275 | 276 | if (Yii::$app->user->getId() == $id) { 277 | return [ 278 | 'title' => 'An error occurred', 279 | 'content' => 'You can not disable superuser of yourself', 280 | 'footer' => Html::button('Close', ['class' => 'btn btn-default pull-left', 'data-dismiss' => "modal"]) 281 | ]; 282 | } 283 | 284 | Yii::$app->response->format = Response::FORMAT_JSON; 285 | if ($model != null && $model->toggleAdministrator()) { 286 | return ['forceClose' => true, 'forceReload' => true]; 287 | } else { 288 | return [ 289 | 'title' => 'An error occurred', 290 | 'content' => 'Can not toggle block this user. Getting unknow error', 291 | 'footer' => Html::button('Close', ['class' => 'btn btn-default pull-left', 'data-dismiss' => "modal"]) 292 | ]; 293 | } 294 | } 295 | 296 | /** 297 | * Delete multiple existing UserAccounts model. 298 | * For ajax request will return json object 299 | * and for non-ajax request if deletion is successful, the browser will be redirected to the 'index' page. 300 | * @param integer $id 301 | * @return mixed 302 | */ 303 | public function actionBulkDelete() { 304 | $request = Yii::$app->request; 305 | $pks = json_decode($request->post('pks')); // Array or selected records primary keys 306 | 307 | if (in_array(Yii::$app->user->getId(), $pks)) { 308 | if ($request->isAjax) { 309 | Yii::$app->response->format = Response::FORMAT_JSON; 310 | return [ 311 | 'title' => 'An error occurred', 312 | 'content' => 'You can not delete yourself. Please get our your account in your selection', 313 | 'footer' => Html::button('Close', ['class' => 'btn btn-default pull-left', 'data-dismiss' => "modal"]) 314 | ]; 315 | } else { 316 | return $this->redirect(['index']); 317 | } 318 | } 319 | 320 | $userClassName = $this->userPlusModule->getModelClassName('UserAccounts'); 321 | foreach (call_user_func($userClassName . '::findAll', $pks) as $model) { 322 | $model->delete(); 323 | } 324 | 325 | 326 | if ($request->isAjax) { 327 | /* 328 | * Process for ajax request 329 | */ 330 | Yii::$app->response->format = Response::FORMAT_JSON; 331 | return ['forceClose' => true, 'forceReload' => true]; 332 | } else { 333 | /* 334 | * Process for non-ajax request 335 | */ 336 | return $this->redirect(['index']); 337 | } 338 | } 339 | 340 | public function actionBulkBlock() { 341 | $request = Yii::$app->request; 342 | $pks = json_decode($request->post('pks')); // Array or selected records primary keys 343 | 344 | 345 | if (in_array(Yii::$app->user->getId(), $pks)) { 346 | if ($request->isAjax) { 347 | Yii::$app->response->format = Response::FORMAT_JSON; 348 | return [ 349 | 'title' => 'An error occurred', 350 | 'content' => 'You can not block yourself. Please get our your account in your selection', 351 | 'footer' => Html::button('Close', ['class' => 'btn btn-default pull-left', 'data-dismiss' => "modal"]) 352 | ]; 353 | } else { 354 | return $this->redirect(['index']); 355 | } 356 | } 357 | 358 | $userClassName = $this->userPlusModule->getModelClassName('UserAccounts'); 359 | foreach (call_user_func($userClassName . '::findAll', $pks) as $model) { 360 | $model->scenario = 'block'; 361 | $model->block(); 362 | } 363 | 364 | 365 | if ($request->isAjax) { 366 | /* 367 | * Process for ajax request 368 | */ 369 | Yii::$app->response->format = Response::FORMAT_JSON; 370 | return ['forceClose' => true, 'forceReload' => true]; 371 | } else { 372 | /* 373 | * Process for non-ajax request 374 | */ 375 | return $this->redirect(['index']); 376 | } 377 | } 378 | 379 | public function actionBulkUnblock() { 380 | $request = Yii::$app->request; 381 | $pks = json_decode($request->post('pks')); // Array or selected records primary keys 382 | 383 | $userClassName = $this->userPlusModule->getModelClassName('UserAccounts'); 384 | foreach (call_user_func($userClassName . '::findAll', $pks) as $model) { 385 | $model->scenario = 'unblock'; 386 | $model->unblock(); 387 | } 388 | 389 | 390 | if ($request->isAjax) { 391 | /* 392 | * Process for ajax request 393 | */ 394 | Yii::$app->response->format = Response::FORMAT_JSON; 395 | return ['forceClose' => true, 'forceReload' => true]; 396 | } else { 397 | /* 398 | * Process for non-ajax request 399 | */ 400 | return $this->redirect(['index']); 401 | } 402 | } 403 | 404 | /** 405 | * Finds the UserAccounts model based on its primary key value. 406 | * If the model is not found, a 404 HTTP exception will be thrown. 407 | * @param integer $id 408 | * @return johnitvn\userplus\base\models\UserAccounts the loaded model 409 | * @throws NotFoundHttpException if the model cannot be found 410 | */ 411 | protected function findModel($id) { 412 | $userClassName = $this->userPlusModule->getModelClassName('UserAccounts'); 413 | if (($model = call_user_func($userClassName . '::findOne', $id)) !== null) { 414 | return $model; 415 | } else { 416 | throw new NotFoundHttpException('The requested page does not exist.'); 417 | } 418 | } 419 | 420 | } 421 | -------------------------------------------------------------------------------- /src/simple/controllers/SecurityController.php: -------------------------------------------------------------------------------- 1 | 12 | * @since 1.0.0 13 | */ 14 | class SecurityController extends WebController { 15 | 16 | /** 17 | * 18 | * @var string The view of login action 19 | */ 20 | protected $loginView = '@userplus/simple/views/security/login'; 21 | 22 | /** 23 | * 24 | * @var string The view of register action 25 | */ 26 | protected $registerView = '@userplus/simple/views/security/register'; 27 | 28 | /** 29 | * 30 | * @var string The view of change password action 31 | */ 32 | protected $changePasswordView = '@userplus/simple/views/security/change-password'; 33 | 34 | /** 35 | * @inheritdoc 36 | */ 37 | public function behaviors() { 38 | return [ 39 | 'access' => [ 40 | 'class' => AccessControl::className(), 41 | 'only' => ['logout', 'change-password', 'login', 'register'], 42 | 'rules' => [ 43 | [ 44 | 'actions' => ['login', 'register'], 45 | 'allow' => true, 46 | 'roles' => ['?'], 47 | ], 48 | [ 49 | 'actions' => ['logout', 'change-password'], 50 | 'allow' => true, 51 | 'roles' => ['@'], 52 | ], 53 | ], 54 | ], 55 | 'verbs' => [ 56 | 'class' => VerbFilter::className(), 57 | 'actions' => [ 58 | 'logout' => ['post'], 59 | ], 60 | ], 61 | ]; 62 | } 63 | 64 | /** 65 | * @inheritdoc 66 | */ 67 | public function actions() { 68 | return [ 69 | 'logout' => [ 70 | 'class' => 'johnitvn\userplus\base\actions\LogoutAction', 71 | ], 72 | 'login' => [ 73 | 'class' => 'johnitvn\userplus\base\actions\LoginAction', 74 | 'view' => $this->loginView, 75 | ], 76 | 'register' => [ 77 | 'class' => 'johnitvn\userplus\base\actions\RegisterAction', 78 | 'view' => $this->registerView, 79 | ], 80 | 'change-password' => [ 81 | 'class' => 'johnitvn\userplus\base\actions\ChangePasswordAction', 82 | 'view' => $this->changePasswordView, 83 | ], 84 | ]; 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /src/simple/migrations/m150703_191015_init.php: -------------------------------------------------------------------------------- 1 | createTable('user_accounts', [ 10 | 'id' => Schema::TYPE_PK, 11 | 'login' => Schema::TYPE_STRING . '(255) NOT NULL', 12 | 'password_hash' => Schema::TYPE_STRING . '(255) NOT NULL', 13 | 'auth_key' => Schema::TYPE_STRING . '(255) NOT NULL', 14 | 'administrator' => Schema::TYPE_INTEGER, 15 | 'creator' => Schema::TYPE_INTEGER, 16 | 'creator_ip' => Schema::TYPE_STRING . '(40)', 17 | 'confirm_token' => Schema::TYPE_STRING, 18 | 'recovery_token' => Schema::TYPE_STRING, 19 | 'blocked_at' => Schema::TYPE_INTEGER, 20 | 'confirmed_at' => Schema::TYPE_INTEGER, 21 | 'created_at' => Schema::TYPE_INTEGER . ' NOT NULL', 22 | 'updated_at' => Schema::TYPE_INTEGER . ' NOT NULL', 23 | ], $this->tableOptions); 24 | 25 | $this->createIndex('user_unique_login', 'user_accounts', 'login', true); 26 | } 27 | 28 | public function down() { 29 | $this->dropTable('user_accounts'); 30 | return true; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/simple/models/ChangePasswordForm.php: -------------------------------------------------------------------------------- 1 | 11 | * @since 1.0.0 12 | */ 13 | class ChangePasswordForm extends BaseChangePasswordForm { 14 | 15 | 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/simple/models/LoginForm.php: -------------------------------------------------------------------------------- 1 | 11 | * @since 1.0.0 12 | */ 13 | class LoginForm extends BaseLoginForm { 14 | 15 | /** 16 | * @inheritdoc 17 | */ 18 | public function attributeLabels() 19 | { 20 | $labels = parent::attributeLabels(); 21 | 22 | if($this->userPlusModule->loginType=="username"){ 23 | $labels['login'] = Yii::t('user', 'Username'); 24 | }else{ 25 | $labels['login'] = Yii::t('user', 'Email'); 26 | } 27 | 28 | return $labels; 29 | } 30 | 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/simple/models/RegisterForm.php: -------------------------------------------------------------------------------- 1 | 11 | * @since 1.0.0 12 | */ 13 | class RegisterForm extends BaseRegisterForm { 14 | 15 | /** 16 | * @inheritdoc 17 | */ 18 | public function attributeLabels() 19 | { 20 | $labels = parent::attributeLabels(); 21 | 22 | if($this->userPlusModule->loginType=="username"){ 23 | $labels['login'] = Yii::t('user', 'Username'); 24 | }else{ 25 | $labels['login'] = Yii::t('user', 'Email'); 26 | } 27 | 28 | return $labels; 29 | } 30 | 31 | /** 32 | * @inheritdoc 33 | */ 34 | public function rules(){ 35 | $rules = parent::rules(); 36 | 37 | if($this->userPlusModule->loginType=="username"){ 38 | $rules['loginPattern'] = ['login', 'match', 'pattern' => '/^[-a-zA-Z0-9_\.@]+$/']; 39 | $rules['loginLength'] = ['login', 'string', 'min' => 3, 'max' => 255]; 40 | }else{ 41 | $rules['loginPattern'] = ['login','email']; 42 | } 43 | return $rules; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/simple/models/UserAccounts.php: -------------------------------------------------------------------------------- 1 | 11 | * @since 1.0.0 12 | * 13 | * @property integer $id 14 | * @property string $login 15 | * @property string $username 16 | * @property string $password_hash 17 | * @property string $auth_key 18 | * @property integer $administrator 19 | * @property integer $creator 20 | * @property string $creator_ip 21 | * @property string $confirm_token 22 | * @property string $recovery_token 23 | * @property integer $blocked_at 24 | * @property integer $confirmed_at 25 | * @property integer $created_at 26 | * @property integer $updated_at 27 | */ 28 | class UserAccounts extends BaseUserAccounts{ 29 | 30 | 31 | /** 32 | * @inheritdoc 33 | */ 34 | public function rules(){ 35 | $rules = parent::rules(); 36 | 37 | if($this->userPlusModule->loginType=="username"){ 38 | $rules['loginPattern'] = ['login', 'match', 'pattern' => '/^[-a-zA-Z0-9_\.@]+$/']; 39 | $rules['loginLength'] = ['login', 'string', 'min' => 3, 'max' => 255]; 40 | }else{ 41 | $rules['loginPattern'] = ['login','email']; 42 | } 43 | 44 | return $rules; 45 | } 46 | 47 | /** 48 | * @inheritdoc 49 | */ 50 | public function attributeLabels() 51 | { 52 | $labels = parent::attributeLabels(); 53 | if($this->userPlusModule->loginType=="username"){ 54 | $labels['login'] = Yii::t('user', 'Username'); 55 | }else{ 56 | $labels['login'] = Yii::t('user', 'Email'); 57 | } 58 | return $labels; 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/simple/models/UserSearch.php: -------------------------------------------------------------------------------- 1 | 12 | * @since 1.0.0 13 | */ 14 | class UserSearch extends UserAccounts 15 | { 16 | /** 17 | * @inheritdoc 18 | */ 19 | public function rules() 20 | { 21 | return [ 22 | [['id','creator', 'creator_ip', 'confirmed_at','administrator' ,'created_at', 'updated_at'], 'integer'], 23 | [['login', 'password'], 'safe'], 24 | ]; 25 | } 26 | 27 | /** 28 | * @inheritdoc 29 | */ 30 | public function scenarios() 31 | { 32 | // bypass scenarios() implementation in the parent class 33 | return Model::scenarios(); 34 | } 35 | 36 | /** 37 | * Creates data provider instance with search query applied 38 | * 39 | * @param array $params 40 | * 41 | * @return ActiveDataProvider 42 | */ 43 | public function search($params) 44 | { 45 | $query = UserAccounts::find(); 46 | 47 | $dataProvider = new ActiveDataProvider([ 48 | 'query' => $query, 49 | ]); 50 | 51 | $this->load($params); 52 | 53 | if (!$this->validate()) { 54 | return $dataProvider; 55 | } 56 | 57 | $query->andFilterWhere([ 58 | 'id' => $this->id, 59 | 'creator'=> $this->creator, 60 | 'creator_ip' => $this->creator_ip, 61 | 'confirmed_at' => $this->confirmed_at, 62 | 'administrator'=> $this->administrator, 63 | 'created_at' => $this->created_at, 64 | 'updated_at' => $this->updated_at, 65 | ]); 66 | 67 | $query->andFilterWhere(['like', 'login', $this->login]); 68 | 69 | return $dataProvider; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/simple/views/manager/_assignment.php: -------------------------------------------------------------------------------- 1 | 'kartik\grid\CheckboxColumn', 10 | 'width' => '20px', 11 | ], 12 | [ 13 | 'class' => 'kartik\grid\SerialColumn', 14 | 'width' => '30px', 15 | ], 16 | [ 17 | 'class' => '\kartik\grid\DataColumn', 18 | 'attribute' => 'id', 19 | 'width' => '40px', 20 | ], 21 | [ 22 | 'class' => '\kartik\grid\DataColumn', 23 | 'attribute' => 'login', 24 | ], 25 | [ 26 | 'class' => '\kartik\grid\DataColumn', 27 | 'attribute' => 'created_at', 28 | 'value' => function($model) { 29 | return date('d/m/Y', $model->created_at); 30 | }, 31 | 'filter' => DatePicker::widget([ 32 | 'model' => $searchModel, 33 | 'attribute' => 'created_at', 34 | 'dateFormat' => 'php:Y-m-d', 35 | 'options' => [ 36 | 'class' => 'form-control', 37 | ], 38 | ]), 39 | ], 40 | [ 41 | 'class' => '\kartik\grid\DataColumn', 42 | 'width' => '50px', 43 | 'attribute' => 'blocked_at', 44 | 'label'=>'Status', 45 | 'value' => function ($model) { 46 | if ($model->blocked_at !== null) { 47 | return Html::a(Yii::t('user', 'Unblock'), ['toggle-block', 'id' => $model->id], [ 48 | 'class' => 'btn btn-xs btn-warning btn-block', 49 | 'role' => 'modal-remote', 50 | 'data-confirm' => false, 'data-method' => false, // for overide yii data api 51 | 'data-request-method' => 'post', 52 | 'data-confirm-title' => Yii::t('user', 'Are you sure?'), 53 | 'data-confirm-message' => Yii::t('user', 'Are you sure you want to unblock this user?'), 54 | ]); 55 | } else { 56 | return Html::a(Yii::t('user', 'Block'), ['toggle-block', 'id' => $model->id], [ 57 | 'class' => 'btn btn-xs btn-danger btn-block', 58 | 'role' => 'modal-remote', 59 | 'data-confirm' => false, 'data-method' => false, // for overide yii data api 60 | 'data-request-method' => 'post', 61 | 'data-confirm-title' => Yii::t('user', 'Are you sure?'), 62 | 'data-confirm-message' => Yii::t('user', 'Are you sure you want to unblock this user?'), 63 | ]); 64 | } 65 | }, 66 | 'format' => 'raw', 67 | 'visible' => Yii::$app->user->identity->isAdministrator(), 68 | ], 69 | [ 70 | 'class' => '\kartik\grid\DataColumn', 71 | 'width' => '130px', 72 | 'attribute' => 'administrator', 73 | 'value' => function ($model) { 74 | if (!$model->administrator) { 75 | return Html::a(Yii::t('user', 'Set SU'), ['toggle-superuser', 'id' => $model->id], [ 76 | 'class' => 'btn btn-xs btn-danger btn-block', 77 | 'role' => 'modal-remote', 78 | 'data-confirm' => false, 'data-method' => false, // for overide yii data api 79 | 'data-request-method' => 'post', 80 | 'data-confirm-title' => Yii::t('user', 'Are you sure?'), 81 | 'data-confirm-message' => Yii::t('user', 'Are you sure you want to unblock this user?'), 82 | ]); 83 | } else { 84 | return Html::a(Yii::t('user', 'Remove SU'), ['toggle-superuser', 'id' => $model->id], [ 85 | 'class' => 'btn btn-xs btn-info btn-block', 86 | 'role' => 'modal-remote', 87 | 'data-confirm' => false, 'data-method' => false, // for overide yii data api 88 | 'data-request-method' => 'post', 89 | 'data-confirm-title' => Yii::t('user', 'Are you sure?'), 90 | 'data-confirm-message' => Yii::t('user', 'Are you sure you want to unblock this user?'), 91 | ]); 92 | } 93 | }, 94 | 'format' => 'raw', 95 | 'visible' => Yii::$app->user->identity->isAdministrator(), 96 | 'filter' => [0 => 'Not Admin', 1 => 'Admin'], 97 | ] 98 | ]; 99 | 100 | $rbacModule = Yii::$app->getModule('rbac'); 101 | if (get_class($rbacModule) === 'johnitvn\rbacplus\Module') { 102 | /** 103 | * Intergrate with Rbac Plus extension 104 | */ 105 | $columns[] = [ 106 | 'class' => 'kartik\grid\DataColumn', 107 | 'header' => Yii::t('rbac', 'Assignment'), 108 | 'hAlign' => 'center', 109 | 'value'=>function($model){ 110 | return Html::a('', 111 | ['/rbac/assignment/assignment', 'id' => $model->id], 112 | [ 113 | 'role' => 'modal-remote', 114 | 'title' => Yii::t('user', 'Assignment'), 115 | ] 116 | ); 117 | }, 118 | 'format' => 'raw', 119 | 'visible' => Yii::$app->user->identity->isAdministrator(), 120 | ]; 121 | 122 | } 123 | 124 | 125 | $columns[] = [ 126 | 'class' => 'kartik\grid\ActionColumn', 127 | 'dropdown' => false, 128 | 'vAlign' => 'middle', 129 | 'hAlign' => 'center', 130 | 'urlCreator' => function($action, $model, $key, $index) { 131 | return Url::to([$action, 'id' => $key]); 132 | }, 133 | 'viewOptions' => ['role' => 'modal-remote', 'title' => 'View', 'data-toggle' => 'tooltip'], 134 | 'updateOptions' => ['role' => 'modal-remote', 'title' => 'Update', 'data-toggle' => 'tooltip'], 135 | 'deleteOptions' => ['role' => 'modal-remote', 'title' => 'Delete', 136 | 'data-confirm' => false, 'data-method' => false, // for overide yii data api 137 | 'data-request-method' => 'post', 138 | 'data-toggle' => 'tooltip', 139 | 'data-confirm-title' => 'Are you sure?', 140 | 'data-confirm-message' => 'Are you sure want to delete this item'], 141 | ]; 142 | 143 | return $columns; -------------------------------------------------------------------------------- /src/simple/views/manager/_detail.php: -------------------------------------------------------------------------------- 1 | 6 |
7 | 8 | $model, 10 | 'attributes' => [ 11 | 'id', 12 | 'login', 13 | [ 14 | 'attribute'=>'administrator', 15 | 'value'=> $model['administrator']?"Yes":"No" 16 | ], 17 | [ 18 | 'attribute'=>'creator', 19 | 'format' => 'raw', 20 | 'value'=> $model['creator']==-1?"Created by Console": 21 | $model['creator']==-2?"User register by my self": 22 | Html::a(UserAccounts::findOne($model['creator'])->login,['/user/manager/view','id'=>UserAccounts::findOne($model['creator'])->id],["role"=>"modal-remote"]) 23 | ], 24 | 'creator_ip', 25 | [ 26 | 'attribute'=>'blocked_at', 27 | 'value'=> $model['blocked_at']==null?"Not blocked":date("d/m/Y H:i:s",$model['blocked_at']) 28 | ], 29 | [ 30 | 'attribute'=>'created_at', 31 | 'value'=>date("d/m/Y H:i:s",$model['created_at']) 32 | ], 33 | [ 34 | 'attribute'=>'updated_at', 35 | 'value'=>$model['updated_at']==-1?\Yii::t("user","Never Update"):date("d/m/Y H:i:s",$model['updated_at']) 36 | ], 37 | ], 38 | ]) ?> 39 | 40 |
41 | -------------------------------------------------------------------------------- /src/simple/views/manager/_form.php: -------------------------------------------------------------------------------- 1 | 5 | 6 |
7 | 8 | 9 | 10 | 11 | field($model, 'login')->textInput(['maxlength' => true]) ?> 12 | 13 | field($model, 'password')->passwordInput(['maxlength' => true]) ?> 14 | 15 | field($model, 'confirm_password')->passwordInput(['maxlength' => true]) ?> 16 | 17 | request->isAjax) { ?> 18 |
19 | isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?> 20 |
21 | 22 | 23 | 24 | 25 |
26 | -------------------------------------------------------------------------------- /src/simple/views/manager/create.php: -------------------------------------------------------------------------------- 1 |
2 | render('_form', [ 3 | 'model' => $model, 4 | ]) ?> 5 |
6 | -------------------------------------------------------------------------------- /src/simple/views/manager/index.php: -------------------------------------------------------------------------------- 1 | title = 'Users'; 9 | $this->params['breadcrumbs'][] = $this->title; 10 | 11 | CrudAsset::register($this); 12 | 13 | ?> 14 |
15 |
16 | 'crud-datatable', 18 | 'dataProvider' => $dataProvider, 19 | 'filterModel' => $searchModel, 20 | 'pjax'=>true, 21 | 'columns' => require(__DIR__.'/_columns.php'), 22 | 'toolbar'=> [ 23 | ['content'=> 24 | Html::a('', ['create'], 25 | ['role'=>'modal-remote','title'=> 'Create new Users','class'=>'btn btn-default']). 26 | Html::a('', [''], 27 | ['data-pjax'=>1, 'class'=>'btn btn-default', 'title'=>'Reset Grid']). 28 | '{toggleData}'. 29 | '{export}' 30 | ], 31 | ], 32 | 'striped' => true, 33 | 'condensed' => true, 34 | 'responsive' => true, 35 | 'panel' => [ 36 | 'type' => 'primary', 37 | 'heading' => ' Users listing', 38 | 'before'=>'* Resize table columns just like a spreadsheet by dragging the column edges.', 39 | 'after'=>BulkButtonWidget::widget([ 40 | 'buttons'=> Html::a('  Delete All', 41 | ["bulk-delete"] , 42 | [ 43 | "class"=>"btn btn-danger btn-xs", 44 | 'role'=>'modal-remote-bulk', 45 | 'data-confirm'=>false, 'data-method'=>false,// for overide yii data api 46 | 'data-request-method'=>'post', 47 | 'data-confirm-title'=>'Are you sure?', 48 | 'data-confirm-message'=>'Are you sure want to delete all this items' 49 | ]).' '. 50 | Html::a('  Block All', 51 | ["bulk-block"] , 52 | [ 53 | "class"=>"btn btn-danger btn-xs", 54 | 'role'=>'modal-remote-bulk', 55 | 'data-confirm'=>false, 'data-method'=>false,// for overide yii data api 56 | 'data-request-method'=>'post', 57 | 'data-confirm-title'=>'Are you sure?', 58 | 'data-confirm-message'=>'Are you sure want to block all this items' 59 | ]).' '. 60 | Html::a('  Unblock All', 61 | ["bulk-unblock"] , 62 | [ 63 | "class"=>"btn btn-warning btn-xs", 64 | 'role'=>'modal-remote-bulk', 65 | 'data-confirm'=>false, 'data-method'=>false,// for overide yii data api 66 | 'data-request-method'=>'post', 67 | 'data-confirm-title'=>'Are you sure?', 68 | 'data-confirm-message'=>'Are you sure want to unblock all this items' 69 | ]), 70 | ]). 71 | '
', 72 | ] 73 | ])?> 74 |
75 |
76 | "ajaxCrubModal", 78 | "footer"=>"",// always need it for jquery plugin 79 | ])?> 80 | 81 | -------------------------------------------------------------------------------- /src/simple/views/manager/update.php: -------------------------------------------------------------------------------- 1 |
2 | render('_form', [ 3 | 'model' => $model, 4 | ]) ?> 5 | 6 |
7 | -------------------------------------------------------------------------------- /src/simple/views/manager/view.php: -------------------------------------------------------------------------------- 1 | [ 6 | [ 7 | 'label' => Yii::t('user','User Detail'), 8 | 'content' => $this->render("_detail",['model'=>$model]), 9 | 'active' => true 10 | ], 11 | [ 12 | 'label' => Yii::t('user','Role Assignment'), 13 | 'content' => $this->render("_assignment",['model'=>$model]), 14 | ], 15 | ] 16 | ]); 17 | -------------------------------------------------------------------------------- /src/simple/views/security/change-password.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('user', 'Change Password'); 5 | ?> 6 |
7 |
8 |
9 |
10 |

title) ?>

11 |
12 |
13 | 'change-password-form', 15 | 'enableAjaxValidation' => true, 16 | 'enableClientValidation' => false, 17 | ]); ?> 18 | 19 | field($model, 'old_password')->passwordInput() ?> 20 | 21 | field($model, 'new_password')->passwordInput() ?> 22 | 23 | field($model, 'confirm_password')->passwordInput() ?> 24 | 25 | 'btn btn-primary btn-block']) ?> 26 | 27 | 28 |
29 |
30 |
31 |
-------------------------------------------------------------------------------- /src/simple/views/security/login.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('user', 'Sign in'); 7 | $module = Yii::$app->getModule('user'); 8 | ?> 9 |
10 |
11 |
12 |
13 |

title) ?>

14 |
15 |
16 | 'login-form', 18 | 'enableAjaxValidation' => true, 19 | 'enableClientValidation' => false, 20 | 'validateOnBlur' => false, 21 | 'validateOnType' => false, 22 | 'validateOnChange' => false, 23 | ]) ?> 24 | 25 | field($model, 'login', ['inputOptions' => ['autofocus' => 'autofocus', 'class' => 'form-control', 'tabindex' => '1']]) ?> 26 | 27 | field($model, 'password', ['inputOptions' => ['class' => 'form-control', 'tabindex' => '2']])->passwordInput()->label(Yii::t('user', 'Password')) ?> 28 | 29 | field($model, 'rememberMe')->checkbox(['tabindex' => '4']) ?> 30 | 31 | 'btn btn-primary btn-block', 'tabindex' => '3']) ?> 32 | 33 | 34 |
35 |
36 | enableRegister): ?> 37 |

38 | 39 |

40 | 41 |
42 |
43 | -------------------------------------------------------------------------------- /src/simple/views/security/register.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('user', 'Sign up'); 5 | ?> 6 |
7 |
8 |
9 |
10 |

title) ?>

11 |
12 |
13 | 'registration-form', 15 | 'enableAjaxValidation' => true, 16 | 'enableClientValidation' => false, 17 | ]); ?> 18 | 19 | field($model, 'login') ?> 20 | 21 | field($model, 'password')->passwordInput() ?> 22 | 23 | field($model, 'confirm_password')->passwordInput() ?> 24 | 25 | 'btn btn-primary btn-block']) ?> 26 | 27 | 28 |
29 |
30 |

31 | 32 |

33 |
34 |
--------------------------------------------------------------------------------