├── messages └── en.php ├── runtime └── .gitignore ├── tests ├── codeception │ ├── unit │ │ ├── fixtures │ │ │ ├── .gitkeep │ │ │ └── data │ │ │ │ └── .gitkeep │ │ ├── templates │ │ │ └── fixtures │ │ │ │ └── .gitkeep │ │ ├── _bootstrap.php │ │ └── models │ │ │ ├── UserTest.php │ │ │ ├── ContactFormTest.php │ │ │ └── LoginFormTest.php │ ├── _output │ │ └── .gitignore │ ├── fixtures │ │ └── .gitignore │ ├── templates │ │ └── .gitignore │ ├── acceptance │ │ ├── _bootstrap.php │ │ ├── AboutCept.php │ │ ├── HomeCept.php │ │ ├── LoginCept.php │ │ └── ContactCept.php │ ├── functional │ │ ├── _bootstrap.php │ │ ├── AboutCept.php │ │ ├── HomeCept.php │ │ ├── LoginCept.php │ │ └── ContactCept.php │ ├── .gitignore │ ├── unit.suite.yml │ ├── config │ │ ├── unit.php │ │ ├── acceptance.php │ │ ├── config.php │ │ └── functional.php │ ├── _pages │ │ ├── AboutPage.php │ │ ├── LoginPage.php │ │ └── ContactPage.php │ ├── functional.suite.yml │ ├── bin │ │ ├── yii.bat │ │ ├── _bootstrap.php │ │ └── yii │ ├── _bootstrap.php │ └── acceptance.suite.yml ├── codeception.yml └── README.md ├── web ├── assets │ └── .gitignore ├── robots.txt ├── favicon.ico ├── index.php ├── .htaccess.sample ├── index-test.php └── css │ └── site.css ├── commands ├── data │ └── readme.txt └── HelloController.php ├── .bowerrc ├── config ├── params.php ├── db.php ├── console.php └── web.php ├── views ├── site │ ├── about.php │ ├── error.php │ ├── login.php │ ├── contact.php │ └── index.php ├── user │ ├── admin │ │ ├── flash.php │ │ ├── create.php │ │ ├── update.php │ │ └── index.php │ ├── recovery │ │ ├── reset.php │ │ ├── request.php │ │ └── finish.php │ ├── registration │ │ ├── resend.php │ │ ├── register.php │ │ ├── connect.php │ │ └── finish.php │ ├── settings │ │ ├── _menu.php │ │ ├── account.php │ │ ├── profile.php │ │ └── networks.php │ ├── mail │ │ ├── welcome.php │ │ ├── recovery.php │ │ ├── reconfirmation.php │ │ ├── confirmation.php │ │ └── layouts │ │ │ └── html.php │ ├── profile │ │ └── show.php │ └── security │ │ └── login.php └── layouts │ └── main.php ├── .gitignore ├── yii.bat ├── assets └── AppAsset.php ├── yii ├── mail └── layouts │ └── html.php ├── LICENSE.md ├── LICENSE-yii.md ├── models ├── ContactForm.php ├── RegistrationForm.php ├── LoginForm.php └── User.php ├── controllers ├── SecurityController.php ├── SiteController.php └── DashboardController.php ├── composer.json ├── README.md ├── yii2simple.sql └── requirements.php /messages/en.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /runtime/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /tests/codeception/unit/fixtures/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/assets/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /web/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: -------------------------------------------------------------------------------- /commands/data/readme.txt: -------------------------------------------------------------------------------- 1 | rbac data location. 2 | -------------------------------------------------------------------------------- /tests/codeception/unit/fixtures/data/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/codeception/_output/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /tests/codeception/unit/templates/fixtures/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory" : "vendor/bower" 3 | } 4 | -------------------------------------------------------------------------------- /tests/codeception/fixtures/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /tests/codeception/templates/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /web/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azraf/yii2-simple/HEAD/web/favicon.ico -------------------------------------------------------------------------------- /config/params.php: -------------------------------------------------------------------------------- 1 | 'admin@example.com', 5 | ]; 6 | -------------------------------------------------------------------------------- /tests/codeception/unit/_bootstrap.php: -------------------------------------------------------------------------------- 1 | 'yii\db\Connection', 5 | 'dsn' => 'mysql:host=localhost;dbname=yii2simple', 6 | 'username' => 'root', 7 | 'password' => '', 8 | 'charset' => 'utf8', 9 | ]; 10 | -------------------------------------------------------------------------------- /tests/codeception/acceptance/AboutCept.php: -------------------------------------------------------------------------------- 1 | wantTo('ensure that about works'); 7 | AboutPage::openBy($I); 8 | $I->see('About', 'h1'); 9 | -------------------------------------------------------------------------------- /tests/codeception/functional/AboutCept.php: -------------------------------------------------------------------------------- 1 | wantTo('ensure that about works'); 7 | AboutPage::openBy($I); 8 | $I->see('About', 'h1'); 9 | -------------------------------------------------------------------------------- /tests/codeception/config/unit.php: -------------------------------------------------------------------------------- 1 | wantTo('ensure that home page works'); 5 | $I->amOnPage(Yii::$app->homeUrl); 6 | $I->see('My Company'); 7 | $I->seeLink('About'); 8 | $I->click('About'); 9 | $I->see('This is the About page.'); 10 | -------------------------------------------------------------------------------- /tests/codeception/functional/HomeCept.php: -------------------------------------------------------------------------------- 1 | wantTo('ensure that home page works'); 5 | $I->amOnPage(Yii::$app->homeUrl); 6 | $I->see('My Company'); 7 | $I->seeLink('About'); 8 | $I->click('About'); 9 | $I->see('This is the About page.'); 10 | -------------------------------------------------------------------------------- /tests/codeception/_pages/AboutPage.php: -------------------------------------------------------------------------------- 1 | run(); 13 | -------------------------------------------------------------------------------- /tests/codeception/unit/models/UserTest.php: -------------------------------------------------------------------------------- 1 | loadFixtures(['user']); 14 | } 15 | 16 | // TODO add test methods here 17 | } 18 | -------------------------------------------------------------------------------- /views/site/about.php: -------------------------------------------------------------------------------- 1 | title = 'About'; 6 | $this->params['breadcrumbs'][] = $this->title; 7 | ?> 8 |
9 |

title) ?>

10 | 11 |

12 | This is the About page. You may modify the following file to customize its content: 13 |

14 | 15 | 16 |
17 | -------------------------------------------------------------------------------- /tests/codeception/config/config.php: -------------------------------------------------------------------------------- 1 | [ 7 | 'db' => [ 8 | 'dsn' => 'mysql:host=localhost;dbname=yii2_basic_tests', 9 | ], 10 | 'mailer' => [ 11 | 'useFileTransport' => true, 12 | ], 13 | 'urlManager' => [ 14 | 'showScriptName' => true, 15 | ], 16 | ], 17 | ]; 18 | -------------------------------------------------------------------------------- /web/.htaccess.sample: -------------------------------------------------------------------------------- 1 | # Turning on the rewrite engine is necessary for the following rules and features. 2 | # FollowSymLinks must be enabled for this to work. 3 | 4 | Options +FollowSymlinks 5 | RewriteEngine On 6 | 7 | # Unless an explicit file or directory exists, redirect all request to Yii entry script 8 | 9 | RewriteCond %{REQUEST_FILENAME} !-f 10 | RewriteCond %{REQUEST_FILENAME} !-d 11 | RewriteRule . index.php 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # phpstorm project files 2 | .idea 3 | 4 | # netbeans project files 5 | nbproject 6 | 7 | # zend studio for eclipse project files 8 | .buildpath 9 | .project 10 | .settings 11 | 12 | # windows thumbnail cache 13 | Thumbs.db 14 | 15 | # composer vendor dir 16 | /vendor 17 | 18 | # composer itself is not needed 19 | composer.phar 20 | 21 | # Mac DS_Store Files 22 | .DS_Store 23 | 24 | # phpunit itself is not needed 25 | phpunit.phar 26 | # local phpunit config 27 | /phpunit.xml 28 | -------------------------------------------------------------------------------- /tests/codeception/functional.suite.yml: -------------------------------------------------------------------------------- 1 | # Codeception Test Suite Configuration 2 | 3 | # suite for functional (integration) tests. 4 | # emulate web requests and make application process them. 5 | # (tip: better to use with frameworks). 6 | 7 | # RUN `build` COMMAND AFTER ADDING/REMOVING MODULES. 8 | #basic/web/index.php 9 | class_name: FunctionalTester 10 | modules: 11 | enabled: 12 | - Filesystem 13 | - Yii2 14 | config: 15 | Yii2: 16 | configFile: 'codeception/config/functional.php' 17 | -------------------------------------------------------------------------------- /tests/codeception.yml: -------------------------------------------------------------------------------- 1 | actor: Tester 2 | paths: 3 | tests: codeception 4 | log: codeception/_output 5 | data: codeception/_data 6 | helpers: codeception/_support 7 | settings: 8 | bootstrap: _bootstrap.php 9 | suite_class: \PHPUnit_Framework_TestSuite 10 | memory_limit: 1024M 11 | log: true 12 | colors: true 13 | config: 14 | # the entry script URL (without host info) for functional and acceptance tests 15 | # PLEASE ADJUST IT TO THE ACTUAL ENTRY SCRIPT URL 16 | test_entry_url: /index-test.php -------------------------------------------------------------------------------- /yii.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | rem ------------------------------------------------------------- 4 | rem Yii command line bootstrap script for Windows. 5 | rem 6 | rem @author Qiang Xue 7 | rem @link http://www.yiiframework.com/ 8 | rem @copyright Copyright (c) 2008 Yii Software LLC 9 | rem @license http://www.yiiframework.com/license/ 10 | rem ------------------------------------------------------------- 11 | 12 | @setlocal 13 | 14 | set YII_PATH=%~dp0 15 | 16 | if "%PHP_COMMAND%" == "" set PHP_COMMAND=php.exe 17 | 18 | "%PHP_COMMAND%" "%YII_PATH%yii" %* 19 | 20 | @endlocal 21 | -------------------------------------------------------------------------------- /web/index-test.php: -------------------------------------------------------------------------------- 1 | run(); 17 | -------------------------------------------------------------------------------- /tests/codeception/bin/yii.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | rem ------------------------------------------------------------- 4 | rem Yii command line bootstrap script for Windows. 5 | rem 6 | rem @author Qiang Xue 7 | rem @link http://www.yiiframework.com/ 8 | rem @copyright Copyright (c) 2008 Yii Software LLC 9 | rem @license http://www.yiiframework.com/license/ 10 | rem ------------------------------------------------------------- 11 | 12 | @setlocal 13 | 14 | set YII_PATH=%~dp0 15 | 16 | if "%PHP_COMMAND%" == "" set PHP_COMMAND=php.exe 17 | 18 | "%PHP_COMMAND%" "%YII_PATH%yii" %* 19 | 20 | @endlocal 21 | -------------------------------------------------------------------------------- /tests/codeception/bin/_bootstrap.php: -------------------------------------------------------------------------------- 1 | title = $name; 11 | ?> 12 |
13 | 14 |

title) ?>

15 | 16 |
17 | 18 |
19 | 20 |

21 | The above error occurred while the Web server was processing your request. 22 |

23 |

24 | Please contact us if you think this is a server error. Thank you. 25 |

26 | 27 |
28 | -------------------------------------------------------------------------------- /assets/AppAsset.php: -------------------------------------------------------------------------------- 1 | 14 | * @since 2.0 15 | */ 16 | class AppAsset extends AssetBundle 17 | { 18 | public $basePath = '@webroot'; 19 | public $baseUrl = '@web'; 20 | public $css = [ 21 | 'css/site.css', 22 | ]; 23 | public $js = [ 24 | ]; 25 | public $depends = [ 26 | 'yii\web\YiiAsset', 27 | 'yii\bootstrap\BootstrapAsset', 28 | ]; 29 | } 30 | -------------------------------------------------------------------------------- /tests/codeception/_pages/LoginPage.php: -------------------------------------------------------------------------------- 1 | actor->fillField('input[name="LoginForm[username]"]', $username); 22 | $this->actor->fillField('input[name="LoginForm[password]"]', $password); 23 | $this->actor->click('login-button'); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tests/codeception/_bootstrap.php: -------------------------------------------------------------------------------- 1 | $value) { 21 | $inputType = $field === 'body' ? 'textarea' : 'input'; 22 | $this->actor->fillField($inputType . '[name="ContactForm[' . $field . ']"]', $value); 23 | } 24 | $this->actor->click('contact-button'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /yii: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | run(); 24 | exit($exitCode); 25 | -------------------------------------------------------------------------------- /mail/layouts/html.php: -------------------------------------------------------------------------------- 1 | 8 | beginPage() ?> 9 | 10 | 11 | 12 | 13 | <?= Html::encode($this->title) ?> 14 | head() ?> 15 | 16 | 17 | beginBody() ?> 18 | 19 | endBody() ?> 20 | 21 | 22 | endPage() ?> 23 | -------------------------------------------------------------------------------- /views/user/admin/flash.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE.md 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | /** 13 | * @var yii\web\View $this 14 | */ 15 | 16 | ?> 17 | 18 | getSession()->hasFlash('user.success')): ?> 19 |
20 |

getSession()->getFlash('user.success') ?>

21 |
22 | 23 | 24 | getSession()->hasFlash('user.error')): ?> 25 |
26 |

getSession()->getFlash('user.error') ?>

27 |
28 | -------------------------------------------------------------------------------- /tests/codeception/functional/LoginCept.php: -------------------------------------------------------------------------------- 1 | wantTo('ensure that login works'); 7 | 8 | $loginPage = LoginPage::openBy($I); 9 | 10 | $I->see('Login', 'h1'); 11 | 12 | $I->amGoingTo('try to login with empty credentials'); 13 | $loginPage->login('', ''); 14 | $I->expectTo('see validations errors'); 15 | $I->see('Username cannot be blank.'); 16 | $I->see('Password cannot be blank.'); 17 | 18 | $I->amGoingTo('try to login with wrong credentials'); 19 | $loginPage->login('admin', 'wrong'); 20 | $I->expectTo('see validations errors'); 21 | $I->see('Incorrect username or password.'); 22 | 23 | $I->amGoingTo('try to login with correct credentials'); 24 | $loginPage->login('admin', 'admin'); 25 | $I->expectTo('see user info'); 26 | $I->see('Logout (admin)'); 27 | -------------------------------------------------------------------------------- /commands/HelloController.php: -------------------------------------------------------------------------------- 1 | 18 | * @since 2.0 19 | */ 20 | class HelloController extends Controller 21 | { 22 | /** 23 | * This command echoes what you have entered as the message. 24 | * @param string $message the message to be echoed. 25 | */ 26 | public function actionIndex($message = 'hello world') 27 | { 28 | echo $message . "\n"; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /config/console.php: -------------------------------------------------------------------------------- 1 | 'basic-console', 10 | 'basePath' => dirname(__DIR__), 11 | 'bootstrap' => ['log', 'gii'], 12 | 'controllerNamespace' => 'app\commands', 13 | 'modules' => [ 14 | 'gii' => 'yii\gii\Module', 15 | ], 16 | 'components' => [ 17 | 'cache' => [ 18 | 'class' => 'yii\caching\FileCache', 19 | ], 20 | 'log' => [ 21 | 'targets' => [ 22 | [ 23 | 'class' => 'yii\log\FileTarget', 24 | 'levels' => ['error', 'warning'], 25 | ], 26 | ], 27 | ], 28 | 'db' => $db, 29 | ], 30 | 'params' => $params, 31 | ]; 32 | -------------------------------------------------------------------------------- /tests/codeception/config/functional.php: -------------------------------------------------------------------------------- 1 | [ 13 | 'request' => [ 14 | // it's not recommended to run functional tests with CSRF validation enabled 15 | 'enableCsrfValidation' => false, 16 | // but if you absolutely need it set cookie domain to localhost 17 | /* 18 | 'csrfCookie' => [ 19 | 'domain' => 'localhost', 20 | ], 21 | */ 22 | ], 23 | ], 24 | ] 25 | ); 26 | -------------------------------------------------------------------------------- /tests/codeception/bin/yii: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | [ 18 | 'fixture' => [ 19 | 'class' => 'yii\faker\FixtureController', 20 | 'fixtureDataPath' => '@tests/codeception/fixtures', 21 | 'templatePath' => '@tests/codeception/templates', 22 | 'namespace' => 'tests\codeception\fixtures', 23 | ], 24 | ], 25 | ] 26 | ); 27 | 28 | $application = new yii\console\Application($config); 29 | $exitCode = $application->run(); 30 | exit($exitCode); 31 | -------------------------------------------------------------------------------- /tests/codeception/acceptance/LoginCept.php: -------------------------------------------------------------------------------- 1 | wantTo('ensure that login works'); 7 | 8 | $loginPage = LoginPage::openBy($I); 9 | 10 | $I->see('Login', 'h1'); 11 | 12 | $I->amGoingTo('try to login with empty credentials'); 13 | $loginPage->login('', ''); 14 | $I->expectTo('see validations errors'); 15 | $I->see('Username cannot be blank.'); 16 | $I->see('Password cannot be blank.'); 17 | 18 | $I->amGoingTo('try to login with wrong credentials'); 19 | $loginPage->login('admin', 'wrong'); 20 | if (method_exists($I, 'wait')) { 21 | $I->wait(3); // only for selenium 22 | } 23 | $I->expectTo('see validations errors'); 24 | $I->see('Incorrect username or password.'); 25 | 26 | $I->amGoingTo('try to login with correct credentials'); 27 | $loginPage->login('admin', 'admin'); 28 | if (method_exists($I, 'wait')) { 29 | $I->wait(3); // only for selenium 30 | } 31 | $I->expectTo('see user info'); 32 | $I->see('Logout (admin)'); 33 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Simple project 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /tests/codeception/acceptance.suite.yml: -------------------------------------------------------------------------------- 1 | # Codeception Test Suite Configuration 2 | 3 | # suite for acceptance tests. 4 | # perform tests in browser using the Selenium-like tools. 5 | # powered by Mink (http://mink.behat.org). 6 | # (tip: that's what your customer will see). 7 | # (tip: test your ajax and javascript by one of Mink drivers). 8 | 9 | # RUN `build` COMMAND AFTER ADDING/REMOVING MODULES. 10 | 11 | class_name: AcceptanceTester 12 | modules: 13 | enabled: 14 | - PhpBrowser 15 | # you can use WebDriver instead of PhpBrowser to test javascript and ajax. 16 | # This will require you to install selenium. See http://codeception.com/docs/04-AcceptanceTests#Selenium 17 | # "restart" option is used by the WebDriver to start each time per test-file new session and cookies, 18 | # it is useful if you want to login in your app in each test. 19 | # - WebDriver 20 | config: 21 | PhpBrowser: 22 | url: 'http://localhost:8080' 23 | # WebDriver: 24 | # url: 'http://localhost' 25 | # browser: firefox 26 | # restart: true 27 | -------------------------------------------------------------------------------- /views/user/recovery/reset.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE.md 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | use yii\helpers\Html; 13 | use yii\widgets\ActiveForm; 14 | 15 | /** 16 | * @var yii\web\View $this 17 | * @var yii\widgets\ActiveForm $form 18 | * @var dektrium\user\models\RecoveryForm $model 19 | */ 20 | 21 | $this->title = Yii::t('user', 'Reset your password'); 22 | $this->params['breadcrumbs'][] = $this->title; 23 | ?> 24 |
25 |
26 |
27 |
28 |

title) ?>

29 |
30 |
31 | 'password-recovery-form', 33 | ]); ?> 34 | 35 | field($model, 'password')->passwordInput() ?> 36 | 37 | 'btn btn-success btn-block']) ?>
38 | 39 | 40 |
41 |
42 |
43 |
-------------------------------------------------------------------------------- /views/user/registration/resend.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE.md 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | use yii\helpers\Html; 13 | use yii\widgets\ActiveForm; 14 | 15 | /** 16 | * @var yii\web\View $this 17 | * @var yii\widgets\ActiveForm $form 18 | * @var dektrium\user\forms\Resend $model 19 | */ 20 | 21 | $this->title = Yii::t('user', 'Request new confirmation message'); 22 | $this->params['breadcrumbs'][] = $this->title; 23 | ?> 24 |
25 |
26 |
27 |
28 |

title) ?>

29 |
30 |
31 | 'resend-form', 33 | ]); ?> 34 | 35 | field($model, 'email')->textInput(['autofocus' => true]) ?> 36 | 37 | 'btn btn-primary btn-block']) ?>
38 | 39 | 40 |
41 |
42 |
43 |
44 | -------------------------------------------------------------------------------- /views/user/settings/_menu.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE.md 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | use yii\widgets\Menu; 13 | 14 | /** @var dektrium\user\models\User $user */ 15 | $user = Yii::$app->user->identity; 16 | $networksVisible = count(Yii::$app->authClientCollection->clients) > 0; 17 | 18 | ?> 19 | 20 |
21 |
22 |

23 | <?= $user->username ?> 24 | username ?> 25 |

26 |
27 |
28 | [ 30 | 'class' => 'nav nav-pills nav-stacked' 31 | ], 32 | 'items' => [ 33 | ['label' => Yii::t('user', 'Profile'), 'url' => ['/user/settings/profile']], 34 | ['label' => Yii::t('user', 'Account'), 'url' => ['/user/settings/account']], 35 | ['label' => Yii::t('user', 'Networks'), 'url' => ['/user/settings/networks'], 'visible' => $networksVisible], 36 | ] 37 | ]) ?> 38 |
39 |
-------------------------------------------------------------------------------- /views/user/recovery/request.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE.md 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | use yii\helpers\Html; 13 | use yii\widgets\ActiveForm; 14 | 15 | /** 16 | * @var yii\web\View $this 17 | * @var yii\widgets\ActiveForm $form 18 | * @var dektrium\user\models\RecoveryRequestForm $model 19 | */ 20 | 21 | $this->title = Yii::t('user', 'Recover your password'); 22 | $this->params['breadcrumbs'][] = $this->title; 23 | ?> 24 |
25 |
26 |
27 |
28 |

title) ?>

29 |
30 |
31 | 'password-recovery-form', 33 | ]); ?> 34 | 35 | field($model, 'email')->textInput(['autofocus' => true]) ?> 36 | 37 | 'btn btn-primary btn-block']) ?>
38 | 39 | 40 |
41 |
42 |
43 |
44 | -------------------------------------------------------------------------------- /tests/codeception/functional/ContactCept.php: -------------------------------------------------------------------------------- 1 | wantTo('ensure that contact works'); 7 | 8 | $contactPage = ContactPage::openBy($I); 9 | 10 | $I->see('Contact', 'h1'); 11 | 12 | $I->amGoingTo('submit contact form with no data'); 13 | $contactPage->submit([]); 14 | $I->expectTo('see validations errors'); 15 | $I->see('Contact', 'h1'); 16 | $I->see('Name cannot be blank'); 17 | $I->see('Email cannot be blank'); 18 | $I->see('Subject cannot be blank'); 19 | $I->see('Body cannot be blank'); 20 | $I->see('The verification code is incorrect'); 21 | 22 | $I->amGoingTo('submit contact form with not correct email'); 23 | $contactPage->submit([ 24 | 'name' => 'tester', 25 | 'email' => 'tester.email', 26 | 'subject' => 'test subject', 27 | 'body' => 'test content', 28 | 'verifyCode' => 'testme', 29 | ]); 30 | $I->expectTo('see that email adress is wrong'); 31 | $I->dontSee('Name cannot be blank', '.help-inline'); 32 | $I->see('Email is not a valid email address.'); 33 | $I->dontSee('Subject cannot be blank', '.help-inline'); 34 | $I->dontSee('Body cannot be blank', '.help-inline'); 35 | $I->dontSee('The verification code is incorrect', '.help-inline'); 36 | 37 | $I->amGoingTo('submit contact form with correct data'); 38 | $contactPage->submit([ 39 | 'name' => 'tester', 40 | 'email' => 'tester@example.com', 41 | 'subject' => 'test subject', 42 | 'body' => 'test content', 43 | 'verifyCode' => 'testme', 44 | ]); 45 | $I->dontSeeElement('#contact-form'); 46 | $I->see('Thank you for contacting us. We will respond to you as soon as possible.'); 47 | -------------------------------------------------------------------------------- /views/user/mail/welcome.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE.md 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | /** 13 | * @var dektrium\user\models\User $user 14 | */ 15 | ?> 16 |

17 | , 18 |

19 |

20 | name) ?>. 21 | . 22 |

23 |

24 | : email ?>
25 | : username ?>
26 | : password ?> 27 |

28 |

29 | . 30 |

31 | -------------------------------------------------------------------------------- /views/site/login.php: -------------------------------------------------------------------------------- 1 | title = 'Login'; 10 | $this->params['breadcrumbs'][] = $this->title; 11 | ?> 12 | 47 | -------------------------------------------------------------------------------- /views/user/admin/create.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE.md 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | use yii\helpers\Html; 13 | use yii\widgets\ActiveForm; 14 | 15 | /** 16 | * @var yii\web\View $this 17 | * @var dektrium\user\models\User $model 18 | */ 19 | 20 | $this->title = Yii::t('user', 'Create a user account'); 21 | $this->params['breadcrumbs'][] = ['label' => Yii::t('user', 'Users'), 'url' => ['index']]; 22 | $this->params['breadcrumbs'][] = $this->title; 23 | ?> 24 | 25 | render('flash') ?> 26 | 27 |
28 |
29 | title) ?> 30 |
31 |
32 |
33 | . 34 | . 35 |
36 | 37 | 38 | field($model, 'username')->textInput(['maxlength' => 25, 'autofocus' => true]) ?> 39 | 40 | field($model, 'email')->textInput(['maxlength' => 255]) ?> 41 | 42 | field($model, 'password')->passwordInput() ?> 43 | 44 |
45 | 'btn btn-success']) ?> 46 |
47 | 48 | 49 |
50 |
51 | -------------------------------------------------------------------------------- /LICENSE-yii.md: -------------------------------------------------------------------------------- 1 | The Yii framework is free software. It is released under the terms of 2 | the following BSD License. 3 | 4 | Copyright © 2008 by Yii Software LLC (http://www.yiisoft.com) 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions 9 | are met: 10 | 11 | * Redistributions of source code must retain the above copyright 12 | notice, this list of conditions and the following disclaimer. 13 | * Redistributions in binary form must reproduce the above copyright 14 | notice, this list of conditions and the following disclaimer in 15 | the documentation and/or other materials provided with the 16 | distribution. 17 | * Neither the name of Yii Software LLC nor the names of its 18 | contributors may be used to endorse or promote products derived 19 | from this software without specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | POSSIBILITY OF SUCH DAMAGE. 33 | -------------------------------------------------------------------------------- /views/user/mail/recovery.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE.md 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | use yii\helpers\Html; 13 | 14 | /** 15 | * @var dektrium\user\models\User $user 16 | * @var dektrium\user\models\Token $token 17 | */ 18 | ?> 19 |

20 | , 21 |

22 |

23 | name) ?>. 24 | . 25 | . 26 |

27 |

28 | url), $token->url); ?> 29 |

30 |

31 | . 32 |

33 | -------------------------------------------------------------------------------- /tests/codeception/acceptance/ContactCept.php: -------------------------------------------------------------------------------- 1 | wantTo('ensure that contact works'); 7 | 8 | $contactPage = ContactPage::openBy($I); 9 | 10 | $I->see('Contact', 'h1'); 11 | 12 | $I->amGoingTo('submit contact form with no data'); 13 | $contactPage->submit([]); 14 | $I->expectTo('see validations errors'); 15 | $I->see('Contact', 'h1'); 16 | $I->see('Name cannot be blank'); 17 | $I->see('Email cannot be blank'); 18 | $I->see('Subject cannot be blank'); 19 | $I->see('Body cannot be blank'); 20 | $I->see('The verification code is incorrect'); 21 | 22 | $I->amGoingTo('submit contact form with not correct email'); 23 | $contactPage->submit([ 24 | 'name' => 'tester', 25 | 'email' => 'tester.email', 26 | 'subject' => 'test subject', 27 | 'body' => 'test content', 28 | 'verifyCode' => 'testme', 29 | ]); 30 | $I->expectTo('see that email adress is wrong'); 31 | $I->dontSee('Name cannot be blank', '.help-inline'); 32 | $I->see('Email is not a valid email address.'); 33 | $I->dontSee('Subject cannot be blank', '.help-inline'); 34 | $I->dontSee('Body cannot be blank', '.help-inline'); 35 | $I->dontSee('The verification code is incorrect', '.help-inline'); 36 | 37 | $I->amGoingTo('submit contact form with correct data'); 38 | $contactPage->submit([ 39 | 'name' => 'tester', 40 | 'email' => 'tester@example.com', 41 | 'subject' => 'test subject', 42 | 'body' => 'test content', 43 | 'verifyCode' => 'testme', 44 | ]); 45 | if (method_exists($I, 'wait')) { 46 | $I->wait(3); // only for selenium 47 | } 48 | $I->dontSeeElement('#contact-form'); 49 | $I->see('Thank you for contacting us. We will respond to you as soon as possible.'); 50 | -------------------------------------------------------------------------------- /web/css/site.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | height: 100%; 4 | } 5 | 6 | .wrap { 7 | min-height: 100%; 8 | height: auto; 9 | margin: 0 auto -60px; 10 | padding: 0 0 60px; 11 | } 12 | 13 | .wrap > .container { 14 | padding: 70px 15px 20px; 15 | } 16 | 17 | .footer { 18 | height: 60px; 19 | background-color: #f5f5f5; 20 | border-top: 1px solid #ddd; 21 | padding-top: 20px; 22 | } 23 | 24 | .jumbotron { 25 | text-align: center; 26 | background-color: transparent; 27 | } 28 | 29 | .jumbotron .btn { 30 | font-size: 21px; 31 | padding: 14px 24px; 32 | } 33 | 34 | .not-set { 35 | color: #c55; 36 | font-style: italic; 37 | } 38 | 39 | /* add sorting icons to gridview sort links */ 40 | a.asc:after, a.desc:after { 41 | position: relative; 42 | top: 1px; 43 | display: inline-block; 44 | font-family: 'Glyphicons Halflings'; 45 | font-style: normal; 46 | font-weight: normal; 47 | line-height: 1; 48 | padding-left: 5px; 49 | } 50 | 51 | a.asc:after { 52 | content: /*"\e113"*/ "\e151"; 53 | } 54 | 55 | a.desc:after { 56 | content: /*"\e114"*/ "\e152"; 57 | } 58 | 59 | .sort-numerical a.asc:after { 60 | content: "\e153"; 61 | } 62 | 63 | .sort-numerical a.desc:after { 64 | content: "\e154"; 65 | } 66 | 67 | .sort-ordinal a.asc:after { 68 | content: "\e155"; 69 | } 70 | 71 | .sort-ordinal a.desc:after { 72 | content: "\e156"; 73 | } 74 | 75 | .grid-view th { 76 | white-space: nowrap; 77 | } 78 | 79 | .hint-block { 80 | display: block; 81 | margin-top: 5px; 82 | color: #999; 83 | } 84 | 85 | .error-summary { 86 | color: #a94442; 87 | background: #fdf7f7; 88 | border-left: 3px solid #eed3d7; 89 | padding: 10px 20px; 90 | margin: 0 0 15px 0; 91 | } 92 | -------------------------------------------------------------------------------- /models/ContactForm.php: -------------------------------------------------------------------------------- 1 | 'Verification Code', 41 | ]; 42 | } 43 | 44 | /** 45 | * Sends an email to the specified email address using the information collected by this model. 46 | * @param string $email the target email address 47 | * @return boolean whether the model passes validation 48 | */ 49 | public function contact($email) 50 | { 51 | if ($this->validate()) { 52 | Yii::$app->mailer->compose() 53 | ->setTo($email) 54 | ->setFrom([$this->email => $this->name]) 55 | ->setSubject($this->subject) 56 | ->setTextBody($this->body) 57 | ->send(); 58 | 59 | return true; 60 | } else { 61 | return false; 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /views/user/registration/register.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE.md 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | use yii\helpers\Html; 13 | use yii\widgets\ActiveForm; 14 | 15 | /** 16 | * @var yii\web\View $this 17 | * @var yii\widgets\ActiveForm $form 18 | * @var dektrium\user\models\User $user 19 | */ 20 | 21 | $this->title = Yii::t('user', 'Sign up'); 22 | $this->params['breadcrumbs'][] = $this->title; 23 | ?> 24 |
25 |
26 |
27 |
28 |

title) ?>

29 |
30 |
31 | 'registration-form', 33 | ]); ?> 34 | 35 | field($model, 'username') ?> 36 | 37 | field($model, 'email') ?> 38 | 39 | getModule('user')->enableGeneratingPassword == false): ?> 40 | field($model, 'password')->passwordInput() ?> 41 | 42 | 43 | 'btn btn-success btn-block']) ?> 44 | 45 | 46 |
47 |
48 |

49 | 50 |

51 |
52 |
53 | -------------------------------------------------------------------------------- /controllers/SecurityController.php: -------------------------------------------------------------------------------- 1 | module->manager->createLoginForm(); 24 | 25 | if ($model->load(\Yii::$app->getRequest()->post()) && $model->login()) { 26 | Yii::$app->view->params['user'] = [ 27 | 'loggedIn'=>true, 28 | Yii::$app->wtsecure->sessionUserInfoTag => [ 29 | 'id'=>Yii::$app->user->identity->id, 30 | 'username'=>Yii::$app->user->identity->username, 31 | ], 32 | Yii::$app->wtsecure->sessionRoleTag => Yii::$app->wtsecure->encryptRoles($roles=[],$userInfo=[]) 33 | ]; 34 | return $this->goBack(); 35 | } 36 | 37 | return $this->render('login', [ 38 | 'model' => $model 39 | ]); 40 | } 41 | 42 | /** 43 | * Logs the user out and then redirects to the homepage. 44 | * 45 | * @return \yii\web\Response 46 | */ 47 | public function actionLogout() 48 | { 49 | Simple::setNull(); 50 | \Yii::$app->getUser()->logout(); 51 | 52 | return $this->goHome(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /views/user/mail/reconfirmation.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE.md 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | use yii\helpers\Html; 13 | 14 | /** 15 | * @var dektrium\user\models\Token $token 16 | */ 17 | ?> 18 |

19 | , 20 |

21 |

22 | name) ?>. 23 | . 24 |

25 |

26 | getUrl()), $token->getUrl()); ?> 27 |

28 |

29 | . 30 | . 31 |

32 |

33 | . 34 |

-------------------------------------------------------------------------------- /views/user/mail/confirmation.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE.md 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | use yii\helpers\Html; 13 | 14 | /** 15 | * @var dektrium\user\models\User $user 16 | * @var dektrium\user\models\Token $token 17 | */ 18 | ?> 19 |

20 | , 21 |

22 |

23 | name) ?>. 24 | . 25 |

26 |

27 | url), $token->url); ?> 28 |

29 |

30 | . 31 | . 32 |

33 |

34 | . 35 |

36 | -------------------------------------------------------------------------------- /tests/README.md: -------------------------------------------------------------------------------- 1 | This directory contains various tests for the basic application. 2 | 3 | Tests in `codeception` directory are developed with [Codeception PHP Testing Framework](http://codeception.com/). 4 | 5 | After creating the basic application, follow these steps to prepare for the tests: 6 | 7 | 1. Install Codeception if it's not yet installed: 8 | 9 | ``` 10 | composer global require "codeception/codeception=2.0.*" 11 | composer global require "codeception/specify=*" 12 | composer global require "codeception/verify=*" 13 | ``` 14 | 15 | If you've never used Composer for global packages run `composer global status`. It should output: 16 | 17 | ``` 18 | Changed current directory to 19 | ``` 20 | 21 | Then add `/vendor/bin` to you `PATH` environment variable. Now we're able to use `codecept` from command 22 | line globally. 23 | 24 | 2. Install faker extension by running the following from template root directory where `composer.json` is: 25 | 26 | ``` 27 | composer require --dev yiisoft/yii2-faker:* 28 | ``` 29 | 30 | 3. Create `yii2_basic_tests` database and update it by applying migrations: 31 | 32 | ``` 33 | codeception/bin/yii migrate 34 | ``` 35 | 36 | 4. Build the test suites: 37 | 38 | ``` 39 | codecept build 40 | ``` 41 | 42 | 5. In order to be able to run acceptance tests you need to start a webserver. The simplest way is to use PHP built in 43 | webserver. In the `web` directory execute the following: 44 | 45 | ``` 46 | php -S localhost:8080 47 | ``` 48 | 49 | 6. Now you can run the tests with the following commands: 50 | 51 | ``` 52 | # run all available tests 53 | codecept run 54 | # run acceptance tests 55 | codecept run acceptance 56 | # run functional tests 57 | codecept run functional 58 | # run unit tests 59 | codecept run unit 60 | ``` 61 | 62 | Please refer to [Codeception tutorial](http://codeception.com/docs/01-Introduction) for 63 | more details about writing and running acceptance, functional and unit tests. 64 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "yiisoft/yii2-app-basic", 3 | "description": "Yii 2 Basic Application Template", 4 | "keywords": ["yii2", "framework", "basic", "application template"], 5 | "homepage": "http://www.yiiframework.com/", 6 | "type": "project", 7 | "license": "BSD-3-Clause", 8 | "support": { 9 | "issues": "https://github.com/yiisoft/yii2/issues?state=open", 10 | "forum": "http://www.yiiframework.com/forum/", 11 | "wiki": "http://www.yiiframework.com/wiki/", 12 | "irc": "irc://irc.freenode.net/yii", 13 | "source": "https://github.com/yiisoft/yii2" 14 | }, 15 | "minimum-stability": "dev", 16 | "require": { 17 | "php": ">=5.4.0", 18 | "yiisoft/yii2": "*", 19 | "yiisoft/yii2-bootstrap": "*", 20 | "azraf/yii2-simpleapp": ">=0.2", 21 | "mdmsoft/yii2-admin": "*", 22 | "dektrium/yii2-user": "*", 23 | "yiisoft/yii2-swiftmailer": "*" 24 | }, 25 | "require-dev": { 26 | "yiisoft/yii2-codeception": "*", 27 | "yiisoft/yii2-debug": "*", 28 | "yiisoft/yii2-gii": "*", 29 | "yiisoft/yii2-faker": "*" 30 | }, 31 | "config": { 32 | "process-timeout": 1800 33 | }, 34 | "scripts": { 35 | "post-create-project-cmd": [ 36 | "yii\\composer\\Installer::postCreateProject" 37 | ] 38 | }, 39 | "extra": { 40 | "yii\\composer\\Installer::postCreateProject": { 41 | "setPermission": [ 42 | { 43 | "runtime": "0777", 44 | "web/assets": "0777", 45 | "yii": "0755" 46 | } 47 | ], 48 | "generateCookieValidationKey": [ 49 | "config/web.php" 50 | ] 51 | }, 52 | "asset-installer-paths": { 53 | "npm-asset-library": "vendor/npm", 54 | "bower-asset-library": "vendor/bower" 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /tests/codeception/unit/models/ContactFormTest.php: -------------------------------------------------------------------------------- 1 | mailer->fileTransportCallback = function ($mailer, $message) { 17 | return 'testing_message.eml'; 18 | }; 19 | } 20 | 21 | protected function tearDown() 22 | { 23 | unlink($this->getMessageFile()); 24 | parent::tearDown(); 25 | } 26 | 27 | public function testContact() 28 | { 29 | $model = $this->getMock('app\models\ContactForm', ['validate']); 30 | $model->expects($this->once())->method('validate')->will($this->returnValue(true)); 31 | 32 | $model->attributes = [ 33 | 'name' => 'Tester', 34 | 'email' => 'tester@example.com', 35 | 'subject' => 'very important letter subject', 36 | 'body' => 'body of current message', 37 | ]; 38 | 39 | $model->contact('admin@example.com'); 40 | 41 | $this->specify('email should be send', function () { 42 | expect('email file should exist', file_exists($this->getMessageFile()))->true(); 43 | }); 44 | 45 | $this->specify('message should contain correct data', function () use ($model) { 46 | $emailMessage = file_get_contents($this->getMessageFile()); 47 | 48 | expect('email should contain user name', $emailMessage)->contains($model->name); 49 | expect('email should contain sender email', $emailMessage)->contains($model->email); 50 | expect('email should contain subject', $emailMessage)->contains($model->subject); 51 | expect('email should contain body', $emailMessage)->contains($model->body); 52 | }); 53 | } 54 | 55 | private function getMessageFile() 56 | { 57 | return Yii::getAlias(Yii::$app->mailer->fileTransportPath) . '/testing_message.eml'; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /tests/codeception/unit/models/LoginFormTest.php: -------------------------------------------------------------------------------- 1 | user->logout(); 17 | parent::tearDown(); 18 | } 19 | 20 | public function testLoginNoUser() 21 | { 22 | $model = new LoginForm([ 23 | 'username' => 'not_existing_username', 24 | 'password' => 'not_existing_password', 25 | ]); 26 | 27 | $this->specify('user should not be able to login, when there is no identity', function () use ($model) { 28 | expect('model should not login user', $model->login())->false(); 29 | expect('user should not be logged in', Yii::$app->user->isGuest)->true(); 30 | }); 31 | } 32 | 33 | public function testLoginWrongPassword() 34 | { 35 | $model = new LoginForm([ 36 | 'username' => 'demo', 37 | 'password' => 'wrong_password', 38 | ]); 39 | 40 | $this->specify('user should not be able to login with wrong password', function () use ($model) { 41 | expect('model should not login user', $model->login())->false(); 42 | expect('error message should be set', $model->errors)->hasKey('password'); 43 | expect('user should not be logged in', Yii::$app->user->isGuest)->true(); 44 | }); 45 | } 46 | 47 | public function testLoginCorrect() 48 | { 49 | $model = new LoginForm([ 50 | 'username' => 'demo', 51 | 'password' => 'demo', 52 | ]); 53 | 54 | $this->specify('user should be able to login with correct credentials', function () use ($model) { 55 | expect('model should login user', $model->login())->true(); 56 | expect('error message should not be set', $model->errors)->hasntKey('password'); 57 | expect('user should be logged in', Yii::$app->user->isGuest)->false(); 58 | }); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | yii2-simple 2 | ============== 3 | 4 | A yii2 basic package comes with pre-installed jquery UI, RBAC (mdmsoft/yii2-admin), User profile (dektrium/yii2-user), upload files plugin (mdmsoft/yii2-upload-file) and few more coming to boostup initial development time. 5 | 6 | 7 | DIRECTORY STRUCTURE 8 | ------------------- 9 | 10 | assets/ contains assets definition 11 | commands/ contains console commands (controllers) 12 | config/ contains application configurations 13 | controllers/ contains Web controller classes 14 | mail/ contains view files for e-mails 15 | models/ contains model classes 16 | runtime/ contains files generated during runtime 17 | tests/ contains various tests for the basic application 18 | vendor/ contains dependent 3rd-party packages 19 | views/ contains view files for the Web application 20 | web/ contains the entry script and Web resources 21 | 22 | 23 | REQUIREMENTS 24 | ------------ 25 | 26 | The minimum requirement by this application template that your Web server supports PHP 5.4.0. 27 | 28 | 29 | INSTALLATION AND DOCUMENTATION 30 | ------------------------------ 31 | 32 | Please check http://makewebsmart.com/blog/yii2-simpleapp-with-yii2-admin-user-adminlte-and-few-more/234 for documentation. 33 | 34 | 35 | IMPORTANT : 36 | ----------- 37 | 38 | After installation complete, please: 39 | 40 | 1. Uncomment the line `'admin/*'` of `config/web.php` : 41 | 42 | 'as access' => [ 43 | 'class' => 'mdm\admin\components\AccessControl', 44 | 'allowActions' => [ 45 | // 'admin/*', // ::: IMPORTANT :::: Make it disable after configuring the USER Roles/Permissions 46 | 47 | 2. Then browse to `http://[YOUR-APPLICATION-PATH]/admin/` in your browser 48 | 49 | 3. Configure Yii2-admin as your need, set Permission/Roles and assign them to User 50 | 51 | 4. After configuration complete, comment out the line again in your configuration 52 | 53 | // 'admin/*', // ::: IMPORTANT :::: Make it disable after configuring the USER Roles/Permissions 54 | 55 | 56 | Now you all set! 57 | -------------------------------------------------------------------------------- /views/user/registration/connect.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE.md 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | use yii\helpers\Html; 13 | use yii\widgets\ActiveForm; 14 | 15 | /** 16 | * @var yii\web\View $this 17 | * @var yii\widgets\ActiveForm $form 18 | * @var dektrium\user\models\User $model 19 | * @var dektrium\user\models\Account $account 20 | */ 21 | 22 | $this->title = Yii::t('user', 'Connect your account to {0}', $account->provider); 23 | $this->params['breadcrumbs'][] = $this->title; 24 | ?> 25 |
26 |
27 |
28 |
29 |

title) ?>

30 |
31 |
32 |
33 |

34 | provider, Yii::$app->name]) ?>. 35 | . 36 | . 37 |

38 |
39 | 'connect-account-form', 41 | ]); ?> 42 | 43 | field($model, 'username') ?> 44 | 45 | field($model, 'email') ?> 46 | 47 | 'btn btn-success btn-block']) ?> 48 | 49 | 50 |
51 |
52 |

53 | . 54 |

55 |
56 |
57 | -------------------------------------------------------------------------------- /views/user/recovery/finish.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE.md 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | use yii\helpers\Html; 13 | 14 | /** 15 | * @var yii\web\View $this 16 | */ 17 | 18 | ?> 19 | 20 | session->hasFlash('user.invalid_token')): ?> 21 | title = Yii::t('user', 'Recovery token is invalid'); ?> 22 |
23 |

24 | title) ?> 25 |

26 |

27 | . 28 | : 29 |

30 |

31 | 32 |

33 |
34 | 35 | 36 | session->hasFlash('user.recovery_finished')): ?> 37 | title = Yii::t('user', 'Password has been reset'); ?> 38 |
39 |

40 | title) ?> 41 |

42 |

43 | 44 |

45 |
46 | 47 | 48 | session->hasFlash('user.recovery_sent')): ?> 49 | title = Yii::t('user', 'Recovery message sent'); ?> 50 |
51 |

52 | title) ?> 53 |

54 |

55 | 56 | 57 |

58 |

59 | 60 |

61 |
62 | -------------------------------------------------------------------------------- /views/user/profile/show.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE.md 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | use yii\helpers\Html; 13 | 14 | /** 15 | * @var \yii\web\View $this 16 | * @var \dektrium\user\models\Profile $profile 17 | */ 18 | 19 | $this->title = empty($profile->name) ? Html::encode($profile->user->username) : Html::encode($profile->name); 20 | $this->params['breadcrumbs'][] = $this->title; 21 | ?> 22 |
23 |
24 |
25 |
26 | 27 |
28 |
29 |

title ?>

30 |
    31 | location)): ?> 32 |
  • location) ?>
  • 33 | 34 | website)): ?> 35 |
  • website), Html::encode($profile->website)) ?>
  • 36 | 37 | public_email)): ?> 38 |
  • public_email), 'mailto:' . Html::encode($profile->public_email)) ?>
  • 39 | 40 |
  • user->created_at) ?>
  • 41 |
42 | bio)): ?> 43 |

bio) ?>

44 | 45 |
46 |
47 |
48 |
49 | -------------------------------------------------------------------------------- /views/user/security/login.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE.md 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | use yii\helpers\Html; 13 | use yii\widgets\ActiveForm; 14 | use dektrium\user\widgets\Connect; 15 | 16 | /** 17 | * @var yii\web\View $this 18 | * @var yii\widgets\ActiveForm $form 19 | * @var dektrium\user\models\LoginForm $model 20 | */ 21 | 22 | $this->title = Yii::t('user', 'Sign in'); 23 | $this->params['breadcrumbs'][] = $this->title; 24 | ?> 25 |
 
26 |
27 |
 
28 |
29 |
30 |
31 |
32 |

title) ?>

33 |
34 |
35 | 'login-form', 37 | ]) ?> 38 | 39 | field($model, 'login', ['inputOptions' => ['autofocus' => 'autofocus', 'class' => 'form-control', 'tabindex' => '1']]) ?> 40 | 41 | field($model, 'password', ['inputOptions' => ['class' => 'form-control', 'tabindex' => '2']])->passwordInput()->label(Yii::t('user', 'Password') . ' (' . Html::a(Yii::t('user', 'Forgot password?'), ['/user/recovery/request'], ['tabindex' => '5']) . ')') ?> 42 | 43 | field($model, 'rememberMe')->checkbox(['tabindex' => '4']) ?> 44 | 45 | 'btn btn-primary btn-block', 'tabindex' => '3']) ?> 46 | 47 | 48 |
49 |
50 | getModule('user')->enableConfirmation): ?> 51 |

52 | 53 |

54 | 55 | ['/user/security/auth'] 57 | ]) ?> 58 |
59 |
60 | -------------------------------------------------------------------------------- /views/site/contact.php: -------------------------------------------------------------------------------- 1 | title = 'Contact'; 11 | $this->params['breadcrumbs'][] = $this->title; 12 | ?> 13 |
14 |

title) ?>

15 | 16 | session->hasFlash('contactFormSubmitted')): ?> 17 | 18 |
19 | Thank you for contacting us. We will respond to you as soon as possible. 20 |
21 | 22 |

23 | Note that if you turn on the Yii debugger, you should be able 24 | to view the mail message on the mail panel of the debugger. 25 | mailer->useFileTransport): ?> 26 | Because the application is in development mode, the email is not sent but saved as 27 | a file under mailer->fileTransportPath) ?>. 28 | Please configure the useFileTransport property of the mail 29 | application component to be false to enable email sending. 30 | 31 |

32 | 33 | 34 | 35 |

36 | If you have business inquiries or other questions, please fill out the following form to contact us. Thank you. 37 |

38 | 39 |
40 |
41 | 'contact-form']); ?> 42 | field($model, 'name') ?> 43 | field($model, 'email') ?> 44 | field($model, 'subject') ?> 45 | field($model, 'body')->textArea(['rows' => 6]) ?> 46 | field($model, 'verifyCode')->widget(Captcha::className(), [ 47 | 'template' => '
{image}
{input}
', 48 | ]) ?> 49 |
50 | 'btn btn-primary', 'name' => 'contact-button']) ?> 51 |
52 | 53 |
54 |
55 | 56 | 57 |
58 | -------------------------------------------------------------------------------- /views/user/settings/account.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE.md 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | use yii\helpers\Html; 13 | use yii\widgets\ActiveForm; 14 | 15 | /** 16 | * @var $this yii\web\View 17 | * @var $form yii\widgets\ActiveForm 18 | * @var $model dektrium\user\models\SettingsForm 19 | */ 20 | 21 | $this->title = Yii::t('user', 'Account settings'); 22 | $this->params['breadcrumbs'][] = $this->title; 23 | ?> 24 | 25 | render('/_alert') ?> 26 | 27 |
28 |
29 | render('_menu') ?> 30 |
31 |
32 |
33 |
34 | title) ?> 35 |
36 |
37 | 'account-form', 39 | 'options' => ['class' => 'form-horizontal'], 40 | 'fieldConfig' => [ 41 | 'template' => "{label}\n
{input}
\n
{error}\n{hint}
", 42 | 'labelOptions' => ['class' => 'col-lg-3 control-label'], 43 | ], 44 | 'enableAjaxValidation' => true, 45 | 'enableClientValidation' => false 46 | ]); ?> 47 | 48 | field($model, 'email') ?> 49 | 50 | field($model, 'username') ?> 51 | 52 | field($model, 'new_password')->passwordInput() ?> 53 | 54 |
55 | 56 | field($model, 'current_password')->passwordInput() ?> 57 | 58 |
59 |
60 | 'btn btn-block btn-success']) ?>
61 |
62 |
63 | 64 | 65 |
66 |
67 |
68 |
69 | -------------------------------------------------------------------------------- /views/site/index.php: -------------------------------------------------------------------------------- 1 | title = 'My Yii Application'; 4 | ?> 5 |
6 | 7 |
8 |

Congratulations!

9 | 10 |

You have successfully created your Yii-powered application.

11 | 12 |

Get started with Yii

13 |
14 | 15 |
16 | 17 |
18 |
19 |

Heading

20 | 21 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et 22 | dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip 23 | ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu 24 | fugiat nulla pariatur.

25 | 26 |

Yii Documentation »

27 |
28 |
29 |

Heading

30 | 31 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et 32 | dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip 33 | ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu 34 | fugiat nulla pariatur.

35 | 36 |

Yii Forum »

37 |
38 |
39 |

Heading

40 | 41 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et 42 | dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip 43 | ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu 44 | fugiat nulla pariatur.

45 | 46 |

Yii Extensions »

47 |
48 |
49 | 50 |
51 |
52 | -------------------------------------------------------------------------------- /views/layouts/main.php: -------------------------------------------------------------------------------- 1 | 13 | beginPage() ?> 14 | 15 | 16 | 17 | 18 | 19 | 20 | <?= Html::encode($this->title) ?> 21 | head() ?> 22 | 23 | 24 | 25 | beginBody() ?> 26 |
27 | 'My Company', 30 | 'brandUrl' => Yii::$app->homeUrl, 31 | 'options' => [ 32 | 'class' => 'navbar-inverse navbar-fixed-top', 33 | ], 34 | ]); 35 | $menuItems = [ 36 | ['label' => 'Home', 'url' => ['/site/index']], 37 | ['label' => 'About', 'url' => ['/site/about']], 38 | ['label' => 'Contact', 'url' => ['/site/contact']], 39 | ]; 40 | if (Yii::$app->user->isGuest) { 41 | $menuItems[] = ['label' => 'Signup', 'url' => ['/site/signup']]; 42 | $menuItems[] = ['label' => 'Login', 'url' => ['/site/login']]; 43 | } else { 44 | $menuItems[] = [ 45 | 'label' => 'Logout (' . Yii::$app->user->identity->username . ')', 46 | 'url' => ['/site/logout'], 47 | 'linkOptions' => ['data-method' => 'post'] 48 | ]; 49 | } 50 | echo Nav::widget([ 51 | 'options' => ['class' => 'navbar-nav navbar-right'], 52 | 'items' => $menuItems, 53 | ]); 54 | NavBar::end(); 55 | ?> 56 | 57 |
58 | isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [], 60 | ]) ?> 61 | 62 |
63 |
64 | 65 |
66 |
67 |

© My Company

68 |

69 |
70 |
71 | 72 | endBody() ?> 73 | 74 | 75 | endPage() ?> 76 | -------------------------------------------------------------------------------- /views/user/settings/profile.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE.md 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | use yii\helpers\Html; 13 | /** 14 | * @var yii\web\View $this 15 | * @var yii\widgets\ActiveForm $form 16 | * @var dektrium\user\models\Profile $profile 17 | */ 18 | 19 | $this->title = Yii::t('user', 'Profile settings'); 20 | $this->params['breadcrumbs'][] = $this->title; 21 | ?> 22 | 23 | 24 |
25 |
26 | render('_menu') ?> 27 |
28 |
29 |
30 |
31 | title) ?> 32 |
33 |
34 | render('@viewParts/_alert') ?> 35 |
36 |
37 | 'profile-form', 39 | 'options' => ['class' => 'form-horizontal'], 40 | 'fieldConfig' => [ 41 | 'template' => "{label}\n
{input}
\n
{error}\n{hint}
", 42 | 'labelOptions' => ['class' => 'col-lg-3 control-label'], 43 | ], 44 | 'enableAjaxValidation' => true, 45 | 'enableClientValidation' => false 46 | ]); ?> 47 | 48 | field($model, 'name') ?> 49 | 50 | field($model, 'public_email') ?> 51 | 52 | field($model, 'website') ?> 53 | 54 | field($model, 'location') ?> 55 | 56 | field($model, 'gravatar_email')->hint(\yii\helpers\Html::a(Yii::t('user', 'Change your avatar at Gravatar.com'), 'http://gravatar.com')) ?> 57 | 58 | field($model, 'bio')->textarea() ?> 59 | 60 |
61 |
62 | 'btn btn-success']) ?>
63 |
64 |
65 | 66 | 67 |
68 |
69 |
70 |
71 | -------------------------------------------------------------------------------- /views/user/settings/networks.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE.md 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | use dektrium\user\widgets\Connect; 13 | use yii\helpers\Html; 14 | 15 | /** 16 | * @var yii\web\View $this 17 | * @var yii\widgets\ActiveForm $form 18 | */ 19 | 20 | $this->title = Yii::t('user', 'Networks'); 21 | $this->params['breadcrumbs'][] = $this->title; 22 | ?> 23 | 24 | render('/_alert') ?> 25 | 26 |
27 |
28 | render('_menu') ?> 29 |
30 |
31 |
32 |
33 | title) ?> 34 |
35 |
36 | ['/user/settings/connect'], 38 | 'accounts' => $user->accounts, 39 | 'autoRender' => false, 40 | 'popupMode' => false 41 | ]) ?> 42 | 43 | getClients() as $client): ?> 44 | 45 | 48 | 51 | 62 | 63 | 64 |
46 | 'auth-icon ' . $client->getName()]) ?> 47 | 49 | getTitle() ?> 50 | 52 | isConnected($client) ? 53 | Html::a(Yii::t('user', 'Disconnect'), $auth->createClientUrl($client), [ 54 | 'class' => 'btn btn-danger btn-block', 55 | 'data-method' => 'post', 56 | ]) : 57 | Html::a(Yii::t('user', 'Connect'), $auth->createClientUrl($client), [ 58 | 'class' => 'btn btn-success btn-block' 59 | ]) 60 | ?> 61 |
65 | 66 |
67 |
68 |
69 |
70 | -------------------------------------------------------------------------------- /models/RegistrationForm.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | //namespace dektrium\user\models; 13 | namespace app\models; 14 | 15 | use dektrium\user\helpers\ModuleTrait; 16 | use yii\base\Model; 17 | 18 | /** 19 | * Registration form collects user input on registration process, validates it and creates new User model. 20 | * 21 | * @author Dmitry Erofeev 22 | */ 23 | class RegistrationForm extends Model 24 | { 25 | use ModuleTrait; 26 | 27 | /** @var string */ 28 | public $email; 29 | 30 | /** @var string */ 31 | public $username; 32 | 33 | /** @var string */ 34 | public $password; 35 | 36 | /** @inheritdoc */ 37 | public function rules() 38 | { 39 | return [ 40 | ['username', 'filter', 'filter' => 'trim'], 41 | ['username', 'match', 'pattern' => '/^[a-zA-Z]\w+$/'], 42 | ['username', 'required'], 43 | ['username', 'unique', 'targetClass' => $this->module->manager->userClass, 44 | 'message' => \Yii::t('user', 'This username has already been taken')], 45 | ['username', 'string', 'min' => 3, 'max' => 20], 46 | 47 | ['email', 'filter', 'filter' => 'trim'], 48 | ['email', 'required'], 49 | ['email', 'email'], 50 | ['email', 'unique', 'targetClass' => $this->module->manager->userClass, 51 | 'message' => \Yii::t('user', 'This email address has already been taken')], 52 | 53 | ['password', 'required', 'skipOnEmpty' => $this->module->enableGeneratingPassword], 54 | ['password', 'string', 'min' => 6], 55 | ]; 56 | } 57 | 58 | /** @inheritdoc */ 59 | public function attributeLabels() 60 | { 61 | return [ 62 | 'email' => \Yii::t('user', 'Email'), 63 | 'username' => \Yii::t('user', 'Username'), 64 | 'password' => \Yii::t('user', 'Password'), 65 | ]; 66 | } 67 | 68 | /** @inheritdoc */ 69 | public function formName() 70 | { 71 | return 'register-form'; 72 | } 73 | 74 | /** 75 | * Registers a new user account. 76 | * @return bool 77 | */ 78 | public function register() 79 | { 80 | if ($this->validate()) { 81 | $user = $this->module->manager->createUser([ 82 | 'scenario' => 'register', 83 | 'email' => $this->email, 84 | 'username' => $this->username, 85 | 'password' => $this->password 86 | ]); 87 | 88 | return $user->register(); 89 | } 90 | 91 | return false; 92 | } 93 | } -------------------------------------------------------------------------------- /controllers/SiteController.php: -------------------------------------------------------------------------------- 1 | [ 19 | 'class' => AccessControl::className(), 20 | 'only' => ['logout'], 21 | 'rules' => [ 22 | [ 23 | 'actions' => ['logout'], 24 | 'allow' => true, 25 | 'roles' => ['@'], 26 | ], 27 | ], 28 | ], 29 | 'verbs' => [ 30 | 'class' => VerbFilter::className(), 31 | 'actions' => [ 32 | 'logout' => ['post'], 33 | ], 34 | ], 35 | ]; 36 | } 37 | 38 | public function actions() 39 | { 40 | return [ 41 | 'error' => [ 42 | 'class' => 'yii\web\ErrorAction', 43 | ], 44 | 'captcha' => [ 45 | 'class' => 'yii\captcha\CaptchaAction', 46 | 'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null, 47 | ], 48 | ]; 49 | } 50 | 51 | public function actionIndex() 52 | { 53 | return $this->render('index'); 54 | } 55 | 56 | public function actionLogin() 57 | { 58 | if (!\Yii::$app->user->isGuest) { 59 | return $this->goHome(); 60 | } 61 | 62 | $model = new LoginForm(); 63 | if ($model->load(Yii::$app->request->post()) && $model->login()) { 64 | return $this->goBack(); 65 | } else { 66 | return $this->render('/user/security/login', [ 67 | 'model' => $model, 68 | ]); 69 | } 70 | } 71 | 72 | public function actionSignup() 73 | { 74 | if (!\Yii::$app->user->isGuest) { 75 | return $this->goHome(); 76 | } 77 | return $this->redirect(['/user/registration/register']); 78 | } 79 | 80 | public function actionLogout() 81 | { 82 | Yii::$app->user->logout(); 83 | 84 | return $this->goHome(); 85 | } 86 | 87 | public function actionContact() 88 | { 89 | $model = new ContactForm(); 90 | if ($model->load(Yii::$app->request->post()) && $model->contact(Yii::$app->params['adminEmail'])) { 91 | Yii::$app->session->setFlash('contactFormSubmitted'); 92 | 93 | return $this->refresh(); 94 | } else { 95 | return $this->render('contact', [ 96 | 'model' => $model, 97 | ]); 98 | } 99 | } 100 | 101 | public function actionAbout() 102 | { 103 | return $this->render('about'); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /views/user/admin/update.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE.md 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | 13 | use yii\helpers\Html; 14 | use yii\widgets\ActiveForm; 15 | 16 | /** 17 | * @var yii\web\View $this 18 | * @var dektrium\user\models\User $model 19 | */ 20 | 21 | $this->title = Yii::t('user', 'Update user account'); 22 | $this->params['breadcrumbs'][] = ['label' => Yii::t('user', 'Users'), 'url' => ['index']]; 23 | $this->params['breadcrumbs'][] = $this->title; 24 | ?> 25 |

username) ?> 26 | getIsConfirmed()): ?> 27 | $model->id], ['class' => 'btn btn-success btn-xs', 'data-method' => 'post']) ?> 28 | 29 | getIsBlocked()): ?> 30 | $model->id], ['class' => 'btn btn-success btn-xs', 'data-method' => 'post', 'data-confirm' => Yii::t('user', 'Are you sure to block this user?')]) ?> 31 | 32 | $model->id], ['class' => 'btn btn-danger btn-xs', 'data-method' => 'post', 'data-confirm' => Yii::t('user', 'Are you sure to block this user?')]) ?> 33 | 34 |

35 | 36 | render('flash') ?> 37 | 38 |
39 |
40 |
41 | created_at, is_null($model->registration_ip) ? 'N/D' : long2ip($model->registration_ip)]) ?> 42 |
43 | getModule('user')->enableConfirmation && $model->getIsConfirmed()): ?> 44 | created_at]) ?> 45 |
46 | 47 | getIsBlocked()): ?> 48 | blocked_at]) ?> 49 | 50 |
51 |
52 | 53 |
54 |
55 | title) ?> 56 |
57 |
58 | 59 | 60 | field($model, 'username')->textInput(['maxlength' => 25]) ?> 61 | 62 | field($model, 'email')->textInput(['maxlength' => 255]) ?> 63 | 64 | field($model, 'password')->passwordInput() ?> 65 | 66 |
67 | 'btn btn-primary']) ?> 68 |
69 | 70 | 71 |
72 |
73 | -------------------------------------------------------------------------------- /views/user/registration/finish.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE.md 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | use yii\helpers\Html; 13 | 14 | /** 15 | * @var yii\web\View $this 16 | */ 17 | 18 | ?> 19 | 20 | session->hasFlash('user.password_generated')): ?> 21 |
22 |

23 | 24 |

25 |

26 | . 27 | . 28 |

29 |
30 | 31 | 32 | session->hasFlash('user.registration_finished')): ?> 33 | title = Yii::t('user', 'Account has been created'); ?> 34 |
35 |

36 | title) ?> 37 |

38 | . 39 | . 40 |
41 | 42 | 43 | session->hasFlash('user.confirmation_sent')): ?> 44 | title = Yii::t('user', 'We need to confirm your email address'); ?> 45 |
46 |

47 | title) ?> 48 |

49 |

50 | . 51 | . 52 | : 53 |

54 |

55 | 56 |

57 |
58 | 59 | 60 | session->hasFlash('user.invalid_token')): ?> 61 | title = Yii::t('user', 'Invalid token'); ?> 62 |
63 |

64 | title) ?> 65 |

66 |

67 | . 68 | : 69 |

70 |

71 | 72 |

73 |
74 | 75 | 76 | session->hasFlash('user.confirmation_finished')): ?> 77 | title = Yii::t('user', 'Account has been confirmed'); ?> 78 |
79 |

80 | title) ?> 81 |

82 | 83 |
84 | 85 | -------------------------------------------------------------------------------- /models/LoginForm.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace app\models; 13 | 14 | use dektrium\user\helpers\ModuleTrait; 15 | use yii\base\Model; 16 | use dektrium\user\helpers\Password; 17 | 18 | /** 19 | * LoginForm get user's login and password, validates them and logs the user in. If user has been blocked, it adds 20 | * an error to login form. 21 | * 22 | * @author Dmitry Erofeev 23 | */ 24 | class LoginForm extends Model 25 | { 26 | use ModuleTrait; 27 | 28 | /** @var string User's email or username */ 29 | public $login; 30 | 31 | /** @var string User's plain password */ 32 | public $password; 33 | 34 | /** @var string Whether to remember the user */ 35 | public $rememberMe = false; 36 | 37 | /** @var \dektrium\user\models\User */ 38 | protected $user; 39 | 40 | /** @inheritdoc */ 41 | public function attributeLabels() 42 | { 43 | return [ 44 | 'login' => \Yii::t('user', 'Login'), 45 | 'password' => \Yii::t('user', 'Password'), 46 | 'rememberMe' => \Yii::t('user', 'Remember me next time'), 47 | ]; 48 | } 49 | 50 | /** @inheritdoc */ 51 | public function rules() 52 | { 53 | return [ 54 | [['login', 'password'], 'required'], 55 | ['login', 'trim'], 56 | ['password', function ($attribute) { 57 | if ($this->user === null || !Password::validate($this->password, $this->user->password_hash)) { 58 | $this->addError($attribute, \Yii::t('user', 'Invalid login or password')); 59 | } 60 | }], 61 | ['login', function ($attribute) { 62 | if ($this->user !== null) { 63 | $confirmationRequired = $this->module->enableConfirmation && !$this->module->enableUnconfirmedLogin; 64 | if ($confirmationRequired && !$this->user->isConfirmed) { 65 | $this->addError($attribute, \Yii::t('user', 'You need to confirm your email address')); 66 | } 67 | if ($this->user->getIsBlocked()) { 68 | $this->addError($attribute, \Yii::t('user', 'Your account has been blocked')); 69 | } 70 | } 71 | }], 72 | ['rememberMe', 'boolean'], 73 | ]; 74 | } 75 | 76 | /** 77 | * Validates form and logs the user in. 78 | * 79 | * @return boolean whether the user is logged in successfully 80 | */ 81 | public function login() 82 | { 83 | if ($this->validate()) { 84 | return \Yii::$app->getUser()->login($this->user, $this->rememberMe ? $this->module->rememberFor : 0); 85 | } else { 86 | return false; 87 | } 88 | } 89 | 90 | /** @inheritdoc */ 91 | public function formName() 92 | { 93 | return 'login-form'; 94 | } 95 | 96 | /** @inheritdoc */ 97 | public function beforeValidate() 98 | { 99 | if (parent::beforeValidate()) { 100 | $this->user = $this->module->manager->findUserByUsernameOrEmail($this->login); 101 | return true; 102 | } else { 103 | return false; 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /controllers/DashboardController.php: -------------------------------------------------------------------------------- 1 | [ 24 | 'class' => AccessControl::className(), 25 | 'only' => ['logout', 'signup'], 26 | 'rules' => [ 27 | [ 28 | 'actions' => ['signup'], 29 | 'allow' => true, 30 | 'roles' => ['?'], 31 | ], 32 | [ 33 | 'actions' => ['logout'], 34 | 'allow' => true, 35 | 'roles' => ['@'], 36 | ], 37 | ], 38 | ], 39 | 'verbs' => [ 40 | 'class' => VerbFilter::className(), 41 | 'actions' => [ 42 | 'logout' => ['post'], 43 | ], 44 | ], 45 | ]; 46 | } 47 | 48 | public function init() 49 | { 50 | parent::init(); 51 | $this->wtChildPath = DashboardController::className(); 52 | $this->setLayout('admin'); 53 | } 54 | 55 | 56 | /** 57 | * @inheritdoc 58 | */ 59 | public function actions() 60 | { 61 | return [ 62 | 'error' => [ 63 | 'class' => 'yii\web\ErrorAction', 64 | ], 65 | 'captcha' => [ 66 | 'class' => 'yii\captcha\CaptchaAction', 67 | 'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null, 68 | ], 69 | ]; 70 | } 71 | 72 | public function actionIndex() 73 | { 74 | return $this->wtRender('empty'); 75 | } 76 | 77 | public function actionFull() 78 | { 79 | $this->d($this->wtParams,'$this->wtParams'); 80 | return $this->wtRender('dashboard-full'); 81 | } 82 | 83 | public function actionLogout() 84 | { 85 | Yii::$app->user->logout(); 86 | 87 | return $this->goHome(); 88 | } 89 | 90 | public function actionRequestPasswordReset() 91 | { 92 | $model = new PasswordResetRequestForm(); 93 | if ($model->load(Yii::$app->request->post()) && $model->validate()) { 94 | if ($model->sendEmail()) { 95 | Yii::$app->getSession()->setFlash('success', 'Check your email for further instructions.'); 96 | 97 | return $this->goHome(); 98 | } else { 99 | Yii::$app->getSession()->setFlash('error', 'Sorry, we are unable to reset password for email provided.'); 100 | } 101 | } 102 | 103 | return $this->render('requestPasswordResetToken', [ 104 | 'model' => $model, 105 | ]); 106 | } 107 | 108 | public function actionResetPassword($token) 109 | { 110 | try { 111 | $model = new ResetPasswordForm($token); 112 | } catch (InvalidParamException $e) { 113 | throw new BadRequestHttpException($e->getMessage()); 114 | } 115 | 116 | if ($model->load(Yii::$app->request->post()) && $model->validate() && $model->resetPassword()) { 117 | Yii::$app->getSession()->setFlash('success', 'New password was saved.'); 118 | 119 | return $this->goHome(); 120 | } 121 | 122 | return $this->render('resetPassword', [ 123 | 'model' => $model, 124 | ]); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /views/user/admin/index.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE.md 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | use yii\helpers\Html; 13 | use yii\grid\GridView; 14 | 15 | /** 16 | * @var yii\web\View $this 17 | * @var yii\data\ActiveDataProvider $dataProvider 18 | * @var dektrium\user\models\UserSearch $searchModel 19 | */ 20 | 21 | $this->title = Yii::t('user', 'Manage users'); 22 | $this->params['breadcrumbs'][] = $this->title; 23 | ?> 24 |

title) ?> 'btn btn-success']) ?>

25 | 26 | render('flash') ?> 27 | 28 | $dataProvider, 30 | 'filterModel' => $searchModel, 31 | 'layout' => "{items}\n{pager}", 32 | 'columns' => [ 33 | 'username', 34 | 'email:email', 35 | [ 36 | 'attribute' => 'registration_ip', 37 | 'value' => function ($model, $key, $index, $widget) { 38 | return $model->registration_ip == null ? '' . Yii::t('user', '(not set)') . '' : long2ip($model->registration_ip); 39 | }, 40 | 'format' => 'html', 41 | ], 42 | [ 43 | 'attribute' => 'created_at', 44 | 'value' => function ($model, $key, $index, $widget) { 45 | return Yii::t('user', '{0, date, MMMM dd, YYYY HH:mm}', [$model->created_at]); 46 | } 47 | ], 48 | [ 49 | 'header' => Yii::t('user', 'Confirmation'), 50 | 'value' => function ($model, $key, $index, $widget) { 51 | if ($model->isConfirmed) { 52 | return '
' . Yii::t('user', 'Confirmed') . '
'; 53 | } else { 54 | return Html::a(Yii::t('user', 'Confirm'), ['confirm', 'id' => $model->id], [ 55 | 'class' => 'btn btn-xs btn-success btn-block', 56 | 'data-method' => 'post', 57 | 'data-confirm' => Yii::t('user', 'Are you sure to confirm this user?'), 58 | ]); 59 | } 60 | }, 61 | 'format' => 'raw', 62 | 'visible' => Yii::$app->getModule('user')->enableConfirmation 63 | ], 64 | [ 65 | 'header' => Yii::t('user', 'Block status'), 66 | 'value' => function ($model, $key, $index, $widget) { 67 | if ($model->isBlocked) { 68 | return Html::a(Yii::t('user', 'Unblock'), ['block', 'id' => $model->id], [ 69 | 'class' => 'btn btn-xs btn-success btn-block', 70 | 'data-method' => 'post', 71 | 'data-confirm' => Yii::t('user', 'Are you sure to unblock this user?') 72 | ]); 73 | } else { 74 | return Html::a(Yii::t('user', 'Block'), ['block', 'id' => $model->id], [ 75 | 'class' => 'btn btn-xs btn-danger btn-block', 76 | 'data-method' => 'post', 77 | 'data-confirm' => Yii::t('user', 'Are you sure to block this user?') 78 | ]); 79 | } 80 | }, 81 | 'format' => 'raw', 82 | ], 83 | [ 84 | 'class' => 'yii\grid\ActionColumn', 85 | 'template' => '{update} {delete}', 86 | 'buttons' => [ 87 | 'update' => function ($url, $model) { 88 | return Html::a('', $url, [ 89 | 'class' => 'btn btn-xs btn-info', 90 | 'title' => Yii::t('yii', 'Update'), 91 | ]); 92 | }, 93 | 'delete' => function ($url, $model) { 94 | return Html::a('', $url, [ 95 | 'class' => 'btn btn-xs btn-danger', 96 | 'data-method' => 'post', 97 | 'data-confirm' => Yii::t('user', 'Are you sure to delete this user?'), 98 | 'title' => Yii::t('yii', 'Delete'), 99 | ]); 100 | }, 101 | ] 102 | ], 103 | ], 104 | ]); ?> 105 | -------------------------------------------------------------------------------- /views/user/mail/layouts/html.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE.md 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | use yii\mail\BaseMessage; 13 | 14 | /** 15 | * @var \yii\web\View $this 16 | * @var BaseMessage $content 17 | */ 18 | ?> 19 | beginPage() ?> 20 | 21 | 22 | 23 | 24 | 25 | head() ?> 26 | 27 | 28 | 29 | 30 | 31 | 44 | 45 | 46 |
32 |
33 | 34 | 35 | 40 | 41 |
36 | beginBody() ?> 37 | 38 | endBody() ?> 39 |
42 |
43 |
47 | 48 | 61 | 62 | 63 | 64 | 65 | 66 | endPage() ?> 67 | -------------------------------------------------------------------------------- /yii2simple.sql: -------------------------------------------------------------------------------- 1 | 2 | -- 3 | -- Table structure for table `menu` 4 | -- 5 | 6 | CREATE TABLE IF NOT EXISTS `menu` ( 7 | `id` int(11) NOT NULL AUTO_INCREMENT, 8 | `name` varchar(128) NOT NULL, 9 | `parent` int(11) DEFAULT NULL, 10 | `route` varchar(256) DEFAULT NULL, 11 | `order` int(11) DEFAULT NULL, 12 | `data` text, 13 | PRIMARY KEY (`id`), 14 | KEY `parent` (`parent`) 15 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; 16 | 17 | -- -------------------------------------------------------- 18 | 19 | -- 20 | -- Table structure for table `migration` 21 | -- 22 | 23 | CREATE TABLE IF NOT EXISTS `migration` ( 24 | `version` varchar(180) NOT NULL, 25 | `apply_time` int(11) DEFAULT NULL, 26 | PRIMARY KEY (`version`) 27 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 28 | 29 | -- 30 | -- Dumping data for table `migration` 31 | -- 32 | 33 | INSERT INTO `migration` (`version`, `apply_time`) VALUES 34 | ('m000000_000000_base', 1416537492), 35 | ('m140209_132017_init', 1416537497), 36 | ('m140403_174025_create_account_table', 1416537499), 37 | ('m140504_113157_update_tables', 1416537508), 38 | ('m140504_130429_create_token_table', 1416537510), 39 | ('m140602_111327_create_menu_table', 1416537510), 40 | ('m140830_171933_fix_ip_field', 1416537512), 41 | ('m140830_172703_change_account_table_name', 1416537512), 42 | ('m141018_105939_create_table_upload', 1416537512), 43 | ('m141018_105939_session_table', 1416537513); 44 | 45 | -- -------------------------------------------------------- 46 | 47 | -- 48 | -- Table structure for table `profile` 49 | -- 50 | 51 | CREATE TABLE IF NOT EXISTS `profile` ( 52 | `user_id` int(11) NOT NULL, 53 | `name` varchar(255) DEFAULT NULL, 54 | `public_email` varchar(255) DEFAULT NULL, 55 | `gravatar_email` varchar(255) DEFAULT NULL, 56 | `gravatar_id` varchar(32) DEFAULT NULL, 57 | `location` varchar(255) DEFAULT NULL, 58 | `website` varchar(255) DEFAULT NULL, 59 | `bio` text, 60 | PRIMARY KEY (`user_id`) 61 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 62 | 63 | -- -------------------------------------------------------- 64 | 65 | -- 66 | -- Table structure for table `session` 67 | -- 68 | 69 | CREATE TABLE IF NOT EXISTS `session` ( 70 | `id` varchar(40) NOT NULL, 71 | `expire` int(11) DEFAULT NULL, 72 | `data` blob, 73 | PRIMARY KEY (`id`) 74 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 75 | 76 | -- -------------------------------------------------------- 77 | 78 | -- 79 | -- Table structure for table `social_account` 80 | -- 81 | 82 | CREATE TABLE IF NOT EXISTS `social_account` ( 83 | `id` int(11) NOT NULL AUTO_INCREMENT, 84 | `user_id` int(11) DEFAULT NULL, 85 | `provider` varchar(255) NOT NULL, 86 | `client_id` varchar(255) NOT NULL, 87 | `data` text, 88 | PRIMARY KEY (`id`), 89 | UNIQUE KEY `account_unique` (`provider`,`client_id`), 90 | KEY `fk_user_account` (`user_id`) 91 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; 92 | 93 | -- -------------------------------------------------------- 94 | 95 | -- 96 | -- Table structure for table `token` 97 | -- 98 | 99 | CREATE TABLE IF NOT EXISTS `token` ( 100 | `user_id` int(11) NOT NULL, 101 | `code` varchar(32) NOT NULL, 102 | `created_at` int(11) NOT NULL, 103 | `type` smallint(6) NOT NULL, 104 | UNIQUE KEY `token_unique` (`user_id`,`code`,`type`) 105 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 106 | 107 | -- -------------------------------------------------------- 108 | 109 | -- 110 | -- Table structure for table `uploaded_file` 111 | -- 112 | 113 | CREATE TABLE IF NOT EXISTS `uploaded_file` ( 114 | `id` int(11) NOT NULL AUTO_INCREMENT, 115 | `name` varchar(64) DEFAULT NULL, 116 | `filename` varchar(256) DEFAULT NULL, 117 | `size` int(11) DEFAULT NULL, 118 | `type` varchar(32) DEFAULT NULL, 119 | PRIMARY KEY (`id`) 120 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; 121 | 122 | -- -------------------------------------------------------- 123 | 124 | -- 125 | -- Table structure for table `user` 126 | -- 127 | 128 | CREATE TABLE IF NOT EXISTS `user` ( 129 | `id` int(11) NOT NULL AUTO_INCREMENT, 130 | `username` varchar(25) NOT NULL, 131 | `email` varchar(255) NOT NULL, 132 | `password_hash` varchar(60) NOT NULL, 133 | `auth_key` varchar(32) NOT NULL, 134 | `confirmed_at` int(11) DEFAULT NULL, 135 | `unconfirmed_email` varchar(255) DEFAULT NULL, 136 | `blocked_at` int(11) DEFAULT NULL, 137 | `role` varchar(255) DEFAULT NULL, 138 | `registration_ip` bigint(20) DEFAULT NULL, 139 | `created_at` int(11) NOT NULL, 140 | `updated_at` int(11) NOT NULL, 141 | `flags` int(11) NOT NULL DEFAULT '0', 142 | PRIMARY KEY (`id`), 143 | UNIQUE KEY `user_unique_username` (`username`), 144 | UNIQUE KEY `user_unique_email` (`email`) 145 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; 146 | 147 | -- 148 | -- Constraints for dumped tables 149 | -- 150 | 151 | -- 152 | -- Constraints for table `menu` 153 | -- 154 | ALTER TABLE `menu` 155 | ADD CONSTRAINT `menu_ibfk_1` FOREIGN KEY (`parent`) REFERENCES `menu` (`id`) ON DELETE SET NULL ON UPDATE CASCADE; 156 | 157 | -- 158 | -- Constraints for table `profile` 159 | -- 160 | ALTER TABLE `profile` 161 | ADD CONSTRAINT `fk_user_profile` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE; 162 | 163 | -- 164 | -- Constraints for table `social_account` 165 | -- 166 | ALTER TABLE `social_account` 167 | ADD CONSTRAINT `fk_user_account` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE; 168 | 169 | -- 170 | -- Constraints for table `token` 171 | -- 172 | ALTER TABLE `token` 173 | ADD CONSTRAINT `fk_user_token` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE; 174 | -------------------------------------------------------------------------------- /requirements.php: -------------------------------------------------------------------------------- 1 | Error'; 18 | echo '

The path to yii framework seems to be incorrect.

'; 19 | echo '

You need to install Yii framework via composer or adjust the framework path in file ' . basename(__FILE__) . '.

'; 20 | echo '

Please refer to the README on how to install Yii.

'; 21 | } 22 | 23 | require_once($frameworkPath . '/requirements/YiiRequirementChecker.php'); 24 | $requirementsChecker = new YiiRequirementChecker(); 25 | 26 | $gdMemo = $imagickMemo = 'Either GD PHP extension with FreeType support or ImageMagick PHP extension with PNG support is required for image CAPTCHA.'; 27 | $gdOK = $imagickOK = false; 28 | 29 | if (extension_loaded('imagick')) { 30 | $imagick = new Imagick(); 31 | $imagickFormats = $imagick->queryFormats('PNG'); 32 | if (in_array('PNG', $imagickFormats)) { 33 | $imagickOK = true; 34 | } else { 35 | $imagickMemo = 'Imagick extension should be installed with PNG support in order to be used for image CAPTCHA.'; 36 | } 37 | } 38 | 39 | if (extension_loaded('gd')) { 40 | $gdInfo = gd_info(); 41 | if (!empty($gdInfo['FreeType Support'])) { 42 | $gdOK = true; 43 | } else { 44 | $gdMemo = 'GD extension should be installed with FreeType support in order to be used for image CAPTCHA.'; 45 | } 46 | } 47 | 48 | /** 49 | * Adjust requirements according to your application specifics. 50 | */ 51 | $requirements = array( 52 | // Database : 53 | array( 54 | 'name' => 'PDO extension', 55 | 'mandatory' => true, 56 | 'condition' => extension_loaded('pdo'), 57 | 'by' => 'All DB-related classes', 58 | ), 59 | array( 60 | 'name' => 'PDO SQLite extension', 61 | 'mandatory' => false, 62 | 'condition' => extension_loaded('pdo_sqlite'), 63 | 'by' => 'All DB-related classes', 64 | 'memo' => 'Required for SQLite database.', 65 | ), 66 | array( 67 | 'name' => 'PDO MySQL extension', 68 | 'mandatory' => false, 69 | 'condition' => extension_loaded('pdo_mysql'), 70 | 'by' => 'All DB-related classes', 71 | 'memo' => 'Required for MySQL database.', 72 | ), 73 | array( 74 | 'name' => 'PDO PostgreSQL extension', 75 | 'mandatory' => false, 76 | 'condition' => extension_loaded('pdo_pgsql'), 77 | 'by' => 'All DB-related classes', 78 | 'memo' => 'Required for PostgreSQL database.', 79 | ), 80 | // Cache : 81 | array( 82 | 'name' => 'Memcache extension', 83 | 'mandatory' => false, 84 | 'condition' => extension_loaded('memcache') || extension_loaded('memcached'), 85 | 'by' => 'MemCache', 86 | 'memo' => extension_loaded('memcached') ? 'To use memcached set MemCache::useMemcached to true.' : '' 87 | ), 88 | array( 89 | 'name' => 'APC extension', 90 | 'mandatory' => false, 91 | 'condition' => extension_loaded('apc'), 92 | 'by' => 'ApcCache', 93 | ), 94 | // CAPTCHA: 95 | array( 96 | 'name' => 'GD PHP extension with FreeType support', 97 | 'mandatory' => false, 98 | 'condition' => $gdOK, 99 | 'by' => 'Captcha', 100 | 'memo' => $gdMemo, 101 | ), 102 | array( 103 | 'name' => 'ImageMagick PHP extension with PNG support', 104 | 'mandatory' => false, 105 | 'condition' => $imagickOK, 106 | 'by' => 'Captcha', 107 | 'memo' => $imagickMemo, 108 | ), 109 | // PHP ini : 110 | 'phpSafeMode' => array( 111 | 'name' => 'PHP safe mode', 112 | 'mandatory' => false, 113 | 'condition' => $requirementsChecker->checkPhpIniOff("safe_mode"), 114 | 'by' => 'File uploading and console command execution', 115 | 'memo' => '"safe_mode" should be disabled at php.ini', 116 | ), 117 | 'phpExposePhp' => array( 118 | 'name' => 'Expose PHP', 119 | 'mandatory' => false, 120 | 'condition' => $requirementsChecker->checkPhpIniOff("expose_php"), 121 | 'by' => 'Security reasons', 122 | 'memo' => '"expose_php" should be disabled at php.ini', 123 | ), 124 | 'phpAllowUrlInclude' => array( 125 | 'name' => 'PHP allow url include', 126 | 'mandatory' => false, 127 | 'condition' => $requirementsChecker->checkPhpIniOff("allow_url_include"), 128 | 'by' => 'Security reasons', 129 | 'memo' => '"allow_url_include" should be disabled at php.ini', 130 | ), 131 | 'phpSmtp' => array( 132 | 'name' => 'PHP mail SMTP', 133 | 'mandatory' => false, 134 | 'condition' => strlen(ini_get('SMTP'))>0, 135 | 'by' => 'Email sending', 136 | 'memo' => 'PHP mail SMTP server required', 137 | ), 138 | ); 139 | $requirementsChecker->checkYii()->check($requirements)->render(); 140 | -------------------------------------------------------------------------------- /config/web.php: -------------------------------------------------------------------------------- 1 | 'basic', 7 | 'basePath' => dirname(__DIR__), 8 | 'bootstrap' => ['log'], 9 | 'modules' => [ 10 | 'user' => [ 11 | 'class' => 'dektrium\user\Module', 12 | 'controllerMap' => [ 13 | 'security' => 'app\controllers\SecurityController', 14 | ], 15 | 'enableConfirmation' => false, 16 | 'confirmWithin' => 21600, 17 | 'cost' => 12, 18 | 'admins' => ['admin'] 19 | ], 20 | 'admin' => [ 21 | 'class' => 'mdm\admin\Module', 22 | 'layout' => 'left-menu', // avaliable value 'left-menu', 'right-menu' and 'top-menu' 23 | // 'layout' => 'right-menu', // avaliable value 'left-menu', 'right-menu' and 'top-menu' 24 | // 'layout' => 'top-menu', // avaliable value 'left-menu', 'right-menu' and 'top-menu' 25 | 'controllerMap' => [ 26 | 'assignment' => [ 27 | 'class' => 'mdm\admin\controllers\AssignmentController', 28 | 'userClassName' => 'dektrium\user\models\User', 29 | 'idField' => 'id' 30 | ] 31 | ], 32 | 'menus' => [ 33 | 'assignment' => [ 34 | 'label' => 'Grand Access' // change label 35 | ], 36 | // 'route' => null, // disable menu 37 | 'route' => [ 38 | 'label' => 'Route' 39 | ] 40 | ], 41 | ], 42 | ], 43 | 'components' => [ 44 | 'request' => [ 45 | // this is required by cookie validation 46 | 'cookieValidationKey' => '1upyWl1e2z6H3sCnwgv2zqDNkRE5OVqg', 47 | ], 48 | 'cache' => [ 49 | 'class' => 'yii\caching\FileCache', 50 | ], 51 | 'authManager' => [ 52 | 'class' => 'yii\rbac\PhpManager', 53 | 'defaultRoles' => ['admin','editor','client','agent','user'], // here define your roles 54 | //'authFile' => '/commands/data/rbac.php' //the default path for rbac.php | OLD CONFIGURATION 55 | 'itemFile' => dirname(__DIR__) . '/commands/data/items.php', //Default path to items.php | NEW CONFIGURATIONS 56 | 'assignmentFile' => dirname(__DIR__) . '/commands/data/assignments.php', //Default path to assignments.php | NEW CONFIGURATIONS 57 | 'ruleFile' => dirname(__DIR__) . '/commands/data/rules.php', //Default path to rules.php | NEW CONFIGURATIONS 58 | ], 59 | 'user' => [ 60 | 'identityClass' => 'dektrium\user\models\User', 61 | ], 62 | 'wtsecure' => [ 63 | 'class' => 'azraf\simpleapp\classes\SimpleSecurity', 64 | ], 65 | 'urlManager' => [ 66 | 'enablePrettyUrl' => true, 67 | 'showScriptName' => true, // If you want to hide `index.php` from URL, make it false and set a .htaccess file 68 | ], 69 | 'errorHandler' => [ 70 | 'errorAction' => 'site/error', 71 | ], 72 | 'mailer' => [ 73 | 'class' => 'yii\swiftmailer\Mailer', 74 | // send all mails to a file by default. You have to set 75 | // 'useFileTransport' to false and configure a transport 76 | // for the mailer to send real emails. 77 | 'useFileTransport' => true, 78 | ], 79 | 'log' => [ 80 | 'traceLevel' => YII_DEBUG ? 3 : 0, 81 | 'targets' => [ 82 | [ 83 | 'class' => 'yii\log\FileTarget', 84 | 'levels' => ['error', 'warning'], 85 | ], 86 | ], 87 | ], 88 | 'session' => [ 89 | 'class' => 'yii\web\DbSession', 90 | // 'db' => 'mydb', // the application component ID of the DB connection. Defaults to 'db'. 91 | // 'sessionTable' => 'my_session', // session table name. Defaults to 'session'. 92 | ], 93 | 'view' => [ 94 | 'theme' => [ 95 | 'pathMap' => [ 96 | '@dektrium/user/views' => '@app/views/user' 97 | ], 98 | ], 99 | ], 100 | 'i18n' => [ 101 | 'translations' => [ 102 | '*' => [ 103 | 'class' => 'yii\i18n\PhpMessageSource', 104 | 'basePath' => '@app/messages', // if advanced application, set @frontend/messages 105 | 'sourceLanguage' => 'en', 106 | 'fileMap' => [ 107 | //'main' => 'main.php', 108 | ], 109 | ], 110 | ], 111 | ], 112 | 'db' => require(__DIR__ . '/db.php'), 113 | ], 114 | 'as access' => [ 115 | 'class' => 'mdm\admin\components\AccessControl', 116 | 'allowActions' => [ 117 | // 'admin/*', // ::: IMPORTANT :::: Make it disable after configuring the USER Roles/Permissions 118 | 'user/index', // add or remove allowed actions to this list 119 | 'user/login', // add or remove allowed actions to this list 120 | 'user/security/login', // add or remove allowed actions to this list 121 | 'user/logout', // add or remove allowed actions to this list 122 | 'user/security/logout', // add or remove allowed actions to this list 123 | 'user/register', // add or remove allowed actions to this list 124 | 'user/registration/register', // add or remove allowed actions to this list 125 | 'user/registration/confirm', // add or remove allowed actions to this list 126 | 'user/registration/resend', // add or remove allowed actions to this list 127 | 'user/registration/connect', // add or remove allowed actions to this list 128 | 129 | 'site/index', 130 | 'site/about', 131 | 'site/contact', 132 | 'site/signup', 133 | 'site/logout', 134 | 'site/login' 135 | ] 136 | ], 137 | 'params' => $params, 138 | ]; 139 | 140 | if (YII_ENV_DEV) { 141 | // configuration adjustments for 'dev' environment 142 | $config['bootstrap'][] = 'debug'; 143 | $config['modules']['debug'] = 'yii\debug\Module'; 144 | 145 | $config['bootstrap'][] = 'gii'; 146 | $config['modules']['gii'] = 'yii\gii\Module'; 147 | } 148 | 149 | return $config; 150 | -------------------------------------------------------------------------------- /models/User.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace app\models; 13 | 14 | use dektrium\user\helpers\ModuleTrait; 15 | use dektrium\user\helpers\Password; 16 | use yii\base\NotSupportedException; 17 | use yii\behaviors\TimestampBehavior; 18 | use yii\db\ActiveRecord; 19 | use yii\log\Logger; 20 | use yii\web\IdentityInterface; 21 | use Yii; 22 | 23 | /** 24 | * User ActiveRecord model. 25 | * 26 | * Database fields: 27 | * @property integer $id 28 | * @property string $username 29 | * @property string $email 30 | * @property string $unconfirmed_email 31 | * @property string $password_hash 32 | * @property string $auth_key 33 | * @property integer $registration_ip 34 | * @property integer $confirmed_at 35 | * @property integer $blocked_at 36 | * @property integer $created_at 37 | * @property integer $updated_at 38 | * @property integer $flags 39 | * 40 | * Defined relations: 41 | * @property Account[] $accounts 42 | * @property Profile $profile 43 | * 44 | * @author Dmitry Erofeev 45 | */ 46 | class User extends ActiveRecord implements IdentityInterface 47 | { 48 | use ModuleTrait; 49 | 50 | const USER_CREATE_INIT = 'user_create_init'; 51 | const USER_CREATE_DONE = 'user_create_done'; 52 | const USER_REGISTER_INIT = 'user_register_init'; 53 | const USER_REGISTER_DONE = 'user_register_done'; 54 | 55 | /** @var string Plain password. Used for model validation. */ 56 | public $password; 57 | 58 | /** 59 | * @return bool Whether the user is confirmed or not. 60 | */ 61 | public function getIsConfirmed() 62 | { 63 | return $this->confirmed_at != null; 64 | } 65 | 66 | /** 67 | * @return bool Whether the user is blocked or not. 68 | */ 69 | public function getIsBlocked() 70 | { 71 | return $this->blocked_at != null; 72 | } 73 | 74 | /** 75 | * @return bool Whether the user is an admin or not. 76 | */ 77 | public function getIsAdmin() 78 | { 79 | return in_array($this->username, $this->module->admins); 80 | } 81 | 82 | /** 83 | * @return \yii\db\ActiveQuery 84 | */ 85 | public function getProfile() 86 | { 87 | return $this->hasOne($this->module->manager->profileClass, ['user_id' => 'id']); 88 | } 89 | 90 | /** 91 | * @return Account[] Connected accounts ($provider => $account) 92 | */ 93 | public function getAccounts() 94 | { 95 | $connected = []; 96 | $accounts = $this->hasMany($this->module->manager->accountClass, ['user_id' => 'id'])->all(); 97 | 98 | /** @var Account $account */ 99 | foreach ($accounts as $account) { 100 | $connected[$account->provider] = $account; 101 | } 102 | 103 | return $connected; 104 | } 105 | 106 | /** @inheritdoc */ 107 | public function getId() 108 | { 109 | return $this->getAttribute('id'); 110 | } 111 | 112 | /** @inheritdoc */ 113 | public function getAuthKey() 114 | { 115 | return $this->getAttribute('auth_key'); 116 | } 117 | 118 | /** @inheritdoc */ 119 | public function attributeLabels() 120 | { 121 | return [ 122 | 'username' => \Yii::t('user', 'Username'), 123 | 'email' => \Yii::t('user', 'Email'), 124 | 'registration_ip' => \Yii::t('user', 'Registration ip'), 125 | 'unconfirmed_email' => \Yii::t('user', 'New email'), 126 | 'password' => \Yii::t('user', 'Password'), 127 | 'created_at' => \Yii::t('user', 'Registration time'), 128 | 'confirmed_at' => \Yii::t('user', 'Confirmation time'), 129 | ]; 130 | } 131 | 132 | /** @inheritdoc */ 133 | public function behaviors() 134 | { 135 | return [ 136 | TimestampBehavior::className(), 137 | ]; 138 | } 139 | 140 | /** @inheritdoc */ 141 | public function scenarios() 142 | { 143 | return [ 144 | 'register' => ['username', 'email', 'password'], 145 | 'connect' => ['username', 'email'], 146 | 'create' => ['username', 'email', 'password', 'role'], 147 | 'update' => ['username', 'email', 'password', 'role'], 148 | 'settings' => ['username', 'email', 'password'] 149 | ]; 150 | } 151 | 152 | /** @inheritdoc */ 153 | public function rules() 154 | { 155 | return [ 156 | // username rules 157 | ['username', 'required', 'on' => ['register', 'connect', 'create', 'update']], 158 | ['username', 'match', 'pattern' => '/^[a-zA-Z]\w+$/'], 159 | ['username', 'string', 'min' => 3, 'max' => 25], 160 | ['username', 'unique'], 161 | ['username', 'trim'], 162 | 163 | // email rules 164 | ['email', 'required', 'on' => ['register', 'connect', 'create', 'update', 'update_email']], 165 | ['email', 'email'], 166 | ['email', 'string', 'max' => 255], 167 | ['email', 'unique'], 168 | ['email', 'trim'], 169 | 170 | // unconfirmed email rules 171 | ['unconfirmed_email', 'required', 'on' => 'update_email'], 172 | ['unconfirmed_email', 'unique', 'targetAttribute' => 'email', 'on' => 'update_email'], 173 | ['unconfirmed_email', 'email', 'on' => 'update_email'], 174 | 175 | // password rules 176 | ['password', 'required', 'on' => ['register', 'update_password']], 177 | ['password', 'string', 'min' => 6, 'on' => ['register', 'update_password', 'create']], 178 | 179 | // current password rules 180 | ['current_password', 'required', 'on' => ['update_email', 'update_password']], 181 | ['current_password', function ($attr) { 182 | if (!empty($this->$attr) && !Password::validate($this->$attr, $this->password_hash)) { 183 | $this->addError($attr, \Yii::t('user', 'Current password is not valid')); 184 | } 185 | }, 'on' => ['update_email', 'update_password']], 186 | ]; 187 | } 188 | 189 | /** @inheritdoc */ 190 | public function validateAuthKey($authKey) 191 | { 192 | return $this->getAttribute('auth_key') == $authKey; 193 | } 194 | 195 | 196 | /** 197 | * This method is used to create new user account. If password is not set, this method will generate new 8-char 198 | * password. After saving user to database, this method uses mailer component to send credentials 199 | * (username and password) to user via email. 200 | * 201 | * @return bool 202 | */ 203 | public function create() 204 | { 205 | if ($this->getIsNewRecord() == false) { 206 | throw new \RuntimeException('Calling "' . __CLASS__ . '::' . __METHOD__ . '" on existing user'); 207 | } 208 | 209 | $this->confirmed_at = time(); 210 | 211 | if ($this->password == null) { 212 | $this->password = Password::generate(8); 213 | } 214 | 215 | $this->trigger(self::USER_CREATE_INIT); 216 | 217 | if ($this->save()) { 218 | $this->trigger(self::USER_CREATE_DONE); 219 | $this->module->mailer->sendWelcomeMessage($this); 220 | \Yii::getLogger()->log('User has been created', Logger::LEVEL_INFO); 221 | return true; 222 | } 223 | 224 | \Yii::getLogger()->log('An error occurred while creating user account', Logger::LEVEL_ERROR); 225 | 226 | return false; 227 | } 228 | 229 | /** 230 | * This method is used to register new user account. If Module::enableConfirmation is set true, this method 231 | * will generate new confirmation token and use mailer to send it to the user. Otherwise it will log the user in. 232 | * If Module::enableGeneratingPassword is set true, this method will generate new 8-char password. After saving user 233 | * to database, this method uses mailer component to send credentials (username and password) to user via email. 234 | * 235 | * @return bool 236 | */ 237 | public function register() 238 | { 239 | if ($this->getIsNewRecord() == false) { 240 | throw new \RuntimeException('Calling "' . __CLASS__ . '::' . __METHOD__ . '" on existing user'); 241 | } 242 | 243 | if ($this->module->enableConfirmation == false) { 244 | $this->confirmed_at = time(); 245 | } 246 | 247 | if ($this->module->enableGeneratingPassword) { 248 | $this->password = Password::generate(8); 249 | } 250 | 251 | $this->trigger(self::USER_REGISTER_INIT); 252 | 253 | if ($this->save()) { 254 | $this->trigger(self::USER_REGISTER_DONE); 255 | if ($this->module->enableConfirmation) { 256 | $token = $this->module->manager->createToken(['type' => Token::TYPE_CONFIRMATION]); 257 | $token->link('user', $this); 258 | $this->module->mailer->sendConfirmationMessage($this, $token); 259 | \Yii::$app->session->setFlash('user.confirmation_sent'); 260 | } else { 261 | \Yii::$app->session->setFlash('user.registration_finished'); 262 | \Yii::$app->user->login($this); 263 | } 264 | if ($this->module->enableGeneratingPassword) { 265 | $this->module->mailer->sendWelcomeMessage($this); 266 | \Yii::$app->session->setFlash('user.password_generated'); 267 | } 268 | \Yii::getLogger()->log('User has been registered', Logger::LEVEL_INFO); 269 | return true; 270 | } 271 | 272 | \Yii::getLogger()->log('An error occurred while registering user account', Logger::LEVEL_ERROR); 273 | 274 | return false; 275 | } 276 | 277 | /** 278 | * This method attempts user confirmation. It uses model manager to find token with given code and if it is expired 279 | * or does not exist, this method will throw exception. 280 | * 281 | * If confirmation passes it will return true, otherwise it will return false. 282 | * 283 | * @param string $code Confirmation code. 284 | * @return boolean 285 | */ 286 | public function attemptConfirmation($code) 287 | { 288 | $token = $this->module->manager->findToken($this->id, $code, Token::TYPE_CONFIRMATION); 289 | 290 | if ($token === null || $token->isExpired) { 291 | return false; 292 | } 293 | 294 | $token->delete(); 295 | 296 | $this->confirmed_at = time(); 297 | 298 | \Yii::getLogger()->log('User has been confirmed', Logger::LEVEL_INFO); 299 | 300 | return $this->save(false); 301 | } 302 | 303 | /** 304 | * This method attempts changing user email. If user's "unconfirmed_email" field is empty is returns false, else if 305 | * somebody already has email that equals user's "unconfirmed_email" it returns false, otherwise returns true and 306 | * updates user's password. 307 | * 308 | * @param string $code 309 | * @return bool 310 | * @throws \Exception 311 | */ 312 | public function attemptEmailChange($code) 313 | { 314 | $token = $this->module->manager->findToken($this->id, $code, Token::TYPE_CONFIRM_NEW_EMAIL); 315 | 316 | if (empty($this->unconfirmed_email) || $token === null || $token->isExpired) { 317 | return false; 318 | } 319 | 320 | $token->delete(); 321 | 322 | if (empty($this->unconfirmed_email)) { 323 | return false; 324 | } else if (static::find()->where(['email' => $this->unconfirmed_email])->exists() == false) { 325 | $status = true; 326 | $this->email = $this->unconfirmed_email; 327 | } else { 328 | $status = false; 329 | } 330 | 331 | $this->unconfirmed_email = null; 332 | $this->save(false); 333 | 334 | return $status; 335 | } 336 | 337 | /** 338 | * Resets password. 339 | * 340 | * @param string $password 341 | * @return bool 342 | */ 343 | public function resetPassword($password) 344 | { 345 | return (bool) $this->updateAttributes(['password_hash' => Password::hash($password)]); 346 | } 347 | 348 | /** 349 | * Confirms the user by setting 'blocked_at' field to current time. 350 | */ 351 | public function confirm() 352 | { 353 | return (bool) $this->updateAttributes(['confirmed_at' => time()]); 354 | } 355 | 356 | /** 357 | * Blocks the user by setting 'blocked_at' field to current time. 358 | */ 359 | public function block() 360 | { 361 | return (bool) $this->updateAttributes(['blocked_at' => time()]); 362 | } 363 | 364 | /** 365 | * Blocks the user by setting 'blocked_at' field to null. 366 | */ 367 | public function unblock() 368 | { 369 | return (bool) $this->updateAttributes(['blocked_at' => null]); 370 | } 371 | 372 | /** @inheritdoc */ 373 | public function beforeSave($insert) 374 | { 375 | if ($insert) { 376 | $this->setAttribute('auth_key', \Yii::$app->security->generateRandomString()); 377 | if (\Yii::$app instanceof \yii\web\Application) { 378 | $this->setAttribute('registration_ip', ip2long(Yii::$app->request->userIP)); 379 | } 380 | } 381 | 382 | if (!empty($this->password)) { 383 | $this->setAttribute('password_hash', Password::hash($this->password)); 384 | } 385 | 386 | return parent::beforeSave($insert); 387 | } 388 | 389 | /** @inheritdoc */ 390 | public function afterSave($insert, $changedAttributes) 391 | { 392 | if ($insert) { 393 | $profile = $this->module->manager->createProfile([ 394 | 'user_id' => $this->id, 395 | 'gravatar_email' => $this->email 396 | ]); 397 | $profile->save(false); 398 | } 399 | parent::afterSave($insert, $changedAttributes); 400 | } 401 | 402 | /** @inheritdoc */ 403 | public static function tableName() 404 | { 405 | return '{{%user}}'; 406 | } 407 | 408 | /** @inheritdoc */ 409 | public static function findIdentity($id) 410 | { 411 | return static::findOne($id); 412 | } 413 | 414 | /** @inheritdoc */ 415 | public static function findIdentityByAccessToken($token, $type = null) 416 | { 417 | throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.'); 418 | } 419 | } 420 | --------------------------------------------------------------------------------