├── .bowerrc
├── .gitignore
├── LICENSE.md
├── README.md
├── backend
├── assets
│ └── AppAsset.php
├── config
│ ├── .gitignore
│ ├── bootstrap.php
│ ├── main.php
│ └── params.php
├── controllers
│ └── SiteController.php
├── models
│ └── .gitkeep
├── runtime
│ └── .gitignore
├── views
│ ├── layouts
│ │ └── main.php
│ └── site
│ │ ├── error.php
│ │ ├── index.php
│ │ └── login.php
└── web
│ ├── .gitignore
│ ├── assets
│ └── .gitignore
│ ├── css
│ └── site.css
│ ├── favicon.ico
│ └── robots.txt
├── common
├── config
│ ├── .gitignore
│ ├── bootstrap.php
│ ├── main.php
│ └── params.php
├── mail
│ ├── layouts
│ │ ├── html.php
│ │ └── text.php
│ ├── passwordResetToken-html.php
│ └── passwordResetToken-text.php
└── models
│ ├── LoginForm.php
│ └── User.php
├── composer.json
├── composer.lock
├── console
├── config
│ ├── .gitignore
│ ├── bootstrap.php
│ ├── main.php
│ └── params.php
├── controllers
│ └── .gitkeep
├── migrations
│ └── m130524_201442_init.php
├── models
│ └── .gitkeep
└── runtime
│ └── .gitignore
├── db
└── users.db
├── environments
├── dev
│ ├── backend
│ │ ├── config
│ │ │ ├── main-local.php
│ │ │ └── params-local.php
│ │ └── web
│ │ │ ├── index-test.php
│ │ │ └── index.php
│ ├── common
│ │ └── config
│ │ │ ├── main-local.php
│ │ │ └── params-local.php
│ ├── console
│ │ └── config
│ │ │ ├── main-local.php
│ │ │ └── params-local.php
│ ├── frontend
│ │ ├── config
│ │ │ ├── main-local.php
│ │ │ └── params-local.php
│ │ └── web
│ │ │ ├── index-test.php
│ │ │ └── index.php
│ └── yii
├── index.php
└── prod
│ ├── backend
│ ├── config
│ │ ├── main-local.php
│ │ └── params-local.php
│ └── web
│ │ └── index.php
│ ├── common
│ └── config
│ │ ├── main-local.php
│ │ └── params-local.php
│ ├── console
│ └── config
│ │ ├── main-local.php
│ │ └── params-local.php
│ ├── frontend
│ ├── config
│ │ ├── main-local.php
│ │ └── params-local.php
│ └── web
│ │ └── index.php
│ └── yii
├── frontend
├── assets
│ ├── AngularAsset.php
│ └── AppAsset.php
├── config
│ ├── .gitignore
│ ├── bootstrap.php
│ ├── main.php
│ └── params.php
├── controllers
│ ├── ApiController.php
│ └── SiteController.php
├── models
│ ├── ContactForm.php
│ ├── PasswordResetRequestForm.php
│ ├── ResetPasswordForm.php
│ └── SignupForm.php
├── runtime
│ └── .gitignore
├── views
│ ├── layouts
│ │ └── main.php
│ └── site
│ │ └── error.php
└── web
│ ├── .gitignore
│ ├── .htaccess
│ ├── assets
│ └── .gitignore
│ ├── css
│ └── site.css
│ ├── favicon.ico
│ ├── js
│ ├── app.js
│ └── controllers.js
│ ├── partials
│ ├── 404.html
│ ├── about.html
│ ├── contact.html
│ ├── dashboard.html
│ ├── index.html
│ └── login.html
│ └── robots.txt
├── init
├── init.bat
├── requirements.php
├── tests
├── README.md
├── codeception.yml
└── codeception
│ ├── _output
│ └── .gitignore
│ ├── backend
│ ├── .gitignore
│ ├── _bootstrap.php
│ ├── _output
│ │ └── .gitignore
│ ├── acceptance.suite.yml
│ ├── acceptance
│ │ ├── LoginCept.php
│ │ └── _bootstrap.php
│ ├── codeception.yml
│ ├── functional.suite.yml
│ ├── functional
│ │ ├── LoginCept.php
│ │ └── _bootstrap.php
│ ├── unit.suite.yml
│ └── unit
│ │ ├── DbTestCase.php
│ │ ├── TestCase.php
│ │ ├── _bootstrap.php
│ │ └── fixtures
│ │ └── data
│ │ └── .gitkeep
│ ├── bin
│ ├── _bootstrap.php
│ ├── yii
│ └── yii.bat
│ ├── common
│ ├── .gitignore
│ ├── _bootstrap.php
│ ├── _output
│ │ └── .gitignore
│ ├── _pages
│ │ └── LoginPage.php
│ ├── _support
│ │ └── FixtureHelper.php
│ ├── codeception.yml
│ ├── fixtures
│ │ ├── UserFixture.php
│ │ └── data
│ │ │ └── init_login.php
│ ├── templates
│ │ └── fixtures
│ │ │ └── user.php
│ ├── unit.suite.yml
│ └── unit
│ │ ├── DbTestCase.php
│ │ ├── TestCase.php
│ │ ├── _bootstrap.php
│ │ ├── fixtures
│ │ └── data
│ │ │ └── models
│ │ │ └── user.php
│ │ └── models
│ │ └── LoginFormTest.php
│ ├── config
│ ├── acceptance.php
│ ├── backend
│ │ ├── acceptance.php
│ │ ├── config.php
│ │ ├── functional.php
│ │ └── unit.php
│ ├── common
│ │ └── unit.php
│ ├── config.php
│ ├── console
│ │ └── unit.php
│ ├── frontend
│ │ ├── acceptance.php
│ │ ├── config.php
│ │ ├── functional.php
│ │ └── unit.php
│ ├── functional.php
│ └── unit.php
│ ├── console
│ ├── .gitignore
│ ├── _bootstrap.php
│ ├── _output
│ │ └── .gitignore
│ ├── codeception.yml
│ ├── unit.suite.yml
│ └── unit
│ │ ├── DbTestCase.php
│ │ ├── TestCase.php
│ │ ├── _bootstrap.php
│ │ └── fixtures
│ │ └── data
│ │ └── .gitkeep
│ └── frontend
│ ├── .gitignore
│ ├── _bootstrap.php
│ ├── _output
│ └── .gitignore
│ ├── _pages
│ ├── AboutPage.php
│ ├── ContactPage.php
│ └── SignupPage.php
│ ├── acceptance.suite.yml
│ ├── acceptance
│ ├── AboutCept.php
│ ├── ContactCept.php
│ ├── HomeCept.php
│ ├── LoginCept.php
│ ├── SignupCest.php
│ └── _bootstrap.php
│ ├── codeception.yml
│ ├── functional.suite.yml
│ ├── functional
│ ├── AboutCept.php
│ ├── ContactCept.php
│ ├── HomeCept.php
│ ├── LoginCept.php
│ ├── SignupCest.php
│ └── _bootstrap.php
│ ├── unit.suite.yml
│ └── unit
│ ├── DbTestCase.php
│ ├── TestCase.php
│ ├── _bootstrap.php
│ ├── fixtures
│ └── data
│ │ └── models
│ │ └── user.php
│ └── models
│ ├── ContactFormTest.php
│ ├── PasswordResetRequestFormTest.php
│ ├── ResetPasswordFormTest.php
│ └── SignupFormTest.php
└── yii.bat
/.bowerrc:
--------------------------------------------------------------------------------
1 | {
2 | "directory" : "vendor/bower"
3 | }
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # yii console command
2 | /yii
3 |
4 | # phpstorm project files
5 | .idea
6 |
7 | # netbeans project files
8 | nbproject
9 |
10 | # zend studio for eclipse project files
11 | .buildpath
12 | .project
13 | .settings
14 |
15 | # windows thumbnail cache
16 | Thumbs.db
17 |
18 | # composer vendor dir
19 | /vendor
20 |
21 | # composer itself is not needed
22 | composer.phar
23 |
24 | # Mac DS_Store Files
25 | .DS_Store
26 |
27 | # phpunit itself is not needed
28 | phpunit.phar
29 | # local phpunit config
30 | /phpunit.xml
31 |
--------------------------------------------------------------------------------
/LICENSE.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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | AngularJS and Yii2 Part 2: Authentication
2 | ================================
3 |
4 | If you're planning on running these on your server don't forget to:
5 | ~~~
6 | php composer.phar install
7 | ~~~
8 | and initialize the environment
9 | ~~~
10 | php init
11 | ~~~
12 |
13 | The tutorial is located here [Neat Tutorials](http://blog.neattutorials.com/angularjs-and-yii2-part-2-authentication/)
14 |
--------------------------------------------------------------------------------
/backend/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 |
--------------------------------------------------------------------------------
/backend/config/.gitignore:
--------------------------------------------------------------------------------
1 | main-local.php
2 | params-local.php
--------------------------------------------------------------------------------
/backend/config/bootstrap.php:
--------------------------------------------------------------------------------
1 | 'app-backend',
11 | 'basePath' => dirname(__DIR__),
12 | 'controllerNamespace' => 'backend\controllers',
13 | 'bootstrap' => ['log'],
14 | 'modules' => [],
15 | 'components' => [
16 | 'user' => [
17 | 'identityClass' => 'common\models\User',
18 | 'enableAutoLogin' => true,
19 | ],
20 | 'log' => [
21 | 'traceLevel' => YII_DEBUG ? 3 : 0,
22 | 'targets' => [
23 | [
24 | 'class' => 'yii\log\FileTarget',
25 | 'levels' => ['error', 'warning'],
26 | ],
27 | ],
28 | ],
29 | 'errorHandler' => [
30 | 'errorAction' => 'site/error',
31 | ],
32 | ],
33 | 'params' => $params,
34 | ];
35 |
--------------------------------------------------------------------------------
/backend/config/params.php:
--------------------------------------------------------------------------------
1 | 'admin@example.com',
4 | ];
5 |
--------------------------------------------------------------------------------
/backend/controllers/SiteController.php:
--------------------------------------------------------------------------------
1 | [
22 | 'class' => AccessControl::className(),
23 | 'rules' => [
24 | [
25 | 'actions' => ['login', 'error'],
26 | 'allow' => true,
27 | ],
28 | [
29 | 'actions' => ['logout', 'index'],
30 | 'allow' => true,
31 | 'roles' => ['@'],
32 | ],
33 | ],
34 | ],
35 | 'verbs' => [
36 | 'class' => VerbFilter::className(),
37 | 'actions' => [
38 | 'logout' => ['post'],
39 | ],
40 | ],
41 | ];
42 | }
43 |
44 | /**
45 | * @inheritdoc
46 | */
47 | public function actions()
48 | {
49 | return [
50 | 'error' => [
51 | 'class' => 'yii\web\ErrorAction',
52 | ],
53 | ];
54 | }
55 |
56 | public function actionIndex()
57 | {
58 | return $this->render('index');
59 | }
60 |
61 | public function actionLogin()
62 | {
63 | if (!\Yii::$app->user->isGuest) {
64 | return $this->goHome();
65 | }
66 |
67 | $model = new LoginForm();
68 | if ($model->load(Yii::$app->request->post()) && $model->login()) {
69 | return $this->goBack();
70 | } else {
71 | return $this->render('login', [
72 | 'model' => $model,
73 | ]);
74 | }
75 | }
76 |
77 | public function actionLogout()
78 | {
79 | Yii::$app->user->logout();
80 |
81 | return $this->goHome();
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/backend/models/.gitkeep:
--------------------------------------------------------------------------------
1 | *
2 |
--------------------------------------------------------------------------------
/backend/runtime/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
--------------------------------------------------------------------------------
/backend/views/layouts/main.php:
--------------------------------------------------------------------------------
1 |
13 | beginPage() ?>
14 |
15 |
16 |
17 |
18 |
19 | = Html::csrfMetaTags() ?>
20 | = Html::encode($this->title) ?>
21 | head() ?>
22 |
23 |
24 | beginBody() ?>
25 |
26 | 'My Company',
29 | 'brandUrl' => Yii::$app->homeUrl,
30 | 'options' => [
31 | 'class' => 'navbar-inverse navbar-fixed-top',
32 | ],
33 | ]);
34 | $menuItems = [
35 | ['label' => 'Home', 'url' => ['/site/index']],
36 | ];
37 | if (Yii::$app->user->isGuest) {
38 | $menuItems[] = ['label' => 'Login', 'url' => ['/site/login']];
39 | } else {
40 | $menuItems[] = [
41 | 'label' => 'Logout (' . Yii::$app->user->identity->username . ')',
42 | 'url' => ['/site/logout'],
43 | 'linkOptions' => ['data-method' => 'post']
44 | ];
45 | }
46 | echo Nav::widget([
47 | 'options' => ['class' => 'navbar-nav navbar-right'],
48 | 'items' => $menuItems,
49 | ]);
50 | NavBar::end();
51 | ?>
52 |
53 |
54 | = Breadcrumbs::widget([
55 | 'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [],
56 | ]) ?>
57 | = $content ?>
58 |
59 |
60 |
61 |
67 |
68 | endBody() ?>
69 |
70 |
71 | endPage() ?>
72 |
--------------------------------------------------------------------------------
/backend/views/site/error.php:
--------------------------------------------------------------------------------
1 | title = $name;
11 | ?>
12 |
13 |
14 |
= Html::encode($this->title) ?>
15 |
16 |
17 | = nl2br(Html::encode($message)) ?>
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 |
--------------------------------------------------------------------------------
/backend/views/site/index.php:
--------------------------------------------------------------------------------
1 | title = 'My Yii Application';
5 | ?>
6 |
7 |
8 |
9 |
Congratulations!
10 |
11 |
You have successfully created your Yii-powered application.
12 |
13 |
Get started with Yii
14 |
15 |
16 |
17 |
18 |
19 |
20 |
Heading
21 |
22 |
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et
23 | dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
24 | ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
25 | fugiat nulla pariatur.
26 |
27 |
Yii Documentation »
28 |
29 |
30 |
Heading
31 |
32 |
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et
33 | dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
34 | ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
35 | fugiat nulla pariatur.
36 |
37 |
Yii Forum »
38 |
39 |
40 |
Heading
41 |
42 |
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et
43 | dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
44 | ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
45 | fugiat nulla pariatur.
46 |
47 |
Yii Extensions »
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/backend/views/site/login.php:
--------------------------------------------------------------------------------
1 | title = 'Login';
10 | $this->params['breadcrumbs'][] = $this->title;
11 | ?>
12 |
13 |
= Html::encode($this->title) ?>
14 |
15 |
Please fill out the following fields to login:
16 |
17 |
18 |
19 | 'login-form']); ?>
20 | = $form->field($model, 'username') ?>
21 | = $form->field($model, 'password')->passwordInput() ?>
22 | = $form->field($model, 'rememberMe')->checkbox() ?>
23 |
24 | = Html::submitButton('Login', ['class' => 'btn btn-primary', 'name' => 'login-button']) ?>
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/backend/web/.gitignore:
--------------------------------------------------------------------------------
1 | /index.php
2 | /index-test.php
3 |
--------------------------------------------------------------------------------
/backend/web/assets/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/backend/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 |
--------------------------------------------------------------------------------
/backend/web/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neattutorials/angularjs-yii2-part-2-authentication/726353f9a475c61da3a53fce0afe120c841ccf3a/backend/web/favicon.ico
--------------------------------------------------------------------------------
/backend/web/robots.txt:
--------------------------------------------------------------------------------
1 | User-Agent: *
2 | Disallow: /
3 |
--------------------------------------------------------------------------------
/common/config/.gitignore:
--------------------------------------------------------------------------------
1 | main-local.php
2 | params-local.php
3 |
--------------------------------------------------------------------------------
/common/config/bootstrap.php:
--------------------------------------------------------------------------------
1 | dirname(dirname(__DIR__)) . '/vendor',
4 | 'components' => [
5 | 'cache' => [
6 | 'class' => 'yii\caching\FileCache',
7 | ],
8 | ],
9 | ];
10 |
--------------------------------------------------------------------------------
/common/config/params.php:
--------------------------------------------------------------------------------
1 | 'admin@example.com',
4 | 'supportEmail' => 'support@example.com',
5 | 'user.passwordResetTokenExpire' => 3600,
6 | ];
7 |
--------------------------------------------------------------------------------
/common/mail/layouts/html.php:
--------------------------------------------------------------------------------
1 |
8 | beginPage() ?>
9 |
10 |
11 |
12 |
13 | = Html::encode($this->title) ?>
14 | head() ?>
15 |
16 |
17 | beginBody() ?>
18 | = $content ?>
19 | endBody() ?>
20 |
21 |
22 | endPage() ?>
23 |
--------------------------------------------------------------------------------
/common/mail/layouts/text.php:
--------------------------------------------------------------------------------
1 |
8 | beginPage() ?>
9 | beginBody() ?>
10 | = $content ?>
11 | endBody() ?>
12 | endPage() ?>
13 |
--------------------------------------------------------------------------------
/common/mail/passwordResetToken-html.php:
--------------------------------------------------------------------------------
1 | urlManager->createAbsoluteUrl(['site/reset-password', 'token' => $user->password_reset_token]);
8 | ?>
9 |
10 |
Hello = Html::encode($user->username) ?>,
11 |
12 |
Follow the link below to reset your password:
13 |
14 |
= Html::a(Html::encode($resetLink), $resetLink) ?>
15 |
16 |
--------------------------------------------------------------------------------
/common/mail/passwordResetToken-text.php:
--------------------------------------------------------------------------------
1 | urlManager->createAbsoluteUrl(['site/reset-password', 'token' => $user->password_reset_token]);
7 | ?>
8 | Hello = $user->username ?>,
9 |
10 | Follow the link below to reset your password:
11 |
12 | = $resetLink ?>
13 |
--------------------------------------------------------------------------------
/common/models/LoginForm.php:
--------------------------------------------------------------------------------
1 | hasErrors()) {
44 | $user = $this->getUser();
45 | if (!$user || !$user->validatePassword($this->password)) {
46 | $this->addError($attribute, 'Incorrect username or password.');
47 | }
48 | }
49 | }
50 |
51 | /**
52 | * Logs in a user using the provided username and password.
53 | *
54 | * @return boolean whether the user is logged in successfully
55 | */
56 | public function login()
57 | {
58 | if ($this->validate()) {
59 | return Yii::$app->user->login($this->getUser()/*, $this->rememberMe ? 3600 * 24 * 30 : 0*/);
60 | } else {
61 | return false;
62 | }
63 | }
64 |
65 | /**
66 | * Finds user by [[username]]
67 | *
68 | * @return User|null
69 | */
70 | public function getUser()
71 | {
72 | if ($this->_user === false) {
73 | $this->_user = User::findByUsername($this->username);
74 | }
75 |
76 | return $this->_user;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/common/models/User.php:
--------------------------------------------------------------------------------
1 | self::STATUS_ACTIVE],
54 | ['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED]],
55 | ];
56 | }
57 |
58 | /**
59 | * @inheritdoc
60 | */
61 | public static function findIdentity($id)
62 | {
63 | return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);
64 | }
65 |
66 | /**
67 | * @inheritdoc
68 | */
69 | public static function findIdentityByAccessToken($token, $type = null)
70 | {
71 | return static::findOne(['auth_key' => $token]);
72 | }
73 |
74 | /**
75 | * Finds user by username
76 | *
77 | * @param string $username
78 | * @return static|null
79 | */
80 | public static function findByUsername($username)
81 | {
82 | return static::findOne(['username' => $username, 'status' => self::STATUS_ACTIVE]);
83 | }
84 |
85 | /**
86 | * Finds user by password reset token
87 | *
88 | * @param string $token password reset token
89 | * @return static|null
90 | */
91 | public static function findByPasswordResetToken($token)
92 | {
93 | if (!static::isPasswordResetTokenValid($token)) {
94 | return null;
95 | }
96 |
97 | return static::findOne([
98 | 'password_reset_token' => $token,
99 | 'status' => self::STATUS_ACTIVE,
100 | ]);
101 | }
102 |
103 | /**
104 | * Finds out if password reset token is valid
105 | *
106 | * @param string $token password reset token
107 | * @return boolean
108 | */
109 | public static function isPasswordResetTokenValid($token)
110 | {
111 | if (empty($token)) {
112 | return false;
113 | }
114 | $expire = Yii::$app->params['user.passwordResetTokenExpire'];
115 | $parts = explode('_', $token);
116 | $timestamp = (int) end($parts);
117 | return $timestamp + $expire >= time();
118 | }
119 |
120 | /**
121 | * @inheritdoc
122 | */
123 | public function getId()
124 | {
125 | return $this->getPrimaryKey();
126 | }
127 |
128 | /**
129 | * @inheritdoc
130 | */
131 | public function getAuthKey()
132 | {
133 | return $this->auth_key;
134 | }
135 |
136 | /**
137 | * @inheritdoc
138 | */
139 | public function validateAuthKey($authKey)
140 | {
141 | return $this->getAuthKey() === $authKey;
142 | }
143 |
144 | /**
145 | * Validates password
146 | *
147 | * @param string $password password to validate
148 | * @return boolean if password provided is valid for current user
149 | */
150 | public function validatePassword($password)
151 | {
152 | return Yii::$app->security->validatePassword($password, $this->password_hash);
153 | }
154 |
155 | /**
156 | * Generates password hash from password and sets it to the model
157 | *
158 | * @param string $password
159 | */
160 | public function setPassword($password)
161 | {
162 | $this->password_hash = Yii::$app->security->generatePasswordHash($password);
163 | }
164 |
165 | /**
166 | * Generates "remember me" authentication key
167 | */
168 | public function generateAuthKey()
169 | {
170 | $this->auth_key = Yii::$app->security->generateRandomString();
171 | }
172 |
173 | /**
174 | * Generates new password reset token
175 | */
176 | public function generatePasswordResetToken()
177 | {
178 | $this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time();
179 | }
180 |
181 | /**
182 | * Removes password reset token
183 | */
184 | public function removePasswordResetToken()
185 | {
186 | $this->password_reset_token = null;
187 | }
188 | }
189 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "yiisoft/yii2-app-advanced",
3 | "description": "Yii 2 Advanced Application Template",
4 | "keywords": ["yii2", "framework", "advanced", "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": "stable",
16 | "require": {
17 | "php": ">=5.4.0",
18 | "yiisoft/yii2": "*",
19 | "yiisoft/yii2-bootstrap": "*",
20 | "yiisoft/yii2-swiftmailer": "*",
21 | "bower-asset/angular": "*",
22 | "bower-asset/angular-route": "*",
23 | "bower-asset/angular-strap": "*"
24 |
25 | },
26 | "require-dev": {
27 | "yiisoft/yii2-codeception": "*",
28 | "yiisoft/yii2-debug": "*",
29 | "yiisoft/yii2-gii": "*",
30 | "yiisoft/yii2-faker": "*"
31 | },
32 | "config": {
33 | "process-timeout": 1800
34 | },
35 | "extra": {
36 | "asset-installer-paths": {
37 | "npm-asset-library": "vendor/npm",
38 | "bower-asset-library": "vendor/bower"
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/composer.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_readme": [
3 | "This file locks the dependencies of your project to a known state",
4 | "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
5 | "This file is @generated automatically"
6 | ],
7 | "hash": "71736ffee996c56eeff126dbefbfe013",
8 | "packages": [
9 | {
10 | "name": "bower-asset/angular",
11 | "version": "v1.3.15",
12 | "source": {
13 | "type": "git",
14 | "url": "https://github.com/angular/bower-angular.git",
15 | "reference": "ba7abcfa409ba852146e6ba206693cf7bac3e359"
16 | },
17 | "dist": {
18 | "type": "zip",
19 | "url": "https://api.github.com/repos/angular/bower-angular/zipball/ba7abcfa409ba852146e6ba206693cf7bac3e359",
20 | "reference": "ba7abcfa409ba852146e6ba206693cf7bac3e359",
21 | "shasum": ""
22 | },
23 | "type": "bower-asset-library",
24 | "extra": {
25 | "bower-asset-main": "./angular.js",
26 | "bower-asset-ignore": []
27 | }
28 | },
29 | {
30 | "name": "bower-asset/angular-cookies",
31 | "version": "v1.3.15",
32 | "source": {
33 | "type": "git",
34 | "url": "https://github.com/angular/bower-angular-cookies.git",
35 | "reference": "846700fd8e45eefa1a43cf1865bcb7aaf95a68e0"
36 | },
37 | "dist": {
38 | "type": "zip",
39 | "url": "https://api.github.com/repos/angular/bower-angular-cookies/zipball/846700fd8e45eefa1a43cf1865bcb7aaf95a68e0",
40 | "reference": "846700fd8e45eefa1a43cf1865bcb7aaf95a68e0",
41 | "shasum": ""
42 | },
43 | "require": {
44 | "bower-asset/angular": "1.3.15"
45 | },
46 | "type": "bower-asset-library",
47 | "extra": {
48 | "bower-asset-main": "./angular-cookies.js",
49 | "bower-asset-ignore": []
50 | }
51 | },
52 | {
53 | "name": "bower-asset/angular-route",
54 | "version": "v1.3.15",
55 | "source": {
56 | "type": "git",
57 | "url": "https://github.com/angular/bower-angular-route.git",
58 | "reference": "1f6e6ac94e20b98bca10155363042411f7729ce2"
59 | },
60 | "dist": {
61 | "type": "zip",
62 | "url": "https://api.github.com/repos/angular/bower-angular-route/zipball/1f6e6ac94e20b98bca10155363042411f7729ce2",
63 | "reference": "1f6e6ac94e20b98bca10155363042411f7729ce2",
64 | "shasum": ""
65 | },
66 | "require": {
67 | "bower-asset/angular": "1.3.15"
68 | },
69 | "type": "bower-asset-library",
70 | "extra": {
71 | "bower-asset-main": "./angular-route.js",
72 | "bower-asset-ignore": []
73 | }
74 | },
75 | {
76 | "name": "bower-asset/angular-strap",
77 | "version": "v2.2.1",
78 | "source": {
79 | "type": "git",
80 | "url": "https://github.com/mgcrea/angular-strap.git",
81 | "reference": "206fd5b73dc012b8886fc4a2b8e4a62389d3af45"
82 | },
83 | "dist": {
84 | "type": "zip",
85 | "url": "https://api.github.com/repos/mgcrea/angular-strap/zipball/206fd5b73dc012b8886fc4a2b8e4a62389d3af45",
86 | "reference": "206fd5b73dc012b8886fc4a2b8e4a62389d3af45",
87 | "shasum": ""
88 | },
89 | "require": {
90 | "bower-asset/angular": ">=1.2.21,<2.0.0"
91 | },
92 | "require-dev": {
93 | "bower-asset/angular-animate": ">=1.2.21,<2.0.0",
94 | "bower-asset/angular-i18n": ">=1.2.21,<2.0.0",
95 | "bower-asset/angular-mocks": ">=1.2.21,<2.0.0",
96 | "bower-asset/angular-motion": ">=0.3.3,<0.4.0",
97 | "bower-asset/angular-route": ">=1.2.21,<2.0.0",
98 | "bower-asset/angular-sanitize": ">=1.2.21,<2.0.0",
99 | "bower-asset/angular-scenario": ">=1.2.21,<2.0.0",
100 | "bower-asset/bootstrap": ">=3.2.0,<4.0.0",
101 | "bower-asset/bootstrap-additions": ">=0.2.3,<0.3.0",
102 | "bower-asset/fastclick": ">=1.0.3,<2.0.0",
103 | "bower-asset/font-awesome": ">=4.1.0,<5.0.0",
104 | "bower-asset/highlightjs": ">=8.0.0,<9.0.0",
105 | "bower-asset/jquery": ">=2.1.1,<3.0.0"
106 | },
107 | "type": "bower-asset-library",
108 | "extra": {
109 | "bower-asset-main": [
110 | "dist/angular-strap.js",
111 | "dist/angular-strap.tpl.js"
112 | ],
113 | "bower-asset-ignore": [
114 | "docs",
115 | "test",
116 | "CONTRIBUTING.md"
117 | ]
118 | },
119 | "description": "AngularStrap - AngularJS directives for Bootstrap",
120 | "keywords": [
121 | "angular",
122 | "bootstrap"
123 | ]
124 | },
125 | {
126 | "name": "bower-asset/bootstrap",
127 | "version": "v3.3.4",
128 | "source": {
129 | "type": "git",
130 | "url": "https://github.com/twbs/bootstrap.git",
131 | "reference": "a10eb60bc0b07b747fa0c4ebd8821eb7307bd07f"
132 | },
133 | "dist": {
134 | "type": "zip",
135 | "url": "https://api.github.com/repos/twbs/bootstrap/zipball/a10eb60bc0b07b747fa0c4ebd8821eb7307bd07f",
136 | "reference": "a10eb60bc0b07b747fa0c4ebd8821eb7307bd07f",
137 | "shasum": ""
138 | },
139 | "require": {
140 | "bower-asset/jquery": ">=1.9.1"
141 | },
142 | "type": "bower-asset-library",
143 | "extra": {
144 | "bower-asset-main": [
145 | "less/bootstrap.less",
146 | "dist/css/bootstrap.css",
147 | "dist/js/bootstrap.js",
148 | "dist/fonts/glyphicons-halflings-regular.eot",
149 | "dist/fonts/glyphicons-halflings-regular.svg",
150 | "dist/fonts/glyphicons-halflings-regular.ttf",
151 | "dist/fonts/glyphicons-halflings-regular.woff",
152 | "dist/fonts/glyphicons-halflings-regular.woff2"
153 | ],
154 | "bower-asset-ignore": [
155 | "/.*",
156 | "_config.yml",
157 | "CNAME",
158 | "composer.json",
159 | "CONTRIBUTING.md",
160 | "docs",
161 | "js/tests",
162 | "test-infra"
163 | ]
164 | },
165 | "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.",
166 | "keywords": [
167 | "css",
168 | "framework",
169 | "front-end",
170 | "js",
171 | "less",
172 | "mobile-first",
173 | "responsive",
174 | "web"
175 | ]
176 | },
177 | {
178 | "name": "bower-asset/jquery",
179 | "version": "2.1.3",
180 | "source": {
181 | "type": "git",
182 | "url": "https://github.com/jquery/jquery.git",
183 | "reference": "8f2a9d9272d6ed7f32d3a484740ab342c02541e0"
184 | },
185 | "dist": {
186 | "type": "zip",
187 | "url": "https://api.github.com/repos/jquery/jquery/zipball/8f2a9d9272d6ed7f32d3a484740ab342c02541e0",
188 | "reference": "8f2a9d9272d6ed7f32d3a484740ab342c02541e0",
189 | "shasum": ""
190 | },
191 | "require-dev": {
192 | "bower-asset/qunit": "1.14.0",
193 | "bower-asset/requirejs": "2.1.10",
194 | "bower-asset/sinon": "1.8.1",
195 | "bower-asset/sizzle": "2.1.1-patch2"
196 | },
197 | "type": "bower-asset-library",
198 | "extra": {
199 | "bower-asset-main": "dist/jquery.js",
200 | "bower-asset-ignore": [
201 | "**/.*",
202 | "build",
203 | "speed",
204 | "test",
205 | "*.md",
206 | "AUTHORS.txt",
207 | "Gruntfile.js",
208 | "package.json"
209 | ]
210 | },
211 | "license": [
212 | "MIT"
213 | ],
214 | "keywords": [
215 | "javascript",
216 | "jquery",
217 | "library"
218 | ]
219 | },
220 | {
221 | "name": "bower-asset/jquery.inputmask",
222 | "version": "3.1.62",
223 | "source": {
224 | "type": "git",
225 | "url": "https://github.com/RobinHerbots/jquery.inputmask.git",
226 | "reference": "da1a274cefa18a52a0519ac7ffe8e8d31e950eae"
227 | },
228 | "dist": {
229 | "type": "zip",
230 | "url": "https://api.github.com/repos/RobinHerbots/jquery.inputmask/zipball/da1a274cefa18a52a0519ac7ffe8e8d31e950eae",
231 | "reference": "da1a274cefa18a52a0519ac7ffe8e8d31e950eae",
232 | "shasum": ""
233 | },
234 | "require": {
235 | "bower-asset/jquery": ">=1.7"
236 | },
237 | "type": "bower-asset-library",
238 | "extra": {
239 | "bower-asset-main": [
240 | "./dist/inputmask/jquery.inputmask.js",
241 | "./dist/inputmask/jquery.inputmask.extensions.js",
242 | "./dist/inputmask/jquery.inputmask.date.extensions.js",
243 | "./dist/inputmask/jquery.inputmask.numeric.extensions.js",
244 | "./dist/inputmask/jquery.inputmask.phone.extensions.js",
245 | "./dist/inputmask/jquery.inputmask.regex.extensions.js"
246 | ],
247 | "bower-asset-ignore": [
248 | "**/.*",
249 | "qunit/",
250 | "nuget/",
251 | "tools/",
252 | "js/",
253 | "*.md",
254 | "build.properties",
255 | "build.xml",
256 | "jquery.inputmask.jquery.json"
257 | ]
258 | },
259 | "license": [
260 | "http://opensource.org/licenses/mit-license.php"
261 | ],
262 | "description": "jquery.inputmask is a jquery plugin which create an input mask.",
263 | "keywords": [
264 | "form",
265 | "input",
266 | "inputmask",
267 | "jquery",
268 | "mask",
269 | "plugins"
270 | ]
271 | },
272 | {
273 | "name": "bower-asset/punycode",
274 | "version": "v1.3.2",
275 | "source": {
276 | "type": "git",
277 | "url": "https://github.com/bestiejs/punycode.js.git",
278 | "reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3"
279 | },
280 | "dist": {
281 | "type": "zip",
282 | "url": "https://api.github.com/repos/bestiejs/punycode.js/zipball/38c8d3131a82567bfef18da09f7f4db68c84f8a3",
283 | "reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3",
284 | "shasum": ""
285 | },
286 | "type": "bower-asset-library",
287 | "extra": {
288 | "bower-asset-main": "punycode.js",
289 | "bower-asset-ignore": [
290 | "coverage",
291 | "tests",
292 | ".*",
293 | "component.json",
294 | "Gruntfile.js",
295 | "node_modules",
296 | "package.json"
297 | ]
298 | }
299 | },
300 | {
301 | "name": "bower-asset/yii2-pjax",
302 | "version": "v2.0.4",
303 | "source": {
304 | "type": "git",
305 | "url": "https://github.com/yiisoft/jquery-pjax.git",
306 | "reference": "3f20897307cca046fca5323b318475ae9dac0ca0"
307 | },
308 | "dist": {
309 | "type": "zip",
310 | "url": "https://api.github.com/repos/yiisoft/jquery-pjax/zipball/3f20897307cca046fca5323b318475ae9dac0ca0",
311 | "reference": "3f20897307cca046fca5323b318475ae9dac0ca0",
312 | "shasum": ""
313 | },
314 | "require": {
315 | "bower-asset/jquery": ">=1.8"
316 | },
317 | "type": "bower-asset-library",
318 | "extra": {
319 | "bower-asset-main": "./jquery.pjax.js",
320 | "bower-asset-ignore": [
321 | ".travis.yml",
322 | "Gemfile",
323 | "Gemfile.lock",
324 | "vendor/",
325 | "script/",
326 | "test/"
327 | ]
328 | },
329 | "license": [
330 | "MIT"
331 | ]
332 | },
333 | {
334 | "name": "cebe/markdown",
335 | "version": "1.0.2",
336 | "source": {
337 | "type": "git",
338 | "url": "https://github.com/cebe/markdown.git",
339 | "reference": "f681fee8303310415b746f3758eeda0a7ad08bda"
340 | },
341 | "dist": {
342 | "type": "zip",
343 | "url": "https://api.github.com/repos/cebe/markdown/zipball/f681fee8303310415b746f3758eeda0a7ad08bda",
344 | "reference": "f681fee8303310415b746f3758eeda0a7ad08bda",
345 | "shasum": ""
346 | },
347 | "require": {
348 | "lib-pcre": "*",
349 | "php": ">=5.4.0"
350 | },
351 | "require-dev": {
352 | "cebe/indent": "*",
353 | "facebook/xhprof": "*@dev",
354 | "phpunit/phpunit": "3.7.*"
355 | },
356 | "bin": [
357 | "bin/markdown"
358 | ],
359 | "type": "library",
360 | "extra": {
361 | "branch-alias": {
362 | "dev-master": "1.0.x-dev"
363 | }
364 | },
365 | "autoload": {
366 | "psr-4": {
367 | "cebe\\markdown\\": ""
368 | }
369 | },
370 | "notification-url": "https://packagist.org/downloads/",
371 | "license": [
372 | "MIT"
373 | ],
374 | "authors": [
375 | {
376 | "name": "Carsten Brandt",
377 | "email": "mail@cebe.cc",
378 | "homepage": "http://cebe.cc/",
379 | "role": "Creator"
380 | }
381 | ],
382 | "description": "A super fast, highly extensible markdown parser for PHP",
383 | "homepage": "https://github.com/cebe/markdown#readme",
384 | "keywords": [
385 | "extensible",
386 | "fast",
387 | "gfm",
388 | "markdown",
389 | "markdown-extra"
390 | ],
391 | "time": "2015-03-06 05:21:16"
392 | },
393 | {
394 | "name": "ezyang/htmlpurifier",
395 | "version": "v4.6.0",
396 | "source": {
397 | "type": "git",
398 | "url": "https://github.com/ezyang/htmlpurifier.git",
399 | "reference": "6f389f0f25b90d0b495308efcfa073981177f0fd"
400 | },
401 | "dist": {
402 | "type": "zip",
403 | "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/6f389f0f25b90d0b495308efcfa073981177f0fd",
404 | "reference": "6f389f0f25b90d0b495308efcfa073981177f0fd",
405 | "shasum": ""
406 | },
407 | "require": {
408 | "php": ">=5.2"
409 | },
410 | "type": "library",
411 | "autoload": {
412 | "psr-0": {
413 | "HTMLPurifier": "library/"
414 | },
415 | "files": [
416 | "library/HTMLPurifier.composer.php"
417 | ]
418 | },
419 | "notification-url": "https://packagist.org/downloads/",
420 | "license": [
421 | "LGPL"
422 | ],
423 | "authors": [
424 | {
425 | "name": "Edward Z. Yang",
426 | "email": "admin@htmlpurifier.org",
427 | "homepage": "http://ezyang.com"
428 | }
429 | ],
430 | "description": "Standards compliant HTML filter written in PHP",
431 | "homepage": "http://htmlpurifier.org/",
432 | "keywords": [
433 | "html"
434 | ],
435 | "time": "2013-11-30 08:25:19"
436 | },
437 | {
438 | "name": "swiftmailer/swiftmailer",
439 | "version": "v5.4.0",
440 | "source": {
441 | "type": "git",
442 | "url": "https://github.com/swiftmailer/swiftmailer.git",
443 | "reference": "31454f258f10329ae7c48763eb898a75c39e0a9f"
444 | },
445 | "dist": {
446 | "type": "zip",
447 | "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/31454f258f10329ae7c48763eb898a75c39e0a9f",
448 | "reference": "31454f258f10329ae7c48763eb898a75c39e0a9f",
449 | "shasum": ""
450 | },
451 | "require": {
452 | "php": ">=5.3.3"
453 | },
454 | "require-dev": {
455 | "mockery/mockery": "~0.9.1"
456 | },
457 | "type": "library",
458 | "extra": {
459 | "branch-alias": {
460 | "dev-master": "5.4-dev"
461 | }
462 | },
463 | "autoload": {
464 | "files": [
465 | "lib/swift_required.php"
466 | ]
467 | },
468 | "notification-url": "https://packagist.org/downloads/",
469 | "license": [
470 | "MIT"
471 | ],
472 | "authors": [
473 | {
474 | "name": "Chris Corbyn"
475 | },
476 | {
477 | "name": "Fabien Potencier",
478 | "email": "fabien@symfony.com"
479 | }
480 | ],
481 | "description": "Swiftmailer, free feature-rich PHP mailer",
482 | "homepage": "http://swiftmailer.org",
483 | "keywords": [
484 | "mail",
485 | "mailer"
486 | ],
487 | "time": "2015-03-14 06:06:39"
488 | },
489 | {
490 | "name": "yiisoft/yii2",
491 | "version": "2.0.3",
492 | "source": {
493 | "type": "git",
494 | "url": "https://github.com/yiisoft/yii2-framework.git",
495 | "reference": "85b773a384f3894d558905cb13522bb338c99dba"
496 | },
497 | "dist": {
498 | "type": "zip",
499 | "url": "https://api.github.com/repos/yiisoft/yii2-framework/zipball/85b773a384f3894d558905cb13522bb338c99dba",
500 | "reference": "85b773a384f3894d558905cb13522bb338c99dba",
501 | "shasum": ""
502 | },
503 | "require": {
504 | "bower-asset/jquery": "2.1.*@stable | 1.11.*@stable",
505 | "bower-asset/jquery.inputmask": "3.1.*",
506 | "bower-asset/punycode": "1.3.*",
507 | "bower-asset/yii2-pjax": ">=2.0.1",
508 | "cebe/markdown": "~1.0.0",
509 | "ext-mbstring": "*",
510 | "ezyang/htmlpurifier": "4.6.*",
511 | "lib-pcre": "*",
512 | "php": ">=5.4.0",
513 | "yiisoft/yii2-composer": "*"
514 | },
515 | "bin": [
516 | "yii"
517 | ],
518 | "type": "library",
519 | "extra": {
520 | "branch-alias": {
521 | "dev-master": "2.0.x-dev"
522 | }
523 | },
524 | "autoload": {
525 | "psr-4": {
526 | "yii\\": ""
527 | }
528 | },
529 | "notification-url": "https://packagist.org/downloads/",
530 | "license": [
531 | "BSD-3-Clause"
532 | ],
533 | "authors": [
534 | {
535 | "name": "Qiang Xue",
536 | "email": "qiang.xue@gmail.com",
537 | "homepage": "http://www.yiiframework.com/",
538 | "role": "Founder and project lead"
539 | },
540 | {
541 | "name": "Alexander Makarov",
542 | "email": "sam@rmcreative.ru",
543 | "homepage": "http://rmcreative.ru/",
544 | "role": "Core framework development"
545 | },
546 | {
547 | "name": "Maurizio Domba",
548 | "homepage": "http://mdomba.info/",
549 | "role": "Core framework development"
550 | },
551 | {
552 | "name": "Carsten Brandt",
553 | "email": "mail@cebe.cc",
554 | "homepage": "http://cebe.cc/",
555 | "role": "Core framework development"
556 | },
557 | {
558 | "name": "Timur Ruziev",
559 | "email": "resurtm@gmail.com",
560 | "homepage": "http://resurtm.com/",
561 | "role": "Core framework development"
562 | },
563 | {
564 | "name": "Paul Klimov",
565 | "email": "klimov.paul@gmail.com",
566 | "role": "Core framework development"
567 | }
568 | ],
569 | "description": "Yii PHP Framework Version 2",
570 | "homepage": "http://www.yiiframework.com/",
571 | "keywords": [
572 | "framework",
573 | "yii2"
574 | ],
575 | "time": "2015-03-01 06:22:44"
576 | },
577 | {
578 | "name": "yiisoft/yii2-bootstrap",
579 | "version": "2.0.3",
580 | "source": {
581 | "type": "git",
582 | "url": "https://github.com/yiisoft/yii2-bootstrap.git",
583 | "reference": "d4bd9c5f97ea891ebbfaf276d3083d85e27fbcb6"
584 | },
585 | "dist": {
586 | "type": "zip",
587 | "url": "https://api.github.com/repos/yiisoft/yii2-bootstrap/zipball/d4bd9c5f97ea891ebbfaf276d3083d85e27fbcb6",
588 | "reference": "d4bd9c5f97ea891ebbfaf276d3083d85e27fbcb6",
589 | "shasum": ""
590 | },
591 | "require": {
592 | "bower-asset/bootstrap": "3.3.* | 3.2.* | 3.1.*",
593 | "yiisoft/yii2": "*"
594 | },
595 | "type": "yii2-extension",
596 | "extra": {
597 | "branch-alias": {
598 | "dev-master": "2.0.x-dev"
599 | }
600 | },
601 | "autoload": {
602 | "psr-4": {
603 | "yii\\bootstrap\\": ""
604 | }
605 | },
606 | "notification-url": "https://packagist.org/downloads/",
607 | "license": [
608 | "BSD-3-Clause"
609 | ],
610 | "authors": [
611 | {
612 | "name": "Qiang Xue",
613 | "email": "qiang.xue@gmail.com"
614 | }
615 | ],
616 | "description": "The Twitter Bootstrap extension for the Yii framework",
617 | "keywords": [
618 | "bootstrap",
619 | "yii2"
620 | ],
621 | "time": "2015-03-01 06:22:44"
622 | },
623 | {
624 | "name": "yiisoft/yii2-composer",
625 | "version": "2.0.3",
626 | "source": {
627 | "type": "git",
628 | "url": "https://github.com/yiisoft/yii2-composer.git",
629 | "reference": "ca8d23707ae47d20b0454e4b135c156f6da6d7be"
630 | },
631 | "dist": {
632 | "type": "zip",
633 | "url": "https://api.github.com/repos/yiisoft/yii2-composer/zipball/ca8d23707ae47d20b0454e4b135c156f6da6d7be",
634 | "reference": "ca8d23707ae47d20b0454e4b135c156f6da6d7be",
635 | "shasum": ""
636 | },
637 | "require": {
638 | "composer-plugin-api": "1.0.0"
639 | },
640 | "type": "composer-plugin",
641 | "extra": {
642 | "class": "yii\\composer\\Plugin",
643 | "branch-alias": {
644 | "dev-master": "2.0.x-dev"
645 | }
646 | },
647 | "autoload": {
648 | "psr-4": {
649 | "yii\\composer\\": ""
650 | }
651 | },
652 | "notification-url": "https://packagist.org/downloads/",
653 | "license": [
654 | "BSD-3-Clause"
655 | ],
656 | "authors": [
657 | {
658 | "name": "Qiang Xue",
659 | "email": "qiang.xue@gmail.com"
660 | }
661 | ],
662 | "description": "The composer plugin for Yii extension installer",
663 | "keywords": [
664 | "composer",
665 | "extension installer",
666 | "yii2"
667 | ],
668 | "time": "2015-03-01 06:22:44"
669 | },
670 | {
671 | "name": "yiisoft/yii2-swiftmailer",
672 | "version": "2.0.3",
673 | "source": {
674 | "type": "git",
675 | "url": "https://github.com/yiisoft/yii2-swiftmailer.git",
676 | "reference": "cb5f0a70d871b409bef7333fc3e0d262fb57eb5c"
677 | },
678 | "dist": {
679 | "type": "zip",
680 | "url": "https://api.github.com/repos/yiisoft/yii2-swiftmailer/zipball/cb5f0a70d871b409bef7333fc3e0d262fb57eb5c",
681 | "reference": "cb5f0a70d871b409bef7333fc3e0d262fb57eb5c",
682 | "shasum": ""
683 | },
684 | "require": {
685 | "swiftmailer/swiftmailer": "*",
686 | "yiisoft/yii2": "*"
687 | },
688 | "type": "yii2-extension",
689 | "extra": {
690 | "branch-alias": {
691 | "dev-master": "2.0.x-dev"
692 | }
693 | },
694 | "autoload": {
695 | "psr-4": {
696 | "yii\\swiftmailer\\": ""
697 | }
698 | },
699 | "notification-url": "https://packagist.org/downloads/",
700 | "license": [
701 | "BSD-3-Clause"
702 | ],
703 | "authors": [
704 | {
705 | "name": "Paul Klimov",
706 | "email": "klimov.paul@gmail.com"
707 | }
708 | ],
709 | "description": "The SwiftMailer integration for the Yii framework",
710 | "keywords": [
711 | "email",
712 | "mail",
713 | "mailer",
714 | "swift",
715 | "swiftmailer",
716 | "yii2"
717 | ],
718 | "time": "2015-03-01 06:22:44"
719 | }
720 | ],
721 | "packages-dev": [
722 | {
723 | "name": "bower-asset/typeahead.js",
724 | "version": "v0.10.5",
725 | "source": {
726 | "type": "git",
727 | "url": "https://github.com/twitter/typeahead.js.git",
728 | "reference": "5f198b87d1af845da502ea9df93a5e84801ce742"
729 | },
730 | "dist": {
731 | "type": "zip",
732 | "url": "https://api.github.com/repos/twitter/typeahead.js/zipball/5f198b87d1af845da502ea9df93a5e84801ce742",
733 | "reference": "5f198b87d1af845da502ea9df93a5e84801ce742",
734 | "shasum": ""
735 | },
736 | "require": {
737 | "bower-asset/jquery": ">=1.7"
738 | },
739 | "require-dev": {
740 | "bower-asset/jasmine-ajax": ">=1.3.1,<1.4",
741 | "bower-asset/jasmine-jquery": ">=1.5.2,<1.6",
742 | "bower-asset/jquery": ">=1.7,<1.8"
743 | },
744 | "type": "bower-asset-library",
745 | "extra": {
746 | "bower-asset-main": "dist/typeahead.bundle.js"
747 | }
748 | },
749 | {
750 | "name": "fzaninotto/faker",
751 | "version": "v1.4.0",
752 | "source": {
753 | "type": "git",
754 | "url": "https://github.com/fzaninotto/Faker.git",
755 | "reference": "010c7efedd88bf31141a02719f51fb44c732d5a0"
756 | },
757 | "dist": {
758 | "type": "zip",
759 | "url": "https://api.github.com/repos/fzaninotto/Faker/zipball/010c7efedd88bf31141a02719f51fb44c732d5a0",
760 | "reference": "010c7efedd88bf31141a02719f51fb44c732d5a0",
761 | "shasum": ""
762 | },
763 | "require": {
764 | "php": ">=5.3.3"
765 | },
766 | "require-dev": {
767 | "phpunit/phpunit": "~4.0",
768 | "squizlabs/php_codesniffer": "~1.5"
769 | },
770 | "type": "library",
771 | "extra": {
772 | "branch-alias": []
773 | },
774 | "autoload": {
775 | "psr-0": {
776 | "Faker": "src/",
777 | "Faker\\PHPUnit": "test/"
778 | }
779 | },
780 | "notification-url": "https://packagist.org/downloads/",
781 | "license": [
782 | "MIT"
783 | ],
784 | "authors": [
785 | {
786 | "name": "François Zaninotto"
787 | }
788 | ],
789 | "description": "Faker is a PHP library that generates fake data for you.",
790 | "keywords": [
791 | "data",
792 | "faker",
793 | "fixtures"
794 | ],
795 | "time": "2014-06-04 14:43:02"
796 | },
797 | {
798 | "name": "phpspec/php-diff",
799 | "version": "v1.0.2",
800 | "source": {
801 | "type": "git",
802 | "url": "https://github.com/phpspec/php-diff.git",
803 | "reference": "30e103d19519fe678ae64a60d77884ef3d71b28a"
804 | },
805 | "dist": {
806 | "type": "zip",
807 | "url": "https://api.github.com/repos/phpspec/php-diff/zipball/30e103d19519fe678ae64a60d77884ef3d71b28a",
808 | "reference": "30e103d19519fe678ae64a60d77884ef3d71b28a",
809 | "shasum": ""
810 | },
811 | "type": "library",
812 | "autoload": {
813 | "psr-0": {
814 | "Diff": "lib/"
815 | }
816 | },
817 | "notification-url": "https://packagist.org/downloads/",
818 | "license": [
819 | "BSD-3-Clause"
820 | ],
821 | "authors": [
822 | {
823 | "name": "Chris Boulton",
824 | "homepage": "http://github.com/chrisboulton",
825 | "role": "Original developer"
826 | }
827 | ],
828 | "description": "A comprehensive library for generating differences between two hashable objects (strings or arrays).",
829 | "time": "2013-11-01 13:02:21"
830 | },
831 | {
832 | "name": "yiisoft/yii2-codeception",
833 | "version": "2.0.3",
834 | "source": {
835 | "type": "git",
836 | "url": "https://github.com/yiisoft/yii2-codeception.git",
837 | "reference": "c2fdee4e7e9846e141ceddeb4386325e921e375a"
838 | },
839 | "dist": {
840 | "type": "zip",
841 | "url": "https://api.github.com/repos/yiisoft/yii2-codeception/zipball/c2fdee4e7e9846e141ceddeb4386325e921e375a",
842 | "reference": "c2fdee4e7e9846e141ceddeb4386325e921e375a",
843 | "shasum": ""
844 | },
845 | "require": {
846 | "yiisoft/yii2": "*"
847 | },
848 | "type": "yii2-extension",
849 | "extra": {
850 | "branch-alias": {
851 | "dev-master": "2.0.x-dev"
852 | }
853 | },
854 | "autoload": {
855 | "psr-4": {
856 | "yii\\codeception\\": ""
857 | }
858 | },
859 | "notification-url": "https://packagist.org/downloads/",
860 | "license": [
861 | "BSD-3-Clause"
862 | ],
863 | "authors": [
864 | {
865 | "name": "Mark Jebri",
866 | "email": "mark.github@yandex.ru"
867 | }
868 | ],
869 | "description": "The Codeception integration for the Yii framework",
870 | "keywords": [
871 | "codeception",
872 | "yii2"
873 | ],
874 | "time": "2015-03-01 06:22:44"
875 | },
876 | {
877 | "name": "yiisoft/yii2-debug",
878 | "version": "2.0.3",
879 | "source": {
880 | "type": "git",
881 | "url": "https://github.com/yiisoft/yii2-debug.git",
882 | "reference": "8a0db5130a9ea3941304dd77cef23d69257e8d48"
883 | },
884 | "dist": {
885 | "type": "zip",
886 | "url": "https://api.github.com/repos/yiisoft/yii2-debug/zipball/8a0db5130a9ea3941304dd77cef23d69257e8d48",
887 | "reference": "8a0db5130a9ea3941304dd77cef23d69257e8d48",
888 | "shasum": ""
889 | },
890 | "require": {
891 | "yiisoft/yii2": "*",
892 | "yiisoft/yii2-bootstrap": "*"
893 | },
894 | "type": "yii2-extension",
895 | "extra": {
896 | "branch-alias": {
897 | "dev-master": "2.0.x-dev"
898 | }
899 | },
900 | "autoload": {
901 | "psr-4": {
902 | "yii\\debug\\": ""
903 | }
904 | },
905 | "notification-url": "https://packagist.org/downloads/",
906 | "license": [
907 | "BSD-3-Clause"
908 | ],
909 | "authors": [
910 | {
911 | "name": "Qiang Xue",
912 | "email": "qiang.xue@gmail.com"
913 | }
914 | ],
915 | "description": "The debugger extension for the Yii framework",
916 | "keywords": [
917 | "debug",
918 | "debugger",
919 | "yii2"
920 | ],
921 | "time": "2015-03-01 06:22:44"
922 | },
923 | {
924 | "name": "yiisoft/yii2-faker",
925 | "version": "2.0.3",
926 | "source": {
927 | "type": "git",
928 | "url": "https://github.com/yiisoft/yii2-faker.git",
929 | "reference": "b88ca69ee226a3610b2c26c026c3203d7ac50f6c"
930 | },
931 | "dist": {
932 | "type": "zip",
933 | "url": "https://api.github.com/repos/yiisoft/yii2-faker/zipball/b88ca69ee226a3610b2c26c026c3203d7ac50f6c",
934 | "reference": "b88ca69ee226a3610b2c26c026c3203d7ac50f6c",
935 | "shasum": ""
936 | },
937 | "require": {
938 | "fzaninotto/faker": "*",
939 | "yiisoft/yii2": "*"
940 | },
941 | "type": "yii2-extension",
942 | "extra": {
943 | "branch-alias": {
944 | "dev-master": "2.0.x-dev"
945 | }
946 | },
947 | "autoload": {
948 | "psr-4": {
949 | "yii\\faker\\": ""
950 | }
951 | },
952 | "notification-url": "https://packagist.org/downloads/",
953 | "license": [
954 | "BSD-3-Clause"
955 | ],
956 | "authors": [
957 | {
958 | "name": "Mark Jebri",
959 | "email": "mark.github@yandex.ru"
960 | }
961 | ],
962 | "description": "Fixture generator. The Faker integration for the Yii framework.",
963 | "keywords": [
964 | "Fixture",
965 | "faker",
966 | "yii2"
967 | ],
968 | "time": "2015-03-01 06:22:44"
969 | },
970 | {
971 | "name": "yiisoft/yii2-gii",
972 | "version": "2.0.3",
973 | "source": {
974 | "type": "git",
975 | "url": "https://github.com/yiisoft/yii2-gii.git",
976 | "reference": "bb79aeafa8e3b89dd25e07ac895b269680e537a8"
977 | },
978 | "dist": {
979 | "type": "zip",
980 | "url": "https://api.github.com/repos/yiisoft/yii2-gii/zipball/bb79aeafa8e3b89dd25e07ac895b269680e537a8",
981 | "reference": "bb79aeafa8e3b89dd25e07ac895b269680e537a8",
982 | "shasum": ""
983 | },
984 | "require": {
985 | "bower-asset/typeahead.js": "0.10.*",
986 | "phpspec/php-diff": ">=1.0.2",
987 | "yiisoft/yii2": "*",
988 | "yiisoft/yii2-bootstrap": "*"
989 | },
990 | "type": "yii2-extension",
991 | "extra": {
992 | "branch-alias": {
993 | "dev-master": "2.0.x-dev"
994 | }
995 | },
996 | "autoload": {
997 | "psr-4": {
998 | "yii\\gii\\": ""
999 | }
1000 | },
1001 | "notification-url": "https://packagist.org/downloads/",
1002 | "license": [
1003 | "BSD-3-Clause"
1004 | ],
1005 | "authors": [
1006 | {
1007 | "name": "Qiang Xue",
1008 | "email": "qiang.xue@gmail.com"
1009 | }
1010 | ],
1011 | "description": "The Gii extension for the Yii framework",
1012 | "keywords": [
1013 | "code generator",
1014 | "gii",
1015 | "yii2"
1016 | ],
1017 | "time": "2015-03-01 06:22:44"
1018 | }
1019 | ],
1020 | "aliases": [],
1021 | "minimum-stability": "stable",
1022 | "stability-flags": [],
1023 | "prefer-stable": false,
1024 | "prefer-lowest": false,
1025 | "platform": {
1026 | "php": ">=5.4.0"
1027 | },
1028 | "platform-dev": []
1029 | }
1030 |
--------------------------------------------------------------------------------
/console/config/.gitignore:
--------------------------------------------------------------------------------
1 | main-local.php
2 | params-local.php
--------------------------------------------------------------------------------
/console/config/bootstrap.php:
--------------------------------------------------------------------------------
1 | 'app-console',
11 | 'basePath' => dirname(__DIR__),
12 | 'bootstrap' => ['log'],
13 | 'controllerNamespace' => 'console\controllers',
14 | 'components' => [
15 | 'log' => [
16 | 'targets' => [
17 | [
18 | 'class' => 'yii\log\FileTarget',
19 | 'levels' => ['error', 'warning'],
20 | ],
21 | ],
22 | ],
23 | ],
24 | 'params' => $params,
25 | ];
26 |
--------------------------------------------------------------------------------
/console/config/params.php:
--------------------------------------------------------------------------------
1 | 'admin@example.com',
4 | ];
5 |
--------------------------------------------------------------------------------
/console/controllers/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neattutorials/angularjs-yii2-part-2-authentication/726353f9a475c61da3a53fce0afe120c841ccf3a/console/controllers/.gitkeep
--------------------------------------------------------------------------------
/console/migrations/m130524_201442_init.php:
--------------------------------------------------------------------------------
1 | db->driverName === 'mysql') {
13 | // http://stackoverflow.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci
14 | $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB';
15 | }
16 |
17 | $this->createTable('{{%user}}', [
18 | 'id' => Schema::TYPE_PK,
19 | 'username' => Schema::TYPE_STRING . ' NOT NULL',
20 | 'auth_key' => Schema::TYPE_STRING . '(32) NOT NULL',
21 | 'password_hash' => Schema::TYPE_STRING . ' NOT NULL',
22 | 'password_reset_token' => Schema::TYPE_STRING,
23 | 'email' => Schema::TYPE_STRING . ' NOT NULL',
24 |
25 | 'status' => Schema::TYPE_SMALLINT . ' NOT NULL DEFAULT 10',
26 | 'created_at' => Schema::TYPE_INTEGER . ' NOT NULL',
27 | 'updated_at' => Schema::TYPE_INTEGER . ' NOT NULL',
28 | ], $tableOptions);
29 |
30 | $user = new User();
31 | $user->username = 'demo';
32 | $user->email = 'demo@example.com';
33 | $user->generateAuthKey();
34 | $user->setPassword('demo');
35 | return $user->save(false);
36 | }
37 |
38 | public function down()
39 | {
40 | $this->dropTable('{{%user}}');
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/console/models/.gitkeep:
--------------------------------------------------------------------------------
1 | *
2 |
--------------------------------------------------------------------------------
/console/runtime/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
--------------------------------------------------------------------------------
/db/users.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neattutorials/angularjs-yii2-part-2-authentication/726353f9a475c61da3a53fce0afe120c841ccf3a/db/users.db
--------------------------------------------------------------------------------
/environments/dev/backend/config/main-local.php:
--------------------------------------------------------------------------------
1 | [
5 | 'request' => [
6 | // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
7 | 'cookieValidationKey' => '',
8 | ],
9 | ],
10 | ];
11 |
12 | if (!YII_ENV_TEST) {
13 | // configuration adjustments for 'dev' environment
14 | $config['bootstrap'][] = 'debug';
15 | $config['modules']['debug'] = 'yii\debug\Module';
16 |
17 | $config['bootstrap'][] = 'gii';
18 | $config['modules']['gii'] = 'yii\gii\Module';
19 | }
20 |
21 | return $config;
22 |
--------------------------------------------------------------------------------
/environments/dev/backend/config/params-local.php:
--------------------------------------------------------------------------------
1 | run();
20 |
--------------------------------------------------------------------------------
/environments/dev/backend/web/index.php:
--------------------------------------------------------------------------------
1 | run();
19 |
--------------------------------------------------------------------------------
/environments/dev/common/config/main-local.php:
--------------------------------------------------------------------------------
1 | [
4 | 'db' => [
5 | 'class' => 'yii\db\Connection',
6 | 'dsn' => 'mysql:host=localhost;dbname=ay',
7 | 'username' => 'root',
8 | 'password' => '',
9 | 'charset' => 'utf8',
10 | ],
11 | 'mailer' => [
12 | 'class' => 'yii\swiftmailer\Mailer',
13 | 'viewPath' => '@common/mail',
14 | // send all mails to a file by default. You have to set
15 | // 'useFileTransport' to false and configure a transport
16 | // for the mailer to send real emails.
17 | 'useFileTransport' => true,
18 | ],
19 | ],
20 | ];
21 |
--------------------------------------------------------------------------------
/environments/dev/common/config/params-local.php:
--------------------------------------------------------------------------------
1 | ['gii'],
4 | 'modules' => [
5 | 'gii' => 'yii\gii\Module',
6 | ],
7 | ];
8 |
--------------------------------------------------------------------------------
/environments/dev/console/config/params-local.php:
--------------------------------------------------------------------------------
1 | [
5 | 'request' => [
6 | // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
7 | 'cookieValidationKey' => '',
8 | ],
9 | ],
10 | ];
11 |
12 | if (!YII_ENV_TEST) {
13 | // configuration adjustments for 'dev' environment
14 | $config['bootstrap'][] = 'debug';
15 | $config['modules']['debug'] = 'yii\debug\Module';
16 |
17 | $config['bootstrap'][] = 'gii';
18 | $config['modules']['gii'] = 'yii\gii\Module';
19 | }
20 |
21 | return $config;
22 |
--------------------------------------------------------------------------------
/environments/dev/frontend/config/params-local.php:
--------------------------------------------------------------------------------
1 | run();
19 |
--------------------------------------------------------------------------------
/environments/dev/frontend/web/index.php:
--------------------------------------------------------------------------------
1 | run();
19 |
--------------------------------------------------------------------------------
/environments/dev/yii:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | run();
32 | exit($exitCode);
33 |
--------------------------------------------------------------------------------
/environments/index.php:
--------------------------------------------------------------------------------
1 | [
11 | * 'path' => 'directory storing the local files',
12 | * 'setWritable' => [
13 | * // list of directories that should be set writable
14 | * ],
15 | * 'setExecutable' => [
16 | * // list of files that should be set executable
17 | * ],
18 | * 'setCookieValidationKey' => [
19 | * // list of config files that need to be inserted with automatically generated cookie validation keys
20 | * ],
21 | * 'createSymlink' => [
22 | * // list of symlinks to be created. Keys are symlinks, and values are the targets.
23 | * ],
24 | * ],
25 | * ];
26 | * ```
27 | */
28 | return [
29 | 'Development' => [
30 | 'path' => 'dev',
31 | 'setWritable' => [
32 | 'backend/runtime',
33 | 'backend/web/assets',
34 | 'frontend/runtime',
35 | 'frontend/web/assets',
36 | ],
37 | 'setExecutable' => [
38 | 'yii',
39 | ],
40 | 'setCookieValidationKey' => [
41 | 'backend/config/main-local.php',
42 | 'frontend/config/main-local.php',
43 | ],
44 | ],
45 | 'Production' => [
46 | 'path' => 'prod',
47 | 'setWritable' => [
48 | 'backend/runtime',
49 | 'backend/web/assets',
50 | 'frontend/runtime',
51 | 'frontend/web/assets',
52 | ],
53 | 'setExecutable' => [
54 | 'yii',
55 | ],
56 | 'setCookieValidationKey' => [
57 | 'backend/config/main-local.php',
58 | 'frontend/config/main-local.php',
59 | ],
60 | ],
61 | ];
62 |
--------------------------------------------------------------------------------
/environments/prod/backend/config/main-local.php:
--------------------------------------------------------------------------------
1 | [
4 | 'request' => [
5 | // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
6 | 'cookieValidationKey' => '',
7 | ],
8 | ],
9 | ];
10 |
--------------------------------------------------------------------------------
/environments/prod/backend/config/params-local.php:
--------------------------------------------------------------------------------
1 | run();
19 |
--------------------------------------------------------------------------------
/environments/prod/common/config/main-local.php:
--------------------------------------------------------------------------------
1 | [
4 | 'db' => [
5 | 'class' => 'yii\db\Connection',
6 | 'dsn' => 'mysql:host=localhost;dbname=yii2advanced',
7 | 'username' => 'root',
8 | 'password' => '',
9 | 'charset' => 'utf8',
10 | ],
11 | 'mailer' => [
12 | 'class' => 'yii\swiftmailer\Mailer',
13 | 'viewPath' => '@common/mail',
14 | ],
15 | ],
16 | ];
17 |
--------------------------------------------------------------------------------
/environments/prod/common/config/params-local.php:
--------------------------------------------------------------------------------
1 | [
4 | 'request' => [
5 | // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
6 | 'cookieValidationKey' => '',
7 | ],
8 | ],
9 | ];
10 |
--------------------------------------------------------------------------------
/environments/prod/frontend/config/params-local.php:
--------------------------------------------------------------------------------
1 | run();
19 |
--------------------------------------------------------------------------------
/environments/prod/yii:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | run();
32 | exit($exitCode);
33 |
--------------------------------------------------------------------------------
/frontend/assets/AngularAsset.php:
--------------------------------------------------------------------------------
1 | View::POS_HEAD,
17 | ];
18 | }
19 |
--------------------------------------------------------------------------------
/frontend/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 | 'js/app.js',
25 | 'js/controllers.js',
26 | ];
27 | public $depends = [
28 | 'yii\web\YiiAsset',
29 | 'yii\bootstrap\BootstrapAsset',
30 | 'frontend\assets\AngularAsset',
31 | ];
32 | }
33 |
--------------------------------------------------------------------------------
/frontend/config/.gitignore:
--------------------------------------------------------------------------------
1 | main-local.php
2 | params-local.php
--------------------------------------------------------------------------------
/frontend/config/bootstrap.php:
--------------------------------------------------------------------------------
1 | 'app-frontend',
11 | 'basePath' => dirname(__DIR__),
12 | 'bootstrap' => ['log'],
13 | 'controllerNamespace' => 'frontend\controllers',
14 | 'components' => [
15 | 'user' => [
16 | 'identityClass' => 'common\models\User',
17 | 'enableSession' => false,
18 | 'loginUrl' => null,
19 |
20 | ],
21 | 'request' => [
22 | 'class' => '\yii\web\Request',
23 | 'enableCookieValidation' => false,
24 | 'parsers' => [
25 | 'application/json' => 'yii\web\JsonParser',
26 | ],
27 | ],
28 | 'urlManager' => [
29 | 'enablePrettyUrl' => true,
30 | 'showScriptName' => false,
31 | ],
32 | 'log' => [
33 | 'traceLevel' => YII_DEBUG ? 3 : 0,
34 | 'targets' => [
35 | [
36 | 'class' => 'yii\log\FileTarget',
37 | 'levels' => ['error', 'warning'],
38 | ],
39 | ],
40 | ],
41 | 'errorHandler' => [
42 | 'errorAction' => 'site/error',
43 | ],
44 | ],
45 | 'params' => $params,
46 | ];
47 |
--------------------------------------------------------------------------------
/frontend/config/params.php:
--------------------------------------------------------------------------------
1 | 'admin@example.com',
4 | ];
5 |
--------------------------------------------------------------------------------
/frontend/controllers/ApiController.php:
--------------------------------------------------------------------------------
1 | HttpBearerAuth::className(),
26 | 'only' => ['dashboard'],
27 | ];
28 | $behaviors['contentNegotiator'] = [
29 | 'class' => ContentNegotiator::className(),
30 | 'formats' => [
31 | 'application/json' => Response::FORMAT_JSON,
32 | ],
33 | ];
34 | $behaviors['access'] = [
35 | 'class' => AccessControl::className(),
36 | 'only' => ['dashboard'],
37 | 'rules' => [
38 | [
39 | 'actions' => ['dashboard'],
40 | 'allow' => true,
41 | 'roles' => ['@'],
42 | ],
43 | ],
44 | ];
45 | return $behaviors;
46 | }
47 |
48 | public function actionLogin()
49 | {
50 | $model = new LoginForm();
51 |
52 | if ($model->load(Yii::$app->getRequest()->getBodyParams(), '') && $model->login()) {
53 | return ['access_token' => Yii::$app->user->identity->getAuthKey()];
54 | } else {
55 | $model->validate();
56 | return $model;
57 | }
58 | }
59 |
60 | public function actionDashboard()
61 | {
62 | $response = [
63 | 'username' => Yii::$app->user->identity->username,
64 | 'access_token' => Yii::$app->user->identity->getAuthKey(),
65 | ];
66 |
67 | return $response;
68 | }
69 |
70 | public function actionContact()
71 | {
72 | $model = new ContactForm();
73 | if ($model->load(Yii::$app->getRequest()->getBodyParams(), '') && $model->validate()) {
74 | if ($model->sendEmail(Yii::$app->params['adminEmail'])) {
75 | $response = [
76 | 'flash' => [
77 | 'class' => 'success',
78 | 'message' => 'Thank you for contacting us. We will respond to you as soon as possible.',
79 | ]
80 | ];
81 | } else {
82 | $response = [
83 | 'flash' => [
84 | 'class' => 'error',
85 | 'message' => 'There was an error sending email.',
86 | ]
87 | ];
88 | }
89 | return $response;
90 | } else {
91 | $model->validate();
92 | return $model;
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/frontend/controllers/SiteController.php:
--------------------------------------------------------------------------------
1 | [
19 | 'class' => 'yii\web\ErrorAction',
20 | ],
21 | 'captcha' => [
22 | 'class' => 'yii\captcha\CaptchaAction',
23 | 'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
24 | ],
25 | ];
26 | }
27 |
28 | public function actionIndex()
29 | {
30 | return $this->renderContent(null);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/frontend/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 | *
47 | * @param string $email the target email address
48 | * @return boolean whether the email was sent
49 | */
50 | public function sendEmail($email)
51 | {
52 | return 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 | }
60 |
--------------------------------------------------------------------------------
/frontend/models/PasswordResetRequestForm.php:
--------------------------------------------------------------------------------
1 | 'trim'],
21 | ['email', 'required'],
22 | ['email', 'email'],
23 | ['email', 'exist',
24 | 'targetClass' => '\common\models\User',
25 | 'filter' => ['status' => User::STATUS_ACTIVE],
26 | 'message' => 'There is no user with such email.'
27 | ],
28 | ];
29 | }
30 |
31 | /**
32 | * Sends an email with a link, for resetting the password.
33 | *
34 | * @return boolean whether the email was send
35 | */
36 | public function sendEmail()
37 | {
38 | /* @var $user User */
39 | $user = User::findOne([
40 | 'status' => User::STATUS_ACTIVE,
41 | 'email' => $this->email,
42 | ]);
43 |
44 | if ($user) {
45 | if (!User::isPasswordResetTokenValid($user->password_reset_token)) {
46 | $user->generatePasswordResetToken();
47 | }
48 |
49 | if ($user->save()) {
50 | return \Yii::$app->mailer->compose(['html' => 'passwordResetToken-html', 'text' => 'passwordResetToken-text'], ['user' => $user])
51 | ->setFrom([\Yii::$app->params['supportEmail'] => \Yii::$app->name . ' robot'])
52 | ->setTo($this->email)
53 | ->setSubject('Password reset for ' . \Yii::$app->name)
54 | ->send();
55 | }
56 | }
57 |
58 | return false;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/frontend/models/ResetPasswordForm.php:
--------------------------------------------------------------------------------
1 | _user = User::findByPasswordResetToken($token);
35 | if (!$this->_user) {
36 | throw new InvalidParamException('Wrong password reset token.');
37 | }
38 | parent::__construct($config);
39 | }
40 |
41 | /**
42 | * @inheritdoc
43 | */
44 | public function rules()
45 | {
46 | return [
47 | ['password', 'required'],
48 | ['password', 'string', 'min' => 6],
49 | ];
50 | }
51 |
52 | /**
53 | * Resets password.
54 | *
55 | * @return boolean if password was reset.
56 | */
57 | public function resetPassword()
58 | {
59 | $user = $this->_user;
60 | $user->setPassword($this->password);
61 | $user->removePasswordResetToken();
62 |
63 | return $user->save();
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/frontend/models/SignupForm.php:
--------------------------------------------------------------------------------
1 | 'trim'],
24 | ['username', 'required'],
25 | ['username', 'unique', 'targetClass' => '\common\models\User', 'message' => 'This username has already been taken.'],
26 | ['username', 'string', 'min' => 2, 'max' => 255],
27 |
28 | ['email', 'filter', 'filter' => 'trim'],
29 | ['email', 'required'],
30 | ['email', 'email'],
31 | ['email', 'unique', 'targetClass' => '\common\models\User', 'message' => 'This email address has already been taken.'],
32 |
33 | ['password', 'required'],
34 | ['password', 'string', 'min' => 6],
35 | ];
36 | }
37 |
38 | /**
39 | * Signs user up.
40 | *
41 | * @return User|null the saved model or null if saving fails
42 | */
43 | public function signup()
44 | {
45 | if ($this->validate()) {
46 | $user = new User();
47 | $user->username = $this->username;
48 | $user->email = $this->email;
49 | $user->setPassword($this->password);
50 | $user->generateAuthKey();
51 | if ($user->save()) {
52 | return $user;
53 | }
54 | }
55 |
56 | return null;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/frontend/runtime/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
--------------------------------------------------------------------------------
/frontend/views/layouts/main.php:
--------------------------------------------------------------------------------
1 |
8 | beginPage() ?>
9 |
10 |
11 |
12 |
13 |
14 | My Angular Yii Application
15 | head() ?>
16 |
17 |
18 |
19 |
20 |
21 |
22 | beginBody() ?>
23 |
24 |
25 |
57 |
58 |
59 |
63 |
64 |
65 |
66 |
72 |
73 | endBody() ?>
74 |
75 |
76 | endPage() ?>
--------------------------------------------------------------------------------
/frontend/views/site/error.php:
--------------------------------------------------------------------------------
1 | title = $name;
11 | ?>
12 |
13 |
14 |
= Html::encode($this->title) ?>
15 |
16 |
17 | = nl2br(Html::encode($message)) ?>
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 |
--------------------------------------------------------------------------------
/frontend/web/.gitignore:
--------------------------------------------------------------------------------
1 | /index.php
2 | /index-test.php
3 |
--------------------------------------------------------------------------------
/frontend/web/.htaccess:
--------------------------------------------------------------------------------
1 | RewriteEngine on
2 |
3 | RewriteCond %{REQUEST_FILENAME} !-f
4 | RewriteCond %{REQUEST_FILENAME} !-d
5 |
6 | RewriteRule . index.php
--------------------------------------------------------------------------------
/frontend/web/assets/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/frontend/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 |
--------------------------------------------------------------------------------
/frontend/web/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neattutorials/angularjs-yii2-part-2-authentication/726353f9a475c61da3a53fce0afe120c841ccf3a/frontend/web/favicon.ico
--------------------------------------------------------------------------------
/frontend/web/js/app.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var app = angular.module('app', [
4 | 'ngRoute', //$routeProvider
5 | 'mgcrea.ngStrap', //bs-navbar, data-match-route directives
6 | 'controllers' //Our module frontend/web/js/controllers.js
7 | ]);
8 |
9 | app.config(['$routeProvider', '$httpProvider',
10 | function($routeProvider, $httpProvider) {
11 | $routeProvider.
12 | when('/', {
13 | templateUrl: 'partials/index.html'
14 | }).
15 | when('/about', {
16 | templateUrl: 'partials/about.html'
17 | }).
18 | when('/contact', {
19 | templateUrl: 'partials/contact.html',
20 | controller: 'ContactController'
21 | }).
22 | when('/login', {
23 | templateUrl: 'partials/login.html',
24 | controller: 'LoginController'
25 | }).
26 | when('/dashboard', {
27 | templateUrl: 'partials/dashboard.html',
28 | controller: 'DashboardController'
29 | }).
30 | otherwise({
31 | templateUrl: 'partials/404.html'
32 | });
33 | $httpProvider.interceptors.push('authInterceptor');
34 | }
35 | ]);
36 |
37 | app.factory('authInterceptor', function ($q, $window, $location) {
38 | return {
39 | request: function (config) {
40 | if ($window.sessionStorage.access_token) {
41 | //HttpBearerAuth
42 | config.headers.Authorization = 'Bearer ' + $window.sessionStorage.access_token;
43 | }
44 | return config;
45 | },
46 | responseError: function (rejection) {
47 | if (rejection.status === 401) {
48 | $location.path('/login').replace();
49 | }
50 | return $q.reject(rejection);
51 | }
52 | };
53 | });
--------------------------------------------------------------------------------
/frontend/web/js/controllers.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var controllers = angular.module('controllers', []);
4 |
5 | controllers.controller('MainController', ['$scope', '$location', '$window',
6 | function ($scope, $location, $window) {
7 | $scope.loggedIn = function() {
8 | return Boolean($window.sessionStorage.access_token);
9 | };
10 |
11 | $scope.logout = function () {
12 | delete $window.sessionStorage.access_token;
13 | $location.path('/login').replace();
14 | };
15 | }
16 | ]);
17 |
18 | controllers.controller('ContactController', ['$scope', '$http', '$window',
19 | function($scope, $http, $window) {
20 | $scope.captchaUrl = 'site/captcha';
21 | $scope.contact = function () {
22 | $scope.submitted = true;
23 | $scope.error = {};
24 | $http.post('api/contact', $scope.contactModel).success(
25 | function (data) {
26 | $scope.contactModel = {};
27 | $scope.flash = data.flash;
28 | $window.scrollTo(0,0);
29 | $scope.submitted = false;
30 | $scope.captchaUrl = 'site/captcha' + '?' + new Date().getTime();
31 | }).error(
32 | function (data) {
33 | angular.forEach(data, function (error) {
34 | $scope.error[error.field] = error.message;
35 | });
36 | }
37 | );
38 | };
39 |
40 | $scope.refreshCaptcha = function() {
41 | $http.get('site/captcha?refresh=1').success(function(data) {
42 | $scope.captchaUrl = data.url;
43 | });
44 | };
45 | }]);
46 |
47 | controllers.controller('DashboardController', ['$scope', '$http',
48 | function ($scope, $http) {
49 | $http.get('api/dashboard').success(function (data) {
50 | $scope.dashboard = data;
51 | })
52 | }
53 | ]);
54 |
55 | controllers.controller('LoginController', ['$scope', '$http', '$window', '$location',
56 | function($scope, $http, $window, $location) {
57 | $scope.login = function () {
58 | $scope.submitted = true;
59 | $scope.error = {};
60 | $http.post('api/login', $scope.userModel).success(
61 | function (data) {
62 | $window.sessionStorage.access_token = data.access_token;
63 | $location.path('/dashboard').replace();
64 | }).error(
65 | function (data) {
66 | angular.forEach(data, function (error) {
67 | $scope.error[error.field] = error.message;
68 | });
69 | }
70 | );
71 | };
72 | }
73 | ]);
--------------------------------------------------------------------------------
/frontend/web/partials/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Not Found (#404)
4 |
5 |
6 | Page not found.
7 |
8 |
9 |
10 | The above error occurred while the Web server was processing your request.
11 |
12 |
13 |
14 | Please contact us if you think this is a server error. Thank you.
15 |
16 |
17 |
--------------------------------------------------------------------------------
/frontend/web/partials/about.html:
--------------------------------------------------------------------------------
1 | About
2 |
3 | This is the About page. You may modify the following file to customize its content:
4 |
5 | frontend\web\partials\about.html
--------------------------------------------------------------------------------
/frontend/web/partials/contact.html:
--------------------------------------------------------------------------------
1 |
2 | {{flash.message}}
3 |
4 | Contact
5 |
6 |
7 | If you have business inquiries or other questions, please fill out the following form to contact us. Thank you.
8 |
9 |
10 |
69 |
--------------------------------------------------------------------------------
/frontend/web/partials/dashboard.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Hello {{ dashboard.username }}
4 | Welcome to the secret page.
5 | Your access_token is {{ dashboard.access_token }}
6 |
7 |
--------------------------------------------------------------------------------
/frontend/web/partials/index.html:
--------------------------------------------------------------------------------
1 |
2 |
Congratulations!
3 |
4 |
You have successfully created your Angular/Yii-powered application.
5 |
6 |
Get started with Yii
7 |
8 |
9 |
10 |
11 |
12 |
13 |
Heading
14 |
15 |
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et
16 | dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
17 | ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
18 | fugiat nulla pariatur.
19 |
20 |
Yii Documentation »
21 |
22 |
23 |
Heading
24 |
25 |
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et
26 | dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
27 | ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
28 | fugiat nulla pariatur.
29 |
30 |
Yii Forum »
31 |
32 |
33 |
Heading
34 |
35 |
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et
36 | dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
37 | ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
38 | fugiat nulla pariatur.
39 |
40 |
Yii Extensions »
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/frontend/web/partials/login.html:
--------------------------------------------------------------------------------
1 | Login
2 |
3 | Please fill out the following fields to login:
4 |
5 |
6 |
7 |
8 |
15 |
16 |
23 |
24 |
25 | Login
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/frontend/web/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow:
--------------------------------------------------------------------------------
/init:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 |
11 | *
12 | * @link http://www.yiiframework.com/
13 | * @copyright Copyright (c) 2008 Yii Software LLC
14 | * @license http://www.yiiframework.com/license/
15 | */
16 |
17 | if (!extension_loaded('openssl')) {
18 | die('The OpenSSL PHP extension is required by Yii2.');
19 | }
20 |
21 | $params = getParams();
22 | $root = str_replace('\\', '/', __DIR__);
23 | $envs = require("$root/environments/index.php");
24 | $envNames = array_keys($envs);
25 |
26 | echo "Yii Application Initialization Tool v1.0\n\n";
27 |
28 | $envName = null;
29 | if (empty($params['env']) || $params['env'] === '1') {
30 | echo "Which environment do you want the application to be initialized in?\n\n";
31 | foreach ($envNames as $i => $name) {
32 | echo " [$i] $name\n";
33 | }
34 | echo "\n Your choice [0-" . (count($envs) - 1) . ', or "q" to quit] ';
35 | $answer = trim(fgets(STDIN));
36 |
37 | if (!ctype_digit($answer) || !in_array($answer, range(0, count($envs) - 1))) {
38 | echo "\n Quit initialization.\n";
39 | exit(0);
40 | }
41 |
42 | if (isset($envNames[$answer])) {
43 | $envName = $envNames[$answer];
44 | }
45 | } else {
46 | $envName = $params['env'];
47 | }
48 |
49 | if (!in_array($envName, $envNames)) {
50 | $envsList = implode(', ', $envNames);
51 | echo "\n $envName is not a valid environment. Try one of the following: $envsList. \n";
52 | exit(2);
53 | }
54 |
55 | $env = $envs[$envName];
56 |
57 | if (empty($params['env'])) {
58 | echo "\n Initialize the application under '{$envNames[$answer]}' environment? [yes|no] ";
59 | $answer = trim(fgets(STDIN));
60 | if (strncasecmp($answer, 'y', 1)) {
61 | echo "\n Quit initialization.\n";
62 | exit(0);
63 | }
64 | }
65 |
66 | echo "\n Start initialization ...\n\n";
67 | $files = getFileList("$root/environments/{$env['path']}");
68 | $all = false;
69 | foreach ($files as $file) {
70 | if (!copyFile($root, "environments/{$env['path']}/$file", $file, $all, $params)) {
71 | break;
72 | }
73 | }
74 |
75 | $callbacks = ['setCookieValidationKey', 'setWritable', 'setExecutable'];
76 | foreach ($callbacks as $callback) {
77 | if (!empty($env[$callback])) {
78 | $callback($root, $env[$callback]);
79 | }
80 | }
81 |
82 | echo "\n ... initialization completed.\n\n";
83 |
84 | function getFileList($root, $basePath = '')
85 | {
86 | $files = [];
87 | $handle = opendir($root);
88 | while (($path = readdir($handle)) !== false) {
89 | if ($path === '.svn' || $path === '.' || $path === '..') {
90 | continue;
91 | }
92 | $fullPath = "$root/$path";
93 | $relativePath = $basePath === '' ? $path : "$basePath/$path";
94 | if (is_dir($fullPath)) {
95 | $files = array_merge($files, getFileList($fullPath, $relativePath));
96 | } else {
97 | $files[] = $relativePath;
98 | }
99 | }
100 | closedir($handle);
101 | return $files;
102 | }
103 |
104 | function copyFile($root, $source, $target, &$all, $params)
105 | {
106 | if (!is_file($root . '/' . $source)) {
107 | echo " skip $target ($source not exist)\n";
108 | return true;
109 | }
110 | if (is_file($root . '/' . $target)) {
111 | if (file_get_contents($root . '/' . $source) === file_get_contents($root . '/' . $target)) {
112 | echo " unchanged $target\n";
113 | return true;
114 | }
115 | if ($all) {
116 | echo " overwrite $target\n";
117 | } else {
118 | echo " exist $target\n";
119 | echo " ...overwrite? [Yes|No|All|Quit] ";
120 |
121 |
122 | $answer = !empty($params['overwrite']) ? $params['overwrite'] : trim(fgets(STDIN));
123 | if (!strncasecmp($answer, 'q', 1)) {
124 | return false;
125 | } else {
126 | if (!strncasecmp($answer, 'y', 1)) {
127 | echo " overwrite $target\n";
128 | } else {
129 | if (!strncasecmp($answer, 'a', 1)) {
130 | echo " overwrite $target\n";
131 | $all = true;
132 | } else {
133 | echo " skip $target\n";
134 | return true;
135 | }
136 | }
137 | }
138 | }
139 | file_put_contents($root . '/' . $target, file_get_contents($root . '/' . $source));
140 | return true;
141 | }
142 | echo " generate $target\n";
143 | @mkdir(dirname($root . '/' . $target), 0777, true);
144 | file_put_contents($root . '/' . $target, file_get_contents($root . '/' . $source));
145 | return true;
146 | }
147 |
148 | function getParams()
149 | {
150 | $rawParams = [];
151 | if (isset($_SERVER['argv'])) {
152 | $rawParams = $_SERVER['argv'];
153 | array_shift($rawParams);
154 | }
155 |
156 | $params = [];
157 | foreach ($rawParams as $param) {
158 | if (preg_match('/^--(\w+)(=(.*))?$/', $param, $matches)) {
159 | $name = $matches[1];
160 | $params[$name] = isset($matches[3]) ? $matches[3] : true;
161 | } else {
162 | $params[] = $param;
163 | }
164 | }
165 | return $params;
166 | }
167 |
168 | function setWritable($root, $paths)
169 | {
170 | foreach ($paths as $writable) {
171 | echo " chmod 0777 $writable\n";
172 | @chmod("$root/$writable", 0777);
173 | }
174 | }
175 |
176 | function setExecutable($root, $paths)
177 | {
178 | foreach ($paths as $executable) {
179 | echo " chmod 0755 $executable\n";
180 | @chmod("$root/$executable", 0755);
181 | }
182 | }
183 |
184 | function setCookieValidationKey($root, $paths)
185 | {
186 | foreach ($paths as $file) {
187 | echo " generate cookie validation key in $file\n";
188 | $file = $root . '/' . $file;
189 | $length = 32;
190 | $bytes = openssl_random_pseudo_bytes($length);
191 | $key = strtr(substr(base64_encode($bytes), 0, $length), '+/=', '_-.');
192 | $content = preg_replace('/(("|\')cookieValidationKey("|\')\s*=>\s*)(""|\'\')/', "\\1'$key'", file_get_contents($file));
193 | file_put_contents($file, $content);
194 | }
195 | }
196 |
197 | function createSymlink($links)
198 | {
199 | foreach ($links as $link => $target) {
200 | echo " symlink $target as $link\n";
201 | if (!is_link($link)) {
202 | symlink($target, $link);
203 | }
204 | }
205 | }
206 |
--------------------------------------------------------------------------------
/init.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | rem -------------------------------------------------------------
4 | rem Yii command line init 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%init" %*
19 |
20 | @endlocal
21 |
--------------------------------------------------------------------------------
/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 | 'phpExposePhp' => array(
111 | 'name' => 'Expose PHP',
112 | 'mandatory' => false,
113 | 'condition' => $requirementsChecker->checkPhpIniOff("expose_php"),
114 | 'by' => 'Security reasons',
115 | 'memo' => '"expose_php" should be disabled at php.ini',
116 | ),
117 | 'phpAllowUrlInclude' => array(
118 | 'name' => 'PHP allow url include',
119 | 'mandatory' => false,
120 | 'condition' => $requirementsChecker->checkPhpIniOff("allow_url_include"),
121 | 'by' => 'Security reasons',
122 | 'memo' => '"allow_url_include" should be disabled at php.ini',
123 | ),
124 | 'phpSmtp' => array(
125 | 'name' => 'PHP mail SMTP',
126 | 'mandatory' => false,
127 | 'condition' => strlen(ini_get('SMTP')) > 0,
128 | 'by' => 'Email sending',
129 | 'memo' => 'PHP mail SMTP server required',
130 | ),
131 | );
132 | $requirementsChecker->checkYii()->check($requirements)->render();
133 |
--------------------------------------------------------------------------------
/tests/README.md:
--------------------------------------------------------------------------------
1 | This directory contains various tests for the advanced applications.
2 |
3 | Tests in `codeception` directory are developed with [Codeception PHP Testing Framework](http://codeception.com/).
4 |
5 | After creating and setting up the advanced 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.*" "codeception/specify=*" "codeception/verify=*"
11 | ```
12 |
13 | If you've never used Composer for global packages run `composer global status`. It should output:
14 |
15 | ```
16 | Changed current directory to
17 | ```
18 |
19 | Then add `/vendor/bin` to you `PATH` environment variable. Now you're able to use `codecept` from command
20 | line globally.
21 |
22 | 2. Install faker extension by running the following from template root directory where `composer.json` is:
23 |
24 | ```
25 | composer require --dev yiisoft/yii2-faker:*
26 | ```
27 |
28 | 3. Create `yii2_advanced_tests` database then update it by applying migrations:
29 |
30 | ```
31 | codeception/bin/yii migrate
32 | ```
33 |
34 | 4. In order to be able to run acceptance tests you need to start a webserver. The simplest way is to use PHP built in
35 | webserver. In the root directory where `common`, `frontend` etc. are execute the following:
36 |
37 | ```
38 | php -S localhost:8080
39 | ```
40 |
41 | 5. Now you can run the tests with the following commands, assuming you are in the `tests/codeception` directory:
42 |
43 | ```
44 | # frontend tests
45 | cd frontend
46 | codecept build
47 | codecept run
48 |
49 | # backend tests
50 |
51 | cd backend
52 | codecept build
53 | codecept run
54 |
55 | # etc.
56 | ```
57 |
58 | If you already have run `codecept build` for each application, you can skip that step and run all tests by a single `codecept run`.
59 |
--------------------------------------------------------------------------------
/tests/codeception.yml:
--------------------------------------------------------------------------------
1 | include:
2 | - codeception/common
3 | - codeception/console
4 | - codeception/backend
5 | - codeception/frontend
6 |
7 | paths:
8 | log: codeception/_output
9 |
10 | settings:
11 | colors: true
12 |
--------------------------------------------------------------------------------
/tests/codeception/_output/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/tests/codeception/backend/.gitignore:
--------------------------------------------------------------------------------
1 | # these files are auto generated by codeception build
2 | /unit/UnitTester.php
3 | /functional/FunctionalTester.php
4 | /acceptance/AcceptanceTester.php
5 |
--------------------------------------------------------------------------------
/tests/codeception/backend/_bootstrap.php:
--------------------------------------------------------------------------------
1 | wantTo('ensure login page works');
10 |
11 | $loginPage = LoginPage::openBy($I);
12 |
13 | $I->amGoingTo('submit login form with no data');
14 | $loginPage->login('', '');
15 | if (method_exists($I, 'wait')) {
16 | $I->wait(3); // only for selenium
17 | }
18 | $I->expectTo('see validations errors');
19 | $I->see('Username cannot be blank.', '.help-block');
20 | $I->see('Password cannot be blank.', '.help-block');
21 |
22 | $I->amGoingTo('try to login with wrong credentials');
23 | $I->expectTo('see validations errors');
24 | $loginPage->login('admin', 'wrong');
25 | if (method_exists($I, 'wait')) {
26 | $I->wait(3); // only for selenium
27 | }
28 | $I->expectTo('see validations errors');
29 | $I->see('Incorrect username or password.', '.help-block');
30 |
31 | $I->amGoingTo('try to login with correct credentials');
32 | $loginPage->login('erau', 'password_0');
33 | if (method_exists($I, 'wait')) {
34 | $I->wait(3); // only for selenium
35 | }
36 | $I->expectTo('see that user is logged');
37 | $I->seeLink('Logout (erau)');
38 | $I->dontSeeLink('Login');
39 | $I->dontSeeLink('Signup');
40 | /** Uncomment if using WebDriver
41 | * $I->click('Logout (erau)');
42 | * $I->dontSeeLink('Logout (erau)');
43 | * $I->seeLink('Login');
44 | */
45 |
--------------------------------------------------------------------------------
/tests/codeception/backend/acceptance/_bootstrap.php:
--------------------------------------------------------------------------------
1 | wantTo('ensure login page works');
10 |
11 | $loginPage = LoginPage::openBy($I);
12 |
13 | $I->amGoingTo('submit login form with no data');
14 | $loginPage->login('', '');
15 | $I->expectTo('see validations errors');
16 | $I->see('Username cannot be blank.', '.help-block');
17 | $I->see('Password cannot be blank.', '.help-block');
18 |
19 | $I->amGoingTo('try to login with wrong credentials');
20 | $I->expectTo('see validations errors');
21 | $loginPage->login('admin', 'wrong');
22 | $I->expectTo('see validations errors');
23 | $I->see('Incorrect username or password.', '.help-block');
24 |
25 | $I->amGoingTo('try to login with correct credentials');
26 | $loginPage->login('erau', 'password_0');
27 | $I->expectTo('see that user is logged');
28 | $I->seeLink('Logout (erau)');
29 | $I->dontSeeLink('Login');
30 | $I->dontSeeLink('Signup');
31 |
--------------------------------------------------------------------------------
/tests/codeception/backend/functional/_bootstrap.php:
--------------------------------------------------------------------------------
1 | run();
23 | exit($exitCode);
24 |
--------------------------------------------------------------------------------
/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/common/.gitignore:
--------------------------------------------------------------------------------
1 | # these files are auto generated by codeception build
2 | /unit/UnitTester.php
3 | /functional/FunctionalTester.php
4 | /acceptance/AcceptanceTester.php
5 |
--------------------------------------------------------------------------------
/tests/codeception/common/_bootstrap.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/common/_support/FixtureHelper.php:
--------------------------------------------------------------------------------
1 | loadFixtures();
38 | }
39 |
40 | /**
41 | * Method is called after all suite tests run
42 | */
43 | public function _afterSuite()
44 | {
45 | $this->unloadFixtures();
46 | }
47 |
48 | /**
49 | * @inheritdoc
50 | */
51 | public function fixtures()
52 | {
53 | return [
54 | 'user' => [
55 | 'class' => UserFixture::className(),
56 | 'dataFile' => '@tests/codeception/common/fixtures/data/init_login.php',
57 | ],
58 | ];
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/tests/codeception/common/codeception.yml:
--------------------------------------------------------------------------------
1 | namespace: tests\codeception\common
2 | actor: Tester
3 | paths:
4 | tests: .
5 | log: _output
6 | data: _data
7 | helpers: _support
8 | settings:
9 | bootstrap: _bootstrap.php
10 | suite_class: \PHPUnit_Framework_TestSuite
11 | colors: true
12 | memory_limit: 1024M
13 | log: true
14 |
--------------------------------------------------------------------------------
/tests/codeception/common/fixtures/UserFixture.php:
--------------------------------------------------------------------------------
1 | 'erau',
6 | 'auth_key' => 'tUu1qHcde0diwUol3xeI-18MuHkkprQI',
7 | // password_0
8 | 'password_hash' => '$2y$13$nJ1WDlBaGcbCdbNC5.5l4.sgy.OMEKCqtDQOdQ2OWpgiKRWYyzzne',
9 | 'password_reset_token' => 'RkD_Jw0_8HEedzLk7MM-ZKEFfYR7VbMr_1392559490',
10 | 'created_at' => '1392559490',
11 | 'updated_at' => '1392559490',
12 | 'email' => 'sfriesen@jenkins.info',
13 | ],
14 | ];
15 |
--------------------------------------------------------------------------------
/tests/codeception/common/templates/fixtures/user.php:
--------------------------------------------------------------------------------
1 | getSecurity();
8 |
9 | return [
10 | 'username' => $faker->userName,
11 | 'email' => $faker->email,
12 | 'auth_key' => $security->generateRandomString(),
13 | 'password_hash' => $security->generatePasswordHash('password_' . $index),
14 | 'password_reset_token' => $security->generateRandomString() . '_' . time(),
15 | 'created_at' => time(),
16 | 'updated_at' => time(),
17 | ];
18 |
--------------------------------------------------------------------------------
/tests/codeception/common/unit.suite.yml:
--------------------------------------------------------------------------------
1 | # Codeception Test Suite Configuration
2 |
3 | # suite for unit (internal) tests.
4 | # RUN `build` COMMAND AFTER ADDING/REMOVING MODULES.
5 |
6 | class_name: UnitTester
7 |
--------------------------------------------------------------------------------
/tests/codeception/common/unit/DbTestCase.php:
--------------------------------------------------------------------------------
1 | 'bayer.hudson',
6 | 'auth_key' => 'HP187Mvq7Mmm3CTU80dLkGmni_FUH_lR',
7 | //password_0
8 | 'password_hash' => '$2y$13$EjaPFBnZOQsHdGuHI.xvhuDp1fHpo8hKRSk6yshqa9c5EG8s3C3lO',
9 | 'password_reset_token' => 'ExzkCOaYc1L8IOBs4wdTGGbgNiG3Wz1I_1402312317',
10 | 'created_at' => '1402312317',
11 | 'updated_at' => '1402312317',
12 | 'email' => 'nicole.paucek@schultz.info',
13 | ],
14 | ];
15 |
--------------------------------------------------------------------------------
/tests/codeception/common/unit/models/LoginFormTest.php:
--------------------------------------------------------------------------------
1 | [
25 | 'user' => [
26 | 'class' => 'yii\web\User',
27 | 'identityClass' => 'common\models\User',
28 | ],
29 | ],
30 | ]);
31 | }
32 |
33 | protected function tearDown()
34 | {
35 | Yii::$app->user->logout();
36 | parent::tearDown();
37 | }
38 |
39 | public function testLoginNoUser()
40 | {
41 | $model = new LoginForm([
42 | 'username' => 'not_existing_username',
43 | 'password' => 'not_existing_password',
44 | ]);
45 |
46 | $this->specify('user should not be able to login, when there is no identity', function () use ($model) {
47 | expect('model should not login user', $model->login())->false();
48 | expect('user should not be logged in', Yii::$app->user->isGuest)->true();
49 | });
50 | }
51 |
52 | public function testLoginWrongPassword()
53 | {
54 | $model = new LoginForm([
55 | 'username' => 'bayer.hudson',
56 | 'password' => 'wrong_password',
57 | ]);
58 |
59 | $this->specify('user should not be able to login with wrong password', function () use ($model) {
60 | expect('model should not login user', $model->login())->false();
61 | expect('error message should be set', $model->errors)->hasKey('password');
62 | expect('user should not be logged in', Yii::$app->user->isGuest)->true();
63 | });
64 | }
65 |
66 | public function testLoginCorrect()
67 | {
68 |
69 | $model = new LoginForm([
70 | 'username' => 'bayer.hudson',
71 | 'password' => 'password_0',
72 | ]);
73 |
74 | $this->specify('user should be able to login with correct credentials', function () use ($model) {
75 | expect('model should login user', $model->login())->true();
76 | expect('error message should not be set', $model->errors)->hasntKey('password');
77 | expect('user should be logged in', Yii::$app->user->isGuest)->false();
78 | });
79 | }
80 |
81 | /**
82 | * @inheritdoc
83 | */
84 | public function fixtures()
85 | {
86 | return [
87 | 'user' => [
88 | 'class' => UserFixture::className(),
89 | 'dataFile' => '@tests/codeception/common/unit/fixtures/data/models/user.php'
90 | ],
91 | ];
92 | }
93 |
94 | }
95 |
--------------------------------------------------------------------------------
/tests/codeception/config/acceptance.php:
--------------------------------------------------------------------------------
1 | 'app-common',
12 | 'basePath' => dirname(__DIR__),
13 | ]
14 | );
15 |
--------------------------------------------------------------------------------
/tests/codeception/config/config.php:
--------------------------------------------------------------------------------
1 | [
7 | 'fixture' => [
8 | 'class' => 'yii\faker\FixtureController',
9 | 'fixtureDataPath' => '@tests/codeception/common/fixtures/data',
10 | 'templatePath' => '@tests/codeception/common/templates/fixtures',
11 | 'namespace' => 'tests\codeception\common\fixtures',
12 | ],
13 | ],
14 | 'components' => [
15 | 'db' => [
16 | 'dsn' => 'mysql:host=localhost;dbname=yii2_advanced_tests',
17 | ],
18 | 'mailer' => [
19 | 'useFileTransport' => true,
20 | ],
21 | 'urlManager' => [
22 | 'showScriptName' => true,
23 | ],
24 | ],
25 | ];
26 |
--------------------------------------------------------------------------------
/tests/codeception/config/console/unit.php:
--------------------------------------------------------------------------------
1 | [
7 | 'request' => [
8 | // it's not recommended to run functional tests with CSRF validation enabled
9 | 'enableCsrfValidation' => false,
10 | // but if you absolutely need it set cookie domain to localhost
11 | /*
12 | 'csrfCookie' => [
13 | 'domain' => 'localhost',
14 | ],
15 | */
16 | ],
17 | ],
18 | ];
--------------------------------------------------------------------------------
/tests/codeception/config/unit.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 |
--------------------------------------------------------------------------------
/tests/codeception/frontend/_pages/SignupPage.php:
--------------------------------------------------------------------------------
1 | $value) {
22 | $inputType = $field === 'body' ? 'textarea' : 'input';
23 | $this->actor->fillField($inputType . '[name="SignupForm[' . $field . ']"]', $value);
24 | }
25 | $this->actor->click('signup-button');
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/tests/codeception/frontend/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 | - tests\codeception\common\_support\FixtureHelper
16 | # you can use WebDriver instead of PhpBrowser to test javascript and ajax.
17 | # This will require you to install selenium. See http://codeception.com/docs/04-AcceptanceTests#Selenium
18 | # "restart" option is used by the WebDriver to start each time per test-file new session and cookies,
19 | # it is useful if you want to login in your app in each test.
20 | # - WebDriver
21 | config:
22 | PhpBrowser:
23 | # PLEASE ADJUST IT TO THE ACTUAL ENTRY POINT WITHOUT PATH INFO
24 | url: http://localhost:8080
25 | # WebDriver:
26 | # url: http://localhost:8080
27 | # browser: firefox
28 | # restart: true
29 |
--------------------------------------------------------------------------------
/tests/codeception/frontend/acceptance/AboutCept.php:
--------------------------------------------------------------------------------
1 | wantTo('ensure that about works');
9 | AboutPage::openBy($I);
10 | $I->see('About', 'h1');
11 |
--------------------------------------------------------------------------------
/tests/codeception/frontend/acceptance/ContactCept.php:
--------------------------------------------------------------------------------
1 | wantTo('ensure that contact works');
9 |
10 | $contactPage = ContactPage::openBy($I);
11 |
12 | $I->see('Contact', 'h1');
13 |
14 | $I->amGoingTo('submit contact form with no data');
15 | $contactPage->submit([]);
16 | if (method_exists($I, 'wait')) {
17 | $I->wait(3); // only for selenium
18 | }
19 | $I->expectTo('see validations errors');
20 | $I->see('Contact', 'h1');
21 | $I->see('Name cannot be blank', '.help-block');
22 | $I->see('Email cannot be blank', '.help-block');
23 | $I->see('Subject cannot be blank', '.help-block');
24 | $I->see('Body cannot be blank', '.help-block');
25 | $I->see('The verification code is incorrect', '.help-block');
26 |
27 | $I->amGoingTo('submit contact form with not correct email');
28 | $contactPage->submit([
29 | 'name' => 'tester',
30 | 'email' => 'tester.email',
31 | 'subject' => 'test subject',
32 | 'body' => 'test content',
33 | 'verifyCode' => 'testme',
34 | ]);
35 | if (method_exists($I, 'wait')) {
36 | $I->wait(3); // only for selenium
37 | }
38 | $I->expectTo('see that email adress is wrong');
39 | $I->dontSee('Name cannot be blank', '.help-block');
40 | $I->see('Email is not a valid email address.', '.help-block');
41 | $I->dontSee('Subject cannot be blank', '.help-block');
42 | $I->dontSee('Body cannot be blank', '.help-block');
43 | $I->dontSee('The verification code is incorrect', '.help-block');
44 |
45 | $I->amGoingTo('submit contact form with correct data');
46 | $contactPage->submit([
47 | 'name' => 'tester',
48 | 'email' => 'tester@example.com',
49 | 'subject' => 'test subject',
50 | 'body' => 'test content',
51 | 'verifyCode' => 'testme',
52 | ]);
53 | if (method_exists($I, 'wait')) {
54 | $I->wait(3); // only for selenium
55 | }
56 | $I->see('Thank you for contacting us. We will respond to you as soon as possible.');
57 |
--------------------------------------------------------------------------------
/tests/codeception/frontend/acceptance/HomeCept.php:
--------------------------------------------------------------------------------
1 | wantTo('ensure that home page works');
8 | $I->amOnPage(Yii::$app->homeUrl);
9 | $I->see('My Company');
10 | $I->seeLink('About');
11 | $I->click('About');
12 | $I->see('This is the About page.');
13 |
--------------------------------------------------------------------------------
/tests/codeception/frontend/acceptance/LoginCept.php:
--------------------------------------------------------------------------------
1 | wantTo('ensure login page works');
9 |
10 | $loginPage = LoginPage::openBy($I);
11 |
12 | $I->amGoingTo('submit login form with no data');
13 | $loginPage->login('', '');
14 | $I->expectTo('see validations errors');
15 | $I->see('Username cannot be blank.', '.help-block');
16 | $I->see('Password cannot be blank.', '.help-block');
17 |
18 | $I->amGoingTo('try to login with wrong credentials');
19 | $I->expectTo('see validations errors');
20 | $loginPage->login('admin', 'wrong');
21 | $I->expectTo('see validations errors');
22 | $I->see('Incorrect username or password.', '.help-block');
23 |
24 | $I->amGoingTo('try to login with correct credentials');
25 | $loginPage->login('erau', 'password_0');
26 | $I->expectTo('see that user is logged');
27 | $I->seeLink('Logout (erau)');
28 | $I->dontSeeLink('Login');
29 | $I->dontSeeLink('Signup');
30 | /** Uncomment if using WebDriver
31 | * $I->click('Logout (erau)');
32 | * $I->dontSeeLink('Logout (erau)');
33 | * $I->seeLink('Login');
34 | */
35 |
--------------------------------------------------------------------------------
/tests/codeception/frontend/acceptance/SignupCest.php:
--------------------------------------------------------------------------------
1 | 'tester.email@example.com',
27 | 'username' => 'tester',
28 | ]);
29 | }
30 |
31 | /**
32 | * This method is called when test fails.
33 | * @param \Codeception\Event\FailEvent $event
34 | */
35 | public function _fail($event)
36 | {
37 | }
38 |
39 | /**
40 | * @param \codeception_frontend\AcceptanceTester $I
41 | * @param \Codeception\Scenario $scenario
42 | */
43 | public function testUserSignup($I, $scenario)
44 | {
45 | $I->wantTo('ensure that signup works');
46 |
47 | $signupPage = SignupPage::openBy($I);
48 | $I->see('Signup', 'h1');
49 | $I->see('Please fill out the following fields to signup:');
50 |
51 | $I->amGoingTo('submit signup form with no data');
52 |
53 | $signupPage->submit([]);
54 |
55 | $I->expectTo('see validation errors');
56 | $I->see('Username cannot be blank.', '.help-block');
57 | $I->see('Email cannot be blank.', '.help-block');
58 | $I->see('Password cannot be blank.', '.help-block');
59 |
60 | $I->amGoingTo('submit signup form with not correct email');
61 | $signupPage->submit([
62 | 'username' => 'tester',
63 | 'email' => 'tester.email',
64 | 'password' => 'tester_password',
65 | ]);
66 |
67 | $I->expectTo('see that email address is wrong');
68 | $I->dontSee('Username cannot be blank.', '.help-block');
69 | $I->dontSee('Password cannot be blank.', '.help-block');
70 | $I->see('Email is not a valid email address.', '.help-block');
71 |
72 | $I->amGoingTo('submit signup form with correct email');
73 | $signupPage->submit([
74 | 'username' => 'tester',
75 | 'email' => 'tester.email@example.com',
76 | 'password' => 'tester_password',
77 | ]);
78 |
79 | $I->expectTo('see that user logged in');
80 | $I->seeLink('Logout (tester)');
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/tests/codeception/frontend/acceptance/_bootstrap.php:
--------------------------------------------------------------------------------
1 | wantTo('ensure that about works');
9 | AboutPage::openBy($I);
10 | $I->see('About', 'h1');
11 |
--------------------------------------------------------------------------------
/tests/codeception/frontend/functional/ContactCept.php:
--------------------------------------------------------------------------------
1 | wantTo('ensure that contact works');
9 |
10 | $contactPage = ContactPage::openBy($I);
11 |
12 | $I->see('Contact', 'h1');
13 |
14 | $I->amGoingTo('submit contact form with no data');
15 | $contactPage->submit([]);
16 | $I->expectTo('see validations errors');
17 | $I->see('Contact', 'h1');
18 | $I->see('Name cannot be blank', '.help-block');
19 | $I->see('Email cannot be blank', '.help-block');
20 | $I->see('Subject cannot be blank', '.help-block');
21 | $I->see('Body cannot be blank', '.help-block');
22 | $I->see('The verification code is incorrect', '.help-block');
23 |
24 | $I->amGoingTo('submit contact form with not correct email');
25 | $contactPage->submit([
26 | 'name' => 'tester',
27 | 'email' => 'tester.email',
28 | 'subject' => 'test subject',
29 | 'body' => 'test content',
30 | 'verifyCode' => 'testme',
31 | ]);
32 | $I->expectTo('see that email adress is wrong');
33 | $I->dontSee('Name cannot be blank', '.help-block');
34 | $I->see('Email is not a valid email address.', '.help-block');
35 | $I->dontSee('Subject cannot be blank', '.help-block');
36 | $I->dontSee('Body cannot be blank', '.help-block');
37 | $I->dontSee('The verification code is incorrect', '.help-block');
38 |
39 | $I->amGoingTo('submit contact form with correct data');
40 | $contactPage->submit([
41 | 'name' => 'tester',
42 | 'email' => 'tester@example.com',
43 | 'subject' => 'test subject',
44 | 'body' => 'test content',
45 | 'verifyCode' => 'testme',
46 | ]);
47 | $I->see('Thank you for contacting us. We will respond to you as soon as possible.');
48 |
--------------------------------------------------------------------------------
/tests/codeception/frontend/functional/HomeCept.php:
--------------------------------------------------------------------------------
1 | wantTo('ensure that home page works');
8 | $I->amOnPage(Yii::$app->homeUrl);
9 | $I->see('My Company');
10 | $I->seeLink('About');
11 | $I->click('About');
12 | $I->see('This is the About page.');
13 |
--------------------------------------------------------------------------------
/tests/codeception/frontend/functional/LoginCept.php:
--------------------------------------------------------------------------------
1 | wantTo('ensure login page works');
9 |
10 | $loginPage = LoginPage::openBy($I);
11 |
12 | $I->amGoingTo('submit login form with no data');
13 | $loginPage->login('', '');
14 | $I->expectTo('see validations errors');
15 | $I->see('Username cannot be blank.', '.help-block');
16 | $I->see('Password cannot be blank.', '.help-block');
17 |
18 | $I->amGoingTo('try to login with wrong credentials');
19 | $I->expectTo('see validations errors');
20 | $loginPage->login('admin', 'wrong');
21 | $I->expectTo('see validations errors');
22 | $I->see('Incorrect username or password.', '.help-block');
23 |
24 | $I->amGoingTo('try to login with correct credentials');
25 | $loginPage->login('erau', 'password_0');
26 | $I->expectTo('see that user is logged');
27 | $I->seeLink('Logout (erau)');
28 | $I->dontSeeLink('Login');
29 | $I->dontSeeLink('Signup');
30 |
--------------------------------------------------------------------------------
/tests/codeception/frontend/functional/SignupCest.php:
--------------------------------------------------------------------------------
1 | 'tester.email@example.com',
27 | 'username' => 'tester',
28 | ]);
29 | }
30 |
31 | /**
32 | * This method is called when test fails.
33 | * @param \Codeception\Event\FailEvent $event
34 | */
35 | public function _fail($event)
36 | {
37 |
38 | }
39 |
40 | /**
41 | *
42 | * @param \codeception_frontend\FunctionalTester $I
43 | * @param \Codeception\Scenario $scenario
44 | */
45 | public function testUserSignup($I, $scenario)
46 | {
47 | $I->wantTo('ensure that signup works');
48 |
49 | $signupPage = SignupPage::openBy($I);
50 | $I->see('Signup', 'h1');
51 | $I->see('Please fill out the following fields to signup:');
52 |
53 | $I->amGoingTo('submit signup form with no data');
54 |
55 | $signupPage->submit([]);
56 |
57 | $I->expectTo('see validation errors');
58 | $I->see('Username cannot be blank.', '.help-block');
59 | $I->see('Email cannot be blank.', '.help-block');
60 | $I->see('Password cannot be blank.', '.help-block');
61 |
62 | $I->amGoingTo('submit signup form with not correct email');
63 | $signupPage->submit([
64 | 'username' => 'tester',
65 | 'email' => 'tester.email',
66 | 'password' => 'tester_password',
67 | ]);
68 |
69 | $I->expectTo('see that email address is wrong');
70 | $I->dontSee('Username cannot be blank.', '.help-block');
71 | $I->dontSee('Password cannot be blank.', '.help-block');
72 | $I->see('Email is not a valid email address.', '.help-block');
73 |
74 | $I->amGoingTo('submit signup form with correct email');
75 | $signupPage->submit([
76 | 'username' => 'tester',
77 | 'email' => 'tester.email@example.com',
78 | 'password' => 'tester_password',
79 | ]);
80 |
81 | $I->expectTo('see that user is created');
82 | $I->seeRecord('common\models\User', [
83 | 'username' => 'tester',
84 | 'email' => 'tester.email@example.com',
85 | ]);
86 |
87 | $I->expectTo('see that user logged in');
88 | $I->seeLink('Logout (tester)');
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/tests/codeception/frontend/functional/_bootstrap.php:
--------------------------------------------------------------------------------
1 | 'okirlin',
6 | 'auth_key' => 'iwTNae9t34OmnK6l4vT4IeaTk-YWI2Rv',
7 | 'password_hash' => '$2y$13$CXT0Rkle1EMJ/c1l5bylL.EylfmQ39O5JlHJVFpNn618OUS1HwaIi',
8 | 'password_reset_token' => 't5GU9NwpuGYSfb7FEZMAxqtuz2PkEvv_' . time(),
9 | 'created_at' => '1391885313',
10 | 'updated_at' => '1391885313',
11 | 'email' => 'brady.renner@rutherford.com',
12 | ],
13 | [
14 | 'username' => 'troy.becker',
15 | 'auth_key' => 'EdKfXrx88weFMV0vIxuTMWKgfK2tS3Lp',
16 | 'password_hash' => '$2y$13$g5nv41Px7VBqhS3hVsVN2.MKfgT3jFdkXEsMC4rQJLfaMa7VaJqL2',
17 | 'password_reset_token' => '4BSNyiZNAuxjs5Mty990c47sVrgllIi_' . time(),
18 | 'created_at' => '1391885313',
19 | 'updated_at' => '1391885313',
20 | 'email' => 'nicolas.dianna@hotmail.com',
21 | 'status' => '0',
22 | ],
23 | ];
24 |
--------------------------------------------------------------------------------
/tests/codeception/frontend/unit/models/ContactFormTest.php:
--------------------------------------------------------------------------------
1 | mailer->fileTransportCallback = function ($mailer, $message) {
18 | return 'testing_message.eml';
19 | };
20 | }
21 |
22 | protected function tearDown()
23 | {
24 | unlink($this->getMessageFile());
25 | parent::tearDown();
26 | }
27 |
28 | public function testContact()
29 | {
30 | $model = new ContactForm();
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->sendEmail('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 |
--------------------------------------------------------------------------------
/tests/codeception/frontend/unit/models/PasswordResetRequestFormTest.php:
--------------------------------------------------------------------------------
1 | mailer->fileTransportCallback = function ($mailer, $message) {
21 | return 'testing_message.eml';
22 | };
23 | }
24 |
25 | protected function tearDown()
26 | {
27 | @unlink($this->getMessageFile());
28 |
29 | parent::tearDown();
30 | }
31 |
32 | public function testSendEmailWrongUser()
33 | {
34 | $this->specify('no user with such email, message should not be send', function () {
35 |
36 | $model = new PasswordResetRequestForm();
37 | $model->email = 'not-existing-email@example.com';
38 |
39 | expect('email not send', $model->sendEmail())->false();
40 |
41 | });
42 |
43 | $this->specify('user is not active, message should not be send', function () {
44 |
45 | $model = new PasswordResetRequestForm();
46 | $model->email = $this->user[1]['email'];
47 |
48 | expect('email not send', $model->sendEmail())->false();
49 |
50 | });
51 | }
52 |
53 | public function testSendEmailCorrectUser()
54 | {
55 | $model = new PasswordResetRequestForm();
56 | $model->email = $this->user[0]['email'];
57 | $user = User::findOne(['password_reset_token' => $this->user[0]['password_reset_token']]);
58 |
59 | expect('email sent', $model->sendEmail())->true();
60 | expect('user has valid token', $user->password_reset_token)->notNull();
61 |
62 | $this->specify('message has correct format', function () use ($model) {
63 |
64 | expect('message file exists', file_exists($this->getMessageFile()))->true();
65 |
66 | $message = file_get_contents($this->getMessageFile());
67 | expect('message "from" is correct', $message)->contains(Yii::$app->params['supportEmail']);
68 | expect('message "to" is correct', $message)->contains($model->email);
69 |
70 | });
71 | }
72 |
73 | public function fixtures()
74 | {
75 | return [
76 | 'user' => [
77 | 'class' => UserFixture::className(),
78 | 'dataFile' => '@tests/codeception/frontend/unit/fixtures/data/models/user.php'
79 | ],
80 | ];
81 | }
82 |
83 | private function getMessageFile()
84 | {
85 | return Yii::getAlias(Yii::$app->mailer->fileTransportPath) . '/testing_message.eml';
86 | }
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/tests/codeception/frontend/unit/models/ResetPasswordFormTest.php:
--------------------------------------------------------------------------------
1 | user[0]['password_reset_token']);
31 | expect('password should be resetted', $form->resetPassword())->true();
32 | }
33 |
34 | public function fixtures()
35 | {
36 | return [
37 | 'user' => [
38 | 'class' => UserFixture::className(),
39 | 'dataFile' => '@tests/codeception/frontend/unit/fixtures/data/models/user.php'
40 | ],
41 | ];
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/tests/codeception/frontend/unit/models/SignupFormTest.php:
--------------------------------------------------------------------------------
1 | 'some_username',
19 | 'email' => 'some_email@example.com',
20 | 'password' => 'some_password',
21 | ]);
22 |
23 | $user = $model->signup();
24 |
25 | $this->assertInstanceOf('common\models\User', $user, 'user should be valid');
26 |
27 | expect('username should be correct', $user->username)->equals('some_username');
28 | expect('email should be correct', $user->email)->equals('some_email@example.com');
29 | expect('password should be correct', $user->validatePassword('some_password'))->true();
30 | }
31 |
32 | public function testNotCorrectSignup()
33 | {
34 | $model = new SignupForm([
35 | 'username' => 'troy.becker',
36 | 'email' => 'nicolas.dianna@hotmail.com',
37 | 'password' => 'some_password',
38 | ]);
39 |
40 | expect('username and email are in use, user should not be created', $model->signup())->null();
41 | }
42 |
43 | public function fixtures()
44 | {
45 | return [
46 | 'user' => [
47 | 'class' => UserFixture::className(),
48 | 'dataFile' => '@tests/codeception/frontend/unit/fixtures/data/models/user.php',
49 | ],
50 | ];
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------